*** a/contrib/file_fdw/file_fdw.c
--- b/contrib/file_fdw/file_fdw.c
***************
*** 74,87 **** static const struct FileFdwOption valid_options[] = {
};
/*
! * FDW-specific information for RelOptInfo.fdw_private.
*/
typedef struct FileFdwPlanState
{
char *filename; /* file to read */
List *options; /* merged COPY options, excluding filename */
- BlockNumber pages; /* estimate of file's physical size */
- double ntuples; /* estimate of number of rows in file */
} FileFdwPlanState;
/*
--- 74,85 ----
};
/*
! * FDW-specific information for RelOptInfo.fdw_state.
*/
typedef struct FileFdwPlanState
{
char *filename; /* file to read */
List *options; /* merged COPY options, excluding filename */
} FileFdwPlanState;
/*
***************
*** 132,140 **** static void fileGetOptions(Oid foreigntableid,
char **filename, List **other_options);
static List *get_file_fdw_attribute_options(Oid relid);
static void estimate_size(PlannerInfo *root, RelOptInfo *baserel,
! FileFdwPlanState *fdw_private);
static void estimate_costs(PlannerInfo *root, RelOptInfo *baserel,
- FileFdwPlanState *fdw_private,
Cost *startup_cost, Cost *total_cost);
--- 130,137 ----
char **filename, List **other_options);
static List *get_file_fdw_attribute_options(Oid relid);
static void estimate_size(PlannerInfo *root, RelOptInfo *baserel,
! FileFdwPlanState *fpstate);
static void estimate_costs(PlannerInfo *root, RelOptInfo *baserel,
Cost *startup_cost, Cost *total_cost);
***************
*** 415,433 **** fileGetForeignRelSize(PlannerInfo *root,
RelOptInfo *baserel,
Oid foreigntableid)
{
! FileFdwPlanState *fdw_private;
/*
* Fetch options. We only need filename at this point, but we might
* as well get everything and not need to re-fetch it later in planning.
*/
! fdw_private = (FileFdwPlanState *) palloc(sizeof(FileFdwPlanState));
! fileGetOptions(foreigntableid,
! &fdw_private->filename, &fdw_private->options);
! baserel->fdw_private = (void *) fdw_private;
/* Estimate relation size */
! estimate_size(root, baserel, fdw_private);
}
/*
--- 412,429 ----
RelOptInfo *baserel,
Oid foreigntableid)
{
! FileFdwPlanState *fpstate;
/*
* Fetch options. We only need filename at this point, but we might
* as well get everything and not need to re-fetch it later in planning.
*/
! fpstate = (FileFdwPlanState *) palloc(sizeof(FileFdwPlanState));
! fileGetOptions(foreigntableid, &fpstate->filename, &fpstate->options);
! baserel->fdw_state = (void *) fpstate;
/* Estimate relation size */
! estimate_size(root, baserel, fpstate);
}
/*
***************
*** 443,455 **** fileGetForeignPaths(PlannerInfo *root,
RelOptInfo *baserel,
Oid foreigntableid)
{
- FileFdwPlanState *fdw_private = (FileFdwPlanState *) baserel->fdw_private;
Cost startup_cost;
Cost total_cost;
/* Estimate costs */
! estimate_costs(root, baserel, fdw_private,
! &startup_cost, &total_cost);
/* Create a ForeignPath node and add it as only possible path */
add_path(baserel, (Path *)
--- 439,449 ----
RelOptInfo *baserel,
Oid foreigntableid)
{
Cost startup_cost;
Cost total_cost;
/* Estimate costs */
! estimate_costs(root, baserel, &startup_cost, &total_cost);
/* Create a ForeignPath node and add it as only possible path */
add_path(baserel, (Path *)
***************
*** 647,659 **** fileReScanForeignScan(ForeignScanState *node)
/*
* Estimate size of a foreign table.
*
! * The main result is returned in baserel->rows. We also set
! * fdw_private->pages and fdw_private->ntuples for later use in the cost
! * calculation.
*/
static void
estimate_size(PlannerInfo *root, RelOptInfo *baserel,
! FileFdwPlanState *fdw_private)
{
struct stat stat_buf;
BlockNumber pages;
--- 641,652 ----
/*
* Estimate size of a foreign table.
*
! * The main result is returned in baserel->rows. We also set baserel->pages
! * and baserel->tuples for later use in the cost calculation.
*/
static void
estimate_size(PlannerInfo *root, RelOptInfo *baserel,
! FileFdwPlanState *fpstate)
{
struct stat stat_buf;
BlockNumber pages;
***************
*** 665,671 **** estimate_size(PlannerInfo *root, RelOptInfo *baserel,
* Get size of the file. It might not be there at plan time, though, in
* which case we have to use a default estimate.
*/
! if (stat(fdw_private->filename, &stat_buf) < 0)
stat_buf.st_size = 10 * BLCKSZ;
/*
--- 658,664 ----
* Get size of the file. It might not be there at plan time, though, in
* which case we have to use a default estimate.
*/
! if (stat(fpstate->filename, &stat_buf) < 0)
stat_buf.st_size = 10 * BLCKSZ;
/*
***************
*** 675,681 **** estimate_size(PlannerInfo *root, RelOptInfo *baserel,
if (pages < 1)
pages = 1;
! fdw_private->pages = pages;
/*
* Estimate the number of tuples in the file. We back into this estimate
--- 668,674 ----
if (pages < 1)
pages = 1;
! baserel->pages = pages;
/*
* Estimate the number of tuples in the file. We back into this estimate
***************
*** 688,694 **** estimate_size(PlannerInfo *root, RelOptInfo *baserel,
ntuples = clamp_row_est((double) stat_buf.st_size / (double) tuple_width);
! fdw_private->ntuples = ntuples;
/*
* Now estimate the number of rows returned by the scan after applying the
--- 681,687 ----
ntuples = clamp_row_est((double) stat_buf.st_size / (double) tuple_width);
! baserel->tuples = ntuples;
/*
* Now estimate the number of rows returned by the scan after applying the
***************
*** 715,725 **** estimate_size(PlannerInfo *root, RelOptInfo *baserel,
*/
static void
estimate_costs(PlannerInfo *root, RelOptInfo *baserel,
- FileFdwPlanState *fdw_private,
Cost *startup_cost, Cost *total_cost)
{
! BlockNumber pages = fdw_private->pages;
! double ntuples = fdw_private->ntuples;
Cost run_cost = 0;
Cost cpu_per_tuple;
--- 708,717 ----
*/
static void
estimate_costs(PlannerInfo *root, RelOptInfo *baserel,
Cost *startup_cost, Cost *total_cost)
{
! BlockNumber pages = baserel->pages;
! double ntuples = baserel->tuples;
Cost run_cost = 0;
Cost cpu_per_tuple;
*** a/doc/src/sgml/fdwhandler.sgml
--- b/doc/src/sgml/fdwhandler.sgml
***************
*** 126,132 **** GetForeignRelSize (PlannerInfo *root,
! baserel->fdw_private> is a void> pointer that is
available for use by FDW planning functions. It can be used to pass
information forward from GetForeignRelSize> to
GetForeignPaths> and/or GetForeignPaths> to
--- 126,132 ----
! baserel->fdw_state> is a void> pointer that is
available for use by FDW planning functions. It can be used to pass
information forward from GetForeignRelSize> to
GetForeignPaths> and/or GetForeignPaths> to
*** a/src/backend/optimizer/util/relnode.c
--- b/src/backend/optimizer/util/relnode.c
***************
*** 114,120 **** build_simple_rel(PlannerInfo *root, int relid, RelOptKind reloptkind)
rel->subplan = NULL;
rel->subroot = NULL;
rel->fdwroutine = NULL;
! rel->fdw_private = NULL;
rel->baserestrictinfo = NIL;
rel->baserestrictcost.startup = 0;
rel->baserestrictcost.per_tuple = 0;
--- 114,120 ----
rel->subplan = NULL;
rel->subroot = NULL;
rel->fdwroutine = NULL;
! rel->fdw_state = NULL;
rel->baserestrictinfo = NIL;
rel->baserestrictcost.startup = 0;
rel->baserestrictcost.per_tuple = 0;
***************
*** 369,375 **** build_join_rel(PlannerInfo *root,
joinrel->subplan = NULL;
joinrel->subroot = NULL;
joinrel->fdwroutine = NULL;
! joinrel->fdw_private = NULL;
joinrel->baserestrictinfo = NIL;
joinrel->baserestrictcost.startup = 0;
joinrel->baserestrictcost.per_tuple = 0;
--- 369,375 ----
joinrel->subplan = NULL;
joinrel->subroot = NULL;
joinrel->fdwroutine = NULL;
! joinrel->fdw_state = NULL;
joinrel->baserestrictinfo = NIL;
joinrel->baserestrictcost.startup = 0;
joinrel->baserestrictcost.per_tuple = 0;
*** a/src/include/nodes/relation.h
--- b/src/include/nodes/relation.h
***************
*** 422,428 **** typedef struct RelOptInfo
PlannerInfo *subroot; /* if subquery */
/* use "struct FdwRoutine" to avoid including fdwapi.h here */
struct FdwRoutine *fdwroutine; /* if foreign table */
! void *fdw_private; /* if foreign table */
/* used by various scans and joins: */
List *baserestrictinfo; /* RestrictInfo structures (if base
--- 422,428 ----
PlannerInfo *subroot; /* if subquery */
/* use "struct FdwRoutine" to avoid including fdwapi.h here */
struct FdwRoutine *fdwroutine; /* if foreign table */
! void *fdw_state; /* if foreign table */
/* used by various scans and joins: */
List *baserestrictinfo; /* RestrictInfo structures (if base