#include "postgres.h"#include "access/heapam.h"#include "access/htup_details.h"#include "access/xact.h"#include "access/reloptions.h"#include "catalog/dependency.h"#include "catalog/indexing.h"#include "catalog/objectaccess.h"#include "catalog/pg_foreign_data_wrapper.h"#include "catalog/pg_foreign_server.h"#include "catalog/pg_foreign_table.h"#include "catalog/pg_proc.h"#include "catalog/pg_type.h"#include "catalog/pg_user_mapping.h"#include "commands/defrem.h"#include "foreign/foreign.h"#include "miscadmin.h"#include "parser/parse_func.h"#include "utils/acl.h"#include "utils/builtins.h"#include "utils/lsyscache.h"#include "utils/rel.h"#include "utils/syscache.h"
Go to the source code of this file.
| Oid AlterForeignDataWrapper | ( | AlterFdwStmt * | stmt | ) |
Definition at line 620 of file foreigncmds.c.
References Anum_pg_foreign_data_wrapper_fdwhandler, Anum_pg_foreign_data_wrapper_fdwoptions, Anum_pg_foreign_data_wrapper_fdwvalidator, CatalogUpdateIndexes(), ObjectAddress::classId, CStringGetDatum, DatumGetPointer, deleteDependencyRecordsForClass(), DEPENDENCY_NORMAL, ereport, errcode(), errhint(), errmsg(), ERROR, AlterFdwStmt::fdwname, FOREIGNDATAWRAPPERNAME, FOREIGNDATAWRAPPEROID, ForeignDataWrapperRelationId, AlterFdwStmt::func_options, GETSTRUCT, heap_close, heap_freetuple(), heap_modify_tuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, InvokeObjectPostAlterHook, NULL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OidIsValid, AlterFdwStmt::options, parse_func_options(), PointerGetDatum, PointerIsValid, ProcedureRelationId, recordDependencyOn(), RelationGetDescr, RowExclusiveLock, SearchSysCacheCopy1, simple_heap_update(), superuser(), SysCacheGetAttr(), HeapTupleData::t_self, transformGenericOptions(), and WARNING.
Referenced by ProcessUtilitySlow().
{
Relation rel;
HeapTuple tp;
Form_pg_foreign_data_wrapper fdwForm;
Datum repl_val[Natts_pg_foreign_data_wrapper];
bool repl_null[Natts_pg_foreign_data_wrapper];
bool repl_repl[Natts_pg_foreign_data_wrapper];
Oid fdwId;
bool isnull;
Datum datum;
bool handler_given;
bool validator_given;
Oid fdwhandler;
Oid fdwvalidator;
rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
/* Must be super user */
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied to alter foreign-data wrapper \"%s\"",
stmt->fdwname),
errhint("Must be superuser to alter a foreign-data wrapper.")));
tp = SearchSysCacheCopy1(FOREIGNDATAWRAPPERNAME,
CStringGetDatum(stmt->fdwname));
if (!HeapTupleIsValid(tp))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("foreign-data wrapper \"%s\" does not exist", stmt->fdwname)));
fdwForm = (Form_pg_foreign_data_wrapper) GETSTRUCT(tp);
fdwId = HeapTupleGetOid(tp);
memset(repl_val, 0, sizeof(repl_val));
memset(repl_null, false, sizeof(repl_null));
memset(repl_repl, false, sizeof(repl_repl));
parse_func_options(stmt->func_options,
&handler_given, &fdwhandler,
&validator_given, &fdwvalidator);
if (handler_given)
{
repl_val[Anum_pg_foreign_data_wrapper_fdwhandler - 1] = ObjectIdGetDatum(fdwhandler);
repl_repl[Anum_pg_foreign_data_wrapper_fdwhandler - 1] = true;
/*
* It could be that the behavior of accessing foreign table changes
* with the new handler. Warn about this.
*/
ereport(WARNING,
(errmsg("changing the foreign-data wrapper handler can change behavior of existing foreign tables")));
}
if (validator_given)
{
repl_val[Anum_pg_foreign_data_wrapper_fdwvalidator - 1] = ObjectIdGetDatum(fdwvalidator);
repl_repl[Anum_pg_foreign_data_wrapper_fdwvalidator - 1] = true;
/*
* It could be that the options for the FDW, SERVER and USER MAPPING
* are no longer valid with the new validator. Warn about this.
*/
if (OidIsValid(fdwvalidator))
ereport(WARNING,
(errmsg("changing the foreign-data wrapper validator can cause "
"the options for dependent objects to become invalid")));
}
else
{
/*
* Validator is not changed, but we need it for validating options.
*/
fdwvalidator = fdwForm->fdwvalidator;
}
/*
* If options specified, validate and update.
*/
if (stmt->options)
{
/* Extract the current options */
datum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID,
tp,
Anum_pg_foreign_data_wrapper_fdwoptions,
&isnull);
if (isnull)
datum = PointerGetDatum(NULL);
/* Transform the options */
datum = transformGenericOptions(ForeignDataWrapperRelationId,
datum,
stmt->options,
fdwvalidator);
if (PointerIsValid(DatumGetPointer(datum)))
repl_val[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = datum;
else
repl_null[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = true;
repl_repl[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = true;
}
/* Everything looks good - update the tuple */
tp = heap_modify_tuple(tp, RelationGetDescr(rel),
repl_val, repl_null, repl_repl);
simple_heap_update(rel, &tp->t_self, tp);
CatalogUpdateIndexes(rel, tp);
heap_freetuple(tp);
/* Update function dependencies if we changed them */
if (handler_given || validator_given)
{
ObjectAddress myself;
ObjectAddress referenced;
/*
* Flush all existing dependency records of this FDW on functions; we
* assume there can be none other than the ones we are fixing.
*/
deleteDependencyRecordsForClass(ForeignDataWrapperRelationId,
fdwId,
ProcedureRelationId,
DEPENDENCY_NORMAL);
/* And build new ones. */
myself.classId = ForeignDataWrapperRelationId;
myself.objectId = fdwId;
myself.objectSubId = 0;
if (OidIsValid(fdwhandler))
{
referenced.classId = ProcedureRelationId;
referenced.objectId = fdwhandler;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
if (OidIsValid(fdwvalidator))
{
referenced.classId = ProcedureRelationId;
referenced.objectId = fdwvalidator;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
}
InvokeObjectPostAlterHook(ForeignDataWrapperRelationId, fdwId, 0);
heap_close(rel, RowExclusiveLock);
return fdwId;
}
Definition at line 255 of file foreigncmds.c.
References AlterForeignDataWrapperOwner_internal(), CStringGetDatum, ereport, errcode(), errmsg(), ERROR, FOREIGNDATAWRAPPERNAME, ForeignDataWrapperRelationId, heap_close, heap_freetuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, RowExclusiveLock, and SearchSysCacheCopy1.
Referenced by ExecAlterOwnerStmt().
{
Oid fdwId;
HeapTuple tup;
Relation rel;
rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPERNAME, CStringGetDatum(name));
if (!HeapTupleIsValid(tup))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("foreign-data wrapper \"%s\" does not exist", name)));
fdwId = HeapTupleGetOid(tup);
AlterForeignDataWrapperOwner_internal(rel, tup, newOwnerId);
heap_freetuple(tup);
heap_close(rel, RowExclusiveLock);
return fdwId;
}
| static void AlterForeignDataWrapperOwner_internal | ( | Relation | rel, | |
| HeapTuple | tup, | |||
| Oid | newOwnerId | |||
| ) | [static] |
Definition at line 210 of file foreigncmds.c.
References CatalogUpdateIndexes(), changeDependencyOnOwner(), ereport, errcode(), errhint(), errmsg(), ERROR, ForeignDataWrapperRelationId, GETSTRUCT, HeapTupleGetOid, InvokeObjectPostAlterHook, NameStr, simple_heap_update(), superuser(), superuser_arg(), and HeapTupleData::t_self.
Referenced by AlterForeignDataWrapperOwner(), and AlterForeignDataWrapperOwner_oid().
{
Form_pg_foreign_data_wrapper form;
form = (Form_pg_foreign_data_wrapper) GETSTRUCT(tup);
/* Must be a superuser to change a FDW owner */
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied to change owner of foreign-data wrapper \"%s\"",
NameStr(form->fdwname)),
errhint("Must be superuser to change owner of a foreign-data wrapper.")));
/* New owner must also be a superuser */
if (!superuser_arg(newOwnerId))
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied to change owner of foreign-data wrapper \"%s\"",
NameStr(form->fdwname)),
errhint("The owner of a foreign-data wrapper must be a superuser.")));
if (form->fdwowner != newOwnerId)
{
form->fdwowner = newOwnerId;
simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup);
/* Update owner dependency reference */
changeDependencyOnOwner(ForeignDataWrapperRelationId,
HeapTupleGetOid(tup),
newOwnerId);
}
InvokeObjectPostAlterHook(ForeignDataWrapperRelationId,
HeapTupleGetOid(tup), 0);
}
Definition at line 287 of file foreigncmds.c.
References AlterForeignDataWrapperOwner_internal(), ereport, errcode(), errmsg(), ERROR, FOREIGNDATAWRAPPEROID, ForeignDataWrapperRelationId, heap_close, heap_freetuple(), heap_open(), HeapTupleIsValid, ObjectIdGetDatum, RowExclusiveLock, and SearchSysCacheCopy1.
Referenced by shdepReassignOwned().
{
HeapTuple tup;
Relation rel;
rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fwdId));
if (!HeapTupleIsValid(tup))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("foreign-data wrapper with OID %u does not exist", fwdId)));
AlterForeignDataWrapperOwner_internal(rel, tup, newOwnerId);
heap_freetuple(tup);
heap_close(rel, RowExclusiveLock);
}
| Oid AlterForeignServer | ( | AlterForeignServerStmt * | stmt | ) |
Definition at line 922 of file foreigncmds.c.
References ACL_KIND_FOREIGN_SERVER, aclcheck_error(), ACLCHECK_NOT_OWNER, Anum_pg_foreign_server_srvoptions, Anum_pg_foreign_server_srvversion, CatalogUpdateIndexes(), CStringGetDatum, CStringGetTextDatum, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, ForeignDataWrapper::fdwvalidator, FOREIGNSERVERNAME, FOREIGNSERVEROID, ForeignServerRelationId, GetForeignDataWrapper(), GETSTRUCT, GetUserId(), AlterForeignServerStmt::has_version, heap_close, heap_freetuple(), heap_modify_tuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, InvokeObjectPostAlterHook, NULL, AlterForeignServerStmt::options, pg_foreign_server_ownercheck(), PointerGetDatum, PointerIsValid, RelationGetDescr, RowExclusiveLock, SearchSysCacheCopy1, AlterForeignServerStmt::servername, simple_heap_update(), SysCacheGetAttr(), HeapTupleData::t_self, transformGenericOptions(), and AlterForeignServerStmt::version.
Referenced by ProcessUtilitySlow().
{
Relation rel;
HeapTuple tp;
Datum repl_val[Natts_pg_foreign_server];
bool repl_null[Natts_pg_foreign_server];
bool repl_repl[Natts_pg_foreign_server];
Oid srvId;
Form_pg_foreign_server srvForm;
rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
tp = SearchSysCacheCopy1(FOREIGNSERVERNAME,
CStringGetDatum(stmt->servername));
if (!HeapTupleIsValid(tp))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("server \"%s\" does not exist", stmt->servername)));
srvId = HeapTupleGetOid(tp);
srvForm = (Form_pg_foreign_server) GETSTRUCT(tp);
/*
* Only owner or a superuser can ALTER a SERVER.
*/
if (!pg_foreign_server_ownercheck(srvId, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER,
stmt->servername);
memset(repl_val, 0, sizeof(repl_val));
memset(repl_null, false, sizeof(repl_null));
memset(repl_repl, false, sizeof(repl_repl));
if (stmt->has_version)
{
/*
* Change the server VERSION string.
*/
if (stmt->version)
repl_val[Anum_pg_foreign_server_srvversion - 1] =
CStringGetTextDatum(stmt->version);
else
repl_null[Anum_pg_foreign_server_srvversion - 1] = true;
repl_repl[Anum_pg_foreign_server_srvversion - 1] = true;
}
if (stmt->options)
{
ForeignDataWrapper *fdw = GetForeignDataWrapper(srvForm->srvfdw);
Datum datum;
bool isnull;
/* Extract the current srvoptions */
datum = SysCacheGetAttr(FOREIGNSERVEROID,
tp,
Anum_pg_foreign_server_srvoptions,
&isnull);
if (isnull)
datum = PointerGetDatum(NULL);
/* Prepare the options array */
datum = transformGenericOptions(ForeignServerRelationId,
datum,
stmt->options,
fdw->fdwvalidator);
if (PointerIsValid(DatumGetPointer(datum)))
repl_val[Anum_pg_foreign_server_srvoptions - 1] = datum;
else
repl_null[Anum_pg_foreign_server_srvoptions - 1] = true;
repl_repl[Anum_pg_foreign_server_srvoptions - 1] = true;
}
/* Everything looks good - update the tuple */
tp = heap_modify_tuple(tp, RelationGetDescr(rel),
repl_val, repl_null, repl_repl);
simple_heap_update(rel, &tp->t_self, tp);
CatalogUpdateIndexes(rel, tp);
InvokeObjectPostAlterHook(ForeignServerRelationId, srvId, 0);
heap_freetuple(tp);
heap_close(rel, RowExclusiveLock);
return srvId;
}
Definition at line 364 of file foreigncmds.c.
References AlterForeignServerOwner_internal(), CStringGetDatum, ereport, errcode(), errmsg(), ERROR, FOREIGNSERVERNAME, ForeignServerRelationId, heap_close, heap_freetuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, RowExclusiveLock, and SearchSysCacheCopy1.
Referenced by ExecAlterOwnerStmt().
{
Oid servOid;
HeapTuple tup;
Relation rel;
rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
tup = SearchSysCacheCopy1(FOREIGNSERVERNAME, CStringGetDatum(name));
if (!HeapTupleIsValid(tup))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("server \"%s\" does not exist", name)));
servOid = HeapTupleGetOid(tup);
AlterForeignServerOwner_internal(rel, tup, newOwnerId);
heap_freetuple(tup);
heap_close(rel, RowExclusiveLock);
return servOid;
}
| static void AlterForeignServerOwner_internal | ( | Relation | rel, | |
| HeapTuple | tup, | |||
| Oid | newOwnerId | |||
| ) | [static] |
Definition at line 312 of file foreigncmds.c.
References ACL_KIND_FDW, ACL_KIND_FOREIGN_SERVER, ACL_USAGE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, CatalogUpdateIndexes(), changeDependencyOnOwner(), check_is_member_of_role(), ForeignDataWrapper::fdwname, ForeignServerRelationId, GetForeignDataWrapper(), GETSTRUCT, GetUserId(), HeapTupleGetOid, InvokeObjectPostAlterHook, NameStr, pg_foreign_data_wrapper_aclcheck(), pg_foreign_server_ownercheck(), simple_heap_update(), superuser(), and HeapTupleData::t_self.
Referenced by AlterForeignServerOwner(), and AlterForeignServerOwner_oid().
{
Form_pg_foreign_server form;
form = (Form_pg_foreign_server) GETSTRUCT(tup);
if (form->srvowner != newOwnerId)
{
/* Superusers can always do it */
if (!superuser())
{
Oid srvId;
AclResult aclresult;
srvId = HeapTupleGetOid(tup);
/* Must be owner */
if (!pg_foreign_server_ownercheck(srvId, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER,
NameStr(form->srvname));
/* Must be able to become new owner */
check_is_member_of_role(GetUserId(), newOwnerId);
/* New owner must have USAGE privilege on foreign-data wrapper */
aclresult = pg_foreign_data_wrapper_aclcheck(form->srvfdw, newOwnerId, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
{
ForeignDataWrapper *fdw = GetForeignDataWrapper(form->srvfdw);
aclcheck_error(aclresult, ACL_KIND_FDW, fdw->fdwname);
}
}
form->srvowner = newOwnerId;
simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup);
/* Update owner dependency reference */
changeDependencyOnOwner(ForeignServerRelationId, HeapTupleGetOid(tup),
newOwnerId);
}
InvokeObjectPostAlterHook(ForeignServerRelationId,
HeapTupleGetOid(tup), 0);
}
Definition at line 394 of file foreigncmds.c.
References AlterForeignServerOwner_internal(), ereport, errcode(), errmsg(), ERROR, FOREIGNSERVEROID, ForeignServerRelationId, heap_close, heap_freetuple(), heap_open(), HeapTupleIsValid, ObjectIdGetDatum, RowExclusiveLock, and SearchSysCacheCopy1.
Referenced by shdepReassignOwned().
{
HeapTuple tup;
Relation rel;
rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
tup = SearchSysCacheCopy1(FOREIGNSERVEROID, ObjectIdGetDatum(srvId));
if (!HeapTupleIsValid(tup))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("foreign server with OID %u does not exist", srvId)));
AlterForeignServerOwner_internal(rel, tup, newOwnerId);
heap_freetuple(tup);
heap_close(rel, RowExclusiveLock);
}
| Oid AlterUserMapping | ( | AlterUserMappingStmt * | stmt | ) |
Definition at line 1168 of file foreigncmds.c.
References Anum_pg_user_mapping_umoptions, CatalogUpdateIndexes(), DatumGetPointer, elog, ereport, errcode(), errmsg(), ERROR, ForeignServer::fdwid, ForeignDataWrapper::fdwvalidator, GetForeignDataWrapper(), GetForeignServerByName(), GetSysCacheOid2, GetUserOidFromMapping(), heap_close, heap_freetuple(), heap_modify_tuple(), heap_open(), HeapTupleIsValid, MappingUserName, NULL, ObjectIdGetDatum, OidIsValid, AlterUserMappingStmt::options, PointerGetDatum, PointerIsValid, RelationGetDescr, RowExclusiveLock, SearchSysCacheCopy1, ForeignServer::serverid, AlterUserMappingStmt::servername, simple_heap_update(), SysCacheGetAttr(), HeapTupleData::t_self, transformGenericOptions(), user_mapping_ddl_aclcheck(), USERMAPPINGOID, UserMappingRelationId, USERMAPPINGUSERSERVER, and AlterUserMappingStmt::username.
Referenced by ProcessUtilitySlow().
{
Relation rel;
HeapTuple tp;
Datum repl_val[Natts_pg_user_mapping];
bool repl_null[Natts_pg_user_mapping];
bool repl_repl[Natts_pg_user_mapping];
Oid useId;
Oid umId;
ForeignServer *srv;
rel = heap_open(UserMappingRelationId, RowExclusiveLock);
useId = GetUserOidFromMapping(stmt->username, false);
srv = GetForeignServerByName(stmt->servername, false);
umId = GetSysCacheOid2(USERMAPPINGUSERSERVER,
ObjectIdGetDatum(useId),
ObjectIdGetDatum(srv->serverid));
if (!OidIsValid(umId))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("user mapping \"%s\" does not exist for the server",
MappingUserName(useId))));
user_mapping_ddl_aclcheck(useId, srv->serverid, stmt->servername);
tp = SearchSysCacheCopy1(USERMAPPINGOID, ObjectIdGetDatum(umId));
if (!HeapTupleIsValid(tp))
elog(ERROR, "cache lookup failed for user mapping %u", umId);
memset(repl_val, 0, sizeof(repl_val));
memset(repl_null, false, sizeof(repl_null));
memset(repl_repl, false, sizeof(repl_repl));
if (stmt->options)
{
ForeignDataWrapper *fdw;
Datum datum;
bool isnull;
/*
* Process the options.
*/
fdw = GetForeignDataWrapper(srv->fdwid);
datum = SysCacheGetAttr(USERMAPPINGUSERSERVER,
tp,
Anum_pg_user_mapping_umoptions,
&isnull);
if (isnull)
datum = PointerGetDatum(NULL);
/* Prepare the options array */
datum = transformGenericOptions(UserMappingRelationId,
datum,
stmt->options,
fdw->fdwvalidator);
if (PointerIsValid(DatumGetPointer(datum)))
repl_val[Anum_pg_user_mapping_umoptions - 1] = datum;
else
repl_null[Anum_pg_user_mapping_umoptions - 1] = true;
repl_repl[Anum_pg_user_mapping_umoptions - 1] = true;
}
/* Everything looks good - update the tuple */
tp = heap_modify_tuple(tp, RelationGetDescr(rel),
repl_val, repl_null, repl_repl);
simple_heap_update(rel, &tp->t_self, tp);
CatalogUpdateIndexes(rel, tp);
heap_freetuple(tp);
heap_close(rel, RowExclusiveLock);
return umId;
}
| Oid CreateForeignDataWrapper | ( | CreateFdwStmt * | stmt | ) |
Definition at line 506 of file foreigncmds.c.
References Anum_pg_foreign_data_wrapper_fdwacl, Anum_pg_foreign_data_wrapper_fdwhandler, Anum_pg_foreign_data_wrapper_fdwname, Anum_pg_foreign_data_wrapper_fdwoptions, Anum_pg_foreign_data_wrapper_fdwowner, Anum_pg_foreign_data_wrapper_fdwvalidator, CatalogUpdateIndexes(), ObjectAddress::classId, CStringGetDatum, DatumGetPointer, DEPENDENCY_NORMAL, DirectFunctionCall1, ereport, errcode(), errhint(), errmsg(), ERROR, CreateFdwStmt::fdwname, ForeignDataWrapperRelationId, CreateFdwStmt::func_options, GetForeignDataWrapperByName(), GetUserId(), heap_close, heap_form_tuple(), heap_freetuple(), heap_open(), InvokeObjectPostCreateHook, namein(), NULL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OidIsValid, CreateFdwStmt::options, parse_func_options(), PointerGetDatum, PointerIsValid, RelationData::rd_att, recordDependencyOn(), recordDependencyOnCurrentExtension(), recordDependencyOnOwner(), RowExclusiveLock, simple_heap_insert(), superuser(), transformGenericOptions(), and values.
Referenced by ProcessUtilitySlow().
{
Relation rel;
Datum values[Natts_pg_foreign_data_wrapper];
bool nulls[Natts_pg_foreign_data_wrapper];
HeapTuple tuple;
Oid fdwId;
bool handler_given;
bool validator_given;
Oid fdwhandler;
Oid fdwvalidator;
Datum fdwoptions;
Oid ownerId;
ObjectAddress myself;
ObjectAddress referenced;
rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
/* Must be super user */
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied to create foreign-data wrapper \"%s\"",
stmt->fdwname),
errhint("Must be superuser to create a foreign-data wrapper.")));
/* For now the owner cannot be specified on create. Use effective user ID. */
ownerId = GetUserId();
/*
* Check that there is no other foreign-data wrapper by this name.
*/
if (GetForeignDataWrapperByName(stmt->fdwname, true) != NULL)
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("foreign-data wrapper \"%s\" already exists",
stmt->fdwname)));
/*
* Insert tuple into pg_foreign_data_wrapper.
*/
memset(values, 0, sizeof(values));
memset(nulls, false, sizeof(nulls));
values[Anum_pg_foreign_data_wrapper_fdwname - 1] =
DirectFunctionCall1(namein, CStringGetDatum(stmt->fdwname));
values[Anum_pg_foreign_data_wrapper_fdwowner - 1] = ObjectIdGetDatum(ownerId);
/* Lookup handler and validator functions, if given */
parse_func_options(stmt->func_options,
&handler_given, &fdwhandler,
&validator_given, &fdwvalidator);
values[Anum_pg_foreign_data_wrapper_fdwhandler - 1] = ObjectIdGetDatum(fdwhandler);
values[Anum_pg_foreign_data_wrapper_fdwvalidator - 1] = ObjectIdGetDatum(fdwvalidator);
nulls[Anum_pg_foreign_data_wrapper_fdwacl - 1] = true;
fdwoptions = transformGenericOptions(ForeignDataWrapperRelationId,
PointerGetDatum(NULL),
stmt->options,
fdwvalidator);
if (PointerIsValid(DatumGetPointer(fdwoptions)))
values[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = fdwoptions;
else
nulls[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = true;
tuple = heap_form_tuple(rel->rd_att, values, nulls);
fdwId = simple_heap_insert(rel, tuple);
CatalogUpdateIndexes(rel, tuple);
heap_freetuple(tuple);
/* record dependencies */
myself.classId = ForeignDataWrapperRelationId;
myself.objectId = fdwId;
myself.objectSubId = 0;
if (OidIsValid(fdwhandler))
{
referenced.classId = ProcedureRelationId;
referenced.objectId = fdwhandler;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
if (OidIsValid(fdwvalidator))
{
referenced.classId = ProcedureRelationId;
referenced.objectId = fdwvalidator;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
recordDependencyOnOwner(ForeignDataWrapperRelationId, fdwId, ownerId);
/* dependency on extension */
recordDependencyOnCurrentExtension(&myself, false);
/* Post creation hook for new foreign data wrapper */
InvokeObjectPostCreateHook(ForeignDataWrapperRelationId, fdwId, 0);
heap_close(rel, RowExclusiveLock);
return fdwId;
}
| Oid CreateForeignServer | ( | CreateForeignServerStmt * | stmt | ) |
Definition at line 809 of file foreigncmds.c.
References ACL_KIND_FDW, ACL_USAGE, aclcheck_error(), ACLCHECK_OK, Anum_pg_foreign_server_srvacl, Anum_pg_foreign_server_srvfdw, Anum_pg_foreign_server_srvname, Anum_pg_foreign_server_srvoptions, Anum_pg_foreign_server_srvowner, Anum_pg_foreign_server_srvtype, Anum_pg_foreign_server_srvversion, CatalogUpdateIndexes(), ObjectAddress::classId, CStringGetDatum, CStringGetTextDatum, DatumGetPointer, DEPENDENCY_NORMAL, DirectFunctionCall1, ereport, errcode(), errmsg(), ERROR, ForeignDataWrapper::fdwid, ForeignDataWrapper::fdwname, CreateForeignServerStmt::fdwname, ForeignDataWrapper::fdwvalidator, ForeignServerRelationId, GetForeignDataWrapperByName(), GetForeignServerByName(), GetUserId(), heap_close, heap_form_tuple(), heap_freetuple(), heap_open(), InvokeObjectPostCreateHook, namein(), NULL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, CreateForeignServerStmt::options, pg_foreign_data_wrapper_aclcheck(), PointerGetDatum, PointerIsValid, RelationData::rd_att, recordDependencyOn(), recordDependencyOnCurrentExtension(), recordDependencyOnOwner(), RowExclusiveLock, CreateForeignServerStmt::servername, CreateForeignServerStmt::servertype, simple_heap_insert(), transformGenericOptions(), values, and CreateForeignServerStmt::version.
Referenced by ProcessUtilitySlow().
{
Relation rel;
Datum srvoptions;
Datum values[Natts_pg_foreign_server];
bool nulls[Natts_pg_foreign_server];
HeapTuple tuple;
Oid srvId;
Oid ownerId;
AclResult aclresult;
ObjectAddress myself;
ObjectAddress referenced;
ForeignDataWrapper *fdw;
rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
/* For now the owner cannot be specified on create. Use effective user ID. */
ownerId = GetUserId();
/*
* Check that there is no other foreign server by this name.
*/
if (GetForeignServerByName(stmt->servername, true) != NULL)
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("server \"%s\" already exists",
stmt->servername)));
/*
* Check that the FDW exists and that we have USAGE on it. Also get the
* actual FDW for option validation etc.
*/
fdw = GetForeignDataWrapperByName(stmt->fdwname, false);
aclresult = pg_foreign_data_wrapper_aclcheck(fdw->fdwid, ownerId, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_FDW, fdw->fdwname);
/*
* Insert tuple into pg_foreign_server.
*/
memset(values, 0, sizeof(values));
memset(nulls, false, sizeof(nulls));
values[Anum_pg_foreign_server_srvname - 1] =
DirectFunctionCall1(namein, CStringGetDatum(stmt->servername));
values[Anum_pg_foreign_server_srvowner - 1] = ObjectIdGetDatum(ownerId);
values[Anum_pg_foreign_server_srvfdw - 1] = ObjectIdGetDatum(fdw->fdwid);
/* Add server type if supplied */
if (stmt->servertype)
values[Anum_pg_foreign_server_srvtype - 1] =
CStringGetTextDatum(stmt->servertype);
else
nulls[Anum_pg_foreign_server_srvtype - 1] = true;
/* Add server version if supplied */
if (stmt->version)
values[Anum_pg_foreign_server_srvversion - 1] =
CStringGetTextDatum(stmt->version);
else
nulls[Anum_pg_foreign_server_srvversion - 1] = true;
/* Start with a blank acl */
nulls[Anum_pg_foreign_server_srvacl - 1] = true;
/* Add server options */
srvoptions = transformGenericOptions(ForeignServerRelationId,
PointerGetDatum(NULL),
stmt->options,
fdw->fdwvalidator);
if (PointerIsValid(DatumGetPointer(srvoptions)))
values[Anum_pg_foreign_server_srvoptions - 1] = srvoptions;
else
nulls[Anum_pg_foreign_server_srvoptions - 1] = true;
tuple = heap_form_tuple(rel->rd_att, values, nulls);
srvId = simple_heap_insert(rel, tuple);
CatalogUpdateIndexes(rel, tuple);
heap_freetuple(tuple);
/* record dependencies */
myself.classId = ForeignServerRelationId;
myself.objectId = srvId;
myself.objectSubId = 0;
referenced.classId = ForeignDataWrapperRelationId;
referenced.objectId = fdw->fdwid;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
recordDependencyOnOwner(ForeignServerRelationId, srvId, ownerId);
/* dependency on extension */
recordDependencyOnCurrentExtension(&myself, false);
/* Post creation hook for new foreign server */
InvokeObjectPostCreateHook(ForeignServerRelationId, srvId, 0);
heap_close(rel, RowExclusiveLock);
return srvId;
}
| void CreateForeignTable | ( | CreateForeignTableStmt * | stmt, | |
| Oid | relid | |||
| ) |
Definition at line 1350 of file foreigncmds.c.
References ACL_KIND_FOREIGN_SERVER, ACL_USAGE, aclcheck_error(), ACLCHECK_OK, Anum_pg_foreign_table_ftoptions, Anum_pg_foreign_table_ftrelid, Anum_pg_foreign_table_ftserver, CatalogUpdateIndexes(), ObjectAddress::classId, CommandCounterIncrement(), DatumGetPointer, DEPENDENCY_NORMAL, ForeignServer::fdwid, ForeignDataWrapper::fdwvalidator, ForeignTableRelationId, GetForeignDataWrapper(), GetForeignServerByName(), GetUserId(), heap_close, heap_form_tuple(), heap_freetuple(), heap_open(), NULL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, CreateForeignTableStmt::options, pg_foreign_server_aclcheck(), PointerGetDatum, PointerIsValid, RelationData::rd_att, recordDependencyOn(), RowExclusiveLock, ForeignServer::serverid, ForeignServer::servername, CreateForeignTableStmt::servername, simple_heap_insert(), transformGenericOptions(), and values.
Referenced by ProcessUtilitySlow().
{
Relation ftrel;
Datum ftoptions;
Datum values[Natts_pg_foreign_table];
bool nulls[Natts_pg_foreign_table];
HeapTuple tuple;
AclResult aclresult;
ObjectAddress myself;
ObjectAddress referenced;
Oid ownerId;
ForeignDataWrapper *fdw;
ForeignServer *server;
/*
* Advance command counter to ensure the pg_attribute tuple is visible;
* the tuple might be updated to add constraints in previous step.
*/
CommandCounterIncrement();
ftrel = heap_open(ForeignTableRelationId, RowExclusiveLock);
/*
* For now the owner cannot be specified on create. Use effective user ID.
*/
ownerId = GetUserId();
/*
* Check that the foreign server exists and that we have USAGE on it. Also
* get the actual FDW for option validation etc.
*/
server = GetForeignServerByName(stmt->servername, false);
aclresult = pg_foreign_server_aclcheck(server->serverid, ownerId, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_FOREIGN_SERVER, server->servername);
fdw = GetForeignDataWrapper(server->fdwid);
/*
* Insert tuple into pg_foreign_table.
*/
memset(values, 0, sizeof(values));
memset(nulls, false, sizeof(nulls));
values[Anum_pg_foreign_table_ftrelid - 1] = ObjectIdGetDatum(relid);
values[Anum_pg_foreign_table_ftserver - 1] = ObjectIdGetDatum(server->serverid);
/* Add table generic options */
ftoptions = transformGenericOptions(ForeignTableRelationId,
PointerGetDatum(NULL),
stmt->options,
fdw->fdwvalidator);
if (PointerIsValid(DatumGetPointer(ftoptions)))
values[Anum_pg_foreign_table_ftoptions - 1] = ftoptions;
else
nulls[Anum_pg_foreign_table_ftoptions - 1] = true;
tuple = heap_form_tuple(ftrel->rd_att, values, nulls);
simple_heap_insert(ftrel, tuple);
CatalogUpdateIndexes(ftrel, tuple);
heap_freetuple(tuple);
/* Add pg_class dependency on the server */
myself.classId = RelationRelationId;
myself.objectId = relid;
myself.objectSubId = 0;
referenced.classId = ForeignServerRelationId;
referenced.objectId = server->serverid;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
heap_close(ftrel, RowExclusiveLock);
}
| Oid CreateUserMapping | ( | CreateUserMappingStmt * | stmt | ) |
Definition at line 1070 of file foreigncmds.c.
References Anum_pg_user_mapping_umoptions, Anum_pg_user_mapping_umserver, Anum_pg_user_mapping_umuser, CatalogUpdateIndexes(), ObjectAddress::classId, DatumGetPointer, DEPENDENCY_NORMAL, ereport, errcode(), errmsg(), ERROR, ForeignServer::fdwid, ForeignDataWrapper::fdwvalidator, GetForeignDataWrapper(), GetForeignServerByName(), GetSysCacheOid2, GetUserOidFromMapping(), heap_close, heap_form_tuple(), heap_freetuple(), heap_open(), InvokeObjectPostCreateHook, MappingUserName, NULL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OidIsValid, CreateUserMappingStmt::options, PointerGetDatum, PointerIsValid, RelationData::rd_att, recordDependencyOn(), recordDependencyOnCurrentExtension(), recordDependencyOnOwner(), RowExclusiveLock, ForeignServer::serverid, CreateUserMappingStmt::servername, simple_heap_insert(), transformGenericOptions(), user_mapping_ddl_aclcheck(), UserMappingRelationId, USERMAPPINGUSERSERVER, CreateUserMappingStmt::username, and values.
Referenced by ProcessUtilitySlow().
{
Relation rel;
Datum useoptions;
Datum values[Natts_pg_user_mapping];
bool nulls[Natts_pg_user_mapping];
HeapTuple tuple;
Oid useId;
Oid umId;
ObjectAddress myself;
ObjectAddress referenced;
ForeignServer *srv;
ForeignDataWrapper *fdw;
rel = heap_open(UserMappingRelationId, RowExclusiveLock);
useId = GetUserOidFromMapping(stmt->username, false);
/* Check that the server exists. */
srv = GetForeignServerByName(stmt->servername, false);
user_mapping_ddl_aclcheck(useId, srv->serverid, stmt->servername);
/*
* Check that the user mapping is unique within server.
*/
umId = GetSysCacheOid2(USERMAPPINGUSERSERVER,
ObjectIdGetDatum(useId),
ObjectIdGetDatum(srv->serverid));
if (OidIsValid(umId))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("user mapping \"%s\" already exists for server %s",
MappingUserName(useId),
stmt->servername)));
fdw = GetForeignDataWrapper(srv->fdwid);
/*
* Insert tuple into pg_user_mapping.
*/
memset(values, 0, sizeof(values));
memset(nulls, false, sizeof(nulls));
values[Anum_pg_user_mapping_umuser - 1] = ObjectIdGetDatum(useId);
values[Anum_pg_user_mapping_umserver - 1] = ObjectIdGetDatum(srv->serverid);
/* Add user options */
useoptions = transformGenericOptions(UserMappingRelationId,
PointerGetDatum(NULL),
stmt->options,
fdw->fdwvalidator);
if (PointerIsValid(DatumGetPointer(useoptions)))
values[Anum_pg_user_mapping_umoptions - 1] = useoptions;
else
nulls[Anum_pg_user_mapping_umoptions - 1] = true;
tuple = heap_form_tuple(rel->rd_att, values, nulls);
umId = simple_heap_insert(rel, tuple);
CatalogUpdateIndexes(rel, tuple);
heap_freetuple(tuple);
/* Add dependency on the server */
myself.classId = UserMappingRelationId;
myself.objectId = umId;
myself.objectSubId = 0;
referenced.classId = ForeignServerRelationId;
referenced.objectId = srv->serverid;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
if (OidIsValid(useId))
{
/* Record the mapped user dependency */
recordDependencyOnOwner(UserMappingRelationId, umId, useId);
}
/* dependency on extension */
recordDependencyOnCurrentExtension(&myself, false);
/* Post creation hook for new user mapping */
InvokeObjectPostCreateHook(UserMappingRelationId, umId, 0);
heap_close(rel, RowExclusiveLock);
return umId;
}
Definition at line 189 of file foreigncmds.c.
References get_role_oid(), and GetUserId().
Referenced by AlterUserMapping(), CreateUserMapping(), and RemoveUserMapping().
{
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);
}
Definition at line 419 of file foreigncmds.c.
References DefElem::arg, ereport, errcode(), errmsg(), ERROR, FDW_HANDLEROID, get_func_rettype(), LookupFuncName(), NameListToString(), and NULL.
Referenced by parse_func_options().
{
Oid handlerOid;
if (handler == NULL || handler->arg == NULL)
return InvalidOid;
/* handlers have no arguments */
handlerOid = LookupFuncName((List *) handler->arg, 0, NULL, 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))));
return handlerOid;
}
Definition at line 443 of file foreigncmds.c.
References DefElem::arg, LookupFuncName(), and NULL.
Referenced by parse_func_options().
{
Oid funcargtypes[2];
if (validator == NULL || validator->arg == NULL)
return InvalidOid;
/* validators take text[], oid */
funcargtypes[0] = TEXTARRAYOID;
funcargtypes[1] = OIDOID;
return LookupFuncName((List *) validator->arg, 2, funcargtypes, false);
/* validator's return value is ignored, so we don't check the type */
}
Definition at line 51 of file foreigncmds.c.
References accumArrayResult(), CurrentMemoryContext, defGetString(), DefElem::defname, lfirst, makeArrayResult(), NULL, palloc(), PointerGetDatum, SET_VARSIZE, TEXTOID, value, VARDATA, and VARHDRSZ.
Referenced by transformGenericOptions().
{
ArrayBuildState *astate = NULL;
ListCell *cell;
foreach(cell, options)
{
DefElem *def = lfirst(cell);
const char *value;
Size len;
text *t;
value = defGetString(def);
len = VARHDRSZ + strlen(def->defname) + 1 + strlen(value);
t = palloc(len + 1);
SET_VARSIZE(t, len);
sprintf(VARDATA(t), "%s=%s", def->defname, value);
astate = accumArrayResult(astate, PointerGetDatum(t),
false, TEXTOID,
CurrentMemoryContext);
}
if (astate)
return makeArrayResult(astate, CurrentMemoryContext);
return PointerGetDatum(NULL);
}
| static void parse_func_options | ( | List * | func_options, | |
| bool * | handler_given, | |||
| Oid * | fdwhandler, | |||
| bool * | validator_given, | |||
| Oid * | fdwvalidator | |||
| ) | [static] |
Definition at line 462 of file foreigncmds.c.
References DefElem::defname, elog, ereport, errcode(), errmsg(), ERROR, lfirst, lookup_fdw_handler_func(), and lookup_fdw_validator_func().
Referenced by AlterForeignDataWrapper(), and CreateForeignDataWrapper().
{
ListCell *cell;
*handler_given = false;
*validator_given = false;
/* return InvalidOid if not given */
*fdwhandler = InvalidOid;
*fdwvalidator = InvalidOid;
foreach(cell, func_options)
{
DefElem *def = (DefElem *) lfirst(cell);
if (strcmp(def->defname, "handler") == 0)
{
if (*handler_given)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
*handler_given = true;
*fdwhandler = lookup_fdw_handler_func(def);
}
else if (strcmp(def->defname, "validator") == 0)
{
if (*validator_given)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
*validator_given = true;
*fdwvalidator = lookup_fdw_validator_func(def);
}
else
elog(ERROR, "option \"%s\" not recognized",
def->defname);
}
}
| void RemoveForeignDataWrapperById | ( | Oid | fdwId | ) |
Definition at line 785 of file foreigncmds.c.
References elog, ERROR, FOREIGNDATAWRAPPEROID, ForeignDataWrapperRelationId, heap_close, heap_open(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1, simple_heap_delete(), and HeapTupleData::t_self.
Referenced by doDeletion().
{
HeapTuple tp;
Relation rel;
rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
tp = SearchSysCache1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwId));
if (!HeapTupleIsValid(tp))
elog(ERROR, "cache lookup failed for foreign-data wrapper %u", fdwId);
simple_heap_delete(rel, &tp->t_self);
ReleaseSysCache(tp);
heap_close(rel, RowExclusiveLock);
}
| void RemoveForeignServerById | ( | Oid | srvId | ) |
Definition at line 1019 of file foreigncmds.c.
References elog, ERROR, FOREIGNSERVEROID, ForeignServerRelationId, heap_close, heap_open(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1, simple_heap_delete(), and HeapTupleData::t_self.
Referenced by doDeletion().
{
HeapTuple tp;
Relation rel;
rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
tp = SearchSysCache1(FOREIGNSERVEROID, ObjectIdGetDatum(srvId));
if (!HeapTupleIsValid(tp))
elog(ERROR, "cache lookup failed for foreign server %u", srvId);
simple_heap_delete(rel, &tp->t_self);
ReleaseSysCache(tp);
heap_close(rel, RowExclusiveLock);
}
| Oid RemoveUserMapping | ( | DropUserMappingStmt * | stmt | ) |
Definition at line 1256 of file foreigncmds.c.
References DROP_CASCADE, elog, ereport, errcode(), errmsg(), ERROR, GetForeignServerByName(), GetSysCacheOid2, GetUserOidFromMapping(), MappingUserName, DropUserMappingStmt::missing_ok, NOTICE, ObjectIdGetDatum, OidIsValid, performDeletion(), ForeignServer::serverid, ForeignServer::servername, DropUserMappingStmt::servername, user_mapping_ddl_aclcheck(), USERMAPPINGUSERSERVER, and DropUserMappingStmt::username.
Referenced by ProcessUtilitySlow().
{
ObjectAddress object;
Oid useId;
Oid umId;
ForeignServer *srv;
useId = GetUserOidFromMapping(stmt->username, stmt->missing_ok);
srv = GetForeignServerByName(stmt->servername, true);
if (stmt->username && !OidIsValid(useId))
{
/*
* 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;
}
if (!srv)
{
if (!stmt->missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("server \"%s\" does not exist",
stmt->servername)));
/* IF EXISTS, just note it */
ereport(NOTICE, (errmsg("server does not exist, skipping")));
return InvalidOid;
}
umId = GetSysCacheOid2(USERMAPPINGUSERSERVER,
ObjectIdGetDatum(useId),
ObjectIdGetDatum(srv->serverid));
if (!OidIsValid(umId))
{
if (!stmt->missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("user mapping \"%s\" does not exist for the server",
MappingUserName(useId))));
/* IF EXISTS specified, just note it */
ereport(NOTICE,
(errmsg("user mapping \"%s\" does not exist for the server, skipping",
MappingUserName(useId))));
return InvalidOid;
}
user_mapping_ddl_aclcheck(useId, srv->serverid, srv->servername);
/*
* Do the deletion
*/
object.classId = UserMappingRelationId;
object.objectId = umId;
object.objectSubId = 0;
performDeletion(&object, DROP_CASCADE, 0);
return umId;
}
| void RemoveUserMappingById | ( | Oid | umId | ) |
Definition at line 1326 of file foreigncmds.c.
References elog, ERROR, heap_close, heap_open(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1, simple_heap_delete(), HeapTupleData::t_self, USERMAPPINGOID, and UserMappingRelationId.
Referenced by doDeletion().
{
HeapTuple tp;
Relation rel;
rel = heap_open(UserMappingRelationId, RowExclusiveLock);
tp = SearchSysCache1(USERMAPPINGOID, ObjectIdGetDatum(umId));
if (!HeapTupleIsValid(tp))
elog(ERROR, "cache lookup failed for user mapping %u", umId);
simple_heap_delete(rel, &tp->t_self);
ReleaseSysCache(tp);
heap_close(rel, RowExclusiveLock);
}
Definition at line 94 of file foreigncmds.c.
References construct_empty_array(), DatumGetPointer, DefElem::defaction, DEFELEM_ADD, DEFELEM_DROP, DEFELEM_SET, DEFELEM_UNSPEC, DefElem::defname, elog, ereport, errcode(), errmsg(), ERROR, lappend(), lfirst, list_delete_cell(), NULL, ObjectIdGetDatum, OidFunctionCall2, OidIsValid, optionListToArray(), PointerGetDatum, TEXTOID, and untransformRelOptions().
Referenced by AlterForeignDataWrapper(), AlterForeignServer(), AlterUserMapping(), ATExecAlterColumnGenericOptions(), ATExecGenericOptions(), CreateForeignDataWrapper(), CreateForeignServer(), CreateForeignTable(), and CreateUserMapping().
{
List *resultOptions = untransformRelOptions(oldOptions);
ListCell *optcell;
Datum result;
foreach(optcell, options)
{
DefElem *od = lfirst(optcell);
ListCell *cell;
ListCell *prev = NULL;
/*
* Find the element in resultOptions. We need this for validation in
* all cases. Also identify the previous element.
*/
foreach(cell, resultOptions)
{
DefElem *def = lfirst(cell);
if (strcmp(def->defname, od->defname) == 0)
break;
else
prev = cell;
}
/*
* It is possible to perform multiple SET/DROP actions on the same
* option. The standard permits this, as long as the options to be
* added are unique. Note that an unspecified action is taken to be
* ADD.
*/
switch (od->defaction)
{
case DEFELEM_DROP:
if (!cell)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("option \"%s\" not found",
od->defname)));
resultOptions = list_delete_cell(resultOptions, cell, prev);
break;
case DEFELEM_SET:
if (!cell)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("option \"%s\" not found",
od->defname)));
lfirst(cell) = od;
break;
case DEFELEM_ADD:
case DEFELEM_UNSPEC:
if (cell)
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("option \"%s\" provided more than once",
od->defname)));
resultOptions = lappend(resultOptions, od);
break;
default:
elog(ERROR, "unrecognized action %d on option \"%s\"",
(int) od->defaction, od->defname);
break;
}
}
result = optionListToArray(resultOptions);
if (OidIsValid(fdwvalidator))
{
Datum valarg = result;
/*
* Pass a null options list as an empty array, so that validators
* don't have to be declared non-strict to handle the case.
*/
if (DatumGetPointer(valarg) == NULL)
valarg = PointerGetDatum(construct_empty_array(TEXTOID));
OidFunctionCall2(fdwvalidator, valarg, ObjectIdGetDatum(catalogId));
}
return result;
}
| static void user_mapping_ddl_aclcheck | ( | Oid | umuserid, | |
| Oid | serverid, | |||
| const char * | servername | |||
| ) | [static] |
Definition at line 1045 of file foreigncmds.c.
References ACL_KIND_FOREIGN_SERVER, ACL_USAGE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, GetUserId(), pg_foreign_server_aclcheck(), and pg_foreign_server_ownercheck().
Referenced by AlterUserMapping(), CreateUserMapping(), and RemoveUserMapping().
{
Oid curuserid = GetUserId();
if (!pg_foreign_server_ownercheck(serverid, curuserid))
{
if (umuserid == curuserid)
{
AclResult aclresult;
aclresult = pg_foreign_server_aclcheck(serverid, curuserid, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_FOREIGN_SERVER, servername);
}
else
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER,
servername);
}
}
1.7.1