Add explain_filter calls to window function tests for better query plan visibility

pull/8344/head
Mehmet Yilmaz 2025-11-17 11:15:49 +00:00
parent 643282df8c
commit a5c68ed720
12 changed files with 236 additions and 164 deletions

View File

@ -633,11 +633,13 @@ $Q$);
(4 rows)
-- pull to coordinator WINDOW
select public.explain_filter('
SELECT public.coordinator_plan($Q$
EXPLAIN (COSTS OFF)
SELECT a, COUNT(*) OVER (PARTITION BY a+1) FROM partitioned_distributed_table ORDER BY 1,2;
$Q$);
coordinator_plan
$Q$)
');
explain_filter
---------------------------------------------------------------------
Sort
Sort Key: remote_scan.a, (count(*) OVER (?))
@ -645,7 +647,7 @@ $Q$);
-> Sort
Sort Key: remote_scan.worker_column_2
-> Custom Scan (Citus Adaptive)
Task Count: 4
Task Count: N
(7 rows)
-- FOR UPDATE

View File

@ -3118,46 +3118,50 @@ CREATE TABLE distributed_table_1(a int, b int);
SELECT create_distributed_table('distributed_table_1','a');
INSERT INTO distributed_table_1 values (1,1);
EXPLAIN :default_analyze_flags SELECT row_number() OVER() AS r FROM distributed_table_1;
WindowAgg (actual rows=1 loops=1)
-> Custom Scan (Citus Adaptive) (actual rows=1 loops=1)
Task Count: 2
Tasks Shown: One of 2
select public.explain_filter('
EXPLAIN (ANALYZE on, COSTS off, TIMING off, SUMMARY off, BUFFERS off) SELECT row_number() OVER() AS r FROM distributed_table_1
');
WindowAgg (actual rows=N loops=N)
-> Custom Scan (Citus Adaptive) (actual rows=N loops=N)
Task Count: N
Tasks Shown: One of N
-> Task
Node: host=localhost port=xxxxx dbname=regression
-> Seq Scan on distributed_table_1_570032 distributed_table_1 (actual rows=1 loops=1)
Node: host=localhost port=N dbname=regression
-> Seq Scan on distributed_table_1_570032 distributed_table_1 (actual rows=N loops=N)
CREATE TABLE distributed_table_2(a int, b int);
SELECT create_distributed_table('distributed_table_2','a');
INSERT INTO distributed_table_2 VALUES (1,1);
EXPLAIN :default_analyze_flags
select public.explain_filter('
EXPLAIN (ANALYZE on, COSTS off, TIMING off, SUMMARY off, BUFFERS off)
WITH r AS (SELECT row_number() OVER () AS r FROM distributed_table_1)
SELECT * FROM distributed_table_2
JOIN r ON (r = distributed_table_2.b)
LIMIT 3;
Limit (actual rows=1 loops=1)
-> Custom Scan (Citus Adaptive) (actual rows=1 loops=1)
LIMIT 3
');
Limit (actual rows=N loops=N)
-> Custom Scan (Citus Adaptive) (actual rows=N loops=N)
-> Distributed Subplan XXX_1
Intermediate Data Size: 14 bytes
Result destination: Send to 2 nodes
-> WindowAgg (actual rows=1 loops=1)
-> Custom Scan (Citus Adaptive) (actual rows=1 loops=1)
Task Count: 2
Tasks Shown: One of 2
Intermediate Data Size: N bytes
Result destination: Send to N nodes
-> WindowAgg (actual rows=N loops=N)
-> Custom Scan (Citus Adaptive) (actual rows=N loops=N)
Task Count: N
Tasks Shown: One of N
-> Task
Node: host=localhost port=xxxxx dbname=regression
-> Seq Scan on distributed_table_1_570032 distributed_table_1 (actual rows=1 loops=1)
Task Count: 2
Tuple data received from nodes: 16 bytes
Tasks Shown: One of 2
Node: host=localhost port=N dbname=regression
-> Seq Scan on distributed_table_1_570032 distributed_table_1 (actual rows=N loops=N)
Task Count: N
Tuple data received from nodes: N bytes
Tasks Shown: One of N
-> Task
Tuple data received from node: 16 bytes
Node: host=localhost port=xxxxx dbname=regression
-> Limit (actual rows=1 loops=1)
-> Nested Loop (actual rows=1 loops=1)
Tuple data received from node: N bytes
Node: host=localhost port=N dbname=regression
-> Limit (actual rows=N loops=N)
-> Nested Loop (actual rows=N loops=N)
Join Filter: (distributed_table_2.b = intermediate_result.r)
-> Function Scan on read_intermediate_result intermediate_result (actual rows=1 loops=1)
-> Seq Scan on distributed_table_2_570034 distributed_table_2 (actual rows=1 loops=1)
-> Function Scan on read_intermediate_result intermediate_result (actual rows=N loops=N)
-> Seq Scan on distributed_table_2_570034 distributed_table_2 (actual rows=N loops=N)
EXPLAIN :default_analyze_flags SELECT FROM (SELECT * FROM reference_table) subquery;
Custom Scan (Citus Adaptive) (actual rows=1 loops=1)
Task Count: 1

View File

@ -3107,46 +3107,50 @@ CREATE TABLE distributed_table_1(a int, b int);
SELECT create_distributed_table('distributed_table_1','a');
INSERT INTO distributed_table_1 values (1,1);
EXPLAIN :default_analyze_flags SELECT row_number() OVER() AS r FROM distributed_table_1;
WindowAgg (actual rows=1 loops=1)
-> Custom Scan (Citus Adaptive) (actual rows=1 loops=1)
Task Count: 2
Tasks Shown: One of 2
select public.explain_filter('
EXPLAIN (ANALYZE on, COSTS off, TIMING off, SUMMARY off, BUFFERS off) SELECT row_number() OVER() AS r FROM distributed_table_1
');
WindowAgg (actual rows=N loops=N)
-> Custom Scan (Citus Adaptive) (actual rows=N loops=N)
Task Count: N
Tasks Shown: One of N
-> Task
Node: host=localhost port=xxxxx dbname=regression
-> Seq Scan on distributed_table_1_570032 distributed_table_1 (actual rows=1 loops=1)
Node: host=localhost port=N dbname=regression
-> Seq Scan on distributed_table_1_570032 distributed_table_1 (actual rows=N loops=N)
CREATE TABLE distributed_table_2(a int, b int);
SELECT create_distributed_table('distributed_table_2','a');
INSERT INTO distributed_table_2 VALUES (1,1);
EXPLAIN :default_analyze_flags
select public.explain_filter('
EXPLAIN (ANALYZE on, COSTS off, TIMING off, SUMMARY off, BUFFERS off)
WITH r AS (SELECT row_number() OVER () AS r FROM distributed_table_1)
SELECT * FROM distributed_table_2
JOIN r ON (r = distributed_table_2.b)
LIMIT 3;
Limit (actual rows=1 loops=1)
-> Custom Scan (Citus Adaptive) (actual rows=1 loops=1)
LIMIT 3
');
Limit (actual rows=N loops=N)
-> Custom Scan (Citus Adaptive) (actual rows=N loops=N)
-> Distributed Subplan XXX_1
Intermediate Data Size: 14 bytes
Result destination: Send to 2 nodes
-> WindowAgg (actual rows=1 loops=1)
-> Custom Scan (Citus Adaptive) (actual rows=1 loops=1)
Task Count: 2
Tasks Shown: One of 2
Intermediate Data Size: N bytes
Result destination: Send to N nodes
-> WindowAgg (actual rows=N loops=N)
-> Custom Scan (Citus Adaptive) (actual rows=N loops=N)
Task Count: N
Tasks Shown: One of N
-> Task
Node: host=localhost port=xxxxx dbname=regression
-> Seq Scan on distributed_table_1_570032 distributed_table_1 (actual rows=1 loops=1)
Task Count: 2
Tuple data received from nodes: 16 bytes
Tasks Shown: One of 2
Node: host=localhost port=N dbname=regression
-> Seq Scan on distributed_table_1_570032 distributed_table_1 (actual rows=N loops=N)
Task Count: N
Tuple data received from nodes: N bytes
Tasks Shown: One of N
-> Task
Tuple data received from node: 16 bytes
Node: host=localhost port=xxxxx dbname=regression
-> Limit (actual rows=1 loops=1)
-> Nested Loop (actual rows=1 loops=1)
Tuple data received from node: N bytes
Node: host=localhost port=N dbname=regression
-> Limit (actual rows=N loops=N)
-> Nested Loop (actual rows=N loops=N)
Join Filter: (distributed_table_2.b = intermediate_result.r)
-> Function Scan on read_intermediate_result intermediate_result (actual rows=1 loops=1)
-> Seq Scan on distributed_table_2_570034 distributed_table_2 (actual rows=1 loops=1)
-> Function Scan on read_intermediate_result intermediate_result (actual rows=N loops=N)
-> Seq Scan on distributed_table_2_570034 distributed_table_2 (actual rows=N loops=N)
EXPLAIN :default_analyze_flags SELECT FROM (SELECT * FROM reference_table) subquery;
Custom Scan (Citus Adaptive) (actual rows=1 loops=1)
Task Count: 1

View File

@ -55,10 +55,12 @@ FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
1 |
(3 rows)
select public.explain_filter('
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT t1.id, MAX(t2.a2) OVER (PARTITION BY t2.id)
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
QUERY PLAN
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
');
explain_filter
---------------------------------------------------------------------
WindowAgg
Output: remote_scan.id, max(remote_scan.max) OVER (?), remote_scan.worker_column_3
@ -67,11 +69,11 @@ FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
Sort Key: remote_scan.worker_column_3
-> Custom Scan (Citus Adaptive)
Output: remote_scan.worker_column_3, remote_scan.id, remote_scan.max
Task Count: 4
Tasks Shown: One of 4
Task Count: N
Tasks Shown: One of N
-> Task
Query: SELECT worker_column_1 AS id, worker_column_2 AS max, worker_column_3 FROM (SELECT t1.id AS worker_column_1, t2.a2 AS worker_column_2, t2.id AS worker_column_3 FROM (outer_join_columns_testing.t1_30070000 t1 LEFT JOIN outer_join_columns_testing.t2_30070004 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.account_id)))) worker_subquery
Node: host=localhost port=xxxxx dbname=regression
Node: host=localhost port=N dbname=regression
-> Hash Right Join
Output: t1.id, t2.a2, t2.id
Inner Unique: true
@ -93,10 +95,12 @@ FROM t2 RIGHT OUTER JOIN t1 ON t1.id = t2.account_id;
1 |
(3 rows)
select public.explain_filter('
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT t1.id, MAX(t2.a2) OVER (PARTITION BY t2.id)
FROM t2 RIGHT OUTER JOIN t1 ON t1.id = t2.account_id;
QUERY PLAN
FROM t2 RIGHT OUTER JOIN t1 ON t1.id = t2.account_id
');
explain_filter
---------------------------------------------------------------------
WindowAgg
Output: remote_scan.id, max(remote_scan.max) OVER (?), remote_scan.worker_column_3
@ -105,11 +109,11 @@ FROM t2 RIGHT OUTER JOIN t1 ON t1.id = t2.account_id;
Sort Key: remote_scan.worker_column_3
-> Custom Scan (Citus Adaptive)
Output: remote_scan.worker_column_3, remote_scan.id, remote_scan.max
Task Count: 4
Tasks Shown: One of 4
Task Count: N
Tasks Shown: One of N
-> Task
Query: SELECT worker_column_1 AS id, worker_column_2 AS max, worker_column_3 FROM (SELECT t1.id AS worker_column_1, t2.a2 AS worker_column_2, t2.id AS worker_column_3 FROM (outer_join_columns_testing.t2_30070004 t2 RIGHT JOIN outer_join_columns_testing.t1_30070000 t1 ON ((t1.id OPERATOR(pg_catalog.=) t2.account_id)))) worker_subquery
Node: host=localhost port=xxxxx dbname=regression
Node: host=localhost port=N dbname=regression
-> Hash Right Join
Output: t1.id, t2.a2, t2.id
Inner Unique: true
@ -131,10 +135,12 @@ FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
2 | 20
(3 rows)
select public.explain_filter('
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT DISTINCT t1.id, MAX(t2.a2) OVER (PARTITION BY t2.id)
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
QUERY PLAN
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
');
explain_filter
---------------------------------------------------------------------
HashAggregate
Output: remote_scan.id, (max(remote_scan.max) OVER (?)), remote_scan.worker_column_3
@ -146,11 +152,11 @@ FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
Sort Key: remote_scan.worker_column_3
-> Custom Scan (Citus Adaptive)
Output: remote_scan.worker_column_3, remote_scan.id, remote_scan.max
Task Count: 4
Tasks Shown: One of 4
Task Count: N
Tasks Shown: One of N
-> Task
Query: SELECT worker_column_1 AS id, worker_column_2 AS max, worker_column_3 FROM (SELECT t1.id AS worker_column_1, t2.a2 AS worker_column_2, t2.id AS worker_column_3 FROM (outer_join_columns_testing.t1_30070000 t1 LEFT JOIN outer_join_columns_testing.t2_30070004 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.account_id)))) worker_subquery
Node: host=localhost port=xxxxx dbname=regression
Node: host=localhost port=N dbname=regression
-> Hash Right Join
Output: t1.id, t2.a2, t2.id
Inner Unique: true
@ -302,27 +308,29 @@ HAVING COUNT(DISTINCT a2) > 1;
1
(1 row)
select public.explain_filter('
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT 1
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
HAVING COUNT(DISTINCT a2) > 1;
QUERY PLAN
');
explain_filter
---------------------------------------------------------------------
Aggregate
Output: remote_scan."?column?"
Filter: (count(DISTINCT remote_scan.worker_column_2) > 1)
Filter: (count(DISTINCT remote_scan.worker_column_2) > N)
-> Sort
Output: remote_scan."?column?", remote_scan.worker_column_2
Sort Key: remote_scan.worker_column_2
-> Custom Scan (Citus Adaptive)
Output: remote_scan."?column?", remote_scan.worker_column_2
Task Count: 4
Tasks Shown: One of 4
Task Count: N
Tasks Shown: One of N
-> Task
Query: SELECT 1, worker_column_1 AS worker_column_2 FROM (SELECT t2.a2 AS worker_column_1 FROM (outer_join_columns_testing.t1_30070000 t1 LEFT JOIN outer_join_columns_testing.t2_30070004 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.account_id)))) worker_subquery GROUP BY worker_column_1
Node: host=localhost port=xxxxx dbname=regression
Query: SELECT N, worker_column_1 AS worker_column_2 FROM (SELECT t2.a2 AS worker_column_1 FROM (outer_join_columns_testing.t1_30070000 t1 LEFT JOIN outer_join_columns_testing.t2_30070004 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.account_id)))) worker_subquery GROUP BY worker_column_1
Node: host=localhost port=N dbname=regression
-> HashAggregate
Output: 1, t2.a2
Output: N, t2.a2
Group Key: t2.a2
-> Hash Right Join
Output: t2.a2

