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

Commit6eeb95f

Browse files
committed
Restructure representation of join alias variables. An explicit JOIN
now has an RTE of its own, and references to its outputs now are Varsreferencing the JOIN RTE, rather than CASE-expressions. This allowsreverse-listing in ruleutils.c to use the correct alias easily, ratherthan painfully reverse-engineering the alias namespace as it used to do.Also, nested FULL JOINs work correctly, because the result of the innerjoins are simple Vars that the planner can cope with. This fixes a bugreported a couple times now, notably by Tatsuo on 18-Nov-01. The aliasVars are expanded into COALESCE expressions where needed at the very endof planning, rather than during parsing.Also, beginnings of support for showing plan qualifier expressions inEXPLAIN. There are probably still cases that need work.initdb forced due to change of stored-rule representation.
1 parent66b6bf6 commit6eeb95f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1941
-987
lines changed

‎src/backend/commands/explain.c

Lines changed: 214 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
66
* Portions Copyright (c) 1994-5, Regents of the University of California
77
*
8-
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.70 2002/03/06 06:09:33 momjian Exp $
8+
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.71 2002/03/12 00:51:35 tgl Exp $
99
*
1010
*/
1111

@@ -15,12 +15,15 @@
1515
#include"executor/instrument.h"
1616
#include"lib/stringinfo.h"
1717
#include"nodes/print.h"
18+
#include"optimizer/clauses.h"
1819
#include"optimizer/planner.h"
1920
#include"parser/parsetree.h"
2021
#include"rewrite/rewriteHandler.h"
2122
#include"tcop/pquery.h"
23+
#include"utils/builtins.h"
2224
#include"utils/relcache.h"
2325

26+
2427
typedefstructExplainState
2528
{
2629
/* options */
@@ -32,6 +35,14 @@ typedef struct ExplainState
3235

3336
staticStringInfoExplain_PlanToString(Plan*plan,ExplainState*es);
3437
staticvoidExplainOneQuery(Query*query,boolverbose,boolanalyze,CommandDestdest);
38+
staticvoidshow_scan_qual(List*qual,boolis_or_qual,constchar*qlabel,
39+
intscanrelid,
40+
StringInfostr,intindent,ExplainState*es);
41+
staticvoidshow_upper_qual(List*qual,constchar*qlabel,
42+
constchar*outer_name,intouter_varno,Plan*outer_plan,
43+
constchar*inner_name,intinner_varno,Plan*inner_plan,
44+
StringInfostr,intindent,ExplainState*es);
45+
staticNode*make_ors_ands_explicit(List*orclauses);
3546

3647
/* Convert a null string pointer into "<>" */
3748
#definestringStringInfo(s) (((s) == NULL) ? "<>" : (s))
@@ -40,7 +51,6 @@ static void ExplainOneQuery(Query *query, bool verbose, bool analyze, CommandDes
4051
/*
4152
* ExplainQuery -
4253
* print out the execution plan for a given query
43-
*
4454
*/
4555
void
4656
ExplainQuery(Query*query,boolverbose,boolanalyze,CommandDestdest)
@@ -81,7 +91,6 @@ ExplainQuery(Query *query, bool verbose, bool analyze, CommandDest dest)
8191
/*
8292
* ExplainOneQuery -
8393
* print out the execution plan for one query
84-
*
8594
*/
8695
staticvoid
8796
ExplainOneQuery(Query*query,boolverbose,boolanalyze,CommandDestdest)
@@ -176,9 +185,6 @@ ExplainOneQuery(Query *query, bool verbose, bool analyze, CommandDest dest)
176185
pfree(es);
177186
}
178187

179-
/*****************************************************************************
180-
*
181-
*****************************************************************************/
182188

183189
/*
184190
* explain_outNode -
@@ -341,6 +347,90 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
341347
}
342348
appendStringInfo(str,"\n");
343349

350+
/* quals */
351+
switch (nodeTag(plan))
352+
{
353+
caseT_IndexScan:
354+
show_scan_qual(((IndexScan*)plan)->indxqualorig, true,
355+
"indxqual",
356+
((Scan*)plan)->scanrelid,
357+
str,indent,es);
358+
show_scan_qual(plan->qual, false,"qual",
359+
((Scan*)plan)->scanrelid,
360+
str,indent,es);
361+
break;
362+
caseT_SeqScan:
363+
caseT_TidScan:
364+
show_scan_qual(plan->qual, false,"qual",
365+
((Scan*)plan)->scanrelid,
366+
str,indent,es);
367+
break;
368+
caseT_NestLoop:
369+
show_upper_qual(((NestLoop*)plan)->join.joinqual,"joinqual",
370+
"outer",OUTER,outerPlan(plan),
371+
"inner",INNER,innerPlan(plan),
372+
str,indent,es);
373+
show_upper_qual(plan->qual,"qual",
374+
"outer",OUTER,outerPlan(plan),
375+
"inner",INNER,innerPlan(plan),
376+
str,indent,es);
377+
break;
378+
caseT_MergeJoin:
379+
show_upper_qual(((MergeJoin*)plan)->mergeclauses,"merge",
380+
"outer",OUTER,outerPlan(plan),
381+
"inner",INNER,innerPlan(plan),
382+
str,indent,es);
383+
show_upper_qual(((MergeJoin*)plan)->join.joinqual,"joinqual",
384+
"outer",OUTER,outerPlan(plan),
385+
"inner",INNER,innerPlan(plan),
386+
str,indent,es);
387+
show_upper_qual(plan->qual,"qual",
388+
"outer",OUTER,outerPlan(plan),
389+
"inner",INNER,innerPlan(plan),
390+
str,indent,es);
391+
break;
392+
caseT_HashJoin:
393+
show_upper_qual(((HashJoin*)plan)->hashclauses,"hash",
394+
"outer",OUTER,outerPlan(plan),
395+
"inner",INNER,innerPlan(plan),
396+
str,indent,es);
397+
show_upper_qual(((HashJoin*)plan)->join.joinqual,"joinqual",
398+
"outer",OUTER,outerPlan(plan),
399+
"inner",INNER,innerPlan(plan),
400+
str,indent,es);
401+
show_upper_qual(plan->qual,"qual",
402+
"outer",OUTER,outerPlan(plan),
403+
"inner",INNER,innerPlan(plan),
404+
str,indent,es);
405+
break;
406+
caseT_SubqueryScan:
407+
show_upper_qual(plan->qual,"qual",
408+
"subplan",1, ((SubqueryScan*)plan)->subplan,
409+
"",0,NULL,
410+
str,indent,es);
411+
break;
412+
caseT_Agg:
413+
caseT_Group:
414+
show_upper_qual(plan->qual,"qual",
415+
"subplan",0,outerPlan(plan),
416+
"",0,NULL,
417+
str,indent,es);
418+
break;
419+
caseT_Result:
420+
show_upper_qual((List*) ((Result*)plan)->resconstantqual,
421+
"constqual",
422+
"subplan",OUTER,outerPlan(plan),
423+
"",0,NULL,
424+
str,indent,es);
425+
show_upper_qual(plan->qual,"qual",
426+
"subplan",OUTER,outerPlan(plan),
427+
"",0,NULL,
428+
str,indent,es);
429+
break;
430+
default:
431+
break;
432+
}
433+
344434
/* initPlan-s */
345435
if (plan->initPlan)
346436
{
@@ -448,3 +538,121 @@ Explain_PlanToString(Plan *plan, ExplainState *es)
448538
explain_outNode(str,plan,0,es);
449539
returnstr;
450540
}
541+
542+
/*
543+
* Show a qualifier expression for a scan plan node
544+
*/
545+
staticvoid
546+
show_scan_qual(List*qual,boolis_or_qual,constchar*qlabel,
547+
intscanrelid,
548+
StringInfostr,intindent,ExplainState*es)
549+
{
550+
RangeTblEntry*rte;
551+
List*context;
552+
Node*node;
553+
char*exprstr;
554+
inti;
555+
556+
/* No work if empty qual */
557+
if (qual==NIL)
558+
return;
559+
if (is_or_qual)
560+
{
561+
if (lfirst(qual)==NIL&&lnext(qual)==NIL)
562+
return;
563+
}
564+
565+
/* Generate deparse context */
566+
Assert(scanrelid>0&&scanrelid <=length(es->rtable));
567+
rte=rt_fetch(scanrelid,es->rtable);
568+
569+
/* Assume it's on a real relation */
570+
Assert(rte->relname);
571+
572+
context=deparse_context_for(rte->relname,rte->relid);
573+
574+
/* Fix qual --- indexqual requires different processing */
575+
if (is_or_qual)
576+
node=make_ors_ands_explicit(qual);
577+
else
578+
node= (Node*)make_ands_explicit(qual);
579+
580+
/* Deparse the expression */
581+
exprstr=deparse_expression(node,context, false);
582+
583+
/* And add to str */
584+
for (i=0;i<indent;i++)
585+
appendStringInfo(str," ");
586+
appendStringInfo(str," %s: %s\n",qlabel,exprstr);
587+
}
588+
589+
/*
590+
* Show a qualifier expression for an upper-level plan node
591+
*/
592+
staticvoid
593+
show_upper_qual(List*qual,constchar*qlabel,
594+
constchar*outer_name,intouter_varno,Plan*outer_plan,
595+
constchar*inner_name,intinner_varno,Plan*inner_plan,
596+
StringInfostr,intindent,ExplainState*es)
597+
{
598+
List*context;
599+
Node*outercontext;
600+
Node*innercontext;
601+
Node*node;
602+
char*exprstr;
603+
inti;
604+
605+
/* No work if empty qual */
606+
if (qual==NIL)
607+
return;
608+
609+
/* Generate deparse context */
610+
if (outer_plan)
611+
outercontext=deparse_context_for_subplan(outer_name,
612+
outer_plan->targetlist,
613+
es->rtable);
614+
else
615+
outercontext=NULL;
616+
if (inner_plan)
617+
innercontext=deparse_context_for_subplan(inner_name,
618+
inner_plan->targetlist,
619+
es->rtable);
620+
else
621+
innercontext=NULL;
622+
context=deparse_context_for_plan(outer_varno,outercontext,
623+
inner_varno,innercontext);
624+
625+
/* Deparse the expression */
626+
node= (Node*)make_ands_explicit(qual);
627+
exprstr=deparse_expression(node,context, (inner_plan!=NULL));
628+
629+
/* And add to str */
630+
for (i=0;i<indent;i++)
631+
appendStringInfo(str," ");
632+
appendStringInfo(str," %s: %s\n",qlabel,exprstr);
633+
}
634+
635+
/*
636+
* Indexscan qual lists have an implicit OR-of-ANDs structure. Make it
637+
* explicit so deparsing works properly.
638+
*/
639+
staticNode*
640+
make_ors_ands_explicit(List*orclauses)
641+
{
642+
if (orclauses==NIL)
643+
returnNULL;/* probably can't happen */
644+
elseif (lnext(orclauses)==NIL)
645+
return (Node*)make_ands_explicit(lfirst(orclauses));
646+
else
647+
{
648+
List*args=NIL;
649+
List*orptr;
650+
651+
foreach(orptr,orclauses)
652+
{
653+
args=lappend(args,make_ands_explicit(lfirst(orptr)));
654+
}
655+
656+
return (Node*)make_orclause(args);
657+
}
658+
}

‎src/backend/nodes/copyfuncs.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.168 2002/03/08 04:37:16 tgl Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.169 2002/03/12 00:51:37 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -323,6 +323,7 @@ CopyJoinFields(Join *from, Join *newnode)
323323
{
324324
newnode->jointype=from->jointype;
325325
Node_Copy(from,newnode,joinqual);
326+
newnode->joinrti=from->joinrti;
326327
/* subPlan list must point to subplans in the new subtree, not the old */
327328
if (from->plan.subPlan!=NIL)
328329
newnode->plan.subPlan=nconc(newnode->plan.subPlan,
@@ -970,8 +971,7 @@ _copyJoinExpr(JoinExpr *from)
970971
Node_Copy(from,newnode,using);
971972
Node_Copy(from,newnode,quals);
972973
Node_Copy(from,newnode,alias);
973-
Node_Copy(from,newnode,colnames);
974-
Node_Copy(from,newnode,colvars);
974+
newnode->rtindex=from->rtindex;
975975

976976
returnnewnode;
977977
}
@@ -1081,16 +1081,13 @@ _copyArrayRef(ArrayRef *from)
10811081
*_copyRelOptInfo
10821082
* ----------------
10831083
*/
1084-
/*
1085-
*when you change this, also make sure to fix up xfunc_copyRelOptInfo in
1086-
*planner/path/xfunc.c accordingly!!!
1087-
*-- JMH, 8/2/93
1088-
*/
10891084
staticRelOptInfo*
10901085
_copyRelOptInfo(RelOptInfo*from)
10911086
{
10921087
RelOptInfo*newnode=makeNode(RelOptInfo);
10931088

1089+
newnode->reloptkind=from->reloptkind;
1090+
10941091
newnode->relids=listCopy(from->relids);
10951092

10961093
newnode->rows=from->rows;
@@ -1109,6 +1106,9 @@ _copyRelOptInfo(RelOptInfo *from)
11091106
newnode->tuples=from->tuples;
11101107
Node_Copy(from,newnode,subplan);
11111108

1109+
newnode->joinrti=from->joinrti;
1110+
newnode->joinrteids=listCopy(from->joinrteids);
1111+
11121112
Node_Copy(from,newnode,baserestrictinfo);
11131113
newnode->baserestrictcost=from->baserestrictcost;
11141114
newnode->outerjoinset=listCopy(from->outerjoinset);
@@ -1487,10 +1487,16 @@ _copyRangeTblEntry(RangeTblEntry *from)
14871487
{
14881488
RangeTblEntry*newnode=makeNode(RangeTblEntry);
14891489

1490+
newnode->rtekind=from->rtekind;
14901491
if (from->relname)
14911492
newnode->relname=pstrdup(from->relname);
14921493
newnode->relid=from->relid;
14931494
Node_Copy(from,newnode,subquery);
1495+
newnode->jointype=from->jointype;
1496+
newnode->joincoltypes=listCopy(from->joincoltypes);
1497+
newnode->joincoltypmods=listCopy(from->joincoltypmods);
1498+
newnode->joinleftcols=listCopy(from->joinleftcols);
1499+
newnode->joinrightcols=listCopy(from->joinrightcols);
14941500
Node_Copy(from,newnode,alias);
14951501
Node_Copy(from,newnode,eref);
14961502
newnode->inh=from->inh;

‎src/backend/nodes/equalfuncs.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* Portions Copyright (c) 1994, Regents of the University of California
2121
*
2222
* IDENTIFICATION
23-
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.116 2002/03/08 04:37:16 tgl Exp $
23+
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.117 2002/03/12 00:51:37 tgl Exp $
2424
*
2525
*-------------------------------------------------------------------------
2626
*/
@@ -335,9 +335,7 @@ _equalJoinExpr(JoinExpr *a, JoinExpr *b)
335335
return false;
336336
if (!equal(a->alias,b->alias))
337337
return false;
338-
if (!equal(a->colnames,b->colnames))
339-
return false;
340-
if (!equal(a->colvars,b->colvars))
338+
if (a->rtindex!=b->rtindex)
341339
return false;
342340

343341
return true;
@@ -1639,12 +1637,24 @@ _equalTargetEntry(TargetEntry *a, TargetEntry *b)
16391637
staticbool
16401638
_equalRangeTblEntry(RangeTblEntry*a,RangeTblEntry*b)
16411639
{
1640+
if (a->rtekind!=b->rtekind)
1641+
return false;
16421642
if (!equalstr(a->relname,b->relname))
16431643
return false;
16441644
if (a->relid!=b->relid)
16451645
return false;
16461646
if (!equal(a->subquery,b->subquery))
16471647
return false;
1648+
if (a->jointype!=b->jointype)
1649+
return false;
1650+
if (!equali(a->joincoltypes,b->joincoltypes))
1651+
return false;
1652+
if (!equali(a->joincoltypmods,b->joincoltypmods))
1653+
return false;
1654+
if (!equali(a->joinleftcols,b->joinleftcols))
1655+
return false;
1656+
if (!equali(a->joinrightcols,b->joinrightcols))
1657+
return false;
16481658
if (!equal(a->alias,b->alias))
16491659
return false;
16501660
if (!equal(a->eref,b->eref))

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp