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

672 {
673  Oid oid;
674 
675  oid = GetSysCacheOid1(FOREIGNDATAWRAPPERNAME,
676  Anum_pg_foreign_data_wrapper_oid,
677  CStringGetDatum(fdwname));
678  if (!OidIsValid(oid) && !missing_ok)
679  ereport(ERROR,
680  (errcode(ERRCODE_UNDEFINED_OBJECT),
681  errmsg("foreign-data wrapper \"%s\" does not exist",
682  fdwname)));
683  return oid;
684 }
#define OidIsValid(objectId)
Definition: c.h:775
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
unsigned int Oid
Definition: postgres_ext.h:31
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:104

References CStringGetDatum(), ereport, errcode(), errmsg(), ERROR, 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 694 of file foreign.c.

695 {
696  Oid oid;
697 
698  oid = GetSysCacheOid1(FOREIGNSERVERNAME, Anum_pg_foreign_server_oid,
699  CStringGetDatum(servername));
700  if (!OidIsValid(oid) && !missing_ok)
701  ereport(ERROR,
702  (errcode(ERRCODE_UNDEFINED_OBJECT),
703  errmsg("server \"%s\" does not exist", servername)));
704  return oid;
705 }

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

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

◆ GetExistingLocalJoinPath()

Path* GetExistingLocalJoinPath ( RelOptInfo joinrel)

Definition at line 731 of file foreign.c.

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

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

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

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

Referenced by GetFdwRoutineByServerId(), and ImportForeignSchema().

◆ GetFdwRoutineByRelId()

FdwRoutine* GetFdwRoutineByRelId ( Oid  relid)

Definition at line 409 of file foreign.c.

410 {
411  Oid serverid;
412 
413  /* Get server OID for the foreign table. */
414  serverid = GetForeignServerIdByRelId(relid);
415 
416  /* Now retrieve server's FdwRoutine struct. */
417  return GetFdwRoutineByServerId(serverid);
418 }
Oid GetForeignServerIdByRelId(Oid relid)
Definition: foreign.c:345
FdwRoutine * GetFdwRoutineByServerId(Oid serverid)
Definition: foreign.c:367

References GetFdwRoutineByServerId(), and GetForeignServerIdByRelId().

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

◆ GetFdwRoutineByServerId()

FdwRoutine* GetFdwRoutineByServerId ( Oid  serverid)

Definition at line 367 of file foreign.c.

368 {
369  HeapTuple tp;
371  Form_pg_foreign_server serverform;
372  Oid fdwid;
373  Oid fdwhandler;
374 
375  /* Get foreign-data wrapper OID for the server. */
376  tp = SearchSysCache1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid));
377  if (!HeapTupleIsValid(tp))
378  elog(ERROR, "cache lookup failed for foreign server %u", serverid);
379  serverform = (Form_pg_foreign_server) GETSTRUCT(tp);
380  fdwid = serverform->srvfdw;
381  ReleaseSysCache(tp);
382 
383  /* Get handler function OID for the FDW. */
384  tp = SearchSysCache1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid));
385  if (!HeapTupleIsValid(tp))
386  elog(ERROR, "cache lookup failed for foreign-data wrapper %u", fdwid);
387  fdwform = (Form_pg_foreign_data_wrapper) GETSTRUCT(tp);
388  fdwhandler = fdwform->fdwhandler;
389 
390  /* Complain if FDW has been set to NO HANDLER. */
391  if (!OidIsValid(fdwhandler))
392  ereport(ERROR,
393  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
394  errmsg("foreign-data wrapper \"%s\" has no handler",
395  NameStr(fdwform->fdwname))));
396 
397  ReleaseSysCache(tp);
398 
399  /* And finally, call the handler function. */
400  return GetFdwRoutine(fdwhandler);
401 }
#define NameStr(name)
Definition: c.h:746
FdwRoutine * GetFdwRoutine(Oid fdwhandler)
Definition: foreign.c:324
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
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:252
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:266
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:218

References elog, ereport, errcode(), errmsg(), ERROR, 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 432 of file foreign.c.

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

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

292 {
293  List *options;
294  HeapTuple tp;
295  Datum datum;
296  bool isnull;
297 
298  tp = SearchSysCache2(ATTNUM,
299  ObjectIdGetDatum(relid),
301  if (!HeapTupleIsValid(tp))
302  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
303  attnum, relid);
304  datum = SysCacheGetAttr(ATTNUM,
305  tp,
306  Anum_pg_attribute_attfdwoptions,
307  &isnull);
308  if (isnull)
309  options = NIL;
310  else
312 
313  ReleaseSysCache(tp);
314 
315  return options;
316 }
int16 attnum
Definition: pg_attribute.h:74
#define NIL
Definition: pg_list.h:68
static char ** options
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:172
List * untransformRelOptions(Datum options)
Definition: reloptions.c:1331
Definition: pg_list.h:54
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:479
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:229

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

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

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

Referenced by CreateForeignDataWrapper(), and CreateForeignServer().

◆ GetForeignDataWrapperExtended()

ForeignDataWrapper* GetForeignDataWrapperExtended ( Oid  fdwid,
bits16  flags 
)

Definition at line 48 of file foreign.c.

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

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

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

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

346 {
347  HeapTuple tp;
348  Form_pg_foreign_table tableform;
349  Oid serverid;
350 
351  tp = SearchSysCache1(FOREIGNTABLEREL, ObjectIdGetDatum(relid));
352  if (!HeapTupleIsValid(tp))
353  elog(ERROR, "cache lookup failed for foreign table %u", relid);
354  tableform = (Form_pg_foreign_table) GETSTRUCT(tp);
355  serverid = tableform->ftserver;
356  ReleaseSysCache(tp);
357 
358  return serverid;
359 }
FormData_pg_foreign_table * Form_pg_foreign_table

References elog, ERROR, 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 253 of file foreign.c.

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

References elog, ERROR, 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(), postgresGetAnalyzeInfoForForeignTable(), postgresGetForeignRelSize(), and postgresIsForeignRelUpdatable().

◆ GetUserMapping()

UserMapping* GetUserMapping ( Oid  userid,
Oid  serverid 
)

Definition at line 199 of file foreign.c.

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

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

◆ is_conninfo_option()

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

Definition at line 591 of file foreign.c.

592 {
593  const struct ConnectionOption *opt;
594 
595  for (opt = libpq_conninfo_options; opt->optname; opt++)
596  if (context == opt->optcontext && strcmp(opt->optname, option) == 0)
597  return true;
598  return false;
599 }
static const struct ConnectionOption libpq_conninfo_options[]
Definition: foreign.c:565
tree context
Definition: radixtree.h:1829
const char * optname
Definition: foreign.c:556

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

Referenced by postgresql_fdw_validator().

◆ IsImportableForeignTable()

bool IsImportableForeignTable ( const char *  tablename,
ImportForeignSchemaStmt stmt 
)

Definition at line 472 of file foreign.c.

474 {
475  ListCell *lc;
476 
477  switch (stmt->list_type)
478  {
480  return true;
481 
483  foreach(lc, stmt->table_list)
484  {
485  RangeVar *rv = (RangeVar *) lfirst(lc);
486 
487  if (strcmp(tablename, rv->relname) == 0)
488  return true;
489  }
490  return false;
491 
493  foreach(lc, stmt->table_list)
494  {
495  RangeVar *rv = (RangeVar *) lfirst(lc);
496 
497  if (strcmp(tablename, rv->relname) == 0)
498  return false;
499  }
500  return true;
501  }
502  return false; /* shouldn't get here */
503 }
#define stmt
Definition: indent_codes.h:59
@ FDW_IMPORT_SCHEMA_LIMIT_TO
Definition: parsenodes.h:2951
@ FDW_IMPORT_SCHEMA_ALL
Definition: parsenodes.h:2950
@ FDW_IMPORT_SCHEMA_EXCEPT
Definition: parsenodes.h:2952
char * relname
Definition: primnodes.h:82

References FDW_IMPORT_SCHEMA_ALL, FDW_IMPORT_SCHEMA_EXCEPT, FDW_IMPORT_SCHEMA_LIMIT_TO, lfirst, RangeVar::relname, and stmt.

Referenced by ImportForeignSchema().

◆ pg_options_to_table()

Datum pg_options_to_table ( PG_FUNCTION_ARGS  )

Definition at line 512 of file foreign.c.

513 {
514  Datum array = PG_GETARG_DATUM(0);
515  ListCell *cell;
516  List *options;
517  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
518 
520  rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
521 
522  /* prepare the result set */
524 
525  foreach(cell, options)
526  {
527  DefElem *def = lfirst(cell);
528  Datum values[2];
529  bool nulls[2];
530 
532  nulls[0] = false;
533  if (def->arg)
534  {
535  values[1] = CStringGetTextDatum(strVal(def->arg));
536  nulls[1] = false;
537  }
538  else
539  {
540  values[1] = (Datum) 0;
541  nulls[1] = true;
542  }
543  tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
544  values, nulls);
545  }
546 
547  return (Datum) 0;
548 }
static Datum values[MAXATTR]
Definition: bootstrap.c:152
#define CStringGetTextDatum(s)
Definition: builtins.h:97
#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:296
char * defname
Definition: parsenodes.h:815
Node * arg
Definition: parsenodes.h:816
TupleDesc setDesc
Definition: execnodes.h:340
Tuplestorestate * setResult
Definition: execnodes.h:339
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const 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 615 of file foreign.c.

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

References DefElem::defname, ereport, errcode(), errhint(), errmsg(), ERROR, getClosestMatch(), initClosestMatch(), is_conninfo_option(), lfirst, libpq_conninfo_options, match_state, 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},
{"gssdelegation", ForeignServerRelationId},
{NULL, InvalidOid}
}

Definition at line 512 of file foreign.c.

Referenced by is_conninfo_option(), and postgresql_fdw_validator().