Commit 5843659d authored by Tom Lane's avatar Tom Lane

Stabilize test case added by commit f61db909.

Buildfarm members ayu and tern have sometimes shown a different
plan than expected for this query.  I'd been unable to reproduce
that before today, but I finally realized what is happening.
If there is a concurrent open transaction (probably an autovacuum
run in the buildfarm, but this can also be arranged manually),
then the index entries for the rows removed by the DELETE a few
lines up are not killed promptly, causing a change in the planner's
estimate of the extremal value of ft2.c1, which moves the rowcount
estimate for "c1 > 1100" by enough to change the join plan from
nestloop to hash.

To fix, change the query condition to "c1 > 1000", causing the
hash plan to be preferred whether or not a concurrent open
transaction exists.  Since this UPDATE is tailored to be a no-op,
nothing else changes.

Report: https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=ayu&dt=2021-06-09%2022%3A45%3A48
Report: https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=ayu&dt=2021-06-13%2022%3A38%3A18
Report: https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=tern&dt=2021-06-20%2004%3A55%3A36
parent 6991e774
...@@ -5535,7 +5535,7 @@ UPDATE ft2 AS target SET (c2) = ( ...@@ -5535,7 +5535,7 @@ UPDATE ft2 AS target SET (c2) = (
-- but a SET clause that can't be -- but a SET clause that can't be
EXPLAIN (VERBOSE, COSTS OFF) EXPLAIN (VERBOSE, COSTS OFF)
UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END
FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1100; FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1000;
QUERY PLAN QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Update on public.ft2 d Update on public.ft2 d
...@@ -5543,19 +5543,22 @@ UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END ...@@ -5543,19 +5543,22 @@ UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END
-> Foreign Scan -> Foreign Scan
Output: CASE WHEN (random() >= '0'::double precision) THEN d.c2 ELSE 0 END, d.ctid, d.*, t.* Output: CASE WHEN (random() >= '0'::double precision) THEN d.c2 ELSE 0 END, d.ctid, d.*, t.*
Relations: (public.ft2 d) INNER JOIN (public.ft2 t) Relations: (public.ft2 d) INNER JOIN (public.ft2 t)
Remote SQL: SELECT r1.c2, r1.ctid, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")) AND ((r1."C 1" > 1100)))) FOR UPDATE OF r1 Remote SQL: SELECT r1.c2, r1.ctid, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")) AND ((r1."C 1" > 1000)))) FOR UPDATE OF r1
-> Nested Loop -> Hash Join
Output: d.c2, d.ctid, d.*, t.* Output: d.c2, d.ctid, d.*, t.*
Hash Cond: (d.c1 = t.c1)
-> Foreign Scan on public.ft2 d -> Foreign Scan on public.ft2 d
Output: d.c2, d.ctid, d.*, d.c1 Output: d.c2, d.ctid, d.*, d.c1
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8, ctid FROM "S 1"."T 1" WHERE (("C 1" > 1100)) ORDER BY "C 1" ASC NULLS LAST FOR UPDATE Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8, ctid FROM "S 1"."T 1" WHERE (("C 1" > 1000)) ORDER BY "C 1" ASC NULLS LAST FOR UPDATE
-> Hash
Output: t.*, t.c1
-> Foreign Scan on public.ft2 t -> Foreign Scan on public.ft2 t
Output: t.*, t.c1 Output: t.*, t.c1
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (($1::integer = "C 1")) Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1"
(14 rows) (17 rows)
UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END
FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1100; FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1000;
-- Test UPDATE/DELETE with WHERE or JOIN/ON conditions containing -- Test UPDATE/DELETE with WHERE or JOIN/ON conditions containing
-- user-defined operators/functions -- user-defined operators/functions
ALTER SERVER loopback OPTIONS (DROP extensions); ALTER SERVER loopback OPTIONS (DROP extensions);
......
...@@ -1259,9 +1259,9 @@ UPDATE ft2 AS target SET (c2) = ( ...@@ -1259,9 +1259,9 @@ UPDATE ft2 AS target SET (c2) = (
-- but a SET clause that can't be -- but a SET clause that can't be
EXPLAIN (VERBOSE, COSTS OFF) EXPLAIN (VERBOSE, COSTS OFF)
UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END
FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1100; FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1000;
UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END
FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1100; FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1000;
-- Test UPDATE/DELETE with WHERE or JOIN/ON conditions containing -- Test UPDATE/DELETE with WHERE or JOIN/ON conditions containing
-- user-defined operators/functions -- user-defined operators/functions
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment