Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit df5a996

Browse files
committed
Simplify ExecutorRun's API and save some trivial number of cycles by having
it just return void instead of sometimes returning a TupleTableSlot. SQL functions don't need that anymore, and noplace else does either. Eliminating the return value also means one less hassle for the ExecutorRun hook functions that will be supported beginning in 8.4.
1 parent e981653 commit df5a996

File tree

3 files changed

+51
-69
lines changed

3 files changed

+51
-69
lines changed

src/backend/executor/execMain.c

+25-49
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.313 2008/08/25 22:42:32 tgl Exp $
29+
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.314 2008/10/31 21:07:54 tgl Exp $
3030
*
3131
*-------------------------------------------------------------------------
3232
*/
@@ -76,7 +76,7 @@ typedef struct evalPlanQual
7676
static void InitPlan(QueryDesc *queryDesc, int eflags);
7777
static void ExecCheckPlanOutput(Relation resultRel, List *targetList);
7878
static void ExecEndPlan(PlanState *planstate, EState *estate);
79-
static TupleTableSlot *ExecutePlan(EState *estate, PlanState *planstate,
79+
static void ExecutePlan(EState *estate, PlanState *planstate,
8080
CmdType operation,
8181
long numberTuples,
8282
ScanDirection direction,
@@ -220,34 +220,35 @@ ExecutorStart(QueryDesc *queryDesc, int eflags)
220220
* Note: count = 0 is interpreted as no portal limit, i.e., run to
221221
* completion.
222222
*
223+
* There is no return value, but output tuples (if any) are sent to
224+
* the destination receiver specified in the QueryDesc; and the number
225+
* of tuples processed at the top level can be found in
226+
* estate->es_processed.
227+
*
223228
* We provide a function hook variable that lets loadable plugins
224229
* get control when ExecutorRun is called. Such a plugin would
225230
* normally call standard_ExecutorRun().
226231
*
227232
* ----------------------------------------------------------------
228233
*/
229-
TupleTableSlot *
234+
void
230235
ExecutorRun(QueryDesc *queryDesc,
231236
ScanDirection direction, long count)
232237
{
233-
TupleTableSlot *result;
234-
235238
if (ExecutorRun_hook)
236-
result = (*ExecutorRun_hook) (queryDesc, direction, count);
239+
(*ExecutorRun_hook) (queryDesc, direction, count);
237240
else
238-
result = standard_ExecutorRun(queryDesc, direction, count);
239-
return result;
241+
standard_ExecutorRun(queryDesc, direction, count);
240242
}
241243

242-
TupleTableSlot *
244+
void
243245
standard_ExecutorRun(QueryDesc *queryDesc,
244246
ScanDirection direction, long count)
245247
{
246248
EState *estate;
247249
CmdType operation;
248250
DestReceiver *dest;
249251
bool sendTuples;
250-
TupleTableSlot *result;
251252
MemoryContext oldcontext;
252253

253254
/* sanity checks */
@@ -283,15 +284,13 @@ standard_ExecutorRun(QueryDesc *queryDesc,
283284
/*
284285
* run plan
285286
*/
286-
if (ScanDirectionIsNoMovement(direction))
287-
result = NULL;
288-
else
289-
result = ExecutePlan(estate,
290-
queryDesc->planstate,
291-
operation,
292-
count,
293-
direction,
294-
dest);
287+
if (!ScanDirectionIsNoMovement(direction))
288+
ExecutePlan(estate,
289+
queryDesc->planstate,
290+
operation,
291+
count,
292+
direction,
293+
dest);
295294

296295
/*
297296
* shutdown tuple receiver, if we started it
@@ -300,8 +299,6 @@ standard_ExecutorRun(QueryDesc *queryDesc,
300299
(*dest->rShutdown) (dest);
301300

302301
MemoryContextSwitchTo(oldcontext);
303-
304-
return result;
305302
}
306303

307304
/* ----------------------------------------------------------------
@@ -1271,19 +1268,16 @@ ExecEndPlan(PlanState *planstate, EState *estate)
12711268
/* ----------------------------------------------------------------
12721269
* ExecutePlan
12731270
*
1274-
* processes the query plan to retrieve 'numberTuples' tuples in the
1275-
* direction specified.
1276-
*
1277-
* Retrieves all tuples if numberTuples is 0
1271+
* Processes the query plan until we have processed 'numberTuples' tuples,
1272+
* moving in the specified direction.
12781273
*
1279-
* result is either a slot containing the last tuple in the case
1280-
* of a SELECT or NULL otherwise.
1274+
* Runs to completion if numberTuples is 0
12811275
*
12821276
* Note: the ctid attribute is a 'junk' attribute that is removed before the
12831277
* user can see it
12841278
* ----------------------------------------------------------------
12851279
*/
1286-
static TupleTableSlot *
1280+
static void
12871281
ExecutePlan(EState *estate,
12881282
PlanState *planstate,
12891283
CmdType operation,
@@ -1297,13 +1291,11 @@ ExecutePlan(EState *estate,
12971291
ItemPointer tupleid = NULL;
12981292
ItemPointerData tuple_ctid;
12991293
long current_tuple_count;
1300-
TupleTableSlot *result;
13011294

13021295
/*
13031296
* initialize local variables
13041297
*/
13051298
current_tuple_count = 0;
1306-
result = NULL;
13071299

13081300
/*
13091301
* Set the direction.
@@ -1332,7 +1324,6 @@ ExecutePlan(EState *estate,
13321324
/*
13331325
* Loop until we've processed the proper number of tuples from the plan.
13341326
*/
1335-
13361327
for (;;)
13371328
{
13381329
/* Reset the per-output-tuple exprcontext */
@@ -1353,13 +1344,10 @@ lnext: ;
13531344

13541345
/*
13551346
* if the tuple is null, then we assume there is nothing more to
1356-
* process so we just return null...
1347+
* process so we just end the loop...
13571348
*/
13581349
if (TupIsNull(planSlot))
1359-
{
1360-
result = NULL;
13611350
break;
1362-
}
13631351
slot = planSlot;
13641352

13651353
/*
@@ -1453,7 +1441,6 @@ lnext: ;
14531441
default:
14541442
elog(ERROR, "unrecognized heap_lock_tuple status: %u",
14551443
test);
1456-
return NULL;
14571444
}
14581445
}
14591446
}
@@ -1488,35 +1475,30 @@ lnext: ;
14881475

14891476
/*
14901477
* now that we have a tuple, do the appropriate thing with it.. either
1491-
* return it to the user, add it to a relation someplace, delete it
1492-
* from a relation, or modify some of its attributes.
1478+
* send it to the output destination, add it to a relation someplace,
1479+
* delete it from a relation, or modify some of its attributes.
14931480
*/
14941481
switch (operation)
14951482
{
14961483
case CMD_SELECT:
14971484
ExecSelect(slot, dest, estate);
1498-
result = slot;
14991485
break;
15001486

15011487
case CMD_INSERT:
15021488
ExecInsert(slot, tupleid, planSlot, dest, estate);
1503-
result = NULL;
15041489
break;
15051490

15061491
case CMD_DELETE:
15071492
ExecDelete(tupleid, planSlot, dest, estate);
1508-
result = NULL;
15091493
break;
15101494

15111495
case CMD_UPDATE:
15121496
ExecUpdate(slot, tupleid, planSlot, dest, estate);
1513-
result = NULL;
15141497
break;
15151498

15161499
default:
15171500
elog(ERROR, "unrecognized operation code: %d",
15181501
(int) operation);
1519-
result = NULL;
15201502
break;
15211503
}
15221504

@@ -1548,12 +1530,6 @@ lnext: ;
15481530
/* do nothing */
15491531
break;
15501532
}
1551-
1552-
/*
1553-
* here, result is either a slot containing a tuple in the case of a
1554-
* SELECT or NULL otherwise.
1555-
*/
1556-
return result;
15571533
}
15581534

15591535
/* ----------------------------------------------------------------

src/backend/executor/functions.c

+18-12
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.127 2008/10/31 19:37:56 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.128 2008/10/31 21:07:55 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -105,8 +105,7 @@ static execution_state *init_execution_state(List *queryTree_list,
105105
bool lazyEvalOK);
106106
static void init_sql_fcache(FmgrInfo *finfo, bool lazyEvalOK);
107107
static void postquel_start(execution_state *es, SQLFunctionCachePtr fcache);
108-
static TupleTableSlot *postquel_getnext(execution_state *es,
109-
SQLFunctionCachePtr fcache);
108+
static bool postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache);
110109
static void postquel_end(execution_state *es);
111110
static void postquel_sub_params(SQLFunctionCachePtr fcache,
112111
FunctionCallInfo fcinfo);
@@ -441,10 +440,11 @@ postquel_start(execution_state *es, SQLFunctionCachePtr fcache)
441440
}
442441

443442
/* Run one execution_state; either to completion or to first result row */
444-
static TupleTableSlot *
443+
/* Returns true if we ran to completion */
444+
static bool
445445
postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache)
446446
{
447-
TupleTableSlot *result;
447+
bool result;
448448

449449
/* Make our snapshot the active one for any called functions */
450450
PushActiveSnapshot(es->qd->snapshot);
@@ -460,14 +460,20 @@ postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache)
460460
false, /* not top level */
461461
es->qd->dest,
462462
NULL);
463-
result = NULL;
463+
result = true; /* never stops early */
464464
}
465465
else
466466
{
467467
/* Run regular commands to completion unless lazyEval */
468468
long count = (es->lazyEval) ? 1L : 0L;
469469

470-
result = ExecutorRun(es->qd, ForwardScanDirection, count);
470+
ExecutorRun(es->qd, ForwardScanDirection, count);
471+
472+
/*
473+
* If we requested run to completion OR there was no tuple returned,
474+
* command must be complete.
475+
*/
476+
result = (count == 0L || es->qd->estate->es_processed == 0);
471477
}
472478

473479
PopActiveSnapshot();
@@ -678,22 +684,22 @@ fmgr_sql(PG_FUNCTION_ARGS)
678684
*/
679685
while (es)
680686
{
681-
TupleTableSlot *slot;
687+
bool completed;
682688

683689
if (es->status == F_EXEC_START)
684690
postquel_start(es, fcache);
685691

686-
slot = postquel_getnext(es, fcache);
692+
completed = postquel_getnext(es, fcache);
687693

688694
/*
689695
* If we ran the command to completion, we can shut it down now.
690696
* Any row(s) we need to return are safely stashed in the tuplestore,
691697
* and we want to be sure that, for example, AFTER triggers get fired
692698
* before we return anything. Also, if the function doesn't return
693-
* set, we can shut it down anyway because we don't care about
694-
* fetching any more result rows.
699+
* set, we can shut it down anyway because it must be a SELECT and
700+
* we don't care about fetching any more result rows.
695701
*/
696-
if (TupIsNull(slot) || !fcache->returnsSet)
702+
if (completed || !fcache->returnsSet)
697703
postquel_end(es);
698704

699705
/*

src/include/executor/executor.h

+8-8
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/executor/executor.h,v 1.151 2008/10/29 00:00:39 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/executor/executor.h,v 1.152 2008/10/31 21:07:55 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -61,9 +61,9 @@
6161

6262

6363
/* Hook for plugins to get control in ExecutorRun() */
64-
typedef TupleTableSlot *(*ExecutorRun_hook_type) (QueryDesc *queryDesc,
65-
ScanDirection direction,
66-
long count);
64+
typedef void (*ExecutorRun_hook_type) (QueryDesc *queryDesc,
65+
ScanDirection direction,
66+
long count);
6767
extern PGDLLIMPORT ExecutorRun_hook_type ExecutorRun_hook;
6868

6969

@@ -140,10 +140,10 @@ extern HeapTuple ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot);
140140
* prototypes from functions in execMain.c
141141
*/
142142
extern void ExecutorStart(QueryDesc *queryDesc, int eflags);
143-
extern TupleTableSlot *ExecutorRun(QueryDesc *queryDesc,
144-
ScanDirection direction, long count);
145-
extern TupleTableSlot *standard_ExecutorRun(QueryDesc *queryDesc,
146-
ScanDirection direction, long count);
143+
extern void ExecutorRun(QueryDesc *queryDesc,
144+
ScanDirection direction, long count);
145+
extern void standard_ExecutorRun(QueryDesc *queryDesc,
146+
ScanDirection direction, long count);
147147
extern void ExecutorEnd(QueryDesc *queryDesc);
148148
extern void ExecutorRewind(QueryDesc *queryDesc);
149149
extern void InitResultRelInfo(ResultRelInfo *resultRelInfo,

0 commit comments

Comments
 (0)