Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ All notable changes to this project will be documented in this file. It uses the
over floats. Aggregates with an internal transition state (anything over
`numeric`, `avg(bigint)`, `avg(interval)`) still fall back to local
aggregation. Requires `enable_partitionwise_aggregate` ([#298]).
* Disabled remote MIN/MAX optimization by raising `MinMaxAggPath` cost
rather than understating foreign scan cost ([#310]).

### 🐞 Bug Fixes

Expand Down Expand Up @@ -103,8 +105,10 @@ All notable changes to this project will be documented in this file. It uses the
"ClickHouse/pg_clickhouse#303 Flush buffered data during binary insert"
[#307]: https://github.com/ClickHouse/pg_clickhouse/pull/307
"ClickHouse/pg_clickhouse#307 Push down three-argument trim functions"
[#307]: https://github.com/ClickHouse/pg_clickhouse/pull/309
[#309]: https://github.com/ClickHouse/pg_clickhouse/pull/309
"ClickHouse/pg_clickhouse#309 add binary support to clickhouse_raw_query, add clickhouse_query"
[#310]: https://github.com/ClickHouse/pg_clickhouse/pull/310
"ClickHouse/pg_clickhouse#310 Disable MinMaxAgg without impacting overall query planner costs"

## [v0.3.2] — 2026-06-16

Expand Down
17 changes: 16 additions & 1 deletion src/fdw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1799,7 +1799,7 @@ estimate_path_cost_size(
*p_rows = 1000;
*p_width = 32;
*p_startup_cost = 1.0;
*p_total_cost = 0.1 + coef;
*p_total_cost = 5.0 + coef;
}

/*
Expand Down Expand Up @@ -2927,6 +2927,7 @@ add_foreign_grouping_paths(
CHFdwRelationInfo* ifpinfo = input_rel->fdw_private;
CHFdwRelationInfo* fpinfo = grouped_rel->fdw_private;
ForeignPath* grouppath;
ListCell* lc;
double rows;
int width;
Cost startup_cost;
Expand Down Expand Up @@ -3009,6 +3010,20 @@ add_foreign_grouping_paths(
); /* no fdw_private */
#endif

/*
* For simple min/max queries Postgres adds MinMaxAggPath that rewrites as
* ORDER BY col LIMIT 1. LIMIT is invisible to FDW, causing full remote
* scan, so increase the cost to prevent this optimization.
*/
foreach (lc, grouped_rel->pathlist) {
Path* path = (Path*)lfirst(lc);

if (IsA(path, MinMaxAggPath)) {
path->startup_cost += disable_cost;
path->total_cost += disable_cost;
}
}

/* Add generated path into grouped_rel by add_path(). */
add_path(grouped_rel, (Path*)grouppath);
}
Expand Down
6 changes: 3 additions & 3 deletions test/expected/binary_queries.out
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON
EXPLAIN SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10;
QUERY PLAN
----------------------------------------------------------------
Limit (cost=1.00..1.05 rows=10 width=32)
-> Unique (cost=1.00..5.60 rows=1000 width=32)
-> Foreign Scan (cost=1.00..0.60 rows=1000 width=32)
Limit (cost=1.00..1.09 rows=10 width=32)
-> Unique (cost=1.00..10.50 rows=1000 width=32)
-> Foreign Scan (cost=1.00..5.50 rows=1000 width=32)
Relations: (ft2 t1) LEFT JOIN (ft1 t2)
(4 rows)

Expand Down
6 changes: 3 additions & 3 deletions test/expected/binary_queries_1.out
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON
EXPLAIN SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10;
QUERY PLAN
----------------------------------------------------------------
Limit (cost=1.00..1.05 rows=10 width=32)
-> Unique (cost=1.00..5.60 rows=1000 width=32)
-> Foreign Scan (cost=1.00..0.60 rows=1000 width=32)
Limit (cost=1.00..1.09 rows=10 width=32)
-> Unique (cost=1.00..10.50 rows=1000 width=32)
-> Foreign Scan (cost=1.00..5.50 rows=1000 width=32)
Relations: (ft2 t1) LEFT JOIN (ft1 t2)
(4 rows)

Expand Down
6 changes: 3 additions & 3 deletions test/expected/binary_queries_2.out
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON
EXPLAIN SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10;
QUERY PLAN
----------------------------------------------------------------
Limit (cost=1.00..1.05 rows=10 width=8)
-> Unique (cost=1.00..5.60 rows=1000 width=8)
-> Foreign Scan (cost=1.00..0.60 rows=1000 width=32)
Limit (cost=1.00..1.09 rows=10 width=8)
-> Unique (cost=1.00..10.50 rows=1000 width=8)
-> Foreign Scan (cost=1.00..5.50 rows=1000 width=32)
Relations: (ft2 t1) LEFT JOIN (ft1 t2)
(4 rows)

Expand Down
6 changes: 3 additions & 3 deletions test/expected/binary_queries_3.out
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON
EXPLAIN SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10;
QUERY PLAN
----------------------------------------------------------------
Limit (cost=1.00..1.05 rows=10 width=8)
-> Unique (cost=1.00..5.60 rows=1000 width=8)
-> Foreign Scan (cost=1.00..0.60 rows=1000 width=32)
Limit (cost=1.00..1.09 rows=10 width=8)
-> Unique (cost=1.00..10.50 rows=1000 width=8)
-> Foreign Scan (cost=1.00..5.50 rows=1000 width=32)
Relations: (ft2 t1) LEFT JOIN (ft1 t2)
(4 rows)

Expand Down
6 changes: 3 additions & 3 deletions test/expected/binary_queries_4.out
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON
EXPLAIN SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10;
QUERY PLAN
----------------------------------------------------------------
Limit (cost=1.00..1.05 rows=10 width=8)
-> Unique (cost=1.00..5.60 rows=1000 width=8)
-> Foreign Scan (cost=1.00..0.60 rows=1000 width=32)
Limit (cost=1.00..1.09 rows=10 width=8)
-> Unique (cost=1.00..10.50 rows=1000 width=8)
-> Foreign Scan (cost=1.00..5.50 rows=1000 width=32)
Relations: (ft2 t1) LEFT JOIN (ft1 t2)
(4 rows)

Expand Down
6 changes: 3 additions & 3 deletions test/expected/binary_queries_5.out
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON
EXPLAIN SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10;
QUERY PLAN
----------------------------------------------------------------
Limit (cost=1.00..1.05 rows=10 width=32)
-> Unique (cost=1.00..5.60 rows=1000 width=32)
-> Foreign Scan (cost=1.00..0.60 rows=1000 width=32)
Limit (cost=1.00..1.09 rows=10 width=32)
-> Unique (cost=1.00..10.50 rows=1000 width=32)
-> Foreign Scan (cost=1.00..5.50 rows=1000 width=32)
Relations: (ft2 t1) LEFT JOIN (ft1 t2)
(4 rows)

Expand Down
6 changes: 3 additions & 3 deletions test/expected/binary_queries_6.out
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON
EXPLAIN SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10;
QUERY PLAN
----------------------------------------------------------------
Limit (cost=1.00..1.05 rows=10 width=32)
-> Unique (cost=1.00..5.60 rows=1000 width=32)
-> Foreign Scan (cost=1.00..0.60 rows=1000 width=32)
Limit (cost=1.00..1.09 rows=10 width=32)
-> Unique (cost=1.00..10.50 rows=1000 width=32)
-> Foreign Scan (cost=1.00..5.50 rows=1000 width=32)
Relations: (ft2 t1) LEFT JOIN (ft1 t2)
(4 rows)

Expand Down
8 changes: 4 additions & 4 deletions test/expected/http.out
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ INSERT INTO ftcopy VALUES
EXPLAIN (VERBOSE) SELECT * FROM ftcopy ORDER BY c1;
QUERY PLAN
---------------------------------------------------------------------------------------------
Foreign Scan on public.ftcopy (cost=1.00..0.60 rows=1000 width=64)
Foreign Scan on public.ftcopy (cost=1.00..5.50 rows=1000 width=64)
Output: c1, c2, c3, c4, c5, c6
Remote SQL: SELECT c1, c2, c3, c4, c5, c6 FROM http_test.tcopy ORDER BY c1 ASC NULLS LAST
(3 rows)
Expand Down Expand Up @@ -408,9 +408,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON
EXPLAIN SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10;
QUERY PLAN
----------------------------------------------------------------
Limit (cost=1.00..1.05 rows=10 width=32)
-> Unique (cost=1.00..5.60 rows=1000 width=32)
-> Foreign Scan (cost=1.00..0.60 rows=1000 width=32)
Limit (cost=1.00..1.09 rows=10 width=32)
-> Unique (cost=1.00..10.50 rows=1000 width=32)
-> Foreign Scan (cost=1.00..5.50 rows=1000 width=32)
Relations: (ft2 t1) LEFT JOIN (ft1 t2)
(4 rows)

Expand Down
8 changes: 4 additions & 4 deletions test/expected/http_1.out
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ INSERT INTO ftcopy VALUES
EXPLAIN (VERBOSE) SELECT * FROM ftcopy ORDER BY c1;
QUERY PLAN
---------------------------------------------------------------------------------------------
Foreign Scan on public.ftcopy (cost=1.00..0.60 rows=1000 width=64)
Foreign Scan on public.ftcopy (cost=1.00..5.50 rows=1000 width=64)
Output: c1, c2, c3, c4, c5, c6
Remote SQL: SELECT c1, c2, c3, c4, c5, c6 FROM http_test.tcopy ORDER BY c1 ASC NULLS LAST
(3 rows)
Expand Down Expand Up @@ -408,9 +408,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON
EXPLAIN SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10;
QUERY PLAN
----------------------------------------------------------------
Limit (cost=1.00..1.05 rows=10 width=32)
-> Unique (cost=1.00..5.60 rows=1000 width=32)
-> Foreign Scan (cost=1.00..0.60 rows=1000 width=32)
Limit (cost=1.00..1.09 rows=10 width=32)
-> Unique (cost=1.00..10.50 rows=1000 width=32)
-> Foreign Scan (cost=1.00..5.50 rows=1000 width=32)
Relations: (ft2 t1) LEFT JOIN (ft1 t2)
(4 rows)

Expand Down
8 changes: 4 additions & 4 deletions test/expected/http_2.out
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ INSERT INTO ftcopy VALUES
EXPLAIN (VERBOSE) SELECT * FROM ftcopy ORDER BY c1;
QUERY PLAN
---------------------------------------------------------------------------------------------
Foreign Scan on public.ftcopy (cost=1.00..0.60 rows=1000 width=64)
Foreign Scan on public.ftcopy (cost=1.00..5.50 rows=1000 width=64)
Output: c1, c2, c3, c4, c5, c6
Remote SQL: SELECT c1, c2, c3, c4, c5, c6 FROM http_test.tcopy ORDER BY c1 ASC NULLS LAST
(3 rows)
Expand Down Expand Up @@ -408,9 +408,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON
EXPLAIN SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10;
QUERY PLAN
----------------------------------------------------------------
Limit (cost=1.00..1.05 rows=10 width=8)
-> Unique (cost=1.00..5.60 rows=1000 width=8)
-> Foreign Scan (cost=1.00..0.60 rows=1000 width=32)
Limit (cost=1.00..1.09 rows=10 width=8)
-> Unique (cost=1.00..10.50 rows=1000 width=8)
-> Foreign Scan (cost=1.00..5.50 rows=1000 width=32)
Relations: (ft2 t1) LEFT JOIN (ft1 t2)
(4 rows)

Expand Down
8 changes: 4 additions & 4 deletions test/expected/http_3.out
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ INSERT INTO ftcopy VALUES
EXPLAIN (VERBOSE) SELECT * FROM ftcopy ORDER BY c1;
QUERY PLAN
---------------------------------------------------------------------------------------------
Foreign Scan on public.ftcopy (cost=1.00..0.60 rows=1000 width=64)
Foreign Scan on public.ftcopy (cost=1.00..5.50 rows=1000 width=64)
Output: c1, c2, c3, c4, c5, c6
Remote SQL: SELECT c1, c2, c3, c4, c5, c6 FROM http_test.tcopy ORDER BY c1 ASC NULLS LAST
(3 rows)
Expand Down Expand Up @@ -408,9 +408,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON
EXPLAIN SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10;
QUERY PLAN
----------------------------------------------------------------
Limit (cost=1.00..1.05 rows=10 width=8)
-> Unique (cost=1.00..5.60 rows=1000 width=8)
-> Foreign Scan (cost=1.00..0.60 rows=1000 width=32)
Limit (cost=1.00..1.09 rows=10 width=8)
-> Unique (cost=1.00..10.50 rows=1000 width=8)
-> Foreign Scan (cost=1.00..5.50 rows=1000 width=32)
Relations: (ft2 t1) LEFT JOIN (ft1 t2)
(4 rows)

Expand Down
8 changes: 4 additions & 4 deletions test/expected/http_4.out
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ INSERT INTO ftcopy VALUES
EXPLAIN (VERBOSE) SELECT * FROM ftcopy ORDER BY c1;
QUERY PLAN
---------------------------------------------------------------------------------------------
Foreign Scan on public.ftcopy (cost=1.00..0.60 rows=1000 width=64)
Foreign Scan on public.ftcopy (cost=1.00..5.50 rows=1000 width=64)
Output: c1, c2, c3, c4, c5, c6
Remote SQL: SELECT c1, c2, c3, c4, c5, c6 FROM http_test.tcopy ORDER BY c1 ASC NULLS LAST
(3 rows)
Expand Down Expand Up @@ -408,9 +408,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON
EXPLAIN SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10;
QUERY PLAN
----------------------------------------------------------------
Limit (cost=1.00..1.05 rows=10 width=8)
-> Unique (cost=1.00..5.60 rows=1000 width=8)
-> Foreign Scan (cost=1.00..0.60 rows=1000 width=32)
Limit (cost=1.00..1.09 rows=10 width=8)
-> Unique (cost=1.00..10.50 rows=1000 width=8)
-> Foreign Scan (cost=1.00..5.50 rows=1000 width=32)
Relations: (ft2 t1) LEFT JOIN (ft1 t2)
(4 rows)

Expand Down
8 changes: 4 additions & 4 deletions test/expected/http_5.out
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ INSERT INTO ftcopy VALUES
EXPLAIN (VERBOSE) SELECT * FROM ftcopy ORDER BY c1;
QUERY PLAN
---------------------------------------------------------------------------------------------
Foreign Scan on public.ftcopy (cost=1.00..0.60 rows=1000 width=64)
Foreign Scan on public.ftcopy (cost=1.00..5.50 rows=1000 width=64)
Output: c1, c2, c3, c4, c5, c6
Remote SQL: SELECT c1, c2, c3, c4, c5, c6 FROM http_test.tcopy ORDER BY c1 ASC NULLS LAST
(3 rows)
Expand Down Expand Up @@ -408,9 +408,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON
EXPLAIN SELECT DISTINCT t1.c1, t2.c1 FROM ft2 t1 LEFT JOIN ft1 t2 ON (t1.c1 = t2.c1) order by t1.c1 LIMIT 10;
QUERY PLAN
----------------------------------------------------------------
Limit (cost=1.00..1.05 rows=10 width=32)
-> Unique (cost=1.00..5.60 rows=1000 width=32)
-> Foreign Scan (cost=1.00..0.60 rows=1000 width=32)
Limit (cost=1.00..1.09 rows=10 width=32)
-> Unique (cost=1.00..10.50 rows=1000 width=32)
-> Foreign Scan (cost=1.00..5.50 rows=1000 width=32)
Relations: (ft2 t1) LEFT JOIN (ft1 t2)
(4 rows)

Expand Down
Loading