Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/commands/explain.c22
-rw-r--r--src/backend/optimizer/plan/createplan.c13
-rw-r--r--src/backend/optimizer/plan/setrefs.c8
-rw-r--r--src/backend/optimizer/plan/subselect.c25
4 files changed, 63 insertions, 5 deletions
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index a82c6ff7b4d..0d1ecc2a3ed 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -115,6 +115,8 @@ static void ExplainMemberNodes(List *plans, PlanState **planstates,
List *ancestors, ExplainState *es);
static void ExplainSubPlans(List *plans, List *ancestors,
const char *relationship, ExplainState *es);
+static void ExplainCustomChildren(CustomScanState *css,
+ List *ancestors, ExplainState *es);
static void ExplainProperty(const char *qlabel, const char *value,
bool numeric, ExplainState *es);
static void ExplainOpenGroup(const char *objtype, const char *labelname,
@@ -1624,6 +1626,8 @@ ExplainNode(PlanState *planstate, List *ancestors,
IsA(plan, BitmapAnd) ||
IsA(plan, BitmapOr) ||
IsA(plan, SubqueryScan) ||
+ (IsA(planstate, CustomScanState) &&
+ ((CustomScanState *) planstate)->custom_ps != NIL) ||
planstate->subPlan;
if (haschildren)
{
@@ -1678,6 +1682,10 @@ ExplainNode(PlanState *planstate, List *ancestors,
ExplainNode(((SubqueryScanState *) planstate)->subplan, ancestors,
"Subquery", NULL, es);
break;
+ case T_CustomScan:
+ ExplainCustomChildren((CustomScanState *) planstate,
+ ancestors, es);
+ break;
default:
break;
}
@@ -2648,6 +2656,20 @@ ExplainSubPlans(List *plans, List *ancestors,
}
/*
+ * Explain a list of children of a CustomScan.
+ */
+static void
+ExplainCustomChildren(CustomScanState *css, List *ancestors, ExplainState *es)
+{
+ ListCell *cell;
+ const char *label =
+ (list_length(css->custom_ps) != 1 ? "children" : "child");
+
+ foreach (cell, css->custom_ps)
+ ExplainNode((PlanState *) lfirst(cell), ancestors, label, NULL, es);
+}
+
+/*
* Explain a property, such as sort keys or targets, that takes the form of
* a list of unlabeled items. "data" is a list of C strings.
*/
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index a3482def643..dc2dcbf93f7 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -2157,6 +2157,16 @@ create_customscan_plan(PlannerInfo *root, CustomPath *best_path,
{
CustomScan *cplan;
RelOptInfo *rel = best_path->path.parent;
+ List *custom_plans = NIL;
+ ListCell *lc;
+
+ /* Recursively transform child paths. */
+ foreach (lc, best_path->custom_paths)
+ {
+ Plan *plan = create_plan_recurse(root, (Path *) lfirst(lc));
+
+ custom_plans = lappend(custom_plans, plan);
+ }
/*
* Sort clauses into the best execution order, although custom-scan
@@ -2172,7 +2182,8 @@ create_customscan_plan(PlannerInfo *root, CustomPath *best_path,
rel,
best_path,
tlist,
- scan_clauses);
+ scan_clauses,
+ custom_plans);
Assert(IsA(cplan, CustomScan));
/*
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index a7f65dd529f..c0641a7cfb0 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -1151,6 +1151,8 @@ set_customscan_references(PlannerInfo *root,
CustomScan *cscan,
int rtoffset)
{
+ ListCell *lc;
+
/* Adjust scanrelid if it's valid */
if (cscan->scan.scanrelid > 0)
cscan->scan.scanrelid += rtoffset;
@@ -1194,6 +1196,12 @@ set_customscan_references(PlannerInfo *root,
fix_scan_list(root, cscan->custom_exprs, rtoffset);
}
+ /* Adjust child plan-nodes recursively, if needed */
+ foreach (lc, cscan->custom_plans)
+ {
+ lfirst(lc) = set_plan_refs(root, (Plan *) lfirst(lc), rtoffset);
+ }
+
/* Adjust custom_relids if needed */
if (rtoffset > 0)
{
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index f80abb494c7..4708b87f330 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -2373,10 +2373,27 @@ finalize_plan(PlannerInfo *root, Plan *plan, Bitmapset *valid_params,
break;
case T_CustomScan:
- finalize_primnode((Node *) ((CustomScan *) plan)->custom_exprs,
- &context);
- /* We assume custom_scan_tlist cannot contain Params */
- context.paramids = bms_add_members(context.paramids, scan_params);
+ {
+ CustomScan *cscan = (CustomScan *) plan;
+ ListCell *lc;
+
+ finalize_primnode((Node *) cscan->custom_exprs,
+ &context);
+ /* We assume custom_scan_tlist cannot contain Params */
+ context.paramids =
+ bms_add_members(context.paramids, scan_params);
+
+ /* child nodes if any */
+ foreach (lc, cscan->custom_plans)
+ {
+ context.paramids =
+ bms_add_members(context.paramids,
+ finalize_plan(root,
+ (Plan *) lfirst(lc),
+ valid_params,
+ scan_params));
+ }
+ }
break;
case T_ModifyTable: