subtest grant_revoke

statement ok
CREATE SCHEMA test_priv_sc1;
SET search_path = public,test_priv_sc1;
CREATE PROCEDURE test_priv_p1() LANGUAGE SQL AS $$ SELECT 1 $$;
CREATE PROCEDURE test_priv_p2(int) LANGUAGE SQL AS $$ SELECT 1 $$;
CREATE PROCEDURE test_priv_sc1.test_priv_p3() LANGUAGE SQL AS $$ SELECT 1 $$;
CREATE USER test_user;

query TTTTTTTTTT colnames
SELECT * FROM information_schema.role_routine_grants
WHERE routine_name IN ('test_priv_p1', 'test_priv_p2', 'test_priv_p3')
ORDER BY grantee, routine_name;
----
grantor  grantee  specific_catalog  specific_schema  specific_name        routine_catalog  routine_schema  routine_name  privilege_type  is_grantable
NULL     admin    test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     admin    test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     admin    test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     public   test              public           test_priv_p1_100107  test             public          test_priv_p1  EXECUTE         NO
NULL     public   test              public           test_priv_p2_100108  test             public          test_priv_p2  EXECUTE         NO
NULL     public   test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  EXECUTE         NO
NULL     root     test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     root     test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     root     test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES

query TTTTTTB colnames,rowsort
SHOW GRANTS ON PROCEDURE test_priv_p1, test_priv_p2, test_priv_p3
----
database_name  schema_name    routine_id  routine_signature   grantee  privilege_type  is_grantable
test           public         100107      test_priv_p1()      admin    ALL             true
test           public         100107      test_priv_p1()      public   EXECUTE         false
test           public         100107      test_priv_p1()      root     ALL             true
test           public         100108      test_priv_p2(int8)  admin    ALL             true
test           public         100108      test_priv_p2(int8)  public   EXECUTE         false
test           public         100108      test_priv_p2(int8)  root     ALL             true
test           test_priv_sc1  100109      test_priv_p3()      admin    ALL             true
test           test_priv_sc1  100109      test_priv_p3()      public   EXECUTE         false
test           test_priv_sc1  100109      test_priv_p3()      root     ALL             true

query TTTTTTB colnames,rowsort
SHOW GRANTS ON PROCEDURE test_priv_p1(), test_priv_p2(INT), test_priv_p3()
----
database_name  schema_name    routine_id  routine_signature   grantee  privilege_type  is_grantable
test           public         100107      test_priv_p1()      admin    ALL             true
test           public         100107      test_priv_p1()      public   EXECUTE         false
test           public         100107      test_priv_p1()      root     ALL             true
test           public         100108      test_priv_p2(int8)  admin    ALL             true
test           public         100108      test_priv_p2(int8)  public   EXECUTE         false
test           public         100108      test_priv_p2(int8)  root     ALL             true
test           test_priv_sc1  100109      test_priv_p3()      admin    ALL             true
test           test_priv_sc1  100109      test_priv_p3()      public   EXECUTE         false
test           test_priv_sc1  100109      test_priv_p3()      root     ALL             true

statement error pgcode 42883 procedure test_priv_p2\(string\) does not exist
SHOW GRANTS ON PROCEDURE test_priv_p2(STRING)

query TTT colnames
SELECT * FROM [SHOW PROCEDURES] ORDER BY procedure_name
----
schema_name    procedure_name  argument_data_types
public         test_priv_p1    ·
public         test_priv_p2    int8
test_priv_sc1  test_priv_p3    ·

query TTT colnames
SELECT * FROM [SHOW PROCEDURES FROM public] ORDER BY procedure_name
----
schema_name  procedure_name  argument_data_types
public       test_priv_p1    ·
public       test_priv_p2    int8

query TTT colnames
SHOW PROCEDURES FROM test_priv_sc1
----
schema_name    procedure_name  argument_data_types
test_priv_sc1  test_priv_p3    ·

query TTT colnames
SELECT * FROM [SHOW PROCEDURES FROM test] ORDER BY procedure_name
----
schema_name    procedure_name  argument_data_types
public         test_priv_p1    ·
public         test_priv_p2    int8
test_priv_sc1  test_priv_p3    ·

statement error pgcode 42809 test_priv_p1\(\) is not a function
GRANT EXECUTE ON FUNCTION test_priv_p1() TO test_user WITH GRANT OPTION

statement ok
GRANT EXECUTE ON PROCEDURE test_priv_p1(), test_priv_p2(int), test_priv_sc1.test_priv_p3 TO test_user WITH GRANT OPTION;

query TTTTTTTTTT colnames
SELECT * FROM information_schema.role_routine_grants
WHERE routine_name IN ('test_priv_p1', 'test_priv_p2', 'test_priv_p3')
ORDER BY grantee, routine_name;
----
grantor  grantee    specific_catalog  specific_schema  specific_name        routine_catalog  routine_schema  routine_name  privilege_type  is_grantable
NULL     admin      test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     admin      test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     admin      test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     public     test              public           test_priv_p1_100107  test             public          test_priv_p1  EXECUTE         NO
NULL     public     test              public           test_priv_p2_100108  test             public          test_priv_p2  EXECUTE         NO
NULL     public     test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  EXECUTE         NO
NULL     root       test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     root       test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     root       test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     test_user  test              public           test_priv_p1_100107  test             public          test_priv_p1  EXECUTE         YES
NULL     test_user  test              public           test_priv_p2_100108  test             public          test_priv_p2  EXECUTE         YES
NULL     test_user  test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  EXECUTE         YES

query TTTTTTB colnames,rowsort
SHOW GRANTS ON PROCEDURE test_priv_p1, test_priv_p2, test_priv_p3
----
database_name  schema_name    routine_id  routine_signature   grantee    privilege_type  is_grantable
test           public         100107      test_priv_p1()      admin      ALL             true
test           public         100107      test_priv_p1()      public     EXECUTE         false
test           public         100107      test_priv_p1()      root       ALL             true
test           public         100107      test_priv_p1()      test_user  EXECUTE         true
test           public         100108      test_priv_p2(int8)  admin      ALL             true
test           public         100108      test_priv_p2(int8)  public     EXECUTE         false
test           public         100108      test_priv_p2(int8)  root       ALL             true
test           public         100108      test_priv_p2(int8)  test_user  EXECUTE         true
test           test_priv_sc1  100109      test_priv_p3()      admin      ALL             true
test           test_priv_sc1  100109      test_priv_p3()      public     EXECUTE         false
test           test_priv_sc1  100109      test_priv_p3()      root       ALL             true
test           test_priv_sc1  100109      test_priv_p3()      test_user  EXECUTE         true

statement error pgcode 2BP01 pq: cannot drop role/user test_user: grants still exist on.*
DROP USER test_user;

statement error pgcode 42809 test_priv_p1\(\) is not a function
REVOKE GRANT OPTION FOR EXECUTE ON FUNCTION test_priv_p1() FROM test_user

statement ok
REVOKE GRANT OPTION FOR EXECUTE ON PROCEDURE test_priv_p1(), test_priv_p2(int), test_priv_sc1.test_priv_p3 FROM test_user;

query TTTTTTTTTT colnames
SELECT * FROM information_schema.role_routine_grants
WHERE routine_name IN ('test_priv_p1', 'test_priv_p2', 'test_priv_p3')
ORDER BY grantee, routine_name;
----
grantor  grantee    specific_catalog  specific_schema  specific_name        routine_catalog  routine_schema  routine_name  privilege_type  is_grantable
NULL     admin      test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     admin      test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     admin      test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     public     test              public           test_priv_p1_100107  test             public          test_priv_p1  EXECUTE         NO
NULL     public     test              public           test_priv_p2_100108  test             public          test_priv_p2  EXECUTE         NO
NULL     public     test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  EXECUTE         NO
NULL     root       test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     root       test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     root       test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     test_user  test              public           test_priv_p1_100107  test             public          test_priv_p1  EXECUTE         NO
NULL     test_user  test              public           test_priv_p2_100108  test             public          test_priv_p2  EXECUTE         NO
NULL     test_user  test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  EXECUTE         NO

query TTTTTTB colnames,rowsort
SHOW GRANTS ON PROCEDURE test_priv_p1, test_priv_p2, test_priv_p3
----
database_name  schema_name    routine_id  routine_signature   grantee    privilege_type  is_grantable
test           public         100107      test_priv_p1()      admin      ALL             true
test           public         100107      test_priv_p1()      public     EXECUTE         false
test           public         100107      test_priv_p1()      root       ALL             true
test           public         100107      test_priv_p1()      test_user  EXECUTE         false
test           public         100108      test_priv_p2(int8)  admin      ALL             true
test           public         100108      test_priv_p2(int8)  public     EXECUTE         false
test           public         100108      test_priv_p2(int8)  root       ALL             true
test           public         100108      test_priv_p2(int8)  test_user  EXECUTE         false
test           test_priv_sc1  100109      test_priv_p3()      admin      ALL             true
test           test_priv_sc1  100109      test_priv_p3()      public     EXECUTE         false
test           test_priv_sc1  100109      test_priv_p3()      root       ALL             true
test           test_priv_sc1  100109      test_priv_p3()      test_user  EXECUTE         false

statement ok
REVOKE EXECUTE ON PROCEDURE test_priv_p1(), test_priv_p2(int), test_priv_sc1.test_priv_p3 FROM test_user;

query TTTTTTTTTT colnames
SELECT * FROM information_schema.role_routine_grants
WHERE routine_name IN ('test_priv_p1', 'test_priv_p2', 'test_priv_p3')
ORDER BY grantee, routine_name;
----
grantor  grantee  specific_catalog  specific_schema  specific_name        routine_catalog  routine_schema  routine_name  privilege_type  is_grantable
NULL     admin    test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     admin    test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     admin    test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     public   test              public           test_priv_p1_100107  test             public          test_priv_p1  EXECUTE         NO
NULL     public   test              public           test_priv_p2_100108  test             public          test_priv_p2  EXECUTE         NO
NULL     public   test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  EXECUTE         NO
NULL     root     test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     root     test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     root     test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES

query TTTTTTB colnames,rowsort
SHOW GRANTS ON PROCEDURE test_priv_p1, test_priv_p2, test_priv_p3
----
database_name  schema_name    routine_id  routine_signature   grantee  privilege_type  is_grantable
test           public         100107      test_priv_p1()      admin    ALL             true
test           public         100107      test_priv_p1()      public   EXECUTE         false
test           public         100107      test_priv_p1()      root     ALL             true
test           public         100108      test_priv_p2(int8)  admin    ALL             true
test           public         100108      test_priv_p2(int8)  public   EXECUTE         false
test           public         100108      test_priv_p2(int8)  root     ALL             true
test           test_priv_sc1  100109      test_priv_p3()      admin    ALL             true
test           test_priv_sc1  100109      test_priv_p3()      public   EXECUTE         false
test           test_priv_sc1  100109      test_priv_p3()      root     ALL             true

# Granting on functions should have no effect on procedures.
statement ok
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public, test_priv_sc1 TO test_user WITH GRANT OPTION;

query TTTTTTTTTT colnames
SELECT * FROM information_schema.role_routine_grants
WHERE routine_name IN ('test_priv_p1', 'test_priv_p2', 'test_priv_p3')
ORDER BY grantee, routine_name;
----
grantor  grantee  specific_catalog  specific_schema  specific_name        routine_catalog  routine_schema  routine_name  privilege_type  is_grantable
NULL     admin    test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     admin    test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     admin    test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     public   test              public           test_priv_p1_100107  test             public          test_priv_p1  EXECUTE         NO
NULL     public   test              public           test_priv_p2_100108  test             public          test_priv_p2  EXECUTE         NO
NULL     public   test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  EXECUTE         NO
NULL     root     test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     root     test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     root     test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES

statement ok
GRANT EXECUTE ON ALL PROCEDURES IN SCHEMA public, test_priv_sc1 TO test_user WITH GRANT OPTION;

query TTTTTTTTTT colnames
SELECT * FROM information_schema.role_routine_grants
WHERE routine_name IN ('test_priv_p1', 'test_priv_p2', 'test_priv_p3')
ORDER BY grantee, routine_name;
----
grantor  grantee    specific_catalog  specific_schema  specific_name        routine_catalog  routine_schema  routine_name  privilege_type  is_grantable
NULL     admin      test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     admin      test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     admin      test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     public     test              public           test_priv_p1_100107  test             public          test_priv_p1  EXECUTE         NO
NULL     public     test              public           test_priv_p2_100108  test             public          test_priv_p2  EXECUTE         NO
NULL     public     test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  EXECUTE         NO
NULL     root       test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     root       test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     root       test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     test_user  test              public           test_priv_p1_100107  test             public          test_priv_p1  EXECUTE         YES
NULL     test_user  test              public           test_priv_p2_100108  test             public          test_priv_p2  EXECUTE         YES
NULL     test_user  test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  EXECUTE         YES

query TTTTTTB colnames,rowsort
SHOW GRANTS ON PROCEDURE test_priv_p1, test_priv_p2, test_priv_p3
----
database_name  schema_name    routine_id  routine_signature   grantee    privilege_type  is_grantable
test           public         100107      test_priv_p1()      admin      ALL             true
test           public         100107      test_priv_p1()      public     EXECUTE         false
test           public         100107      test_priv_p1()      root       ALL             true
test           public         100107      test_priv_p1()      test_user  EXECUTE         true
test           public         100108      test_priv_p2(int8)  admin      ALL             true
test           public         100108      test_priv_p2(int8)  public     EXECUTE         false
test           public         100108      test_priv_p2(int8)  root       ALL             true
test           public         100108      test_priv_p2(int8)  test_user  EXECUTE         true
test           test_priv_sc1  100109      test_priv_p3()      admin      ALL             true
test           test_priv_sc1  100109      test_priv_p3()      public     EXECUTE         false
test           test_priv_sc1  100109      test_priv_p3()      root       ALL             true
test           test_priv_sc1  100109      test_priv_p3()      test_user  EXECUTE         true

# Revoking on functions should have no effect on procedures.
statement ok
REVOKE GRANT OPTION FOR EXECUTE ON ALL FUNCTIONS in schema public, test_priv_sc1 FROM test_user;

query TTTTTTTTTT colnames
SELECT * FROM information_schema.role_routine_grants
WHERE routine_name IN ('test_priv_p1', 'test_priv_p2', 'test_priv_p3')
ORDER BY grantee, routine_name;
----
grantor  grantee    specific_catalog  specific_schema  specific_name        routine_catalog  routine_schema  routine_name  privilege_type  is_grantable
NULL     admin      test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     admin      test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     admin      test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     public     test              public           test_priv_p1_100107  test             public          test_priv_p1  EXECUTE         NO
NULL     public     test              public           test_priv_p2_100108  test             public          test_priv_p2  EXECUTE         NO
NULL     public     test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  EXECUTE         NO
NULL     root       test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     root       test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     root       test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     test_user  test              public           test_priv_p1_100107  test             public          test_priv_p1  EXECUTE         YES
NULL     test_user  test              public           test_priv_p2_100108  test             public          test_priv_p2  EXECUTE         YES
NULL     test_user  test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  EXECUTE         YES

statement ok
REVOKE GRANT OPTION FOR EXECUTE ON ALL PROCEDURES in schema public, test_priv_sc1 FROM test_user;

query TTTTTTTTTT colnames
SELECT * FROM information_schema.role_routine_grants
WHERE routine_name IN ('test_priv_p1', 'test_priv_p2', 'test_priv_p3')
ORDER BY grantee, routine_name;
----
grantor  grantee    specific_catalog  specific_schema  specific_name        routine_catalog  routine_schema  routine_name  privilege_type  is_grantable
NULL     admin      test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     admin      test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     admin      test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     public     test              public           test_priv_p1_100107  test             public          test_priv_p1  EXECUTE         NO
NULL     public     test              public           test_priv_p2_100108  test             public          test_priv_p2  EXECUTE         NO
NULL     public     test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  EXECUTE         NO
NULL     root       test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     root       test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     root       test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     test_user  test              public           test_priv_p1_100107  test             public          test_priv_p1  EXECUTE         NO
NULL     test_user  test              public           test_priv_p2_100108  test             public          test_priv_p2  EXECUTE         NO
NULL     test_user  test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  EXECUTE         NO

query TTTTTTB colnames,rowsort
SHOW GRANTS ON PROCEDURE test_priv_p1, test_priv_p2, test_priv_p3
----
database_name  schema_name    routine_id  routine_signature   grantee    privilege_type  is_grantable
test           public         100107      test_priv_p1()      admin      ALL             true
test           public         100107      test_priv_p1()      public     EXECUTE         false
test           public         100107      test_priv_p1()      root       ALL             true
test           public         100107      test_priv_p1()      test_user  EXECUTE         false
test           public         100108      test_priv_p2(int8)  admin      ALL             true
test           public         100108      test_priv_p2(int8)  public     EXECUTE         false
test           public         100108      test_priv_p2(int8)  root       ALL             true
test           public         100108      test_priv_p2(int8)  test_user  EXECUTE         false
test           test_priv_sc1  100109      test_priv_p3()      admin      ALL             true
test           test_priv_sc1  100109      test_priv_p3()      public     EXECUTE         false
test           test_priv_sc1  100109      test_priv_p3()      root       ALL             true
test           test_priv_sc1  100109      test_priv_p3()      test_user  EXECUTE         false

# Revoking on functions should have no effect on procedures.
statement ok
REVOKE EXECUTE ON ALL FUNCTIONS IN SCHEMA public, test_priv_sc1 FROM test_user;

query TTTTTTTTTT colnames
SELECT * FROM information_schema.role_routine_grants
WHERE routine_name IN ('test_priv_p1', 'test_priv_p2', 'test_priv_p3')
ORDER BY grantee, routine_name;
----
grantor  grantee    specific_catalog  specific_schema  specific_name        routine_catalog  routine_schema  routine_name  privilege_type  is_grantable
NULL     admin      test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     admin      test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     admin      test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     public     test              public           test_priv_p1_100107  test             public          test_priv_p1  EXECUTE         NO
NULL     public     test              public           test_priv_p2_100108  test             public          test_priv_p2  EXECUTE         NO
NULL     public     test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  EXECUTE         NO
NULL     root       test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     root       test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     root       test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     test_user  test              public           test_priv_p1_100107  test             public          test_priv_p1  EXECUTE         NO
NULL     test_user  test              public           test_priv_p2_100108  test             public          test_priv_p2  EXECUTE         NO
NULL     test_user  test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  EXECUTE         NO

statement ok
REVOKE EXECUTE ON ALL PROCEDURES IN SCHEMA public, test_priv_sc1 FROM test_user;

query TTTTTTTTTT colnames
SELECT * FROM information_schema.role_routine_grants
WHERE routine_name IN ('test_priv_p1', 'test_priv_p2', 'test_priv_p3')
ORDER BY grantee, routine_name;
----
grantor  grantee  specific_catalog  specific_schema  specific_name        routine_catalog  routine_schema  routine_name  privilege_type  is_grantable
NULL     admin    test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     admin    test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     admin    test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     public   test              public           test_priv_p1_100107  test             public          test_priv_p1  EXECUTE         NO
NULL     public   test              public           test_priv_p2_100108  test             public          test_priv_p2  EXECUTE         NO
NULL     public   test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  EXECUTE         NO
NULL     root     test              public           test_priv_p1_100107  test             public          test_priv_p1  ALL             YES
NULL     root     test              public           test_priv_p2_100108  test             public          test_priv_p2  ALL             YES
NULL     root     test              test_priv_sc1    test_priv_p3_100109  test             test_priv_sc1   test_priv_p3  ALL             YES

query TTTTTTB colnames,rowsort
SHOW GRANTS ON PROCEDURE test_priv_p1, test_priv_p2, test_priv_p3
----
database_name  schema_name    routine_id  routine_signature   grantee  privilege_type  is_grantable
test           public         100107      test_priv_p1()      admin    ALL             true
test           public         100107      test_priv_p1()      public   EXECUTE         false
test           public         100107      test_priv_p1()      root     ALL             true
test           public         100108      test_priv_p2(int8)  admin    ALL             true
test           public         100108      test_priv_p2(int8)  public   EXECUTE         false
test           public         100108      test_priv_p2(int8)  root     ALL             true
test           test_priv_sc1  100109      test_priv_p3()      admin    ALL             true
test           test_priv_sc1  100109      test_priv_p3()      public   EXECUTE         false
test           test_priv_sc1  100109      test_priv_p3()      root     ALL             true

statement ok
DROP PROCEDURE test_priv_p1;
DROP PROCEDURE test_priv_p2;
DROP PROCEDURE test_priv_sc1.test_priv_p3;
DROP USER test_user;

subtest end

subtest default_privileges

statement ok
CREATE USER test_user;
CREATE PROCEDURE test_priv_p1() LANGUAGE SQL AS $$ SELECT 1 $$;

query TTTTTTTTTT colnames
SELECT * FROM information_schema.role_routine_grants
WHERE routine_name IN ('test_priv_p1', 'test_priv_p2', 'test_priv_p3')
ORDER BY grantee, routine_name;
----
grantor  grantee  specific_catalog  specific_schema  specific_name        routine_catalog  routine_schema  routine_name  privilege_type  is_grantable
NULL     admin    test              public           test_priv_p1_100110  test             public          test_priv_p1  ALL             YES
NULL     public   test              public           test_priv_p1_100110  test             public          test_priv_p1  EXECUTE         NO
NULL     root     test              public           test_priv_p1_100110  test             public          test_priv_p1  ALL             YES

query TTTTTTB colnames,rowsort
SHOW GRANTS ON PROCEDURE test_priv_p1
----
database_name  schema_name  routine_id  routine_signature  grantee  privilege_type  is_grantable
test           public       100110      test_priv_p1()     admin    ALL             true
test           public       100110      test_priv_p1()     public   EXECUTE         false
test           public       100110      test_priv_p1()     root     ALL             true

# Add default privilege and make sure it apples only to newly created
# procedures.
# NOTE: We use GRANT EXECUTE ON FUNCTIONS here because GRANT EXECUTE ON
# PROCEDURES is not supported. "FUNCTIONS" applies to procedures too. This
# matches Postgres behavior.
statement ok
ALTER DEFAULT PRIVILEGES IN SCHEMA public, test_priv_sc1 GRANT EXECUTE ON FUNCTIONS TO test_user WITH GRANT OPTION;

statement ok
CREATE PROCEDURE test_priv_p2(int) LANGUAGE SQL AS $$ SELECT 1 $$;
CREATE PROCEDURE test_priv_sc1.test_priv_p3() LANGUAGE SQL AS $$ SELECT 1 $$;

query TTTTTTTTTT colnames
SELECT * FROM information_schema.role_routine_grants
WHERE routine_name IN ('test_priv_p1', 'test_priv_p2', 'test_priv_p3')
ORDER BY grantee, routine_name;
----
grantor  grantee    specific_catalog  specific_schema  specific_name        routine_catalog  routine_schema  routine_name  privilege_type  is_grantable
NULL     admin      test              public           test_priv_p1_100110  test             public          test_priv_p1  ALL             YES
NULL     admin      test              public           test_priv_p2_100111  test             public          test_priv_p2  ALL             YES
NULL     admin      test              test_priv_sc1    test_priv_p3_100112  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     public     test              public           test_priv_p1_100110  test             public          test_priv_p1  EXECUTE         NO
NULL     public     test              public           test_priv_p2_100111  test             public          test_priv_p2  EXECUTE         NO
NULL     public     test              test_priv_sc1    test_priv_p3_100112  test             test_priv_sc1   test_priv_p3  EXECUTE         NO
NULL     root       test              public           test_priv_p1_100110  test             public          test_priv_p1  ALL             YES
NULL     root       test              public           test_priv_p2_100111  test             public          test_priv_p2  ALL             YES
NULL     root       test              test_priv_sc1    test_priv_p3_100112  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     test_user  test              public           test_priv_p2_100111  test             public          test_priv_p2  EXECUTE         YES
NULL     test_user  test              test_priv_sc1    test_priv_p3_100112  test             test_priv_sc1   test_priv_p3  EXECUTE         YES

query TTTTTTB colnames,rowsort
SHOW GRANTS ON PROCEDURE test_priv_p1, test_priv_p2, test_priv_p3
----
database_name  schema_name    routine_id  routine_signature   grantee    privilege_type  is_grantable
test           public         100110      test_priv_p1()      admin      ALL             true
test           public         100110      test_priv_p1()      public     EXECUTE         false
test           public         100110      test_priv_p1()      root       ALL             true
test           public         100111      test_priv_p2(int8)  admin      ALL             true
test           public         100111      test_priv_p2(int8)  public     EXECUTE         false
test           public         100111      test_priv_p2(int8)  root       ALL             true
test           public         100111      test_priv_p2(int8)  test_user  EXECUTE         true
test           test_priv_sc1  100112      test_priv_p3()      admin      ALL             true
test           test_priv_sc1  100112      test_priv_p3()      public     EXECUTE         false
test           test_priv_sc1  100112      test_priv_p3()      root       ALL             true
test           test_priv_sc1  100112      test_priv_p3()      test_user  EXECUTE         true

statement ok
DROP PROCEDURE test_priv_p2;
DROP PROCEDURE test_priv_sc1.test_priv_p3;

query TTTTTTTTTT colnames
SELECT * FROM information_schema.role_routine_grants
WHERE routine_name IN ('test_priv_p1', 'test_priv_p2', 'test_priv_p3')
ORDER BY grantee, routine_name;
----
grantor  grantee  specific_catalog  specific_schema  specific_name        routine_catalog  routine_schema  routine_name  privilege_type  is_grantable
NULL     admin    test              public           test_priv_p1_100110  test             public          test_priv_p1  ALL             YES
NULL     public   test              public           test_priv_p1_100110  test             public          test_priv_p1  EXECUTE         NO
NULL     root     test              public           test_priv_p1_100110  test             public          test_priv_p1  ALL             YES

query TTTTTTB colnames,rowsort
SHOW GRANTS ON PROCEDURE test_priv_p1
----
database_name  schema_name  routine_id  routine_signature  grantee  privilege_type  is_grantable
test           public       100110      test_priv_p1()     admin    ALL             true
test           public       100110      test_priv_p1()     public   EXECUTE         false
test           public       100110      test_priv_p1()     root     ALL             true

statement ok
ALTER DEFAULT PRIVILEGES IN SCHEMA public, test_priv_sc1 REVOKE EXECUTE ON FUNCTIONS FROM test_user;

statement ok
CREATE PROCEDURE test_priv_p2(int) LANGUAGE SQL AS $$ SELECT 1 $$;
CREATE PROCEDURE test_priv_sc1.test_priv_p3() LANGUAGE SQL AS $$ SELECT 1 $$;

query TTTTTTTTTT colnames
SELECT * FROM information_schema.role_routine_grants
WHERE routine_name IN ('test_priv_p1', 'test_priv_p2', 'test_priv_p3')
ORDER BY grantee, routine_name;
----
grantor  grantee  specific_catalog  specific_schema  specific_name        routine_catalog  routine_schema  routine_name  privilege_type  is_grantable
NULL     admin    test              public           test_priv_p1_100110  test             public          test_priv_p1  ALL             YES
NULL     admin    test              public           test_priv_p2_100113  test             public          test_priv_p2  ALL             YES
NULL     admin    test              test_priv_sc1    test_priv_p3_100114  test             test_priv_sc1   test_priv_p3  ALL             YES
NULL     public   test              public           test_priv_p1_100110  test             public          test_priv_p1  EXECUTE         NO
NULL     public   test              public           test_priv_p2_100113  test             public          test_priv_p2  EXECUTE         NO
NULL     public   test              test_priv_sc1    test_priv_p3_100114  test             test_priv_sc1   test_priv_p3  EXECUTE         NO
NULL     root     test              public           test_priv_p1_100110  test             public          test_priv_p1  ALL             YES
NULL     root     test              public           test_priv_p2_100113  test             public          test_priv_p2  ALL             YES
NULL     root     test              test_priv_sc1    test_priv_p3_100114  test             test_priv_sc1   test_priv_p3  ALL             YES

query TTTTTTB colnames,rowsort
SHOW GRANTS ON PROCEDURE test_priv_p1, test_priv_p2, test_priv_p3
----
database_name  schema_name    routine_id  routine_signature   grantee  privilege_type  is_grantable
test           public         100110      test_priv_p1()      admin    ALL             true
test           public         100110      test_priv_p1()      public   EXECUTE         false
test           public         100110      test_priv_p1()      root     ALL             true
test           public         100113      test_priv_p2(int8)  admin    ALL             true
test           public         100113      test_priv_p2(int8)  public   EXECUTE         false
test           public         100113      test_priv_p2(int8)  root     ALL             true
test           test_priv_sc1  100114      test_priv_p3()      admin    ALL             true
test           test_priv_sc1  100114      test_priv_p3()      public   EXECUTE         false
test           test_priv_sc1  100114      test_priv_p3()      root     ALL             true

# Make sure has_function_privilege works.
query B
SELECT has_function_privilege('test_priv_p2(INT)', 'EXECUTE')
----
true

query B
SELECT has_function_privilege('test_priv_p2(INT)', 'EXECUTE WITH GRANT OPTION')
----
true

query B
SELECT has_function_privilege('test_priv_p2(INT)', 'EXECUTE, EXECUTE WITH GRANT OPTION')
----
true

user testuser

query B
SELECT has_function_privilege('test_priv_p2(INT)', 'EXECUTE')
----
true

query B
SELECT has_function_privilege('test_priv_p2(INT)', 'EXECUTE WITH GRANT OPTION')
----
false

query B
SELECT has_function_privilege('test_priv_p2(INT)', 'EXECUTE, EXECUTE WITH GRANT OPTION')
----
true

user root

statement ok
GRANT EXECUTE ON PROCEDURE test_priv_p1(), test_priv_p2(int), test_priv_sc1.test_priv_p3 TO testuser WITH GRANT OPTION;

user testuser

query B retry
SELECT has_function_privilege('test_priv_p2(INT)', 'EXECUTE')
----
true

query B
SELECT has_function_privilege('test_priv_p2(INT)', 'EXECUTE WITH GRANT OPTION')
----
true

query B
SELECT has_function_privilege('test_priv_p2(INT)', 'EXECUTE, EXECUTE WITH GRANT OPTION')
----
true

user root

statement ok
REVOKE GRANT OPTION FOR EXECUTE ON PROCEDURE test_priv_p1(), test_priv_p2(int), test_priv_sc1.test_priv_p3 FROM testuser;

user testuser

query B retry
SELECT has_function_privilege('test_priv_p2(INT)', 'EXECUTE WITH GRANT OPTION')
----
false

query B
SELECT has_function_privilege('test_priv_p2(INT)', 'EXECUTE')
----
true

query B
SELECT has_function_privilege('test_priv_p2(INT)', 'EXECUTE, EXECUTE WITH GRANT OPTION')
----
true

user root

statement ok
SET search_path = public;

subtest end

subtest show_grants

statement ok
CREATE SCHEMA sc_test_show_grants;
SET search_path = sc_test_show_grants;
CREATE PROCEDURE p_test_show_grants(INT) LANGUAGE SQL AS $$ SELECT 1 $$;
CREATE PROCEDURE p_test_show_grants(INT, string, OID) LANGUAGE SQL AS $$ SELECT 1 $$;
CREATE FUNCTION test_priv_f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$;
CREATE USER u_test_show_grants;
GRANT EXECUTE ON PROCEDURE p_test_show_grants(INT), p_test_show_grants(INT, string, OID) TO u_test_show_grants;

statement error pgcode 42725 pq: procedure name "p_test_show_grants" is not unique
SHOW GRANTS ON PROCEDURE p_test_show_grants;

query TTTTTTB colnames
SELECT * FROM [
  SHOW GRANTS ON PROCEDURE p_test_show_grants(INT), p_test_show_grants(INT, string, OID)
] ORDER BY routine_signature, grantee
----
database_name  schema_name          routine_id  routine_signature                    grantee             privilege_type  is_grantable
test           sc_test_show_grants  100116      p_test_show_grants(int8)             admin               ALL             true
test           sc_test_show_grants  100116      p_test_show_grants(int8)             public              EXECUTE         false
test           sc_test_show_grants  100116      p_test_show_grants(int8)             root                ALL             true
test           sc_test_show_grants  100116      p_test_show_grants(int8)             u_test_show_grants  EXECUTE         false
test           sc_test_show_grants  100117      p_test_show_grants(int8, text, oid)  admin               ALL             true
test           sc_test_show_grants  100117      p_test_show_grants(int8, text, oid)  public              EXECUTE         false
test           sc_test_show_grants  100117      p_test_show_grants(int8, text, oid)  root                ALL             true
test           sc_test_show_grants  100117      p_test_show_grants(int8, text, oid)  u_test_show_grants  EXECUTE         false

statement error pgcode 42883 pq: procedure p_test_show_grants\(string\) does not exist
SHOW GRANTS ON PROCEDURE p_test_show_grants(string);

