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 "optimizer/paths.h"
#include "tcop/tcopprot.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 682 of file foreign.c.

683{
684 Oid oid;
685
686 oid = GetSysCacheOid1(FOREIGNDATAWRAPPERNAME,
687 Anum_pg_foreign_data_wrapper_oid,
688 CStringGetDatum(fdwname));
689 if (!OidIsValid(oid) && !missing_ok)
691 (errcode(ERRCODE_UNDEFINED_OBJECT),
692 errmsg("foreign-data wrapper \"%s\" does not exist",
693 fdwname)));
694 return oid;
695}
#define OidIsValid(objectId)
Definition: c.h:746
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:355
unsigned int Oid
Definition: postgres_ext.h:30
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:109

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

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

◆ get_foreign_server_oid()

Oid get_foreign_server_oid ( const char *  servername,
bool  missing_ok 
)

Definition at line 705 of file foreign.c.

706{
707 Oid oid;
708
709 oid = GetSysCacheOid1(FOREIGNSERVERNAME, Anum_pg_foreign_server_oid,
710 CStringGetDatum(servername));
711 if (!OidIsValid(oid) && !missing_ok)
713 (errcode(ERRCODE_UNDEFINED_OBJECT),
714 errmsg("server \"%s\" does not exist", servername)));
715 return oid;
716}

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

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

◆ GetExistingLocalJoinPath()

Path * GetExistingLocalJoinPath ( RelOptInfo joinrel)

Definition at line 742 of file foreign.c.

743{
744 ListCell *lc;
745
746 Assert(IS_JOIN_REL(joinrel));
747
748 foreach(lc, joinrel->pathlist)
749 {
750 Path *path = (Path *) lfirst(lc);
751 JoinPath *joinpath = NULL;
752
753 /* Skip parameterized paths. */
754 if (path->param_info != NULL)
755 continue;
756
757 switch (path->pathtype)
758 {
759 case T_HashJoin:
760 {
761 HashPath *hash_path = makeNode(HashPath);
762
763 memcpy(hash_path, path, sizeof(HashPath));
764 joinpath = (JoinPath *) hash_path;
765 }
766 break;
767
768 case T_NestLoop:
769 {
770 NestPath *nest_path = makeNode(NestPath);
771
772 memcpy(nest_path, path, sizeof(NestPath));
773 joinpath = (JoinPath *) nest_path;
774 }
775 break;
776
777 case T_MergeJoin:
778 {
779 MergePath *merge_path = makeNode(MergePath);
780
781 memcpy(merge_path, path, sizeof(MergePath));
782 joinpath = (JoinPath *) merge_path;
783 }
784 break;
785
786 default:
787
788 /*
789 * Just skip anything else. We don't know if corresponding
790 * plan would build the output row from whole-row references
791 * of base relations and execute the EPQ checks.
792 */
793 break;
794 }
795
796 /* This path isn't good for us, check next. */
797 if (!joinpath)
798 continue;
799
800 /*
801 * If either inner or outer path is a ForeignPath corresponding to a
802 * pushed down join, replace it with the fdw_outerpath, so that we
803 * maintain path for EPQ checks built entirely of local join
804 * strategies.
805 */
806 if (IsA(joinpath->outerjoinpath, ForeignPath))
807 {
808 ForeignPath *foreign_path;
809
810 foreign_path = (ForeignPath *) joinpath->outerjoinpath;
811 if (IS_JOIN_REL(foreign_path->path.parent))
812 {
813 joinpath->outerjoinpath = foreign_path->fdw_outerpath;
814
815 if (joinpath->path.pathtype == T_MergeJoin)
816 {
817 MergePath *merge_path = (MergePath *) joinpath;
818
819 /*
820 * If the new outer path is already well enough ordered
821 * for the mergejoin, we can skip doing an explicit sort.
822 */
823 if (merge_path->outersortkeys &&
825 joinpath->outerjoinpath->pathkeys,
826 &merge_path->outer_presorted_keys))
827 merge_path->outersortkeys = NIL;
828 }
829 }
830 }
831
832 if (IsA(joinpath->innerjoinpath, ForeignPath))
833 {
834 ForeignPath *foreign_path;
835
836 foreign_path = (ForeignPath *) joinpath->innerjoinpath;
837 if (IS_JOIN_REL(foreign_path->path.parent))
838 {
839 joinpath->innerjoinpath = foreign_path->fdw_outerpath;
840
841 if (joinpath->path.pathtype == T_MergeJoin)
842 {
843 MergePath *merge_path = (MergePath *) joinpath;
844
845 /*
846 * If the new inner path is already well enough ordered
847 * for the mergejoin, we can skip doing an explicit sort.
848 */
849 if (merge_path->innersortkeys &&
851 joinpath->innerjoinpath->pathkeys))
852 merge_path->innersortkeys = NIL;
853 }
854 }
855 }
856
857 return (Path *) joinpath;
858 }
859 return NULL;
860}
Assert(PointerIsAligned(start, uint64))
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
#define makeNode(_type_)
Definition: nodes.h:161
bool pathkeys_count_contained_in(List *keys1, List *keys2, int *n_common)
Definition: pathkeys.c:558
bool pathkeys_contained_in(List *keys1, List *keys2)
Definition: pathkeys.c:343
#define IS_JOIN_REL(rel)
Definition: pathnodes.h:868
#define lfirst(lc)
Definition: pg_list.h:172
#define NIL
Definition: pg_list.h:68
Path * fdw_outerpath
Definition: pathnodes.h:2004
Path * outerjoinpath
Definition: pathnodes.h:2208
Path * innerjoinpath
Definition: pathnodes.h:2209
List * outersortkeys
Definition: pathnodes.h:2274
List * innersortkeys
Definition: pathnodes.h:2275
int outer_presorted_keys
Definition: pathnodes.h:2276
List * pathkeys
Definition: pathnodes.h:1799
NodeTag pathtype
Definition: pathnodes.h:1759
List * pathlist
Definition: pathnodes.h:922

References Assert(), ForeignPath::fdw_outerpath, if(), JoinPath::innerjoinpath, MergePath::innersortkeys, IS_JOIN_REL, IsA, lfirst, makeNode, NIL, MergePath::outer_presorted_keys, JoinPath::outerjoinpath, MergePath::outersortkeys, ForeignPath::path, Path::pathkeys, pathkeys_contained_in(), pathkeys_count_contained_in(), RelOptInfo::pathlist, and Path::pathtype.

Referenced by postgresGetForeignJoinPaths().

◆ GetFdwRoutine()

FdwRoutine * GetFdwRoutine ( Oid  fdwhandler)

Definition at line 326 of file foreign.c.

327{
328 Datum datum;
329 FdwRoutine *routine;
330
331 /* Check if the access to foreign tables is restricted */
333 {
334 /* there must not be built-in FDW handler */
336 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
337 errmsg("access to non-system foreign table is restricted")));
338 }
339
340 datum = OidFunctionCall0(fdwhandler);
341 routine = (FdwRoutine *) DatumGetPointer(datum);
342
343 if (routine == NULL || !IsA(routine, FdwRoutine))
344 elog(ERROR, "foreign-data wrapper handler function %u did not return an FdwRoutine struct",
345 fdwhandler);
346
347 return routine;
348}
#define unlikely(x)
Definition: c.h:347
#define elog(elevel,...)
Definition: elog.h:225
#define OidFunctionCall0(functionId)
Definition: fmgr.h:718
int restrict_nonsystem_relation_kind
Definition: postgres.c:105
uintptr_t Datum
Definition: postgres.h:69
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:317
#define RESTRICT_RELKIND_FOREIGN_TABLE
Definition: tcopprot.h:44

References DatumGetPointer(), elog, ereport, errcode(), errmsg(), ERROR, IsA, OidFunctionCall0, restrict_nonsystem_relation_kind, RESTRICT_RELKIND_FOREIGN_TABLE, and unlikely.

Referenced by GetFdwRoutineByServerId(), and ImportForeignSchema().

◆ GetFdwRoutineByRelId()

FdwRoutine * GetFdwRoutineByRelId ( Oid  relid)

Definition at line 420 of file foreign.c.

421{
422 Oid serverid;
423
424 /* Get server OID for the foreign table. */
425 serverid = GetForeignServerIdByRelId(relid);
426
427 /* Now retrieve server's FdwRoutine struct. */
428 return GetFdwRoutineByServerId(serverid);
429}
FdwRoutine * GetFdwRoutineByServerId(Oid serverid)
Definition: foreign.c:378
Oid GetForeignServerIdByRelId(Oid relid)
Definition: foreign.c:356

References GetFdwRoutineByServerId(), and GetForeignServerIdByRelId().

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

◆ GetFdwRoutineByServerId()

FdwRoutine * GetFdwRoutineByServerId ( Oid  serverid)

Definition at line 378 of file foreign.c.

379{
380 HeapTuple tp;
382 Form_pg_foreign_server serverform;
383 Oid fdwid;
384 Oid fdwhandler;
385
386 /* Get foreign-data wrapper OID for the server. */
387 tp = SearchSysCache1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid));
388 if (!HeapTupleIsValid(tp))
389 elog(ERROR, "cache lookup failed for foreign server %u", serverid);
390 serverform = (Form_pg_foreign_server) GETSTRUCT(tp);
391 fdwid = serverform->srvfdw;
392 ReleaseSysCache(tp);
393
394 /* Get handler function OID for the FDW. */
395 tp = SearchSysCache1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid));
396 if (!HeapTupleIsValid(tp))
397 elog(ERROR, "cache lookup failed for foreign-data wrapper %u", fdwid);
399 fdwhandler = fdwform->fdwhandler;
400
401 /* Complain if FDW has been set to NO HANDLER. */
402 if (!OidIsValid(fdwhandler))
404 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
405 errmsg("foreign-data wrapper \"%s\" has no handler",
406 NameStr(fdwform->fdwname))));
407
408 ReleaseSysCache(tp);
409
410 /* And finally, call the handler function. */
411 return GetFdwRoutine(fdwhandler);
412}
#define NameStr(name)
Definition: c.h:717
FdwRoutine * GetFdwRoutine(Oid fdwhandler)
Definition: foreign.c:326
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
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:257
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221

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

444{
445 FdwRoutine *fdwroutine;
446 FdwRoutine *cfdwroutine;
447
448 if (relation->rd_fdwroutine == NULL)
449 {
450 /* Get the info by consulting the catalogs and the FDW code */
451 fdwroutine = GetFdwRoutineByRelId(RelationGetRelid(relation));
452
453 /* Save the data for later reuse in CacheMemoryContext */
455 sizeof(FdwRoutine));
456 memcpy(cfdwroutine, fdwroutine, sizeof(FdwRoutine));
457 relation->rd_fdwroutine = cfdwroutine;
458
459 /* Give back the locally palloc'd copy regardless of makecopy */
460 return fdwroutine;
461 }
462
463 /* We have valid cached data --- does the caller want a copy? */
464 if (makecopy)
465 {
466 fdwroutine = (FdwRoutine *) palloc(sizeof(FdwRoutine));
467 memcpy(fdwroutine, relation->rd_fdwroutine, sizeof(FdwRoutine));
468 return fdwroutine;
469 }
470
471 /* Only a short-lived reference is needed, so just hand back cached copy */
472 return relation->rd_fdwroutine;
473}
FdwRoutine * GetFdwRoutineByRelId(Oid relid)
Definition: foreign.c:420
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1260
void * palloc(Size size)
Definition: mcxt.c:1945
MemoryContext CacheMemoryContext
Definition: mcxt.c:168
#define RelationGetRelid(relation)
Definition: rel.h:516
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 293 of file foreign.c.

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

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

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

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

Referenced by CreateForeignDataWrapper(), and CreateForeignServer().

◆ GetForeignDataWrapperExtended()

ForeignDataWrapper * GetForeignDataWrapperExtended ( Oid  fdwid,
bits16  flags 
)

Definition at line 50 of file foreign.c.

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

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

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

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

◆ GetForeignServerIdByRelId()

Oid GetForeignServerIdByRelId ( Oid  relid)

Definition at line 356 of file foreign.c.

357{
358 HeapTuple tp;
359 Form_pg_foreign_table tableform;
360 Oid serverid;
361
362 tp = SearchSysCache1(FOREIGNTABLEREL, ObjectIdGetDatum(relid));
363 if (!HeapTupleIsValid(tp))
364 elog(ERROR, "cache lookup failed for foreign table %u", relid);
365 tableform = (Form_pg_foreign_table) GETSTRUCT(tp);
366 serverid = tableform->ftserver;
367 ReleaseSysCache(tp);
368
369 return serverid;
370}
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 255 of file foreign.c.

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

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

603{
604 const struct ConnectionOption *opt;
605
606 for (opt = libpq_conninfo_options; opt->optname; opt++)
607 if (context == opt->optcontext && strcmp(opt->optname, option) == 0)
608 return true;
609 return false;
610}
static const struct ConnectionOption libpq_conninfo_options[]
Definition: foreign.c:576
const char * optname
Definition: foreign.c:567

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

485{
486 ListCell *lc;
487
488 switch (stmt->list_type)
489 {
491 return true;
492
494 foreach(lc, stmt->table_list)
495 {
496 RangeVar *rv = (RangeVar *) lfirst(lc);
497
498 if (strcmp(tablename, rv->relname) == 0)
499 return true;
500 }
501 return false;
502
504 foreach(lc, stmt->table_list)
505 {
506 RangeVar *rv = (RangeVar *) lfirst(lc);
507
508 if (strcmp(tablename, rv->relname) == 0)
509 return false;
510 }
511 return true;
512 }
513 return false; /* shouldn't get here */
514}
#define stmt
Definition: indent_codes.h:59
@ FDW_IMPORT_SCHEMA_LIMIT_TO
Definition: parsenodes.h:3034
@ FDW_IMPORT_SCHEMA_ALL
Definition: parsenodes.h:3033
@ FDW_IMPORT_SCHEMA_EXCEPT
Definition: parsenodes.h:3035
char * relname
Definition: primnodes.h:83

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

524{
525 Datum array = PG_GETARG_DATUM(0);
526 ListCell *cell;
527 List *options;
528 ReturnSetInfo *rsinfo;
529
531 rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
532
533 /* prepare the result set */
535
536 foreach(cell, options)
537 {
538 DefElem *def = lfirst(cell);
539 Datum values[2];
540 bool nulls[2];
541
543 nulls[0] = false;
544 if (def->arg)
545 {
547 nulls[1] = false;
548 }
549 else
550 {
551 values[1] = (Datum) 0;
552 nulls[1] = true;
553 }
554 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
555 values, nulls);
556 }
557
558 return (Datum) 0;
559}
static Datum values[MAXATTR]
Definition: bootstrap.c:151
#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:826
Node * arg
Definition: parsenodes.h:827
TupleDesc setDesc
Definition: execnodes.h:358
Tuplestorestate * setResult
Definition: execnodes.h:357
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
Definition: tuplestore.c:784
#define strVal(v)
Definition: value.h:82

References DefElem::arg, CStringGetTextDatum, DefElem::defname, InitMaterializedSRF(), lfirst, MAT_SRF_USE_EXPECTED_DESC, options, PG_GETARG_DATUM, ReturnSetInfo::setDesc, ReturnSetInfo::setResult, strVal, tuplestore_putvalues(), untransformRelOptions(), and values.

◆ postgresql_fdw_validator()

Datum postgresql_fdw_validator ( PG_FUNCTION_ARGS  )

Definition at line 626 of file foreign.c.

627{
628 List *options_list = untransformRelOptions(PG_GETARG_DATUM(0));
629 Oid catalog = PG_GETARG_OID(1);
630
631 ListCell *cell;
632
633 foreach(cell, options_list)
634 {
635 DefElem *def = lfirst(cell);
636
637 if (!is_conninfo_option(def->defname, catalog))
638 {
639 const struct ConnectionOption *opt;
640 const char *closest_match;
642 bool has_valid_options = false;
643
644 /*
645 * Unknown option specified, complain about it. Provide a hint
646 * with a valid option that looks similar, if there is one.
647 */
649 for (opt = libpq_conninfo_options; opt->optname; opt++)
650 {
651 if (catalog == opt->optcontext)
652 {
653 has_valid_options = true;
655 }
656 }
657
658 closest_match = getClosestMatch(&match_state);
660 (errcode(ERRCODE_SYNTAX_ERROR),
661 errmsg("invalid option \"%s\"", def->defname),
662 has_valid_options ? closest_match ?
663 errhint("Perhaps you meant the option \"%s\".",
664 closest_match) : 0 :
665 errhint("There are no valid options in this context.")));
666
667 PG_RETURN_BOOL(false);
668 }
669 }
670
671 PG_RETURN_BOOL(true);
672}
int errhint(const char *fmt,...)
Definition: elog.c:1318
#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:602
struct parser_state match_state[5]
const char * getClosestMatch(ClosestMatchState *state)
Definition: varlena.c:6445
void initClosestMatch(ClosestMatchState *state, const char *source, int max_d)
Definition: varlena.c:6390
void updateClosestMatch(ClosestMatchState *state, const char *candidate)
Definition: varlena.c:6410

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

Referenced by is_conninfo_option(), and postgresql_fdw_validator().