aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/executor/execMain.c13
-rw-r--r--src/backend/executor/nodeModifyTable.c26
2 files changed, 19 insertions, 20 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 422f737e82d..36dcc8e4b5d 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -2347,11 +2347,7 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
* ExecInitSubPlan expects to be able to find these entries. Some of the
* SubPlans might not be used in the part of the plan tree we intend to
* run, but since it's not easy to tell which, we just initialize them
- * all. (However, if the subplan is headed by a ModifyTable node, then it
- * must be a data-modifying CTE, which we will certainly not need to
- * re-run, so we can skip initializing it. This is just an efficiency
- * hack; it won't skip data-modifying CTEs for which the ModifyTable node
- * is not at the top.)
+ * all.
*/
Assert(estate->es_subplanstates == NIL);
foreach(l, parentestate->es_plannedstmt->subplans)
@@ -2359,12 +2355,7 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
Plan *subplan = (Plan *) lfirst(l);
PlanState *subplanstate;
- /* Don't initialize ModifyTable subplans, per comment above */
- if (IsA(subplan, ModifyTable))
- subplanstate = NULL;
- else
- subplanstate = ExecInitNode(subplan, estate, 0);
-
+ subplanstate = ExecInitNode(subplan, estate, 0);
estate->es_subplanstates = lappend(estate->es_subplanstates,
subplanstate);
}
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index 37b70b88d53..dfdcb20b1d1 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -716,6 +716,18 @@ ExecModifyTable(ModifyTableState *node)
HeapTupleHeader oldtuple = NULL;
/*
+ * This should NOT get called during EvalPlanQual; we should have passed a
+ * subplan tree to EvalPlanQual, instead. Use a runtime test not just
+ * Assert because this condition is easy to miss in testing. (Note:
+ * although ModifyTable should not get executed within an EvalPlanQual
+ * operation, we do have to allow it to be initialized and shut down in
+ * case it is within a CTE subplan. Hence this test must be here, not in
+ * ExecInitModifyTable.)
+ */
+ if (estate->es_epqTuple != NULL)
+ elog(ERROR, "ModifyTable should not be called during EvalPlanQual");
+
+ /*
* If we've already completed processing, don't try to do more. We need
* this test because ExecPostprocessPlan might call us an extra time, and
* our subplan's nodes aren't necessarily robust against being called
@@ -893,14 +905,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
/*
- * This should NOT get called during EvalPlanQual; we should have passed a
- * subplan tree to EvalPlanQual, instead. Use a runtime test not just
- * Assert because this condition is easy to miss in testing ...
- */
- if (estate->es_epqTuple != NULL)
- elog(ERROR, "ModifyTable should not be called during EvalPlanQual");
-
- /*
* create state structure
*/
mtstate = makeNode(ModifyTableState);
@@ -947,9 +951,13 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
* descriptors in the result relation info, so that we can add new
* index entries for the tuples we add/update. We need not do this
* for a DELETE, however, since deletion doesn't affect indexes.
+ * Also, inside an EvalPlanQual operation, the indexes might be open
+ * already, since we share the resultrel state with the original
+ * query.
*/
if (resultRelInfo->ri_RelationDesc->rd_rel->relhasindex &&
- operation != CMD_DELETE)
+ operation != CMD_DELETE &&
+ resultRelInfo->ri_IndexRelationDescs == NULL)
ExecOpenIndices(resultRelInfo);
/* Now init the plan for this result rel */