Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4d04299

Browse files
committed
Print a given subplan only once in EXPLAIN.
We have, for a very long time, allowed the same subplan (same member of thePlannedStmt.subplans list) to be referenced by more than one SubPlan node;this avoids problems for cases such as subplans within an IndexScan'sindxqual and indxqualorig fields. However, EXPLAIN had not gotten the memoand would print each reference as though it were an independent identicalsubplan. To fix, track plan_ids of subplans we've printed and don't printthe same plan_id twice. Per report from Pavel Stehule.BTW: the particular case of IndexScan didn't cause visible duplicationin a plain EXPLAIN, only EXPLAIN ANALYZE, because in the former case weshort-circuit executor startup before the indxqual field is processed byExecInitExpr. That seems like it could easily lead to other EXPLAINproblems in future, but it's not clear how to avoid it without breakingthe "EXPLAIN a plan using hypothetical indexes" use-case. For now I'veleft that issue alone.Although this is a longstanding bug, it's purely cosmetic (no great harmis done by the repeat printout) and we haven't had field complaints before.So I'm hesitant to back-patch it, especially since there is some small riskof ABI problems due to the need to add a new field to ExplainState.In passing, rearrange order of fields in ExplainState to be less random,and update some obsolete comments about when/where to initialize them.Report: <CAFj8pRAimq+NK-menjt+3J4-LFoodDD8Or6=Lc_stcFD+eD4DA@mail.gmail.com>
1 parenta670c24 commit4d04299

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

‎src/backend/commands/explain.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -565,8 +565,9 @@ ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es,
565565
* convert a QueryDesc's plan tree to text and append it to es->str
566566
*
567567
* The caller should have set up the options fields of *es, as well as
568-
* initializing the output buffer es->str. Other fields in *es are
569-
* initialized here.
568+
* initializing the output buffer es->str. Also, output formatting state
569+
* such as the indent level is assumed valid. Plan-tree-specific fields
570+
* in *es are initialized here.
570571
*
571572
* NB: will not work on utility statements
572573
*/
@@ -576,13 +577,15 @@ ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc)
576577
Bitmapset*rels_used=NULL;
577578
PlanState*ps;
578579

580+
/* Set up ExplainState fields associated with this plan tree */
579581
Assert(queryDesc->plannedstmt!=NULL);
580582
es->pstmt=queryDesc->plannedstmt;
581583
es->rtable=queryDesc->plannedstmt->rtable;
582584
ExplainPreScanNode(queryDesc->planstate,&rels_used);
583585
es->rtable_names=select_rtable_names_for_explain(es->rtable,rels_used);
584586
es->deparse_cxt=deparse_context_for_plan_rtable(es->rtable,
585587
es->rtable_names);
588+
es->printed_subplans=NULL;
586589

587590
/*
588591
* Sometimes we mark a Gather node as "invisible", which means that it's
@@ -2798,6 +2801,21 @@ ExplainSubPlans(List *plans, List *ancestors,
27982801
SubPlanState*sps= (SubPlanState*)lfirst(lst);
27992802
SubPlan*sp= (SubPlan*)sps->xprstate.expr;
28002803

2804+
/*
2805+
* There can be multiple SubPlan nodes referencing the same physical
2806+
* subplan (same plan_id, which is its index in PlannedStmt.subplans).
2807+
* We should print a subplan only once, so track which ones we already
2808+
* printed. This state must be global across the plan tree, since the
2809+
* duplicate nodes could be in different plan nodes, eg both a bitmap
2810+
* indexscan's indexqual and its parent heapscan's recheck qual. (We
2811+
* do not worry too much about which plan node we show the subplan as
2812+
* attached to in such cases.)
2813+
*/
2814+
if (bms_is_member(sp->plan_id,es->printed_subplans))
2815+
continue;
2816+
es->printed_subplans=bms_add_member(es->printed_subplans,
2817+
sp->plan_id);
2818+
28012819
ExplainNode(sps->planstate,ancestors,
28022820
relationship,sp->plan_name,es);
28032821
}

‎src/include/commands/explain.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,15 @@ typedef struct ExplainState
3535
booltiming;/* print detailed node timing */
3636
boolsummary;/* print total planning and execution timing */
3737
ExplainFormatformat;/* output format */
38-
/* other states */
38+
/* state for output formatting --- not reset for each new plan tree */
39+
intindent;/* current indentation level */
40+
List*grouping_stack;/* format-specific grouping state */
41+
/* state related to the current plan tree (filled by ExplainPrintPlan) */
3942
PlannedStmt*pstmt;/* top of plan */
4043
List*rtable;/* range table */
4144
List*rtable_names;/* alias names for RTEs */
42-
intindent;/* current indentation level */
43-
List*grouping_stack;/* format-specific grouping state */
4445
List*deparse_cxt;/* context list for deparsing expressions */
46+
Bitmapset*printed_subplans;/* ids of SubPlans we've printed */
4547
}ExplainState;
4648

4749
/* Hook for plugins to get control in ExplainOneQuery() */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp