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

Commitd2c555e

Browse files
committed
Teach nodeSort and nodeMaterial to optimize out unnecessary overhead
when the passed-down eflags indicate they can.Simon Riggs and Tom Lane
1 parent2c0ef97 commitd2c555e

File tree

3 files changed

+80
-31
lines changed

3 files changed

+80
-31
lines changed

‎src/backend/executor/nodeMaterial.c

Lines changed: 57 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/nodeMaterial.c,v 1.52 2006/02/2804:10:27 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/nodeMaterial.c,v 1.53 2006/02/2805:48:44 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -58,9 +58,9 @@ ExecMaterial(MaterialState *node)
5858
tuplestorestate= (Tuplestorestate*)node->tuplestorestate;
5959

6060
/*
61-
* If first time through,initialize thetuplestore.
61+
* If first time through,and we need atuplestore, initialize it.
6262
*/
63-
if (tuplestorestate==NULL)
63+
if (tuplestorestate==NULL&&node->randomAccess)
6464
{
6565
tuplestorestate=tuplestore_begin_heap(true, false,work_mem);
6666

@@ -71,7 +71,8 @@ ExecMaterial(MaterialState *node)
7171
* If we are not at the end of the tuplestore, or are going backwards, try
7272
* to fetch a tuple from tuplestore.
7373
*/
74-
eof_tuplestore=tuplestore_ateof(tuplestorestate);
74+
eof_tuplestore= (tuplestorestate==NULL)||
75+
tuplestore_ateof(tuplestorestate);
7576

7677
if (!forward&&eof_tuplestore)
7778
{
@@ -135,7 +136,8 @@ ExecMaterial(MaterialState *node)
135136
* tuplestore is certainly in EOF state, its read position will move
136137
* forward over the added tuple. This is what we want.
137138
*/
138-
tuplestore_puttuple(tuplestorestate, (void*)heapTuple);
139+
if (tuplestorestate)
140+
tuplestore_puttuple(tuplestorestate, (void*)heapTuple);
139141
}
140142

141143
/*
@@ -165,8 +167,18 @@ ExecInitMaterial(Material *node, EState *estate, int eflags)
165167
matstate->ss.ps.plan= (Plan*)node;
166168
matstate->ss.ps.state=estate;
167169

168-
matstate->tuplestorestate=NULL;
170+
/*
171+
* We must have random access to the subplan output to do backward scan
172+
* or mark/restore. We also prefer to materialize the subplan output
173+
* if we might be called on to rewind and replay it many times.
174+
* However, if none of these cases apply, we can skip storing the data.
175+
*/
176+
matstate->randomAccess= (eflags& (EXEC_FLAG_REWIND |
177+
EXEC_FLAG_BACKWARD |
178+
EXEC_FLAG_MARK))!=0;
179+
169180
matstate->eof_underlying= false;
181+
matstate->tuplestorestate=NULL;
170182

171183
/*
172184
* Miscellaneous initialization
@@ -249,6 +261,8 @@ ExecEndMaterial(MaterialState *node)
249261
void
250262
ExecMaterialMarkPos(MaterialState*node)
251263
{
264+
Assert(node->randomAccess);
265+
252266
/*
253267
* if we haven't materialized yet, just return.
254268
*/
@@ -267,6 +281,8 @@ ExecMaterialMarkPos(MaterialState *node)
267281
void
268282
ExecMaterialRestrPos(MaterialState*node)
269283
{
284+
Assert(node->randomAccess);
285+
270286
/*
271287
* if we haven't materialized yet, just return.
272288
*/
@@ -288,29 +304,44 @@ ExecMaterialRestrPos(MaterialState *node)
288304
void
289305
ExecMaterialReScan(MaterialState*node,ExprContext*exprCtxt)
290306
{
291-
/*
292-
* If we haven't materialized yet, just return. If outerplan' chgParam is
293-
* not NULL then it will be re-scanned by ExecProcNode, else - no reason
294-
* to re-scan it at all.
295-
*/
296-
if (!node->tuplestorestate)
297-
return;
298-
299307
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
300308

301-
/*
302-
* If subnode is to be rescanned then we forget previous stored results;
303-
* we have to re-read the subplan and re-store.
304-
*
305-
* Otherwise we can just rewind and rescan the stored output. The state of
306-
* the subnode does not change.
307-
*/
308-
if (((PlanState*)node)->lefttree->chgParam!=NULL)
309+
if (node->randomAccess)
309310
{
310-
tuplestore_end((Tuplestorestate*)node->tuplestorestate);
311-
node->tuplestorestate=NULL;
312-
node->eof_underlying= false;
311+
/*
312+
* If we haven't materialized yet, just return. If outerplan' chgParam
313+
* is not NULL then it will be re-scanned by ExecProcNode, else - no
314+
* reason to re-scan it at all.
315+
*/
316+
if (!node->tuplestorestate)
317+
return;
318+
319+
/*
320+
* If subnode is to be rescanned then we forget previous stored
321+
* results; we have to re-read the subplan and re-store.
322+
*
323+
* Otherwise we can just rewind and rescan the stored output. The
324+
* state of the subnode does not change.
325+
*/
326+
if (((PlanState*)node)->lefttree->chgParam!=NULL)
327+
{
328+
tuplestore_end((Tuplestorestate*)node->tuplestorestate);
329+
node->tuplestorestate=NULL;
330+
node->eof_underlying= false;
331+
}
332+
else
333+
tuplestore_rescan((Tuplestorestate*)node->tuplestorestate);
313334
}
314335
else
315-
tuplestore_rescan((Tuplestorestate*)node->tuplestorestate);
336+
{
337+
/* In this case we are just passing on the subquery's output */
338+
339+
/*
340+
* if chgParam of subnode is not null then plan will be re-scanned by
341+
* first ExecProcNode.
342+
*/
343+
if (((PlanState*)node)->lefttree->chgParam==NULL)
344+
ExecReScan(((PlanState*)node)->lefttree,exprCtxt);
345+
node->eof_underlying= false;
346+
}
316347
}

‎src/backend/executor/nodeSort.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/nodeSort.c,v 1.54 2006/02/2804:10:27 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/nodeSort.c,v 1.55 2006/02/2805:48:44 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -89,7 +89,7 @@ ExecSort(SortState *node)
8989
plannode->sortOperators,
9090
plannode->sortColIdx,
9191
work_mem,
92-
true/*randomAccess */);
92+
node->randomAccess);
9393
node->tuplesortstate= (void*)tuplesortstate;
9494

9595
/*
@@ -164,6 +164,15 @@ ExecInitSort(Sort *node, EState *estate, int eflags)
164164
sortstate->ss.ps.plan= (Plan*)node;
165165
sortstate->ss.ps.state=estate;
166166

167+
/*
168+
* We must have random access to the sort output to do backward scan
169+
* or mark/restore. We also prefer to materialize the sort output
170+
* if we might be called on to rewind and replay it many times.
171+
*/
172+
sortstate->randomAccess= (eflags& (EXEC_FLAG_REWIND |
173+
EXEC_FLAG_BACKWARD |
174+
EXEC_FLAG_MARK))!=0;
175+
167176
sortstate->sort_Done= false;
168177
sortstate->tuplesortstate=NULL;
169178

@@ -308,11 +317,18 @@ ExecReScanSort(SortState *node, ExprContext *exprCtxt)
308317
*
309318
* Otherwise we can just rewind and rescan the sorted output.
310319
*/
311-
if (((PlanState*)node)->lefttree->chgParam!=NULL)
320+
if (((PlanState*)node)->lefttree->chgParam!=NULL||
321+
!node->randomAccess)
312322
{
313323
node->sort_Done= false;
314324
tuplesort_end((Tuplesortstate*)node->tuplesortstate);
315325
node->tuplesortstate=NULL;
326+
/*
327+
* if chgParam of subnode is not null then plan will be re-scanned by
328+
* first ExecProcNode.
329+
*/
330+
if (((PlanState*)node)->lefttree->chgParam==NULL)
331+
ExecReScan(((PlanState*)node)->lefttree,exprCtxt);
316332
}
317333
else
318334
tuplesort_rescan((Tuplesortstate*)node->tuplesortstate);

‎src/include/nodes/execnodes.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.147 2005/12/2801:30:01 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.148 2006/02/2805:48:44 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -1185,8 +1185,9 @@ typedef struct HashJoinState
11851185
typedefstructMaterialState
11861186
{
11871187
ScanStatess;/* its first field is NodeTag */
1188-
void*tuplestorestate;/*private state of tuplestore.c */
1188+
boolrandomAccess;/*need random access to subplan output? */
11891189
booleof_underlying;/* reached end of underlying plan? */
1190+
void*tuplestorestate;/* private state of tuplestore.c */
11901191
}MaterialState;
11911192

11921193
/* ----------------
@@ -1196,6 +1197,7 @@ typedef struct MaterialState
11961197
typedefstructSortState
11971198
{
11981199
ScanStatess;/* its first field is NodeTag */
1200+
boolrandomAccess;/* need random access to sort output? */
11991201
boolsort_Done;/* sort completed yet? */
12001202
void*tuplesortstate;/* private state of tuplesort.c */
12011203
}SortState;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp