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

Commit4d20bad

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 parent725d981 commit4d20bad

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
@@ -80,14 +80,12 @@ static void InitPlan(QueryDesc *queryDesc, int eflags);
8080
staticvoidCheckValidRowMarkRel(Relationrel,RowMarkTypemarkType);
8181
staticvoidExecPostprocessPlan(EState*estate);
8282
staticvoidExecEndPlan(PlanState*planstate,EState*estate);
83-
staticvoidExecutePlan(EState*estate,PlanState*planstate,
84-
booluse_parallel_mode,
83+
staticvoidExecutePlan(QueryDesc*queryDesc,
8584
CmdTypeoperation,
8685
boolsendTuples,
8786
uint64numberTuples,
8887
ScanDirectiondirection,
89-
DestReceiver*dest,
90-
boolexecute_once);
88+
DestReceiver*dest);
9189
staticboolExecCheckRTEPerms(RangeTblEntry*rte);
9290
staticboolExecCheckRTEPermsModified(OidrelOid,Oiduserid,
9391
Bitmapset*modifiedCols,
@@ -272,6 +270,9 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
272270
*retrieved tuples, not for instance to those inserted/updated/deleted
273271
*by a ModifyTable plan node.
274272
*
273+
*execute_once is ignored, and is present only to avoid an API break
274+
*in stable branches.
275+
*
275276
*There is no return value, but output tuples (if any) are sent to
276277
*the destination receiver specified in the QueryDesc; and the number
277278
*of tuples processed at the top level can be found in
@@ -342,21 +343,12 @@ standard_ExecutorRun(QueryDesc *queryDesc,
342343
* run plan
343344
*/
344345
if (!ScanDirectionIsNoMovement(direction))
345-
{
346-
if (execute_once&&queryDesc->already_executed)
347-
elog(ERROR,"can't re-execute query flagged for single execution");
348-
queryDesc->already_executed= true;
349-
350-
ExecutePlan(estate,
351-
queryDesc->planstate,
352-
queryDesc->plannedstmt->parallelModeNeeded,
346+
ExecutePlan(queryDesc,
353347
operation,
354348
sendTuples,
355349
count,
356350
direction,
357-
dest,
358-
execute_once);
359-
}
351+
dest);
360352

361353
/*
362354
* shutdown tuple receiver, if we started it
@@ -1578,22 +1570,19 @@ ExecEndPlan(PlanState *planstate, EState *estate)
15781570
*moving in the specified direction.
15791571
*
15801572
*Runs to completion if numberTuples is 0
1581-
*
1582-
* Note: the ctid attribute is a 'junk' attribute that is removed before the
1583-
* user can see it
15841573
* ----------------------------------------------------------------
15851574
*/
15861575
staticvoid
1587-
ExecutePlan(EState*estate,
1588-
PlanState*planstate,
1589-
booluse_parallel_mode,
1576+
ExecutePlan(QueryDesc*queryDesc,
15901577
CmdTypeoperation,
15911578
boolsendTuples,
15921579
uint64numberTuples,
15931580
ScanDirectiondirection,
1594-
DestReceiver*dest,
1595-
boolexecute_once)
1581+
DestReceiver*dest)
15961582
{
1583+
EState*estate=queryDesc->estate;
1584+
PlanState*planstate=queryDesc->planstate;
1585+
booluse_parallel_mode;
15971586
TupleTableSlot*slot;
15981587
uint64current_tuple_count;
15991588

@@ -1608,11 +1597,17 @@ ExecutePlan(EState *estate,
16081597
estate->es_direction=direction;
16091598

16101599
/*
1611-
* If the plan might potentially be executed multiple times, we must force
1612-
* it to run without parallelism, because we might exit early.
1600+
* Set up parallel mode if appropriate.
1601+
*
1602+
* Parallel mode only supports complete execution of a plan. If we've
1603+
* already partially executed it, or if the caller asks us to exit early,
1604+
* we must force the plan to run without parallelism.
16131605
*/
1614-
if (!execute_once)
1606+
if (queryDesc->already_executed||numberTuples!=0)
16151607
use_parallel_mode= false;
1608+
else
1609+
use_parallel_mode=queryDesc->plannedstmt->parallelModeNeeded;
1610+
queryDesc->already_executed= true;
16161611

16171612
estate->es_use_parallel_mode=use_parallel_mode;
16181613
if (use_parallel_mode)

‎src/backend/tcop/postgres.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,7 +1241,7 @@ exec_simple_query(const char *query_string)
12411241
(void)PortalRun(portal,
12421242
FETCH_ALL,
12431243
true,/* always top level */
1244-
true,
1244+
true,/* ignored */
12451245
receiver,
12461246
receiver,
12471247
&qc);
@@ -2188,7 +2188,7 @@ exec_execute_message(const char *portal_name, long max_rows)
21882188
completed=PortalRun(portal,
21892189
max_rows,
21902190
true,/* always top level */
2191-
!execute_is_fetch&&max_rows==FETCH_ALL,
2191+
true,/* ignored */
21922192
receiver,
21932193
receiver,
21942194
&qc);

‎src/backend/tcop/pquery.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,8 @@ PortalSetResultFormat(Portal portal, int nFormats, int16 *formats)
667667
* isTopLevel: true if query is being executed at backend "top level"
668668
* (that is, directly from a client command message)
669669
*
670+
* run_once: ignored, present only to avoid an API break in stable branches.
671+
*
670672
* dest: where to send output of primary (canSetTag) query
671673
*
672674
* altdest: where to send output of non-primary queries
@@ -711,10 +713,6 @@ PortalRun(Portal portal, long count, bool isTopLevel, bool run_once,
711713
*/
712714
MarkPortalActive(portal);
713715

714-
/* Set run_once flag. Shouldn't be clear if previously set. */
715-
Assert(!portal->run_once||run_once);
716-
portal->run_once=run_once;
717-
718716
/*
719717
* Set up global portal context pointers.
720718
*
@@ -919,7 +917,7 @@ PortalRunSelect(Portal portal,
919917
{
920918
PushActiveSnapshot(queryDesc->snapshot);
921919
ExecutorRun(queryDesc,direction, (uint64)count,
922-
portal->run_once);
920+
false);
923921
nprocessed=queryDesc->estate->es_processed;
924922
PopActiveSnapshot();
925923
}
@@ -959,7 +957,7 @@ PortalRunSelect(Portal portal,
959957
{
960958
PushActiveSnapshot(queryDesc->snapshot);
961959
ExecutorRun(queryDesc,direction, (uint64)count,
962-
portal->run_once);
960+
false);
963961
nprocessed=queryDesc->estate->es_processed;
964962
PopActiveSnapshot();
965963
}
@@ -1400,9 +1398,6 @@ PortalRunFetch(Portal portal,
14001398
*/
14011399
MarkPortalActive(portal);
14021400

1403-
/* If supporting FETCH, portal can't be run-once. */
1404-
Assert(!portal->run_once);
1405-
14061401
/*
14071402
* Set up global portal context pointers.
14081403
*/

‎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
@@ -144,7 +144,7 @@ typedef struct PortalData
144144
/* Features/options */
145145
PortalStrategystrategy;/* see above */
146146
intcursorOptions;/* DECLARE CURSOR option bits */
147-
boolrun_once;/*portal will only be run once */
147+
boolrun_once;/*unused */
148148

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp