/* * GetForeignDataWrapper - look up the foreign-data wrapper by OID. */ ForeignDataWrapper * GetForeignDataWrapper(Oid fdwid) { Form_pg_foreign_data_wrapper fdwform; ForeignDataWrapper *fdw; Datum datum; HeapTuple tp; bool isnull; tp = SearchSysCache1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid)); if (!HeapTupleIsValid(tp)) elog(ERROR, "cache lookup failed for foreign-data wrapper %u", fdwid); fdwform = (Form_pg_foreign_data_wrapper) GETSTRUCT(tp); fdw = palloc(sizeof(ForeignDataWrapper)); fdw->fdwid = fdwid; fdw->owner = fdwform->fdwowner; fdw->fdwname = pstrdup(NameStr(fdwform->fdwname)); fdw->fdwvalidator = fdwform->fdwvalidator; /* Extract the options */ datum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID, tp, Anum_pg_foreign_data_wrapper_fdwoptions, &isnull); fdw->options = untransformRelOptions(datum); ReleaseSysCache(tp); return fdw; }
/* * GetForeignTable - look up the foreign table definition by relation oid. */ ForeignTable * GetForeignTable(Oid relid) { Form_pg_foreign_table tableform; ForeignTable *ft; HeapTuple tp; Datum datum; bool isnull; tp = SearchSysCache1(FOREIGNTABLEREL, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(tp)) elog(ERROR, "cache lookup failed for foreign table %u", relid); tableform = (Form_pg_foreign_table) GETSTRUCT(tp); ft = (ForeignTable *) palloc(sizeof(ForeignTable)); ft->relid = relid; ft->serverid = tableform->ftserver; /* Extract the ftoptions */ datum = SysCacheGetAttr(FOREIGNTABLEREL, tp, Anum_pg_foreign_table_ftoptions, &isnull); if (isnull) ft->options = NIL; else ft->options = untransformRelOptions(datum); ReleaseSysCache(tp); return ft; }
/* * GetForeignColumnOptions - Get attfdwoptions of given relation/attnum * as list of DefElem. */ List * GetForeignColumnOptions(Oid relid, AttrNumber attnum) { List *options; HeapTuple tp; Datum datum; bool isnull; tp = SearchSysCache2(ATTNUM, ObjectIdGetDatum(relid), Int16GetDatum(attnum)); if (!HeapTupleIsValid(tp)) elog(ERROR, "cache lookup failed for attribute %d of relation %u", attnum, relid); datum = SysCacheGetAttr(ATTNUM, tp, Anum_pg_attribute_attfdwoptions, &isnull); if (isnull) options = NIL; else options = untransformRelOptions(datum); ReleaseSysCache(tp); return options; }
Datum multicorn_validator(PG_FUNCTION_ARGS) { List *options_list = untransformRelOptions(PG_GETARG_DATUM(0)); Oid catalog = PG_GETARG_OID(1); char *className = NULL; ListCell *cell; PyObject *p_class; foreach(cell, options_list) { DefElem *def = (DefElem *) lfirst(cell); if (strcmp(def->defname, "wrapper") == 0) { /* Only at server creation can we set the wrapper, */ /* for security issues. */ if (catalog == ForeignTableRelationId) { ereport(ERROR, (errmsg("%s", "Cannot set the wrapper class on the table"), errhint("%s", "Set it on the server"))); } else { className = (char *) defGetString(def); } } }
/* * cstore_fdw_validator validates options given to one of the following commands: * foreign data wrapper, server, user mapping, or foreign table. This function * errors out if the given option name or its value is considered invalid. */ Datum cstore_fdw_validator(PG_FUNCTION_ARGS) { Datum optionArray = PG_GETARG_DATUM(0); Oid optionContextId = PG_GETARG_OID(1); List *optionList = untransformRelOptions(optionArray); ListCell *optionCell = NULL; char *filename = NULL; char *compressionTypeString = NULL; char *stripeRowCountString = NULL; char *blockRowCountString = NULL; foreach(optionCell, optionList) { DefElem *optionDef = (DefElem *) lfirst(optionCell); char *optionName = optionDef->defname; bool optionValid = false; int32 optionIndex = 0; for (optionIndex = 0; optionIndex < ValidOptionCount; optionIndex++) { const CStoreValidOption *validOption = &(ValidOptionArray[optionIndex]); if ((optionContextId == validOption->optionContextId) && (strncmp(optionName, validOption->optionName, NAMEDATALEN) == 0)) { optionValid = true; break; } } /* if invalid option, display an informative error message */ if (!optionValid) { StringInfo optionNamesString = OptionNamesString(optionContextId); ereport(ERROR, (errcode(ERRCODE_FDW_INVALID_OPTION_NAME), errmsg("invalid option \"%s\"", optionName), errhint("Valid options in this context are: %s", optionNamesString->data))); } if (strncmp(optionName, OPTION_NAME_FILENAME, NAMEDATALEN) == 0) { filename = defGetString(optionDef); } else if (strncmp(optionName, OPTION_NAME_COMPRESSION_TYPE, NAMEDATALEN) == 0) { compressionTypeString = defGetString(optionDef); } else if (strncmp(optionName, OPTION_NAME_STRIPE_ROW_COUNT, NAMEDATALEN) == 0) { stripeRowCountString = defGetString(optionDef); } else if (strncmp(optionName, OPTION_NAME_BLOCK_ROW_COUNT, NAMEDATALEN) == 0) { blockRowCountString = defGetString(optionDef); } }
/* * GetForeignServer - look up the foreign server definition. */ ForeignServer * GetForeignServer(Oid serverid) { Form_pg_foreign_server serverform; ForeignServer *server; HeapTuple tp; Datum datum; bool isnull; tp = SearchSysCache(FOREIGNSERVEROID, ObjectIdGetDatum(serverid), 0, 0, 0); if (!HeapTupleIsValid(tp)) elog(ERROR, "cache lookup failed for foreign server %u", serverid); serverform = (Form_pg_foreign_server) GETSTRUCT(tp); server = palloc(sizeof(ForeignServer)); server->serverid = serverid; server->servername = pstrdup(NameStr(serverform->srvname)); server->owner = serverform->srvowner; server->fdwid = serverform->srvfdw; /* Extract server type */ datum = SysCacheGetAttr(FOREIGNSERVEROID, tp, Anum_pg_foreign_server_srvtype, &isnull); server->servertype = isnull ? NULL : pstrdup(TextDatumGetCString(datum)); /* Extract server version */ datum = SysCacheGetAttr(FOREIGNSERVEROID, tp, Anum_pg_foreign_server_srvversion, &isnull); server->serverversion = isnull ? NULL : pstrdup(TextDatumGetCString(datum)); /* Extract the srvoptions */ datum = SysCacheGetAttr(FOREIGNSERVEROID, tp, Anum_pg_foreign_server_srvoptions, &isnull); /* untransformRelOptions does exactly what we want - avoid duplication */ server->options = untransformRelOptions(datum); ReleaseSysCache(tp); return server; }
static void ParseOptions(Datum options, Reader **rd, Writer **wt, time_t tm) { List *defs; List *rest_defs = NIL; ListCell *cell; DefElem *opt; char *keyword; char *value; char *type = NULL; char *writer = NULL; bool multi_process = false; Assert(*rd == NULL); Assert(*wt == NULL); /* parse for each option */ defs = untransformRelOptions(options); foreach (cell, defs) { opt = lfirst(cell); if (opt->arg == NULL) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("option \"%s\" has no value", opt->defname))); keyword = opt->defname; value = strVal(opt->arg); if (CompareKeyword(keyword, "TYPE")) { ASSERT_ONCE(type == NULL); type = value; } else if (CompareKeyword(keyword, "WRITER") || CompareKeyword(keyword, "LOADER")) { ASSERT_ONCE(writer == NULL); writer = value; } else if (CompareKeyword(keyword, "MULTI_PROCESS")) { multi_process = ParseBoolean(value); } else { rest_defs = lappend(rest_defs, opt); continue; } }
/* * mongo_fdw_validator validates options given to one of the following commands: * foreign data wrapper, server, user mapping, or foreign table. This function * errors out if the given option name or its value is considered invalid. */ Datum mongo_fdw_validator(PG_FUNCTION_ARGS) { Datum optionArray = PG_GETARG_DATUM(0); Oid optionContextId = PG_GETARG_OID(1); List *optionList = untransformRelOptions(optionArray); ListCell *optionCell = NULL; foreach(optionCell, optionList) { DefElem *optionDef = (DefElem *) lfirst(optionCell); char *optionName = optionDef->defname; bool optionValid = false; int32 optionIndex = 0; for (optionIndex = 0; optionIndex < ValidOptionCount; optionIndex++) { const MongoValidOption *validOption = &(ValidOptionArray[optionIndex]); if ((optionContextId == validOption->optionContextId) && (strncmp(optionName, validOption->optionName, NAMEDATALEN) == 0)) { optionValid = true; break; } } /* if invalid option, display an informative error message */ if (!optionValid) { StringInfo optionNamesString = OptionNamesString(optionContextId); ereport(ERROR, (errcode(ERRCODE_FDW_INVALID_OPTION_NAME), errmsg("invalid option \"%s\"", optionName), errhint("Valid options in this context are: %s", optionNamesString->data))); } /* if port option is given, error out if its value isn't an integer */ if (strncmp(optionName, OPTION_NAME_PORT, NAMEDATALEN) == 0) { char *optionValue = defGetString(optionDef); int32 portNumber = pg_atoi(optionValue, sizeof(int32), 0); (void) portNumber; } }
/* * GetUserMapping - look up the user mapping. * * If no mapping is found for the supplied user, we also look for * PUBLIC mappings (userid == InvalidOid). */ UserMapping * GetUserMapping(Oid userid, Oid serverid) { Form_pg_user_mapping umform; Datum datum; HeapTuple tp; bool isnull; UserMapping *um; tp = SearchSysCache(USERMAPPINGUSERSERVER, ObjectIdGetDatum(userid), ObjectIdGetDatum(serverid), 0, 0); if (!HeapTupleIsValid(tp)) { /* Not found for the specific user -- try PUBLIC */ tp = SearchSysCache(USERMAPPINGUSERSERVER, ObjectIdGetDatum(InvalidOid), ObjectIdGetDatum(serverid), 0, 0); } if (!HeapTupleIsValid(tp)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("user mapping not found for \"%s\"", MappingUserName(userid)))); umform = (Form_pg_user_mapping) GETSTRUCT(tp); /* Extract the umoptions */ datum = SysCacheGetAttr(USERMAPPINGUSERSERVER, tp, Anum_pg_user_mapping_umoptions, &isnull); um = palloc(sizeof(UserMapping)); um->userid = userid; um->serverid = serverid; um->options = untransformRelOptions(datum); ReleaseSysCache(tp); return um; }
Datum cassandra_fdw_validator(PG_FUNCTION_ARGS) { List *options_list = untransformRelOptions(PG_GETARG_DATUM(0)); elog(DEBUG1,"entering function %s",__func__); /* make sure the options are valid */ /* no options are supported */ if (list_length(options_list) > 0) ereport(ERROR, (errcode(ERRCODE_FDW_INVALID_OPTION_NAME), errmsg("invalid options"), errhint("Cassandra FDW doies not support any options"))); PG_RETURN_VOID(); }
/* * Validate the generic options given to a FOREIGN DATA WRAPPER, SERVER, * USER MAPPING or FOREIGN TABLE that uses file_fdw. * * Raise an ERROR if the option or its value is considered invalid. */ Datum hdfs_fdw_validator(PG_FUNCTION_ARGS) { List *options_list = untransformRelOptions(PG_GETARG_DATUM(0)); Oid catalog = PG_GETARG_OID(1); ListCell *cell; /* * Check that only options supported by hdfs_fdw, * and allowed for the current object type, are given. */ foreach(cell, options_list) { DefElem *def = (DefElem *) lfirst(cell); if (!hdfs_is_valid_option(def->defname, catalog)) { struct HDFSFdwOption *opt; StringInfoData buf; /* * Unknown option specified, complain about it. Provide a hint * with list of valid options for the object. */ initStringInfo(&buf); for (opt = valid_options; opt->optname; opt++) { if (catalog == opt->optcontext) appendStringInfo(&buf, "%s%s", (buf.len > 0) ? ", " : "", opt->optname); } ereport(ERROR, (errcode(ERRCODE_FDW_INVALID_OPTION_NAME), errmsg("invalid option \"%s\"", def->defname), errhint("Valid options in this context are: %s", buf.len ? buf.data : "<none>") )); } }
/* * Validate the generic options given to a FOREIGN DATA WRAPPER, SERVER, * USER MAPPING or FOREIGN TABLE that uses file_fdw. * * Raise an ERROR if the option or its value is considered invalid. */ Datum s3_fdw_validator(PG_FUNCTION_ARGS) { List *options_list = untransformRelOptions(PG_GETARG_DATUM(0)); Oid catalog = PG_GETARG_OID(1); char *filename = NULL, *bucketname = NULL, *hostname = NULL, *accesskey = NULL, *secretkey = NULL; List *copy_options = NIL; ListCell *cell; /* * Check that only options supported by s3_fdw, and allowed for the * current object type, are given. */ foreach(cell, options_list) { DefElem *def = (DefElem *) lfirst(cell); if (!is_valid_option(def->defname, catalog)) { struct S3FdwOption *opt; StringInfoData buf; /* * Unknown option specified, complain about it. Provide a hint * with list of valid options for the object. */ initStringInfo(&buf); for (opt = valid_options; opt->optname; opt++) { if (catalog == opt->optcontext) appendStringInfo(&buf, "%s%s", (buf.len > 0) ? ", " : "", opt->optname); } ereport(ERROR, (errcode(ERRCODE_FDW_INVALID_OPTION_NAME), errmsg("invalid option \"%s\"", def->defname), errhint("Valid options in this context are: %s", buf.data))); } /* Separate out filename, since ProcessCopyOptions won't allow it */ if (strcmp(def->defname, "filename") == 0) { if (filename) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); filename = defGetString(def); } else if(strcmp(def->defname, "bucketname") == 0) { if (bucketname) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); bucketname = defGetString(def); } else if(strcmp(def->defname, "hostname") == 0) { if (hostname) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); hostname = defGetString(def); } else if(strcmp(def->defname, "accesskey") == 0) { if (accesskey) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); accesskey = defGetString(def); } else if(strcmp(def->defname, "secretkey") == 0) { if (secretkey) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); secretkey = defGetString(def); } else copy_options = lappend(copy_options, def); }
/* * Validate the generic options given to a FOREIGN DATA WRAPPER, SERVER, * USER MAPPING or FOREIGN TABLE that uses couchdb_fdw. * * TODO: Should there be a validator function because the options can be any * string unless we have a way to retrieve the column names of the newly created * table. Also we need to know which statement (CREATE SERVER? CREATE FDW? or CREATE TBALE?) * is calling the validator because each will have its own valid options. */ Datum couchdb_fdw_validator(PG_FUNCTION_ARGS) { List *options_list = untransformRelOptions(PG_GETARG_DATUM(0)); Oid catalog = PG_GETARG_OID(1); char *svr_address = NULL; int svr_port = 0; char *svr_database = NULL; char *username = NULL; char *password = NULL; ListCell *cell; #ifdef DEBUG elog(NOTICE, "couchdb_fdw_validator"); #endif /* * Check that the necessary options: address, port, database */ foreach(cell, options_list) { DefElem *def = (DefElem *) lfirst(cell); /* Compain invalid options */ if (!couchdbIsValidOption(def->defname, catalog)) { struct CouchDBFdwOption *opt; StringInfoData buf; /* * Unknown option specified, complain about it. Provide a hint * with list of valid options for the object. */ initStringInfo(&buf); for (opt = valid_options; opt->optname; opt++) { if (catalog == opt->optcontext) appendStringInfo(&buf, "%s%s", (buf.len > 0) ? ", " : "", opt->optname); } ereport(ERROR, (errcode(ERRCODE_FDW_INVALID_OPTION_NAME), errmsg("invalid option \"%s\"", def->defname), errhint("Valid options in this context are: %s", buf.len ? buf.data : "<none>") )); } /* Complain about redundent options */ if (strcmp(def->defname, "address") == 0) { if (svr_address) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: address (%s)", defGetString(def)) )); svr_address = defGetString(def); } else if (strcmp(def->defname, "port") == 0) { if (svr_port) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: port (%s)", defGetString(def)) )); svr_port = atoi(defGetString(def)); } else if (strcmp(def->defname, "database") == 0) { if (svr_database) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: database (%s)", defGetString(def)) )); svr_database = defGetString(def); } else if (strcmp(def->defname, "username") == 0) { if (username) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: username (%s)", defGetString(def)) )); username = defGetString(def); } else if (strcmp(def->defname, "password") == 0) { if (password) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: password (%s)", defGetString(def)) )); password = defGetString(def); } }
Datum ppg_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(); /* * Check that only options supported by postgres_fdw, and allowed for the * current object type, are given. */ foreach(cell, options_list) { DefElem *def = (DefElem *) lfirst(cell); if (!is_valid_option(def->defname, catalog)) { /* * Unknown option specified, complain about it. Provide a hint * with list of valid options for the object. */ PgFdwOption *opt; StringInfoData buf; initStringInfo(&buf); for (opt = postgres_fdw_options; opt->keyword; opt++) { if (catalog == opt->optcontext) appendStringInfo(&buf, "%s%s", (buf.len > 0) ? ", " : "", opt->keyword); } ereport(ERROR, (errcode(ERRCODE_FDW_INVALID_OPTION_NAME), errmsg("invalid option \"%s\"", def->defname), errhint("Valid options in this context are: %s", buf.data))); } /* * Validate option value, when we can do so without any context. */ if (strcmp(def->defname, "use_remote_estimate") == 0) { /* use_remote_estimate accepts only boolean values */ (void) defGetBoolean(def); } else if (strcmp(def->defname, "fdw_startup_cost") == 0 || strcmp(def->defname, "fdw_tuple_cost") == 0) { /* these must have a non-negative numeric value */ double val; char *endp; val = strtod(defGetString(def), &endp); if (*endp || val < 0) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("%s requires a non-negative numeric value", def->defname))); } }
/* * Validate the generic options given to a FOREIGN DATA WRAPPER, SERVER, * USER MAPPING or FOREIGN TABLE that uses file_fdw. * * Raise an ERROR if the option or its value is considered invalid. */ Datum mysql_fdw_validator(PG_FUNCTION_ARGS) { List *options_list = untransformRelOptions(PG_GETARG_DATUM(0)); Oid catalog = PG_GETARG_OID(1); char *svr_address = NULL; int svr_port = 0; char *svr_username = NULL; char *svr_password = NULL; char *svr_database = NULL; char *svr_query = NULL; char *svr_table = NULL; ListCell *cell; /* * Check that only options supported by mysql_fdw, * and allowed for the current object type, are given. */ foreach(cell, options_list) { DefElem *def = (DefElem *) lfirst(cell); if (!mysqlIsValidOption(def->defname, catalog)) { struct MySQLFdwOption *opt; StringInfoData buf; /* * Unknown option specified, complain about it. Provide a hint * with list of valid options for the object. */ initStringInfo(&buf); for (opt = valid_options; opt->optname; opt++) { if (catalog == opt->optcontext) appendStringInfo(&buf, "%s%s", (buf.len > 0) ? ", " : "", opt->optname); } ereport(ERROR, (errcode(ERRCODE_FDW_INVALID_OPTION_NAME), errmsg("invalid option \"%s\"", def->defname), errhint("Valid options in this context are: %s", buf.len ? buf.data : "<none>") )); } if (strcmp(def->defname, "address") == 0) { if (svr_address) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: address (%s)", defGetString(def)) )); svr_address = defGetString(def); } else if (strcmp(def->defname, "port") == 0) { if (svr_port) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: port (%s)", defGetString(def)) )); svr_port = atoi(defGetString(def)); } if (strcmp(def->defname, "username") == 0) { if (svr_username) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: username (%s)", defGetString(def)) )); svr_username = defGetString(def); } if (strcmp(def->defname, "password") == 0) { if (svr_password) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: password") )); svr_password = defGetString(def); } else if (strcmp(def->defname, "database") == 0) { if (svr_database) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: database (%s)", defGetString(def)) )); svr_database = defGetString(def); } else if (strcmp(def->defname, "query") == 0) { if (svr_table) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting options: query cannot be used with table") )); if (svr_query) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: query (%s)", defGetString(def)) )); svr_query = defGetString(def); } else if (strcmp(def->defname, "table") == 0) { if (svr_query) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting options: table cannot be used with query") )); if (svr_table) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: table (%s)", defGetString(def)) )); svr_table = defGetString(def); } }
/* * Validate the generic options given to a FOREIGN DATA WRAPPER, SERVER, * USER MAPPING or FOREIGN TABLE that uses file_fdw. * * Raise an ERROR if the option or its value is considered invalid. */ Datum redis_fdw_validator(PG_FUNCTION_ARGS) { List *options_list = untransformRelOptions(PG_GETARG_DATUM(0)); Oid catalog = PG_GETARG_OID(1); char *svr_address = NULL; int svr_port = 0; char *svr_password = NULL; int svr_database = 0; redis_table_type tabletype = PG_REDIS_SCALAR_TABLE; char *tablekeyprefix = NULL; char *tablekeyset = NULL; ListCell *cell; #ifdef DEBUG elog(NOTICE, "redis_fdw_validator"); #endif /* * Check that only options supported by redis_fdw, and allowed for the * current object type, are given. */ foreach(cell, options_list) { DefElem *def = (DefElem *) lfirst(cell); if (!redisIsValidOption(def->defname, catalog)) { struct RedisFdwOption *opt; StringInfoData buf; /* * Unknown option specified, complain about it. Provide a hint * with list of valid options for the object. */ initStringInfo(&buf); for (opt = valid_options; opt->optname; opt++) { if (catalog == opt->optcontext) appendStringInfo(&buf, "%s%s", (buf.len > 0) ? ", " : "", opt->optname); } ereport(ERROR, (errcode(ERRCODE_FDW_INVALID_OPTION_NAME), errmsg("invalid option \"%s\"", def->defname), errhint("Valid options in this context are: %s", buf.len ? buf.data : "<none>") )); } if (strcmp(def->defname, "address") == 0) { if (svr_address) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: " "address (%s)", defGetString(def)) )); svr_address = defGetString(def); } else if (strcmp(def->defname, "port") == 0) { if (svr_port) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: port (%s)", defGetString(def)) )); svr_port = atoi(defGetString(def)); } if (strcmp(def->defname, "password") == 0) { if (svr_password) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: password") )); svr_password = defGetString(def); } else if (strcmp(def->defname, "database") == 0) { if (svr_database) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: database " "(%s)", defGetString(def)) )); svr_database = atoi(defGetString(def)); } else if (strcmp(def->defname, "tablekeyprefix") == 0) { if (tablekeyset) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting options: tablekeyset(%s) and " "tablekeyprefix (%s)", tablekeyset, defGetString(def)) )); if (tablekeyprefix) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: " "tablekeyprefix (%s)", defGetString(def)) )); tablekeyprefix = defGetString(def); } else if (strcmp(def->defname, "tablekeyset") == 0) { if (tablekeyprefix) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting options: tablekeyprefix (%s) and " "tablekeyset (%s)", tablekeyprefix, defGetString(def)) )); if (tablekeyset) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: " "tablekeyset (%s)", defGetString(def)) )); tablekeyset = defGetString(def); } else if (strcmp(def->defname, "tabletype") == 0) { char *typeval = defGetString(def); if (tabletype) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options: tabletype " "(%s)", typeval))); if (strcmp(typeval,"hash") == 0) tabletype = PG_REDIS_HASH_TABLE; else if (strcmp(typeval,"list") == 0) tabletype = PG_REDIS_LIST_TABLE; else if (strcmp(typeval,"set") == 0) tabletype = PG_REDIS_SET_TABLE; else if (strcmp(typeval,"zset") == 0) tabletype = PG_REDIS_ZSET_TABLE; else ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("invalid tabletype (%s) - must be hash, " "list, set or zset", typeval))); } }
/* * Validate the generic options given to a FOREIGN DATA WRAPPER, SERVER, * USER MAPPING or FOREIGN TABLE that uses file_fdw. * * Raise an ERROR if the option or its value is considered invalid. */ Datum file_fdw_validator(PG_FUNCTION_ARGS) { List *options_list = untransformRelOptions(PG_GETARG_DATUM(0)); Oid catalog = PG_GETARG_OID(1); char *filename = NULL; DefElem *force_not_null = NULL; List *other_options = NIL; ListCell *cell; /* * Only superusers are allowed to set options of a file_fdw foreign table. * This is because the filename is one of those options, and we don't want * non-superusers to be able to determine which file gets read. * * Putting this sort of permissions check in a validator is a bit of a * crock, but there doesn't seem to be any other place that can enforce * the check more cleanly. * * Note that the valid_options[] array disallows setting filename at any * options level other than foreign table --- otherwise there'd still be a * security hole. */ if (catalog == ForeignTableRelationId && !superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("only superuser can change options of a file_fdw foreign table"))); /* * Check that only options supported by file_fdw, and allowed for the * current object type, are given. */ foreach(cell, options_list) { DefElem *def = (DefElem *) lfirst(cell); if (!is_valid_option(def->defname, catalog)) { struct FileFdwOption *opt; StringInfoData buf; /* * Unknown option specified, complain about it. Provide a hint * with list of valid options for the object. */ initStringInfo(&buf); for (opt = valid_options; opt->optname; opt++) { if (catalog == opt->optcontext) appendStringInfo(&buf, "%s%s", (buf.len > 0) ? ", " : "", opt->optname); } ereport(ERROR, (errcode(ERRCODE_FDW_INVALID_OPTION_NAME), errmsg("invalid option \"%s\"", def->defname), errhint("Valid options in this context are: %s", buf.data))); } /* * Separate out filename and force_not_null, since ProcessCopyOptions * won't accept them. (force_not_null only comes in a boolean * per-column flavor here.) */ if (strcmp(def->defname, "filename") == 0) { if (filename) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); filename = defGetString(def); } else if (strcmp(def->defname, "force_not_null") == 0) { if (force_not_null) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); force_not_null = def; /* Don't care what the value is, as long as it's a legal boolean */ (void) defGetBoolean(def); } else other_options = lappend(other_options, def); }
/* * Validate the generic options given to a FOREIGN DATA WRAPPER, SERVER, * USER MAPPING or FOREIGN TABLE that uses file_fdw. * * Raise an ERROR if the option or its value is considered invalid. */ Datum cassandra2_fdw_validator (PG_FUNCTION_ARGS) { List *options_list = untransformRelOptions (PG_GETARG_DATUM (0)); Oid catalog = PG_GETARG_OID (1); char *svr_url = NULL; char *svr_username = NULL; char *svr_password = NULL; char *svr_queryableColumns = NULL; char *svr_table = NULL; int svr_querytimeout = 0; int svr_portNumber = 0; ListCell *cell; /* * Check that only options supported by cassandra2_fdw, * and allowed for the current object type, are given. */ foreach (cell, options_list) { DefElem *def = (DefElem *) lfirst (cell); if (!cassIsValidOption (def->defname, catalog)) { const struct CassFdwOption *opt; StringInfoData buf; /* * Unknown option specified, complain about it. Provide a hint * with list of valid options for the object. */ initStringInfo (&buf); for (opt = valid_options; opt->optname; opt++) { if (catalog == opt->optcontext) appendStringInfo (&buf, "%s%s", (buf.len > 0) ? ", " : "", opt->optname); } ereport (ERROR, (errcode (ERRCODE_FDW_INVALID_OPTION_NAME), errmsg ("invalid option \"%s\"", def->defname), buf.len > 0 ? errhint ("Valid options in this context are: %s", buf.data) : errhint ("There are no valid options in this context."))); } if (strcmp (def->defname, "url") == 0) { if (svr_url) ereport (ERROR, (errcode (ERRCODE_SYNTAX_ERROR), errmsg ("conflicting or redundant options"))); svr_url = defGetString (def); } else if (strcmp (def->defname, "querytimeout") == 0) { if (svr_querytimeout) ereport (ERROR, (errcode (ERRCODE_SYNTAX_ERROR), errmsg ("conflicting or redundant options"))); svr_querytimeout = atoi (defGetString (def)); } else if (strcmp (def->defname, "portNumber") == 0) { if (svr_portNumber) ereport (ERROR, (errcode (ERRCODE_SYNTAX_ERROR), errmsg ("conflicting or redundant options"))); svr_portNumber = atoi (defGetString (def)); } else if (strcmp (def->defname, "username") == 0) { if (svr_username) ereport (ERROR, (errcode (ERRCODE_SYNTAX_ERROR), errmsg ("conflicting or redundant options"))); svr_username = defGetString (def); } else if (strcmp (def->defname, "password") == 0) { if (svr_password) ereport (ERROR, (errcode (ERRCODE_SYNTAX_ERROR), errmsg ("conflicting or redundant options"))); svr_password = defGetString (def); } else if (strcmp (def->defname, "queryable_columns") == 0) { if (svr_queryableColumns) ereport (ERROR, (errcode (ERRCODE_SYNTAX_ERROR), errmsg ("conflicting or redundant options"))); svr_queryableColumns = defGetString (def); } else if (strcmp (def->defname, "table") == 0) { if (svr_table) ereport (ERROR, (errcode (ERRCODE_SYNTAX_ERROR), errmsg ("conflicting or redundant options"))); svr_table = defGetString (def); } }