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 55a1954da),
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 1cc29fe7c, 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
This commit is contained in:
Tom Lane 2019-12-11 17:05:18 -05:00
parent ba79cb5dc8
commit 6ef77cf46e
26 changed files with 1966 additions and 1762 deletions

View File

@ -7094,10 +7094,10 @@ select * from bar where f1 in (select f1 from foo) for update;
Inner Unique: true
Hash Cond: (bar.f1 = foo.f1)
-> Append
-> Seq Scan on public.bar
Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid
-> Foreign Scan on public.bar2 bar_1
-> Seq Scan on public.bar bar_1
Output: bar_1.f1, bar_1.f2, bar_1.ctid, bar_1.*, bar_1.tableoid
-> Foreign Scan on public.bar2 bar_2
Output: bar_2.f1, bar_2.f2, bar_2.ctid, bar_2.*, bar_2.tableoid
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE
-> Hash
Output: foo.ctid, foo.f1, foo.*, foo.tableoid
@ -7105,10 +7105,10 @@ select * from bar where f1 in (select f1 from foo) for update;
Output: foo.ctid, foo.f1, foo.*, foo.tableoid
Group Key: foo.f1
-> Append
-> Seq Scan on public.foo
Output: foo.ctid, foo.f1, foo.*, foo.tableoid
-> Foreign Scan on public.foo2 foo_1
-> Seq Scan on public.foo foo_1
Output: foo_1.ctid, foo_1.f1, foo_1.*, foo_1.tableoid
-> Foreign Scan on public.foo2 foo_2
Output: foo_2.ctid, foo_2.f1, foo_2.*, foo_2.tableoid
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1
(23 rows)
@ -7132,10 +7132,10 @@ select * from bar where f1 in (select f1 from foo) for share;
Inner Unique: true
Hash Cond: (bar.f1 = foo.f1)
-> Append
-> Seq Scan on public.bar
Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid
-> Foreign Scan on public.bar2 bar_1
-> Seq Scan on public.bar bar_1
Output: bar_1.f1, bar_1.f2, bar_1.ctid, bar_1.*, bar_1.tableoid
-> Foreign Scan on public.bar2 bar_2
Output: bar_2.f1, bar_2.f2, bar_2.ctid, bar_2.*, bar_2.tableoid
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR SHARE
-> Hash
Output: foo.ctid, foo.f1, foo.*, foo.tableoid
@ -7143,10 +7143,10 @@ select * from bar where f1 in (select f1 from foo) for share;
Output: foo.ctid, foo.f1, foo.*, foo.tableoid
Group Key: foo.f1
-> Append
-> Seq Scan on public.foo
Output: foo.ctid, foo.f1, foo.*, foo.tableoid
-> Foreign Scan on public.foo2 foo_1
-> Seq Scan on public.foo foo_1
Output: foo_1.ctid, foo_1.f1, foo_1.*, foo_1.tableoid
-> Foreign Scan on public.foo2 foo_2
Output: foo_2.ctid, foo_2.f1, foo_2.*, foo_2.tableoid
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1
(23 rows)
@ -7180,10 +7180,10 @@ update bar set f2 = f2 + 100 where f1 in (select f1 from foo);
Output: foo.ctid, foo.f1, foo.*, foo.tableoid
Group Key: foo.f1
-> Append
-> Seq Scan on public.foo
Output: foo.ctid, foo.f1, foo.*, foo.tableoid
-> Foreign Scan on public.foo2 foo_1
-> Seq Scan on public.foo foo_1
Output: foo_1.ctid, foo_1.f1, foo_1.*, foo_1.tableoid
-> Foreign Scan on public.foo2 foo_2
Output: foo_2.ctid, foo_2.f1, foo_2.*, foo_2.tableoid
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1
-> Hash Join
Output: bar_1.f1, (bar_1.f2 + 100), bar_1.f3, bar_1.ctid, foo.ctid, foo.*, foo.tableoid
@ -7198,10 +7198,10 @@ update bar set f2 = f2 + 100 where f1 in (select f1 from foo);
Output: foo.ctid, foo.f1, foo.*, foo.tableoid
Group Key: foo.f1
-> Append
-> Seq Scan on public.foo
Output: foo.ctid, foo.f1, foo.*, foo.tableoid
-> Foreign Scan on public.foo2 foo_1
-> Seq Scan on public.foo foo_1
Output: foo_1.ctid, foo_1.f1, foo_1.*, foo_1.tableoid
-> Foreign Scan on public.foo2 foo_2
Output: foo_2.ctid, foo_2.f1, foo_2.*, foo_2.tableoid
Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1
(39 rows)
@ -7316,10 +7316,10 @@ explain (verbose, costs off)
Merge Cond: (foo.f1 = loct1.f1)
-> Merge Append
Sort Key: foo.f1
-> Index Scan using i_foo_f1 on public.foo
Output: foo.f1, foo.f2
-> Foreign Scan on public.foo2 foo_1
-> Index Scan using i_foo_f1 on public.foo foo_1
Output: foo_1.f1, foo_1.f2
-> Foreign Scan on public.foo2 foo_2
Output: foo_2.f1, foo_2.f2
Remote SQL: SELECT f1, f2 FROM public.loct1 ORDER BY f1 ASC NULLS LAST
-> Index Only Scan using i_loct1_f1 on public.loct1
Output: loct1.f1
@ -7356,10 +7356,10 @@ explain (verbose, costs off)
Merge Cond: (foo.f1 = loct1.f1)
-> Merge Append
Sort Key: foo.f1
-> Index Scan using i_foo_f1 on public.foo
Output: foo.f1, foo.f2
-> Foreign Scan on public.foo2 foo_1
-> Index Scan using i_foo_f1 on public.foo foo_1
Output: foo_1.f1, foo_1.f2
-> Foreign Scan on public.foo2 foo_2
Output: foo_2.f1, foo_2.f2
Remote SQL: SELECT f1, f2 FROM public.loct1 ORDER BY f1 ASC NULLS LAST
-> Index Only Scan using i_loct1_f1 on public.loct1
Output: loct1.f1
@ -8516,9 +8516,9 @@ SELECT t1.a,t2.b,t3.c FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) INNER J
Sort Key: t1.a, t3.c
-> Append
-> Foreign Scan
Relations: ((ftprt1_p1 t1) INNER JOIN (ftprt2_p1 t2)) INNER JOIN (ftprt1_p1 t3)
Relations: ((ftprt1_p1 t1_1) INNER JOIN (ftprt2_p1 t2_1)) INNER JOIN (ftprt1_p1 t3_1)
-> Foreign Scan
Relations: ((ftprt1_p2 t1_1) INNER JOIN (ftprt2_p2 t2_1)) INNER JOIN (ftprt1_p2 t3_1)
Relations: ((ftprt1_p2 t1_2) INNER JOIN (ftprt2_p2 t2_2)) INNER JOIN (ftprt1_p2 t3_2)
(7 rows)
SELECT t1.a,t2.b,t3.c FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) INNER JOIN fprt1 t3 ON (t2.b = t3.a) WHERE t1.a % 25 =0 ORDER BY 1,2,3;
@ -8561,12 +8561,12 @@ SELECT t1.wr, t2.wr FROM (SELECT t1 wr, a FROM fprt1 t1 WHERE t1.a % 25 = 0) t1
-> Hash Full Join
Hash Cond: (t1.a = t2.b)
-> Append
-> Foreign Scan on ftprt1_p1 t1
-> Foreign Scan on ftprt1_p2 t1_1
-> Foreign Scan on ftprt1_p1 t1_1
-> Foreign Scan on ftprt1_p2 t1_2
-> Hash
-> Append
-> Foreign Scan on ftprt2_p1 t2
-> Foreign Scan on ftprt2_p2 t2_1
-> Foreign Scan on ftprt2_p1 t2_1
-> Foreign Scan on ftprt2_p2 t2_2
(11 rows)
SELECT t1.wr, t2.wr FROM (SELECT t1 wr, a FROM fprt1 t1 WHERE t1.a % 25 = 0) t1 FULL JOIN (SELECT t2 wr, b FROM fprt2 t2 WHERE t2.b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY 1,2;
@ -8597,9 +8597,9 @@ SELECT t1.a,t1.b FROM fprt1 t1, LATERAL (SELECT t2.a, t2.b FROM fprt2 t2 WHERE t
Sort Key: t1.a, t1.b
-> Append
-> Foreign Scan
Relations: (ftprt1_p1 t1) INNER JOIN (ftprt2_p1 t2)
Relations: (ftprt1_p1 t1_1) INNER JOIN (ftprt2_p1 t2_1)
-> Foreign Scan
Relations: (ftprt1_p2 t1_1) INNER JOIN (ftprt2_p2 t2_1)
Relations: (ftprt1_p2 t1_2) INNER JOIN (ftprt2_p2 t2_2)
(7 rows)
SELECT t1.a,t1.b FROM fprt1 t1, LATERAL (SELECT t2.a, t2.b FROM fprt2 t2 WHERE t1.a = t2.b AND t1.b = t2.a) q WHERE t1.a%25 = 0 ORDER BY 1,2;
@ -8619,16 +8619,16 @@ SELECT t1.a, t1.phv, t2.b, t2.phv FROM (SELECT 't1_phv' phv, * FROM fprt1 WHERE
Sort
Sort Key: fprt1.a, fprt2.b
-> Append
-> Hash Full Join
Hash Cond: (fprt1.a = fprt2.b)
-> Foreign Scan on ftprt1_p1 fprt1
-> Hash
-> Foreign Scan on ftprt2_p1 fprt2
-> Hash Full Join
Hash Cond: (fprt1_1.a = fprt2_1.b)
-> Foreign Scan on ftprt1_p2 fprt1_1
-> Foreign Scan on ftprt1_p1 fprt1_1
-> Hash
-> Foreign Scan on ftprt2_p2 fprt2_1
-> Foreign Scan on ftprt2_p1 fprt2_1
-> Hash Full Join
Hash Cond: (fprt1_2.a = fprt2_2.b)
-> Foreign Scan on ftprt1_p2 fprt1_2
-> Hash
-> Foreign Scan on ftprt2_p2 fprt2_2
(13 rows)
SELECT t1.a, t1.phv, t2.b, t2.phv FROM (SELECT 't1_phv' phv, * FROM fprt1 WHERE a % 25 = 0) t1 FULL JOIN (SELECT 't2_phv' phv, * FROM fprt2 WHERE b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY t1.a, t2.b;
@ -8661,12 +8661,12 @@ SELECT t1.a, t2.b FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) WHERE t1.a
-> Hash Join
Hash Cond: (t2.b = t1.a)
-> Append
-> Foreign Scan on ftprt2_p1 t2
-> Foreign Scan on ftprt2_p2 t2_1
-> Foreign Scan on ftprt2_p1 t2_1
-> Foreign Scan on ftprt2_p2 t2_2
-> Hash
-> Append
-> Foreign Scan on ftprt1_p1 t1
-> Foreign Scan on ftprt1_p2 t1_1
-> Foreign Scan on ftprt1_p1 t1_1
-> Foreign Scan on ftprt1_p2 t1_2
(12 rows)
SELECT t1.a, t2.b FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) WHERE t1.a % 25 = 0 ORDER BY 1,2 FOR UPDATE OF t1;
@ -8710,9 +8710,9 @@ SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 O
Group Key: pagg_tab.a
Filter: (avg(pagg_tab.b) < '22'::numeric)
-> Append
-> Foreign Scan on fpagg_tab_p1 pagg_tab
-> Foreign Scan on fpagg_tab_p2 pagg_tab_1
-> Foreign Scan on fpagg_tab_p3 pagg_tab_2
-> Foreign Scan on fpagg_tab_p1 pagg_tab_1
-> Foreign Scan on fpagg_tab_p2 pagg_tab_2
-> Foreign Scan on fpagg_tab_p3 pagg_tab_3
(9 rows)
-- Plan with partitionwise aggregates is enabled

View File

@ -689,8 +689,8 @@ ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc)
es->rtable = queryDesc->plannedstmt->rtable;
ExplainPreScanNode(queryDesc->planstate, &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->rtable_names);
es->deparse_cxt = deparse_context_for_plan_tree(queryDesc->plannedstmt,
es->rtable_names);
es->printed_subplans = NULL;
/*
@ -1034,6 +1034,14 @@ ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used)
*rels_used = bms_add_member(*rels_used,
((ModifyTable *) plan)->exclRelRTI);
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:
break;
}
@ -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
* 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.
* These are needed in order to interpret PARAM_EXEC Params.
* ancestors is a list of parent Plan and SubPlan nodes, most-closely-nested
* first. These are needed in order to interpret PARAM_EXEC Params.
*
* 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
@ -1953,8 +1961,8 @@ ExplainNode(PlanState *planstate, List *ancestors,
if (haschildren)
{
ExplainOpenGroup("Plans", "Plans", false, es);
/* Pass current PlanState as head of ancestors list for children */
ancestors = lcons(planstate, ancestors);
/* Pass current Plan as head of ancestors list for children */
ancestors = lcons(plan, ancestors);
}
/* initPlan-s */
@ -2075,9 +2083,9 @@ show_plan_tlist(PlanState *planstate, List *ancestors, ExplainState *es)
return;
/* Set up deparsing context */
context = set_deparse_context_planstate(es->deparse_cxt,
(Node *) planstate,
ancestors);
context = set_deparse_context_plan(es->deparse_cxt,
plan,
ancestors);
useprefix = list_length(es->rtable) > 1;
/* Deparse each result column (we now include resjunk ones) */
@ -2106,9 +2114,9 @@ show_expression(Node *node, const char *qlabel,
char *exprstr;
/* Set up deparsing context */
context = set_deparse_context_planstate(es->deparse_cxt,
(Node *) planstate,
ancestors);
context = set_deparse_context_plan(es->deparse_cxt,
planstate->plan,
ancestors);
/* Deparse the expression */
exprstr = deparse_expression(node, context, useprefix, false);
@ -2209,7 +2217,7 @@ show_agg_keys(AggState *astate, List *ancestors,
if (plan->numCols > 0 || plan->groupingSets)
{
/* The key columns refer to the tlist of the child plan */
ancestors = lcons(astate, ancestors);
ancestors = lcons(plan, ancestors);
if (plan->groupingSets)
show_grouping_sets(outerPlanState(astate), plan, ancestors, es);
@ -2232,9 +2240,9 @@ show_grouping_sets(PlanState *planstate, Agg *agg,
ListCell *lc;
/* Set up deparsing context */
context = set_deparse_context_planstate(es->deparse_cxt,
(Node *) planstate,
ancestors);
context = set_deparse_context_plan(es->deparse_cxt,
planstate->plan,
ancestors);
useprefix = (list_length(es->rtable) > 1 || es->verbose);
ExplainOpenGroup("Grouping Sets", "Grouping Sets", false, es);
@ -2339,7 +2347,7 @@ show_group_keys(GroupState *gstate, List *ancestors,
Group *plan = (Group *) gstate->ss.ps.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",
plan->numCols, plan->grpColIdx,
NULL, NULL, NULL,
@ -2371,9 +2379,9 @@ show_sort_group_keys(PlanState *planstate, const char *qlabel,
initStringInfo(&sortkeybuf);
/* Set up deparsing context */
context = set_deparse_context_planstate(es->deparse_cxt,
(Node *) planstate,
ancestors);
context = set_deparse_context_plan(es->deparse_cxt,
plan,
ancestors);
useprefix = (list_length(es->rtable) > 1 || es->verbose);
for (keyno = 0; keyno < nkeys; keyno++)
@ -2479,9 +2487,9 @@ show_tablesample(TableSampleClause *tsc, PlanState *planstate,
ListCell *lc;
/* Set up deparsing context */
context = set_deparse_context_planstate(es->deparse_cxt,
(Node *) planstate,
ancestors);
context = set_deparse_context_plan(es->deparse_cxt,
planstate->plan,
ancestors);
useprefix = list_length(es->rtable) > 1;
/* Get the tablesample method name */
@ -3344,7 +3352,7 @@ ExplainMemberNodes(PlanState **planstates, int nsubnodes, int nplans,
* Explain a list of SubPlans (or initPlans, which also use SubPlan nodes).
*
* The ancestors list should already contain the immediate parent of these
* SubPlanStates.
* SubPlans.
*/
static void
ExplainSubPlans(List *plans, List *ancestors,
@ -3372,8 +3380,17 @@ ExplainSubPlans(List *plans, List *ancestors,
es->printed_subplans = bms_add_member(es->printed_subplans,
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,
relationship, sp->plan_name, es);
ancestors = list_delete_first(ancestors);
}
}

View File

@ -181,6 +181,8 @@ ExecSerializePlan(Plan *plan, EState *estate)
pstmt->planTree = plan;
pstmt->rtable = estate->es_range_table;
pstmt->resultRelations = NIL;
pstmt->rootResultRelations = NIL;
pstmt->appendRelations = NIL;
/*
* Transfer only parallel-safe subplans, leaving a NULL "hole" in the list

View File

@ -2526,9 +2526,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
econtext = mtstate->ps.ps_ExprContext;
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 */
resultRelInfo->ri_onConflict = makeNode(OnConflictSetState);

View File

@ -92,6 +92,7 @@ _copyPlannedStmt(const PlannedStmt *from)
COPY_NODE_FIELD(rtable);
COPY_NODE_FIELD(resultRelations);
COPY_NODE_FIELD(rootResultRelations);
COPY_NODE_FIELD(appendRelations);
COPY_NODE_FIELD(subplans);
COPY_BITMAPSET_FIELD(rewindPlanIDs);
COPY_NODE_FIELD(rowMarks);
@ -241,6 +242,7 @@ _copyAppend(const Append *from)
/*
* copy remainder of node
*/
COPY_BITMAPSET_FIELD(apprelids);
COPY_NODE_FIELD(appendplans);
COPY_SCALAR_FIELD(first_partial_plan);
COPY_NODE_FIELD(part_prune_info);
@ -264,6 +266,7 @@ _copyMergeAppend(const MergeAppend *from)
/*
* copy remainder of node
*/
COPY_BITMAPSET_FIELD(apprelids);
COPY_NODE_FIELD(mergeplans);
COPY_SCALAR_FIELD(numCols);
COPY_POINTER_FIELD(sortColIdx, from->numCols * sizeof(AttrNumber));

View File

@ -310,6 +310,7 @@ _outPlannedStmt(StringInfo str, const PlannedStmt *node)
WRITE_NODE_FIELD(rtable);
WRITE_NODE_FIELD(resultRelations);
WRITE_NODE_FIELD(rootResultRelations);
WRITE_NODE_FIELD(appendRelations);
WRITE_NODE_FIELD(subplans);
WRITE_BITMAPSET_FIELD(rewindPlanIDs);
WRITE_NODE_FIELD(rowMarks);
@ -431,6 +432,7 @@ _outAppend(StringInfo str, const Append *node)
_outPlanInfo(str, (const Plan *) node);
WRITE_BITMAPSET_FIELD(apprelids);
WRITE_NODE_FIELD(appendplans);
WRITE_INT_FIELD(first_partial_plan);
WRITE_NODE_FIELD(part_prune_info);
@ -443,6 +445,7 @@ _outMergeAppend(StringInfo str, const MergeAppend *node)
_outPlanInfo(str, (const Plan *) node);
WRITE_BITMAPSET_FIELD(apprelids);
WRITE_NODE_FIELD(mergeplans);
WRITE_INT_FIELD(numCols);
WRITE_ATTRNUMBER_ARRAY(sortColIdx, node->numCols);
@ -2167,6 +2170,7 @@ _outPlannerGlobal(StringInfo str, const PlannerGlobal *node)
WRITE_NODE_FIELD(finalrowmarks);
WRITE_NODE_FIELD(resultRelations);
WRITE_NODE_FIELD(rootResultRelations);
WRITE_NODE_FIELD(appendRelations);
WRITE_NODE_FIELD(relationOids);
WRITE_NODE_FIELD(invalItems);
WRITE_NODE_FIELD(paramExecTypes);

View File

@ -1512,6 +1512,7 @@ _readPlannedStmt(void)
READ_NODE_FIELD(rtable);
READ_NODE_FIELD(resultRelations);
READ_NODE_FIELD(rootResultRelations);
READ_NODE_FIELD(appendRelations);
READ_NODE_FIELD(subplans);
READ_BITMAPSET_FIELD(rewindPlanIDs);
READ_NODE_FIELD(rowMarks);
@ -1636,6 +1637,7 @@ _readAppend(void)
ReadCommonPlan(&local_node->plan);
READ_BITMAPSET_FIELD(apprelids);
READ_NODE_FIELD(appendplans);
READ_INT_FIELD(first_partial_plan);
READ_NODE_FIELD(part_prune_info);
@ -1653,6 +1655,7 @@ _readMergeAppend(void)
ReadCommonPlan(&local_node->plan);
READ_BITMAPSET_FIELD(apprelids);
READ_NODE_FIELD(mergeplans);
READ_INT_FIELD(numCols);
READ_ATTRNUMBER_ARRAY(sortColIdx, local_node->numCols);

View File

@ -1118,6 +1118,7 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags)
plan->plan.qual = NIL;
plan->plan.lefttree = NULL;
plan->plan.righttree = NULL;
plan->apprelids = rel->relids;
if (pathkeys != NIL)
{
@ -1295,6 +1296,7 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path,
plan->qual = NIL;
plan->lefttree = NULL;
plan->righttree = NULL;
node->apprelids = rel->relids;
/*
* Compute sort column info, and adjust MergeAppend's tlist as needed.

View File

@ -304,6 +304,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
glob->finalrowmarks = NIL;
glob->resultRelations = NIL;
glob->rootResultRelations = NIL;
glob->appendRelations = NIL;
glob->relationOids = NIL;
glob->invalItems = NIL;
glob->paramExecTypes = NIL;
@ -494,6 +495,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
Assert(glob->finalrowmarks == NIL);
Assert(glob->resultRelations == NIL);
Assert(glob->rootResultRelations == NIL);
Assert(glob->appendRelations == NIL);
top_plan = set_plan_references(root, top_plan);
/* ... and the subplans (both regular subplans and initplans) */
Assert(list_length(glob->subplans) == list_length(glob->subroots));
@ -520,6 +522,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
result->rtable = glob->finalrtable;
result->resultRelations = glob->resultRelations;
result->rootResultRelations = glob->rootResultRelations;
result->appendRelations = glob->appendRelations;
result->subplans = glob->subplans;
result->rewindPlanIDs = glob->rewindPlanIDs;
result->rowMarks = glob->finalrowmarks;
@ -1219,6 +1222,7 @@ inheritance_planner(PlannerInfo *root)
Index rootRelation = 0;
List *final_rtable = NIL;
List *final_rowmarks = NIL;
List *final_appendrels = NIL;
int save_rel_array_size = 0;
RelOptInfo **save_rel_array = NULL;
AppendRelInfo **save_append_rel_array = NULL;
@ -1627,12 +1631,13 @@ inheritance_planner(PlannerInfo *root)
* modified subquery RTEs into final_rtable, to ensure we have sane
* copies of those. Also save the first non-excluded child's version
* 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)
{
final_rtable = subroot->parse->rtable;
final_rowmarks = subroot->rowMarks;
final_appendrels = subroot->append_rel_list;
}
else
{
@ -1764,8 +1769,9 @@ inheritance_planner(PlannerInfo *root)
root->simple_rte_array[rti++] = rte;
}
/* Put back adjusted rowmarks, too */
/* Put back adjusted rowmarks and appendrels, too */
root->rowMarks = final_rowmarks;
root->append_rel_list = final_appendrels;
}
/*

View File

@ -108,6 +108,7 @@ static Plan *set_mergeappend_references(PlannerInfo *root,
MergeAppend *mplan,
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_mutator(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,
*
* The flattened rangetable entries are appended to root->glob->finalrtable.
* 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)
* and root->glob->invalItems (for everything else).
*
@ -250,6 +252,28 @@ set_plan_references(PlannerInfo *root, Plan *plan)
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 */
return set_plan_refs(root, plan, rtoffset);
}
@ -1215,16 +1239,7 @@ set_foreignscan_references(PlannerInfo *root,
fix_scan_list(root, fscan->fdw_recheck_quals, rtoffset);
}
/* Adjust fs_relids if needed */
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;
}
fscan->fs_relids = offset_relid_set(fscan->fs_relids, rtoffset);
}
/*
@ -1287,16 +1302,7 @@ set_customscan_references(PlannerInfo *root,
lfirst(lc) = set_plan_refs(root, (Plan *) lfirst(lc), rtoffset);
}
/* Adjust custom_relids if needed */
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;
}
cscan->custom_relids = offset_relid_set(cscan->custom_relids, rtoffset);
}
/*
@ -1338,6 +1344,8 @@ set_append_references(PlannerInfo *root,
*/
set_dummy_tlist_references((Plan *) aplan, rtoffset);
aplan->apprelids = offset_relid_set(aplan->apprelids, rtoffset);
if (aplan->part_prune_info)
{
foreach(l, aplan->part_prune_info->prune_infos)
@ -1400,6 +1408,8 @@ set_mergeappend_references(PlannerInfo *root,
*/
set_dummy_tlist_references((Plan *) mplan, rtoffset);
mplan->apprelids = offset_relid_set(mplan->apprelids, rtoffset);
if (mplan->part_prune_info)
{
foreach(l, mplan->part_prune_info->prune_infos)
@ -1454,6 +1464,25 @@ set_hash_references(PlannerInfo *root, Plan *plan, int rtoffset)
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
* Copy a Var node.

View File

@ -49,6 +49,7 @@
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "nodes/pathnodes.h"
#include "optimizer/optimizer.h"
#include "parser/parse_agg.h"
#include "parser/parse_func.h"
@ -118,6 +119,8 @@ typedef struct
bool varprefix; /* true to print prefixes on Vars */
ParseExprKind special_exprkind; /* set only for exprkinds needing special
* handling */
Bitmapset *appendparents; /* if not null, map child Vars of these relids
* back to the parent rel */
} deparse_context;
/*
@ -125,13 +128,18 @@ typedef struct
* A Var having varlevelsup=N refers to the N'th item (counting from 0) in
* the current context's namespaces list.
*
* The rangetable is the list of actual RTEs from the query tree, and the
* cte list is the list of actual CTEs.
*
* rtable is the list of actual RTEs from the Query or PlannedStmt.
* rtable_names holds the alias name to be used for each RTE (either a C
* string, or NULL for nameless RTEs such as unnamed joins).
* rtable_columns holds the column alias names to be used for each RTE.
*
* subplans is a list of Plan trees for SubPlans and CTEs (it's only used
* in the PlannedStmt case).
* ctes is a list of CommonTableExpr nodes (only used in the Query case).
* appendrels, if not null (it's only used in the PlannedStmt case), is an
* array of AppendRelInfo nodes, indexed by child relid. We use that to map
* child-table Vars to their inheritance parents.
*
* In some cases we need to make names of merged JOIN USING columns unique
* across the whole query, not only per-RTE. If so, unique_using is true
* and using_names is a list of C strings representing names already assigned
@ -139,28 +147,30 @@ typedef struct
*
* When deparsing plan trees, there is always just a single item in the
* deparse_namespace list (since a plan tree never contains Vars with
* varlevelsup > 0). We store the PlanState node that is the immediate
* varlevelsup > 0). We store the Plan node that is the immediate
* parent of the expression to be deparsed, as well as a list of that
* PlanState's ancestors. In addition, we store its outer and inner subplan
* state nodes, as well as their plan nodes' targetlists, and the index tlist
* if the current plan node might contain INDEX_VAR Vars. (These fields could
* be derived on-the-fly from the current PlanState, but it seems notationally
* clearer to set them up as separate fields.)
* Plan's ancestors. In addition, we store its outer and inner subplan nodes,
* as well as their targetlists, and the index tlist if the current plan node
* might contain INDEX_VAR Vars. (These fields could be derived on-the-fly
* from the current Plan node, but it seems notationally clearer to set them
* up as separate fields.)
*/
typedef struct
{
List *rtable; /* List of RangeTblEntry nodes */
List *rtable_names; /* Parallel list of names for RTEs */
List *rtable_columns; /* Parallel list of deparse_columns structs */
List *subplans; /* List of Plan trees for SubPlans */
List *ctes; /* List of CommonTableExpr nodes */
AppendRelInfo **appendrels; /* Array of AppendRelInfo nodes, or NULL */
/* Workspace for column alias assignment: */
bool unique_using; /* Are we making USING names globally unique */
List *using_names; /* List of assigned names for USING columns */
/* Remaining fields are used only when deparsing a Plan tree: */
PlanState *planstate; /* immediate parent of current expression */
List *ancestors; /* ancestors of planstate */
PlanState *outer_planstate; /* outer subplan state, or NULL if none */
PlanState *inner_planstate; /* inner subplan state, or NULL if none */
Plan *plan; /* immediate parent of current expression */
List *ancestors; /* ancestors of plan */
Plan *outer_plan; /* outer subnode, or NULL if none */
Plan *inner_plan; /* inner subnode, or NULL if none */
List *outer_tlist; /* referent for OUTER_VAR Vars */
List *inner_tlist; /* referent for INNER_VAR Vars */
List *index_tlist; /* referent for INDEX_VAR Vars */
@ -287,6 +297,10 @@ typedef struct
int counter; /* Largest addition used so far for name */
} NameHashEntry;
/* Callback signature for resolve_special_varno() */
typedef void (*rsv_callback) (Node *node, deparse_context *context,
void *callback_arg);
/* ----------
* Global data
@ -357,8 +371,8 @@ static void identify_join_columns(JoinExpr *j, RangeTblEntry *jrte,
static void flatten_join_using_qual(Node *qual,
List **leftvars, List **rightvars);
static char *get_rtable_name(int rtindex, deparse_context *context);
static void set_deparse_planstate(deparse_namespace *dpns, PlanState *ps);
static void push_child_plan(deparse_namespace *dpns, PlanState *ps,
static void set_deparse_plan(deparse_namespace *dpns, Plan *plan);
static void push_child_plan(deparse_namespace *dpns, Plan *plan,
deparse_namespace *save_dpns);
static void pop_child_plan(deparse_namespace *dpns,
deparse_namespace *save_dpns);
@ -404,10 +418,9 @@ static void get_rule_windowspec(WindowClause *wc, List *targetList,
static char *get_variable(Var *var, int levelsup, bool istoplevel,
deparse_context *context);
static void get_special_variable(Node *node, deparse_context *context,
void *private);
void *callback_arg);
static void resolve_special_varno(Node *node, deparse_context *context,
void *private,
void (*callback) (Node *, deparse_context *, void *));
rsv_callback callback, void *callback_arg);
static Node *find_param_referent(Param *param, deparse_context *context,
deparse_namespace **dpns_p, ListCell **ancestor_cell_p);
static void get_parameter(Param *param, deparse_context *context);
@ -429,7 +442,7 @@ static void get_func_expr(FuncExpr *expr, deparse_context *context,
static void get_agg_expr(Aggref *aggref, deparse_context *context,
Aggref *original_aggref);
static void get_agg_combine_expr(Node *node, deparse_context *context,
void *private);
void *callback_arg);
static void get_windowfunc_expr(WindowFunc *wfunc, deparse_context *context);
static void get_coercion_expr(Node *arg, deparse_context *context,
Oid resulttype, int32 resulttypmod,
@ -1022,7 +1035,9 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty)
/* Build two-element rtable */
memset(&dpns, 0, sizeof(dpns));
dpns.rtable = list_make2(oldrte, newrte);
dpns.subplans = NIL;
dpns.ctes = NIL;
dpns.appendrels = NULL;
set_rtable_names(&dpns, NIL, NULL);
set_simple_column_names(&dpns);
@ -1036,6 +1051,7 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty)
context.wrapColumn = WRAP_COLUMN_DEFAULT;
context.indentLevel = PRETTYINDENT_STD;
context.special_exprkind = EXPR_KIND_NONE;
context.appendparents = NULL;
get_rule_expr(qual, &context, false);
@ -3238,6 +3254,7 @@ deparse_expression_pretty(Node *expr, List *dpcontext,
context.wrapColumn = WRAP_COLUMN_DEFAULT;
context.indentLevel = startIndent;
context.special_exprkind = EXPR_KIND_NONE;
context.appendparents = NULL;
get_rule_expr(expr, &context, showimplicit);
@ -3274,7 +3291,9 @@ deparse_context_for(const char *aliasname, Oid relid)
/* Build one-element rtable */
dpns->rtable = list_make1(rte);
dpns->subplans = NIL;
dpns->ctes = NIL;
dpns->appendrels = NULL;
set_rtable_names(dpns, NIL, NULL);
set_simple_column_names(dpns);
@ -3283,29 +3302,50 @@ deparse_context_for(const char *aliasname, Oid relid)
}
/*
* deparse_context_for_plan_rtable - Build deparse context for a plan's rtable
* deparse_context_for_plan_tree - Build deparse context for a Plan tree
*
* When deparsing an expression in a Plan tree, we use the plan's rangetable
* to resolve names of simple Vars. The initialization of column names for
* this is rather expensive if the rangetable is large, and it'll be the same
* for every expression in the Plan tree; so we do it just once and re-use
* the result of this function for each expression. (Note that the result
* is not usable until set_deparse_context_planstate() is applied to it.)
* is not usable until set_deparse_context_plan() is applied to it.)
*
* In addition to the plan's rangetable list, pass the per-RTE alias names
* In addition to the PlannedStmt, pass the per-RTE alias names
* assigned by a previous call to select_rtable_names_for_explain.
*/
List *
deparse_context_for_plan_rtable(List *rtable, List *rtable_names)
deparse_context_for_plan_tree(PlannedStmt *pstmt, List *rtable_names)
{
deparse_namespace *dpns;
dpns = (deparse_namespace *) palloc0(sizeof(deparse_namespace));
/* Initialize fields that stay the same across the whole plan tree */
dpns->rtable = rtable;
dpns->rtable = pstmt->rtable;
dpns->rtable_names = rtable_names;
dpns->subplans = pstmt->subplans;
dpns->ctes = NIL;
if (pstmt->appendRelations)
{
/* Set up the array, indexed by child relid */
int ntables = list_length(dpns->rtable);
ListCell *lc;
dpns->appendrels = (AppendRelInfo **)
palloc0((ntables + 1) * sizeof(AppendRelInfo *));
foreach(lc, pstmt->appendRelations)
{
AppendRelInfo *appinfo = lfirst_node(AppendRelInfo, lc);
Index crelid = appinfo->child_relid;
Assert(crelid > 0 && crelid <= ntables);
Assert(dpns->appendrels[crelid] == NULL);
dpns->appendrels[crelid] = appinfo;
}
}
else
dpns->appendrels = NULL; /* don't need it */
/*
* Set up column name aliases. We will get rather bogus results for join
@ -3319,11 +3359,11 @@ deparse_context_for_plan_rtable(List *rtable, List *rtable_names)
}
/*
* set_deparse_context_planstate - Specify Plan node containing expression
* set_deparse_context_plan - Specify Plan node containing expression
*
* When deparsing an expression in a Plan tree, we might have to resolve
* OUTER_VAR, INNER_VAR, or INDEX_VAR references. To do this, the caller must
* provide the parent PlanState node. Then OUTER_VAR and INNER_VAR references
* provide the parent Plan node. Then OUTER_VAR and INNER_VAR references
* can be resolved by drilling down into the left and right child plans.
* Similarly, INDEX_VAR references can be resolved by reference to the
* indextlist given in a parent IndexOnlyScan node, or to the scan tlist in
@ -3332,23 +3372,19 @@ deparse_context_for_plan_rtable(List *rtable, List *rtable_names)
* for those, we can only deparse the indexqualorig fields, which won't
* contain INDEX_VAR Vars.)
*
* Note: planstate really ought to be declared as "PlanState *", but we use
* "Node *" to avoid having to include execnodes.h in ruleutils.h.
*
* The ancestors list is a list of the PlanState's parent PlanStates, the
* most-closely-nested first. This is needed to resolve PARAM_EXEC Params.
* Note we assume that all the PlanStates share the same rtable.
* The ancestors list is a list of the Plan's parent Plan and SubPlan nodes,
* the most-closely-nested first. This is needed to resolve PARAM_EXEC
* Params. Note we assume that all the Plan nodes share the same rtable.
*
* Once this function has been called, deparse_expression() can be called on
* subsidiary expression(s) of the specified PlanState node. To deparse
* subsidiary expression(s) of the specified Plan node. To deparse
* expressions of a different Plan node in the same Plan tree, re-call this
* function to identify the new parent Plan node.
*
* The result is the same List passed in; this is a notational convenience.
*/
List *
set_deparse_context_planstate(List *dpcontext,
Node *planstate, List *ancestors)
set_deparse_context_plan(List *dpcontext, Plan *plan, List *ancestors)
{
deparse_namespace *dpns;
@ -3357,7 +3393,7 @@ set_deparse_context_planstate(List *dpcontext,
dpns = (deparse_namespace *) linitial(dpcontext);
/* Set our attention on the specific plan node passed in */
set_deparse_planstate(dpns, (PlanState *) planstate);
set_deparse_plan(dpns, plan);
dpns->ancestors = ancestors;
return dpcontext;
@ -3377,7 +3413,9 @@ select_rtable_names_for_explain(List *rtable, Bitmapset *rels_used)
memset(&dpns, 0, sizeof(dpns));
dpns.rtable = rtable;
dpns.subplans = NIL;
dpns.ctes = NIL;
dpns.appendrels = NULL;
set_rtable_names(&dpns, NIL, rels_used);
/* We needn't bother computing column aliases yet */
@ -3557,7 +3595,9 @@ set_deparse_for_query(deparse_namespace *dpns, Query *query,
/* Initialize *dpns and fill rtable/ctes links */
memset(dpns, 0, sizeof(deparse_namespace));
dpns->rtable = query->rtable;
dpns->subplans = NIL;
dpns->ctes = query->cteList;
dpns->appendrels = NULL;
/* Assign a unique relation alias to each RTE */
set_rtable_names(dpns, parent_namespaces, NULL);
@ -4625,19 +4665,19 @@ get_rtable_name(int rtindex, deparse_context *context)
}
/*
* set_deparse_planstate: set up deparse_namespace to parse subexpressions
* of a given PlanState node
* set_deparse_plan: set up deparse_namespace to parse subexpressions
* of a given Plan node
*
* This sets the planstate, outer_planstate, inner_planstate, outer_tlist,
* inner_tlist, and index_tlist fields. Caller is responsible for adjusting
* the ancestors list if necessary. Note that the rtable and ctes fields do
* This sets the plan, outer_plan, inner_plan, outer_tlist, inner_tlist,
* and index_tlist fields. Caller is responsible for adjusting the ancestors
* list if necessary. Note that the rtable, subplans, and ctes fields do
* not need to change when shifting attention to different plan nodes in a
* single plan tree.
*/
static void
set_deparse_planstate(deparse_namespace *dpns, PlanState *ps)
set_deparse_plan(deparse_namespace *dpns, Plan *plan)
{
dpns->planstate = ps;
dpns->plan = plan;
/*
* We special-case Append and MergeAppend to pretend that the first child
@ -4647,17 +4687,17 @@ set_deparse_planstate(deparse_namespace *dpns, PlanState *ps)
* first child plan is the OUTER referent; this is to support RETURNING
* lists containing references to non-target relations.
*/
if (IsA(ps, AppendState))
dpns->outer_planstate = ((AppendState *) ps)->appendplans[0];
else if (IsA(ps, MergeAppendState))
dpns->outer_planstate = ((MergeAppendState *) ps)->mergeplans[0];
else if (IsA(ps, ModifyTableState))
dpns->outer_planstate = ((ModifyTableState *) ps)->mt_plans[0];
if (IsA(plan, Append))
dpns->outer_plan = linitial(((Append *) plan)->appendplans);
else if (IsA(plan, MergeAppend))
dpns->outer_plan = linitial(((MergeAppend *) plan)->mergeplans);
else if (IsA(plan, ModifyTable))
dpns->outer_plan = linitial(((ModifyTable *) plan)->plans);
else
dpns->outer_planstate = outerPlanState(ps);
dpns->outer_plan = outerPlan(plan);
if (dpns->outer_planstate)
dpns->outer_tlist = dpns->outer_planstate->plan->targetlist;
if (dpns->outer_plan)
dpns->outer_tlist = dpns->outer_plan->targetlist;
else
dpns->outer_tlist = NIL;
@ -4670,29 +4710,30 @@ set_deparse_planstate(deparse_namespace *dpns, PlanState *ps)
* to reuse OUTER, it's used for RETURNING in some modify table cases,
* although not INSERT .. CONFLICT).
*/
if (IsA(ps, SubqueryScanState))
dpns->inner_planstate = ((SubqueryScanState *) ps)->subplan;
else if (IsA(ps, CteScanState))
dpns->inner_planstate = ((CteScanState *) ps)->cteplanstate;
else if (IsA(ps, ModifyTableState))
dpns->inner_planstate = ps;
if (IsA(plan, SubqueryScan))
dpns->inner_plan = ((SubqueryScan *) plan)->subplan;
else if (IsA(plan, CteScan))
dpns->inner_plan = list_nth(dpns->subplans,
((CteScan *) plan)->ctePlanId - 1);
else if (IsA(plan, ModifyTable))
dpns->inner_plan = plan;
else
dpns->inner_planstate = innerPlanState(ps);
dpns->inner_plan = innerPlan(plan);
if (IsA(ps, ModifyTableState))
dpns->inner_tlist = ((ModifyTableState *) ps)->mt_excludedtlist;
else if (dpns->inner_planstate)
dpns->inner_tlist = dpns->inner_planstate->plan->targetlist;
if (IsA(plan, ModifyTable))
dpns->inner_tlist = ((ModifyTable *) plan)->exclRelTlist;
else if (dpns->inner_plan)
dpns->inner_tlist = dpns->inner_plan->targetlist;
else
dpns->inner_tlist = NIL;
/* Set up referent for INDEX_VAR Vars, if needed */
if (IsA(ps->plan, IndexOnlyScan))
dpns->index_tlist = ((IndexOnlyScan *) ps->plan)->indextlist;
else if (IsA(ps->plan, ForeignScan))
dpns->index_tlist = ((ForeignScan *) ps->plan)->fdw_scan_tlist;
else if (IsA(ps->plan, CustomScan))
dpns->index_tlist = ((CustomScan *) ps->plan)->custom_scan_tlist;
if (IsA(plan, IndexOnlyScan))
dpns->index_tlist = ((IndexOnlyScan *) plan)->indextlist;
else if (IsA(plan, ForeignScan))
dpns->index_tlist = ((ForeignScan *) plan)->fdw_scan_tlist;
else if (IsA(plan, CustomScan))
dpns->index_tlist = ((CustomScan *) plan)->custom_scan_tlist;
else
dpns->index_tlist = NIL;
}
@ -4710,17 +4751,17 @@ set_deparse_planstate(deparse_namespace *dpns, PlanState *ps)
* previous state for pop_child_plan.
*/
static void
push_child_plan(deparse_namespace *dpns, PlanState *ps,
push_child_plan(deparse_namespace *dpns, Plan *plan,
deparse_namespace *save_dpns)
{
/* Save state for restoration later */
*save_dpns = *dpns;
/* Link current plan node into ancestors list */
dpns->ancestors = lcons(dpns->planstate, dpns->ancestors);
dpns->ancestors = lcons(dpns->plan, dpns->ancestors);
/* Set attention on selected child */
set_deparse_planstate(dpns, ps);
set_deparse_plan(dpns, plan);
}
/*
@ -4760,7 +4801,7 @@ static void
push_ancestor_plan(deparse_namespace *dpns, ListCell *ancestor_cell,
deparse_namespace *save_dpns)
{
PlanState *ps = (PlanState *) lfirst(ancestor_cell);
Plan *plan = (Plan *) lfirst(ancestor_cell);
/* Save state for restoration later */
*save_dpns = *dpns;
@ -4771,7 +4812,7 @@ push_ancestor_plan(deparse_namespace *dpns, ListCell *ancestor_cell,
list_cell_number(dpns->ancestors, ancestor_cell) + 1);
/* Set attention on selected ancestor */
set_deparse_planstate(dpns, ps);
set_deparse_plan(dpns, plan);
}
/*
@ -4931,6 +4972,7 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
context.wrapColumn = WRAP_COLUMN_DEFAULT;
context.indentLevel = PRETTYINDENT_STD;
context.special_exprkind = EXPR_KIND_NONE;
context.appendparents = NULL;
set_deparse_for_query(&dpns, query, NIL);
@ -5093,6 +5135,7 @@ get_query_def(Query *query, StringInfo buf, List *parentnamespace,
context.wrapColumn = wrapColumn;
context.indentLevel = startIndent;
context.special_exprkind = EXPR_KIND_NONE;
context.appendparents = NULL;
set_deparse_for_query(&dpns, query, parentnamespace);
@ -6694,15 +6737,62 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
*/
if (var->varno >= 1 && var->varno <= list_length(dpns->rtable))
{
rte = rt_fetch(var->varno, dpns->rtable);
refname = (char *) list_nth(dpns->rtable_names, var->varno - 1);
colinfo = deparse_columns_fetch(var->varno, dpns);
attnum = var->varattno;
Index varno = var->varno;
AttrNumber varattno = var->varattno;
/*
* We might have been asked to map child Vars to some parent relation.
*/
if (context->appendparents && dpns->appendrels)
{
Index pvarno = varno;
AttrNumber pvarattno = varattno;
AppendRelInfo *appinfo = dpns->appendrels[pvarno];
bool found = false;
/* Only map up to inheritance parents, not UNION ALL appendrels */
while (appinfo &&
rt_fetch(appinfo->parent_relid,
dpns->rtable)->rtekind == RTE_RELATION)
{
found = false;
if (pvarattno > 0) /* system columns stay as-is */
{
if (pvarattno > appinfo->num_child_cols)
break; /* safety check */
pvarattno = appinfo->parent_colnos[pvarattno - 1];
if (pvarattno == 0)
break; /* Var is local to child */
}
pvarno = appinfo->parent_relid;
found = true;
/* If the parent is itself a child, continue up. */
Assert(pvarno > 0 && pvarno <= list_length(dpns->rtable));
appinfo = dpns->appendrels[pvarno];
}
/*
* If we found an ancestral rel, and that rel is included in
* appendparents, print that column not the original one.
*/
if (found && bms_is_member(pvarno, context->appendparents))
{
varno = pvarno;
varattno = pvarattno;
}
}
rte = rt_fetch(varno, dpns->rtable);
refname = (char *) list_nth(dpns->rtable_names, varno - 1);
colinfo = deparse_columns_fetch(varno, dpns);
attnum = varattno;
}
else
{
resolve_special_varno((Node *) var, context, NULL,
get_special_variable);
resolve_special_varno((Node *) var, context,
get_special_variable, NULL);
return NULL;
}
@ -6715,22 +6805,22 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
* no alias. So in that case, drill down to the subplan and print the
* contents of the referenced tlist item. This works because in a plan
* tree, such Vars can only occur in a SubqueryScan or CteScan node, and
* we'll have set dpns->inner_planstate to reference the child plan node.
* we'll have set dpns->inner_plan to reference the child plan node.
*/
if ((rte->rtekind == RTE_SUBQUERY || rte->rtekind == RTE_CTE) &&
attnum > list_length(rte->eref->colnames) &&
dpns->inner_planstate)
dpns->inner_plan)
{
TargetEntry *tle;
deparse_namespace save_dpns;
tle = get_tle_by_resno(dpns->inner_tlist, var->varattno);
tle = get_tle_by_resno(dpns->inner_tlist, attnum);
if (!tle)
elog(ERROR, "invalid attnum %d for relation \"%s\"",
var->varattno, rte->eref->aliasname);
attnum, rte->eref->aliasname);
Assert(netlevelsup == 0);
push_child_plan(dpns, dpns->inner_planstate, &save_dpns);
push_child_plan(dpns, dpns->inner_plan, &save_dpns);
/*
* Force parentheses because our caller probably assumed a Var is a
@ -6829,13 +6919,13 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
* get_rule_expr.
*/
static void
get_special_variable(Node *node, deparse_context *context, void *private)
get_special_variable(Node *node, deparse_context *context, void *callback_arg)
{
StringInfo buf = context->buf;
/*
* Force parentheses because our caller probably assumed a Var is a simple
* expression.
* For a non-Var referent, force parentheses because our caller probably
* assumed a Var is a simple expression.
*/
if (!IsA(node, Var))
appendStringInfoChar(buf, '(');
@ -6850,16 +6940,19 @@ get_special_variable(Node *node, deparse_context *context, void *private)
* invoke the callback provided.
*/
static void
resolve_special_varno(Node *node, deparse_context *context, void *private,
void (*callback) (Node *, deparse_context *, void *))
resolve_special_varno(Node *node, deparse_context *context,
rsv_callback callback, void *callback_arg)
{
Var *var;
deparse_namespace *dpns;
/* This function is recursive, so let's be paranoid. */
check_stack_depth();
/* If it's not a Var, invoke the callback. */
if (!IsA(node, Var))
{
callback(node, context, private);
(*callback) (node, context, callback_arg);
return;
}
@ -6869,20 +6962,37 @@ resolve_special_varno(Node *node, deparse_context *context, void *private,
var->varlevelsup);
/*
* It's a special RTE, so recurse.
* If varno is special, recurse.
*/
if (var->varno == OUTER_VAR && dpns->outer_tlist)
{
TargetEntry *tle;
deparse_namespace save_dpns;
Bitmapset *save_appendparents;
tle = get_tle_by_resno(dpns->outer_tlist, var->varattno);
if (!tle)
elog(ERROR, "bogus varattno for OUTER_VAR var: %d", var->varattno);
push_child_plan(dpns, dpns->outer_planstate, &save_dpns);
resolve_special_varno((Node *) tle->expr, context, private, callback);
/*
* If we're descending to the first child of an Append or MergeAppend,
* update appendparents. This will affect deparsing of all Vars
* appearing within the eventually-resolved subexpression.
*/
save_appendparents = context->appendparents;
if (IsA(dpns->plan, Append))
context->appendparents = bms_union(context->appendparents,
((Append *) dpns->plan)->apprelids);
else if (IsA(dpns->plan, MergeAppend))
context->appendparents = bms_union(context->appendparents,
((MergeAppend *) dpns->plan)->apprelids);
push_child_plan(dpns, dpns->outer_plan, &save_dpns);
resolve_special_varno((Node *) tle->expr, context,
callback, callback_arg);
pop_child_plan(dpns, &save_dpns);
context->appendparents = save_appendparents;
return;
}
else if (var->varno == INNER_VAR && dpns->inner_tlist)
@ -6894,8 +7004,9 @@ resolve_special_varno(Node *node, deparse_context *context, void *private,
if (!tle)
elog(ERROR, "bogus varattno for INNER_VAR var: %d", var->varattno);
push_child_plan(dpns, dpns->inner_planstate, &save_dpns);
resolve_special_varno((Node *) tle->expr, context, private, callback);
push_child_plan(dpns, dpns->inner_plan, &save_dpns);
resolve_special_varno((Node *) tle->expr, context,
callback, callback_arg);
pop_child_plan(dpns, &save_dpns);
return;
}
@ -6907,14 +7018,15 @@ resolve_special_varno(Node *node, deparse_context *context, void *private,
if (!tle)
elog(ERROR, "bogus varattno for INDEX_VAR var: %d", var->varattno);
resolve_special_varno((Node *) tle->expr, context, private, callback);
resolve_special_varno((Node *) tle->expr, context,
callback, callback_arg);
return;
}
else if (var->varno < 1 || var->varno > list_length(dpns->rtable))
elog(ERROR, "bogus varno: %d", var->varno);
/* Not special. Just invoke the callback. */
callback(node, context, private);
(*callback) (node, context, callback_arg);
}
/*
@ -7005,6 +7117,10 @@ get_name_for_var_field(Var *var, int fieldno,
* Try to find the relevant RTE in this rtable. In a plan tree, it's
* likely that varno is OUTER_VAR or INNER_VAR, in which case we must dig
* down into the subplans, or INDEX_VAR, which is resolved similarly.
*
* Note: unlike get_variable and resolve_special_varno, we need not worry
* about inheritance mapping: a child Var should have the same datatype as
* its parent, and here we're really only interested in the Var's type.
*/
if (var->varno >= 1 && var->varno <= list_length(dpns->rtable))
{
@ -7022,7 +7138,7 @@ get_name_for_var_field(Var *var, int fieldno,
elog(ERROR, "bogus varattno for OUTER_VAR var: %d", var->varattno);
Assert(netlevelsup == 0);
push_child_plan(dpns, dpns->outer_planstate, &save_dpns);
push_child_plan(dpns, dpns->outer_plan, &save_dpns);
result = get_name_for_var_field((Var *) tle->expr, fieldno,
levelsup, context);
@ -7041,7 +7157,7 @@ get_name_for_var_field(Var *var, int fieldno,
elog(ERROR, "bogus varattno for INNER_VAR var: %d", var->varattno);
Assert(netlevelsup == 0);
push_child_plan(dpns, dpns->inner_planstate, &save_dpns);
push_child_plan(dpns, dpns->inner_plan, &save_dpns);
result = get_name_for_var_field((Var *) tle->expr, fieldno,
levelsup, context);
@ -7151,7 +7267,7 @@ get_name_for_var_field(Var *var, int fieldno,
deparse_namespace save_dpns;
const char *result;
if (!dpns->inner_planstate)
if (!dpns->inner_plan)
elog(ERROR, "failed to find plan for subquery %s",
rte->eref->aliasname);
tle = get_tle_by_resno(dpns->inner_tlist, attnum);
@ -7159,7 +7275,7 @@ get_name_for_var_field(Var *var, int fieldno,
elog(ERROR, "bogus varattno for subquery var: %d",
attnum);
Assert(netlevelsup == 0);
push_child_plan(dpns, dpns->inner_planstate, &save_dpns);
push_child_plan(dpns, dpns->inner_plan, &save_dpns);
result = get_name_for_var_field((Var *) tle->expr, fieldno,
levelsup, context);
@ -7269,7 +7385,7 @@ get_name_for_var_field(Var *var, int fieldno,
deparse_namespace save_dpns;
const char *result;
if (!dpns->inner_planstate)
if (!dpns->inner_plan)
elog(ERROR, "failed to find plan for CTE %s",
rte->eref->aliasname);
tle = get_tle_by_resno(dpns->inner_tlist, attnum);
@ -7277,7 +7393,7 @@ get_name_for_var_field(Var *var, int fieldno,
elog(ERROR, "bogus varattno for subquery var: %d",
attnum);
Assert(netlevelsup == 0);
push_child_plan(dpns, dpns->inner_planstate, &save_dpns);
push_child_plan(dpns, dpns->inner_plan, &save_dpns);
result = get_name_for_var_field((Var *) tle->expr, fieldno,
levelsup, context);
@ -7318,22 +7434,22 @@ find_param_referent(Param *param, deparse_context *context,
/*
* If it's a PARAM_EXEC parameter, look for a matching NestLoopParam or
* SubPlan argument. This will necessarily be in some ancestor of the
* current expression's PlanState.
* current expression's Plan node.
*/
if (param->paramkind == PARAM_EXEC)
{
deparse_namespace *dpns;
PlanState *child_ps;
Plan *child_plan;
bool in_same_plan_level;
ListCell *lc;
dpns = (deparse_namespace *) linitial(context->namespaces);
child_ps = dpns->planstate;
child_plan = dpns->plan;
in_same_plan_level = true;
foreach(lc, dpns->ancestors)
{
PlanState *ps = (PlanState *) lfirst(lc);
Node *ancestor = (Node *) lfirst(lc);
ListCell *lc2;
/*
@ -7341,11 +7457,11 @@ find_param_referent(Param *param, deparse_context *context,
* we've crawled up out of a subplan, this couldn't possibly be
* the right match.
*/
if (IsA(ps, NestLoopState) &&
child_ps == innerPlanState(ps) &&
if (IsA(ancestor, NestLoop) &&
child_plan == innerPlan(ancestor) &&
in_same_plan_level)
{
NestLoop *nl = (NestLoop *) ps->plan;
NestLoop *nl = (NestLoop *) ancestor;
foreach(lc2, nl->nestParams)
{
@ -7362,19 +7478,14 @@ find_param_referent(Param *param, deparse_context *context,
}
/*
* Check to see if we're crawling up from a subplan.
* If ancestor is a SubPlan, check the arguments it provides.
*/
foreach(lc2, ps->subPlan)
if (IsA(ancestor, SubPlan))
{
SubPlanState *sstate = (SubPlanState *) lfirst(lc2);
SubPlan *subplan = sstate->subplan;
SubPlan *subplan = (SubPlan *) ancestor;
ListCell *lc3;
ListCell *lc4;
if (child_ps != sstate->planstate)
continue;
/* Matched subplan, so check its arguments */
forboth(lc3, subplan->parParam, lc4, subplan->args)
{
int paramid = lfirst_int(lc3);
@ -7382,41 +7493,61 @@ find_param_referent(Param *param, deparse_context *context,
if (paramid == param->paramid)
{
/* Found a match, so return it */
*dpns_p = dpns;
*ancestor_cell_p = lc;
return arg;
/*
* Found a match, so return it. But, since Vars in
* the arg are to be evaluated in the surrounding
* context, we have to point to the next ancestor item
* that is *not* a SubPlan.
*/
ListCell *rest;
for_each_cell(rest, dpns->ancestors,
lnext(dpns->ancestors, lc))
{
Node *ancestor2 = (Node *) lfirst(rest);
if (!IsA(ancestor2, SubPlan))
{
*dpns_p = dpns;
*ancestor_cell_p = rest;
return arg;
}
}
elog(ERROR, "SubPlan cannot be outermost ancestor");
}
}
/* Keep looking, but we are emerging from a subplan. */
/* We have emerged from a subplan. */
in_same_plan_level = false;
break;
/* SubPlan isn't a kind of Plan, so skip the rest */
continue;
}
/*
* Likewise check to see if we're emerging from an initplan.
* Initplans never have any parParams, so no need to search that
* list, but we need to know if we should reset
* Check to see if we're emerging from an initplan of the current
* ancestor plan. Initplans never have any parParams, so no need
* to search that list, but we need to know if we should reset
* in_same_plan_level.
*/
foreach(lc2, ps->initPlan)
foreach(lc2, ((Plan *) ancestor)->initPlan)
{
SubPlanState *sstate = (SubPlanState *) lfirst(lc2);
SubPlan *subplan = castNode(SubPlan, lfirst(lc2));
if (child_ps != sstate->planstate)
if (child_plan != (Plan *) list_nth(dpns->subplans,
subplan->plan_id - 1))
continue;
/* No parameters to be had here. */
Assert(sstate->subplan->parParam == NIL);
Assert(subplan->parParam == NIL);
/* Keep looking, but we are emerging from an initplan. */
/* We have emerged from an initplan. */
in_same_plan_level = false;
break;
}
/* No luck, crawl up to next ancestor */
child_ps = ps;
child_plan = (Plan *) ancestor;
}
}
@ -9269,11 +9400,12 @@ get_agg_expr(Aggref *aggref, deparse_context *context,
*/
if (DO_AGGSPLIT_COMBINE(aggref->aggsplit))
{
TargetEntry *tle = linitial_node(TargetEntry, aggref->args);
TargetEntry *tle;
Assert(list_length(aggref->args) == 1);
resolve_special_varno((Node *) tle->expr, context, original_aggref,
get_agg_combine_expr);
tle = linitial_node(TargetEntry, aggref->args);
resolve_special_varno((Node *) tle->expr, context,
get_agg_combine_expr, original_aggref);
return;
}
@ -9358,10 +9490,10 @@ get_agg_expr(Aggref *aggref, deparse_context *context,
* Aggref and then calls this.
*/
static void
get_agg_combine_expr(Node *node, deparse_context *context, void *private)
get_agg_combine_expr(Node *node, deparse_context *context, void *callback_arg)
{
Aggref *aggref;
Aggref *original_aggref = private;
Aggref *original_aggref = callback_arg;
if (!IsA(node, Aggref))
elog(ERROR, "combining Aggref does not point to an Aggref");

View File

@ -1171,7 +1171,6 @@ typedef struct ModifyTableState
List **mt_arowmarks; /* per-subplan ExecAuxRowMark lists */
EPQState mt_epqstate; /* for evaluating EvalPlanQual rechecks */
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

View File

@ -122,6 +122,8 @@ typedef struct PlannerGlobal
List *rootResultRelations; /* "flat" list of integer RT indexes */
List *appendRelations; /* "flat" list of AppendRelInfos */
List *relationOids; /* OIDs of relations the plan depends on */
List *invalItems; /* other dependencies, as PlanInvalItems */

View File

@ -74,6 +74,8 @@ typedef struct PlannedStmt
*/
List *rootResultRelations;
List *appendRelations; /* list of AppendRelInfo nodes */
List *subplans; /* Plan trees for SubPlan expressions; note
* that some could be NULL */
@ -249,6 +251,7 @@ struct PartitionPruneInfo; /* forward reference to struct below */
typedef struct Append
{
Plan plan;
Bitmapset *apprelids; /* RTIs of appendrel(s) formed by this node */
List *appendplans;
/*
@ -269,6 +272,7 @@ typedef struct Append
typedef struct MergeAppend
{
Plan plan;
Bitmapset *apprelids; /* RTIs of appendrel(s) formed by this node */
List *mergeplans;
/* these fields are just like the sort-key info in struct Sort: */
int numCols; /* number of sort-key columns */

View File

@ -17,6 +17,9 @@
#include "nodes/parsenodes.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_columns(Oid indexrelid, bool pretty);
@ -28,9 +31,10 @@ extern char *pg_get_constraintdef_command(Oid constraintId);
extern char *deparse_expression(Node *expr, List *dpcontext,
bool forceprefix, bool showimplicit);
extern List *deparse_context_for(const char *aliasname, Oid relid);
extern List *deparse_context_for_plan_rtable(List *rtable, List *rtable_names);
extern List *set_deparse_context_planstate(List *dpcontext,
Node *planstate, List *ancestors);
extern List *deparse_context_for_plan_tree(struct PlannedStmt *pstmt,
List *rtable_names);
extern List *set_deparse_context_plan(List *dpcontext,
struct Plan *plan, List *ancestors);
extern List *select_rtable_names_for_explain(List *rtable,
Bitmapset *rels_used);
extern char *generate_collation_name(Oid collid);

View File

@ -1005,24 +1005,24 @@ explain (costs off)
-> Limit
-> Merge Append
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 Only Scan using minmaxtest1i on minmaxtest1 minmaxtest_1
-> Index Only Scan using minmaxtest1i on minmaxtest1 minmaxtest_2
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 Only Scan using minmaxtest3i on minmaxtest3 minmaxtest_3
-> Index Only Scan using minmaxtest3i on minmaxtest3 minmaxtest_4
InitPlan 2 (returns $1)
-> Limit
-> Merge Append
Sort Key: minmaxtest_4.f1 DESC
-> Index Only Scan Backward using minmaxtesti on minmaxtest minmaxtest_4
Sort Key: minmaxtest_5.f1 DESC
-> Index Only Scan Backward using minmaxtesti on minmaxtest minmaxtest_6
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 Only Scan using minmaxtest2i on minmaxtest2 minmaxtest_6
-> Index Only Scan using minmaxtest2i on minmaxtest2 minmaxtest_8
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)
select min(f1), max(f1) from minmaxtest;
@ -1041,24 +1041,24 @@ explain (costs off)
-> Limit
-> Merge Append
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 Only Scan using minmaxtest1i on minmaxtest1 minmaxtest_1
-> Index Only Scan using minmaxtest1i on minmaxtest1 minmaxtest_2
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 Only Scan using minmaxtest3i on minmaxtest3 minmaxtest_3
-> Index Only Scan using minmaxtest3i on minmaxtest3 minmaxtest_4
InitPlan 2 (returns $1)
-> Limit
-> Merge Append
Sort Key: minmaxtest_4.f1 DESC
-> Index Only Scan Backward using minmaxtesti on minmaxtest minmaxtest_4
Sort Key: minmaxtest_5.f1 DESC
-> Index Only Scan Backward using minmaxtesti on minmaxtest minmaxtest_6
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 Only Scan using minmaxtest2i on minmaxtest2 minmaxtest_6
-> Index Only Scan using minmaxtest2i on minmaxtest2 minmaxtest_8
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 Key: ($0), ($1)
-> Result
@ -1155,8 +1155,8 @@ explain (costs off) select * from t1 group by a,b,c,d;
HashAggregate
Group Key: t1.a, t1.b, t1.c, t1.d
-> Append
-> Seq Scan on t1
-> Seq Scan on t1c t1_1
-> Seq Scan on t1 t1_1
-> Seq Scan on t1c t1_2
(5 rows)
-- Okay to remove columns if we're only querying the parent.
@ -1179,13 +1179,13 @@ create temp table p_t1_1 partition of p_t1 for values in(1);
create temp table p_t1_2 partition of p_t1 for values in(2);
-- Ensure we can remove non-PK columns for partitioned tables.
explain (costs off) select * from p_t1 group by a,b,c,d;
QUERY PLAN
---------------------------------------
QUERY PLAN
--------------------------------
HashAggregate
Group Key: p_t1.a, p_t1.b
-> Append
-> Seq Scan on p_t1_1 p_t1
-> Seq Scan on p_t1_2 p_t1_1
-> Seq Scan on p_t1_1
-> Seq Scan on p_t1_2
(5 rows)
drop table t1 cascade;

View File

@ -540,11 +540,11 @@ explain (costs off) select * from nv_parent where d between '2011-08-01' and '20
QUERY PLAN
---------------------------------------------------------------------------
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))
-> 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))
-> 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))
(7 rows)
@ -553,11 +553,11 @@ explain (costs off) select * from nv_parent where d between '2011-08-01'::date a
QUERY PLAN
---------------------------------------------------------------------------
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))
-> 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))
-> 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))
(7 rows)
@ -565,13 +565,13 @@ explain (costs off) select * from nv_parent where d between '2009-08-01'::date a
QUERY PLAN
---------------------------------------------------------------------------
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))
-> 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))
-> 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))
-> 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))
(9 rows)
@ -581,11 +581,11 @@ explain (costs off) select * from nv_parent where d between '2009-08-01'::date a
QUERY PLAN
---------------------------------------------------------------------------
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))
-> 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))
-> 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))
(7 rows)

View File

@ -1338,11 +1338,11 @@ select * from patest0 join (select f1 from int4_tbl limit 1) ss on id = f1;
-> Limit
-> Seq Scan on int4_tbl
-> Append
-> Index Scan using patest0i on patest0
-> Index Scan using patest0i on patest0 patest0_1
Index Cond: (id = int4_tbl.f1)
-> Index Scan using patest1i on patest1 patest0_1
-> Index Scan using patest1i on patest1 patest0_2
Index Cond: (id = int4_tbl.f1)
-> Index Scan using patest2i on patest2 patest0_2
-> Index Scan using patest2i on patest2 patest0_3
Index Cond: (id = int4_tbl.f1)
(10 rows)
@ -1363,11 +1363,11 @@ select * from patest0 join (select f1 from int4_tbl limit 1) ss on id = f1;
-> Limit
-> Seq Scan on int4_tbl
-> Append
-> Index Scan using patest0i on patest0
-> Index Scan using patest0i on patest0 patest0_1
Index Cond: (id = int4_tbl.f1)
-> Index Scan using patest1i on patest1 patest0_1
-> Index Scan using patest1i on patest1 patest0_2
Index Cond: (id = int4_tbl.f1)
-> Seq Scan on patest2 patest0_2
-> Seq Scan on patest2 patest0_3
Filter: (int4_tbl.f1 = id)
(10 rows)
@ -1413,14 +1413,14 @@ explain (verbose, costs off) select * from matest0 order by 1-id;
-> Result
Output: matest0.id, matest0.name, (1 - matest0.id)
-> Append
-> Seq Scan on public.matest0
Output: matest0.id, matest0.name
-> Seq Scan on public.matest1 matest0_1
-> Seq Scan on public.matest0 matest0_1
Output: matest0_1.id, matest0_1.name
-> Seq Scan on public.matest2 matest0_2
-> Seq Scan on public.matest1 matest0_2
Output: matest0_2.id, matest0_2.name
-> Seq Scan on public.matest3 matest0_3
-> Seq Scan on public.matest2 matest0_3
Output: matest0_3.id, matest0_3.name
-> Seq Scan on public.matest3 matest0_4
Output: matest0_4.id, matest0_4.name
(14 rows)
select * from matest0 order by 1-id;
@ -1440,14 +1440,14 @@ explain (verbose, costs off) select min(1-id) from matest0;
Aggregate
Output: min((1 - matest0.id))
-> Append
-> Seq Scan on public.matest0
Output: matest0.id
-> Seq Scan on public.matest1 matest0_1
-> Seq Scan on public.matest0 matest0_1
Output: matest0_1.id
-> Seq Scan on public.matest2 matest0_2
-> Seq Scan on public.matest1 matest0_2
Output: matest0_2.id
-> Seq Scan on public.matest3 matest0_3
-> Seq Scan on public.matest2 matest0_3
Output: matest0_3.id
-> Seq Scan on public.matest3 matest0_4
Output: matest0_4.id
(11 rows)
select min(1-id) from matest0;
@ -1464,17 +1464,17 @@ explain (verbose, costs off) select * from matest0 order by 1-id;
------------------------------------------------------------------------
Merge Append
Sort Key: ((1 - matest0.id))
-> Index Scan using matest0i on public.matest0
Output: matest0.id, matest0.name, (1 - matest0.id)
-> Index Scan using matest1i on public.matest1 matest0_1
-> Index Scan using matest0i on public.matest0 matest0_1
Output: matest0_1.id, matest0_1.name, (1 - matest0_1.id)
-> Index Scan using matest1i on public.matest1 matest0_2
Output: matest0_2.id, matest0_2.name, (1 - matest0_2.id)
-> Sort
Output: matest0_2.id, matest0_2.name, ((1 - matest0_2.id))
Sort Key: ((1 - matest0_2.id))
-> Seq Scan on public.matest2 matest0_2
Output: matest0_2.id, matest0_2.name, (1 - matest0_2.id)
-> Index Scan using matest3i on public.matest3 matest0_3
Output: matest0_3.id, matest0_3.name, (1 - matest0_3.id)
Output: matest0_3.id, matest0_3.name, ((1 - matest0_3.id))
Sort Key: ((1 - matest0_3.id))
-> Seq Scan on public.matest2 matest0_3
Output: matest0_3.id, matest0_3.name, (1 - matest0_3.id)
-> Index Scan using matest3i on public.matest3 matest0_4
Output: matest0_4.id, matest0_4.name, (1 - matest0_4.id)
(13 rows)
select * from matest0 order by 1-id;
@ -1500,22 +1500,22 @@ explain (verbose, costs off) select min(1-id) from matest0;
Output: ((1 - matest0.id))
-> Merge Append
Sort Key: ((1 - matest0.id))
-> Index Scan using matest0i on public.matest0
Output: matest0.id, (1 - matest0.id)
Index Cond: ((1 - matest0.id) IS NOT NULL)
-> Index Scan using matest1i on public.matest1 matest0_1
-> Index Scan using matest0i on public.matest0 matest0_1
Output: matest0_1.id, (1 - matest0_1.id)
Index Cond: ((1 - matest0_1.id) IS NOT NULL)
-> Index Scan using matest1i on public.matest1 matest0_2
Output: matest0_2.id, (1 - matest0_2.id)
Index Cond: ((1 - matest0_2.id) IS NOT NULL)
-> Sort
Output: matest0_2.id, ((1 - matest0_2.id))
Sort Key: ((1 - matest0_2.id))
-> Bitmap Heap Scan on public.matest2 matest0_2
Output: matest0_2.id, (1 - matest0_2.id)
Filter: ((1 - matest0_2.id) IS NOT NULL)
Output: matest0_3.id, ((1 - matest0_3.id))
Sort Key: ((1 - matest0_3.id))
-> Bitmap Heap Scan on public.matest2 matest0_3
Output: matest0_3.id, (1 - matest0_3.id)
Filter: ((1 - matest0_3.id) IS NOT NULL)
-> Bitmap Index Scan on matest2_pkey
-> Index Scan using matest3i on public.matest3 matest0_3
Output: matest0_3.id, (1 - matest0_3.id)
Index Cond: ((1 - matest0_3.id) IS NOT NULL)
-> Index Scan using matest3i on public.matest3 matest0_4
Output: matest0_4.id, (1 - matest0_4.id)
Index Cond: ((1 - matest0_4.id) IS NOT NULL)
(25 rows)
select min(1-id) from matest0;
@ -1551,14 +1551,14 @@ order by t1.b limit 10;
Merge Cond: (t1.b = t2.b)
-> Merge Append
Sort Key: t1.b
-> Index Scan using matest0i on matest0 t1
-> Index Scan using matest1i on matest1 t1_1
-> Index Scan using matest0i on matest0 t1_1
-> Index Scan using matest1i on matest1 t1_2
-> Materialize
-> Merge Append
Sort Key: t2.b
-> Index Scan using matest0i on matest0 t2
-> Index Scan using matest0i on matest0 t2_1
Filter: (c = d)
-> Index Scan using matest1i on matest1 t2_1
-> Index Scan using matest1i on matest1 t2_2
Filter: (c = d)
(14 rows)
@ -1783,9 +1783,9 @@ explain (costs off) select * from list_parted;
QUERY PLAN
----------------------------------------------
Append
-> Seq Scan on part_ab_cd list_parted
-> Seq Scan on part_ef_gh list_parted_1
-> Seq Scan on part_null_xy list_parted_2
-> Seq Scan on part_ab_cd list_parted_1
-> Seq Scan on part_ef_gh list_parted_2
-> Seq Scan on part_null_xy list_parted_3
(4 rows)
explain (costs off) select * from list_parted where a is null;
@ -1799,11 +1799,11 @@ explain (costs off) select * from list_parted where a is not null;
QUERY PLAN
----------------------------------------------
Append
-> Seq Scan on part_ab_cd list_parted
-> Seq Scan on part_ab_cd list_parted_1
Filter: (a IS NOT NULL)
-> Seq Scan on part_ef_gh list_parted_1
-> Seq Scan on part_ef_gh list_parted_2
Filter: (a IS NOT NULL)
-> Seq Scan on part_null_xy list_parted_2
-> Seq Scan on part_null_xy list_parted_3
Filter: (a IS NOT NULL)
(7 rows)
@ -1811,9 +1811,9 @@ explain (costs off) select * from list_parted where a in ('ab', 'cd', 'ef');
QUERY PLAN
----------------------------------------------------------
Append
-> Seq Scan on part_ab_cd list_parted
-> Seq Scan on part_ab_cd list_parted_1
Filter: ((a)::text = ANY ('{ab,cd,ef}'::text[]))
-> Seq Scan on part_ef_gh list_parted_1
-> Seq Scan on part_ef_gh list_parted_2
Filter: ((a)::text = ANY ('{ab,cd,ef}'::text[]))
(5 rows)
@ -1852,24 +1852,24 @@ explain (costs off) select * from range_list_parted;
QUERY PLAN
--------------------------------------------------------
Append
-> Seq Scan on part_1_10_ab range_list_parted
-> Seq Scan on part_1_10_cd range_list_parted_1
-> Seq Scan on part_10_20_ab range_list_parted_2
-> Seq Scan on part_10_20_cd range_list_parted_3
-> Seq Scan on part_21_30_ab range_list_parted_4
-> Seq Scan on part_21_30_cd range_list_parted_5
-> Seq Scan on part_40_inf_ab range_list_parted_6
-> Seq Scan on part_40_inf_cd range_list_parted_7
-> Seq Scan on part_40_inf_null range_list_parted_8
-> Seq Scan on part_1_10_ab range_list_parted_1
-> Seq Scan on part_1_10_cd range_list_parted_2
-> Seq Scan on part_10_20_ab range_list_parted_3
-> Seq Scan on part_10_20_cd range_list_parted_4
-> Seq Scan on part_21_30_ab range_list_parted_5
-> Seq Scan on part_21_30_cd range_list_parted_6
-> Seq Scan on part_40_inf_ab range_list_parted_7
-> Seq Scan on part_40_inf_cd range_list_parted_8
-> Seq Scan on part_40_inf_null range_list_parted_9
(10 rows)
explain (costs off) select * from range_list_parted where a = 5;
QUERY PLAN
----------------------------------------------------
Append
-> Seq Scan on part_1_10_ab range_list_parted
-> Seq Scan on part_1_10_ab range_list_parted_1
Filter: (a = 5)
-> Seq Scan on part_1_10_cd range_list_parted_1
-> Seq Scan on part_1_10_cd range_list_parted_2
Filter: (a = 5)
(5 rows)
@ -1877,13 +1877,13 @@ explain (costs off) select * from range_list_parted where b = 'ab';
QUERY PLAN
------------------------------------------------------
Append
-> Seq Scan on part_1_10_ab range_list_parted
-> Seq Scan on part_1_10_ab range_list_parted_1
Filter: (b = 'ab'::bpchar)
-> Seq Scan on part_10_20_ab range_list_parted_1
-> Seq Scan on part_10_20_ab range_list_parted_2
Filter: (b = 'ab'::bpchar)
-> Seq Scan on part_21_30_ab range_list_parted_2
-> Seq Scan on part_21_30_ab range_list_parted_3
Filter: (b = 'ab'::bpchar)
-> Seq Scan on part_40_inf_ab range_list_parted_3
-> Seq Scan on part_40_inf_ab range_list_parted_4
Filter: (b = 'ab'::bpchar)
(9 rows)
@ -1891,11 +1891,11 @@ explain (costs off) select * from range_list_parted where a between 3 and 23 and
QUERY PLAN
-----------------------------------------------------------------
Append
-> Seq Scan on part_1_10_ab range_list_parted
-> Seq Scan on part_1_10_ab range_list_parted_1
Filter: ((a >= 3) AND (a <= 23) AND (b = 'ab'::bpchar))
-> Seq Scan on part_10_20_ab range_list_parted_1
-> Seq Scan on part_10_20_ab range_list_parted_2
Filter: ((a >= 3) AND (a <= 23) AND (b = 'ab'::bpchar))
-> Seq Scan on part_21_30_ab range_list_parted_2
-> Seq Scan on part_21_30_ab range_list_parted_3
Filter: ((a >= 3) AND (a <= 23) AND (b = 'ab'::bpchar))
(7 rows)
@ -1919,23 +1919,23 @@ explain (costs off) select * from range_list_parted where a is not null and a <
QUERY PLAN
--------------------------------------------------------
Append
-> Seq Scan on part_1_10_ab range_list_parted
-> Seq Scan on part_1_10_ab range_list_parted_1
Filter: ((a IS NOT NULL) AND (a < 67))
-> Seq Scan on part_1_10_cd range_list_parted_1
-> Seq Scan on part_1_10_cd range_list_parted_2
Filter: ((a IS NOT NULL) AND (a < 67))
-> Seq Scan on part_10_20_ab range_list_parted_2
-> Seq Scan on part_10_20_ab range_list_parted_3
Filter: ((a IS NOT NULL) AND (a < 67))
-> Seq Scan on part_10_20_cd range_list_parted_3
-> Seq Scan on part_10_20_cd range_list_parted_4
Filter: ((a IS NOT NULL) AND (a < 67))
-> Seq Scan on part_21_30_ab range_list_parted_4
-> Seq Scan on part_21_30_ab range_list_parted_5
Filter: ((a IS NOT NULL) AND (a < 67))
-> Seq Scan on part_21_30_cd range_list_parted_5
-> Seq Scan on part_21_30_cd range_list_parted_6
Filter: ((a IS NOT NULL) AND (a < 67))
-> Seq Scan on part_40_inf_ab range_list_parted_6
-> Seq Scan on part_40_inf_ab range_list_parted_7
Filter: ((a IS NOT NULL) AND (a < 67))
-> Seq Scan on part_40_inf_cd range_list_parted_7
-> Seq Scan on part_40_inf_cd range_list_parted_8
Filter: ((a IS NOT NULL) AND (a < 67))
-> Seq Scan on part_40_inf_null range_list_parted_8
-> Seq Scan on part_40_inf_null range_list_parted_9
Filter: ((a IS NOT NULL) AND (a < 67))
(19 rows)
@ -1943,11 +1943,11 @@ explain (costs off) select * from range_list_parted where a >= 30;
QUERY PLAN
--------------------------------------------------------
Append
-> Seq Scan on part_40_inf_ab range_list_parted
-> Seq Scan on part_40_inf_ab range_list_parted_1
Filter: (a >= 30)
-> Seq Scan on part_40_inf_cd range_list_parted_1
-> Seq Scan on part_40_inf_cd range_list_parted_2
Filter: (a >= 30)
-> Seq Scan on part_40_inf_null range_list_parted_2
-> Seq Scan on part_40_inf_null range_list_parted_3
Filter: (a >= 30)
(7 rows)
@ -1967,9 +1967,9 @@ explain (costs off) select * from mcrparted where a = 0; -- scans mcrparted0, mc
QUERY PLAN
---------------------------------------------
Append
-> Seq Scan on mcrparted0 mcrparted
-> Seq Scan on mcrparted0 mcrparted_1
Filter: (a = 0)
-> Seq Scan on mcrparted_def mcrparted_1
-> Seq Scan on mcrparted_def mcrparted_2
Filter: (a = 0)
(5 rows)
@ -1977,9 +1977,9 @@ explain (costs off) select * from mcrparted where a = 10 and abs(b) < 5; -- scan
QUERY PLAN
---------------------------------------------
Append
-> Seq Scan on mcrparted1 mcrparted
-> Seq Scan on mcrparted1 mcrparted_1
Filter: ((a = 10) AND (abs(b) < 5))
-> Seq Scan on mcrparted_def mcrparted_1
-> Seq Scan on mcrparted_def mcrparted_2
Filter: ((a = 10) AND (abs(b) < 5))
(5 rows)
@ -1987,11 +1987,11 @@ explain (costs off) select * from mcrparted where a = 10 and abs(b) = 5; -- scan
QUERY PLAN
---------------------------------------------
Append
-> Seq Scan on mcrparted1 mcrparted
-> Seq Scan on mcrparted1 mcrparted_1
Filter: ((a = 10) AND (abs(b) = 5))
-> Seq Scan on mcrparted2 mcrparted_1
-> Seq Scan on mcrparted2 mcrparted_2
Filter: ((a = 10) AND (abs(b) = 5))
-> Seq Scan on mcrparted_def mcrparted_2
-> Seq Scan on mcrparted_def mcrparted_3
Filter: ((a = 10) AND (abs(b) = 5))
(7 rows)
@ -1999,19 +1999,19 @@ explain (costs off) select * from mcrparted where abs(b) = 5; -- scans all parti
QUERY PLAN
---------------------------------------------
Append
-> Seq Scan on mcrparted0 mcrparted
-> Seq Scan on mcrparted0 mcrparted_1
Filter: (abs(b) = 5)
-> Seq Scan on mcrparted1 mcrparted_1
-> Seq Scan on mcrparted1 mcrparted_2
Filter: (abs(b) = 5)
-> Seq Scan on mcrparted2 mcrparted_2
-> Seq Scan on mcrparted2 mcrparted_3
Filter: (abs(b) = 5)
-> Seq Scan on mcrparted3 mcrparted_3
-> Seq Scan on mcrparted3 mcrparted_4
Filter: (abs(b) = 5)
-> Seq Scan on mcrparted4 mcrparted_4
-> Seq Scan on mcrparted4 mcrparted_5
Filter: (abs(b) = 5)
-> Seq Scan on mcrparted5 mcrparted_5
-> Seq Scan on mcrparted5 mcrparted_6
Filter: (abs(b) = 5)
-> Seq Scan on mcrparted_def mcrparted_6
-> Seq Scan on mcrparted_def mcrparted_7
Filter: (abs(b) = 5)
(15 rows)
@ -2019,19 +2019,19 @@ explain (costs off) select * from mcrparted where a > -1; -- scans all partition
QUERY PLAN
---------------------------------------------
Append
-> Seq Scan on mcrparted0 mcrparted
-> Seq Scan on mcrparted0 mcrparted_1
Filter: (a > '-1'::integer)
-> Seq Scan on mcrparted1 mcrparted_1
-> Seq Scan on mcrparted1 mcrparted_2
Filter: (a > '-1'::integer)
-> Seq Scan on mcrparted2 mcrparted_2
-> Seq Scan on mcrparted2 mcrparted_3
Filter: (a > '-1'::integer)
-> Seq Scan on mcrparted3 mcrparted_3
-> Seq Scan on mcrparted3 mcrparted_4
Filter: (a > '-1'::integer)
-> Seq Scan on mcrparted4 mcrparted_4
-> Seq Scan on mcrparted4 mcrparted_5
Filter: (a > '-1'::integer)
-> Seq Scan on mcrparted5 mcrparted_5
-> Seq Scan on mcrparted5 mcrparted_6
Filter: (a > '-1'::integer)
-> Seq Scan on mcrparted_def mcrparted_6
-> Seq Scan on mcrparted_def mcrparted_7
Filter: (a > '-1'::integer)
(15 rows)
@ -2046,13 +2046,13 @@ explain (costs off) select * from mcrparted where a = 20 and c > 20; -- scans mc
QUERY PLAN
---------------------------------------------
Append
-> Seq Scan on mcrparted3 mcrparted
-> Seq Scan on mcrparted3 mcrparted_1
Filter: ((c > 20) AND (a = 20))
-> Seq Scan on mcrparted4 mcrparted_1
-> Seq Scan on mcrparted4 mcrparted_2
Filter: ((c > 20) AND (a = 20))
-> Seq Scan on mcrparted5 mcrparted_2
-> Seq Scan on mcrparted5 mcrparted_3
Filter: ((c > 20) AND (a = 20))
-> Seq Scan on mcrparted_def mcrparted_3
-> Seq Scan on mcrparted_def mcrparted_4
Filter: ((c > 20) AND (a = 20))
(9 rows)
@ -2092,13 +2092,13 @@ explain (costs off) select * from mcrparted order by a, abs(b), c;
-------------------------------------------------------------------------------
Merge Append
Sort Key: mcrparted.a, (abs(mcrparted.b)), mcrparted.c
-> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 mcrparted
-> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_1
-> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_2
-> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_3
-> Index Scan using mcrparted4_a_abs_c_idx on mcrparted4 mcrparted_4
-> Index Scan using mcrparted5_a_abs_c_idx on mcrparted5 mcrparted_5
-> Index Scan using mcrparted_def_a_abs_c_idx on mcrparted_def mcrparted_6
-> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 mcrparted_1
-> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_2
-> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_3
-> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_4
-> Index Scan using mcrparted4_a_abs_c_idx on mcrparted4 mcrparted_5
-> Index Scan using mcrparted5_a_abs_c_idx on mcrparted5 mcrparted_6
-> Index Scan using mcrparted_def_a_abs_c_idx on mcrparted_def mcrparted_7
(9 rows)
drop table mcrparted_def;
@ -2108,12 +2108,12 @@ explain (costs off) select * from mcrparted order by a, abs(b), c;
QUERY PLAN
-------------------------------------------------------------------------
Append
-> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 mcrparted
-> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_1
-> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_2
-> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_3
-> Index Scan using mcrparted4_a_abs_c_idx on mcrparted4 mcrparted_4
-> Index Scan using mcrparted5_a_abs_c_idx on mcrparted5 mcrparted_5
-> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 mcrparted_1
-> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_2
-> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_3
-> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_4
-> Index Scan using mcrparted4_a_abs_c_idx on mcrparted4 mcrparted_5
-> Index Scan using mcrparted5_a_abs_c_idx on mcrparted5 mcrparted_6
(7 rows)
-- Append is used with subpaths in reverse order with backwards index scans
@ -2121,12 +2121,12 @@ explain (costs off) select * from mcrparted order by a desc, abs(b) desc, c desc
QUERY PLAN
----------------------------------------------------------------------------------
Append
-> Index Scan Backward using mcrparted5_a_abs_c_idx on mcrparted5 mcrparted_5
-> Index Scan Backward using mcrparted4_a_abs_c_idx on mcrparted4 mcrparted_4
-> Index Scan Backward using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_3
-> Index Scan Backward using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_2
-> Index Scan Backward using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_1
-> Index Scan Backward using mcrparted0_a_abs_c_idx on mcrparted0 mcrparted
-> Index Scan Backward using mcrparted5_a_abs_c_idx on mcrparted5 mcrparted_6
-> Index Scan Backward using mcrparted4_a_abs_c_idx on mcrparted4 mcrparted_5
-> Index Scan Backward using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_4
-> Index Scan Backward using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_3
-> Index Scan Backward using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_2
-> Index Scan Backward using mcrparted0_a_abs_c_idx on mcrparted0 mcrparted_1
(7 rows)
-- check that Append plan is used containing a MergeAppend for sub-partitions
@ -2139,15 +2139,15 @@ explain (costs off) select * from mcrparted order by a, abs(b), c;
QUERY PLAN
---------------------------------------------------------------------------------------
Append
-> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 mcrparted
-> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_1
-> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_2
-> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_3
-> Index Scan using mcrparted4_a_abs_c_idx on mcrparted4 mcrparted_4
-> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 mcrparted_1
-> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_2
-> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_3
-> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_4
-> Index Scan using mcrparted4_a_abs_c_idx on mcrparted4 mcrparted_5
-> Merge Append
Sort Key: mcrparted_5.a, (abs(mcrparted_5.b)), mcrparted_5.c
-> Index Scan using mcrparted5a_a_abs_c_idx on mcrparted5a mcrparted_5
-> Index Scan using mcrparted5_def_a_abs_c_idx on mcrparted5_def mcrparted_6
Sort Key: mcrparted_7.a, (abs(mcrparted_7.b)), mcrparted_7.c
-> Index Scan using mcrparted5a_a_abs_c_idx on mcrparted5a mcrparted_7
-> Index Scan using mcrparted5_def_a_abs_c_idx on mcrparted5_def mcrparted_8
(10 rows)
drop table mcrparted5_def;
@ -2158,12 +2158,12 @@ explain (costs off) select a, abs(b) from mcrparted order by a, abs(b), c;
QUERY PLAN
---------------------------------------------------------------------------
Append
-> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 mcrparted
-> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_1
-> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_2
-> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_3
-> Index Scan using mcrparted4_a_abs_c_idx on mcrparted4 mcrparted_4
-> Index Scan using mcrparted5a_a_abs_c_idx on mcrparted5a mcrparted_5
-> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 mcrparted_1
-> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_2
-> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_3
-> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_4
-> Index Scan using mcrparted4_a_abs_c_idx on mcrparted4 mcrparted_5
-> Index Scan using mcrparted5a_a_abs_c_idx on mcrparted5a mcrparted_6
(7 rows)
-- check that Append is used when the sub-partitioned tables are pruned
@ -2172,13 +2172,13 @@ explain (costs off) select * from mcrparted where a < 20 order by a, abs(b), c;
QUERY PLAN
-------------------------------------------------------------------------
Append
-> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 mcrparted
-> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 mcrparted_1
Index Cond: (a < 20)
-> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_1
-> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_2
Index Cond: (a < 20)
-> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_2
-> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_3
Index Cond: (a < 20)
-> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_3
-> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_4
Index Cond: (a < 20)
(9 rows)
@ -2191,8 +2191,8 @@ explain (costs off) select * from mclparted order by a;
QUERY PLAN
------------------------------------------------------------------------
Append
-> Index Only Scan using mclparted1_a_idx on mclparted1 mclparted
-> Index Only Scan using mclparted2_a_idx on mclparted2 mclparted_1
-> Index Only Scan using mclparted1_a_idx on mclparted1 mclparted_1
-> Index Only Scan using mclparted2_a_idx on mclparted2 mclparted_2
(3 rows)
-- Ensure a MergeAppend is used when a partition exists with interleaved
@ -2204,10 +2204,10 @@ explain (costs off) select * from mclparted order by a;
----------------------------------------------------------------------------
Merge Append
Sort Key: mclparted.a
-> Index Only Scan using mclparted1_a_idx on mclparted1 mclparted
-> Index Only Scan using mclparted2_a_idx on mclparted2 mclparted_1
-> Index Only Scan using mclparted3_5_a_idx on mclparted3_5 mclparted_2
-> Index Only Scan using mclparted4_a_idx on mclparted4 mclparted_3
-> Index Only Scan using mclparted1_a_idx on mclparted1 mclparted_1
-> Index Only Scan using mclparted2_a_idx on mclparted2 mclparted_2
-> Index Only Scan using mclparted3_5_a_idx on mclparted3_5 mclparted_3
-> Index Only Scan using mclparted4_a_idx on mclparted4 mclparted_4
(6 rows)
drop table mclparted;
@ -2224,14 +2224,14 @@ explain (costs off) select * from mcrparted where a < 20 order by a, abs(b), c l
Limit
-> Append
-> Sort
Sort Key: mcrparted.a, (abs(mcrparted.b)), mcrparted.c
-> Seq Scan on mcrparted0 mcrparted
Sort Key: mcrparted_1.a, (abs(mcrparted_1.b)), mcrparted_1.c
-> Seq Scan on mcrparted0 mcrparted_1
Filter: (a < 20)
-> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_1
-> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_2
Index Cond: (a < 20)
-> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_2
-> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_3
Index Cond: (a < 20)
-> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_3
-> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_4
Index Cond: (a < 20)
(12 rows)
@ -2242,9 +2242,9 @@ explain (costs off) select * from mcrparted where a = 10 order by a, abs(b), c;
QUERY PLAN
-------------------------------------------------------------------------
Append
-> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted
-> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_1
Index Cond: (a = 10)
-> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_1
-> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_2
Index Cond: (a = 10)
(5 rows)
@ -2256,11 +2256,11 @@ create table bool_lp_true partition of bool_lp for values in(true);
create table bool_lp_false partition of bool_lp for values in(false);
create index on bool_lp (b);
explain (costs off) select * from bool_lp order by b;
QUERY PLAN
--------------------------------------------------------------------------
QUERY PLAN
----------------------------------------------------------------------------
Append
-> Index Only Scan using bool_lp_false_b_idx on bool_lp_false bool_lp
-> Index Only Scan using bool_lp_true_b_idx on bool_lp_true bool_lp_1
-> Index Only Scan using bool_lp_false_b_idx on bool_lp_false bool_lp_1
-> Index Only Scan using bool_lp_true_b_idx on bool_lp_true bool_lp_2
(3 rows)
drop table bool_lp;
@ -2275,9 +2275,9 @@ explain (costs off) select * from bool_rp where b = true order by b,a;
QUERY PLAN
----------------------------------------------------------------------------------
Append
-> Index Only Scan using bool_rp_true_1k_b_a_idx on bool_rp_true_1k bool_rp
-> Index Only Scan using bool_rp_true_1k_b_a_idx on bool_rp_true_1k bool_rp_1
Index Cond: (b = true)
-> Index Only Scan using bool_rp_true_2k_b_a_idx on bool_rp_true_2k bool_rp_1
-> Index Only Scan using bool_rp_true_2k_b_a_idx on bool_rp_true_2k bool_rp_2
Index Cond: (b = true)
(5 rows)
@ -2285,9 +2285,9 @@ explain (costs off) select * from bool_rp where b = false order by b,a;
QUERY PLAN
------------------------------------------------------------------------------------
Append
-> Index Only Scan using bool_rp_false_1k_b_a_idx on bool_rp_false_1k bool_rp
-> Index Only Scan using bool_rp_false_1k_b_a_idx on bool_rp_false_1k bool_rp_1
Index Cond: (b = false)
-> Index Only Scan using bool_rp_false_2k_b_a_idx on bool_rp_false_2k bool_rp_1
-> Index Only Scan using bool_rp_false_2k_b_a_idx on bool_rp_false_2k bool_rp_2
Index Cond: (b = false)
(5 rows)
@ -2295,9 +2295,9 @@ explain (costs off) select * from bool_rp where b = true order by a;
QUERY PLAN
----------------------------------------------------------------------------------
Append
-> Index Only Scan using bool_rp_true_1k_b_a_idx on bool_rp_true_1k bool_rp
-> Index Only Scan using bool_rp_true_1k_b_a_idx on bool_rp_true_1k bool_rp_1
Index Cond: (b = true)
-> Index Only Scan using bool_rp_true_2k_b_a_idx on bool_rp_true_2k bool_rp_1
-> Index Only Scan using bool_rp_true_2k_b_a_idx on bool_rp_true_2k bool_rp_2
Index Cond: (b = true)
(5 rows)
@ -2305,9 +2305,9 @@ explain (costs off) select * from bool_rp where b = false order by a;
QUERY PLAN
------------------------------------------------------------------------------------
Append
-> Index Only Scan using bool_rp_false_1k_b_a_idx on bool_rp_false_1k bool_rp
-> Index Only Scan using bool_rp_false_1k_b_a_idx on bool_rp_false_1k bool_rp_1
Index Cond: (b = false)
-> Index Only Scan using bool_rp_false_2k_b_a_idx on bool_rp_false_2k bool_rp_1
-> Index Only Scan using bool_rp_false_2k_b_a_idx on bool_rp_false_2k bool_rp_2
Index Cond: (b = false)
(5 rows)
@ -2322,16 +2322,16 @@ explain (costs off) select * from range_parted order by a,b,c;
QUERY PLAN
-------------------------------------------------------------------------------------
Append
-> Index Only Scan using range_parted1_a_b_c_idx on range_parted1 range_parted
-> Index Only Scan using range_parted2_a_b_c_idx on range_parted2 range_parted_1
-> Index Only Scan using range_parted1_a_b_c_idx on range_parted1 range_parted_1
-> Index Only Scan using range_parted2_a_b_c_idx on range_parted2 range_parted_2
(3 rows)
explain (costs off) select * from range_parted order by a desc,b desc,c desc;
QUERY PLAN
----------------------------------------------------------------------------------------------
Append
-> Index Only Scan Backward using range_parted2_a_b_c_idx on range_parted2 range_parted_1
-> Index Only Scan Backward using range_parted1_a_b_c_idx on range_parted1 range_parted
-> Index Only Scan Backward using range_parted2_a_b_c_idx on range_parted2 range_parted_2
-> Index Only Scan Backward using range_parted1_a_b_c_idx on range_parted1 range_parted_1
(3 rows)
drop table range_parted;

View File

@ -5779,8 +5779,8 @@ select t1.b, ss.phv from join_ut1 t1 left join lateral
(select t2.a as t2a, t3.a t3a, least(t1.a, t2.a, t3.a) phv
from join_pt1 t2 join join_ut1 t3 on t2.a = t3.b) ss
on t1.a = ss.t2a order by t1.a;
QUERY PLAN
------------------------------------------------------------------
QUERY PLAN
--------------------------------------------------------------------
Sort
Output: t1.b, (LEAST(t1.a, t2.a, t3.a)), t1.a
Sort Key: t1.a
@ -5796,12 +5796,12 @@ select t1.b, ss.phv from join_ut1 t1 left join lateral
-> Hash
Output: t2.a
-> Append
-> Seq Scan on public.join_pt1p1p1 t2
Output: t2.a
Filter: (t1.a = t2.a)
-> Seq Scan on public.join_pt1p2 t2_1
-> Seq Scan on public.join_pt1p1p1 t2_1
Output: 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)
select t1.b, ss.phv from join_ut1 t1 left join lateral

View File

@ -343,9 +343,9 @@ SELECT c, sum(a) FROM pagg_tab GROUP BY rollup(c) ORDER BY 1, 2;
Hash Key: pagg_tab.c
Group Key: ()
-> Append
-> Seq Scan on pagg_tab_p1 pagg_tab
-> Seq Scan on pagg_tab_p2 pagg_tab_1
-> Seq Scan on pagg_tab_p3 pagg_tab_2
-> Seq Scan on pagg_tab_p1 pagg_tab_1
-> Seq Scan on pagg_tab_p2 pagg_tab_2
-> Seq Scan on pagg_tab_p3 pagg_tab_3
(9 rows)
-- ORDERED SET within the aggregate.
@ -390,9 +390,9 @@ SELECT a, sum(b order by a) FROM pagg_tab GROUP BY a ORDER BY 1, 2;
-> Sort
Sort Key: pagg_tab.a
-> Append
-> Seq Scan on pagg_tab_p1 pagg_tab
-> Seq Scan on pagg_tab_p2 pagg_tab_1
-> Seq Scan on pagg_tab_p3 pagg_tab_2
-> Seq Scan on pagg_tab_p1 pagg_tab_1
-> Seq Scan on pagg_tab_p2 pagg_tab_2
-> Seq Scan on pagg_tab_p3 pagg_tab_3
(10 rows)
-- JOIN query
@ -461,14 +461,14 @@ SELECT t1.x, sum(t1.y), count(t1) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t
-> Hash Join
Hash Cond: (t1.x = t2.y)
-> Append
-> Seq Scan on pagg_tab1_p1 t1
-> Seq Scan on pagg_tab1_p2 t1_1
-> Seq Scan on pagg_tab1_p3 t1_2
-> Seq Scan on pagg_tab1_p1 t1_1
-> Seq Scan on pagg_tab1_p2 t1_2
-> Seq Scan on pagg_tab1_p3 t1_3
-> Hash
-> Append
-> Seq Scan on pagg_tab2_p1 t2
-> Seq Scan on pagg_tab2_p2 t2_1
-> Seq Scan on pagg_tab2_p3 t2_2
-> Seq Scan on pagg_tab2_p1 t2_1
-> Seq Scan on pagg_tab2_p2 t2_2
-> Seq Scan on pagg_tab2_p3 t2_3
(15 rows)
SELECT t1.x, sum(t1.y), count(t1) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3;
@ -732,15 +732,15 @@ SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT JOI
Hash Cond: (pagg_tab1.x = pagg_tab2.y)
Filter: ((pagg_tab1.x > 5) OR (pagg_tab2.y < 20))
-> Append
-> Seq Scan on pagg_tab1_p1 pagg_tab1
-> Seq Scan on pagg_tab1_p1 pagg_tab1_1
Filter: (x < 20)
-> Seq Scan on pagg_tab1_p2 pagg_tab1_1
-> Seq Scan on pagg_tab1_p2 pagg_tab1_2
Filter: (x < 20)
-> Hash
-> Append
-> Seq Scan on pagg_tab2_p2 pagg_tab2
-> Seq Scan on pagg_tab2_p2 pagg_tab2_1
Filter: (y > 10)
-> Seq Scan on pagg_tab2_p3 pagg_tab2_1
-> Seq Scan on pagg_tab2_p3 pagg_tab2_2
Filter: (y > 10)
(18 rows)
@ -772,15 +772,15 @@ SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a FULL JOI
Hash Cond: (pagg_tab1.x = pagg_tab2.y)
Filter: ((pagg_tab1.x > 5) OR (pagg_tab2.y < 20))
-> Append
-> Seq Scan on pagg_tab1_p1 pagg_tab1
-> Seq Scan on pagg_tab1_p1 pagg_tab1_1
Filter: (x < 20)
-> Seq Scan on pagg_tab1_p2 pagg_tab1_1
-> Seq Scan on pagg_tab1_p2 pagg_tab1_2
Filter: (x < 20)
-> Hash
-> Append
-> Seq Scan on pagg_tab2_p2 pagg_tab2
-> Seq Scan on pagg_tab2_p2 pagg_tab2_1
Filter: (y > 10)
-> Seq Scan on pagg_tab2_p3 pagg_tab2_1
-> Seq Scan on pagg_tab2_p3 pagg_tab2_2
Filter: (y > 10)
(18 rows)
@ -946,26 +946,26 @@ SELECT a, sum(b), array_agg(distinct c), count(*) FROM pagg_tab_ml GROUP BY a HA
QUERY PLAN
--------------------------------------------------------------------------------------------
Sort
Sort Key: pagg_tab_ml_1.a, (sum(pagg_tab_ml_1.b)), (array_agg(DISTINCT pagg_tab_ml_1.c))
Sort Key: pagg_tab_ml_2.a, (sum(pagg_tab_ml_2.b)), (array_agg(DISTINCT pagg_tab_ml_2.c))
-> Gather
Workers Planned: 2
-> Parallel Append
-> GroupAggregate
Group Key: pagg_tab_ml_1.a
Filter: (avg(pagg_tab_ml_1.b) < '3'::numeric)
Group Key: pagg_tab_ml_2.a
Filter: (avg(pagg_tab_ml_2.b) < '3'::numeric)
-> Sort
Sort Key: pagg_tab_ml_1.a
Sort Key: pagg_tab_ml_2.a
-> Append
-> Seq Scan on pagg_tab_ml_p2_s1 pagg_tab_ml_1
-> Seq Scan on pagg_tab_ml_p2_s2 pagg_tab_ml_2
-> Seq Scan on pagg_tab_ml_p2_s1 pagg_tab_ml_2
-> Seq Scan on pagg_tab_ml_p2_s2 pagg_tab_ml_3
-> GroupAggregate
Group Key: pagg_tab_ml_3.a
Filter: (avg(pagg_tab_ml_3.b) < '3'::numeric)
Group Key: pagg_tab_ml_5.a
Filter: (avg(pagg_tab_ml_5.b) < '3'::numeric)
-> Sort
Sort Key: pagg_tab_ml_3.a
Sort Key: pagg_tab_ml_5.a
-> Append
-> Seq Scan on pagg_tab_ml_p3_s1 pagg_tab_ml_3
-> Seq Scan on pagg_tab_ml_p3_s2 pagg_tab_ml_4
-> Seq Scan on pagg_tab_ml_p3_s1 pagg_tab_ml_5
-> Seq Scan on pagg_tab_ml_p3_s2 pagg_tab_ml_6
-> GroupAggregate
Group Key: pagg_tab_ml.a
Filter: (avg(pagg_tab_ml.b) < '3'::numeric)
@ -997,21 +997,21 @@ SELECT a, sum(b), array_agg(distinct c), count(*) FROM pagg_tab_ml GROUP BY a HA
Workers Planned: 2
-> Parallel Append
-> GroupAggregate
Group Key: pagg_tab_ml_1.a
Filter: (avg(pagg_tab_ml_1.b) < '3'::numeric)
Group Key: pagg_tab_ml_2.a
Filter: (avg(pagg_tab_ml_2.b) < '3'::numeric)
-> Sort
Sort Key: pagg_tab_ml_1.a
Sort Key: pagg_tab_ml_2.a
-> Append
-> Seq Scan on pagg_tab_ml_p2_s1 pagg_tab_ml_1
-> Seq Scan on pagg_tab_ml_p2_s2 pagg_tab_ml_2
-> Seq Scan on pagg_tab_ml_p2_s1 pagg_tab_ml_2
-> Seq Scan on pagg_tab_ml_p2_s2 pagg_tab_ml_3
-> GroupAggregate
Group Key: pagg_tab_ml_3.a
Filter: (avg(pagg_tab_ml_3.b) < '3'::numeric)
Group Key: pagg_tab_ml_5.a
Filter: (avg(pagg_tab_ml_5.b) < '3'::numeric)
-> Sort
Sort Key: pagg_tab_ml_3.a
Sort Key: pagg_tab_ml_5.a
-> Append
-> Seq Scan on pagg_tab_ml_p3_s1 pagg_tab_ml_3
-> Seq Scan on pagg_tab_ml_p3_s2 pagg_tab_ml_4
-> Seq Scan on pagg_tab_ml_p3_s1 pagg_tab_ml_5
-> Seq Scan on pagg_tab_ml_p3_s2 pagg_tab_ml_6
-> GroupAggregate
Group Key: pagg_tab_ml.a
Filter: (avg(pagg_tab_ml.b) < '3'::numeric)
@ -1035,29 +1035,29 @@ SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER B
Filter: (avg(pagg_tab_ml.b) < '3'::numeric)
-> Seq Scan on pagg_tab_ml_p1 pagg_tab_ml
-> Finalize GroupAggregate
Group Key: pagg_tab_ml_1.a
Filter: (avg(pagg_tab_ml_1.b) < '3'::numeric)
Group Key: pagg_tab_ml_2.a
Filter: (avg(pagg_tab_ml_2.b) < '3'::numeric)
-> Sort
Sort Key: pagg_tab_ml_1.a
Sort Key: pagg_tab_ml_2.a
-> Append
-> Partial HashAggregate
Group Key: pagg_tab_ml_1.a
-> Seq Scan on pagg_tab_ml_p2_s1 pagg_tab_ml_1
-> Partial HashAggregate
Group Key: pagg_tab_ml_2.a
-> Seq Scan on pagg_tab_ml_p2_s2 pagg_tab_ml_2
-> Finalize GroupAggregate
Group Key: pagg_tab_ml_3.a
Filter: (avg(pagg_tab_ml_3.b) < '3'::numeric)
-> Sort
Sort Key: pagg_tab_ml_3.a
-> Append
-> Seq Scan on pagg_tab_ml_p2_s1 pagg_tab_ml_2
-> Partial HashAggregate
Group Key: pagg_tab_ml_3.a
-> Seq Scan on pagg_tab_ml_p3_s1 pagg_tab_ml_3
-> Seq Scan on pagg_tab_ml_p2_s2 pagg_tab_ml_3
-> Finalize GroupAggregate
Group Key: pagg_tab_ml_5.a
Filter: (avg(pagg_tab_ml_5.b) < '3'::numeric)
-> Sort
Sort Key: pagg_tab_ml_5.a
-> Append
-> Partial HashAggregate
Group Key: pagg_tab_ml_4.a
-> Seq Scan on pagg_tab_ml_p3_s2 pagg_tab_ml_4
Group Key: pagg_tab_ml_5.a
-> Seq Scan on pagg_tab_ml_p3_s1 pagg_tab_ml_5
-> Partial HashAggregate
Group Key: pagg_tab_ml_6.a
-> Seq Scan on pagg_tab_ml_p3_s2 pagg_tab_ml_6
(31 rows)
SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3;
@ -1185,33 +1185,33 @@ SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER B
Group Key: pagg_tab_ml.a
-> Parallel Seq Scan on pagg_tab_ml_p1 pagg_tab_ml
-> Finalize GroupAggregate
Group Key: pagg_tab_ml_1.a
Filter: (avg(pagg_tab_ml_1.b) < '3'::numeric)
Group Key: pagg_tab_ml_2.a
Filter: (avg(pagg_tab_ml_2.b) < '3'::numeric)
-> Gather Merge
Workers Planned: 2
-> Sort
Sort Key: pagg_tab_ml_1.a
Sort Key: pagg_tab_ml_2.a
-> Parallel Append
-> Partial HashAggregate
Group Key: pagg_tab_ml_1.a
-> Parallel Seq Scan on pagg_tab_ml_p2_s1 pagg_tab_ml_1
-> Partial HashAggregate
Group Key: pagg_tab_ml_2.a
-> Parallel Seq Scan on pagg_tab_ml_p2_s2 pagg_tab_ml_2
-> Parallel Seq Scan on pagg_tab_ml_p2_s1 pagg_tab_ml_2
-> Partial HashAggregate
Group Key: pagg_tab_ml_3.a
-> Parallel Seq Scan on pagg_tab_ml_p2_s2 pagg_tab_ml_3
-> Finalize GroupAggregate
Group Key: pagg_tab_ml_3.a
Filter: (avg(pagg_tab_ml_3.b) < '3'::numeric)
Group Key: pagg_tab_ml_5.a
Filter: (avg(pagg_tab_ml_5.b) < '3'::numeric)
-> Gather Merge
Workers Planned: 2
-> Sort
Sort Key: pagg_tab_ml_3.a
Sort Key: pagg_tab_ml_5.a
-> Parallel Append
-> Partial HashAggregate
Group Key: pagg_tab_ml_3.a
-> Parallel Seq Scan on pagg_tab_ml_p3_s1 pagg_tab_ml_3
Group Key: pagg_tab_ml_5.a
-> Parallel Seq Scan on pagg_tab_ml_p3_s1 pagg_tab_ml_5
-> Partial HashAggregate
Group Key: pagg_tab_ml_4.a
-> Parallel Seq Scan on pagg_tab_ml_p3_s2 pagg_tab_ml_4
Group Key: pagg_tab_ml_6.a
-> Parallel Seq Scan on pagg_tab_ml_p3_s2 pagg_tab_ml_6
(41 rows)
SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3;
@ -1426,9 +1426,9 @@ SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) <
-> Partial HashAggregate
Group Key: pagg_tab_para.x
-> Parallel Append
-> Seq Scan on pagg_tab_para_p1 pagg_tab_para
-> Seq Scan on pagg_tab_para_p3 pagg_tab_para_2
-> Parallel Seq Scan on pagg_tab_para_p2 pagg_tab_para_1
-> Seq Scan on pagg_tab_para_p1 pagg_tab_para_1
-> Seq Scan on pagg_tab_para_p3 pagg_tab_para_3
-> Parallel Seq Scan on pagg_tab_para_p2 pagg_tab_para_2
(15 rows)
SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3;
@ -1460,9 +1460,9 @@ SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) <
-> Partial HashAggregate
Group Key: pagg_tab_para.x
-> Parallel Append
-> Seq Scan on pagg_tab_para_p1 pagg_tab_para
-> Seq Scan on pagg_tab_para_p2 pagg_tab_para_1
-> Seq Scan on pagg_tab_para_p3 pagg_tab_para_2
-> Seq Scan on pagg_tab_para_p1 pagg_tab_para_1
-> Seq Scan on pagg_tab_para_p2 pagg_tab_para_2
-> Seq Scan on pagg_tab_para_p3 pagg_tab_para_3
(15 rows)
SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -662,11 +662,11 @@ EXPLAIN (COSTS OFF) SELECT * FROM t1;
QUERY PLAN
-------------------------------
Append
-> Seq Scan on t1
-> Seq Scan on t1 t1_1
Filter: ((a % 2) = 0)
-> Seq Scan on t2 t1_1
-> Seq Scan on t2 t1_2
Filter: ((a % 2) = 0)
-> Seq Scan on t3 t1_2
-> Seq Scan on t3 t1_3
Filter: ((a % 2) = 0)
(7 rows)
@ -689,11 +689,11 @@ EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b);
QUERY PLAN
-----------------------------------------------
Append
-> Seq Scan on t1
-> Seq Scan on t1 t1_1
Filter: (((a % 2) = 0) AND f_leak(b))
-> Seq Scan on t2 t1_1
-> Seq Scan on t2 t1_2
Filter: (((a % 2) = 0) AND f_leak(b))
-> Seq Scan on t3 t1_2
-> Seq Scan on t3 t1_3
Filter: (((a % 2) = 0) AND f_leak(b))
(7 rows)
@ -712,11 +712,11 @@ EXPLAIN (COSTS OFF) SELECT *, t1 FROM t1;
QUERY PLAN
-------------------------------
Append
-> Seq Scan on t1
-> Seq Scan on t1 t1_1
Filter: ((a % 2) = 0)
-> Seq Scan on t2 t1_1
-> Seq Scan on t2 t1_2
Filter: ((a % 2) = 0)
-> Seq Scan on t3 t1_2
-> Seq Scan on t3 t1_3
Filter: ((a % 2) = 0)
(7 rows)
@ -735,11 +735,11 @@ EXPLAIN (COSTS OFF) SELECT *, t1 FROM t1;
QUERY PLAN
-------------------------------
Append
-> Seq Scan on t1
-> Seq Scan on t1 t1_1
Filter: ((a % 2) = 0)
-> Seq Scan on t2 t1_1
-> Seq Scan on t2 t1_2
Filter: ((a % 2) = 0)
-> Seq Scan on t3 t1_2
-> Seq Scan on t3 t1_3
Filter: ((a % 2) = 0)
(7 rows)
@ -759,11 +759,11 @@ EXPLAIN (COSTS OFF) SELECT * FROM t1 FOR SHARE;
-------------------------------------
LockRows
-> Append
-> Seq Scan on t1
-> Seq Scan on t1 t1_1
Filter: ((a % 2) = 0)
-> Seq Scan on t2 t1_1
-> Seq Scan on t2 t1_2
Filter: ((a % 2) = 0)
-> Seq Scan on t3 t1_2
-> Seq Scan on t3 t1_3
Filter: ((a % 2) = 0)
(8 rows)
@ -787,11 +787,11 @@ EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) FOR SHARE;
-----------------------------------------------------
LockRows
-> Append
-> Seq Scan on t1
-> Seq Scan on t1 t1_1
Filter: (((a % 2) = 0) AND f_leak(b))
-> Seq Scan on t2 t1_1
-> Seq Scan on t2 t1_2
Filter: (((a % 2) = 0) AND f_leak(b))
-> Seq Scan on t3 t1_2
-> Seq Scan on t3 t1_3
Filter: (((a % 2) = 0) AND f_leak(b))
(8 rows)
@ -849,11 +849,11 @@ EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b);
QUERY PLAN
---------------------------
Append
-> Seq Scan on t1
-> Seq Scan on t1 t1_1
Filter: f_leak(b)
-> Seq Scan on t2 t1_1
-> Seq Scan on t2 t1_2
Filter: f_leak(b)
-> Seq Scan on t3 t1_2
-> Seq Scan on t3 t1_3
Filter: f_leak(b)
(7 rows)
@ -891,11 +891,11 @@ EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b);
QUERY PLAN
---------------------------
Append
-> Seq Scan on t1
-> Seq Scan on t1 t1_1
Filter: f_leak(b)
-> Seq Scan on t2 t1_1
-> Seq Scan on t2 t1_2
Filter: f_leak(b)
-> Seq Scan on t3 t1_2
-> Seq Scan on t3 t1_3
Filter: f_leak(b)
(7 rows)
@ -991,11 +991,11 @@ EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle);
InitPlan 1 (returns $0)
-> Index Scan using uaccount_pkey on uaccount
Index Cond: (pguser = CURRENT_USER)
-> Seq Scan on part_document_fiction part_document
-> Seq Scan on part_document_fiction part_document_1
Filter: ((dlevel <= $0) AND f_leak(dtitle))
-> Seq Scan on part_document_satire part_document_1
-> Seq Scan on part_document_satire part_document_2
Filter: ((dlevel <= $0) AND f_leak(dtitle))
-> Seq Scan on part_document_nonfiction part_document_2
-> Seq Scan on part_document_nonfiction part_document_3
Filter: ((dlevel <= $0) AND f_leak(dtitle))
(10 rows)
@ -1033,11 +1033,11 @@ EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle);
InitPlan 1 (returns $0)
-> Index Scan using uaccount_pkey on uaccount
Index Cond: (pguser = CURRENT_USER)
-> Seq Scan on part_document_fiction part_document
-> Seq Scan on part_document_fiction part_document_1
Filter: ((dlevel <= $0) AND f_leak(dtitle))
-> Seq Scan on part_document_satire part_document_1
-> Seq Scan on part_document_satire part_document_2
Filter: ((dlevel <= $0) AND f_leak(dtitle))
-> Seq Scan on part_document_nonfiction part_document_2
-> Seq Scan on part_document_nonfiction part_document_3
Filter: ((dlevel <= $0) AND f_leak(dtitle))
(10 rows)
@ -1180,11 +1180,11 @@ EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle);
InitPlan 1 (returns $0)
-> Index Scan using uaccount_pkey on uaccount
Index Cond: (pguser = CURRENT_USER)
-> Seq Scan on part_document_fiction part_document
-> Seq Scan on part_document_fiction part_document_1
Filter: ((dlevel <= $0) AND f_leak(dtitle))
-> Seq Scan on part_document_satire part_document_1
-> Seq Scan on part_document_satire part_document_2
Filter: ((dlevel <= $0) AND f_leak(dtitle))
-> Seq Scan on part_document_nonfiction part_document_2
-> Seq Scan on part_document_nonfiction part_document_3
Filter: ((dlevel <= $0) AND f_leak(dtitle))
(10 rows)
@ -1229,11 +1229,11 @@ EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle);
QUERY PLAN
---------------------------------------------------------------
Append
-> Seq Scan on part_document_fiction part_document
-> Seq Scan on part_document_fiction part_document_1
Filter: ((dauthor = CURRENT_USER) AND f_leak(dtitle))
-> Seq Scan on part_document_satire part_document_1
-> Seq Scan on part_document_satire part_document_2
Filter: ((dauthor = CURRENT_USER) AND f_leak(dtitle))
-> Seq Scan on part_document_nonfiction part_document_2
-> Seq Scan on part_document_nonfiction part_document_3
Filter: ((dauthor = CURRENT_USER) AND f_leak(dtitle))
(7 rows)
@ -1509,11 +1509,11 @@ EXPLAIN (COSTS OFF) EXECUTE p1(2);
QUERY PLAN
----------------------------------------------
Append
-> Seq Scan on t1
-> Seq Scan on t1 t1_1
Filter: ((a <= 2) AND ((a % 2) = 0))
-> Seq Scan on t2 t1_1
-> Seq Scan on t2 t1_2
Filter: ((a <= 2) AND ((a % 2) = 0))
-> Seq Scan on t3 t1_2
-> Seq Scan on t3 t1_3
Filter: ((a <= 2) AND ((a % 2) = 0))
(7 rows)
@ -1551,11 +1551,11 @@ EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b);
QUERY PLAN
---------------------------
Append
-> Seq Scan on t1
-> Seq Scan on t1 t1_1
Filter: f_leak(b)
-> Seq Scan on t2 t1_1
-> Seq Scan on t2 t1_2
Filter: f_leak(b)
-> Seq Scan on t3 t1_2
-> Seq Scan on t3 t1_3
Filter: f_leak(b)
(7 rows)
@ -1575,11 +1575,11 @@ EXPLAIN (COSTS OFF) EXECUTE p1(2);
QUERY PLAN
---------------------------
Append
-> Seq Scan on t1
-> Seq Scan on t1 t1_1
Filter: (a <= 2)
-> Seq Scan on t2 t1_1
-> Seq Scan on t2 t1_2
Filter: (a <= 2)
-> Seq Scan on t3 t1_2
-> Seq Scan on t3 t1_3
Filter: (a <= 2)
(7 rows)
@ -1596,11 +1596,11 @@ EXPLAIN (COSTS OFF) EXECUTE p2(2);
QUERY PLAN
---------------------------
Append
-> Seq Scan on t1
-> Seq Scan on t1 t1_1
Filter: (a = 2)
-> Seq Scan on t2 t1_1
-> Seq Scan on t2 t1_2
Filter: (a = 2)
-> Seq Scan on t3 t1_2
-> Seq Scan on t3 t1_3
Filter: (a = 2)
(7 rows)
@ -1619,11 +1619,11 @@ EXPLAIN (COSTS OFF) EXECUTE p2(2);
QUERY PLAN
---------------------------------------------
Append
-> Seq Scan on t1
-> Seq Scan on t1 t1_1
Filter: ((a = 2) AND ((a % 2) = 0))
-> Seq Scan on t2 t1_1
-> Seq Scan on t2 t1_2
Filter: ((a = 2) AND ((a % 2) = 0))
-> Seq Scan on t3 t1_2
-> Seq Scan on t3 t1_3
Filter: ((a = 2) AND ((a % 2) = 0))
(7 rows)
@ -1756,11 +1756,11 @@ WHERE t1.a = 3 and t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b);
-> Seq Scan on t2
Filter: ((a = 3) AND ((a % 2) = 1) AND f_leak(b))
-> Append
-> Seq Scan on t1
-> Seq Scan on t1 t1_1
Filter: ((a = 3) AND ((a % 2) = 0) AND f_leak(b))
-> Seq Scan on t2 t1_1
-> Seq Scan on t2 t1_2
Filter: ((a = 3) AND ((a % 2) = 0) AND f_leak(b))
-> Seq Scan on t3 t1_2
-> Seq Scan on t3 t1_3
Filter: ((a = 3) AND ((a % 2) = 0) AND f_leak(b))
(11 rows)
@ -1806,33 +1806,33 @@ AND f_leak(t1_1.b) AND f_leak(t1_2.b) RETURNING *, t1_1, t1_2;
-> Seq Scan on t1 t1_1
Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
-> Append
-> Seq Scan on t1 t1_2
-> Seq Scan on t1 t1_2_1
Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
-> Seq Scan on t2 t1_2_1
-> Seq Scan on t2 t1_2_2
Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
-> Seq Scan on t3 t1_2_2
-> Seq Scan on t3 t1_2_3
Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
-> Nested Loop
Join Filter: (t1_1_1.b = t1_2.b)
-> Seq Scan on t2 t1_1_1
Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
-> Append
-> Seq Scan on t1 t1_2
-> Seq Scan on t1 t1_2_1
Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
-> Seq Scan on t2 t1_2_1
-> Seq Scan on t2 t1_2_2
Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
-> Seq Scan on t3 t1_2_2
-> Seq Scan on t3 t1_2_3
Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
-> Nested Loop
Join Filter: (t1_1_2.b = t1_2.b)
-> Seq Scan on t3 t1_1_2
Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
-> Append
-> Seq Scan on t1 t1_2
-> Seq Scan on t1 t1_2_1
Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
-> Seq Scan on t2 t1_2_1
-> Seq Scan on t2 t1_2_2
Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
-> Seq Scan on t3 t1_2_2
-> Seq Scan on t3 t1_2_3
Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
(37 rows)

View File

@ -21,12 +21,12 @@ explain (costs off)
Workers Planned: 3
-> Partial Aggregate
-> Parallel Append
-> Parallel Seq Scan on d_star a_star_3
-> Parallel Seq Scan on f_star a_star_5
-> Parallel Seq Scan on e_star a_star_4
-> Parallel Seq Scan on b_star a_star_1
-> Parallel Seq Scan on c_star a_star_2
-> Parallel Seq Scan on a_star
-> Parallel Seq Scan on d_star a_star_4
-> Parallel Seq Scan on f_star a_star_6
-> Parallel Seq Scan on e_star a_star_5
-> Parallel Seq Scan on b_star a_star_2
-> Parallel Seq Scan on c_star a_star_3
-> Parallel Seq Scan on a_star a_star_1
(11 rows)
select round(avg(aa)), sum(aa) from a_star a1;
@ -47,12 +47,12 @@ explain (costs off)
Workers Planned: 3
-> Partial Aggregate
-> Parallel Append
-> Seq Scan on d_star a_star_3
-> Seq Scan on c_star a_star_2
-> Parallel Seq Scan on f_star a_star_5
-> Parallel Seq Scan on e_star a_star_4
-> Parallel Seq Scan on b_star a_star_1
-> Parallel Seq Scan on a_star
-> Seq Scan on d_star a_star_4
-> Seq Scan on c_star a_star_3
-> Parallel Seq Scan on f_star a_star_6
-> Parallel Seq Scan on e_star a_star_5
-> Parallel Seq Scan on b_star a_star_2
-> Parallel Seq Scan on a_star a_star_1
(11 rows)
select round(avg(aa)), sum(aa) from a_star a2;
@ -75,12 +75,12 @@ explain (costs off)
Workers Planned: 3
-> Partial Aggregate
-> Parallel Append
-> Seq Scan on d_star a_star_3
-> Seq Scan on f_star a_star_5
-> Seq Scan on e_star a_star_4
-> Seq Scan on b_star a_star_1
-> Seq Scan on c_star a_star_2
-> Seq Scan on a_star
-> Seq Scan on d_star a_star_4
-> Seq Scan on f_star a_star_6
-> Seq Scan on e_star a_star_5
-> Seq Scan on b_star a_star_2
-> Seq Scan on c_star a_star_3
-> Seq Scan on a_star a_star_1
(11 rows)
select round(avg(aa)), sum(aa) from a_star a3;
@ -106,12 +106,12 @@ explain (costs off)
Workers Planned: 1
-> Partial Aggregate
-> Append
-> Parallel Seq Scan on a_star
-> Parallel Seq Scan on b_star a_star_1
-> Parallel Seq Scan on c_star a_star_2
-> Parallel Seq Scan on d_star a_star_3
-> Parallel Seq Scan on e_star a_star_4
-> Parallel Seq Scan on f_star a_star_5
-> Parallel Seq Scan on a_star a_star_1
-> Parallel Seq Scan on b_star a_star_2
-> Parallel Seq Scan on c_star a_star_3
-> Parallel Seq Scan on d_star a_star_4
-> Parallel Seq Scan on e_star a_star_5
-> Parallel Seq Scan on f_star a_star_6
(11 rows)
select round(avg(aa)), sum(aa) from a_star a4;
@ -145,15 +145,15 @@ explain (costs off)
-> Gather
Workers Planned: 3
-> Parallel Append
-> Parallel Seq Scan on part_pa_test_p1 pa2
-> Parallel Seq Scan on part_pa_test_p2 pa2_1
-> Parallel Seq Scan on part_pa_test_p1 pa2_1
-> Parallel Seq Scan on part_pa_test_p2 pa2_2
SubPlan 2
-> Result
SubPlan 1
-> Append
-> Seq Scan on part_pa_test_p1 pa1
-> Seq Scan on part_pa_test_p1 pa1_1
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)
(14 rows)

View File

@ -198,13 +198,13 @@ explain (costs off)
-------------------------------------------------
Aggregate
-> Append
-> Sample Scan on person
-> Sample Scan on person person_1
Sampling: bernoulli ('100'::real)
-> Sample Scan on emp person_1
-> Sample Scan on emp person_2
Sampling: bernoulli ('100'::real)
-> Sample Scan on student person_2
-> Sample Scan on student person_3
Sampling: bernoulli ('100'::real)
-> Sample Scan on stud_emp person_3
-> Sample Scan on stud_emp person_4
Sampling: bernoulli ('100'::real)
(10 rows)
@ -319,12 +319,12 @@ create table parted_sample_1 partition of parted_sample for values in (1);
create table parted_sample_2 partition of parted_sample for values in (2);
explain (costs off)
select * from parted_sample tablesample bernoulli (100);
QUERY PLAN
------------------------------------------------------
QUERY PLAN
-------------------------------------------
Append
-> Sample Scan on parted_sample_1 parted_sample
-> Sample Scan on parted_sample_1
Sampling: bernoulli ('100'::real)
-> Sample Scan on parted_sample_2 parted_sample_1
-> Sample Scan on parted_sample_2
Sampling: bernoulli ('100'::real)
(5 rows)

View File

@ -1548,16 +1548,16 @@ INSERT INTO other_tbl_parent VALUES (7),(200);
INSERT INTO other_tbl_child VALUES (8),(100);
EXPLAIN (costs off)
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_child base_tbl_parent_1
-> Hash Join
Hash Cond: (other_tbl_parent.id = base_tbl_parent.a)
-> Append
-> Seq Scan on other_tbl_parent
-> Seq Scan on other_tbl_child other_tbl_parent_1
-> Seq Scan on other_tbl_parent other_tbl_parent_1
-> Seq Scan on other_tbl_child other_tbl_parent_2
-> Hash
-> Seq Scan on base_tbl_parent
-> Merge Join
@ -1568,8 +1568,8 @@ UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id;
-> Sort
Sort Key: other_tbl_parent.id
-> Append
-> Seq Scan on other_tbl_parent
-> Seq Scan on other_tbl_child other_tbl_parent_1
-> Seq Scan on other_tbl_parent other_tbl_parent_1
-> Seq Scan on other_tbl_child other_tbl_parent_2
(20 rows)
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;
Filter: ((t1.a <> 6) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t1.a) AND leakproof(t1.a))
SubPlan 1
-> Append
-> Seq Scan on public.t12
Filter: (t12.a = t1.a)
-> Seq Scan on public.t111 t12_1
-> Seq Scan on public.t12 t12_1
Filter: (t12_1.a = t1.a)
-> Seq Scan on public.t111 t12_2
Filter: (t12_2.a = t1.a)
SubPlan 2
-> Append
-> Seq Scan on public.t12 t12_2
Output: t12_2.a
-> Seq Scan on public.t111 t12_3
Output: t12_3.a
-> Seq Scan on public.t12 t12_4
Output: t12_4.a
-> Seq Scan on public.t111 t12_5
Output: t12_5.a
-> 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
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;
Filter: ((alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t1.a) AND leakproof(t1.a))
SubPlan 1
-> Append
-> Seq Scan on public.t12
Filter: (t12.a = t1.a)
-> Seq Scan on public.t111 t12_1
-> Seq Scan on public.t12 t12_1
Filter: (t12_1.a = t1.a)
-> Seq Scan on public.t111 t12_2
Filter: (t12_2.a = t1.a)
SubPlan 2
-> Append
-> Seq Scan on public.t12 t12_2
Output: t12_2.a
-> Seq Scan on public.t111 t12_3
Output: t12_3.a
-> Seq Scan on public.t12 t12_4
Output: t12_4.a
-> Seq Scan on public.t111 t12_5
Output: t12_5.a
-> 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
Index Cond: ((t1_1.a > 5) AND (t1_1.a = 8))