* foreigncmds.c
* foreign-data wrapper/server creation/manipulation commands
*
- * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
*
*
* IDENTIFICATION
}
-/*
- * 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.
*
AlterForeignDataWrapperOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
{
Form_pg_foreign_data_wrapper form;
+ Datum repl_val[Natts_pg_foreign_data_wrapper];
+ bool repl_null[Natts_pg_foreign_data_wrapper];
+ bool repl_repl[Natts_pg_foreign_data_wrapper];
+ Acl *newAcl;
+ Datum aclDatum;
+ bool isNull;
form = (Form_pg_foreign_data_wrapper) GETSTRUCT(tup);
if (form->fdwowner != newOwnerId)
{
- form->fdwowner = newOwnerId;
+ memset(repl_null, false, sizeof(repl_null));
+ memset(repl_repl, false, sizeof(repl_repl));
+
+ repl_repl[Anum_pg_foreign_data_wrapper_fdwowner - 1] = true;
+ repl_val[Anum_pg_foreign_data_wrapper_fdwowner - 1] = ObjectIdGetDatum(newOwnerId);
+
+ aclDatum = heap_getattr(tup,
+ Anum_pg_foreign_data_wrapper_fdwacl,
+ RelationGetDescr(rel),
+ &isNull);
+ /* Null ACLs do not require changes */
+ if (!isNull)
+ {
+ newAcl = aclnewowner(DatumGetAclP(aclDatum),
+ form->fdwowner, newOwnerId);
+ repl_repl[Anum_pg_foreign_data_wrapper_fdwacl - 1] = true;
+ repl_val[Anum_pg_foreign_data_wrapper_fdwacl - 1] = PointerGetDatum(newAcl);
+ }
+
+ tup = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val, repl_null,
+ repl_repl);
simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup);
*
* Note restrictions in the "_internal" function, above.
*/
-Oid
+ObjectAddress
AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
{
Oid fdwId;
HeapTuple tup;
Relation rel;
+ ObjectAddress address;
rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
AlterForeignDataWrapperOwner_internal(rel, tup, newOwnerId);
+ ObjectAddressSet(address, ForeignDataWrapperRelationId, fdwId);
+
heap_freetuple(tup);
heap_close(rel, RowExclusiveLock);
- return fdwId;
+ return address;
}
/*
AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
{
Form_pg_foreign_server form;
+ Datum repl_val[Natts_pg_foreign_server];
+ bool repl_null[Natts_pg_foreign_server];
+ bool repl_repl[Natts_pg_foreign_server];
+ Acl *newAcl;
+ Datum aclDatum;
+ bool isNull;
form = (Form_pg_foreign_server) GETSTRUCT(tup);
}
}
- form->srvowner = newOwnerId;
+ memset(repl_null, false, sizeof(repl_null));
+ memset(repl_repl, false, sizeof(repl_repl));
+
+ repl_repl[Anum_pg_foreign_server_srvowner - 1] = true;
+ repl_val[Anum_pg_foreign_server_srvowner - 1] = ObjectIdGetDatum(newOwnerId);
+
+ aclDatum = heap_getattr(tup,
+ Anum_pg_foreign_server_srvacl,
+ RelationGetDescr(rel),
+ &isNull);
+ /* Null ACLs do not require changes */
+ if (!isNull)
+ {
+ newAcl = aclnewowner(DatumGetAclP(aclDatum),
+ form->srvowner, newOwnerId);
+ repl_repl[Anum_pg_foreign_server_srvacl - 1] = true;
+ repl_val[Anum_pg_foreign_server_srvacl - 1] = PointerGetDatum(newAcl);
+ }
+
+ tup = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val, repl_null,
+ repl_repl);
simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup);
/*
* Change foreign server owner -- by name
*/
-Oid
+ObjectAddress
AlterForeignServerOwner(const char *name, Oid newOwnerId)
{
Oid servOid;
HeapTuple tup;
Relation rel;
+ ObjectAddress address;
rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
AlterForeignServerOwner_internal(rel, tup, newOwnerId);
+ ObjectAddressSet(address, ForeignServerRelationId, servOid);
+
heap_freetuple(tup);
heap_close(rel, RowExclusiveLock);
- return servOid;
+ return address;
}
/*
lookup_fdw_handler_func(DefElem *handler)
{
Oid handlerOid;
+ Oid funcargtypes[1]; /* dummy */
if (handler == NULL || handler->arg == NULL)
return InvalidOid;
/* handlers have no arguments */
- handlerOid = LookupFuncName((List *) handler->arg, 0, NULL, false);
+ handlerOid = LookupFuncName((List *) handler->arg, 0, funcargtypes, false);
/* check that handler has correct return type */
if (get_func_rettype(handlerOid) != FDW_HANDLEROID)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("function %s must return type \"fdw_handler\"",
- NameListToString((List *) handler->arg))));
+ errmsg("function %s must return type \"%s\"",
+ NameListToString((List *) handler->arg), "fdw_handler")));
return handlerOid;
}
/*
* Create a foreign-data wrapper
*/
-Oid
+ObjectAddress
CreateForeignDataWrapper(CreateFdwStmt *stmt)
{
Relation rel;
heap_close(rel, RowExclusiveLock);
- return fdwId;
+ return myself;
}
/*
* Alter foreign-data wrapper
*/
-Oid
+ObjectAddress
AlterForeignDataWrapper(AlterFdwStmt *stmt)
{
Relation rel;
bool validator_given;
Oid fdwhandler;
Oid fdwvalidator;
+ ObjectAddress myself;
rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
heap_freetuple(tp);
+ ObjectAddressSet(myself, ForeignDataWrapperRelationId, fdwId);
+
/* Update function dependencies if we changed them */
if (handler_given || validator_given)
{
- ObjectAddress myself;
ObjectAddress referenced;
/*
DEPENDENCY_NORMAL);
/* And build new ones. */
- myself.classId = ForeignDataWrapperRelationId;
- myself.objectId = fdwId;
- myself.objectSubId = 0;
if (OidIsValid(fdwhandler))
{
heap_close(rel, RowExclusiveLock);
- return fdwId;
+ return myself;
}
/*
* Create a foreign server
*/
-Oid
+ObjectAddress
CreateForeignServer(CreateForeignServerStmt *stmt)
{
Relation rel;
heap_close(rel, RowExclusiveLock);
- return srvId;
+ return myself;
}
/*
* Alter foreign server
*/
-Oid
+ObjectAddress
AlterForeignServer(AlterForeignServerStmt *stmt)
{
Relation rel;
bool repl_repl[Natts_pg_foreign_server];
Oid srvId;
Form_pg_foreign_server srvForm;
+ ObjectAddress address;
rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
InvokeObjectPostAlterHook(ForeignServerRelationId, srvId, 0);
+ ObjectAddressSet(address, ForeignServerRelationId, srvId);
+
heap_freetuple(tp);
heap_close(rel, RowExclusiveLock);
- return srvId;
+ return address;
}
/*
* Create user mapping
*/
-Oid
+ObjectAddress
CreateUserMapping(CreateUserMappingStmt *stmt)
{
Relation rel;
ObjectAddress referenced;
ForeignServer *srv;
ForeignDataWrapper *fdw;
+ RoleSpec *role = (RoleSpec *) stmt->user;
rel = heap_open(UserMappingRelationId, RowExclusiveLock);
- useId = GetUserOidFromMapping(stmt->username, false);
+ if (role->roletype == ROLESPEC_PUBLIC)
+ useId = ACL_ID_PUBLIC;
+ else
+ useId = get_rolespec_oid(stmt->user, false);
/* Check that the server exists. */
srv = GetForeignServerByName(stmt->servername, false);
heap_close(rel, RowExclusiveLock);
- return umId;
+ return myself;
}
/*
* Alter user mapping
*/
-Oid
+ObjectAddress
AlterUserMapping(AlterUserMappingStmt *stmt)
{
Relation rel;
Oid useId;
Oid umId;
ForeignServer *srv;
+ ObjectAddress address;
+ RoleSpec *role = (RoleSpec *) stmt->user;
rel = heap_open(UserMappingRelationId, RowExclusiveLock);
- useId = GetUserOidFromMapping(stmt->username, false);
+ if (role->roletype == ROLESPEC_PUBLIC)
+ useId = ACL_ID_PUBLIC;
+ else
+ useId = get_rolespec_oid(stmt->user, false);
+
srv = GetForeignServerByName(stmt->servername, false);
umId = GetSysCacheOid2(USERMAPPINGUSERSERVER,
simple_heap_update(rel, &tp->t_self, tp);
CatalogUpdateIndexes(rel, tp);
+ ObjectAddressSet(address, UserMappingRelationId, umId);
+
heap_freetuple(tp);
heap_close(rel, RowExclusiveLock);
- return umId;
+ return address;
}
Oid useId;
Oid umId;
ForeignServer *srv;
+ RoleSpec *role = (RoleSpec *) stmt->user;
- useId = GetUserOidFromMapping(stmt->username, stmt->missing_ok);
- srv = GetForeignServerByName(stmt->servername, true);
-
- if (stmt->username && !OidIsValid(useId))
+ if (role->roletype == ROLESPEC_PUBLIC)
+ useId = ACL_ID_PUBLIC;
+ else
{
- /*
- * IF EXISTS specified, role not found and not public. Notice this and
- * leave.
- */
- elog(NOTICE, "role \"%s\" does not exist, skipping", stmt->username);
- return InvalidOid;
+ useId = get_rolespec_oid(stmt->user, stmt->missing_ok);
+ if (!OidIsValid(useId))
+ {
+ /*
+ * IF EXISTS specified, role not found and not public. Notice this
+ * and leave.
+ */
+ elog(NOTICE, "role \"%s\" does not exist, skipping",
+ role->rolename);
+ return InvalidOid;
+ }
}
+ srv = GetForeignServerByName(stmt->servername, true);
+
if (!srv)
{
if (!stmt->missing_ok)