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

Commit1fd0c59

Browse files
committed
Phase 1 of read-only-plans project: cause executor state nodes to point
to plan nodes, not vice-versa. All executor state nodes now inherit fromstruct PlanState. Copying of plan trees has been simplified by notstoring a list of SubPlans in Plan nodes (eliminating duplicate links).The executor still needs such a list, but it can build it duringExecutorStart since it has to scan the plan tree anyway.No initdb forced since no stored-on-disk structures changed, but youwill need a full recompile because of node-numbering changes.
1 parent0f3b83e commit1fd0c59

File tree

71 files changed

+3001
-3727
lines changed

Some content is hidden

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

71 files changed

+3001
-3727
lines changed

‎src/backend/commands/explain.c

Lines changed: 125 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Portions Copyright (c) 1996-2002, 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.93 2002/11/13 00:39:46 momjian Exp $
8+
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.94 2002/12/05 15:50:30 tgl Exp $
99
*
1010
*/
1111

@@ -34,17 +34,19 @@ typedef struct ExplainState
3434
{
3535
/* options */
3636
boolprintCost;/* print cost */
37-
boolprintNodes;/* do nodeToString()instead */
38-
boolprintAnalyze;/* print actual times */
37+
boolprintNodes;/* do nodeToString()too */
38+
boolprintAnalyze;/* print actual times */
3939
/* other states */
4040
List*rtable;/* range table */
4141
}ExplainState;
4242

43-
staticStringInfoExplain_PlanToString(Plan*plan,ExplainState*es);
4443
staticvoidExplainOneQuery(Query*query,ExplainStmt*stmt,
4544
TupOutputState*tstate);
46-
staticvoidexplain_outNode(StringInfostr,Plan*plan,Plan*outer_plan,
47-
intindent,ExplainState*es);
45+
staticdoubleelapsed_time(structtimeval*starttime);
46+
staticvoidexplain_outNode(StringInfostr,
47+
Plan*plan,PlanState*planstate,
48+
Plan*outer_plan,
49+
intindent,ExplainState*es);
4850
staticvoidshow_scan_qual(List*qual,boolis_or_qual,constchar*qlabel,
4951
intscanrelid,Plan*outer_plan,
5052
StringInfostr,intindent,ExplainState*es);
@@ -116,8 +118,11 @@ static void
116118
ExplainOneQuery(Query*query,ExplainStmt*stmt,TupOutputState*tstate)
117119
{
118120
Plan*plan;
121+
QueryDesc*queryDesc;
119122
ExplainState*es;
123+
StringInfostr;
120124
doubletotaltime=0;
125+
structtimevalstarttime;
121126

122127
/* planner will not cope with utility statements */
123128
if (query->commandType==CMD_UTILITY)
@@ -136,41 +141,34 @@ ExplainOneQuery(Query *query, ExplainStmt *stmt, TupOutputState *tstate)
136141
if (plan==NULL)
137142
return;
138143

144+
/* We don't support DECLARE CURSOR here */
145+
Assert(!query->isPortal);
146+
147+
gettimeofday(&starttime,NULL);
148+
149+
/* Create a QueryDesc requesting no output */
150+
queryDesc=CreateQueryDesc(query,plan,None,NULL,NULL,
151+
stmt->analyze);
152+
153+
/* call ExecutorStart to prepare the plan for execution */
154+
ExecutorStart(queryDesc);
155+
139156
/* Execute the plan for statistics if asked for */
140157
if (stmt->analyze)
141158
{
142-
structtimevalstarttime;
143-
structtimevalendtime;
144-
145-
/*
146-
* Set up the instrumentation for the top node. This will cascade
147-
* during plan initialisation
148-
*/
149-
plan->instrument=InstrAlloc();
159+
/* run the plan */
160+
ExecutorRun(queryDesc,ForwardScanDirection,0L);
150161

151-
gettimeofday(&starttime,NULL);
152-
ProcessQuery(query,plan,None,NULL);
153-
CommandCounterIncrement();
154-
gettimeofday(&endtime,NULL);
162+
/* We can't clean up 'till we're done printing the stats... */
155163

156-
endtime.tv_sec-=starttime.tv_sec;
157-
endtime.tv_usec-=starttime.tv_usec;
158-
while (endtime.tv_usec<0)
159-
{
160-
endtime.tv_usec+=1000000;
161-
endtime.tv_sec--;
162-
}
163-
totaltime= (double)endtime.tv_sec+
164-
(double)endtime.tv_usec /1000000.0;
164+
totaltime+=elapsed_time(&starttime);
165165
}
166166

167167
es= (ExplainState*)palloc0(sizeof(ExplainState));
168168

169169
es->printCost= true;/* default */
170-
171-
if (stmt->verbose)
172-
es->printNodes= true;
173-
170+
es->printNodes=stmt->verbose;
171+
es->printAnalyze=stmt->analyze;
174172
es->rtable=query->rtable;
175173

176174
if (es->printNodes)
@@ -193,33 +191,73 @@ ExplainOneQuery(Query *query, ExplainStmt *stmt, TupOutputState *tstate)
193191
}
194192
}
195193

194+
str=makeStringInfo();
195+
196196
if (es->printCost)
197197
{
198-
StringInfostr;
198+
explain_outNode(str,plan,queryDesc->planstate,
199+
NULL,0,es);
200+
}
199201

200-
str=Explain_PlanToString(plan,es);
202+
/*
203+
* Close down the query and free resources. Include time for this
204+
* in the total runtime.
205+
*/
206+
gettimeofday(&starttime,NULL);
207+
208+
ExecutorEnd(queryDesc);
209+
CommandCounterIncrement();
210+
211+
totaltime+=elapsed_time(&starttime);
212+
213+
if (es->printCost)
214+
{
201215
if (stmt->analyze)
202216
appendStringInfo(str,"Total runtime: %.2f msec\n",
203217
1000.0*totaltime);
204218
do_text_output_multiline(tstate,str->data);
205-
pfree(str->data);
206-
pfree(str);
207219
}
208220

221+
pfree(str->data);
222+
pfree(str);
209223
pfree(es);
210224
}
211225

226+
/* Compute elapsed time in seconds since given gettimeofday() timestamp */
227+
staticdouble
228+
elapsed_time(structtimeval*starttime)
229+
{
230+
structtimevalendtime;
231+
232+
gettimeofday(&endtime,NULL);
233+
234+
endtime.tv_sec-=starttime->tv_sec;
235+
endtime.tv_usec-=starttime->tv_usec;
236+
while (endtime.tv_usec<0)
237+
{
238+
endtime.tv_usec+=1000000;
239+
endtime.tv_sec--;
240+
}
241+
return (double)endtime.tv_sec+
242+
(double)endtime.tv_usec /1000000.0;
243+
}
212244

213245
/*
214246
* explain_outNode -
215247
* converts a Plan node into ascii string and appends it to 'str'
216248
*
249+
* planstate points to the executor state node corresponding to the plan node.
250+
* We need this to get at the instrumentation data (if any) as well as the
251+
* list of subplans.
252+
*
217253
* outer_plan, if not null, references another plan node that is the outer
218254
* side of a join with the current node. This is only interesting for
219255
* deciphering runtime keys of an inner indexscan.
220256
*/
221257
staticvoid
222-
explain_outNode(StringInfostr,Plan*plan,Plan*outer_plan,
258+
explain_outNode(StringInfostr,
259+
Plan*plan,PlanState*planstate,
260+
Plan*outer_plan,
223261
intindent,ExplainState*es)
224262
{
225263
List*l;
@@ -410,18 +448,23 @@ explain_outNode(StringInfo str, Plan *plan, Plan *outer_plan,
410448
plan->startup_cost,plan->total_cost,
411449
plan->plan_rows,plan->plan_width);
412450

413-
if (plan->instrument&&plan->instrument->nloops>0)
451+
/*
452+
* We have to forcibly clean up the instrumentation state because
453+
* we haven't done ExecutorEnd yet. This is pretty grotty ...
454+
*/
455+
InstrEndLoop(planstate->instrument);
456+
457+
if (planstate->instrument&&planstate->instrument->nloops>0)
414458
{
415-
doublenloops=plan->instrument->nloops;
459+
doublenloops=planstate->instrument->nloops;
416460

417461
appendStringInfo(str," (actual time=%.2f..%.2f rows=%.0f loops=%.0f)",
418-
1000.0*plan->instrument->startup /nloops,
419-
1000.0*plan->instrument->total /nloops,
420-
plan->instrument->ntuples /nloops,
421-
plan->instrument->nloops);
422-
es->printAnalyze= true;
462+
1000.0*planstate->instrument->startup /nloops,
463+
1000.0*planstate->instrument->total /nloops,
464+
planstate->instrument->ntuples /nloops,
465+
planstate->instrument->nloops);
423466
}
424-
elseif(es->printAnalyze)
467+
elseif (es->printAnalyze)
425468
{
426469
appendStringInfo(str," (never executed)");
427470
}
@@ -538,19 +581,26 @@ explain_outNode(StringInfo str, Plan *plan, Plan *outer_plan,
538581
if (plan->initPlan)
539582
{
540583
List*saved_rtable=es->rtable;
584+
List*pslist=planstate->initPlan;
541585
List*lst;
542586

543587
for (i=0;i<indent;i++)
544588
appendStringInfo(str," ");
545589
appendStringInfo(str," InitPlan\n");
546590
foreach(lst,plan->initPlan)
547591
{
548-
es->rtable= ((SubPlan*)lfirst(lst))->rtable;
592+
SubPlan*subplan= (SubPlan*)lfirst(lst);
593+
SubPlanState*subplanstate= (SubPlanState*)lfirst(pslist);
594+
595+
es->rtable=subplan->rtable;
549596
for (i=0;i<indent;i++)
550597
appendStringInfo(str," ");
551598
appendStringInfo(str," -> ");
552-
explain_outNode(str, ((SubPlan*)lfirst(lst))->plan,NULL,
599+
explain_outNode(str,subplan->plan,
600+
subplanstate->planstate,
601+
NULL,
553602
indent+4,es);
603+
pslist=lnext(pslist);
554604
}
555605
es->rtable=saved_rtable;
556606
}
@@ -561,7 +611,10 @@ explain_outNode(StringInfo str, Plan *plan, Plan *outer_plan,
561611
for (i=0;i<indent;i++)
562612
appendStringInfo(str," ");
563613
appendStringInfo(str," -> ");
564-
explain_outNode(str,outerPlan(plan),NULL,indent+3,es);
614+
explain_outNode(str,outerPlan(plan),
615+
outerPlanState(planstate),
616+
NULL,
617+
indent+3,es);
565618
}
566619

567620
/* righttree */
@@ -570,15 +623,20 @@ explain_outNode(StringInfo str, Plan *plan, Plan *outer_plan,
570623
for (i=0;i<indent;i++)
571624
appendStringInfo(str," ");
572625
appendStringInfo(str," -> ");
573-
explain_outNode(str,innerPlan(plan),outerPlan(plan),
626+
explain_outNode(str,innerPlan(plan),
627+
innerPlanState(planstate),
628+
outerPlan(plan),
574629
indent+3,es);
575630
}
576631

577632
if (IsA(plan,Append))
578633
{
579634
Append*appendplan= (Append*)plan;
635+
AppendState*appendstate= (AppendState*)planstate;
580636
List*lst;
637+
intj;
581638

639+
j=0;
582640
foreach(lst,appendplan->appendplans)
583641
{
584642
Plan*subnode= (Plan*)lfirst(lst);
@@ -587,13 +645,18 @@ explain_outNode(StringInfo str, Plan *plan, Plan *outer_plan,
587645
appendStringInfo(str," ");
588646
appendStringInfo(str," -> ");
589647

590-
explain_outNode(str,subnode,NULL,indent+3,es);
648+
explain_outNode(str,subnode,
649+
appendstate->appendplans[j],
650+
NULL,
651+
indent+3,es);
652+
j++;
591653
}
592654
}
593655

594656
if (IsA(plan,SubqueryScan))
595657
{
596658
SubqueryScan*subqueryscan= (SubqueryScan*)plan;
659+
SubqueryScanState*subquerystate= (SubqueryScanState*)planstate;
597660
Plan*subnode=subqueryscan->subplan;
598661
RangeTblEntry*rte=rt_fetch(subqueryscan->scan.scanrelid,
599662
es->rtable);
@@ -606,43 +669,41 @@ explain_outNode(StringInfo str, Plan *plan, Plan *outer_plan,
606669
appendStringInfo(str," ");
607670
appendStringInfo(str," -> ");
608671

609-
explain_outNode(str,subnode,NULL,indent+3,es);
672+
explain_outNode(str,subnode,
673+
subquerystate->subplan,
674+
NULL,
675+
indent+3,es);
610676

611677
es->rtable=saved_rtable;
612678
}
613679

614680
/* subPlan-s */
615-
if (plan->subPlan)
681+
if (planstate->subPlan)
616682
{
617683
List*saved_rtable=es->rtable;
618684
List*lst;
619685

620686
for (i=0;i<indent;i++)
621687
appendStringInfo(str," ");
622688
appendStringInfo(str," SubPlan\n");
623-
foreach(lst,plan->subPlan)
689+
foreach(lst,planstate->subPlan)
624690
{
625-
es->rtable= ((SubPlan*)lfirst(lst))->rtable;
691+
SubPlanState*sps= (SubPlanState*)lfirst(lst);
692+
SubPlan*sp= (SubPlan*)sps->ps.plan;
693+
694+
es->rtable=sp->rtable;
626695
for (i=0;i<indent;i++)
627696
appendStringInfo(str," ");
628697
appendStringInfo(str," -> ");
629-
explain_outNode(str, ((SubPlan*)lfirst(lst))->plan,NULL,
698+
explain_outNode(str,sp->plan,
699+
sps->planstate,
700+
NULL,
630701
indent+4,es);
631702
}
632703
es->rtable=saved_rtable;
633704
}
634705
}
635706

636-
staticStringInfo
637-
Explain_PlanToString(Plan*plan,ExplainState*es)
638-
{
639-
StringInfostr=makeStringInfo();
640-
641-
if (plan!=NULL)
642-
explain_outNode(str,plan,NULL,0,es);
643-
returnstr;
644-
}
645-
646707
/*
647708
* Show a qualifier expression for a scan plan node
648709
*/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp