Allow CURRENT/SESSION_USER to be used in certain commands

Commands such as ALTER USER, ALTER GROUP, ALTER ROLE, GRANT, and the
various ALTER OBJECT / OWNER TO, as well as ad-hoc clauses related to
roles such as the AUTHORIZATION clause of CREATE SCHEMA, the FOR clause
of CREATE USER MAPPING, and the FOR ROLE clause of ALTER DEFAULT
PRIVILEGES can now take the keywords CURRENT_USER and SESSION_USER as
user specifiers in place of an explicit user name.

This commit also fixes some quite ugly handling of special standards-
mandated syntax in CREATE USER MAPPING, which in particular would fail
to work in presence of a role named "current_user".

The special role specifiers PUBLIC and NONE also have more consistent
handling now.

Also take the opportunity to add location tracking to user specifiers.

Authors: Kyotaro Horiguchi.  Heavily reworked by Álvaro Herrera.
Reviewed by: Rushabh Lathia, Adam Brightwell, Marti Raudsepp.
This commit is contained in:
Alvaro Herrera 2015-03-09 15:41:54 -03:00
parent fa83f80945
commit 31eae6028e
52 changed files with 2000 additions and 347 deletions

View file

@ -22,7 +22,8 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
ALTER AGGREGATE <replaceable>name</replaceable> ( <replaceable>aggregate_signature</replaceable> ) RENAME TO <replaceable>new_name</replaceable>
ALTER AGGREGATE <replaceable>name</replaceable> ( <replaceable>aggregate_signature</replaceable> ) OWNER TO <replaceable>new_owner</replaceable>
ALTER AGGREGATE <replaceable>name</replaceable> ( <replaceable>aggregate_signature</replaceable> )
OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER AGGREGATE <replaceable>name</replaceable> ( <replaceable>aggregate_signature</replaceable> ) SET SCHEMA <replaceable>new_schema</replaceable>
<phrase>where <replaceable>aggregate_signature</replaceable> is:</phrase>

View file

@ -22,7 +22,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
ALTER COLLATION <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
ALTER COLLATION <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
ALTER COLLATION <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER COLLATION <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
</synopsis>
</refsynopsisdiv>

View file

@ -22,7 +22,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
ALTER CONVERSION <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
ALTER CONVERSION <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
ALTER CONVERSION <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER CONVERSION <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
</synopsis>
</refsynopsisdiv>

View file

@ -31,7 +31,7 @@ ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <rep
ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> SET TABLESPACE <replaceable class="PARAMETER">new_tablespace</replaceable>

View file

@ -36,7 +36,7 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
VALIDATE CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable>
ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
OWNER TO { <replaceable class="PARAMETER">new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
RENAME TO <replaceable class="PARAMETER">new_name</replaceable>
ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>

View file

@ -23,7 +23,7 @@ PostgreSQL documentation
<synopsis>
ALTER EVENT TRIGGER <replaceable class="PARAMETER">name</replaceable> DISABLE
ALTER EVENT TRIGGER <replaceable class="PARAMETER">name</replaceable> ENABLE [ REPLICA | ALWAYS ]
ALTER EVENT TRIGGER <replaceable class="PARAMETER">name</replaceable> OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
ALTER EVENT TRIGGER <replaceable class="PARAMETER">name</replaceable> OWNER TO { <replaceable class="PARAMETER">new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER EVENT TRIGGER <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable class="PARAMETER">new_name</replaceable>
</synopsis>
</refsynopsisdiv>

View file

@ -25,7 +25,7 @@ ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable>
[ HANDLER <replaceable class="parameter">handler_function</replaceable> | NO HANDLER ]
[ VALIDATOR <replaceable class="parameter">validator_function</replaceable> | NO VALIDATOR ]
[ OPTIONS ( [ ADD | SET | DROP ] <replaceable class="PARAMETER">option</replaceable> ['<replaceable class="PARAMETER">value</replaceable>'] [, ... ]) ]
ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
</synopsis>
</refsynopsisdiv>

View file

@ -48,7 +48,7 @@ ALTER FOREIGN TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceab
ENABLE TRIGGER [ <replaceable class="PARAMETER">trigger_name</replaceable> | ALL | USER ]
ENABLE REPLICA TRIGGER <replaceable class="PARAMETER">trigger_name</replaceable>
ENABLE ALWAYS TRIGGER <replaceable class="PARAMETER">trigger_name</replaceable>
OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
OWNER TO { <replaceable class="PARAMETER">new_owner</replaceable> | CURRENT_USER | SESSION_USER }
OPTIONS ( [ ADD | SET | DROP ] <replaceable class="PARAMETER">option</replaceable> ['<replaceable class="PARAMETER">value</replaceable>'] [, ... ])
</synopsis>
</refsynopsisdiv>

View file

@ -26,7 +26,7 @@ ALTER FUNCTION <replaceable>name</replaceable> ( [ [ <replaceable class="paramet
ALTER FUNCTION <replaceable>name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] )
RENAME TO <replaceable>new_name</replaceable>
ALTER FUNCTION <replaceable>name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] )
OWNER TO <replaceable>new_owner</replaceable>
OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER FUNCTION <replaceable>name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] )
SET SCHEMA <replaceable>new_schema</replaceable>

View file

@ -21,8 +21,14 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
ALTER GROUP <replaceable class="PARAMETER">group_name</replaceable> ADD USER <replaceable class="PARAMETER">user_name</replaceable> [, ... ]
ALTER GROUP <replaceable class="PARAMETER">group_name</replaceable> DROP USER <replaceable class="PARAMETER">user_name</replaceable> [, ... ]
ALTER GROUP <replaceable class="PARAMETER">role_specification</replaceable> ADD USER <replaceable class="PARAMETER">user_name</replaceable> [, ... ]
ALTER GROUP <replaceable class="PARAMETER">role_specification</replaceable> DROP USER <replaceable class="PARAMETER">user_name</replaceable> [, ... ]
<phrase>where <replaceable class="PARAMETER">role_specification</replaceable> can be:</phrase>
<replaceable class="PARAMETER">role_name</replaceable>
| CURRENT_USER
| SESSION_USER
ALTER GROUP <replaceable class="PARAMETER">group_name</replaceable> RENAME TO <replaceable>new_name</replaceable>
</synopsis>

View file

@ -22,7 +22,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
ALTER [ PROCEDURAL ] LANGUAGE <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
ALTER [ PROCEDURAL ] LANGUAGE <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
ALTER [ PROCEDURAL ] LANGUAGE <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
</synopsis>
</refsynopsisdiv>

View file

@ -21,7 +21,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
ALTER LARGE OBJECT <replaceable class="PARAMETER">large_object_oid</replaceable> OWNER TO <replaceable>new_owner</replaceable>
ALTER LARGE OBJECT <replaceable class="PARAMETER">large_object_oid</replaceable> { OWNER TO <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
</synopsis>
</refsynopsisdiv>

View file

@ -42,7 +42,7 @@ ALTER MATERIALIZED VIEW ALL IN TABLESPACE <replaceable class="parameter">name</r
SET WITHOUT CLUSTER
SET ( <replaceable class="PARAMETER">storage_parameter</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] )
RESET ( <replaceable class="PARAMETER">storage_parameter</replaceable> [, ... ] )
OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
OWNER TO { <replaceable class="PARAMETER">new_owner</replaceable> | CURRENT_USER | SESSION_USER }
SET TABLESPACE <replaceable class="PARAMETER">new_tablespace</replaceable>
</synopsis>
</refsynopsisdiv>

View file

@ -21,9 +21,14 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> RENAME TO <replaceable>new_name</replaceable>
ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> OWNER TO <replaceable>new_owner</replaceable>
ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable>
RENAME TO <replaceable>new_name</replaceable>
ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable>
{ OWNER TO <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable>
SET SCHEMA <replaceable>new_schema</replaceable>
</synopsis>
</refsynopsisdiv>

View file

@ -21,8 +21,11 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } , { <replaceable>right_type</replaceable> | NONE } ) OWNER TO <replaceable>new_owner</replaceable>
ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } , { <replaceable>right_type</replaceable> | NONE } ) SET SCHEMA <replaceable>new_schema</replaceable>
ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } , { <replaceable>right_type</replaceable> | NONE } )
{ OWNER TO <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } , { <replaceable>right_type</replaceable> | NONE } )
SET SCHEMA <replaceable>new_schema</replaceable>
</synopsis>
</refsynopsisdiv>

View file

@ -22,16 +22,25 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> ADD
{ OPERATOR <replaceable class="parameter">strategy_number</replaceable> <replaceable class="parameter">operator_name</replaceable> ( <replaceable class="parameter">op_type</replaceable>, <replaceable class="parameter">op_type</replaceable> ) [ FOR SEARCH | FOR ORDER BY <replaceable class="parameter">sort_family_name</replaceable> ]
| FUNCTION <replaceable class="parameter">support_number</replaceable> [ ( <replaceable class="parameter">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] ) ] <replaceable class="parameter">function_name</replaceable> ( <replaceable class="parameter">argument_type</replaceable> [, ...] )
{ OPERATOR <replaceable class="parameter">strategy_number</replaceable> <replaceable class="parameter">operator_name</replaceable> ( <replaceable class="parameter">op_type</replaceable>, <replaceable class="parameter">op_type</replaceable> )
[ FOR SEARCH | FOR ORDER BY <replaceable class="parameter">sort_family_name</replaceable> ]
| FUNCTION <replaceable class="parameter">support_number</replaceable> [ ( <replaceable class="parameter">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] ) ]
<replaceable class="parameter">function_name</replaceable> ( <replaceable class="parameter">argument_type</replaceable> [, ...] )
} [, ... ]
ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> DROP
{ OPERATOR <replaceable class="parameter">strategy_number</replaceable> ( <replaceable class="parameter">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] )
| FUNCTION <replaceable class="parameter">support_number</replaceable> ( <replaceable class="parameter">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] )
} [, ... ]
ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> RENAME TO <replaceable>new_name</replaceable>
ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> OWNER TO <replaceable>new_owner</replaceable>
ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable>
RENAME TO <replaceable>new_name</replaceable>
ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable>
OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable>
SET SCHEMA <replaceable>new_schema</replaceable>
</synopsis>
</refsynopsisdiv>

View file

@ -21,7 +21,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
ALTER ROLE <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replaceable class="PARAMETER">option</replaceable> [ ... ] ]
ALTER ROLE <replaceable class="PARAMETER">role_specification</replaceable> [ WITH ] <replaceable class="PARAMETER">option</replaceable> [ ... ]
<phrase>where <replaceable class="PARAMETER">option</replaceable> can be:</phrase>
@ -39,10 +39,16 @@ ALTER ROLE <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replace
ALTER ROLE <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
ALTER ROLE <replaceable class="PARAMETER">name</replaceable> [ IN DATABASE <replaceable class="PARAMETER">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT }
ALTER ROLE { <replaceable class="PARAMETER">name</replaceable> | ALL } [ IN DATABASE <replaceable class="PARAMETER">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> FROM CURRENT
ALTER ROLE { <replaceable class="PARAMETER">name</replaceable> | ALL } [ IN DATABASE <replaceable class="PARAMETER">database_name</replaceable> ] RESET <replaceable>configuration_parameter</replaceable>
ALTER ROLE { <replaceable class="PARAMETER">name</replaceable> | ALL } [ IN DATABASE <replaceable class="PARAMETER">database_name</replaceable> ] RESET ALL
ALTER ROLE { <replaceable class="PARAMETER">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="PARAMETER">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT }
ALTER ROLE { <replaceable class="PARAMETER">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="PARAMETER">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> FROM CURRENT
ALTER ROLE { <replaceable class="PARAMETER">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="PARAMETER">database_name</replaceable> ] RESET <replaceable>configuration_parameter</replaceable>
ALTER ROLE { <replaceable class="PARAMETER">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="PARAMETER">database_name</replaceable> ] RESET ALL
<phrase>where <replaceable class="PARAMETER">role_specification</replaceable> can be:</phrase>
[ GROUP ] <replaceable class="PARAMETER">role_name</replaceable>
| CURRENT_USER
| SESSION_USER
</synopsis>
</refsynopsisdiv>
@ -128,6 +134,25 @@ ALTER ROLE { <replaceable class="PARAMETER">name</replaceable> | ALL } [ IN DATA
</listitem>
</varlistentry>
<varlistentry>
<term>CURRENT_USER</term>
<listitem>
<para>
Alter the current user instead of an explicitely identified role.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>SESSION_USER</term>
<listitem>
<para>
Alter the current session user instead of an explicitely identified
role.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>SUPERUSER</literal></term>
<term><literal>NOSUPERUSER</literal></term>

View file

@ -22,7 +22,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
ALTER SCHEMA <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
ALTER SCHEMA <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
ALTER SCHEMA <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
</synopsis>
</refsynopsisdiv>

View file

@ -29,7 +29,7 @@ ALTER SEQUENCE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [
[ RESTART [ [ WITH ] <replaceable class="parameter">restart</replaceable> ] ]
[ CACHE <replaceable class="parameter">cache</replaceable> ] [ [ NO ] CYCLE ]
[ OWNED BY { <replaceable class="parameter">table_name</replaceable>.<replaceable class="parameter">column_name</replaceable> | NONE } ]
ALTER SEQUENCE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
ALTER SEQUENCE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable class="PARAMETER">new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER SEQUENCE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
ALTER SEQUENCE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
</synopsis>

View file

@ -23,7 +23,7 @@ PostgreSQL documentation
<synopsis>
ALTER SERVER <replaceable class="parameter">name</replaceable> [ VERSION '<replaceable class="parameter">new_version</replaceable>' ]
[ OPTIONS ( [ ADD | SET | DROP ] <replaceable class="PARAMETER">option</replaceable> ['<replaceable class="PARAMETER">value</replaceable>'] [, ... ] ) ]
ALTER SERVER <replaceable class="PARAMETER">name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
ALTER SERVER <replaceable class="PARAMETER">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER SERVER <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
</synopsis>
</refsynopsisdiv>

View file

@ -73,7 +73,7 @@ ALTER TABLE ALL IN TABLESPACE <replaceable class="PARAMETER">name</replaceable>
NO INHERIT <replaceable class="PARAMETER">parent_table</replaceable>
OF <replaceable class="PARAMETER">type_name</replaceable>
NOT OF
OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
OWNER TO { <replaceable class="PARAMETER">new_owner</replaceable> | CURRENT_USER | SESSION_USER }
REPLICA IDENTITY {DEFAULT | USING INDEX <replaceable class="PARAMETER">index_name</replaceable> | FULL | NOTHING}
<phrase>and <replaceable class="PARAMETER">table_constraint_using_index</replaceable> is:</phrase>

View file

@ -22,7 +22,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
ALTER TABLESPACE <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
ALTER TABLESPACE <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
ALTER TABLESPACE <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER TABLESPACE <replaceable>name</replaceable> SET ( <replaceable class="PARAMETER">tablespace_option</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] )
ALTER TABLESPACE <replaceable>name</replaceable> RESET ( <replaceable class="PARAMETER">tablespace_option</replaceable> [, ... ] )
</synopsis>

View file

@ -32,7 +32,7 @@ ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable>
ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable>
DROP MAPPING [ IF EXISTS ] FOR <replaceable class="parameter">token_type</replaceable> [, ... ]
ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
</synopsis>
</refsynopsisdiv>

View file

@ -25,7 +25,7 @@ ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> (
<replaceable class="parameter">option</replaceable> [ = <replaceable class="parameter">value</replaceable> ] [, ... ]
)
ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
</synopsis>
</refsynopsisdiv>

View file

@ -24,7 +24,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
ALTER TYPE <replaceable class="PARAMETER">name</replaceable> <replaceable class="PARAMETER">action</replaceable> [, ... ]
ALTER TYPE <replaceable class="PARAMETER">name</replaceable> OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
ALTER TYPE <replaceable class="PARAMETER">name</replaceable> OWNER TO { <replaceable class="PARAMETER">new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER TYPE <replaceable class="PARAMETER">name</replaceable> RENAME ATTRIBUTE <replaceable class="PARAMETER">attribute_name</replaceable> TO <replaceable class="PARAMETER">new_attribute_name</replaceable> [ CASCADE | RESTRICT ]
ALTER TYPE <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable class="PARAMETER">new_name</replaceable>
ALTER TYPE <replaceable class="PARAMETER">name</replaceable> SET SCHEMA <replaceable class="PARAMETER">new_schema</replaceable>

View file

@ -21,7 +21,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
ALTER USER <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replaceable class="PARAMETER">option</replaceable> [ ... ] ]
ALTER USER <replaceable class="PARAMETER">role_specification</replaceable> [ WITH ] <replaceable class="PARAMETER">option</replaceable> [ ... ]
<phrase>where <replaceable class="PARAMETER">option</replaceable> can be:</phrase>
@ -38,10 +38,16 @@ ALTER USER <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replace
ALTER USER <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
ALTER USER <replaceable class="PARAMETER">name</replaceable> SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT }
ALTER USER <replaceable class="PARAMETER">name</replaceable> SET <replaceable>configuration_parameter</replaceable> FROM CURRENT
ALTER USER <replaceable class="PARAMETER">name</replaceable> RESET <replaceable>configuration_parameter</replaceable>
ALTER USER <replaceable class="PARAMETER">name</replaceable> RESET ALL
ALTER USER <replaceable class="PARAMETER">role_specification</replaceable> SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT }
ALTER USER <replaceable class="PARAMETER">role_specification</replaceable> SET <replaceable>configuration_parameter</replaceable> FROM CURRENT
ALTER USER <replaceable class="PARAMETER">role_specification</replaceable> RESET <replaceable>configuration_parameter</replaceable>
ALTER USER <replaceable class="PARAMETER">role_specification</replaceable> RESET ALL
<phrase>where <replaceable class="PARAMETER">role_specification</replaceable> can be:</phrase>
[ GROUP ] <replaceable class="PARAMETER">role_name</replaceable>
| CURRENT_USER
| SESSION_USER
</synopsis>
</refsynopsisdiv>

View file

@ -21,7 +21,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
ALTER USER MAPPING FOR { <replaceable class="parameter">user_name</replaceable> | USER | CURRENT_USER | PUBLIC }
ALTER USER MAPPING FOR { <replaceable class="parameter">user_name</replaceable> | USER | CURRENT_USER | SESSION_USER | PUBLIC }
SERVER <replaceable class="parameter">server_name</replaceable>
OPTIONS ( [ ADD | SET | DROP ] <replaceable class="PARAMETER">option</replaceable> ['<replaceable class="PARAMETER">value</replaceable>'] [, ... ] )
</synopsis>

View file

@ -23,7 +23,7 @@ PostgreSQL documentation
<synopsis>
ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ALTER [ COLUMN ] <replaceable class="PARAMETER">column_name</replaceable> SET DEFAULT <replaceable class="PARAMETER">expression</replaceable>
ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ALTER [ COLUMN ] <replaceable class="PARAMETER">column_name</replaceable> DROP DEFAULT
ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable class="PARAMETER">new_owner</replaceable> | CURRENT_USER | SESSION_USER }
ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> SET ( <replaceable class="parameter">view_option_name</replaceable> [= <replaceable class="parameter">view_option_value</replaceable>] [, ... ] )

