CREATE SCHEMA recursive_union; SET search_path TO recursive_union, public; CREATE TABLE recursive_union.test (x int, y int); SELECT create_distributed_table('test', 'x'); create_distributed_table -------------------------- (1 row) CREATE TABLE recursive_union.ref (a int, b int); SELECT create_reference_table('ref'); create_reference_table ------------------------ (1 row) INSERT INTO test VALUES (1,1), (2,2); INSERT INTO ref VALUES (2,2), (3,3); -- top-level set operations are supported through recursive planning SET client_min_messages TO DEBUG; (SELECT * FROM test) UNION (SELECT * FROM test) ORDER BY 1,2; DEBUG: generating subplan 3_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 3_2 for subquery SELECT x, y FROM recursive_union.test DEBUG: Plan 3 query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('3_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('3_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) ORDER BY 1, 2 DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 1 | 1 2 | 2 (2 rows) (SELECT * FROM test) UNION (SELECT * FROM ref) ORDER BY 1,2; DEBUG: generating subplan 6_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: Plan 6 query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('6_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT ref.a, ref.b FROM recursive_union.ref ORDER BY 1, 2 DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 1 | 1 2 | 2 3 | 3 (3 rows) (SELECT * FROM ref) UNION (SELECT * FROM ref) ORDER BY 1,2; DEBUG: Creating router plan DEBUG: Plan is router executable a | b ---+--- 2 | 2 3 | 3 (2 rows) (SELECT * FROM test) UNION ALL (SELECT * FROM test) ORDER BY 1,2; DEBUG: generating subplan 9_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 9_2 for subquery SELECT x, y FROM recursive_union.test DEBUG: Plan 9 query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('9_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION ALL SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('9_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) ORDER BY 1, 2 DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 1 | 1 1 | 1 2 | 2 2 | 2 (4 rows) (SELECT * FROM test) UNION ALL (SELECT * FROM ref) ORDER BY 1,2; DEBUG: generating subplan 12_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: Plan 12 query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('12_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION ALL SELECT ref.a, ref.b FROM recursive_union.ref ORDER BY 1, 2 DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 1 | 1 2 | 2 2 | 2 3 | 3 (4 rows) (SELECT * FROM ref) UNION ALL (SELECT * FROM ref) ORDER BY 1,2; DEBUG: Creating router plan DEBUG: Plan is router executable a | b ---+--- 2 | 2 2 | 2 3 | 3 3 | 3 (4 rows) (SELECT * FROM test) INTERSECT (SELECT * FROM test) ORDER BY 1,2; DEBUG: generating subplan 15_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 15_2 for subquery SELECT x, y FROM recursive_union.test DEBUG: Plan 15 query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('15_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) INTERSECT SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('15_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) ORDER BY 1, 2 DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 1 | 1 2 | 2 (2 rows) (SELECT * FROM test) INTERSECT (SELECT * FROM ref) ORDER BY 1,2; DEBUG: generating subplan 18_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: Plan 18 query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('18_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) INTERSECT SELECT ref.a, ref.b FROM recursive_union.ref ORDER BY 1, 2 DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 2 | 2 (1 row) (SELECT * FROM ref) INTERSECT (SELECT * FROM ref) ORDER BY 1,2; DEBUG: Creating router plan DEBUG: Plan is router executable a | b ---+--- 2 | 2 3 | 3 (2 rows) (SELECT * FROM test) INTERSECT ALL (SELECT * FROM test) ORDER BY 1,2; DEBUG: generating subplan 21_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 21_2 for subquery SELECT x, y FROM recursive_union.test DEBUG: Plan 21 query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('21_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) INTERSECT ALL SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('21_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) ORDER BY 1, 2 DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 1 | 1 2 | 2 (2 rows) (SELECT * FROM test) INTERSECT ALL (SELECT * FROM ref) ORDER BY 1,2; DEBUG: generating subplan 24_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: Plan 24 query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('24_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) INTERSECT ALL SELECT ref.a, ref.b FROM recursive_union.ref ORDER BY 1, 2 DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 2 | 2 (1 row) (SELECT * FROM ref) INTERSECT ALL (SELECT * FROM ref) ORDER BY 1,2; DEBUG: Creating router plan DEBUG: Plan is router executable a | b ---+--- 2 | 2 3 | 3 (2 rows) (SELECT * FROM test) EXCEPT (SELECT * FROM test) ORDER BY 1,2; DEBUG: generating subplan 27_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 27_2 for subquery SELECT x, y FROM recursive_union.test DEBUG: Plan 27 query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('27_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) EXCEPT SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('27_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) ORDER BY 1, 2 DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- (0 rows) (SELECT * FROM test) EXCEPT (SELECT * FROM ref) ORDER BY 1,2; DEBUG: generating subplan 30_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: Plan 30 query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('30_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) EXCEPT SELECT ref.a, ref.b FROM recursive_union.ref ORDER BY 1, 2 DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 1 | 1 (1 row) (SELECT * FROM ref) EXCEPT (SELECT * FROM ref) ORDER BY 1,2; DEBUG: Creating router plan DEBUG: Plan is router executable a | b ---+--- (0 rows) (SELECT * FROM test) EXCEPT ALL (SELECT * FROM test) ORDER BY 1,2; DEBUG: generating subplan 33_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 33_2 for subquery SELECT x, y FROM recursive_union.test DEBUG: Plan 33 query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('33_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) EXCEPT ALL SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('33_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) ORDER BY 1, 2 DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- (0 rows) (SELECT * FROM test) EXCEPT ALL (SELECT * FROM ref) ORDER BY 1,2; DEBUG: generating subplan 36_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: Plan 36 query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('36_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) EXCEPT ALL SELECT ref.a, ref.b FROM recursive_union.ref ORDER BY 1, 2 DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 1 | 1 (1 row) (SELECT * FROM ref) EXCEPT ALL (SELECT * FROM ref) ORDER BY 1,2; DEBUG: Creating router plan DEBUG: Plan is router executable a | b ---+--- (0 rows) -- more complex set operation trees are supported (SELECT * FROM test) INTERSECT (SELECT * FROM ref) UNION ALL (SELECT s, s FROM generate_series(1,10) s) EXCEPT (SELECT 1,1) UNION (SELECT test.x, ref.a FROM test LEFT JOIN ref ON (x = a)) ORDER BY 1,2; DEBUG: generating subplan 39_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 39_2 for subquery SELECT test.x, ref.a FROM (recursive_union.test LEFT JOIN recursive_union.ref ON ((test.x = ref.a))) DEBUG: Plan 39 query after replacing subqueries and CTEs: (((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('39_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) INTERSECT SELECT ref.a, ref.b FROM recursive_union.ref) UNION ALL SELECT s.s, s.s FROM generate_series(1, 10) s(s)) EXCEPT SELECT 1, 1) UNION SELECT intermediate_result.x, intermediate_result.a FROM read_intermediate_result('39_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, a integer) ORDER BY 1, 2 DEBUG: Creating router plan DEBUG: Plan is router executable x | y ----+---- 1 | 2 | 2 3 | 3 4 | 4 5 | 5 6 | 6 7 | 7 8 | 8 9 | 9 10 | 10 (10 rows) -- within a subquery, some unions can be pushed down SELECT * FROM ((SELECT * FROM test) UNION (SELECT * FROM test)) u ORDER BY 1,2; x | y ---+--- 1 | 1 2 | 2 (2 rows) SELECT * FROM ((SELECT x, y FROM test) UNION (SELECT y, x FROM test)) u ORDER BY 1,2; DEBUG: generating subplan 43_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 43_2 for subquery SELECT y, x FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 43_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('43_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT intermediate_result.y, intermediate_result.x FROM read_intermediate_result('43_2'::text, 'binary'::citus_copy_format) intermediate_result(y integer, x integer) DEBUG: Plan 43 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('43_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u ORDER BY x, y DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 1 | 1 2 | 2 (2 rows) SELECT * FROM ((SELECT * FROM test) UNION (SELECT * FROM ref)) u ORDER BY 1,2; DEBUG: generating subplan 47_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 47_2 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('47_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT ref.a, ref.b FROM recursive_union.ref DEBUG: Plan 47 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('47_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u ORDER BY x, y DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 1 | 1 2 | 2 3 | 3 (3 rows) SELECT * FROM ((SELECT * FROM ref) UNION (SELECT * FROM ref)) u ORDER BY 1,2; DEBUG: Creating router plan DEBUG: Plan is router executable a | b ---+--- 2 | 2 3 | 3 (2 rows) SELECT * FROM ((SELECT * FROM test) UNION ALL (SELECT * FROM test)) u ORDER BY 1,2; x | y ---+--- 1 | 1 1 | 1 2 | 2 2 | 2 (4 rows) SELECT * FROM ((SELECT x, y FROM test) UNION ALL (SELECT y, x FROM test)) u ORDER BY 1,2; x | y ---+--- 1 | 1 1 | 1 2 | 2 2 | 2 (4 rows) SELECT * FROM ((SELECT * FROM test) UNION ALL (SELECT * FROM ref)) u ORDER BY 1,2; DEBUG: generating subplan 53_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 53_2 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('53_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION ALL SELECT ref.a, ref.b FROM recursive_union.ref DEBUG: Plan 53 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('53_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u ORDER BY x, y DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 1 | 1 2 | 2 2 | 2 3 | 3 (4 rows) SELECT * FROM ((SELECT * FROM ref) UNION ALL (SELECT * FROM ref)) u ORDER BY 1,2; DEBUG: Creating router plan DEBUG: Plan is router executable a | b ---+--- 2 | 2 2 | 2 3 | 3 3 | 3 (4 rows) SELECT * FROM ((SELECT * FROM test) INTERSECT (SELECT * FROM test)) u ORDER BY 1,2; DEBUG: generating subplan 57_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 57_2 for subquery SELECT x, y FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 57_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('57_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) INTERSECT SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('57_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) DEBUG: Plan 57 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('57_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u ORDER BY x, y DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 1 | 1 2 | 2 (2 rows) SELECT * FROM ((SELECT x, y FROM test) INTERSECT (SELECT y, x FROM test)) u ORDER BY 1,2; DEBUG: generating subplan 61_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 61_2 for subquery SELECT y, x FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 61_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('61_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) INTERSECT SELECT intermediate_result.y, intermediate_result.x FROM read_intermediate_result('61_2'::text, 'binary'::citus_copy_format) intermediate_result(y integer, x integer) DEBUG: Plan 61 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('61_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u ORDER BY x, y DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 1 | 1 2 | 2 (2 rows) SELECT * FROM ((SELECT * FROM test) INTERSECT (SELECT * FROM ref)) u ORDER BY 1,2; DEBUG: generating subplan 65_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 65_2 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('65_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) INTERSECT SELECT ref.a, ref.b FROM recursive_union.ref DEBUG: Plan 65 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('65_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u ORDER BY x, y DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 2 | 2 (1 row) SELECT * FROM ((SELECT * FROM ref) INTERSECT (SELECT * FROM ref)) u ORDER BY 1,2; DEBUG: Creating router plan DEBUG: Plan is router executable a | b ---+--- 2 | 2 3 | 3 (2 rows) SELECT * FROM ((SELECT * FROM test) EXCEPT (SELECT * FROM test)) u ORDER BY 1,2; DEBUG: generating subplan 69_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 69_2 for subquery SELECT x, y FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 69_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('69_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) EXCEPT SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('69_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) DEBUG: Plan 69 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('69_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u ORDER BY x, y DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- (0 rows) SELECT * FROM ((SELECT x, y FROM test) EXCEPT (SELECT y, x FROM test)) u ORDER BY 1,2; DEBUG: generating subplan 73_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 73_2 for subquery SELECT y, x FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 73_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('73_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) EXCEPT SELECT intermediate_result.y, intermediate_result.x FROM read_intermediate_result('73_2'::text, 'binary'::citus_copy_format) intermediate_result(y integer, x integer) DEBUG: Plan 73 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('73_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u ORDER BY x, y DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- (0 rows) SELECT * FROM ((SELECT * FROM test) EXCEPT (SELECT * FROM ref)) u ORDER BY 1,2; DEBUG: generating subplan 77_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 77_2 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('77_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) EXCEPT SELECT ref.a, ref.b FROM recursive_union.ref DEBUG: Plan 77 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('77_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u ORDER BY x, y DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 1 | 1 (1 row) SELECT * FROM ((SELECT * FROM ref) EXCEPT (SELECT * FROM ref)) u ORDER BY 1,2; DEBUG: Creating router plan DEBUG: Plan is router executable a | b ---+--- (0 rows) -- unions can even be pushed down within a join SELECT * FROM ((SELECT * FROM test) UNION (SELECT * FROM test)) u JOIN test USING (x) ORDER BY 1,2; x | y | y ---+---+--- 1 | 1 | 1 2 | 2 | 2 (2 rows) SELECT * FROM ((SELECT * FROM test) UNION ALL (SELECT * FROM test)) u LEFT JOIN test USING (x) ORDER BY 1,2; x | y | y ---+---+--- 1 | 1 | 1 1 | 1 | 1 2 | 2 | 2 2 | 2 | 2 (4 rows) -- unions cannot be pushed down if one leaf recurs SELECT * FROM ((SELECT * FROM test) UNION (SELECT * FROM test ORDER BY x LIMIT 1)) u JOIN test USING (x) ORDER BY 1,2; DEBUG: push down of limit count: 1 DEBUG: generating subplan 83_1 for subquery SELECT x, y FROM recursive_union.test ORDER BY x LIMIT 1 DEBUG: generating subplan 83_2 for subquery SELECT x, y FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 83_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('83_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('83_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) DEBUG: Plan 83 query after replacing subqueries and CTEs: SELECT u.x, u.y, test.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('83_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u JOIN recursive_union.test USING (x)) ORDER BY u.x, u.y x | y | y ---+---+--- 1 | 1 | 1 2 | 2 | 2 (2 rows) SELECT * FROM ((SELECT * FROM test) UNION ALL (SELECT * FROM test ORDER BY x LIMIT 1)) u LEFT JOIN test USING (x) ORDER BY 1,2; DEBUG: push down of limit count: 1 DEBUG: generating subplan 87_1 for subquery SELECT x, y FROM recursive_union.test ORDER BY x LIMIT 1 DEBUG: generating subplan 87_2 for subquery SELECT x, y FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 87_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('87_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION ALL SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('87_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) DEBUG: Plan 87 query after replacing subqueries and CTEs: SELECT u.x, u.y, test.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('87_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u LEFT JOIN recursive_union.test USING (x)) ORDER BY u.x, u.y ERROR: cannot pushdown the subquery DETAIL: Complex subqueries and CTEs cannot be in the outer part of the outer join -- unions in a join without partition column equality (column names from first query are used for join) SELECT * FROM ((SELECT x, y FROM test) UNION (SELECT y, x FROM test)) u JOIN test USING (x) ORDER BY 1,2; DEBUG: generating subplan 91_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 91_2 for subquery SELECT y, x FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 91_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('91_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT intermediate_result.y, intermediate_result.x FROM read_intermediate_result('91_2'::text, 'binary'::citus_copy_format) intermediate_result(y integer, x integer) DEBUG: Plan 91 query after replacing subqueries and CTEs: SELECT u.x, u.y, test.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('91_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u JOIN recursive_union.test USING (x)) ORDER BY u.x, u.y x | y | y ---+---+--- 1 | 1 | 1 2 | 2 | 2 (2 rows) SELECT * FROM ((SELECT x, y FROM test) UNION (SELECT 1, 1 FROM test)) u JOIN test USING (x) ORDER BY 1,2; DEBUG: generating subplan 95_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 95_2 for subquery SELECT 1, 1 FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 95_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('95_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT intermediate_result."?column?", intermediate_result."?column?_1" AS "?column?" FROM read_intermediate_result('95_2'::text, 'binary'::citus_copy_format) intermediate_result("?column?" integer, "?column?_1" integer) DEBUG: Plan 95 query after replacing subqueries and CTEs: SELECT u.x, u.y, test.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('95_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u JOIN recursive_union.test USING (x)) ORDER BY u.x, u.y x | y | y ---+---+--- 1 | 1 | 1 2 | 2 | 2 (2 rows) -- a join between a set operation and a generate_series which is pushdownable SELECT * FROM ((SELECT * FROM test) UNION (SELECT * FROM test ORDER BY x)) u JOIN generate_series(1,10) x USING (x) ORDER BY 1,2; x | y ---+--- 1 | 1 2 | 2 (2 rows) -- a join between a set operation and a generate_series which is not pushdownable due to EXCEPT SELECT * FROM ((SELECT * FROM test) EXCEPT (SELECT * FROM test ORDER BY x)) u JOIN generate_series(1,10) x USING (x) ORDER BY 1,2; DEBUG: generating subplan 100_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 100_2 for subquery SELECT x, y FROM recursive_union.test ORDER BY x DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 100_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('100_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) EXCEPT SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('100_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) DEBUG: Plan 100 query after replacing subqueries and CTEs: SELECT u.x, u.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('100_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u JOIN generate_series(1, 10) x(x) USING (x)) ORDER BY u.x, u.y DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- (0 rows) -- subqueries in WHERE clause with set operations fails due to the current limitaions of recursive planning IN WHERE clause SELECT * FROM ((SELECT * FROM test) UNION (SELECT * FROM test)) foo WHERE x IN (SELECT y FROM test); ERROR: cannot pushdown the subquery since not all subqueries in the UNION have the partition column in the same position DETAIL: Each leaf query of the UNION should return the partition column in the same position and all joins must be on the partition column -- subqueries in WHERE clause forced to be recursively planned SELECT * FROM ((SELECT * FROM test) UNION (SELECT * FROM test)) foo WHERE x IN (SELECT y FROM test ORDER BY 1 LIMIT 4) ORDER BY 1; DEBUG: push down of limit count: 4 DEBUG: generating subplan 105_1 for subquery SELECT y FROM recursive_union.test ORDER BY y LIMIT 4 DEBUG: Plan 105 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT test.x, test.y FROM recursive_union.test UNION SELECT test.x, test.y FROM recursive_union.test) foo WHERE (x IN (SELECT intermediate_result.y FROM read_intermediate_result('105_1'::text, 'binary'::citus_copy_format) intermediate_result(y integer))) ORDER BY x x | y ---+--- 1 | 1 2 | 2 (2 rows) -- now both the set operations and the sublink is recursively planned SELECT * FROM ((SELECT x,y FROM test) UNION (SELECT y,x FROM test)) foo WHERE x IN (SELECT y FROM test ORDER BY 1 LIMIT 4) ORDER BY 1; DEBUG: push down of limit count: 4 DEBUG: generating subplan 107_1 for subquery SELECT y FROM recursive_union.test ORDER BY y LIMIT 4 DEBUG: generating subplan 107_2 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 107_3 for subquery SELECT y, x FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 107_4 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('107_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT intermediate_result.y, intermediate_result.x FROM read_intermediate_result('107_3'::text, 'binary'::citus_copy_format) intermediate_result(y integer, x integer) DEBUG: Plan 107 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('107_4'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) foo WHERE (x IN (SELECT intermediate_result.y FROM read_intermediate_result('107_1'::text, 'binary'::citus_copy_format) intermediate_result(y integer))) ORDER BY x DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 1 | 1 2 | 2 (2 rows) -- set operations are recursively planned and not the sublink, thus should error out SELECT * FROM ((SELECT x,y FROM test) UNION (SELECT y,x FROM test)) foo WHERE x IN (SELECT y FROM test) ORDER BY 1; DEBUG: generating subplan 112_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 112_2 for subquery SELECT y, x FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 112_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('112_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT intermediate_result.y, intermediate_result.x FROM read_intermediate_result('112_2'::text, 'binary'::citus_copy_format) intermediate_result(y integer, x integer) DEBUG: Plan 112 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('112_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) foo WHERE (x IN (SELECT test.y FROM recursive_union.test)) ORDER BY x ERROR: cannot pushdown the subquery DETAIL: Complex subqueries and CTEs are not allowed in the FROM clause when the query has subqueries in the WHERE clause -- set operations works fine with pushdownable window functions SELECT x, y, rnk FROM (SELECT *, rank() OVER my_win as rnk FROM test WINDOW my_win AS (PARTITION BY x ORDER BY y DESC)) as foo UNION SELECT x, y, rnk FROM (SELECT *, rank() OVER my_win as rnk FROM test WINDOW my_win AS (PARTITION BY x ORDER BY y DESC)) as bar ORDER BY 1 DESC, 2 DESC, 3 DESC; DEBUG: generating subplan 116_1 for subquery SELECT x, y, rnk FROM (SELECT test.x, test.y, rank() OVER my_win AS rnk FROM recursive_union.test WINDOW my_win AS (PARTITION BY test.x ORDER BY test.y DESC)) foo DEBUG: generating subplan 116_2 for subquery SELECT x, y, rnk FROM (SELECT test.x, test.y, rank() OVER my_win AS rnk FROM recursive_union.test WINDOW my_win AS (PARTITION BY test.x ORDER BY test.y DESC)) bar DEBUG: Plan 116 query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.y, intermediate_result.rnk FROM read_intermediate_result('116_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer, rnk bigint) UNION SELECT intermediate_result.x, intermediate_result.y, intermediate_result.rnk FROM read_intermediate_result('116_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer, rnk bigint) ORDER BY 1 DESC, 2 DESC, 3 DESC DEBUG: Creating router plan DEBUG: Plan is router executable x | y | rnk ---+---+----- 2 | 2 | 1 1 | 1 | 1 (2 rows) -- set operations errors out with non-pushdownable window functions SELECT x, y, rnk FROM (SELECT *, rank() OVER my_win as rnk FROM test WINDOW my_win AS (PARTITION BY y ORDER BY x DESC)) as foo UNION SELECT x, y, rnk FROM (SELECT *, rank() OVER my_win as rnk FROM test WINDOW my_win AS (PARTITION BY y ORDER BY x DESC)) as bar; ERROR: could not run distributed query because the window function that is used cannot be pushed down HINT: Window functions are supported in two ways. Either add an equality filter on the distributed tables' partition column or use the window functions inside a subquery with a PARTITION BY clause containing the distribution column -- other set operations in joins also cannot be pushed down SELECT * FROM ((SELECT * FROM test) EXCEPT (SELECT * FROM test ORDER BY x LIMIT 1)) u JOIN test USING (x) ORDER BY 1,2; DEBUG: push down of limit count: 1 DEBUG: generating subplan 121_1 for subquery SELECT x, y FROM recursive_union.test ORDER BY x LIMIT 1 DEBUG: generating subplan 121_2 for subquery SELECT x, y FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 121_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('121_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) EXCEPT SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('121_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) DEBUG: Plan 121 query after replacing subqueries and CTEs: SELECT u.x, u.y, test.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('121_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u JOIN recursive_union.test USING (x)) ORDER BY u.x, u.y x | y | y ---+---+--- 2 | 2 | 2 (1 row) SELECT * FROM ((SELECT * FROM test) INTERSECT (SELECT * FROM test ORDER BY x LIMIT 1)) u LEFT JOIN test USING (x) ORDER BY 1,2; DEBUG: push down of limit count: 1 DEBUG: generating subplan 125_1 for subquery SELECT x, y FROM recursive_union.test ORDER BY x LIMIT 1 DEBUG: generating subplan 125_2 for subquery SELECT x, y FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 125_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('125_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) INTERSECT SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('125_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) DEBUG: Plan 125 query after replacing subqueries and CTEs: SELECT u.x, u.y, test.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('125_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u LEFT JOIN recursive_union.test USING (x)) ORDER BY u.x, u.y ERROR: cannot pushdown the subquery DETAIL: Complex subqueries and CTEs cannot be in the outer part of the outer join -- distributed table in WHERE clause, but not FROM clause still disallowed SELECT * FROM ((SELECT * FROM test) UNION (SELECT * FROM ref WHERE a IN (SELECT x FROM test))) u ORDER BY 1,2; ERROR: cannot pushdown the subquery DETAIL: Reference tables are not allowed in FROM clause when the query has subqueries in WHERE clause -- subquery union in WHERE clause with partition column equality and implicit join is pushed down SELECT * FROM test a WHERE x IN (SELECT x FROM test b WHERE y = 1 UNION SELECT x FROM test c WHERE y = 2) ORDER BY 1,2; x | y ---+--- 1 | 1 2 | 2 (2 rows) -- subquery union in WHERE clause with partition column equality, without implicit join on partition column SELECT * FROM test a WHERE x NOT IN (SELECT x FROM test b WHERE y = 1 UNION SELECT x FROM test c WHERE y = 2) ORDER BY 1,2; ERROR: complex joins are only supported when all distributed tables are joined on their distribution columns with equal operator -- subquery union in WHERE clause without parition column equality is recursively planned SELECT * FROM test a WHERE x IN (SELECT x FROM test b UNION SELECT y FROM test c) ORDER BY 1,2; DEBUG: generating subplan 133_1 for subquery SELECT x FROM recursive_union.test b DEBUG: generating subplan 133_2 for subquery SELECT y FROM recursive_union.test c DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 133_3 for subquery SELECT intermediate_result.x FROM read_intermediate_result('133_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer) UNION SELECT intermediate_result.y FROM read_intermediate_result('133_2'::text, 'binary'::citus_copy_format) intermediate_result(y integer) DEBUG: Plan 133 query after replacing subqueries and CTEs: SELECT x, y FROM recursive_union.test a WHERE (x IN (SELECT intermediate_result.x FROM read_intermediate_result('133_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer))) ORDER BY x, y x | y ---+--- 1 | 1 2 | 2 (2 rows) -- correlated subquery with union in WHERE clause SELECT * FROM test a WHERE x IN (SELECT x FROM test b UNION SELECT y FROM test c WHERE a.x = c.x) ORDER BY 1,2; DEBUG: generating subplan 137_1 for subquery SELECT x FROM recursive_union.test b DEBUG: skipping recursive planning for the subquery since it contains references to outer queries DEBUG: skipping recursive planning for the subquery since it contains references to outer queries DEBUG: Plan 137 query after replacing subqueries and CTEs: SELECT x, y FROM recursive_union.test a WHERE (x IN (SELECT intermediate_result.x FROM read_intermediate_result('137_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer) UNION SELECT c.y FROM recursive_union.test c WHERE (a.x = c.x))) ORDER BY x, y DEBUG: skipping recursive planning for the subquery since it contains references to outer queries DEBUG: skipping recursive planning for the subquery since it contains references to outer queries ERROR: complex joins are only supported when all distributed tables are joined on their distribution columns with equal operator -- force unions to be planned while subqueries are being planned SELECT * FROM ((SELECT * FROM test) UNION (SELECT * FROM test) ORDER BY 1,2 LIMIT 5) as foo ORDER BY 1 DESC LIMIT 3; DEBUG: generating subplan 140_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 140_2 for subquery SELECT x, y FROM recursive_union.test DEBUG: Plan 140 query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('140_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('140_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) ORDER BY 1, 2 LIMIT 5 DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 139_1 for subquery SELECT test.x, test.y FROM recursive_union.test UNION SELECT test.x, test.y FROM recursive_union.test ORDER BY 1, 2 LIMIT 5 DEBUG: Plan 139 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('139_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) foo ORDER BY x DESC LIMIT 3 DEBUG: Creating router plan DEBUG: Plan is router executable x | y ---+--- 2 | 2 1 | 1 (2 rows) -- distinct and count distinct should work without any problems select count(DISTINCT t.x) FROM ((SELECT DISTINCT x FROM test) UNION (SELECT DISTINCT y FROM test)) as t(x) ORDER BY 1; DEBUG: generating subplan 143_1 for subquery SELECT DISTINCT y FROM recursive_union.test DEBUG: generating subplan 143_2 for subquery SELECT DISTINCT x FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 143_3 for subquery SELECT intermediate_result.x FROM read_intermediate_result('143_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer) UNION SELECT intermediate_result.y FROM read_intermediate_result('143_1'::text, 'binary'::citus_copy_format) intermediate_result(y integer) DEBUG: Plan 143 query after replacing subqueries and CTEs: SELECT count(DISTINCT x) AS count FROM (SELECT intermediate_result.x FROM read_intermediate_result('143_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer)) t(x) ORDER BY (count(DISTINCT x)) DEBUG: Creating router plan DEBUG: Plan is router executable count ------- 2 (1 row) select count(DISTINCT t.x) FROM ((SELECT count(DISTINCT x) FROM test) UNION (SELECT count(DISTINCT y) FROM test)) as t(x) ORDER BY 1; DEBUG: generating subplan 147_1 for subquery SELECT count(DISTINCT x) AS count FROM recursive_union.test DEBUG: generating subplan 147_2 for subquery SELECT count(DISTINCT y) AS count FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 147_3 for subquery SELECT intermediate_result.count FROM read_intermediate_result('147_1'::text, 'binary'::citus_copy_format) intermediate_result(count bigint) UNION SELECT intermediate_result.count FROM read_intermediate_result('147_2'::text, 'binary'::citus_copy_format) intermediate_result(count bigint) DEBUG: Plan 147 query after replacing subqueries and CTEs: SELECT count(DISTINCT x) AS count FROM (SELECT intermediate_result.count FROM read_intermediate_result('147_3'::text, 'binary'::citus_copy_format) intermediate_result(count bigint)) t(x) ORDER BY (count(DISTINCT x)) DEBUG: Creating router plan DEBUG: Plan is router executable count ------- 1 (1 row) -- other agg. distincts are also supported when group by includes partition key select avg(DISTINCT t.x) FROM ((SELECT avg(DISTINCT y) FROM test GROUP BY x) UNION (SELECT avg(DISTINCT y) FROM test GROUP BY x)) as t(x) ORDER BY 1; DEBUG: generating subplan 151_1 for subquery SELECT avg(DISTINCT y) AS avg FROM recursive_union.test GROUP BY x DEBUG: generating subplan 151_2 for subquery SELECT avg(DISTINCT y) AS avg FROM recursive_union.test GROUP BY x DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 151_3 for subquery SELECT intermediate_result.avg FROM read_intermediate_result('151_1'::text, 'binary'::citus_copy_format) intermediate_result(avg numeric) UNION SELECT intermediate_result.avg FROM read_intermediate_result('151_2'::text, 'binary'::citus_copy_format) intermediate_result(avg numeric) DEBUG: Plan 151 query after replacing subqueries and CTEs: SELECT avg(DISTINCT x) AS avg FROM (SELECT intermediate_result.avg FROM read_intermediate_result('151_3'::text, 'binary'::citus_copy_format) intermediate_result(avg numeric)) t(x) ORDER BY (avg(DISTINCT x)) DEBUG: Creating router plan DEBUG: Plan is router executable avg ------------------------ 1.50000000000000000000 (1 row) -- other agg. distincts are not supported when group by doesn't include partition key select count(DISTINCT t.x) FROM ((SELECT avg(DISTINCT y) FROM test GROUP BY y) UNION (SELECT avg(DISTINCT y) FROM test GROUP BY y)) as t(x) ORDER BY 1; ERROR: cannot compute aggregate (distinct) DETAIL: table partitioning is unsuitable for aggregate (distinct) -- one of the leaves is a repartition join SET citus.enable_repartition_joins TO ON; -- repartition is recursively planned before the set operation (SELECT x FROM test) INTERSECT (SELECT t1.x FROM test as t1, test as t2 WHERE t1.x = t2.y LIMIT 0) ORDER BY 1 DESC; DEBUG: push down of limit count: 0 DEBUG: join prunable for task partitionId 0 and 1 DEBUG: join prunable for task partitionId 0 and 2 DEBUG: join prunable for task partitionId 0 and 3 DEBUG: join prunable for task partitionId 1 and 0 DEBUG: join prunable for task partitionId 1 and 2 DEBUG: join prunable for task partitionId 1 and 3 DEBUG: join prunable for task partitionId 2 and 0 DEBUG: join prunable for task partitionId 2 and 1 DEBUG: join prunable for task partitionId 2 and 3 DEBUG: join prunable for task partitionId 3 and 0 DEBUG: join prunable for task partitionId 3 and 1 DEBUG: join prunable for task partitionId 3 and 2 DEBUG: pruning merge fetch taskId 1 DETAIL: Creating dependency on merge taskId 9 DEBUG: pruning merge fetch taskId 2 DETAIL: Creating dependency on merge taskId 9 DEBUG: pruning merge fetch taskId 4 DETAIL: Creating dependency on merge taskId 14 DEBUG: pruning merge fetch taskId 5 DETAIL: Creating dependency on merge taskId 14 DEBUG: pruning merge fetch taskId 7 DETAIL: Creating dependency on merge taskId 19 DEBUG: pruning merge fetch taskId 8 DETAIL: Creating dependency on merge taskId 19 DEBUG: pruning merge fetch taskId 10 DETAIL: Creating dependency on merge taskId 24 DEBUG: pruning merge fetch taskId 11 DETAIL: Creating dependency on merge taskId 24 DEBUG: cannot use real time executor with repartition jobs HINT: Since you enabled citus.enable_repartition_joins Citus chose to use task-tracker. DEBUG: generating subplan 157_1 for subquery SELECT t1.x FROM recursive_union.test t1, recursive_union.test t2 WHERE (t1.x = t2.y) LIMIT 0 DEBUG: generating subplan 157_2 for subquery SELECT x FROM recursive_union.test DEBUG: Plan 157 query after replacing subqueries and CTEs: SELECT intermediate_result.x FROM read_intermediate_result('157_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer) INTERSECT SELECT intermediate_result.x FROM read_intermediate_result('157_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer) ORDER BY 1 DESC DEBUG: Creating router plan DEBUG: Plan is router executable x --- (0 rows) -- repartition is recursively planned with the set operation (SELECT x FROM test) INTERSECT (SELECT t1.x FROM test as t1, test as t2 WHERE t1.x = t2.y) ORDER BY 1 DESC; DEBUG: generating subplan 160_1 for subquery SELECT x FROM recursive_union.test DEBUG: join prunable for task partitionId 0 and 1 DEBUG: join prunable for task partitionId 0 and 2 DEBUG: join prunable for task partitionId 0 and 3 DEBUG: join prunable for task partitionId 1 and 0 DEBUG: join prunable for task partitionId 1 and 2 DEBUG: join prunable for task partitionId 1 and 3 DEBUG: join prunable for task partitionId 2 and 0 DEBUG: join prunable for task partitionId 2 and 1 DEBUG: join prunable for task partitionId 2 and 3 DEBUG: join prunable for task partitionId 3 and 0 DEBUG: join prunable for task partitionId 3 and 1 DEBUG: join prunable for task partitionId 3 and 2 DEBUG: pruning merge fetch taskId 1 DETAIL: Creating dependency on merge taskId 9 DEBUG: pruning merge fetch taskId 2 DETAIL: Creating dependency on merge taskId 9 DEBUG: pruning merge fetch taskId 4 DETAIL: Creating dependency on merge taskId 14 DEBUG: pruning merge fetch taskId 5 DETAIL: Creating dependency on merge taskId 14 DEBUG: pruning merge fetch taskId 7 DETAIL: Creating dependency on merge taskId 19 DEBUG: pruning merge fetch taskId 8 DETAIL: Creating dependency on merge taskId 19 DEBUG: pruning merge fetch taskId 10 DETAIL: Creating dependency on merge taskId 24 DEBUG: pruning merge fetch taskId 11 DETAIL: Creating dependency on merge taskId 24 DEBUG: cannot use real time executor with repartition jobs HINT: Since you enabled citus.enable_repartition_joins Citus chose to use task-tracker. DEBUG: generating subplan 160_2 for subquery SELECT t1.x FROM recursive_union.test t1, recursive_union.test t2 WHERE (t1.x = t2.y) DEBUG: Plan 160 query after replacing subqueries and CTEs: SELECT intermediate_result.x FROM read_intermediate_result('160_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer) INTERSECT SELECT intermediate_result.x FROM read_intermediate_result('160_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer) ORDER BY 1 DESC DEBUG: Creating router plan DEBUG: Plan is router executable x --- 2 1 (2 rows) SET citus.enable_repartition_joins TO OFF; -- this should be recursively planned CREATE VIEW set_view_recursive AS (SELECT y FROM test) UNION (SELECT y FROM test); SELECT * FROM set_view_recursive ORDER BY 1 DESC; DEBUG: generating subplan 163_1 for subquery SELECT y FROM recursive_union.test DEBUG: generating subplan 163_2 for subquery SELECT y FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 163_3 for subquery SELECT intermediate_result.y FROM read_intermediate_result('163_1'::text, 'binary'::citus_copy_format) intermediate_result(y integer) UNION SELECT intermediate_result.y FROM read_intermediate_result('163_2'::text, 'binary'::citus_copy_format) intermediate_result(y integer) DEBUG: Plan 163 query after replacing subqueries and CTEs: SELECT y FROM (SELECT intermediate_result.y FROM read_intermediate_result('163_3'::text, 'binary'::citus_copy_format) intermediate_result(y integer)) set_view_recursive ORDER BY y DESC DEBUG: Creating router plan DEBUG: Plan is router executable y --- 2 1 (2 rows) -- this should be pushed down CREATE VIEW set_view_pushdown AS (SELECT x FROM test) UNION (SELECT x FROM test); SELECT * FROM set_view_pushdown ORDER BY 1 DESC; x --- 2 1 (2 rows) -- this should be recursively planned CREATE VIEW set_view_recursive_second AS SELECT u.x, test.y FROM ((SELECT x, y FROM test) UNION (SELECT 1, 1 FROM test)) u JOIN test USING (x) ORDER BY 1,2; SELECT * FROM set_view_recursive_second; DEBUG: generating subplan 168_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 168_2 for subquery SELECT 1, 1 FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 168_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('168_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT intermediate_result."?column?", intermediate_result."?column?_1" AS "?column?" FROM read_intermediate_result('168_2'::text, 'binary'::citus_copy_format) intermediate_result("?column?" integer, "?column?_1" integer) DEBUG: Plan 168 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT u.x, test.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('168_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u JOIN recursive_union.test USING (x)) ORDER BY u.x, test.y) set_view_recursive_second x | y ---+--- 1 | 1 2 | 2 (2 rows) -- this should create lots of recursive calls since both views and set operations lead to recursive plans :) ((SELECT x FROM set_view_recursive_second) INTERSECT (SELECT * FROM set_view_recursive)) EXCEPT (SELECT * FROM set_view_pushdown); DEBUG: generating subplan 172_1 for subquery SELECT x, y FROM recursive_union.test DEBUG: generating subplan 172_2 for subquery SELECT 1, 1 FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 172_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('172_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT intermediate_result."?column?", intermediate_result."?column?_1" AS "?column?" FROM read_intermediate_result('172_2'::text, 'binary'::citus_copy_format) intermediate_result("?column?" integer, "?column?_1" integer) DEBUG: generating subplan 172_4 for subquery SELECT y FROM recursive_union.test DEBUG: generating subplan 172_5 for subquery SELECT y FROM recursive_union.test DEBUG: Creating router plan DEBUG: Plan is router executable DEBUG: generating subplan 172_6 for subquery SELECT intermediate_result.y FROM read_intermediate_result('172_4'::text, 'binary'::citus_copy_format) intermediate_result(y integer) UNION SELECT intermediate_result.y FROM read_intermediate_result('172_5'::text, 'binary'::citus_copy_format) intermediate_result(y integer) DEBUG: generating subplan 172_7 for subquery SELECT x FROM (SELECT u.x, test.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('172_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u JOIN recursive_union.test USING (x)) ORDER BY u.x, test.y) set_view_recursive_second DEBUG: generating subplan 172_8 for subquery SELECT x FROM (SELECT test.x FROM recursive_union.test UNION SELECT test.x FROM recursive_union.test) set_view_pushdown DEBUG: Plan 172 query after replacing subqueries and CTEs: (SELECT intermediate_result.x FROM read_intermediate_result('172_7'::text, 'binary'::citus_copy_format) intermediate_result(x integer) INTERSECT SELECT set_view_recursive.y FROM (SELECT intermediate_result.y FROM read_intermediate_result('172_6'::text, 'binary'::citus_copy_format) intermediate_result(y integer)) set_view_recursive) EXCEPT SELECT intermediate_result.x FROM read_intermediate_result('172_8'::text, 'binary'::citus_copy_format) intermediate_result(x integer) DEBUG: Creating router plan DEBUG: Plan is router executable x --- (0 rows) RESET client_min_messages; DROP SCHEMA recursive_union CASCADE; NOTICE: drop cascades to 5 other objects DETAIL: drop cascades to table test drop cascades to table ref drop cascades to view set_view_recursive drop cascades to view set_view_pushdown drop cascades to view set_view_recursive_second