PostgreSQL Source Code  git master
foreign.c File Reference
#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 "funcapi.h"
#include "lib/stringinfo.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/syscache.h"
#include "utils/varlena.h"
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)
 
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

◆ get_foreign_data_wrapper_oid()

Oid get_foreign_data_wrapper_oid ( const char *  fdwname,
bool  missing_ok 
)

Definition at line 667 of file foreign.c.

668 {
669  Oid oid;
670 
672  Anum_pg_foreign_data_wrapper_oid,
673  CStringGetDatum(fdwname));
674  if (!OidIsValid(oid) && !missing_ok)
675  ereport(ERROR,
676  (errcode(ERRCODE_UNDEFINED_OBJECT),
677  errmsg("foreign-data wrapper \"%s\" does not exist",
678  fdwname)));
679  return oid;
680 }
#define OidIsValid(objectId)
Definition: c.h:711
int errcode(int sqlerrcode)
Definition: elog.c:735
int errmsg(const char *fmt,...)
Definition: elog.c:946
#define ERROR
Definition: elog.h:35
#define ereport(elevel,...)
Definition: elog.h:145
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:698
unsigned int Oid
Definition: postgres_ext.h:31
@ FOREIGNDATAWRAPPERNAME
Definition: syscache.h:61
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:197

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 690 of file foreign.c.

691 {
692  Oid oid;
693 
694  oid = GetSysCacheOid1(FOREIGNSERVERNAME, Anum_pg_foreign_server_oid,
695  CStringGetDatum(servername));
696  if (!OidIsValid(oid) && !missing_ok)
697  ereport(ERROR,
698  (errcode(ERRCODE_UNDEFINED_OBJECT),
699  errmsg("server \"%s\" does not exist", servername)));
700  return oid;
701 }
@ FOREIGNSERVERNAME
Definition: syscache.h:63

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

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

◆ GetExistingLocalJoinPath()

Path* GetExistingLocalJoinPath ( RelOptInfo joinrel)

Definition at line 727 of file foreign.c.

728 {
729  ListCell *lc;
730 
731  Assert(IS_JOIN_REL(joinrel));
732 
733  foreach(lc, joinrel->pathlist)
734  {
735  Path *path = (Path *) lfirst(lc);
736  JoinPath *joinpath = NULL;
737 
738  /* Skip parameterized paths. */
739  if (path->param_info != NULL)
740  continue;
741 
742  switch (path->pathtype)
743  {
744  case T_HashJoin:
745  {
746  HashPath *hash_path = makeNode(HashPath);
747 
748  memcpy(hash_path, path, sizeof(HashPath));
749  joinpath = (JoinPath *) hash_path;
750  }
751  break;
752 
753  case T_NestLoop:
754  {
755  NestPath *nest_path = makeNode(NestPath);
756 
757  memcpy(nest_path, path, sizeof(NestPath));
758  joinpath = (JoinPath *) nest_path;
759  }
760  break;
761 
762  case T_MergeJoin:
763  {
764  MergePath *merge_path = makeNode(MergePath);
765 
766  memcpy(merge_path, path, sizeof(MergePath));
767  joinpath = (JoinPath *) merge_path;
768  }
769  break;
770 
771  default:
772 
773  /*
774  * Just skip anything else. We don't know if corresponding
775  * plan would build the output row from whole-row references
776  * of base relations and execute the EPQ checks.
777  */
778  break;
779  }
780 
781  /* This path isn't good for us, check next. */
782  if (!joinpath)
783  continue;
784 
785  /*
786  * If either inner or outer path is a ForeignPath corresponding to a
787  * pushed down join, replace it with the fdw_outerpath, so that we
788  * maintain path for EPQ checks built entirely of local join
789  * strategies.
790  */
791  if (IsA(joinpath->outerjoinpath, ForeignPath))
792  {
793  ForeignPath *foreign_path;
794 
795  foreign_path = (ForeignPath *) joinpath->outerjoinpath;
796  if (IS_JOIN_REL(foreign_path->path.parent))
797  joinpath->outerjoinpath = foreign_path->fdw_outerpath;
798  }
799 
800  if (IsA(joinpath->innerjoinpath, ForeignPath))
801  {
802  ForeignPath *foreign_path;
803 
804  foreign_path = (ForeignPath *) joinpath->innerjoinpath;
805  if (IS_JOIN_REL(foreign_path->path.parent))
806  joinpath->innerjoinpath = foreign_path->fdw_outerpath;
807  }
808 
809  return (Path *) joinpath;
810  }
811  return NULL;
812 }
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
Assert(fmt[strlen(fmt) - 1] !='\n')
#define IsA(nodeptr, _type_)
Definition: nodes.h:168
#define makeNode(_type_)
Definition: nodes.h:165
#define IS_JOIN_REL(rel)
Definition: pathnodes.h:797
#define lfirst(lc)
Definition: pg_list.h:170
Path * fdw_outerpath
Definition: pathnodes.h:1756
Path * outerjoinpath
Definition: pathnodes.h:1951
Path * innerjoinpath
Definition: pathnodes.h:1952
NodeTag pathtype
Definition: pathnodes.h:1513
List * pathlist
Definition: pathnodes.h:851

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