View file

@ -21,10 +21,16 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
CREATE SCHEMA <replaceable class="parameter">schema_name</replaceable> [ AUTHORIZATION <replaceable class="parameter">user_name</replaceable> ] [ <replaceable class="parameter">schema_element</replaceable> [ ... ] ]
CREATE SCHEMA AUTHORIZATION <replaceable class="parameter">user_name</replaceable> [ <replaceable class="parameter">schema_element</replaceable> [ ... ] ]
CREATE SCHEMA IF NOT EXISTS <replaceable class="parameter">schema_name</replaceable> [ AUTHORIZATION <replaceable class="parameter">user_name</replaceable> ]
CREATE SCHEMA IF NOT EXISTS AUTHORIZATION <replaceable class="parameter">user_name</replaceable>
CREATE SCHEMA <replaceable class="parameter">schema_name</replaceable> [ AUTHORIZATION <replaceable class="PARAMETER">role_specification</replaceable> ] [ <replaceable class="parameter">schema_element</replaceable> [ ... ] ]
CREATE SCHEMA AUTHORIZATION <replaceable class="PARAMETER">role_specification</replaceable> [ <replaceable class="parameter">schema_element</replaceable> [ ... ] ]
CREATE SCHEMA IF NOT EXISTS <replaceable class="parameter">schema_name</replaceable> [ AUTHORIZATION <replaceable class="PARAMETER">role_specification</replaceable> ]
CREATE SCHEMA IF NOT EXISTS AUTHORIZATION <replaceable class="PARAMETER">role_specification</replaceable>
<phrase>where <replaceable class="PARAMETER">role_specification</replaceable> can be:</phrase>
[ GROUP ] <replaceable class="PARAMETER">user_name</replaceable>
| CURRENT_USER
| SESSION_USER
</synopsis>
</refsynopsisdiv>

View file

@ -25,59 +25,66 @@ GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
[, ...] | ALL [ PRIVILEGES ] }
ON { [ TABLE ] <replaceable class="PARAMETER">table_name</replaceable> [, ...]
| ALL TABLES IN SCHEMA <replaceable class="PARAMETER">schema_name</replaceable> [, ...] }
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( <replaceable class="PARAMETER">column_name</replaceable> [, ...] )
[, ...] | ALL [ PRIVILEGES ] ( <replaceable class="PARAMETER">column_name</replaceable> [, ...] ) }
ON [ TABLE ] <replaceable class="PARAMETER">table_name</replaceable> [, ...]
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
GRANT { { USAGE | SELECT | UPDATE }
[, ...] | ALL [ PRIVILEGES ] }
ON { SEQUENCE <replaceable class="PARAMETER">sequence_name</replaceable> [, ...]
| ALL SEQUENCES IN SCHEMA <replaceable class="PARAMETER">schema_name</replaceable> [, ...] }
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }
ON DATABASE <replaceable>database_name</replaceable> [, ...]
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON DOMAIN <replaceable>domain_name</replaceable> [, ...]
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON FOREIGN DATA WRAPPER <replaceable>fdw_name</replaceable> [, ...]
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON FOREIGN SERVER <replaceable>server_name</replaceable> [, ...]
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
GRANT { EXECUTE | ALL [ PRIVILEGES ] }
ON { FUNCTION <replaceable>function_name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">arg_name</replaceable> ] <replaceable class="parameter">arg_type</replaceable> [, ...] ] ) [, ...]
| ALL FUNCTIONS IN SCHEMA <replaceable class="PARAMETER">schema_name</replaceable> [, ...] }
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON LANGUAGE <replaceable>lang_name</replaceable> [, ...]
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
GRANT { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
ON LARGE OBJECT <replaceable class="PARAMETER">loid</replaceable> [, ...]
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
ON SCHEMA <replaceable>schema_name</replaceable> [, ...]
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
GRANT { CREATE | ALL [ PRIVILEGES ] }
ON TABLESPACE <replaceable>tablespace_name</replaceable> [, ...]
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON TYPE <replaceable>type_name</replaceable> [, ...]
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
TO <replaceable class="PARAMETER">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
<phrase>where <replaceable class="PARAMETER">role_specification</replaceable> can be:</phrase>
[ GROUP ] <replaceable class="PARAMETER">role_name</replaceable>
| PUBLIC
| CURRENT_USER
| SESSION_USER
GRANT <replaceable class="PARAMETER">role_name</replaceable> [, ...] TO <replaceable class="PARAMETER">role_name</replaceable> [, ...] [ WITH ADMIN OPTION ]
</synopsis>

View file

@ -421,22 +421,25 @@ ExecuteGrantStmt(GrantStmt *stmt)
istmt.behavior = stmt->behavior;
/*
* Convert the PrivGrantee list into an Oid list. Note that at this point
* we insert an ACL_ID_PUBLIC into the list if an empty role name is
* detected (which is what the grammar uses if PUBLIC is found), so
* downstream there shouldn't be any additional work needed to support
* this case.
* Convert the RoleSpec list into an Oid list. Note that at this point
* we insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
* there shouldn't be any additional work needed to support this case.
*/
foreach(cell, stmt->grantees)
{
PrivGrantee *grantee = (PrivGrantee *) lfirst(cell);
RoleSpec *grantee = (RoleSpec *) lfirst(cell);
Oid grantee_uid;
if (grantee->rolname == NULL)
istmt.grantees = lappend_oid(istmt.grantees, ACL_ID_PUBLIC);
else
istmt.grantees =
lappend_oid(istmt.grantees,
get_role_oid(grantee->rolname, false));
switch (grantee->roletype)
{
case ROLESPEC_PUBLIC:
grantee_uid = ACL_ID_PUBLIC;
break;
default:
grantee_uid = get_rolespec_oid((Node *) grantee, false);
break;
}
istmt.grantees = lappend_oid(istmt.grantees, grantee_uid);
}
/*
@ -904,22 +907,25 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
iacls.behavior = action->behavior;
/*
* Convert the PrivGrantee list into an Oid list. Note that at this point
* we insert an ACL_ID_PUBLIC into the list if an empty role name is
* detected (which is what the grammar uses if PUBLIC is found), so
* downstream there shouldn't be any additional work needed to support
* this case.
* Convert the RoleSpec list into an Oid list. Note that at this point
* we insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
* there shouldn't be any additional work needed to support this case.
*/
foreach(cell, action->grantees)
{
PrivGrantee *grantee = (PrivGrantee *) lfirst(cell);
RoleSpec *grantee = (RoleSpec *) lfirst(cell);
Oid grantee_uid;
if (grantee->rolname == NULL)
iacls.grantees = lappend_oid(iacls.grantees, ACL_ID_PUBLIC);
else
iacls.grantees =
lappend_oid(iacls.grantees,
get_role_oid(grantee->rolname, false));
switch (grantee->roletype)
{
case ROLESPEC_PUBLIC:
grantee_uid = ACL_ID_PUBLIC;
break;
default:
grantee_uid = get_rolespec_oid((Node *) grantee, false);
break;
}
iacls.grantees = lappend_oid(iacls.grantees, grantee_uid);
}
/*

View file

@ -699,7 +699,7 @@ AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
ObjectAddress
ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
{
Oid newowner = get_role_oid(stmt->newowner, false);
Oid newowner = get_rolespec_oid(stmt->newowner, false);
switch (stmt->objectType)
{

View file

@ -1371,7 +1371,7 @@ CreateExtension(CreateExtensionStmt *stmt)
CreateSchemaStmt *csstmt = makeNode(CreateSchemaStmt);
csstmt->schemaname = schemaName;
csstmt->authid = NULL; /* will be created by current user */
csstmt->authrole = NULL; /* will be created by current user */
csstmt->schemaElts = NIL;
csstmt->if_not_exists = false;
CreateSchemaCommand(csstmt, NULL);

View file

@ -197,24 +197,6 @@ transformGenericOptions(Oid catalogId,
}
/*
* Convert the user mapping user name to OID
*/
static Oid
GetUserOidFromMapping(const char *username, bool missing_ok)
{
if (!username)
/* PUBLIC user mapping */
return InvalidOid;
if (strcmp(username, "current_user") == 0)
/* map to the owner */
return GetUserId();
/* map to provided user */
return get_role_oid(username, missing_ok);
}
/*
* Internal workhorse for changing a data wrapper's owner.
*
@ -1156,10 +1138,14 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
ObjectAddress referenced;
ForeignServer *srv;
ForeignDataWrapper *fdw;
RoleSpec *role = (RoleSpec *) stmt->user;
rel = heap_open(UserMappingRelationId, RowExclusiveLock);
useId = GetUserOidFromMapping(stmt->username, false);
if (role->roletype == ROLESPEC_PUBLIC)
useId = ACL_ID_PUBLIC;
else
useId = get_rolespec_oid(stmt->user, false);
/* Check that the server exists. */
srv = GetForeignServerByName(stmt->servername, false);
@ -1252,10 +1238,15 @@ AlterUserMapping(AlterUserMappingStmt *stmt)
Oid umId;
ForeignServer *srv;
ObjectAddress address;
RoleSpec *role = (RoleSpec *) stmt->user;
rel = heap_open(UserMappingRelationId, RowExclusiveLock);
useId = GetUserOidFromMapping(stmt->username, false);
if (role->roletype == ROLESPEC_PUBLIC)
useId = ACL_ID_PUBLIC;
else
useId = get_rolespec_oid(stmt->user, false);
srv = GetForeignServerByName(stmt->servername, false);
umId = GetSysCacheOid2(USERMAPPINGUSERSERVER,
@ -1338,20 +1329,27 @@ RemoveUserMapping(DropUserMappingStmt *stmt)
Oid useId;
Oid umId;
ForeignServer *srv;
RoleSpec *role = (RoleSpec *) stmt->user;
useId = GetUserOidFromMapping(stmt->username, stmt->missing_ok);
srv = GetForeignServerByName(stmt->servername, true);
if (stmt->username && !OidIsValid(useId))
if (role->roletype == ROLESPEC_PUBLIC)
useId = ACL_ID_PUBLIC;
else
{
/*
* IF EXISTS specified, role not found and not public. Notice this and
* leave.
*/
elog(NOTICE, "role \"%s\" does not exist, skipping", stmt->username);
return InvalidOid;
useId = get_rolespec_oid(stmt->user, stmt->missing_ok);
if (!OidIsValid(useId))
{
/*
* IF EXISTS specified, role not found and not public. Notice this
* and leave.
*/
elog(NOTICE, "role \"%s\" does not exist, skipping",
role->rolename);
return InvalidOid;
}
}
srv = GetForeignServerByName(stmt->servername, true);
if (!srv)
{
if (!stmt->missing_ok)

View file

@ -129,13 +129,7 @@ parse_policy_command(const char *cmd_name)
/*
* policy_role_list_to_array
* helper function to convert a list of role names in to an array of
* role ids.
*
* Note: If PUBLIC is provided as a role name, then ACL_ID_PUBLIC is
* used as the role id.
*
* roles - the list of role names to convert.
* helper function to convert a list of RoleSpecs to an array of role ids.
*/
static ArrayType *
policy_role_list_to_array(List *roles)
@ -162,25 +156,25 @@ policy_role_list_to_array(List *roles)
foreach(cell, roles)
{
Oid roleid = get_role_oid_or_public(strVal(lfirst(cell)));
RoleSpec *spec = lfirst(cell);
/*
* PUBLIC covers all roles, so it only makes sense alone.
*/
if (roleid == ACL_ID_PUBLIC)
if (spec->roletype == ROLESPEC_PUBLIC)
{
if (num_roles != 1)
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("ignoring roles specified other than public"),
errhint("All roles are members of the public role.")));
temp_array[0] = ObjectIdGetDatum(roleid);
temp_array[0] = ObjectIdGetDatum(ACL_ID_PUBLIC);
num_roles = 1;
break;
}
else
temp_array[i++] = ObjectIdGetDatum(roleid);
temp_array[i++] =
ObjectIdGetDatum(get_rolespec_oid((Node *) spec, false));
}
role_ids = construct_array(temp_array, num_roles, OIDOID, sizeof(Oid), true,

View file

@ -21,6 +21,7 @@
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_namespace.h"
#include "commands/dbcommands.h"
@ -42,8 +43,7 @@ static void AlterSchemaOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerI
Oid
CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString)
{
const char *schemaName = stmt->schemaname;
const char *authId = stmt->authid;
const char *schemaName = stmt->schemaname;
Oid namespaceId;
OverrideSearchPath *overridePath;
List *parsetree_list;
@ -58,11 +58,24 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString)
/*
* Who is supposed to own the new schema?
*/
if (authId)
owner_uid = get_role_oid(authId, false);
if (stmt->authrole)
owner_uid = get_rolespec_oid(stmt->authrole, false);
else
owner_uid = saved_uid;
/* fill schema name with the user name if not specified */
if (!schemaName)
{
HeapTuple tuple;
tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(owner_uid));
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for role %u", owner_uid);
schemaName =
pstrdup(NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname));
ReleaseSysCache(tuple);
}
/*
* To create a schema, must have schema-create privilege on the current
* database and must be able to become the target role (this does not

View file

@ -3507,7 +3507,7 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
break;
case AT_ChangeOwner: /* ALTER OWNER */
ATExecChangeOwner(RelationGetRelid(rel),
get_role_oid(cmd->name, false),
get_rolespec_oid(cmd->newowner, false),
false, lockmode);
break;
case AT_ClusterOn: /* CLUSTER ON */
@ -9388,7 +9388,7 @@ AlterTableMoveAll(AlterTableMoveAllStmt *stmt)
HeapTuple tuple;
Oid orig_tablespaceoid;
Oid new_tablespaceoid;
List *role_oids = roleNamesToIds(stmt->roles);
List *role_oids = roleSpecsToIds(stmt->roles);
/* Ensure we were not asked to move something we can't */
if (stmt->objtype != OBJECT_TABLE && stmt->objtype != OBJECT_INDEX &&

View file

@ -252,7 +252,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
/* However, the eventual owner of the tablespace need not be */
if (stmt->owner)
ownerId = get_role_oid(stmt->owner, false);
ownerId = get_rolespec_oid(stmt->owner, false);
else
ownerId = GetUserId();

View file

@ -49,10 +49,10 @@ extern bool Password_encryption;
check_password_hook_type check_password_hook = NULL;
static void AddRoleMems(const char *rolename, Oid roleid,
List *memberNames, List *memberIds,
List *memberSpecs, List *memberIds,
Oid grantorId, bool admin_opt);
static void DelRoleMems(const char *rolename, Oid roleid,
List *memberNames, List *memberIds,
List *memberSpecs, List *memberIds,
bool admin_opt);
@ -443,10 +443,10 @@ CreateRole(CreateRoleStmt *stmt)
* option, rolemembers don't.
*/
AddRoleMems(stmt->role, roleid,
adminmembers, roleNamesToIds(adminmembers),
adminmembers, roleSpecsToIds(adminmembers),
GetUserId(), true);
AddRoleMems(stmt->role, roleid,
rolemembers, roleNamesToIds(rolemembers),
rolemembers, roleSpecsToIds(rolemembers),
GetUserId(), false);
/* Post creation hook for new role */
@ -478,7 +478,9 @@ AlterRole(AlterRoleStmt *stmt)
TupleDesc pg_authid_dsc;
HeapTuple tuple,
new_tuple;
Form_pg_authid authform;
ListCell *option;
char *rolename = NULL;
char *password = NULL; /* user password */
bool encrypt_password = Password_encryption; /* encrypt password? */
char encrypted_password[MD5_PASSWD_LEN + 1];
@ -647,33 +649,30 @@ AlterRole(AlterRoleStmt *stmt)
pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock);
pg_authid_dsc = RelationGetDescr(pg_authid_rel);
tuple = SearchSysCache1(AUTHNAME, PointerGetDatum(stmt->role));
if (!HeapTupleIsValid(tuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("role \"%s\" does not exist", stmt->role)));
tuple = get_rolespec_tuple(stmt->role);
authform = (Form_pg_authid) GETSTRUCT(tuple);
rolename = pstrdup(NameStr(authform->rolname));
roleid = HeapTupleGetOid(tuple);
/*
* To mess with a superuser you gotta be superuser; else you need
* createrole, or just want to change your own password
*/
if (((Form_pg_authid) GETSTRUCT(tuple))->rolsuper || issuper >= 0)
if (authform->rolsuper || issuper >= 0)
{
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to alter superusers")));
}
else if (((Form_pg_authid) GETSTRUCT(tuple))->rolreplication || isreplication >= 0)
else if (authform->rolreplication || isreplication >= 0)
{
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to alter replication users")));
}
else if (((Form_pg_authid) GETSTRUCT(tuple))->rolbypassrls || bypassrls >= 0)
else if (authform->rolbypassrls || bypassrls >= 0)
{
if (!superuser())
ereport(ERROR,
@ -718,11 +717,11 @@ AlterRole(AlterRoleStmt *stmt)
* Call the password checking hook if there is one defined
*/
if (check_password_hook && password)
(*check_password_hook) (stmt->role,
password,
isMD5(password) ? PASSWORD_TYPE_MD5 : PASSWORD_TYPE_PLAINTEXT,
validUntil_datum,
validUntil_null);
(*check_password_hook)(rolename ,
password,
isMD5(password) ? PASSWORD_TYPE_MD5 : PASSWORD_TYPE_PLAINTEXT,
validUntil_datum,
validUntil_null);
/*
* Build an updated tuple, perusing the information just obtained
@ -784,7 +783,7 @@ AlterRole(AlterRoleStmt *stmt)
CStringGetTextDatum(password);
else
{
if (!pg_md5_encrypt(password, stmt->role, strlen(stmt->role),
if (!pg_md5_encrypt(password, rolename, strlen(rolename),
encrypted_password))
elog(ERROR, "password encryption failed");
new_record[Anum_pg_authid_rolpassword - 1] =
@ -831,12 +830,12 @@ AlterRole(AlterRoleStmt *stmt)
CommandCounterIncrement();
if (stmt->action == +1) /* add members to role */
AddRoleMems(stmt->role, roleid,
rolemembers, roleNamesToIds(rolemembers),
AddRoleMems(rolename, roleid,
rolemembers, roleSpecsToIds(rolemembers),
GetUserId(), false);
else if (stmt->action == -1) /* drop members from role */
DelRoleMems(stmt->role, roleid,
rolemembers, roleNamesToIds(rolemembers),
DelRoleMems(rolename, roleid,
rolemembers, roleSpecsToIds(rolemembers),
false);
/*
@ -860,13 +859,7 @@ AlterRoleSet(AlterRoleSetStmt *stmt)
if (stmt->role)
{
roletuple = SearchSysCache1(AUTHNAME, PointerGetDatum(stmt->role));
if (!HeapTupleIsValid(roletuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("role \"%s\" does not exist", stmt->role)));
roletuple = get_rolespec_tuple(stmt->role);
roleid = HeapTupleGetOid(roletuple);
/*
@ -955,7 +948,8 @@ DropRole(DropRoleStmt *stmt)
foreach(item, stmt->roles)
{
const char *role = strVal(lfirst(item));
RoleSpec *rolspec = lfirst(item);
char *role;
HeapTuple tuple,
tmp_tuple;
ScanKeyData scankey;
@ -964,6 +958,12 @@ DropRole(DropRoleStmt *stmt)
SysScanDesc sscan;
Oid roleid;
if (rolspec->roletype != ROLESPEC_CSTRING)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("cannot use special role specifier in \"%s\"", "DROP ROLE")));
role = rolspec->rolename;
tuple = SearchSysCache1(AUTHNAME, PointerGetDatum(role));
if (!HeapTupleIsValid(tuple))
{
@ -1233,11 +1233,11 @@ GrantRole(GrantRoleStmt *stmt)
ListCell *item;
if (stmt->grantor)
grantor = get_role_oid(stmt->grantor, false);
grantor = get_rolespec_oid(stmt->grantor, false);
else
grantor = GetUserId();
grantee_ids = roleNamesToIds(stmt->grantee_roles);
grantee_ids = roleSpecsToIds(stmt->grantee_roles);
/* AccessShareLock is enough since we aren't modifying pg_authid */
pg_authid_rel = heap_open(AuthIdRelationId, AccessShareLock);
@ -1286,7 +1286,7 @@ GrantRole(GrantRoleStmt *stmt)
void
DropOwnedObjects(DropOwnedStmt *stmt)
{
List *role_ids = roleNamesToIds(stmt->roles);
List *role_ids = roleSpecsToIds(stmt->roles);
ListCell *cell;
/* Check privileges */
@ -1312,7 +1312,7 @@ DropOwnedObjects(DropOwnedStmt *stmt)
void
ReassignOwnedObjects(ReassignOwnedStmt *stmt)
{
List *role_ids = roleNamesToIds(stmt->roles);
List *role_ids = roleSpecsToIds(stmt->roles);
ListCell *cell;
Oid newrole;
@ -1328,7 +1328,7 @@ ReassignOwnedObjects(ReassignOwnedStmt *stmt)
}
/* Must have privileges on the receiving side too */
newrole = get_role_oid(stmt->newrole, false);
newrole = get_rolespec_oid(stmt->newrole, false);
if (!has_privs_of_role(GetUserId(), newrole))
ereport(ERROR,
@ -1340,22 +1340,24 @@ ReassignOwnedObjects(ReassignOwnedStmt *stmt)
}
/*
* roleNamesToIds
* roleSpecsToIds
*
* Given a list of role names (as String nodes), generate a list of role OIDs
* in the same order.
* Given a list of RoleSpecs, generate a list of role OIDs in the same order.
*
* ROLESPEC_PUBLIC is not allowed.
*/
List *
roleNamesToIds(List *memberNames)
roleSpecsToIds(List *memberNames)
{
List *result = NIL;
ListCell *l;
foreach(l, memberNames)
{
char *rolename = strVal(lfirst(l));
Oid roleid = get_role_oid(rolename, false);
Node *rolespec = (Node *) lfirst(l);
Oid roleid;
roleid = get_rolespec_oid(rolespec, false);
result = lappend_oid(result, roleid);
}
return result;
@ -1366,7 +1368,7 @@ roleNamesToIds(List *memberNames)
*
* rolename: name of role to add to (used only for error messages)
* roleid: OID of role to add to
* memberNames: list of names of roles to add (used only for error messages)
* memberSpecs: list of RoleSpec of roles to add (used only for error messages)
* memberIds: OIDs of roles to add
* grantorId: who is granting the membership
* admin_opt: granting admin option?
@ -1375,15 +1377,15 @@ roleNamesToIds(List *memberNames)
*/
static void
AddRoleMems(const char *rolename, Oid roleid,
List *memberNames, List *memberIds,
List *memberSpecs, List *memberIds,
Oid grantorId, bool admin_opt)
{
Relation pg_authmem_rel;
TupleDesc pg_authmem_dsc;
ListCell *nameitem;
ListCell *specitem;
ListCell *iditem;
Assert(list_length(memberNames) == list_length(memberIds));
Assert(list_length(memberSpecs) == list_length(memberIds));
/* Skip permission check if nothing to do */
if (!memberIds)
@ -1428,9 +1430,9 @@ AddRoleMems(const char *rolename, Oid roleid,
pg_authmem_rel = heap_open(AuthMemRelationId, RowExclusiveLock);
pg_authmem_dsc = RelationGetDescr(pg_authmem_rel);
forboth(nameitem, memberNames, iditem, memberIds)
forboth(specitem, memberSpecs, iditem, memberIds)
{
const char *membername = strVal(lfirst(nameitem));
RoleSpec *memberRole = lfirst(specitem);
Oid memberid = lfirst_oid(iditem);
HeapTuple authmem_tuple;
HeapTuple tuple;
@ -1449,7 +1451,7 @@ AddRoleMems(const char *rolename, Oid roleid,
ereport(ERROR,
(errcode(ERRCODE_INVALID_GRANT_OPERATION),
(errmsg("role \"%s\" is a member of role \"%s\"",
rolename, membername))));
rolename, get_rolespec_name((Node *) memberRole)))));
/*
* Check if entry for this role/member already exists; if so, give
@ -1464,7 +1466,7 @@ AddRoleMems(const char *rolename, Oid roleid,
{
ereport(NOTICE,
(errmsg("role \"%s\" is already a member of role \"%s\"",
membername, rolename)));
get_rolespec_name((Node *) memberRole), rolename)));
ReleaseSysCache(authmem_tuple);
continue;
}
@ -1513,7 +1515,7 @@ AddRoleMems(const char *rolename, Oid roleid,
*
* rolename: name of role to del from (used only for error messages)
* roleid: OID of role to del from
* memberNames: list of names of roles to del (used only for error messages)
* memberSpecs: list of RoleSpec of roles to del (used only for error messages)
* memberIds: OIDs of roles to del
* admin_opt: remove admin option only?
*
@ -1521,15 +1523,15 @@ AddRoleMems(const char *rolename, Oid roleid,
*/
static void
DelRoleMems(const char *rolename, Oid roleid,
List *memberNames, List *memberIds,
List *memberSpecs, List *memberIds,
bool admin_opt)
{
Relation pg_authmem_rel;
TupleDesc pg_authmem_dsc;
ListCell *nameitem;
ListCell *specitem;
ListCell *iditem;
Assert(list_length(memberNames) == list_length(memberIds));
Assert(list_length(memberSpecs) == list_length(memberIds));
/* Skip permission check if nothing to do */
if (!memberIds)
@ -1559,9 +1561,9 @@ DelRoleMems(const char *rolename, Oid roleid,
pg_authmem_rel = heap_open(AuthMemRelationId, RowExclusiveLock);
pg_authmem_dsc = RelationGetDescr(pg_authmem_rel);
forboth(nameitem, memberNames, iditem, memberIds)
forboth(specitem, memberSpecs, iditem, memberIds)
{
const char *membername = strVal(lfirst(nameitem));
RoleSpec *memberRole = lfirst(specitem);
Oid memberid = lfirst_oid(iditem);
HeapTuple authmem_tuple;
@ -1575,7 +1577,7 @@ DelRoleMems(const char *rolename, Oid roleid,
{
ereport(WARNING,
(errmsg("role \"%s\" is not a member of role \"%s\"",
membername, rolename)));
get_rolespec_name((Node *) memberRole), rolename)));
continue;
}

View file

@ -2504,6 +2504,18 @@ _copyXmlSerialize(const XmlSerialize *from)
return newnode;
}
static RoleSpec *
_copyRoleSpec(const RoleSpec *from)
{
RoleSpec *newnode = makeNode(RoleSpec);
COPY_SCALAR_FIELD(roletype);
COPY_STRING_FIELD(rolename);
COPY_LOCATION_FIELD(location);
return newnode;
}
static Query *
_copyQuery(const Query *from)
{
@ -2650,6 +2662,7 @@ _copyAlterTableCmd(const AlterTableCmd *from)
COPY_SCALAR_FIELD(subtype);
COPY_STRING_FIELD(name);
COPY_NODE_FIELD(newowner);
COPY_NODE_FIELD(def);
COPY_SCALAR_FIELD(behavior);
COPY_SCALAR_FIELD(missing_ok);
@ -2689,16 +2702,6 @@ _copyGrantStmt(const GrantStmt *from)
return newnode;
}
static PrivGrantee *
_copyPrivGrantee(const PrivGrantee *from)
{
PrivGrantee *newnode = makeNode(PrivGrantee);
COPY_STRING_FIELD(rolname);
return newnode;
}
static FuncWithArgs *
_copyFuncWithArgs(const FuncWithArgs *from)
{
@ -2730,7 +2733,7 @@ _copyGrantRoleStmt(const GrantRoleStmt *from)
COPY_NODE_FIELD(grantee_roles);
COPY_SCALAR_FIELD(is_grant);
COPY_SCALAR_FIELD(admin_opt);
COPY_STRING_FIELD(grantor);
COPY_NODE_FIELD(grantor);
COPY_SCALAR_FIELD(behavior);
return newnode;
@ -3038,7 +3041,7 @@ _copyAlterOwnerStmt(const AlterOwnerStmt *from)
COPY_NODE_FIELD(relation);
COPY_NODE_FIELD(object);
COPY_NODE_FIELD(objarg);
COPY_STRING_FIELD(newowner);
COPY_NODE_FIELD(newowner);
return newnode;
}
@ -3424,7 +3427,7 @@ _copyCreateTableSpaceStmt(const CreateTableSpaceStmt *from)
CreateTableSpaceStmt *newnode = makeNode(CreateTableSpaceStmt);
COPY_STRING_FIELD(tablespacename);
COPY_STRING_FIELD(owner);
COPY_NODE_FIELD(owner);
COPY_STRING_FIELD(location);
COPY_NODE_FIELD(options);
@ -3561,7 +3564,7 @@ _copyCreateUserMappingStmt(const CreateUserMappingStmt *from)
{
CreateUserMappingStmt *newnode = makeNode(CreateUserMappingStmt);
COPY_STRING_FIELD(username);
COPY_NODE_FIELD(user);
COPY_STRING_FIELD(servername);
COPY_NODE_FIELD(options);
@ -3573,7 +3576,7 @@ _copyAlterUserMappingStmt(const AlterUserMappingStmt *from)
{
AlterUserMappingStmt *newnode = makeNode(AlterUserMappingStmt);
COPY_STRING_FIELD(username);
COPY_NODE_FIELD(user);
COPY_STRING_FIELD(servername);
COPY_NODE_FIELD(options);
@ -3585,7 +3588,7 @@ _copyDropUserMappingStmt(const DropUserMappingStmt *from)
{
DropUserMappingStmt *newnode = makeNode(DropUserMappingStmt);
COPY_STRING_FIELD(username);
COPY_NODE_FIELD(user);
COPY_STRING_FIELD(servername);
COPY_SCALAR_FIELD(missing_ok);
@ -3698,7 +3701,7 @@ _copyAlterRoleStmt(const AlterRoleStmt *from)
{
AlterRoleStmt *newnode = makeNode(AlterRoleStmt);
COPY_STRING_FIELD(role);
COPY_NODE_FIELD(role);
COPY_NODE_FIELD(options);
COPY_SCALAR_FIELD(action);
@ -3710,7 +3713,7 @@ _copyAlterRoleSetStmt(const AlterRoleSetStmt *from)
{
AlterRoleSetStmt *newnode = makeNode(AlterRoleSetStmt);
COPY_STRING_FIELD(role);
COPY_NODE_FIELD(role);
COPY_STRING_FIELD(database);
COPY_NODE_FIELD(setstmt);
@ -3769,7 +3772,7 @@ _copyCreateSchemaStmt(const CreateSchemaStmt *from)
CreateSchemaStmt *newnode = makeNode(CreateSchemaStmt);
COPY_STRING_FIELD(schemaname);
COPY_STRING_FIELD(authid);
COPY_NODE_FIELD(authrole);
COPY_NODE_FIELD(schemaElts);
COPY_SCALAR_FIELD(if_not_exists);
@ -3854,7 +3857,7 @@ _copyReassignOwnedStmt(const ReassignOwnedStmt *from)
ReassignOwnedStmt *newnode = makeNode(ReassignOwnedStmt);
COPY_NODE_FIELD(roles);
COPY_STRING_FIELD(newrole);
COPY_NODE_FIELD(newrole);
return newnode;
}
@ -4728,9 +4731,6 @@ copyObject(const void *from)
case T_CommonTableExpr:
retval = _copyCommonTableExpr(from);
break;
case T_PrivGrantee:
retval = _copyPrivGrantee(from);
break;
case T_FuncWithArgs:
retval = _copyFuncWithArgs(from);
break;
@ -4740,6 +4740,9 @@ copyObject(const void *from)
case T_XmlSerialize:
retval = _copyXmlSerialize(from);
break;
case T_RoleSpec:
retval = _copyRoleSpec(from);
break;
default:
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(from));

View file

@ -973,6 +973,7 @@ _equalAlterTableCmd(const AlterTableCmd *a, const AlterTableCmd *b)
{
COMPARE_SCALAR_FIELD(subtype);
COMPARE_STRING_FIELD(name);
COMPARE_NODE_FIELD(newowner);
COMPARE_NODE_FIELD(def);
COMPARE_SCALAR_FIELD(behavior);
COMPARE_SCALAR_FIELD(missing_ok);
@ -1008,14 +1009,6 @@ _equalGrantStmt(const GrantStmt *a, const GrantStmt *b)
return true;
}
static bool
_equalPrivGrantee(const PrivGrantee *a, const PrivGrantee *b)
{
COMPARE_STRING_FIELD(rolname);
return true;
}
static bool
_equalFuncWithArgs(const FuncWithArgs *a, const FuncWithArgs *b)
{
@ -1041,7 +1034,7 @@ _equalGrantRoleStmt(const GrantRoleStmt *a, const GrantRoleStmt *b)
COMPARE_NODE_FIELD(grantee_roles);
COMPARE_SCALAR_FIELD(is_grant);
COMPARE_SCALAR_FIELD(admin_opt);
COMPARE_STRING_FIELD(grantor);
COMPARE_NODE_FIELD(grantor);
COMPARE_SCALAR_FIELD(behavior);
return true;
@ -1295,7 +1288,7 @@ _equalAlterOwnerStmt(const AlterOwnerStmt *a, const AlterOwnerStmt *b)
COMPARE_NODE_FIELD(relation);
COMPARE_NODE_FIELD(object);
COMPARE_NODE_FIELD(objarg);
COMPARE_STRING_FIELD(newowner);
COMPARE_NODE_FIELD(newowner);
return true;
}
@ -1618,7 +1611,7 @@ static bool
_equalCreateTableSpaceStmt(const CreateTableSpaceStmt *a, const CreateTableSpaceStmt *b)
{
COMPARE_STRING_FIELD(tablespacename);
COMPARE_STRING_FIELD(owner);
COMPARE_NODE_FIELD(owner);
COMPARE_STRING_FIELD(location);
COMPARE_NODE_FIELD(options);
@ -1735,7 +1728,7 @@ _equalAlterForeignServerStmt(const AlterForeignServerStmt *a, const AlterForeign
static bool
_equalCreateUserMappingStmt(const CreateUserMappingStmt *a, const CreateUserMappingStmt *b)
{
COMPARE_STRING_FIELD(username);
COMPARE_NODE_FIELD(user);
COMPARE_STRING_FIELD(servername);
COMPARE_NODE_FIELD(options);
@ -1745,7 +1738,7 @@ _equalCreateUserMappingStmt(const CreateUserMappingStmt *a, const CreateUserMapp
static bool
_equalAlterUserMappingStmt(const AlterUserMappingStmt *a, const AlterUserMappingStmt *b)
{
COMPARE_STRING_FIELD(username);
COMPARE_NODE_FIELD(user);
COMPARE_STRING_FIELD(servername);
COMPARE_NODE_FIELD(options);
@ -1755,7 +1748,7 @@ _equalAlterUserMappingStmt(const AlterUserMappingStmt *a, const AlterUserMapping
static bool
_equalDropUserMappingStmt(const DropUserMappingStmt *a, const DropUserMappingStmt *b)
{
COMPARE_STRING_FIELD(username);
COMPARE_NODE_FIELD(user);
COMPARE_STRING_FIELD(servername);
COMPARE_SCALAR_FIELD(missing_ok);
@ -1853,7 +1846,7 @@ _equalCreateRoleStmt(const CreateRoleStmt *a, const CreateRoleStmt *b)
static bool
_equalAlterRoleStmt(const AlterRoleStmt *a, const AlterRoleStmt *b)
{
COMPARE_STRING_FIELD(role);
COMPARE_NODE_FIELD(role);
COMPARE_NODE_FIELD(options);
COMPARE_SCALAR_FIELD(action);
@ -1863,7 +1856,7 @@ _equalAlterRoleStmt(const AlterRoleStmt *a, const AlterRoleStmt *b)
static bool
_equalAlterRoleSetStmt(const AlterRoleSetStmt *a, const AlterRoleSetStmt *b)
{
COMPARE_STRING_FIELD(role);
COMPARE_NODE_FIELD(role);
COMPARE_STRING_FIELD(database);
COMPARE_NODE_FIELD(setstmt);
@ -1912,7 +1905,7 @@ static bool
_equalCreateSchemaStmt(const CreateSchemaStmt *a, const CreateSchemaStmt *b)
{
COMPARE_STRING_FIELD(schemaname);
COMPARE_STRING_FIELD(authid);
COMPARE_NODE_FIELD(authrole);
COMPARE_NODE_FIELD(schemaElts);
COMPARE_SCALAR_FIELD(if_not_exists);
@ -1983,7 +1976,7 @@ static bool
_equalReassignOwnedStmt(const ReassignOwnedStmt *a, const ReassignOwnedStmt *b)
{
COMPARE_NODE_FIELD(roles);
COMPARE_STRING_FIELD(newrole);
COMPARE_NODE_FIELD(newrole);
return true;
}
@ -2455,6 +2448,16 @@ _equalXmlSerialize(const XmlSerialize *a, const XmlSerialize *b)
return true;
}
static bool
_equalRoleSpec(const RoleSpec *a, const RoleSpec *b)
{
COMPARE_SCALAR_FIELD(roletype);
COMPARE_STRING_FIELD(rolename);
COMPARE_LOCATION_FIELD(location);
return true;
}
/*
* Stuff from pg_list.h
*/
@ -3153,9 +3156,6 @@ equal(const void *a, const void *b)
case T_CommonTableExpr:
retval = _equalCommonTableExpr(a, b);
break;
case T_PrivGrantee:
retval = _equalPrivGrantee(a, b);
break;
case T_FuncWithArgs:
retval = _equalFuncWithArgs(a, b);
break;
@ -3165,6 +3165,9 @@ equal(const void *a, const void *b)
case T_XmlSerialize:
retval = _equalXmlSerialize(a, b);
break;
case T_RoleSpec:
retval = _equalRoleSpec(a, b);
break;
default:
elog(ERROR, "unrecognized node type: %d",

View file

@ -143,6 +143,7 @@ static Node *makeBitStringConst(char *str, int location);
static Node *makeNullAConst(int location);
static Node *makeAConst(Value *v, int location);
static Node *makeBoolAConst(bool state, int location);
static Node *makeRoleSpec(RoleSpecType type, int location);
static void check_qualified_name(List *names, core_yyscan_t yyscanner);
static List *check_func_name(List *names, core_yyscan_t yyscanner);
static List *check_indirection(List *indirection, core_yyscan_t yyscanner);
@ -291,7 +292,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <str> opt_type
%type <str> foreign_server_version opt_foreign_server_version
%type <str> auth_ident
%type <str> opt_in_database
%type <str> OptSchemaName
@ -474,12 +474,13 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <ival> Iconst SignedIconst
%type <str> Sconst comment_text notify_payload
%type <str> RoleId opt_granted_by opt_boolean_or_string
%type <str> RoleId opt_boolean_or_string
%type <list> var_list
%type <str> ColId ColLabel var_name type_function_name param_name
%type <str> NonReservedWord NonReservedWord_or_Sconst
%type <str> createdb_opt_name
%type <node> var_value zone_value
%type <node> auth_ident RoleSpec opt_granted_by
%type <keyword> unreserved_keyword type_func_name_keyword
%type <keyword> col_name_keyword reserved_keyword
@ -494,7 +495,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <list> constraints_set_list
%type <boolean> constraints_set_mode
%type <str> OptTableSpace OptConsTableSpace OptTableSpaceOwner
%type <str> OptTableSpace OptConsTableSpace
%type <node> OptTableSpaceOwner
%type <ival> opt_check_option
%type <str> opt_provider security_label
@ -1037,7 +1039,7 @@ CreateUserStmt:
*****************************************************************************/
AlterRoleStmt:
ALTER ROLE RoleId opt_with AlterOptRoleList
ALTER ROLE RoleSpec opt_with AlterOptRoleList
{
AlterRoleStmt *n = makeNode(AlterRoleStmt);
n->role = $3;
@ -1053,7 +1055,7 @@ opt_in_database:
;
AlterRoleSetStmt:
ALTER ROLE RoleId opt_in_database SetResetClause
ALTER ROLE RoleSpec opt_in_database SetResetClause
{
AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
n->role = $3;
@ -1079,7 +1081,7 @@ AlterRoleSetStmt:
*****************************************************************************/
AlterUserStmt:
ALTER USER RoleId opt_with AlterOptRoleList
ALTER USER RoleSpec opt_with AlterOptRoleList
{
AlterRoleStmt *n = makeNode(AlterRoleStmt);
n->role = $3;
@ -1091,7 +1093,7 @@ AlterUserStmt:
AlterUserSetStmt:
ALTER USER RoleId SetResetClause
ALTER USER RoleSpec SetResetClause
{
AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
n->role = $3;
@ -1180,7 +1182,7 @@ CreateGroupStmt:
*****************************************************************************/
AlterGroupStmt:
ALTER GROUP_P RoleId add_drop USER role_list
ALTER GROUP_P RoleSpec add_drop USER role_list
{
AlterRoleStmt *n = makeNode(AlterRoleStmt);
n->role = $3;
@ -1228,15 +1230,12 @@ DropGroupStmt:
*****************************************************************************/
CreateSchemaStmt:
CREATE SCHEMA OptSchemaName AUTHORIZATION RoleId OptSchemaEltList
CREATE SCHEMA OptSchemaName AUTHORIZATION RoleSpec OptSchemaEltList
{
CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
/* One can omit the schema name or the authorization id. */
if ($3 != NULL)
n->schemaname = $3;
else
n->schemaname = $5;
n->authid = $5;
n->schemaname = $3;
n->authrole = $5;
n->schemaElts = $6;
n->if_not_exists = false;
$$ = (Node *)n;
@ -1246,20 +1245,17 @@ CreateSchemaStmt:
CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
/* ...but not both */
n->schemaname = $3;
n->authid = NULL;
n->authrole = NULL;
n->schemaElts = $4;
n->if_not_exists = false;
$$ = (Node *)n;
}
| CREATE SCHEMA IF_P NOT EXISTS OptSchemaName AUTHORIZATION RoleId OptSchemaEltList
| CREATE SCHEMA IF_P NOT EXISTS OptSchemaName AUTHORIZATION RoleSpec OptSchemaEltList
{
CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
/* One can omit the schema name or the authorization id. */
if ($6 != NULL)
n->schemaname = $6;
else
n->schemaname = $8;
n->authid = $8;
/* schema name can be omitted here, too */
n->schemaname = $6;
n->authrole = $8;
if ($9 != NIL)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@ -1272,9 +1268,9 @@ CreateSchemaStmt:
| CREATE SCHEMA IF_P NOT EXISTS ColId OptSchemaEltList
{
CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
/* ...but not both */
/* ...but not here */
n->schemaname = $6;
n->authid = NULL;
n->authrole = NULL;
if ($7 != NIL)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@ -2259,12 +2255,12 @@ alter_table_cmd:
n->subtype = AT_DropOf;
$$ = (Node *)n;
}
/* ALTER TABLE <name> OWNER TO RoleId */
| OWNER TO RoleId
/* ALTER TABLE <name> OWNER TO RoleSpec */
| OWNER TO RoleSpec
{
AlterTableCmd *n = makeNode(AlterTableCmd);
n->subtype = AT_ChangeOwner;
n->name = $3;
n->newowner = $3;
$$ = (Node *)n;
}
/* ALTER TABLE <name> SET TABLESPACE <tablespacename> */
@ -3756,7 +3752,7 @@ CreateTableSpaceStmt: CREATE TABLESPACE name OptTableSpaceOwner LOCATION Sconst
}
;
OptTableSpaceOwner: OWNER name { $$ = $2; }
OptTableSpaceOwner: OWNER RoleSpec { $$ = $2; }
| /*EMPTY */ { $$ = NULL; }
;
@ -4478,7 +4474,7 @@ import_qualification:
CreateUserMappingStmt: CREATE USER MAPPING FOR auth_ident SERVER name create_generic_options
{
CreateUserMappingStmt *n = makeNode(CreateUserMappingStmt);
n->username = $5;
n->user = $5;
n->servername = $7;
n->options = $8;
$$ = (Node *) n;
@ -4486,10 +4482,8 @@ CreateUserMappingStmt: CREATE USER MAPPING FOR auth_ident SERVER name create_gen
;
/* User mapping authorization identifier */
auth_ident:
CURRENT_USER { $$ = "current_user"; }
| USER { $$ = "current_user"; }
| RoleId { $$ = (strcmp($1, "public") == 0) ? NULL : $1; }
auth_ident: RoleSpec { $$ = $1; }
| USER { $$ = makeRoleSpec(ROLESPEC_CURRENT_USER, @1); }
;
/*****************************************************************************
@ -4502,7 +4496,7 @@ auth_ident:
DropUserMappingStmt: DROP USER MAPPING FOR auth_ident SERVER name
{
DropUserMappingStmt *n = makeNode(DropUserMappingStmt);
n->username = $5;
n->user = $5;
n->servername = $7;
n->missing_ok = false;
$$ = (Node *) n;
@ -4510,7 +4504,7 @@ DropUserMappingStmt: DROP USER MAPPING FOR auth_ident SERVER name
| DROP USER MAPPING IF_P EXISTS FOR auth_ident SERVER name
{
DropUserMappingStmt *n = makeNode(DropUserMappingStmt);
n->username = $7;
n->user = $7;
n->servername = $9;
n->missing_ok = true;
$$ = (Node *) n;
@ -4527,7 +4521,7 @@ DropUserMappingStmt: DROP USER MAPPING FOR auth_ident SERVER name
AlterUserMappingStmt: ALTER USER MAPPING FOR auth_ident SERVER name alter_generic_options
{
AlterUserMappingStmt *n = makeNode(AlterUserMappingStmt);
n->username = $5;
n->user = $5;
n->servername = $7;
n->options = $8;
$$ = (Node *) n;
@ -4612,7 +4606,7 @@ RowSecurityOptionalWithCheck:
RowSecurityDefaultToRole:
TO role_list { $$ = $2; }
| /* EMPTY */ { $$ = list_make1(makeString("public")); }
| /* EMPTY */ { $$ = list_make1(makeRoleSpec(ROLESPEC_PUBLIC, -1)); }
;
RowSecurityOptionalToRole:
@ -5432,7 +5426,7 @@ DropOwnedStmt:
;
ReassignOwnedStmt:
REASSIGN OWNED BY role_list TO name
REASSIGN OWNED BY role_list TO RoleSpec
{
ReassignOwnedStmt *n = makeNode(ReassignOwnedStmt);
n->roles = $4;
@ -6348,26 +6342,9 @@ grantee_list:
| grantee_list ',' grantee { $$ = lappend($1, $3); }
;
grantee: RoleId
{
PrivGrantee *n = makeNode(PrivGrantee);
/* This hack lets us avoid reserving PUBLIC as a keyword*/
if (strcmp($1, "public") == 0)
n->rolname = NULL;
else
n->rolname = $1;
$$ = (Node *)n;
}
| GROUP_P RoleId
{
PrivGrantee *n = makeNode(PrivGrantee);
/* Treat GROUP PUBLIC as a synonym for PUBLIC */
if (strcmp($2, "public") == 0)
n->rolname = NULL;
else
n->rolname = $2;
$$ = (Node *)n;
}
grantee:
RoleSpec { $$ = $1; }
| GROUP_P RoleSpec { $$ = $2; }
;
@ -6438,7 +6415,7 @@ opt_grant_admin_option: WITH ADMIN OPTION { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; }
;
opt_granted_by: GRANTED BY RoleId { $$ = $3; }
opt_granted_by: GRANTED BY RoleSpec { $$ = $3; }
| /*EMPTY*/ { $$ = NULL; }
;
@ -8104,7 +8081,7 @@ AlterObjectSchemaStmt:
*
*****************************************************************************/
AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_AGGREGATE;
@ -8113,7 +8090,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $7;
$$ = (Node *)n;
}
| ALTER COLLATION any_name OWNER TO RoleId
| ALTER COLLATION any_name OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_COLLATION;
@ -8121,7 +8098,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $6;
$$ = (Node *)n;
}
| ALTER CONVERSION_P any_name OWNER TO RoleId
| ALTER CONVERSION_P any_name OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_CONVERSION;
@ -8129,7 +8106,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $6;
$$ = (Node *)n;
}
| ALTER DATABASE database_name OWNER TO RoleId
| ALTER DATABASE database_name OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_DATABASE;
@ -8137,7 +8114,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $6;
$$ = (Node *)n;
}
| ALTER DOMAIN_P any_name OWNER TO RoleId
| ALTER DOMAIN_P any_name OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_DOMAIN;
@ -8145,7 +8122,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $6;
$$ = (Node *)n;
}
| ALTER FUNCTION function_with_argtypes OWNER TO RoleId
| ALTER FUNCTION function_with_argtypes OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_FUNCTION;
@ -8154,7 +8131,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $6;
$$ = (Node *)n;
}
| ALTER opt_procedural LANGUAGE name OWNER TO RoleId
| ALTER opt_procedural LANGUAGE name OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_LANGUAGE;
@ -8162,7 +8139,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $7;
$$ = (Node *)n;
}
| ALTER LARGE_P OBJECT_P NumericOnly OWNER TO RoleId
| ALTER LARGE_P OBJECT_P NumericOnly OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_LARGEOBJECT;
@ -8170,7 +8147,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $7;
$$ = (Node *)n;
}
| ALTER OPERATOR any_operator oper_argtypes OWNER TO RoleId
| ALTER OPERATOR any_operator oper_argtypes OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_OPERATOR;
@ -8179,7 +8156,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $7;
$$ = (Node *)n;
}
| ALTER OPERATOR CLASS any_name USING access_method OWNER TO RoleId
| ALTER OPERATOR CLASS any_name USING access_method OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_OPCLASS;
@ -8188,7 +8165,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $9;
$$ = (Node *)n;
}
| ALTER OPERATOR FAMILY any_name USING access_method OWNER TO RoleId
| ALTER OPERATOR FAMILY any_name USING access_method OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_OPFAMILY;
@ -8197,7 +8174,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $9;
$$ = (Node *)n;
}
| ALTER SCHEMA name OWNER TO RoleId
| ALTER SCHEMA name OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_SCHEMA;
@ -8205,7 +8182,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $6;
$$ = (Node *)n;
}
| ALTER TYPE_P any_name OWNER TO RoleId
| ALTER TYPE_P any_name OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_TYPE;
@ -8213,7 +8190,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $6;
$$ = (Node *)n;
}
| ALTER TABLESPACE name OWNER TO RoleId
| ALTER TABLESPACE name OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_TABLESPACE;
@ -8221,7 +8198,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $6;
$$ = (Node *)n;
}
| ALTER TEXT_P SEARCH DICTIONARY any_name OWNER TO RoleId
| ALTER TEXT_P SEARCH DICTIONARY any_name OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_TSDICTIONARY;
@ -8229,7 +8206,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $8;
$$ = (Node *)n;
}
| ALTER TEXT_P SEARCH CONFIGURATION any_name OWNER TO RoleId
| ALTER TEXT_P SEARCH CONFIGURATION any_name OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_TSCONFIGURATION;
@ -8237,7 +8214,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $8;
$$ = (Node *)n;
}
| ALTER FOREIGN DATA_P WRAPPER name OWNER TO RoleId
| ALTER FOREIGN DATA_P WRAPPER name OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_FDW;
@ -8245,7 +8222,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $8;
$$ = (Node *)n;
}
| ALTER SERVER name OWNER TO RoleId
| ALTER SERVER name OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_FOREIGN_SERVER;
@ -8253,7 +8230,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $6;
$$ = (Node *)n;
}
| ALTER EVENT TRIGGER name OWNER TO RoleId
| ALTER EVENT TRIGGER name OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_EVENT_TRIGGER;
@ -13113,19 +13090,86 @@ AexprConst: Iconst
Iconst: ICONST { $$ = $1; };
Sconst: SCONST { $$ = $1; };
RoleId: NonReservedWord { $$ = $1; };
role_list: RoleId
{ $$ = list_make1(makeString($1)); }
| role_list ',' RoleId
{ $$ = lappend($1, makeString($3)); }
;
SignedIconst: Iconst { $$ = $1; }
| '+' Iconst { $$ = + $2; }
| '-' Iconst { $$ = - $2; }
;
/* Role specifications */
RoleId: RoleSpec
{
RoleSpec *spc = (RoleSpec *) $1;
switch (spc->roletype)
{
case ROLESPEC_CSTRING:
$$ = spc->rolename;
break;
case ROLESPEC_PUBLIC:
ereport(ERROR,
(errcode(ERRCODE_RESERVED_NAME),
errmsg("role name \"%s\" is reserved",
"public"),
parser_errposition(@1)));
case ROLESPEC_SESSION_USER:
ereport(ERROR,
(errcode(ERRCODE_RESERVED_NAME),
errmsg("%s cannot be used as a role name",
"SESSION_USER"),
parser_errposition(@1)));
case ROLESPEC_CURRENT_USER:
ereport(ERROR,
(errcode(ERRCODE_RESERVED_NAME),
errmsg("%s cannot be used as a role name",
"CURRENT_USER"),
parser_errposition(@1)));
}
}
;
RoleSpec: NonReservedWord
{
/*
* "public" and "none" are not keywords, but they must
* be treated specially here.
*/
RoleSpec *n;
if (strcmp($1, "public") == 0)
{
n = (RoleSpec *) makeRoleSpec(ROLESPEC_PUBLIC, @1);
n->roletype = ROLESPEC_PUBLIC;
}
else if (strcmp($1, "none") == 0)
{
ereport(ERROR,
(errcode(ERRCODE_RESERVED_NAME),
errmsg("role name \"%s\" is reserved",
"none"),
parser_errposition(@1)));
}
else
{
n = (RoleSpec *) makeRoleSpec(ROLESPEC_CSTRING, @1);
n->rolename = pstrdup($1);
}
$$ = (Node *) n;
}
| CURRENT_USER
{
$$ = makeRoleSpec(ROLESPEC_CURRENT_USER, @1);
}
| SESSION_USER
{
$$ = makeRoleSpec(ROLESPEC_SESSION_USER, @1);
}
;
role_list: RoleSpec
{ $$ = list_make1($1); }
| role_list ',' RoleSpec
{ $$ = lappend($1, $3); }
;
/*
* Name classification hierarchy.
*
@ -13812,6 +13856,20 @@ makeBoolAConst(bool state, int location)
return makeTypeCast((Node *)n, SystemTypeName("bool"), -1);
}
/* makeRoleSpec
* Create a RoleSpec with the given type
*/
static Node *
makeRoleSpec(RoleSpecType type, int location)
{
RoleSpec *spec = makeNode(RoleSpec);
spec->roletype = type;
spec->location = location;
return (Node *) spec;
}
/* check_qualified_name --- check the result of qualified_name production
*
* It's easiest to let the grammar production for qualified_name allow

View file

@ -90,7 +90,7 @@ typedef struct
{
const char *stmtType; /* "CREATE SCHEMA" or "ALTER SCHEMA" */
char *schemaname; /* name of schema */
char *authid; /* owner of schema */
RoleSpec *authrole; /* owner of schema */
List *sequences; /* CREATE SEQUENCE items */
List *tables; /* CREATE TABLE items */
List *views; /* CREATE VIEW items */
@ -2723,7 +2723,7 @@ transformCreateSchemaStmt(CreateSchemaStmt *stmt)
cxt.stmtType = "CREATE SCHEMA";
cxt.schemaname = stmt->schemaname;
cxt.authid = stmt->authid;
cxt.authrole = (RoleSpec *) stmt->authrole;
cxt.sequences = NIL;
cxt.tables = NIL;
cxt.views = NIL;

View file

@ -5105,7 +5105,7 @@ select_best_grantor(Oid roleId, AclMode privileges,
/*
* get_role_oid - Given a role name, look up the role's OID.
*
* If missing_ok is false, throw an error if tablespace name not found. If
* If missing_ok is false, throw an error if role name not found. If
* true, just return InvalidOid.
*/
Oid
@ -5133,3 +5133,117 @@ get_role_oid_or_public(const char *rolname)
return get_role_oid(rolname, false);
}
/*
* Given a RoleSpec node, return the OID it corresponds to. If missing_ok is
* true, return InvalidOid if the role does not exist.
*
* PUBLIC is always disallowed here. Routines wanting to handle the PUBLIC
* case must check the case separately.
*/
Oid
get_rolespec_oid(const Node *node, bool missing_ok)
{
RoleSpec *role;
Oid oid;
if (!IsA(node, RoleSpec))
elog(ERROR, "invalid node type %d", node->type);
role = (RoleSpec *) node;
switch (role->roletype)
{
case ROLESPEC_CSTRING:
Assert(role->rolename);
oid = get_role_oid(role->rolename, missing_ok);
break;
case ROLESPEC_CURRENT_USER:
oid = GetUserId();
break;
case ROLESPEC_SESSION_USER:
oid = GetSessionUserId();
break;
case ROLESPEC_PUBLIC:
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("role \"%s\" does not exist", "public")));
oid = InvalidOid; /* make compiler happy */
break;
default:
elog(ERROR, "unexpected role type %d", role->roletype);
}
return oid;
}
/*
* Given a RoleSpec node, return the pg_authid HeapTuple it corresponds to.
* Caller must ReleaseSysCache when done with the result tuple.
*/
HeapTuple
get_rolespec_tuple(const Node *node)
{
RoleSpec *role;
HeapTuple tuple;
role = (RoleSpec *) node;
if (!IsA(node, RoleSpec))
elog(ERROR, "invalid node type %d", node->type);
switch (role->roletype)
{
case ROLESPEC_CSTRING:
Assert(role->rolename);
tuple = SearchSysCache1(AUTHNAME, CStringGetDatum(role->rolename));
if (!HeapTupleIsValid(tuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("role \"%s\" does not exist", role->rolename)));
break;
case ROLESPEC_CURRENT_USER:
tuple = SearchSysCache1(AUTHOID, GetUserId());
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for role %u", GetUserId());
break;
case ROLESPEC_SESSION_USER:
tuple = SearchSysCache1(AUTHOID, GetSessionUserId());
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for role %u", GetSessionUserId());
break;
case ROLESPEC_PUBLIC:
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("role \"%s\" does not exist", "public")));
tuple = NULL; /* make compiler happy */
default:
elog(ERROR, "unexpected role type %d", role->roletype);
}
return tuple;
}
/*
* Given a RoleSpec, returns a palloc'ed copy of the corresponding role's name.
*/
char *
get_rolespec_name(const Node *node)
{
HeapTuple tp;
Form_pg_authid authForm;
char *rolename;
tp = get_rolespec_tuple(node);
authForm = (Form_pg_authid) GETSTRUCT(tp);
rolename = pstrdup(NameStr(authForm->rolname));
ReleaseSysCache(tp);
return rolename;
}

View file

@ -31,6 +31,6 @@ extern void GrantRole(GrantRoleStmt *stmt);
extern ObjectAddress RenameRole(const char *oldname, const char *newname);
extern void DropOwnedObjects(DropOwnedStmt *stmt);
extern void ReassignOwnedObjects(ReassignOwnedStmt *stmt);
extern List *roleNamesToIds(List *memberNames);
extern List *roleSpecsToIds(List *memberNames);
#endif /* USER_H */

View file

@ -413,6 +413,7 @@ typedef enum NodeTag
T_XmlSerialize,
T_WithClause,
T_CommonTableExpr,
T_RoleSpec,
/*
* TAGS FOR REPLICATION GRAMMAR PARSE NODES (replnodes.h)

View file

@ -284,6 +284,25 @@ typedef struct CollateClause
int location; /* token location, or -1 if unknown */
} CollateClause;
/*
* RoleSpec - a role name or one of a few special values.
*/
typedef enum RoleSpecType
{
ROLESPEC_CSTRING, /* role name is stored as a C string */
ROLESPEC_CURRENT_USER, /* role spec is CURRENT_USER */
ROLESPEC_SESSION_USER, /* role spec is SESSION_USER */
ROLESPEC_PUBLIC /* role name is "public" */
} RoleSpecType;
typedef struct RoleSpec
{
NodeTag type;
RoleSpecType roletype; /* Type of this rolespec */
char *rolename; /* filled only for ROLESPEC_CSTRING */
int location; /* token location, or -1 if unknown */
} RoleSpec;
/*
* FuncCall - a function or aggregate invocation
*
@ -1263,7 +1282,7 @@ typedef struct CreateSchemaStmt
{
NodeTag type;
char *schemaname; /* the name of the schema to create */
char *authid; /* the owner of the created schema */
Node *authrole; /* the owner of the created schema */
List *schemaElts; /* schema components (list of parsenodes) */
bool if_not_exists; /* just do nothing if schema already exists? */
} CreateSchemaStmt;
@ -1362,7 +1381,8 @@ typedef struct AlterTableCmd /* one subcommand of an ALTER TABLE */
NodeTag type;
AlterTableType subtype; /* Type of table alteration to apply */
char *name; /* column, constraint, or trigger to act on,
* or new owner or tablespace */
* or tablespace */
Node *newowner; /* RoleSpec */
Node *def; /* definition of new column, index,
* constraint, or parent table */
DropBehavior behavior; /* RESTRICT or CASCADE for DROP cases */
@ -1434,17 +1454,11 @@ typedef struct GrantStmt
* or plain names (as Value strings) */
List *privileges; /* list of AccessPriv nodes */
/* privileges == NIL denotes ALL PRIVILEGES */
List *grantees; /* list of PrivGrantee nodes */
List *grantees; /* list of RoleSpec nodes */
bool grant_option; /* grant or revoke grant option */
DropBehavior behavior; /* drop behavior (for REVOKE) */
} GrantStmt;
typedef struct PrivGrantee
{
NodeTag type;
char *rolname; /* if NULL then PUBLIC */
} PrivGrantee;
/*
* Note: FuncWithArgs carries only the types of the input parameters of the
* function. So it is sufficient to identify an existing function, but it
@ -1487,7 +1501,7 @@ typedef struct GrantRoleStmt
List *grantee_roles; /* list of member roles to add/delete */
bool is_grant; /* true = GRANT, false = REVOKE */
bool admin_opt; /* with admin option */
char *grantor; /* set grantor to other than current role */
Node *grantor; /* set grantor to other than current role */
DropBehavior behavior; /* drop behavior (for REVOKE) */
} GrantRoleStmt;
@ -1699,7 +1713,7 @@ typedef struct CreateTableSpaceStmt
{
NodeTag type;
char *tablespacename;
char *owner;
Node *owner;
char *location;
List *options;
} CreateTableSpaceStmt;
@ -1825,7 +1839,7 @@ typedef struct CreateForeignTableStmt
typedef struct CreateUserMappingStmt
{
NodeTag type;
char *username; /* username or PUBLIC/CURRENT_USER */
Node *user; /* user role */
char *servername; /* server name */
List *options; /* generic options to server */
} CreateUserMappingStmt;
@ -1833,7 +1847,7 @@ typedef struct CreateUserMappingStmt
typedef struct AlterUserMappingStmt
{
NodeTag type;
char *username; /* username or PUBLIC/CURRENT_USER */
Node *user; /* user role */
char *servername; /* server name */
List *options; /* generic options to server */
} AlterUserMappingStmt;
@ -1841,7 +1855,7 @@ typedef struct AlterUserMappingStmt
typedef struct DropUserMappingStmt
{
NodeTag type;
char *username; /* username or PUBLIC/CURRENT_USER */
Node *user; /* user role */
char *servername; /* server name */
bool missing_ok; /* ignore missing mappings */
} DropUserMappingStmt;
@ -1991,7 +2005,7 @@ typedef struct CreateRoleStmt
typedef struct AlterRoleStmt
{
NodeTag type;
char *role; /* role name */
Node *role; /* role */
List *options; /* List of DefElem nodes */
int action; /* +1 = add members, -1 = drop members */
} AlterRoleStmt;
@ -1999,7 +2013,7 @@ typedef struct AlterRoleStmt
typedef struct AlterRoleSetStmt
{
NodeTag type;
char *role; /* role name */
Node *role; /* role */
char *database; /* database name, or NULL */
VariableSetStmt *setstmt; /* SET or RESET subcommand */
} AlterRoleSetStmt;
@ -2375,7 +2389,7 @@ typedef struct AlterOwnerStmt
RangeVar *relation; /* in case it's a table */
List *object; /* in case it's some other object */
List *objarg; /* argument types, if applicable */
char *newowner; /* the new owner */
Node *newowner; /* the new owner */
} AlterOwnerStmt;
@ -2831,7 +2845,7 @@ typedef struct ReassignOwnedStmt
{
NodeTag type;
List *roles;
char *newrole;
Node *newrole;
} ReassignOwnedStmt;
/*

View file

@ -24,6 +24,7 @@
#ifndef ACL_H
#define ACL_H
#include "access/htup.h"
#include "nodes/parsenodes.h"
#include "utils/array.h"
#include "utils/snapshot.h"
@ -227,8 +228,11 @@ extern bool is_member_of_role(Oid member, Oid role);
extern bool is_member_of_role_nosuper(Oid member, Oid role);
extern bool is_admin_of_role(Oid member, Oid role);
extern void check_is_member_of_role(Oid member, Oid role);
extern Oid get_role_oid(const char *rolname, bool missing_ok);
extern Oid get_role_oid_or_public(const char *rolname);
extern Oid get_role_oid(const char *rolename, bool missing_ok);
extern Oid get_role_oid_or_public(const char *rolename);
extern Oid get_rolespec_oid(const Node *node, bool missing_ok);
extern HeapTuple get_rolespec_tuple(const Node *node);
extern char *get_rolespec_name(const Node *node);
extern void select_best_grantor(Oid roleId, AclMode privileges,
const Acl *acl, Oid ownerId,

View file

@ -0,0 +1,940 @@
CREATE OR REPLACE FUNCTION chkrolattr()
RETURNS TABLE ("role" name, rolekeyword text, canlogin bool, replication bool)
AS $$
SELECT r.rolname, v.keyword, r.rolcanlogin, r.rolreplication
FROM pg_roles r
JOIN (VALUES(CURRENT_USER, 'current_user'),
(SESSION_USER, 'session_user'),
('current_user', '-'),
('session_user', '-'),
('Public', '-'),
('None', '-'))
AS v(uname, keyword)
ON (r.rolname = v.uname)
ORDER BY 1;
$$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION chksetconfig()
RETURNS TABLE (db name, "role" name, rolkeyword text, setconfig text[])
AS $$
SELECT COALESCE(d.datname, 'ALL'), COALESCE(r.rolname, 'ALL'),
COALESCE(v.keyword, '-'), s.setconfig
FROM pg_db_role_setting s
LEFT JOIN pg_roles r ON (r.oid = s.setrole)
LEFT JOIN pg_database d ON (d.oid = s.setdatabase)
LEFT JOIN (VALUES(CURRENT_USER, 'current_user'),
(SESSION_USER, 'session_user'))
AS v(uname, keyword)
ON (r.rolname = v.uname)
WHERE (r.rolname) IN ('Public', 'current_user', 'testrol1', 'testrol2')
ORDER BY 1, 2;
$$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION chkumapping()
RETURNS TABLE (umname name, umserver name, umoptions text[])
AS $$
SELECT r.rolname, s.srvname, m.umoptions
FROM pg_user_mapping m
LEFT JOIN pg_roles r ON (r.oid = m.umuser)
JOIN pg_foreign_server s ON (s.oid = m.umserver)
ORDER BY 2;
$$ LANGUAGE SQL;
CREATE ROLE "Public";
CREATE ROLE "None";
CREATE ROLE "current_user";
CREATE ROLE "session_user";
CREATE ROLE "user";
CREATE ROLE current_user; -- error
ERROR: CURRENT_USER cannot be used as a role name
LINE 1: CREATE ROLE current_user;
^
CREATE ROLE current_role; -- error
ERROR: syntax error at or near "current_role"
LINE 1: CREATE ROLE current_role;
^
CREATE ROLE session_user; -- error
ERROR: SESSION_USER cannot be used as a role name
LINE 1: CREATE ROLE session_user;
^
CREATE ROLE user; -- error
ERROR: syntax error at or near "user"
LINE 1: CREATE ROLE user;
^
CREATE ROLE all; -- error
ERROR: syntax error at or near "all"
LINE 1: CREATE ROLE all;
^
CREATE ROLE public; -- error
ERROR: role name "public" is reserved
LINE 1: CREATE ROLE public;
^
CREATE ROLE "public"; -- error
ERROR: role name "public" is reserved
LINE 1: CREATE ROLE "public";
^
CREATE ROLE none; -- error
ERROR: role name "none" is reserved
LINE 1: CREATE ROLE none;
^
CREATE ROLE "none"; -- error
ERROR: role name "none" is reserved
LINE 1: CREATE ROLE "none";
^
CREATE ROLE testrol0 SUPERUSER LOGIN;
CREATE ROLE testrolx SUPERUSER LOGIN;
CREATE ROLE testrol2 SUPERUSER;
CREATE ROLE testrol1 SUPERUSER LOGIN IN ROLE testrol2;
\c -
SET SESSION AUTHORIZATION testrol1;
SET ROLE testrol2;
-- ALTER ROLE
BEGIN;
SELECT * FROM chkrolattr();
role | rolekeyword | canlogin | replication
--------------+--------------+----------+-------------
None | - | f | f
Public | - | f | f
current_user | - | f | f
session_user | - | f | f
testrol1 | session_user | t | f
testrol2 | current_user | f | f
(6 rows)
ALTER ROLE CURRENT_USER WITH REPLICATION;
SELECT * FROM chkrolattr();
role | rolekeyword | canlogin | replication
--------------+--------------+----------+-------------
None | - | f | f
Public | - | f | f
current_user | - | f | f
session_user | - | f | f
testrol1 | session_user | t | f
testrol2 | current_user | f | t
(6 rows)
ALTER ROLE "current_user" WITH REPLICATION;
SELECT * FROM chkrolattr();
role | rolekeyword | canlogin | replication
--------------+--------------+----------+-------------
None | - | f | f
Public | - | f | f
current_user | - | f | t
session_user | - | f | f
testrol1 | session_user | t | f
testrol2 | current_user | f | t
(6 rows)
ALTER ROLE SESSION_USER WITH REPLICATION;
SELECT * FROM chkrolattr();
role | rolekeyword | canlogin | replication
--------------+--------------+----------+-------------
None | - | f | f
Public | - | f | f
current_user | - | f | t
session_user | - | f | f
testrol1 | session_user | t | t
testrol2 | current_user | f | t
(6 rows)
ALTER ROLE "session_user" WITH REPLICATION;
SELECT * FROM chkrolattr();
role | rolekeyword | canlogin | replication
--------------+--------------+----------+-------------
None | - | f | f
Public | - | f | f
current_user | - | f | t
session_user | - | f | t
testrol1 | session_user | t | t
testrol2 | current_user | f | t
(6 rows)
ALTER USER "Public" WITH REPLICATION;
ALTER USER "None" WITH REPLICATION;
SELECT * FROM chkrolattr();
role | rolekeyword | canlogin | replication
--------------+--------------+----------+-------------
None | - | f | t
Public | - | f | t
current_user | - | f | t
session_user | - | f | t
testrol1 | session_user | t | t
testrol2 | current_user | f | t
(6 rows)
ALTER USER testrol1 WITH NOREPLICATION;
ALTER USER testrol2 WITH NOREPLICATION;
SELECT * FROM chkrolattr();
role | rolekeyword | canlogin | replication
--------------+--------------+----------+-------------
None | - | f | t
Public | - | f | t
current_user | - | f | t
session_user | - | f | t
testrol1 | session_user | t | f
testrol2 | current_user | f | f
(6 rows)
ROLLBACK;
ALTER ROLE USER WITH LOGIN; -- error
ERROR: syntax error at or near "USER"
LINE 1: ALTER ROLE USER WITH LOGIN;
^
ALTER ROLE CURRENT_ROLE WITH LOGIN; --error
ERROR: syntax error at or near "CURRENT_ROLE"
LINE 1: ALTER ROLE CURRENT_ROLE WITH LOGIN;
^
ALTER ROLE ALL WITH REPLICATION; -- error
ERROR: syntax error at or near "WITH"
LINE 1: ALTER ROLE ALL WITH REPLICATION;
^
ALTER ROLE SESSION_ROLE WITH NOREPLICATION; -- error
ERROR: role "session_role" does not exist
ALTER ROLE PUBLIC WITH NOREPLICATION; -- error
ERROR: role "public" does not exist
ALTER ROLE "public" WITH NOREPLICATION; -- error
ERROR: role "public" does not exist
ALTER ROLE NONE WITH NOREPLICATION; -- error
ERROR: role name "none" is reserved
LINE 1: ALTER ROLE NONE WITH NOREPLICATION;
^
ALTER ROLE "none" WITH NOREPLICATION; -- error
ERROR: role name "none" is reserved
LINE 1: ALTER ROLE "none" WITH NOREPLICATION;
^
ALTER ROLE nonexistent WITH NOREPLICATION; -- error
ERROR: role "nonexistent" does not exist
-- ALTER USER
BEGIN;
SELECT * FROM chkrolattr();
role | rolekeyword | canlogin | replication
--------------+--------------+----------+-------------
None | - | f | f
Public | - | f | f
current_user | - | f | f
session_user | - | f | f
testrol1 | session_user | t | f
testrol2 | current_user | f | f
(6 rows)
ALTER USER CURRENT_USER WITH REPLICATION;
SELECT * FROM chkrolattr();
role | rolekeyword | canlogin | replication
--------------+--------------+----------+-------------
None | - | f | f
Public | - | f | f
current_user | - | f | f
session_user | - | f | f
testrol1 | session_user | t | f
testrol2 | current_user | f | t
(6 rows)
ALTER USER "current_user" WITH REPLICATION;
SELECT * FROM chkrolattr();
role | rolekeyword | canlogin | replication
--------------+--------------+----------+-------------
None | - | f | f
Public | - | f | f
current_user | - | f | t
session_user | - | f | f
testrol1 | session_user | t | f
testrol2 | current_user | f | t
(6 rows)
ALTER USER SESSION_USER WITH REPLICATION;
SELECT * FROM chkrolattr();
role | rolekeyword | canlogin | replication
--------------+--------------+----------+-------------
None | - | f | f
Public | - | f | f
current_user | - | f | t
session_user | - | f | f
testrol1 | session_user | t | t
testrol2 | current_user | f | t
(6 rows)
ALTER USER "session_user" WITH REPLICATION;
SELECT * FROM chkrolattr();
role | rolekeyword | canlogin | replication
--------------+--------------+----------+-------------
None | - | f | f
Public | - | f | f
current_user | - | f | t
session_user | - | f | t
testrol1 | session_user | t | t
testrol2 | current_user | f | t
(6 rows)
ALTER USER "Public" WITH REPLICATION;
ALTER USER "None" WITH REPLICATION;
SELECT * FROM chkrolattr();
role | rolekeyword | canlogin | replication
--------------+--------------+----------+-------------
None | - | f | t
Public | - | f | t
current_user | - | f | t
session_user | - | f | t
testrol1 | session_user | t | t
testrol2 | current_user | f | t
(6 rows)
ALTER USER testrol1 WITH NOREPLICATION;
ALTER USER testrol2 WITH NOREPLICATION;
SELECT * FROM chkrolattr();
role | rolekeyword | canlogin | replication
--------------+--------------+----------+-------------
None | - | f | t
Public | - | f | t
current_user | - | f | t
session_user | - | f | t
testrol1 | session_user | t | f
testrol2 | current_user | f | f
(6 rows)
ROLLBACK;
ALTER USER USER WITH LOGIN; -- error
ERROR: syntax error at or near "USER"
LINE 1: ALTER USER USER WITH LOGIN;
^
ALTER USER CURRENT_ROLE WITH LOGIN; -- error
ERROR: syntax error at or near "CURRENT_ROLE"
LINE 1: ALTER USER CURRENT_ROLE WITH LOGIN;
^
ALTER USER ALL WITH REPLICATION; -- error
ERROR: syntax error at or near "ALL"
LINE 1: ALTER USER ALL WITH REPLICATION;
^
ALTER USER SESSION_ROLE WITH NOREPLICATION; -- error
ERROR: role "session_role" does not exist
ALTER USER PUBLIC WITH NOREPLICATION; -- error
ERROR: role "public" does not exist
ALTER USER "public" WITH NOREPLICATION; -- error
ERROR: role "public" does not exist
ALTER USER NONE WITH NOREPLICATION; -- error
ERROR: role name "none" is reserved
LINE 1: ALTER USER NONE WITH NOREPLICATION;
^
ALTER USER "none" WITH NOREPLICATION; -- error
ERROR: role name "none" is reserved
LINE 1: ALTER USER "none" WITH NOREPLICATION;
^
ALTER USER nonexistent WITH NOREPLICATION; -- error
ERROR: role "nonexistent" does not exist
-- ALTER ROLE SET/RESET
SELECT * FROM chksetconfig();
db | role | rolkeyword | setconfig
----+------+------------+-----------
(0 rows)
ALTER ROLE CURRENT_USER SET application_name to 'FOO';
ALTER ROLE SESSION_USER SET application_name to 'BAR';
ALTER ROLE "current_user" SET application_name to 'FOOFOO';
ALTER ROLE "Public" SET application_name to 'BARBAR';
ALTER ROLE ALL SET application_name to 'SLAP';
SELECT * FROM chksetconfig();
db | role | rolkeyword | setconfig
-----+--------------+--------------+---------------------------
ALL | Public | - | {application_name=BARBAR}
ALL | current_user | - | {application_name=FOOFOO}
ALL | testrol1 | session_user | {application_name=BAR}
ALL | testrol2 | current_user | {application_name=FOO}
(4 rows)
ALTER ROLE testrol1 SET application_name to 'SLAM';
SELECT * FROM chksetconfig();
db | role | rolkeyword | setconfig
-----+--------------+--------------+---------------------------
ALL | Public | - | {application_name=BARBAR}
ALL | current_user | - | {application_name=FOOFOO}
ALL | testrol1 | session_user | {application_name=SLAM}
ALL | testrol2 | current_user | {application_name=FOO}
(4 rows)
ALTER ROLE CURRENT_USER RESET application_name;
ALTER ROLE SESSION_USER RESET application_name;
ALTER ROLE "current_user" RESET application_name;
ALTER ROLE "Public" RESET application_name;
ALTER ROLE ALL RESET application_name;
SELECT * FROM chksetconfig();
db | role | rolkeyword | setconfig
----+------+------------+-----------
(0 rows)
ALTER ROLE CURRENT_ROLE SET application_name to 'BAZ'; -- error
ERROR: syntax error at or near "CURRENT_ROLE"
LINE 1: ALTER ROLE CURRENT_ROLE SET application_name to 'BAZ';
^
ALTER ROLE USER SET application_name to 'BOOM'; -- error
ERROR: syntax error at or near "USER"
LINE 1: ALTER ROLE USER SET application_name to 'BOOM';
^
ALTER ROLE PUBLIC SET application_name to 'BOMB'; -- error
ERROR: role "public" does not exist
ALTER ROLE nonexistent SET application_name to 'BOMB'; -- error
ERROR: role "nonexistent" does not exist
-- ALTER USER SET/RESET
SELECT * FROM chksetconfig();
db | role | rolkeyword | setconfig
----+------+------------+-----------
(0 rows)
ALTER USER CURRENT_USER SET application_name to 'FOO';
ALTER USER SESSION_USER SET application_name to 'BAR';
ALTER USER "current_user" SET application_name to 'FOOFOO';
ALTER USER "Public" SET application_name to 'BARBAR';
ALTER USER ALL SET application_name to 'SLAP';
ERROR: syntax error at or near "ALL"
LINE 1: ALTER USER ALL SET application_name to 'SLAP';
^
SELECT * FROM chksetconfig();
db | role | rolkeyword | setconfig
-----+--------------+--------------+---------------------------
ALL | Public | - | {application_name=BARBAR}
ALL | current_user | - | {application_name=FOOFOO}
ALL | testrol1 | session_user | {application_name=BAR}
ALL | testrol2 | current_user | {application_name=FOO}
(4 rows)
ALTER USER testrol1 SET application_name to 'SLAM';
SELECT * FROM chksetconfig();
db | role | rolkeyword | setconfig
-----+--------------+--------------+---------------------------
ALL | Public | - | {application_name=BARBAR}
ALL | current_user | - | {application_name=FOOFOO}
ALL | testrol1 | session_user | {application_name=SLAM}
ALL | testrol2 | current_user | {application_name=FOO}
(4 rows)
ALTER USER CURRENT_USER RESET application_name;
ALTER USER SESSION_USER RESET application_name;
ALTER USER "current_user" RESET application_name;
ALTER USER "Public" RESET application_name;
ALTER USER ALL RESET application_name;
ERROR: syntax error at or near "ALL"
LINE 1: ALTER USER ALL RESET application_name;
^
SELECT * FROM chksetconfig();
db | role | rolkeyword | setconfig
----+------+------------+-----------
(0 rows)
ALTER USER CURRENT_USER SET application_name to 'BAZ'; -- error
ALTER USER USER SET application_name to 'BOOM'; -- error
ERROR: syntax error at or near "USER"
LINE 1: ALTER USER USER SET application_name to 'BOOM';
^
ALTER USER PUBLIC SET application_name to 'BOMB'; -- error
ERROR: role "public" does not exist
ALTER USER NONE SET application_name to 'BOMB'; -- error
ERROR: role name "none" is reserved
LINE 1: ALTER USER NONE SET application_name to 'BOMB';
^
ALTER USER nonexistent SET application_name to 'BOMB'; -- error
ERROR: role "nonexistent" does not exist
-- CREAETE SCHEMA
set client_min_messages to error;
CREATE SCHEMA newschema1 AUTHORIZATION CURRENT_USER;
CREATE SCHEMA newschema2 AUTHORIZATION "current_user";
CREATE SCHEMA newschema3 AUTHORIZATION SESSION_USER;
CREATE SCHEMA newschema4 AUTHORIZATION testrolx;
CREATE SCHEMA newschema5 AUTHORIZATION "Public";
CREATE SCHEMA newschema6 AUTHORIZATION USER; -- error
ERROR: syntax error at or near "USER"
LINE 1: CREATE SCHEMA newschema6 AUTHORIZATION USER;
^
CREATE SCHEMA newschema6 AUTHORIZATION CURRENT_ROLE; -- error
ERROR: syntax error at or near "CURRENT_ROLE"
LINE 1: CREATE SCHEMA newschema6 AUTHORIZATION CURRENT_ROLE;
^
CREATE SCHEMA newschema6 AUTHORIZATION PUBLIC; -- error
ERROR: role "public" does not exist
CREATE SCHEMA newschema6 AUTHORIZATION "public"; -- error
ERROR: role "public" does not exist
CREATE SCHEMA newschema6 AUTHORIZATION NONE; -- error
ERROR: role name "none" is reserved
LINE 1: CREATE SCHEMA newschema6 AUTHORIZATION NONE;
^
CREATE SCHEMA newschema6 AUTHORIZATION nonexistent; -- error
ERROR: role "nonexistent" does not exist
SELECT n.nspname, r.rolname FROM pg_namespace n
JOIN pg_roles r ON (r.oid = n.nspowner)
WHERE n.nspname LIKE 'newschema_' ORDER BY 1;
nspname | rolname
------------+--------------
newschema1 | testrol2
newschema2 | current_user
newschema3 | testrol1
newschema4 | testrolx
newschema5 | Public
(5 rows)
CREATE SCHEMA IF NOT EXISTS newschema1 AUTHORIZATION CURRENT_USER;
CREATE SCHEMA IF NOT EXISTS newschema2 AUTHORIZATION "current_user";
CREATE SCHEMA IF NOT EXISTS newschema3 AUTHORIZATION SESSION_USER;
CREATE SCHEMA IF NOT EXISTS newschema4 AUTHORIZATION testrolx;
CREATE SCHEMA IF NOT EXISTS newschema5 AUTHORIZATION "Public";
CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION USER; -- error
ERROR: syntax error at or near "USER"
LINE 1: CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION USER;
^
CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION CURRENT_ROLE; -- error
ERROR: syntax error at or near "CURRENT_ROLE"
LINE 1: ...ATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION CURRENT_RO...
^
CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION PUBLIC; -- error
ERROR: role "public" does not exist
CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION "public"; -- error
ERROR: role "public" does not exist
CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION NONE; -- error
ERROR: role name "none" is reserved
LINE 1: CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION NONE;
^
CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION nonexistent; -- error
ERROR: role "nonexistent" does not exist
SELECT n.nspname, r.rolname FROM pg_namespace n
JOIN pg_roles r ON (r.oid = n.nspowner)
WHERE n.nspname LIKE 'newschema_' ORDER BY 1;
nspname | rolname
------------+--------------
newschema1 | testrol2
newschema2 | current_user
newschema3 | testrol1
newschema4 | testrolx
newschema5 | Public
(5 rows)
-- ALTER TABLE OWNER TO
\c -
SET SESSION AUTHORIZATION testrol0;
set client_min_messages to error;
CREATE TABLE testtab1 (a int);
CREATE TABLE testtab2 (a int);
CREATE TABLE testtab3 (a int);
CREATE TABLE testtab4 (a int);
CREATE TABLE testtab5 (a int);
CREATE TABLE testtab6 (a int);
\c -
SET SESSION AUTHORIZATION testrol1;
SET ROLE testrol2;
ALTER TABLE testtab1 OWNER TO CURRENT_USER;
ALTER TABLE testtab2 OWNER TO "current_user";
ALTER TABLE testtab3 OWNER TO SESSION_USER;
ALTER TABLE testtab4 OWNER TO testrolx;
ALTER TABLE testtab5 OWNER TO "Public";
ALTER TABLE testtab6 OWNER TO CURRENT_ROLE; -- error
ERROR: syntax error at or near "CURRENT_ROLE"
LINE 1: ALTER TABLE testtab6 OWNER TO CURRENT_ROLE;
^
ALTER TABLE testtab6 OWNER TO USER; --error
ERROR: syntax error at or near "USER"
LINE 1: ALTER TABLE testtab6 OWNER TO USER;
^
ALTER TABLE testtab6 OWNER TO PUBLIC; -- error
ERROR: role "public" does not exist
ALTER TABLE testtab6 OWNER TO "public"; -- error
ERROR: role "public" does not exist
ALTER TABLE testtab6 OWNER TO nonexistent; -- error
ERROR: role "nonexistent" does not exist
SELECT c.relname, r.rolname
FROM pg_class c JOIN pg_roles r ON (r.oid = c.relowner)
WHERE relname LIKE 'testtab_'
ORDER BY 1;
relname | rolname
----------+--------------
testtab1 | testrol2
testtab2 | current_user
testtab3 | testrol1
testtab4 | testrolx
testtab5 | Public
testtab6 | testrol0
(6 rows)
-- ALTER TABLE, VIEW, MATERIALIZED VIEW, FOREIGN TABLE, SEQUENCE are
-- changed their owner in the same way.
-- ALTER AGGREGATE
\c -
SET SESSION AUTHORIZATION testrol0;
CREATE AGGREGATE testagg1(int2) (SFUNC = int2_sum, STYPE = int8);
CREATE AGGREGATE testagg2(int2) (SFUNC = int2_sum, STYPE = int8);
CREATE AGGREGATE testagg3(int2) (SFUNC = int2_sum, STYPE = int8);
CREATE AGGREGATE testagg4(int2) (SFUNC = int2_sum, STYPE = int8);
CREATE AGGREGATE testagg5(int2) (SFUNC = int2_sum, STYPE = int8);
CREATE AGGREGATE testagg5(int2) (SFUNC = int2_sum, STYPE = int8);
ERROR: function "testagg5" already exists with same argument types
CREATE AGGREGATE testagg6(int2) (SFUNC = int2_sum, STYPE = int8);
CREATE AGGREGATE testagg7(int2) (SFUNC = int2_sum, STYPE = int8);
CREATE AGGREGATE testagg8(int2) (SFUNC = int2_sum, STYPE = int8);
CREATE AGGREGATE testagg9(int2) (SFUNC = int2_sum, STYPE = int8);
\c -
SET SESSION AUTHORIZATION testrol1;
SET ROLE testrol2;
ALTER AGGREGATE testagg1(int2) OWNER TO CURRENT_USER;
ALTER AGGREGATE testagg2(int2) OWNER TO "current_user";
ALTER AGGREGATE testagg3(int2) OWNER TO SESSION_USER;
ALTER AGGREGATE testagg4(int2) OWNER TO testrolx;
ALTER AGGREGATE testagg5(int2) OWNER TO "Public";
ALTER AGGREGATE testagg5(int2) OWNER TO CURRENT_ROLE; -- error
ERROR: syntax error at or near "CURRENT_ROLE"
LINE 1: ALTER AGGREGATE testagg5(int2) OWNER TO CURRENT_ROLE;
^
ALTER AGGREGATE testagg5(int2) OWNER TO USER; -- error
ERROR: syntax error at or near "USER"
LINE 1: ALTER AGGREGATE testagg5(int2) OWNER TO USER;
^
ALTER AGGREGATE testagg5(int2) OWNER TO PUBLIC; -- error
ERROR: role "public" does not exist
ALTER AGGREGATE testagg5(int2) OWNER TO "public"; -- error
ERROR: role "public" does not exist
ALTER AGGREGATE testagg5(int2) OWNER TO nonexistent; -- error
ERROR: role "nonexistent" does not exist
SELECT p.proname, r.rolname
FROM pg_proc p JOIN pg_roles r ON (r.oid = p.proowner)
WHERE proname LIKE 'testagg_'
ORDER BY 1;
proname | rolname
----------+--------------
testagg1 | testrol2
testagg2 | current_user
testagg3 | testrol1
testagg4 | testrolx
testagg5 | Public
testagg6 | testrol0
testagg7 | testrol0
testagg8 | testrol0
testagg9 | testrol0
(9 rows)
-- CREATE USER MAPPING
CREATE FOREIGN DATA WRAPPER test_wrapper;
CREATE SERVER sv1 FOREIGN DATA WRAPPER test_wrapper;
CREATE SERVER sv2 FOREIGN DATA WRAPPER test_wrapper;
CREATE SERVER sv3 FOREIGN DATA WRAPPER test_wrapper;
CREATE SERVER sv4 FOREIGN DATA WRAPPER test_wrapper;
CREATE SERVER sv5 FOREIGN DATA WRAPPER test_wrapper;
CREATE SERVER sv6 FOREIGN DATA WRAPPER test_wrapper;
CREATE SERVER sv7 FOREIGN DATA WRAPPER test_wrapper;
CREATE SERVER sv8 FOREIGN DATA WRAPPER test_wrapper;
CREATE SERVER sv9 FOREIGN DATA WRAPPER test_wrapper;
CREATE USER MAPPING FOR CURRENT_USER SERVER sv1 OPTIONS (user 'CURRENT_USER');
CREATE USER MAPPING FOR "current_user" SERVER sv2 OPTIONS (user '"current_user"');
CREATE USER MAPPING FOR USER SERVER sv3 OPTIONS (user 'USER');
CREATE USER MAPPING FOR "user" SERVER sv4 OPTIONS (user '"USER"');
CREATE USER MAPPING FOR SESSION_USER SERVER sv5 OPTIONS (user 'SESSION_USER');
CREATE USER MAPPING FOR PUBLIC SERVER sv6 OPTIONS (user 'PUBLIC');
CREATE USER MAPPING FOR "Public" SERVER sv7 OPTIONS (user '"Public"');
CREATE USER MAPPING FOR testrolx SERVER sv8 OPTIONS (user 'testrolx');
CREATE USER MAPPING FOR CURRENT_ROLE SERVER sv9
OPTIONS (user 'CURRENT_ROLE'); -- error
ERROR: syntax error at or near "CURRENT_ROLE"
LINE 1: CREATE USER MAPPING FOR CURRENT_ROLE SERVER sv9
^
CREATE USER MAPPING FOR nonexistent SERVER sv9
OPTIONS (user 'nonexistent'); -- error;
ERROR: role "nonexistent" does not exist
SELECT * FROM chkumapping();
umname | umserver | umoptions
--------------+----------+---------------------------
testrol2 | sv1 | {user=CURRENT_USER}
current_user | sv2 | {"user=\"current_user\""}
testrol2 | sv3 | {user=USER}
user | sv4 | {"user=\"USER\""}
testrol1 | sv5 | {user=SESSION_USER}
| sv6 | {user=PUBLIC}
Public | sv7 | {"user=\"Public\""}
testrolx | sv8 | {user=testrolx}
(8 rows)
-- ALTER USER MAPPING
ALTER USER MAPPING FOR CURRENT_USER SERVER sv1
OPTIONS (SET user 'CURRENT_USER_alt');
ALTER USER MAPPING FOR "current_user" SERVER sv2
OPTIONS (SET user '"current_user"_alt');
ALTER USER MAPPING FOR USER SERVER sv3
OPTIONS (SET user 'USER_alt');
ALTER USER MAPPING FOR "user" SERVER sv4
OPTIONS (SET user '"user"_alt');
ALTER USER MAPPING FOR SESSION_USER SERVER sv5
OPTIONS (SET user 'SESSION_USER_alt');
ALTER USER MAPPING FOR PUBLIC SERVER sv6
OPTIONS (SET user 'public_alt');
ALTER USER MAPPING FOR "Public" SERVER sv7
OPTIONS (SET user '"Public"_alt');
ALTER USER MAPPING FOR testrolx SERVER sv8
OPTIONS (SET user 'testrolx_alt');
ALTER USER MAPPING FOR CURRENT_ROLE SERVER sv9
OPTIONS (SET user 'CURRENT_ROLE_alt');
ERROR: syntax error at or near "CURRENT_ROLE"
LINE 1: ALTER USER MAPPING FOR CURRENT_ROLE SERVER sv9
^
ALTER USER MAPPING FOR nonexistent SERVER sv9
OPTIONS (SET user 'nonexistent_alt'); -- error
ERROR: role "nonexistent" does not exist
SELECT * FROM chkumapping();
umname | umserver | umoptions
--------------+----------+-------------------------------
testrol2 | sv1 | {user=CURRENT_USER_alt}
current_user | sv2 | {"user=\"current_user\"_alt"}
testrol2 | sv3 | {user=USER_alt}
user | sv4 | {"user=\"user\"_alt"}
testrol1 | sv5 | {user=SESSION_USER_alt}
| sv6 | {user=public_alt}
Public | sv7 | {"user=\"Public\"_alt"}
testrolx | sv8 | {user=testrolx_alt}
(8 rows)
-- DROP USER MAPPING
DROP USER MAPPING FOR CURRENT_USER SERVER sv1;
DROP USER MAPPING FOR "current_user" SERVER sv2;
DROP USER MAPPING FOR USER SERVER sv3;
DROP USER MAPPING FOR "user" SERVER sv4;
DROP USER MAPPING FOR SESSION_USER SERVER sv5;
DROP USER MAPPING FOR PUBLIC SERVER sv6;
DROP USER MAPPING FOR "Public" SERVER sv7;
DROP USER MAPPING FOR testrolx SERVER sv8;
DROP USER MAPPING FOR CURRENT_ROLE SERVER sv9; -- error
ERROR: syntax error at or near "CURRENT_ROLE"
LINE 1: DROP USER MAPPING FOR CURRENT_ROLE SERVER sv9;
^
DROP USER MAPPING FOR nonexistent SERVER sv; -- error
ERROR: role "nonexistent" does not exist
SELECT * FROM chkumapping();
umname | umserver | umoptions
--------+----------+-----------
(0 rows)
CREATE USER MAPPING FOR CURRENT_USER SERVER sv1 OPTIONS (user 'CURRENT_USER');
CREATE USER MAPPING FOR "current_user" SERVER sv2 OPTIONS (user '"current_user"');
CREATE USER MAPPING FOR USER SERVER sv3 OPTIONS (user 'USER');
CREATE USER MAPPING FOR "user" SERVER sv4 OPTIONS (user '"USER"');
CREATE USER MAPPING FOR SESSION_USER SERVER sv5 OPTIONS (user 'SESSION_USER');
CREATE USER MAPPING FOR PUBLIC SERVER sv6 OPTIONS (user 'PUBLIC');
CREATE USER MAPPING FOR "Public" SERVER sv7 OPTIONS (user '"Public"');
CREATE USER MAPPING FOR testrolx SERVER sv8 OPTIONS (user 'testrolx');
SELECT * FROM chkumapping();
umname | umserver | umoptions
--------------+----------+---------------------------
testrol2 | sv1 | {user=CURRENT_USER}
current_user | sv2 | {"user=\"current_user\""}
testrol2 | sv3 | {user=USER}
user | sv4 | {"user=\"USER\""}
testrol1 | sv5 | {user=SESSION_USER}
| sv6 | {user=PUBLIC}
Public | sv7 | {"user=\"Public\""}
testrolx | sv8 | {user=testrolx}
(8 rows)
-- DROP USER MAPPING IF EXISTS
DROP USER MAPPING IF EXISTS FOR CURRENT_USER SERVER sv1;
SELECT * FROM chkumapping();
umname | umserver | umoptions
--------------+----------+---------------------------
current_user | sv2 | {"user=\"current_user\""}
testrol2 | sv3 | {user=USER}
user | sv4 | {"user=\"USER\""}
testrol1 | sv5 | {user=SESSION_USER}
| sv6 | {user=PUBLIC}
Public | sv7 | {"user=\"Public\""}
testrolx | sv8 | {user=testrolx}
(7 rows)
DROP USER MAPPING IF EXISTS FOR "current_user" SERVER sv2;
SELECT * FROM chkumapping();
umname | umserver | umoptions
----------+----------+---------------------
testrol2 | sv3 | {user=USER}
user | sv4 | {"user=\"USER\""}
testrol1 | sv5 | {user=SESSION_USER}
| sv6 | {user=PUBLIC}
Public | sv7 | {"user=\"Public\""}
testrolx | sv8 | {user=testrolx}
(6 rows)
DROP USER MAPPING IF EXISTS FOR USER SERVER sv3;
SELECT * FROM chkumapping();
umname | umserver | umoptions
----------+----------+---------------------
user | sv4 | {"user=\"USER\""}
testrol1 | sv5 | {user=SESSION_USER}
| sv6 | {user=PUBLIC}
Public | sv7 | {"user=\"Public\""}
testrolx | sv8 | {user=testrolx}
(5 rows)
DROP USER MAPPING IF EXISTS FOR "user" SERVER sv4;
SELECT * FROM chkumapping();
umname | umserver | umoptions
----------+----------+---------------------
testrol1 | sv5 | {user=SESSION_USER}
| sv6 | {user=PUBLIC}
Public | sv7 | {"user=\"Public\""}
testrolx | sv8 | {user=testrolx}
(4 rows)
DROP USER MAPPING IF EXISTS FOR SESSION_USER SERVER sv5;
SELECT * FROM chkumapping();
umname | umserver | umoptions
----------+----------+---------------------
| sv6 | {user=PUBLIC}
Public | sv7 | {"user=\"Public\""}
testrolx | sv8 | {user=testrolx}
(3 rows)
DROP USER MAPPING IF EXISTS FOR PUBLIC SERVER sv6;
SELECT * FROM chkumapping();
umname | umserver | umoptions
----------+----------+---------------------
Public | sv7 | {"user=\"Public\""}
testrolx | sv8 | {user=testrolx}
(2 rows)
DROP USER MAPPING IF EXISTS FOR "Public" SERVER sv7;
SELECT * FROM chkumapping();
umname | umserver | umoptions
----------+----------+-----------------
testrolx | sv8 | {user=testrolx}
(1 row)
DROP USER MAPPING IF EXISTS FOR testrolx SERVER sv8;
SELECT * FROM chkumapping();
umname | umserver | umoptions
--------+----------+-----------
(0 rows)
DROP USER MAPPING IF EXISTS FOR CURRENT_ROLE SERVER sv9; --error
ERROR: syntax error at or near "CURRENT_ROLE"
LINE 1: DROP USER MAPPING IF EXISTS FOR CURRENT_ROLE SERVER sv9;
^
DROP USER MAPPING IF EXISTS FOR nonexistent SERVER sv9; -- error
NOTICE: role "nonexistent" does not exist, skipping
-- GRANT/REVOKE
UPDATE pg_proc SET proacl = null WHERE proname LIKE 'testagg_';
SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_';
proname | proacl
----------+--------
testagg1 |
testagg2 |
testagg3 |
testagg4 |
testagg5 |
testagg6 |
testagg7 |
testagg8 |
testagg9 |
(9 rows)
REVOKE ALL PRIVILEGES ON FUNCTION testagg1(int2) FROM PUBLIC;
REVOKE ALL PRIVILEGES ON FUNCTION testagg2(int2) FROM PUBLIC;
REVOKE ALL PRIVILEGES ON FUNCTION testagg3(int2) FROM PUBLIC;
REVOKE ALL PRIVILEGES ON FUNCTION testagg4(int2) FROM PUBLIC;
REVOKE ALL PRIVILEGES ON FUNCTION testagg5(int2) FROM PUBLIC;
REVOKE ALL PRIVILEGES ON FUNCTION testagg6(int2) FROM PUBLIC;
REVOKE ALL PRIVILEGES ON FUNCTION testagg7(int2) FROM PUBLIC;
REVOKE ALL PRIVILEGES ON FUNCTION testagg8(int2) FROM PUBLIC;
GRANT ALL PRIVILEGES ON FUNCTION testagg1(int2) TO PUBLIC;
GRANT ALL PRIVILEGES ON FUNCTION testagg2(int2) TO CURRENT_USER;
GRANT ALL PRIVILEGES ON FUNCTION testagg3(int2) TO "current_user";
GRANT ALL PRIVILEGES ON FUNCTION testagg4(int2) TO SESSION_USER;
GRANT ALL PRIVILEGES ON FUNCTION testagg5(int2) TO "Public";
GRANT ALL PRIVILEGES ON FUNCTION testagg6(int2) TO testrolx;
GRANT ALL PRIVILEGES ON FUNCTION testagg7(int2) TO "public";
GRANT ALL PRIVILEGES ON FUNCTION testagg8(int2)
TO current_user, public, testrolx;
SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_';
proname | proacl
----------+---------------------------------------------------------------------------
testagg1 | {testrol2=X/testrol2,=X/testrol2}
testagg2 | {current_user=X/current_user,testrol2=X/current_user}
testagg3 | {testrol1=X/testrol1,current_user=X/testrol1}
testagg4 | {testrolx=X/testrolx,testrol1=X/testrolx}
testagg5 | {Public=X/Public}
testagg6 | {testrol0=X/testrol0,testrolx=X/testrol0}
testagg7 | {testrol0=X/testrol0,=X/testrol0}
testagg8 | {testrol0=X/testrol0,testrol2=X/testrol0,=X/testrol0,testrolx=X/testrol0}
testagg9 |
(9 rows)
GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO CURRENT_ROLE; --error
ERROR: syntax error at or near "CURRENT_ROLE"
LINE 1: ...RANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO CURRENT_RO...
^
GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO USER; --error
ERROR: syntax error at or near "USER"
LINE 1: GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO USER;
^
GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO NONE; --error
ERROR: role name "none" is reserved
LINE 1: GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO NONE;
^
GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO "none"; --error
ERROR: role name "none" is reserved
LINE 1: GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO "none";
^
SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_';
proname | proacl
----------+---------------------------------------------------------------------------
testagg1 | {testrol2=X/testrol2,=X/testrol2}
testagg2 | {current_user=X/current_user,testrol2=X/current_user}
testagg3 | {testrol1=X/testrol1,current_user=X/testrol1}
testagg4 | {testrolx=X/testrolx,testrol1=X/testrolx}
testagg5 | {Public=X/Public}
testagg6 | {testrol0=X/testrol0,testrolx=X/testrol0}
testagg7 | {testrol0=X/testrol0,=X/testrol0}
testagg8 | {testrol0=X/testrol0,testrol2=X/testrol0,=X/testrol0,testrolx=X/testrol0}
testagg9 |
(9 rows)
REVOKE ALL PRIVILEGES ON FUNCTION testagg1(int2) FROM PUBLIC;
REVOKE ALL PRIVILEGES ON FUNCTION testagg2(int2) FROM CURRENT_USER;
REVOKE ALL PRIVILEGES ON FUNCTION testagg3(int2) FROM "current_user";
REVOKE ALL PRIVILEGES ON FUNCTION testagg4(int2) FROM SESSION_USER;
REVOKE ALL PRIVILEGES ON FUNCTION testagg5(int2) FROM "Public";
REVOKE ALL PRIVILEGES ON FUNCTION testagg6(int2) FROM testrolx;
REVOKE ALL PRIVILEGES ON FUNCTION testagg7(int2) FROM "public";
REVOKE ALL PRIVILEGES ON FUNCTION testagg8(int2)
FROM current_user, public, testrolx;
SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_';
proname | proacl
----------+-------------------------------
testagg1 | {testrol2=X/testrol2}
testagg2 | {current_user=X/current_user}
testagg3 | {testrol1=X/testrol1}
testagg4 | {testrolx=X/testrolx}
testagg5 | {}
testagg6 | {testrol0=X/testrol0}
testagg7 | {testrol0=X/testrol0}
testagg8 | {testrol0=X/testrol0}
testagg9 |
(9 rows)
REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM CURRENT_ROLE; --error
ERROR: syntax error at or near "CURRENT_ROLE"
LINE 1: ...KE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM CURRENT_RO...
^
REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM USER; --error
ERROR: syntax error at or near "USER"
LINE 1: REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM USER;
^
REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM NONE; --error
ERROR: role name "none" is reserved
LINE 1: REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM NONE;
^
REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM "none"; --error
ERROR: role name "none" is reserved
LINE 1: ...EVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM "none";
^
SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_';
proname | proacl
----------+-------------------------------
testagg1 | {testrol2=X/testrol2}
testagg2 | {current_user=X/current_user}
testagg3 | {testrol1=X/testrol1}
testagg4 | {testrolx=X/testrolx}
testagg5 | {}
testagg6 | {testrol0=X/testrol0}
testagg7 | {testrol0=X/testrol0}
testagg8 | {testrol0=X/testrol0}
testagg9 |
(9 rows)
-- clean up
\c
DROP OWNED BY testrol0, "Public", "current_user", testrol1, testrol2, testrolx CASCADE;
DROP ROLE testrol0, testrol1, testrol2, testrolx;
DROP ROLE "Public", "None", "current_user", "session_user", "user";

View file

@ -59,7 +59,7 @@ test: create_index create_view
# ----------
# Another group of parallel tests
# ----------
test: create_aggregate create_function_3 create_cast constraints triggers inherit create_table_like typed_table vacuum drop_if_exists updatable_views
test: create_aggregate create_function_3 create_cast constraints triggers inherit create_table_like typed_table vacuum drop_if_exists updatable_views rolenames
# ----------
# sanity_check does a vacuum, affecting the sort order of SELECT *

View file

@ -71,6 +71,7 @@ test: typed_table
test: vacuum
test: drop_if_exists
test: updatable_views
test: rolenames
test: sanity_check
test: errors
test: select

View file

@ -0,0 +1,434 @@
CREATE OR REPLACE FUNCTION chkrolattr()
RETURNS TABLE ("role" name, rolekeyword text, canlogin bool, replication bool)
AS $$
SELECT r.rolname, v.keyword, r.rolcanlogin, r.rolreplication
FROM pg_roles r
JOIN (VALUES(CURRENT_USER, 'current_user'),
(SESSION_USER, 'session_user'),
('current_user', '-'),
('session_user', '-'),
('Public', '-'),
('None', '-'))
AS v(uname, keyword)
ON (r.rolname = v.uname)
ORDER BY 1;
$$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION chksetconfig()
RETURNS TABLE (db name, "role" name, rolkeyword text, setconfig text[])
AS $$
SELECT COALESCE(d.datname, 'ALL'), COALESCE(r.rolname, 'ALL'),
COALESCE(v.keyword, '-'), s.setconfig
FROM pg_db_role_setting s
LEFT JOIN pg_roles r ON (r.oid = s.setrole)
LEFT JOIN pg_database d ON (d.oid = s.setdatabase)
LEFT JOIN (VALUES(CURRENT_USER, 'current_user'),
(SESSION_USER, 'session_user'))
AS v(uname, keyword)
ON (r.rolname = v.uname)
WHERE (r.rolname) IN ('Public', 'current_user', 'testrol1', 'testrol2')
ORDER BY 1, 2;
$$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION chkumapping()
RETURNS TABLE (umname name, umserver name, umoptions text[])
AS $$
SELECT r.rolname, s.srvname, m.umoptions
FROM pg_user_mapping m
LEFT JOIN pg_roles r ON (r.oid = m.umuser)
JOIN pg_foreign_server s ON (s.oid = m.umserver)
ORDER BY 2;
$$ LANGUAGE SQL;
CREATE ROLE "Public";
CREATE ROLE "None";
CREATE ROLE "current_user";
CREATE ROLE "session_user";
CREATE ROLE "user";
CREATE ROLE current_user; -- error
CREATE ROLE current_role; -- error
CREATE ROLE session_user; -- error
CREATE ROLE user; -- error
CREATE ROLE all; -- error
CREATE ROLE public; -- error
CREATE ROLE "public"; -- error
CREATE ROLE none; -- error
CREATE ROLE "none"; -- error
CREATE ROLE testrol0 SUPERUSER LOGIN;
CREATE ROLE testrolx SUPERUSER LOGIN;
CREATE ROLE testrol2 SUPERUSER;
CREATE ROLE testrol1 SUPERUSER LOGIN IN ROLE testrol2;
\c -
SET SESSION AUTHORIZATION testrol1;
SET ROLE testrol2;
-- ALTER ROLE
BEGIN;
SELECT * FROM chkrolattr();
ALTER ROLE CURRENT_USER WITH REPLICATION;
SELECT * FROM chkrolattr();
ALTER ROLE "current_user" WITH REPLICATION;
SELECT * FROM chkrolattr();
ALTER ROLE SESSION_USER WITH REPLICATION;
SELECT * FROM chkrolattr();
ALTER ROLE "session_user" WITH REPLICATION;
SELECT * FROM chkrolattr();
ALTER USER "Public" WITH REPLICATION;
ALTER USER "None" WITH REPLICATION;
SELECT * FROM chkrolattr();
ALTER USER testrol1 WITH NOREPLICATION;
ALTER USER testrol2 WITH NOREPLICATION;
SELECT * FROM chkrolattr();
ROLLBACK;
ALTER ROLE USER WITH LOGIN; -- error
ALTER ROLE CURRENT_ROLE WITH LOGIN; --error
ALTER ROLE ALL WITH REPLICATION; -- error
ALTER ROLE SESSION_ROLE WITH NOREPLICATION; -- error
ALTER ROLE PUBLIC WITH NOREPLICATION; -- error
ALTER ROLE "public" WITH NOREPLICATION; -- error
ALTER ROLE NONE WITH NOREPLICATION; -- error
ALTER ROLE "none" WITH NOREPLICATION; -- error
ALTER ROLE nonexistent WITH NOREPLICATION; -- error
-- ALTER USER
BEGIN;
SELECT * FROM chkrolattr();
ALTER USER CURRENT_USER WITH REPLICATION;
SELECT * FROM chkrolattr();
ALTER USER "current_user" WITH REPLICATION;
SELECT * FROM chkrolattr();
ALTER USER SESSION_USER WITH REPLICATION;
SELECT * FROM chkrolattr();
ALTER USER "session_user" WITH REPLICATION;
SELECT * FROM chkrolattr();
ALTER USER "Public" WITH REPLICATION;
ALTER USER "None" WITH REPLICATION;
SELECT * FROM chkrolattr();
ALTER USER testrol1 WITH NOREPLICATION;
ALTER USER testrol2 WITH NOREPLICATION;
SELECT * FROM chkrolattr();
ROLLBACK;
ALTER USER USER WITH LOGIN; -- error
ALTER USER CURRENT_ROLE WITH LOGIN; -- error
ALTER USER ALL WITH REPLICATION; -- error
ALTER USER SESSION_ROLE WITH NOREPLICATION; -- error
ALTER USER PUBLIC WITH NOREPLICATION; -- error
ALTER USER "public" WITH NOREPLICATION; -- error
ALTER USER NONE WITH NOREPLICATION; -- error
ALTER USER "none" WITH NOREPLICATION; -- error
ALTER USER nonexistent WITH NOREPLICATION; -- error
-- ALTER ROLE SET/RESET
SELECT * FROM chksetconfig();
ALTER ROLE CURRENT_USER SET application_name to 'FOO';
ALTER ROLE SESSION_USER SET application_name to 'BAR';
ALTER ROLE "current_user" SET application_name to 'FOOFOO';
ALTER ROLE "Public" SET application_name to 'BARBAR';
ALTER ROLE ALL SET application_name to 'SLAP';
SELECT * FROM chksetconfig();
ALTER ROLE testrol1 SET application_name to 'SLAM';
SELECT * FROM chksetconfig();
ALTER ROLE CURRENT_USER RESET application_name;
ALTER ROLE SESSION_USER RESET application_name;
ALTER ROLE "current_user" RESET application_name;
ALTER ROLE "Public" RESET application_name;
ALTER ROLE ALL RESET application_name;
SELECT * FROM chksetconfig();
ALTER ROLE CURRENT_ROLE SET application_name to 'BAZ'; -- error
ALTER ROLE USER SET application_name to 'BOOM'; -- error
ALTER ROLE PUBLIC SET application_name to 'BOMB'; -- error
ALTER ROLE nonexistent SET application_name to 'BOMB'; -- error
-- ALTER USER SET/RESET
SELECT * FROM chksetconfig();
ALTER USER CURRENT_USER SET application_name to 'FOO';
ALTER USER SESSION_USER SET application_name to 'BAR';
ALTER USER "current_user" SET application_name to 'FOOFOO';
ALTER USER "Public" SET application_name to 'BARBAR';
ALTER USER ALL SET application_name to 'SLAP';
SELECT * FROM chksetconfig();
ALTER USER testrol1 SET application_name to 'SLAM';
SELECT * FROM chksetconfig();
ALTER USER CURRENT_USER RESET application_name;
ALTER USER SESSION_USER RESET application_name;
ALTER USER "current_user" RESET application_name;
ALTER USER "Public" RESET application_name;
ALTER USER ALL RESET application_name;
SELECT * FROM chksetconfig();
ALTER USER CURRENT_USER SET application_name to 'BAZ'; -- error
ALTER USER USER SET application_name to 'BOOM'; -- error
ALTER USER PUBLIC SET application_name to 'BOMB'; -- error
ALTER USER NONE SET application_name to 'BOMB'; -- error
ALTER USER nonexistent SET application_name to 'BOMB'; -- error
-- CREAETE SCHEMA
set client_min_messages to error;
CREATE SCHEMA newschema1 AUTHORIZATION CURRENT_USER;
CREATE SCHEMA newschema2 AUTHORIZATION "current_user";
CREATE SCHEMA newschema3 AUTHORIZATION SESSION_USER;
CREATE SCHEMA newschema4 AUTHORIZATION testrolx;
CREATE SCHEMA newschema5 AUTHORIZATION "Public";
CREATE SCHEMA newschema6 AUTHORIZATION USER; -- error
CREATE SCHEMA newschema6 AUTHORIZATION CURRENT_ROLE; -- error
CREATE SCHEMA newschema6 AUTHORIZATION PUBLIC; -- error
CREATE SCHEMA newschema6 AUTHORIZATION "public"; -- error
CREATE SCHEMA newschema6 AUTHORIZATION NONE; -- error
CREATE SCHEMA newschema6 AUTHORIZATION nonexistent; -- error
SELECT n.nspname, r.rolname FROM pg_namespace n
JOIN pg_roles r ON (r.oid = n.nspowner)
WHERE n.nspname LIKE 'newschema_' ORDER BY 1;
CREATE SCHEMA IF NOT EXISTS newschema1 AUTHORIZATION CURRENT_USER;
CREATE SCHEMA IF NOT EXISTS newschema2 AUTHORIZATION "current_user";
CREATE SCHEMA IF NOT EXISTS newschema3 AUTHORIZATION SESSION_USER;
CREATE SCHEMA IF NOT EXISTS newschema4 AUTHORIZATION testrolx;
CREATE SCHEMA IF NOT EXISTS newschema5 AUTHORIZATION "Public";
CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION USER; -- error
CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION CURRENT_ROLE; -- error
CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION PUBLIC; -- error
CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION "public"; -- error
CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION NONE; -- error
CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION nonexistent; -- error
SELECT n.nspname, r.rolname FROM pg_namespace n
JOIN pg_roles r ON (r.oid = n.nspowner)
WHERE n.nspname LIKE 'newschema_' ORDER BY 1;
-- ALTER TABLE OWNER TO
\c -
SET SESSION AUTHORIZATION testrol0;
set client_min_messages to error;
CREATE TABLE testtab1 (a int);
CREATE TABLE testtab2 (a int);
CREATE TABLE testtab3 (a int);
CREATE TABLE testtab4 (a int);
CREATE TABLE testtab5 (a int);
CREATE TABLE testtab6 (a int);
\c -
SET SESSION AUTHORIZATION testrol1;
SET ROLE testrol2;
ALTER TABLE testtab1 OWNER TO CURRENT_USER;
ALTER TABLE testtab2 OWNER TO "current_user";
ALTER TABLE testtab3 OWNER TO SESSION_USER;
ALTER TABLE testtab4 OWNER TO testrolx;
ALTER TABLE testtab5 OWNER TO "Public";
ALTER TABLE testtab6 OWNER TO CURRENT_ROLE; -- error
ALTER TABLE testtab6 OWNER TO USER; --error
ALTER TABLE testtab6 OWNER TO PUBLIC; -- error
ALTER TABLE testtab6 OWNER TO "public"; -- error
ALTER TABLE testtab6 OWNER TO nonexistent; -- error
SELECT c.relname, r.rolname
FROM pg_class c JOIN pg_roles r ON (r.oid = c.relowner)
WHERE relname LIKE 'testtab_'
ORDER BY 1;
-- ALTER TABLE, VIEW, MATERIALIZED VIEW, FOREIGN TABLE, SEQUENCE are
-- changed their owner in the same way.
-- ALTER AGGREGATE
\c -
SET SESSION AUTHORIZATION testrol0;
CREATE AGGREGATE testagg1(int2) (SFUNC = int2_sum, STYPE = int8);
CREATE AGGREGATE testagg2(int2) (SFUNC = int2_sum, STYPE = int8);
CREATE AGGREGATE testagg3(int2) (SFUNC = int2_sum, STYPE = int8);
CREATE AGGREGATE testagg4(int2) (SFUNC = int2_sum, STYPE = int8);
CREATE AGGREGATE testagg5(int2) (SFUNC = int2_sum, STYPE = int8);
CREATE AGGREGATE testagg5(int2) (SFUNC = int2_sum, STYPE = int8);
CREATE AGGREGATE testagg6(int2) (SFUNC = int2_sum, STYPE = int8);
CREATE AGGREGATE testagg7(int2) (SFUNC = int2_sum, STYPE = int8);
CREATE AGGREGATE testagg8(int2) (SFUNC = int2_sum, STYPE = int8);
CREATE AGGREGATE testagg9(int2) (SFUNC = int2_sum, STYPE = int8);
\c -
SET SESSION AUTHORIZATION testrol1;
SET ROLE testrol2;
ALTER AGGREGATE testagg1(int2) OWNER TO CURRENT_USER;
ALTER AGGREGATE testagg2(int2) OWNER TO "current_user";
ALTER AGGREGATE testagg3(int2) OWNER TO SESSION_USER;
ALTER AGGREGATE testagg4(int2) OWNER TO testrolx;
ALTER AGGREGATE testagg5(int2) OWNER TO "Public";
ALTER AGGREGATE testagg5(int2) OWNER TO CURRENT_ROLE; -- error
ALTER AGGREGATE testagg5(int2) OWNER TO USER; -- error
ALTER AGGREGATE testagg5(int2) OWNER TO PUBLIC; -- error
ALTER AGGREGATE testagg5(int2) OWNER TO "public"; -- error
ALTER AGGREGATE testagg5(int2) OWNER TO nonexistent; -- error
SELECT p.proname, r.rolname
FROM pg_proc p JOIN pg_roles r ON (r.oid = p.proowner)
WHERE proname LIKE 'testagg_'
ORDER BY 1;
-- CREATE USER MAPPING
CREATE FOREIGN DATA WRAPPER test_wrapper;
CREATE SERVER sv1 FOREIGN DATA WRAPPER test_wrapper;
CREATE SERVER sv2 FOREIGN DATA WRAPPER test_wrapper;
CREATE SERVER sv3 FOREIGN DATA WRAPPER test_wrapper;
CREATE SERVER sv4 FOREIGN DATA WRAPPER test_wrapper;
CREATE SERVER sv5 FOREIGN DATA WRAPPER test_wrapper;
CREATE SERVER sv6 FOREIGN DATA WRAPPER test_wrapper;
CREATE SERVER sv7 FOREIGN DATA WRAPPER test_wrapper;
CREATE SERVER sv8 FOREIGN DATA WRAPPER test_wrapper;
CREATE SERVER sv9 FOREIGN DATA WRAPPER test_wrapper;
CREATE USER MAPPING FOR CURRENT_USER SERVER sv1 OPTIONS (user 'CURRENT_USER');
CREATE USER MAPPING FOR "current_user" SERVER sv2 OPTIONS (user '"current_user"');
CREATE USER MAPPING FOR USER SERVER sv3 OPTIONS (user 'USER');
CREATE USER MAPPING FOR "user" SERVER sv4 OPTIONS (user '"USER"');
CREATE USER MAPPING FOR SESSION_USER SERVER sv5 OPTIONS (user 'SESSION_USER');
CREATE USER MAPPING FOR PUBLIC SERVER sv6 OPTIONS (user 'PUBLIC');
CREATE USER MAPPING FOR "Public" SERVER sv7 OPTIONS (user '"Public"');
CREATE USER MAPPING FOR testrolx SERVER sv8 OPTIONS (user 'testrolx');
CREATE USER MAPPING FOR CURRENT_ROLE SERVER sv9
OPTIONS (user 'CURRENT_ROLE'); -- error
CREATE USER MAPPING FOR nonexistent SERVER sv9
OPTIONS (user 'nonexistent'); -- error;
SELECT * FROM chkumapping();
-- ALTER USER MAPPING
ALTER USER MAPPING FOR CURRENT_USER SERVER sv1
OPTIONS (SET user 'CURRENT_USER_alt');
ALTER USER MAPPING FOR "current_user" SERVER sv2
OPTIONS (SET user '"current_user"_alt');
ALTER USER MAPPING FOR USER SERVER sv3
OPTIONS (SET user 'USER_alt');
ALTER USER MAPPING FOR "user" SERVER sv4
OPTIONS (SET user '"user"_alt');
ALTER USER MAPPING FOR SESSION_USER SERVER sv5
OPTIONS (SET user 'SESSION_USER_alt');
ALTER USER MAPPING FOR PUBLIC SERVER sv6
OPTIONS (SET user 'public_alt');
ALTER USER MAPPING FOR "Public" SERVER sv7
OPTIONS (SET user '"Public"_alt');
ALTER USER MAPPING FOR testrolx SERVER sv8
OPTIONS (SET user 'testrolx_alt');
ALTER USER MAPPING FOR CURRENT_ROLE SERVER sv9
OPTIONS (SET user 'CURRENT_ROLE_alt');
ALTER USER MAPPING FOR nonexistent SERVER sv9
OPTIONS (SET user 'nonexistent_alt'); -- error
SELECT * FROM chkumapping();
-- DROP USER MAPPING
DROP USER MAPPING FOR CURRENT_USER SERVER sv1;
DROP USER MAPPING FOR "current_user" SERVER sv2;
DROP USER MAPPING FOR USER SERVER sv3;
DROP USER MAPPING FOR "user" SERVER sv4;
DROP USER MAPPING FOR SESSION_USER SERVER sv5;
DROP USER MAPPING FOR PUBLIC SERVER sv6;
DROP USER MAPPING FOR "Public" SERVER sv7;
DROP USER MAPPING FOR testrolx SERVER sv8;
DROP USER MAPPING FOR CURRENT_ROLE SERVER sv9; -- error
DROP USER MAPPING FOR nonexistent SERVER sv; -- error
SELECT * FROM chkumapping();
CREATE USER MAPPING FOR CURRENT_USER SERVER sv1 OPTIONS (user 'CURRENT_USER');
CREATE USER MAPPING FOR "current_user" SERVER sv2 OPTIONS (user '"current_user"');
CREATE USER MAPPING FOR USER SERVER sv3 OPTIONS (user 'USER');
CREATE USER MAPPING FOR "user" SERVER sv4 OPTIONS (user '"USER"');
CREATE USER MAPPING FOR SESSION_USER SERVER sv5 OPTIONS (user 'SESSION_USER');
CREATE USER MAPPING FOR PUBLIC SERVER sv6 OPTIONS (user 'PUBLIC');
CREATE USER MAPPING FOR "Public" SERVER sv7 OPTIONS (user '"Public"');
CREATE USER MAPPING FOR testrolx SERVER sv8 OPTIONS (user 'testrolx');
SELECT * FROM chkumapping();
-- DROP USER MAPPING IF EXISTS
DROP USER MAPPING IF EXISTS FOR CURRENT_USER SERVER sv1;
SELECT * FROM chkumapping();
DROP USER MAPPING IF EXISTS FOR "current_user" SERVER sv2;
SELECT * FROM chkumapping();
DROP USER MAPPING IF EXISTS FOR USER SERVER sv3;
SELECT * FROM chkumapping();
DROP USER MAPPING IF EXISTS FOR "user" SERVER sv4;
SELECT * FROM chkumapping();
DROP USER MAPPING IF EXISTS FOR SESSION_USER SERVER sv5;
SELECT * FROM chkumapping();
DROP USER MAPPING IF EXISTS FOR PUBLIC SERVER sv6;
SELECT * FROM chkumapping();
DROP USER MAPPING IF EXISTS FOR "Public" SERVER sv7;
SELECT * FROM chkumapping();
DROP USER MAPPING IF EXISTS FOR testrolx SERVER sv8;
SELECT * FROM chkumapping();
DROP USER MAPPING IF EXISTS FOR CURRENT_ROLE SERVER sv9; --error
DROP USER MAPPING IF EXISTS FOR nonexistent SERVER sv9; -- error
-- GRANT/REVOKE
UPDATE pg_proc SET proacl = null WHERE proname LIKE 'testagg_';
SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_';
REVOKE ALL PRIVILEGES ON FUNCTION testagg1(int2) FROM PUBLIC;
REVOKE ALL PRIVILEGES ON FUNCTION testagg2(int2) FROM PUBLIC;
REVOKE ALL PRIVILEGES ON FUNCTION testagg3(int2) FROM PUBLIC;
REVOKE ALL PRIVILEGES ON FUNCTION testagg4(int2) FROM PUBLIC;
REVOKE ALL PRIVILEGES ON FUNCTION testagg5(int2) FROM PUBLIC;
REVOKE ALL PRIVILEGES ON FUNCTION testagg6(int2) FROM PUBLIC;
REVOKE ALL PRIVILEGES ON FUNCTION testagg7(int2) FROM PUBLIC;
REVOKE ALL PRIVILEGES ON FUNCTION testagg8(int2) FROM PUBLIC;
GRANT ALL PRIVILEGES ON FUNCTION testagg1(int2) TO PUBLIC;
GRANT ALL PRIVILEGES ON FUNCTION testagg2(int2) TO CURRENT_USER;
GRANT ALL PRIVILEGES ON FUNCTION testagg3(int2) TO "current_user";
GRANT ALL PRIVILEGES ON FUNCTION testagg4(int2) TO SESSION_USER;
GRANT ALL PRIVILEGES ON FUNCTION testagg5(int2) TO "Public";
GRANT ALL PRIVILEGES ON FUNCTION testagg6(int2) TO testrolx;
GRANT ALL PRIVILEGES ON FUNCTION testagg7(int2) TO "public";
GRANT ALL PRIVILEGES ON FUNCTION testagg8(int2)
TO current_user, public, testrolx;
SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_';
GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO CURRENT_ROLE; --error
GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO USER; --error
GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO NONE; --error
GRANT ALL PRIVILEGES ON FUNCTION testagg9(int2) TO "none"; --error
SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_';
REVOKE ALL PRIVILEGES ON FUNCTION testagg1(int2) FROM PUBLIC;
REVOKE ALL PRIVILEGES ON FUNCTION testagg2(int2) FROM CURRENT_USER;
REVOKE ALL PRIVILEGES ON FUNCTION testagg3(int2) FROM "current_user";
REVOKE ALL PRIVILEGES ON FUNCTION testagg4(int2) FROM SESSION_USER;
REVOKE ALL PRIVILEGES ON FUNCTION testagg5(int2) FROM "Public";
REVOKE ALL PRIVILEGES ON FUNCTION testagg6(int2) FROM testrolx;
REVOKE ALL PRIVILEGES ON FUNCTION testagg7(int2) FROM "public";
REVOKE ALL PRIVILEGES ON FUNCTION testagg8(int2)
FROM current_user, public, testrolx;
SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_';
REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM CURRENT_ROLE; --error
REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM USER; --error
REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM NONE; --error
REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM "none"; --error
SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_';
-- clean up
\c
DROP OWNED BY testrol0, "Public", "current_user", testrol1, testrol2, testrolx CASCADE;
DROP ROLE testrol0, testrol1, testrol2, testrolx;
DROP ROLE "Public", "None", "current_user", "session_user", "user";