PostgreSQL Source Code  git master
foreign.c File Reference
Include dependency graph for foreign.c:

Go to the source code of this file.

Data Structures

struct  ConnectionOption
 

Functions

ForeignDataWrapperGetForeignDataWrapper (Oid fdwid)
 
ForeignDataWrapperGetForeignDataWrapperExtended (Oid fdwid, bits16 flags)
 
ForeignDataWrapperGetForeignDataWrapperByName (const char *fdwname, bool missing_ok)
 
ForeignServerGetForeignServer (Oid serverid)
 
ForeignServerGetForeignServerExtended (Oid serverid, bits16 flags)
 
ForeignServerGetForeignServerByName (const char *srvname, bool missing_ok)
 
UserMappingGetUserMapping (Oid userid, Oid serverid)
 
ForeignTableGetForeignTable (Oid relid)
 
ListGetForeignColumnOptions (Oid relid, AttrNumber attnum)
 
FdwRoutineGetFdwRoutine (Oid fdwhandler)
 
Oid GetForeignServerIdByRelId (Oid relid)
 
FdwRoutineGetFdwRoutineByServerId (Oid serverid)
 
FdwRoutineGetFdwRoutineByRelId (Oid relid)
 
FdwRoutineGetFdwRoutineForRelation (Relation relation, bool makecopy)
 
bool IsImportableForeignTable (const char *tablename, ImportForeignSchemaStmt *stmt)
 
static void deflist_to_tuplestore (ReturnSetInfo *rsinfo, List *options)
 
Datum pg_options_to_table (PG_FUNCTION_ARGS)
 
static bool is_conninfo_option (const char *option, Oid context)
 
Datum postgresql_fdw_validator (PG_FUNCTION_ARGS)
 
Oid get_foreign_data_wrapper_oid (const char *fdwname, bool missing_ok)
 
Oid get_foreign_server_oid (const char *servername, bool missing_ok)
 
PathGetExistingLocalJoinPath (RelOptInfo *joinrel)
 

Variables

static const struct ConnectionOption libpq_conninfo_options []
 

Function Documentation

◆ deflist_to_tuplestore()

static void deflist_to_tuplestore ( ReturnSetInfo rsinfo,
List options 
)
static

Definition at line 506 of file foreign.c.

507 {
508  ListCell *cell;
509  TupleDesc tupdesc;
510  Tuplestorestate *tupstore;
511  Datum values[2];
512  bool nulls[2];
513  MemoryContext per_query_ctx;
514  MemoryContext oldcontext;
515 
516  /* check to see if caller supports us returning a tuplestore */
517  if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
518  ereport(ERROR,
519  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
520  errmsg("set-valued function called in context that cannot accept a set")));
521  if (!(rsinfo->allowedModes & SFRM_Materialize) ||
522  rsinfo->expectedDesc == NULL)
523  ereport(ERROR,
524  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
525  errmsg("materialize mode required, but it is not allowed in this context")));
526 
527  per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
528  oldcontext = MemoryContextSwitchTo(per_query_ctx);
529 
530  /*
531  * Now prepare the result set.
532  */
533  tupdesc = CreateTupleDescCopy(rsinfo->expectedDesc);
534  tupstore = tuplestore_begin_heap(true, false, work_mem);
535  rsinfo->returnMode = SFRM_Materialize;
536  rsinfo->setResult = tupstore;
537  rsinfo->setDesc = tupdesc;
538 
539  foreach(cell, options)
540  {
541  DefElem *def = lfirst(cell);
542 
544  nulls[0] = false;
545  if (def->arg)
546  {
547  values[1] = CStringGetTextDatum(strVal(def->arg));
548  nulls[1] = false;
549  }
550  else
551  {
552  values[1] = (Datum) 0;
553  nulls[1] = true;
554  }
555  tuplestore_putvalues(tupstore, tupdesc, values, nulls);
556  }
557 
558  /* clean up and return the tuplestore */
559  tuplestore_donestoring(tupstore);
560 
561  MemoryContextSwitchTo(oldcontext);
562 }
static Datum values[MAXATTR]
Definition: bootstrap.c:156
#define CStringGetTextDatum(s)
Definition: builtins.h:85
int errcode(int sqlerrcode)
Definition: elog.c:693
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define ERROR
Definition: elog.h:33
#define ereport(elevel,...)
Definition: elog.h:143
@ SFRM_Materialize
Definition: execnodes.h:293
int work_mem
Definition: globals.c:124
#define IsA(nodeptr, _type_)
Definition: nodes.h:589
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define lfirst(lc)
Definition: pg_list.h:169
uintptr_t Datum
Definition: postgres.h:411
char * defname
Definition: parsenodes.h:758
Node * arg
Definition: parsenodes.h:759
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:238
SetFunctionReturnMode returnMode
Definition: execnodes.h:312
ExprContext * econtext
Definition: execnodes.h:308
TupleDesc setDesc
Definition: execnodes.h:316
Tuplestorestate * setResult
Definition: execnodes.h:315
TupleDesc expectedDesc
Definition: execnodes.h:309
int allowedModes
Definition: execnodes.h:310
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:111
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, Datum *values, bool *isnull)
Definition: tuplestore.c:750
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
Definition: tuplestore.c:318
#define tuplestore_donestoring(state)
Definition: tuplestore.h:60
#define strVal(v)
Definition: value.h:72

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(), ReturnSetInfo::returnMode, ReturnSetInfo::setDesc, ReturnSetInfo::setResult, SFRM_Materialize, strVal, tuplestore_begin_heap(), tuplestore_donestoring, tuplestore_putvalues(), values, and work_mem.

