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

Commit11e1318

Browse files
committed
Improve ruleutils.c's heuristics for dealing with rangetable aliases.
The previous scheme had bugs in some corner cases involving tables that hadbeen renamed since a view was made. This could result in dumped views thatfailed to reload or reloaded incorrectly, as seen in bug #7553 from LloydAlbin, as well as in some pgsql-hackers discussion back in January. Also,its behavior for printing EXPLAIN plans was sometimes confusing because ofwillingness to use the same alias for multiple RTEs (it was AshutoshBapat's complaint about that aspect that started the January thread).To fix, ensure that each RTE in the query has a unique unqualified alias,by modifying the alias if necessary (we add "_" and digits as needed tocreate a non-conflicting name). Then we can just print its variables withthat alias, avoiding the confusing and bug-prone scheme of sometimesschema-qualifying variable names. In EXPLAIN, it proves to be expedient totake the further step of only assigning such aliases to RTEs that areactually referenced in the query, since the planner has a habit ofgenerating extra RTEs with the same alias in situations such asinheritance-tree expansion.Although this fixes a bug of very long standing, I'm hesitant to back-patchsuch a noticeable behavioral change. My experiments while creating aregression test convinced me that actually incorrect output (as opposed toconfusing output) occurs only in very narrow cases, which is backed up bythe lack of previous complaints from the field. So we may be better offliving with it in released branches; and in any case it'd be smart to letthis ripen awhile in HEAD before we consider back-patching it.
1 parent7c45e3a commit11e1318

File tree

12 files changed

+886
-226
lines changed

12 files changed

+886
-226
lines changed

‎src/backend/commands/explain.c

Lines changed: 147 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ static void ExplainOneQuery(Query *query, IntoClause *into, ExplainState *es,
5151
staticvoidreport_triggers(ResultRelInfo*rInfo,boolshow_relname,
5252
ExplainState*es);
5353
staticdoubleelapsed_time(instr_time*starttime);
54+
staticvoidExplainPreScanNode(PlanState*planstate,Bitmapset**rels_used);
55+
staticvoidExplainPreScanMemberNodes(List*plans,PlanState**planstates,
56+
Bitmapset**rels_used);
57+
staticvoidExplainPreScanSubPlans(List*plans,Bitmapset**rels_used);
5458
staticvoidExplainNode(PlanState*planstate,List*ancestors,
5559
constchar*relationship,constchar*plan_name,
5660
ExplainState*es);
@@ -539,9 +543,13 @@ ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es,
539543
void
540544
ExplainPrintPlan(ExplainState*es,QueryDesc*queryDesc)
541545
{
546+
Bitmapset*rels_used=NULL;
547+
542548
Assert(queryDesc->plannedstmt!=NULL);
543549
es->pstmt=queryDesc->plannedstmt;
544550
es->rtable=queryDesc->plannedstmt->rtable;
551+
ExplainPreScanNode(queryDesc->planstate,&rels_used);
552+
es->rtable_names=select_rtable_names_for_explain(es->rtable,rels_used);
545553
ExplainNode(queryDesc->planstate,NIL,NULL,NULL,es);
546554
}
547555

@@ -640,6 +648,132 @@ elapsed_time(instr_time *starttime)
640648
returnINSTR_TIME_GET_DOUBLE(endtime);
641649
}
642650

651+
/*
652+
* ExplainPreScanNode -
653+
* Prescan the planstate tree to identify which RTEs are referenced
654+
*
655+
* Adds the relid of each referenced RTE to *rels_used. The result controls
656+
* which RTEs are assigned aliases by select_rtable_names_for_explain.This
657+
* ensures that we don't confusingly assign un-suffixed aliases to RTEs that
658+
* never appear in the EXPLAIN output (such as inheritance parents).
659+
*/
660+
staticvoid
661+
ExplainPreScanNode(PlanState*planstate,Bitmapset**rels_used)
662+
{
663+
Plan*plan=planstate->plan;
664+
665+
switch (nodeTag(plan))
666+
{
667+
caseT_SeqScan:
668+
caseT_IndexScan:
669+
caseT_IndexOnlyScan:
670+
caseT_BitmapHeapScan:
671+
caseT_TidScan:
672+
caseT_SubqueryScan:
673+
caseT_FunctionScan:
674+
caseT_ValuesScan:
675+
caseT_CteScan:
676+
caseT_WorkTableScan:
677+
caseT_ForeignScan:
678+
*rels_used=bms_add_member(*rels_used,
679+
((Scan*)plan)->scanrelid);
680+
break;
681+
caseT_ModifyTable:
682+
/* cf ExplainModifyTarget */
683+
*rels_used=bms_add_member(*rels_used,
684+
linitial_int(((ModifyTable*)plan)->resultRelations));
685+
break;
686+
default:
687+
break;
688+
}
689+
690+
/* initPlan-s */
691+
if (planstate->initPlan)
692+
ExplainPreScanSubPlans(planstate->initPlan,rels_used);
693+
694+
/* lefttree */
695+
if (outerPlanState(planstate))
696+
ExplainPreScanNode(outerPlanState(planstate),rels_used);
697+
698+
/* righttree */
699+
if (innerPlanState(planstate))
700+
ExplainPreScanNode(innerPlanState(planstate),rels_used);
701+
702+
/* special child plans */
703+
switch (nodeTag(plan))
704+
{
705+
caseT_ModifyTable:
706+
ExplainPreScanMemberNodes(((ModifyTable*)plan)->plans,
707+
((ModifyTableState*)planstate)->mt_plans,
708+
rels_used);
709+
break;
710+
caseT_Append:
711+
ExplainPreScanMemberNodes(((Append*)plan)->appendplans,
712+
((AppendState*)planstate)->appendplans,
713+
rels_used);
714+
break;
715+
caseT_MergeAppend:
716+
ExplainPreScanMemberNodes(((MergeAppend*)plan)->mergeplans,
717+
((MergeAppendState*)planstate)->mergeplans,
718+
rels_used);
719+
break;
720+
caseT_BitmapAnd:
721+
ExplainPreScanMemberNodes(((BitmapAnd*)plan)->bitmapplans,
722+
((BitmapAndState*)planstate)->bitmapplans,
723+
rels_used);
724+
break;
725+
caseT_BitmapOr:
726+
ExplainPreScanMemberNodes(((BitmapOr*)plan)->bitmapplans,
727+
((BitmapOrState*)planstate)->bitmapplans,
728+
rels_used);
729+
break;
730+
caseT_SubqueryScan:
731+
ExplainPreScanNode(((SubqueryScanState*)planstate)->subplan,
732+
rels_used);
733+
break;
734+
default:
735+
break;
736+
}
737+
738+
/* subPlan-s */
739+
if (planstate->subPlan)
740+
ExplainPreScanSubPlans(planstate->subPlan,rels_used);
741+
}
742+
743+
/*
744+
* Prescan the constituent plans of a ModifyTable, Append, MergeAppend,
745+
* BitmapAnd, or BitmapOr node.
746+
*
747+
* Note: we don't actually need to examine the Plan list members, but
748+
* we need the list in order to determine the length of the PlanState array.
749+
*/
750+
staticvoid
751+
ExplainPreScanMemberNodes(List*plans,PlanState**planstates,
752+
Bitmapset**rels_used)
753+
{
754+
intnplans=list_length(plans);
755+
intj;
756+
757+
for (j=0;j<nplans;j++)
758+
ExplainPreScanNode(planstates[j],rels_used);
759+
}
760+
761+
/*
762+
* Prescan a list of SubPlans (or initPlans, which also use SubPlan nodes).
763+
*/
764+
staticvoid
765+
ExplainPreScanSubPlans(List*plans,Bitmapset**rels_used)
766+
{
767+
ListCell*lst;
768+
769+
foreach(lst,plans)
770+
{
771+
SubPlanState*sps= (SubPlanState*)lfirst(lst);
772+
773+
ExplainPreScanNode(sps->planstate,rels_used);
774+
}
775+
}
776+
643777
/*
644778
* ExplainNode -
645779
* Appends a description of a plan tree to es->str
@@ -1440,7 +1574,8 @@ show_plan_tlist(PlanState *planstate, List *ancestors, ExplainState *es)
14401574
/* Set up deparsing context */
14411575
context=deparse_context_for_planstate((Node*)planstate,
14421576
ancestors,
1443-
es->rtable);
1577+
es->rtable,
1578+
es->rtable_names);
14441579
useprefix=list_length(es->rtable)>1;
14451580

14461581
/* Deparse each result column (we now include resjunk ones) */
@@ -1471,7 +1606,8 @@ show_expression(Node *node, const char *qlabel,
14711606
/* Set up deparsing context */
14721607
context=deparse_context_for_planstate((Node*)planstate,
14731608
ancestors,
1474-
es->rtable);
1609+
es->rtable,
1610+
es->rtable_names);
14751611

14761612
/* Deparse the expression */
14771613
exprstr=deparse_expression(node,context,useprefix, false);
@@ -1573,7 +1709,8 @@ show_sort_keys_common(PlanState *planstate, int nkeys, AttrNumber *keycols,
15731709
/* Set up deparsing context */
15741710
context=deparse_context_for_planstate((Node*)planstate,
15751711
ancestors,
1576-
es->rtable);
1712+
es->rtable,
1713+
es->rtable_names);
15771714
useprefix= (list_length(es->rtable)>1||es->verbose);
15781715

15791716
for (keyno=0;keyno<nkeys;keyno++)
@@ -1813,8 +1950,10 @@ ExplainTargetRel(Plan *plan, Index rti, ExplainState *es)
18131950
char*namespace=NULL;
18141951
constchar*objecttag=NULL;
18151952
RangeTblEntry*rte;
1953+
char*refname;
18161954

18171955
rte=rt_fetch(rti,es->rtable);
1956+
refname= (char*)list_nth(es->rtable_names,rti-1);
18181957

18191958
switch (nodeTag(plan))
18201959
{
@@ -1887,18 +2026,18 @@ ExplainTargetRel(Plan *plan, Index rti, ExplainState *es)
18872026
quote_identifier(objectname));
18882027
elseif (objectname!=NULL)
18892028
appendStringInfo(es->str," %s",quote_identifier(objectname));
1890-
if (objectname==NULL||
1891-
strcmp(rte->eref->aliasname,objectname)!=0)
1892-
appendStringInfo(es->str," %s",
1893-
quote_identifier(rte->eref->aliasname));
2029+
if (refname!=NULL&&
2030+
(objectname==NULL||strcmp(refname,objectname)!=0))
2031+
appendStringInfo(es->str," %s",quote_identifier(refname));
18942032
}
18952033
else
18962034
{
18972035
if (objecttag!=NULL&&objectname!=NULL)
18982036
ExplainPropertyText(objecttag,objectname,es);
18992037
if (namespace!=NULL)
19002038
ExplainPropertyText("Schema",namespace,es);
1901-
ExplainPropertyText("Alias",rte->eref->aliasname,es);
2039+
if (refname!=NULL)
2040+
ExplainPropertyText("Alias",refname,es);
19022041
}
19032042
}
19042043

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp