Allow GRANTED BY clause in normal GRANT and REVOKE statements

The SQL standard allows a GRANTED BY clause on GRANT and
REVOKE (privilege) statements that can specify CURRENT_USER or
CURRENT_ROLE.  In PostgreSQL, both of these are the default behavior.
Since we already have all the parsing support for this for the
GRANT (role) statement, we might as well add basic support for this
for the privilege variant as well.  This allows us to check off SQL
feature T332.  In the future, perhaps more interesting things could be
done with this, too.

Reviewed-by: Simon Riggs <simon@2ndquadrant.com>
Discussion: https://www.postgresql.org/message-id/flat/f2feac44-b4c5-f38f-3699-2851d6a76dc9@2ndquadrant.com
This commit is contained in:
Peter Eisentraut 2021-01-30 09:41:44 +01:00
parent 7da83415e5
commit 6aaaa76bb4
10 changed files with 71 additions and 13 deletions

View File

@ -26,58 +26,71 @@ GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
ON { [ TABLE ] <replaceable class="parameter">table_name</replaceable> [, ...] ON { [ TABLE ] <replaceable class="parameter">table_name</replaceable> [, ...]
| ALL TABLES IN SCHEMA <replaceable class="parameter">schema_name</replaceable> [, ...] } | ALL TABLES IN SCHEMA <replaceable class="parameter">schema_name</replaceable> [, ...] }
TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( <replaceable class="parameter">column_name</replaceable> [, ...] ) GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( <replaceable class="parameter">column_name</replaceable> [, ...] )
[, ...] | ALL [ PRIVILEGES ] ( <replaceable class="parameter">column_name</replaceable> [, ...] ) } [, ...] | ALL [ PRIVILEGES ] ( <replaceable class="parameter">column_name</replaceable> [, ...] ) }
ON [ TABLE ] <replaceable class="parameter">table_name</replaceable> [, ...] ON [ TABLE ] <replaceable class="parameter">table_name</replaceable> [, ...]
TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
GRANT { { USAGE | SELECT | UPDATE } GRANT { { USAGE | SELECT | UPDATE }
[, ...] | ALL [ PRIVILEGES ] } [, ...] | ALL [ PRIVILEGES ] }
ON { SEQUENCE <replaceable class="parameter">sequence_name</replaceable> [, ...] ON { SEQUENCE <replaceable class="parameter">sequence_name</replaceable> [, ...]
| ALL SEQUENCES IN SCHEMA <replaceable class="parameter">schema_name</replaceable> [, ...] } | ALL SEQUENCES IN SCHEMA <replaceable class="parameter">schema_name</replaceable> [, ...] }
TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] } GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }
ON DATABASE <replaceable>database_name</replaceable> [, ...] ON DATABASE <replaceable>database_name</replaceable> [, ...]
TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
GRANT { USAGE | ALL [ PRIVILEGES ] } GRANT { USAGE | ALL [ PRIVILEGES ] }
ON DOMAIN <replaceable>domain_name</replaceable> [, ...] ON DOMAIN <replaceable>domain_name</replaceable> [, ...]
TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
GRANT { USAGE | ALL [ PRIVILEGES ] } GRANT { USAGE | ALL [ PRIVILEGES ] }
ON FOREIGN DATA WRAPPER <replaceable>fdw_name</replaceable> [, ...] ON FOREIGN DATA WRAPPER <replaceable>fdw_name</replaceable> [, ...]
TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
GRANT { USAGE | ALL [ PRIVILEGES ] } GRANT { USAGE | ALL [ PRIVILEGES ] }
ON FOREIGN SERVER <replaceable>server_name</replaceable> [, ...] ON FOREIGN SERVER <replaceable>server_name</replaceable> [, ...]
TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
GRANT { EXECUTE | ALL [ PRIVILEGES ] } GRANT { EXECUTE | ALL [ PRIVILEGES ] }
ON { { FUNCTION | PROCEDURE | ROUTINE } <replaceable>routine_name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">arg_name</replaceable> ] <replaceable class="parameter">arg_type</replaceable> [, ...] ] ) ] [, ...] ON { { FUNCTION | PROCEDURE | ROUTINE } <replaceable>routine_name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">arg_name</replaceable> ] <replaceable class="parameter">arg_type</replaceable> [, ...] ] ) ] [, ...]
| ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA <replaceable class="parameter">schema_name</replaceable> [, ...] } | ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA <replaceable class="parameter">schema_name</replaceable> [, ...] }
TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
GRANT { USAGE | ALL [ PRIVILEGES ] } GRANT { USAGE | ALL [ PRIVILEGES ] }
ON LANGUAGE <replaceable>lang_name</replaceable> [, ...] ON LANGUAGE <replaceable>lang_name</replaceable> [, ...]
TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
GRANT { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] } GRANT { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
ON LARGE OBJECT <replaceable class="parameter">loid</replaceable> [, ...] ON LARGE OBJECT <replaceable class="parameter">loid</replaceable> [, ...]
TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] } GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
ON SCHEMA <replaceable>schema_name</replaceable> [, ...] ON SCHEMA <replaceable>schema_name</replaceable> [, ...]
TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
GRANT { CREATE | ALL [ PRIVILEGES ] } GRANT { CREATE | ALL [ PRIVILEGES ] }
ON TABLESPACE <replaceable>tablespace_name</replaceable> [, ...] ON TABLESPACE <replaceable>tablespace_name</replaceable> [, ...]
TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
GRANT { USAGE | ALL [ PRIVILEGES ] } GRANT { USAGE | ALL [ PRIVILEGES ] }
ON TYPE <replaceable>type_name</replaceable> [, ...] ON TYPE <replaceable>type_name</replaceable> [, ...]
TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ] TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
GRANT <replaceable class="parameter">role_name</replaceable> [, ...] TO <replaceable class="parameter">role_specification</replaceable> [, ...] GRANT <replaceable class="parameter">role_name</replaceable> [, ...] TO <replaceable class="parameter">role_specification</replaceable> [, ...]
[ WITH ADMIN OPTION ] [ WITH ADMIN OPTION ]
@ -133,6 +146,12 @@ GRANT <replaceable class="parameter">role_name</replaceable> [, ...] TO <replace
to <literal>PUBLIC</literal>. to <literal>PUBLIC</literal>.
</para> </para>
<para>
If <literal>GRANTED BY</literal> is specified, the specified grantor must
be the current user. This clause is currently present in this form only
for SQL compatibility.
</para>
<para> <para>
There is no need to grant privileges to the owner of an object There is no need to grant privileges to the owner of an object
(usually the user that created it), (usually the user that created it),
@ -410,9 +429,9 @@ GRANT admins TO joe;
<para> <para>
The SQL standard allows the <literal>GRANTED BY</literal> option to The SQL standard allows the <literal>GRANTED BY</literal> option to
be used in all forms of <command>GRANT</command>. PostgreSQL only specify only <literal>CURRENT_USER</literal> or
supports it when granting role membership, and even then only superusers <literal>CURRENT_ROLE</literal>. The other variants are PostgreSQL
may use it in nontrivial ways. extensions.
</para> </para>
<para> <para>

View File

@ -27,6 +27,7 @@ REVOKE [ GRANT OPTION FOR ]
ON { [ TABLE ] <replaceable class="parameter">table_name</replaceable> [, ...] ON { [ TABLE ] <replaceable class="parameter">table_name</replaceable> [, ...]
| ALL TABLES IN SCHEMA <replaceable>schema_name</replaceable> [, ...] } | ALL TABLES IN SCHEMA <replaceable>schema_name</replaceable> [, ...] }
FROM <replaceable class="parameter">role_specification</replaceable> [, ...] FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
[ CASCADE | RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ] REVOKE [ GRANT OPTION FOR ]
@ -34,6 +35,7 @@ REVOKE [ GRANT OPTION FOR ]
[, ...] | ALL [ PRIVILEGES ] ( <replaceable class="parameter">column_name</replaceable> [, ...] ) } [, ...] | ALL [ PRIVILEGES ] ( <replaceable class="parameter">column_name</replaceable> [, ...] ) }
ON [ TABLE ] <replaceable class="parameter">table_name</replaceable> [, ...] ON [ TABLE ] <replaceable class="parameter">table_name</replaceable> [, ...]
FROM <replaceable class="parameter">role_specification</replaceable> [, ...] FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
[ CASCADE | RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ] REVOKE [ GRANT OPTION FOR ]
@ -42,30 +44,35 @@ REVOKE [ GRANT OPTION FOR ]
ON { SEQUENCE <replaceable class="parameter">sequence_name</replaceable> [, ...] ON { SEQUENCE <replaceable class="parameter">sequence_name</replaceable> [, ...]
| ALL SEQUENCES IN SCHEMA <replaceable>schema_name</replaceable> [, ...] } | ALL SEQUENCES IN SCHEMA <replaceable>schema_name</replaceable> [, ...] }
FROM <replaceable class="parameter">role_specification</replaceable> [, ...] FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
[ CASCADE | RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ] REVOKE [ GRANT OPTION FOR ]
{ { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] } { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }
ON DATABASE <replaceable>database_name</replaceable> [, ...] ON DATABASE <replaceable>database_name</replaceable> [, ...]
FROM <replaceable class="parameter">role_specification</replaceable> [, ...] FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
[ CASCADE | RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ] REVOKE [ GRANT OPTION FOR ]
{ USAGE | ALL [ PRIVILEGES ] } { USAGE | ALL [ PRIVILEGES ] }
ON DOMAIN <replaceable>domain_name</replaceable> [, ...] ON DOMAIN <replaceable>domain_name</replaceable> [, ...]
FROM <replaceable class="parameter">role_specification</replaceable> [, ...] FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
[ CASCADE | RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ] REVOKE [ GRANT OPTION FOR ]
{ USAGE | ALL [ PRIVILEGES ] } { USAGE | ALL [ PRIVILEGES ] }
ON FOREIGN DATA WRAPPER <replaceable>fdw_name</replaceable> [, ...] ON FOREIGN DATA WRAPPER <replaceable>fdw_name</replaceable> [, ...]
FROM <replaceable class="parameter">role_specification</replaceable> [, ...] FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
[ CASCADE | RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ] REVOKE [ GRANT OPTION FOR ]
{ USAGE | ALL [ PRIVILEGES ] } { USAGE | ALL [ PRIVILEGES ] }
ON FOREIGN SERVER <replaceable>server_name</replaceable> [, ...] ON FOREIGN SERVER <replaceable>server_name</replaceable> [, ...]
FROM <replaceable class="parameter">role_specification</replaceable> [, ...] FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
[ CASCADE | RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ] REVOKE [ GRANT OPTION FOR ]
@ -73,36 +80,42 @@ REVOKE [ GRANT OPTION FOR ]
ON { { FUNCTION | PROCEDURE | ROUTINE } <replaceable>function_name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">arg_name</replaceable> ] <replaceable class="parameter">arg_type</replaceable> [, ...] ] ) ] [, ...] ON { { FUNCTION | PROCEDURE | ROUTINE } <replaceable>function_name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">arg_name</replaceable> ] <replaceable class="parameter">arg_type</replaceable> [, ...] ] ) ] [, ...]
| ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA <replaceable>schema_name</replaceable> [, ...] } | ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA <replaceable>schema_name</replaceable> [, ...] }
FROM <replaceable class="parameter">role_specification</replaceable> [, ...] FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
[ CASCADE | RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ] REVOKE [ GRANT OPTION FOR ]
{ USAGE | ALL [ PRIVILEGES ] } { USAGE | ALL [ PRIVILEGES ] }
ON LANGUAGE <replaceable>lang_name</replaceable> [, ...] ON LANGUAGE <replaceable>lang_name</replaceable> [, ...]
FROM <replaceable class="parameter">role_specification</replaceable> [, ...] FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
[ CASCADE | RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ] REVOKE [ GRANT OPTION FOR ]
{ { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] } { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
ON LARGE OBJECT <replaceable class="parameter">loid</replaceable> [, ...] ON LARGE OBJECT <replaceable class="parameter">loid</replaceable> [, ...]
FROM <replaceable class="parameter">role_specification</replaceable> [, ...] FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
[ CASCADE | RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ] REVOKE [ GRANT OPTION FOR ]
{ { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] } { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
ON SCHEMA <replaceable>schema_name</replaceable> [, ...] ON SCHEMA <replaceable>schema_name</replaceable> [, ...]
FROM <replaceable class="parameter">role_specification</replaceable> [, ...] FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
[ CASCADE | RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ] REVOKE [ GRANT OPTION FOR ]
{ CREATE | ALL [ PRIVILEGES ] } { CREATE | ALL [ PRIVILEGES ] }
ON TABLESPACE <replaceable>tablespace_name</replaceable> [, ...] ON TABLESPACE <replaceable>tablespace_name</replaceable> [, ...]
FROM <replaceable class="parameter">role_specification</replaceable> [, ...] FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
[ CASCADE | RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ] REVOKE [ GRANT OPTION FOR ]
{ USAGE | ALL [ PRIVILEGES ] } { USAGE | ALL [ PRIVILEGES ] }
ON TYPE <replaceable>type_name</replaceable> [, ...] ON TYPE <replaceable>type_name</replaceable> [, ...]
FROM <replaceable class="parameter">role_specification</replaceable> [, ...] FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
[ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
[ CASCADE | RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE [ ADMIN OPTION FOR ] REVOKE [ ADMIN OPTION FOR ]

View File

@ -363,6 +363,22 @@ ExecuteGrantStmt(GrantStmt *stmt)
const char *errormsg; const char *errormsg;
AclMode all_privileges; AclMode all_privileges;
if (stmt->grantor)
{
Oid grantor;
grantor = get_rolespec_oid(stmt->grantor, false);
/*
* Currently, this clause is only for SQL compatibility, not very
* interesting otherwise.
*/
if (grantor != GetUserId())
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("grantor must be current user")));
}
/* /*
* Turn the regular GrantStmt into the InternalGrant form. * Turn the regular GrantStmt into the InternalGrant form.
*/ */

View File

@ -475,7 +475,7 @@ T324 Explicit security for SQL routines NO
T325 Qualified SQL parameter references YES T325 Qualified SQL parameter references YES
T326 Table functions NO T326 Table functions NO
T331 Basic roles YES T331 Basic roles YES
T332 Extended roles NO mostly supported T332 Extended roles YES
T341 Overloading of SQL-invoked functions and procedures YES T341 Overloading of SQL-invoked functions and procedures YES
T351 Bracketed SQL comments (/*...*/ comments) YES T351 Bracketed SQL comments (/*...*/ comments) YES
T431 Extended grouping capabilities YES T431 Extended grouping capabilities YES

View File

@ -3270,6 +3270,7 @@ _copyGrantStmt(const GrantStmt *from)
COPY_NODE_FIELD(privileges); COPY_NODE_FIELD(privileges);
COPY_NODE_FIELD(grantees); COPY_NODE_FIELD(grantees);
COPY_SCALAR_FIELD(grant_option); COPY_SCALAR_FIELD(grant_option);
COPY_NODE_FIELD(grantor);
COPY_SCALAR_FIELD(behavior); COPY_SCALAR_FIELD(behavior);
return newnode; return newnode;

View File

@ -1145,6 +1145,7 @@ _equalGrantStmt(const GrantStmt *a, const GrantStmt *b)
COMPARE_NODE_FIELD(privileges); COMPARE_NODE_FIELD(privileges);
COMPARE_NODE_FIELD(grantees); COMPARE_NODE_FIELD(grantees);
COMPARE_SCALAR_FIELD(grant_option); COMPARE_SCALAR_FIELD(grant_option);
COMPARE_NODE_FIELD(grantor);
COMPARE_SCALAR_FIELD(behavior); COMPARE_SCALAR_FIELD(behavior);
return true; return true;

View File

@ -6772,7 +6772,7 @@ opt_from_in: from_in
*****************************************************************************/ *****************************************************************************/
GrantStmt: GRANT privileges ON privilege_target TO grantee_list GrantStmt: GRANT privileges ON privilege_target TO grantee_list
opt_grant_grant_option opt_grant_grant_option opt_granted_by
{ {
GrantStmt *n = makeNode(GrantStmt); GrantStmt *n = makeNode(GrantStmt);
n->is_grant = true; n->is_grant = true;
@ -6782,13 +6782,14 @@ GrantStmt: GRANT privileges ON privilege_target TO grantee_list
n->objects = ($4)->objs; n->objects = ($4)->objs;
n->grantees = $6; n->grantees = $6;
n->grant_option = $7; n->grant_option = $7;
n->grantor = $8;
$$ = (Node*)n; $$ = (Node*)n;
} }
; ;
RevokeStmt: RevokeStmt:
REVOKE privileges ON privilege_target REVOKE privileges ON privilege_target
FROM grantee_list opt_drop_behavior FROM grantee_list opt_granted_by opt_drop_behavior
{ {
GrantStmt *n = makeNode(GrantStmt); GrantStmt *n = makeNode(GrantStmt);
n->is_grant = false; n->is_grant = false;
@ -6798,11 +6799,12 @@ RevokeStmt:
n->objtype = ($4)->objtype; n->objtype = ($4)->objtype;
n->objects = ($4)->objs; n->objects = ($4)->objs;
n->grantees = $6; n->grantees = $6;
n->behavior = $7; n->grantor = $7;
n->behavior = $8;
$$ = (Node *)n; $$ = (Node *)n;
} }
| REVOKE GRANT OPTION FOR privileges ON privilege_target | REVOKE GRANT OPTION FOR privileges ON privilege_target
FROM grantee_list opt_drop_behavior FROM grantee_list opt_granted_by opt_drop_behavior
{ {
GrantStmt *n = makeNode(GrantStmt); GrantStmt *n = makeNode(GrantStmt);
n->is_grant = false; n->is_grant = false;
@ -6812,7 +6814,8 @@ RevokeStmt:
n->objtype = ($7)->objtype; n->objtype = ($7)->objtype;
n->objects = ($7)->objs; n->objects = ($7)->objs;
n->grantees = $9; n->grantees = $9;
n->behavior = $10; n->grantor = $10;
n->behavior = $11;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;

View File

@ -1949,6 +1949,7 @@ typedef struct GrantStmt
/* privileges == NIL denotes ALL PRIVILEGES */ /* privileges == NIL denotes ALL PRIVILEGES */
List *grantees; /* list of RoleSpec nodes */ List *grantees; /* list of RoleSpec nodes */
bool grant_option; /* grant or revoke grant option */ bool grant_option; /* grant or revoke grant option */
RoleSpec *grantor;
DropBehavior behavior; /* drop behavior (for REVOKE) */ DropBehavior behavior; /* drop behavior (for REVOKE) */
} GrantStmt; } GrantStmt;

View File

@ -70,8 +70,10 @@ SELECT * FROM atest1;
CREATE TABLE atest2 (col1 varchar(10), col2 boolean); CREATE TABLE atest2 (col1 varchar(10), col2 boolean);
GRANT SELECT ON atest2 TO regress_priv_user2; GRANT SELECT ON atest2 TO regress_priv_user2;
GRANT UPDATE ON atest2 TO regress_priv_user3; GRANT UPDATE ON atest2 TO regress_priv_user3;
GRANT INSERT ON atest2 TO regress_priv_user4; GRANT INSERT ON atest2 TO regress_priv_user4 GRANTED BY CURRENT_USER;
GRANT TRUNCATE ON atest2 TO regress_priv_user5; GRANT TRUNCATE ON atest2 TO regress_priv_user5 GRANTED BY CURRENT_ROLE;
GRANT TRUNCATE ON atest2 TO regress_priv_user4 GRANTED BY regress_priv_user5; -- error
ERROR: grantor must be current user
SET SESSION AUTHORIZATION regress_priv_user2; SET SESSION AUTHORIZATION regress_priv_user2;
SELECT session_user, current_user; SELECT session_user, current_user;
session_user | current_user session_user | current_user

View File

@ -64,8 +64,10 @@ SELECT * FROM atest1;
CREATE TABLE atest2 (col1 varchar(10), col2 boolean); CREATE TABLE atest2 (col1 varchar(10), col2 boolean);
GRANT SELECT ON atest2 TO regress_priv_user2; GRANT SELECT ON atest2 TO regress_priv_user2;
GRANT UPDATE ON atest2 TO regress_priv_user3; GRANT UPDATE ON atest2 TO regress_priv_user3;
GRANT INSERT ON atest2 TO regress_priv_user4; GRANT INSERT ON atest2 TO regress_priv_user4 GRANTED BY CURRENT_USER;
GRANT TRUNCATE ON atest2 TO regress_priv_user5; GRANT TRUNCATE ON atest2 TO regress_priv_user5 GRANTED BY CURRENT_ROLE;
GRANT TRUNCATE ON atest2 TO regress_priv_user4 GRANTED BY regress_priv_user5; -- error
SET SESSION AUTHORIZATION regress_priv_user2; SET SESSION AUTHORIZATION regress_priv_user2;