Hello, This is the new version. (WIP v2)
The first attachment is the patch and the second is test sql
script.
- Behavior changing
Almost all syntax taking role accepts CURRENT_USER and
SESSION_USER and they are distinguished from "current_user" and
"session_user". The exceptions are follows.
- CREATE USER/GROUP <roleid>
- ALTER ROLE/GROUP/USER <roleid> RENAME TO <newname>
These syntax still do not accept the keywords like CURRENT_USER
and special names like "public" at all, but accepts
"current_user". The error message is changed as follows.
| postgres=# create user current_user;
| ERROR: role name should not be a keyword nor reserved name.
| LINE 1: create user current_user;
| ^
# Some other messages may changed...
USER and CURRENT_ROLE haven't been extended to other syntax. The
former still can be used only in CREATE/ALTER/DROP USER MAPPING
and the latter cannot be used out of function expressions.
- Storage for new information
The new struct NameId stores an identifier which telling what it
logically is using the new enum NameIdTypes.
This is still be a bit suffered by the difference between
CURRENT_USER and PUBLIC but now it makes distinction between
current_user and "current_user". User oid does not have the room
for representing the difference among PUBLIC, NONE and 'not
found' as the result of get_nameid_oid(), so members of NameId is
exposed in foreigncmds.c and it gets a bit uglier.
- Changes of related structs and grammar.
Type of role member is changed to NameId in some of parser
structs. AlterTableCmd.name has many other usage so I added new
member NameId *newowner for exclusive usage.
Type of OWNER clause of CREATE TABLESPACE is changed to RoleId. I
suppose there's no particular reason that the non-terminal was
"name".
Usage of "public" and "none" had been blocked for CREATE/RENAME
USER in user.c but now it is blocked in gram.y
- New function to resolve NameId
New function get_nameid_oid() is added. It is an alternative of
get_role_oid which can handle current_user and "current_user"
properly. get_role_oid() still be used in many places having no
direct relation to syntax.
- Others
No doc provided for now.
regards,
> > Adam Brightwell <[email protected]> writes:
> > > FWIW, I found the following in the archives:
> >
> > > http://www.postgresql.org/message-id/[email protected]
> >
> > > Now this is from 2002 and it appears it wasn't necessary to change at the
> > > time, but I haven't yet found anything else related (it's a big archive).
> > > Though, as I understand it, PUBLIC is now non-reserved as of SQL:2011
> > > which
> > > might make a compelling argument to leave it as is?
> >
> > The current spec does list PUBLIC as a non-reserved keyword, but it also
> > says (5.4 "Names and identifiers" syntax rules)
> >
> > 20) No <authorization identifier> shall specify "PUBLIC".
> >
> > which, oddly enough, seems to license us to handle "PUBLIC" the way
> > we are doing. OTOH, it lists CURRENT_USER as a reserved word, suggesting
> > that they don't think the same type of hack should be used for that.
> >
> > I'd be inclined to leave the grammar as such alone (ie CURRENT_USER is
> > a keyword, PUBLIC isn't). Changing that has more downside than upside,
> > and we do have justification in the spec for treating the two cases
> > differently. However, I agree that we should fix the subsequent
> > processing so that "current_user" is not confused with CURRENT_USER.
>
> Sure, maybe.
>
> - PUBLIC should be left as it is, as an supecial identifier
> which cannot be used even if quoted under some syntax.
>
> - CURRENT_USER should be a kayword as it is, but we shouldn't
> inhibit it from being used as an identifier if
> quoted. SESSION_USER and USER should be treated in the same way.
>
> We don't want to use something other than string (prefixed by
> zero-byte) as a matter of course:). And resolving the name to
> roleid instantly in gram.y is not allowed for the reason shown
> upthread.
>
> So it is necessary to add a new member for the struct, say
> "int special_role;:... Let me have more sane name for it :(
>
> - USER and CURRENT_ROLE are not needed for the syntax other than
> them which already uses them.
>
> I will work on this way. Let me know if something is not acceptable.
--
Kyotaro Horiguchi
NTT Open Source Software Center
>From f18d078d5e6e4005e803ecc954e59c899dbfd557 Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <[email protected]>
Date: Mon, 10 Nov 2014 19:08:42 +0900
Subject: [PATCH] ALTER USER CURRENT_USER v2
---
src/backend/catalog/aclchk.c | 13 ++-
src/backend/commands/alter.c | 2 +-
src/backend/commands/foreigncmds.c | 39 ++++-----
src/backend/commands/schemacmds.c | 26 +++++-
src/backend/commands/tablecmds.c | 2 +-
src/backend/commands/tablespace.c | 2 +-
src/backend/commands/user.c | 70 +++++++--------
src/backend/nodes/copyfuncs.c | 37 +++++---
src/backend/nodes/equalfuncs.c | 35 +++++---
src/backend/parser/gram.y | 174 ++++++++++++++++++++++++++++---------
src/backend/parser/parse_utilcmd.c | 2 +-
src/backend/utils/adt/acl.c | 31 +++++++
src/include/nodes/nodes.h | 1 +
src/include/nodes/parsenodes.h | 44 +++++++---
src/include/utils/acl.h | 2 +-
15 files changed, 338 insertions(+), 142 deletions(-)
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index d30612c..a2b6a70 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -434,9 +434,14 @@ ExecuteGrantStmt(GrantStmt *stmt)
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));
+ {
+ Oid grantee_uid = get_nameid_oid(grantee->rolname, false);
+
+ if (grantee_uid == InvalidOid)
+ grantee_uid = ACL_ID_PUBLIC;
+
+ istmt.grantees = lappend_oid(istmt.grantees, grantee_uid);
+ }
}
/*
@@ -919,7 +924,7 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
else
iacls.grantees =
lappend_oid(iacls.grantees,
- get_role_oid(grantee->rolname, false));
+ get_nameid_oid(grantee->rolname, false));
}
/*
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index c9a9baf..5117a35 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -678,7 +678,7 @@ AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
Oid
ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
{
- Oid newowner = get_role_oid(stmt->newowner, false);
+ Oid newowner = get_nameid_oid(stmt->newowner, false);
switch (stmt->objectType)
{
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index ab4ed6c..d5eb4cc 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -198,24 +198,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.
*
* Allow this only for superusers; also the new owner must be a
@@ -1099,13 +1081,17 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
rel = heap_open(UserMappingRelationId, RowExclusiveLock);
- useId = GetUserOidFromMapping(stmt->username, false);
+ useId = get_nameid_oid(stmt->username, false);
/* Check that the server exists. */
srv = GetForeignServerByName(stmt->servername, false);
user_mapping_ddl_aclcheck(useId, srv->serverid, stmt->servername);
+ /* XXX: Inhibit none to be used explicitly*/
+ if (!OidIsValid(useId) && stmt->username->idtype != NAMEID_PUBLIC)
+ elog(ERROR, "role \"%s\" does not exist", stmt->username->str);
+
/*
* Check that the user mapping is unique within server.
*/
@@ -1194,9 +1180,13 @@ AlterUserMapping(AlterUserMappingStmt *stmt)
rel = heap_open(UserMappingRelationId, RowExclusiveLock);
- useId = GetUserOidFromMapping(stmt->username, false);
+ useId = get_nameid_oid(stmt->username, false);
srv = GetForeignServerByName(stmt->servername, false);
+ /* XXX: Inhibit none to be used explicitly*/
+ if (!OidIsValid(useId) && stmt->username->idtype != NAMEID_PUBLIC)
+ elog(ERROR, "role \"%s\" does not exist", stmt->username->str);
+
umId = GetSysCacheOid2(USERMAPPINGUSERSERVER,
ObjectIdGetDatum(useId),
ObjectIdGetDatum(srv->serverid));
@@ -1276,16 +1266,19 @@ RemoveUserMapping(DropUserMappingStmt *stmt)
Oid umId;
ForeignServer *srv;
- useId = GetUserOidFromMapping(stmt->username, stmt->missing_ok);
+ useId = get_nameid_oid(stmt->username, stmt->missing_ok);
srv = GetForeignServerByName(stmt->servername, true);
- if (stmt->username && !OidIsValid(useId))
+ /* XXX: Inhibit none to be used explicitly*/
+ if (!OidIsValid(useId) && stmt->username->idtype != NAMEID_PUBLIC)
{
+ if (!stmt->missing_ok)
+ elog(ERROR, "role \"%s\" does not exist", stmt->username->str);
/*
* IF EXISTS specified, role not found and not public. Notice this and
* leave.
*/
- elog(NOTICE, "role \"%s\" does not exist, skipping", stmt->username);
+ elog(NOTICE, "role \"%s\" does not exist, skipping", stmt->username->str);
return InvalidOid;
}
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index 03f5514..f97183a 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -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"
@@ -43,7 +44,7 @@ Oid
CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString)
{
const char *schemaName = stmt->schemaname;
- const char *authId = stmt->authid;
+ const NameId *authId = stmt->authid;
Oid namespaceId;
OverrideSearchPath *overridePath;
List *parsetree_list;
@@ -59,10 +60,31 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString)
* Who is supposed to own the new schema?
*/
if (authId)
- owner_uid = get_role_oid(authId, false);
+ {
+ owner_uid = get_nameid_oid(authId, false);
+ if (!OidIsValid(owner_uid))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("role \"%s\" does not exist", authId->str)));
+
+ }
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))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("invalid role oid: %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
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 714a9f1..27bc760 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -3474,7 +3474,7 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
break;
case AT_ChangeOwner: /* ALTER OWNER */
ATExecChangeOwner(RelationGetRelid(rel),
- get_role_oid(cmd->name, false),
+ get_nameid_oid(cmd->newowner, false),
false, lockmode);
break;
case AT_ClusterOn: /* CLUSTER ON */
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index 378e355..0e611f3 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -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_nameid_oid(stmt->owner, false);
else
ownerId = GetUserId();
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 1a73fd8..5c32c3e 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -310,13 +310,6 @@ CreateRole(CreateRoleStmt *stmt)
errmsg("permission denied to create role")));
}
- if (strcmp(stmt->role, "public") == 0 ||
- strcmp(stmt->role, "none") == 0)
- ereport(ERROR,
- (errcode(ERRCODE_RESERVED_NAME),
- errmsg("role name \"%s\" is reserved",
- stmt->role)));
-
/*
* Check the pg_authid relation to be certain the role doesn't already
* exist.
@@ -481,6 +474,7 @@ AlterRole(AlterRoleStmt *stmt)
HeapTuple tuple,
new_tuple;
ListCell *option;
+ char *rolename = NULL;
char *password = NULL; /* user password */
bool encrypt_password = Password_encryption; /* encrypt password? */
char encrypted_password[MD5_PASSWD_LEN + 1];
@@ -649,18 +643,25 @@ 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))
+ roleid = get_nameid_oid(stmt->role, false);
+ if (!OidIsValid(roleid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("role \"%s\" does not exist", stmt->role)));
-
- roleid = HeapTupleGetOid(tuple);
+ errmsg("role \"%s\" does not exist", stmt->role->str)));
/*
* To mess with a superuser you gotta be superuser; else you need
* createrole, or just want to change your own password
*/
+ tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
+ if (!HeapTupleIsValid(tuple))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("invalid role oid: %u", roleid)));
+
+ rolename =
+ pstrdup(NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname));
+
if (((Form_pg_authid) GETSTRUCT(tuple))->rolsuper || issuper >= 0)
{
if (!superuser())
@@ -720,12 +721,12 @@ 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
*/
@@ -794,7 +795,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] =
@@ -841,11 +842,11 @@ AlterRole(AlterRoleStmt *stmt)
CommandCounterIncrement();
if (stmt->action == +1) /* add members to role */
- AddRoleMems(stmt->role, roleid,
+ AddRoleMems(rolename, roleid,
rolemembers, roleNamesToIds(rolemembers),
GetUserId(), false);
else if (stmt->action == -1) /* drop members from role */
- DelRoleMems(stmt->role, roleid,
+ DelRoleMems(rolename, roleid,
rolemembers, roleNamesToIds(rolemembers),
false);
@@ -870,12 +871,20 @@ AlterRoleSet(AlterRoleSetStmt *stmt)
if (stmt->role)
{
- roletuple = SearchSysCache1(AUTHNAME, PointerGetDatum(stmt->role));
+ roleid = get_nameid_oid(stmt->role, false);
+
+ if (!OidIsValid(roleid))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("role \"%s\" does not exist", stmt->role->str)));
+
+
+ roletuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
if (!HeapTupleIsValid(roletuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("role \"%s\" does not exist", stmt->role)));
+ errmsg("invalid role oid: %u", roleid)));
roleid = HeapTupleGetOid(roletuple);
@@ -1163,13 +1172,6 @@ RenameRole(const char *oldname, const char *newname)
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("role \"%s\" already exists", newname)));
- if (strcmp(newname, "public") == 0 ||
- strcmp(newname, "none") == 0)
- ereport(ERROR,
- (errcode(ERRCODE_RESERVED_NAME),
- errmsg("role name \"%s\" is reserved",
- newname)));
-
/*
* createrole is enough privilege unless you want to mess with a superuser
*/
@@ -1240,7 +1242,7 @@ GrantRole(GrantRoleStmt *stmt)
ListCell *item;
if (stmt->grantor)
- grantor = get_role_oid(stmt->grantor, false);
+ grantor = get_nameid_oid(stmt->grantor, false);
else
grantor = GetUserId();
@@ -1335,7 +1337,7 @@ ReassignOwnedObjects(ReassignOwnedStmt *stmt)
}
/* Must have privileges on the receiving side too */
- newrole = get_role_oid(stmt->newrole, false);
+ newrole = get_nameid_oid(stmt->newrole, false);
if (!has_privs_of_role(GetUserId(), newrole))
ereport(ERROR,
@@ -1360,8 +1362,8 @@ roleNamesToIds(List *memberNames)
foreach(l, memberNames)
{
- char *rolename = strVal(lfirst(l));
- Oid roleid = get_role_oid(rolename, false);
+ NameId *rolename = (NameId*) lfirst(l);
+ Oid roleid = get_nameid_oid(rolename, false);
result = lappend_oid(result, roleid);
}
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 7b51d33..6a7efec 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -2470,6 +2470,17 @@ _copyXmlSerialize(const XmlSerialize *from)
return newnode;
}
+static NameId *
+_copyNameId(const NameId *from)
+{
+ NameId *newnode = makeNode(NameId);
+
+ COPY_SCALAR_FIELD(idtype);
+ COPY_STRING_FIELD(str);
+
+ return newnode;
+}
+
static Query *
_copyQuery(const Query *from)
{
@@ -2616,6 +2627,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);
@@ -2660,7 +2672,7 @@ _copyPrivGrantee(const PrivGrantee *from)
{
PrivGrantee *newnode = makeNode(PrivGrantee);
- COPY_STRING_FIELD(rolname);
+ COPY_NODE_FIELD(rolname);
return newnode;
}
@@ -2696,7 +2708,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;
@@ -3003,7 +3015,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;
}
@@ -3388,7 +3400,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);
@@ -3525,7 +3537,7 @@ _copyCreateUserMappingStmt(const CreateUserMappingStmt *from)
{
CreateUserMappingStmt *newnode = makeNode(CreateUserMappingStmt);
- COPY_STRING_FIELD(username);
+ COPY_NODE_FIELD(username);
COPY_STRING_FIELD(servername);
COPY_NODE_FIELD(options);
@@ -3537,7 +3549,7 @@ _copyAlterUserMappingStmt(const AlterUserMappingStmt *from)
{
AlterUserMappingStmt *newnode = makeNode(AlterUserMappingStmt);
- COPY_STRING_FIELD(username);
+ COPY_NODE_FIELD(username);
COPY_STRING_FIELD(servername);
COPY_NODE_FIELD(options);
@@ -3549,7 +3561,7 @@ _copyDropUserMappingStmt(const DropUserMappingStmt *from)
{
DropUserMappingStmt *newnode = makeNode(DropUserMappingStmt);
- COPY_STRING_FIELD(username);
+ COPY_NODE_FIELD(username);
COPY_STRING_FIELD(servername);
COPY_SCALAR_FIELD(missing_ok);
@@ -3662,7 +3674,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);
@@ -3674,7 +3686,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);
@@ -3735,7 +3747,7 @@ _copyCreateSchemaStmt(const CreateSchemaStmt *from)
CreateSchemaStmt *newnode = makeNode(CreateSchemaStmt);
COPY_STRING_FIELD(schemaname);
- COPY_STRING_FIELD(authid);
+ COPY_NODE_FIELD(authid);
COPY_NODE_FIELD(schemaElts);
COPY_SCALAR_FIELD(if_not_exists);
@@ -3820,7 +3832,7 @@ _copyReassignOwnedStmt(const ReassignOwnedStmt *from)
ReassignOwnedStmt *newnode = makeNode(ReassignOwnedStmt);
COPY_NODE_FIELD(roles);
- COPY_STRING_FIELD(newrole);
+ COPY_NODE_FIELD(newrole);
return newnode;
}
@@ -4703,6 +4715,9 @@ copyObject(const void *from)
case T_XmlSerialize:
retval = _copyXmlSerialize(from);
break;
+ case T_NameId:
+ retval = _copyNameId(from);
+ break;
default:
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(from));
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index d5db71d..407d229 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -971,6 +971,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);
@@ -1009,7 +1010,7 @@ _equalGrantStmt(const GrantStmt *a, const GrantStmt *b)
static bool
_equalPrivGrantee(const PrivGrantee *a, const PrivGrantee *b)
{
- COMPARE_STRING_FIELD(rolname);
+ COMPARE_NODE_FIELD(rolname);
return true;
}
@@ -1039,7 +1040,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;
@@ -1292,7 +1293,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;
}
@@ -1614,7 +1615,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);
@@ -1731,7 +1732,7 @@ _equalAlterForeignServerStmt(const AlterForeignServerStmt *a, const AlterForeign
static bool
_equalCreateUserMappingStmt(const CreateUserMappingStmt *a, const CreateUserMappingStmt *b)
{
- COMPARE_STRING_FIELD(username);
+ COMPARE_NODE_FIELD(username);
COMPARE_STRING_FIELD(servername);
COMPARE_NODE_FIELD(options);
@@ -1741,7 +1742,7 @@ _equalCreateUserMappingStmt(const CreateUserMappingStmt *a, const CreateUserMapp
static bool
_equalAlterUserMappingStmt(const AlterUserMappingStmt *a, const AlterUserMappingStmt *b)
{
- COMPARE_STRING_FIELD(username);
+ COMPARE_NODE_FIELD(username);
COMPARE_STRING_FIELD(servername);
COMPARE_NODE_FIELD(options);
@@ -1751,7 +1752,7 @@ _equalAlterUserMappingStmt(const AlterUserMappingStmt *a, const AlterUserMapping
static bool
_equalDropUserMappingStmt(const DropUserMappingStmt *a, const DropUserMappingStmt *b)
{
- COMPARE_STRING_FIELD(username);
+ COMPARE_NODE_FIELD(username);
COMPARE_STRING_FIELD(servername);
COMPARE_SCALAR_FIELD(missing_ok);
@@ -1849,7 +1850,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);
@@ -1859,7 +1860,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);
@@ -1910,7 +1911,7 @@ static bool
_equalCreateSchemaStmt(const CreateSchemaStmt *a, const CreateSchemaStmt *b)
{
COMPARE_STRING_FIELD(schemaname);
- COMPARE_STRING_FIELD(authid);
+ COMPARE_NODE_FIELD(authid);
COMPARE_NODE_FIELD(schemaElts);
COMPARE_SCALAR_FIELD(if_not_exists);
@@ -1981,7 +1982,7 @@ static bool
_equalReassignOwnedStmt(const ReassignOwnedStmt *a, const ReassignOwnedStmt *b)
{
COMPARE_NODE_FIELD(roles);
- COMPARE_STRING_FIELD(newrole);
+ COMPARE_NODE_FIELD(newrole);
return true;
}
@@ -2453,6 +2454,15 @@ _equalXmlSerialize(const XmlSerialize *a, const XmlSerialize *b)
return true;
}
+static bool
+_equalNameId(const NameId *a, const NameId *b)
+{
+ COMPARE_SCALAR_FIELD(idtype);
+ COMPARE_STRING_FIELD(str);
+
+ return true;
+}
+
/*
* Stuff from pg_list.h
*/
@@ -3163,6 +3173,9 @@ equal(const void *a, const void *b)
case T_XmlSerialize:
retval = _equalXmlSerialize(a, b);
break;
+ case T_NameId:
+ retval = _equalNameId(a, b);
+ break;
default:
elog(ERROR, "unrecognized node type: %d",
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index bd180e7..d523776 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -192,6 +192,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
int ival;
char *str;
const char *keyword;
+ NameId *nameid;
char chr;
bool boolean;
@@ -291,7 +292,7 @@ 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 <nameid> auth_ident
%type <str> opt_in_database
%type <str> OptSchemaName
@@ -474,7 +475,8 @@ 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 <nameid> RoleId opt_granted_by
+%type <str> 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
@@ -494,7 +496,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 <nameid> OptTableSpaceOwner
%type <ival> opt_check_option
%type <str> opt_provider security_label
@@ -864,8 +867,14 @@ CreateRoleStmt:
CREATE ROLE RoleId opt_with OptRoleList
{
CreateRoleStmt *n = makeNode(CreateRoleStmt);
+ NameId *nid = $3;
+ if (nid->idtype != NAMEID_CSTRING)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("role name should not be a keyword nor reserved name."),
+ parser_errposition(@3)));
n->stmt_type = ROLESTMT_ROLE;
- n->role = $3;
+ n->role = nid->str;
n->options = $5;
$$ = (Node *)n;
}
@@ -1021,8 +1030,14 @@ CreateUserStmt:
CREATE USER RoleId opt_with OptRoleList
{
CreateRoleStmt *n = makeNode(CreateRoleStmt);
+ NameId *nid = $3;
+ if (nid->idtype != NAMEID_CSTRING)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("role name should not be a keyword nor reserved name."),
+ parser_errposition(@3)));
n->stmt_type = ROLESTMT_USER;
- n->role = $3;
+ n->role = nid->str;
n->options = $5;
$$ = (Node *)n;
}
@@ -1164,8 +1179,14 @@ CreateGroupStmt:
CREATE GROUP_P RoleId opt_with OptRoleList
{
CreateRoleStmt *n = makeNode(CreateRoleStmt);
+ NameId *nid = $3;
+ if (nid->idtype != NAMEID_CSTRING)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("role name should not be a keyword nor reserved name."),
+ parser_errposition(@3)));
n->stmt_type = ROLESTMT_GROUP;
- n->role = $3;
+ n->role = nid->str;
n->options = $5;
$$ = (Node *)n;
}
@@ -1231,10 +1252,7 @@ CreateSchemaStmt:
{
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->schemaname = $3;
n->authid = $5;
n->schemaElts = $6;
n->if_not_exists = false;
@@ -1254,10 +1272,7 @@ CreateSchemaStmt:
{
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->schemaname = $6;
n->authid = $8;
if ($9 != NIL)
ereport(ERROR,
@@ -2263,7 +2278,7 @@ alter_table_cmd:
{
AlterTableCmd *n = makeNode(AlterTableCmd);
n->subtype = AT_ChangeOwner;
- n->name = $3;
+ n->newowner = $3;
$$ = (Node *)n;
}
/* ALTER TABLE <name> SET TABLESPACE <tablespacename> */
@@ -3727,7 +3742,7 @@ CreateTableSpaceStmt: CREATE TABLESPACE name OptTableSpaceOwner LOCATION Sconst
}
;
-OptTableSpaceOwner: OWNER name { $$ = $2; }
+OptTableSpaceOwner: OWNER RoleId { $$ = $2; }
| /*EMPTY */ { $$ = NULL; }
;
@@ -4458,9 +4473,19 @@ 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; }
+ RoleId
+ { $$ = $1; }
+ /*
+ * The keyword USER won't be appear in other syntxes so it is
+ * processed here, not at RoleId.
+ */
+ | USER
+ {
+ NameId *n = makeNode(NameId);
+ n->idtype = NAMEID_CURRENT_USER;
+ n->str = $1;
+ $$ = n;
+ }
;
/*****************************************************************************
@@ -5403,7 +5428,7 @@ DropOwnedStmt:
;
ReassignOwnedStmt:
- REASSIGN OWNED BY role_list TO name
+ REASSIGN OWNED BY role_list TO RoleId
{
ReassignOwnedStmt *n = makeNode(ReassignOwnedStmt);
n->roles = $4;
@@ -6221,21 +6246,27 @@ grantee_list:
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;
+ NameId *nid = $1;
+ if (nid->idtype == NAMEID_NONE)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("%s cannot be used as grantee name",
+ nid->str)));
+ n->rolname = nid;
$$ = (Node *)n;
}
| GROUP_P RoleId
+ /* Treat GROUP PUBLIC as a synonym for PUBLIC */
{
PrivGrantee *n = makeNode(PrivGrantee);
- /* Treat GROUP PUBLIC as a synonym for PUBLIC */
- if (strcmp($2, "public") == 0)
- n->rolname = NULL;
- else
- n->rolname = $2;
+ NameId *nid = $2;
+
+ if (nid->idtype == NAMEID_NONE)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("%s cannot be used as grantee name",
+ nid->str)));
+ n->rolname = nid;
$$ = (Node *)n;
}
;
@@ -7340,9 +7371,19 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
| ALTER GROUP_P RoleId RENAME TO RoleId
{
RenameStmt *n = makeNode(RenameStmt);
+ NameId *nold = $3;
+ NameId *nnew = $6;
+ if (nold->idtype != NAMEID_CSTRING ||
+ nnew->idtype != NAMEID_CSTRING)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("role name should not be a keyword nor reserved name."),
+ parser_errposition(
+ nold->idtype != NAMEID_CSTRING ?
+ @3 : @6)));
n->renameType = OBJECT_ROLE;
- n->subname = $3;
- n->newname = $6;
+ n->subname = nold->str;
+ n->newname = nnew->str;
n->missing_ok = false;
$$ = (Node *)n;
}
@@ -7640,18 +7681,38 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
| ALTER ROLE RoleId RENAME TO RoleId
{
RenameStmt *n = makeNode(RenameStmt);
+ NameId *nold = $3;
+ NameId *nnew = $6;
+ if (nold->idtype != NAMEID_CSTRING ||
+ nnew->idtype != NAMEID_CSTRING)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("role name should not be a keyword nor reserved name."),
+ parser_errposition(
+ nold->idtype != NAMEID_CSTRING ?
+ @3 : @6)));
n->renameType = OBJECT_ROLE;
- n->subname = $3;
- n->newname = $6;
+ n->subname = nold->str;
+ n->newname = nnew->str;
n->missing_ok = false;
$$ = (Node *)n;
}
| ALTER USER RoleId RENAME TO RoleId
{
RenameStmt *n = makeNode(RenameStmt);
+ NameId *nold = $3;
+ NameId *nnew = $6;
+ if (nold->idtype != NAMEID_CSTRING ||
+ nnew->idtype != NAMEID_CSTRING)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("role name should not be a keyword nor reserved name."),
+ parser_errposition(
+ nold->idtype != NAMEID_CSTRING ?
+ @3 : @6)));
n->renameType = OBJECT_ROLE;
- n->subname = $3;
- n->newname = $6;
+ n->subname = nold->str;
+ n->newname = nnew->str;
n->missing_ok = false;
$$ = (Node *)n;
}
@@ -10716,7 +10777,7 @@ opt_float: '(' Iconst ')'
if ($2 < 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("precision for type float must be at least 1 bit"),
+ errmsg("recision for type float must be at least 1 bit"),
parser_errposition(@2)));
else if ($2 <= 24)
$$ = SystemTypeName("float4");
@@ -12946,12 +13007,45 @@ AexprConst: Iconst
Iconst: ICONST { $$ = $1; };
Sconst: SCONST { $$ = $1; };
-RoleId: NonReservedWord { $$ = $1; };
+RoleId: NonReservedWord
+ {
+ /*
+ * The name "public" and "none" are decided not to be
+ * keywords. They cannot be used as identifier by any
+ * means as the result.
+ */
+ NameId *n = makeNode(NameId);
+ char *w = pstrdup($1);
+ if (strcmp(w, "public") == 0)
+ n->idtype = NAMEID_PUBLIC;
+ else if (strcmp(w, "none") == 0)
+ n->idtype = NAMEID_NONE;
+ else
+ n->idtype = NAMEID_CSTRING;
+ n->str = w;
+ $$ = n;
+ }
+ | CURRENT_USER
+ {
+ NameId *n = makeNode(NameId);
+ n->idtype = NAMEID_CURRENT_USER;
+ n->str = pstrdup($1);
+ $$ = n;
+ }
+ | SESSION_USER
+ {
+ NameId *n = makeNode(NameId);
+ n->idtype = NAMEID_SESSION_USER;
+ n->str = pstrdup($1);
+ $$ = n;
+ }
+ ;
+
role_list: RoleId
- { $$ = list_make1(makeString($1)); }
+ { $$ = list_make1($1); }
| role_list ',' RoleId
- { $$ = lappend($1, makeString($3)); }
+ { $$ = lappend($1, $3); }
;
SignedIconst: Iconst { $$ = $1; }
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 7c1939f..6753aea 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -90,7 +90,7 @@ typedef struct
{
const char *stmtType; /* "CREATE SCHEMA" or "ALTER SCHEMA" */
char *schemaname; /* name of schema */
- char *authid; /* owner of schema */
+ NameId *authid; /* owner of schema */
List *sequences; /* CREATE SEQUENCE items */
List *tables; /* CREATE TABLE items */
List *views; /* CREATE VIEW items */
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index dc6eb2c..f160dd1 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -5133,3 +5133,34 @@ get_role_oid_or_public(const char *rolname)
return get_role_oid(rolname, false);
}
+
+Oid
+get_nameid_oid(const NameId *rolname, bool missing_ok)
+{
+ Oid oid;
+
+ switch (rolname->idtype)
+ {
+ case NAMEID_CSTRING:
+ oid = get_role_oid(rolname->str, missing_ok);
+ break;
+ case NAMEID_CURRENT_USER:
+ oid = GetUserId();
+ break;
+ case NAMEID_SESSION_USER:
+ oid = GetSessionUserId();
+ break;
+ case NAMEID_PUBLIC:
+ case NAMEID_NONE:
+ /*
+ * XXX: this returning oid cannot be distinguised with not found in
+ * get_role_oid when messimg_ok.
+ */
+ oid = InvalidOid;
+ break;
+ default:
+ elog(ERROR, "Unexpected nameid for role: %d", rolname->idtype);
+ }
+
+ return oid;
+}
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 154d943..0393ea6 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -410,6 +410,7 @@ typedef enum NodeTag
T_XmlSerialize,
T_WithClause,
T_CommonTableExpr,
+ T_NameId,
/*
* TAGS FOR REPLICATION GRAMMAR PARSE NODES (replnodes.h)
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 3e4f815..1a0c35d 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -278,6 +278,25 @@ typedef struct CollateClause
} CollateClause;
/*
+ * NameId - Stroes arbitrary string or predefined id number
+ */
+typedef enum NameIdTypes
+{
+ NAMEID_CSTRING,
+ NAMEID_CURRENT_USER,
+ NAMEID_SESSION_USER,
+ NAMEID_PUBLIC,
+ NAMEID_NONE
+} NameIdTypes;
+
+typedef struct NameId
+{
+ NodeTag type;
+ NameIdTypes idtype; /* Type of this identifier */
+ char *str; /* Will be filled only for NAMEID_CSTRING */
+} NameId;
+
+/*
* FuncCall - a function or aggregate invocation
*
* agg_order (if not NIL) indicates we saw 'foo(... ORDER BY ...)', or if
@@ -1254,7 +1273,7 @@ typedef struct CreateSchemaStmt
{
NodeTag type;
char *schemaname; /* the name of the schema to create */
- char *authid; /* the owner of the created schema */
+ NameId *authid; /* 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;
@@ -1353,7 +1372,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 */
+ NameId *newowner; /* new owner could be special values */
Node *def; /* definition of new column, index,
* constraint, or parent table */
DropBehavior behavior; /* RESTRICT or CASCADE for DROP cases */
@@ -1433,7 +1453,7 @@ typedef struct GrantStmt
typedef struct PrivGrantee
{
NodeTag type;
- char *rolname; /* if NULL then PUBLIC */
+ NameId *rolname; /* if NULL then PUBLIC */
} PrivGrantee;
/*
@@ -1478,7 +1498,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 */
+ NameId *grantor; /* set grantor to other than current role */
DropBehavior behavior; /* drop behavior (for REVOKE) */
} GrantRoleStmt;
@@ -1690,7 +1710,7 @@ typedef struct CreateTableSpaceStmt
{
NodeTag type;
char *tablespacename;
- char *owner;
+ NameId *owner;
char *location;
List *options;
} CreateTableSpaceStmt;
@@ -1816,7 +1836,7 @@ typedef struct CreateForeignTableStmt
typedef struct CreateUserMappingStmt
{
NodeTag type;
- char *username; /* username or PUBLIC/CURRENT_USER */
+ NameId *username; /* username or PUBLIC/CURRENT_USER */
char *servername; /* server name */
List *options; /* generic options to server */
} CreateUserMappingStmt;
@@ -1824,7 +1844,7 @@ typedef struct CreateUserMappingStmt
typedef struct AlterUserMappingStmt
{
NodeTag type;
- char *username; /* username or PUBLIC/CURRENT_USER */
+ NameId *username; /* username or PUBLIC/CURRENT_USER */
char *servername; /* server name */
List *options; /* generic options to server */
} AlterUserMappingStmt;
@@ -1832,7 +1852,7 @@ typedef struct AlterUserMappingStmt
typedef struct DropUserMappingStmt
{
NodeTag type;
- char *username; /* username or PUBLIC/CURRENT_USER */
+ NameId *username; /* username or PUBLIC/CURRENT_USER */
char *servername; /* server name */
bool missing_ok; /* ignore missing mappings */
} DropUserMappingStmt;
@@ -1982,7 +2002,7 @@ typedef struct CreateRoleStmt
typedef struct AlterRoleStmt
{
NodeTag type;
- char *role; /* role name */
+ NameId *role; /* role name */
List *options; /* List of DefElem nodes */
int action; /* +1 = add members, -1 = drop members */
} AlterRoleStmt;
@@ -1990,7 +2010,7 @@ typedef struct AlterRoleStmt
typedef struct AlterRoleSetStmt
{
NodeTag type;
- char *role; /* role name */
+ NameId *role; /* role name */
char *database; /* database name, or NULL */
VariableSetStmt *setstmt; /* SET or RESET subcommand */
} AlterRoleSetStmt;
@@ -2365,7 +2385,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 */
+ NameId *newowner; /* the new owner */
} AlterOwnerStmt;
@@ -2813,7 +2833,7 @@ typedef struct ReassignOwnedStmt
{
NodeTag type;
List *roles;
- char *newrole;
+ NameId *newrole;
} ReassignOwnedStmt;
/*
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index a8e3164..0707f6c 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -229,7 +229,7 @@ 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_nameid_oid(const NameId *rolname, bool missing_ok);
extern void select_best_grantor(Oid roleId, AclMode privileges,
const Acl *acl, Oid ownerId,
Oid *grantorId, AclMode *grantOptions);
--
2.1.0.GIT
/* Current database is 'testdb' */
CREATE EXTENSION postgres_fdw;
-- postgres user is expected to be a superuser
\c testdb postgres
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)
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;
DROP ROLE IF EXISTS "Public";
DROP ROLE IF EXISTS "None";
DROP ROLE IF EXISTS "current_user";
DROP ROLE IF EXISTS "user";
DROP ROLE IF EXISTS "testrol0";
DROP ROLE IF EXISTS "testrol1";
DROP ROLE IF EXISTS "testrol2";
DROP ROLE IF EXISTS "testrolx";
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 testdb 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 NOREPLICATION;
SELECT * FROM chkrolattr();
ALTER USER 'current_user' WITH NOREPLICATION;
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;
DROP SCHEMA IF EXISTS newschema1;
DROP SCHEMA IF EXISTS newschema2;
DROP SCHEMA IF EXISTS newschema3;
DROP SCHEMA IF EXISTS newschema4;
DROP SCHEMA IF EXISTS newschema5;
DROP SCHEMA IF EXISTS newschema6;
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 testdb 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 testdb 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 testdb testrol0
DROP AGGREGATE IF EXISTS testagg1(int2);
DROP AGGREGATE IF EXISTS testagg2(int2);
DROP AGGREGATE IF EXISTS testagg3(int2);
DROP AGGREGATE IF EXISTS testagg4(int2);
DROP AGGREGATE IF EXISTS testagg5(int2);
DROP AGGREGATE IF EXISTS testagg6(int2);
DROP AGGREGATE IF EXISTS testagg7(int2);
DROP AGGREGATE IF EXISTS testagg8(int2);
DROP AGGREGATE IF EXISTS testagg9(int2);
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 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 testdb 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 testagg6(int2) OWNER TO CURRENT_ROLE; -- error
ALTER AGGREGATE testagg6(int2) OWNER TO USER; -- error
ALTER AGGREGATE testagg6(int2) OWNER TO PUBLIC; -- error
ALTER AGGREGATE testagg6(int2) OWNER TO "public"; -- error
ALTER AGGREGATE testagg6(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;
ALTER AGGREGATE testagg1(int2) OWNER TO postgres;
ALTER AGGREGATE testagg2(int2) OWNER TO postgres;
ALTER AGGREGATE testagg3(int2) OWNER TO postgres;
ALTER AGGREGATE testagg4(int2) OWNER TO postgres;
ALTER AGGREGATE testagg5(int2) OWNER TO postgres;
ALTER AGGREGATE testagg6(int2) OWNER TO postgres;
ALTER AGGREGATE testagg7(int2) OWNER TO postgres;
ALTER AGGREGATE testagg8(int2) OWNER TO postgres;
ALTER AGGREGATE testagg9(int2) OWNER TO postgres;
-- ALTER COLLATION, CONVERSION, DATABASE, DOMAIN, FUNCTION, LANGUAGE,
-- LARGEOBJECT, OPERATOR, OPCLASS, OPFAMILY, SCHEMA, TYPE,
-- TABLESPACE, TSDICTIONARY, TSCONFIGURATION, FDW, FOREIGN_SERVER,
-- EVENT_TRIGGER are processed in the same way.
-- See ExecAlterOwner Stmt for details.
-- CREATE USER MAPPING
-- needs postgres_fdw
CREATE SERVER sv1 FOREIGN DATA WRAPPER postgres_fdw;
CREATE SERVER sv2 FOREIGN DATA WRAPPER postgres_fdw;
CREATE SERVER sv3 FOREIGN DATA WRAPPER postgres_fdw;
CREATE SERVER sv4 FOREIGN DATA WRAPPER postgres_fdw;
CREATE SERVER sv5 FOREIGN DATA WRAPPER postgres_fdw;
CREATE SERVER sv6 FOREIGN DATA WRAPPER postgres_fdw;
CREATE SERVER sv7 FOREIGN DATA WRAPPER postgres_fdw;
CREATE SERVER sv8 FOREIGN DATA WRAPPER postgres_fdw;
CREATE SERVER sv9 FOREIGN DATA WRAPPER postgres_fdw;
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_';
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers