postgresql-fdw.patch

text/plain

Filename: postgresql-fdw.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: context
File+
contrib/file_fdw/file_fdw.c 20 0
doc/src/sgml/fdwhandler.sgml 12 6
src/backend/optimizer/path/allpaths.c 3 0
src/backend/optimizer/util/pathnode.c 4 0
src/include/foreign/fdwapi.h 1 0
src/include/optimizer/pathnode.h 1 0
*** a/contrib/file_fdw/file_fdw.c
--- b/contrib/file_fdw/file_fdw.c
***************
*** 25,30 ****
--- 25,31 ----
  #include "miscadmin.h"
  #include "nodes/makefuncs.h"
  #include "optimizer/cost.h"
+ #include "optimizer/pathnode.h"
  #include "utils/rel.h"
  #include "utils/syscache.h"
  
***************
*** 93,99 **** PG_FUNCTION_INFO_V1(file_fdw_validator);
  /*
   * FDW callback routines
   */
! static FdwPlan *filePlanForeignScan(Oid foreigntableid,
  					PlannerInfo *root,
  					RelOptInfo *baserel);
  static void fileExplainForeignScan(ForeignScanState *node, ExplainState *es);
--- 94,100 ----
  /*
   * FDW callback routines
   */
! static void filePlanForeignScan(Oid foreigntableid,
  					PlannerInfo *root,
  					RelOptInfo *baserel);
  static void fileExplainForeignScan(ForeignScanState *node, ExplainState *es);
***************
*** 406,432 **** get_file_fdw_attribute_options(Oid relid)
  
  /*
   * filePlanForeignScan
!  *		Create a FdwPlan for a scan on the foreign table
   */
! static FdwPlan *
  filePlanForeignScan(Oid foreigntableid,
  					PlannerInfo *root,
  					RelOptInfo *baserel)
  {
  	FdwPlan    *fdwplan;
  	char	   *filename;
  	List	   *options;
  
  	/* Fetch options --- we only need filename at this point */
  	fileGetOptions(foreigntableid, &filename, &options);
  
  	/* Construct FdwPlan with cost estimates */
  	fdwplan = makeNode(FdwPlan);
  	estimate_costs(root, baserel, filename,
  				   &fdwplan->startup_cost, &fdwplan->total_cost);
- 	fdwplan->fdw_private = NIL; /* not used */
  
! 	return fdwplan;
  }
  
  /*
--- 407,447 ----
  
  /*
   * filePlanForeignScan
!  *		Create the (single) path for a scan on the foreign table
   */
! static void
  filePlanForeignScan(Oid foreigntableid,
  					PlannerInfo *root,
  					RelOptInfo *baserel)
  {
+ 	ForeignPath *pathnode = makeNode(ForeignPath);
  	FdwPlan    *fdwplan;
  	char	   *filename;
  	List	   *options;
  
+ 	pathnode->path.pathtype = T_ForeignScan;
+ 	pathnode->path.parent = baserel;
+ 	pathnode->path.pathkeys = NIL;		/* result is always unordered */
+ 	pathnode->path.required_outer = NULL;
+ 	pathnode->path.param_clauses = NIL;
+ 
  	/* Fetch options --- we only need filename at this point */
  	fileGetOptions(foreigntableid, &filename, &options);
  
  	/* Construct FdwPlan with cost estimates */
  	fdwplan = makeNode(FdwPlan);
+ 	fdwplan->fdw_private = NIL;			/* not used */
  	estimate_costs(root, baserel, filename,
  				   &fdwplan->startup_cost, &fdwplan->total_cost);
  
! 	pathnode->fdwplan = fdwplan;
! 
! 	/* Use costs estimated by FDW */
! 	pathnode->path.rows = baserel->rows;
! 	pathnode->path.startup_cost = fdwplan->startup_cost;
! 	pathnode->path.total_cost = fdwplan->total_cost;
! 
! 	add_path(baserel, (Path *) pathnode);
  }
  
  /*
*** a/doc/src/sgml/fdwhandler.sgml
--- b/doc/src/sgml/fdwhandler.sgml
***************
*** 88,108 ****
  
      <para>
  <programlisting>
! FdwPlan *
  PlanForeignScan (Oid foreigntableid,
                   PlannerInfo *root,
                   RelOptInfo *baserel);
  </programlisting>
  
!      Plan a scan on a foreign table. This is called when a query is planned.
       <literal>foreigntableid</> is the <structname>pg_class</> OID of the
       foreign table.  <literal>root</> is the planner's global information
       about the query, and <literal>baserel</> is the planner's information
       about this table.
!      The function must return a palloc'd struct that contains cost estimates
!      plus any FDW-private information that is needed to execute the foreign
!      scan at a later time.  (Note that the private information must be
!      represented in a form that <function>copyObject</> knows how to copy.)
      </para>
  
      <para>
--- 88,114 ----
  
      <para>
  <programlisting>
! void
  PlanForeignScan (Oid foreigntableid,
                   PlannerInfo *root,
                   RelOptInfo *baserel);
  </programlisting>
  
!      Create the access paths for a scan on a foreign table. This is called
!      when a query is planned.
       <literal>foreigntableid</> is the <structname>pg_class</> OID of the
       foreign table.  <literal>root</> is the planner's global information
       about the query, and <literal>baserel</> is the planner's information
       about this table.
!      The function must generate at least one access path for a scan on the
!      foreign table and call <function>add_path</> to add the access path to
!      <literal>baserel-&gt;pathlist</>. The function may generate multiple
!      access paths for a scan on the foreign table and add them to
!      <literal>baserel-&gt;pathlist</>. Each access path generated should
!      contain cost estimates plus any FDW-private information that is needed
!      to execute the foreign scan at a later time.
!      (Note that the private information must be represented in a form that
!      <function>copyObject</> knows how to copy.)
      </para>
  
      <para>
*** a/src/backend/optimizer/path/allpaths.c
--- b/src/backend/optimizer/path/allpaths.c
***************
*** 399,411 **** set_foreign_size(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
  
  /*
   * set_foreign_pathlist
!  *		Build the (single) access path for a foreign table RTE
   */
  static void
  set_foreign_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
  {
! 	/* Generate appropriate path */
! 	add_path(rel, (Path *) create_foreignscan_path(root, rel));
  
  	/* Select cheapest path (pretty easy in this case...) */
  	set_cheapest(rel);
--- 399,411 ----
  
  /*
   * set_foreign_pathlist
!  *		Build one or more access paths for a foreign table RTE
   */
  static void
  set_foreign_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
  {
! 	/* Generate appropriate paths */
! 	create_foreignscan_path(root, rel);
  
  	/* Select cheapest path (pretty easy in this case...) */
  	set_cheapest(rel);
*** a/src/backend/optimizer/util/pathnode.c
--- b/src/backend/optimizer/util/pathnode.c
***************
*** 1764,1803 **** create_worktablescan_path(PlannerInfo *root, RelOptInfo *rel)
  
  /*
   * create_foreignscan_path
!  *	  Creates a path corresponding to a scan of a foreign table,
!  *	  returning the pathnode.
   */
! ForeignPath *
  create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel)
  {
- 	ForeignPath *pathnode = makeNode(ForeignPath);
  	RangeTblEntry *rte;
  	FdwRoutine *fdwroutine;
- 	FdwPlan    *fdwplan;
- 
- 	pathnode->path.pathtype = T_ForeignScan;
- 	pathnode->path.parent = rel;
- 	pathnode->path.pathkeys = NIL;		/* result is always unordered */
- 	pathnode->path.required_outer = NULL;
- 	pathnode->path.param_clauses = NIL;
  
  	/* Get FDW's callback info */
  	rte = planner_rt_fetch(rel->relid, root);
  	fdwroutine = GetFdwRoutineByRelId(rte->relid);
  
  	/* Let the FDW do its planning */
! 	fdwplan = fdwroutine->PlanForeignScan(rte->relid, root, rel);
! 	if (fdwplan == NULL || !IsA(fdwplan, FdwPlan))
! 		elog(ERROR, "foreign-data wrapper PlanForeignScan function for relation %u did not return an FdwPlan struct",
! 			 rte->relid);
! 	pathnode->fdwplan = fdwplan;
! 
! 	/* use costs estimated by FDW */
! 	pathnode->path.rows = rel->rows;
! 	pathnode->path.startup_cost = fdwplan->startup_cost;
! 	pathnode->path.total_cost = fdwplan->total_cost;
! 
! 	return pathnode;
  }
  
  /*
--- 1764,1784 ----
  
  /*
   * create_foreignscan_path
!  *	  Creates one or more paths corresponding to a scan of a foreign table,
!  *	  returning void.
   */
! void
  create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel)
  {
  	RangeTblEntry *rte;
  	FdwRoutine *fdwroutine;
  
  	/* Get FDW's callback info */
  	rte = planner_rt_fetch(rel->relid, root);
  	fdwroutine = GetFdwRoutineByRelId(rte->relid);
  
  	/* Let the FDW do its planning */
! 	fdwroutine->PlanForeignScan(rte->relid, root, rel);
  }
  
  /*
*** a/src/include/foreign/fdwapi.h
--- b/src/include/foreign/fdwapi.h
***************
*** 52,58 **** typedef struct FdwPlan
   * Callback function signatures --- see fdwhandler.sgml for more info.
   */
  
! typedef FdwPlan *(*PlanForeignScan_function) (Oid foreigntableid,
  														  PlannerInfo *root,
  														RelOptInfo *baserel);
  
--- 52,58 ----
   * Callback function signatures --- see fdwhandler.sgml for more info.
   */
  
! typedef void (*PlanForeignScan_function) (Oid foreigntableid,
  														  PlannerInfo *root,
  														RelOptInfo *baserel);
  
*** a/src/include/optimizer/pathnode.h
--- b/src/include/optimizer/pathnode.h
***************
*** 68,74 **** extern Path *create_functionscan_path(PlannerInfo *root, RelOptInfo *rel);
  extern Path *create_valuesscan_path(PlannerInfo *root, RelOptInfo *rel);
  extern Path *create_ctescan_path(PlannerInfo *root, RelOptInfo *rel);
  extern Path *create_worktablescan_path(PlannerInfo *root, RelOptInfo *rel);
! extern ForeignPath *create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel);
  
  extern Relids calc_nestloop_required_outer(Path *outer_path, Path *inner_path);
  extern Relids calc_non_nestloop_required_outer(Path *outer_path, Path *inner_path);
--- 68,74 ----
  extern Path *create_valuesscan_path(PlannerInfo *root, RelOptInfo *rel);
  extern Path *create_ctescan_path(PlannerInfo *root, RelOptInfo *rel);
  extern Path *create_worktablescan_path(PlannerInfo *root, RelOptInfo *rel);
! extern void create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel);
  
  extern Relids calc_nestloop_required_outer(Path *outer_path, Path *inner_path);
  extern Relids calc_non_nestloop_required_outer(Path *outer_path, Path *inner_path);