subplanstate);
}
- /*
- * These arrays are reused across different plans set with
- * EvalPlanQualSetPlan(), which is safe because they all use the same
- * parent EState. Therefore we can reuse if already allocated.
- */
- if (epqstate->relsubs_rowmark == NULL)
- {
- Assert(epqstate->relsubs_done == NULL);
- epqstate->relsubs_rowmark = (ExecAuxRowMark **)
- palloc0(rtsize * sizeof(ExecAuxRowMark *));
- epqstate->relsubs_done = (bool *)
- palloc0(rtsize * sizeof(bool));
- }
- else
- {
- Assert(epqstate->relsubs_done != NULL);
- memset(epqstate->relsubs_rowmark, 0,
- rtsize * sizeof(ExecAuxRowMark *));
- memset(epqstate->relsubs_done, 0,
- rtsize * sizeof(bool));
- }
-
/*
* Build an RTI indexed array of rowmarks, so that
* EvalPlanQualFetchRowMark() can efficiently access the to be fetched
* rowmark.
*/
+ epqstate->relsubs_rowmark = (ExecAuxRowMark **)
+ palloc0(rtsize * sizeof(ExecAuxRowMark *));
foreach(l, epqstate->arowMarks)
{
ExecAuxRowMark *earm = (ExecAuxRowMark *) lfirst(l);
epqstate->relsubs_rowmark[earm->rowmark->rti - 1] = earm;
}
+ /*
+ * Initialize per-relation EPQ tuple states to not-fetched.
+ */
+ epqstate->relsubs_done = (bool *)
+ palloc0(rtsize * sizeof(bool));
+
/*
* Initialize the private state information for all the nodes in the part
* of the plan tree we need to run. This opens files, allocates storage
FreeExecutorState(estate);
/* Mark EPQState idle */
+ epqstate->origslot = NULL;
epqstate->recheckestate = NULL;
epqstate->recheckplanstate = NULL;
- epqstate->origslot = NULL;
+ epqstate->relsubs_rowmark = NULL;
+ epqstate->relsubs_done = NULL;
}
# readp1/writep1/readp2 tests a bug where nodeLockRows did the wrong thing
# when the first updated tuple was in a non-first child table.
# writep2/returningp1 tests a memory allocation issue
+# writep3a/writep3b tests updates touching more than one table
step "readp1" { SELECT tableoid::regclass, ctid, * FROM p WHERE b IN (0, 1) AND c = 0 FOR UPDATE; }
step "writep1" { UPDATE p SET b = -1 WHERE a = 1 AND b = 1 AND c = 0; }
step "writep2" { UPDATE p SET b = -b WHERE a = 1 AND c = 0; }
+step "writep3a" { UPDATE p SET b = -b WHERE c = 0; }
step "c1" { COMMIT; }
step "r1" { ROLLBACK; }
WITH u AS ( UPDATE p SET b = b WHERE a > 0 RETURNING * )
SELECT * FROM u;
}
+step "writep3b" { UPDATE p SET b = -b WHERE c = 0; }
step "readforss" {
SELECT ta.id AS ta_id, ta.value AS ta_value,
(SELECT ROW(tb.id, tb.value)
permutation "upsert1" "upsert2" "c1" "c2" "read"
permutation "readp1" "writep1" "readp2" "c1" "c2"
permutation "writep2" "returningp1" "c1" "c2"
+permutation "writep3a" "writep3b" "c1" "c2"
permutation "wx2" "partiallock" "c2" "c1" "read"
permutation "wx2" "lockwithvalues" "c2" "c1" "read"
permutation "wx2_ext" "partiallock_ext" "c2" "c1" "read_ext"