From a2418f9e238794fcaaf00bbd5b8f953ca2856aa0 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 9 Apr 2019 11:42:53 -0400 Subject: [PATCH] Test some more cases with partitioned tables in EvalPlanQual. We weren't testing anything involving EPQ on UPDATEs that move tuples into different partitions. Depending on the implementation, it might be that these cases aren't actually very interesting ... but given our thin coverage of EPQ in general, I think it's a good idea to have a test case. Amit Langote, minor tweak by me Discussion: https://postgr.es/m/7889df35-ad1a-691a-00e3-4d4b18f364e3@lab.ntt.co.jp --- .../isolation/expected/eval-plan-qual.out | 52 +++++++++++++++++++ src/test/isolation/specs/eval-plan-qual.spec | 39 +++++++++++++- 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/src/test/isolation/expected/eval-plan-qual.out b/src/test/isolation/expected/eval-plan-qual.out index 703f410068..5bf6ec1c27 100644 --- a/src/test/isolation/expected/eval-plan-qual.out +++ b/src/test/isolation/expected/eval-plan-qual.out @@ -641,3 +641,55 @@ step complexpartupdate: step c1: COMMIT; step complexpartupdate: <... completed> step c2: COMMIT; + +starting permutation: simplepartupdate_route1to2 complexpartupdate_route_err1 c1 c2 +step simplepartupdate_route1to2: + update parttbl set a = 2 where c = 1 returning *; + +a b c + +2 1 1 +step complexpartupdate_route_err1: + with u as (update another_parttbl set a = 1 returning another_parttbl.*) + update parttbl p set a = u.a from u where p.a = u.a and p.c = 1 returning p.*; + +step c1: COMMIT; +step complexpartupdate_route_err1: <... completed> +error in steps c1 complexpartupdate_route_err1: ERROR: tuple to be locked was already moved to another partition due to concurrent update +step c2: COMMIT; + +starting permutation: simplepartupdate_noroute complexpartupdate_route c1 c2 +step simplepartupdate_noroute: + update parttbl set b = 2 where c = 1 returning *; + +a b c + +1 2 1 +step complexpartupdate_route: + with u as (update another_parttbl set a = 1 returning another_parttbl.*) + update parttbl p set a = p.b from u where p.a = u.a and p.c = 1 returning p.*; + +step c1: COMMIT; +step complexpartupdate_route: <... completed> +a b c + +2 2 1 +step c2: COMMIT; + +starting permutation: simplepartupdate_noroute complexpartupdate_doesnt_route c1 c2 +step simplepartupdate_noroute: + update parttbl set b = 2 where c = 1 returning *; + +a b c + +1 2 1 +step complexpartupdate_doesnt_route: + with u as (update another_parttbl set a = 1 returning another_parttbl.*) + update parttbl p set a = 3 - p.b from u where p.a = u.a and p.c = 1 returning p.*; + +step c1: COMMIT; +step complexpartupdate_doesnt_route: <... completed> +a b c + +1 2 1 +step c2: COMMIT; diff --git a/src/test/isolation/specs/eval-plan-qual.spec b/src/test/isolation/specs/eval-plan-qual.spec index 4744f558b0..f35a64ef63 100644 --- a/src/test/isolation/specs/eval-plan-qual.spec +++ b/src/test/isolation/specs/eval-plan-qual.spec @@ -33,9 +33,15 @@ setup CREATE TABLE jointest AS SELECT generate_series(1,10) AS id, 0 AS data; CREATE INDEX ON jointest(id); - CREATE TABLE parttbl (a int) PARTITION BY LIST (a); + CREATE TABLE parttbl (a int, b int, c int) PARTITION BY LIST (a); CREATE TABLE parttbl1 PARTITION OF parttbl FOR VALUES IN (1); - INSERT INTO parttbl VALUES (1); + CREATE TABLE parttbl2 PARTITION OF parttbl FOR VALUES IN (2); + INSERT INTO parttbl VALUES (1, 1, 1); + + CREATE TABLE another_parttbl (a int, b int, c int) PARTITION BY LIST (a); + CREATE TABLE another_parttbl1 PARTITION OF another_parttbl FOR VALUES IN (1); + CREATE TABLE another_parttbl2 PARTITION OF another_parttbl FOR VALUES IN (2); + INSERT INTO another_parttbl VALUES (1, 1, 1); } teardown @@ -46,6 +52,7 @@ teardown DROP TABLE p CASCADE; DROP TABLE table_a, table_b, jointest; DROP TABLE parttbl; + DROP TABLE another_parttbl; } session "s1" @@ -148,6 +155,16 @@ step "simplepartupdate" { update parttbl set a = a; } +# test scenarios where update may cause row movement + +step "simplepartupdate_route1to2" { + update parttbl set a = 2 where c = 1 returning *; +} + +step "simplepartupdate_noroute" { + update parttbl set b = 2 where c = 1 returning *; +} + session "s2" setup { BEGIN ISOLATION LEVEL READ COMMITTED; } @@ -190,6 +207,21 @@ step "complexpartupdate" { update parttbl set a = u.a from u; } +step "complexpartupdate_route_err1" { + with u as (update another_parttbl set a = 1 returning another_parttbl.*) + update parttbl p set a = u.a from u where p.a = u.a and p.c = 1 returning p.*; +} + +step "complexpartupdate_route" { + with u as (update another_parttbl set a = 1 returning another_parttbl.*) + update parttbl p set a = p.b from u where p.a = u.a and p.c = 1 returning p.*; +} + +step "complexpartupdate_doesnt_route" { + with u as (update another_parttbl set a = 1 returning another_parttbl.*) + update parttbl p set a = 3 - p.b from u where p.a = u.a and p.c = 1 returning p.*; +} + # Use writable CTEs to create self-updated rows, that then are # (updated|deleted). The *fail versions of the tests additionally # perform an update, via a function, in a different command, to test @@ -278,3 +310,6 @@ permutation "wrjt" "selectresultforupdate" "c2" "c1" permutation "wrtwcte" "multireadwcte" "c1" "c2" permutation "simplepartupdate" "complexpartupdate" "c1" "c2" +permutation "simplepartupdate_route1to2" "complexpartupdate_route_err1" "c1" "c2" +permutation "simplepartupdate_noroute" "complexpartupdate_route" "c1" "c2" +permutation "simplepartupdate_noroute" "complexpartupdate_doesnt_route" "c1" "c2"