/* Insist that name not contain "=", else "a=b=c" is ambiguous */ if (strchr(name, '=') != NULL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid option name \"%s\": must not contain \"=\"",
name)));
len = VARHDRSZ + strlen(name) + 1 + strlen(value); /* +1 leaves room for sprintf's trailing null */
t = palloc(len + 1);
SET_VARSIZE(t, len);
sprintf(VARDATA(t), "%s=%s", name, value);
if (strcmp(def->defname, od->defname) == 0) break;
}
/* *ItispossibletoperformmultipleSET/DROPactionsonthesame *option.Thestandardpermitsthis,aslongastheoptionstobe *addedareunique.Notethatanunspecifiedactionistakentobe *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); 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;
/* *Internalworkhorseforchangingadatawrapper'sowner. * *Allowthisonlyforsuperusers;alsothenewownermustbea *superuser.
*/ staticvoid
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);
/* 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.")));
/* *Internalworkhorseforchangingaforeignserver'sowner
*/ staticvoid
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);
if (form->srvowner != newOwnerId)
{ /* Superusers can always do it */ if (!superuser())
{
Oid srvId;
AclResult aclresult;
srvId = form->oid;
/* Must be owner */ if (!object_ownercheck(ForeignServerRelationId, srvId, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FOREIGN_SERVER,
NameStr(form->srvname));
/* Must be able to become new owner */
check_can_set_role(GetUserId(), newOwnerId);
/* New owner must have USAGE privilege on foreign-data wrapper */
aclresult = object_aclcheck(ForeignDataWrapperRelationId, form->srvfdw, newOwnerId, ACL_USAGE); if (aclresult != ACLCHECK_OK)
{
ForeignDataWrapper *fdw = GetForeignDataWrapper(form->srvfdw);
/* *ConvertahandlerfunctionnamepassedfromtheparsertoanOid.
*/ static Oid
lookup_fdw_handler_func(DefElem *handler)
{
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 %s",
NameListToString((List *) handler->arg), "fdw_handler")));
return handlerOid;
}
/* *ConvertavalidatorfunctionnamepassedfromtheparsertoanOid.
*/ static Oid
lookup_fdw_validator_func(DefElem *validator)
{
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 */
}
/* *ProcessfunctionoptionsofCREATE/ALTERFDW
*/ staticvoid
parse_func_options(ParseState *pstate, List *func_options, bool *handler_given, Oid *fdwhandler, bool *validator_given, Oid *fdwvalidator)
{
ListCell *cell;
*handler_given = false;
*validator_given = false; /* return InvalidOid if not given */
*fdwhandler = InvalidOid;
*fdwvalidator = InvalidOid;
/* Must be superuser */ 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();
/* Lookup handler and validator functions, if given */
parse_func_options(pstate, stmt->func_options,
&handler_given, &fdwhandler,
&validator_given, &fdwvalidator);
/* Must be superuser */ 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.")));
/* *ItcouldbethatexistingoptionsfortheFDWordependentSERVER, *USERMAPPINGorFOREIGNTABLEobjectsarenolongervalidaccording *tothenewvalidator.Warnaboutthis.
*/ if (OidIsValid(fdwvalidator))
ereport(WARNING,
(errmsg("changing the foreign-data wrapper validator can cause " "the options for dependent objects to become invalid")));
} else
{ /* *Validatorisnotchanged,butweneeditforvalidatingoptions.
*/
fdwvalidator = fdwForm->fdwvalidator;
}
/* *Ifoptionsspecified,validateandupdate.
*/ 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);
/* 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;
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);
/* *Checkthattheusermappingisuniquewithinserver.
*/
umId = GetSysCacheOid2(USERMAPPINGUSERSERVER, Anum_pg_user_mapping_oid,
ObjectIdGetDatum(useId),
ObjectIdGetDatum(srv->serverid));
if (OidIsValid(umId))
{ if (stmt->if_not_exists)
{ /* *Sinceusermappingsaren'tmembersofextensions(seecomments *below),noneedforcheckMembershipInCurrentExtensionhere.
*/
ereport(NOTICE,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("user mapping for \"%s\" already exists for server \"%s\", skipping",
MappingUserName(useId),
stmt->servername)));
table_close(rel, RowExclusiveLock); return InvalidObjectAddress;
} else
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("user mapping for \"%s\" already exists for server \"%s\"",
MappingUserName(useId),
stmt->servername)));
}
umId = GetSysCacheOid2(USERMAPPINGUSERSERVER, Anum_pg_user_mapping_oid,
ObjectIdGetDatum(useId),
ObjectIdGetDatum(srv->serverid)); if (!OidIsValid(umId))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("user mapping for \"%s\" does not exist for server \"%s\"",
MappingUserName(useId), stmt->servername)));
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 \"%s\" does not exist, skipping",
stmt->servername))); return InvalidOid;
}
umId = GetSysCacheOid2(USERMAPPINGUSERSERVER, Anum_pg_user_mapping_oid,
ObjectIdGetDatum(useId),
ObjectIdGetDatum(srv->serverid));
if (!OidIsValid(umId))
{ if (!stmt->missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("user mapping for \"%s\" does not exist for server \"%s\"",
MappingUserName(useId), stmt->servername)));
/* IF EXISTS specified, just note it */
ereport(NOTICE,
(errmsg("user mapping for \"%s\" does not exist for server \"%s\", skipping",
MappingUserName(useId), stmt->servername))); return InvalidOid;
}
/* Check that the foreign server exists and that we have USAGE on it */
server = GetForeignServerByName(stmt->server_name, false);
aclresult = object_aclcheck(ForeignServerRelationId, server->serverid, GetUserId(), ACL_USAGE); if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, server->servername);
/* Check that the schema exists and we have CREATE permissions on it */
(void) LookupCreationNamespace(stmt->local_schema);
/* Get the FDW and check it supports IMPORT */
fdw = GetForeignDataWrapper(server->fdwid); if (!OidIsValid(fdw->fdwhandler))
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("foreign-data wrapper \"%s\" has no handler",
fdw->fdwname)));
fdw_routine = GetFdwRoutine(fdw->fdwhandler); if (fdw_routine->ImportForeignSchema == NULL)
ereport(ERROR,
(errcode(ERRCODE_FDW_NO_SCHEMAS),
errmsg("foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA",
fdw->fdwname)));
/* Call FDW to get a list of commands */
cmd_list = fdw_routine->ImportForeignSchema(stmt, server->serverid);
/* Parse and execute each command */
foreach(lc, cmd_list)
{ char *cmd = (char *) lfirst(lc);
import_error_callback_arg callback_arg;
ErrorContextCallback sqlerrcontext;
List *raw_parsetree_list;
ListCell *lc2;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.