#include "optimizer/cost.h"
#include "optimizer/pathnode.h"
#include "utils/rel.h"
-#include "utils/syscache.h"
PG_MODULE_MAGIC;
/* 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);
</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>
extern Datum postgresql_fdw_validator(PG_FUNCTION_ARGS);
-
/*
* GetForeignDataWrapper - look up the foreign-data wrapper by OID.
*/
}
-
/*
* GetForeignDataWrapperByName - look up the foreign-data wrapper
* definition by name.
}
+/*
+ * 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.
PG_RETURN_BOOL(true);
}
+
/*
* get_foreign_data_wrapper_oid - given a FDW name, look up the OID
*
return oid;
}
+
/*
* get_foreign_server_oid - given a FDW name, look up the OID
*
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);