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