mirror of
https://github.com/postgres/postgres.git
synced 2025-07-12 21:01:52 +03:00
Implement an API to let foreign-data wrappers actually be functional.
This commit provides the core code and documentation needed. A contrib module test case will follow shortly. Shigeru Hanada, Jan Urbanski, Heikki Linnakangas
This commit is contained in:
@ -17,6 +17,7 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "catalog/pg_class.h"
|
||||
#include "nodes/nodeFuncs.h"
|
||||
#ifdef OPTIMIZER_DEBUG
|
||||
#include "nodes/print.h"
|
||||
@ -34,6 +35,7 @@
|
||||
#include "parser/parse_clause.h"
|
||||
#include "parser/parsetree.h"
|
||||
#include "rewrite/rewriteManip.h"
|
||||
#include "utils/lsyscache.h"
|
||||
|
||||
|
||||
/* These parameters are set by GUC */
|
||||
@ -63,6 +65,8 @@ static void set_cte_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||
RangeTblEntry *rte);
|
||||
static void set_worktable_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||
RangeTblEntry *rte);
|
||||
static void set_foreign_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||
RangeTblEntry *rte);
|
||||
static RelOptInfo *make_rel_from_joinlist(PlannerInfo *root, List *joinlist);
|
||||
static bool subquery_is_pushdown_safe(Query *subquery, Query *topquery,
|
||||
bool *differentTypes);
|
||||
@ -197,9 +201,17 @@ set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Plain relation */
|
||||
Assert(rel->rtekind == RTE_RELATION);
|
||||
set_plain_rel_pathlist(root, rel, rte);
|
||||
if (get_rel_relkind(rte->relid) == RELKIND_FOREIGN_TABLE)
|
||||
{
|
||||
/* Foreign table */
|
||||
set_foreign_pathlist(root, rel, rte);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Plain relation */
|
||||
set_plain_rel_pathlist(root, rel, rte);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef OPTIMIZER_DEBUG
|
||||
@ -904,6 +916,23 @@ set_worktable_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
|
||||
set_cheapest(rel);
|
||||
}
|
||||
|
||||
/*
|
||||
* set_foreign_pathlist
|
||||
* Build the (single) access path for a foreign table RTE
|
||||
*/
|
||||
static void
|
||||
set_foreign_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
|
||||
{
|
||||
/* Mark rel with estimated output rows, width, etc */
|
||||
set_foreign_size_estimates(root, rel);
|
||||
|
||||
/* Generate appropriate path */
|
||||
add_path(rel, (Path *) create_foreignscan_path(root, rel));
|
||||
|
||||
/* Select cheapest path (pretty easy in this case...) */
|
||||
set_cheapest(rel);
|
||||
}
|
||||
|
||||
/*
|
||||
* make_rel_from_joinlist
|
||||
* Build access paths using a "joinlist" to guide the join path search.
|
||||
@ -1503,6 +1532,9 @@ print_path(PlannerInfo *root, Path *path, int indent)
|
||||
case T_TidPath:
|
||||
ptype = "TidScan";
|
||||
break;
|
||||
case T_ForeignPath:
|
||||
ptype = "ForeignScan";
|
||||
break;
|
||||
case T_AppendPath:
|
||||
ptype = "Append";
|
||||
break;
|
||||
|
@ -3324,6 +3324,34 @@ set_cte_size_estimates(PlannerInfo *root, RelOptInfo *rel, Plan *cteplan)
|
||||
set_baserel_size_estimates(root, rel);
|
||||
}
|
||||
|
||||
/*
|
||||
* set_foreign_size_estimates
|
||||
* Set the size estimates for a base relation that is a foreign table.
|
||||
*
|
||||
* There is not a whole lot that we can do here; the foreign-data wrapper
|
||||
* is responsible for producing useful estimates. We can do a decent job
|
||||
* of estimating baserestrictcost, so we set that, and we also set up width
|
||||
* using what will be purely datatype-driven estimates from the targetlist.
|
||||
* There is no way to do anything sane with the rows value, so we just put
|
||||
* a default estimate and hope that the wrapper can improve on it. The
|
||||
* wrapper's PlanForeignScan function will be called momentarily.
|
||||
*
|
||||
* The rel's targetlist and restrictinfo list must have been constructed
|
||||
* already.
|
||||
*/
|
||||
void
|
||||
set_foreign_size_estimates(PlannerInfo *root, RelOptInfo *rel)
|
||||
{
|
||||
/* Should only be applied to base relations */
|
||||
Assert(rel->relid > 0);
|
||||
|
||||
rel->rows = 1000; /* entirely bogus default estimate */
|
||||
|
||||
cost_qual_eval(&rel->baserestrictcost, rel->baserestrictinfo, root);
|
||||
|
||||
set_rel_width(root, rel);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* set_rel_width
|
||||
|
Reference in New Issue
Block a user