Commit 9088d1b9 authored by Tom Lane's avatar Tom Lane

Add GetForeignColumnOptions() to foreign.c, and add some documentation.

GetForeignColumnOptions provides some abstraction for accessing
column-specific FDW options, on a par with the access functions that were
already provided here for other FDW-related information.

Adjust file_fdw.c to use GetForeignColumnOptions instead of equivalent
hand-rolled code.

In addition, add some SGML documentation for the functions exported by
foreign.c that are meant for use by FDW authors.

(This is the fdw_helper portion of the proposed pgsql_fdw patch.)

Hanada Shigeru, reviewed by KaiGai Kohei
parent cf7026b6
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#include "optimizer/cost.h" #include "optimizer/cost.h"
#include "optimizer/pathnode.h" #include "optimizer/pathnode.h"
#include "utils/rel.h" #include "utils/rel.h"
#include "utils/syscache.h"
PG_MODULE_MAGIC; PG_MODULE_MAGIC;
...@@ -346,36 +345,15 @@ get_file_fdw_attribute_options(Oid relid) ...@@ -346,36 +345,15 @@ get_file_fdw_attribute_options(Oid relid)
/* Retrieve FDW options for all user-defined attributes. */ /* Retrieve FDW options for all user-defined attributes. */
for (attnum = 1; attnum <= natts; attnum++) for (attnum = 1; attnum <= natts; attnum++)
{ {
HeapTuple tuple; Form_pg_attribute attr = tupleDesc->attrs[attnum - 1];
Form_pg_attribute attr; List *options;
Datum datum; ListCell *lc;
bool isnull;
/* Skip dropped attributes. */ /* Skip dropped attributes. */
if (tupleDesc->attrs[attnum - 1]->attisdropped) if (attr->attisdropped)
continue; continue;
/* options = GetForeignColumnOptions(relid, attnum);
* 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) foreach(lc, options)
{ {
DefElem *def = (DefElem *) lfirst(lc); DefElem *def = (DefElem *) lfirst(lc);
...@@ -393,9 +371,6 @@ get_file_fdw_attribute_options(Oid relid) ...@@ -393,9 +371,6 @@ get_file_fdw_attribute_options(Oid relid)
} }
} }
ReleaseSysCache(tuple);
}
heap_close(rel, AccessShareLock); heap_close(rel, AccessShareLock);
/* Return DefElem only when some column(s) have force_not_null */ /* Return DefElem only when some column(s) have force_not_null */
......
...@@ -244,4 +244,109 @@ EndForeignScan (ForeignScanState *node); ...@@ -244,4 +244,109 @@ EndForeignScan (ForeignScanState *node);
</sect1> </sect1>
<sect1 id="fdw-helpers">
<title>Foreign Data Wrapper Helper Functions</title>
<para>
Several helper functions are exported from the core server so that
authors of foreign data wrappers can get easy access to attributes of
FDW-related objects, such as FDW options.
To use any of these functions, you need to include the header file
<filename>foreign/foreign.h</filename> in your source file.
That header also defines the struct types that are returned by
these functions.
</para>
<para>
<programlisting>
ForeignDataWrapper *
GetForeignDataWrapper(Oid fdwid);
</programlisting>
This function returns a <structname>ForeignDataWrapper</structname>
object for the foreign-data wrapper with the given OID. A
<structname>ForeignDataWrapper</structname> object contains properties
of the FDW (see <filename>foreign/foreign.h</filename> for details).
</para>
<para>
<programlisting>
ForeignServer *
GetForeignServer(Oid serverid);
</programlisting>
This function returns a <structname>ForeignServer</structname> object
for the foreign server with the given OID. A
<structname>ForeignServer</structname> object contains properties
of the server (see <filename>foreign/foreign.h</filename> for details).
</para>
<para>
<programlisting>
UserMapping *
GetUserMapping(Oid userid, Oid serverid);
</programlisting>
This function returns a <structname>UserMapping</structname> object for
the user mapping of the given role on the given server. (If there is no
mapping for the specific user, it will return the mapping for
<literal>PUBLIC</>, or throw error if there is none.) A
<structname>UserMapping</structname> object contains properties of the
user mapping (see <filename>foreign/foreign.h</filename> for details).
</para>
<para>
<programlisting>
ForeignTable *
GetForeignTable(Oid relid);
</programlisting>
This function returns a <structname>ForeignTable</structname> object for
the foreign table with the given OID. A
<structname>ForeignTable</structname> object contains properties of the
foreign table (see <filename>foreign/foreign.h</filename> for details).
</para>
<para>
<programlisting>
List *
GetForeignTableColumnOptions(Oid relid, AttrNumber attnum);
</programlisting>
This function returns the per-column FDW options for the column with the
given foreign table OID and attribute number, in the form of a list of
<structname>DefElem</structname>. NIL is returned if the column has no
options.
</para>
<para>
Some object types have name-based lookup functions in addition to the
OID-based ones:
</para>
<para>
<programlisting>
ForeignDataWrapper *
GetForeignDataWrapperByName(const char *name, bool missing_ok);
</programlisting>
This function returns a <structname>ForeignDataWrapper</structname>
object for the foreign-data wrapper with the given name. If the wrapper
is not found, return NULL if missing_ok is 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 the foreign server with the given name. If the server is not found,
return NULL if missing_ok is true, otherwise raise an error.
</para>
</sect1>
</chapter> </chapter>
...@@ -28,7 +28,6 @@ extern Datum pg_options_to_table(PG_FUNCTION_ARGS); ...@@ -28,7 +28,6 @@ extern Datum pg_options_to_table(PG_FUNCTION_ARGS);
extern Datum postgresql_fdw_validator(PG_FUNCTION_ARGS); extern Datum postgresql_fdw_validator(PG_FUNCTION_ARGS);
/* /*
* GetForeignDataWrapper - look up the foreign-data wrapper by OID. * GetForeignDataWrapper - look up the foreign-data wrapper by OID.
*/ */
...@@ -71,7 +70,6 @@ GetForeignDataWrapper(Oid fdwid) ...@@ -71,7 +70,6 @@ GetForeignDataWrapper(Oid fdwid)
} }
/* /*
* GetForeignDataWrapperByName - look up the foreign-data wrapper * GetForeignDataWrapperByName - look up the foreign-data wrapper
* definition by name. * definition by name.
...@@ -247,6 +245,39 @@ GetForeignTable(Oid relid) ...@@ -247,6 +245,39 @@ GetForeignTable(Oid relid)
} }
/*
* 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 * GetFdwRoutine - call the specified foreign-data wrapper handler routine
* to get its FdwRoutine struct. * to get its FdwRoutine struct.
...@@ -498,6 +529,7 @@ postgresql_fdw_validator(PG_FUNCTION_ARGS) ...@@ -498,6 +529,7 @@ postgresql_fdw_validator(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(true); PG_RETURN_BOOL(true);
} }
/* /*
* get_foreign_data_wrapper_oid - given a FDW name, look up the OID * get_foreign_data_wrapper_oid - given a FDW name, look up the OID
* *
...@@ -518,6 +550,7 @@ get_foreign_data_wrapper_oid(const char *fdwname, bool missing_ok) ...@@ -518,6 +550,7 @@ get_foreign_data_wrapper_oid(const char *fdwname, bool missing_ok)
return oid; return oid;
} }
/* /*
* get_foreign_server_oid - given a FDW name, look up the OID * get_foreign_server_oid - given a FDW name, look up the OID
* *
......
...@@ -76,6 +76,8 @@ extern ForeignDataWrapper *GetForeignDataWrapperByName(const char *name, ...@@ -76,6 +76,8 @@ extern ForeignDataWrapper *GetForeignDataWrapperByName(const char *name,
bool missing_ok); bool missing_ok);
extern ForeignTable *GetForeignTable(Oid relid); 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_data_wrapper_oid(const char *fdwname, bool missing_ok);
extern Oid get_foreign_server_oid(const char *servername, bool missing_ok); extern Oid get_foreign_server_oid(const char *servername, bool missing_ok);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment