-- ===================================================================
-- 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;
