diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/executor/execAmi.c | 44 | ||||
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 97 | ||||
-rw-r--r-- | src/backend/optimizer/plan/setrefs.c | 13 | ||||
-rw-r--r-- | src/backend/optimizer/util/pathnode.c | 15 |
4 files changed, 88 insertions, 81 deletions
diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c index b14e08cd1a..643aaace3a 100644 --- a/src/backend/executor/execAmi.c +++ b/src/backend/executor/execAmi.c @@ -381,11 +381,14 @@ ExecRestrPos(PlanState *node) } /* - * ExecSupportsMarkRestore - does a plan type support mark/restore? + * ExecSupportsMarkRestore - does a Path support mark/restore? + * + * This is used during planning and so must accept a Path, not a Plan. + * We keep it here to be adjacent to the routines above, which also must + * know which plan types support mark/restore. * * XXX Ideally, all plan node types would support mark/restore, and this * wouldn't be needed. For now, this had better match the routines above. - * But note the test is on Plan nodetype, not PlanState nodetype. * * (However, since the only present use of mark/restore is in mergejoin, * there is no need to support mark/restore in any plan type that is not @@ -395,6 +398,11 @@ ExecRestrPos(PlanState *node) bool ExecSupportsMarkRestore(Path *pathnode) { + /* + * For consistency with the routines above, we do not examine the nodeTag + * but rather the pathtype, which is the Plan node type the Path would + * produce. + */ switch (pathnode->pathtype) { case T_SeqScan: @@ -406,27 +414,23 @@ ExecSupportsMarkRestore(Path *pathnode) case T_Sort: return true; + case T_CustomScan: + Assert(IsA(pathnode, CustomPath)); + if (((CustomPath *) pathnode)->flags & CUSTOMPATH_SUPPORT_MARK_RESTORE) + return true; + return false; + case T_Result: /* - * T_Result only supports mark/restore if it has a child plan that - * does, so we do not have enough information to give a really - * correct answer. However, for current uses it's enough to - * always say "false", because this routine is not asked about - * gating Result plans, only base-case Results. + * Although Result supports mark/restore if it has a child plan + * that does, we presently come here only for ResultPath nodes, + * which represent Result plans without a child plan. So there is + * nothing to recurse to and we can just say "false". */ + Assert(IsA(pathnode, ResultPath)); return false; - case T_CustomScan: - { - CustomPath *cpath = (CustomPath *) pathnode; - - Assert(IsA(cpath, CustomPath)); - if (cpath->flags & CUSTOMPATH_SUPPORT_MARK_RESTORE) - return true; - } - break; - default: break; } @@ -491,10 +495,10 @@ ExecSupportsBackwardScan(Plan *node) case T_CustomScan: { - uint32 flags = ((CustomScan *) node)->flags; + uint32 flags = ((CustomScan *) node)->flags; - if (TargetListSupportsBackwardScan(node->targetlist) && - (flags & CUSTOMPATH_SUPPORT_BACKWARD_SCAN) != 0) + if ((flags & CUSTOMPATH_SUPPORT_BACKWARD_SCAN) && + TargetListSupportsBackwardScan(node->targetlist)) return true; } return false; diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 0a85cd9906..e6bd4c326c 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -78,8 +78,8 @@ static WorkTableScan *create_worktablescan_plan(PlannerInfo *root, Path *best_pa static ForeignScan *create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path, List *tlist, List *scan_clauses); static Plan *create_customscan_plan(PlannerInfo *root, - CustomPath *best_path, - List *tlist, List *scan_clauses); + CustomPath *best_path, + List *tlist, List *scan_clauses); static NestLoop *create_nestloop_plan(PlannerInfo *root, NestPath *best_path, Plan *outer_plan, Plan *inner_plan); static MergeJoin *create_mergejoin_plan(PlannerInfo *root, MergePath *best_path, @@ -1083,52 +1083,6 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path) return plan; } -/* - * create_custom_plan - * - * Transform a CustomPath into a Plan. - */ -static Plan * -create_customscan_plan(PlannerInfo *root, CustomPath *best_path, - List *tlist, List *scan_clauses) -{ - Plan *plan; - RelOptInfo *rel = best_path->path.parent; - - /* - * Right now, all we can support is CustomScan node which is associated - * with a particular base relation to be scanned. - */ - Assert(rel && rel->reloptkind == RELOPT_BASEREL); - - /* - * Sort clauses into the best execution order, although custom-scan - * provider can reorder them again. - */ - scan_clauses = order_qual_clauses(root, scan_clauses); - - /* - * Create a CustomScan (or its inheritance) node according to - * the supplied CustomPath. - */ - plan = best_path->methods->PlanCustomPath(root, rel, best_path, tlist, - scan_clauses); - - /* - * NOTE: unlike create_foreignscan_plan(), it is responsibility of - * the custom plan provider to replace outer-relation variables - * with nestloop params, because we cannot know how many expression - * trees are held in the private fields. - */ - - /* - * Copy cost data from Path to Plan; no need to make custom-plan - * providers do this - */ - copy_path_costsize(plan, &best_path->path); - - return plan; -} /***************************************************************************** * @@ -2063,6 +2017,53 @@ create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path, return scan_plan; } +/* + * create_custom_plan + * + * Transform a CustomPath into a Plan. + */ +static Plan * +create_customscan_plan(PlannerInfo *root, CustomPath *best_path, + List *tlist, List *scan_clauses) +{ + Plan *plan; + RelOptInfo *rel = best_path->path.parent; + + /* + * Right now, all we can support is CustomScan node which is associated + * with a particular base relation to be scanned. + */ + Assert(rel && rel->reloptkind == RELOPT_BASEREL); + + /* + * Sort clauses into the best execution order, although custom-scan + * provider can reorder them again. + */ + scan_clauses = order_qual_clauses(root, scan_clauses); + + /* + * Invoke custom plan provider to create the Plan node represented by the + * CustomPath. + */ + plan = best_path->methods->PlanCustomPath(root, rel, best_path, tlist, + scan_clauses); + + /* + * NOTE: unlike create_foreignscan_plan(), it is the responsibility of the + * custom plan provider to replace outer-relation variables with nestloop + * params, because we cannot know what expression trees may be held in + * private fields. + */ + + /* + * Copy cost data from Path to Plan; no need to make custom-plan providers + * do this + */ + copy_path_costsize(plan, &best_path->path); + + return plan; +} + /***************************************************************************** * diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index bbc68a05a6..e42972750b 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -587,12 +587,13 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) fix_scan_list(root, cscan->scan.plan.targetlist, rtoffset); cscan->scan.plan.qual = fix_scan_list(root, cscan->scan.plan.qual, rtoffset); + /* - * The core implementation applies the routine to fixup - * varno on the target-list and scan qualifier. - * If custom-scan has additional expression nodes on its - * private fields, it has to apply same fixup on them. - * Otherwise, the custom-plan provider can skip this callback. + * The core implementation applies the routine to fixup varno + * on the target-list and scan qualifier. If custom-scan has + * additional expression nodes on its private fields, it has + * to apply same fixup on them. Otherwise, the custom-plan + * provider can skip this callback. */ if (cscan->methods->SetCustomScanRef) cscan->methods->SetCustomScanRef(root, cscan, rtoffset); @@ -1083,7 +1084,7 @@ copyVar(Var *var) * We assume it's okay to update opcode info in-place. So this could possibly * scribble on the planner's input data structures, but it's OK. */ -void +static void fix_expr_common(PlannerInfo *root, Node *node) { /* We assume callers won't call us on a NULL pointer */ diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index 6f1c6cfb2a..121b9ff3e4 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -1929,10 +1929,10 @@ reparameterize_path(PlannerInfo *root, Path *path, } /***************************************************************************** - * creation of custom-plan paths + * creation of custom-plan paths *****************************************************************************/ -static List *custom_path_providers = NIL; +static List *custom_path_providers = NIL; /* * register_custom_path_provider @@ -1942,12 +1942,13 @@ static List *custom_path_providers = NIL; * methods of scanning a relation. */ void -register_custom_path_provider(CustomPathMethods *cpp_methods) +register_custom_path_provider(const CustomPathMethods *cpp_methods) { - MemoryContext oldcxt; + MemoryContext oldcxt; oldcxt = MemoryContextSwitchTo(TopMemoryContext); - custom_path_providers = lappend(custom_path_providers, cpp_methods); + custom_path_providers = lappend(custom_path_providers, + (void *) cpp_methods); MemoryContextSwitchTo(oldcxt); } @@ -1963,9 +1964,9 @@ create_customscan_paths(PlannerInfo *root, RelOptInfo *baserel, RangeTblEntry *rte) { - ListCell *cell; + ListCell *cell; - foreach (cell, custom_path_providers) + foreach(cell, custom_path_providers) { const CustomPathMethods *cpp_methods = lfirst(cell); |