1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-13 16:22:44 +03:00

Support user mappings in get_object_address

Since commit 72dd233d3e we were trying to obtain object addressing
information in sql_drop event triggers, but that caused failures when
the drops involved user mappings.  This addition enables that to work
again.  Naturally, pg_get_object_address can work with these objects
now, too.

I toyed with the idea of removing DropUserMappingStmt as a node and
using DropStmt instead in the DropUserMappingStmt grammar production,
but that didn't go very well: for one thing the messages thrown by the
specific code are specialized (you get "server not found" if you specify
the wrong server, instead of a generic "user mapping for ... not found"
which you'd get it we were to merge this with RemoveObjects --- unless
we added even more special cases).  For another thing, it would require
to pass RoleSpec nodes through the objname/objargs representation used
by RemoveObjects, which works in isolation, but gets messy when
pg_get_object_address is involved.  So I dropped this part for now.

Reviewed by Stephen Frost.
This commit is contained in:
Alvaro Herrera
2015-03-11 17:01:13 -03:00
parent 1ce7a57ca6
commit 890192e99a
7 changed files with 109 additions and 13 deletions

View File

@@ -520,7 +520,7 @@ ObjectTypeMap[] =
/* OCLASS_FOREIGN_SERVER */
{ "server", OBJECT_FOREIGN_SERVER },
/* OCLASS_USER_MAPPING */
{ "user mapping", -1 }, /* unmapped */
{ "user mapping", OBJECT_USER_MAPPING },
/* OCLASS_DEFACL */
{ "default acl", -1 }, /* unmapped */
/* OCLASS_EXTENSION */
@@ -555,6 +555,8 @@ static ObjectAddress get_object_address_type(ObjectType objtype,
List *objname, bool missing_ok);
static ObjectAddress get_object_address_opcf(ObjectType objtype, List *objname,
List *objargs, bool missing_ok);
static ObjectAddress get_object_address_usermapping(List *objname,
List *objargs, bool missing_ok);
static const ObjectPropertyType *get_object_property_data(Oid class_id);
static void getRelationDescription(StringInfo buffer, Oid relid);
@@ -769,6 +771,10 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
address.objectId = get_ts_config_oid(objname, missing_ok);
address.objectSubId = 0;
break;
case OBJECT_USER_MAPPING:
address = get_object_address_usermapping(objname, objargs,
missing_ok);
break;
default:
elog(ERROR, "unrecognized objtype: %d", (int) objtype);
/* placate compiler, in case it thinks elog might return */
@@ -1372,6 +1378,75 @@ get_object_address_opcf(ObjectType objtype,
return address;
}
/*
* Find the ObjectAddress for a user mapping.
*/
static ObjectAddress
get_object_address_usermapping(List *objname, List *objargs, bool missing_ok)
{
ObjectAddress address;
Oid userid;
char *username;
char *servername;
ForeignServer *server;
HeapTuple tp;
ObjectAddressSet(address, UserMappingRelationId, InvalidOid);
/* fetch string names from input lists, for error messages */
username = strVal(linitial(objname));
servername = strVal(linitial(objargs));
/* look up pg_authid OID of mapped user; InvalidOid if PUBLIC */
if (strcmp(username, "public") == 0)
userid = InvalidOid;
else
{
tp = SearchSysCache1(AUTHNAME,
CStringGetDatum(username));
if (!HeapTupleIsValid(tp))
{
if (!missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("user mapping for user \"%s\" in server \"%s\" does not exist",
username, servername)));
return address;
}
userid = HeapTupleGetOid(tp);
ReleaseSysCache(tp);
}
/* Now look up the pg_user_mapping tuple */
server = GetForeignServerByName(servername, true);
if (!server)
{
if (!missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("server \"%s\" does not exist", servername)));
return address;
}
tp = SearchSysCache2(USERMAPPINGUSERSERVER,
ObjectIdGetDatum(userid),
ObjectIdGetDatum(server->serverid));
if (!HeapTupleIsValid(tp))
{
if (!missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("user mapping for user \"%s\" in server \"%s\" does not exist",
username, servername)));
return address;
}
address.objectId = HeapTupleGetOid(tp);
ReleaseSysCache(tp);
return address;
}
/*
* Convert an array of TEXT into a List of string Values, as emitted by the
* parser, which is what get_object_address uses as input.
@@ -1523,6 +1598,7 @@ pg_get_object_address(PG_FUNCTION_ARGS)
case OBJECT_OPCLASS:
case OBJECT_OPFAMILY:
case OBJECT_CAST:
case OBJECT_USER_MAPPING:
if (list_length(args) != 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),

View File

@@ -1092,6 +1092,7 @@ EventTriggerSupportsObjectType(ObjectType obtype)
case OBJECT_TSPARSER:
case OBJECT_TSTEMPLATE:
case OBJECT_TYPE:
case OBJECT_USER_MAPPING:
case OBJECT_VIEW:
return true;
}