PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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/tuplestore.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)
 
charForeignServerName (Oid serverid)
 
ForeignServerGetForeignServerByName (const char *srvname, bool missing_ok)
 
charForeignServerConnectionString (Oid userid, Oid serverid)
 
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

◆ ForeignServerConnectionString()

char * ForeignServerConnectionString ( Oid  userid,
Oid  serverid 
)

Definition at line 225 of file foreign.c.

226{
227 MemoryContext tempContext;
229 text *volatile connection_text = NULL;
230 char *result = NULL;
231
232 /*
233 * GetForeignServer, GetForeignDataWrapper, and the connection function
234 * itself all leak memory into CurrentMemoryContext. Switch to a temporary
235 * context for easy cleanup.
236 */
238 "FDWConnectionContext",
240
241 oldcxt = MemoryContextSwitchTo(tempContext);
242
243 PG_TRY();
244 {
245 ForeignServer *server;
248
249 server = GetForeignServer(serverid);
251
252 if (!OidIsValid(fdw->fdwconnection))
255 errmsg("foreign data wrapper \"%s\" does not support subscription connections",
256 fdw->fdwname),
257 errdetail("Foreign data wrapper must be defined with CONNECTION specified.")));
258
259
260 connection_datum = OidFunctionCall3(fdw->fdwconnection,
261 ObjectIdGetDatum(userid),
262 ObjectIdGetDatum(serverid),
264
266 }
267 PG_FINALLY();
268 {
270
271 if (connection_text)
273
274 MemoryContextDelete(tempContext);
275 }
276 PG_END_TRY();
277
278 return result;
279}
#define OidIsValid(objectId)
Definition c.h:860
int errcode(int sqlerrcode)
Definition elog.c:874
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define PG_TRY(...)
Definition elog.h:372
#define PG_END_TRY(...)
Definition elog.h:397
#define ERROR
Definition elog.h:39
#define PG_FINALLY(...)
Definition elog.h:389
#define ereport(elevel,...)
Definition elog.h:150
#define DatumGetTextPP(X)
Definition fmgr.h:293
#define OidFunctionCall3(functionId, arg1, arg2, arg3)
Definition fmgr.h:726
ForeignDataWrapper * GetForeignDataWrapper(Oid fdwid)
Definition foreign.c:39
ForeignServer * GetForeignServer(Oid serverid)
Definition foreign.c:114
MemoryContext CurrentMemoryContext
Definition mcxt.c:160
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:472
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_SMALL_SIZES
Definition memutils.h:170
static char * errmsg
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
static Datum PointerGetDatum(const void *X)
Definition postgres.h:342
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
uint64_t Datum
Definition postgres.h:70
static int fb(int x)
Definition c.h:778
char * text_to_cstring(const text *t)
Definition varlena.c:217

References ALLOCSET_SMALL_SIZES, AllocSetContextCreate, CurrentMemoryContext, DatumGetTextPP, ereport, errcode(), errdetail(), errmsg, ERROR, fb(), ForeignServer::fdwid, GetForeignDataWrapper(), GetForeignServer(), MemoryContextDelete(), MemoryContextSwitchTo(), ObjectIdGetDatum(), OidFunctionCall3, OidIsValid, PG_END_TRY, PG_FINALLY, PG_TRY, PointerGetDatum(), and text_to_cstring().

Referenced by AlterSubscription(), CreateSubscription(), DropSubscription(), and GetSubscription().

◆ ForeignServerName()

char * ForeignServerName ( Oid  serverid)

Definition at line 185 of file foreign.c.

186{
188 char *servername;
189 HeapTuple tp;
190
192
193 if (!HeapTupleIsValid(tp))
194 elog(ERROR, "cache lookup failed for foreign server %u", serverid);
195
197
198 servername = pstrdup(NameStr(serverform->srvname));
199
200 ReleaseSysCache(tp);
201
202 return servername;
203}
#define NameStr(name)
Definition c.h:837
#define elog(elevel,...)
Definition elog.h:226
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
char * pstrdup(const char *in)
Definition mcxt.c:1781
END_CATALOG_STRUCT typedef FormData_pg_foreign_server * Form_pg_foreign_server
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:220

References elog, ERROR, fb(), Form_pg_foreign_server, GETSTRUCT(), HeapTupleIsValid, NameStr, ObjectIdGetDatum(), pstrdup(), ReleaseSysCache(), and SearchSysCache1().

Referenced by AlterSubscription(), AlterSubscriptionOwner_internal(), DropSubscription(), and GetSubscription().

◆ get_foreign_data_wrapper_oid()

Oid get_foreign_data_wrapper_oid ( const char fdwname,
bool  missing_ok 
)

Definition at line 770 of file foreign.c.

771{
772 Oid oid;
773
776 CStringGetDatum(fdwname));
777 if (!OidIsValid(oid) && !missing_ok)
780 errmsg("foreign-data wrapper \"%s\" does not exist",
781 fdwname)));
782 return oid;
783}
static Datum CStringGetDatum(const char *X)
Definition postgres.h:370
unsigned int Oid
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition syscache.h:109

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

794{
795 Oid oid;
796
798 CStringGetDatum(servername));
799 if (!OidIsValid(oid) && !missing_ok)
802 errmsg("server \"%s\" does not exist", servername)));
803 return oid;
804}

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

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

◆ GetExistingLocalJoinPath()

Path * GetExistingLocalJoinPath ( RelOptInfo joinrel)

Definition at line 830 of file foreign.c.

831{
832 ListCell *lc;
833
834 Assert(IS_JOIN_REL(joinrel));
835
836 foreach(lc, joinrel->pathlist)
837 {
838 Path *path = (Path *) lfirst(lc);
840
841 /* Skip parameterized paths. */
842 if (path->param_info != NULL)
843 continue;
844
845 switch (path->pathtype)
846 {
847 case T_HashJoin:
848 {
850
851 memcpy(hash_path, path, sizeof(HashPath));
853 }
854 break;
855
856 case T_NestLoop:
857 {
859
860 memcpy(nest_path, path, sizeof(NestPath));
862 }
863 break;
864
865 case T_MergeJoin:
866 {
868
869 memcpy(merge_path, path, sizeof(MergePath));
871 }
872 break;
873
874 default:
875
876 /*
877 * Just skip anything else. We don't know if corresponding
878 * plan would build the output row from whole-row references
879 * of base relations and execute the EPQ checks.
880 */
881 break;
882 }
883
884 /* This path isn't good for us, check next. */
885 if (!joinpath)
886 continue;
887
888 /*
889 * If either inner or outer path is a ForeignPath corresponding to a
890 * pushed down join, replace it with the fdw_outerpath, so that we
891 * maintain path for EPQ checks built entirely of local join
892 * strategies.
893 */
894 if (IsA(joinpath->outerjoinpath, ForeignPath))
895 {
897
898 foreign_path = (ForeignPath *) joinpath->outerjoinpath;
899 if (IS_JOIN_REL(foreign_path->path.parent))
900 {
901 joinpath->outerjoinpath = foreign_path->fdw_outerpath;
902
903 if (joinpath->path.pathtype == T_MergeJoin)
904 {
906
907 /*
908 * If the new outer path is already well enough ordered
909 * for the mergejoin, we can skip doing an explicit sort.
910 */
911 if (merge_path->outersortkeys &&
913 joinpath->outerjoinpath->pathkeys,
914 &merge_path->outer_presorted_keys))
916 }
917 }
918 }
919
920 if (IsA(joinpath->innerjoinpath, ForeignPath))
921 {
923
924 foreign_path = (ForeignPath *) joinpath->innerjoinpath;
925 if (IS_JOIN_REL(foreign_path->path.parent))
926 {
927 joinpath->innerjoinpath = foreign_path->fdw_outerpath;
928
929 if (joinpath->path.pathtype == T_MergeJoin)
930 {
932
933 /*
934 * If the new inner path is already well enough ordered
935 * for the mergejoin, we can skip doing an explicit sort.
936 */
937 if (merge_path->innersortkeys &&
938 pathkeys_contained_in(merge_path->innersortkeys,
939 joinpath->innerjoinpath->pathkeys))
941 }
942 }
943 }
944
945 return (Path *) joinpath;
946 }
947 return NULL;
948}
#define Assert(condition)
Definition c.h:945
#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:982
#define lfirst(lc)
Definition pg_list.h:172
#define NIL
Definition pg_list.h:68
List * outersortkeys
Definition pathnodes.h:2458
List * innersortkeys
Definition pathnodes.h:2459
NodeTag pathtype
Definition pathnodes.h:1959
List * pathlist
Definition pathnodes.h:1038

References Assert, fb(), MergePath::innersortkeys, IS_JOIN_REL, IsA, lfirst, makeNode, NIL, MergePath::outersortkeys, pathkeys_contained_in(), pathkeys_count_contained_in(), RelOptInfo::pathlist, and Path::pathtype.

Referenced by postgresGetForeignJoinPaths().

◆ GetFdwRoutine()

FdwRoutine * GetFdwRoutine ( Oid  fdwhandler)

Definition at line 414 of file foreign.c.

415{
416 Datum datum;
417 FdwRoutine *routine;
418
419 /* Check if the access to foreign tables is restricted */
421 {
422 /* there must not be built-in FDW handler */
425 errmsg("access to non-system foreign table is restricted")));
426 }
427
428 datum = OidFunctionCall0(fdwhandler);
429 routine = (FdwRoutine *) DatumGetPointer(datum);
430
431 if (routine == NULL || !IsA(routine, FdwRoutine))
432 elog(ERROR, "foreign-data wrapper handler function %u did not return an FdwRoutine struct",
433 fdwhandler);
434
435 return routine;
436}
#define unlikely(x)
Definition c.h:432
#define OidFunctionCall0(functionId)
Definition fmgr.h:720
int restrict_nonsystem_relation_kind
Definition postgres.c:108
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:332
#define RESTRICT_RELKIND_FOREIGN_TABLE
Definition tcopprot.h:45

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

509{
510 Oid serverid;
511
512 /* Get server OID for the foreign table. */
513 serverid = GetForeignServerIdByRelId(relid);
514
515 /* Now retrieve server's FdwRoutine struct. */
516 return GetFdwRoutineByServerId(serverid);
517}
FdwRoutine * GetFdwRoutineByServerId(Oid serverid)
Definition foreign.c:466
Oid GetForeignServerIdByRelId(Oid relid)
Definition foreign.c:444

References GetFdwRoutineByServerId(), and GetForeignServerIdByRelId().

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

◆ GetFdwRoutineByServerId()

FdwRoutine * GetFdwRoutineByServerId ( Oid  serverid)

Definition at line 466 of file foreign.c.

467{
468 HeapTuple tp;
471 Oid fdwid;
472 Oid fdwhandler;
473
474 /* Get foreign-data wrapper OID for the server. */
476 if (!HeapTupleIsValid(tp))
477 elog(ERROR, "cache lookup failed for foreign server %u", serverid);
479 fdwid = serverform->srvfdw;
480 ReleaseSysCache(tp);
481
482 /* Get handler function OID for the FDW. */
484 if (!HeapTupleIsValid(tp))
485 elog(ERROR, "cache lookup failed for foreign-data wrapper %u", fdwid);
487 fdwhandler = fdwform->fdwhandler;
488
489 /* Complain if FDW has been set to NO HANDLER. */
490 if (!OidIsValid(fdwhandler))
493 errmsg("foreign-data wrapper \"%s\" has no handler",
494 NameStr(fdwform->fdwname))));
495
496 ReleaseSysCache(tp);
497
498 /* And finally, call the handler function. */
499 return GetFdwRoutine(fdwhandler);
500}
FdwRoutine * GetFdwRoutine(Oid fdwhandler)
Definition foreign.c:414
END_CATALOG_STRUCT typedef FormData_pg_foreign_data_wrapper * Form_pg_foreign_data_wrapper

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

532{
533 FdwRoutine *fdwroutine;
535
536 if (relation->rd_fdwroutine == NULL)
537 {
538 /* Get the info by consulting the catalogs and the FDW code */
539 fdwroutine = GetFdwRoutineByRelId(RelationGetRelid(relation));
540
541 /* Save the data for later reuse in CacheMemoryContext */
543 sizeof(FdwRoutine));
544 memcpy(cfdwroutine, fdwroutine, sizeof(FdwRoutine));
545 relation->rd_fdwroutine = cfdwroutine;
546
547 /* Give back the locally palloc'd copy regardless of makecopy */
548 return fdwroutine;
549 }
550
551 /* We have valid cached data --- does the caller want a copy? */
552 if (makecopy)
553 {
554 fdwroutine = palloc_object(FdwRoutine);
555 memcpy(fdwroutine, relation->rd_fdwroutine, sizeof(FdwRoutine));
556 return fdwroutine;
557 }
558
559 /* Only a short-lived reference is needed, so just hand back cached copy */
560 return relation->rd_fdwroutine;
561}
#define palloc_object(type)
Definition fe_memutils.h:74
FdwRoutine * GetFdwRoutineByRelId(Oid relid)
Definition foreign.c:508
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1232
MemoryContext CacheMemoryContext
Definition mcxt.c:169
#define RelationGetRelid(relation)
Definition rel.h:514
struct FdwRoutine * rd_fdwroutine
Definition rel.h:240

References CacheMemoryContext, fb(), GetFdwRoutineByRelId(), MemoryContextAlloc(), palloc_object, 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 381 of file foreign.c.

382{
383 List *options;
384 HeapTuple tp;
385 Datum datum;
386 bool isnull;
387
389 ObjectIdGetDatum(relid),
391 if (!HeapTupleIsValid(tp))
392 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
393 attnum, relid);
394 datum = SysCacheGetAttr(ATTNUM,
395 tp,
397 &isnull);
398 if (isnull)
399 options = NIL;
400 else
402
403 ReleaseSysCache(tp);
404
405 return options;
406}
int16 attnum
static Datum Int16GetDatum(int16 X)
Definition postgres.h:172
List * untransformRelOptions(Datum options)
Definition pg_list.h:54
HeapTuple SearchSysCache2(SysCacheIdentifier cacheId, Datum key1, Datum key2)
Definition syscache.c:230
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:595

References attnum, elog, ERROR, fb(), HeapTupleIsValid, Int16GetDatum(), NIL, ObjectIdGetDatum(), 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 99 of file foreign.c.

100{
101 Oid fdwId = get_foreign_data_wrapper_oid(fdwname, missing_ok);
102
103 if (!OidIsValid(fdwId))
104 return NULL;
105
107}
Oid get_foreign_data_wrapper_oid(const char *fdwname, bool missing_ok)
Definition foreign.c:770

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

Referenced by CreateForeignDataWrapper(), and CreateForeignServer().

◆ GetForeignDataWrapperExtended()

ForeignDataWrapper * GetForeignDataWrapperExtended ( Oid  fdwid,
bits16  flags 
)

Definition at line 51 of file foreign.c.

52{
55 Datum datum;
56 HeapTuple tp;
57 bool isnull;
58
60
61 if (!HeapTupleIsValid(tp))
62 {
63 if ((flags & FDW_MISSING_OK) == 0)
64 elog(ERROR, "cache lookup failed for foreign-data wrapper %u", fdwid);
65 return NULL;
66 }
67
69
71 fdw->fdwid = fdwid;
72 fdw->owner = fdwform->fdwowner;
73 fdw->fdwname = pstrdup(NameStr(fdwform->fdwname));
74 fdw->fdwhandler = fdwform->fdwhandler;
75 fdw->fdwvalidator = fdwform->fdwvalidator;
76 fdw->fdwconnection = fdwform->fdwconnection;
77
78 /* Extract the fdwoptions */
80 tp,
82 &isnull);
83 if (isnull)
84 fdw->options = NIL;
85 else
86 fdw->options = untransformRelOptions(datum);
87
89
90 return fdw;
91}
#define FDW_MISSING_OK
Definition foreign.h:65

References elog, ERROR, fb(), FDW_MISSING_OK, Form_pg_foreign_data_wrapper, GETSTRUCT(), HeapTupleIsValid, NameStr, NIL, ObjectIdGetDatum(), palloc_object, 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 210 of file foreign.c.

211{
212 Oid serverid = get_foreign_server_oid(srvname, missing_ok);
213
214 if (!OidIsValid(serverid))
215 return NULL;
216
217 return GetForeignServer(serverid);
218}
Oid get_foreign_server_oid(const char *servername, bool missing_ok)
Definition foreign.c:793

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

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

◆ GetForeignServerExtended()

ForeignServer * GetForeignServerExtended ( Oid  serverid,
bits16  flags 
)

Definition at line 126 of file foreign.c.

127{
129 ForeignServer *server;
130 HeapTuple tp;
131 Datum datum;
132 bool isnull;
133
135
136 if (!HeapTupleIsValid(tp))
137 {
138 if ((flags & FSV_MISSING_OK) == 0)
139 elog(ERROR, "cache lookup failed for foreign server %u", serverid);
140 return NULL;
141 }
142
144
146 server->serverid = serverid;
147 server->servername = pstrdup(NameStr(serverform->srvname));
148 server->owner = serverform->srvowner;
149 server->fdwid = serverform->srvfdw;
150
151 /* Extract server type */
153 tp,
155 &isnull);
156 server->servertype = isnull ? NULL : TextDatumGetCString(datum);
157
158 /* Extract server version */
160 tp,
162 &isnull);
163 server->serverversion = isnull ? NULL : TextDatumGetCString(datum);
164
165 /* Extract the srvoptions */
167 tp,
169 &isnull);
170 if (isnull)
171 server->options = NIL;
172 else
173 server->options = untransformRelOptions(datum);
174
175 ReleaseSysCache(tp);
176
177 return server;
178}
#define TextDatumGetCString(d)
Definition builtins.h:99
#define FSV_MISSING_OK
Definition foreign.h:62
List * options
Definition foreign.h:43
char * serverversion
Definition foreign.h:42
char * servername
Definition foreign.h:40
char * servertype
Definition foreign.h:41

References elog, ERROR, fb(), ForeignServer::fdwid, Form_pg_foreign_server, FSV_MISSING_OK, GETSTRUCT(), HeapTupleIsValid, NameStr, NIL, ObjectIdGetDatum(), ForeignServer::options, ForeignServer::owner, palloc_object, 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 444 of file foreign.c.

445{
446 HeapTuple tp;
448 Oid serverid;
449
451 if (!HeapTupleIsValid(tp))
452 elog(ERROR, "cache lookup failed for foreign table %u", relid);
454 serverid = tableform->ftserver;
455 ReleaseSysCache(tp);
456
457 return serverid;
458}
END_CATALOG_STRUCT typedef FormData_pg_foreign_table * Form_pg_foreign_table

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

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

◆ GetForeignTable()

◆ GetUserMapping()

UserMapping * GetUserMapping ( Oid  userid,
Oid  serverid 
)

Definition at line 289 of file foreign.c.

290{
291 Datum datum;
292 HeapTuple tp;
293 bool isnull;
295
297 ObjectIdGetDatum(userid),
298 ObjectIdGetDatum(serverid));
299
300 if (!HeapTupleIsValid(tp))
301 {
302 /* Not found for the specific user -- try PUBLIC */
305 ObjectIdGetDatum(serverid));
306 }
307
308 if (!HeapTupleIsValid(tp))
309 {
310 ForeignServer *server = GetForeignServer(serverid);
311
314 errmsg("user mapping not found for user \"%s\", server \"%s\"",
315 MappingUserName(userid), server->servername)));
316 }
317
319 um->umid = ((Form_pg_user_mapping) GETSTRUCT(tp))->oid;
320 um->userid = userid;
321 um->serverid = serverid;
322
323 /* Extract the umoptions */
325 tp,
327 &isnull);
328 if (isnull)
329 um->options = NIL;
330 else
331 um->options = untransformRelOptions(datum);
332
333 ReleaseSysCache(tp);
334
335 return um;
336}
#define MappingUserName(userid)
Definition foreign.h:20
END_CATALOG_STRUCT typedef FormData_pg_user_mapping * Form_pg_user_mapping
#define InvalidOid

References ereport, errcode(), errmsg, ERROR, fb(), Form_pg_user_mapping, GetForeignServer(), GETSTRUCT(), HeapTupleIsValid, InvalidOid, MappingUserName, NIL, ObjectIdGetDatum(), palloc_object, ReleaseSysCache(), SearchSysCache2(), ForeignServer::servername, SysCacheGetAttr(), and untransformRelOptions().

Referenced by AlterSubscription(), AlterSubscriptionOwner_internal(), create_foreign_modify(), CreateSubscription(), get_connect_string(), postgres_fdw_connection(), 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 690 of file foreign.c.

691{
692 const struct ConnectionOption *opt;
693
694 for (opt = libpq_conninfo_options; opt->optname; opt++)
695 if (context == opt->optcontext && strcmp(opt->optname, option) == 0)
696 return true;
697 return false;
698}
static const struct ConnectionOption libpq_conninfo_options[]
Definition foreign.c:664
const char * optname
Definition foreign.c:655

References fb(), libpq_conninfo_options, ConnectionOption::optcontext, and ConnectionOption::optname.

Referenced by postgresql_fdw_validator().

◆ IsImportableForeignTable()

bool IsImportableForeignTable ( const char tablename,
ImportForeignSchemaStmt stmt 
)

Definition at line 571 of file foreign.c.