Referenced by postgresGetForeignJoinPaths().

◆ GetFdwRoutine()

FdwRoutine* GetFdwRoutine ( Oid  fdwhandler)

Definition at line 321 of file foreign.c.

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

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

Referenced by GetFdwRoutineByServerId(), and ImportForeignSchema().

◆ GetFdwRoutineByRelId()

FdwRoutine* GetFdwRoutineByRelId ( Oid  relid)

Definition at line 406 of file foreign.c.

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

References GetFdwRoutineByServerId(), and GetForeignServerIdByRelId().

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

◆ GetFdwRoutineByServerId()

FdwRoutine* GetFdwRoutineByServerId ( Oid  serverid)

Definition at line 364 of file foreign.c.

365 {
366  HeapTuple tp;
368  Form_pg_foreign_server serverform;
369  Oid fdwid;
370  Oid fdwhandler;
371 
372  /* Get foreign-data wrapper OID for the server. */
374  if (!HeapTupleIsValid(tp))
375  elog(ERROR, "cache lookup failed for foreign server %u", serverid);
376  serverform = (Form_pg_foreign_server) GETSTRUCT(tp);
377  fdwid = serverform->srvfdw;
378  ReleaseSysCache(tp);
379 
380  /* Get handler function OID for the FDW. */
382  if (!HeapTupleIsValid(tp))
383  elog(ERROR, "cache lookup failed for foreign-data wrapper %u", fdwid);
384  fdwform = (Form_pg_foreign_data_wrapper) GETSTRUCT(tp);
385  fdwhandler = fdwform->fdwhandler;
386 
387  /* Complain if FDW has been set to NO HANDLER. */
388  if (!OidIsValid(fdwhandler))
389  ereport(ERROR,
390  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
391  errmsg("foreign-data wrapper \"%s\" has no handler",
392  NameStr(fdwform->fdwname))));
393 
394  ReleaseSysCache(tp);
395 
396  /* And finally, call the handler function. */
397  return GetFdwRoutine(fdwhandler);
398 }
#define NameStr(name)
Definition: c.h:682
FdwRoutine * GetFdwRoutine(Oid fdwhandler)
Definition: foreign.c:321
#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
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:600
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1221
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1173
@ 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 429 of file foreign.c.

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

289 {
290  List *options;
291  HeapTuple tp;
292  Datum datum;
293  bool isnull;
294 
295  tp = SearchSysCache2(ATTNUM,
296  ObjectIdGetDatum(relid),
298  if (!HeapTupleIsValid(tp))
299  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
300  attnum, relid);
301  datum = SysCacheGetAttr(ATTNUM,
302  tp,
303  Anum_pg_attribute_attfdwoptions,
304  &isnull);
305  if (isnull)
306  options = NIL;
307  else
309 
310  ReleaseSysCache(tp);
311 
312  return options;
313 }
int16 attnum
Definition: pg_attribute.h:83
#define NIL
Definition: pg_list.h:66
static char ** options
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:520
List * untransformRelOptions(Datum options)
Definition: reloptions.c:1333
Definition: pg_list.h:52
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1434
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1184
@ 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 96 of file foreign.c.

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

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

Referenced by CreateForeignDataWrapper(), and CreateForeignServer().

◆ GetForeignDataWrapperExtended()

ForeignDataWrapper* GetForeignDataWrapperExtended ( Oid  fdwid,
bits16  flags 
)

Definition at line 49 of file foreign.c.

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

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

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

Referenced by AlterUserMapping(), 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 123 of file foreign.c.

124 {
125  Form_pg_foreign_server serverform;
126  ForeignServer *server;
127  HeapTuple tp;
128  Datum datum;
129  bool isnull;
130 
132 
133  if (!HeapTupleIsValid(tp))
134  {
135  if ((flags & FSV_MISSING_OK) == 0)
136  elog(ERROR, "cache lookup failed for foreign server %u", serverid);
137  return NULL;
138  }
139 
140  serverform = (Form_pg_foreign_server) GETSTRUCT(tp);
141 
142  server = (ForeignServer *) palloc(sizeof(ForeignServer));
143  server->serverid = serverid;
144  server->servername = pstrdup(NameStr(serverform->srvname));
145  server->owner = serverform->srvowner;
146  server->fdwid = serverform->srvfdw;
147 
148  /* Extract server type */
150  tp,
151  Anum_pg_foreign_server_srvtype,
152  &isnull);
153  server->servertype = isnull ? NULL : TextDatumGetCString(datum);
154 
155  /* Extract server version */
157  tp,
158  Anum_pg_foreign_server_srvversion,
159  &isnull);
160  server->serverversion = isnull ? NULL : TextDatumGetCString(datum);
161 
162  /* Extract the srvoptions */
164  tp,
165  Anum_pg_foreign_server_srvoptions,
166  &isnull);
167  if (isnull)
168  server->options = NIL;
169  else
170  server->options = untransformRelOptions(datum);
171 
172  ReleaseSysCache(tp);
173 
174  return server;
175 }
#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 342 of file foreign.c.

343 {
344  HeapTuple tp;
345  Form_pg_foreign_table tableform;
346  Oid serverid;
347 
349  if (!HeapTupleIsValid(tp))
350  elog(ERROR, "cache lookup failed for foreign table %u", relid);
351  tableform = (Form_pg_foreign_table) GETSTRUCT(tp);
352  serverid = tableform->ftserver;
353  ReleaseSysCache(tp);
354 
355  return serverid;
356 }
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 250 of file foreign.c.

251 {
252  Form_pg_foreign_table tableform;
253  ForeignTable *ft;
254  HeapTuple tp;
255  Datum datum;
256  bool isnull;
257 
259  if (!HeapTupleIsValid(tp))
260  elog(ERROR, "cache lookup failed for foreign table %u", relid);
261  tableform = (Form_pg_foreign_table) GETSTRUCT(tp);
262 
263  ft = (ForeignTable *) palloc(sizeof(ForeignTable));
264  ft->relid = relid;
265  ft->serverid = tableform->ftserver;
266 
267  /* Extract the ftoptions */
269  tp,
270  Anum_pg_foreign_table_ftoptions,
271  &isnull);
272  if (isnull)
273  ft->options = NIL;
274  else
275  ft->options = untransformRelOptions(datum);
276 
277  ReleaseSysCache(tp);
278 
279  return ft;
280 }
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 200 of file foreign.c.

201 {
202  Datum datum;
203  HeapTuple tp;
204  bool isnull;
205  UserMapping *um;
206 
207  tp = SearchSysCache2(USERMAPPINGUSERSERVER,
208  ObjectIdGetDatum(userid),
209  ObjectIdGetDatum(serverid));
210 
211  if (!HeapTupleIsValid(tp))
212  {
213  /* Not found for the specific user -- try PUBLIC */
214  tp = SearchSysCache2(USERMAPPINGUSERSERVER,
216  ObjectIdGetDatum(serverid));
217  }
218 
219  if (!HeapTupleIsValid(tp))
220  ereport(ERROR,
221  (errcode(ERRCODE_UNDEFINED_OBJECT),
222  errmsg("user mapping not found for \"%s\"",
223  MappingUserName(userid))));
224 
225  um = (UserMapping *) palloc(sizeof(UserMapping));
226  um->umid = ((Form_pg_user_mapping) GETSTRUCT(tp))->oid;
227  um->userid = userid;
228  um->serverid = serverid;
229 
230  /* Extract the umoptions */
231  datum = SysCacheGetAttr(USERMAPPINGUSERSERVER,
232  tp,
233  Anum_pg_user_mapping_umoptions,
234  &isnull);
235  if (isnull)
236  um->options = NIL;
237  else
238  um->options = untransformRelOptions(datum);
239 
240  ReleaseSysCache(tp);
241 
242  return um;
243 }
#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 587 of file foreign.c.

588 {
589  const struct ConnectionOption *opt;
590 
591  for (opt = libpq_conninfo_options; opt->optname; opt++)
592  if (context == opt->optcontext && strcmp(opt->optname, option) == 0)
593  return true;
594  return false;
595 }
static const struct ConnectionOption libpq_conninfo_options[]
Definition: foreign.c:562
const char * optname
Definition: foreign.c:553

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 469 of file foreign.c.

471 {
472  ListCell *lc;
473 
474  switch (stmt->list_type)
475  {
477  return true;
478 
480  foreach(lc, stmt->table_list)
481  {
482  RangeVar *rv = (RangeVar *) lfirst(lc);
483 
484  if (strcmp(tablename, rv->relname) == 0)
485  return true;
486  }
487  return false;
488 
490  foreach(lc, stmt->table_list)
491  {
492  RangeVar *rv = (RangeVar *) lfirst(lc);
493 
494  if (strcmp(tablename, rv->relname) == 0)
495  return false;
496  }
497  return true;
498  }
499  return false; /* shouldn't get here */
500 }
@ FDW_IMPORT_SCHEMA_LIMIT_TO
Definition: parsenodes.h:2583
@ FDW_IMPORT_SCHEMA_ALL
Definition: parsenodes.h:2582
@ FDW_IMPORT_SCHEMA_EXCEPT
Definition: parsenodes.h:2584
ImportForeignSchemaType list_type
Definition: parsenodes.h:2593
char * relname
Definition: primnodes.h:77

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 509 of file foreign.c.

510 {
511  Datum array = PG_GETARG_DATUM(0);
512  ListCell *cell;
513  List *options;
514  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
515 
517  rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
518 
519  /* prepare the result set */
521 
522  foreach(cell, options)
523  {
524  DefElem *def = lfirst(cell);
525  Datum values[2];
526  bool nulls[2];
527 
529  nulls[0] = false;
530  if (def->arg)
531  {
532  values[1] = CStringGetTextDatum(strVal(def->arg));
533  nulls[1] = false;
534  }
535  else
536  {
537  values[1] = (Datum) 0;
538  nulls[1] = true;
539  }
540  tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
541  values, nulls);
542  }
543 
544  return (Datum) 0;
545 }
static Datum values[MAXATTR]
Definition: bootstrap.c:156
#define CStringGetTextDatum(s)
Definition: builtins.h:85
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
Definition: funcapi.c:76
#define MAT_SRF_USE_EXPECTED_DESC
Definition: funcapi.h:295
char * defname
Definition: parsenodes.h:779
Node * arg
Definition: parsenodes.h:780
TupleDesc setDesc
Definition: execnodes.h:332
Tuplestorestate * setResult
Definition: execnodes.h:331
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, Datum *values, bool *isnull)
Definition: tuplestore.c:750
#define strVal(v)
Definition: value.h:82

◆ postgresql_fdw_validator()

Datum postgresql_fdw_validator ( PG_FUNCTION_ARGS  )

Definition at line 611 of file foreign.c.

612 {
613  List *options_list = untransformRelOptions(PG_GETARG_DATUM(0));
614  Oid catalog = PG_GETARG_OID(1);
615 
616  ListCell *cell;
617 
618  foreach(cell, options_list)
619  {
620  DefElem *def = lfirst(cell);
621 
622  if (!is_conninfo_option(def->defname, catalog))
623  {
624  const struct ConnectionOption *opt;
625  const char *closest_match;
626  ClosestMatchState match_state;
627  bool has_valid_options = false;
628 
629  /*
630  * Unknown option specified, complain about it. Provide a hint
631  * with a valid option that looks similar, if there is one.
632  */
633  initClosestMatch(&match_state, def->defname, 4);
634  for (opt = libpq_conninfo_options; opt->optname; opt++)
635  {
636  if (catalog == opt->optcontext)
637  {
638  has_valid_options = true;
639  updateClosestMatch(&match_state, opt->optname);
640  }
641  }
642 
643  closest_match = getClosestMatch(&match_state);
644  ereport(ERROR,
645  (errcode(ERRCODE_SYNTAX_ERROR),
646  errmsg("invalid option \"%s\"", def->defname),
647  has_valid_options ? closest_match ?
648  errhint("Perhaps you meant the option \"%s\".",
649  closest_match) : 0 :
650  errhint("There are no valid options in this context.")));
651 
652  PG_RETURN_BOOL(false);
653  }
654  }
655 
656  PG_RETURN_BOOL(true);
657 }
int errhint(const char *fmt,...)
Definition: elog.c:1193
#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:587
const char * getClosestMatch(ClosestMatchState *state)
Definition: varlena.c:6274
void initClosestMatch(ClosestMatchState *state, const char *source, int max_d)
Definition: varlena.c:6219
void updateClosestMatch(ClosestMatchState *state, const char *candidate)
Definition: varlena.c:6239

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

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 509 of file foreign.c.

Referenced by is_conninfo_option(), and postgresql_fdw_validator().