1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Redesign PlanForeignScan API to allow multiple paths for a foreign table.

The original API specification only allowed an FDW to create a single
access path, which doesn't seem like a terribly good idea in hindsight.
Instead, move the responsibility for building the Path node and calling
add_path() into the FDW's PlanForeignScan function.  Now, it can do that
more than once if appropriate.  There is no longer any need for the
transient FdwPlan struct, so get rid of that.

Etsuro Fujita, Shigeru Hanada, Tom Lane
This commit is contained in:
Tom Lane
2012-03-05 16:15:59 -05:00
parent 3f47e145f1
commit 6b289942bf
12 changed files with 103 additions and 125 deletions

View File

@ -25,6 +25,7 @@
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "optimizer/cost.h"
#include "optimizer/pathnode.h"
#include "utils/rel.h"
#include "utils/syscache.h"
@ -93,7 +94,7 @@ PG_FUNCTION_INFO_V1(file_fdw_validator);
/*
* FDW callback routines
*/
static FdwPlan *filePlanForeignScan(Oid foreigntableid,
static void filePlanForeignScan(Oid foreigntableid,
PlannerInfo *root,
RelOptInfo *baserel);
static void fileExplainForeignScan(ForeignScanState *node, ExplainState *es);
@ -406,27 +407,44 @@ get_file_fdw_attribute_options(Oid relid)
/*
* filePlanForeignScan
* Create a FdwPlan for a scan on the foreign table
* Create possible access paths for a scan on the foreign table
*
* Currently we don't support any push-down feature, so there is only one
* possible access path, which simply returns all records in the order in
* the data file.
*/
static FdwPlan *
static void
filePlanForeignScan(Oid foreigntableid,
PlannerInfo *root,
RelOptInfo *baserel)
{
FdwPlan *fdwplan;
char *filename;
List *options;
Cost startup_cost;
Cost total_cost;
/* Fetch options --- we only need filename at this point */
fileGetOptions(foreigntableid, &filename, &options);
/* Construct FdwPlan with cost estimates */
fdwplan = makeNode(FdwPlan);
/* Estimate costs and update baserel->rows */
estimate_costs(root, baserel, filename,
&fdwplan->startup_cost, &fdwplan->total_cost);
fdwplan->fdw_private = NIL; /* not used */
&startup_cost, &total_cost);
return fdwplan;
/* Create a ForeignPath node and add it as only possible path */
add_path(baserel, (Path *)
create_foreignscan_path(root, baserel,
baserel->rows,
startup_cost,
total_cost,
NIL, /* no pathkeys */
NULL, /* no outer rel either */
NIL,
NIL)); /* no fdw_private data */
/*
* If data file was sorted, and we knew it somehow, we could insert
* appropriate pathkeys into the ForeignPath node to tell the planner that.
*/
}
/*
@ -576,6 +594,9 @@ fileReScanForeignScan(ForeignScanState *node)
/*
* Estimate costs of scanning a foreign table.
*
* In addition to setting *startup_cost and *total_cost, this should
* update baserel->rows.
*/
static void
estimate_costs(PlannerInfo *root, RelOptInfo *baserel,