Commit 6ef77cf4 authored by Tom Lane's avatar Tom Lane

Further adjust EXPLAIN's choices of table alias names.

This patch causes EXPLAIN to always assign a separate table alias to the
parent RTE of an append relation (inheritance set); before, such RTEs
were ignored if not actually scanned by the plan.  Since the child RTEs
now always have that same alias to start with (cf. commit 55a1954d),
the net effect is that the parent RTE usually gets the alias used or
implied by the query text, and the children all get that alias with "_N"
appended.  (The exception to "usually" is if there are duplicate aliases
in different subtrees of the original query; then some of those original
RTEs will also have "_N" appended.)

This results in more uniform output for partitioned-table plans than
we had before: the partitioned table itself gets the original alias,
and all child tables have aliases with "_N", rather than the previous
behavior where one of the children would get an alias without "_N".

The reason for giving the parent RTE an alias, even if it isn't scanned
by the plan, is that we now use the parent's alias to qualify Vars that
refer to an appendrel output column and appear above the Append or
MergeAppend that computes the appendrel.  But below the append, Vars
refer to some one of the child relations, and are displayed that way.
This seems clearer than the old behavior where a Var that could carry
values from any child relation was displayed as if it referred to only
one of them.

While at it, change ruleutils.c so that the code paths used by EXPLAIN
deal in Plan trees not PlanState trees.  This effectively reverts a
decision made in commit 1cc29fe7, which seemed like a good idea at
the time to make ruleutils.c consistent with explain.c.  However,
it's problematic because we'd really like to allow executor startup
pruning to remove all the children of an append node when possible,
leaving no child PlanState to resolve Vars against.  (That's not done
here, but will be in the next patch.)  This requires different handling
of subplans and initplans than before, but is otherwise a pretty
straightforward change.

Discussion: https://postgr.es/m/001001d4f44b$2a2cca50$7e865ef0$@lab.ntt.co.jp
parent ba79cb5d
...@@ -689,7 +689,7 @@ ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc) ...@@ -689,7 +689,7 @@ ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc)
es->rtable = queryDesc->plannedstmt->rtable; es->rtable = queryDesc->plannedstmt->rtable;
ExplainPreScanNode(queryDesc->planstate, &rels_used); ExplainPreScanNode(queryDesc->planstate, &rels_used);
es->rtable_names = select_rtable_names_for_explain(es->rtable, rels_used); es->rtable_names = select_rtable_names_for_explain(es->rtable, rels_used);
es->deparse_cxt = deparse_context_for_plan_rtable(es->rtable, es->deparse_cxt = deparse_context_for_plan_tree(queryDesc->plannedstmt,
es->rtable_names); es->rtable_names);
es->printed_subplans = NULL; es->printed_subplans = NULL;
...@@ -1034,6 +1034,14 @@ ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used) ...@@ -1034,6 +1034,14 @@ ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used)
*rels_used = bms_add_member(*rels_used, *rels_used = bms_add_member(*rels_used,
((ModifyTable *) plan)->exclRelRTI); ((ModifyTable *) plan)->exclRelRTI);
break; break;
case T_Append:
*rels_used = bms_add_members(*rels_used,
((Append *) plan)->apprelids);
break;
case T_MergeAppend:
*rels_used = bms_add_members(*rels_used,
((MergeAppend *) plan)->apprelids);
break;
default: default:
break; break;
} }
...@@ -1049,8 +1057,8 @@ ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used) ...@@ -1049,8 +1057,8 @@ ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used)
* We need to work from a PlanState node, not just a Plan node, in order to * We need to work from a PlanState node, not just a Plan node, in order to
* get at the instrumentation data (if any) as well as the list of subplans. * get at the instrumentation data (if any) as well as the list of subplans.
* *
* ancestors is a list of parent PlanState nodes, most-closely-nested first. * ancestors is a list of parent Plan and SubPlan nodes, most-closely-nested
* These are needed in order to interpret PARAM_EXEC Params. * first. These are needed in order to interpret PARAM_EXEC Params.
* *
* relationship describes the relationship of this plan node to its parent * relationship describes the relationship of this plan node to its parent
* (eg, "Outer", "Inner"); it can be null at top level. plan_name is an * (eg, "Outer", "Inner"); it can be null at top level. plan_name is an
...@@ -1953,8 +1961,8 @@ ExplainNode(PlanState *planstate, List *ancestors, ...@@ -1953,8 +1961,8 @@ ExplainNode(PlanState *planstate, List *ancestors,
if (haschildren) if (haschildren)
{ {
ExplainOpenGroup("Plans", "Plans", false, es); ExplainOpenGroup("Plans", "Plans", false, es);
/* Pass current PlanState as head of ancestors list for children */ /* Pass current Plan as head of ancestors list for children */
ancestors = lcons(planstate, ancestors); ancestors = lcons(plan, ancestors);
} }
/* initPlan-s */ /* initPlan-s */
...@@ -2075,8 +2083,8 @@ show_plan_tlist(PlanState *planstate, List *ancestors, ExplainState *es) ...@@ -2075,8 +2083,8 @@ show_plan_tlist(PlanState *planstate, List *ancestors, ExplainState *es)
return; return;
/* Set up deparsing context */ /* Set up deparsing context */
context = set_deparse_context_planstate(es->deparse_cxt, context = set_deparse_context_plan(es->deparse_cxt,
(Node *) planstate, plan,
ancestors); ancestors);
useprefix = list_length(es->rtable) > 1; useprefix = list_length(es->rtable) > 1;
...@@ -2106,8 +2114,8 @@ show_expression(Node *node, const char *qlabel, ...@@ -2106,8 +2114,8 @@ show_expression(Node *node, const char *qlabel,
char *exprstr; char *exprstr;
/* Set up deparsing context */ /* Set up deparsing context */
context = set_deparse_context_planstate(es->deparse_cxt, context = set_deparse_context_plan(es->deparse_cxt,
(Node *) planstate, planstate->plan,
ancestors); ancestors);
/* Deparse the expression */ /* Deparse the expression */
...@@ -2209,7 +2217,7 @@ show_agg_keys(AggState *astate, List *ancestors, ...@@ -2209,7 +2217,7 @@ show_agg_keys(AggState *astate, List *ancestors,
if (plan->numCols > 0 || plan->groupingSets) if (plan->numCols > 0 || plan->groupingSets)
{ {
/* The key columns refer to the tlist of the child plan */ /* The key columns refer to the tlist of the child plan */
ancestors = lcons(astate, ancestors); ancestors = lcons(plan, ancestors);
if (plan->groupingSets) if (plan->groupingSets)
show_grouping_sets(outerPlanState(astate), plan, ancestors, es); show_grouping_sets(outerPlanState(astate), plan, ancestors, es);
...@@ -2232,8 +2240,8 @@ show_grouping_sets(PlanState *planstate, Agg *agg, ...@@ -2232,8 +2240,8 @@ show_grouping_sets(PlanState *planstate, Agg *agg,
ListCell *lc; ListCell *lc;
/* Set up deparsing context */ /* Set up deparsing context */
context = set_deparse_context_planstate(es->deparse_cxt, context = set_deparse_context_plan(es->deparse_cxt,
(Node *) planstate, planstate->plan,
ancestors); ancestors);
useprefix = (list_length(es->rtable) > 1 || es->verbose); useprefix = (list_length(es->rtable) > 1 || es->verbose);
...@@ -2339,7 +2347,7 @@ show_group_keys(GroupState *gstate, List *ancestors, ...@@ -2339,7 +2347,7 @@ show_group_keys(GroupState *gstate, List *ancestors,
Group *plan = (Group *) gstate->ss.ps.plan; Group *plan = (Group *) gstate->ss.ps.plan;
/* The key columns refer to the tlist of the child plan */ /* The key columns refer to the tlist of the child plan */
ancestors = lcons(gstate, ancestors); ancestors = lcons(plan, ancestors);
show_sort_group_keys(outerPlanState(gstate), "Group Key", show_sort_group_keys(outerPlanState(gstate), "Group Key",
plan->numCols, plan->grpColIdx, plan->numCols, plan->grpColIdx,
NULL, NULL, NULL, NULL, NULL, NULL,
...@@ -2371,8 +2379,8 @@ show_sort_group_keys(PlanState *planstate, const char *qlabel, ...@@ -2371,8 +2379,8 @@ show_sort_group_keys(PlanState *planstate, const char *qlabel,
initStringInfo(&sortkeybuf); initStringInfo(&sortkeybuf);
/* Set up deparsing context */ /* Set up deparsing context */
context = set_deparse_context_planstate(es->deparse_cxt, context = set_deparse_context_plan(es->deparse_cxt,
(Node *) planstate, plan,
ancestors); ancestors);
useprefix = (list_length(es->rtable) > 1 || es->verbose); useprefix = (list_length(es->rtable) > 1 || es->verbose);
...@@ -2479,8 +2487,8 @@ show_tablesample(TableSampleClause *tsc, PlanState *planstate, ...@@ -2479,8 +2487,8 @@ show_tablesample(TableSampleClause *tsc, PlanState *planstate,
ListCell *lc; ListCell *lc;
/* Set up deparsing context */ /* Set up deparsing context */
context = set_deparse_context_planstate(es->deparse_cxt, context = set_deparse_context_plan(es->deparse_cxt,
(Node *) planstate, planstate->plan,
ancestors); ancestors);
useprefix = list_length(es->rtable) > 1; useprefix = list_length(es->rtable) > 1;
...@@ -3344,7 +3352,7 @@ ExplainMemberNodes(PlanState **planstates, int nsubnodes, int nplans, ...@@ -3344,7 +3352,7 @@ ExplainMemberNodes(PlanState **planstates, int nsubnodes, int nplans,
* Explain a list of SubPlans (or initPlans, which also use SubPlan nodes). * Explain a list of SubPlans (or initPlans, which also use SubPlan nodes).
* *
* The ancestors list should already contain the immediate parent of these * The ancestors list should already contain the immediate parent of these
* SubPlanStates. * SubPlans.
*/ */
static void static void
ExplainSubPlans(List *plans, List *ancestors, ExplainSubPlans(List *plans, List *ancestors,
...@@ -3372,8 +3380,17 @@ ExplainSubPlans(List *plans, List *ancestors, ...@@ -3372,8 +3380,17 @@ ExplainSubPlans(List *plans, List *ancestors,
es->printed_subplans = bms_add_member(es->printed_subplans, es->printed_subplans = bms_add_member(es->printed_subplans,
sp->plan_id); sp->plan_id);
/*
* Treat the SubPlan node as an ancestor of the plan node(s) within
* it, so that ruleutils.c can find the referents of subplan
* parameters.
*/
ancestors = lcons(sp, ancestors);
ExplainNode(sps->planstate, ancestors, ExplainNode(sps->planstate, ancestors,
relationship, sp->plan_name, es); relationship, sp->plan_name, es);
ancestors = list_delete_first(ancestors);
} }
} }
......
...@@ -181,6 +181,8 @@ ExecSerializePlan(Plan *plan, EState *estate) ...@@ -181,6 +181,8 @@ ExecSerializePlan(Plan *plan, EState *estate)
pstmt->planTree = plan; pstmt->planTree = plan;
pstmt->rtable = estate->es_range_table; pstmt->rtable = estate->es_range_table;
pstmt->resultRelations = NIL; pstmt->resultRelations = NIL;
pstmt->rootResultRelations = NIL;
pstmt->appendRelations = NIL;
/* /*
* Transfer only parallel-safe subplans, leaving a NULL "hole" in the list * Transfer only parallel-safe subplans, leaving a NULL "hole" in the list
......
...@@ -2526,9 +2526,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) ...@@ -2526,9 +2526,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
econtext = mtstate->ps.ps_ExprContext; econtext = mtstate->ps.ps_ExprContext;
relationDesc = resultRelInfo->ri_RelationDesc->rd_att; relationDesc = resultRelInfo->ri_RelationDesc->rd_att;
/* carried forward solely for the benefit of explain */
mtstate->mt_excludedtlist = node->exclRelTlist;
/* create state for DO UPDATE SET operation */ /* create state for DO UPDATE SET operation */
resultRelInfo->ri_onConflict = makeNode(OnConflictSetState); resultRelInfo->ri_onConflict = makeNode(OnConflictSetState);
......
...@@ -92,6 +92,7 @@ _copyPlannedStmt(const PlannedStmt *from) ...@@ -92,6 +92,7 @@ _copyPlannedStmt(const PlannedStmt *from)
COPY_NODE_FIELD(rtable); COPY_NODE_FIELD(rtable);
COPY_NODE_FIELD(resultRelations); COPY_NODE_FIELD(resultRelations);
COPY_NODE_FIELD(rootResultRelations); COPY_NODE_FIELD(rootResultRelations);
COPY_NODE_FIELD(appendRelations);
COPY_NODE_FIELD(subplans); COPY_NODE_FIELD(subplans);
COPY_BITMAPSET_FIELD(rewindPlanIDs); COPY_BITMAPSET_FIELD(rewindPlanIDs);
COPY_NODE_FIELD(rowMarks); COPY_NODE_FIELD(rowMarks);
...@@ -241,6 +242,7 @@ _copyAppend(const Append *from) ...@@ -241,6 +242,7 @@ _copyAppend(const Append *from)
/* /*
* copy remainder of node * copy remainder of node
*/ */
COPY_BITMAPSET_FIELD(apprelids);
COPY_NODE_FIELD(appendplans); COPY_NODE_FIELD(appendplans);
COPY_SCALAR_FIELD(first_partial_plan); COPY_SCALAR_FIELD(first_partial_plan);
COPY_NODE_FIELD(part_prune_info); COPY_NODE_FIELD(part_prune_info);
...@@ -264,6 +266,7 @@ _copyMergeAppend(const MergeAppend *from) ...@@ -264,6 +266,7 @@ _copyMergeAppend(const MergeAppend *from)
/* /*
* copy remainder of node * copy remainder of node
*/ */
COPY_BITMAPSET_FIELD(apprelids);
COPY_NODE_FIELD(mergeplans); COPY_NODE_FIELD(mergeplans);
COPY_SCALAR_FIELD(numCols); COPY_SCALAR_FIELD(numCols);
COPY_POINTER_FIELD(sortColIdx, from->numCols * sizeof(AttrNumber)); COPY_POINTER_FIELD(sortColIdx, from->numCols * sizeof(AttrNumber));
......
...@@ -310,6 +310,7 @@ _outPlannedStmt(StringInfo str, const PlannedStmt *node) ...@@ -310,6 +310,7 @@ _outPlannedStmt(StringInfo str, const PlannedStmt *node)
WRITE_NODE_FIELD(rtable); WRITE_NODE_FIELD(rtable);
WRITE_NODE_FIELD(resultRelations); WRITE_NODE_FIELD(resultRelations);
WRITE_NODE_FIELD(rootResultRelations); WRITE_NODE_FIELD(rootResultRelations);
WRITE_NODE_FIELD(appendRelations);
WRITE_NODE_FIELD(subplans); WRITE_NODE_FIELD(subplans);
WRITE_BITMAPSET_FIELD(rewindPlanIDs); WRITE_BITMAPSET_FIELD(rewindPlanIDs);
WRITE_NODE_FIELD(rowMarks); WRITE_NODE_FIELD(rowMarks);
...@@ -431,6 +432,7 @@ _outAppend(StringInfo str, const Append *node) ...@@ -431,6 +432,7 @@ _outAppend(StringInfo str, const Append *node)
_outPlanInfo(str, (const Plan *) node); _outPlanInfo(str, (const Plan *) node);
WRITE_BITMAPSET_FIELD(apprelids);
WRITE_NODE_FIELD(appendplans); WRITE_NODE_FIELD(appendplans);
WRITE_INT_FIELD(first_partial_plan); WRITE_INT_FIELD(first_partial_plan);
WRITE_NODE_FIELD(part_prune_info); WRITE_NODE_FIELD(part_prune_info);
...@@ -443,6 +445,7 @@ _outMergeAppend(StringInfo str, const MergeAppend *node) ...@@ -443,6 +445,7 @@ _outMergeAppend(StringInfo str, const MergeAppend *node)
_outPlanInfo(str, (const Plan *) node); _outPlanInfo(str, (const Plan *) node);
WRITE_BITMAPSET_FIELD(apprelids);
WRITE_NODE_FIELD(mergeplans); WRITE_NODE_FIELD(mergeplans);
WRITE_INT_FIELD(numCols); WRITE_INT_FIELD(numCols);
WRITE_ATTRNUMBER_ARRAY(sortColIdx, node->numCols); WRITE_ATTRNUMBER_ARRAY(sortColIdx, node->numCols);
...@@ -2167,6 +2170,7 @@ _outPlannerGlobal(StringInfo str, const PlannerGlobal *node) ...@@ -2167,6 +2170,7 @@ _outPlannerGlobal(StringInfo str, const PlannerGlobal *node)
WRITE_NODE_FIELD(finalrowmarks); WRITE_NODE_FIELD(finalrowmarks);
WRITE_NODE_FIELD(resultRelations); WRITE_NODE_FIELD(resultRelations);
WRITE_NODE_FIELD(rootResultRelations); WRITE_NODE_FIELD(rootResultRelations);
WRITE_NODE_FIELD(appendRelations);
WRITE_NODE_FIELD(relationOids); WRITE_NODE_FIELD(relationOids);
WRITE_NODE_FIELD(invalItems); WRITE_NODE_FIELD(invalItems);
WRITE_NODE_FIELD(paramExecTypes); WRITE_NODE_FIELD(paramExecTypes);
......
...@@ -1512,6 +1512,7 @@ _readPlannedStmt(void) ...@@ -1512,6 +1512,7 @@ _readPlannedStmt(void)
READ_NODE_FIELD(rtable); READ_NODE_FIELD(rtable);
READ_NODE_FIELD(resultRelations); READ_NODE_FIELD(resultRelations);
READ_NODE_FIELD(rootResultRelations); READ_NODE_FIELD(rootResultRelations);
READ_NODE_FIELD(appendRelations);
READ_NODE_FIELD(subplans); READ_NODE_FIELD(subplans);
READ_BITMAPSET_FIELD(rewindPlanIDs); READ_BITMAPSET_FIELD(rewindPlanIDs);
READ_NODE_FIELD(rowMarks); READ_NODE_FIELD(rowMarks);
...@@ -1636,6 +1637,7 @@ _readAppend(void) ...@@ -1636,6 +1637,7 @@ _readAppend(void)
ReadCommonPlan(&local_node->plan); ReadCommonPlan(&local_node->plan);
READ_BITMAPSET_FIELD(apprelids);
READ_NODE_FIELD(appendplans); READ_NODE_FIELD(appendplans);
READ_INT_FIELD(first_partial_plan); READ_INT_FIELD(first_partial_plan);
READ_NODE_FIELD(part_prune_info); READ_NODE_FIELD(part_prune_info);
...@@ -1653,6 +1655,7 @@ _readMergeAppend(void) ...@@ -1653,6 +1655,7 @@ _readMergeAppend(void)
ReadCommonPlan(&local_node->plan); ReadCommonPlan(&local_node->plan);
READ_BITMAPSET_FIELD(apprelids);
READ_NODE_FIELD(mergeplans); READ_NODE_FIELD(mergeplans);
READ_INT_FIELD(numCols); READ_INT_FIELD(numCols);
READ_ATTRNUMBER_ARRAY(sortColIdx, local_node->numCols); READ_ATTRNUMBER_ARRAY(sortColIdx, local_node->numCols);
......
...@@ -1118,6 +1118,7 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags) ...@@ -1118,6 +1118,7 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags)
plan->plan.qual = NIL; plan->plan.qual = NIL;
plan->plan.lefttree = NULL; plan->plan.lefttree = NULL;
plan->plan.righttree = NULL; plan->plan.righttree = NULL;
plan->apprelids = rel->relids;
if (pathkeys != NIL) if (pathkeys != NIL)
{ {
...@@ -1295,6 +1296,7 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path, ...@@ -1295,6 +1296,7 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path,
plan->qual = NIL; plan->qual = NIL;
plan->lefttree = NULL; plan->lefttree = NULL;
plan->righttree = NULL; plan->righttree = NULL;
node->apprelids = rel->relids;
/* /*
* Compute sort column info, and adjust MergeAppend's tlist as needed. * Compute sort column info, and adjust MergeAppend's tlist as needed.
......
...@@ -304,6 +304,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) ...@@ -304,6 +304,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
glob->finalrowmarks = NIL; glob->finalrowmarks = NIL;
glob->resultRelations = NIL; glob->resultRelations = NIL;
glob->rootResultRelations = NIL; glob->rootResultRelations = NIL;
glob->appendRelations = NIL;
glob->relationOids = NIL; glob->relationOids = NIL;
glob->invalItems = NIL; glob->invalItems = NIL;
glob->paramExecTypes = NIL; glob->paramExecTypes = NIL;
...@@ -494,6 +495,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) ...@@ -494,6 +495,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
Assert(glob->finalrowmarks == NIL); Assert(glob->finalrowmarks == NIL);
Assert(glob->resultRelations == NIL); Assert(glob->resultRelations == NIL);
Assert(glob->rootResultRelations == NIL); Assert(glob->rootResultRelations == NIL);
Assert(glob->appendRelations == NIL);
top_plan = set_plan_references(root, top_plan); top_plan = set_plan_references(root, top_plan);
/* ... and the subplans (both regular subplans and initplans) */ /* ... and the subplans (both regular subplans and initplans) */
Assert(list_length(glob->subplans) == list_length(glob->subroots)); Assert(list_length(glob->subplans) == list_length(glob->subroots));
...@@ -520,6 +522,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) ...@@ -520,6 +522,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
result->rtable = glob->finalrtable; result->rtable = glob->finalrtable;
result->resultRelations = glob->resultRelations; result->resultRelations = glob->resultRelations;
result->rootResultRelations = glob->rootResultRelations; result->rootResultRelations = glob->rootResultRelations;
result->appendRelations = glob->appendRelations;
result->subplans = glob->subplans; result->subplans = glob->subplans;
result->rewindPlanIDs = glob->rewindPlanIDs; result->rewindPlanIDs = glob->rewindPlanIDs;
result->rowMarks = glob->finalrowmarks; result->rowMarks = glob->finalrowmarks;
...@@ -1219,6 +1222,7 @@ inheritance_planner(PlannerInfo *root) ...@@ -1219,6 +1222,7 @@ inheritance_planner(PlannerInfo *root)
Index rootRelation = 0; Index rootRelation = 0;
List *final_rtable = NIL; List *final_rtable = NIL;
List *final_rowmarks = NIL; List *final_rowmarks = NIL;
List *final_appendrels = NIL;
int save_rel_array_size = 0; int save_rel_array_size = 0;
RelOptInfo **save_rel_array = NULL; RelOptInfo **save_rel_array = NULL;
AppendRelInfo **save_append_rel_array = NULL; AppendRelInfo **save_append_rel_array = NULL;
...@@ -1627,12 +1631,13 @@ inheritance_planner(PlannerInfo *root) ...@@ -1627,12 +1631,13 @@ inheritance_planner(PlannerInfo *root)
* modified subquery RTEs into final_rtable, to ensure we have sane * modified subquery RTEs into final_rtable, to ensure we have sane
* copies of those. Also save the first non-excluded child's version * copies of those. Also save the first non-excluded child's version
* of the rowmarks list; we assume all children will end up with * of the rowmarks list; we assume all children will end up with
* equivalent versions of that. * equivalent versions of that. Likewise for append_rel_list.
*/ */
if (final_rtable == NIL) if (final_rtable == NIL)
{ {
final_rtable = subroot->parse->rtable; final_rtable = subroot->parse->rtable;
final_rowmarks = subroot->rowMarks; final_rowmarks = subroot->rowMarks;
final_appendrels = subroot->append_rel_list;
} }
else else
{ {
...@@ -1764,8 +1769,9 @@ inheritance_planner(PlannerInfo *root) ...@@ -1764,8 +1769,9 @@ inheritance_planner(PlannerInfo *root)
root->simple_rte_array[rti++] = rte; root->simple_rte_array[rti++] = rte;
} }
/* Put back adjusted rowmarks, too */ /* Put back adjusted rowmarks and appendrels, too */
root->rowMarks = final_rowmarks; root->rowMarks = final_rowmarks;
root->append_rel_list = final_appendrels;
} }
/* /*
......
...@@ -108,6 +108,7 @@ static Plan *set_mergeappend_references(PlannerInfo *root, ...@@ -108,6 +108,7 @@ static Plan *set_mergeappend_references(PlannerInfo *root,
MergeAppend *mplan, MergeAppend *mplan,
int rtoffset); int rtoffset);
static void set_hash_references(PlannerInfo *root, Plan *plan, int rtoffset); static void set_hash_references(PlannerInfo *root, Plan *plan, int rtoffset);
static Relids offset_relid_set(Relids relids, int rtoffset);
static Node *fix_scan_expr(PlannerInfo *root, Node *node, int rtoffset); static Node *fix_scan_expr(PlannerInfo *root, Node *node, int rtoffset);
static Node *fix_scan_expr_mutator(Node *node, fix_scan_expr_context *context); static Node *fix_scan_expr_mutator(Node *node, fix_scan_expr_context *context);
static bool fix_scan_expr_walker(Node *node, fix_scan_expr_context *context); static bool fix_scan_expr_walker(Node *node, fix_scan_expr_context *context);
...@@ -208,7 +209,8 @@ static List *set_returning_clause_references(PlannerInfo *root, ...@@ -208,7 +209,8 @@ static List *set_returning_clause_references(PlannerInfo *root,
* *
* The flattened rangetable entries are appended to root->glob->finalrtable. * The flattened rangetable entries are appended to root->glob->finalrtable.
* Also, rowmarks entries are appended to root->glob->finalrowmarks, and the * Also, rowmarks entries are appended to root->glob->finalrowmarks, and the
* RT indexes of ModifyTable result relations to root->glob->resultRelations. * RT indexes of ModifyTable result relations to root->glob->resultRelations,
* and flattened AppendRelInfos are appended to root->glob->appendRelations.
* Plan dependencies are appended to root->glob->relationOids (for relations) * Plan dependencies are appended to root->glob->relationOids (for relations)
* and root->glob->invalItems (for everything else). * and root->glob->invalItems (for everything else).
* *
...@@ -250,6 +252,28 @@ set_plan_references(PlannerInfo *root, Plan *plan) ...@@ -250,6 +252,28 @@ set_plan_references(PlannerInfo *root, Plan *plan)
glob->finalrowmarks = lappend(glob->finalrowmarks, newrc); glob->finalrowmarks = lappend(glob->finalrowmarks, newrc);
} }
/*
* Adjust RT indexes of AppendRelInfos and add to final appendrels list.
* We assume the AppendRelInfos were built during planning and don't need
* to be copied.
*/
foreach(lc, root->append_rel_list)
{
AppendRelInfo *appinfo = lfirst_node(AppendRelInfo, lc);
/* adjust RT indexes */
appinfo->parent_relid += rtoffset;
appinfo->child_relid += rtoffset;
/*
* Rather than adjust the translated_vars entries, just drop 'em.
* Neither the executor nor EXPLAIN currently need that data.
*/
appinfo->translated_vars = NIL;
glob->appendRelations = lappend(glob->appendRelations, appinfo);
}
/* Now fix the Plan tree */ /* Now fix the Plan tree */
return set_plan_refs(root, plan, rtoffset); return set_plan_refs(root, plan, rtoffset);
} }
...@@ -1215,16 +1239,7 @@ set_foreignscan_references(PlannerInfo *root, ...@@ -1215,16 +1239,7 @@ set_foreignscan_references(PlannerInfo *root,
fix_scan_list(root, fscan->fdw_recheck_quals, rtoffset); fix_scan_list(root, fscan->fdw_recheck_quals, rtoffset);
} }
/* Adjust fs_relids if needed */ fscan->fs_relids = offset_relid_set(fscan->fs_relids, rtoffset);
if (rtoffset > 0)
{
Bitmapset *tempset = NULL;
int x = -1;
while ((x = bms_next_member(fscan->fs_relids, x)) >= 0)
tempset = bms_add_member(tempset, x + rtoffset);
fscan->fs_relids = tempset;
}
} }
/* /*
...@@ -1287,16 +1302,7 @@ set_customscan_references(PlannerInfo *root, ...@@ -1287,16 +1302,7 @@ set_customscan_references(PlannerInfo *root,
lfirst(lc) = set_plan_refs(root, (Plan *) lfirst(lc), rtoffset); lfirst(lc) = set_plan_refs(root, (Plan *) lfirst(lc), rtoffset);
} }
/* Adjust custom_relids if needed */ cscan->custom_relids = offset_relid_set(cscan->custom_relids, rtoffset);
if (rtoffset > 0)
{
Bitmapset *tempset = NULL;
int x = -1;
while ((x = bms_next_member(cscan->custom_relids, x)) >= 0)
tempset = bms_add_member(tempset, x + rtoffset);
cscan->custom_relids = tempset;
}
} }
/* /*
...@@ -1338,6 +1344,8 @@ set_append_references(PlannerInfo *root, ...@@ -1338,6 +1344,8 @@ set_append_references(PlannerInfo *root,
*/ */
set_dummy_tlist_references((Plan *) aplan, rtoffset); set_dummy_tlist_references((Plan *) aplan, rtoffset);
aplan->apprelids = offset_relid_set(aplan->apprelids, rtoffset);
if (aplan->part_prune_info) if (aplan->part_prune_info)
{ {
foreach(l, aplan->part_prune_info->prune_infos) foreach(l, aplan->part_prune_info->prune_infos)
...@@ -1400,6 +1408,8 @@ set_mergeappend_references(PlannerInfo *root, ...@@ -1400,6 +1408,8 @@ set_mergeappend_references(PlannerInfo *root,
*/ */
set_dummy_tlist_references((Plan *) mplan, rtoffset); set_dummy_tlist_references((Plan *) mplan, rtoffset);
mplan->apprelids = offset_relid_set(mplan->apprelids, rtoffset);
if (mplan->part_prune_info) if (mplan->part_prune_info)
{ {
foreach(l, mplan->part_prune_info->prune_infos) foreach(l, mplan->part_prune_info->prune_infos)
...@@ -1454,6 +1464,25 @@ set_hash_references(PlannerInfo *root, Plan *plan, int rtoffset) ...@@ -1454,6 +1464,25 @@ set_hash_references(PlannerInfo *root, Plan *plan, int rtoffset)
Assert(plan->qual == NIL); Assert(plan->qual == NIL);
} }
/*
* offset_relid_set
* Apply rtoffset to the members of a Relids set.
*/
static Relids
offset_relid_set(Relids relids, int rtoffset)
{
Relids result = NULL;
int rtindex;
/* If there's no offset to apply, we needn't recompute the value */
if (rtoffset == 0)
return relids;
rtindex = -1;
while ((rtindex = bms_next_member(relids, rtindex)) >= 0)
result = bms_add_member(result, rtindex + rtoffset);
return result;
}
/* /*
* copyVar * copyVar
* Copy a Var node. * Copy a Var node.
......
This diff is collapsed.
...@@ -1171,7 +1171,6 @@ typedef struct ModifyTableState ...@@ -1171,7 +1171,6 @@ typedef struct ModifyTableState
List **mt_arowmarks; /* per-subplan ExecAuxRowMark lists */ List **mt_arowmarks; /* per-subplan ExecAuxRowMark lists */
EPQState mt_epqstate; /* for evaluating EvalPlanQual rechecks */ EPQState mt_epqstate; /* for evaluating EvalPlanQual rechecks */
bool fireBSTriggers; /* do we need to fire stmt triggers? */ bool fireBSTriggers; /* do we need to fire stmt triggers? */
List *mt_excludedtlist; /* the excluded pseudo relation's tlist */
/* /*
* Slot for storing tuples in the root partitioned table's rowtype during * Slot for storing tuples in the root partitioned table's rowtype during
......
...@@ -122,6 +122,8 @@ typedef struct PlannerGlobal ...@@ -122,6 +122,8 @@ typedef struct PlannerGlobal
List *rootResultRelations; /* "flat" list of integer RT indexes */ List *rootResultRelations; /* "flat" list of integer RT indexes */
List *appendRelations; /* "flat" list of AppendRelInfos */
List *relationOids; /* OIDs of relations the plan depends on */ List *relationOids; /* OIDs of relations the plan depends on */
List *invalItems; /* other dependencies, as PlanInvalItems */ List *invalItems; /* other dependencies, as PlanInvalItems */
......
...@@ -74,6 +74,8 @@ typedef struct PlannedStmt ...@@ -74,6 +74,8 @@ typedef struct PlannedStmt
*/ */
List *rootResultRelations; List *rootResultRelations;
List *appendRelations; /* list of AppendRelInfo nodes */
List *subplans; /* Plan trees for SubPlan expressions; note List *subplans; /* Plan trees for SubPlan expressions; note
* that some could be NULL */ * that some could be NULL */
...@@ -249,6 +251,7 @@ struct PartitionPruneInfo; /* forward reference to struct below */ ...@@ -249,6 +251,7 @@ struct PartitionPruneInfo; /* forward reference to struct below */
typedef struct Append typedef struct Append
{ {
Plan plan; Plan plan;
Bitmapset *apprelids; /* RTIs of appendrel(s) formed by this node */
List *appendplans; List *appendplans;
/* /*
...@@ -269,6 +272,7 @@ typedef struct Append ...@@ -269,6 +272,7 @@ typedef struct Append
typedef struct MergeAppend typedef struct MergeAppend
{ {
Plan plan; Plan plan;
Bitmapset *apprelids; /* RTIs of appendrel(s) formed by this node */
List *mergeplans; List *mergeplans;
/* these fields are just like the sort-key info in struct Sort: */ /* these fields are just like the sort-key info in struct Sort: */
int numCols; /* number of sort-key columns */ int numCols; /* number of sort-key columns */
......
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
#include "nodes/parsenodes.h" #include "nodes/parsenodes.h"
#include "nodes/pg_list.h" #include "nodes/pg_list.h"
struct Plan; /* avoid including plannodes.h here */
struct PlannedStmt;
extern char *pg_get_indexdef_string(Oid indexrelid); extern char *pg_get_indexdef_string(Oid indexrelid);
extern char *pg_get_indexdef_columns(Oid indexrelid, bool pretty); extern char *pg_get_indexdef_columns(Oid indexrelid, bool pretty);
...@@ -28,9 +31,10 @@ extern char *pg_get_constraintdef_command(Oid constraintId); ...@@ -28,9 +31,10 @@ extern char *pg_get_constraintdef_command(Oid constraintId);
extern char *deparse_expression(Node *expr, List *dpcontext, extern char *deparse_expression(Node *expr, List *dpcontext,
bool forceprefix, bool showimplicit); bool forceprefix, bool showimplicit);
extern List *deparse_context_for(const char *aliasname, Oid relid); extern List *deparse_context_for(const char *aliasname, Oid relid);
extern List *deparse_context_for_plan_rtable(List *rtable, List *rtable_names); extern List *deparse_context_for_plan_tree(struct PlannedStmt *pstmt,
extern List *set_deparse_context_planstate(List *dpcontext, List *rtable_names);
Node *planstate, List *ancestors); extern List *set_deparse_context_plan(List *dpcontext,
struct Plan *plan, List *ancestors);
extern List *select_rtable_names_for_explain(List *rtable, extern List *select_rtable_names_for_explain(List *rtable,
Bitmapset *rels_used); Bitmapset *rels_used);
extern char *generate_collation_name(Oid collid); extern char *generate_collation_name(Oid collid);
......
...@@ -1005,24 +1005,24 @@ explain (costs off) ...@@ -1005,24 +1005,24 @@ explain (costs off)
-> Limit -> Limit
-> Merge Append -> Merge Append
Sort Key: minmaxtest.f1 Sort Key: minmaxtest.f1
-> Index Only Scan using minmaxtesti on minmaxtest -> Index Only Scan using minmaxtesti on minmaxtest minmaxtest_1
Index Cond: (f1 IS NOT NULL) Index Cond: (f1 IS NOT NULL)
-> Index Only Scan using minmaxtest1i on minmaxtest1 minmaxtest_1 -> Index Only Scan using minmaxtest1i on minmaxtest1 minmaxtest_2
Index Cond: (f1 IS NOT NULL) Index Cond: (f1 IS NOT NULL)
-> Index Only Scan Backward using minmaxtest2i on minmaxtest2 minmaxtest_2 -> Index Only Scan Backward using minmaxtest2i on minmaxtest2 minmaxtest_3
Index Cond: (f1 IS NOT NULL) Index Cond: (f1 IS NOT NULL)
-> Index Only Scan using minmaxtest3i on minmaxtest3 minmaxtest_3 -> Index Only Scan using minmaxtest3i on minmaxtest3 minmaxtest_4
InitPlan 2 (returns $1) InitPlan 2 (returns $1)
-> Limit -> Limit
-> Merge Append -> Merge Append
Sort Key: minmaxtest_4.f1 DESC Sort Key: minmaxtest_5.f1 DESC
-> Index Only Scan Backward using minmaxtesti on minmaxtest minmaxtest_4 -> Index Only Scan Backward using minmaxtesti on minmaxtest minmaxtest_6
Index Cond: (f1 IS NOT NULL) Index Cond: (f1 IS NOT NULL)
-> Index Only Scan Backward using minmaxtest1i on minmaxtest1 minmaxtest_5 -> Index Only Scan Backward using minmaxtest1i on minmaxtest1 minmaxtest_7
Index Cond: (f1 IS NOT NULL) Index Cond: (f1 IS NOT NULL)
-> Index Only Scan using minmaxtest2i on minmaxtest2 minmaxtest_6 -> Index Only Scan using minmaxtest2i on minmaxtest2 minmaxtest_8
Index Cond: (f1 IS NOT NULL) Index Cond: (f1 IS NOT NULL)
-> Index Only Scan Backward using minmaxtest3i on minmaxtest3 minmaxtest_7 -> Index Only Scan Backward using minmaxtest3i on minmaxtest3 minmaxtest_9
(23 rows) (23 rows)
select min(f1), max(f1) from minmaxtest; select min(f1), max(f1) from minmaxtest;
...@@ -1041,24 +1041,24 @@ explain (costs off) ...@@ -1041,24 +1041,24 @@ explain (costs off)
-> Limit -> Limit
-> Merge Append -> Merge Append
Sort Key: minmaxtest.f1 Sort Key: minmaxtest.f1
-> Index Only Scan using minmaxtesti on minmaxtest -> Index Only Scan using minmaxtesti on minmaxtest minmaxtest_1
Index Cond: (f1 IS NOT NULL) Index Cond: (f1 IS NOT NULL)
-> Index Only Scan using minmaxtest1i on minmaxtest1 minmaxtest_1 -> Index Only Scan using minmaxtest1i on minmaxtest1 minmaxtest_2
Index Cond: (f1 IS NOT NULL) Index Cond: (f1 IS NOT NULL)
-> Index Only Scan Backward using minmaxtest2i on minmaxtest2 minmaxtest_2 -> Index Only Scan Backward using minmaxtest2i on minmaxtest2 minmaxtest_3
Index Cond: (f1 IS NOT NULL) Index Cond: (f1 IS NOT NULL)
-> Index Only Scan using minmaxtest3i on minmaxtest3 minmaxtest_3 -> Index Only Scan using minmaxtest3i on minmaxtest3 minmaxtest_4
InitPlan 2 (returns $1) InitPlan 2 (returns $1)
-> Limit -> Limit
-> Merge Append -> Merge Append
Sort Key: minmaxtest_4.f1 DESC Sort Key: minmaxtest_5.f1 DESC
-> Index Only Scan Backward using minmaxtesti on minmaxtest minmaxtest_4 -> Index Only Scan Backward using minmaxtesti on minmaxtest minmaxtest_6
Index Cond: (f1 IS NOT NULL) Index Cond: (f1 IS NOT NULL)
-> Index Only Scan Backward using minmaxtest1i on minmaxtest1 minmaxtest_5 -> Index Only Scan Backward using minmaxtest1i on minmaxtest1 minmaxtest_7
Index Cond: (f1 IS NOT NULL) Index Cond: (f1 IS NOT NULL)
-> Index Only Scan using minmaxtest2i on minmaxtest2 minmaxtest_6 -> Index Only Scan using minmaxtest2i on minmaxtest2 minmaxtest_8
Index Cond: (f1 IS NOT NULL) Index Cond: (f1 IS NOT NULL)
-> Index Only Scan Backward using minmaxtest3i on minmaxtest3 minmaxtest_7 -> Index Only Scan Backward using minmaxtest3i on minmaxtest3 minmaxtest_9
-> Sort -> Sort
Sort Key: ($0), ($1) Sort Key: ($0), ($1)
-> Result -> Result
...@@ -1155,8 +1155,8 @@ explain (costs off) select * from t1 group by a,b,c,d; ...@@ -1155,8 +1155,8 @@ explain (costs off) select * from t1 group by a,b,c,d;
HashAggregate HashAggregate
Group Key: t1.a, t1.b, t1.c, t1.d Group Key: t1.a, t1.b, t1.c, t1.d
-> Append -> Append
-> Seq Scan on t1 -> Seq Scan on t1 t1_1
-> Seq Scan on t1c t1_1 -> Seq Scan on t1c t1_2
(5 rows) (5 rows)
-- Okay to remove columns if we're only querying the parent. -- Okay to remove columns if we're only querying the parent.
...@@ -1180,12 +1180,12 @@ create temp table p_t1_2 partition of p_t1 for values in(2); ...@@ -1180,12 +1180,12 @@ create temp table p_t1_2 partition of p_t1 for values in(2);
-- Ensure we can remove non-PK columns for partitioned tables. -- Ensure we can remove non-PK columns for partitioned tables.
explain (costs off) select * from p_t1 group by a,b,c,d; explain (costs off) select * from p_t1 group by a,b,c,d;
QUERY PLAN QUERY PLAN
--------------------------------------- --------------------------------
HashAggregate HashAggregate
Group Key: p_t1.a, p_t1.b Group Key: p_t1.a, p_t1.b
-> Append -> Append
-> Seq Scan on p_t1_1 p_t1 -> Seq Scan on p_t1_1
-> Seq Scan on p_t1_2 p_t1_1 -> Seq Scan on p_t1_2
(5 rows) (5 rows)
drop table t1 cascade; drop table t1 cascade;
......
...@@ -540,11 +540,11 @@ explain (costs off) select * from nv_parent where d between '2011-08-01' and '20 ...@@ -540,11 +540,11 @@ explain (costs off) select * from nv_parent where d between '2011-08-01' and '20
QUERY PLAN QUERY PLAN
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Append Append
-> Seq Scan on nv_parent -> Seq Scan on nv_parent nv_parent_1
Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date)) Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date))
-> Seq Scan on nv_child_2010 nv_parent_1 -> Seq Scan on nv_child_2010 nv_parent_2
Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date)) Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date))
-> Seq Scan on nv_child_2011 nv_parent_2 -> Seq Scan on nv_child_2011 nv_parent_3
Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date)) Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date))
(7 rows) (7 rows)
...@@ -553,11 +553,11 @@ explain (costs off) select * from nv_parent where d between '2011-08-01'::date a ...@@ -553,11 +553,11 @@ explain (costs off) select * from nv_parent where d between '2011-08-01'::date a
QUERY PLAN QUERY PLAN
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Append Append
-> Seq Scan on nv_parent -> Seq Scan on nv_parent nv_parent_1
Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date)) Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date))
-> Seq Scan on nv_child_2010 nv_parent_1 -> Seq Scan on nv_child_2010 nv_parent_2
Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date)) Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date))
-> Seq Scan on nv_child_2011 nv_parent_2 -> Seq Scan on nv_child_2011 nv_parent_3
Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date)) Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date))
(7 rows) (7 rows)
...@@ -565,13 +565,13 @@ explain (costs off) select * from nv_parent where d between '2009-08-01'::date a ...@@ -565,13 +565,13 @@ explain (costs off) select * from nv_parent where d between '2009-08-01'::date a
QUERY PLAN QUERY PLAN
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Append Append
-> Seq Scan on nv_parent -> Seq Scan on nv_parent nv_parent_1
Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date)) Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
-> Seq Scan on nv_child_2010 nv_parent_1 -> Seq Scan on nv_child_2010 nv_parent_2
Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date)) Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
-> Seq Scan on nv_child_2011 nv_parent_2 -> Seq Scan on nv_child_2011 nv_parent_3
Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date)) Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
-> Seq Scan on nv_child_2009 nv_parent_3 -> Seq Scan on nv_child_2009 nv_parent_4
Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date)) Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
(9 rows) (9 rows)
...@@ -581,11 +581,11 @@ explain (costs off) select * from nv_parent where d between '2009-08-01'::date a ...@@ -581,11 +581,11 @@ explain (costs off) select * from nv_parent where d between '2009-08-01'::date a
QUERY PLAN QUERY PLAN
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Append Append
-> Seq Scan on nv_parent -> Seq Scan on nv_parent nv_parent_1
Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date)) Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
-> Seq Scan on nv_child_2010 nv_parent_1 -> Seq Scan on nv_child_2010 nv_parent_2
Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date)) Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
-> Seq Scan on nv_child_2009 nv_parent_2 -> Seq Scan on nv_child_2009 nv_parent_3
Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date)) Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
(7 rows) (7 rows)
......
This diff is collapsed.
...@@ -5780,7 +5780,7 @@ select t1.b, ss.phv from join_ut1 t1 left join lateral ...@@ -5780,7 +5780,7 @@ select t1.b, ss.phv from join_ut1 t1 left join lateral
from join_pt1 t2 join join_ut1 t3 on t2.a = t3.b) ss from join_pt1 t2 join join_ut1 t3 on t2.a = t3.b) ss
on t1.a = ss.t2a order by t1.a; on t1.a = ss.t2a order by t1.a;
QUERY PLAN QUERY PLAN
------------------------------------------------------------------ --------------------------------------------------------------------
Sort Sort
Output: t1.b, (LEAST(t1.a, t2.a, t3.a)), t1.a Output: t1.b, (LEAST(t1.a, t2.a, t3.a)), t1.a
Sort Key: t1.a Sort Key: t1.a
...@@ -5796,12 +5796,12 @@ select t1.b, ss.phv from join_ut1 t1 left join lateral ...@@ -5796,12 +5796,12 @@ select t1.b, ss.phv from join_ut1 t1 left join lateral
-> Hash -> Hash
Output: t2.a Output: t2.a
-> Append -> Append
-> Seq Scan on public.join_pt1p1p1 t2 -> Seq Scan on public.join_pt1p1p1 t2_1
Output: t2.a
Filter: (t1.a = t2.a)
-> Seq Scan on public.join_pt1p2 t2_1
Output: t2_1.a Output: t2_1.a
Filter: (t1.a = t2_1.a) Filter: (t1.a = t2_1.a)
-> Seq Scan on public.join_pt1p2 t2_2
Output: t2_2.a
Filter: (t1.a = t2_2.a)
(21 rows) (21 rows)
select t1.b, ss.phv from join_ut1 t1 left join lateral select t1.b, ss.phv from join_ut1 t1 left join lateral
......
This diff is collapsed.
...@@ -21,12 +21,12 @@ explain (costs off) ...@@ -21,12 +21,12 @@ explain (costs off)
Workers Planned: 3 Workers Planned: 3
-> Partial Aggregate -> Partial Aggregate
-> Parallel Append -> Parallel Append
-> Parallel Seq Scan on d_star a_star_3 -> Parallel Seq Scan on d_star a_star_4
-> Parallel Seq Scan on f_star a_star_5 -> Parallel Seq Scan on f_star a_star_6
-> Parallel Seq Scan on e_star a_star_4 -> Parallel Seq Scan on e_star a_star_5
-> Parallel Seq Scan on b_star a_star_1 -> Parallel Seq Scan on b_star a_star_2
-> Parallel Seq Scan on c_star a_star_2 -> Parallel Seq Scan on c_star a_star_3
-> Parallel Seq Scan on a_star -> Parallel Seq Scan on a_star a_star_1
(11 rows) (11 rows)
select round(avg(aa)), sum(aa) from a_star a1; select round(avg(aa)), sum(aa) from a_star a1;
...@@ -47,12 +47,12 @@ explain (costs off) ...@@ -47,12 +47,12 @@ explain (costs off)
Workers Planned: 3 Workers Planned: 3
-> Partial Aggregate -> Partial Aggregate
-> Parallel Append -> Parallel Append
-> Seq Scan on d_star a_star_3 -> Seq Scan on d_star a_star_4
-> Seq Scan on c_star a_star_2 -> Seq Scan on c_star a_star_3
-> Parallel Seq Scan on f_star a_star_5 -> Parallel Seq Scan on f_star a_star_6
-> Parallel Seq Scan on e_star a_star_4 -> Parallel Seq Scan on e_star a_star_5
-> Parallel Seq Scan on b_star a_star_1 -> Parallel Seq Scan on b_star a_star_2
-> Parallel Seq Scan on a_star -> Parallel Seq Scan on a_star a_star_1
(11 rows) (11 rows)
select round(avg(aa)), sum(aa) from a_star a2; select round(avg(aa)), sum(aa) from a_star a2;
...@@ -75,12 +75,12 @@ explain (costs off) ...@@ -75,12 +75,12 @@ explain (costs off)
Workers Planned: 3 Workers Planned: 3
-> Partial Aggregate -> Partial Aggregate
-> Parallel Append -> Parallel Append
-> Seq Scan on d_star a_star_3 -> Seq Scan on d_star a_star_4
-> Seq Scan on f_star a_star_5 -> Seq Scan on f_star a_star_6
-> Seq Scan on e_star a_star_4 -> Seq Scan on e_star a_star_5
-> Seq Scan on b_star a_star_1 -> Seq Scan on b_star a_star_2
-> Seq Scan on c_star a_star_2 -> Seq Scan on c_star a_star_3
-> Seq Scan on a_star -> Seq Scan on a_star a_star_1
(11 rows) (11 rows)
select round(avg(aa)), sum(aa) from a_star a3; select round(avg(aa)), sum(aa) from a_star a3;
...@@ -106,12 +106,12 @@ explain (costs off) ...@@ -106,12 +106,12 @@ explain (costs off)
Workers Planned: 1 Workers Planned: 1
-> Partial Aggregate -> Partial Aggregate
-> Append -> Append
-> Parallel Seq Scan on a_star -> Parallel Seq Scan on a_star a_star_1
-> Parallel Seq Scan on b_star a_star_1 -> Parallel Seq Scan on b_star a_star_2
-> Parallel Seq Scan on c_star a_star_2 -> Parallel Seq Scan on c_star a_star_3
-> Parallel Seq Scan on d_star a_star_3 -> Parallel Seq Scan on d_star a_star_4
-> Parallel Seq Scan on e_star a_star_4 -> Parallel Seq Scan on e_star a_star_5
-> Parallel Seq Scan on f_star a_star_5 -> Parallel Seq Scan on f_star a_star_6
(11 rows) (11 rows)
select round(avg(aa)), sum(aa) from a_star a4; select round(avg(aa)), sum(aa) from a_star a4;
...@@ -145,15 +145,15 @@ explain (costs off) ...@@ -145,15 +145,15 @@ explain (costs off)
-> Gather -> Gather
Workers Planned: 3 Workers Planned: 3
-> Parallel Append -> Parallel Append
-> Parallel Seq Scan on part_pa_test_p1 pa2 -> Parallel Seq Scan on part_pa_test_p1 pa2_1
-> Parallel Seq Scan on part_pa_test_p2 pa2_1 -> Parallel Seq Scan on part_pa_test_p2 pa2_2
SubPlan 2 SubPlan 2
-> Result -> Result
SubPlan 1 SubPlan 1
-> Append -> Append
-> Seq Scan on part_pa_test_p1 pa1 -> Seq Scan on part_pa_test_p1 pa1_1
Filter: (a = pa2.a) Filter: (a = pa2.a)
-> Seq Scan on part_pa_test_p2 pa1_1 -> Seq Scan on part_pa_test_p2 pa1_2
Filter: (a = pa2.a) Filter: (a = pa2.a)
(14 rows) (14 rows)
......
...@@ -198,13 +198,13 @@ explain (costs off) ...@@ -198,13 +198,13 @@ explain (costs off)
------------------------------------------------- -------------------------------------------------
Aggregate Aggregate
-> Append -> Append
-> Sample Scan on person -> Sample Scan on person person_1
Sampling: bernoulli ('100'::real) Sampling: bernoulli ('100'::real)
-> Sample Scan on emp person_1 -> Sample Scan on emp person_2
Sampling: bernoulli ('100'::real) Sampling: bernoulli ('100'::real)
-> Sample Scan on student person_2 -> Sample Scan on student person_3
Sampling: bernoulli ('100'::real) Sampling: bernoulli ('100'::real)
-> Sample Scan on stud_emp person_3 -> Sample Scan on stud_emp person_4
Sampling: bernoulli ('100'::real) Sampling: bernoulli ('100'::real)
(10 rows) (10 rows)
...@@ -320,11 +320,11 @@ create table parted_sample_2 partition of parted_sample for values in (2); ...@@ -320,11 +320,11 @@ create table parted_sample_2 partition of parted_sample for values in (2);
explain (costs off) explain (costs off)
select * from parted_sample tablesample bernoulli (100); select * from parted_sample tablesample bernoulli (100);
QUERY PLAN QUERY PLAN
------------------------------------------------------ -------------------------------------------
Append Append
-> Sample Scan on parted_sample_1 parted_sample -> Sample Scan on parted_sample_1
Sampling: bernoulli ('100'::real) Sampling: bernoulli ('100'::real)
-> Sample Scan on parted_sample_2 parted_sample_1 -> Sample Scan on parted_sample_2
Sampling: bernoulli ('100'::real) Sampling: bernoulli ('100'::real)
(5 rows) (5 rows)
......
...@@ -1549,15 +1549,15 @@ INSERT INTO other_tbl_child VALUES (8),(100); ...@@ -1549,15 +1549,15 @@ INSERT INTO other_tbl_child VALUES (8),(100);
EXPLAIN (costs off) EXPLAIN (costs off)
UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id; UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id;
QUERY PLAN QUERY PLAN
------------------------------------------------------------------------ -------------------------------------------------------------------------
Update on base_tbl_parent Update on base_tbl_parent
Update on base_tbl_parent Update on base_tbl_parent
Update on base_tbl_child base_tbl_parent_1 Update on base_tbl_child base_tbl_parent_1
-> Hash Join -> Hash Join
Hash Cond: (other_tbl_parent.id = base_tbl_parent.a) Hash Cond: (other_tbl_parent.id = base_tbl_parent.a)
-> Append -> Append
-> Seq Scan on other_tbl_parent -> Seq Scan on other_tbl_parent other_tbl_parent_1
-> Seq Scan on other_tbl_child other_tbl_parent_1 -> Seq Scan on other_tbl_child other_tbl_parent_2
-> Hash -> Hash
-> Seq Scan on base_tbl_parent -> Seq Scan on base_tbl_parent
-> Merge Join -> Merge Join
...@@ -1568,8 +1568,8 @@ UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id; ...@@ -1568,8 +1568,8 @@ UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id;
-> Sort -> Sort
Sort Key: other_tbl_parent.id Sort Key: other_tbl_parent.id
-> Append -> Append
-> Seq Scan on other_tbl_parent -> Seq Scan on other_tbl_parent other_tbl_parent_1
-> Seq Scan on other_tbl_child other_tbl_parent_1 -> Seq Scan on other_tbl_child other_tbl_parent_2
(20 rows) (20 rows)
UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id; UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id;
...@@ -2293,16 +2293,16 @@ UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND a != 6; ...@@ -2293,16 +2293,16 @@ UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND a != 6;
Filter: ((t1.a <> 6) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t1.a) AND leakproof(t1.a)) Filter: ((t1.a <> 6) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t1.a) AND leakproof(t1.a))
SubPlan 1 SubPlan 1
-> Append -> Append
-> Seq Scan on public.t12 -> Seq Scan on public.t12 t12_1
Filter: (t12.a = t1.a)
-> Seq Scan on public.t111 t12_1
Filter: (t12_1.a = t1.a) Filter: (t12_1.a = t1.a)
-> Seq Scan on public.t111 t12_2
Filter: (t12_2.a = t1.a)
SubPlan 2 SubPlan 2
-> Append -> Append
-> Seq Scan on public.t12 t12_2 -> Seq Scan on public.t12 t12_4
Output: t12_2.a Output: t12_4.a
-> Seq Scan on public.t111 t12_3 -> Seq Scan on public.t111 t12_5
Output: t12_3.a Output: t12_5.a
-> Index Scan using t11_a_idx on public.t11 t1_1 -> Index Scan using t11_a_idx on public.t11 t1_1
Output: 100, t1_1.b, t1_1.c, t1_1.d, t1_1.ctid Output: 100, t1_1.b, t1_1.c, t1_1.d, t1_1.ctid
Index Cond: ((t1_1.a > 5) AND (t1_1.a < 7)) Index Cond: ((t1_1.a > 5) AND (t1_1.a < 7))
...@@ -2343,16 +2343,16 @@ UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND a = 8; ...@@ -2343,16 +2343,16 @@ UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND a = 8;
Filter: ((alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t1.a) AND leakproof(t1.a)) Filter: ((alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t1.a) AND leakproof(t1.a))
SubPlan 1 SubPlan 1
-> Append -> Append
-> Seq Scan on public.t12 -> Seq Scan on public.t12 t12_1
Filter: (t12.a = t1.a)
-> Seq Scan on public.t111 t12_1
Filter: (t12_1.a = t1.a) Filter: (t12_1.a = t1.a)
-> Seq Scan on public.t111 t12_2
Filter: (t12_2.a = t1.a)
SubPlan 2 SubPlan 2
-> Append -> Append
-> Seq Scan on public.t12 t12_2 -> Seq Scan on public.t12 t12_4
Output: t12_2.a Output: t12_4.a
-> Seq Scan on public.t111 t12_3 -> Seq Scan on public.t111 t12_5
Output: t12_3.a Output: t12_5.a
-> Index Scan using t11_a_idx on public.t11 t1_1 -> Index Scan using t11_a_idx on public.t11 t1_1
Output: (t1_1.a + 1), t1_1.b, t1_1.c, t1_1.d, t1_1.ctid Output: (t1_1.a + 1), t1_1.b, t1_1.c, t1_1.d, t1_1.ctid
Index Cond: ((t1_1.a > 5) AND (t1_1.a = 8)) Index Cond: ((t1_1.a > 5) AND (t1_1.a = 8))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment