fdw_helper_v6.patch

text/plain

Filename: fdw_helper_v6.patch
Type: text/plain
Part: 0
Message: Re: pgsql_fdw, FDW for PostgreSQL server

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);