diff --git a/src/test/regress/expected/subquery_basics.out b/src/test/regress/expected/subquery_basics.out index a138b596d..e6f39da79 100644 --- a/src/test/regress/expected/subquery_basics.out +++ b/src/test/regress/expected/subquery_basics.out @@ -83,6 +83,73 @@ DEBUG: Plan 5 query after replacing subqueries and CTEs: SELECT value_2, avg FR 0 | 2.0940170940170940 (6 rows) +-- subqueries with only generate_series +SELECT + * +FROM + (SELECT + events_table.value_2 + FROM + events_table + WHERE + event_type IN (1,2,3,4) + ORDER BY 1 DESC + LIMIT 5 + ) as foo, + ( + SELECT i FROM generate_series(0, 100) i + ) as bar + WHERE foo.value_2 = bar.i + ORDER BY 2 DESC, 1; +DEBUG: push down of limit count: 5 +DEBUG: generating subplan 7_1 for subquery SELECT value_2 FROM public.events_table WHERE (event_type = ANY (ARRAY[1, 2, 3, 4])) ORDER BY value_2 DESC LIMIT 5 +DEBUG: Plan 7 query after replacing subqueries and CTEs: SELECT foo.value_2, bar.i FROM (SELECT intermediate_result.value_2 FROM read_intermediate_result('7_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) foo, (SELECT i.i FROM generate_series(0, 100) i(i)) bar WHERE (foo.value_2 = bar.i) ORDER BY bar.i DESC, foo.value_2 + value_2 | i +---------+--- + 5 | 5 + 5 | 5 + 5 | 5 + 5 | 5 + 5 | 5 +(5 rows) + +-- subquery with aggregates without GROUP BY +SELECT + * +FROM + (SELECT + count(*) + FROM + events_table + WHERE + event_type IN (1,2,3,4) + ) as foo; +DEBUG: generating subplan 9_1 for subquery SELECT count(*) AS count FROM public.events_table WHERE (event_type = ANY (ARRAY[1, 2, 3, 4])) +DEBUG: Plan 9 query after replacing subqueries and CTEs: SELECT count FROM (SELECT intermediate_result.count FROM read_intermediate_result('9_1'::text, 'binary'::citus_copy_format) intermediate_result(count bigint)) foo + count +------- + 87 +(1 row) + +-- subquery having without GROUP BY +SELECT + * +FROM + (SELECT + SUM(events_table.user_id) + FROM + events_table + WHERE + event_type IN (1,2,3,4) + HAVING + MIN(value_2) > 2 + ) as foo; +DEBUG: generating subplan 11_1 for subquery SELECT sum(user_id) AS sum FROM public.events_table WHERE (event_type = ANY (ARRAY[1, 2, 3, 4])) HAVING (min(value_2) > 2) +DEBUG: Plan 11 query after replacing subqueries and CTEs: SELECT sum FROM (SELECT intermediate_result.sum FROM read_intermediate_result('11_1'::text, 'binary'::citus_copy_format) intermediate_result(sum bigint)) foo + sum +----- +(0 rows) + -- multiple subqueries in FROM clause should be replaced -- and the final query is router query SELECT @@ -110,9 +177,9 @@ FROM ) as bar WHERE foo.value_2 = bar.value_3 ORDER BY 2 DESC, 1; -DEBUG: generating subplan 7_1 for subquery SELECT users_table.value_2 FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4]))) GROUP BY users_table.value_2 ORDER BY users_table.value_2 DESC -DEBUG: generating subplan 7_2 for subquery SELECT users_table.value_3 FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[5, 6, 7, 8]))) GROUP BY users_table.value_3 ORDER BY users_table.value_3 DESC -DEBUG: Plan 7 query after replacing subqueries and CTEs: SELECT foo.value_2, bar.value_3 FROM (SELECT intermediate_result.value_2 FROM read_intermediate_result('7_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) foo, (SELECT intermediate_result.value_3 FROM read_intermediate_result('7_2'::text, 'binary'::citus_copy_format) intermediate_result(value_3 double precision)) bar WHERE ((foo.value_2)::double precision = bar.value_3) ORDER BY bar.value_3 DESC, foo.value_2 +DEBUG: generating subplan 13_1 for subquery SELECT users_table.value_2 FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4]))) GROUP BY users_table.value_2 ORDER BY users_table.value_2 DESC +DEBUG: generating subplan 13_2 for subquery SELECT users_table.value_3 FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[5, 6, 7, 8]))) GROUP BY users_table.value_3 ORDER BY users_table.value_3 DESC +DEBUG: Plan 13 query after replacing subqueries and CTEs: SELECT foo.value_2, bar.value_3 FROM (SELECT intermediate_result.value_2 FROM read_intermediate_result('13_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) foo, (SELECT intermediate_result.value_3 FROM read_intermediate_result('13_2'::text, 'binary'::citus_copy_format) intermediate_result(value_3 double precision)) bar WHERE ((foo.value_2)::double precision = bar.value_3) ORDER BY bar.value_3 DESC, foo.value_2 value_2 | value_3 ---------+--------- 5 | 5 @@ -149,8 +216,8 @@ FROM WHERE foo.postgres = bar.citus ORDER BY 1 DESC, 2 DESC LIMIT 3; -DEBUG: generating subplan 10_1 for subquery SELECT users_table.value_2 FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4]))) GROUP BY users_table.value_2 ORDER BY users_table.value_2 DESC -DEBUG: Plan 10 query after replacing subqueries and CTEs: SELECT DISTINCT ON (bar.citus) bar.citus, foo.postgres, (bar.citus + 1) AS c1, (foo.postgres - 1) AS p1 FROM (SELECT intermediate_result.value_2 FROM read_intermediate_result('10_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) foo(postgres), (SELECT users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[5, 6, 7, 8]))) ORDER BY users_table.user_id DESC) bar(citus) WHERE (foo.postgres = bar.citus) ORDER BY bar.citus DESC, foo.postgres DESC LIMIT 3 +DEBUG: generating subplan 16_1 for subquery SELECT users_table.value_2 FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4]))) GROUP BY users_table.value_2 ORDER BY users_table.value_2 DESC +DEBUG: Plan 16 query after replacing subqueries and CTEs: SELECT DISTINCT ON (bar.citus) bar.citus, foo.postgres, (bar.citus + 1) AS c1, (foo.postgres - 1) AS p1 FROM (SELECT intermediate_result.value_2 FROM read_intermediate_result('16_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) foo(postgres), (SELECT users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[5, 6, 7, 8]))) ORDER BY users_table.user_id DESC) bar(citus) WHERE (foo.postgres = bar.citus) ORDER BY bar.citus DESC, foo.postgres DESC LIMIT 3 DEBUG: push down of limit count: 3 citus | postgres | c1 | p1 -------+----------+----+---- @@ -186,8 +253,8 @@ FROM WHERE foo.value_2 = bar.user_id ORDER BY 2 DESC, 1 DESC LIMIT 3; -DEBUG: generating subplan 12_1 for subquery SELECT users_table.value_2 FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4]))) GROUP BY users_table.value_2 ORDER BY users_table.value_2 DESC -DEBUG: Plan 12 query after replacing subqueries and CTEs: SELECT foo.value_2, bar.user_id FROM (SELECT intermediate_result.value_2 FROM read_intermediate_result('12_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) foo, (SELECT users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[5, 6, 7, 8]))) ORDER BY users_table.user_id DESC) bar WHERE (foo.value_2 = bar.user_id) ORDER BY bar.user_id DESC, foo.value_2 DESC LIMIT 3 +DEBUG: generating subplan 18_1 for subquery SELECT users_table.value_2 FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4]))) GROUP BY users_table.value_2 ORDER BY users_table.value_2 DESC +DEBUG: Plan 18 query after replacing subqueries and CTEs: SELECT foo.value_2, bar.user_id FROM (SELECT intermediate_result.value_2 FROM read_intermediate_result('18_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) foo, (SELECT users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[5, 6, 7, 8]))) ORDER BY users_table.user_id DESC) bar WHERE (foo.value_2 = bar.user_id) ORDER BY bar.user_id DESC, foo.value_2 DESC LIMIT 3 DEBUG: push down of limit count: 3 value_2 | user_id ---------+--------- @@ -203,8 +270,8 @@ WHERE user_id IN (SELECT DISTINCT value_2 FROM users_table WHERE value_1 >= 1 AND value_1 <= 20 ORDER BY 1 LIMIT 5) ORDER BY 1 DESC; DEBUG: push down of limit count: 5 -DEBUG: generating subplan 14_1 for subquery SELECT DISTINCT value_2 FROM public.users_table WHERE ((value_1 >= 1) AND (value_1 <= 20)) ORDER BY value_2 LIMIT 5 -DEBUG: Plan 14 query after replacing subqueries and CTEs: SELECT DISTINCT user_id FROM public.users_table WHERE (user_id IN (SELECT intermediate_result.value_2 FROM read_intermediate_result('14_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer))) ORDER BY user_id DESC +DEBUG: generating subplan 20_1 for subquery SELECT DISTINCT value_2 FROM public.users_table WHERE ((value_1 >= 1) AND (value_1 <= 20)) ORDER BY value_2 LIMIT 5 +DEBUG: Plan 20 query after replacing subqueries and CTEs: SELECT DISTINCT user_id FROM public.users_table WHERE (user_id IN (SELECT intermediate_result.value_2 FROM read_intermediate_result('20_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer))) ORDER BY user_id DESC user_id --------- 4 @@ -232,8 +299,8 @@ FROM ) as sub1 ORDER BY 1 DESC LIMIT 3; -DEBUG: generating subplan 16_1 for subquery SELECT user_id, event_type FROM public.events_table WHERE (value_2 < 3) OFFSET 3 -DEBUG: Plan 16 query after replacing subqueries and CTEs: SELECT DISTINCT user_id FROM (SELECT users_table.user_id FROM public.users_table, (SELECT bar.event_type, bar.user_id FROM (SELECT foo.event_type, users_table_1.user_id FROM public.users_table users_table_1, (SELECT intermediate_result.user_id, intermediate_result.event_type FROM read_intermediate_result('16_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, event_type integer)) foo WHERE (foo.user_id = users_table_1.user_id)) bar) baz WHERE (baz.user_id = users_table.user_id)) sub1 ORDER BY user_id DESC LIMIT 3 +DEBUG: generating subplan 22_1 for subquery SELECT user_id, event_type FROM public.events_table WHERE (value_2 < 3) OFFSET 3 +DEBUG: Plan 22 query after replacing subqueries and CTEs: SELECT DISTINCT user_id FROM (SELECT users_table.user_id FROM public.users_table, (SELECT bar.event_type, bar.user_id FROM (SELECT foo.event_type, users_table_1.user_id FROM public.users_table users_table_1, (SELECT intermediate_result.user_id, intermediate_result.event_type FROM read_intermediate_result('22_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, event_type integer)) foo WHERE (foo.user_id = users_table_1.user_id)) bar) baz WHERE (baz.user_id = users_table.user_id)) sub1 ORDER BY user_id DESC LIMIT 3 DEBUG: push down of limit count: 3 user_id --------- @@ -269,8 +336,8 @@ FROM ( ) q ORDER BY 2 DESC, 1; DEBUG: push down of limit count: 5 -DEBUG: generating subplan 18_1 for subquery SELECT user_id FROM public.users_table WHERE ((value_2 >= 5) AND (EXISTS (SELECT events_table.user_id FROM public.events_table WHERE ((events_table.event_type > 1) AND (events_table.event_type <= 3) AND (events_table.value_3 > (1)::double precision) AND (events_table.user_id = users_table.user_id)))) AND (NOT (EXISTS (SELECT events_table.user_id FROM public.events_table WHERE ((events_table.event_type > 3) AND (events_table.event_type <= 4) AND (events_table.value_3 > (1)::double precision) AND (events_table.user_id = users_table.user_id)))))) LIMIT 5 -DEBUG: Plan 18 query after replacing subqueries and CTEs: SELECT user_id, array_length(events_table, 1) AS array_length FROM (SELECT t.user_id, array_agg(t.event ORDER BY t."time") AS events_table FROM (SELECT u.user_id, (e.event_type)::text AS event, e."time" FROM public.users_table u, public.events_table e WHERE ((u.user_id = e.user_id) AND (u.user_id IN (SELECT intermediate_result.user_id FROM read_intermediate_result('18_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer))))) t GROUP BY t.user_id) q ORDER BY (array_length(events_table, 1)) DESC, user_id +DEBUG: generating subplan 24_1 for subquery SELECT user_id FROM public.users_table WHERE ((value_2 >= 5) AND (EXISTS (SELECT events_table.user_id FROM public.events_table WHERE ((events_table.event_type > 1) AND (events_table.event_type <= 3) AND (events_table.value_3 > (1)::double precision) AND (events_table.user_id = users_table.user_id)))) AND (NOT (EXISTS (SELECT events_table.user_id FROM public.events_table WHERE ((events_table.event_type > 3) AND (events_table.event_type <= 4) AND (events_table.value_3 > (1)::double precision) AND (events_table.user_id = users_table.user_id)))))) LIMIT 5 +DEBUG: Plan 24 query after replacing subqueries and CTEs: SELECT user_id, array_length(events_table, 1) AS array_length FROM (SELECT t.user_id, array_agg(t.event ORDER BY t."time") AS events_table FROM (SELECT u.user_id, (e.event_type)::text AS event, e."time" FROM public.users_table u, public.events_table e WHERE ((u.user_id = e.user_id) AND (u.user_id IN (SELECT intermediate_result.user_id FROM read_intermediate_result('24_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer))))) t GROUP BY t.user_id) q ORDER BY (array_length(events_table, 1)) DESC, user_id user_id | array_length ---------+-------------- 5 | 364 @@ -347,8 +414,8 @@ GROUP BY user_id HAVING count(*) > 1 AND sum(value_2) > 29 ORDER BY 1; DEBUG: push down of limit count: 10 -DEBUG: generating subplan 20_1 for subquery SELECT user_id, count(*) AS count_pay FROM public.users_table WHERE ((user_id >= 1) AND (user_id <= 3) AND (value_1 > 3) AND (value_1 < 5)) GROUP BY user_id HAVING (count(*) > 1) LIMIT 10 -DEBUG: Plan 20 query after replacing subqueries and CTEs: SELECT user_id FROM public.users_table WHERE (user_id IN (SELECT subquery_top.user_id FROM (SELECT subquery_1.user_id, subquery_2.count_pay FROM ((SELECT users_table_1.user_id, 'action=>1'::text AS event, events_table."time" FROM public.users_table users_table_1, public.events_table WHERE ((users_table_1.user_id = events_table.user_id) AND (users_table_1.user_id >= 1) AND (users_table_1.user_id <= 3) AND (events_table.event_type > 1) AND (events_table.event_type < 3)) UNION SELECT users_table_1.user_id, 'action=>2'::text AS event, events_table."time" FROM public.users_table users_table_1, public.events_table WHERE ((users_table_1.user_id = events_table.user_id) AND (users_table_1.user_id >= 1) AND (users_table_1.user_id <= 3) AND (events_table.event_type > 2) AND (events_table.event_type < 4))) subquery_1 LEFT JOIN (SELECT intermediate_result.user_id, intermediate_result.count_pay FROM read_intermediate_result('20_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, count_pay bigint)) subquery_2 ON ((subquery_1.user_id = subquery_2.user_id))) GROUP BY subquery_1.user_id, subquery_2.count_pay) subquery_top GROUP BY subquery_top.count_pay, subquery_top.user_id)) GROUP BY user_id HAVING ((count(*) > 1) AND (sum(value_2) > 29)) ORDER BY user_id +DEBUG: generating subplan 26_1 for subquery SELECT user_id, count(*) AS count_pay FROM public.users_table WHERE ((user_id >= 1) AND (user_id <= 3) AND (value_1 > 3) AND (value_1 < 5)) GROUP BY user_id HAVING (count(*) > 1) LIMIT 10 +DEBUG: Plan 26 query after replacing subqueries and CTEs: SELECT user_id FROM public.users_table WHERE (user_id IN (SELECT subquery_top.user_id FROM (SELECT subquery_1.user_id, subquery_2.count_pay FROM ((SELECT users_table_1.user_id, 'action=>1'::text AS event, events_table."time" FROM public.users_table users_table_1, public.events_table WHERE ((users_table_1.user_id = events_table.user_id) AND (users_table_1.user_id >= 1) AND (users_table_1.user_id <= 3) AND (events_table.event_type > 1) AND (events_table.event_type < 3)) UNION SELECT users_table_1.user_id, 'action=>2'::text AS event, events_table."time" FROM public.users_table users_table_1, public.events_table WHERE ((users_table_1.user_id = events_table.user_id) AND (users_table_1.user_id >= 1) AND (users_table_1.user_id <= 3) AND (events_table.event_type > 2) AND (events_table.event_type < 4))) subquery_1 LEFT JOIN (SELECT intermediate_result.user_id, intermediate_result.count_pay FROM read_intermediate_result('26_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, count_pay bigint)) subquery_2 ON ((subquery_1.user_id = subquery_2.user_id))) GROUP BY subquery_1.user_id, subquery_2.count_pay) subquery_top GROUP BY subquery_top.count_pay, subquery_top.user_id)) GROUP BY user_id HAVING ((count(*) > 1) AND (sum(value_2) > 29)) ORDER BY user_id user_id --------- 2 diff --git a/src/test/regress/sql/subquery_basics.sql b/src/test/regress/sql/subquery_basics.sql index 877476824..fe482a2d1 100644 --- a/src/test/regress/sql/subquery_basics.sql +++ b/src/test/regress/sql/subquery_basics.sql @@ -53,6 +53,51 @@ FROM ) as foo ORDER BY 2 DESC, 1; +-- subqueries with only generate_series +SELECT + * +FROM + (SELECT + events_table.value_2 + FROM + events_table + WHERE + event_type IN (1,2,3,4) + ORDER BY 1 DESC + LIMIT 5 + ) as foo, + ( + SELECT i FROM generate_series(0, 100) i + ) as bar + WHERE foo.value_2 = bar.i + ORDER BY 2 DESC, 1; + +-- subquery with aggregates without GROUP BY +SELECT + * +FROM + (SELECT + count(*) + FROM + events_table + WHERE + event_type IN (1,2,3,4) + ) as foo; + +-- subquery having without GROUP BY +SELECT + * +FROM + (SELECT + SUM(events_table.user_id) + FROM + events_table + WHERE + event_type IN (1,2,3,4) + HAVING + MIN(value_2) > 2 + ) as foo; + -- multiple subqueries in FROM clause should be replaced -- and the final query is router query SELECT