#include "postgres.h"#include "access/htup_details.h"#include "access/reloptions.h"#include "catalog/pg_foreign_data_wrapper.h"#include "catalog/pg_foreign_server.h"#include "catalog/pg_foreign_table.h"#include "catalog/pg_user_mapping.h"#include "foreign/fdwapi.h"#include "foreign/foreign.h"#include "lib/stringinfo.h"#include "miscadmin.h"#include "utils/builtins.h"#include "utils/memutils.h"#include "utils/rel.h"#include "utils/syscache.h"
Go to the source code of this file.
| static void deflist_to_tuplestore | ( | ReturnSetInfo * | rsinfo, | |
| List * | options | |||
| ) | [static] |
Definition at line 407 of file foreign.c.
References ReturnSetInfo::allowedModes, DefElem::arg, CreateTupleDescCopy(), CStringGetTextDatum, DefElem::defname, ReturnSetInfo::econtext, ExprContext::ecxt_per_query_memory, ereport, errcode(), errmsg(), ERROR, ReturnSetInfo::expectedDesc, IsA, lfirst, MemoryContextSwitchTo(), NULL, ReturnSetInfo::returnMode, ReturnSetInfo::setDesc, ReturnSetInfo::setResult, SFRM_Materialize, tuplestore_begin_heap(), tuplestore_donestoring, tuplestore_putvalues(), values, and work_mem.
Referenced by pg_options_to_table().
{
ListCell *cell;
TupleDesc tupdesc;
Tuplestorestate *tupstore;
Datum values[2];
bool nulls[2];
MemoryContext per_query_ctx;
MemoryContext oldcontext;
/* check to see if caller supports us returning a tuplestore */
if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("set-valued function called in context that cannot accept a set")));
if (!(rsinfo->allowedModes & SFRM_Materialize) ||
rsinfo->expectedDesc == NULL)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("materialize mode required, but it is not allowed in this context")));
per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
oldcontext = MemoryContextSwitchTo(per_query_ctx);
/*
* Now prepare the result set.
*/
tupdesc = CreateTupleDescCopy(rsinfo->expectedDesc);
tupstore = tuplestore_begin_heap(true, false, work_mem);
rsinfo->returnMode = SFRM_Materialize;
rsinfo->setResult = tupstore;
rsinfo->setDesc = tupdesc;
foreach(cell, options)
{
DefElem *def = lfirst(cell);
values[0] = CStringGetTextDatum(def->defname);
nulls[0] = false;
if (def->arg)
{
values[1] = CStringGetTextDatum(((Value *) (def->arg))->val.str);
nulls[1] = false;
}
else
{
values[1] = (Datum) 0;
nulls[1] = true;
}
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
}
/* clean up and return the tuplestore */
tuplestore_donestoring(tupstore);
MemoryContextSwitchTo(oldcontext);
}
Definition at line 592 of file foreign.c.
References CStringGetDatum, ereport, errcode(), errmsg(), ERROR, FOREIGNDATAWRAPPERNAME, GetSysCacheOid1, and OidIsValid.
Referenced by convert_foreign_data_wrapper_name(), get_object_address_unqualified(), GetForeignDataWrapperByName(), and objectNamesToOids().
{
Oid oid;
oid = GetSysCacheOid1(FOREIGNDATAWRAPPERNAME, CStringGetDatum(fdwname));
if (!OidIsValid(oid) && !missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("foreign-data wrapper \"%s\" does not exist",
fdwname)));
return oid;
}
Definition at line 613 of file foreign.c.
References CStringGetDatum, ereport, errcode(), errmsg(), ERROR, FOREIGNSERVERNAME, GetSysCacheOid1, and OidIsValid.
Referenced by convert_server_name(), get_object_address_unqualified(), GetForeignServerByName(), and objectNamesToOids().
{
Oid oid;
oid = GetSysCacheOid1(FOREIGNSERVERNAME, CStringGetDatum(servername));
if (!OidIsValid(oid) && !missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("server \"%s\" does not exist", servername)));
return oid;
}
| FdwRoutine* GetFdwRoutine | ( | Oid | fdwhandler | ) |
Definition at line 290 of file foreign.c.
References DatumGetPointer, elog, ERROR, IsA, NULL, and OidFunctionCall0.
Referenced by GetFdwRoutineByRelId().
{
Datum datum;
FdwRoutine *routine;
datum = OidFunctionCall0(fdwhandler);
routine = (FdwRoutine *) DatumGetPointer(datum);
if (routine == NULL || !IsA(routine, FdwRoutine))
elog(ERROR, "foreign-data wrapper handler function %u did not return an FdwRoutine struct",
fdwhandler);
return routine;
}
| FdwRoutine* GetFdwRoutineByRelId | ( | Oid | relid | ) |
Definition at line 311 of file foreign.c.
References elog, ereport, errcode(), errmsg(), ERROR, FOREIGNDATAWRAPPEROID, FOREIGNSERVEROID, FOREIGNTABLEREL, GetFdwRoutine(), GETSTRUCT, HeapTupleIsValid, NameStr, ObjectIdGetDatum, OidIsValid, ReleaseSysCache(), and SearchSysCache1.
Referenced by GetFdwRoutineForRelation(), and make_modifytable().
{
HeapTuple tp;
Form_pg_foreign_data_wrapper fdwform;
Form_pg_foreign_server serverform;
Form_pg_foreign_table tableform;
Oid serverid;
Oid fdwid;
Oid fdwhandler;
/* Get server OID for the foreign table. */
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);
serverid = tableform->ftserver;
ReleaseSysCache(tp);
/* Get foreign-data wrapper OID for the server. */
tp = SearchSysCache1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid));
if (!HeapTupleIsValid(tp))
elog(ERROR, "cache lookup failed for foreign server %u", serverid);
serverform = (Form_pg_foreign_server) GETSTRUCT(tp);
fdwid = serverform->srvfdw;
ReleaseSysCache(tp);
/* Get handler function OID for the FDW. */
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);
fdwhandler = fdwform->fdwhandler;
/* Complain if FDW has been set to NO HANDLER. */
if (!OidIsValid(fdwhandler))
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("foreign-data wrapper \"%s\" has no handler",
NameStr(fdwform->fdwname))));
ReleaseSysCache(tp);
/* And finally, call the handler function. */
return GetFdwRoutine(fdwhandler);
}
| FdwRoutine* GetFdwRoutineForRelation | ( | Relation | relation, | |
| bool | makecopy | |||
| ) |
Definition at line 369 of file foreign.c.
References CacheMemoryContext, GetFdwRoutineByRelId(), MemoryContextAlloc(), NULL, palloc(), RelationData::rd_fdwroutine, and RelationGetRelid.
Referenced by analyze_rel(), CheckValidResultRel(), ExecInitForeignScan(), get_relation_info(), InitResultRelInfo(), and rewriteTargetListUD().
{
FdwRoutine *fdwroutine;
FdwRoutine *cfdwroutine;
if (relation->rd_fdwroutine == NULL)
{
/* Get the info by consulting the catalogs and the FDW code */
fdwroutine = GetFdwRoutineByRelId(RelationGetRelid(relation));
/* Save the data for later reuse in CacheMemoryContext */
cfdwroutine = (FdwRoutine *) MemoryContextAlloc(CacheMemoryContext,
sizeof(FdwRoutine));
memcpy(cfdwroutine, fdwroutine, sizeof(FdwRoutine));
relation->rd_fdwroutine = cfdwroutine;
/* Give back the locally palloc'd copy regardless of makecopy */
return fdwroutine;
}
/* We have valid cached data --- does the caller want a copy? */
if (makecopy)
{
fdwroutine = (FdwRoutine *) palloc(sizeof(FdwRoutine));
memcpy(fdwroutine, relation->rd_fdwroutine, sizeof(FdwRoutine));
return fdwroutine;
}
/* Only a short-lived reference is needed, so just hand back cached copy */
return relation->rd_fdwroutine;
}
| List* GetForeignColumnOptions | ( | Oid | relid, | |
| AttrNumber | attnum | |||
| ) |
Definition at line 257 of file foreign.c.
References Anum_pg_attribute_attfdwoptions, ATTNUM, elog, ERROR, HeapTupleIsValid, Int16GetDatum, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache2, SysCacheGetAttr(), and untransformRelOptions().
Referenced by deparseAnalyzeSql(), deparseColumnRef(), and get_file_fdw_attribute_options().
{
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;
}
| ForeignDataWrapper* GetForeignDataWrapper | ( | Oid | fdwid | ) |
Definition at line 39 of file foreign.c.
References Anum_pg_foreign_data_wrapper_fdwoptions, elog, ERROR, ForeignDataWrapper::fdwhandler, ForeignDataWrapper::fdwid, ForeignDataWrapper::fdwname, ForeignDataWrapper::fdwvalidator, FOREIGNDATAWRAPPEROID, GETSTRUCT, HeapTupleIsValid, NameStr, ObjectIdGetDatum, ForeignDataWrapper::options, ForeignDataWrapper::owner, palloc(), pstrdup(), ReleaseSysCache(), SearchSysCache1, SysCacheGetAttr(), and untransformRelOptions().
Referenced by AlterForeignServer(), AlterForeignServerOwner_internal(), AlterUserMapping(), ATExecAlterColumnGenericOptions(), ATExecGenericOptions(), CreateForeignTable(), CreateUserMapping(), fileGetOptions(), get_connect_string(), GetForeignDataWrapperByName(), getObjectDescription(), and getObjectIdentity().
{
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 = (ForeignDataWrapper *) palloc(sizeof(ForeignDataWrapper));
fdw->fdwid = fdwid;
fdw->owner = fdwform->fdwowner;
fdw->fdwname = pstrdup(NameStr(fdwform->fdwname));
fdw->fdwhandler = fdwform->fdwhandler;
fdw->fdwvalidator = fdwform->fdwvalidator;
/* Extract the fdwoptions */
datum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID,
tp,
Anum_pg_foreign_data_wrapper_fdwoptions,
&isnull);
if (isnull)
fdw->options = NIL;
else
fdw->options = untransformRelOptions(datum);
ReleaseSysCache(tp);
return fdw;
}
| ForeignDataWrapper* GetForeignDataWrapperByName | ( | const char * | fdwname, | |
| bool | missing_ok | |||
| ) |
Definition at line 82 of file foreign.c.
References get_foreign_data_wrapper_oid(), GetForeignDataWrapper(), and OidIsValid.
Referenced by CreateForeignDataWrapper(), and CreateForeignServer().
{
Oid fdwId = get_foreign_data_wrapper_oid(fdwname, missing_ok);
if (!OidIsValid(fdwId))
return NULL;
return GetForeignDataWrapper(fdwId);
}
| ForeignServer* GetForeignServer | ( | Oid | serverid | ) |
Definition at line 97 of file foreign.c.
References Anum_pg_foreign_server_srvoptions, Anum_pg_foreign_server_srvtype, Anum_pg_foreign_server_srvversion, elog, ERROR, ForeignServer::fdwid, FOREIGNSERVEROID, GETSTRUCT, HeapTupleIsValid, NameStr, NULL, ObjectIdGetDatum, ForeignServer::options, ForeignServer::owner, palloc(), pstrdup(), ReleaseSysCache(), SearchSysCache1, ForeignServer::serverid, ForeignServer::servername, ForeignServer::servertype, ForeignServer::serverversion, SysCacheGetAttr(), TextDatumGetCString, and untransformRelOptions().
Referenced by ATExecAlterColumnGenericOptions(), ATExecGenericOptions(), fileGetOptions(), GetForeignServerByName(), getObjectDescription(), getObjectIdentity(), postgresAcquireSampleRowsFunc(), postgresAnalyzeForeignTable(), postgresBeginForeignModify(), postgresBeginForeignScan(), and postgresGetForeignRelSize().
{
Form_pg_foreign_server serverform;
ForeignServer *server;
HeapTuple tp;
Datum datum;
bool isnull;
tp = SearchSysCache1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid));
if (!HeapTupleIsValid(tp))
elog(ERROR, "cache lookup failed for foreign server %u", serverid);
serverform = (Form_pg_foreign_server) GETSTRUCT(tp);
server = (ForeignServer *) 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);
if (isnull)
server->options = NIL;
else
server->options = untransformRelOptions(datum);
ReleaseSysCache(tp);
return server;
}
| ForeignServer* GetForeignServerByName | ( | const char * | srvname, | |
| bool | missing_ok | |||
| ) |
Definition at line 152 of file foreign.c.
References get_foreign_server_oid(), GetForeignServer(), and OidIsValid.
Referenced by AlterUserMapping(), CreateForeignServer(), CreateForeignTable(), CreateUserMapping(), get_connect_string(), and RemoveUserMapping().
{
Oid serverid = get_foreign_server_oid(srvname, missing_ok);
if (!OidIsValid(serverid))
return NULL;
return GetForeignServer(serverid);
}
| ForeignTable* GetForeignTable | ( | Oid | relid | ) |
Definition at line 219 of file foreign.c.
References Anum_pg_foreign_table_ftoptions, elog, ERROR, FOREIGNTABLEREL, GETSTRUCT, HeapTupleIsValid, ObjectIdGetDatum, ForeignTable::options, palloc(), ReleaseSysCache(), ForeignTable::relid, SearchSysCache1, ForeignTable::serverid, SysCacheGetAttr(), and untransformRelOptions().
Referenced by check_selective_binary_conversion(), deparseRelation(), fileGetOptions(), postgresAcquireSampleRowsFunc(), postgresAnalyzeForeignTable(), postgresBeginForeignModify(), postgresBeginForeignScan(), and postgresGetForeignRelSize().
{
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;
}
| UserMapping* GetUserMapping | ( | Oid | userid, | |
| Oid | serverid | |||
| ) |
Definition at line 170 of file foreign.c.
References Anum_pg_user_mapping_umoptions, ereport, errcode(), errmsg(), ERROR, HeapTupleIsValid, InvalidOid, MappingUserName, ObjectIdGetDatum, UserMapping::options, palloc(), ReleaseSysCache(), SearchSysCache2, UserMapping::serverid, SysCacheGetAttr(), untransformRelOptions(), UserMapping::userid, and USERMAPPINGUSERSERVER.
Referenced by get_connect_string(), postgresAcquireSampleRowsFunc(), postgresAnalyzeForeignTable(), postgresBeginForeignModify(), postgresBeginForeignScan(), and postgresGetForeignRelSize().
{
Datum datum;
HeapTuple tp;
bool isnull;
UserMapping *um;
tp = SearchSysCache2(USERMAPPINGUSERSERVER,
ObjectIdGetDatum(userid),
ObjectIdGetDatum(serverid));
if (!HeapTupleIsValid(tp))
{
/* Not found for the specific user -- try PUBLIC */
tp = SearchSysCache2(USERMAPPINGUSERSERVER,
ObjectIdGetDatum(InvalidOid),
ObjectIdGetDatum(serverid));
}
if (!HeapTupleIsValid(tp))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("user mapping not found for \"%s\"",
MappingUserName(userid))));
um = (UserMapping *) palloc(sizeof(UserMapping));
um->userid = userid;
um->serverid = serverid;
/* Extract the umoptions */
datum = SysCacheGetAttr(USERMAPPINGUSERSERVER,
tp,
Anum_pg_user_mapping_umoptions,
&isnull);
if (isnull)
um->options = NIL;
else
um->options = untransformRelOptions(datum);
ReleaseSysCache(tp);
return um;
}
Definition at line 521 of file foreign.c.
References ConnectionOption::optcontext, and ConnectionOption::optname.
Referenced by postgresql_fdw_validator().
{
struct ConnectionOption *opt;
for (opt = libpq_conninfo_options; opt->optname; opt++)
if (context == opt->optcontext && strcmp(opt->optname, option) == 0)
return true;
return false;
}
| Datum pg_options_to_table | ( | PG_FUNCTION_ARGS | ) |
Definition at line 471 of file foreign.c.
References deflist_to_tuplestore(), PG_GETARG_DATUM, and untransformRelOptions().
{
Datum array = PG_GETARG_DATUM(0);
deflist_to_tuplestore((ReturnSetInfo *) fcinfo->resultinfo,
untransformRelOptions(array));
return (Datum) 0;
}
| Datum postgresql_fdw_validator | ( | PG_FUNCTION_ARGS | ) |
Definition at line 545 of file foreign.c.
References appendStringInfo(), buf, StringInfoData::data, DefElem::defname, ereport, errcode(), errhint(), errmsg(), ERROR, initStringInfo(), is_conninfo_option(), StringInfoData::len, lfirst, ConnectionOption::optcontext, ConnectionOption::optname, PG_GETARG_DATUM, PG_GETARG_OID, PG_RETURN_BOOL, and untransformRelOptions().
{
List *options_list = untransformRelOptions(PG_GETARG_DATUM(0));
Oid catalog = PG_GETARG_OID(1);
ListCell *cell;
foreach(cell, options_list)
{
DefElem *def = lfirst(cell);
if (!is_conninfo_option(def->defname, catalog))
{
struct ConnectionOption *opt;
StringInfoData buf;
/*
* Unknown option specified, complain about it. Provide a hint
* with list of valid options for the object.
*/
initStringInfo(&buf);
for (opt = libpq_conninfo_options; opt->optname; opt++)
if (catalog == opt->optcontext)
appendStringInfo(&buf, "%s%s", (buf.len > 0) ? ", " : "",
opt->optname);
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("invalid option \"%s\"", def->defname),
errhint("Valid options in this context are: %s",
buf.data)));
PG_RETURN_BOOL(false);
}
}
PG_RETURN_BOOL(true);
}
struct ConnectionOption libpq_conninfo_options[] [static] |
{
{"authtype", ForeignServerRelationId},
{"service", ForeignServerRelationId},
{"user", UserMappingRelationId},
{"password", UserMappingRelationId},
{"connect_timeout", ForeignServerRelationId},
{"dbname", ForeignServerRelationId},
{"host", ForeignServerRelationId},
{"hostaddr", ForeignServerRelationId},
{"port", ForeignServerRelationId},
{"tty", ForeignServerRelationId},
{"options", ForeignServerRelationId},
{"requiressl", ForeignServerRelationId},
{"sslmode", ForeignServerRelationId},
{"gsslib", ForeignServerRelationId},
{NULL, InvalidOid}
}
1.7.1