diff --git a/doc/src/sgml/ref/alter_role.sgml b/doc/src/sgml/ref/alter_role.sgml index c135364..28bcc07 100644 --- a/doc/src/sgml/ref/alter_role.sgml +++ b/doc/src/sgml/ref/alter_role.sgml @@ -38,16 +38,21 @@ ALTER ROLE role_specification [ WIT ALTER ROLE name RENAME TO new_name -ALTER ROLE { role_specification | ALL } [ IN DATABASE database_name ] SET configuration_parameter { TO | = } { value | DEFAULT } -ALTER ROLE { role_specification | ALL } [ IN DATABASE database_name ] SET configuration_parameter FROM CURRENT -ALTER ROLE { role_specification | ALL } [ IN DATABASE database_name ] RESET configuration_parameter -ALTER ROLE { role_specification | ALL } [ IN DATABASE database_name ] RESET ALL +ALTER ROLE { role_specification | ALL } [ IN DATABASE database_specification ] SET configuration_parameter { TO | = } { value | DEFAULT } +ALTER ROLE { role_specification | ALL } [ IN DATABASE database_specification ] SET configuration_parameter FROM CURRENT +ALTER ROLE { role_specification | ALL } [ IN DATABASE database_specification ] RESET configuration_parameter +ALTER ROLE { role_specification | ALL } [ IN DATABASE database_specification ] RESET ALL where role_specification can be: role_name | CURRENT_USER | SESSION_USER + +where database_specification can be: + + database_name + | CURRENT_DATABASE diff --git a/doc/src/sgml/ref/alter_user.sgml b/doc/src/sgml/ref/alter_user.sgml index 8e03510..b33d87d 100644 --- a/doc/src/sgml/ref/alter_user.sgml +++ b/doc/src/sgml/ref/alter_user.sgml @@ -38,16 +38,21 @@ ALTER USER role_specification [ WIT ALTER USER name RENAME TO new_name -ALTER USER { role_specification | ALL } [ IN DATABASE database_name ] SET configuration_parameter { TO | = } { value | DEFAULT } -ALTER USER { role_specification | ALL } [ IN DATABASE database_name ] SET configuration_parameter FROM CURRENT -ALTER USER { role_specification | ALL } [ IN DATABASE database_name ] RESET configuration_parameter -ALTER USER { role_specification | ALL } [ IN DATABASE database_name ] RESET ALL +ALTER USER { role_specification | ALL } [ IN DATABASE database_specification ] SET configuration_parameter { TO | = } { value | DEFAULT } +ALTER USER { role_specification | ALL } [ IN DATABASE database_specification ] SET configuration_parameter FROM CURRENT +ALTER USER { role_specification | ALL } [ IN DATABASE database_specification ] RESET configuration_parameter +ALTER USER { role_specification | ALL } [ IN DATABASE database_specification ] RESET ALL where role_specification can be: role_name | CURRENT_USER | SESSION_USER + +where database_specification can be: + + database_name + | CURRENT_DATABASE diff --git a/doc/src/sgml/ref/comment.sgml b/doc/src/sgml/ref/comment.sgml index d02179f..d978789 100644 --- a/doc/src/sgml/ref/comment.sgml +++ b/doc/src/sgml/ref/comment.sgml @@ -74,7 +74,7 @@ COMMENT ON where database_specification is: - object_name + database_name | CURRENT_DATABASE diff --git a/doc/src/sgml/ref/grant.sgml b/doc/src/sgml/ref/grant.sgml index 475c85b..fac722f 100644 --- a/doc/src/sgml/ref/grant.sgml +++ b/doc/src/sgml/ref/grant.sgml @@ -39,9 +39,14 @@ GRANT { { USAGE | SELECT | UPDATE } TO role_specification [, ...] [ WITH GRANT OPTION ] GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] } - ON DATABASE database_name [, ...] + ON DATABASE database_specification [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] +where database_specification can be: + + database_name + | CURRENT_DATABASE + GRANT { USAGE | ALL [ PRIVILEGES ] } ON DOMAIN domain_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] diff --git a/doc/src/sgml/ref/revoke.sgml b/doc/src/sgml/ref/revoke.sgml index e3e3f2f..c7caaf1 100644 --- a/doc/src/sgml/ref/revoke.sgml +++ b/doc/src/sgml/ref/revoke.sgml @@ -46,10 +46,15 @@ REVOKE [ GRANT OPTION FOR ] REVOKE [ GRANT OPTION FOR ] { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] } - ON DATABASE database_name [, ...] + ON DATABASE database_specification [, ...] FROM { [ GROUP ] role_name | PUBLIC } [, ...] [ CASCADE | RESTRICT ] +where database_specification can be: + + database_name + | CURRENT_DATABASE + REVOKE [ GRANT OPTION FOR ] { USAGE | ALL [ PRIVILEGES ] } ON DOMAIN domain_name [, ...] diff --git a/doc/src/sgml/ref/security_label.sgml b/doc/src/sgml/ref/security_label.sgml index 3e2391b..050243f 100644 --- a/doc/src/sgml/ref/security_label.sgml +++ b/doc/src/sgml/ref/security_label.sgml @@ -52,7 +52,7 @@ SECURITY LABEL [ FOR provider ] ON where database_specification is: - object_name + database_name | CURRENT_DATABASE diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index ccde66a..c1a3e06 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -65,6 +65,7 @@ #include "foreign/foreign.h" #include "miscadmin.h" #include "nodes/makefuncs.h" +#include "nodes/parsenodes.h" #include "parser/parse_func.h" #include "parser/parse_type.h" #include "utils/acl.h" @@ -647,10 +648,10 @@ objectNamesToOids(GrantObjectType objtype, List *objnames) case ACL_OBJECT_DATABASE: foreach(cell, objnames) { - char *dbname = strVal(lfirst(cell)); + DbSpec *dbspec = lfirst(cell); Oid dbid; - dbid = get_database_oid(dbname, false); + dbid = get_dbspec_oid(dbspec,false); objects = lappend_oid(objects, dbid); } break; diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index f294135..71cfa13 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -927,9 +927,9 @@ AlterRoleSet(AlterRoleSetStmt *stmt) } /* look up and lock the database, if specified */ - if (stmt->database != NULL) + if (stmt->dbspec != NULL) { - databaseid = get_database_oid(stmt->database, false); + databaseid = get_dbspec_oid((DbSpec *)stmt->dbspec,false); shdepLockAndCheckObject(DatabaseRelationId, databaseid); if (!stmt->role) @@ -940,11 +940,11 @@ AlterRoleSet(AlterRoleSetStmt *stmt) */ if (!pg_database_ownercheck(databaseid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE, - stmt->database); + get_dbspec_name((DbSpec *)stmt->dbspec)); } } - if (!stmt->role && !stmt->database) + if (!stmt->role && !stmt->dbspec) { /* Must be superuser to alter settings globally. */ if (!superuser()) diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 933378a..3c67c45 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -4236,7 +4236,7 @@ _copyAlterRoleSetStmt(const AlterRoleSetStmt *from) AlterRoleSetStmt *newnode = makeNode(AlterRoleSetStmt); COPY_NODE_FIELD(role); - COPY_STRING_FIELD(database); + COPY_NODE_FIELD(dbspec); COPY_NODE_FIELD(setstmt); return newnode; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 3570514..fcdd8fa 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -2051,7 +2051,7 @@ static bool _equalAlterRoleSetStmt(const AlterRoleSetStmt *a, const AlterRoleSetStmt *b) { COMPARE_NODE_FIELD(role); - COMPARE_STRING_FIELD(database); + COMPARE_NODE_FIELD(dbspec); COMPARE_NODE_FIELD(setstmt); return true; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 431a287..b8a2c73 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -397,7 +397,7 @@ static Node *makeDbSpec(DbSpecType type, int location); transform_element_list transform_type_list TriggerTransitions TriggerReferencing publication_name_list - vacuum_relation_list opt_vacuum_relation_list + vacuum_relation_list opt_vacuum_relation_list db_spec_name_list %type group_by_list %type group_by_item empty_grouping_set rollup_clause cube_clause @@ -1142,7 +1142,7 @@ AlterRoleStmt: opt_in_database: /* EMPTY */ { $$ = NULL; } - | IN_P DATABASE database_name { $$ = $3; } + | IN_P DATABASE db_spec_name { $$ = $3; } ; AlterRoleSetStmt: @@ -1150,7 +1150,7 @@ AlterRoleSetStmt: { AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); n->role = $3; - n->database = $4; + n->dbspec = (Node *)$4; n->setstmt = $5; $$ = (Node *)n; } @@ -1158,7 +1158,7 @@ AlterRoleSetStmt: { AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); n->role = NULL; - n->database = $4; + n->dbspec = (Node *)$4; n->setstmt = $5; $$ = (Node *)n; } @@ -1166,7 +1166,7 @@ AlterRoleSetStmt: { AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); n->role = $3; - n->database = $4; + n->dbspec = (Node *)$4; n->setstmt = $5; $$ = (Node *)n; } @@ -1174,7 +1174,7 @@ AlterRoleSetStmt: { AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); n->role = NULL; - n->database = $4; + n->dbspec = (Node *)$4; n->setstmt = $5; $$ = (Node *)n; } @@ -6994,7 +6994,7 @@ privilege_target: n->objs = $2; $$ = n; } - | DATABASE name_list + | DATABASE db_spec_name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); n->targtype = ACL_TARGET_OBJECT; @@ -14431,6 +14431,13 @@ database_name: } ; +db_spec_name_list: db_spec_name + { $$ = list_make1($1); } + | db_spec_name_list ',' db_spec_name + { $$ = lappend($1, $3); } + ; + + db_spec_name: ColId { diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 4852c7d..692ad74 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -2455,7 +2455,7 @@ typedef struct AlterRoleSetStmt { NodeTag type; RoleSpec *role; /* role */ - char *database; /* database name, or NULL */ + Node *dbspec; /* name of database to set, DbSpec */ VariableSetStmt *setstmt; /* SET or RESET subcommand */ } AlterRoleSetStmt; diff --git a/src/test/regress/expected/publication.out b/src/test/regress/expected/publication.out index b101331..81d8629 100644 --- a/src/test/regress/expected/publication.out +++ b/src/test/regress/expected/publication.out @@ -206,6 +206,17 @@ ALTER PUBLICATION testpub2 ADD TABLE testpub_tbl1; -- ok DROP PUBLICATION testpub2; SET ROLE regress_publication_user; REVOKE CREATE ON DATABASE regression FROM regress_publication_user2; +--- test grant on database current_database +GRANT CREATE ON DATABASE CURRENT_DATABASE TO regress_publication_user2; +SET ROLE regress_publication_user2; +CREATE PUBLICATION testpub2; -- ok +DROP PUBLICATION testpub2; +SET ROLE regress_publication_user; +REVOKE CREATE ON DATABASE CURRENT_DATABASE FROM regress_publication_user2; +SET ROLE regress_publication_user2; +CREATE PUBLICATION testpub2; -- fail +ERROR: permission denied for database regression +SET ROLE regress_publication_user; DROP TABLE testpub_parted; DROP VIEW testpub_view; DROP TABLE testpub_tbl1; diff --git a/src/test/regress/expected/rolenames.out b/src/test/regress/expected/rolenames.out index dce82f5..ab02155 100644 --- a/src/test/regress/expected/rolenames.out +++ b/src/test/regress/expected/rolenames.out @@ -369,6 +369,26 @@ SELECT * FROM chksetconfig(); ----+------+------------+----------- (0 rows) +-- ALTER ROLE IN DATABASE CURRENT_DATABASE SET/RESET +ALTER ROLE CURRENT_USER IN DATABASE CURRENT_DATABASE SET application_name to 'FOO'; +ALTER ROLE "current_user" IN DATABASE CURRENT_DATABASE SET application_name to 'FOOFOO'; +ALTER ROLE "Public" IN DATABASE CURRENT_DATABASE SET application_name to 'BARBAR'; +SELECT * FROM chksetconfig(); + db | role | rolkeyword | setconfig +------------+------------------+--------------+--------------------------- + regression | Public | - | {application_name=BARBAR} + regression | current_user | - | {application_name=FOOFOO} + regression | regress_testrol2 | current_user | {application_name=FOO} +(3 rows) + +ALTER ROLE CURRENT_USER IN DATABASE CURRENT_DATABASE RESET application_name; +ALTER ROLE "current_user" IN DATABASE CURRENT_DATABASE RESET application_name; +ALTER ROLE "Public" IN DATABASE CURRENT_DATABASE 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'; @@ -421,6 +441,26 @@ SELECT * FROM chksetconfig(); ----+------+------------+----------- (0 rows) +-- ALTER USER IN DATABASE CURRENT_DATABASE SET/RESET +ALTER USER SESSION_USER IN DATABASE CURRENT_DATABASE SET application_name to 'BAR'; +ALTER USER "current_user" IN DATABASE CURRENT_DATABASE SET application_name to 'FOOFOO'; +ALTER USER "Public" IN DATABASE CURRENT_DATABASE SET application_name to 'BARBAR'; +SELECT * FROM chksetconfig(); + db | role | rolkeyword | setconfig +------------+------------------+--------------+--------------------------- + regression | Public | - | {application_name=BARBAR} + regression | current_user | - | {application_name=FOOFOO} + regression | regress_testrol1 | session_user | {application_name=BAR} +(3 rows) + +ALTER USER SESSION_USER IN DATABASE CURRENT_DATABASE RESET application_name; +ALTER USER "current_user" IN DATABASE CURRENT_DATABASE RESET application_name; +ALTER USER "Public" IN DATABASE CURRENT_DATABASE 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" diff --git a/src/test/regress/sql/publication.sql b/src/test/regress/sql/publication.sql index 815410b..0ee3fd3 100644 --- a/src/test/regress/sql/publication.sql +++ b/src/test/regress/sql/publication.sql @@ -112,6 +112,18 @@ DROP PUBLICATION testpub2; SET ROLE regress_publication_user; REVOKE CREATE ON DATABASE regression FROM regress_publication_user2; +--- test grant on database current_database +GRANT CREATE ON DATABASE CURRENT_DATABASE TO regress_publication_user2; +SET ROLE regress_publication_user2; +CREATE PUBLICATION testpub2; -- ok +DROP PUBLICATION testpub2; + +SET ROLE regress_publication_user; +REVOKE CREATE ON DATABASE CURRENT_DATABASE FROM regress_publication_user2; +SET ROLE regress_publication_user2; +CREATE PUBLICATION testpub2; -- fail +SET ROLE regress_publication_user; + DROP TABLE testpub_parted; DROP VIEW testpub_view; DROP TABLE testpub_tbl1; diff --git a/src/test/regress/sql/rolenames.sql b/src/test/regress/sql/rolenames.sql index 4c5706b..ff11931 100644 --- a/src/test/regress/sql/rolenames.sql +++ b/src/test/regress/sql/rolenames.sql @@ -146,6 +146,15 @@ ALTER ROLE "Public" RESET application_name; ALTER ROLE ALL RESET application_name; SELECT * FROM chksetconfig(); +-- ALTER ROLE IN DATABASE CURRENT_DATABASE SET/RESET +ALTER ROLE CURRENT_USER IN DATABASE CURRENT_DATABASE SET application_name to 'FOO'; +ALTER ROLE "current_user" IN DATABASE CURRENT_DATABASE SET application_name to 'FOOFOO'; +ALTER ROLE "Public" IN DATABASE CURRENT_DATABASE SET application_name to 'BARBAR'; +SELECT * FROM chksetconfig(); +ALTER ROLE CURRENT_USER IN DATABASE CURRENT_DATABASE RESET application_name; +ALTER ROLE "current_user" IN DATABASE CURRENT_DATABASE RESET application_name; +ALTER ROLE "Public" IN DATABASE CURRENT_DATABASE 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 @@ -170,6 +179,16 @@ ALTER USER ALL RESET application_name; SELECT * FROM chksetconfig(); +-- ALTER USER IN DATABASE CURRENT_DATABASE SET/RESET +ALTER USER SESSION_USER IN DATABASE CURRENT_DATABASE SET application_name to 'BAR'; +ALTER USER "current_user" IN DATABASE CURRENT_DATABASE SET application_name to 'FOOFOO'; +ALTER USER "Public" IN DATABASE CURRENT_DATABASE SET application_name to 'BARBAR'; +SELECT * FROM chksetconfig(); +ALTER USER SESSION_USER IN DATABASE CURRENT_DATABASE RESET application_name; +ALTER USER "current_user" IN DATABASE CURRENT_DATABASE RESET application_name; +ALTER USER "Public" IN DATABASE CURRENT_DATABASE 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