concurrent-update-experiment.patch
text/x-patch
Filename: concurrent-update-experiment.patch
Type: text/x-patch
Part: 0
From 54526773321a525a0e806bf17353537a4bc23fef Mon Sep 17 00:00:00 2001
From: Bernice Southey <bernice.southey@gmail.com>
Date: Wed, 31 Dec 2025 14:26:39 +0000
Subject: [PATCH] concurrent update experiment
---
.../pg_overexplain/expected/pg_overexplain.out | 9 +++++----
src/backend/optimizer/plan/setrefs.c | 5 +++--
src/test/isolation/expected/eval-plan-qual.out | 17 +++++++++++++++++
src/test/isolation/specs/eval-plan-qual.spec | 10 ++++++++++
4 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/contrib/pg_overexplain/expected/pg_overexplain.out b/contrib/pg_overexplain/expected/pg_overexplain.out
index 55d34666d87..45a71af5776 100644
--- a/contrib/pg_overexplain/expected/pg_overexplain.out
+++ b/contrib/pg_overexplain/expected/pg_overexplain.out
@@ -47,7 +47,8 @@ EXPLAIN (RANGE_TABLE) SELECT 1;
RTIs: 1
RTI 1 (result):
Eref: "*RESULT*" ()
-(4 rows)
+ Unprunable RTIs: 1
+(5 rows)
-- Create a partitioned table.
CREATE TABLE vegetables (id serial, name text, genus text)
@@ -141,7 +142,7 @@ $$);
Relation: daucus
Relation Kind: relation
Relation Lock Mode: AccessShareLock
- Unprunable RTIs: 1 3 4
+ Unprunable RTIs: 1 2 3 4
(53 rows)
-- Test a different output format.
@@ -292,7 +293,7 @@ $$);
<Security-Barrier>false</Security-Barrier> +
<Lateral>false</Lateral> +
</Range-Table-Entry> +
- <Unprunable-RTIs>1 3 4</Unprunable-RTIs> +
+ <Unprunable-RTIs>1 2 3 4</Unprunable-RTIs> +
<Result-RTIs>none</Result-RTIs> +
</Range-Table> +
</Query> +
@@ -485,7 +486,7 @@ INSERT INTO vegetables (name, genus) VALUES ('broccoflower', 'brassica');
Permission Info Index: 1
RTI 2 (result):
Eref: "*RESULT*" ()
- Unprunable RTIs: 1
+ Unprunable RTIs: 1 2
Result RTIs: 1
(15 rows)
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index cd7ea1e6b58..4bfcbf4efb5 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -580,12 +580,13 @@ add_rte_to_flat_rtable(PlannerGlobal *glob, List *rteperminfos,
* Note we don't bother to avoid making duplicate list entries. We could,
* but it would probably cost more cycles than it would save.
*/
+ glob->allRelids = bms_add_member(glob->allRelids,
+ list_length(glob->finalrtable));
+
if (newrte->rtekind == RTE_RELATION ||
(newrte->rtekind == RTE_SUBQUERY && OidIsValid(newrte->relid)))
{
glob->relationOids = lappend_oid(glob->relationOids, newrte->relid);
- glob->allRelids = bms_add_member(glob->allRelids,
- list_length(glob->finalrtable));
}
/*
diff --git a/src/test/isolation/expected/eval-plan-qual.out b/src/test/isolation/expected/eval-plan-qual.out
index 05fffe0d570..d182bbe2722 100644
--- a/src/test/isolation/expected/eval-plan-qual.out
+++ b/src/test/isolation/expected/eval-plan-qual.out
@@ -1432,6 +1432,23 @@ a|b|c| d
(2 rows)
+starting permutation: updateforvalues updatevalues c1 c2 read
+step updateforvalues: UPDATE accounts SET balance = balance + 100;
+step updatevalues:
+ set local enable_seqscan to 0;
+ UPDATE accounts SET balance = v.balance FROM (VALUES('checking', 610), ('savings', 620)) v(accountid, balance) WHERE accounts.accountid = v.accountid;
+ <waiting ...>
+step c1: COMMIT;
+step updatevalues: <... completed>
+step c2: COMMIT;
+step read: SELECT * FROM accounts ORDER BY accountid;
+accountid|balance|balance2
+---------+-------+--------
+checking | 610| 1220
+savings | 620| 1240
+(2 rows)
+
+
starting permutation: sys1 sysupd2 c1 c2
step sys1:
UPDATE pg_class SET reltuples = 123 WHERE oid = 'accounts'::regclass;
diff --git a/src/test/isolation/specs/eval-plan-qual.spec b/src/test/isolation/specs/eval-plan-qual.spec
index 80e1e6bb307..4870690ac5b 100644
--- a/src/test/isolation/specs/eval-plan-qual.spec
+++ b/src/test/isolation/specs/eval-plan-qual.spec
@@ -206,6 +206,8 @@ step sys1 {
step s1pp1 { UPDATE another_parttbl SET b = b + 1 WHERE a = 1; }
+step updateforvalues { UPDATE accounts SET balance = balance + 100; }
+
session s2
setup { BEGIN ISOLATION LEVEL READ COMMITTED; }
step wx2 { UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; }
@@ -318,6 +320,11 @@ step s2pp2 { PREPARE epd AS DELETE FROM another_parttbl WHERE a = $1; }
step s2pp3 { EXECUTE epd(1); }
step s2pp4 { DELETE FROM another_parttbl WHERE a = (SELECT 1); }
+step updatevalues {
+ set local enable_seqscan to 0;
+ UPDATE accounts SET balance = v.balance FROM (VALUES('checking', 610), ('savings', 620)) v(accountid, balance) WHERE accounts.accountid = v.accountid;
+}
+
session s3
setup { BEGIN ISOLATION LEVEL READ COMMITTED; }
step read { SELECT * FROM accounts ORDER BY accountid; }
@@ -419,6 +426,9 @@ permutation simplepartupdate_route1to2 complexpartupdate_route_err1 c1 c2 read_p
permutation simplepartupdate_noroute complexpartupdate_route c1 c2 read_part
permutation simplepartupdate_noroute complexpartupdate_doesnt_route c1 c2 read_part
+# test EPQ recheck in UPDATE from VALUES_RTE, cf bug #19355
+permutation updateforvalues updatevalues c1 c2 read
+
permutation sys1 sysupd2 c1 c2
permutation sys1 sysmerge2 c1 c2
--
2.43.0