/* *Describesthevalidoptionsforobjectsthatthiswrapperuses.
*/ typedefstruct PgFdwOption
{ constchar *keyword;
Oid optcontext; /* OID of catalog in which option may appear */ bool is_libpq_opt; /* true if it's used in libpq */
} PgFdwOption;
Datum
postgres_fdw_validator(PG_FUNCTION_ARGS)
{
List *options_list = untransformRelOptions(PG_GETARG_DATUM(0));
Oid catalog = PG_GETARG_OID(1);
ListCell *cell;
/* Build our options lists if we didn't yet. */
InitPgFdwOptions();
value = defGetString(def);
is_parsed = parse_real(value, &real_val, 0, NULL);
if (!is_parsed)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid value for floating point option \"%s\": %s",
def->defname, value)));
if (real_val < 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("\"%s\" must be a floating point value greater than or equal to zero",
def->defname)));
} elseif (strcmp(def->defname, "extensions") == 0)
{ /* check list syntax, warn about uninstalled extensions */
(void) ExtractExtensionList(defGetString(def), true);
} elseif (strcmp(def->defname, "fetch_size") == 0 ||
strcmp(def->defname, "batch_size") == 0)
{ char *value; int int_val; bool is_parsed;
value = defGetString(def);
is_parsed = parse_int(value, &int_val, 0, NULL);
if (!is_parsed)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid value for integer option \"%s\": %s",
def->defname, value)));
if (int_val <= 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("\"%s\" must be an integer value greater than zero",
def->defname)));
} elseif (strcmp(def->defname, "password_required") == 0)
{ bool pw_required = defGetBoolean(def);
/* *Onlythesuperusermaysetthisoptiononausermapping,or *alterausermappingonwhichthisoptionisset.Weallowa *usertoclearthisoptionifit'sset-infact,wedon'thave *achoicesincewecan'tseetheoldmappingwhenvalidatingan *alter.
*/ if (!superuser() && !pw_required)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("password_required=false is superuser-only"),
errhint("User mappings with the password_required option set to false may only be created or modified by the superuser.")));
} elseif (strcmp(def->defname, "sslcert") == 0 ||
strcmp(def->defname, "sslkey") == 0)
{ /* similarly for sslcert / sslkey on user mapping */ if (catalog == UserMappingRelationId && !superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("sslcert and sslkey are superuser-only"),
errhint("User mappings with the sslcert or sslkey options set may only be created or modified by the superuser.")));
} elseif (strcmp(def->defname, "analyze_sampling") == 0)
{ char *value;
/* non-libpq FDW-specific FDW options */ staticconst PgFdwOption non_libpq_options[] = {
{"schema_name", ForeignTableRelationId, false},
{"table_name", ForeignTableRelationId, false},
{"column_name", AttributeRelationId, false}, /* use_remote_estimate is available on both server and table */
{"use_remote_estimate", ForeignServerRelationId, false},
{"use_remote_estimate", ForeignTableRelationId, false}, /* cost factors */
{"fdw_startup_cost", ForeignServerRelationId, false},
{"fdw_tuple_cost", ForeignServerRelationId, false}, /* shippable extensions */
{"extensions", ForeignServerRelationId, false}, /* updatable is available on both server and table */
{"updatable", ForeignServerRelationId, false},
{"updatable", ForeignTableRelationId, false}, /* truncatable is available on both server and table */
{"truncatable", ForeignServerRelationId, false},
{"truncatable", ForeignTableRelationId, false}, /* fetch_size is available on both server and table */
{"fetch_size", ForeignServerRelationId, false},
{"fetch_size", ForeignTableRelationId, false}, /* batch_size is available on both server and table */
{"batch_size", ForeignServerRelationId, false},
{"batch_size", ForeignTableRelationId, false}, /* async_capable is available on both server and table */
{"async_capable", ForeignServerRelationId, false},
{"async_capable", ForeignTableRelationId, false},
{"parallel_commit", ForeignServerRelationId, false},
{"parallel_abort", ForeignServerRelationId, false},
{"keep_connections", ForeignServerRelationId, false},
{"password_required", UserMappingRelationId, false},
/* sampling is available on both server and table */
{"analyze_sampling", ForeignServerRelationId, false},
{"analyze_sampling", ForeignTableRelationId, false},
/* *Parseacomma-separatedstringandreturnaListoftheOIDsofthe *extensionsnamedinthestring.Ifanynamesinthelistcannotbe *found,reportawarningifwarnOnMissingistrue,elsejustsilently *ignorethem.
*/
List *
ExtractExtensionList(constchar *extensionsString, bool warnOnMissing)
{
List *extensionOids = NIL;
List *extlist;
ListCell *lc;
/* SplitIdentifierString scribbles on its input, so pstrdup first */ if (!SplitIdentifierString(pstrdup(extensionsString), ',', &extlist))
{ /* syntax error in name list */
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("parameter \"%s\" must be a list of extension names", "extensions")));
}
for (p = appname; *p != '\0'; p++)
{ if (*p != '%')
{ /* literal char, just copy */
appendStringInfoChar(&buf, *p); continue;
}
/* must be a '%', so skip to the next char */
p++; if (*p == '\0') break; /* format error - ignore it */ elseif (*p == '%')
{ /* string contains %% */
appendStringInfoChar(&buf, '%'); continue;
}
if (username)
appendStringInfoString(&buf, username); else
appendStringInfoString(&buf, "[unknown]");
} break; default: /* format error - ignore it */ break;
}
}
return buf.data;
}
/* *Moduleloadcallback
*/ void
_PG_init(void)
{ /* *Unlikeapplication_nameGUC,don'tsetGUC_IS_NAMEflagnorcheck_hook *toallowpostgres_fdw.application_nametobeanystringmorethan *NAMEDATALENcharactersandtoincludenon-ASCIIcharacters.Instead, *remoteservertruncatesapplication_nameofremoteconnectiontoless *thanNAMEDATALENandreplacesanynon-ASCIIcharactersinitwitha'?' *character.
*/
DefineCustomStringVariable("postgres_fdw.application_name", "Sets the application name to be used on the remote server.",
NULL,
&pgfdw_application_name,
NULL,
PGC_USERSET, 0,
NULL,
NULL,
NULL);
MarkGUCPrefixReserved("postgres_fdw");
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-08-08)
¤
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.