◆ get_foreign_data_wrapper_oid()

Oid get_foreign_data_wrapper_oid ( const char *  fdwname,
bool  missing_ok 
)

Definition at line 693 of file foreign.c.

694 {
695  Oid oid;
696 
698  Anum_pg_foreign_data_wrapper_oid,
699  CStringGetDatum(fdwname));
700  if (!OidIsValid(oid) && !missing_ok)
701  ereport(ERROR,
702  (errcode(ERRCODE_UNDEFINED_OBJECT),
703  errmsg("foreign-data wrapper \"%s\" does not exist",
704  fdwname)));
705  return oid;
706 }
#define OidIsValid(objectId)
Definition: c.h:710
#define CStringGetDatum(X)
Definition: postgres.h:622
unsigned int Oid
Definition: postgres_ext.h:31
@ FOREIGNDATAWRAPPERNAME
Definition: syscache.h:61
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:195

References CStringGetDatum, ereport, errcode(), errmsg(), ERROR, FOREIGNDATAWRAPPERNAME, GetSysCacheOid1, and OidIsValid.

Referenced by convert_foreign_data_wrapper_name(), get_object_address_unqualified(), GetForeignDataWrapperByName(), and objectNamesToOids().

◆ get_foreign_server_oid()

Oid get_foreign_server_oid ( const char *  servername,
bool  missing_ok 
)

Definition at line 716 of file foreign.c.

717 {
718  Oid oid;
719 
720  oid = GetSysCacheOid1(FOREIGNSERVERNAME, Anum_pg_foreign_server_oid,
721  CStringGetDatum(servername));
722  if (!OidIsValid(oid) && !missing_ok)
723  ereport(ERROR,
724  (errcode(ERRCODE_UNDEFINED_OBJECT),
725  errmsg("server \"%s\" does not exist", servername)));
726  return oid;
727 }
@ FOREIGNSERVERNAME
Definition: syscache.h:63

References CStringGetDatum, ereport, errcode(), errmsg(), ERROR, FOREIGNSERVERNAME, GetSysCacheOid1, and OidIsValid.

Referenced by convert_server_name(), get_object_address_unqualified(), GetForeignServerByName(), and objectNamesToOids().

◆ GetExistingLocalJoinPath()

Path* GetExistingLocalJoinPath ( RelOptInfo joinrel)

Definition at line 753 of file foreign.c.

754 {
755  ListCell *lc;
756 
757  Assert(IS_JOIN_REL(joinrel));
758 
759  foreach(lc, joinrel->pathlist)
760  {
761  Path *path = (Path *) lfirst(lc);
762  JoinPath *joinpath = NULL;
763 
764  /* Skip parameterized paths. */
765  if (path->param_info != NULL)
766  continue;
767 
768  switch (path->pathtype)
769  {
770  case T_HashJoin:
771  {
772  HashPath *hash_path = makeNode(HashPath);
773 
774  memcpy(hash_path, path, sizeof(HashPath));
775  joinpath = (JoinPath *) hash_path;
776  }
777  break;
778 
779  case T_NestLoop:
780  {
781  NestPath *nest_path = makeNode(NestPath);
782 
783  memcpy(nest_path, path, sizeof(NestPath));
784  joinpath = (JoinPath *) nest_path;
785  }
786  break;
787 
788  case T_MergeJoin:
789  {
790  MergePath *merge_path = makeNode(MergePath);
791 
792  memcpy(merge_path, path, sizeof(MergePath));
793  joinpath = (JoinPath *) merge_path;
794  }
795  break;
796 
797  default:
798 
799  /*
800  * Just skip anything else. We don't know if corresponding
801  * plan would build the output row from whole-row references
802  * of base relations and execute the EPQ checks.
803  */
804  break;
805  }
806 
807  /* This path isn't good for us, check next. */
808  if (!joinpath)
809  continue;
810 
811  /*
812  * If either inner or outer path is a ForeignPath corresponding to a
813  * pushed down join, replace it with the fdw_outerpath, so that we
814  * maintain path for EPQ checks built entirely of local join
815  * strategies.
816  */
817  if (IsA(joinpath->outerjoinpath, ForeignPath))
818  {
819  ForeignPath *foreign_path;
820 
821  foreign_path = (ForeignPath *) joinpath->outerjoinpath;
822  if (IS_JOIN_REL(foreign_path->path.parent))
823  joinpath->outerjoinpath = foreign_path->fdw_outerpath;
824  }
825 
826  if (IsA(joinpath->innerjoinpath, ForeignPath))
827  {
828  ForeignPath *foreign_path;
829 
830  foreign_path = (ForeignPath *) joinpath->innerjoinpath;
831  if (IS_JOIN_REL(foreign_path->path.parent))
832  joinpath->innerjoinpath = foreign_path->fdw_outerpath;
833  }
834 
835  return (Path *) joinpath;
836  }
837  return NULL;
838 }
Assert(fmt[strlen(fmt) - 1] !='\n')
@ T_MergeJoin
Definition: nodes.h:74
@ T_NestLoop
Definition: nodes.h:73
@ T_HashJoin
Definition: nodes.h:75
#define makeNode(_type_)
Definition: nodes.h:586
#define IS_JOIN_REL(rel)
Definition: pathnodes.h:659
Path * fdw_outerpath
Definition: pathnodes.h:1400
Path * outerjoinpath
Definition: pathnodes.h:1593
Path * innerjoinpath
Definition: pathnodes.h:1594
NodeTag pathtype
Definition: pathnodes.h:1181
RelOptInfo * parent
Definition: pathnodes.h:1183
ParamPathInfo * param_info
Definition: pathnodes.h:1186
List * pathlist
Definition: pathnodes.h:695

References Assert(), ForeignPath::fdw_outerpath, if(), JoinPath::innerjoinpath, IS_JOIN_REL, IsA, lfirst, makeNode, JoinPath::outerjoinpath, Path::param_info, Path::parent, ForeignPath::path, RelOptInfo::pathlist, Path::pathtype, T_HashJoin, T_MergeJoin, and T_NestLoop.

Referenced by postgresGetForeignJoinPaths().

◆ GetFdwRoutine()

FdwRoutine* GetFdwRoutine ( Oid  fdwhandler)

Definition at line 319 of file foreign.c.

320 {
321  Datum datum;
322  FdwRoutine *routine;
323 
324  datum = OidFunctionCall0(fdwhandler);
325  routine = (FdwRoutine *) DatumGetPointer(datum);
326 
327  if (routine == NULL || !IsA(routine, FdwRoutine))
328  elog(ERROR, "foreign-data wrapper handler function %u did not return an FdwRoutine struct",
329  fdwhandler);
330 
331  return routine;
332 }
#define elog(elevel,...)
Definition: elog.h:218
#define OidFunctionCall0(functionId)
Definition: fmgr.h:667
#define DatumGetPointer(X)
Definition: postgres.h:593

References DatumGetPointer, elog, ERROR, IsA, and OidFunctionCall0.

Referenced by GetFdwRoutineByServerId(), and ImportForeignSchema().

◆ GetFdwRoutineByRelId()

FdwRoutine* GetFdwRoutineByRelId ( Oid  relid)

Definition at line 404 of file foreign.c.

405 {
406  Oid serverid;
407 
408  /* Get server OID for the foreign table. */
409  serverid = GetForeignServerIdByRelId(relid);
410 
411  /* Now retrieve server's FdwRoutine struct. */
412  return GetFdwRoutineByServerId(serverid);
413 }
Oid GetForeignServerIdByRelId(Oid relid)
Definition: foreign.c:340
FdwRoutine * GetFdwRoutineByServerId(Oid serverid)
Definition: foreign.c:362

References GetFdwRoutineByServerId(), and GetForeignServerIdByRelId().

Referenced by GetFdwRoutineForRelation(), make_modifytable(), and select_rowmark_type().

◆ GetFdwRoutineByServerId()

FdwRoutine* GetFdwRoutineByServerId ( Oid  serverid)

Definition at line 362 of file foreign.c.

