fdw_helper_v6.patch
text/plain
Filename: fdw_helper_v6.patch
Type: text/plain
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v6
| File | + | − |
|---|---|---|
| contrib/file_fdw/file_fdw.c | 0 | 0 |
| doc/src/sgml/fdwhandler.sgml | 0 | 0 |
| src/backend/foreign/foreign.c | 0 | 0 |
| src/include/foreign/foreign.h | 0 | 0 |
diff --git a/contrib/file_fdw/file_fdw.c b/contrib/file_fdw/file_fdw.c
index c2faa62..0193aae 100644
*** a/contrib/file_fdw/file_fdw.c
--- b/contrib/file_fdw/file_fdw.c
***************
*** 27,33 ****
#include "optimizer/cost.h"
#include "optimizer/pathnode.h"
#include "utils/rel.h"
! #include "utils/syscache.h"
PG_MODULE_MAGIC;
--- 27,33 ----
#include "optimizer/cost.h"
#include "optimizer/pathnode.h"
#include "utils/rel.h"
! #include "utils/lsyscache.h"
PG_MODULE_MAGIC;
*************** get_file_fdw_attribute_options(Oid relid
*** 346,399 ****
/* Retrieve FDW options for all user-defined attributes. */
for (attnum = 1; attnum <= natts; attnum++)
{
! HeapTuple tuple;
! Form_pg_attribute attr;
! Datum datum;
! bool isnull;
/* Skip dropped attributes. */
if (tupleDesc->attrs[attnum - 1]->attisdropped)
continue;
! /*
! * We need the whole pg_attribute tuple not just what is in the
! * tupleDesc, so must do a catalog lookup.
! */
! tuple = SearchSysCache2(ATTNUM,
! RelationGetRelid(rel),
! Int16GetDatum(attnum));
! if (!HeapTupleIsValid(tuple))
! elog(ERROR, "cache lookup failed for attribute %d of relation %u",
! attnum, RelationGetRelid(rel));
! attr = (Form_pg_attribute) GETSTRUCT(tuple);
!
! datum = SysCacheGetAttr(ATTNUM,
! tuple,
! Anum_pg_attribute_attfdwoptions,
! &isnull);
! if (!isnull)
{
! List *options = untransformRelOptions(datum);
! ListCell *lc;
! foreach(lc, options)
{
! DefElem *def = (DefElem *) lfirst(lc);
!
! if (strcmp(def->defname, "force_not_null") == 0)
{
! if (defGetBoolean(def))
! {
! char *attname = pstrdup(NameStr(attr->attname));
! fnncolumns = lappend(fnncolumns, makeString(attname));
! }
}
- /* maybe in future handle other options here */
}
}
-
- ReleaseSysCache(tuple);
}
heap_close(rel, AccessShareLock);
--- 346,374 ----
/* Retrieve FDW options for all user-defined attributes. */
for (attnum = 1; attnum <= natts; attnum++)
{
! List *options;
! ListCell *lc;
/* Skip dropped attributes. */
if (tupleDesc->attrs[attnum - 1]->attisdropped)
continue;
! options = GetForeignColumnOptions(relid, attnum);
! foreach(lc, options)
{
! DefElem *def = (DefElem *) lfirst(lc);
! if (strcmp(def->defname, "force_not_null") == 0)
{
! if (defGetBoolean(def))
{
! char *attname = pstrdup(get_attname(relid, attnum));
! fnncolumns = lappend(fnncolumns, makeString(attname));
}
}
+ /* maybe in future handle other options here */
}
}
heap_close(rel, AccessShareLock);
diff --git a/doc/src/sgml/fdwhandler.sgml b/doc/src/sgml/fdwhandler.sgml
index 12c5f75..7900484 100644
*** a/doc/src/sgml/fdwhandler.sgml
--- b/doc/src/sgml/fdwhandler.sgml
*************** EndForeignScan (ForeignScanState *node);
*** 244,247 ****
--- 244,352 ----
</sect1>
+ <sect1 id="fdw-helpers">
+ <title>Foreign Data Wrapper Helper Functions</title>
+
+ <para>
+ Several helper functions are exported from core so that authors of FDW
+ can get easy access to attributes of FDW-related objects such as FDW
+ options.
+ </para>
+
+ <para>
+ <programlisting>
+ ForeignDataWrapper *
+ GetForeignDataWrapper(Oid fdwid);
+ </programlisting>
+
+ This function returns a <structname>ForeignDataWrapper</structname> object
+ for a foreign-data wrapper with given oid. A
+ <structname>ForeignDataWrapper</structname> object contains oid of the
+ wrapper itself, oid of the owner of the wrapper, name of the wrapper, oid
+ of fdwhandler function, oid of fdwvalidator function, and FDW options in
+ the form of list of <structname>DefElem</structname>.
+ </para>
+
+ <para>
+ <programlisting>
+ ForeignServer *
+ GetForeignServer(Oid serverid);
+ </programlisting>
+
+ This function returns a <structname>ForeignServer</structname> object for
+ a foreign server with given oid. A <structname>ForeignServer</structname>
+ object contains oid of the server, oid of the wrapper for the server, oid
+ of the owner of the server, name of the server, type of the server,
+ version of the server, and FDW options in the form of list of
+ <structname>DefElem</structname>.
+ </para>
+
+ <para>
+ <programlisting>
+ UserMapping *
+ GetUserMapping(Oid userid, Oid serverid);
+ </programlisting>
+
+ This function returns a <structname>UserMapping</structname> object for a
+ user mapping with given oid pair. A <structname>UserMapping</structname>
+ object contains oid of the user, oid of the server, and FDW options in the
+ form of list of <structname>DefElem</structname>.
+ </para>
+
+ <para>
+ <programlisting>
+ ForeignTable *
+ GetForeignTable(Oid relid);
+ </programlisting>
+
+ This function returns a <structname>ForeignTable</structname> object for a
+ foreign table with given oid. A <structname>ForeignTable</structname>
+ object contains oid of the foreign table, oid of the server for the table,
+ and FDW options in the form of list of <structname>DefElem</structname>.
+ </para>
+
+ <para>
+ <programlisting>
+ List *
+ GetForeignTableColumnOptions(Oid relid, AttrNumber attnum);
+ </programlisting>
+
+ This function returns per-column FDW options for a column with given
+ relation oid and attribute number in the form of list of
+ <structname>DefElem</structname>.
+ </para>
+
+ <para>
+ Some object types have name-based functions.
+ </para>
+
+ <para>
+ <programlisting>
+ ForeignDataWrapper *
+ GetForeignDataWrapperByName(const char *name, bool missing_ok);
+ </programlisting>
+
+ This function returns a <structname>ForeignDataWrapper</structname> object
+ for a foreign-data wrapper with given name. If the wrapper is not found,
+ return NULL if missing_ok was true, otherwise raise an error.
+ </para>
+
+ <para>
+ <programlisting>
+ ForeignServer *
+ GetForeignServerByName(const char *name, bool missing_ok);
+ </programlisting>
+
+ This function returns a <structname>ForeignServer</structname> object for
+ a foreign server with given name. If the server is not found, return NULL
+ if missing_ok was true, otherwise raise an error.
+ </para>
+
+ <para>
+ To use any of these functions, you need to include
+ <filename>foreign/foreign.h</filename> in your source file.
+ </para>
+
+ </sect1>
+
</chapter>
diff --git a/src/backend/foreign/foreign.c b/src/backend/foreign/foreign.c
index c4c2a61..4db26b5 100644
*** a/src/backend/foreign/foreign.c
--- b/src/backend/foreign/foreign.c
***************
*** 17,22 ****
--- 17,23 ----
#include "catalog/pg_foreign_server.h"
#include "catalog/pg_foreign_table.h"
#include "catalog/pg_user_mapping.h"
+ #include "commands/defrem.h"
#include "foreign/fdwapi.h"
#include "foreign/foreign.h"
#include "miscadmin.h"
*************** GetForeignTable(Oid relid)
*** 246,251 ****
--- 247,282 ----
return ft;
}
+ /*
+ * GetForeignColumnOptions - Get attfdwoptions of given relation/attnum as
+ * list of DefElem.
+ */
+ List *
+ GetForeignColumnOptions(Oid relid, AttrNumber attnum)
+ {
+ List *options;
+ HeapTuple tp;
+ Datum datum;
+ bool isnull;
+
+ tp = SearchSysCache2(ATTNUM,
+ ObjectIdGetDatum(relid),
+ Int16GetDatum(attnum));
+ if (!HeapTupleIsValid(tp))
+ elog(ERROR, "cache lookup failed for attribute %d of relation %u", attnum, relid);
+ datum = SysCacheGetAttr(ATTNUM,
+ tp,
+ Anum_pg_attribute_attfdwoptions,
+ &isnull);
+ if (isnull)
+ options = NIL;
+ else
+ options = untransformRelOptions(datum);
+
+ ReleaseSysCache(tp);
+
+ return options;
+ }
/*
* GetFdwRoutine - call the specified foreign-data wrapper handler routine
diff --git a/src/include/foreign/foreign.h b/src/include/foreign/foreign.h
index 191122d..4a4ce23 100644
*** a/src/include/foreign/foreign.h
--- b/src/include/foreign/foreign.h
*************** extern ForeignDataWrapper *GetForeignDat
*** 75,80 ****
--- 75,81 ----
extern ForeignDataWrapper *GetForeignDataWrapperByName(const char *name,
bool missing_ok);
extern ForeignTable *GetForeignTable(Oid relid);
+ extern List *GetForeignColumnOptions(Oid relid, AttrNumber attnum);
extern Oid get_foreign_data_wrapper_oid(const char *fdwname, bool missing_ok);
extern Oid get_foreign_server_oid(const char *servername, bool missing_ok);