return NULL;
}
+ /*
+ * There are corner cases where the subplan could change which
+ * tuplestore read pointer is active, so be sure to reselect ours
+ * before storing the tuple we got.
+ */
+ tuplestore_select_read_pointer(tuplestorestate, node->readptr);
+
/*
* Append a copy of the returned tuple to tuplestore. NOTE: because
* our read pointer is certainly in EOF state, its read position will
* we might be asked to rescan the CTE even though upper levels didn't
* tell us to be prepared to do it efficiently. Annoying, since this
* prevents truncation of the tuplestore. XXX FIXME
+ *
+ * Note: if we are in an EPQ recheck plan tree, it's likely that no access
+ * to the tuplestore is needed at all, making this even more annoying.
+ * It's not worth improving that as long as all the read pointers would
+ * have REWIND anyway, but if we ever improve this logic then that aspect
+ * should be considered too.
*/
eflags |= EXEC_FLAG_REWIND;
9 0 9 0
10 0 10 0
step c1: COMMIT;
+
+starting permutation: wrtwcte multireadwcte c1 c2
+step wrtwcte: UPDATE table_a SET value = 'tableAValue2' WHERE id = 1;
+step multireadwcte:
+ WITH updated AS (
+ UPDATE table_a SET value = 'tableAValue3' WHERE id = 1 RETURNING id
+ )
+ SELECT (SELECT id FROM updated) AS subid, * FROM updated;
+ <waiting ...>
+step c1: COMMIT;
+step c2: COMMIT;
+step multireadwcte: <... completed>
+subid id
+
+1 1
SELECT * FROM cte2;
}
+# this test exercises a different CTE misbehavior, cf bug #14870
+step "multireadwcte" {
+ WITH updated AS (
+ UPDATE table_a SET value = 'tableAValue3' WHERE id = 1 RETURNING id
+ )
+ SELECT (SELECT id FROM updated) AS subid, * FROM updated;
+}
+
teardown { COMMIT; }
permutation "wx1" "wx2" "c1" "c2" "read"
permutation "updateforss" "readforss" "c1" "c2"
permutation "wrtwcte" "readwcte" "c1" "c2"
permutation "wrjt" "selectjoinforupdate" "c2" "c1"
+permutation "wrtwcte" "multireadwcte" "c1" "c2"