diff --git a/src/test/regress/expected/mixed_relkind_tests.out b/src/test/regress/expected/mixed_relkind_tests.out index b2c30d1e4..a47c669ec 100644 --- a/src/test/regress/expected/mixed_relkind_tests.out +++ b/src/test/regress/expected/mixed_relkind_tests.out @@ -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 diff --git a/src/test/regress/expected/multi_explain.out b/src/test/regress/expected/multi_explain.out index 5d80f4ce4..38e5b1efb 100644 --- a/src/test/regress/expected/multi_explain.out +++ b/src/test/regress/expected/multi_explain.out @@ -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 diff --git a/src/test/regress/expected/multi_explain_0.out b/src/test/regress/expected/multi_explain_0.out index b7cdc0e11..0195abcf5 100644 --- a/src/test/regress/expected/multi_explain_0.out +++ b/src/test/regress/expected/multi_explain_0.out @@ -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 diff --git a/src/test/regress/expected/multi_outer_join_columns.out b/src/test/regress/expected/multi_outer_join_columns.out index 79527f7c6..02223f0f4 100644 --- a/src/test/regress/expected/multi_outer_join_columns.out +++ b/src/test/regress/expected/multi_outer_join_columns.out @@ -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 diff --git a/src/test/regress/expected/multi_outer_join_columns_1.out b/src/test/regress/expected/multi_outer_join_columns_1.out index 10dc6773d..54f6f71f3 100644 --- a/src/test/regress/expected/multi_outer_join_columns_1.out +++ b/src/test/regress/expected/multi_outer_join_columns_1.out @@ -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 diff --git a/src/test/regress/expected/multi_subquery_window_functions.out b/src/test/regress/expected/multi_subquery_window_functions.out index aa4249efc..ebd5c5f72 100644 --- a/src/test/regress/expected/multi_subquery_window_functions.out +++ b/src/test/regress/expected/multi_subquery_window_functions.out @@ -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 diff --git a/src/test/regress/expected/window_functions.out b/src/test/regress/expected/window_functions.out index d4718c4dd..a2fa1b376 100644 --- a/src/test/regress/expected/window_functions.out +++ b/src/test/regress/expected/window_functions.out @@ -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) diff --git a/src/test/regress/sql/mixed_relkind_tests.sql b/src/test/regress/sql/mixed_relkind_tests.sql index 6b7463cfd..e57f87875 100644 --- a/src/test/regress/sql/mixed_relkind_tests.sql +++ b/src/test/regress/sql/mixed_relkind_tests.sql @@ -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; diff --git a/src/test/regress/sql/multi_explain.sql b/src/test/regress/sql/multi_explain.sql index 437c54218..4dcb93bdf 100644 --- a/src/test/regress/sql/multi_explain.sql +++ b/src/test/regress/sql/multi_explain.sql @@ -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; diff --git a/src/test/regress/sql/multi_outer_join_columns.sql b/src/test/regress/sql/multi_outer_join_columns.sql index eec111cb5..b0f853f0b 100644 --- a/src/test/regress/sql/multi_outer_join_columns.sql +++ b/src/test/regress/sql/multi_outer_join_columns.sql @@ -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) diff --git a/src/test/regress/sql/multi_subquery_window_functions.sql b/src/test/regress/sql/multi_subquery_window_functions.sql index 706aa64fa..029ede00a 100644 --- a/src/test/regress/sql/multi_subquery_window_functions.sql +++ b/src/test/regress/sql/multi_subquery_window_functions.sql @@ -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 diff --git a/src/test/regress/sql/window_functions.sql b/src/test/regress/sql/window_functions.sql index 2f7ea18d2..5b0d9735d 100644 --- a/src/test/regress/sql/window_functions.sql +++ b/src/test/regress/sql/window_functions.sql @@ -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;