aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/executor/execMain.c47
-rw-r--r--src/backend/tcop/postgres.c4
-rw-r--r--src/backend/tcop/pquery.c13
-rw-r--r--src/include/executor/execdesc.h2
-rw-r--r--src/include/utils/portal.h2
5 files changed, 29 insertions, 39 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 150d369d055..85d3f05f2b6 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -82,14 +82,12 @@ static void InitPlan(QueryDesc *queryDesc, int eflags);
static void CheckValidRowMarkRel(Relation rel, RowMarkType markType);
static void ExecPostprocessPlan(EState *estate);
static void ExecEndPlan(PlanState *planstate, EState *estate);
-static void ExecutePlan(EState *estate, PlanState *planstate,
- bool use_parallel_mode,
+static void ExecutePlan(QueryDesc *queryDesc,
CmdType operation,
bool sendTuples,
uint64 numberTuples,
ScanDirection direction,
- DestReceiver *dest,
- bool execute_once);
+ DestReceiver *dest);
static bool ExecCheckRTEPerms(RangeTblEntry *rte);
static bool ExecCheckRTEPermsModified(Oid relOid, Oid userid,
Bitmapset *modifiedCols,
@@ -286,6 +284,9 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
* retrieved tuples, not for instance to those inserted/updated/deleted
* by a ModifyTable plan node.
*
+ * execute_once is ignored, and is present only to avoid an API break
+ * in stable branches.
+ *
* There is no return value, but output tuples (if any) are sent to
* the destination receiver specified in the QueryDesc; and the number
* of tuples processed at the top level can be found in
@@ -356,21 +357,12 @@ standard_ExecutorRun(QueryDesc *queryDesc,
* run plan
*/
if (!ScanDirectionIsNoMovement(direction))
- {
- if (execute_once && queryDesc->already_executed)
- elog(ERROR, "can't re-execute query flagged for single execution");
- queryDesc->already_executed = true;
-
- ExecutePlan(estate,
- queryDesc->planstate,
- queryDesc->plannedstmt->parallelModeNeeded,
+ ExecutePlan(queryDesc,
operation,
sendTuples,
count,
direction,
- dest,
- execute_once);
- }
+ dest);
/*
* shutdown tuple receiver, if we started it
@@ -1506,22 +1498,19 @@ ExecCloseRangeTableRelations(EState *estate)
* moving in the specified direction.
*
* Runs to completion if numberTuples is 0
- *
- * Note: the ctid attribute is a 'junk' attribute that is removed before the
- * user can see it
* ----------------------------------------------------------------
*/
static void
-ExecutePlan(EState *estate,
- PlanState *planstate,
- bool use_parallel_mode,
+ExecutePlan(QueryDesc *queryDesc,
CmdType operation,
bool sendTuples,
uint64 numberTuples,
ScanDirection direction,
- DestReceiver *dest,
- bool execute_once)
+ DestReceiver *dest)
{
+ EState *estate = queryDesc->estate;
+ PlanState *planstate = queryDesc->planstate;
+ bool use_parallel_mode;
TupleTableSlot *slot;
uint64 current_tuple_count;
@@ -1536,11 +1525,17 @@ ExecutePlan(EState *estate,
estate->es_direction = direction;
/*
- * If the plan might potentially be executed multiple times, we must force
- * it to run without parallelism, because we might exit early.
+ * Set up parallel mode if appropriate.
+ *
+ * Parallel mode only supports complete execution of a plan. If we've
+ * already partially executed it, or if the caller asks us to exit early,
+ * we must force the plan to run without parallelism.
*/
- if (!execute_once)
+ if (queryDesc->already_executed || numberTuples != 0)
use_parallel_mode = false;
+ else
+ use_parallel_mode = queryDesc->plannedstmt->parallelModeNeeded;
+ queryDesc->already_executed = true;
estate->es_use_parallel_mode = use_parallel_mode;
if (use_parallel_mode)
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 5d699f7ff7c..52e6cb638eb 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -1217,7 +1217,7 @@ exec_simple_query(const char *query_string)
(void) PortalRun(portal,
FETCH_ALL,
true, /* always top level */
- true,
+ true, /* ignored */
receiver,
receiver,
&qc);
@@ -2215,7 +2215,7 @@ exec_execute_message(const char *portal_name, long max_rows)
completed = PortalRun(portal,
max_rows,
true, /* always top level */
- !execute_is_fetch && max_rows == FETCH_ALL,
+ true, /* ignored */
receiver,
receiver,
&qc);
diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c
index 61e18926a5b..500620a22e4 100644
--- a/src/backend/tcop/pquery.c
+++ b/src/backend/tcop/pquery.c
@@ -667,6 +667,8 @@ PortalSetResultFormat(Portal portal, int nFormats, int16 *formats)
* isTopLevel: true if query is being executed at backend "top level"
* (that is, directly from a client command message)
*
+ * run_once: ignored, present only to avoid an API break in stable branches.
+ *
* dest: where to send output of primary (canSetTag) query
*
* altdest: where to send output of non-primary queries
@@ -711,10 +713,6 @@ PortalRun(Portal portal, long count, bool isTopLevel, bool run_once,
*/
MarkPortalActive(portal);
- /* Set run_once flag. Shouldn't be clear if previously set. */
- Assert(!portal->run_once || run_once);
- portal->run_once = run_once;
-
/*
* Set up global portal context pointers.
*
@@ -919,7 +917,7 @@ PortalRunSelect(Portal portal,
{
PushActiveSnapshot(queryDesc->snapshot);
ExecutorRun(queryDesc, direction, (uint64) count,
- portal->run_once);
+ false);
nprocessed = queryDesc->estate->es_processed;
PopActiveSnapshot();
}
@@ -959,7 +957,7 @@ PortalRunSelect(Portal portal,
{
PushActiveSnapshot(queryDesc->snapshot);
ExecutorRun(queryDesc, direction, (uint64) count,
- portal->run_once);
+ false);
nprocessed = queryDesc->estate->es_processed;
PopActiveSnapshot();
}
@@ -1403,9 +1401,6 @@ PortalRunFetch(Portal portal,
*/
MarkPortalActive(portal);
- /* If supporting FETCH, portal can't be run-once. */
- Assert(!portal->run_once);
-
/*
* Set up global portal context pointers.
*/
diff --git a/src/include/executor/execdesc.h b/src/include/executor/execdesc.h
index 017ad871175..5d91f97ef79 100644
--- a/src/include/executor/execdesc.h
+++ b/src/include/executor/execdesc.h
@@ -48,7 +48,7 @@ typedef struct QueryDesc
EState *estate; /* executor's query-wide state */
PlanState *planstate; /* tree of per-plan-node state */
- /* This field is set by ExecutorRun */
+ /* This field is set by ExecutePlan */
bool already_executed; /* true if previously executed */
/* This is always set NULL by the core system, but plugins can change it */
diff --git a/src/include/utils/portal.h b/src/include/utils/portal.h
index 5516084afaa..77e0dc84f91 100644
--- a/src/include/utils/portal.h
+++ b/src/include/utils/portal.h
@@ -144,7 +144,7 @@ typedef struct PortalData
/* Features/options */
PortalStrategy strategy; /* see above */
int cursorOptions; /* DECLARE CURSOR option bits */
- bool run_once; /* portal will only be run once */
+ bool run_once; /* unused */
/* Status data */
PortalStatus status; /* see above */