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

Commit691b8d5

Browse files
committed
Allow for parallel execution whenever ExecutorRun() is done only once.
Previously, it was unsafe to execute a plan in parallel ifExecutorRun() might be called with a non-zero row count. However,it's quite easy to fix things up so that we can support that case,provided that it is known that we will never call ExecutorRun() asecond time for the same QueryDesc. Add infrastructure to signalthis, and cross-checks to make sure that a caller who claims this istrue doesn't later reneg.While that pattern never happens with queries received directly from aclient -- there's no way to know whether multiple Execute messageswill be sent unless the first one requests all the rows -- it's prettycommon for queries originating from procedural languages, which oftenlimit the result to a single tuple or to a user-specified number oftuples.This commit doesn't actually enable parallelism in any additionalcases, because currently none of the places that would be able tobenefit from this infrastructure pass CURSOR_OPT_PARALLEL_OK in thefirst place, but it makes it much more palatable to passCURSOR_OPT_PARALLEL_OK in places where we currently don't, because iteliminates some cases where we'd end up having to run the parallelplan serially.Patch by me, based on some ideas from Rafia Sabih and corrected byRafia Sabih based on feedback from Dilip Kumar and myself.Discussion:http://postgr.es/m/CA+TgmobXEhvHbJtWDuPZM9bVSLiTj-kShxQJ2uM5GPDze9fRYA@mail.gmail.com
1 parent218f515 commit691b8d5

File tree

19 files changed

+73
-38
lines changed

19 files changed

+73
-38
lines changed

‎contrib/auto_explain/auto_explain.c‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ void_PG_fini(void);
6161
staticvoidexplain_ExecutorStart(QueryDesc*queryDesc,inteflags);
6262
staticvoidexplain_ExecutorRun(QueryDesc*queryDesc,
6363
ScanDirectiondirection,
64-
uint64count);
64+
uint64count,boolexecute_once);
6565
staticvoidexplain_ExecutorFinish(QueryDesc*queryDesc);
6666
staticvoidexplain_ExecutorEnd(QueryDesc*queryDesc);
6767

@@ -257,15 +257,16 @@ explain_ExecutorStart(QueryDesc *queryDesc, int eflags)
257257
* ExecutorRun hook: all we need do is track nesting depth
258258
*/
259259
staticvoid
260-
explain_ExecutorRun(QueryDesc*queryDesc,ScanDirectiondirection,uint64count)
260+
explain_ExecutorRun(QueryDesc*queryDesc,ScanDirectiondirection,
261+
uint64count,boolexecute_once)
261262
{
262263
nesting_level++;
263264
PG_TRY();
264265
{
265266
if (prev_ExecutorRun)
266-
prev_ExecutorRun(queryDesc,direction,count);
267+
prev_ExecutorRun(queryDesc,direction,count,execute_once);
267268
else
268-
standard_ExecutorRun(queryDesc,direction,count);
269+
standard_ExecutorRun(queryDesc,direction,count,execute_once);
269270
nesting_level--;
270271
}
271272
PG_CATCH();

‎contrib/pg_stat_statements/pg_stat_statements.c‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ static void pgss_post_parse_analyze(ParseState *pstate, Query *query);
290290
staticvoidpgss_ExecutorStart(QueryDesc*queryDesc,inteflags);
291291
staticvoidpgss_ExecutorRun(QueryDesc*queryDesc,
292292
ScanDirectiondirection,
293-
uint64count);
293+
uint64count,boolexecute_once);
294294
staticvoidpgss_ExecutorFinish(QueryDesc*queryDesc);
295295
staticvoidpgss_ExecutorEnd(QueryDesc*queryDesc);
296296
staticvoidpgss_ProcessUtility(PlannedStmt*pstmt,constchar*queryString,
@@ -871,15 +871,16 @@ pgss_ExecutorStart(QueryDesc *queryDesc, int eflags)
871871
* ExecutorRun hook: all we need do is track nesting depth
872872
*/
873873
staticvoid
874-
pgss_ExecutorRun(QueryDesc*queryDesc,ScanDirectiondirection,uint64count)
874+
pgss_ExecutorRun(QueryDesc*queryDesc,ScanDirectiondirection,uint64count,
875+
boolexecute_once)
875876
{
876877
nested_level++;
877878
PG_TRY();
878879
{
879880
if (prev_ExecutorRun)
880-
prev_ExecutorRun(queryDesc,direction,count);
881+
prev_ExecutorRun(queryDesc,direction,count,execute_once);
881882
else
882-
standard_ExecutorRun(queryDesc,direction,count);
883+
standard_ExecutorRun(queryDesc,direction,count,execute_once);
883884
nested_level--;
884885
}
885886
PG_CATCH();

‎src/backend/commands/copy.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2074,7 +2074,7 @@ CopyTo(CopyState cstate)
20742074
else
20752075
{
20762076
/* run the plan --- the dest receiver will send tuples */
2077-
ExecutorRun(cstate->queryDesc,ForwardScanDirection,0L);
2077+
ExecutorRun(cstate->queryDesc,ForwardScanDirection,0L, true);
20782078
processed= ((DR_copy*)cstate->queryDesc->dest)->processed;
20792079
}
20802080

‎src/backend/commands/createas.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString,
347347
ExecutorStart(queryDesc,GetIntoRelEFlags(into));
348348

349349
/* run the plan to completion */
350-
ExecutorRun(queryDesc,ForwardScanDirection,0L);
350+
ExecutorRun(queryDesc,ForwardScanDirection,0L, true);
351351

352352
/* save the rowcount if we're given a completionTag to fill */
353353
if (completionTag)

‎src/backend/commands/explain.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es,
530530
dir=ForwardScanDirection;
531531

532532
/* run the plan */
533-
ExecutorRun(queryDesc,dir,0L);
533+
ExecutorRun(queryDesc,dir,0L, true);
534534

535535
/* run cleanup too */
536536
ExecutorFinish(queryDesc);

‎src/backend/commands/extension.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ execute_sql_string(const char *sql, const char *filename)
742742
dest,NULL,0);
743743

744744
ExecutorStart(qdesc,0);
745-
ExecutorRun(qdesc,ForwardScanDirection,0);
745+
ExecutorRun(qdesc,ForwardScanDirection,0, true);
746746
ExecutorFinish(qdesc);
747747
ExecutorEnd(qdesc);
748748

‎src/backend/commands/matview.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ refresh_matview_datafill(DestReceiver *dest, Query *query,
424424
ExecutorStart(queryDesc,EXEC_FLAG_WITHOUT_OIDS);
425425

426426
/* run the plan */
427-
ExecutorRun(queryDesc,ForwardScanDirection,0L);
427+
ExecutorRun(queryDesc,ForwardScanDirection,0L, true);
428428

429429
processed=queryDesc->estate->es_processed;
430430

‎src/backend/commands/portalcmds.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ PersistHoldablePortal(Portal portal)
395395
true);
396396

397397
/* Fetch the result set into the tuplestore */
398-
ExecutorRun(queryDesc,ForwardScanDirection,0L);
398+
ExecutorRun(queryDesc,ForwardScanDirection,0L, false);
399399

400400
(*queryDesc->dest->rDestroy) (queryDesc->dest);
401401
queryDesc->dest=NULL;

‎src/backend/commands/prepare.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ ExecuteQuery(ExecuteStmt *stmt, IntoClause *intoClause,
301301
*/
302302
PortalStart(portal,paramLI,eflags,GetActiveSnapshot());
303303

304-
(void)PortalRun(portal,count, false,dest,dest,completionTag);
304+
(void)PortalRun(portal,count, false,true,dest,dest,completionTag);
305305

306306
PortalDrop(portal, false);
307307

‎src/backend/executor/execMain.c‎

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ static void ExecutePlan(EState *estate, PlanState *planstate,
8585
boolsendTuples,
8686
uint64numberTuples,
8787
ScanDirectiondirection,
88-
DestReceiver*dest);
88+
DestReceiver*dest,
89+
boolexecute_once);
8990
staticboolExecCheckRTEPerms(RangeTblEntry*rte);
9091
staticboolExecCheckRTEPermsModified(OidrelOid,Oiduserid,
9192
Bitmapset*modifiedCols,
@@ -288,17 +289,18 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
288289
*/
289290
void
290291
ExecutorRun(QueryDesc*queryDesc,
291-
ScanDirectiondirection,uint64count)
292+
ScanDirectiondirection,uint64count,
293+
boolexecute_once)
292294
{
293295
if (ExecutorRun_hook)
294-
(*ExecutorRun_hook) (queryDesc,direction,count);
296+
(*ExecutorRun_hook) (queryDesc,direction,count,execute_once);
295297
else
296-
standard_ExecutorRun(queryDesc,direction,count);
298+
standard_ExecutorRun(queryDesc,direction,count,execute_once);
297299
}
298300

299301
void
300302
standard_ExecutorRun(QueryDesc*queryDesc,
301-
ScanDirectiondirection,uint64count)
303+
ScanDirectiondirection,uint64count,boolexecute_once)
302304
{
303305
EState*estate;
304306
CmdTypeoperation;
@@ -345,14 +347,21 @@ standard_ExecutorRun(QueryDesc *queryDesc,
345347
* run plan
346348
*/
347349
if (!ScanDirectionIsNoMovement(direction))
350+
{
351+
if (execute_once&&queryDesc->already_executed)
352+
elog(ERROR,"can't re-execute query flagged for single execution");
353+
queryDesc->already_executed= true;
354+
348355
ExecutePlan(estate,
349356
queryDesc->planstate,
350357
queryDesc->plannedstmt->parallelModeNeeded,
351358
operation,
352359
sendTuples,
353360
count,
354361
direction,
355-
dest);
362+
dest,
363+
execute_once);
364+
}
356365

357366
/*
358367
* shutdown tuple receiver, if we started it
@@ -1595,7 +1604,8 @@ ExecutePlan(EState *estate,
15951604
boolsendTuples,
15961605
uint64numberTuples,
15971606
ScanDirectiondirection,
1598-
DestReceiver*dest)
1607+
DestReceiver*dest,
1608+
boolexecute_once)
15991609
{
16001610
TupleTableSlot*slot;
16011611
uint64current_tuple_count;
@@ -1611,12 +1621,12 @@ ExecutePlan(EState *estate,
16111621
estate->es_direction=direction;
16121622

16131623
/*
1614-
* Ifa tuple count was supplied, we must force the plan to run without
1615-
* parallelism, because we might exit early. Also disable parallelism
1616-
* when writing into a relation, because no database changes are allowed
1617-
* in parallel mode.
1624+
* Ifthe plan might potentially be executed multiple times, we must force
1625+
*it to run withoutparallelism, because we might exit early. Also
1626+
*disable parallelismwhen writing into a relation, because no database
1627+
*changes are allowedin parallel mode.
16181628
*/
1619-
if (numberTuples||dest->mydest==DestIntoRel)
1629+
if (!execute_once||dest->mydest==DestIntoRel)
16201630
use_parallel_mode= false;
16211631

16221632
if (use_parallel_mode)
@@ -1687,7 +1697,11 @@ ExecutePlan(EState *estate,
16871697
*/
16881698
current_tuple_count++;
16891699
if (numberTuples&&numberTuples==current_tuple_count)
1700+
{
1701+
/* Allow nodes to release or shut down resources. */
1702+
(void)ExecShutdownNode(planstate);
16901703
break;
1704+
}
16911705
}
16921706

16931707
if (use_parallel_mode)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp