From: Tom Lane Date: Mon, 29 Dec 2025 17:53:49 +0000 (-0500) Subject: Further stabilize a postgres_fdw test case. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cb77bc04422fbbd1be48dde9794bfc0d0e5d7ad5;p=thirdparty%2Fpostgresql.git Further stabilize a postgres_fdw test case. This patch causes one postgres_fdw test case to revert to the plan it used before aa86129e1, i.e., using a remote sort in preference to local sort. That decision is actually a coin-flip because cost_sort() will give the same answer on both sides, so that the plan choice comes down to little more than roundoff error. In consequence, the test output can change as a result of even minor changes in nearby costs, as we saw in aa86129e1 (compare also b690e5fac and 4b14e1871). b690e5fac's solution to stabilizing the adjacent test case was to disable sorting locally, and here we extend that to the currently- problematic case. Without this, the following patch would cause this plan choice to change back in this same way, for even less apparent reason. Author: Tom Lane Reviewed-by: Chao Li Discussion: https://postgr.es/m/2551253.1766952956@sss.pgh.pa.us --- diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 48e3185b227..6066510c7c0 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -4178,9 +4178,12 @@ EXECUTE st1(101, 101); 00101 | 00101 (1 row) -SET enable_hashjoin TO off; +-- These next tests require choosing between remote and local sort, which is +-- a coin flip so long as cost_sort() gives the same results on both sides. +-- To stabilize the expected plans, disable sorting locally. SET enable_sort TO off; -- subquery using stable function (can't be sent to remote) +SET enable_hashjoin TO off; -- this one needs even more help to be stable PREPARE st2(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 < $2 AND t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 > $1 AND date(c4) = '1970-01-17'::date) ORDER BY c1; EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st2(10, 20); QUERY PLAN @@ -4212,20 +4215,16 @@ EXECUTE st2(101, 121); (1 row) RESET enable_hashjoin; -RESET enable_sort; -- subquery using immutable function (can be sent to remote) PREPARE st3(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 < $2 AND t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 > $1 AND date(c5) = '1970-01-17'::date) ORDER BY c1; EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st3(10, 20); - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: t1.c1, t1.c2, t1.c3, t1.c4, t1.c5, t1.c6, t1.c7, t1.c8 - Sort Key: t1.c1 - -> Foreign Scan - Output: t1.c1, t1.c2, t1.c3, t1.c4, t1.c5, t1.c6, t1.c7, t1.c8 - Relations: (public.ft1 t1) SEMI JOIN (public.ft2 t2) - Remote SQL: SELECT r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8 FROM "S 1"."T 1" r1 WHERE ((r1."C 1" < 20)) AND EXISTS (SELECT NULL FROM "S 1"."T 1" r3 WHERE ((r3."C 1" > 10)) AND ((date(r3.c5) = '1970-01-17'::date)) AND ((r3.c3 = r1.c3))) -(7 rows) + Relations: (public.ft1 t1) SEMI JOIN (public.ft2 t2) + Remote SQL: SELECT r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8 FROM "S 1"."T 1" r1 WHERE ((r1."C 1" < 20)) AND EXISTS (SELECT NULL FROM "S 1"."T 1" r3 WHERE ((r3."C 1" > 10)) AND ((date(r3.c5) = '1970-01-17'::date)) AND ((r3.c3 = r1.c3))) ORDER BY r1."C 1" ASC NULLS LAST +(4 rows) EXECUTE st3(10, 20); c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 @@ -4238,6 +4237,7 @@ EXECUTE st3(20, 30); ----+----+----+----+----+----+----+---- (0 rows) +RESET enable_sort; -- custom plan should be chosen initially PREPARE st4(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 = $1; EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index 9a8f9e28135..4f7ab2ed0ac 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -1165,20 +1165,28 @@ PREPARE st1(int, int) AS SELECT t1.c3, t2.c3 FROM ft1 t1, ft2 t2 WHERE t1.c1 = $ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st1(1, 2); EXECUTE st1(1, 1); EXECUTE st1(101, 101); -SET enable_hashjoin TO off; + +-- These next tests require choosing between remote and local sort, which is +-- a coin flip so long as cost_sort() gives the same results on both sides. +-- To stabilize the expected plans, disable sorting locally. SET enable_sort TO off; + -- subquery using stable function (can't be sent to remote) +SET enable_hashjoin TO off; -- this one needs even more help to be stable PREPARE st2(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 < $2 AND t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 > $1 AND date(c4) = '1970-01-17'::date) ORDER BY c1; EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st2(10, 20); EXECUTE st2(10, 20); EXECUTE st2(101, 121); RESET enable_hashjoin; -RESET enable_sort; + -- subquery using immutable function (can be sent to remote) PREPARE st3(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 < $2 AND t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 > $1 AND date(c5) = '1970-01-17'::date) ORDER BY c1; EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st3(10, 20); EXECUTE st3(10, 20); EXECUTE st3(20, 30); + +RESET enable_sort; + -- custom plan should be chosen initially PREPARE st4(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 = $1; EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1);