query TTTTTTB colnames
SELECT * FROM [SHOW GRANTS ON PROCEDURE p_test_show_grants(INT)] ORDER BY grantee
----
database_name  schema_name          routine_id  routine_signature         grantee             privilege_type  is_grantable
test           sc_test_show_grants  100116      p_test_show_grants(int8)  admin               ALL             true
test           sc_test_show_grants  100116      p_test_show_grants(int8)  public              EXECUTE         false
test           sc_test_show_grants  100116      p_test_show_grants(int8)  root                ALL             true
test           sc_test_show_grants  100116      p_test_show_grants(int8)  u_test_show_grants  EXECUTE         false

query TTTTTTB colnames
SELECT * FROM [SHOW GRANTS ON PROCEDURE p_test_show_grants(INT, string, OID)] ORDER BY routine_signature, grantee
----
database_name  schema_name          routine_id  routine_signature                    grantee             privilege_type  is_grantable
test           sc_test_show_grants  100117      p_test_show_grants(int8, text, oid)  admin               ALL             true
test           sc_test_show_grants  100117      p_test_show_grants(int8, text, oid)  public              EXECUTE         false
test           sc_test_show_grants  100117      p_test_show_grants(int8, text, oid)  root                ALL             true
test           sc_test_show_grants  100117      p_test_show_grants(int8, text, oid)  u_test_show_grants  EXECUTE         false

# TODO(mgartner): Fix the error message to mention "procedure" or "routine"
# instead of "function".
statement error pgcode 42883 pq: unknown function: p_not_existing\(\)
SHOW GRANTS ON PROCEDURE p_not_existing;

query TTTTTTB colnames
SELECT * FROM [
  SHOW GRANTS ON PROCEDURE p_test_show_grants(INT), p_test_show_grants(INT, string, OID) FOR u_test_show_grants
] ORDER BY routine_id
----
database_name  schema_name          routine_id  routine_signature                    grantee             privilege_type  is_grantable
test           sc_test_show_grants  100116      p_test_show_grants(int8)             u_test_show_grants  EXECUTE         false
test           sc_test_show_grants  100116      p_test_show_grants(int8)             public              EXECUTE         false
test           sc_test_show_grants  100117      p_test_show_grants(int8, text, oid)  public              EXECUTE         false
test           sc_test_show_grants  100117      p_test_show_grants(int8, text, oid)  u_test_show_grants  EXECUTE         false

query TTTTTTB colnames
SELECT * FROM [SHOW GRANTS FOR u_test_show_grants] ORDER BY object_name
----
database_name  schema_name          object_name                          object_type  grantee             privilege_type  is_grantable
test           public               NULL                                 schema       public              CREATE          false
test           public               NULL                                 schema       public              USAGE           false
test           sc_test_show_grants  p_test_show_grants(int8)             routine      public              EXECUTE         false
test           sc_test_show_grants  p_test_show_grants(int8)             routine      u_test_show_grants  EXECUTE         false
test           sc_test_show_grants  p_test_show_grants(int8, text, oid)  routine      u_test_show_grants  EXECUTE         false
test           sc_test_show_grants  p_test_show_grants(int8, text, oid)  routine      public              EXECUTE         false
test           sc_test_show_grants  test_priv_f()                        routine      public              EXECUTE         false
test           public               test_priv_p1()                       routine      public              EXECUTE         false
test           public               test_priv_p2(int8)                   routine      public              EXECUTE         false
test           test_priv_sc1        test_priv_p3()                       routine      public              EXECUTE         false

statement ok
SET search_path = public;

subtest end

subtest udf_create_privilege

statement ok
CREATE SCHEMA sc_test_priv;

user testuser

statement error pgcode 42501 pq: user testuser does not have CREATE privilege on schema sc_test_priv
CREATE PROCEDURE sc_test_priv.f() LANGUAGE SQL AS $$ SELECT 1 $$;

user root

statement ok
GRANT CREATE ON SCHEMA sc_test_priv TO testuser

user testuser

statement ok
CREATE PROCEDURE sc_test_priv.f() LANGUAGE SQL AS $$ SELECT 1 $$;

user root

subtest end

subtest check_privileges

statement ok
CREATE USER tester

statement ok
CREATE SCHEMA test;

statement ok
GRANT USAGE ON SCHEMA test TO tester;

statement ok
CREATE PROCEDURE test.p() LANGUAGE SQL AS 'SELECT 1'

statement ok
SET ROLE tester

# The tester role receives execute privileges to procedures via the public role.
statement ok
CALL test.p()

statement ok
SET ROLE root

# Revoke execute privilege from the public role.
statement ok
REVOKE EXECUTE ON PROCEDURE test.p FROM public

# The root role can still execute the procedure.
statement ok
CALL test.p()

statement ok
SET ROLE tester

statement error pgcode 42501 user tester does not have EXECUTE privilege on procedure p
CALL test.p()

statement ok
SET ROLE root

# Re-grant execute privilege to the public role.
statement ok
GRANT EXECUTE ON PROCEDURE test.p TO public

statement ok
SET ROLE tester

statement ok
CALL test.p()

subtest end
