diff options
author | Robert Haas <rhaas@postgresql.org> | 2015-12-08 12:31:03 -0500 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2015-12-08 12:31:03 -0500 |
commit | 385f337c9f39b21dca96ca4770552a10a6d5af24 (patch) | |
tree | 5ca533100c4e832f830540b230ebd0bbe81aed05 /src/backend/optimizer/plan/createplan.c | |
parent | edca44b1525b3d591263d032dc4fe500ea771e0e (diff) | |
download | postgresql-385f337c9f39b21dca96ca4770552a10a6d5af24.tar.gz postgresql-385f337c9f39b21dca96ca4770552a10a6d5af24.zip |
Allow foreign and custom joins to handle EvalPlanQual rechecks.
Commit e7cb7ee14555cc9c5773e2c102efd6371f6f2005 provided basic
infrastructure for allowing a foreign data wrapper or custom scan
provider to replace a join of one or more tables with a scan.
However, this infrastructure failed to take into account the need
for possible EvalPlanQual rechecks, and ExecScanFetch would fail
an assertion (or just overwrite memory) if such a check was attempted
for a plan containing a pushed-down join. To fix, adjust the EPQ
machinery to skip some processing steps when scanrelid == 0, making
those the responsibility of scan's recheck method, which also has
the responsibility in this case of correctly populating the relevant
slot.
To allow foreign scans to gain control in the right place to make
use of this new facility, add a new, optional RecheckForeignScan
method. Also, allow a foreign scan to have a child plan, which can
be used to correctly populate the slot (or perhaps for something
else, but this is the only use currently envisioned).
KaiGai Kohei, reviewed by Robert Haas, Etsuro Fujita, and Kyotaro
Horiguchi.
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 411b36c418e..32f903d8dca 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -2095,11 +2095,16 @@ create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path, Index scan_relid = rel->relid; Oid rel_oid = InvalidOid; Bitmapset *attrs_used = NULL; + Plan *outer_plan = NULL; ListCell *lc; int i; Assert(rel->fdwroutine != NULL); + /* transform the child path if any */ + if (best_path->fdw_outerpath) + outer_plan = create_plan_recurse(root, best_path->fdw_outerpath); + /* * If we're scanning a base relation, fetch its OID. (Irrelevant if * scanning a join relation.) @@ -2129,7 +2134,8 @@ create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path, */ scan_plan = rel->fdwroutine->GetForeignPlan(root, rel, rel_oid, best_path, - tlist, scan_clauses); + tlist, scan_clauses, + outer_plan); /* Copy cost data from Path to Plan; no need to make FDW do this */ copy_generic_path_info(&scan_plan->scan.plan, &best_path->path); @@ -3747,7 +3753,8 @@ make_foreignscan(List *qptlist, List *fdw_exprs, List *fdw_private, List *fdw_scan_tlist, - List *fdw_recheck_quals) + List *fdw_recheck_quals, + Plan *outer_plan) { ForeignScan *node = makeNode(ForeignScan); Plan *plan = &node->scan.plan; @@ -3755,7 +3762,7 @@ make_foreignscan(List *qptlist, /* cost will be filled in by create_foreignscan_plan */ plan->targetlist = qptlist; plan->qual = qpqual; - plan->lefttree = NULL; + plan->lefttree = outer_plan; plan->righttree = NULL; node->scan.scanrelid = scanrelid; /* fs_server will be filled in by create_foreignscan_plan */ |