-- =================================================================== -- test recursive planning functionality with Set Operations and CTEs -- =================================================================== SET client_min_messages TO DEBUG1; -- use ctes inside unions on the top level WITH cte_1 AS (SELECT user_id FROM users_table), cte_2 AS (SELECT user_id FROM events_table) (SELECT * FROM cte_1) UNION (SELECT * FROM cte_2) ORDER BY 1 DESC; DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_2 is going to be inlined via distributed planning DEBUG: generating subplan XXX_1 for subquery SELECT user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 DEBUG: generating subplan XXX_2 for subquery SELECT user_id FROM (SELECT events_table.user_id FROM public.events_table) cte_2 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) UNION SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) ORDER BY 1 DESC user_id --------------------------------------------------------------------- 6 5 4 3 2 1 (6 rows) -- use ctes inside unions in a subquery WITH cte_1 AS (SELECT user_id FROM users_table), cte_2 AS (SELECT user_id FROM events_table) SELECT count(*) FROM ( (SELECT * FROM cte_1) UNION (SELECT * FROM cte_2) ) as foo; DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_2 is going to be inlined via distributed planning count --------------------------------------------------------------------- 6 (1 row) -- cte with unions of other ctes WITH cte_1 AS (SELECT user_id FROM users_table), cte_2 AS (SELECT user_id FROM events_table), cte_3 AS ((SELECT * FROM cte_1) UNION (SELECT * FROM cte_2)) SELECT * FROM cte_3 ORDER BY 1 DESC; DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_2 is going to be inlined via distributed planning DEBUG: CTE cte_3 is going to be inlined via distributed planning user_id --------------------------------------------------------------------- 6 5 4 3 2 1 (6 rows) -- cte with unions of distributed table WITH cte_1 AS ((SELECT user_id FROM users_table) UNION (SELECT user_id FROM users_table)) SELECT * FROM cte_1 ORDER BY 1 DESC; DEBUG: CTE cte_1 is going to be inlined via distributed planning user_id --------------------------------------------------------------------- 6 5 4 3 2 1 (6 rows) -- cte with unions of tables is intersected with another query WITH cte_1 AS ((SELECT user_id FROM users_table) UNION (SELECT user_id FROM users_table)) (SELECT * FROM cte_1) INTERSECT (SELECT user_id FROM users_table) ORDER BY 1 DESC; DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: generating subplan XXX_1 for subquery SELECT user_id FROM (SELECT users_table.user_id FROM public.users_table UNION SELECT users_table.user_id FROM public.users_table) cte_1 DEBUG: generating subplan XXX_2 for subquery SELECT user_id FROM public.users_table DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) INTERSECT SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) ORDER BY 1 DESC user_id --------------------------------------------------------------------- 6 5 4 3 2 1 (6 rows) -- cte with unions of tables is intersected with another query that involves except WITH cte_1 AS ((SELECT user_id FROM users_table) UNION (SELECT user_id FROM users_table)) (SELECT * FROM cte_1) INTERSECT ((SELECT user_id FROM events_table WHERE user_id < 3) EXCEPT (SELECT user_id FROM users_table WHERE user_id > 4)) ORDER BY 1 DESC; DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: generating subplan XXX_1 for subquery SELECT user_id FROM (SELECT users_table.user_id FROM public.users_table UNION SELECT users_table.user_id FROM public.users_table) cte_1 DEBUG: generating subplan XXX_2 for subquery SELECT user_id FROM public.events_table WHERE (user_id OPERATOR(pg_catalog.<) 3) DEBUG: generating subplan XXX_3 for subquery SELECT user_id FROM public.users_table WHERE (user_id OPERATOR(pg_catalog.>) 4) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) INTERSECT (SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) EXCEPT SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) ORDER BY 1 DESC user_id --------------------------------------------------------------------- 2 1 (2 rows) -- CTE inside a top level EXCEPT (WITH cte_1 AS (SELECT user_id FROM events_table WHERE user_id < 3) SELECT * FROM cte_1) INTERSECT (SELECT user_id FROM users_table) ORDER BY 1; DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: generating subplan XXX_1 for subquery SELECT user_id FROM (SELECT events_table.user_id FROM public.events_table WHERE (events_table.user_id OPERATOR(pg_catalog.<) 3)) cte_1 DEBUG: generating subplan XXX_2 for subquery SELECT user_id FROM public.users_table DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) INTERSECT SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) ORDER BY 1 user_id --------------------------------------------------------------------- 1 2 (2 rows) -- INTERSECT inside a CTE, which is inside a subquery SELECT DISTINCT users_table.user_id FROM users_table, (WITH cte_1 AS (SELECT user_id FROM events_table WHERE user_id < 3 INTERSECT SELECT user_id FROM events_table WHERE user_id < 2) SELECT * FROM cte_1) as foo WHERE users_table.user_id = foo.user_id ORDER BY 1 DESC; DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: generating subplan XXX_1 for subquery SELECT user_id FROM public.events_table WHERE (user_id OPERATOR(pg_catalog.<) 3) DEBUG: generating subplan XXX_2 for subquery SELECT user_id FROM public.events_table WHERE (user_id OPERATOR(pg_catalog.<) 2) DEBUG: generating subplan XXX_3 for subquery SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) INTERSECT SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT DISTINCT users_table.user_id FROM public.users_table, (SELECT cte_1.user_id FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) cte_1) foo WHERE (users_table.user_id OPERATOR(pg_catalog.=) foo.user_id) ORDER BY users_table.user_id DESC user_id --------------------------------------------------------------------- 1 (1 row) -- UNION is created via outputs of CTEs, which is inside a subquery -- and the subquery is joined with a distributed table SELECT count(*) FROM events_table, ( WITH cte_1 AS (SELECT user_id FROM users_table), cte_2 AS (SELECT user_id FROM events_table) (SELECT * FROM cte_1) UNION (SELECT * FROM cte_2) ) as foo WHERE foo.user_id = events_table.event_type; DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_2 is going to be inlined via distributed planning DEBUG: generating subplan XXX_1 for subquery SELECT user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 DEBUG: generating subplan XXX_2 for subquery SELECT user_id FROM (SELECT events_table.user_id FROM public.events_table) cte_2 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) UNION SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) DEBUG: generating subplan XXX_1 for subquery SELECT cte_1.user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 UNION SELECT cte_2.user_id FROM (SELECT events_table.user_id FROM public.events_table) cte_2 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM public.events_table, (SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) foo WHERE (foo.user_id OPERATOR(pg_catalog.=) events_table.event_type) count --------------------------------------------------------------------- 95 (1 row) -- joins inside unions that are safe to pushdown (SELECT DISTINCT events_table.user_id FROM users_table, events_table WHERE users_table.user_id = events_table.user_id ) INTERSECT (SELECT DISTINCT events_table.user_id FROM users_table, events_table WHERE users_table.user_id = events_table.user_id ) ORDER BY 1 DESC; DEBUG: generating subplan XXX_1 for subquery SELECT DISTINCT events_table.user_id FROM public.users_table, public.events_table WHERE (users_table.user_id OPERATOR(pg_catalog.=) events_table.user_id) DEBUG: generating subplan XXX_2 for subquery SELECT DISTINCT events_table.user_id FROM public.users_table, public.events_table WHERE (users_table.user_id OPERATOR(pg_catalog.=) events_table.user_id) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) INTERSECT SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) ORDER BY 1 DESC user_id --------------------------------------------------------------------- 6 5 4 3 2 1 (6 rows) -- joins inside unions that are not safe to pushdown (SELECT DISTINCT events_table.user_id FROM users_table, events_table WHERE users_table.user_id = events_table.user_id LIMIT 10) INTERSECT (SELECT DISTINCT events_table.user_id FROM users_table, events_table WHERE users_table.user_id = events_table.user_id LIMIT 10) ORDER BY 1 DESC; DEBUG: push down of limit count: 10 DEBUG: generating subplan XXX_1 for subquery SELECT DISTINCT events_table.user_id FROM public.users_table, public.events_table WHERE (users_table.user_id OPERATOR(pg_catalog.=) events_table.user_id) LIMIT 10 DEBUG: push down of limit count: 10 DEBUG: generating subplan XXX_2 for subquery SELECT DISTINCT events_table.user_id FROM public.users_table, public.events_table WHERE (users_table.user_id OPERATOR(pg_catalog.=) events_table.user_id) LIMIT 10 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) INTERSECT SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) ORDER BY 1 DESC user_id --------------------------------------------------------------------- 6 5 4 3 2 1 (6 rows) -- joins inside unions that are not safe to pushdown inside a subquery SELECT count(*) FROM (SELECT DISTINCT value_2 FROM events_table) as events_table, (WITH foo AS ((SELECT DISTINCT events_table.user_id FROM users_table, events_table WHERE users_table.user_id = events_table.user_id ) INTERSECT (SELECT DISTINCT events_table.user_id FROM users_table, events_table WHERE users_table.user_id = events_table.user_id LIMIT 10)) SELECT * FROM foo) as foo WHERE foo.user_id = events_table.value_2; DEBUG: CTE foo is going to be inlined via distributed planning DEBUG: generating subplan XXX_1 for subquery SELECT DISTINCT value_2 FROM public.events_table DEBUG: push down of limit count: 10 DEBUG: generating subplan XXX_2 for subquery SELECT DISTINCT events_table.user_id FROM public.users_table, public.events_table WHERE (users_table.user_id OPERATOR(pg_catalog.=) events_table.user_id) LIMIT 10 DEBUG: generating subplan XXX_3 for subquery SELECT DISTINCT events_table.user_id FROM public.users_table, public.events_table WHERE (users_table.user_id OPERATOR(pg_catalog.=) events_table.user_id) DEBUG: generating subplan XXX_4 for subquery SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) INTERSECT SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) events_table, (SELECT foo_1.user_id FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) foo_1) foo WHERE (foo.user_id OPERATOR(pg_catalog.=) events_table.value_2) count --------------------------------------------------------------------- 5 (1 row) -- joins inside unions some safe to pushdown SELECT count(*) FROM (WITH events_table AS (SELECT DISTINCT user_id FROM events_table) SELECT * FROM events_table) as events_table, ((SELECT DISTINCT events_table.user_id FROM users_table, events_table WHERE users_table.user_id = events_table.user_id ) INTERSECT (SELECT DISTINCT events_table.user_id FROM users_table, events_table WHERE users_table.user_id = events_table.user_id LIMIT 10)) as foo WHERE foo.user_id = events_table.user_id; DEBUG: CTE events_table is going to be inlined via distributed planning DEBUG: push down of limit count: 10 DEBUG: generating subplan XXX_1 for subquery SELECT DISTINCT events_table.user_id FROM public.users_table, public.events_table WHERE (users_table.user_id OPERATOR(pg_catalog.=) events_table.user_id) LIMIT 10 DEBUG: generating subplan XXX_2 for subquery SELECT DISTINCT events_table.user_id FROM public.users_table, public.events_table WHERE (users_table.user_id OPERATOR(pg_catalog.=) events_table.user_id) DEBUG: generating subplan XXX_3 for subquery SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) INTERSECT SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT events_table_1.user_id FROM (SELECT DISTINCT events_table_2.user_id FROM public.events_table events_table_2) events_table_1) events_table, (SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) foo WHERE (foo.user_id OPERATOR(pg_catalog.=) events_table.user_id) count --------------------------------------------------------------------- 6 (1 row) -- CTE inside unions (WITH cte_1 AS (SELECT user_id FROM users_table) SELECT * FROM cte_1) UNION (WITH cte_1 AS (SELECT user_id FROM users_table) SELECT * FROM cte_1) ORDER BY 1 DESC; DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: generating subplan XXX_1 for subquery SELECT user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 DEBUG: generating subplan XXX_2 for subquery SELECT user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) UNION SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) ORDER BY 1 DESC user_id --------------------------------------------------------------------- 6 5 4 3 2 1 (6 rows) -- more complex CTEs inside unions SELECT count(*) FROM ( (WITH cte_1 AS (SELECT user_id FROM users_table) SELECT * FROM cte_1) UNION (WITH cte_1 AS (SELECT user_id FROM users_table) SELECT * FROM cte_1) ) as foo, users_table WHERE users_table.value_2 = foo.user_id; DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: generating subplan XXX_1 for subquery SELECT user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 DEBUG: generating subplan XXX_2 for subquery SELECT user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) UNION SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) DEBUG: generating subplan XXX_1 for subquery SELECT cte_1.user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 UNION SELECT cte_1.user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) foo, public.users_table WHERE (users_table.value_2 OPERATOR(pg_catalog.=) foo.user_id) count --------------------------------------------------------------------- 92 (1 row) -- CTEs with less alias than the input subquery (WITH cte_1(x) AS (SELECT user_id, value_2 FROM users_table) SELECT * FROM cte_1) UNION (WITH cte_1(x) AS (SELECT user_id, value_2 FROM users_table) SELECT * FROM cte_1) ORDER BY 1 DESC, 2 DESC LIMIT 5; DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: generating subplan XXX_1 for subquery SELECT x, value_2 FROM (SELECT users_table.user_id AS x, users_table.value_2 FROM public.users_table) cte_1 DEBUG: generating subplan XXX_2 for subquery SELECT x, value_2 FROM (SELECT users_table.user_id AS x, users_table.value_2 FROM public.users_table) cte_1 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, value_2 integer) UNION SELECT intermediate_result.x, intermediate_result.value_2 FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, value_2 integer) ORDER BY 1 DESC, 2 DESC LIMIT 5 x | value_2 --------------------------------------------------------------------- 6 | 6 | 4 6 | 3 6 | 2 6 | 1 (5 rows) -- simple subqueries in WHERE with unions SELECT count(*) FROM users_table WHERE value_2 IN ( WITH cte_1 AS ( (SELECT user_id FROM users_table) UNION (SELECT user_id FROM events_table) ) SELECT DISTINCT user_id FROM cte_1 ) ORDER BY 1 DESC; DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: generating subplan XXX_1 for subquery SELECT DISTINCT user_id FROM (SELECT users_table.user_id FROM public.users_table UNION SELECT events_table.user_id FROM public.events_table) cte_1 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM public.users_table WHERE (value_2 OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer))) ORDER BY (count(*)) DESC count --------------------------------------------------------------------- 92 (1 row) -- simple subqueries in WHERE with unions and ctes SELECT count(*) FROM users_table WHERE value_2 IN ( WITH cte_1 AS (SELECT user_id FROM users_table), cte_2 AS (SELECT user_id FROM events_table) (SELECT * FROM cte_1) UNION (SELECT * FROM cte_2) ) ORDER BY 1 DESC; DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_2 is going to be inlined via distributed planning DEBUG: generating subplan XXX_1 for subquery SELECT user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 DEBUG: generating subplan XXX_2 for subquery SELECT user_id FROM (SELECT events_table.user_id FROM public.events_table) cte_2 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) UNION SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) DEBUG: generating subplan XXX_1 for subquery SELECT cte_1.user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 UNION SELECT cte_2.user_id FROM (SELECT events_table.user_id FROM public.events_table) cte_2 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM public.users_table WHERE (value_2 OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer))) ORDER BY (count(*)) DESC count --------------------------------------------------------------------- 92 (1 row) -- unions and ctes inside subqueries in where clause with a pushdownable correlated subquery SELECT DISTINCT user_id FROM events_table WHERE event_type IN ( SELECT users_table.user_id FROM ( (WITH cte_1 AS (SELECT user_id FROM users_table) SELECT * FROM cte_1) UNION (WITH cte_1 AS (SELECT user_id FROM users_table) SELECT * FROM cte_1) ) as foo, users_table WHERE users_table.value_2 = foo.user_id AND events_table.user_id = users_table.user_id ) ORDER BY 1 DESC; DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: generating subplan XXX_1 for subquery SELECT user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 DEBUG: generating subplan XXX_2 for subquery SELECT user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) UNION SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) DEBUG: generating subplan XXX_1 for subquery SELECT cte_1.user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 UNION SELECT cte_1.user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT DISTINCT user_id FROM public.events_table WHERE (event_type OPERATOR(pg_catalog.=) ANY (SELECT users_table.user_id FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) foo, public.users_table WHERE ((users_table.value_2 OPERATOR(pg_catalog.=) foo.user_id) AND (events_table.user_id OPERATOR(pg_catalog.=) users_table.user_id)))) ORDER BY user_id DESC user_id --------------------------------------------------------------------- 5 4 3 2 1 (5 rows) -- unions and ctes inside subqueries in where clause with a not pushdownable correlated subquery -- should error out SELECT DISTINCT user_id FROM events_table WHERE event_type IN ( SELECT users_table.user_id FROM ( (WITH cte_1 AS (SELECT user_id FROM users_table) SELECT * FROM cte_1) UNION (WITH cte_1 AS (SELECT user_id FROM users_table) SELECT * FROM cte_1) ) as foo, users_table WHERE users_table.value_2 = foo.user_id AND events_table.user_id = users_table.user_id LIMIT 5 ) ORDER BY 1 DESC; DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: generating subplan XXX_1 for subquery SELECT user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 DEBUG: generating subplan XXX_2 for subquery SELECT user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) UNION SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) DEBUG: generating subplan XXX_1 for subquery SELECT cte_1.user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 UNION SELECT cte_1.user_id FROM (SELECT users_table.user_id FROM public.users_table) cte_1 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT DISTINCT user_id FROM public.events_table WHERE (event_type OPERATOR(pg_catalog.=) ANY (SELECT users_table.user_id FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) foo, public.users_table WHERE ((users_table.value_2 OPERATOR(pg_catalog.=) foo.user_id) AND (events_table.user_id OPERATOR(pg_catalog.=) users_table.user_id)) LIMIT 5)) ORDER BY user_id DESC user_id --------------------------------------------------------------------- 5 4 3 2 1 (5 rows) SET client_min_messages TO DEFAULT; SET search_path TO public;