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

682{
683 Oid oid;
684
685 oid = GetSysCacheOid1(FOREIGNDATAWRAPPERNAME,
686 Anum_pg_foreign_data_wrapper_oid,
687 CStringGetDatum(fdwname));
688 if (!OidIsValid(oid) && !missing_ok)
690 (errcode(ERRCODE_UNDEFINED_OBJECT),
691 errmsg("foreign-data wrapper \"%s\" does not exist",
692 fdwname)));
693 return oid;
694}
#define OidIsValid(objectId)
Definition: c.h:732
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#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:32
#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 704 of file foreign.c.

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

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

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

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

326{
327 Datum datum;
328 FdwRoutine *routine;
329
330 /* Check if the access to foreign tables is restricted */
332 {
333 /* there must not be built-in FDW handler */
335 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
336 errmsg("access to non-system foreign table is restricted")));
337 }
338
339 datum = OidFunctionCall0(fdwhandler);
340 routine = (FdwRoutine *) DatumGetPointer(datum);
341
342 if (routine == NULL || !IsA(routine, FdwRoutine))
343 elog(ERROR, "foreign-data wrapper handler function %u did not return an FdwRoutine struct",
344 fdwhandler);
345
346 return routine;
347}
#define unlikely(x)
Definition: c.h:333
#define elog(elevel,...)
Definition: elog.h:225
#define OidFunctionCall0(functionId)
Definition: fmgr.h:677
int restrict_nonsystem_relation_kind
Definition: postgres.c:104
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 419 of file foreign.c.

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

References GetFdwRoutineByServerId(), and GetForeignServerIdByRelId().

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

◆ GetFdwRoutineByServerId()

FdwRoutine * GetFdwRoutineByServerId ( Oid  serverid)

Definition at line 377 of file foreign.c.

378{
379 HeapTuple tp;
381 Form_pg_foreign_server serverform;
382 Oid fdwid;
383 Oid fdwhandler;
384
385 /* Get foreign-data wrapper OID for the server. */
386 tp = SearchSysCache1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid));
387 if (!HeapTupleIsValid(tp))
388 elog(ERROR, "cache lookup failed for foreign server %u", serverid);
389 serverform = (Form_pg_foreign_server) GETSTRUCT(tp);
390 fdwid = serverform->srvfdw;
391 ReleaseSysCache(tp);
392
393 /* Get handler function OID for the FDW. */
394 tp = SearchSysCache1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid));
395 if (!HeapTupleIsValid(tp))
396 elog(ERROR, "cache lookup failed for foreign-data wrapper %u", fdwid);
398 fdwhandler = fdwform->fdwhandler;
399
400 /* Complain if FDW has been set to NO HANDLER. */
401 if (!OidIsValid(fdwhandler))
403 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
404 errmsg("foreign-data wrapper \"%s\" has no handler",
405 NameStr(fdwform->fdwname))));
406
407 ReleaseSysCache(tp);
408
409 /* And finally, call the handler function. */
410 return GetFdwRoutine(fdwhandler);
411}
#define NameStr(name)
Definition: c.h:703
FdwRoutine * GetFdwRoutine(Oid fdwhandler)
Definition: foreign.c:325
#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 442 of file foreign.c.

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

293{
294 List *options;
295 HeapTuple tp;
296 Datum datum;
297 bool isnull;
298
299 tp = SearchSysCache2(ATTNUM,
300 ObjectIdGetDatum(relid),
302 if (!HeapTupleIsValid(tp))
303 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
304 attnum, relid);
305 datum = SysCacheGetAttr(ATTNUM,
306 tp,
307 Anum_pg_attribute_attfdwoptions,
308 &isnull);
309 if (isnull)
310 options = NIL;
311 else
313
314 ReleaseSysCache(tp);
315
316 return options;
317}
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:177
List * untransformRelOptions(Datum options)
Definition: reloptions.c:1340
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 96 of file foreign.c.

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

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

Referenced by CreateForeignDataWrapper(), and CreateForeignServer().

◆ GetForeignDataWrapperExtended()

ForeignDataWrapper * GetForeignDataWrapperExtended ( Oid  fdwid,
bits16  flags 
)

Definition at line 49 of file foreign.c.

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

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

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

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

◆ GetForeignServerExtended()

ForeignServer * GetForeignServerExtended ( Oid  serverid,
bits16  flags 
)

Definition at line 123 of file foreign.c.

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

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

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

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

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

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

484{
485 ListCell *lc;
486
487 switch (stmt->list_type)
488 {
490 return true;
491
493 foreach(lc, stmt->table_list)
494 {
495 RangeVar *rv = (RangeVar *) lfirst(lc);
496
497 if (strcmp(tablename, rv->relname) == 0)
498 return true;
499 }
500 return false;
501
503 foreach(lc, stmt->table_list)
504 {
505 RangeVar *rv = (RangeVar *) lfirst(lc);
506
507 if (strcmp(tablename, rv->relname) == 0)
508 return false;
509 }
510 return true;
511 }
512 return false; /* shouldn't get here */
513}
#define stmt
Definition: indent_codes.h:59
@ FDW_IMPORT_SCHEMA_LIMIT_TO
Definition: parsenodes.h:3014
@ FDW_IMPORT_SCHEMA_ALL
Definition: parsenodes.h:3013
@ FDW_IMPORT_SCHEMA_EXCEPT
Definition: parsenodes.h:3015
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 522 of file foreign.c.

523{
524 Datum array = PG_GETARG_DATUM(0);
525 ListCell *cell;
526 List *options;
527 ReturnSetInfo *rsinfo;
528
530 rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
531
532 /* prepare the result set */
534
535 foreach(cell, options)
536 {
537 DefElem *def = lfirst(cell);
538 Datum values[2];
539 bool nulls[2];
540
542 nulls[0] = false;
543 if (def->arg)
544 {
546 nulls[1] = false;
547 }
548 else
549 {
550 values[1] = (Datum) 0;
551 nulls[1] = true;
552 }
553 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
554 values, nulls);
555 }
556
557 return (Datum) 0;
558}
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 625 of file foreign.c.

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

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

Referenced by is_conninfo_option(), and postgresql_fdw_validator().