View File

@ -55,10 +55,12 @@ FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
1 |
(3 rows)
select public.explain_filter('
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT t1.id, MAX(t2.a2) OVER (PARTITION BY t2.id)
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
QUERY PLAN
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
');
explain_filter
---------------------------------------------------------------------
WindowAgg
Output: remote_scan.id, max(remote_scan.max) OVER (?), remote_scan.worker_column_3
@ -67,11 +69,11 @@ FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
Sort Key: remote_scan.worker_column_3
-> Custom Scan (Citus Adaptive)
Output: remote_scan.worker_column_3, remote_scan.id, remote_scan.max
Task Count: 4
Tasks Shown: One of 4
Task Count: N
Tasks Shown: One of N
-> Task
Query: SELECT worker_column_1 AS id, worker_column_2 AS max, worker_column_3 FROM (SELECT t1.id AS worker_column_1, t2.a2 AS worker_column_2, t2.id AS worker_column_3 FROM (outer_join_columns_testing.t1_30070000 t1 LEFT JOIN outer_join_columns_testing.t2_30070004 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.account_id)))) worker_subquery
Node: host=localhost port=xxxxx dbname=regression
Node: host=localhost port=N dbname=regression
-> Hash Right Join
Output: t1.id, t2.a2, t2.id
Inner Unique: true
@ -93,10 +95,12 @@ FROM t2 RIGHT OUTER JOIN t1 ON t1.id = t2.account_id;
1 |
(3 rows)
select public.explain_filter('
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT t1.id, MAX(t2.a2) OVER (PARTITION BY t2.id)
FROM t2 RIGHT OUTER JOIN t1 ON t1.id = t2.account_id;
QUERY PLAN
FROM t2 RIGHT OUTER JOIN t1 ON t1.id = t2.account_id
');
explain_filter
---------------------------------------------------------------------
WindowAgg
Output: remote_scan.id, max(remote_scan.max) OVER (?), remote_scan.worker_column_3
@ -105,11 +109,11 @@ FROM t2 RIGHT OUTER JOIN t1 ON t1.id = t2.account_id;
Sort Key: remote_scan.worker_column_3
-> Custom Scan (Citus Adaptive)
Output: remote_scan.worker_column_3, remote_scan.id, remote_scan.max
Task Count: 4
Tasks Shown: One of 4
Task Count: N
Tasks Shown: One of N
-> Task
Query: SELECT worker_column_1 AS id, worker_column_2 AS max, worker_column_3 FROM (SELECT t1.id AS worker_column_1, t2.a2 AS worker_column_2, t2.id AS worker_column_3 FROM (outer_join_columns_testing.t2_30070004 t2 RIGHT JOIN outer_join_columns_testing.t1_30070000 t1 ON ((t1.id OPERATOR(pg_catalog.=) t2.account_id)))) worker_subquery
Node: host=localhost port=xxxxx dbname=regression
Node: host=localhost port=N dbname=regression
-> Hash Right Join
Output: t1.id, t2.a2, t2.id
Inner Unique: true
@ -131,10 +135,12 @@ FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
2 | 20
(3 rows)
select public.explain_filter('
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT DISTINCT t1.id, MAX(t2.a2) OVER (PARTITION BY t2.id)
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
QUERY PLAN
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
');
explain_filter
---------------------------------------------------------------------
HashAggregate
Output: remote_scan.id, (max(remote_scan.max) OVER (?)), remote_scan.worker_column_3
@ -146,11 +152,11 @@ FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
Sort Key: remote_scan.worker_column_3
-> Custom Scan (Citus Adaptive)
Output: remote_scan.worker_column_3, remote_scan.id, remote_scan.max
Task Count: 4
Tasks Shown: One of 4
Task Count: N
Tasks Shown: One of N
-> Task
Query: SELECT worker_column_1 AS id, worker_column_2 AS max, worker_column_3 FROM (SELECT t1.id AS worker_column_1, t2.a2 AS worker_column_2, t2.id AS worker_column_3 FROM (outer_join_columns_testing.t1_30070000 t1 LEFT JOIN outer_join_columns_testing.t2_30070004 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.account_id)))) worker_subquery
Node: host=localhost port=xxxxx dbname=regression
Node: host=localhost port=N dbname=regression
-> Hash Right Join
Output: t1.id, t2.a2, t2.id
Inner Unique: true
@ -299,24 +305,26 @@ HAVING COUNT(DISTINCT a2) > 1;
1
(1 row)
select public.explain_filter('
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT 1
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
HAVING COUNT(DISTINCT a2) > 1;
QUERY PLAN
');
explain_filter
---------------------------------------------------------------------
Aggregate
Output: remote_scan."?column?"
Filter: (count(DISTINCT remote_scan.worker_column_2) > 1)
Filter: (count(DISTINCT remote_scan.worker_column_2) > N)
-> Custom Scan (Citus Adaptive)
Output: remote_scan."?column?", remote_scan.worker_column_2
Task Count: 4
Tasks Shown: One of 4
Task Count: N
Tasks Shown: One of N
-> Task
Query: SELECT 1, worker_column_1 AS worker_column_2 FROM (SELECT t2.a2 AS worker_column_1 FROM (outer_join_columns_testing.t1_30070000 t1 LEFT JOIN outer_join_columns_testing.t2_30070004 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.account_id)))) worker_subquery GROUP BY worker_column_1
Node: host=localhost port=xxxxx dbname=regression
Query: SELECT N, worker_column_1 AS worker_column_2 FROM (SELECT t2.a2 AS worker_column_1 FROM (outer_join_columns_testing.t1_30070000 t1 LEFT JOIN outer_join_columns_testing.t2_30070004 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.account_id)))) worker_subquery GROUP BY worker_column_1
Node: host=localhost port=N dbname=regression
-> HashAggregate
Output: 1, t2.a2
Output: N, t2.a2
Group Key: t2.a2
-> Hash Right Join
Output: t2.a2

View File

@ -675,6 +675,7 @@ LIMIT
2 | 1
(5 rows)
select public.explain_filter('
EXPLAIN (COSTS FALSE)
SELECT *
FROM (
@ -708,17 +709,18 @@ EXPLAIN (COSTS FALSE)
GROUP BY
user_id)) AS ftop
ORDER BY 2 DESC, 1 DESC
LIMIT 5;
QUERY PLAN
LIMIT 5
');
explain_filter
---------------------------------------------------------------------
Limit
-> Sort
Sort Key: remote_scan.sum DESC, remote_scan.user_id DESC
-> Custom Scan (Citus Adaptive)
Task Count: 4
Tasks Shown: One of 4
Task Count: N
Tasks Shown: One of N
-> Task
Node: host=localhost port=xxxxx dbname=regression
Node: host=localhost port=N dbname=regression
-> Limit
-> Sort
Sort Key: (sum((sum(users_table.value_2) OVER (?)))) DESC, users_table.user_id DESC

View File

@ -1292,6 +1292,7 @@ ORDER BY user_id, avg(value_1) DESC;
6 | 1.00000000000000000000 | 5
(32 rows)
select public.explain_filter('
EXPLAIN (COSTS FALSE)
SELECT
user_id,
@ -1300,19 +1301,20 @@ SELECT
FROM
users_table
GROUP BY user_id, value_2
ORDER BY user_id, avg(value_1) DESC;
QUERY PLAN
ORDER BY user_id, avg(value_1) DESC
');
explain_filter
---------------------------------------------------------------------
Sort
Sort Key: remote_scan.user_id, remote_scan.avg DESC
-> Custom Scan (Citus Adaptive)
Task Count: 4
Tasks Shown: One of 4
Task Count: N
Tasks Shown: One of N
-> Task
Node: host=localhost port=xxxxx dbname=regression
Node: host=localhost port=N dbname=regression
-> WindowAgg
-> Sort
Sort Key: users_table.user_id, (('1'::numeric / ('1'::numeric + avg(users_table.value_1))))
Sort Key: users_table.user_id, (('N'::numeric / ('N'::numeric + avg(users_table.value_1))))
-> HashAggregate
Group Key: users_table.user_id, users_table.value_2
-> Seq Scan on users_table_1400256 users_table
@ -1364,6 +1366,7 @@ ORDER BY user_id, avg(value_1) DESC;
(32 rows)
-- limit is not pushed down to worker !!
select public.explain_filter('
EXPLAIN (COSTS FALSE)
SELECT
user_id,
@ -1373,28 +1376,30 @@ FROM
users_table
GROUP BY user_id, value_2
ORDER BY user_id, avg(value_1) DESC
LIMIT 5;
QUERY PLAN
LIMIT 5
');
explain_filter
---------------------------------------------------------------------
Limit
-> Sort
Sort Key: remote_scan.user_id, remote_scan.avg DESC
-> Custom Scan (Citus Adaptive)
Task Count: 4
Tasks Shown: One of 4
Task Count: N
Tasks Shown: One of N
-> Task
Node: host=localhost port=xxxxx dbname=regression
Node: host=localhost port=N dbname=regression
-> Limit
-> Sort
Sort Key: users_table.user_id, (avg(users_table.value_1)) DESC
-> WindowAgg
-> Sort
Sort Key: users_table.user_id, (('1'::numeric / ('1'::numeric + avg(users_table.value_1))))
Sort Key: users_table.user_id, (('N'::numeric / ('N'::numeric + avg(users_table.value_1))))
-> HashAggregate
Group Key: users_table.user_id, users_table.value_2
-> Seq Scan on users_table_1400256 users_table
(17 rows)
select public.explain_filter('
EXPLAIN (COSTS FALSE)
SELECT
user_id,
@ -1404,28 +1409,30 @@ FROM
users_table
GROUP BY user_id, value_2
ORDER BY user_id, avg(value_1) DESC
LIMIT 5;
QUERY PLAN
LIMIT 5
');
explain_filter
---------------------------------------------------------------------
Limit
-> Sort
Sort Key: remote_scan.user_id, remote_scan.avg DESC
-> Custom Scan (Citus Adaptive)
Task Count: 4
Tasks Shown: One of 4
Task Count: N
Tasks Shown: One of N
-> Task
Node: host=localhost port=xxxxx dbname=regression
Node: host=localhost port=N dbname=regression
-> Limit
-> Sort
Sort Key: users_table.user_id, (avg(users_table.value_1)) DESC
-> WindowAgg
-> Sort
Sort Key: users_table.user_id, (('1'::numeric / ('1'::numeric + avg(users_table.value_1))))
Sort Key: users_table.user_id, (('N'::numeric / ('N'::numeric + avg(users_table.value_1))))
-> HashAggregate
Group Key: users_table.user_id, users_table.value_2
-> Seq Scan on users_table_1400256 users_table
(17 rows)
select public.explain_filter('
EXPLAIN (COSTS FALSE)
SELECT
user_id,
@ -1435,28 +1442,30 @@ FROM
users_table
GROUP BY user_id, value_2
ORDER BY user_id, avg(value_1) DESC
LIMIT 5;
QUERY PLAN
LIMIT 5
');
explain_filter
---------------------------------------------------------------------
Limit
-> Sort
Sort Key: remote_scan.user_id, remote_scan.avg DESC
-> Custom Scan (Citus Adaptive)
Task Count: 4
Tasks Shown: One of 4
Task Count: N
Tasks Shown: One of N
-> Task
Node: host=localhost port=xxxxx dbname=regression
Node: host=localhost port=N dbname=regression
-> Limit
-> Sort
Sort Key: users_table.user_id, (avg(users_table.value_1)) DESC
-> WindowAgg
-> Sort
Sort Key: users_table.user_id, ((1 / (1 + sum(users_table.value_2))))
Sort Key: users_table.user_id, ((N / (N + sum(users_table.value_2))))
-> HashAggregate
Group Key: users_table.user_id, users_table.value_2
-> Seq Scan on users_table_1400256 users_table
(17 rows)
select public.explain_filter('
EXPLAIN (COSTS FALSE)
SELECT
user_id,
@ -1466,17 +1475,18 @@ FROM
users_table
GROUP BY user_id, value_2
ORDER BY user_id, avg(value_1) DESC
LIMIT 5;
QUERY PLAN
LIMIT 5
');
explain_filter
---------------------------------------------------------------------
Limit
-> Sort
Sort Key: remote_scan.user_id, remote_scan.avg DESC
-> Custom Scan (Citus Adaptive)
Task Count: 4
Tasks Shown: One of 4
Task Count: N
Tasks Shown: One of N
-> Task
Node: host=localhost port=xxxxx dbname=regression
Node: host=localhost port=N dbname=regression
-> Limit
-> Sort
Sort Key: users_table.user_id, (avg(users_table.value_1)) DESC
@ -1489,23 +1499,25 @@ LIMIT 5;
(17 rows)
-- Grouping can be pushed down with aggregates even when window function can't
select public.explain_filter('
EXPLAIN (COSTS FALSE)
SELECT user_id, count(value_1), stddev(value_1), count(user_id) OVER (PARTITION BY random())
FROM users_table GROUP BY user_id HAVING avg(value_1) > 2 LIMIT 1;
QUERY PLAN
FROM users_table GROUP BY user_id HAVING avg(value_1) > 2 LIMIT 1
');
explain_filter
---------------------------------------------------------------------
Limit
-> WindowAgg
-> Sort
Sort Key: remote_scan.worker_column_5
-> Custom Scan (Citus Adaptive)
Task Count: 4
Tasks Shown: One of 4
Task Count: N
Tasks Shown: One of N
-> Task
Node: host=localhost port=xxxxx dbname=regression
Node: host=localhost port=N dbname=regression
-> HashAggregate
Group Key: user_id
Filter: (avg(value_1) > '2'::numeric)
Filter: (avg(value_1) > 'N'::numeric)
-> Seq Scan on users_table_1400256 users_table
(13 rows)
@ -1534,6 +1546,7 @@ SELECT create_distributed_table('daily_uniques', 'user_id');
(1 row)
select public.explain_filter('
EXPLAIN (COSTS FALSE) SELECT
user_id,
sum(value_2) AS commits,
@ -1547,17 +1560,18 @@ GROUP BY user_id
HAVING
sum(value_2) > 0
ORDER BY commits DESC
LIMIT 10;
QUERY PLAN
LIMIT 10
');
explain_filter
---------------------------------------------------------------------
Limit
-> Sort
Sort Key: remote_scan.commits DESC
-> Custom Scan (Citus Adaptive)
Task Count: 4
Tasks Shown: One of 4
Task Count: N
Tasks Shown: One of N
-> Task
Node: host=localhost port=xxxxx dbname=regression
Node: host=localhost port=N dbname=regression
-> Limit
-> Sort
Sort Key: (sum(daily_uniques.value_2)) DESC
@ -1566,7 +1580,7 @@ LIMIT 10;
Sort Key: daily_uniques.user_id, (sum(daily_uniques.value_2)) DESC
-> HashAggregate
Group Key: daily_uniques.user_id
Filter: (sum(daily_uniques.value_2) > '0'::double precision)
Filter: (sum(daily_uniques.value_2) > 'N'::double precision)
-> Seq Scan on daily_uniques_xxxxxxx daily_uniques
(18 rows)

View File

@ -232,10 +232,12 @@ SELECT a, COUNT(*) OVER (PARTITION BY a) FROM partitioned_distributed_table ORDE
$Q$);
-- pull to coordinator WINDOW
select public.explain_filter('
SELECT public.coordinator_plan($Q$
EXPLAIN (COSTS OFF)
SELECT a, COUNT(*) OVER (PARTITION BY a+1) FROM partitioned_distributed_table ORDER BY 1,2;
$Q$);
$Q$)
');
-- FOR UPDATE
SELECT * FROM partitioned_distributed_table WHERE a = 1 ORDER BY 1,2 FOR UPDATE;

View File

@ -1137,17 +1137,21 @@ CREATE TABLE distributed_table_1(a int, b int);
SELECT create_distributed_table('distributed_table_1','a');
INSERT INTO distributed_table_1 values (1,1);
EXPLAIN :default_analyze_flags SELECT row_number() OVER() AS r FROM distributed_table_1;
select public.explain_filter('
EXPLAIN (ANALYZE on, COSTS off, TIMING off, SUMMARY off, BUFFERS off) SELECT row_number() OVER() AS r FROM distributed_table_1
');
CREATE TABLE distributed_table_2(a int, b int);
SELECT create_distributed_table('distributed_table_2','a');
INSERT INTO distributed_table_2 VALUES (1,1);
EXPLAIN :default_analyze_flags
select public.explain_filter('
EXPLAIN (ANALYZE on, COSTS off, TIMING off, SUMMARY off, BUFFERS off)
WITH r AS (SELECT row_number() OVER () AS r FROM distributed_table_1)
SELECT * FROM distributed_table_2
JOIN r ON (r = distributed_table_2.b)
LIMIT 3;
LIMIT 3
');
EXPLAIN :default_analyze_flags SELECT FROM (SELECT * FROM reference_table) subquery;

View File

@ -32,21 +32,27 @@ SELECT create_distributed_table('t2', 'account_id');
-- produces a non-empty varnullingrels set in PG 16 (and higher)
SELECT t1.id, MAX(t2.a2) OVER (PARTITION BY t2.id)
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
select public.explain_filter('
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT t1.id, MAX(t2.a2) OVER (PARTITION BY t2.id)
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
');
SELECT t1.id, MAX(t2.a2) OVER (PARTITION BY t2.id)
FROM t2 RIGHT OUTER JOIN t1 ON t1.id = t2.account_id;
select public.explain_filter('
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT t1.id, MAX(t2.a2) OVER (PARTITION BY t2.id)
FROM t2 RIGHT OUTER JOIN t1 ON t1.id = t2.account_id;
FROM t2 RIGHT OUTER JOIN t1 ON t1.id = t2.account_id
');
SELECT DISTINCT t1.id, MAX(t2.a2) OVER (PARTITION BY t2.id)
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
select public.explain_filter('
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT DISTINCT t1.id, MAX(t2.a2) OVER (PARTITION BY t2.id)
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
');
CREATE SEQUENCE test_seq START 101;
CREATE OR REPLACE FUNCTION TEST_F(int) returns INT language sql stable as $$ select $1 + 42; $$ ;
@ -86,10 +92,12 @@ FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id;
SELECT 1
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
HAVING COUNT(DISTINCT a2) > 1;
select public.explain_filter('
EXPLAIN (VERBOSE, COSTS OFF, TIMING OFF)
SELECT 1
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.account_id
HAVING COUNT(DISTINCT a2) > 1;
');
-- Check right outer join
SELECT COUNT(DISTINCT a2)

View File

@ -441,6 +441,7 @@ ORDER BY
LIMIT
5;
select public.explain_filter('
EXPLAIN (COSTS FALSE)
SELECT *
FROM (
@ -474,7 +475,8 @@ EXPLAIN (COSTS FALSE)
GROUP BY
user_id)) AS ftop
ORDER BY 2 DESC, 1 DESC
LIMIT 5;
LIMIT 5
');
-- test with window functions which aren't pushed down
SELECT

View File

@ -508,6 +508,7 @@ FROM
GROUP BY user_id, value_2
ORDER BY user_id, avg(value_1) DESC;
select public.explain_filter('
EXPLAIN (COSTS FALSE)
SELECT
user_id,
@ -516,7 +517,8 @@ SELECT
FROM
users_table
GROUP BY user_id, value_2
ORDER BY user_id, avg(value_1) DESC;
ORDER BY user_id, avg(value_1) DESC
');
-- order by in the window function is same as avg(value_1) DESC
SELECT
@ -529,6 +531,7 @@ GROUP BY user_id, value_2
ORDER BY user_id, avg(value_1) DESC;
-- limit is not pushed down to worker !!
select public.explain_filter('
EXPLAIN (COSTS FALSE)
SELECT
user_id,
@ -538,8 +541,10 @@ FROM
users_table
GROUP BY user_id, value_2
ORDER BY user_id, avg(value_1) DESC
LIMIT 5;
LIMIT 5
');
select public.explain_filter('
EXPLAIN (COSTS FALSE)
SELECT
user_id,
@ -549,8 +554,10 @@ FROM
users_table
GROUP BY user_id, value_2
ORDER BY user_id, avg(value_1) DESC
LIMIT 5;
LIMIT 5
');
select public.explain_filter('
EXPLAIN (COSTS FALSE)
SELECT
user_id,
@ -560,8 +567,10 @@ FROM
users_table
GROUP BY user_id, value_2
ORDER BY user_id, avg(value_1) DESC
LIMIT 5;
LIMIT 5
');
select public.explain_filter('
EXPLAIN (COSTS FALSE)
SELECT
user_id,
@ -571,12 +580,15 @@ FROM
users_table
GROUP BY user_id, value_2
ORDER BY user_id, avg(value_1) DESC
LIMIT 5;
LIMIT 5
');
-- Grouping can be pushed down with aggregates even when window function can't
select public.explain_filter('
EXPLAIN (COSTS FALSE)
SELECT user_id, count(value_1), stddev(value_1), count(user_id) OVER (PARTITION BY random())
FROM users_table GROUP BY user_id HAVING avg(value_1) > 2 LIMIT 1;
FROM users_table GROUP BY user_id HAVING avg(value_1) > 2 LIMIT 1
');
-- Window function with inlined CTE
WITH cte as (
@ -594,6 +606,7 @@ ORDER BY 1;
CREATE TABLE daily_uniques (value_2 float, user_id bigint);
SELECT create_distributed_table('daily_uniques', 'user_id');
select public.explain_filter('
EXPLAIN (COSTS FALSE) SELECT
user_id,
sum(value_2) AS commits,
@ -607,7 +620,8 @@ GROUP BY user_id
HAVING
sum(value_2) > 0
ORDER BY commits DESC
LIMIT 10;
LIMIT 10
');
DROP TABLE daily_uniques;