PostgreSQL Source Code git master
Loading...
Searching...
No Matches
foreign.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * foreign.c
4 * support for foreign-data wrappers, servers and user mappings.
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 *
8 * IDENTIFICATION
9 * src/backend/foreign/foreign.c
10 *
11 *-------------------------------------------------------------------------
12 */
13#include "postgres.h"
14
15#include "access/htup_details.h"
16#include "access/reloptions.h"
21#include "foreign/fdwapi.h"
22#include "foreign/foreign.h"
23#include "funcapi.h"
24#include "miscadmin.h"
25#include "optimizer/paths.h"
26#include "tcop/tcopprot.h"
27#include "utils/builtins.h"
28#include "utils/memutils.h"
29#include "utils/rel.h"
30#include "utils/syscache.h"
31#include "utils/tuplestore.h"
32#include "utils/varlena.h"
33
34
35/*
36 * GetForeignDataWrapper - look up the foreign-data wrapper by OID.
37 */
40{
41 return GetForeignDataWrapperExtended(fdwid, 0);
42}
43
44
45/*
46 * GetForeignDataWrapperExtended - look up the foreign-data wrapper
47 * by OID. If flags uses FDW_MISSING_OK, return NULL if the object cannot
48 * be found instead of raising an error.
49 */
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}
92
93
94/*
95 * GetForeignDataWrapperByName - look up the foreign-data wrapper
96 * definition by name.
97 */
99GetForeignDataWrapperByName(const char *fdwname, bool missing_ok)
100{
101 Oid fdwId = get_foreign_data_wrapper_oid(fdwname, missing_ok);
102
103 if (!OidIsValid(fdwId))
104 return NULL;
105
107}
108
109
110/*
111 * GetForeignServer - look up the foreign server definition.
112 */
115{
116 return GetForeignServerExtended(serverid, 0);
117}
118
119
120/*
121 * GetForeignServerExtended - look up the foreign server definition. If
122 * flags uses FSV_MISSING_OK, return NULL if the object cannot be found
123 * instead of raising an error.
124 */
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}
179
180
181/*
182 * ForeignServerName - get name of foreign server.
183 */
184char *
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}
204
205
206/*
207 * GetForeignServerByName - look up the foreign server definition by name.
208 */
210GetForeignServerByName(const char *srvname, bool missing_ok)
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}
219
220
221/*
222 * Retrieve connection string from server's FDW.
223 */
224char *
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}
280
281
282/*
283 * GetUserMapping - look up the user mapping.
284 *
285 * If no mapping is found for the supplied user, we also look for
286 * PUBLIC mappings (userid == InvalidOid).
287 */
289GetUserMapping(Oid userid, Oid serverid)
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}
337
338
339/*
340 * GetForeignTable - look up the foreign table definition by relation oid.
341 */
344{
347 HeapTuple tp;
348 Datum datum;
349 bool isnull;
350
352 if (!HeapTupleIsValid(tp))
353 elog(ERROR, "cache lookup failed for foreign table %u", relid);
355
357 ft->relid = relid;
358 ft->serverid = tableform->ftserver;
359
360 /* Extract the ftoptions */
362 tp,
364 &isnull);
365 if (isnull)
366 ft->options = NIL;
367 else
368 ft->options = untransformRelOptions(datum);
369
370 ReleaseSysCache(tp);
371
372 return ft;
373}
374
375
376/*
377 * GetForeignColumnOptions - Get attfdwoptions of given relation/attnum
378 * as list of DefElem.
379 */
380List *
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}
407
408
409/*
410 * GetFdwRoutine - call the specified foreign-data wrapper handler routine
411 * to get its FdwRoutine struct.
412 */
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}
437
438
439/*
440 * GetForeignServerIdByRelId - look up the foreign server
441 * for the given foreign table, and return its OID.
442 */
443Oid
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}
459
460
461/*
462 * GetFdwRoutineByServerId - look up the handler of the foreign-data wrapper
463 * for the given foreign server, and retrieve its FdwRoutine struct.
464 */
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}
501
502
503/*
504 * GetFdwRoutineByRelId - look up the handler of the foreign-data wrapper
505 * for the given foreign table, and retrieve its FdwRoutine struct.
506 */
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}
518
519/*
520 * GetFdwRoutineForRelation - look up the handler of the foreign-data wrapper
521 * for the given foreign table, and retrieve its FdwRoutine struct.
522 *
523 * This function is preferred over GetFdwRoutineByRelId because it caches
524 * the data in the relcache entry, saving a number of catalog lookups.
525 *
526 * If makecopy is true then the returned data is freshly palloc'd in the
527 * caller's memory context. Otherwise, it's a pointer to the relcache data,
528 * which will be lost in any relcache reset --- so don't rely on it long.
529 */
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}
562
563
564/*
565 * IsImportableForeignTable - filter table names for IMPORT FOREIGN SCHEMA
566 *
567 * Returns true if given table name should be imported according to the
568 * statement's import filter options.
569 */
570bool
571IsImportableForeignTable(const char *tablename,
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}
603
604
605/*
606 * pg_options_to_table - Convert options array to name/value table
607 *
608 * This is useful to provide details for information_schema and pg_dump.
609 */
610Datum
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}
648
649
650/*
651 * Describes the valid options for postgresql FDW, server, and user mapping.
652 */
654{
655 const char *optname;
656 Oid optcontext; /* Oid of catalog in which option may appear */
657};
658
659/*
660 * Copied from fe-connect.c PQconninfoOptions.
661 *
662 * The list is small - don't bother with bsearch if it stays so.
663 */
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};
682
683
684/*
685 * Check if the provided option is one of libpq conninfo options.
686 * context is the Oid of the catalog the option came from, or 0 if we
687 * don't care.
688 */
689static bool
690is_conninfo_option(const char *option, Oid context)
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}
699
700
701/*
702 * Validate the generic option given to SERVER or USER MAPPING.
703 * Raise an ERROR if the option or its value is considered invalid.
704 *
705 * Valid server options are all libpq conninfo options except
706 * user and password -- these may only appear in USER MAPPING options.
707 *
708 * Caution: this function is deprecated, and is now meant only for testing
709 * purposes, because the list of options it knows about doesn't necessarily
710 * square with those known to whichever libpq instance you might be using.
711 * Inquire of libpq itself, instead.
712 */
713Datum
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}
761
762
763/*
764 * get_foreign_data_wrapper_oid - given a FDW name, look up the OID
765 *
766 * If missing_ok is false, throw an error if name not found. If true, just
767 * return InvalidOid.
768 */
769Oid
770get_foreign_data_wrapper_oid(const char *fdwname, bool missing_ok)
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}
784
785
786/*
787 * get_foreign_server_oid - given a server name, look up the OID
788 *
789 * If missing_ok is false, throw an error if name not found. If true, just
790 * return InvalidOid.
791 */
792Oid
793get_foreign_server_oid(const char *servername, bool missing_ok)
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}
805
806/*
807 * Get a copy of an existing local path for a given join relation.
808 *
809 * This function is usually helpful to obtain an alternate local path for EPQ
810 * checks.
811 *
812 * Right now, this function only supports unparameterized foreign joins, so we
813 * only search for unparameterized path in the given list of paths. Since we
814 * are searching for a path which can be used to construct an alternative local
815 * plan for a foreign join, we look for only MergeJoin, HashJoin or NestLoop
816 * paths.
817 *
818 * If the inner or outer subpath of the chosen path is a ForeignScan, we
819 * replace it with its outer subpath. For this reason, and also because the
820 * planner might free the original path later, the path returned by this
821 * function is a shallow copy of the original. There's no need to copy
822 * the substructure, so we don't.
823 *
824 * Since the plan created using this path will presumably only be used to
825 * execute EPQ checks, efficiency of the path is not a concern. But since the
826 * path list in RelOptInfo is anyway sorted by total cost we are likely to
827 * choose the most efficient path, which is all for the best.
828 */
829Path *
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}
int16 AttrNumber
Definition attnum.h:21
static Datum values[MAXATTR]
Definition bootstrap.c:188
#define CStringGetTextDatum(s)
Definition builtins.h:98
#define TextDatumGetCString(d)
Definition builtins.h:99
#define NameStr(name)
Definition c.h:837
uint16 bits16
Definition c.h:626
#define Assert(condition)
Definition c.h:945
#define unlikely(x)
Definition c.h:432
#define OidIsValid(objectId)
Definition c.h:860
int errcode(int sqlerrcode)
Definition elog.c:874
int errhint(const char *fmt,...) pg_attribute_printf(1
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 elog(elevel,...)
Definition elog.h:226
#define PG_FINALLY(...)
Definition elog.h:389
#define ereport(elevel,...)
Definition elog.h:150
#define palloc_object(type)
Definition fe_memutils.h:74
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define DatumGetTextPP(X)
Definition fmgr.h:293
#define OidFunctionCall0(functionId)
Definition fmgr.h:720
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
#define OidFunctionCall3(functionId, arg1, arg2, arg3)
Definition fmgr.h:726
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
static bool is_conninfo_option(const char *option, Oid context)
Definition foreign.c:690
static const struct ConnectionOption libpq_conninfo_options[]
Definition foreign.c:664
ForeignDataWrapper * GetForeignDataWrapper(Oid fdwid)
Definition foreign.c:39
ForeignServer * GetForeignServerByName(const char *srvname, bool missing_ok)
Definition foreign.c:210
FdwRoutine * GetFdwRoutineForRelation(Relation relation, bool makecopy)
Definition foreign.c:531
FdwRoutine * GetFdwRoutineByServerId(Oid serverid)
Definition foreign.c:466
ForeignTable * GetForeignTable(Oid relid)
Definition foreign.c:343
Path * GetExistingLocalJoinPath(RelOptInfo *joinrel)
Definition foreign.c:830
UserMapping * GetUserMapping(Oid userid, Oid serverid)
Definition foreign.c:289
Oid get_foreign_server_oid(const char *servername, bool missing_ok)
Definition foreign.c:793
char * ForeignServerName(Oid serverid)
Definition foreign.c:185
ForeignServer * GetForeignServer(Oid serverid)
Definition foreign.c:114
Datum pg_options_to_table(PG_FUNCTION_ARGS)
Definition foreign.c:611
ForeignDataWrapper * GetForeignDataWrapperExtended(Oid fdwid, bits16 flags)
Definition foreign.c:51
Datum postgresql_fdw_validator(PG_FUNCTION_ARGS)
Definition foreign.c:714
FdwRoutine * GetFdwRoutineByRelId(Oid relid)
Definition foreign.c:508
ForeignDataWrapper * GetForeignDataWrapperByName(const char *fdwname, bool missing_ok)
Definition foreign.c:99
char * ForeignServerConnectionString(Oid userid, Oid serverid)
Definition foreign.c:225
Oid GetForeignServerIdByRelId(Oid relid)
Definition foreign.c:444
bool IsImportableForeignTable(const char *tablename, ImportForeignSchemaStmt *stmt)
Definition foreign.c:571
ForeignServer * GetForeignServerExtended(Oid serverid, bits16 flags)
Definition foreign.c:126
FdwRoutine * GetFdwRoutine(Oid fdwhandler)
Definition foreign.c:414
List * GetForeignColumnOptions(Oid relid, AttrNumber attnum)
Definition foreign.c:381
Oid get_foreign_data_wrapper_oid(const char *fdwname, bool missing_ok)
Definition foreign.c:770
#define MappingUserName(userid)
Definition foreign.h:20
#define FSV_MISSING_OK
Definition foreign.h:62
#define FDW_MISSING_OK
Definition foreign.h:65
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
Definition funcapi.c:76
#define MAT_SRF_USE_EXPECTED_DESC
Definition funcapi.h:296
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
#define stmt
struct parser_state match_state[5]
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1232
char * pstrdup(const char *in)
Definition mcxt.c:1781
MemoryContext CurrentMemoryContext
Definition mcxt.c:160
MemoryContext CacheMemoryContext
Definition mcxt.c:169
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:472
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_SMALL_SIZES
Definition memutils.h:170
#define IsA(nodeptr, _type_)
Definition nodes.h:164
#define makeNode(_type_)
Definition nodes.h:161
static char * errmsg
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
@ FDW_IMPORT_SCHEMA_LIMIT_TO
@ FDW_IMPORT_SCHEMA_ALL
@ FDW_IMPORT_SCHEMA_EXCEPT
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
int16 attnum
END_CATALOG_STRUCT typedef FormData_pg_foreign_data_wrapper * Form_pg_foreign_data_wrapper
END_CATALOG_STRUCT typedef FormData_pg_foreign_server * Form_pg_foreign_server
END_CATALOG_STRUCT typedef FormData_pg_foreign_table * Form_pg_foreign_table
#define lfirst(lc)
Definition pg_list.h:172
#define NIL
Definition pg_list.h:68
END_CATALOG_STRUCT typedef FormData_pg_user_mapping * Form_pg_user_mapping
int restrict_nonsystem_relation_kind
Definition postgres.c:108
static Datum PointerGetDatum(const void *X)
Definition postgres.h:342
static Datum Int16GetDatum(int16 X)
Definition postgres.h:172
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
uint64_t Datum
Definition postgres.h:70
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:332
static Datum CStringGetDatum(const char *X)
Definition postgres.h:370
#define InvalidOid
unsigned int Oid
static int fb(int x)
#define RelationGetRelid(relation)
Definition rel.h:514
List * untransformRelOptions(Datum options)
const char * optname
Definition foreign.c:655
char * defname
Definition parsenodes.h:857
Node * arg
Definition parsenodes.h:858
List * options
Definition foreign.h:43
char * serverversion
Definition foreign.h:42
char * servername
Definition foreign.h:40
char * servertype
Definition foreign.h:41
Definition pg_list.h:54
List * outersortkeys
Definition pathnodes.h:2458
List * innersortkeys
Definition pathnodes.h:2459
NodeTag pathtype
Definition pathnodes.h:1959
char * relname
Definition primnodes.h:84
List * pathlist
Definition pathnodes.h:1038
struct FdwRoutine * rd_fdwroutine
Definition rel.h:240
Definition c.h:778
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCache2(SysCacheIdentifier cacheId, Datum key1, Datum key2)
Definition syscache.c:230
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:220
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:595
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition syscache.h:109
#define RESTRICT_RELKIND_FOREIGN_TABLE
Definition tcopprot.h:45
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
Definition tuplestore.c:785
#define strVal(v)
Definition value.h:82
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
char * text_to_cstring(const text *t)
Definition varlena.c:217