From c0c9b37d6df7717a31efbe7706ce90089453ce9e Mon Sep 17 00:00:00 2001 From: Japin Li Date: Thu, 16 May 2024 17:42:53 +0800 Subject: [PATCH v5] Disable push down FETCH FIRST WITH TIES clause --- .../postgres_fdw/expected/postgres_fdw.out | 19 +++++++++++++++++++ contrib/postgres_fdw/postgres_fdw.c | 12 ++++++++++++ contrib/postgres_fdw/sql/postgres_fdw.sql | 2 ++ 3 files changed, 33 insertions(+) diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 078b8a966f..bf36cb0a62 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -339,6 +339,25 @@ SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; (110,0,00110,"Sun Jan 11 00:00:00 1970 PST","Sun Jan 11 00:00:00 1970",0,"0 ",foo) (10 rows) +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c3 > '00960' ORDER BY t1.c2 FETCH FIRST 2 ROWS WITH TIES; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: c1, c2, c3, c4, c5, c6, c7, c8 + -> Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((c3 > '00960')) ORDER BY c2 ASC NULLS LAST +(5 rows) + +SELECT * FROM ft1 t1 WHERE t1.c3 > '00960' ORDER BY t1.c2 FETCH FIRST 2 ROWS WITH TIES; + c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 +------+----+-------+------------------------------+--------------------------+----+------------+----- + 970 | 0 | 00970 | Thu Mar 12 00:00:00 1970 PST | Thu Mar 12 00:00:00 1970 | 0 | 0 | foo + 1000 | 0 | 01000 | Thu Jan 01 00:00:00 1970 PST | Thu Jan 01 00:00:00 1970 | 0 | 0 | foo + 990 | 0 | 00990 | Wed Apr 01 00:00:00 1970 PST | Wed Apr 01 00:00:00 1970 | 0 | 0 | foo + 980 | 0 | 00980 | Sun Mar 22 00:00:00 1970 PST | Sun Mar 22 00:00:00 1970 | 0 | 0 | foo +(4 rows) + -- empty result SELECT * FROM ft1 WHERE false; c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 4053cd641c..347d9803d2 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -7140,6 +7140,18 @@ add_foreign_final_paths(PlannerInfo *root, RelOptInfo *input_rel, if (ifpinfo->local_conds) return; + /* + * Also, the FETCH FIRST/NEXT ... ROW/ROWS WITH TIES cannot be pushed down + * because: + * a) The remote system may have a different understanding of equality, + * can result in varying results, such as non-deterministic + * collations. + * b) We do not have knowledge of the remote server's version as this + * clause is only supported for PG13 and above. + */ + if (parse->limitOption == LIMIT_OPTION_WITH_TIES) + return; + /* * Also, the LIMIT/OFFSET cannot be pushed down, if their expressions are * not safe to remote. diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index 09ba234e43..b008db0178 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -265,6 +265,8 @@ SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tableoid OFFSET 100 LIMIT 10; -- whole-row reference EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c3 > '00960' ORDER BY t1.c2 FETCH FIRST 2 ROWS WITH TIES; +SELECT * FROM ft1 t1 WHERE t1.c3 > '00960' ORDER BY t1.c2 FETCH FIRST 2 ROWS WITH TIES; -- empty result SELECT * FROM ft1 WHERE false; -- with WHERE clause -- 2.34.1