573{
574 ListCell *lc;
575
576 switch (stmt->list_type)
577 {
579 return true;
580
582 foreach(lc, stmt->table_list)
583 {
584 RangeVar *rv = (RangeVar *) lfirst(lc);
585
586 if (strcmp(tablename, rv->relname) == 0)
587 return true;
588 }
589 return false;
590
592 foreach(lc, stmt->table_list)
593 {
594 RangeVar *rv = (RangeVar *) lfirst(lc);
595
596 if (strcmp(tablename, rv->relname) == 0)
597 return false;
598 }
599 return true;
600 }
601 return false; /* shouldn't get here */
602}
#define stmt
@ FDW_IMPORT_SCHEMA_LIMIT_TO
@ FDW_IMPORT_SCHEMA_ALL
@ FDW_IMPORT_SCHEMA_EXCEPT
char * relname
Definition primnodes.h:84

References fb(), 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 611 of file foreign.c.

612{
613 Datum array = PG_GETARG_DATUM(0);
614 ListCell *cell;
615 List *options;
617
619 rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
620
621 /* prepare the result set */
623
624 foreach(cell, options)
625 {
626 DefElem *def = lfirst(cell);
627 Datum values[2];
628 bool nulls[2];
629
631 nulls[0] = false;
632 if (def->arg)
633 {
635 nulls[1] = false;
636 }
637 else
638 {
639 values[1] = (Datum) 0;
640 nulls[1] = true;
641 }
642 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
643 values, nulls);
644 }
645
646 return (Datum) 0;
647}
static Datum values[MAXATTR]
Definition bootstrap.c:188
#define CStringGetTextDatum(s)
Definition builtins.h:98
#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:857
Node * arg
Definition parsenodes.h:858
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
Definition tuplestore.c:785
#define strVal(v)
Definition value.h:82

References DefElem::arg, CStringGetTextDatum, DefElem::defname, fb(), InitMaterializedSRF(), lfirst, MAT_SRF_USE_EXPECTED_DESC, PG_GETARG_DATUM, strVal, tuplestore_putvalues(), untransformRelOptions(), and values.

◆ postgresql_fdw_validator()

Datum postgresql_fdw_validator ( PG_FUNCTION_ARGS  )

Definition at line 714 of file foreign.c.

715{
718
719 ListCell *cell;
720
721 foreach(cell, options_list)
722 {
723 DefElem *def = lfirst(cell);
724
726 {
727 const struct ConnectionOption *opt;
728 const char *closest_match;
730 bool has_valid_options = false;
731
732 /*
733 * Unknown option specified, complain about it. Provide a hint
734 * with a valid option that looks similar, if there is one.
735 */
737 for (opt = libpq_conninfo_options; opt->optname; opt++)
738 {
739 if (catalog == opt->optcontext)
740 {
741 has_valid_options = true;
743 }
744 }
745
749 errmsg("invalid option \"%s\"", def->defname),
751 errhint("Perhaps you meant the option \"%s\".",
752 closest_match) : 0 :
753 errhint("There are no valid options in this context.")));
754
755 PG_RETURN_BOOL(false);
756 }
757 }
758
759 PG_RETURN_BOOL(true);
760}
int errhint(const char *fmt,...) pg_attribute_printf(1
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
static bool is_conninfo_option(const char *option, Oid context)
Definition foreign.c:690
struct parser_state match_state[5]
const char * getClosestMatch(ClosestMatchState *state)
Definition varlena.c:5377
void initClosestMatch(ClosestMatchState *state, const char *source, int max_d)
Definition varlena.c:5322
void updateClosestMatch(ClosestMatchState *state, const char *candidate)
Definition varlena.c:5342

References DefElem::defname, ereport, errcode(), errhint(), errmsg, ERROR, fb(), 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},
{"password", UserMappingRelationId},
{"connect_timeout", ForeignServerRelationId},
{"hostaddr", ForeignServerRelationId},
{"requiressl", ForeignServerRelationId},
{"gssdelegation", ForeignServerRelationId},
}

Definition at line 664 of file foreign.c.

664 {
665 {"authtype", ForeignServerRelationId},
666 {"service", ForeignServerRelationId},
667 {"user", UserMappingRelationId},
668 {"password", UserMappingRelationId},
669 {"connect_timeout", ForeignServerRelationId},
670 {"dbname", ForeignServerRelationId},
671 {"host", ForeignServerRelationId},
672 {"hostaddr", ForeignServerRelationId},
673 {"port", ForeignServerRelationId},
675 {"options", ForeignServerRelationId},
676 {"requiressl", ForeignServerRelationId},
677 {"sslmode", ForeignServerRelationId},
678 {"gsslib", ForeignServerRelationId},
679 {"gssdelegation", ForeignServerRelationId},
681};

Referenced by is_conninfo_option(), and postgresql_fdw_validator().