363 {
364  HeapTuple tp;
366  Form_pg_foreign_server serverform;
367  Oid fdwid;
368  Oid fdwhandler;
369 
370  /* Get foreign-data wrapper OID for the server. */
372  if (!HeapTupleIsValid(tp))
373  elog(ERROR, "cache lookup failed for foreign server %u", serverid);
374  serverform = (Form_pg_foreign_server) GETSTRUCT(tp);
375  fdwid = serverform->srvfdw;
376  ReleaseSysCache(tp);
377 
378  /* Get handler function OID for the FDW. */
380  if (!HeapTupleIsValid(tp))
381  elog(ERROR, "cache lookup failed for foreign-data wrapper %u", fdwid);
382  fdwform = (Form_pg_foreign_data_wrapper) GETSTRUCT(tp);
383  fdwhandler = fdwform->fdwhandler;
384 
385  /* Complain if FDW has been set to NO HANDLER. */
386  if (!OidIsValid(fdwhandler))
387  ereport(ERROR,
388  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
389  errmsg("foreign-data wrapper \"%s\" has no handler",
390  NameStr(fdwform->fdwname))));
391 
392  ReleaseSysCache(tp);
393 
394  /* And finally, call the handler function. */
395  return GetFdwRoutine(fdwhandler);
396 }
#define NameStr(name)
Definition: c.h:681
FdwRoutine * GetFdwRoutine(Oid fdwhandler)
Definition: foreign.c:319
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:649
FormData_pg_foreign_data_wrapper * Form_pg_foreign_data_wrapper
FormData_pg_foreign_server * Form_pg_foreign_server
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1198
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1150
@ FOREIGNSERVEROID
Definition: syscache.h:64
@ FOREIGNDATAWRAPPEROID
Definition: syscache.h:62

References elog, ereport, errcode(), errmsg(), ERROR, FOREIGNDATAWRAPPEROID, FOREIGNSERVEROID, GetFdwRoutine(), GETSTRUCT, HeapTupleIsValid, NameStr, ObjectIdGetDatum, OidIsValid, ReleaseSysCache(), and SearchSysCache1().

Referenced by ExecInitForeignScan(), ExecuteTruncateGuts(), GetFdwRoutineByRelId(), and truncate_check_rel().

◆ GetFdwRoutineForRelation()

FdwRoutine* GetFdwRoutineForRelation ( Relation  relation,
bool  makecopy 
)

Definition at line 427 of file foreign.c.

428 {
429  FdwRoutine *fdwroutine;
430  FdwRoutine *cfdwroutine;
431 
432  if (relation->rd_fdwroutine == NULL)
433  {
434  /* Get the info by consulting the catalogs and the FDW code */
435  fdwroutine = GetFdwRoutineByRelId(RelationGetRelid(relation));
436 
437  /* Save the data for later reuse in CacheMemoryContext */
439  sizeof(FdwRoutine));
440  memcpy(cfdwroutine, fdwroutine, sizeof(FdwRoutine));
441  relation->rd_fdwroutine = cfdwroutine;
442 
443  /* Give back the locally palloc'd copy regardless of makecopy */
444  return fdwroutine;
445  }
446 
447  /* We have valid cached data --- does the caller want a copy? */
448  if (makecopy)
449  {
450  fdwroutine = (FdwRoutine *) palloc(sizeof(FdwRoutine));
451  memcpy(fdwroutine, relation->rd_fdwroutine, sizeof(FdwRoutine));
452  return fdwroutine;
453  }
454 
455  /* Only a short-lived reference is needed, so just hand back cached copy */
456  return relation->rd_fdwroutine;
457 }
FdwRoutine * GetFdwRoutineByRelId(Oid relid)
Definition: foreign.c:404
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
MemoryContext CacheMemoryContext
Definition: mcxt.c:51
void * palloc(Size size)
Definition: mcxt.c:1062
#define RelationGetRelid(relation)
Definition: rel.h:478
struct FdwRoutine * rd_fdwroutine
Definition: rel.h:236

References CacheMemoryContext, GetFdwRoutineByRelId(), MemoryContextAlloc(), palloc(), RelationData::rd_fdwroutine, and RelationGetRelid.

Referenced by acquire_inherited_sample_rows(), add_row_identity_columns(), analyze_rel(), CheckValidRowMarkRel(), EvalPlanQualFetchRowMark(), ExecInitForeignScan(), ExecLockRows(), get_relation_info(), InitResultRelInfo(), and relation_is_updatable().

◆ GetForeignColumnOptions()

List* GetForeignColumnOptions ( Oid  relid,
AttrNumber  attnum 
)

Definition at line 286 of file foreign.c.

287 {
288  List *options;
289  HeapTuple tp;
290  Datum datum;
291  bool isnull;
292 
293  tp = SearchSysCache2(ATTNUM,
294  ObjectIdGetDatum(relid),
296  if (!HeapTupleIsValid(tp))
297  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
298  attnum, relid);
299  datum = SysCacheGetAttr(ATTNUM,
300  tp,
301  Anum_pg_attribute_attfdwoptions,
302  &isnull);
303  if (isnull)
304  options = NIL;
305  else
307 
308  ReleaseSysCache(tp);
309 
310  return options;
311 }
int16 attnum
Definition: pg_attribute.h:83
#define NIL
Definition: pg_list.h:65
static char ** options
#define Int16GetDatum(X)
Definition: postgres.h:495
List * untransformRelOptions(Datum options)
Definition: reloptions.c:1325
Definition: pg_list.h:51
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1411
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1161
@ ATTNUM
Definition: syscache.h:41

References attnum, ATTNUM, elog, ERROR, HeapTupleIsValid, Int16GetDatum, NIL, ObjectIdGetDatum, options, ReleaseSysCache(), SearchSysCache2(), SysCacheGetAttr(), and untransformRelOptions().

Referenced by deparseAnalyzeSql(), deparseColumnRef(), and get_file_fdw_attribute_options().

◆ GetForeignDataWrapper()

◆ GetForeignDataWrapperByName()

ForeignDataWrapper* GetForeignDataWrapperByName ( const char *  fdwname,
bool  missing_ok 
)

Definition at line 94 of file foreign.c.

95 {
96  Oid fdwId = get_foreign_data_wrapper_oid(fdwname, missing_ok);
97 
98  if (!OidIsValid(fdwId))
99  return NULL;
100 
101  return GetForeignDataWrapper(fdwId);
102 }
ForeignDataWrapper * GetForeignDataWrapper(Oid fdwid)
Definition: foreign.c:35
Oid get_foreign_data_wrapper_oid(const char *fdwname, bool missing_ok)
Definition: foreign.c:693

References get_foreign_data_wrapper_oid(), GetForeignDataWrapper(), and OidIsValid.

Referenced by CreateForeignDataWrapper(), and CreateForeignServer().

◆ GetForeignDataWrapperExtended()

ForeignDataWrapper* GetForeignDataWrapperExtended ( Oid  fdwid,
bits16  flags 
)

Definition at line 47 of file foreign.c.

48 {
50  ForeignDataWrapper *fdw;
51  Datum datum;
52  HeapTuple tp;
53  bool isnull;
54 
56 
57  if (!HeapTupleIsValid(tp))
58  {
59  if ((flags & FDW_MISSING_OK) == 0)
60  elog(ERROR, "cache lookup failed for foreign-data wrapper %u", fdwid);
61  return NULL;
62  }
63 
65 
66  fdw = (ForeignDataWrapper *) palloc(sizeof(ForeignDataWrapper));
67  fdw->fdwid = fdwid;
68  fdw->owner = fdwform->fdwowner;
69  fdw->fdwname = pstrdup(NameStr(fdwform->fdwname));
70  fdw->fdwhandler = fdwform->fdwhandler;
71  fdw->fdwvalidator = fdwform->fdwvalidator;
72 
73  /* Extract the fdwoptions */
75  tp,
76  Anum_pg_foreign_data_wrapper_fdwoptions,
77  &isnull);
78  if (isnull)
79  fdw->options = NIL;
80  else
81  fdw->options = untransformRelOptions(datum);
82 
83  ReleaseSysCache(tp);
84 
85  return fdw;
86 }
#define FDW_MISSING_OK
Definition: foreign.h:64
char * pstrdup(const char *in)
Definition: mcxt.c:1299
char * fdwname
Definition: foreign.h:28
List * options
Definition: foreign.h:31

References elog, ERROR, FDW_MISSING_OK, ForeignDataWrapper::fdwhandler, ForeignDataWrapper::fdwid, ForeignDataWrapper::fdwname, ForeignDataWrapper::fdwvalidator, FOREIGNDATAWRAPPEROID, GETSTRUCT, HeapTupleIsValid, NameStr, NIL, ObjectIdGetDatum, ForeignDataWrapper::options, ForeignDataWrapper::owner, palloc(), pstrdup(), ReleaseSysCache(), SearchSysCache1(), SysCacheGetAttr(), and untransformRelOptions().

Referenced by GetForeignDataWrapper(), getObjectDescription(), and getObjectIdentityParts().

◆ GetForeignServer()

◆ GetForeignServerByName()

ForeignServer* GetForeignServerByName ( const char *  srvname,
bool  missing_ok 
)

Definition at line 180 of file foreign.c.

181 {
182  Oid serverid = get_foreign_server_oid(srvname, missing_ok);
183 
184  if (!OidIsValid(serverid))
185  return NULL;
186 
187  return GetForeignServer(serverid);
188 }
Oid get_foreign_server_oid(const char *servername, bool missing_ok)
Definition: foreign.c:716
ForeignServer * GetForeignServer(Oid serverid)
Definition: foreign.c:109

References get_foreign_server_oid(), GetForeignServer(), and OidIsValid.

Referenced by AlterUserMapping(), CreateForeignServer(), CreateForeignTable(), CreateUserMapping(), get_connect_string(), get_object_address_usermapping(), ImportForeignSchema(), postgres_fdw_disconnect(), and RemoveUserMapping().

◆ GetForeignServerExtended()

ForeignServer* GetForeignServerExtended ( Oid  serverid,
bits16  flags 
)

Definition at line 121 of file foreign.c.

122 {
123  Form_pg_foreign_server serverform;
124  ForeignServer *server;
125  HeapTuple tp;
126  Datum datum;
127  bool isnull;
128 
130 
131  if (!HeapTupleIsValid(tp))
132  {
133  if ((flags & FSV_MISSING_OK) == 0)
134  elog(ERROR, "cache lookup failed for foreign server %u", serverid);
135  return NULL;
136  }
137 
138  serverform = (Form_pg_foreign_server) GETSTRUCT(tp);
139 
140  server = (ForeignServer *) palloc(sizeof(ForeignServer));
141  server->serverid = serverid;
142  server->servername = pstrdup(NameStr(serverform->srvname));
143  server->owner = serverform->srvowner;
144  server->fdwid = serverform->srvfdw;
145 
146  /* Extract server type */
148  tp,
149  Anum_pg_foreign_server_srvtype,
150  &isnull);
151  server->servertype = isnull ? NULL : TextDatumGetCString(datum);
152 
153  /* Extract server version */
155  tp,
156  Anum_pg_foreign_server_srvversion,
157  &isnull);
158  server->serverversion = isnull ? NULL : TextDatumGetCString(datum);
159 
160  /* Extract the srvoptions */
162  tp,
163  Anum_pg_foreign_server_srvoptions,
164  &isnull);
165  if (isnull)
166  server->options = NIL;
167  else
168  server->options = untransformRelOptions(datum);
169 
170  ReleaseSysCache(tp);
171 
172  return server;
173 }
#define TextDatumGetCString(d)
Definition: builtins.h:86
#define FSV_MISSING_OK
Definition: foreign.h:61
List * options
Definition: foreign.h:42
char * serverversion
Definition: foreign.h:41
char * servername
Definition: foreign.h:39
Oid serverid
Definition: foreign.h:36
char * servertype
Definition: foreign.h:40

References elog, ERROR, ForeignServer::fdwid, FOREIGNSERVEROID, FSV_MISSING_OK, GETSTRUCT, HeapTupleIsValid, NameStr, NIL, ObjectIdGetDatum, ForeignServer::options, ForeignServer::owner, palloc(), pstrdup(), ReleaseSysCache(), SearchSysCache1(), ForeignServer::serverid, ForeignServer::servername, ForeignServer::servertype, ForeignServer::serverversion, SysCacheGetAttr(), TextDatumGetCString, and untransformRelOptions().

Referenced by disconnect_cached_connections(), GetForeignServer(), getObjectDescription(), getObjectIdentityParts(), and postgres_fdw_get_connections().

◆ GetForeignServerIdByRelId()

Oid GetForeignServerIdByRelId ( Oid  relid)

Definition at line 340 of file foreign.c.

341 {
342  HeapTuple tp;
343  Form_pg_foreign_table tableform;
344  Oid serverid;
345 
347  if (!HeapTupleIsValid(tp))
348  elog(ERROR, "cache lookup failed for foreign table %u", relid);
349  tableform = (Form_pg_foreign_table) GETSTRUCT(tp);
350  serverid = tableform->ftserver;
351  ReleaseSysCache(tp);
352 
353  return serverid;
354 }
FormData_pg_foreign_table * Form_pg_foreign_table
@ FOREIGNTABLEREL
Definition: syscache.h:65

References elog, ERROR, FOREIGNTABLEREL, GETSTRUCT, HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), and SearchSysCache1().

Referenced by ExecuteTruncateGuts(), get_relation_info(), GetFdwRoutineByRelId(), and truncate_check_rel().

◆ GetForeignTable()

ForeignTable* GetForeignTable ( Oid  relid)

Definition at line 248 of file foreign.c.

249 {
250  Form_pg_foreign_table tableform;
251  ForeignTable *ft;
252  HeapTuple tp;
253  Datum datum;
254  bool isnull;
255 
257  if (!HeapTupleIsValid(tp))
258  elog(ERROR, "cache lookup failed for foreign table %u", relid);
259  tableform = (Form_pg_foreign_table) GETSTRUCT(tp);
260 
261  ft = (ForeignTable *) palloc(sizeof(ForeignTable));
262  ft->relid = relid;
263  ft->serverid = tableform->ftserver;
264 
265  /* Extract the ftoptions */
267  tp,
268  Anum_pg_foreign_table_ftoptions,
269  &isnull);
270  if (isnull)
271  ft->options = NIL;
272  else
273  ft->options = untransformRelOptions(datum);
274 
275  ReleaseSysCache(tp);
276 
277  return ft;
278 }
Oid relid
Definition: foreign.h:55
List * options
Definition: foreign.h:57
Oid serverid
Definition: foreign.h:56

References elog, ERROR, FOREIGNTABLEREL, GETSTRUCT, HeapTupleIsValid, NIL, ObjectIdGetDatum, ForeignTable::options, palloc(), ReleaseSysCache(), ForeignTable::relid, SearchSysCache1(), ForeignTable::serverid, SysCacheGetAttr(), and untransformRelOptions().

Referenced by check_selective_binary_conversion(), create_foreign_modify(), deparseRelation(), fileGetOptions(), get_batch_size_option(), postgresAcquireSampleRowsFunc(), postgresAnalyzeForeignTable(), postgresBeginDirectModify(), postgresBeginForeignScan(), postgresExecForeignTruncate(), postgresGetForeignRelSize(), and postgresIsForeignRelUpdatable().

◆ GetUserMapping()

UserMapping* GetUserMapping ( Oid  userid,
Oid  serverid 
)

Definition at line 198 of file foreign.c.

199 {
200  Datum datum;
201  HeapTuple tp;
202  bool isnull;
203  UserMapping *um;
204 
205  tp = SearchSysCache2(USERMAPPINGUSERSERVER,
206  ObjectIdGetDatum(userid),
207  ObjectIdGetDatum(serverid));
208 
209  if (!HeapTupleIsValid(tp))
210  {
211  /* Not found for the specific user -- try PUBLIC */
212  tp = SearchSysCache2(USERMAPPINGUSERSERVER,
214  ObjectIdGetDatum(serverid));
215  }
216 
217  if (!HeapTupleIsValid(tp))
218  ereport(ERROR,
219  (errcode(ERRCODE_UNDEFINED_OBJECT),
220  errmsg("user mapping not found for \"%s\"",
221  MappingUserName(userid))));
222 
223  um = (UserMapping *) palloc(sizeof(UserMapping));
224  um->umid = ((Form_pg_user_mapping) GETSTRUCT(tp))->oid;
225  um->userid = userid;
226  um->serverid = serverid;
227 
228  /* Extract the umoptions */
229  datum = SysCacheGetAttr(USERMAPPINGUSERSERVER,
230  tp,
231  Anum_pg_user_mapping_umoptions,
232  &isnull);
233  if (isnull)
234  um->options = NIL;
235  else
236  um->options = untransformRelOptions(datum);
237 
238  ReleaseSysCache(tp);
239 
240  return um;
241 }
#define MappingUserName(userid)
Definition: foreign.h:20
FormData_pg_user_mapping * Form_pg_user_mapping
#define InvalidOid
Definition: postgres_ext.h:36
Oid userid
Definition: foreign.h:48
Oid umid
Definition: foreign.h:47
Oid serverid
Definition: foreign.h:49
List * options
Definition: foreign.h:50

References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, InvalidOid, MappingUserName, NIL, ObjectIdGetDatum, UserMapping::options, palloc(), ReleaseSysCache(), SearchSysCache2(), UserMapping::serverid, SysCacheGetAttr(), UserMapping::umid, untransformRelOptions(), and UserMapping::userid.

Referenced by create_foreign_modify(), get_connect_string(), postgresAcquireSampleRowsFunc(), postgresAnalyzeForeignTable(), postgresBeginDirectModify(), postgresBeginForeignScan(), postgresExecForeignTruncate(), postgresGetForeignRelSize(), and postgresImportForeignSchema().

◆ is_conninfo_option()

static bool is_conninfo_option ( const char *  option,
Oid  context 
)
static

Definition at line 620 of file foreign.c.

621 {
622  const struct ConnectionOption *opt;
623 
624  for (opt = libpq_conninfo_options; opt->optname; opt++)
625  if (context == opt->optcontext && strcmp(opt->optname, option) == 0)
626  return true;
627  return false;
628 }
static const struct ConnectionOption libpq_conninfo_options[]
Definition: foreign.c:595
const char * optname
Definition: foreign.c:586

References libpq_conninfo_options, ConnectionOption::optcontext, and ConnectionOption::optname.

Referenced by postgresql_fdw_validator().

◆ IsImportableForeignTable()

bool IsImportableForeignTable ( const char *  tablename,
ImportForeignSchemaStmt stmt 
)

Definition at line 467 of file foreign.c.

469 {
470  ListCell *lc;
471 
472  switch (stmt->list_type)
473  {
475  return true;
476 
478  foreach(lc, stmt->table_list)
479  {
480  RangeVar *rv = (RangeVar *) lfirst(lc);
481 
482  if (strcmp(tablename, rv->relname) == 0)
483  return true;
484  }
485  return false;
486 
488  foreach(lc, stmt->table_list)
489  {
490  RangeVar *rv = (RangeVar *) lfirst(lc);
491 
492  if (strcmp(tablename, rv->relname) == 0)
493  return false;
494  }
495  return true;
496  }
497  return false; /* shouldn't get here */
498 }
@ FDW_IMPORT_SCHEMA_LIMIT_TO
Definition: parsenodes.h:2479
@ FDW_IMPORT_SCHEMA_ALL
Definition: parsenodes.h:2478
@ FDW_IMPORT_SCHEMA_EXCEPT
Definition: parsenodes.h:2480
ImportForeignSchemaType list_type
Definition: parsenodes.h:2489
char * relname
Definition: primnodes.h:68

References FDW_IMPORT_SCHEMA_ALL, FDW_IMPORT_SCHEMA_EXCEPT, FDW_IMPORT_SCHEMA_LIMIT_TO, lfirst, ImportForeignSchemaStmt::list_type, RangeVar::relname, and ImportForeignSchemaStmt::table_list.

Referenced by ImportForeignSchema().

◆ pg_options_to_table()

Datum pg_options_to_table ( PG_FUNCTION_ARGS  )

Definition at line 570 of file foreign.c.

571 {
572  Datum array = PG_GETARG_DATUM(0);
573 
574  deflist_to_tuplestore((ReturnSetInfo *) fcinfo->resultinfo,
575  untransformRelOptions(array));
576 
577  return (Datum) 0;
578 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
static void deflist_to_tuplestore(ReturnSetInfo *rsinfo, List *options)
Definition: foreign.c:506

◆ postgresql_fdw_validator()

Datum postgresql_fdw_validator ( PG_FUNCTION_ARGS  )

Definition at line 644 of file foreign.c.

645 {
646  List *options_list = untransformRelOptions(PG_GETARG_DATUM(0));
647  Oid catalog = PG_GETARG_OID(1);
648 
649  ListCell *cell;
650 
651  foreach(cell, options_list)
652  {
653  DefElem *def = lfirst(cell);
654 
655  if (!is_conninfo_option(def->defname, catalog))
656  {
657  const struct ConnectionOption *opt;
659 
660  /*
661  * Unknown option specified, complain about it. Provide a hint
662  * with list of valid options for the object.
663  */
665  for (opt = libpq_conninfo_options; opt->optname; opt++)
666  if (catalog == opt->optcontext)
667  appendStringInfo(&buf, "%s%s", (buf.len > 0) ? ", " : "",
668  opt->optname);
669 
670  ereport(ERROR,
671  (errcode(ERRCODE_SYNTAX_ERROR),
672  errmsg("invalid option \"%s\"", def->defname),
673  buf.len > 0
674  ? errhint("Valid options in this context are: %s",
675  buf.data)
676  : errhint("There are no valid options in this context.")));
677 
678  PG_RETURN_BOOL(false);
679  }
680  }
681 
682  PG_RETURN_BOOL(true);
683 }
int errhint(const char *fmt,...)
Definition: elog.c:1151
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static bool is_conninfo_option(const char *option, Oid context)
Definition: foreign.c:620
static char * buf
Definition: pg_test_fsync.c:70
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59

References appendStringInfo(), buf, DefElem::defname, ereport, errcode(), errhint(), errmsg(), ERROR, initStringInfo(), is_conninfo_option(), lfirst, libpq_conninfo_options, ConnectionOption::optcontext, ConnectionOption::optname, PG_GETARG_DATUM, PG_GETARG_OID, PG_RETURN_BOOL, and untransformRelOptions().

Variable Documentation

◆ libpq_conninfo_options

const struct ConnectionOption libpq_conninfo_options[]
static
Initial value:
= {
{"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}
}

Definition at line 570 of file foreign.c.

Referenced by is_conninfo_option(), and postgresql_fdw_validator().