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

Commite2159f3

Browse files
committed
Teach the planner to remove SubqueryScan nodes from the plan if they
aren't doing anything useful (ie, neither selection nor projection).Also, extend to SubqueryScan the hacks already in place to avoidunnecessary ExecProject calls when the result would just be the sametuple the subquery already delivered. This saves some overhead inUNION and other set operations, as well as avoiding overhead forunflatten-able subqueries. Per example from Sokolov Yura.
1 parentc61207b commite2159f3

File tree

13 files changed

+603
-175
lines changed

13 files changed

+603
-175
lines changed

‎src/backend/executor/execMain.c

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
*
2727
*
2828
* IDENTIFICATION
29-
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.248 2005/05/06 17:24:53 tgl Exp $
29+
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.249 2005/05/22 22:30:19 tgl Exp $
3030
*
3131
*-------------------------------------------------------------------------
3232
*/
@@ -353,16 +353,10 @@ ExecCheckRTEPerms(RangeTblEntry *rte)
353353
AclIduserid;
354354

355355
/*
356-
* If it's a subquery, recursively examine its rangetable.
357-
*/
358-
if (rte->rtekind==RTE_SUBQUERY)
359-
{
360-
ExecCheckRTPerms(rte->subquery->rtable);
361-
return;
362-
}
363-
364-
/*
365-
* Otherwise, only plain-relation RTEs need to be checked here.
356+
* Only plain-relation RTEs need to be checked here. Subquery RTEs
357+
* are checked by ExecInitSubqueryScan if the subquery is still a
358+
* separate subquery --- if it's been pulled up into our query level
359+
* then the RTEs are in our rangetable and will be checked here.
366360
* Function RTEs are checked by init_fcache when the function is
367361
* prepared for execution. Join and special RTEs need no checks.
368362
*/

‎src/backend/executor/execScan.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*
1313
*
1414
* IDENTIFICATION
15-
* $PostgreSQL: pgsql/src/backend/executor/execScan.c,v 1.35 2005/03/16 21:38:06 tgl Exp $
15+
* $PostgreSQL: pgsql/src/backend/executor/execScan.c,v 1.36 2005/05/22 22:30:19 tgl Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -48,7 +48,6 @@ TupleTableSlot *
4848
ExecScan(ScanState*node,
4949
ExecScanAccessMtdaccessMtd)/* function returning a tuple */
5050
{
51-
EState*estate;
5251
ExprContext*econtext;
5352
List*qual;
5453
ProjectionInfo*projInfo;
@@ -58,11 +57,16 @@ ExecScan(ScanState *node,
5857
/*
5958
* Fetch data from node
6059
*/
61-
estate=node->ps.state;
62-
econtext=node->ps.ps_ExprContext;
6360
qual=node->ps.qual;
6461
projInfo=node->ps.ps_ProjInfo;
6562

63+
/*
64+
* If we have neither a qual to check nor a projection to do,
65+
* just skip all the overhead and return the raw scan tuple.
66+
*/
67+
if (!qual&& !projInfo)
68+
return (*accessMtd) (node);
69+
6670
/*
6771
* Check to see if we're still projecting out tuples from a previous
6872
* scan tuple (because there is a function-returning-set in the
@@ -83,6 +87,7 @@ ExecScan(ScanState *node,
8387
* storage allocated in the previous tuple cycle. Note this can't
8488
* happen until we're done projecting out tuples from a scan tuple.
8589
*/
90+
econtext=node->ps.ps_ExprContext;
8691
ResetExprContext(econtext);
8792

8893
/*

‎src/backend/executor/nodeAppend.c

Lines changed: 32 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/nodeAppend.c,v 1.63 2005/04/24 11:46:20 neilc Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/nodeAppend.c,v 1.64 2005/05/22 22:30:19 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -251,67 +251,52 @@ ExecCountSlotsAppend(Append *node)
251251
/* ----------------------------------------------------------------
252252
* ExecAppend
253253
*
254-
*Handlestheiteration overthemultiplescans.
254+
*Handles iteration over multiplesubplans.
255255
* ----------------------------------------------------------------
256256
*/
257257
TupleTableSlot*
258258
ExecAppend(AppendState*node)
259259
{
260-
EState*estate;
261-
intwhichplan;
262-
PlanState*subnode;
263-
TupleTableSlot*result;
264-
TupleTableSlot*result_slot;
265-
ScanDirectiondirection;
266-
267-
/*
268-
* get information from the node
269-
*/
270-
estate=node->ps.state;
271-
direction=estate->es_direction;
272-
whichplan=node->as_whichplan;
273-
result_slot=node->ps.ps_ResultTupleSlot;
274-
275-
/*
276-
* figure out which subplan we are currently processing
277-
*/
278-
subnode=node->appendplans[whichplan];
279-
280-
/*
281-
* get a tuple from the subplan
282-
*/
283-
result=ExecProcNode(subnode);
284-
285-
if (!TupIsNull(result))
260+
for (;;)
286261
{
262+
PlanState*subnode;
263+
TupleTableSlot*result;
264+
287265
/*
288-
* if the subplan gave us something then return it as-is. We do
289-
* NOT make use of the result slot that was set up in ExecInitAppend,
290-
* first because there's no reason to and second because it may have
291-
* the wrong tuple descriptor in inherited-UPDATE cases.
266+
* figure out which subplan we are currently processing
292267
*/
293-
returnresult;
294-
}
295-
else
296-
{
268+
subnode=node->appendplans[node->as_whichplan];
269+
297270
/*
298-
* .. go on to the "next" subplan in the appropriate direction and
299-
* try processing again (recursively)
271+
* get a tuple from the subplan
300272
*/
301-
if (ScanDirectionIsForward(direction))
302-
node->as_whichplan++;
303-
else
304-
node->as_whichplan--;
273+
result=ExecProcNode(subnode);
274+
275+
if (!TupIsNull(result))
276+
{
277+
/*
278+
* If the subplan gave us something then return it as-is.
279+
* We do NOT make use of the result slot that was set up in
280+
* ExecInitAppend, first because there's no reason to and
281+
* second because it may have the wrong tuple descriptor in
282+
* inherited-UPDATE cases.
283+
*/
284+
returnresult;
285+
}
305286

306287
/*
307-
*return something fromnext node or an empty slot if all of our
308-
*subplans have been exhausted. The empty slotis the oneset up
288+
*Go on to the "next" subplan in the appropriate direction.
289+
*If no more subplans, return the empty slot set up for us
309290
* by ExecInitAppend.
310291
*/
311-
if (exec_append_initialize_next(node))
312-
returnExecAppend(node);
292+
if (ScanDirectionIsForward(node->ps.state->es_direction))
293+
node->as_whichplan++;
313294
else
314-
returnExecClearTuple(result_slot);
295+
node->as_whichplan--;
296+
if (!exec_append_initialize_next(node))
297+
returnExecClearTuple(node->ps.ps_ResultTupleSlot);
298+
299+
/* Else loop back and try to get a tuple from the new subplan */
315300
}
316301
}
317302

‎src/backend/executor/nodeFunctionscan.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/nodeFunctionscan.c,v 1.33 2005/04/14 22:09:40 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/nodeFunctionscan.c,v 1.34 2005/05/22 22:30:19 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -219,8 +219,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate)
219219
BlessTupleDesc(tupdesc);
220220

221221
scanstate->tupdesc=tupdesc;
222-
ExecSetSlotDescriptor(scanstate->ss.ss_ScanTupleSlot,
223-
tupdesc, false);
222+
ExecAssignScanType(&scanstate->ss,tupdesc, false);
224223

225224
/*
226225
* Other node-specific setup
@@ -235,7 +234,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate)
235234
* Initialize result tuple type and projection info.
236235
*/
237236
ExecAssignResultTypeFromTL(&scanstate->ss.ps);
238-
ExecAssignProjectionInfo(&scanstate->ss.ps);
237+
ExecAssignScanProjectionInfo(&scanstate->ss);
239238

240239
returnscanstate;
241240
}

‎src/backend/executor/nodeSubqueryscan.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*
1313
*
1414
* IDENTIFICATION
15-
* $PostgreSQL: pgsql/src/backend/executor/nodeSubqueryscan.c,v 1.25 2004/12/31 21:59:45 pgsql Exp $
15+
* $PostgreSQL: pgsql/src/backend/executor/nodeSubqueryscan.c,v 1.26 2005/05/22 22:30:19 tgl Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -78,6 +78,10 @@ SubqueryNext(SubqueryScanState *node)
7878

7979
MemoryContextSwitchTo(oldcontext);
8080

81+
/*
82+
* We just overwrite our ScanTupleSlot with the subplan's result slot,
83+
* rather than expending the cycles for ExecCopySlot().
84+
*/
8185
node->ss.ss_ScanTupleSlot=slot;
8286

8387
returnslot;
@@ -144,12 +148,13 @@ ExecInitSubqueryScan(SubqueryScan *node, EState *estate)
144148
ExecInitExpr((Expr*)node->scan.plan.qual,
145149
(PlanState*)subquerystate);
146150

147-
#defineSUBQUERYSCAN_NSLOTS1
151+
#defineSUBQUERYSCAN_NSLOTS2
148152

149153
/*
150154
* tuple table initialization
151155
*/
152156
ExecInitResultTupleSlot(estate,&subquerystate->ss.ps);
157+
ExecInitScanTupleSlot(estate,&subquerystate->ss);
153158

154159
/*
155160
* initialize subquery
@@ -159,6 +164,11 @@ ExecInitSubqueryScan(SubqueryScan *node, EState *estate)
159164
rte=rt_fetch(node->scan.scanrelid,estate->es_range_table);
160165
Assert(rte->rtekind==RTE_SUBQUERY);
161166

167+
/*
168+
* Do access checking on the rangetable entries in the subquery.
169+
*/
170+
ExecCheckRTPerms(rte->subquery->rtable);
171+
162172
/*
163173
* The subquery needs its own EState because it has its own
164174
* rangetable. It shares our Param ID space, however. XXX if
@@ -187,14 +197,20 @@ ExecInitSubqueryScan(SubqueryScan *node, EState *estate)
187197

188198
MemoryContextSwitchTo(oldcontext);
189199

190-
subquerystate->ss.ss_ScanTupleSlot=NULL;
191200
subquerystate->ss.ps.ps_TupFromTlist= false;
192201

202+
/*
203+
* Initialize scan tuple type (needed by ExecAssignScanProjectionInfo)
204+
*/
205+
ExecAssignScanType(&subquerystate->ss,
206+
ExecGetResultType(subquerystate->subplan),
207+
false);
208+
193209
/*
194210
* Initialize result tuple type and projection info.
195211
*/
196212
ExecAssignResultTypeFromTL(&subquerystate->ss.ps);
197-
ExecAssignProjectionInfo(&subquerystate->ss.ps);
213+
ExecAssignScanProjectionInfo(&subquerystate->ss);
198214

199215
returnsubquerystate;
200216
}
@@ -230,6 +246,7 @@ ExecEndSubqueryScan(SubqueryScanState *node)
230246
* clean out the upper tuple table
231247
*/
232248
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
249+
node->ss.ss_ScanTupleSlot=NULL;/* not ours to clear */
233250

234251
/*
235252
* close down subquery

‎src/backend/optimizer/plan/createplan.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.188 2005/04/25 04:27:12 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.189 2005/05/22 22:30:19 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -308,10 +308,11 @@ use_physical_tlist(RelOptInfo *rel)
308308
inti;
309309

310310
/*
311-
* Currently, can't do this for subquery or function scans. (This is
312-
* mainly because we don't have an equivalent of build_physical_tlist
313-
* for them; worth adding?)
311+
* OK for subquery scans, but not function scans. (This is mainly
312+
* because build_physical_tlist doesn't support them; worth adding?)
314313
*/
314+
if (rel->rtekind==RTE_SUBQUERY)
315+
return true;
315316
if (rel->rtekind!=RTE_RELATION)
316317
return false;
317318

‎src/backend/optimizer/plan/planner.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.185 2005/04/28 21:47:13 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.186 2005/05/22 22:30:19 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -144,12 +144,12 @@ planner(Query *parse, bool isCursor, int cursorOptions,
144144
result_plan=materialize_finished_plan(result_plan);
145145
}
146146

147+
/* final cleanup of the plan */
148+
result_plan=set_plan_references(result_plan,parse->rtable);
149+
147150
/* executor wants to know total number of Params used overall */
148151
result_plan->nParamExec=list_length(PlannerParamList);
149152

150-
/* final cleanup of the plan */
151-
set_plan_references(result_plan,parse->rtable);
152-
153153
/* restore state for outer planner, if any */
154154
PlannerQueryLevel=save_PlannerQueryLevel;
155155
PlannerParamList=save_PlannerParamList;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp