]> granicus.if.org Git - postgresql/commitdiff
Add GetForeignColumnOptions() to foreign.c, and add some documentation.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 7 Mar 2012 23:20:58 +0000 (18:20 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 7 Mar 2012 23:20:58 +0000 (18:20 -0500)
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

contrib/file_fdw/file_fdw.c
doc/src/sgml/fdwhandler.sgml
src/backend/foreign/foreign.c
src/include/foreign/foreign.h

index c2faa6235e7666c11c49eaab5e260e0368243913..29f203c6f10eeeed194670aa37956a6190e8e7a1 100644 (file)
@@ -27,7 +27,6 @@
 #include "optimizer/cost.h"
 #include "optimizer/pathnode.h"
 #include "utils/rel.h"
-#include "utils/syscache.h"
 
 PG_MODULE_MAGIC;
 
@@ -346,54 +345,30 @@ get_file_fdw_attribute_options(Oid relid)
        /* Retrieve FDW options for all user-defined attributes. */
        for (attnum = 1; attnum <= natts; attnum++)
        {
-               HeapTuple       tuple;
-               Form_pg_attribute attr;
-               Datum           datum;
-               bool            isnull;
+               Form_pg_attribute attr = tupleDesc->attrs[attnum - 1];
+               List       *options;
+               ListCell   *lc;
 
                /* Skip dropped attributes. */
-               if (tupleDesc->attrs[attnum - 1]->attisdropped)
+               if (attr->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)
+               options = GetForeignColumnOptions(relid, attnum);
+               foreach(lc, options)
                {
-                       List       *options = untransformRelOptions(datum);
-                       ListCell   *lc;
+                       DefElem    *def = (DefElem *) lfirst(lc);
 
-                       foreach(lc, options)
+                       if (strcmp(def->defname, "force_not_null") == 0)
                        {
-                               DefElem    *def = (DefElem *) lfirst(lc);
-
-                               if (strcmp(def->defname, "force_not_null") == 0)
+                               if (defGetBoolean(def))
                                {
-                                       if (defGetBoolean(def))
-                                       {
-                                               char   *attname = pstrdup(NameStr(attr->attname));
+                                       char   *attname = pstrdup(NameStr(attr->attname));
 
-                                               fnncolumns = lappend(fnncolumns, makeString(attname));
-                                       }
+                                       fnncolumns = lappend(fnncolumns, makeString(attname));
                                }
-                               /* maybe in future handle other options here */
                        }
+                       /* maybe in future handle other options here */
                }
-
-               ReleaseSysCache(tuple);
        }
 
        heap_close(rel, AccessShareLock);
index 12c5f75bfab4ba530923e4f5a6c44d17dbab55aa..dbfcbbc2b36dd49b0f0a8ffc9893da0b2a25a891 100644 (file)
@@ -244,4 +244,109 @@ EndForeignScan (ForeignScanState *node);
 
    </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>
index c4c2a61d5dcb94edcfe60e6a472b6cd728fdbf13..f27b55a66e4b7aab3ce264ceb0701ba16f8aaaad 100644 (file)
@@ -28,7 +28,6 @@ extern Datum pg_options_to_table(PG_FUNCTION_ARGS);
 extern Datum postgresql_fdw_validator(PG_FUNCTION_ARGS);
 
 
-
 /*
  * GetForeignDataWrapper -     look up the foreign-data wrapper by OID.
  */
@@ -71,7 +70,6 @@ GetForeignDataWrapper(Oid fdwid)
 }
 
 
-
 /*
  * GetForeignDataWrapperByName - look up the foreign-data wrapper
  * definition by name.
@@ -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
  * to get its FdwRoutine struct.
@@ -498,6 +529,7 @@ postgresql_fdw_validator(PG_FUNCTION_ARGS)
        PG_RETURN_BOOL(true);
 }
 
+
 /*
  * 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)
        return oid;
 }
 
+
 /*
  * get_foreign_server_oid - given a FDW name, look up the OID
  *
index 191122d08156980b33815658de9a44ee2e01a781..f8aa99e2a45e46f6b09e0f9cf01a7dca6e29e35f 100644 (file)
@@ -76,6 +76,8 @@ 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);