diff --git a/doc/src/sgml/ref/alter_aggregate.sgml b/doc/src/sgml/ref/alter_aggregate.sgml index f92b8e5da379e348b21e9d78e66fa6f9b3c27155..3aa7c259da187b2b481f560892116376f8596b34 100644 --- a/doc/src/sgml/ref/alter_aggregate.sgml +++ b/doc/src/sgml/ref/alter_aggregate.sgml @@ -22,7 +22,8 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> ALTER AGGREGATE <replaceable>name</replaceable> ( <replaceable>aggregate_signature</replaceable> ) RENAME TO <replaceable>new_name</replaceable> -ALTER AGGREGATE <replaceable>name</replaceable> ( <replaceable>aggregate_signature</replaceable> ) OWNER TO <replaceable>new_owner</replaceable> +ALTER AGGREGATE <replaceable>name</replaceable> ( <replaceable>aggregate_signature</replaceable> ) + OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER } ALTER AGGREGATE <replaceable>name</replaceable> ( <replaceable>aggregate_signature</replaceable> ) SET SCHEMA <replaceable>new_schema</replaceable> <phrase>where <replaceable>aggregate_signature</replaceable> is:</phrase> diff --git a/doc/src/sgml/ref/alter_collation.sgml b/doc/src/sgml/ref/alter_collation.sgml index 11ecd93c205f145a6bd62ef01fec071788eb38cc..6708c7e10e896964ecba85c5cb7a8a41bcef4d12 100644 --- a/doc/src/sgml/ref/alter_collation.sgml +++ b/doc/src/sgml/ref/alter_collation.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> ALTER COLLATION <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable> -ALTER COLLATION <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable> +ALTER COLLATION <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER } ALTER COLLATION <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable> </synopsis> </refsynopsisdiv> diff --git a/doc/src/sgml/ref/alter_conversion.sgml b/doc/src/sgml/ref/alter_conversion.sgml index a3f68975bfeffbd73745a76a81fe86a9e0d0bda9..3514720d03ebbf31e8f03dae49705661c0088a66 100644 --- a/doc/src/sgml/ref/alter_conversion.sgml +++ b/doc/src/sgml/ref/alter_conversion.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> ALTER CONVERSION <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable> -ALTER CONVERSION <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable> +ALTER CONVERSION <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER } ALTER CONVERSION <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable> </synopsis> </refsynopsisdiv> diff --git a/doc/src/sgml/ref/alter_database.sgml b/doc/src/sgml/ref/alter_database.sgml index 95c7ac91584267d32d6108b857cf4b3a046a03b8..8b6fa5816f45b2589e039a5d9ed215b1426daf87 100644 --- a/doc/src/sgml/ref/alter_database.sgml +++ b/doc/src/sgml/ref/alter_database.sgml @@ -31,7 +31,7 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <rep ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>new_name</replaceable> -ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <replaceable>new_owner</replaceable> +ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER } ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> SET TABLESPACE <replaceable class="PARAMETER">new_tablespace</replaceable> diff --git a/doc/src/sgml/ref/alter_domain.sgml b/doc/src/sgml/ref/alter_domain.sgml index d65d517bb5f9981021cad19be944f333e720d880..f738b2948b3581045af8a5ca0f8e6dc45a1b380d 100644 --- a/doc/src/sgml/ref/alter_domain.sgml +++ b/doc/src/sgml/ref/alter_domain.sgml @@ -36,7 +36,7 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> VALIDATE CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> - OWNER TO <replaceable class="PARAMETER">new_owner</replaceable> + OWNER TO { <replaceable class="PARAMETER">new_owner</replaceable> | CURRENT_USER | SESSION_USER } ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable class="PARAMETER">new_name</replaceable> ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> diff --git a/doc/src/sgml/ref/alter_event_trigger.sgml b/doc/src/sgml/ref/alter_event_trigger.sgml index 1bf9d8abb609d99e835e6d92c94d6d91bbd20b03..9d6c64ad5299fe73eb1535732cf9ed83467550da 100644 --- a/doc/src/sgml/ref/alter_event_trigger.sgml +++ b/doc/src/sgml/ref/alter_event_trigger.sgml @@ -23,7 +23,7 @@ PostgreSQL documentation <synopsis> ALTER EVENT TRIGGER <replaceable class="PARAMETER">name</replaceable> DISABLE ALTER EVENT TRIGGER <replaceable class="PARAMETER">name</replaceable> ENABLE [ REPLICA | ALWAYS ] -ALTER EVENT TRIGGER <replaceable class="PARAMETER">name</replaceable> OWNER TO <replaceable class="PARAMETER">new_owner</replaceable> +ALTER EVENT TRIGGER <replaceable class="PARAMETER">name</replaceable> OWNER TO { <replaceable class="PARAMETER">new_owner</replaceable> | CURRENT_USER | SESSION_USER } ALTER EVENT TRIGGER <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable class="PARAMETER">new_name</replaceable> </synopsis> </refsynopsisdiv> diff --git a/doc/src/sgml/ref/alter_foreign_data_wrapper.sgml b/doc/src/sgml/ref/alter_foreign_data_wrapper.sgml index 1c82db9e0385f7efb751dedd8b00d890dac4b353..3f5fb0f77ea925dafc29fdd2e4de99f940f218fe 100644 --- a/doc/src/sgml/ref/alter_foreign_data_wrapper.sgml +++ b/doc/src/sgml/ref/alter_foreign_data_wrapper.sgml @@ -25,7 +25,7 @@ ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> [ HANDLER <replaceable class="parameter">handler_function</replaceable> | NO HANDLER ] [ VALIDATOR <replaceable class="parameter">validator_function</replaceable> | NO VALIDATOR ] [ OPTIONS ( [ ADD | SET | DROP ] <replaceable class="PARAMETER">option</replaceable> ['<replaceable class="PARAMETER">value</replaceable>'] [, ... ]) ] -ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> OWNER TO <replaceable>new_owner</replaceable> +ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER } ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> RENAME TO <replaceable>new_name</replaceable> </synopsis> </refsynopsisdiv> diff --git a/doc/src/sgml/ref/alter_foreign_table.sgml b/doc/src/sgml/ref/alter_foreign_table.sgml index ff48ab888299ff258e49d0323a54f561993e2c9e..93f8743071bf30d2bdd1e586b495d995821e08e2 100644 --- a/doc/src/sgml/ref/alter_foreign_table.sgml +++ b/doc/src/sgml/ref/alter_foreign_table.sgml @@ -48,7 +48,7 @@ ALTER FOREIGN TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceab ENABLE TRIGGER [ <replaceable class="PARAMETER">trigger_name</replaceable> | ALL | USER ] ENABLE REPLICA TRIGGER <replaceable class="PARAMETER">trigger_name</replaceable> ENABLE ALWAYS TRIGGER <replaceable class="PARAMETER">trigger_name</replaceable> - OWNER TO <replaceable class="PARAMETER">new_owner</replaceable> + OWNER TO { <replaceable class="PARAMETER">new_owner</replaceable> | CURRENT_USER | SESSION_USER } OPTIONS ( [ ADD | SET | DROP ] <replaceable class="PARAMETER">option</replaceable> ['<replaceable class="PARAMETER">value</replaceable>'] [, ... ]) </synopsis> </refsynopsisdiv> diff --git a/doc/src/sgml/ref/alter_function.sgml b/doc/src/sgml/ref/alter_function.sgml index ba879eb1ea33448ae34f3d2483162daf17782f3f..4e77962c88d6593da38eb92d70ecfb68f3eb6143 100644 --- a/doc/src/sgml/ref/alter_function.sgml +++ b/doc/src/sgml/ref/alter_function.sgml @@ -26,7 +26,7 @@ ALTER FUNCTION <replaceable>name</replaceable> ( [ [ <replaceable class="paramet ALTER FUNCTION <replaceable>name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) RENAME TO <replaceable>new_name</replaceable> ALTER FUNCTION <replaceable>name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) - OWNER TO <replaceable>new_owner</replaceable> + OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER } ALTER FUNCTION <replaceable>name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) SET SCHEMA <replaceable>new_schema</replaceable> diff --git a/doc/src/sgml/ref/alter_group.sgml b/doc/src/sgml/ref/alter_group.sgml index 143224286ab5c14c88011d9437c4800ddee0f33c..adf6f7e932325c3eaa3ffd7ab8fa6a03bea8cd48 100644 --- a/doc/src/sgml/ref/alter_group.sgml +++ b/doc/src/sgml/ref/alter_group.sgml @@ -21,8 +21,14 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> -ALTER GROUP <replaceable class="PARAMETER">group_name</replaceable> ADD USER <replaceable class="PARAMETER">user_name</replaceable> [, ... ] -ALTER GROUP <replaceable class="PARAMETER">group_name</replaceable> DROP USER <replaceable class="PARAMETER">user_name</replaceable> [, ... ] +ALTER GROUP <replaceable class="PARAMETER">role_specification</replaceable> ADD USER <replaceable class="PARAMETER">user_name</replaceable> [, ... ] +ALTER GROUP <replaceable class="PARAMETER">role_specification</replaceable> DROP USER <replaceable class="PARAMETER">user_name</replaceable> [, ... ] + +<phrase>where <replaceable class="PARAMETER">role_specification</replaceable> can be:</phrase> + + <replaceable class="PARAMETER">role_name</replaceable> + | CURRENT_USER + | SESSION_USER ALTER GROUP <replaceable class="PARAMETER">group_name</replaceable> RENAME TO <replaceable>new_name</replaceable> </synopsis> diff --git a/doc/src/sgml/ref/alter_language.sgml b/doc/src/sgml/ref/alter_language.sgml index 5c9ded6837fef608d02a8e4f9cb0ea0a7052077b..63d9ecd924dca136b1b925c52ae3dd7b1bba6355 100644 --- a/doc/src/sgml/ref/alter_language.sgml +++ b/doc/src/sgml/ref/alter_language.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> ALTER [ PROCEDURAL ] LANGUAGE <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable> -ALTER [ PROCEDURAL ] LANGUAGE <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable> +ALTER [ PROCEDURAL ] LANGUAGE <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER } </synopsis> </refsynopsisdiv> diff --git a/doc/src/sgml/ref/alter_large_object.sgml b/doc/src/sgml/ref/alter_large_object.sgml index a6dabca1b2fd29ca3231a617eec597ac3343b897..a0ed6c22f3449d8f72bf28606e2e320877640a2d 100644 --- a/doc/src/sgml/ref/alter_large_object.sgml +++ b/doc/src/sgml/ref/alter_large_object.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> -ALTER LARGE OBJECT <replaceable class="PARAMETER">large_object_oid</replaceable> OWNER TO <replaceable>new_owner</replaceable> +ALTER LARGE OBJECT <replaceable class="PARAMETER">large_object_oid</replaceable> { OWNER TO <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER } </synopsis> </refsynopsisdiv> diff --git a/doc/src/sgml/ref/alter_materialized_view.sgml b/doc/src/sgml/ref/alter_materialized_view.sgml index b0759fc5dca5af497e837f203d9edc7082820f4a..8807e01c365900623f8e45211238150dc80023d7 100644 --- a/doc/src/sgml/ref/alter_materialized_view.sgml +++ b/doc/src/sgml/ref/alter_materialized_view.sgml @@ -42,7 +42,7 @@ ALTER MATERIALIZED VIEW ALL IN TABLESPACE <replaceable class="parameter">name</r SET WITHOUT CLUSTER SET ( <replaceable class="PARAMETER">storage_parameter</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] ) RESET ( <replaceable class="PARAMETER">storage_parameter</replaceable> [, ... ] ) - OWNER TO <replaceable class="PARAMETER">new_owner</replaceable> + OWNER TO { <replaceable class="PARAMETER">new_owner</replaceable> | CURRENT_USER | SESSION_USER } SET TABLESPACE <replaceable class="PARAMETER">new_tablespace</replaceable> </synopsis> </refsynopsisdiv> diff --git a/doc/src/sgml/ref/alter_opclass.sgml b/doc/src/sgml/ref/alter_opclass.sgml index fc41d866611f24b9c68fc7b8878edacfffe02cab..2e561be8d78f4f25ef8c7925e06882f1a060594b 100644 --- a/doc/src/sgml/ref/alter_opclass.sgml +++ b/doc/src/sgml/ref/alter_opclass.sgml @@ -21,9 +21,14 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> -ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> RENAME TO <replaceable>new_name</replaceable> -ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> OWNER TO <replaceable>new_owner</replaceable> -ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> SET SCHEMA <replaceable>new_schema</replaceable> +ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> + RENAME TO <replaceable>new_name</replaceable> + +ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> + { OWNER TO <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER } + +ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> + SET SCHEMA <replaceable>new_schema</replaceable> </synopsis> </refsynopsisdiv> diff --git a/doc/src/sgml/ref/alter_operator.sgml b/doc/src/sgml/ref/alter_operator.sgml index 60754163204d3484488fee71c4230e5e19613d05..bdb2d029b171a297307b1c52a2fcbbc5cd2ffa92 100644 --- a/doc/src/sgml/ref/alter_operator.sgml +++ b/doc/src/sgml/ref/alter_operator.sgml @@ -21,8 +21,11 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> -ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } , { <replaceable>right_type</replaceable> | NONE } ) OWNER TO <replaceable>new_owner</replaceable> -ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } , { <replaceable>right_type</replaceable> | NONE } ) SET SCHEMA <replaceable>new_schema</replaceable> +ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } , { <replaceable>right_type</replaceable> | NONE } ) + { OWNER TO <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER } + +ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } , { <replaceable>right_type</replaceable> | NONE } ) + SET SCHEMA <replaceable>new_schema</replaceable> </synopsis> </refsynopsisdiv> diff --git a/doc/src/sgml/ref/alter_opfamily.sgml b/doc/src/sgml/ref/alter_opfamily.sgml index 55b912611d94eada68880ed8fc4d2a0a783fdf6c..b0942b6ea7de2c71053357cca076fdf168507ccf 100644 --- a/doc/src/sgml/ref/alter_opfamily.sgml +++ b/doc/src/sgml/ref/alter_opfamily.sgml @@ -22,16 +22,25 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> ADD - { OPERATOR <replaceable class="parameter">strategy_number</replaceable> <replaceable class="parameter">operator_name</replaceable> ( <replaceable class="parameter">op_type</replaceable>, <replaceable class="parameter">op_type</replaceable> ) [ FOR SEARCH | FOR ORDER BY <replaceable class="parameter">sort_family_name</replaceable> ] - | FUNCTION <replaceable class="parameter">support_number</replaceable> [ ( <replaceable class="parameter">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] ) ] <replaceable class="parameter">function_name</replaceable> ( <replaceable class="parameter">argument_type</replaceable> [, ...] ) + { OPERATOR <replaceable class="parameter">strategy_number</replaceable> <replaceable class="parameter">operator_name</replaceable> ( <replaceable class="parameter">op_type</replaceable>, <replaceable class="parameter">op_type</replaceable> ) + [ FOR SEARCH | FOR ORDER BY <replaceable class="parameter">sort_family_name</replaceable> ] + | FUNCTION <replaceable class="parameter">support_number</replaceable> [ ( <replaceable class="parameter">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] ) ] + <replaceable class="parameter">function_name</replaceable> ( <replaceable class="parameter">argument_type</replaceable> [, ...] ) } [, ... ] + ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> DROP { OPERATOR <replaceable class="parameter">strategy_number</replaceable> ( <replaceable class="parameter">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] ) | FUNCTION <replaceable class="parameter">support_number</replaceable> ( <replaceable class="parameter">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] ) } [, ... ] -ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> RENAME TO <replaceable>new_name</replaceable> -ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> OWNER TO <replaceable>new_owner</replaceable> -ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> SET SCHEMA <replaceable>new_schema</replaceable> + +ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> + RENAME TO <replaceable>new_name</replaceable> + +ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> + OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER } + +ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> + SET SCHEMA <replaceable>new_schema</replaceable> </synopsis> </refsynopsisdiv> diff --git a/doc/src/sgml/ref/alter_role.sgml b/doc/src/sgml/ref/alter_role.sgml index 0471daa1cce7329d4bce0b3efbe80a0f4cf24790..e97bf4c9d282e27da928068289230b6eac0c0453 100644 --- a/doc/src/sgml/ref/alter_role.sgml +++ b/doc/src/sgml/ref/alter_role.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> -ALTER ROLE <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replaceable class="PARAMETER">option</replaceable> [ ... ] ] +ALTER ROLE <replaceable class="PARAMETER">role_specification</replaceable> [ WITH ] <replaceable class="PARAMETER">option</replaceable> [ ... ] <phrase>where <replaceable class="PARAMETER">option</replaceable> can be:</phrase> @@ -39,10 +39,16 @@ ALTER ROLE <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replace ALTER ROLE <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>new_name</replaceable> -ALTER ROLE <replaceable class="PARAMETER">name</replaceable> [ IN DATABASE <replaceable class="PARAMETER">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT } -ALTER ROLE { <replaceable class="PARAMETER">name</replaceable> | ALL } [ IN DATABASE <replaceable class="PARAMETER">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> FROM CURRENT -ALTER ROLE { <replaceable class="PARAMETER">name</replaceable> | ALL } [ IN DATABASE <replaceable class="PARAMETER">database_name</replaceable> ] RESET <replaceable>configuration_parameter</replaceable> -ALTER ROLE { <replaceable class="PARAMETER">name</replaceable> | ALL } [ IN DATABASE <replaceable class="PARAMETER">database_name</replaceable> ] RESET ALL +ALTER ROLE { <replaceable class="PARAMETER">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="PARAMETER">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT } +ALTER ROLE { <replaceable class="PARAMETER">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="PARAMETER">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> FROM CURRENT +ALTER ROLE { <replaceable class="PARAMETER">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="PARAMETER">database_name</replaceable> ] RESET <replaceable>configuration_parameter</replaceable> +ALTER ROLE { <replaceable class="PARAMETER">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="PARAMETER">database_name</replaceable> ] RESET ALL + +<phrase>where <replaceable class="PARAMETER">role_specification</replaceable> can be:</phrase> + + [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> + | CURRENT_USER + | SESSION_USER </synopsis> </refsynopsisdiv> @@ -128,6 +134,25 @@ ALTER ROLE { <replaceable class="PARAMETER">name</replaceable> | ALL } [ IN DATA </listitem> </varlistentry> + <varlistentry> + <term>CURRENT_USER</term> + <listitem> + <para> + Alter the current user instead of an explicitely identified role. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>SESSION_USER</term> + <listitem> + <para> + Alter the current session user instead of an explicitely identified + role. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><literal>SUPERUSER</literal></term> <term><literal>NOSUPERUSER</literal></term> diff --git a/doc/src/sgml/ref/alter_schema.sgml b/doc/src/sgml/ref/alter_schema.sgml index 00395c02f85867c75ae6e86bd383e303e590195e..dbc5c2d45f54166392afb7372a9e2095038e1153 100644 --- a/doc/src/sgml/ref/alter_schema.sgml +++ b/doc/src/sgml/ref/alter_schema.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> ALTER SCHEMA <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable> -ALTER SCHEMA <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable> +ALTER SCHEMA <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER } </synopsis> </refsynopsisdiv> diff --git a/doc/src/sgml/ref/alter_sequence.sgml b/doc/src/sgml/ref/alter_sequence.sgml index 9ba9bc46229152b2e670377d57daf51635497adf..47d3c8291fa5bfc7153255b583f6ee9316a2a5be 100644 --- a/doc/src/sgml/ref/alter_sequence.sgml +++ b/doc/src/sgml/ref/alter_sequence.sgml @@ -29,7 +29,7 @@ ALTER SEQUENCE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [ [ RESTART [ [ WITH ] <replaceable class="parameter">restart</replaceable> ] ] [ CACHE <replaceable class="parameter">cache</replaceable> ] [ [ NO ] CYCLE ] [ OWNED BY { <replaceable class="parameter">table_name</replaceable>.<replaceable class="parameter">column_name</replaceable> | NONE } ] -ALTER SEQUENCE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> OWNER TO <replaceable class="PARAMETER">new_owner</replaceable> +ALTER SEQUENCE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable class="PARAMETER">new_owner</replaceable> | CURRENT_USER | SESSION_USER } ALTER SEQUENCE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable> ALTER SEQUENCE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable> </synopsis> diff --git a/doc/src/sgml/ref/alter_server.sgml b/doc/src/sgml/ref/alter_server.sgml index 68253b916680ae085d90d153da2783ebdb7f6b2d..e6cf511853f669ca7aba2e2b9c92b913d7819b07 100644 --- a/doc/src/sgml/ref/alter_server.sgml +++ b/doc/src/sgml/ref/alter_server.sgml @@ -23,7 +23,7 @@ PostgreSQL documentation <synopsis> ALTER SERVER <replaceable class="parameter">name</replaceable> [ VERSION '<replaceable class="parameter">new_version</replaceable>' ] [ OPTIONS ( [ ADD | SET | DROP ] <replaceable class="PARAMETER">option</replaceable> ['<replaceable class="PARAMETER">value</replaceable>'] [, ... ] ) ] -ALTER SERVER <replaceable class="PARAMETER">name</replaceable> OWNER TO <replaceable>new_owner</replaceable> +ALTER SERVER <replaceable class="PARAMETER">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER } ALTER SERVER <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>new_name</replaceable> </synopsis> </refsynopsisdiv> diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml index b3a497071357a737c479a660b0d7e994f42a7e15..19baf2961a4826c49e59c7314c7fc6538192839f 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -73,7 +73,7 @@ ALTER TABLE ALL IN TABLESPACE <replaceable class="PARAMETER">name</replaceable> NO INHERIT <replaceable class="PARAMETER">parent_table</replaceable> OF <replaceable class="PARAMETER">type_name</replaceable> NOT OF - OWNER TO <replaceable class="PARAMETER">new_owner</replaceable> + OWNER TO { <replaceable class="PARAMETER">new_owner</replaceable> | CURRENT_USER | SESSION_USER } REPLICA IDENTITY {DEFAULT | USING INDEX <replaceable class="PARAMETER">index_name</replaceable> | FULL | NOTHING} <phrase>and <replaceable class="PARAMETER">table_constraint_using_index</replaceable> is:</phrase> diff --git a/doc/src/sgml/ref/alter_tablespace.sgml b/doc/src/sgml/ref/alter_tablespace.sgml index 9d27173d71e9aececfc0d106e9a7d287194a38de..d9b2a133b10632945ab9a86016e0eb0d27929748 100644 --- a/doc/src/sgml/ref/alter_tablespace.sgml +++ b/doc/src/sgml/ref/alter_tablespace.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> ALTER TABLESPACE <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable> -ALTER TABLESPACE <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable> +ALTER TABLESPACE <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER } ALTER TABLESPACE <replaceable>name</replaceable> SET ( <replaceable class="PARAMETER">tablespace_option</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] ) ALTER TABLESPACE <replaceable>name</replaceable> RESET ( <replaceable class="PARAMETER">tablespace_option</replaceable> [, ... ] ) </synopsis> diff --git a/doc/src/sgml/ref/alter_tsconfig.sgml b/doc/src/sgml/ref/alter_tsconfig.sgml index 1a40d88f6a0cb5fa9ff9d355fc0d7bc1adbf60f7..72a719b8629b75a603355398d67e2c230202a56a 100644 --- a/doc/src/sgml/ref/alter_tsconfig.sgml +++ b/doc/src/sgml/ref/alter_tsconfig.sgml @@ -32,7 +32,7 @@ ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable> ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable> DROP MAPPING [ IF EXISTS ] FOR <replaceable class="parameter">token_type</replaceable> [, ... ] ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable> -ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable> +ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER } ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable> </synopsis> </refsynopsisdiv> diff --git a/doc/src/sgml/ref/alter_tsdictionary.sgml b/doc/src/sgml/ref/alter_tsdictionary.sgml index 368f8ee1352b27eb6e56cc991c3f2f4d05a382dc..7cecabea83bd8da82af906eed7a56bca82cb8c52 100644 --- a/doc/src/sgml/ref/alter_tsdictionary.sgml +++ b/doc/src/sgml/ref/alter_tsdictionary.sgml @@ -25,7 +25,7 @@ ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> ( <replaceable class="parameter">option</replaceable> [ = <replaceable class="parameter">value</replaceable> ] [, ... ] ) ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable> -ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable> +ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER } ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable> </synopsis> </refsynopsisdiv> diff --git a/doc/src/sgml/ref/alter_type.sgml b/doc/src/sgml/ref/alter_type.sgml index 7724c11c78e7c9a0cdd5546ea38bcfdc6e7b0b17..9789881a5cabef66277da8a623fdfb3873816a12 100644 --- a/doc/src/sgml/ref/alter_type.sgml +++ b/doc/src/sgml/ref/alter_type.sgml @@ -24,7 +24,7 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> ALTER TYPE <replaceable class="PARAMETER">name</replaceable> <replaceable class="PARAMETER">action</replaceable> [, ... ] -ALTER TYPE <replaceable class="PARAMETER">name</replaceable> OWNER TO <replaceable class="PARAMETER">new_owner</replaceable> +ALTER TYPE <replaceable class="PARAMETER">name</replaceable> OWNER TO { <replaceable class="PARAMETER">new_owner</replaceable> | CURRENT_USER | SESSION_USER } ALTER TYPE <replaceable class="PARAMETER">name</replaceable> RENAME ATTRIBUTE <replaceable class="PARAMETER">attribute_name</replaceable> TO <replaceable class="PARAMETER">new_attribute_name</replaceable> [ CASCADE | RESTRICT ] ALTER TYPE <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable class="PARAMETER">new_name</replaceable> ALTER TYPE <replaceable class="PARAMETER">name</replaceable> SET SCHEMA <replaceable class="PARAMETER">new_schema</replaceable> diff --git a/doc/src/sgml/ref/alter_user.sgml b/doc/src/sgml/ref/alter_user.sgml index 58ae1da127f68eab9df07b105783a515f5346888..0ffaa16da2fc75fcd1121dcde627837d6a8e9166 100644 --- a/doc/src/sgml/ref/alter_user.sgml +++ b/doc/src/sgml/ref/alter_user.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> -ALTER USER <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replaceable class="PARAMETER">option</replaceable> [ ... ] ] +ALTER USER <replaceable class="PARAMETER">role_specification</replaceable> [ WITH ] <replaceable class="PARAMETER">option</replaceable> [ ... ] <phrase>where <replaceable class="PARAMETER">option</replaceable> can be:</phrase> @@ -38,10 +38,16 @@ ALTER USER <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replace ALTER USER <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>new_name</replaceable> -ALTER USER <replaceable class="PARAMETER">name</replaceable> SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT } -ALTER USER <replaceable class="PARAMETER">name</replaceable> SET <replaceable>configuration_parameter</replaceable> FROM CURRENT -ALTER USER <replaceable class="PARAMETER">name</replaceable> RESET <replaceable>configuration_parameter</replaceable> -ALTER USER <replaceable class="PARAMETER">name</replaceable> RESET ALL +ALTER USER <replaceable class="PARAMETER">role_specification</replaceable> SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT } +ALTER USER <replaceable class="PARAMETER">role_specification</replaceable> SET <replaceable>configuration_parameter</replaceable> FROM CURRENT +ALTER USER <replaceable class="PARAMETER">role_specification</replaceable> RESET <replaceable>configuration_parameter</replaceable> +ALTER USER <replaceable class="PARAMETER">role_specification</replaceable> RESET ALL + +<phrase>where <replaceable class="PARAMETER">role_specification</replaceable> can be:</phrase> + + [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> + | CURRENT_USER + | SESSION_USER </synopsis> </refsynopsisdiv> diff --git a/doc/src/sgml/ref/alter_user_mapping.sgml b/doc/src/sgml/ref/alter_user_mapping.sgml index d0ddd1370b9b32b2c00f5a896739cdffb9b65487..3cd51b14139454c9f318acee8362b7d5af47826a 100644 --- a/doc/src/sgml/ref/alter_user_mapping.sgml +++ b/doc/src/sgml/ref/alter_user_mapping.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> -ALTER USER MAPPING FOR { <replaceable class="parameter">user_name</replaceable> | USER | CURRENT_USER | PUBLIC } +ALTER USER MAPPING FOR { <replaceable class="parameter">user_name</replaceable> | USER | CURRENT_USER | SESSION_USER | PUBLIC } SERVER <replaceable class="parameter">server_name</replaceable> OPTIONS ( [ ADD | SET | DROP ] <replaceable class="PARAMETER">option</replaceable> ['<replaceable class="PARAMETER">value</replaceable>'] [, ... ] ) </synopsis> diff --git a/doc/src/sgml/ref/alter_view.sgml b/doc/src/sgml/ref/alter_view.sgml index 3aef61b67e6d5664b08636da2ec5f7b3b29f2f06..00f4ecb9b1a89650372fba4afaebd1a7aa4562de 100644 --- a/doc/src/sgml/ref/alter_view.sgml +++ b/doc/src/sgml/ref/alter_view.sgml @@ -23,7 +23,7 @@ PostgreSQL documentation <synopsis> ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ALTER [ COLUMN ] <replaceable class="PARAMETER">column_name</replaceable> SET DEFAULT <replaceable class="PARAMETER">expression</replaceable> ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ALTER [ COLUMN ] <replaceable class="PARAMETER">column_name</replaceable> DROP DEFAULT -ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> OWNER TO <replaceable class="PARAMETER">new_owner</replaceable> +ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable class="PARAMETER">new_owner</replaceable> | CURRENT_USER | SESSION_USER } ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable> ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable> ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> SET ( <replaceable class="parameter">view_option_name</replaceable> [= <replaceable class="parameter">view_option_value</replaceable>] [, ... ] ) diff --git a/doc/src/sgml/ref/create_schema.sgml b/doc/src/sgml/ref/create_schema.sgml index 45e4637ab5b21f6b6e05294aaa71081cdf9f17c4..79305f15dd03f052745acbf008e8fc31f87bc63e 100644 --- a/doc/src/sgml/ref/create_schema.sgml +++ b/doc/src/sgml/ref/create_schema.sgml @@ -21,10 +21,16 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> -CREATE SCHEMA <replaceable class="parameter">schema_name</replaceable> [ AUTHORIZATION <replaceable class="parameter">user_name</replaceable> ] [ <replaceable class="parameter">schema_element</replaceable> [ ... ] ] -CREATE SCHEMA AUTHORIZATION <replaceable class="parameter">user_name</replaceable> [ <replaceable class="parameter">schema_element</replaceable> [ ... ] ] -CREATE SCHEMA IF NOT EXISTS <replaceable class="parameter">schema_name</replaceable> [ AUTHORIZATION <replaceable class="parameter">user_name</replaceable> ] -CREATE SCHEMA IF NOT EXISTS AUTHORIZATION <replaceable class="parameter">user_name</replaceable> +CREATE SCHEMA <replaceable class="parameter">schema_name</replaceable> [ AUTHORIZATION <replaceable class="PARAMETER">role_specification</replaceable> ] [ <replaceable class="parameter">schema_element</replaceable> [ ... ] ] +CREATE SCHEMA AUTHORIZATION <replaceable class="PARAMETER">role_specification</replaceable> [ <replaceable class="parameter">schema_element</replaceable> [ ... ] ] +CREATE SCHEMA IF NOT EXISTS <replaceable class="parameter">schema_name</replaceable> [ AUTHORIZATION <replaceable class="PARAMETER">role_specification</replaceable> ] +CREATE SCHEMA IF NOT EXISTS AUTHORIZATION <replaceable class="PARAMETER">role_specification</replaceable> + +<phrase>where <replaceable class="PARAMETER">role_specification</replaceable> can be:</phrase> + + [ GROUP ] <replaceable class="PARAMETER">user_name</replaceable> + | CURRENT_USER + | SESSION_USER </synopsis> </refsynopsisdiv> diff --git a/doc/src/sgml/ref/grant.sgml b/doc/src/sgml/ref/grant.sgml index f2b25e546c3bc5b3d50fdd18b9973cad74784926..d9ac8d20f2dae758b6a0d7177a9caf2991f7335a 100644 --- a/doc/src/sgml/ref/grant.sgml +++ b/doc/src/sgml/ref/grant.sgml @@ -25,59 +25,66 @@ GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER } [, ...] | ALL [ PRIVILEGES ] } ON { [ TABLE ] <replaceable class="PARAMETER">table_name</replaceable> [, ...] | ALL TABLES IN SCHEMA <replaceable class="PARAMETER">schema_name</replaceable> [, ...] } - TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] + TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( <replaceable class="PARAMETER">column_name</replaceable> [, ...] ) [, ...] | ALL [ PRIVILEGES ] ( <replaceable class="PARAMETER">column_name</replaceable> [, ...] ) } ON [ TABLE ] <replaceable class="PARAMETER">table_name</replaceable> [, ...] - TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] + TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] GRANT { { USAGE | SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] } ON { SEQUENCE <replaceable class="PARAMETER">sequence_name</replaceable> [, ...] | ALL SEQUENCES IN SCHEMA <replaceable class="PARAMETER">schema_name</replaceable> [, ...] } - TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] + TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] } ON DATABASE <replaceable>database_name</replaceable> [, ...] - TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] + TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON DOMAIN <replaceable>domain_name</replaceable> [, ...] - TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] + TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON FOREIGN DATA WRAPPER <replaceable>fdw_name</replaceable> [, ...] - TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] + TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON FOREIGN SERVER <replaceable>server_name</replaceable> [, ...] - TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] + TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] GRANT { EXECUTE | ALL [ PRIVILEGES ] } ON { FUNCTION <replaceable>function_name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">arg_name</replaceable> ] <replaceable class="parameter">arg_type</replaceable> [, ...] ] ) [, ...] | ALL FUNCTIONS IN SCHEMA <replaceable class="PARAMETER">schema_name</replaceable> [, ...] } - TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] + TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON LANGUAGE <replaceable>lang_name</replaceable> [, ...] - TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] + TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] GRANT { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] } ON LARGE OBJECT <replaceable class="PARAMETER">loid</replaceable> [, ...] - TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] + TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] } ON SCHEMA <replaceable>schema_name</replaceable> [, ...] - TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] + TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] GRANT { CREATE | ALL [ PRIVILEGES ] } ON TABLESPACE <replaceable>tablespace_name</replaceable> [, ...] - TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] + TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON TYPE <replaceable>type_name</replaceable> [, ...] - TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] + TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] + +<phrase>where <replaceable class="PARAMETER">role_specification</replaceable> can be:</phrase> + + [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> + | PUBLIC + | CURRENT_USER + | SESSION_USER GRANT <replaceable class="PARAMETER">role_name</replaceable> [, ...] TO <replaceable class="PARAMETER">role_name</replaceable> [, ...] [ WITH ADMIN OPTION ] </synopsis> diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 3b456f97efa4ddb95ad783603840bcb3e0a182da..6c8780f794dbfd0764126cf2564c86058ff0dd88 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -421,22 +421,25 @@ ExecuteGrantStmt(GrantStmt *stmt) istmt.behavior = stmt->behavior; /* - * Convert the PrivGrantee list into an Oid list. Note that at this point - * we insert an ACL_ID_PUBLIC into the list if an empty role name is - * detected (which is what the grammar uses if PUBLIC is found), so - * downstream there shouldn't be any additional work needed to support - * this case. + * Convert the RoleSpec list into an Oid list. Note that at this point + * we insert an ACL_ID_PUBLIC into the list if appropriate, so downstream + * there shouldn't be any additional work needed to support this case. */ foreach(cell, stmt->grantees) { - PrivGrantee *grantee = (PrivGrantee *) lfirst(cell); + RoleSpec *grantee = (RoleSpec *) lfirst(cell); + Oid grantee_uid; - if (grantee->rolname == NULL) - istmt.grantees = lappend_oid(istmt.grantees, ACL_ID_PUBLIC); - else - istmt.grantees = - lappend_oid(istmt.grantees, - get_role_oid(grantee->rolname, false)); + switch (grantee->roletype) + { + case ROLESPEC_PUBLIC: + grantee_uid = ACL_ID_PUBLIC; + break; + default: + grantee_uid = get_rolespec_oid((Node *) grantee, false); + break; + } + istmt.grantees = lappend_oid(istmt.grantees, grantee_uid); } /* @@ -904,22 +907,25 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt) iacls.behavior = action->behavior; /* - * Convert the PrivGrantee list into an Oid list. Note that at this point - * we insert an ACL_ID_PUBLIC into the list if an empty role name is - * detected (which is what the grammar uses if PUBLIC is found), so - * downstream there shouldn't be any additional work needed to support - * this case. + * Convert the RoleSpec list into an Oid list. Note that at this point + * we insert an ACL_ID_PUBLIC into the list if appropriate, so downstream + * there shouldn't be any additional work needed to support this case. */ foreach(cell, action->grantees) { - PrivGrantee *grantee = (PrivGrantee *) lfirst(cell); + RoleSpec *grantee = (RoleSpec *) lfirst(cell); + Oid grantee_uid; - if (grantee->rolname == NULL) - iacls.grantees = lappend_oid(iacls.grantees, ACL_ID_PUBLIC); - else - iacls.grantees = - lappend_oid(iacls.grantees, - get_role_oid(grantee->rolname, false)); + switch (grantee->roletype) + { + case ROLESPEC_PUBLIC: + grantee_uid = ACL_ID_PUBLIC; + break; + default: + grantee_uid = get_rolespec_oid((Node *) grantee, false); + break; + } + iacls.grantees = lappend_oid(iacls.grantees, grantee_uid); } /* diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index 59aacef7ea947efeb7f78a0368463d777195f0ac..3ddd7ec4343219de616e17bab26324bce391b17d 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -699,7 +699,7 @@ AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid) ObjectAddress ExecAlterOwnerStmt(AlterOwnerStmt *stmt) { - Oid newowner = get_role_oid(stmt->newowner, false); + Oid newowner = get_rolespec_oid(stmt->newowner, false); switch (stmt->objectType) { diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index aa733575e46796bd60f1df2342a37f21d8bd4681..5cc74d03c11a3aac696eb98393b0d7e0707133e5 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -1371,7 +1371,7 @@ CreateExtension(CreateExtensionStmt *stmt) CreateSchemaStmt *csstmt = makeNode(CreateSchemaStmt); csstmt->schemaname = schemaName; - csstmt->authid = NULL; /* will be created by current user */ + csstmt->authrole = NULL; /* will be created by current user */ csstmt->schemaElts = NIL; csstmt->if_not_exists = false; CreateSchemaCommand(csstmt, NULL); diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c index bd4839189e6efb2a16ddee0b38c7b7633ae0406e..3b85c2c017eec93d1ecba3385173611bd3c8e420 100644 --- a/src/backend/commands/foreigncmds.c +++ b/src/backend/commands/foreigncmds.c @@ -197,24 +197,6 @@ transformGenericOptions(Oid catalogId, } -/* - * Convert the user mapping user name to OID - */ -static Oid -GetUserOidFromMapping(const char *username, bool missing_ok) -{ - if (!username) - /* PUBLIC user mapping */ - return InvalidOid; - - if (strcmp(username, "current_user") == 0) - /* map to the owner */ - return GetUserId(); - - /* map to provided user */ - return get_role_oid(username, missing_ok); -} - /* * Internal workhorse for changing a data wrapper's owner. * @@ -1156,10 +1138,14 @@ CreateUserMapping(CreateUserMappingStmt *stmt) ObjectAddress referenced; ForeignServer *srv; ForeignDataWrapper *fdw; + RoleSpec *role = (RoleSpec *) stmt->user; rel = heap_open(UserMappingRelationId, RowExclusiveLock); - useId = GetUserOidFromMapping(stmt->username, false); + if (role->roletype == ROLESPEC_PUBLIC) + useId = ACL_ID_PUBLIC; + else + useId = get_rolespec_oid(stmt->user, false); /* Check that the server exists. */ srv = GetForeignServerByName(stmt->servername, false); @@ -1252,10 +1238,15 @@ AlterUserMapping(AlterUserMappingStmt *stmt) Oid umId; ForeignServer *srv; ObjectAddress address; + RoleSpec *role = (RoleSpec *) stmt->user; rel = heap_open(UserMappingRelationId, RowExclusiveLock); - useId = GetUserOidFromMapping(stmt->username, false); + if (role->roletype == ROLESPEC_PUBLIC) + useId = ACL_ID_PUBLIC; + else + useId = get_rolespec_oid(stmt->user, false); + srv = GetForeignServerByName(stmt->servername, false); umId = GetSysCacheOid2(USERMAPPINGUSERSERVER, @@ -1338,20 +1329,27 @@ RemoveUserMapping(DropUserMappingStmt *stmt) Oid useId; Oid umId; ForeignServer *srv; + RoleSpec *role = (RoleSpec *) stmt->user; - useId = GetUserOidFromMapping(stmt->username, stmt->missing_ok); - srv = GetForeignServerByName(stmt->servername, true); - - if (stmt->username && !OidIsValid(useId)) + if (role->roletype == ROLESPEC_PUBLIC) + useId = ACL_ID_PUBLIC; + else { - /* - * IF EXISTS specified, role not found and not public. Notice this and - * leave. - */ - elog(NOTICE, "role \"%s\" does not exist, skipping", stmt->username); - return InvalidOid; + useId = get_rolespec_oid(stmt->user, stmt->missing_ok); + if (!OidIsValid(useId)) + { + /* + * IF EXISTS specified, role not found and not public. Notice this + * and leave. + */ + elog(NOTICE, "role \"%s\" does not exist, skipping", + role->rolename); + return InvalidOid; + } } + srv = GetForeignServerByName(stmt->servername, true); + if (!srv) { if (!stmt->missing_ok) diff --git a/src/backend/commands/policy.c b/src/backend/commands/policy.c index e86299781f960b93c0ee27e6e4fec2047aa873e6..a3d840da5cf7f319f498a6602966022f7ad6cc7b 100644 --- a/src/backend/commands/policy.c +++ b/src/backend/commands/policy.c @@ -129,13 +129,7 @@ parse_policy_command(const char *cmd_name) /* * policy_role_list_to_array - * helper function to convert a list of role names in to an array of - * role ids. - * - * Note: If PUBLIC is provided as a role name, then ACL_ID_PUBLIC is - * used as the role id. - * - * roles - the list of role names to convert. + * helper function to convert a list of RoleSpecs to an array of role ids. */ static ArrayType * policy_role_list_to_array(List *roles) @@ -162,25 +156,25 @@ policy_role_list_to_array(List *roles) foreach(cell, roles) { - Oid roleid = get_role_oid_or_public(strVal(lfirst(cell))); + RoleSpec *spec = lfirst(cell); /* * PUBLIC covers all roles, so it only makes sense alone. */ - if (roleid == ACL_ID_PUBLIC) + if (spec->roletype == ROLESPEC_PUBLIC) { if (num_roles != 1) ereport(WARNING, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("ignoring roles specified other than public"), errhint("All roles are members of the public role."))); - - temp_array[0] = ObjectIdGetDatum(roleid); + temp_array[0] = ObjectIdGetDatum(ACL_ID_PUBLIC); num_roles = 1; break; } else - temp_array[i++] = ObjectIdGetDatum(roleid); + temp_array[i++] = + ObjectIdGetDatum(get_rolespec_oid((Node *) spec, false)); } role_ids = construct_array(temp_array, num_roles, OIDOID, sizeof(Oid), true, diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c index 722142e16eaae72b13fb410ff1b63046b75b5911..c090ed220f8ee3d7fc46feec62de249d07e66eef 100644 --- a/src/backend/commands/schemacmds.c +++ b/src/backend/commands/schemacmds.c @@ -21,6 +21,7 @@ #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/namespace.h" +#include "catalog/pg_authid.h" #include "catalog/objectaccess.h" #include "catalog/pg_namespace.h" #include "commands/dbcommands.h" @@ -42,8 +43,7 @@ static void AlterSchemaOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerI Oid CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString) { - const char *schemaName = stmt->schemaname; - const char *authId = stmt->authid; + const char *schemaName = stmt->schemaname; Oid namespaceId; OverrideSearchPath *overridePath; List *parsetree_list; @@ -58,11 +58,24 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString) /* * Who is supposed to own the new schema? */ - if (authId) - owner_uid = get_role_oid(authId, false); + if (stmt->authrole) + owner_uid = get_rolespec_oid(stmt->authrole, false); else owner_uid = saved_uid; + /* fill schema name with the user name if not specified */ + if (!schemaName) + { + HeapTuple tuple; + + tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(owner_uid)); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for role %u", owner_uid); + schemaName = + pstrdup(NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname)); + ReleaseSysCache(tuple); + } + /* * To create a schema, must have schema-create privilege on the current * database and must be able to become the target role (this does not diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 653677892dee133e60cc1ced15cfc6d0be8a5721..623e6bfba81c6ad02284d9984705a4157a550e4b 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -3507,7 +3507,7 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, break; case AT_ChangeOwner: /* ALTER OWNER */ ATExecChangeOwner(RelationGetRelid(rel), - get_role_oid(cmd->name, false), + get_rolespec_oid(cmd->newowner, false), false, lockmode); break; case AT_ClusterOn: /* CLUSTER ON */ @@ -9388,7 +9388,7 @@ AlterTableMoveAll(AlterTableMoveAllStmt *stmt) HeapTuple tuple; Oid orig_tablespaceoid; Oid new_tablespaceoid; - List *role_oids = roleNamesToIds(stmt->roles); + List *role_oids = roleSpecsToIds(stmt->roles); /* Ensure we were not asked to move something we can't */ if (stmt->objtype != OBJECT_TABLE && stmt->objtype != OBJECT_INDEX && diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index 68b6917df5dc513b567535d029e79db6a86bbf97..fd226125a93838a74dad709565e6e7ce6bce6bf1 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -252,7 +252,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt) /* However, the eventual owner of the tablespace need not be */ if (stmt->owner) - ownerId = get_role_oid(stmt->owner, false); + ownerId = get_rolespec_oid(stmt->owner, false); else ownerId = GetUserId(); diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 0ba7ba0c20f88928d9f42531aa6631bde08e38e9..c14465eb87b6dfc9a73a6abed848a29bc8eac280 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -49,10 +49,10 @@ extern bool Password_encryption; check_password_hook_type check_password_hook = NULL; static void AddRoleMems(const char *rolename, Oid roleid, - List *memberNames, List *memberIds, + List *memberSpecs, List *memberIds, Oid grantorId, bool admin_opt); static void DelRoleMems(const char *rolename, Oid roleid, - List *memberNames, List *memberIds, + List *memberSpecs, List *memberIds, bool admin_opt); @@ -443,10 +443,10 @@ CreateRole(CreateRoleStmt *stmt) * option, rolemembers don't. */ AddRoleMems(stmt->role, roleid, - adminmembers, roleNamesToIds(adminmembers), + adminmembers, roleSpecsToIds(adminmembers), GetUserId(), true); AddRoleMems(stmt->role, roleid, - rolemembers, roleNamesToIds(rolemembers), + rolemembers, roleSpecsToIds(rolemembers), GetUserId(), false); /* Post creation hook for new role */ @@ -478,7 +478,9 @@ AlterRole(AlterRoleStmt *stmt) TupleDesc pg_authid_dsc; HeapTuple tuple, new_tuple; + Form_pg_authid authform; ListCell *option; + char *rolename = NULL; char *password = NULL; /* user password */ bool encrypt_password = Password_encryption; /* encrypt password? */ char encrypted_password[MD5_PASSWD_LEN + 1]; @@ -647,33 +649,30 @@ AlterRole(AlterRoleStmt *stmt) pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock); pg_authid_dsc = RelationGetDescr(pg_authid_rel); - tuple = SearchSysCache1(AUTHNAME, PointerGetDatum(stmt->role)); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("role \"%s\" does not exist", stmt->role))); - + tuple = get_rolespec_tuple(stmt->role); + authform = (Form_pg_authid) GETSTRUCT(tuple); + rolename = pstrdup(NameStr(authform->rolname)); roleid = HeapTupleGetOid(tuple); /* * To mess with a superuser you gotta be superuser; else you need * createrole, or just want to change your own password */ - if (((Form_pg_authid) GETSTRUCT(tuple))->rolsuper || issuper >= 0) + if (authform->rolsuper || issuper >= 0) { if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to alter superusers"))); } - else if (((Form_pg_authid) GETSTRUCT(tuple))->rolreplication || isreplication >= 0) + else if (authform->rolreplication || isreplication >= 0) { if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to alter replication users"))); } - else if (((Form_pg_authid) GETSTRUCT(tuple))->rolbypassrls || bypassrls >= 0) + else if (authform->rolbypassrls || bypassrls >= 0) { if (!superuser()) ereport(ERROR, @@ -718,11 +717,11 @@ AlterRole(AlterRoleStmt *stmt) * Call the password checking hook if there is one defined */ if (check_password_hook && password) - (*check_password_hook) (stmt->role, - password, - isMD5(password) ? PASSWORD_TYPE_MD5 : PASSWORD_TYPE_PLAINTEXT, - validUntil_datum, - validUntil_null); + (*check_password_hook)(rolename , + password, + isMD5(password) ? PASSWORD_TYPE_MD5 : PASSWORD_TYPE_PLAINTEXT, + validUntil_datum, + validUntil_null); /* * Build an updated tuple, perusing the information just obtained @@ -784,7 +783,7 @@ AlterRole(AlterRoleStmt *stmt) CStringGetTextDatum(password); else { - if (!pg_md5_encrypt(password, stmt->role, strlen(stmt->role), + if (!pg_md5_encrypt(password, rolename, strlen(rolename), encrypted_password)) elog(ERROR, "password encryption failed"); new_record[Anum_pg_authid_rolpassword - 1] = @@ -831,12 +830,12 @@ AlterRole(AlterRoleStmt *stmt) CommandCounterIncrement(); if (stmt->action == +1) /* add members to role */ - AddRoleMems(stmt->role, roleid, - rolemembers, roleNamesToIds(rolemembers), + AddRoleMems(rolename, roleid, + rolemembers, roleSpecsToIds(rolemembers), GetUserId(), false); else if (stmt->action == -1) /* drop members from role */ - DelRoleMems(stmt->role, roleid, - rolemembers, roleNamesToIds(rolemembers), + DelRoleMems(rolename, roleid, + rolemembers, roleSpecsToIds(rolemembers), false); /* @@ -860,13 +859,7 @@ AlterRoleSet(AlterRoleSetStmt *stmt) if (stmt->role) { - roletuple = SearchSysCache1(AUTHNAME, PointerGetDatum(stmt->role)); - - if (!HeapTupleIsValid(roletuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("role \"%s\" does not exist", stmt->role))); - + roletuple = get_rolespec_tuple(stmt->role); roleid = HeapTupleGetOid(roletuple); /* @@ -955,7 +948,8 @@ DropRole(DropRoleStmt *stmt) foreach(item, stmt->roles) { - const char *role = strVal(lfirst(item)); + RoleSpec *rolspec = lfirst(item); + char *role; HeapTuple tuple, tmp_tuple; ScanKeyData scankey; @@ -964,6 +958,12 @@ DropRole(DropRoleStmt *stmt) SysScanDesc sscan; Oid roleid; + if (rolspec->roletype != ROLESPEC_CSTRING) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("cannot use special role specifier in \"%s\"", "DROP ROLE"))); + role = rolspec->rolename; + tuple = SearchSysCache1(AUTHNAME, PointerGetDatum(role)); if (!HeapTupleIsValid(tuple)) { @@ -1233,11 +1233,11 @@ GrantRole(GrantRoleStmt *stmt) ListCell *item; if (stmt->grantor) - grantor = get_role_oid(stmt->grantor, false); + grantor = get_rolespec_oid(stmt->grantor, false); else grantor = GetUserId(); - grantee_ids = roleNamesToIds(stmt->grantee_roles); + grantee_ids = roleSpecsToIds(stmt->grantee_roles); /* AccessShareLock is enough since we aren't modifying pg_authid */ pg_authid_rel = heap_open(AuthIdRelationId, AccessShareLock); @@ -1286,7 +1286,7 @@ GrantRole(GrantRoleStmt *stmt) void DropOwnedObjects(DropOwnedStmt *stmt) { - List *role_ids = roleNamesToIds(stmt->roles); + List *role_ids = roleSpecsToIds(stmt->roles); ListCell *cell; /* Check privileges */ @@ -1312,7 +1312,7 @@ DropOwnedObjects(DropOwnedStmt *stmt) void ReassignOwnedObjects(ReassignOwnedStmt *stmt) { - List *role_ids = roleNamesToIds(stmt->roles); + List *role_ids = roleSpecsToIds(stmt->roles); ListCell *cell; Oid newrole; @@ -1328,7 +1328,7 @@ ReassignOwnedObjects(ReassignOwnedStmt *stmt) } /* Must have privileges on the receiving side too */ - newrole = get_role_oid(stmt->newrole, false); + newrole = get_rolespec_oid(stmt->newrole, false); if (!has_privs_of_role(GetUserId(), newrole)) ereport(ERROR, @@ -1340,22 +1340,24 @@ ReassignOwnedObjects(ReassignOwnedStmt *stmt) } /* - * roleNamesToIds + * roleSpecsToIds + * + * Given a list of RoleSpecs, generate a list of role OIDs in the same order. * - * Given a list of role names (as String nodes), generate a list of role OIDs - * in the same order. + * ROLESPEC_PUBLIC is not allowed. */ List * -roleNamesToIds(List *memberNames) +roleSpecsToIds(List *memberNames) { List *result = NIL; ListCell *l; foreach(l, memberNames) { - char *rolename = strVal(lfirst(l)); - Oid roleid = get_role_oid(rolename, false); + Node *rolespec = (Node *) lfirst(l); + Oid roleid; + roleid = get_rolespec_oid(rolespec, false); result = lappend_oid(result, roleid); } return result; @@ -1366,7 +1368,7 @@ roleNamesToIds(List *memberNames) * * rolename: name of role to add to (used only for error messages) * roleid: OID of role to add to - * memberNames: list of names of roles to add (used only for error messages) + * memberSpecs: list of RoleSpec of roles to add (used only for error messages) * memberIds: OIDs of roles to add * grantorId: who is granting the membership * admin_opt: granting admin option? @@ -1375,15 +1377,15 @@ roleNamesToIds(List *memberNames) */ static void AddRoleMems(const char *rolename, Oid roleid, - List *memberNames, List *memberIds, + List *memberSpecs, List *memberIds, Oid grantorId, bool admin_opt) { Relation pg_authmem_rel; TupleDesc pg_authmem_dsc; - ListCell *nameitem; + ListCell *specitem; ListCell *iditem; - Assert(list_length(memberNames) == list_length(memberIds)); + Assert(list_length(memberSpecs) == list_length(memberIds)); /* Skip permission check if nothing to do */ if (!memberIds) @@ -1428,9 +1430,9 @@ AddRoleMems(const char *rolename, Oid roleid, pg_authmem_rel = heap_open(AuthMemRelationId, RowExclusiveLock); pg_authmem_dsc = RelationGetDescr(pg_authmem_rel); - forboth(nameitem, memberNames, iditem, memberIds) + forboth(specitem, memberSpecs, iditem, memberIds) { - const char *membername = strVal(lfirst(nameitem)); + RoleSpec *memberRole = lfirst(specitem); Oid memberid = lfirst_oid(iditem); HeapTuple authmem_tuple; HeapTuple tuple; @@ -1449,7 +1451,7 @@ AddRoleMems(const char *rolename, Oid roleid, ereport(ERROR, (errcode(ERRCODE_INVALID_GRANT_OPERATION), (errmsg("role \"%s\" is a member of role \"%s\"", - rolename, membername)))); + rolename, get_rolespec_name((Node *) memberRole))))); /* * Check if entry for this role/member already exists; if so, give @@ -1464,7 +1466,7 @@ AddRoleMems(const char *rolename, Oid roleid, { ereport(NOTICE, (errmsg("role \"%s\" is already a member of role \"%s\"", - membername, rolename))); + get_rolespec_name((Node *) memberRole), rolename))); ReleaseSysCache(authmem_tuple); continue; } @@ -1513,7 +1515,7 @@ AddRoleMems(const char *rolename, Oid roleid, * * rolename: name of role to del from (used only for error messages) * roleid: OID of role to del from - * memberNames: list of names of roles to del (used only for error messages) + * memberSpecs: list of RoleSpec of roles to del (used only for error messages) * memberIds: OIDs of roles to del * admin_opt: remove admin option only? * @@ -1521,15 +1523,15 @@ AddRoleMems(const char *rolename, Oid roleid, */ static void DelRoleMems(const char *rolename, Oid roleid, - List *memberNames, List *memberIds, + List *memberSpecs, List *memberIds, bool admin_opt) { Relation pg_authmem_rel; TupleDesc pg_authmem_dsc; - ListCell *nameitem; + ListCell *specitem; ListCell *iditem; - Assert(list_length(memberNames) == list_length(memberIds)); + Assert(list_length(memberSpecs) == list_length(memberIds)); /* Skip permission check if nothing to do */ if (!memberIds) @@ -1559,9 +1561,9 @@ DelRoleMems(const char *rolename, Oid roleid, pg_authmem_rel = heap_open(AuthMemRelationId, RowExclusiveLock); pg_authmem_dsc = RelationGetDescr(pg_authmem_rel); - forboth(nameitem, memberNames, iditem, memberIds) + forboth(specitem, memberSpecs, iditem, memberIds) { - const char *membername = strVal(lfirst(nameitem)); + RoleSpec *memberRole = lfirst(specitem); Oid memberid = lfirst_oid(iditem); HeapTuple authmem_tuple; @@ -1575,7 +1577,7 @@ DelRoleMems(const char *rolename, Oid roleid, { ereport(WARNING, (errmsg("role \"%s\" is not a member of role \"%s\"", - membername, rolename))); + get_rolespec_name((Node *) memberRole), rolename))); continue; } diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 9fe80080f31884b5153658f988e3a3d80351e134..ebb6f3a49b74d68b82f0bf592f1af2cb69ef7ac7 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -2504,6 +2504,18 @@ _copyXmlSerialize(const XmlSerialize *from) return newnode; } +static RoleSpec * +_copyRoleSpec(const RoleSpec *from) +{ + RoleSpec *newnode = makeNode(RoleSpec); + + COPY_SCALAR_FIELD(roletype); + COPY_STRING_FIELD(rolename); + COPY_LOCATION_FIELD(location); + + return newnode; +} + static Query * _copyQuery(const Query *from) { @@ -2650,6 +2662,7 @@ _copyAlterTableCmd(const AlterTableCmd *from) COPY_SCALAR_FIELD(subtype); COPY_STRING_FIELD(name); + COPY_NODE_FIELD(newowner); COPY_NODE_FIELD(def); COPY_SCALAR_FIELD(behavior); COPY_SCALAR_FIELD(missing_ok); @@ -2689,16 +2702,6 @@ _copyGrantStmt(const GrantStmt *from) return newnode; } -static PrivGrantee * -_copyPrivGrantee(const PrivGrantee *from) -{ - PrivGrantee *newnode = makeNode(PrivGrantee); - - COPY_STRING_FIELD(rolname); - - return newnode; -} - static FuncWithArgs * _copyFuncWithArgs(const FuncWithArgs *from) { @@ -2730,7 +2733,7 @@ _copyGrantRoleStmt(const GrantRoleStmt *from) COPY_NODE_FIELD(grantee_roles); COPY_SCALAR_FIELD(is_grant); COPY_SCALAR_FIELD(admin_opt); - COPY_STRING_FIELD(grantor); + COPY_NODE_FIELD(grantor); COPY_SCALAR_FIELD(behavior); return newnode; @@ -3038,7 +3041,7 @@ _copyAlterOwnerStmt(const AlterOwnerStmt *from) COPY_NODE_FIELD(relation); COPY_NODE_FIELD(object); COPY_NODE_FIELD(objarg); - COPY_STRING_FIELD(newowner); + COPY_NODE_FIELD(newowner); return newnode; } @@ -3424,7 +3427,7 @@ _copyCreateTableSpaceStmt(const CreateTableSpaceStmt *from) CreateTableSpaceStmt *newnode = makeNode(CreateTableSpaceStmt); COPY_STRING_FIELD(tablespacename); - COPY_STRING_FIELD(owner); + COPY_NODE_FIELD(owner); COPY_STRING_FIELD(location); COPY_NODE_FIELD(options); @@ -3561,7 +3564,7 @@ _copyCreateUserMappingStmt(const CreateUserMappingStmt *from) { CreateUserMappingStmt *newnode = makeNode(CreateUserMappingStmt); - COPY_STRING_FIELD(username); + COPY_NODE_FIELD(user); COPY_STRING_FIELD(servername); COPY_NODE_FIELD(options); @@ -3573,7 +3576,7 @@ _copyAlterUserMappingStmt(const AlterUserMappingStmt *from) { AlterUserMappingStmt *newnode = makeNode(AlterUserMappingStmt); - COPY_STRING_FIELD(username); + COPY_NODE_FIELD(user); COPY_STRING_FIELD(servername); COPY_NODE_FIELD(options); @@ -3585,7 +3588,7 @@ _copyDropUserMappingStmt(const DropUserMappingStmt *from) { DropUserMappingStmt *newnode = makeNode(DropUserMappingStmt); - COPY_STRING_FIELD(username); + COPY_NODE_FIELD(user); COPY_STRING_FIELD(servername); COPY_SCALAR_FIELD(missing_ok); @@ -3698,7 +3701,7 @@ _copyAlterRoleStmt(const AlterRoleStmt *from) { AlterRoleStmt *newnode = makeNode(AlterRoleStmt); - COPY_STRING_FIELD(role); + COPY_NODE_FIELD(role); COPY_NODE_FIELD(options); COPY_SCALAR_FIELD(action); @@ -3710,7 +3713,7 @@ _copyAlterRoleSetStmt(const AlterRoleSetStmt *from) { AlterRoleSetStmt *newnode = makeNode(AlterRoleSetStmt); - COPY_STRING_FIELD(role); + COPY_NODE_FIELD(role); COPY_STRING_FIELD(database); COPY_NODE_FIELD(setstmt); @@ -3769,7 +3772,7 @@ _copyCreateSchemaStmt(const CreateSchemaStmt *from) CreateSchemaStmt *newnode = makeNode(CreateSchemaStmt); COPY_STRING_FIELD(schemaname); - COPY_STRING_FIELD(authid); + COPY_NODE_FIELD(authrole); COPY_NODE_FIELD(schemaElts); COPY_SCALAR_FIELD(if_not_exists); @@ -3854,7 +3857,7 @@ _copyReassignOwnedStmt(const ReassignOwnedStmt *from) ReassignOwnedStmt *newnode = makeNode(ReassignOwnedStmt); COPY_NODE_FIELD(roles); - COPY_STRING_FIELD(newrole); + COPY_NODE_FIELD(newrole); return newnode; } @@ -4728,9 +4731,6 @@ copyObject(const void *from) case T_CommonTableExpr: retval = _copyCommonTableExpr(from); break; - case T_PrivGrantee: - retval = _copyPrivGrantee(from); - break; case T_FuncWithArgs: retval = _copyFuncWithArgs(from); break; @@ -4740,6 +4740,9 @@ copyObject(const void *from) case T_XmlSerialize: retval = _copyXmlSerialize(from); break; + case T_RoleSpec: + retval = _copyRoleSpec(from); + break; default: elog(ERROR, "unrecognized node type: %d", (int) nodeTag(from)); diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index fe509b0ad1cb3d43a57e73f5c2803d1077d0919c..8186e84d3395ee6e3f1cd0d40f092402bef99e31 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -973,6 +973,7 @@ _equalAlterTableCmd(const AlterTableCmd *a, const AlterTableCmd *b) { COMPARE_SCALAR_FIELD(subtype); COMPARE_STRING_FIELD(name); + COMPARE_NODE_FIELD(newowner); COMPARE_NODE_FIELD(def); COMPARE_SCALAR_FIELD(behavior); COMPARE_SCALAR_FIELD(missing_ok); @@ -1008,14 +1009,6 @@ _equalGrantStmt(const GrantStmt *a, const GrantStmt *b) return true; } -static bool -_equalPrivGrantee(const PrivGrantee *a, const PrivGrantee *b) -{ - COMPARE_STRING_FIELD(rolname); - - return true; -} - static bool _equalFuncWithArgs(const FuncWithArgs *a, const FuncWithArgs *b) { @@ -1041,7 +1034,7 @@ _equalGrantRoleStmt(const GrantRoleStmt *a, const GrantRoleStmt *b) COMPARE_NODE_FIELD(grantee_roles); COMPARE_SCALAR_FIELD(is_grant); COMPARE_SCALAR_FIELD(admin_opt); - COMPARE_STRING_FIELD(grantor); + COMPARE_NODE_FIELD(grantor); COMPARE_SCALAR_FIELD(behavior); return true; @@ -1295,7 +1288,7 @@ _equalAlterOwnerStmt(const AlterOwnerStmt *a, const AlterOwnerStmt *b) COMPARE_NODE_FIELD(relation); COMPARE_NODE_FIELD(object); COMPARE_NODE_FIELD(objarg); - COMPARE_STRING_FIELD(newowner); + COMPARE_NODE_FIELD(newowner); return true; } @@ -1618,7 +1611,7 @@ static bool _equalCreateTableSpaceStmt(const CreateTableSpaceStmt *a, const CreateTableSpaceStmt *b) { COMPARE_STRING_FIELD(tablespacename); - COMPARE_STRING_FIELD(owner); + COMPARE_NODE_FIELD(owner); COMPARE_STRING_FIELD(location); COMPARE_NODE_FIELD(options); @@ -1735,7 +1728,7 @@ _equalAlterForeignServerStmt(const AlterForeignServerStmt *a, const AlterForeign static bool _equalCreateUserMappingStmt(const CreateUserMappingStmt *a, const CreateUserMappingStmt *b) { - COMPARE_STRING_FIELD(username); + COMPARE_NODE_FIELD(user); COMPARE_STRING_FIELD(servername); COMPARE_NODE_FIELD(options); @@ -1745,7 +1738,7 @@ _equalCreateUserMappingStmt(const CreateUserMappingStmt *a, const CreateUserMapp static bool _equalAlterUserMappingStmt(const AlterUserMappingStmt *a, const AlterUserMappingStmt *b) { - COMPARE_STRING_FIELD(username); + COMPARE_NODE_FIELD(user); COMPARE_STRING_FIELD(servername); COMPARE_NODE_FIELD(options); @@ -1755,7 +1748,7 @@ _equalAlterUserMappingStmt(const AlterUserMappingStmt *a, const AlterUserMapping static bool _equalDropUserMappingStmt(const DropUserMappingStmt *a, const DropUserMappingStmt *b) { - COMPARE_STRING_FIELD(username); + COMPARE_NODE_FIELD(user); COMPARE_STRING_FIELD(servername); COMPARE_SCALAR_FIELD(missing_ok); @@ -1853,7 +1846,7 @@ _equalCreateRoleStmt(const CreateRoleStmt *a, const CreateRoleStmt *b) static bool _equalAlterRoleStmt(const AlterRoleStmt *a, const AlterRoleStmt *b) { - COMPARE_STRING_FIELD(role); + COMPARE_NODE_FIELD(role); COMPARE_NODE_FIELD(options); COMPARE_SCALAR_FIELD(action); @@ -1863,7 +1856,7 @@ _equalAlterRoleStmt(const AlterRoleStmt *a, const AlterRoleStmt *b) static bool _equalAlterRoleSetStmt(const AlterRoleSetStmt *a, const AlterRoleSetStmt *b) { - COMPARE_STRING_FIELD(role); + COMPARE_NODE_FIELD(role); COMPARE_STRING_FIELD(database); COMPARE_NODE_FIELD(setstmt); @@ -1912,7 +1905,7 @@ static bool _equalCreateSchemaStmt(const CreateSchemaStmt *a, const CreateSchemaStmt *b) { COMPARE_STRING_FIELD(schemaname); - COMPARE_STRING_FIELD(authid); + COMPARE_NODE_FIELD(authrole); COMPARE_NODE_FIELD(schemaElts); COMPARE_SCALAR_FIELD(if_not_exists); @@ -1983,7 +1976,7 @@ static bool _equalReassignOwnedStmt(const ReassignOwnedStmt *a, const ReassignOwnedStmt *b) { COMPARE_NODE_FIELD(roles); - COMPARE_STRING_FIELD(newrole); + COMPARE_NODE_FIELD(newrole); return true; } @@ -2455,6 +2448,16 @@ _equalXmlSerialize(const XmlSerialize *a, const XmlSerialize *b) return true; } +static bool +_equalRoleSpec(const RoleSpec *a, const RoleSpec *b) +{ + COMPARE_SCALAR_FIELD(roletype); + COMPARE_STRING_FIELD(rolename); + COMPARE_LOCATION_FIELD(location); + + return true; +} + /* * Stuff from pg_list.h */ @@ -3153,9 +3156,6 @@ equal(const void *a, const void *b) case T_CommonTableExpr: retval = _equalCommonTableExpr(a, b); break; - case T_PrivGrantee: - retval = _equalPrivGrantee(a, b); - break; case T_FuncWithArgs: retval = _equalFuncWithArgs(a, b); break; @@ -3165,6 +3165,9 @@ equal(const void *a, const void *b) case T_XmlSerialize: retval = _equalXmlSerialize(a, b); break; + case T_RoleSpec: + retval = _equalRoleSpec(a, b); + break; default: elog(ERROR, "unrecognized node type: %d", diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 581f7a1c1c64fa20687a372740770345fef35992..435c0451cae194bb784fb76ac148f9f30957ee56 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -143,6 +143,7 @@ static Node *makeBitStringConst(char *str, int location); static Node *makeNullAConst(int location); static Node *makeAConst(Value *v, int location); static Node *makeBoolAConst(bool state, int location); +static Node *makeRoleSpec(RoleSpecType type, int location); static void check_qualified_name(List *names, core_yyscan_t yyscanner); static List *check_func_name(List *names, core_yyscan_t yyscanner); static List *check_indirection(List *indirection, core_yyscan_t yyscanner); @@ -291,7 +292,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type <str> opt_type %type <str> foreign_server_version opt_foreign_server_version -%type <str> auth_ident %type <str> opt_in_database %type <str> OptSchemaName @@ -474,12 +474,13 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type <ival> Iconst SignedIconst %type <str> Sconst comment_text notify_payload -%type <str> RoleId opt_granted_by opt_boolean_or_string +%type <str> RoleId opt_boolean_or_string %type <list> var_list %type <str> ColId ColLabel var_name type_function_name param_name %type <str> NonReservedWord NonReservedWord_or_Sconst %type <str> createdb_opt_name %type <node> var_value zone_value +%type <node> auth_ident RoleSpec opt_granted_by %type <keyword> unreserved_keyword type_func_name_keyword %type <keyword> col_name_keyword reserved_keyword @@ -494,7 +495,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type <list> constraints_set_list %type <boolean> constraints_set_mode -%type <str> OptTableSpace OptConsTableSpace OptTableSpaceOwner +%type <str> OptTableSpace OptConsTableSpace +%type <node> OptTableSpaceOwner %type <ival> opt_check_option %type <str> opt_provider security_label @@ -1037,7 +1039,7 @@ CreateUserStmt: *****************************************************************************/ AlterRoleStmt: - ALTER ROLE RoleId opt_with AlterOptRoleList + ALTER ROLE RoleSpec opt_with AlterOptRoleList { AlterRoleStmt *n = makeNode(AlterRoleStmt); n->role = $3; @@ -1053,7 +1055,7 @@ opt_in_database: ; AlterRoleSetStmt: - ALTER ROLE RoleId opt_in_database SetResetClause + ALTER ROLE RoleSpec opt_in_database SetResetClause { AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); n->role = $3; @@ -1079,7 +1081,7 @@ AlterRoleSetStmt: *****************************************************************************/ AlterUserStmt: - ALTER USER RoleId opt_with AlterOptRoleList + ALTER USER RoleSpec opt_with AlterOptRoleList { AlterRoleStmt *n = makeNode(AlterRoleStmt); n->role = $3; @@ -1091,7 +1093,7 @@ AlterUserStmt: AlterUserSetStmt: - ALTER USER RoleId SetResetClause + ALTER USER RoleSpec SetResetClause { AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); n->role = $3; @@ -1180,7 +1182,7 @@ CreateGroupStmt: *****************************************************************************/ AlterGroupStmt: - ALTER GROUP_P RoleId add_drop USER role_list + ALTER GROUP_P RoleSpec add_drop USER role_list { AlterRoleStmt *n = makeNode(AlterRoleStmt); n->role = $3; @@ -1228,15 +1230,12 @@ DropGroupStmt: *****************************************************************************/ CreateSchemaStmt: - CREATE SCHEMA OptSchemaName AUTHORIZATION RoleId OptSchemaEltList + CREATE SCHEMA OptSchemaName AUTHORIZATION RoleSpec OptSchemaEltList { CreateSchemaStmt *n = makeNode(CreateSchemaStmt); /* One can omit the schema name or the authorization id. */ - if ($3 != NULL) - n->schemaname = $3; - else - n->schemaname = $5; - n->authid = $5; + n->schemaname = $3; + n->authrole = $5; n->schemaElts = $6; n->if_not_exists = false; $$ = (Node *)n; @@ -1246,20 +1245,17 @@ CreateSchemaStmt: CreateSchemaStmt *n = makeNode(CreateSchemaStmt); /* ...but not both */ n->schemaname = $3; - n->authid = NULL; + n->authrole = NULL; n->schemaElts = $4; n->if_not_exists = false; $$ = (Node *)n; } - | CREATE SCHEMA IF_P NOT EXISTS OptSchemaName AUTHORIZATION RoleId OptSchemaEltList + | CREATE SCHEMA IF_P NOT EXISTS OptSchemaName AUTHORIZATION RoleSpec OptSchemaEltList { CreateSchemaStmt *n = makeNode(CreateSchemaStmt); - /* One can omit the schema name or the authorization id. */ - if ($6 != NULL) - n->schemaname = $6; - else - n->schemaname = $8; - n->authid = $8; + /* schema name can be omitted here, too */ + n->schemaname = $6; + n->authrole = $8; if ($9 != NIL) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -1272,9 +1268,9 @@ CreateSchemaStmt: | CREATE SCHEMA IF_P NOT EXISTS ColId OptSchemaEltList { CreateSchemaStmt *n = makeNode(CreateSchemaStmt); - /* ...but not both */ + /* ...but not here */ n->schemaname = $6; - n->authid = NULL; + n->authrole = NULL; if ($7 != NIL) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -2259,12 +2255,12 @@ alter_table_cmd: n->subtype = AT_DropOf; $$ = (Node *)n; } - /* ALTER TABLE <name> OWNER TO RoleId */ - | OWNER TO RoleId + /* ALTER TABLE <name> OWNER TO RoleSpec */ + | OWNER TO RoleSpec { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_ChangeOwner; - n->name = $3; + n->newowner = $3; $$ = (Node *)n; } /* ALTER TABLE <name> SET TABLESPACE <tablespacename> */ @@ -3756,7 +3752,7 @@ CreateTableSpaceStmt: CREATE TABLESPACE name OptTableSpaceOwner LOCATION Sconst } ; -OptTableSpaceOwner: OWNER name { $$ = $2; } +OptTableSpaceOwner: OWNER RoleSpec { $$ = $2; } | /*EMPTY */ { $$ = NULL; } ; @@ -4478,7 +4474,7 @@ import_qualification: CreateUserMappingStmt: CREATE USER MAPPING FOR auth_ident SERVER name create_generic_options { CreateUserMappingStmt *n = makeNode(CreateUserMappingStmt); - n->username = $5; + n->user = $5; n->servername = $7; n->options = $8; $$ = (Node *) n; @@ -4486,10 +4482,8 @@ CreateUserMappingStmt: CREATE USER MAPPING FOR auth_ident SERVER name create_gen ; /* User mapping authorization identifier */ -auth_ident: - CURRENT_USER { $$ = "current_user"; } - | USER { $$ = "current_user"; } - | RoleId { $$ = (strcmp($1, "public") == 0) ? NULL : $1; } +auth_ident: RoleSpec { $$ = $1; } + | USER { $$ = makeRoleSpec(ROLESPEC_CURRENT_USER, @1); } ; /***************************************************************************** @@ -4502,7 +4496,7 @@ auth_ident: DropUserMappingStmt: DROP USER MAPPING FOR auth_ident SERVER name { DropUserMappingStmt *n = makeNode(DropUserMappingStmt); - n->username = $5; + n->user = $5; n->servername = $7; n->missing_ok = false; $$ = (Node *) n; @@ -4510,7 +4504,7 @@ DropUserMappingStmt: DROP USER MAPPING FOR auth_ident SERVER name | DROP USER MAPPING IF_P EXISTS FOR auth_ident SERVER name { DropUserMappingStmt *n = makeNode(DropUserMappingStmt); - n->username = $7; + n->user = $7; n->servername = $9; n->missing_ok = true; $$ = (Node *) n; @@ -4527,7 +4521,7 @@ DropUserMappingStmt: DROP USER MAPPING FOR auth_ident SERVER name AlterUserMappingStmt: ALTER USER MAPPING FOR auth_ident SERVER name alter_generic_options { AlterUserMappingStmt *n = makeNode(AlterUserMappingStmt); - n->username = $5; + n->user = $5; n->servername = $7; n->options = $8; $$ = (Node *) n; @@ -4612,7 +4606,7 @@ RowSecurityOptionalWithCheck: RowSecurityDefaultToRole: TO role_list { $$ = $2; } - | /* EMPTY */ { $$ = list_make1(makeString("public")); } + | /* EMPTY */ { $$ = list_make1(makeRoleSpec(ROLESPEC_PUBLIC, -1)); } ; RowSecurityOptionalToRole: @@ -5432,7 +5426,7 @@ DropOwnedStmt: ; ReassignOwnedStmt: - REASSIGN OWNED BY role_list TO name + REASSIGN OWNED BY role_list TO RoleSpec { ReassignOwnedStmt *n = makeNode(ReassignOwnedStmt); n->roles = $4; @@ -6348,26 +6342,9 @@ grantee_list: | grantee_list ',' grantee { $$ = lappend($1, $3); } ; -grantee: RoleId - { - PrivGrantee *n = makeNode(PrivGrantee); - /* This hack lets us avoid reserving PUBLIC as a keyword*/ - if (strcmp($1, "public") == 0) - n->rolname = NULL; - else - n->rolname = $1; - $$ = (Node *)n; - } - | GROUP_P RoleId - { - PrivGrantee *n = makeNode(PrivGrantee); - /* Treat GROUP PUBLIC as a synonym for PUBLIC */ - if (strcmp($2, "public") == 0) - n->rolname = NULL; - else - n->rolname = $2; - $$ = (Node *)n; - } +grantee: + RoleSpec { $$ = $1; } + | GROUP_P RoleSpec { $$ = $2; } ; @@ -6438,7 +6415,7 @@ opt_grant_admin_option: WITH ADMIN OPTION { $$ = TRUE; } | /*EMPTY*/ { $$ = FALSE; } ; -opt_granted_by: GRANTED BY RoleId { $$ = $3; } +opt_granted_by: GRANTED BY RoleSpec { $$ = $3; } | /*EMPTY*/ { $$ = NULL; } ; @@ -8104,7 +8081,7 @@ AlterObjectSchemaStmt: * *****************************************************************************/ -AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId +AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_AGGREGATE; @@ -8113,7 +8090,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId n->newowner = $7; $$ = (Node *)n; } - | ALTER COLLATION any_name OWNER TO RoleId + | ALTER COLLATION any_name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_COLLATION; @@ -8121,7 +8098,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId n->newowner = $6; $$ = (Node *)n; } - | ALTER CONVERSION_P any_name OWNER TO RoleId + | ALTER CONVERSION_P any_name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_CONVERSION; @@ -8129,7 +8106,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId n->newowner = $6; $$ = (Node *)n; } - | ALTER DATABASE database_name OWNER TO RoleId + | ALTER DATABASE database_name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_DATABASE; @@ -8137,7 +8114,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId n->newowner = $6; $$ = (Node *)n; } - | ALTER DOMAIN_P any_name OWNER TO RoleId + | ALTER DOMAIN_P any_name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_DOMAIN; @@ -8145,7 +8122,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId n->newowner = $6; $$ = (Node *)n; } - | ALTER FUNCTION function_with_argtypes OWNER TO RoleId + | ALTER FUNCTION function_with_argtypes OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_FUNCTION; @@ -8154,7 +8131,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId n->newowner = $6; $$ = (Node *)n; } - | ALTER opt_procedural LANGUAGE name OWNER TO RoleId + | ALTER opt_procedural LANGUAGE name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_LANGUAGE; @@ -8162,7 +8139,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId n->newowner = $7; $$ = (Node *)n; } - | ALTER LARGE_P OBJECT_P NumericOnly OWNER TO RoleId + | ALTER LARGE_P OBJECT_P NumericOnly OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_LARGEOBJECT; @@ -8170,7 +8147,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId n->newowner = $7; $$ = (Node *)n; } - | ALTER OPERATOR any_operator oper_argtypes OWNER TO RoleId + | ALTER OPERATOR any_operator oper_argtypes OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_OPERATOR; @@ -8179,7 +8156,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId n->newowner = $7; $$ = (Node *)n; } - | ALTER OPERATOR CLASS any_name USING access_method OWNER TO RoleId + | ALTER OPERATOR CLASS any_name USING access_method OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_OPCLASS; @@ -8188,7 +8165,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId n->newowner = $9; $$ = (Node *)n; } - | ALTER OPERATOR FAMILY any_name USING access_method OWNER TO RoleId + | ALTER OPERATOR FAMILY any_name USING access_method OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_OPFAMILY; @@ -8197,7 +8174,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId n->newowner = $9; $$ = (Node *)n; } - | ALTER SCHEMA name OWNER TO RoleId + | ALTER SCHEMA name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_SCHEMA; @@ -8205,7 +8182,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId n->newowner = $6; $$ = (Node *)n; } - | ALTER TYPE_P any_name OWNER TO RoleId + | ALTER TYPE_P any_name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_TYPE; @@ -8213,7 +8190,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId n->newowner = $6; $$ = (Node *)n; } - | ALTER TABLESPACE name OWNER TO RoleId + | ALTER TABLESPACE name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_TABLESPACE; @@ -8221,7 +8198,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId n->newowner = $6; $$ = (Node *)n; } - | ALTER TEXT_P SEARCH DICTIONARY any_name OWNER TO RoleId + | ALTER TEXT_P SEARCH DICTIONARY any_name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_TSDICTIONARY; @@ -8229,7 +8206,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId n->newowner = $8; $$ = (Node *)n; } - | ALTER TEXT_P SEARCH CONFIGURATION any_name OWNER TO RoleId + | ALTER TEXT_P SEARCH CONFIGURATION any_name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_TSCONFIGURATION; @@ -8237,7 +8214,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId n->newowner = $8; $$ = (Node *)n; } - | ALTER FOREIGN DATA_P WRAPPER name OWNER TO RoleId + | ALTER FOREIGN DATA_P WRAPPER name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_FDW; @@ -8245,7 +8222,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId n->newowner = $8; $$ = (Node *)n; } - | ALTER SERVER name OWNER TO RoleId + | ALTER SERVER name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_FOREIGN_SERVER; @@ -8253,7 +8230,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId n->newowner = $6; $$ = (Node *)n; } - | ALTER EVENT TRIGGER name OWNER TO RoleId + | ALTER EVENT TRIGGER name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_EVENT_TRIGGER; @@ -13113,19 +13090,86 @@ AexprConst: Iconst Iconst: ICONST { $$ = $1; }; Sconst: SCONST { $$ = $1; }; -RoleId: NonReservedWord { $$ = $1; }; - -role_list: RoleId - { $$ = list_make1(makeString($1)); } - | role_list ',' RoleId - { $$ = lappend($1, makeString($3)); } - ; SignedIconst: Iconst { $$ = $1; } | '+' Iconst { $$ = + $2; } | '-' Iconst { $$ = - $2; } ; +/* Role specifications */ +RoleId: RoleSpec + { + RoleSpec *spc = (RoleSpec *) $1; + switch (spc->roletype) + { + case ROLESPEC_CSTRING: + $$ = spc->rolename; + break; + case ROLESPEC_PUBLIC: + ereport(ERROR, + (errcode(ERRCODE_RESERVED_NAME), + errmsg("role name \"%s\" is reserved", + "public"), + parser_errposition(@1))); + case ROLESPEC_SESSION_USER: + ereport(ERROR, + (errcode(ERRCODE_RESERVED_NAME), + errmsg("%s cannot be used as a role name", + "SESSION_USER"), + parser_errposition(@1))); + case ROLESPEC_CURRENT_USER: + ereport(ERROR, + (errcode(ERRCODE_RESERVED_NAME), + errmsg("%s cannot be used as a role name", + "CURRENT_USER"), + parser_errposition(@1))); + } + } + ; + +RoleSpec: NonReservedWord + { + /* + * "public" and "none" are not keywords, but they must + * be treated specially here. + */ + RoleSpec *n; + if (strcmp($1, "public") == 0) + { + n = (RoleSpec *) makeRoleSpec(ROLESPEC_PUBLIC, @1); + n->roletype = ROLESPEC_PUBLIC; + } + else if (strcmp($1, "none") == 0) + { + ereport(ERROR, + (errcode(ERRCODE_RESERVED_NAME), + errmsg("role name \"%s\" is reserved", + "none"), + parser_errposition(@1))); + } + else + { + n = (RoleSpec *) makeRoleSpec(ROLESPEC_CSTRING, @1); + n->rolename = pstrdup($1); + } + $$ = (Node *) n; + } + | CURRENT_USER + { + $$ = makeRoleSpec(ROLESPEC_CURRENT_USER, @1); + } + | SESSION_USER + { + $$ = makeRoleSpec(ROLESPEC_SESSION_USER, @1); + } + ; + +role_list: RoleSpec + { $$ = list_make1($1); } + | role_list ',' RoleSpec + { $$ = lappend($1, $3); } + ; + /* * Name classification hierarchy. * @@ -13812,6 +13856,20 @@ makeBoolAConst(bool state, int location) return makeTypeCast((Node *)n, SystemTypeName("bool"), -1); } +/* makeRoleSpec + * Create a RoleSpec with the given type + */ +static Node * +makeRoleSpec(RoleSpecType type, int location) +{ + RoleSpec *spec = makeNode(RoleSpec); + + spec->roletype = type; + spec->location = location; + + return (Node *) spec; +} + /* check_qualified_name --- check the result of qualified_name production * * It's easiest to let the grammar production for qualified_name allow diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index c29f1065294a42c4b3d38fcc4c0bce6d3baa4681..1e6da9cc40e397bed92a888a91c32b99b2fed003 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -90,7 +90,7 @@ typedef struct { const char *stmtType; /* "CREATE SCHEMA" or "ALTER SCHEMA" */ char *schemaname; /* name of schema */ - char *authid; /* owner of schema */ + RoleSpec *authrole; /* owner of schema */ List *sequences; /* CREATE SEQUENCE items */ List *tables; /* CREATE TABLE items */ List *views; /* CREATE VIEW items */ @@ -2723,7 +2723,7 @@ transformCreateSchemaStmt(CreateSchemaStmt *stmt) cxt.stmtType = "CREATE SCHEMA"; cxt.schemaname = stmt->schemaname; - cxt.authid = stmt->authid; + cxt.authrole = (RoleSpec *) stmt->authrole; cxt.sequences = NIL; cxt.tables = NIL; cxt.views = NIL; diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index 411d779be6bee24c6358d98675787f037800f6ac..7701fc5ac07f4357ada4858be06e6d6b1eafc225 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -5105,7 +5105,7 @@ select_best_grantor(Oid roleId, AclMode privileges, /* * get_role_oid - Given a role name, look up the role's OID. * - * If missing_ok is false, throw an error if tablespace name not found. If + * If missing_ok is false, throw an error if role name not found. If * true, just return InvalidOid. */ Oid @@ -5133,3 +5133,117 @@ get_role_oid_or_public(const char *rolname) return get_role_oid(rolname, false); } + +/* + * Given a RoleSpec node, return the OID it corresponds to. If missing_ok is + * true, return InvalidOid if the role does not exist. + * + * PUBLIC is always disallowed here. Routines wanting to handle the PUBLIC + * case must check the case separately. + */ +Oid +get_rolespec_oid(const Node *node, bool missing_ok) +{ + RoleSpec *role; + Oid oid; + + if (!IsA(node, RoleSpec)) + elog(ERROR, "invalid node type %d", node->type); + + role = (RoleSpec *) node; + switch (role->roletype) + { + case ROLESPEC_CSTRING: + Assert(role->rolename); + oid = get_role_oid(role->rolename, missing_ok); + break; + + case ROLESPEC_CURRENT_USER: + oid = GetUserId(); + break; + + case ROLESPEC_SESSION_USER: + oid = GetSessionUserId(); + break; + + case ROLESPEC_PUBLIC: + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("role \"%s\" does not exist", "public"))); + oid = InvalidOid; /* make compiler happy */ + break; + + default: + elog(ERROR, "unexpected role type %d", role->roletype); + } + + return oid; +} + +/* + * Given a RoleSpec node, return the pg_authid HeapTuple it corresponds to. + * Caller must ReleaseSysCache when done with the result tuple. + */ +HeapTuple +get_rolespec_tuple(const Node *node) +{ + RoleSpec *role; + HeapTuple tuple; + + role = (RoleSpec *) node; + if (!IsA(node, RoleSpec)) + elog(ERROR, "invalid node type %d", node->type); + + switch (role->roletype) + { + case ROLESPEC_CSTRING: + Assert(role->rolename); + tuple = SearchSysCache1(AUTHNAME, CStringGetDatum(role->rolename)); + if (!HeapTupleIsValid(tuple)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("role \"%s\" does not exist", role->rolename))); + break; + + case ROLESPEC_CURRENT_USER: + tuple = SearchSysCache1(AUTHOID, GetUserId()); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for role %u", GetUserId()); + break; + + case ROLESPEC_SESSION_USER: + tuple = SearchSysCache1(AUTHOID, GetSessionUserId()); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for role %u", GetSessionUserId()); + break; + + case ROLESPEC_PUBLIC: + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("role \"%s\" does not exist", "public"))); + tuple = NULL; /* make compiler happy */ + + default: + elog(ERROR, "unexpected role type %d", role->roletype); + } + + return tuple; +} + +/* + * Given a RoleSpec, returns a palloc'ed copy of the corresponding role's name. + */ +char * +get_rolespec_name(const Node *node) +{ + HeapTuple tp; + Form_pg_authid authForm; + char *rolename; + + tp = get_rolespec_tuple(node); + authForm = (Form_pg_authid) GETSTRUCT(tp); + rolename = pstrdup(NameStr(authForm->rolname)); + ReleaseSysCache(tp); + + return rolename; +} diff --git a/src/include/commands/user.h b/src/include/commands/user.h index ccadb04b8c7688f944706babf2b62991678e4cfc..d35cb0c90deff570fc15da57c1ed6f43728deb2b 100644 --- a/src/include/commands/user.h +++ b/src/include/commands/user.h @@ -31,6 +31,6 @@ extern void GrantRole(GrantRoleStmt *stmt); extern ObjectAddress RenameRole(const char *oldname, const char *newname); extern void DropOwnedObjects(DropOwnedStmt *stmt); extern void ReassignOwnedObjects(ReassignOwnedStmt *stmt); -extern List *roleNamesToIds(List *memberNames); +extern List *roleSpecsToIds(List *memberNames); #endif /* USER_H */ diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 97ef0fcf7d177cb53738505947a2b3d6ee5cd296..38469ef4d1af4abba24935d91e76f1eb30ed25cf 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -413,6 +413,7 @@ typedef enum NodeTag T_XmlSerialize, T_WithClause, T_CommonTableExpr, + T_RoleSpec, /* * TAGS FOR REPLICATION GRAMMAR PARSE NODES (replnodes.h) diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index ac133023b4f6b750ad43b444bbd9536058f1ed9d..497559df5887982b12386d37881ed3b6045e0bff 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -284,6 +284,25 @@ typedef struct CollateClause int location; /* token location, or -1 if unknown */ } CollateClause; +/* + * RoleSpec - a role name or one of a few special values. + */ +typedef enum RoleSpecType +{ + ROLESPEC_CSTRING, /* role name is stored as a C string */ + ROLESPEC_CURRENT_USER, /* role spec is CURRENT_USER */ + ROLESPEC_SESSION_USER, /* role spec is SESSION_USER */ + ROLESPEC_PUBLIC /* role name is "public" */ +} RoleSpecType; + +typedef struct RoleSpec +{ + NodeTag type; + RoleSpecType roletype; /* Type of this rolespec */ + char *rolename; /* filled only for ROLESPEC_CSTRING */ + int location; /* token location, or -1 if unknown */ +} RoleSpec; + /* * FuncCall - a function or aggregate invocation * @@ -1263,7 +1282,7 @@ typedef struct CreateSchemaStmt { NodeTag type; char *schemaname; /* the name of the schema to create */ - char *authid; /* the owner of the created schema */ + Node *authrole; /* the owner of the created schema */ List *schemaElts; /* schema components (list of parsenodes) */ bool if_not_exists; /* just do nothing if schema already exists? */ } CreateSchemaStmt; @@ -1362,7 +1381,8 @@ typedef struct AlterTableCmd /* one subcommand of an ALTER TABLE */ NodeTag type; AlterTableType subtype; /* Type of table alteration to apply */ char *name; /* column, constraint, or trigger to act on, - * or new owner or tablespace */ + * or tablespace */ + Node *newowner; /* RoleSpec */ Node *def; /* definition of new column, index, * constraint, or parent table */ DropBehavior behavior; /* RESTRICT or CASCADE for DROP cases */ @@ -1434,17 +1454,11 @@ typedef struct GrantStmt * or plain names (as Value strings) */ List *privileges; /* list of AccessPriv nodes */ /* privileges == NIL denotes ALL PRIVILEGES */ - List *grantees; /* list of PrivGrantee nodes */ + List *grantees; /* list of RoleSpec nodes */ bool grant_option; /* grant or revoke grant option */ DropBehavior behavior; /* drop behavior (for REVOKE) */ } GrantStmt; -typedef struct PrivGrantee -{ - NodeTag type; - char *rolname; /* if NULL then PUBLIC */ -} PrivGrantee; - /* * Note: FuncWithArgs carries only the types of the input parameters of the * function. So it is sufficient to identify an existing function, but it @@ -1487,7 +1501,7 @@ typedef struct GrantRoleStmt List *grantee_roles; /* list of member roles to add/delete */ bool is_grant; /* true = GRANT, false = REVOKE */ bool admin_opt; /* with admin option */ - char *grantor; /* set grantor to other than current role */ + Node *grantor; /* set grantor to other than current role */ DropBehavior behavior; /* drop behavior (for REVOKE) */ } GrantRoleStmt; @@ -1699,7 +1713,7 @@ typedef struct CreateTableSpaceStmt { NodeTag type; char *tablespacename; - char *owner; + Node *owner; char *location; List *options; } CreateTableSpaceStmt; @@ -1825,7 +1839,7 @@ typedef struct CreateForeignTableStmt typedef struct CreateUserMappingStmt { NodeTag type; - char *username; /* username or PUBLIC/CURRENT_USER */ + Node *user; /* user role */ char *servername; /* server name */ List *options; /* generic options to server */ } CreateUserMappingStmt; @@ -1833,7 +1847,7 @@ typedef struct CreateUserMappingStmt typedef struct AlterUserMappingStmt { NodeTag type; - char *username; /* username or PUBLIC/CURRENT_USER */ + Node *user; /* user role */ char *servername; /* server name */ List *options; /* generic options to server */ } AlterUserMappingStmt; @@ -1841,7 +1855,7 @@ typedef struct AlterUserMappingStmt typedef struct DropUserMappingStmt { NodeTag type; - char *username; /* username or PUBLIC/CURRENT_USER */ + Node *user; /* user role */ char *servername; /* server name */ bool missing_ok; /* ignore missing mappings */ } DropUserMappingStmt; @@ -1991,7 +2005,7 @@ typedef struct CreateRoleStmt typedef struct AlterRoleStmt { NodeTag type; - char *role; /* role name */ + Node *role; /* role */ List *options; /* List of DefElem nodes */ int action; /* +1 = add members, -1 = drop members */ } AlterRoleStmt; @@ -1999,7 +2013,7 @@ typedef struct AlterRoleStmt typedef struct AlterRoleSetStmt { NodeTag type; - char *role; /* role name */ + Node *role; /* role */ char *database; /* database name, or NULL */ VariableSetStmt *setstmt; /* SET or RESET subcommand */ } AlterRoleSetStmt; @@ -2375,7 +2389,7 @@ typedef struct AlterOwnerStmt RangeVar *relation; /* in case it's a table */ List *object; /* in case it's some other object */ List *objarg; /* argument types, if applicable */ - char *newowner; /* the new owner */ + Node *newowner; /* the new owner */ } AlterOwnerStmt; @@ -2831,7 +2845,7 @@ typedef struct ReassignOwnedStmt { NodeTag type; List *roles; - char *newrole; + Node *newrole; } ReassignOwnedStmt; /* diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h index ab0df6c7d8a741d0fca8d516d20ad058c1c0183f..d747579e7a00f227a86a5d68a3d631ff1c39556d 100644 --- a/src/include/utils/acl.h +++ b/src/include/utils/acl.h @@ -24,6 +24,7 @@ #ifndef ACL_H #define ACL_H +#include "access/htup.h" #include "nodes/parsenodes.h" #include "utils/array.h" #include "utils/snapshot.h" @@ -227,8 +228,11 @@ extern bool is_member_of_role(Oid member, Oid role); extern bool is_member_of_role_nosuper(Oid member, Oid role); extern bool is_admin_of_role(Oid member, Oid role); extern void check_is_member_of_role(Oid member, Oid role); -extern Oid get_role_oid(const char *rolname, bool missing_ok); -extern Oid get_role_oid_or_public(const char *rolname); +extern Oid get_role_oid(const char *rolename, bool missing_ok); +extern Oid get_role_oid_or_public(const char *rolename); +extern Oid get_rolespec_oid(const Node *node, bool missing_ok); +extern HeapTuple get_rolespec_tuple(const Node *node); +extern char *get_rolespec_name(const Node *node); extern void select_best_grantor(Oid roleId, AclMode privileges, const Acl *acl, Oid ownerId, diff --git a/src/test/regress/expected/rolenames.out b/src/test/regress/expected/rolenames.out new file mode 100644 index 0000000000000000000000000000000000000000..1879337ea0de36bddabb458d5810de153cffa711 --- /dev/null +++ b/src/test/regress/expected/rolenames.out @@ -0,0 +1,940 @@ +CREATE OR REPLACE FUNCTION chkrolattr() + RETURNS TABLE ("role" name, rolekeyword text, canlogin bool, replication bool) + AS $$ +SELECT r.rolname, v.keyword, r.rolcanlogin, r.rolreplication + FROM pg_roles r + JOIN (VALUES(CURRENT_USER, 'current_user'), + (SESSION_USER, 'session_user'), + ('current_user', '-'), + ('session_user', '-'), + ('Public', '-'), + ('None', '-')) + AS v(uname, keyword) + ON (r.rolname = v.uname) + ORDER BY 1; +$$ LANGUAGE SQL; +CREATE OR REPLACE FUNCTION chksetconfig() + RETURNS TABLE (db name, "role" name, rolkeyword text, setconfig text[]) + AS $$ +SELECT COALESCE(d.datname, 'ALL'), COALESCE(r.rolname, 'ALL'), + COALESCE(v.keyword, '-'), s.setconfig + FROM pg_db_role_setting s + LEFT JOIN pg_roles r ON (r.oid = s.setrole) + LEFT JOIN pg_database d ON (d.oid = s.setdatabase) + LEFT JOIN (VALUES(CURRENT_USER, 'current_user'), + (SESSION_USER, 'session_user')) + AS v(uname, keyword) + ON (r.rolname = v.uname) + WHERE (r.rolname) IN ('Public', 'current_user', 'testrol1', 'testrol2') +ORDER BY 1, 2; +$$ LANGUAGE SQL; +CREATE OR REPLACE FUNCTION chkumapping() + RETURNS TABLE (umname name, umserver name, umoptions text[]) + AS $$ +SELECT r.rolname, s.srvname, m.umoptions + FROM pg_user_mapping m + LEFT JOIN pg_roles r ON (r.oid = m.umuser) + JOIN pg_foreign_server s ON (s.oid = m.umserver) + ORDER BY 2; +$$ LANGUAGE SQL; +CREATE ROLE "Public"; +CREATE ROLE "None"; +CREATE ROLE "current_user"; +CREATE ROLE "session_user"; +CREATE ROLE "user"; +CREATE ROLE current_user; -- error +ERROR: CURRENT_USER cannot be used as a role name +LINE 1: CREATE ROLE current_user; + ^ +CREATE ROLE current_role; -- error +ERROR: syntax error at or near "current_role" +LINE 1: CREATE ROLE current_role; + ^ +CREATE ROLE session_user; -- error +ERROR: SESSION_USER cannot be used as a role name +LINE 1: CREATE ROLE session_user; + ^ +CREATE ROLE user; -- error +ERROR: syntax error at or near "user" +LINE 1: CREATE ROLE user; + ^ +CREATE ROLE all; -- error +ERROR: syntax error at or near "all" +LINE 1: CREATE ROLE all; + ^ +CREATE ROLE public; -- error +ERROR: role name "public" is reserved +LINE 1: CREATE ROLE public; + ^ +CREATE ROLE "public"; -- error +ERROR: role name "public" is reserved +LINE 1: CREATE ROLE "public"; + ^ +CREATE ROLE none; -- error +ERROR: role name "none" is reserved +LINE 1: CREATE ROLE none; + ^ +CREATE ROLE "none"; -- error +ERROR: role name "none" is reserved +LINE 1: CREATE ROLE "none"; + ^ +CREATE ROLE testrol0 SUPERUSER LOGIN; +CREATE ROLE testrolx SUPERUSER LOGIN; +CREATE ROLE testrol2 SUPERUSER; +CREATE ROLE testrol1 SUPERUSER LOGIN IN ROLE testrol2; +\c - +SET SESSION AUTHORIZATION testrol1; +SET ROLE testrol2; +-- ALTER ROLE +BEGIN; +SELECT * FROM chkrolattr(); + role | rolekeyword | canlogin | replication +--------------+--------------+----------+------------- + None | - | f | f + Public | - | f | f + current_user | - | f | f + session_user | - | f | f + testrol1 | session_user | t | f + testrol2 | current_user | f | f +(6 rows) + +ALTER ROLE CURRENT_USER WITH REPLICATION; +SELECT * FROM chkrolattr(); + role | rolekeyword | canlogin | replication +--------------+--------------+----------+------------- + None | - | f | f + Public | - | f | f + current_user | - | f | f + session_user | - | f | f + testrol1 | session_user | t | f + testrol2 | current_user | f | t +(6 rows) + +ALTER ROLE "current_user" WITH REPLICATION; +SELECT * FROM chkrolattr(); + role | rolekeyword | canlogin | replication +--------------+--------------+----------+------------- + None | - | f | f + Public | - | f | f + current_user | - | f | t + session_user | - | f | f + testrol1 | session_user | t | f + testrol2 | current_user | f | t +(6 rows) + +ALTER ROLE SESSION_USER WITH REPLICATION; +SELECT * FROM chkrolattr(); + role | rolekeyword | canlogin | replication +--------------+--------------+----------+------------- + None | - | f | f + Public | - | f | f + current_user | - | f | t + session_user | - | f | f + testrol1 | session_user | t | t + testrol2 | current_user | f | t +(6 rows) + +ALTER ROLE "session_user" WITH REPLICATION; +SELECT * FROM chkrolattr(); + role | rolekeyword | canlogin | replication +--------------+--------------+----------+------------- + None | - | f | f + Public | - | f | f + current_user | - | f | t + session_user | - | f | t + testrol1 | session_user | t | t + testrol2 | current_user | f | t +(6 rows) + +ALTER USER "Public" WITH REPLICATION; +ALTER USER "None" WITH REPLICATION; +SELECT * FROM chkrolattr(); + role | rolekeyword | canlogin | replication +--------------+--------------+----------+------------- + None | - | f | t + Public | - | f | t + current_user | - | f | t + session_user | - | f | t + testrol1 | session_user | t | t + testrol2 | current_user | f | t +(6 rows) + +ALTER USER testrol1 WITH NOREPLICATION; +ALTER USER testrol2 WITH NOREPLICATION; +SELECT * FROM chkrolattr(); + role | rolekeyword | canlogin | replication +--------------+--------------+----------+------------- + None | - | f | t + Public | - | f | t + current_user | - | f | t + session_user | - | f | t + testrol1 | session_user | t | f + testrol2 | current_user | f | f +(6 rows) + +ROLLBACK; +ALTER ROLE USER WITH LOGIN; -- error +ERROR: syntax error at or near "USER" +LINE 1: ALTER ROLE USER WITH LOGIN; + ^ +ALTER ROLE CURRENT_ROLE WITH LOGIN; --error +ERROR: syntax error at or near "CURRENT_ROLE" +LINE 1: ALTER ROLE CURRENT_ROLE WITH LOGIN; + ^ +ALTER ROLE ALL WITH REPLICATION; -- error +ERROR: syntax error at or near "WITH" +LINE 1: ALTER ROLE ALL WITH REPLICATION; + ^ +ALTER ROLE SESSION_ROLE WITH NOREPLICATION; -- error +ERROR: role "session_role" does not exist +ALTER ROLE PUBLIC WITH NOREPLICATION; -- error +ERROR: role "public" does not exist +ALTER ROLE "public" WITH NOREPLICATION; -- error +ERROR: role "public" does not exist +ALTER ROLE NONE WITH NOREPLICATION; -- error +ERROR: role name "none" is reserved +LINE 1: ALTER ROLE NONE WITH NOREPLICATION; + ^ +ALTER ROLE "none" WITH NOREPLICATION; -- error +ERROR: role name "none" is reserved +LINE 1: ALTER ROLE "none" WITH NOREPLICATION; + ^ +ALTER ROLE nonexistent WITH NOREPLICATION; -- error +ERROR: role "nonexistent" does not exist +-- ALTER USER +BEGIN; +SELECT * FROM chkrolattr(); + role | rolekeyword | canlogin | replication +--------------+--------------+----------+------------- + None | - | f | f + Public | - | f | f + current_user | - | f | f + session_user | - | f | f + testrol1 | session_user | t | f + testrol2 | current_user | f | f +(6 rows) + +ALTER USER CURRENT_USER WITH REPLICATION; +SELECT * FROM chkrolattr(); + role | rolekeyword | canlogin | replication +--------------+--------------+----------+------------- + None | - | f | f + Public | - | f | f + current_user | - | f | f + session_user | - | f | f + testrol1 | session_user | t | f + testrol2 | current_user | f | t +(6 rows) + +ALTER USER "current_user" WITH REPLICATION; +SELECT * FROM chkrolattr(); + role | rolekeyword | canlogin | replication +--------------+--------------+----------+------------- + None | - | f | f + Public | - | f | f + current_user | - | f | t + session_user | - | f | f + testrol1 | session_user | t | f + testrol2 | current_user | f | t +(6 rows) + +ALTER USER SESSION_USER WITH REPLICATION; +SELECT * FROM chkrolattr(); + role | rolekeyword | canlogin | replication +--------------+--------------+----------+------------- + None | - | f | f + Public | - | f | f + current_user | - | f | t + session_user | - | f | f + testrol1 | session_user | t | t + testrol2 | current_user | f | t +(6 rows) + +ALTER USER "session_user" WITH REPLICATION; +SELECT * FROM chkrolattr(); + role | rolekeyword | canlogin | replication +--------------+--------------+----------+------------- + None | - | f | f + Public | - | f | f + current_user | - | f | t + session_user | - | f | t + testrol1 | session_user | t | t + testrol2 | current_user | f | t +(6 rows) + +ALTER USER "Public" WITH REPLICATION; +ALTER USER "None" WITH REPLICATION; +SELECT * FROM chkrolattr(); + role | rolekeyword | canlogin | replication +--------------+--------------+----------+------------- + None | - | f | t + Public | - | f | t + current_user | - | f | t + session_user | - | f | t + testrol1 | session_user | t | t + testrol2 | current_user | f | t +(6 rows) + +ALTER USER testrol1 WITH NOREPLICATION; +ALTER USER testrol2 WITH NOREPLICATION; +SELECT * FROM chkrolattr(); + role | rolekeyword | canlogin | replication +--------------+--------------+----------+------------- + None | - | f | t + Public | - | f | t + current_user | - | f | t + session_user | - | f | t + testrol1 | session_user | t | f + testrol2 | current_user | f | f +(6 rows) + +ROLLBACK; +ALTER USER USER WITH LOGIN; -- error +ERROR: syntax error at or near "USER" +LINE 1: ALTER USER USER WITH LOGIN; + ^ +ALTER USER CURRENT_ROLE WITH LOGIN; -- error +ERROR: syntax error at or near "CURRENT_ROLE" +LINE 1: ALTER USER CURRENT_ROLE WITH LOGIN; + ^ +ALTER USER ALL WITH REPLICATION; -- error +ERROR: syntax error at or near "ALL" +LINE 1: ALTER USER ALL WITH REPLICATION; + ^ +ALTER USER SESSION_ROLE WITH NOREPLICATION; -- error +ERROR: role "session_role" does not exist +ALTER USER PUBLIC WITH NOREPLICATION; -- error +ERROR: role "public" does not exist +ALTER USER "public" WITH NOREPLICATION; -- error +ERROR: role "public" does not exist +ALTER USER NONE WITH NOREPLICATION; -- error +ERROR: role name "none" is reserved +LINE 1: ALTER USER NONE WITH NOREPLICATION; + ^ +ALTER USER "none" WITH NOREPLICATION; -- error +ERROR: role name "none" is reserved +LINE 1: ALTER USER "none" WITH NOREPLICATION; + ^ +ALTER USER nonexistent WITH NOREPLICATION; -- error +ERROR: role "nonexistent" does not exist +-- ALTER ROLE SET/RESET +SELECT * FROM chksetconfig(); + db | role | rolkeyword | setconfig +----+------+------------+----------- +(0 rows) + +ALTER ROLE CURRENT_USER SET application_name to 'FOO'; +ALTER ROLE SESSION_USER SET application_name to 'BAR'; +ALTER ROLE "current_user" SET application_name to 'FOOFOO'; +ALTER ROLE "Public" SET application_name to 'BARBAR'; +ALTER ROLE ALL SET application_name to 'SLAP'; +SELECT * FROM chksetconfig(); + db | role | rolkeyword | setconfig +-----+--------------+--------------+--------------------------- + ALL | Public | - | {application_name=BARBAR} + ALL | current_user | - | {application_name=FOOFOO} + ALL | testrol1 | session_user | {application_name=BAR} + ALL | testrol2 | current_user | {application_name=FOO} +(4 rows) + +ALTER ROLE testrol1 SET application_name to 'SLAM'; +SELECT * FROM chksetconfig(); + db | role | rolkeyword | setconfig +-----+--------------+--------------+--------------------------- + ALL | Public | - | {application_name=BARBAR} + ALL | current_user | - | {application_name=FOOFOO} + ALL | testrol1 | session_user | {application_name=SLAM} + ALL | testrol2 | current_user | {application_name=FOO} +(4 rows) + +ALTER ROLE CURRENT_USER RESET application_name; +ALTER ROLE SESSION_USER RESET application_name; +ALTER ROLE "current_user" RESET application_name; +ALTER ROLE "Public" RESET application_name; +ALTER ROLE ALL RESET application_name; +SELECT * FROM chksetconfig(); + db | role | rolkeyword | setconfig +----+------+------------+----------- +(0 rows) + +ALTER ROLE CURRENT_ROLE SET application_name to 'BAZ'; -- error +ERROR: syntax error at or near "CURRENT_ROLE" +LINE 1: ALTER ROLE CURRENT_ROLE SET application_name to 'BAZ'; + ^ +ALTER ROLE USER SET application_name to 'BOOM'; -- error +ERROR: syntax error at or near "USER" +LINE 1: ALTER ROLE USER SET application_name to 'BOOM'; + ^ +ALTER ROLE PUBLIC SET application_name to 'BOMB'; -- error +ERROR: role "public" does not exist +ALTER ROLE nonexistent SET application_name to 'BOMB'; -- error +ERROR: role "nonexistent" does not exist +-- ALTER USER SET/RESET +SELECT * FROM chksetconfig(); + db | role | rolkeyword | setconfig +----+------+------------+----------- +(0 rows) + +ALTER USER CURRENT_USER SET application_name to 'FOO'; +ALTER USER SESSION_USER SET application_name to 'BAR'; +ALTER USER "current_user" SET application_name to 'FOOFOO'; +ALTER USER "Public" SET application_name to 'BARBAR'; +ALTER USER ALL SET application_name to 'SLAP'; +ERROR: syntax error at or near "ALL" +LINE 1: ALTER USER ALL SET application_name to 'SLAP'; + ^ +SELECT * FROM chksetconfig(); + db | role | rolkeyword | setconfig +-----+--------------+--------------+--------------------------- + ALL | Public | - | {application_name=BARBAR} + ALL | current_user | - | {application_name=FOOFOO} + ALL | testrol1 | session_user | {application_name=BAR} + ALL | testrol2 | current_user | {application_name=FOO} +(4 rows) + +ALTER USER testrol1 SET application_name to 'SLAM'; +SELECT * FROM chksetconfig(); + db | role | rolkeyword | setconfig +-----+--------------+--------------+--------------------------- + ALL | Public | - | {application_name=BARBAR} + ALL | current_user | - | {application_name=FOOFOO} + ALL | testrol1 | session_user | {application_name=SLAM} + ALL | testrol2 | current_user | {application_name=FOO} +(4 rows) + +ALTER USER CURRENT_USER RESET application_name; +ALTER USER SESSION_USER RESET application_name; +ALTER USER "current_user" RESET application_name; +ALTER USER "Public" RESET application_name; +ALTER USER ALL RESET application_name; +ERROR: syntax error at or near "ALL" +LINE 1: ALTER USER ALL RESET application_name; + ^ +SELECT * FROM chksetconfig(); + db | role | rolkeyword | setconfig +----+------+------------+----------- +(0 rows) + +ALTER USER CURRENT_USER SET application_name to 'BAZ'; -- error +ALTER USER USER SET application_name to 'BOOM'; -- error +ERROR: syntax error at or near "USER" +LINE 1: ALTER USER USER SET application_name to 'BOOM'; + ^ +ALTER USER PUBLIC SET application_name to 'BOMB'; -- error +ERROR: role "public" does not exist +ALTER USER NONE SET application_name to 'BOMB'; -- error +ERROR: role name "none" is reserved +LINE 1: ALTER USER NONE SET application_name to 'BOMB'; + ^ +ALTER USER nonexistent SET application_name to 'BOMB'; -- error +ERROR: role "nonexistent" does not exist +-- CREAETE SCHEMA +set client_min_messages to error; +CREATE SCHEMA newschema1 AUTHORIZATION CURRENT_USER; +CREATE SCHEMA newschema2 AUTHORIZATION "current_user"; +CREATE SCHEMA newschema3 AUTHORIZATION SESSION_USER; +CREATE SCHEMA newschema4 AUTHORIZATION testrolx; +CREATE SCHEMA newschema5 AUTHORIZATION "Public"; +CREATE SCHEMA newschema6 AUTHORIZATION USER; -- error +ERROR: syntax error at or near "USER" +LINE 1: CREATE SCHEMA newschema6 AUTHORIZATION USER; + ^ +CREATE SCHEMA newschema6 AUTHORIZATION CURRENT_ROLE; -- error +ERROR: syntax error at or near "CURRENT_ROLE" +LINE 1: CREATE SCHEMA newschema6 AUTHORIZATION CURRENT_ROLE; + ^ +CREATE SCHEMA newschema6 AUTHORIZATION PUBLIC; -- error +ERROR: role "public" does not exist +CREATE SCHEMA newschema6 AUTHORIZATION "public"; -- error +ERROR: role "public" does not exist +CREATE SCHEMA newschema6 AUTHORIZATION NONE; -- error +ERROR: role name "none" is reserved +LINE 1: CREATE SCHEMA newschema6 AUTHORIZATION NONE; + ^ +CREATE SCHEMA newschema6 AUTHORIZATION nonexistent; -- error +ERROR: role "nonexistent" does not exist +SELECT n.nspname, r.rolname FROM pg_namespace n + JOIN pg_roles r ON (r.oid = n.nspowner) + WHERE n.nspname LIKE 'newschema_' ORDER BY 1; + nspname | rolname +------------+-------------- + newschema1 | testrol2 + newschema2 | current_user + newschema3 | testrol1 + newschema4 | testrolx + newschema5 | Public +(5 rows) + +CREATE SCHEMA IF NOT EXISTS newschema1 AUTHORIZATION CURRENT_USER; +CREATE SCHEMA IF NOT EXISTS newschema2 AUTHORIZATION "current_user"; +CREATE SCHEMA IF NOT EXISTS newschema3 AUTHORIZATION SESSION_USER; +CREATE SCHEMA IF NOT EXISTS newschema4 AUTHORIZATION testrolx; +CREATE SCHEMA IF NOT EXISTS newschema5 AUTHORIZATION "Public"; +CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION USER; -- error +ERROR: syntax error at or near "USER" +LINE 1: CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION USER; + ^ +CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION CURRENT_ROLE; -- error +ERROR: syntax error at or near "CURRENT_ROLE" +LINE 1: ...ATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION CURRENT_RO... + ^ +CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION PUBLIC; -- error +ERROR: role "public" does not exist +CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION "public"; -- error +ERROR: role "public" does not exist +CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION NONE; -- error +ERROR: role name "none" is reserved +LINE 1: CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION NONE; + ^ +CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION nonexistent; -- error +ERROR: role "nonexistent" does not exist +SELECT n.nspname, r.rolname FROM pg_namespace n + JOIN pg_roles r ON (r.oid = n.nspowner) + WHERE n.nspname LIKE 'newschema_' ORDER BY 1; + nspname | rolname +------------+-------------- + newschema1 | testrol2 + newschema2 | current_user + newschema3 | testrol1 + newschema4 | testrolx + newschema5 | Public +(5 rows) + +-- ALTER TABLE OWNER TO +\c - +SET SESSION AUTHORIZATION testrol0; +set client_min_messages to error; +CREATE TABLE testtab1 (a int); +CREATE TABLE testtab2 (a int); +CREATE TABLE testtab3 (a int); +CREATE TABLE testtab4 (a int); +CREATE TABLE testtab5 (a int); +CREATE TABLE testtab6 (a int); +\c - +SET SESSION AUTHORIZATION testrol1; +SET ROLE testrol2; +ALTER TABLE testtab1 OWNER TO CURRENT_USER; +ALTER TABLE testtab2 OWNER TO "current_user"; +ALTER TABLE testtab3 OWNER TO SESSION_USER; +ALTER TABLE testtab4 OWNER TO testrolx; +ALTER TABLE testtab5 OWNER TO "Public"; +ALTER TABLE testtab6 OWNER TO CURRENT_ROLE; -- error +ERROR: syntax error at or near "CURRENT_ROLE" +LINE 1: ALTER TABLE testtab6 OWNER TO CURRENT_ROLE; + ^ +ALTER TABLE testtab6 OWNER TO USER; --error +ERROR: syntax error at or near "USER" +LINE 1: ALTER TABLE testtab6 OWNER TO USER; + ^ +ALTER TABLE testtab6 OWNER TO PUBLIC; -- error +ERROR: role "public" does not exist +ALTER TABLE testtab6 OWNER TO "public"; -- error +ERROR: role "public" does not exist +ALTER TABLE testtab6 OWNER TO nonexistent; -- error +ERROR: role "nonexistent" does not exist +SELECT c.relname, r.rolname + FROM pg_class c JOIN pg_roles r ON (r.oid = c.relowner) + WHERE relname LIKE 'testtab_' + ORDER BY 1; + relname | rolname +----------+-------------- + testtab1 | testrol2 + testtab2 | current_user + testtab3 | testrol1 + testtab4 | testrolx + testtab5 | Public + testtab6 | testrol0 +(6 rows) + +-- ALTER TABLE, VIEW, MATERIALIZED VIEW, FOREIGN TABLE, SEQUENCE are +-- changed their owner in the same way. +-- ALTER AGGREGATE +\c - +SET SESSION AUTHORIZATION testrol0; +CREATE AGGREGATE testagg1(int2) (SFUNC = int2_sum, STYPE = int8); +CREATE AGGREGATE testagg2(int2) (SFUNC = int2_sum, STYPE = int8); +CREATE AGGREGATE testagg3(int2) (SFUNC = int2_sum, STYPE = int8); +CREATE AGGREGATE testagg4(int2) (SFUNC = int2_sum, STYPE = int8); +CREATE AGGREGATE testagg5(int2) (SFUNC = int2_sum, STYPE = int8); +CREATE AGGREGATE testagg5(int2) (SFUNC = int2_sum, STYPE = int8); +ERROR: function "testagg5" already exists with same argument types +CREATE AGGREGATE testagg6(int2) (SFUNC = int2_sum, STYPE = int8); +CREATE AGGREGATE testagg7(int2) (SFUNC = int2_sum, STYPE = int8); +CREATE AGGREGATE testagg8(int2) (SFUNC = int2_sum, STYPE = int8); +CREATE AGGREGATE testagg9(int2) (SFUNC = int2_sum, STYPE = int8); +\c - +SET SESSION AUTHORIZATION testrol1; +SET ROLE testrol2; +ALTER AGGREGATE testagg1(int2) OWNER TO CURRENT_USER; +ALTER AGGREGATE testagg2(int2) OWNER TO "current_user"; +ALTER AGGREGATE testagg3(int2) OWNER TO SESSION_USER; +ALTER AGGREGATE testagg4(int2) OWNER TO testrolx; +ALTER AGGREGATE testagg5(int2) OWNER TO "Public"; +ALTER AGGREGATE testagg5(int2) OWNER TO CURRENT_ROLE; -- error +ERROR: syntax error at or near "CURRENT_ROLE" +LINE 1: ALTER AGGREGATE testagg5(int2) OWNER TO CURRENT_ROLE; + ^ +ALTER AGGREGATE testagg5(int2) OWNER TO USER; -- error +ERROR: syntax error at or near "USER" +LINE 1: ALTER AGGREGATE testagg5(int2) OWNER TO USER; + ^ +ALTER AGGREGATE testagg5(int2) OWNER TO PUBLIC; -- error +ERROR: role "public" does not exist +ALTER AGGREGATE testagg5(int2) OWNER TO "public"; -- error +ERROR: role "public" does not exist +ALTER AGGREGATE testagg5(int2) OWNER TO nonexistent; -- error +ERROR: role "nonexistent" does not exist +SELECT p.proname, r.rolname + FROM pg_proc p JOIN pg_roles r ON (r.oid = p.proowner) + WHERE proname LIKE 'testagg_' + ORDER BY 1; + proname | rolname +----------+-------------- + testagg1 | testrol2 + testagg2 | current_user + testagg3 | testrol1 + testagg4 | testrolx + testagg5 | Public + testagg6 | testrol0 + testagg7 | testrol0 + testagg8 | testrol0 + testagg9 | testrol0 +(9 rows) + +-- CREATE USER MAPPING +CREATE FOREIGN DATA WRAPPER test_wrapper; +CREATE SERVER sv1 FOREIGN DATA WRAPPER test_wrapper; +CREATE SERVER sv2 FOREIGN DATA WRAPPER test_wrapper; +CREATE SERVER sv3 FOREIGN DATA WRAPPER test_wrapper; +CREATE SERVER sv4 FOREIGN DATA WRAPPER test_wrapper; +CREATE SERVER sv5 FOREIGN DATA WRAPPER test_wrapper; +CREATE SERVER sv6 FOREIGN DATA WRAPPER test_wrapper; +CREATE SERVER sv7 FOREIGN DATA WRAPPER test_wrapper; +CREATE SERVER sv8 FOREIGN DATA WRAPPER test_wrapper; +CREATE SERVER sv9 FOREIGN DATA WRAPPER test_wrapper; +CREATE USER MAPPING FOR CURRENT_USER SERVER sv1 OPTIONS (user 'CURRENT_USER'); +CREATE USER MAPPING FOR "current_user" SERVER sv2 OPTIONS (user '"current_user"'); +CREATE USER MAPPING FOR USER SERVER sv3 OPTIONS (user 'USER'); +CREATE USER MAPPING FOR "user" SERVER sv4 OPTIONS (user '"USER"'); +CREATE USER MAPPING FOR SESSION_USER SERVER sv5 OPTIONS (user 'SESSION_USER'); +CREATE USER MAPPING FOR PUBLIC SERVER sv6 OPTIONS (user 'PUBLIC'); +CREATE USER MAPPING FOR "Public" SERVER sv7 OPTIONS (user '"Public"'); +CREATE USER MAPPING FOR testrolx SERVER sv8 OPTIONS (user 'testrolx'); +CREATE USER MAPPING FOR CURRENT_ROLE SERVER sv9 + OPTIONS (user 'CURRENT_ROLE'); -- error +ERROR: syntax error at or near "CURRENT_ROLE" +LINE 1: CREATE USER MAPPING FOR CURRENT_ROLE SERVER sv9 + ^ +CREATE USER MAPPING FOR nonexistent SERVER sv9 + OPTIONS (user 'nonexistent'); -- error; +ERROR: role "nonexistent" does not exist +SELECT * FROM chkumapping(); + umname | umserver | umoptions +--------------+----------+--------------------------- + testrol2 | sv1 | {user=CURRENT_USER} + current_user | sv2 | {"user=\"current_user\""} + testrol2 | sv3 | {user=USER} + user | sv4 | {"user=\"USER\""} + testrol1 | sv5 | {user=SESSION_USER} + | sv6 | {user=PUBLIC} + Public | sv7 | {"user=\"Public\""} + testrolx | sv8 | {user=testrolx} +(8 rows) + +-- ALTER USER MAPPING +ALTER USER MAPPING FOR CURRENT_USER SERVER sv1 + OPTIONS (SET user 'CURRENT_USER_alt'); +ALTER USER MAPPING FOR "current_user" SERVER sv2 + OPTIONS (SET user '"current_user"_alt'); +ALTER USER MAPPING FOR USER SERVER sv3 + OPTIONS (SET user 'USER_alt'); +ALTER USER MAPPING FOR "user" SERVER sv4 + OPTIONS (SET user '"user"_alt'); +ALTER USER MAPPING FOR SESSION_USER SERVER sv5 + OPTIONS (SET user 'SESSION_USER_alt'); +ALTER USER MAPPING FOR PUBLIC SERVER sv6 + OPTIONS (SET user 'public_alt'); +ALTER USER MAPPING FOR "Public" SERVER sv7 + OPTIONS (SET user '"Public"_alt'); +ALTER USER MAPPING FOR testrolx SERVER sv8 + OPTIONS (SET user 'testrolx_alt'); +ALTER USER MAPPING FOR CURRENT_ROLE SERVER sv9 + OPTIONS (SET user 'CURRENT_ROLE_alt'); +ERROR: syntax error at or near "CURRENT_ROLE" +LINE 1: ALTER USER MAPPING FOR CURRENT_ROLE SERVER sv9 + ^ +ALTER USER MAPPING FOR nonexistent SERVER sv9 + OPTIONS (SET user 'nonexistent_alt'); -- error +ERROR: role "nonexistent" does not exist +SELECT * FROM chkumapping(); + umname | umserver | umoptions +--------------+----------+------------------------------- + testrol2 | sv1 | {user=CURRENT_USER_alt} + current_user | sv2 | {"user=\"current_user\"_alt"} + testrol2 | sv3 | {user=USER_alt} + user | sv4 | {"user=\"user\"_alt"} + testrol1 | sv5 | {user=SESSION_USER_alt} + | sv6 | {user=public_alt} + Public | sv7 | {"user=\"Public\"_alt"} + testrolx | sv8 | {user=testrolx_alt} +(8 rows) + +-- DROP USER MAPPING +DROP USER MAPPING FOR CURRENT_USER SERVER sv1; +DROP USER MAPPING FOR "current_user" SERVER sv2; +DROP USER MAPPING FOR USER SERVER sv3; +DROP USER MAPPING FOR "user" SERVER sv4; +DROP USER MAPPING FOR SESSION_USER SERVER sv5; +DROP USER MAPPING FOR PUBLIC SERVER sv6; +DROP USER MAPPING FOR "Public" SERVER sv7; +DROP USER MAPPING FOR testrolx SERVER sv8; +DROP USER MAPPING FOR CURRENT_ROLE SERVER sv9; -- error +ERROR: syntax error at or near "CURRENT_ROLE" +LINE 1: DROP USER MAPPING FOR CURRENT_ROLE SERVER sv9; + ^ +DROP USER MAPPING FOR nonexistent SERVER sv; -- error +ERROR: role "nonexistent" does not exist +SELECT * FROM chkumapping(); + umname | umserver | umoptions +--------+----------+----------- +(0 rows) + +CREATE USER MAPPING FOR CURRENT_USER SERVER sv1 OPTIONS (user 'CURRENT_USER'); +CREATE USER MAPPING FOR "current_user" SERVER sv2 OPTIONS (user '"current_user"'); +CREATE USER MAPPING FOR USER SERVER sv3 OPTIONS (user 'USER'); +CREATE USER MAPPING FOR "user" SERVER sv4 OPTIONS (user '"USER"'); +CREATE USER MAPPING FOR SESSION_USER SERVER sv5 OPTIONS (user 'SESSION_USER'); +CREATE USER MAPPING FOR PUBLIC SERVER sv6 OPTIONS (user 'PUBLIC'); +CREATE USER MAPPING FOR "Public" SERVER sv7 OPTIONS (user '"Public"'); +CREATE USER MAPPING FOR testrolx SERVER sv8 OPTIONS (user 'testrolx'); +SELECT * FROM chkumapping(); + umname | umserver | umoptions +--------------+----------+--------------------------- + testrol2 | sv1 | {user=CURRENT_USER} + current_user | sv2 | {"user=\"current_user\""} + testrol2 | sv3 | {user=USER} + user | sv4 | {"user=\"USER\""} + testrol1 | sv5 | {user=SESSION_USER} + | sv6 | {user=PUBLIC} + Public | sv7 | {"user=\"Public\""} + testrolx | sv8 | {user=testrolx} +(8 rows) + +-- DROP USER MAPPING IF EXISTS +DROP USER MAPPING IF EXISTS FOR CURRENT_USER SERVER sv1; +SELECT * FROM chkumapping(); + umname | umserver | umoptions +--------------+----------+--------------------------- + current_user | sv2 | {"user=\"current_user\""} + testrol2 | sv3 | {user=USER} + user | sv4 | {"user=\"USER\""} + testrol1 | sv5 | {user=SESSION_USER} + | sv6 | {user=PUBLIC} + Public | sv7 | {"user=\"Public\""} + testrolx | sv8 | {user=testrolx} +(7 rows) + +DROP USER MAPPING IF EXISTS FOR "current_user" SERVER sv2; +SELECT * FROM chkumapping(); + umname | umserver | umoptions +----------+----------+--------------------- + testrol2 | sv3 | {user=USER} + user | sv4 | {"user=\"USER\""} + testrol1 | sv5 | {user=SESSION_USER} + | sv6 | {user=PUBLIC} + Public | sv7 | {"user=\"Public\""} + testrolx | sv8 | {user=testrolx} +(6 rows) + +DROP USER MAPPING IF EXISTS FOR USER SERVER sv3; +SELECT * FROM chkumapping(); + umname | umserver | umoptions +----------+----------+--------------------- + user | sv4 | {"user=\"USER\""} + testrol1 | sv5 | {user=SESSION_USER} + | sv6 | {user=PUBLIC} + Public | sv7 | {"user=\"Public\""} + testrolx | sv8 | {user=testrolx} +(5 rows) + +DROP USER MAPPING IF EXISTS FOR "user" SERVER sv4; +SELECT * FROM chkumapping(); + umname | umserver | umoptions +----------+----------+--------------------- + testrol1 | sv5 | {user=SESSION_USER} + | sv6 | {user=PUBLIC} + Public | sv7 | {"user=\"Public\""} + testrolx | sv8 | {user=testrolx} +(4 rows) + +DROP USER MAPPING IF EXISTS FOR SESSION_USER SERVER sv5; +SELECT * FROM chkumapping(); + umname | umserver | umoptions +----------+----------+--------------------- + | sv6 | {user=PUBLIC} + Public | sv7 | {"user=\"Public\""} + testrolx | sv8 | {user=testrolx} +(3 rows) + +DROP USER MAPPING IF EXISTS FOR PUBLIC SERVER sv6; +SELECT * FROM chkumapping(); + umname | umserver | umoptions +----------+----------+--------------------- + Public | sv7 | {"user=\"Public\""} + testrolx | sv8 | {user=testrolx} +(2 rows) + +DROP USER MAPPING IF EXISTS FOR "Public" SERVER sv7; +SELECT * FROM chkumapping(); + umname | umserver | umoptions +----------+----------+----------------- + testrolx | sv8 | {user=testrolx} +(1 row) + +DROP USER MAPPING IF EXISTS FOR testrolx SERVER sv8; +SELECT * FROM chkumapping(); + umname | umserver | umoptions +--------+----------+----------- +(0 rows) + +DROP USER MAPPING IF EXISTS FOR CURRENT_ROLE SERVER sv9; --error +ERROR: syntax error at or near "CURRENT_ROLE" +LINE 1: DROP USER MAPPING IF EXISTS FOR CURRENT_ROLE SERVER sv9; + ^ +DROP USER MAPPING IF EXISTS FOR nonexistent SERVER sv9; -- error +NOTICE: role "nonexistent" does not exist, skipping +-- GRANT/REVOKE +UPDATE pg_proc SET proacl = null WHERE proname LIKE 'testagg_'; +SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_'; + proname | proacl +----------+-------- + testagg1 | + testagg2 | + testagg3 | + testagg4 | + testagg5 | + testagg6 | + testagg7 | + testagg8 | + testagg9 | +(9 rows) + +REVOKE ALL PRIVILEGES ON FUNCTION testagg1(int2) FROM PUBLIC; +REVOKE ALL PRIVILEGES ON FUNCTION testagg2(int2) FROM PUBLIC; +REVOKE ALL PRIVILEGES ON FUNCTION testagg3(int2) FROM PUBLIC; +REVOKE ALL PRIVILEGES ON FUNCTION testagg4(int2) FROM PUBLIC; +REVOKE ALL PRIVILEGES ON FUNCTION testagg5(int2) FROM PUBLIC; +REVOKE ALL PRIVILEGES ON FUNCTION testagg6(int2) FROM PUBLIC; +REVOKE ALL PRIVILEGES ON FUNCTION testagg7(int2) FROM PUBLIC; +REVOKE ALL PRIVILEGES ON FUNCTION testagg8(int2) FROM PUBLIC; +GRANT ALL PRIVILEGES ON FUNCTION testagg1(int2) TO PUBLIC; +GRANT ALL PRIVILEGES ON FUNCTION testagg2(int2) TO CURRENT_USER; +GRANT ALL PRIVILEGES ON FUNCTION testagg3(int2) TO "current_user"; +GRANT ALL PRIVILEGES ON FUNCTION testagg4(int2) TO SESSION_USER; +GRANT ALL PRIVILEGES ON FUNCTION testagg5(int2) TO "Public"; +GRANT ALL PRIVILEGES ON FUNCTION testagg6(int2) TO testrolx; +GRANT ALL PRIVILEGES ON FUNCTION testagg7(int2) TO "public"; +GRANT ALL PRIVILEGES ON FUNCTION testagg8(int2) + TO current_user, public, testrolx; +SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_'; + proname | proacl +----------+--------------------------------------------------------------------------- + testagg1 | {testrol2=X/testrol2,=X/testrol2} + testagg2 | {current_user=X/current_user,testrol2=X/current_user} + testagg3 | {testrol1=X/testrol1,current_user=X/testrol1} + testagg4 | {testrolx=X/testrolx,testrol1=X/testrolx} + testagg5 | {Public=X/Public} + testagg6 | {testrol0=X/testrol0,testrolx=X/testrol0} + testagg7 | {testrol0=X/testrol0,=X/testrol0} + testagg8 | {testrol0=X/testrol0,testrol2=X/testrol0,=X/testrol0,testrolx=X/testrol0} + testagg9 | +(9 rows) + +GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO CURRENT_ROLE; --error +ERROR: syntax error at or near "CURRENT_ROLE" +LINE 1: ...RANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO CURRENT_RO... + ^ +GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO USER; --error +ERROR: syntax error at or near "USER" +LINE 1: GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO USER; + ^ +GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO NONE; --error +ERROR: role name "none" is reserved +LINE 1: GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO NONE; + ^ +GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO "none"; --error +ERROR: role name "none" is reserved +LINE 1: GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO "none"; + ^ +SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_'; + proname | proacl +----------+--------------------------------------------------------------------------- + testagg1 | {testrol2=X/testrol2,=X/testrol2} + testagg2 | {current_user=X/current_user,testrol2=X/current_user} + testagg3 | {testrol1=X/testrol1,current_user=X/testrol1} + testagg4 | {testrolx=X/testrolx,testrol1=X/testrolx} + testagg5 | {Public=X/Public} + testagg6 | {testrol0=X/testrol0,testrolx=X/testrol0} + testagg7 | {testrol0=X/testrol0,=X/testrol0} + testagg8 | {testrol0=X/testrol0,testrol2=X/testrol0,=X/testrol0,testrolx=X/testrol0} + testagg9 | +(9 rows) + +REVOKE ALL PRIVILEGES ON FUNCTION testagg1(int2) FROM PUBLIC; +REVOKE ALL PRIVILEGES ON FUNCTION testagg2(int2) FROM CURRENT_USER; +REVOKE ALL PRIVILEGES ON FUNCTION testagg3(int2) FROM "current_user"; +REVOKE ALL PRIVILEGES ON FUNCTION testagg4(int2) FROM SESSION_USER; +REVOKE ALL PRIVILEGES ON FUNCTION testagg5(int2) FROM "Public"; +REVOKE ALL PRIVILEGES ON FUNCTION testagg6(int2) FROM testrolx; +REVOKE ALL PRIVILEGES ON FUNCTION testagg7(int2) FROM "public"; +REVOKE ALL PRIVILEGES ON FUNCTION testagg8(int2) + FROM current_user, public, testrolx; +SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_'; + proname | proacl +----------+------------------------------- + testagg1 | {testrol2=X/testrol2} + testagg2 | {current_user=X/current_user} + testagg3 | {testrol1=X/testrol1} + testagg4 | {testrolx=X/testrolx} + testagg5 | {} + testagg6 | {testrol0=X/testrol0} + testagg7 | {testrol0=X/testrol0} + testagg8 | {testrol0=X/testrol0} + testagg9 | +(9 rows) + +REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM CURRENT_ROLE; --error +ERROR: syntax error at or near "CURRENT_ROLE" +LINE 1: ...KE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM CURRENT_RO... + ^ +REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM USER; --error +ERROR: syntax error at or near "USER" +LINE 1: REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM USER; + ^ +REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM NONE; --error +ERROR: role name "none" is reserved +LINE 1: REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM NONE; + ^ +REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM "none"; --error +ERROR: role name "none" is reserved +LINE 1: ...EVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM "none"; + ^ +SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_'; + proname | proacl +----------+------------------------------- + testagg1 | {testrol2=X/testrol2} + testagg2 | {current_user=X/current_user} + testagg3 | {testrol1=X/testrol1} + testagg4 | {testrolx=X/testrolx} + testagg5 | {} + testagg6 | {testrol0=X/testrol0} + testagg7 | {testrol0=X/testrol0} + testagg8 | {testrol0=X/testrol0} + testagg9 | +(9 rows) + +-- clean up +\c +DROP OWNED BY testrol0, "Public", "current_user", testrol1, testrol2, testrolx CASCADE; +DROP ROLE testrol0, testrol1, testrol2, testrolx; +DROP ROLE "Public", "None", "current_user", "session_user", "user"; diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index e0ae2f2b01da8ac4cb2b822d030d7533e94914be..6d3b865351d370f0ed52ca42f8f11a3445bf7b9b 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -59,7 +59,7 @@ test: create_index create_view # ---------- # Another group of parallel tests # ---------- -test: create_aggregate create_function_3 create_cast constraints triggers inherit create_table_like typed_table vacuum drop_if_exists updatable_views +test: create_aggregate create_function_3 create_cast constraints triggers inherit create_table_like typed_table vacuum drop_if_exists updatable_views rolenames # ---------- # sanity_check does a vacuum, affecting the sort order of SELECT * diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule index 7f762bd08fdd92a318b53215d8691153dd5e44ad..8326894ed9d9cece29fc4eda4ede34f731383050 100644 --- a/src/test/regress/serial_schedule +++ b/src/test/regress/serial_schedule @@ -71,6 +71,7 @@ test: typed_table test: vacuum test: drop_if_exists test: updatable_views +test: rolenames test: sanity_check test: errors test: select diff --git a/src/test/regress/sql/rolenames.sql b/src/test/regress/sql/rolenames.sql new file mode 100644 index 0000000000000000000000000000000000000000..e8c6b335ec2e897d68c0795c3fba10c0162359d5 --- /dev/null +++ b/src/test/regress/sql/rolenames.sql @@ -0,0 +1,434 @@ +CREATE OR REPLACE FUNCTION chkrolattr() + RETURNS TABLE ("role" name, rolekeyword text, canlogin bool, replication bool) + AS $$ +SELECT r.rolname, v.keyword, r.rolcanlogin, r.rolreplication + FROM pg_roles r + JOIN (VALUES(CURRENT_USER, 'current_user'), + (SESSION_USER, 'session_user'), + ('current_user', '-'), + ('session_user', '-'), + ('Public', '-'), + ('None', '-')) + AS v(uname, keyword) + ON (r.rolname = v.uname) + ORDER BY 1; +$$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION chksetconfig() + RETURNS TABLE (db name, "role" name, rolkeyword text, setconfig text[]) + AS $$ +SELECT COALESCE(d.datname, 'ALL'), COALESCE(r.rolname, 'ALL'), + COALESCE(v.keyword, '-'), s.setconfig + FROM pg_db_role_setting s + LEFT JOIN pg_roles r ON (r.oid = s.setrole) + LEFT JOIN pg_database d ON (d.oid = s.setdatabase) + LEFT JOIN (VALUES(CURRENT_USER, 'current_user'), + (SESSION_USER, 'session_user')) + AS v(uname, keyword) + ON (r.rolname = v.uname) + WHERE (r.rolname) IN ('Public', 'current_user', 'testrol1', 'testrol2') +ORDER BY 1, 2; +$$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION chkumapping() + RETURNS TABLE (umname name, umserver name, umoptions text[]) + AS $$ +SELECT r.rolname, s.srvname, m.umoptions + FROM pg_user_mapping m + LEFT JOIN pg_roles r ON (r.oid = m.umuser) + JOIN pg_foreign_server s ON (s.oid = m.umserver) + ORDER BY 2; +$$ LANGUAGE SQL; + +CREATE ROLE "Public"; +CREATE ROLE "None"; +CREATE ROLE "current_user"; +CREATE ROLE "session_user"; +CREATE ROLE "user"; + +CREATE ROLE current_user; -- error +CREATE ROLE current_role; -- error +CREATE ROLE session_user; -- error +CREATE ROLE user; -- error +CREATE ROLE all; -- error + +CREATE ROLE public; -- error +CREATE ROLE "public"; -- error +CREATE ROLE none; -- error +CREATE ROLE "none"; -- error + +CREATE ROLE testrol0 SUPERUSER LOGIN; +CREATE ROLE testrolx SUPERUSER LOGIN; +CREATE ROLE testrol2 SUPERUSER; +CREATE ROLE testrol1 SUPERUSER LOGIN IN ROLE testrol2; + +\c - +SET SESSION AUTHORIZATION testrol1; +SET ROLE testrol2; + +-- ALTER ROLE +BEGIN; +SELECT * FROM chkrolattr(); +ALTER ROLE CURRENT_USER WITH REPLICATION; +SELECT * FROM chkrolattr(); +ALTER ROLE "current_user" WITH REPLICATION; +SELECT * FROM chkrolattr(); +ALTER ROLE SESSION_USER WITH REPLICATION; +SELECT * FROM chkrolattr(); +ALTER ROLE "session_user" WITH REPLICATION; +SELECT * FROM chkrolattr(); +ALTER USER "Public" WITH REPLICATION; +ALTER USER "None" WITH REPLICATION; +SELECT * FROM chkrolattr(); +ALTER USER testrol1 WITH NOREPLICATION; +ALTER USER testrol2 WITH NOREPLICATION; +SELECT * FROM chkrolattr(); +ROLLBACK; + +ALTER ROLE USER WITH LOGIN; -- error +ALTER ROLE CURRENT_ROLE WITH LOGIN; --error +ALTER ROLE ALL WITH REPLICATION; -- error +ALTER ROLE SESSION_ROLE WITH NOREPLICATION; -- error +ALTER ROLE PUBLIC WITH NOREPLICATION; -- error +ALTER ROLE "public" WITH NOREPLICATION; -- error +ALTER ROLE NONE WITH NOREPLICATION; -- error +ALTER ROLE "none" WITH NOREPLICATION; -- error +ALTER ROLE nonexistent WITH NOREPLICATION; -- error + +-- ALTER USER +BEGIN; +SELECT * FROM chkrolattr(); +ALTER USER CURRENT_USER WITH REPLICATION; +SELECT * FROM chkrolattr(); +ALTER USER "current_user" WITH REPLICATION; +SELECT * FROM chkrolattr(); +ALTER USER SESSION_USER WITH REPLICATION; +SELECT * FROM chkrolattr(); +ALTER USER "session_user" WITH REPLICATION; +SELECT * FROM chkrolattr(); +ALTER USER "Public" WITH REPLICATION; +ALTER USER "None" WITH REPLICATION; +SELECT * FROM chkrolattr(); +ALTER USER testrol1 WITH NOREPLICATION; +ALTER USER testrol2 WITH NOREPLICATION; +SELECT * FROM chkrolattr(); +ROLLBACK; + +ALTER USER USER WITH LOGIN; -- error +ALTER USER CURRENT_ROLE WITH LOGIN; -- error +ALTER USER ALL WITH REPLICATION; -- error +ALTER USER SESSION_ROLE WITH NOREPLICATION; -- error +ALTER USER PUBLIC WITH NOREPLICATION; -- error +ALTER USER "public" WITH NOREPLICATION; -- error +ALTER USER NONE WITH NOREPLICATION; -- error +ALTER USER "none" WITH NOREPLICATION; -- error +ALTER USER nonexistent WITH NOREPLICATION; -- error + +-- ALTER ROLE SET/RESET +SELECT * FROM chksetconfig(); +ALTER ROLE CURRENT_USER SET application_name to 'FOO'; +ALTER ROLE SESSION_USER SET application_name to 'BAR'; +ALTER ROLE "current_user" SET application_name to 'FOOFOO'; +ALTER ROLE "Public" SET application_name to 'BARBAR'; +ALTER ROLE ALL SET application_name to 'SLAP'; +SELECT * FROM chksetconfig(); +ALTER ROLE testrol1 SET application_name to 'SLAM'; +SELECT * FROM chksetconfig(); +ALTER ROLE CURRENT_USER RESET application_name; +ALTER ROLE SESSION_USER RESET application_name; +ALTER ROLE "current_user" RESET application_name; +ALTER ROLE "Public" RESET application_name; +ALTER ROLE ALL RESET application_name; +SELECT * FROM chksetconfig(); + + +ALTER ROLE CURRENT_ROLE SET application_name to 'BAZ'; -- error +ALTER ROLE USER SET application_name to 'BOOM'; -- error +ALTER ROLE PUBLIC SET application_name to 'BOMB'; -- error +ALTER ROLE nonexistent SET application_name to 'BOMB'; -- error + +-- ALTER USER SET/RESET +SELECT * FROM chksetconfig(); +ALTER USER CURRENT_USER SET application_name to 'FOO'; +ALTER USER SESSION_USER SET application_name to 'BAR'; +ALTER USER "current_user" SET application_name to 'FOOFOO'; +ALTER USER "Public" SET application_name to 'BARBAR'; +ALTER USER ALL SET application_name to 'SLAP'; +SELECT * FROM chksetconfig(); +ALTER USER testrol1 SET application_name to 'SLAM'; +SELECT * FROM chksetconfig(); +ALTER USER CURRENT_USER RESET application_name; +ALTER USER SESSION_USER RESET application_name; +ALTER USER "current_user" RESET application_name; +ALTER USER "Public" RESET application_name; +ALTER USER ALL RESET application_name; +SELECT * FROM chksetconfig(); + + +ALTER USER CURRENT_USER SET application_name to 'BAZ'; -- error +ALTER USER USER SET application_name to 'BOOM'; -- error +ALTER USER PUBLIC SET application_name to 'BOMB'; -- error +ALTER USER NONE SET application_name to 'BOMB'; -- error +ALTER USER nonexistent SET application_name to 'BOMB'; -- error + +-- CREAETE SCHEMA +set client_min_messages to error; +CREATE SCHEMA newschema1 AUTHORIZATION CURRENT_USER; +CREATE SCHEMA newschema2 AUTHORIZATION "current_user"; +CREATE SCHEMA newschema3 AUTHORIZATION SESSION_USER; +CREATE SCHEMA newschema4 AUTHORIZATION testrolx; +CREATE SCHEMA newschema5 AUTHORIZATION "Public"; + +CREATE SCHEMA newschema6 AUTHORIZATION USER; -- error +CREATE SCHEMA newschema6 AUTHORIZATION CURRENT_ROLE; -- error +CREATE SCHEMA newschema6 AUTHORIZATION PUBLIC; -- error +CREATE SCHEMA newschema6 AUTHORIZATION "public"; -- error +CREATE SCHEMA newschema6 AUTHORIZATION NONE; -- error +CREATE SCHEMA newschema6 AUTHORIZATION nonexistent; -- error + +SELECT n.nspname, r.rolname FROM pg_namespace n + JOIN pg_roles r ON (r.oid = n.nspowner) + WHERE n.nspname LIKE 'newschema_' ORDER BY 1; + +CREATE SCHEMA IF NOT EXISTS newschema1 AUTHORIZATION CURRENT_USER; +CREATE SCHEMA IF NOT EXISTS newschema2 AUTHORIZATION "current_user"; +CREATE SCHEMA IF NOT EXISTS newschema3 AUTHORIZATION SESSION_USER; +CREATE SCHEMA IF NOT EXISTS newschema4 AUTHORIZATION testrolx; +CREATE SCHEMA IF NOT EXISTS newschema5 AUTHORIZATION "Public"; + +CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION USER; -- error +CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION CURRENT_ROLE; -- error +CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION PUBLIC; -- error +CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION "public"; -- error +CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION NONE; -- error +CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION nonexistent; -- error + +SELECT n.nspname, r.rolname FROM pg_namespace n + JOIN pg_roles r ON (r.oid = n.nspowner) + WHERE n.nspname LIKE 'newschema_' ORDER BY 1; + +-- ALTER TABLE OWNER TO +\c - +SET SESSION AUTHORIZATION testrol0; +set client_min_messages to error; +CREATE TABLE testtab1 (a int); +CREATE TABLE testtab2 (a int); +CREATE TABLE testtab3 (a int); +CREATE TABLE testtab4 (a int); +CREATE TABLE testtab5 (a int); +CREATE TABLE testtab6 (a int); + +\c - +SET SESSION AUTHORIZATION testrol1; +SET ROLE testrol2; + +ALTER TABLE testtab1 OWNER TO CURRENT_USER; +ALTER TABLE testtab2 OWNER TO "current_user"; +ALTER TABLE testtab3 OWNER TO SESSION_USER; +ALTER TABLE testtab4 OWNER TO testrolx; +ALTER TABLE testtab5 OWNER TO "Public"; + +ALTER TABLE testtab6 OWNER TO CURRENT_ROLE; -- error +ALTER TABLE testtab6 OWNER TO USER; --error +ALTER TABLE testtab6 OWNER TO PUBLIC; -- error +ALTER TABLE testtab6 OWNER TO "public"; -- error +ALTER TABLE testtab6 OWNER TO nonexistent; -- error + +SELECT c.relname, r.rolname + FROM pg_class c JOIN pg_roles r ON (r.oid = c.relowner) + WHERE relname LIKE 'testtab_' + ORDER BY 1; + +-- ALTER TABLE, VIEW, MATERIALIZED VIEW, FOREIGN TABLE, SEQUENCE are +-- changed their owner in the same way. + +-- ALTER AGGREGATE +\c - +SET SESSION AUTHORIZATION testrol0; +CREATE AGGREGATE testagg1(int2) (SFUNC = int2_sum, STYPE = int8); +CREATE AGGREGATE testagg2(int2) (SFUNC = int2_sum, STYPE = int8); +CREATE AGGREGATE testagg3(int2) (SFUNC = int2_sum, STYPE = int8); +CREATE AGGREGATE testagg4(int2) (SFUNC = int2_sum, STYPE = int8); +CREATE AGGREGATE testagg5(int2) (SFUNC = int2_sum, STYPE = int8); +CREATE AGGREGATE testagg5(int2) (SFUNC = int2_sum, STYPE = int8); +CREATE AGGREGATE testagg6(int2) (SFUNC = int2_sum, STYPE = int8); +CREATE AGGREGATE testagg7(int2) (SFUNC = int2_sum, STYPE = int8); +CREATE AGGREGATE testagg8(int2) (SFUNC = int2_sum, STYPE = int8); +CREATE AGGREGATE testagg9(int2) (SFUNC = int2_sum, STYPE = int8); + +\c - +SET SESSION AUTHORIZATION testrol1; +SET ROLE testrol2; + +ALTER AGGREGATE testagg1(int2) OWNER TO CURRENT_USER; +ALTER AGGREGATE testagg2(int2) OWNER TO "current_user"; +ALTER AGGREGATE testagg3(int2) OWNER TO SESSION_USER; +ALTER AGGREGATE testagg4(int2) OWNER TO testrolx; +ALTER AGGREGATE testagg5(int2) OWNER TO "Public"; + +ALTER AGGREGATE testagg5(int2) OWNER TO CURRENT_ROLE; -- error +ALTER AGGREGATE testagg5(int2) OWNER TO USER; -- error +ALTER AGGREGATE testagg5(int2) OWNER TO PUBLIC; -- error +ALTER AGGREGATE testagg5(int2) OWNER TO "public"; -- error +ALTER AGGREGATE testagg5(int2) OWNER TO nonexistent; -- error + +SELECT p.proname, r.rolname + FROM pg_proc p JOIN pg_roles r ON (r.oid = p.proowner) + WHERE proname LIKE 'testagg_' + ORDER BY 1; + +-- CREATE USER MAPPING +CREATE FOREIGN DATA WRAPPER test_wrapper; +CREATE SERVER sv1 FOREIGN DATA WRAPPER test_wrapper; +CREATE SERVER sv2 FOREIGN DATA WRAPPER test_wrapper; +CREATE SERVER sv3 FOREIGN DATA WRAPPER test_wrapper; +CREATE SERVER sv4 FOREIGN DATA WRAPPER test_wrapper; +CREATE SERVER sv5 FOREIGN DATA WRAPPER test_wrapper; +CREATE SERVER sv6 FOREIGN DATA WRAPPER test_wrapper; +CREATE SERVER sv7 FOREIGN DATA WRAPPER test_wrapper; +CREATE SERVER sv8 FOREIGN DATA WRAPPER test_wrapper; +CREATE SERVER sv9 FOREIGN DATA WRAPPER test_wrapper; + +CREATE USER MAPPING FOR CURRENT_USER SERVER sv1 OPTIONS (user 'CURRENT_USER'); +CREATE USER MAPPING FOR "current_user" SERVER sv2 OPTIONS (user '"current_user"'); +CREATE USER MAPPING FOR USER SERVER sv3 OPTIONS (user 'USER'); +CREATE USER MAPPING FOR "user" SERVER sv4 OPTIONS (user '"USER"'); +CREATE USER MAPPING FOR SESSION_USER SERVER sv5 OPTIONS (user 'SESSION_USER'); +CREATE USER MAPPING FOR PUBLIC SERVER sv6 OPTIONS (user 'PUBLIC'); +CREATE USER MAPPING FOR "Public" SERVER sv7 OPTIONS (user '"Public"'); +CREATE USER MAPPING FOR testrolx SERVER sv8 OPTIONS (user 'testrolx'); + +CREATE USER MAPPING FOR CURRENT_ROLE SERVER sv9 + OPTIONS (user 'CURRENT_ROLE'); -- error +CREATE USER MAPPING FOR nonexistent SERVER sv9 + OPTIONS (user 'nonexistent'); -- error; + +SELECT * FROM chkumapping(); + +-- ALTER USER MAPPING +ALTER USER MAPPING FOR CURRENT_USER SERVER sv1 + OPTIONS (SET user 'CURRENT_USER_alt'); +ALTER USER MAPPING FOR "current_user" SERVER sv2 + OPTIONS (SET user '"current_user"_alt'); +ALTER USER MAPPING FOR USER SERVER sv3 + OPTIONS (SET user 'USER_alt'); +ALTER USER MAPPING FOR "user" SERVER sv4 + OPTIONS (SET user '"user"_alt'); +ALTER USER MAPPING FOR SESSION_USER SERVER sv5 + OPTIONS (SET user 'SESSION_USER_alt'); +ALTER USER MAPPING FOR PUBLIC SERVER sv6 + OPTIONS (SET user 'public_alt'); +ALTER USER MAPPING FOR "Public" SERVER sv7 + OPTIONS (SET user '"Public"_alt'); +ALTER USER MAPPING FOR testrolx SERVER sv8 + OPTIONS (SET user 'testrolx_alt'); + +ALTER USER MAPPING FOR CURRENT_ROLE SERVER sv9 + OPTIONS (SET user 'CURRENT_ROLE_alt'); +ALTER USER MAPPING FOR nonexistent SERVER sv9 + OPTIONS (SET user 'nonexistent_alt'); -- error + +SELECT * FROM chkumapping(); + +-- DROP USER MAPPING +DROP USER MAPPING FOR CURRENT_USER SERVER sv1; +DROP USER MAPPING FOR "current_user" SERVER sv2; +DROP USER MAPPING FOR USER SERVER sv3; +DROP USER MAPPING FOR "user" SERVER sv4; +DROP USER MAPPING FOR SESSION_USER SERVER sv5; +DROP USER MAPPING FOR PUBLIC SERVER sv6; +DROP USER MAPPING FOR "Public" SERVER sv7; +DROP USER MAPPING FOR testrolx SERVER sv8; + +DROP USER MAPPING FOR CURRENT_ROLE SERVER sv9; -- error +DROP USER MAPPING FOR nonexistent SERVER sv; -- error +SELECT * FROM chkumapping(); + +CREATE USER MAPPING FOR CURRENT_USER SERVER sv1 OPTIONS (user 'CURRENT_USER'); +CREATE USER MAPPING FOR "current_user" SERVER sv2 OPTIONS (user '"current_user"'); +CREATE USER MAPPING FOR USER SERVER sv3 OPTIONS (user 'USER'); +CREATE USER MAPPING FOR "user" SERVER sv4 OPTIONS (user '"USER"'); +CREATE USER MAPPING FOR SESSION_USER SERVER sv5 OPTIONS (user 'SESSION_USER'); +CREATE USER MAPPING FOR PUBLIC SERVER sv6 OPTIONS (user 'PUBLIC'); +CREATE USER MAPPING FOR "Public" SERVER sv7 OPTIONS (user '"Public"'); +CREATE USER MAPPING FOR testrolx SERVER sv8 OPTIONS (user 'testrolx'); +SELECT * FROM chkumapping(); + +-- DROP USER MAPPING IF EXISTS +DROP USER MAPPING IF EXISTS FOR CURRENT_USER SERVER sv1; +SELECT * FROM chkumapping(); +DROP USER MAPPING IF EXISTS FOR "current_user" SERVER sv2; +SELECT * FROM chkumapping(); +DROP USER MAPPING IF EXISTS FOR USER SERVER sv3; +SELECT * FROM chkumapping(); +DROP USER MAPPING IF EXISTS FOR "user" SERVER sv4; +SELECT * FROM chkumapping(); +DROP USER MAPPING IF EXISTS FOR SESSION_USER SERVER sv5; +SELECT * FROM chkumapping(); +DROP USER MAPPING IF EXISTS FOR PUBLIC SERVER sv6; +SELECT * FROM chkumapping(); +DROP USER MAPPING IF EXISTS FOR "Public" SERVER sv7; +SELECT * FROM chkumapping(); +DROP USER MAPPING IF EXISTS FOR testrolx SERVER sv8; +SELECT * FROM chkumapping(); + +DROP USER MAPPING IF EXISTS FOR CURRENT_ROLE SERVER sv9; --error +DROP USER MAPPING IF EXISTS FOR nonexistent SERVER sv9; -- error + +-- GRANT/REVOKE +UPDATE pg_proc SET proacl = null WHERE proname LIKE 'testagg_'; +SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_'; + +REVOKE ALL PRIVILEGES ON FUNCTION testagg1(int2) FROM PUBLIC; +REVOKE ALL PRIVILEGES ON FUNCTION testagg2(int2) FROM PUBLIC; +REVOKE ALL PRIVILEGES ON FUNCTION testagg3(int2) FROM PUBLIC; +REVOKE ALL PRIVILEGES ON FUNCTION testagg4(int2) FROM PUBLIC; +REVOKE ALL PRIVILEGES ON FUNCTION testagg5(int2) FROM PUBLIC; +REVOKE ALL PRIVILEGES ON FUNCTION testagg6(int2) FROM PUBLIC; +REVOKE ALL PRIVILEGES ON FUNCTION testagg7(int2) FROM PUBLIC; +REVOKE ALL PRIVILEGES ON FUNCTION testagg8(int2) FROM PUBLIC; + +GRANT ALL PRIVILEGES ON FUNCTION testagg1(int2) TO PUBLIC; +GRANT ALL PRIVILEGES ON FUNCTION testagg2(int2) TO CURRENT_USER; +GRANT ALL PRIVILEGES ON FUNCTION testagg3(int2) TO "current_user"; +GRANT ALL PRIVILEGES ON FUNCTION testagg4(int2) TO SESSION_USER; +GRANT ALL PRIVILEGES ON FUNCTION testagg5(int2) TO "Public"; +GRANT ALL PRIVILEGES ON FUNCTION testagg6(int2) TO testrolx; +GRANT ALL PRIVILEGES ON FUNCTION testagg7(int2) TO "public"; +GRANT ALL PRIVILEGES ON FUNCTION testagg8(int2) + TO current_user, public, testrolx; + +SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_'; + +GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO CURRENT_ROLE; --error +GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO USER; --error +GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO NONE; --error +GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO "none"; --error + +SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_'; + +REVOKE ALL PRIVILEGES ON FUNCTION testagg1(int2) FROM PUBLIC; +REVOKE ALL PRIVILEGES ON FUNCTION testagg2(int2) FROM CURRENT_USER; +REVOKE ALL PRIVILEGES ON FUNCTION testagg3(int2) FROM "current_user"; +REVOKE ALL PRIVILEGES ON FUNCTION testagg4(int2) FROM SESSION_USER; +REVOKE ALL PRIVILEGES ON FUNCTION testagg5(int2) FROM "Public"; +REVOKE ALL PRIVILEGES ON FUNCTION testagg6(int2) FROM testrolx; +REVOKE ALL PRIVILEGES ON FUNCTION testagg7(int2) FROM "public"; +REVOKE ALL PRIVILEGES ON FUNCTION testagg8(int2) + FROM current_user, public, testrolx; + +SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_'; + +REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM CURRENT_ROLE; --error +REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM USER; --error +REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM NONE; --error +REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM "none"; --error + +SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_'; + +-- clean up +\c + +DROP OWNED BY testrol0, "Public", "current_user", testrol1, testrol2, testrolx CASCADE; +DROP ROLE testrol0, testrol1, testrol2, testrolx; +DROP ROLE "Public", "None", "current_user", "session_user", "user";