#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);
+
+
Foreign Data Wrapper Helper Functions
+
+ 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
+ foreign/foreign.h in your source file.
+ That header also defines the struct types that are returned by
+ these functions.
+
+
+ForeignDataWrapper *
+GetForeignDataWrapper(Oid fdwid);
+
+
+ This function returns a ForeignDataWrapper
+ object for the foreign-data wrapper with the given OID. A
+ ForeignDataWrapper object contains properties
+ of the FDW (see foreign/foreign.h for details).
+
+
+ForeignServer *
+GetForeignServer(Oid serverid);
+
+
+ This function returns a ForeignServer object
+ for the foreign server with the given OID. A
+ ForeignServer object contains properties
+ of the server (see foreign/foreign.h for details).
+
+
+UserMapping *
+GetUserMapping(Oid userid, Oid serverid);
+
+
+ This function returns a UserMapping 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
+ PUBLIC>, or throw error if there is none.) A
+ UserMapping object contains properties of the
+ user mapping (see foreign/foreign.h for details).
+
+
+ForeignTable *
+GetForeignTable(Oid relid);
+
+
+ This function returns a ForeignTable object for
+ the foreign table with the given OID. A
+ ForeignTable object contains properties of the
+ foreign table (see foreign/foreign.h for details).
+
+
+List *
+GetForeignTableColumnOptions(Oid relid, AttrNumber attnum);
+
+
+ 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
+ DefElem. NIL is returned if the column has no
+ options.
+
+
+ Some object types have name-based lookup functions in addition to the
+ OID-based ones:
+
+
+ForeignDataWrapper *
+GetForeignDataWrapperByName(const char *name, bool missing_ok);
+
+
+ This function returns a ForeignDataWrapper
+ 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.
+
+
+ForeignServer *
+GetForeignServerByName(const char *name, bool missing_ok);
+
+
+ This function returns a ForeignServer 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.
+
+
+
+
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);