diff options
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 83 |
1 files changed, 25 insertions, 58 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 3246332d6e3..c8092372831 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -44,6 +44,7 @@ #include "utils/lsyscache.h" +static Plan *create_plan_recurse(PlannerInfo *root, Path *best_path); static Plan *create_scan_plan(PlannerInfo *root, Path *best_path); static List *build_path_tlist(PlannerInfo *root, Path *path); static bool use_physical_tlist(PlannerInfo *root, RelOptInfo *rel); @@ -219,7 +220,7 @@ create_plan(PlannerInfo *root, Path *best_path) * create_plan_recurse * Recursive guts of create_plan(). */ -Plan * +static Plan * create_plan_recurse(PlannerInfo *root, Path *best_path) { Plan *plan; @@ -1950,7 +1951,7 @@ create_worktablescan_plan(PlannerInfo *root, Path *best_path, /* * create_foreignscan_plan - * Returns a foreignscan plan for the base relation scanned by 'best_path' + * Returns a foreignscan plan for the relation scanned by 'best_path' * with restriction clauses 'scan_clauses' and targetlist 'tlist'. */ static ForeignScan * @@ -1965,9 +1966,11 @@ create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path, ListCell *lc; int i; + Assert(rel->fdwroutine != NULL); + /* - * If we're scanning a base relation, look up the OID. - * (We can skip this if scanning a join relation.) + * If we're scanning a base relation, fetch its OID. (Irrelevant if + * scanning a join relation.) */ if (scan_relid > 0) { @@ -1978,7 +1981,6 @@ create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path, Assert(rte->rtekind == RTE_RELATION); rel_oid = rte->relid; } - Assert(rel->fdwroutine != NULL); /* * Sort clauses into best execution order. We do this first since the FDW @@ -1996,42 +1998,22 @@ create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path, scan_plan = rel->fdwroutine->GetForeignPlan(root, rel, rel_oid, best_path, tlist, scan_clauses); - /* - * Sanity check. There may be resjunk entries in fdw_ps_tlist that - * are included only to help EXPLAIN deparse plans properly. We require - * that these are at the end, so that when the executor builds the scan - * descriptor based on the non-junk entries, it gets the attribute - * numbers correct. - */ - if (scan_plan->scan.scanrelid == 0) - { - bool found_resjunk = false; - - foreach (lc, scan_plan->fdw_ps_tlist) - { - TargetEntry *tle = lfirst(lc); - - if (tle->resjunk) - found_resjunk = true; - else if (found_resjunk) - elog(ERROR, "junk TLE should not apper prior to valid one"); - } - } - /* Set the relids that are represented by this foreign scan for Explain */ - scan_plan->fdw_relids = best_path->path.parent->relids; /* Copy cost data from Path to Plan; no need to make FDW do this */ copy_path_costsize(&scan_plan->scan.plan, &best_path->path); - /* Track FDW server-id; no need to make FDW do this */ - scan_plan->fdw_handler = rel->fdw_handler; + /* Copy foreign server OID; likewise, no need to make FDW do this */ + scan_plan->fs_server = rel->serverid; + + /* Likewise, copy the relids that are represented by this foreign scan */ + scan_plan->fs_relids = best_path->path.parent->relids; /* * Replace any outer-relation variables with nestloop params in the qual * and fdw_exprs expressions. We do this last so that the FDW doesn't * have to be involved. (Note that parts of fdw_exprs could have come * from join clauses, so doing this beforehand on the scan_clauses - * wouldn't work.) + * wouldn't work.) We assume fdw_scan_tlist contains no such variables. */ if (best_path->path.param_info) { @@ -2087,7 +2069,6 @@ create_customscan_plan(PlannerInfo *root, CustomPath *best_path, { CustomScan *cplan; RelOptInfo *rel = best_path->path.parent; - ListCell *lc; /* * Sort clauses into the best execution order, although custom-scan @@ -2107,41 +2088,21 @@ create_customscan_plan(PlannerInfo *root, CustomPath *best_path, Assert(IsA(cplan, CustomScan)); /* - * Sanity check. There may be resjunk entries in custom_ps_tlist that - * are included only to help EXPLAIN deparse plans properly. We require - * that these are at the end, so that when the executor builds the scan - * descriptor based on the non-junk entries, it gets the attribute - * numbers correct. - */ - if (cplan->scan.scanrelid == 0) - { - bool found_resjunk = false; - - foreach (lc, cplan->custom_ps_tlist) - { - TargetEntry *tle = lfirst(lc); - - if (tle->resjunk) - found_resjunk = true; - else if (found_resjunk) - elog(ERROR, "junk TLE should not apper prior to valid one"); - } - } - /* Set the relids that are represented by this custom scan for Explain */ - cplan->custom_relids = best_path->path.parent->relids; - - /* * Copy cost data from Path to Plan; no need to make custom-plan providers * do this */ copy_path_costsize(&cplan->scan.plan, &best_path->path); + /* Likewise, copy the relids that are represented by this custom scan */ + cplan->custom_relids = best_path->path.parent->relids; + /* * Replace any outer-relation variables with nestloop params in the qual * and custom_exprs expressions. We do this last so that the custom-plan * provider doesn't have to be involved. (Note that parts of custom_exprs * could have come from join clauses, so doing this beforehand on the - * scan_clauses wouldn't work.) + * scan_clauses wouldn't work.) We assume custom_scan_tlist contains no + * such variables. */ if (best_path->path.param_info) { @@ -3611,7 +3572,8 @@ make_foreignscan(List *qptlist, List *qpqual, Index scanrelid, List *fdw_exprs, - List *fdw_private) + List *fdw_private, + List *fdw_scan_tlist) { ForeignScan *node = makeNode(ForeignScan); Plan *plan = &node->scan.plan; @@ -3622,8 +3584,13 @@ make_foreignscan(List *qptlist, plan->lefttree = NULL; plan->righttree = NULL; node->scan.scanrelid = scanrelid; + /* fs_server will be filled in by create_foreignscan_plan */ + node->fs_server = InvalidOid; node->fdw_exprs = fdw_exprs; node->fdw_private = fdw_private; + node->fdw_scan_tlist = fdw_scan_tlist; + /* fs_relids will be filled in by create_foreignscan_plan */ + node->fs_relids = NULL; /* fsSystemCol will be filled in by create_foreignscan_plan */ node->fsSystemCol = false; |