<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>
<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>
<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>
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>
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>
<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>
[ 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>
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>
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>
<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>
<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>
<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>
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>
<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>
<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>
<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>
<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>
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>
</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>
<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>
[ 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>
<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>
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>
<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>
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>
<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>
<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>
<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>
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>
<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>
<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>] [, ... ] )
<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>
[, ...] | 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>
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);
}
/*
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);
}
/*
ObjectAddress
ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
{
- Oid newowner = get_role_oid(stmt->newowner, false);
+ Oid newowner = get_rolespec_oid(stmt->newowner, false);
switch (stmt->objectType)
{
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);
}
-/*
- * 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.
*
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);
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,
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)
/*
* 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)
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,
#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"
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;
/*
* 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
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 */
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 &&
/* 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();
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);
* 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 */
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];
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,
* 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
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] =
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);
/*
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);
/*
foreach(item, stmt->roles)
{
- const char *role = strVal(lfirst(item));
+ RoleSpec *rolspec = lfirst(item);
+ char *role;
HeapTuple tuple,
tmp_tuple;
ScanKeyData scankey;
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))
{
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);
void
DropOwnedObjects(DropOwnedStmt *stmt)
{
- List *role_ids = roleNamesToIds(stmt->roles);
+ List *role_ids = roleSpecsToIds(stmt->roles);
ListCell *cell;
/* Check privileges */
void
ReassignOwnedObjects(ReassignOwnedStmt *stmt)
{
- List *role_ids = roleNamesToIds(stmt->roles);
+ List *role_ids = roleSpecsToIds(stmt->roles);
ListCell *cell;
Oid newrole;
}
/* 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,
}
/*
- * 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;
*
* 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?
*/
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)
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;
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
{
ereport(NOTICE,
(errmsg("role \"%s\" is already a member of role \"%s\"",
- membername, rolename)));
+ get_rolespec_name((Node *) memberRole), rolename)));
ReleaseSysCache(authmem_tuple);
continue;
}
*
* 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?
*
*/
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)
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;
{
ereport(WARNING,
(errmsg("role \"%s\" is not a member of role \"%s\"",
- membername, rolename)));
+ get_rolespec_name((Node *) memberRole), rolename)));
continue;
}
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)
{
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);
return newnode;
}
-static PrivGrantee *
-_copyPrivGrantee(const PrivGrantee *from)
-{
- PrivGrantee *newnode = makeNode(PrivGrantee);
-
- COPY_STRING_FIELD(rolname);
-
- return newnode;
-}
-
static FuncWithArgs *
_copyFuncWithArgs(const FuncWithArgs *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;
COPY_NODE_FIELD(relation);
COPY_NODE_FIELD(object);
COPY_NODE_FIELD(objarg);
- COPY_STRING_FIELD(newowner);
+ COPY_NODE_FIELD(newowner);
return newnode;
}
CreateTableSpaceStmt *newnode = makeNode(CreateTableSpaceStmt);
COPY_STRING_FIELD(tablespacename);
- COPY_STRING_FIELD(owner);
+ COPY_NODE_FIELD(owner);
COPY_STRING_FIELD(location);
COPY_NODE_FIELD(options);
{
CreateUserMappingStmt *newnode = makeNode(CreateUserMappingStmt);
- COPY_STRING_FIELD(username);
+ COPY_NODE_FIELD(user);
COPY_STRING_FIELD(servername);
COPY_NODE_FIELD(options);
{
AlterUserMappingStmt *newnode = makeNode(AlterUserMappingStmt);
- COPY_STRING_FIELD(username);
+ COPY_NODE_FIELD(user);
COPY_STRING_FIELD(servername);
COPY_NODE_FIELD(options);
{
DropUserMappingStmt *newnode = makeNode(DropUserMappingStmt);
- COPY_STRING_FIELD(username);
+ COPY_NODE_FIELD(user);
COPY_STRING_FIELD(servername);
COPY_SCALAR_FIELD(missing_ok);
{
AlterRoleStmt *newnode = makeNode(AlterRoleStmt);
- COPY_STRING_FIELD(role);
+ COPY_NODE_FIELD(role);
COPY_NODE_FIELD(options);
COPY_SCALAR_FIELD(action);
{
AlterRoleSetStmt *newnode = makeNode(AlterRoleSetStmt);
- COPY_STRING_FIELD(role);
+ COPY_NODE_FIELD(role);
COPY_STRING_FIELD(database);
COPY_NODE_FIELD(setstmt);
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);
ReassignOwnedStmt *newnode = makeNode(ReassignOwnedStmt);
COPY_NODE_FIELD(roles);
- COPY_STRING_FIELD(newrole);
+ COPY_NODE_FIELD(newrole);
return newnode;
}
case T_CommonTableExpr:
retval = _copyCommonTableExpr(from);
break;
- case T_PrivGrantee:
- retval = _copyPrivGrantee(from);
- break;
case T_FuncWithArgs:
retval = _copyFuncWithArgs(from);
break;
case T_XmlSerialize:
retval = _copyXmlSerialize(from);
break;
+ case T_RoleSpec:
+ retval = _copyRoleSpec(from);
+ break;
default:
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(from));
{
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);
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)
{
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;
COMPARE_NODE_FIELD(relation);
COMPARE_NODE_FIELD(object);
COMPARE_NODE_FIELD(objarg);
- COMPARE_STRING_FIELD(newowner);
+ COMPARE_NODE_FIELD(newowner);
return true;
}
_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);
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);
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);
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);
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);
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);
_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);
_equalReassignOwnedStmt(const ReassignOwnedStmt *a, const ReassignOwnedStmt *b)
{
COMPARE_NODE_FIELD(roles);
- COMPARE_STRING_FIELD(newrole);
+ COMPARE_NODE_FIELD(newrole);
return true;
}
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
*/
case T_CommonTableExpr:
retval = _equalCommonTableExpr(a, b);
break;
- case T_PrivGrantee:
- retval = _equalPrivGrantee(a, b);
- break;
case T_FuncWithArgs:
retval = _equalFuncWithArgs(a, b);
break;
case T_XmlSerialize:
retval = _equalXmlSerialize(a, b);
break;
+ case T_RoleSpec:
+ retval = _equalRoleSpec(a, b);
+ break;
default:
elog(ERROR, "unrecognized node type: %d",
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);
%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
%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
%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
*****************************************************************************/
AlterRoleStmt:
- ALTER ROLE RoleId opt_with AlterOptRoleList
+ ALTER ROLE RoleSpec opt_with AlterOptRoleList
{
AlterRoleStmt *n = makeNode(AlterRoleStmt);
n->role = $3;
;
AlterRoleSetStmt:
- ALTER ROLE RoleId opt_in_database SetResetClause
+ ALTER ROLE RoleSpec opt_in_database SetResetClause
{
AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
n->role = $3;
*****************************************************************************/
AlterUserStmt:
- ALTER USER RoleId opt_with AlterOptRoleList
+ ALTER USER RoleSpec opt_with AlterOptRoleList
{
AlterRoleStmt *n = makeNode(AlterRoleStmt);
n->role = $3;
AlterUserSetStmt:
- ALTER USER RoleId SetResetClause
+ ALTER USER RoleSpec SetResetClause
{
AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
n->role = $3;
*****************************************************************************/
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;
*****************************************************************************/
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;
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),
| 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),
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> */
}
;
-OptTableSpaceOwner: OWNER name { $$ = $2; }
+OptTableSpaceOwner: OWNER RoleSpec { $$ = $2; }
| /*EMPTY */ { $$ = NULL; }
;
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;
;
/* 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); }
;
/*****************************************************************************
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;
| 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;
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;
RowSecurityDefaultToRole:
TO role_list { $$ = $2; }
- | /* EMPTY */ { $$ = list_make1(makeString("public")); }
+ | /* EMPTY */ { $$ = list_make1(makeRoleSpec(ROLESPEC_PUBLIC, -1)); }
;
RowSecurityOptionalToRole:
;
ReassignOwnedStmt:
- REASSIGN OWNED BY role_list TO name
+ REASSIGN OWNED BY role_list TO RoleSpec
{
ReassignOwnedStmt *n = makeNode(ReassignOwnedStmt);
n->roles = $4;
| 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; }
;
| /*EMPTY*/ { $$ = FALSE; }
;
-opt_granted_by: GRANTED BY RoleId { $$ = $3; }
+opt_granted_by: GRANTED BY RoleSpec { $$ = $3; }
| /*EMPTY*/ { $$ = NULL; }
;
*
*****************************************************************************/
-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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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.
*
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
{
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 */
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;
/*
* 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
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;
+}
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 */
T_XmlSerialize,
T_WithClause,
T_CommonTableExpr,
+ T_RoleSpec,
/*
* TAGS FOR REPLICATION GRAMMAR PARSE NODES (replnodes.h)
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
*
{
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;
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 */
* 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
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;
{
NodeTag type;
char *tablespacename;
- char *owner;
+ Node *owner;
char *location;
List *options;
} CreateTableSpaceStmt;
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;
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;
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;
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;
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;
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;
{
NodeTag type;
List *roles;
- char *newrole;
+ Node *newrole;
} ReassignOwnedStmt;
/*
#ifndef ACL_H
#define ACL_H
+#include "access/htup.h"
#include "nodes/parsenodes.h"
#include "utils/array.h"
#include "utils/snapshot.h"
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,
--- /dev/null
+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";
# ----------
# 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 *
test: vacuum
test: drop_if_exists
test: updatable_views
+test: rolenames
test: sanity_check
test: errors
test: select
--- /dev/null
+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";