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

Commit556f7b7

Browse files
committed
Simplify executor's determination of whether to use parallelism.
Our parallel-mode code only works when we are executing a queryin full, so ExecutePlan must disable parallel mode when it isasked to do partial execution. The previous logic for thisinvolved passing down a flag (variously named execute_once orrun_once) from callers of ExecutorRun or PortalRun. This isovercomplicated, and unsurprisingly some of the callers didn'tget it right, since it requires keeping state that not all ofthem have handy; not to mention that the requirements for it wereundocumented. That led to assertion failures in some cornercases. The only state we really need for this is the existingQueryDesc.already_executed flag, so let's just put all theresponsibility in ExecutePlan. (It could have been done inExecutorRun too, leading to a slightly shorter patch -- but ifthere's ever more than one caller of ExecutePlan, it seems betterto have this logic in the subroutine than the callers.)This makes those ExecutorRun/PortalRun parameters unnecessary.In master it seems okay to just remove them, returning theAPI for those functions to what it was before parallelism.Such an API break is clearly not okay in stable branches,but for them we can just leave the parameters in place afterdocumenting that they do nothing.Per report from Yugo Nagata, who also reviewed and testedthis patch. Back-patch to all supported branches.Discussion:https://postgr.es/m/20241206062549.710dc01cf91224809dd6c0e1@sraoss.co.jp
1 parentbb93b33 commit556f7b7

File tree

5 files changed

+29
-39
lines changed

5 files changed

+29
-39
lines changed

‎src/backend/executor/execMain.c

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,12 @@ static void InitPlan(QueryDesc *queryDesc, int eflags);
7575
staticvoidCheckValidRowMarkRel(Relationrel,RowMarkTypemarkType);
7676
staticvoidExecPostprocessPlan(EState*estate);
7777
staticvoidExecEndPlan(PlanState*planstate,EState*estate);
78-
staticvoidExecutePlan(EState*estate,PlanState*planstate,
79-
booluse_parallel_mode,
78+
staticvoidExecutePlan(QueryDesc*queryDesc,
8079
CmdTypeoperation,
8180
boolsendTuples,
8281
uint64numberTuples,
8382
ScanDirectiondirection,
84-
DestReceiver*dest,
85-
boolexecute_once);
83+
DestReceiver*dest);
8684
staticboolExecCheckOneRelPerms(RTEPermissionInfo*perminfo);
8785
staticboolExecCheckPermissionsModified(OidrelOid,Oiduserid,
8886
Bitmapset*modifiedCols,
@@ -283,6 +281,9 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
283281
*retrieved tuples, not for instance to those inserted/updated/deleted
284282
*by a ModifyTable plan node.
285283
*
284+
*execute_once is ignored, and is present only to avoid an API break
285+
*in stable branches.
286+
*
286287
*There is no return value, but output tuples (if any) are sent to
287288
*the destination receiver specified in the QueryDesc; and the number
288289
*of tuples processed at the top level can be found in
@@ -357,21 +358,12 @@ standard_ExecutorRun(QueryDesc *queryDesc,
357358
* run plan
358359
*/
359360
if (!ScanDirectionIsNoMovement(direction))
360-
{
361-
if (execute_once&&queryDesc->already_executed)
362-
elog(ERROR,"can't re-execute query flagged for single execution");
363-
queryDesc->already_executed= true;
364-
365-
ExecutePlan(estate,
366-
queryDesc->planstate,
367-
queryDesc->plannedstmt->parallelModeNeeded,
361+
ExecutePlan(queryDesc,
368362
operation,
369363
sendTuples,
370364
count,
371365
direction,
372-
dest,
373-
execute_once);
374-
}
366+
dest);
375367

376368
/*
377369
* Update es_total_processed to keep track of the number of tuples
@@ -1600,22 +1592,19 @@ ExecCloseRangeTableRelations(EState *estate)
16001592
*moving in the specified direction.
16011593
*
16021594
*Runs to completion if numberTuples is 0
1603-
*
1604-
* Note: the ctid attribute is a 'junk' attribute that is removed before the
1605-
* user can see it
16061595
* ----------------------------------------------------------------
16071596
*/
16081597
staticvoid
1609-
ExecutePlan(EState*estate,
1610-
PlanState*planstate,
1611-
booluse_parallel_mode,
1598+
ExecutePlan(QueryDesc*queryDesc,
16121599
CmdTypeoperation,
16131600
boolsendTuples,
16141601
uint64numberTuples,
16151602
ScanDirectiondirection,
1616-
DestReceiver*dest,
1617-
boolexecute_once)
1603+
DestReceiver*dest)
16181604
{
1605+
EState*estate=queryDesc->estate;
1606+
PlanState*planstate=queryDesc->planstate;
1607+
booluse_parallel_mode;
16191608
TupleTableSlot*slot;
16201609
uint64current_tuple_count;
16211610

@@ -1630,11 +1619,17 @@ ExecutePlan(EState *estate,
16301619
estate->es_direction=direction;
16311620

16321621
/*
1633-
* If the plan might potentially be executed multiple times, we must force
1634-
* it to run without parallelism, because we might exit early.
1622+
* Set up parallel mode if appropriate.
1623+
*
1624+
* Parallel mode only supports complete execution of a plan. If we've
1625+
* already partially executed it, or if the caller asks us to exit early,
1626+
* we must force the plan to run without parallelism.
16351627
*/
1636-
if (!execute_once)
1628+
if (queryDesc->already_executed||numberTuples!=0)
16371629
use_parallel_mode= false;
1630+
else
1631+
use_parallel_mode=queryDesc->plannedstmt->parallelModeNeeded;
1632+
queryDesc->already_executed= true;
16381633

16391634
estate->es_use_parallel_mode=use_parallel_mode;
16401635
if (use_parallel_mode)

‎src/backend/tcop/postgres.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,7 +1278,7 @@ exec_simple_query(const char *query_string)
12781278
(void)PortalRun(portal,
12791279
FETCH_ALL,
12801280
true,/* always top level */
1281-
true,
1281+
true,/* ignored */
12821282
receiver,
12831283
receiver,
12841284
&qc);
@@ -2255,7 +2255,7 @@ exec_execute_message(const char *portal_name, long max_rows)
22552255
completed=PortalRun(portal,
22562256
max_rows,
22572257
true,/* always top level */
2258-
!execute_is_fetch&&max_rows==FETCH_ALL,
2258+
true,/* ignored */
22592259
receiver,
22602260
receiver,
22612261
&qc);

‎src/backend/tcop/pquery.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,8 @@ PortalSetResultFormat(Portal portal, int nFormats, int16 *formats)
670670
* isTopLevel: true if query is being executed at backend "top level"
671671
* (that is, directly from a client command message)
672672
*
673+
* run_once: ignored, present only to avoid an API break in stable branches.
674+
*
673675
* dest: where to send output of primary (canSetTag) query
674676
*
675677
* altdest: where to send output of non-primary queries
@@ -714,10 +716,6 @@ PortalRun(Portal portal, long count, bool isTopLevel, bool run_once,
714716
*/
715717
MarkPortalActive(portal);
716718

717-
/* Set run_once flag. Shouldn't be clear if previously set. */
718-
Assert(!portal->run_once||run_once);
719-
portal->run_once=run_once;
720-
721719
/*
722720
* Set up global portal context pointers.
723721
*
@@ -922,7 +920,7 @@ PortalRunSelect(Portal portal,
922920
{
923921
PushActiveSnapshot(queryDesc->snapshot);
924922
ExecutorRun(queryDesc,direction, (uint64)count,
925-
portal->run_once);
923+
false);
926924
nprocessed=queryDesc->estate->es_processed;
927925
PopActiveSnapshot();
928926
}
@@ -962,7 +960,7 @@ PortalRunSelect(Portal portal,
962960
{
963961
PushActiveSnapshot(queryDesc->snapshot);
964962
ExecutorRun(queryDesc,direction, (uint64)count,
965-
portal->run_once);
963+
false);
966964
nprocessed=queryDesc->estate->es_processed;
967965
PopActiveSnapshot();
968966
}
@@ -1406,9 +1404,6 @@ PortalRunFetch(Portal portal,
14061404
*/
14071405
MarkPortalActive(portal);
14081406

1409-
/* If supporting FETCH, portal can't be run-once. */
1410-
Assert(!portal->run_once);
1411-
14121407
/*
14131408
* Set up global portal context pointers.
14141409
*/

‎src/include/executor/execdesc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ typedef struct QueryDesc
4848
EState*estate;/* executor's query-wide state */
4949
PlanState*planstate;/* tree of per-plan-node state */
5050

51-
/* This field is set byExecutorRun */
51+
/* This field is set byExecutePlan */
5252
boolalready_executed;/* true if previously executed */
5353

5454
/* This is always set NULL by the core system, but plugins can change it */

‎src/include/utils/portal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ typedef struct PortalData
145145
/* Features/options */
146146
PortalStrategystrategy;/* see above */
147147
intcursorOptions;/* DECLARE CURSOR option bits */
148-
boolrun_once;/*portal will only be run once */
148+
boolrun_once;/*unused */
149149

150150
/* Status data */
151151
PortalStatusstatus;/* see above */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp