respect the regression tests for recursively plan inner parts of recurring tuple joins

recursively_plan_outer_joins
Onder Kalaci 2018-11-28 19:33:58 +03:00
parent 8e75753544
commit 7aa718b2f7
14 changed files with 408 additions and 161 deletions

View File

@ -54,9 +54,8 @@ SELECT count(*) FROM customer, orders WHERE c_custkey = o_custkey;
-- Test joinExpr aliases by performing an outer-join. This code path is
-- currently not exercised, but we are adding this test to catch this bug when
-- we start supporting outer joins.
SELECT c_custkey
FROM (customer LEFT OUTER JOIN orders ON (c_custkey = o_custkey)) AS
test(c_custkey, c_nationkey)
INNER JOIN lineitem ON (test.c_custkey = l_orderkey)
LIMIT 10;
ERROR: complex joins are only supported when all distributed tables are joined on their distribution columns with equal operator
--SELECT c_custkey
--FROM (customer LEFT OUTER JOIN orders ON (c_custkey = o_custkey)) AS
-- test(c_custkey, c_nationkey)
-- INNER JOIN lineitem ON (test.c_custkey = l_orderkey)
--LIMIT 10;

View File

@ -686,8 +686,16 @@ WHERE user_id IN
(SELECT DISTINCT e2.user_id
FROM users_reference_copy_table
LEFT JOIN users_test_table e2 ON (e2.user_id = users_reference_copy_table.value_1)) RETURNING *;
ERROR: cannot pushdown the subquery
DETAIL: There exist a reference table in the outer part of the outer join
user_id | value_1 | value_2 | value_3
---------+---------+---------+---------
5 | 4 | 1 | 0
5 | 4 | 1 | 0
5 | 4 | 1 | 0
16 | 4 | | 0
6 | 4 | 11 | 0
6 | 4 | 15 | 0
(6 rows)
-- Volatile functions are also not supported
UPDATE users_test_table
SET value_2 = 5

View File

@ -77,12 +77,27 @@ ORDER BY 1;
7
(10 rows)
-- Shouldn't work, reference table at the outer side is not allowed
SET client_min_messages TO DEBUG;
-- Should work because we can recursively plan the distributed relation on the
-- inner part of the outer join
SELECT * FROM
(SELECT random() FROM users_ref_test_table LEFT JOIN user_buy_test_table
ON users_ref_test_table.id = user_buy_test_table.user_id) subquery_1;
ERROR: cannot pushdown the subquery
DETAIL: There exist a reference table in the outer part of the outer join
(SELECT users_ref_test_table.id FROM users_ref_test_table LEFT JOIN user_buy_test_table
ON users_ref_test_table.id = user_buy_test_table.user_id) subquery_1 ORDER BY 1 DESC;
DEBUG: generating subplan 12_1 for subquery SELECT user_id, NULL::integer AS item_id, NULL::integer AS buy_count FROM public.user_buy_test_table WHERE true
DEBUG: Plan 12 query after replacing subqueries and CTEs: SELECT id FROM (SELECT users_ref_test_table.id FROM (public.users_ref_test_table LEFT JOIN (SELECT intermediate_result.user_id, intermediate_result.item_id, intermediate_result.buy_count FROM read_intermediate_result('12_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, item_id integer, buy_count integer)) user_buy_test_table(user_id, item_id, buy_count) ON ((users_ref_test_table.id OPERATOR(pg_catalog.=) user_buy_test_table.user_id)))) subquery_1 ORDER BY id DESC
DEBUG: Creating router plan
DEBUG: Plan is router executable
id
----
6
5
4
3
2
1
(6 rows)
RESET client_min_messages;
-- Should work, reference table at the inner side is allowed
SELECT count(*) FROM
(SELECT random() FROM users_ref_test_table RIGHT JOIN user_buy_test_table
@ -92,12 +107,22 @@ SELECT count(*) FROM
4
(1 row)
-- Shouldn't work, reference table at the outer side is not allowed
SELECT * FROM
SET client_min_messages TO DEBUG;
-- Should work because we can recursively plan the distributed relation on the
-- inner part of the outer join
SELECT count(*) FROM
(SELECT random() FROM user_buy_test_table RIGHT JOIN users_ref_test_table
ON user_buy_test_table.user_id = users_ref_test_table.id) subquery_1;
ERROR: cannot pushdown the subquery
DETAIL: There exist a reference table in the outer part of the outer join
DEBUG: generating subplan 15_1 for subquery SELECT user_id, NULL::integer AS item_id, NULL::integer AS buy_count FROM public.user_buy_test_table WHERE true
DEBUG: Plan 15 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT random() AS random FROM ((SELECT intermediate_result.user_id, intermediate_result.item_id, intermediate_result.buy_count FROM read_intermediate_result('15_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, item_id integer, buy_count integer)) user_buy_test_table(user_id, item_id, buy_count) RIGHT JOIN public.users_ref_test_table ON ((user_buy_test_table.user_id OPERATOR(pg_catalog.=) users_ref_test_table.id)))) subquery_1
DEBUG: Creating router plan
DEBUG: Plan is router executable
count
-------
6
(1 row)
RESET client_min_messages;
-- Equi join test with reference table on non-partition keys
SELECT count(*) FROM
(SELECT random() FROM user_buy_test_table JOIN users_ref_test_table
@ -266,23 +291,40 @@ ON user_buy_test_table.item_id = users_ref_test_table.id;
4
(1 row)
-- table function cannot be the outer relationship in an outer join
SET client_min_messages TO DEBUG;
-- table function can be the outer relationship in an outer join
-- since the inner side is recursively planned
SELECT count(*) FROM
(SELECT random() FROM user_buy_test_table RIGHT JOIN generate_series(1,10) AS users_ref_test_table(id)
ON user_buy_test_table.item_id > users_ref_test_table.id) subquery_1;
ERROR: cannot pushdown the subquery
DETAIL: There exist a table function in the outer part of the outer join
DEBUG: generating subplan 30_1 for subquery SELECT NULL::integer AS user_id, item_id, NULL::integer AS buy_count FROM public.user_buy_test_table WHERE true
DEBUG: Plan 30 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT random() AS random FROM ((SELECT intermediate_result.user_id, intermediate_result.item_id, intermediate_result.buy_count FROM read_intermediate_result('30_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, item_id integer, buy_count integer)) user_buy_test_table(user_id, item_id, buy_count) RIGHT JOIN (SELECT users_ref_test_table_1.id FROM generate_series(1, 10) users_ref_test_table_1(id)) users_ref_test_table(id) ON ((user_buy_test_table.item_id OPERATOR(pg_catalog.>) users_ref_test_table.id)))) subquery_1
DEBUG: Creating router plan
DEBUG: Plan is router executable
count
-------
16
(1 row)
SELECT count(*) FROM user_buy_test_table RIGHT JOIN (SELECT * FROM generate_series(1,10) id) users_ref_test_table
ON user_buy_test_table.item_id = users_ref_test_table.id;
ERROR: cannot pushdown the subquery
DETAIL: There exist a table function in the outer part of the outer join
DEBUG: generating subplan 32_1 for subquery SELECT NULL::integer AS user_id, item_id, NULL::integer AS buy_count FROM public.user_buy_test_table WHERE true
DEBUG: Plan 32 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.user_id, intermediate_result.item_id, intermediate_result.buy_count FROM read_intermediate_result('32_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, item_id integer, buy_count integer)) user_buy_test_table(user_id, item_id, buy_count) RIGHT JOIN (SELECT id.id FROM generate_series(1, 10) id(id)) users_ref_test_table ON ((user_buy_test_table.item_id OPERATOR(pg_catalog.=) users_ref_test_table.id)))
DEBUG: Creating router plan
DEBUG: Plan is router executable
count
-------
10
(1 row)
RESET client_min_messages;
-- volatile functions can be used as table expressions through recursive planning
SET client_min_messages TO DEBUG;
SELECT count(*) FROM
(SELECT random() FROM user_buy_test_table JOIN random() AS users_ref_test_table(id)
ON user_buy_test_table.item_id > users_ref_test_table.id) subquery_1;
DEBUG: generating subplan 30_1 for subquery SELECT id FROM random() users_ref_test_table(id)
DEBUG: Plan 30 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT random() AS random FROM (public.user_buy_test_table JOIN (SELECT intermediate_result.id FROM read_intermediate_result('30_1'::text, 'binary'::citus_copy_format) intermediate_result(id double precision)) users_ref_test_table(id) ON (((user_buy_test_table.item_id)::double precision OPERATOR(pg_catalog.>) users_ref_test_table.id)))) subquery_1
DEBUG: generating subplan 34_1 for subquery SELECT id FROM random() users_ref_test_table(id)
DEBUG: Plan 34 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT random() AS random FROM (public.user_buy_test_table JOIN (SELECT intermediate_result.id FROM read_intermediate_result('34_1'::text, 'binary'::citus_copy_format) intermediate_result(id double precision)) users_ref_test_table(id) ON (((user_buy_test_table.item_id)::double precision OPERATOR(pg_catalog.>) users_ref_test_table.id)))) subquery_1
count
-------
4
@ -293,8 +335,8 @@ SELECT count(*) FROM
(SELECT item_id FROM user_buy_test_table JOIN generate_series(random()::int,10) AS users_ref_test_table(id)
ON user_buy_test_table.item_id > users_ref_test_table.id) subquery_1
WHERE item_id = 6;
DEBUG: generating subplan 31_1 for subquery SELECT id FROM generate_series((random())::integer, 10) users_ref_test_table(id)
DEBUG: Plan 31 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT user_buy_test_table.item_id FROM (public.user_buy_test_table JOIN (SELECT intermediate_result.id FROM read_intermediate_result('31_1'::text, 'binary'::citus_copy_format) intermediate_result(id integer)) users_ref_test_table(id) ON ((user_buy_test_table.item_id OPERATOR(pg_catalog.>) users_ref_test_table.id)))) subquery_1 WHERE (item_id OPERATOR(pg_catalog.=) 6)
DEBUG: generating subplan 35_1 for subquery SELECT id FROM generate_series((random())::integer, 10) users_ref_test_table(id)
DEBUG: Plan 35 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT user_buy_test_table.item_id FROM (public.user_buy_test_table JOIN (SELECT intermediate_result.id FROM read_intermediate_result('35_1'::text, 'binary'::citus_copy_format) intermediate_result(id integer)) users_ref_test_table(id) ON ((user_buy_test_table.item_id OPERATOR(pg_catalog.>) users_ref_test_table.id)))) subquery_1 WHERE (item_id OPERATOR(pg_catalog.=) 6)
count
-------
0
@ -305,11 +347,11 @@ SELECT count(*) FROM
(SELECT user_id FROM user_buy_test_table
UNION ALL
SELECT id FROM generate_series(1,10) AS users_ref_test_table(id)) subquery_1;
DEBUG: generating subplan 32_1 for subquery SELECT user_id FROM public.user_buy_test_table
DEBUG: generating subplan 36_1 for subquery SELECT user_id FROM public.user_buy_test_table
DEBUG: Creating router plan
DEBUG: Plan is router executable
DEBUG: generating subplan 32_2 for subquery SELECT intermediate_result.user_id FROM read_intermediate_result('32_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) UNION ALL SELECT users_ref_test_table.id FROM generate_series(1, 10) users_ref_test_table(id)
DEBUG: Plan 32 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('32_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) subquery_1
DEBUG: generating subplan 36_2 for subquery SELECT intermediate_result.user_id FROM read_intermediate_result('36_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) UNION ALL SELECT users_ref_test_table.id FROM generate_series(1, 10) users_ref_test_table(id)
DEBUG: Plan 36 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('36_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) subquery_1
DEBUG: Creating router plan
DEBUG: Plan is router executable
count
@ -343,11 +385,19 @@ ON user_buy_test_table.item_id = users_ref_test_table.id;
4
(1 row)
-- subquery without FROM cannot be the outer relationship in an outer join
SET client_min_messages TO DEBUG1;
-- subquery without FROM can be the outer relationship in an outer join
-- since the inner part can be recursively planned
SELECT count(*) FROM user_buy_test_table RIGHT JOIN (SELECT 5 AS id) users_ref_test_table
ON user_buy_test_table.item_id = users_ref_test_table.id;
ERROR: cannot pushdown the subquery
DETAIL: There exist a subquery without FROM in the outer part of the outer join
DEBUG: generating subplan 42_1 for subquery SELECT NULL::integer AS user_id, item_id, NULL::integer AS buy_count FROM public.user_buy_test_table WHERE true
DEBUG: Plan 42 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.user_id, intermediate_result.item_id, intermediate_result.buy_count FROM read_intermediate_result('42_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, item_id integer, buy_count integer)) user_buy_test_table(user_id, item_id, buy_count) RIGHT JOIN (SELECT 5 AS id) users_ref_test_table ON ((user_buy_test_table.item_id OPERATOR(pg_catalog.=) users_ref_test_table.id)))
count
-------
1
(1 row)
RESET client_min_messages;
-- can perform a union with subquery without FROM
-- with pulling data to coordinator
SET client_min_messages TO DEBUG;
@ -355,11 +405,11 @@ SELECT count(*) FROM
(SELECT user_id FROM user_buy_test_table
UNION ALL
SELECT id FROM (SELECT 5 AS id) users_ref_test_table) subquery_1;
DEBUG: generating subplan 39_1 for subquery SELECT user_id FROM public.user_buy_test_table
DEBUG: generating subplan 44_1 for subquery SELECT user_id FROM public.user_buy_test_table
DEBUG: Creating router plan
DEBUG: Plan is router executable
DEBUG: generating subplan 39_2 for subquery SELECT intermediate_result.user_id FROM read_intermediate_result('39_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) UNION ALL SELECT users_ref_test_table.id FROM (SELECT 5 AS id) users_ref_test_table
DEBUG: Plan 39 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('39_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) subquery_1
DEBUG: generating subplan 44_2 for subquery SELECT intermediate_result.user_id FROM read_intermediate_result('44_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) UNION ALL SELECT users_ref_test_table.id FROM (SELECT 5 AS id) users_ref_test_table
DEBUG: Plan 44 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('44_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) subquery_1
DEBUG: Creating router plan
DEBUG: Plan is router executable
count
@ -375,11 +425,11 @@ SELECT * FROM
UNION
SELECT user_id FROM user_buy_test_table) sub
ORDER BY 1 DESC;
DEBUG: generating subplan 42_1 for subquery SELECT user_id FROM public.user_buy_test_table
DEBUG: generating subplan 47_1 for subquery SELECT user_id FROM public.user_buy_test_table
DEBUG: Creating router plan
DEBUG: Plan is router executable
DEBUG: generating subplan 42_2 for subquery SELECT users_ref_test_table.id FROM public.users_ref_test_table UNION SELECT intermediate_result.user_id FROM read_intermediate_result('42_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)
DEBUG: Plan 42 query after replacing subqueries and CTEs: SELECT id FROM (SELECT intermediate_result.id FROM read_intermediate_result('42_2'::text, 'binary'::citus_copy_format) intermediate_result(id integer)) sub ORDER BY id DESC
DEBUG: generating subplan 47_2 for subquery SELECT users_ref_test_table.id FROM public.users_ref_test_table UNION SELECT intermediate_result.user_id FROM read_intermediate_result('47_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)
DEBUG: Plan 47 query after replacing subqueries and CTEs: SELECT id FROM (SELECT intermediate_result.id FROM read_intermediate_result('47_2'::text, 'binary'::citus_copy_format) intermediate_result(id integer)) sub ORDER BY id DESC
DEBUG: Creating router plan
DEBUG: Plan is router executable
id
@ -399,11 +449,11 @@ SELECT * FROM
UNION
SELECT user_id, random() * 0 FROM (SELECT user_id FROM user_buy_test_table) sub2) sub
ORDER BY 1 DESC;
DEBUG: generating subplan 45_1 for subquery SELECT user_id, (random() OPERATOR(pg_catalog.*) (0)::double precision) FROM (SELECT user_buy_test_table.user_id FROM public.user_buy_test_table) sub2
DEBUG: generating subplan 50_1 for subquery SELECT user_id, (random() OPERATOR(pg_catalog.*) (0)::double precision) FROM (SELECT user_buy_test_table.user_id FROM public.user_buy_test_table) sub2
DEBUG: Creating router plan
DEBUG: Plan is router executable
DEBUG: generating subplan 45_2 for subquery SELECT sub1.id, (random() OPERATOR(pg_catalog.*) (0)::double precision) FROM (SELECT users_ref_test_table.id FROM public.users_ref_test_table) sub1 UNION SELECT intermediate_result.user_id, intermediate_result."?column?" FROM read_intermediate_result('45_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "?column?" double precision)
DEBUG: Plan 45 query after replacing subqueries and CTEs: SELECT id, "?column?" FROM (SELECT intermediate_result.id, intermediate_result."?column?" FROM read_intermediate_result('45_2'::text, 'binary'::citus_copy_format) intermediate_result(id integer, "?column?" double precision)) sub ORDER BY id DESC
DEBUG: generating subplan 50_2 for subquery SELECT sub1.id, (random() OPERATOR(pg_catalog.*) (0)::double precision) FROM (SELECT users_ref_test_table.id FROM public.users_ref_test_table) sub1 UNION SELECT intermediate_result.user_id, intermediate_result."?column?" FROM read_intermediate_result('50_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "?column?" double precision)
DEBUG: Plan 50 query after replacing subqueries and CTEs: SELECT id, "?column?" FROM (SELECT intermediate_result.id, intermediate_result."?column?" FROM read_intermediate_result('50_2'::text, 'binary'::citus_copy_format) intermediate_result(id integer, "?column?" double precision)) sub ORDER BY id DESC
DEBUG: Creating router plan
DEBUG: Plan is router executable
id | ?column?
@ -454,8 +504,16 @@ SELECT * FROM
UNION
SELECT user_id FROM user_buy_test_table) sub
ORDER BY 1 DESC;
ERROR: cannot pushdown the subquery
DETAIL: There exist a reference table in the outer part of the outer join
DEBUG: generating subplan 55_1 for subquery SELECT user_id, NULL::integer AS item_id, NULL::integer AS buy_count FROM public.user_buy_test_table WHERE true
DEBUG: Plan 55 query after replacing subqueries and CTEs: SELECT user_id FROM (SELECT dis.user_id FROM (public.users_ref_test_table ref JOIN public.user_buy_test_table dis ON ((ref.id OPERATOR(pg_catalog.=) dis.user_id))) WHERE (ref.id OPERATOR(pg_catalog.=) ANY (SELECT user_buy_test_table.user_id FROM (SELECT intermediate_result.user_id, intermediate_result.item_id, intermediate_result.buy_count FROM read_intermediate_result('55_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, item_id integer, buy_count integer)) user_buy_test_table(user_id, item_id, buy_count))) UNION SELECT user_buy_test_table.user_id FROM public.user_buy_test_table) sub ORDER BY user_id DESC
user_id
---------
7
3
2
1
(4 rows)
SELECT * FROM
(SELECT user_id FROM users_ref_test_table ref JOIN user_buy_test_table dis
on (ref.id = dis.user_id)
@ -495,8 +553,23 @@ SELECT * FROM
UNION
SELECT user_id FROM user_buy_test_table) sub
ORDER BY 1 DESC;
ERROR: cannot pushdown the subquery
DETAIL: There exist a reference table in the outer part of the outer join
DEBUG: generating subplan 59_1 for subquery SELECT user_id, NULL::integer AS item_id, NULL::integer AS buy_count FROM public.user_buy_test_table dis WHERE true
DEBUG: generating subplan 59_2 for subquery SELECT user_id FROM public.user_buy_test_table
DEBUG: Creating router plan
DEBUG: Plan is router executable
DEBUG: generating subplan 59_3 for subquery SELECT user_buy_test_table.user_id FROM (public.users_ref_test_table ref LEFT JOIN (SELECT intermediate_result.user_id, intermediate_result.item_id, intermediate_result.buy_count FROM read_intermediate_result('59_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, item_id integer, buy_count integer)) user_buy_test_table(user_id, item_id, buy_count) ON ((ref.id OPERATOR(pg_catalog.=) user_buy_test_table.user_id))) UNION SELECT intermediate_result.user_id FROM read_intermediate_result('59_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)
DEBUG: Plan 59 query after replacing subqueries and CTEs: SELECT user_id FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('59_3'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) sub ORDER BY user_id DESC
DEBUG: Creating router plan
DEBUG: Plan is router executable
user_id
---------
7
3
2
1
(5 rows)
RESET client_min_messages;
-- should be able to pushdown since reference table is in the
-- inner part of the left join
@ -520,8 +593,10 @@ FROM
6 | 210
(6 rows)
-- should not be able to pushdown since reference table is in the
-- direct outer part of the left join
SET client_min_messages TO DEBUG1;
-- although the inner part of an outer join with reference table is
-- recursively planned, we still hit the agressive outer join checks
-- (recurring tuple Left Join recurring tuple) errors
SELECT
user_id, sum(value_1)
FROM
@ -532,17 +607,34 @@ FROM
LEFT JOIN events_table ON (events_table.user_id = users_table.user_id)
) as foo
GROUP BY user_id ORDER BY 2 DESC LIMIT 10;
DEBUG: generating subplan 64_1 for subquery SELECT user_id, NULL::timestamp without time zone AS "time", value_1, NULL::integer AS value_2, NULL::double precision AS value_3, NULL::bigint AS value_4 FROM public.users_table WHERE true
DEBUG: Plan 64 query after replacing subqueries and CTEs: SELECT user_id, sum(value_1) AS sum FROM (SELECT users_table.user_id, users_table.value_1, random() AS random FROM ((public.events_reference_table LEFT JOIN (SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.value_1, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('64_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, value_1 integer, value_2 integer, value_3 double precision, value_4 bigint)) users_table(user_id, "time", value_1, value_2, value_3, value_4) ON ((users_table.user_id OPERATOR(pg_catalog.=) events_reference_table.value_2))) LEFT JOIN public.events_table ON ((events_table.user_id OPERATOR(pg_catalog.=) users_table.user_id)))) foo GROUP BY user_id ORDER BY (sum(value_1)) DESC LIMIT 10
DEBUG: generating subplan 64_2 for subquery SELECT user_id, NULL::timestamp without time zone AS "time", NULL::integer AS event_type, NULL::integer AS value_2, NULL::double precision AS value_3, NULL::bigint AS value_4 FROM public.events_table WHERE true
DEBUG: Plan 64 query after replacing subqueries and CTEs: SELECT user_id, sum(value_1) AS sum FROM (SELECT users_table.user_id, users_table.value_1, random() AS random FROM ((public.events_reference_table LEFT JOIN (SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.value_1, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('64_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, value_1 integer, value_2 integer, value_3 double precision, value_4 bigint)) users_table(user_id, "time", value_1, value_2, value_3, value_4) ON ((users_table.user_id OPERATOR(pg_catalog.=) events_reference_table.value_2))) LEFT JOIN (SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.event_type, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('64_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, event_type integer, value_2 integer, value_3 double precision, value_4 bigint)) events_table(user_id, "time", event_type, value_2, value_3, value_4) ON ((events_table.user_id OPERATOR(pg_catalog.=) users_table.user_id)))) foo GROUP BY user_id ORDER BY (sum(value_1)) DESC LIMIT 10
ERROR: cannot pushdown the subquery
DETAIL: There exist a reference table in the outer part of the outer join
-- should not be able to pushdown since reference table is in the
-- direct outer part of the left join wrapped into a subquery
DETAIL: Complex subqueries and CTEs cannot be in the outer part of the outer join
-- should be able to pushdown since reference table is in the
-- direct outer part of the left join is recursively planned
-- and the final query becomes a router query
SELECT
*
users_table.time, users_table.value_2
FROM
(SELECT *, random() FROM events_reference_table) as ref_all LEFT JOIN users_table
ON (users_table.user_id = ref_all.value_2);
ERROR: cannot pushdown the subquery
DETAIL: There exist a reference table in the outer part of the outer join
ON (users_table.user_id = ref_all.value_2)
ORDER BY 1, 2 DESC LIMIT 6;
DEBUG: generating subplan 67_1 for subquery SELECT user_id, "time", NULL::integer AS value_1, value_2, NULL::double precision AS value_3, NULL::bigint AS value_4 FROM public.users_table WHERE true
DEBUG: Plan 67 query after replacing subqueries and CTEs: SELECT users_table."time", users_table.value_2 FROM ((SELECT events_reference_table.user_id, events_reference_table."time", events_reference_table.event_type, events_reference_table.value_2, events_reference_table.value_3, events_reference_table.value_4, random() AS random FROM public.events_reference_table) ref_all LEFT JOIN (SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.value_1, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('67_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, value_1 integer, value_2 integer, value_3 double precision, value_4 bigint)) users_table(user_id, "time", value_1, value_2, value_3, value_4) ON ((users_table.user_id OPERATOR(pg_catalog.=) ref_all.value_2))) ORDER BY users_table."time", users_table.value_2 DESC LIMIT 6
time | value_2
---------------------------------+---------
Wed Nov 22 18:19:49.944985 2017 | 5
Wed Nov 22 18:19:49.944985 2017 | 5
Wed Nov 22 18:19:49.944985 2017 | 5
Wed Nov 22 18:19:49.944985 2017 | 5
Wed Nov 22 18:19:49.944985 2017 | 5
Wed Nov 22 18:19:49.944985 2017 | 5
(6 rows)
RESET client_min_messages;
-- should not be able to pushdown since reference table is in the
-- outer part of the left join
SELECT
@ -556,7 +648,7 @@ FROM
) as foo
GROUP BY user_id ORDER BY 2 DESC LIMIT 10;
ERROR: cannot pushdown the subquery
DETAIL: There exist a reference table in the outer part of the outer join
DETAIL: Complex subqueries and CTEs cannot be in the outer part of the outer join
-- should be able to pushdown since reference table is in the
-- inner part of the left join
SELECT * FROM
@ -603,8 +695,14 @@ SELECT * FROM
WHERE
user_id > 2 and value_2 = 1) as foo_in ON (event_val_2 = user_id)) as foo LEFT JOIN
(SELECT user_id as user_user_id FROM users_table) as fooo ON (user_id = user_user_id)) as bar;
ERROR: cannot pushdown the subquery
DETAIL: There exist a reference table in the outer part of the outer join
user_id
---------
3
5
4
(4 rows)
-- we could even support the following where the subquery
-- on the outer part of the left join contains a reference table
SELECT max(events_all.cnt), events_all.usr_id
@ -637,8 +735,15 @@ GROUP BY 2
ORDER BY 1 DESC,
2 DESC
LIMIT 5;
ERROR: cannot pushdown the subquery
DETAIL: There exist a reference table in the outer part of the outer join
max | usr_id
-----+--------
432 | 2
391 | 4
364 | 5
357 | 3
105 | 1
(5 rows)
-- LATERAL JOINs used with INNER JOINs with reference tables
SET citus.subquery_pushdown to ON;
SELECT user_id, lastseen
@ -913,8 +1018,9 @@ count(*) AS cnt, "generated_group_field"
84 | 0
(6 rows)
-- RIGHT JOINs used with INNER JOINs should error out since reference table exist in the
-- right side of the RIGHT JOIN.
-- RIGHT JOINs used with INNER JOINs should work out since reference table exist in the
-- right side of the RIGHT JOIN and the inner subquery is recursively planned
SET client_min_messages TO DEBUG1;
SELECT
count(*) AS cnt, "generated_group_field"
FROM
@ -951,8 +1057,19 @@ count(*) AS cnt, "generated_group_field"
ORDER BY
cnt DESC, generated_group_field ASC
LIMIT 10;
ERROR: cannot pushdown the subquery
DETAIL: There exist a reference table in the outer part of the outer join
DEBUG: generating subplan 85_1 for subquery SELECT temp_data_queries."time", temp_data_queries.event_user_id, user_filters_1.user_id FROM ((SELECT events."time", events.user_id AS event_user_id FROM public.events_table events WHERE (events.user_id OPERATOR(pg_catalog.>) 2)) temp_data_queries JOIN (SELECT users.user_id FROM public.users_table users WHERE ((users.user_id OPERATOR(pg_catalog.>) 2) AND (users.value_2 OPERATOR(pg_catalog.=) 5))) user_filters_1 ON ((temp_data_queries.event_user_id OPERATOR(pg_catalog.=) user_filters_1.user_id)))
DEBUG: Plan 85 query after replacing subqueries and CTEs: SELECT count(*) AS cnt, generated_group_field FROM (SELECT "eventQuery".user_id, random() AS random, "eventQuery".generated_group_field FROM (SELECT multi_group_wrapper_1."time", multi_group_wrapper_1.event_user_id, multi_group_wrapper_1.user_id, right_group_by_1.generated_group_field, random() AS random FROM ((SELECT intermediate_result."time", intermediate_result.event_user_id, intermediate_result.user_id FROM read_intermediate_result('85_1'::text, 'binary'::citus_copy_format) intermediate_result("time" timestamp without time zone, event_user_id integer, user_id integer)) multi_group_wrapper_1 RIGHT JOIN (SELECT users.user_id, users.value_2 AS generated_group_field FROM public.users_reference_table users) right_group_by_1 ON ((right_group_by_1.user_id OPERATOR(pg_catalog.=) multi_group_wrapper_1.event_user_id)))) "eventQuery") "pushedDownQuery" GROUP BY generated_group_field ORDER BY (count(*)) DESC, generated_group_field LIMIT 10
cnt | generated_group_field
------+-----------------------
1007 | 2
952 | 5
773 | 1
696 | 3
433 | 4
190 | 0
(6 rows)
RESET client_min_messages;
-- right join where the inner part of the join includes a reference table
-- joined with hash partitioned table using non-equi join
SELECT user_id, sum(array_length(events_table, 1)), length(hasdone_event), hasdone_event
@ -1315,23 +1432,28 @@ ORDER BY types;
3 | 120
(4 rows)
SET client_min_messages TO DEBUG1;
-- just a sanity check that we don't allow this if the reference table is on the
-- left part of the left join
-- left part of the left join, we can still recursively plan the inner side
SELECT count(*) FROM
(SELECT random() FROM users_ref_test_table LEFT JOIN user_buy_test_table
ON user_buy_test_table.item_id > users_ref_test_table.id) subquery_1;
ERROR: cannot pushdown the subquery
DETAIL: There exist a reference table in the outer part of the outer join
DEBUG: generating subplan 102_1 for subquery SELECT NULL::integer AS user_id, item_id, NULL::integer AS buy_count FROM public.user_buy_test_table WHERE true
DEBUG: Plan 102 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT random() AS random FROM (public.users_ref_test_table LEFT JOIN (SELECT intermediate_result.user_id, intermediate_result.item_id, intermediate_result.buy_count FROM read_intermediate_result('102_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, item_id integer, buy_count integer)) user_buy_test_table(user_id, item_id, buy_count) ON ((user_buy_test_table.item_id OPERATOR(pg_catalog.>) users_ref_test_table.id)))) subquery_1
count
-------
12
(1 row)
-- we do allow non equi join among subqueries via recursive planning
SET client_min_messages TO DEBUG1;
SELECT count(*) FROM
(SELECT user_buy_test_table.user_id, random() FROM user_buy_test_table LEFT JOIN users_ref_test_table
ON user_buy_test_table.item_id > users_ref_test_table.id) subquery_1,
(SELECT user_buy_test_table.user_id, random() FROM user_buy_test_table LEFT JOIN users_ref_test_table
ON user_buy_test_table.user_id > users_ref_test_table.id) subquery_2
WHERE subquery_1.user_id != subquery_2.user_id ;
DEBUG: generating subplan 84_1 for subquery SELECT user_buy_test_table.user_id, random() AS random FROM (public.user_buy_test_table LEFT JOIN public.users_ref_test_table ON ((user_buy_test_table.user_id OPERATOR(pg_catalog.>) users_ref_test_table.id)))
DEBUG: Plan 84 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT user_buy_test_table.user_id, random() AS random FROM (public.user_buy_test_table LEFT JOIN public.users_ref_test_table ON ((user_buy_test_table.item_id OPERATOR(pg_catalog.>) users_ref_test_table.id)))) subquery_1, (SELECT intermediate_result.user_id, intermediate_result.random FROM read_intermediate_result('84_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, random double precision)) subquery_2 WHERE (subquery_1.user_id OPERATOR(pg_catalog.<>) subquery_2.user_id)
DEBUG: generating subplan 104_1 for subquery SELECT user_buy_test_table.user_id, random() AS random FROM (public.user_buy_test_table LEFT JOIN public.users_ref_test_table ON ((user_buy_test_table.user_id OPERATOR(pg_catalog.>) users_ref_test_table.id)))
DEBUG: Plan 104 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT user_buy_test_table.user_id, random() AS random FROM (public.user_buy_test_table LEFT JOIN public.users_ref_test_table ON ((user_buy_test_table.item_id OPERATOR(pg_catalog.>) users_ref_test_table.id)))) subquery_1, (SELECT intermediate_result.user_id, intermediate_result.random FROM read_intermediate_result('104_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, random double precision)) subquery_2 WHERE (subquery_1.user_id OPERATOR(pg_catalog.<>) subquery_2.user_id)
count
-------
67
@ -1376,8 +1498,10 @@ count(*) AS cnt, "generated_group_field"
ORDER BY
cnt DESC, generated_group_field ASC
LIMIT 10;
DEBUG: generating subplan 86_1 for subquery SELECT user_id, value_2 AS generated_group_field FROM public.users_table users
DEBUG: Plan 86 query after replacing subqueries and CTEs: SELECT count(*) AS cnt, generated_group_field FROM (SELECT "eventQuery".user_id, random() AS random, "eventQuery".generated_group_field FROM (SELECT multi_group_wrapper_1."time", multi_group_wrapper_1.event_user_id, multi_group_wrapper_1.user_id, left_group_by_1.generated_group_field, random() AS random FROM ((SELECT temp_data_queries."time", temp_data_queries.event_user_id, user_filters_1.user_id FROM ((SELECT events."time", events.user_id AS event_user_id FROM public.events_table events WHERE (events.user_id OPERATOR(pg_catalog.>) 2)) temp_data_queries JOIN (SELECT users.user_id FROM public.users_reference_table users WHERE ((users.user_id OPERATOR(pg_catalog.>) 2) AND (users.value_2 OPERATOR(pg_catalog.=) 5))) user_filters_1 ON ((temp_data_queries.event_user_id OPERATOR(pg_catalog.<) user_filters_1.user_id)))) multi_group_wrapper_1 RIGHT JOIN (SELECT intermediate_result.user_id, intermediate_result.generated_group_field FROM read_intermediate_result('86_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, generated_group_field integer)) left_group_by_1 ON ((left_group_by_1.user_id OPERATOR(pg_catalog.>) multi_group_wrapper_1.event_user_id)))) "eventQuery") "pushedDownQuery" GROUP BY generated_group_field ORDER BY (count(*)) DESC, generated_group_field LIMIT 10
DEBUG: generating subplan 106_1 for subquery SELECT user_id, value_2 AS generated_group_field FROM public.users_table users
DEBUG: Plan 106 query after replacing subqueries and CTEs: SELECT count(*) AS cnt, generated_group_field FROM (SELECT "eventQuery".user_id, random() AS random, "eventQuery".generated_group_field FROM (SELECT multi_group_wrapper_1."time", multi_group_wrapper_1.event_user_id, multi_group_wrapper_1.user_id, left_group_by_1.generated_group_field, random() AS random FROM ((SELECT temp_data_queries."time", temp_data_queries.event_user_id, user_filters_1.user_id FROM ((SELECT events."time", events.user_id AS event_user_id FROM public.events_table events WHERE (events.user_id OPERATOR(pg_catalog.>) 2)) temp_data_queries JOIN (SELECT users.user_id FROM public.users_reference_table users WHERE ((users.user_id OPERATOR(pg_catalog.>) 2) AND (users.value_2 OPERATOR(pg_catalog.=) 5))) user_filters_1 ON ((temp_data_queries.event_user_id OPERATOR(pg_catalog.<) user_filters_1.user_id)))) multi_group_wrapper_1 RIGHT JOIN (SELECT intermediate_result.user_id, intermediate_result.generated_group_field FROM read_intermediate_result('106_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, generated_group_field integer)) left_group_by_1 ON ((left_group_by_1.user_id OPERATOR(pg_catalog.>) multi_group_wrapper_1.event_user_id)))) "eventQuery") "pushedDownQuery" GROUP BY generated_group_field ORDER BY (count(*)) DESC, generated_group_field LIMIT 10
DEBUG: generating subplan 106_2 for subquery SELECT temp_data_queries."time", temp_data_queries.event_user_id, user_filters_1.user_id FROM ((SELECT events."time", events.user_id AS event_user_id FROM public.events_table events WHERE (events.user_id OPERATOR(pg_catalog.>) 2)) temp_data_queries JOIN (SELECT users.user_id FROM public.users_reference_table users WHERE ((users.user_id OPERATOR(pg_catalog.>) 2) AND (users.value_2 OPERATOR(pg_catalog.=) 5))) user_filters_1 ON ((temp_data_queries.event_user_id OPERATOR(pg_catalog.<) user_filters_1.user_id)))
DEBUG: Plan 106 query after replacing subqueries and CTEs: SELECT count(*) AS cnt, generated_group_field FROM (SELECT "eventQuery".user_id, random() AS random, "eventQuery".generated_group_field FROM (SELECT multi_group_wrapper_1."time", multi_group_wrapper_1.event_user_id, multi_group_wrapper_1.user_id, left_group_by_1.generated_group_field, random() AS random FROM ((SELECT intermediate_result."time", intermediate_result.event_user_id, intermediate_result.user_id FROM read_intermediate_result('106_2'::text, 'binary'::citus_copy_format) intermediate_result("time" timestamp without time zone, event_user_id integer, user_id integer)) multi_group_wrapper_1 RIGHT JOIN (SELECT intermediate_result.user_id, intermediate_result.generated_group_field FROM read_intermediate_result('106_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, generated_group_field integer)) left_group_by_1 ON ((left_group_by_1.user_id OPERATOR(pg_catalog.>) multi_group_wrapper_1.event_user_id)))) "eventQuery") "pushedDownQuery" GROUP BY generated_group_field ORDER BY (count(*)) DESC, generated_group_field LIMIT 10
ERROR: cannot pushdown the subquery
DETAIL: Complex subqueries and CTEs cannot be in the outer part of the outer join
RESET client_min_messages;

View File

@ -46,8 +46,10 @@ LIMIT 3;
---------
(0 rows)
-- subqueries in WHERE with NOT EXISTS operator, should not work since
-- there is a correlated subquery in WHERE clause
SET client_min_messages TO DEBUG1;
-- although the subquery in WHERE with NOT EXISTS operator (e.g., semi-join)
-- is correlated with the reference table, since events_table can be
-- recursively planned the whole query becomes a router query
SELECT
user_id
FROM
@ -62,10 +64,16 @@ WHERE
users_reference_table.user_id = events_table.user_id
)
LIMIT 3;
ERROR: cannot pushdown the subquery
DETAIL: Reference tables are not allowed in FROM clause when the query has subqueries in WHERE clause and it references a column from another query
-- immutable functions are also treated as reference tables, query should not
-- work since there is a correlated subquery in the WHERE clause
DEBUG: generating subplan 3_1 for subquery SELECT user_id, NULL::timestamp without time zone AS "time", NULL::integer AS event_type, NULL::integer AS value_2, NULL::double precision AS value_3, NULL::bigint AS value_4 FROM public.events_table WHERE true
DEBUG: Plan 3 query after replacing subqueries and CTEs: SELECT user_id FROM public.users_reference_table WHERE (NOT (EXISTS (SELECT events_table.value_2 FROM (SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.event_type, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('3_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, event_type integer, value_2 integer, value_3 double precision, value_4 bigint)) events_table(user_id, "time", event_type, value_2, value_3, value_4) WHERE (users_reference_table.user_id OPERATOR(pg_catalog.=) events_table.user_id)))) LIMIT 3
user_id
---------
(0 rows)
-- immutable functions are also treated as reference tables thus
-- although the subquery in WHERE with NOT EXISTS operator (e.g., semi-join)
-- is correlated with the immutable function, since events_table can be
-- recursively planned the whole query becomes a router query
SELECT
user_id
FROM
@ -79,11 +87,21 @@ WHERE
WHERE
users_reference_table.user_id = events_table.user_id
)
ORDER BY 1
LIMIT 3;
ERROR: cannot pushdown the subquery
DETAIL: Functions are not allowed in FROM clause when the query has subqueries in WHERE clause and it references a column from another query
-- subqueries without FROM are also treated as reference tables, query should not
-- work since there is a correlated subquery in the WHERE clause
DEBUG: generating subplan 5_1 for subquery SELECT user_id, NULL::timestamp without time zone AS "time", NULL::integer AS event_type, NULL::integer AS value_2, NULL::double precision AS value_3, NULL::bigint AS value_4 FROM public.events_table WHERE true
DEBUG: Plan 5 query after replacing subqueries and CTEs: SELECT user_id FROM (SELECT series.user_id FROM generate_series(1, 10) series(user_id)) users_reference_table WHERE (NOT (EXISTS (SELECT events_table.value_2 FROM (SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.event_type, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('5_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, event_type integer, value_2 integer, value_3 double precision, value_4 bigint)) events_table(user_id, "time", event_type, value_2, value_3, value_4) WHERE (users_reference_table.user_id OPERATOR(pg_catalog.=) events_table.user_id)))) ORDER BY user_id LIMIT 3
user_id
---------
7
8
9
(3 rows)
-- subqueries without FROM are also treated as reference tables thus
-- although the subquery in WHERE with NOT EXISTS operator (e.g., semi-join)
-- is correlated with the subquery, since events_table can be
-- recursively planned the whole query becomes a router query
SELECT
user_id
FROM
@ -98,8 +116,13 @@ WHERE
users_reference_table.user_id = events_table.user_id
)
LIMIT 3;
ERROR: cannot pushdown the subquery
DETAIL: Subqueries without FROM are not allowed in FROM clause when the outer query has subqueries in WHERE clause and it references a column from another query
DEBUG: generating subplan 7_1 for subquery SELECT user_id, NULL::timestamp without time zone AS "time", NULL::integer AS event_type, NULL::integer AS value_2, NULL::double precision AS value_3, NULL::bigint AS value_4 FROM public.events_table WHERE true
DEBUG: Plan 7 query after replacing subqueries and CTEs: SELECT user_id FROM (SELECT 5 AS user_id) users_reference_table WHERE (NOT (EXISTS (SELECT events_table.value_2 FROM (SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.event_type, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('7_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, event_type integer, value_2 integer, value_3 double precision, value_4 bigint)) events_table(user_id, "time", event_type, value_2, value_3, value_4) WHERE (users_reference_table.user_id OPERATOR(pg_catalog.=) events_table.user_id)))) LIMIT 3
user_id
---------
(0 rows)
RESET client_min_messages;
-- join with distributed table prevents FROM from recurring
SELECT
DISTINCT user_id
@ -166,7 +189,7 @@ WHERE
ORDER BY user_id
LIMIT 3;
ERROR: cannot pushdown the subquery
DETAIL: There exist a reference table in the outer part of the outer join
DETAIL: Complex subqueries and CTEs are not allowed in the FROM clause when the query has subqueries in the WHERE clause and it references a column from another query
-- subqueries in WHERE with IN operator without equality
SELECT
users_table.user_id, count(*)
@ -491,8 +514,8 @@ FROM
WHERE user_id
NOT IN
(SELECT users_table.value_2 FROM users_table JOIN users_reference_table as u2 ON users_table.value_2 = u2.value_2);
DEBUG: generating subplan 18_1 for subquery SELECT users_table.value_2 FROM (public.users_table JOIN public.users_reference_table u2 ON ((users_table.value_2 OPERATOR(pg_catalog.=) u2.value_2)))
DEBUG: Plan 18 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM public.users_reference_table WHERE (NOT (user_id OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.value_2 FROM read_intermediate_result('18_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer))))
DEBUG: generating subplan 22_1 for subquery SELECT users_table.value_2 FROM (public.users_table JOIN public.users_reference_table u2 ON ((users_table.value_2 OPERATOR(pg_catalog.=) u2.value_2)))
DEBUG: Plan 22 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM public.users_reference_table WHERE (NOT (user_id OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.value_2 FROM read_intermediate_result('22_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer))))
count
-------
10
@ -507,8 +530,8 @@ FROM
(SELECT users_table.value_2
FROM users_table
JOIN users_reference_table AS u2 ON users_table.value_2 = u2.value_2);
DEBUG: generating subplan 20_1 for subquery SELECT users_table.value_2 FROM (public.users_table JOIN public.users_reference_table u2 ON ((users_table.value_2 OPERATOR(pg_catalog.=) u2.value_2)))
DEBUG: Plan 20 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT users_reference_table.user_id, random() AS random FROM public.users_reference_table) vals WHERE (NOT (user_id OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.value_2 FROM read_intermediate_result('20_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer))))
DEBUG: generating subplan 24_1 for subquery SELECT users_table.value_2 FROM (public.users_table JOIN public.users_reference_table u2 ON ((users_table.value_2 OPERATOR(pg_catalog.=) u2.value_2)))
DEBUG: Plan 24 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT users_reference_table.user_id, random() AS random FROM public.users_reference_table) vals WHERE (NOT (user_id OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.value_2 FROM read_intermediate_result('24_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer))))
count
-------
10

View File

@ -875,7 +875,7 @@ EXPLAIN (COSTS FALSE) SELECT et.* FROM recent_10_users JOIN events_table et USIN
-> Sort
Sort Key: remote_scan."time" DESC
-> Custom Scan (Citus Real-Time)
-> Distributed Subplan 96_1
-> Distributed Subplan 97_1
-> Limit
-> Sort
Sort Key: max((max(remote_scan.lastseen))) DESC

View File

@ -231,17 +231,19 @@ DEBUG: Creating router plan
DEBUG: Plan is router executable
DEBUG: generating subplan 39_3 for subquery 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 intermediate_result.x, intermediate_result.y FROM read_intermediate_result('39_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)
DEBUG: Plan 39 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('39_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u LEFT JOIN recursive_set_local.test USING (x)) ORDER BY u.x, u.y
DEBUG: generating subplan 39_4 for subquery SELECT x, y FROM recursive_set_local.test WHERE true
DEBUG: Plan 39 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('39_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u LEFT JOIN (SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('39_4'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) test(x, y) 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
-- we replace some queries including the local query, the intermediate result is on the inner part of an outer join
SELECT * FROM ((SELECT * FROM local_test) INTERSECT (SELECT * FROM test ORDER BY x LIMIT 1)) u RIGHT JOIN test USING (x) ORDER BY 1,2;
DEBUG: generating subplan 42_1 for subquery SELECT x, y FROM recursive_set_local.local_test
DEBUG: generating subplan 43_1 for subquery SELECT x, y FROM recursive_set_local.local_test
DEBUG: push down of limit count: 1
DEBUG: generating subplan 42_2 for subquery SELECT x, y FROM recursive_set_local.test ORDER BY x LIMIT 1
DEBUG: generating subplan 43_2 for subquery SELECT x, y FROM recursive_set_local.test ORDER BY x LIMIT 1
DEBUG: Creating router plan
DEBUG: Plan is router executable
DEBUG: generating subplan 42_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('42_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) INTERSECT SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('42_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)
DEBUG: Plan 42 query after replacing subqueries and CTEs: SELECT test.x, u.y, test.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('42_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u RIGHT JOIN recursive_set_local.test USING (x)) ORDER BY test.x, u.y
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) INTERSECT SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('43_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)
DEBUG: Plan 43 query after replacing subqueries and CTEs: SELECT test.x, u.y, test.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 RIGHT JOIN recursive_set_local.test USING (x)) ORDER BY test.x, u.y
x | y | y
---+---+---
1 | | 1
@ -250,29 +252,29 @@ DEBUG: Plan 42 query after replacing subqueries and CTEs: SELECT test.x, u.y, t
-- recurively plan left part of the join, and run a final real-time query
SELECT * FROM ((SELECT * FROM local_test) INTERSECT (SELECT * FROM test ORDER BY x LIMIT 1)) u INNER JOIN test USING (x) ORDER BY 1,2;
DEBUG: generating subplan 45_1 for subquery SELECT x, y FROM recursive_set_local.local_test
DEBUG: generating subplan 46_1 for subquery SELECT x, y FROM recursive_set_local.local_test
DEBUG: push down of limit count: 1
DEBUG: generating subplan 45_2 for subquery SELECT x, y FROM recursive_set_local.test ORDER BY x LIMIT 1
DEBUG: generating subplan 46_2 for subquery SELECT x, y FROM recursive_set_local.test ORDER BY x LIMIT 1
DEBUG: Creating router plan
DEBUG: Plan is router executable
DEBUG: generating subplan 45_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('45_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) INTERSECT SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('45_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)
DEBUG: Plan 45 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('45_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u JOIN recursive_set_local.test USING (x)) ORDER BY u.x, u.y
DEBUG: generating subplan 46_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('46_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) INTERSECT SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('46_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)
DEBUG: Plan 46 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('46_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u JOIN recursive_set_local.test USING (x)) ORDER BY u.x, u.y
x | y | y
---+---+---
(0 rows)
-- set operations and the sublink can be recursively planned
SELECT * FROM ((SELECT x FROM test) UNION (SELECT x FROM (SELECT x FROM local_test) as foo WHERE x IN (SELECT x FROM test))) u ORDER BY 1;
DEBUG: generating subplan 48_1 for subquery SELECT x FROM recursive_set_local.local_test
DEBUG: generating subplan 48_2 for subquery SELECT x FROM recursive_set_local.test
DEBUG: generating subplan 49_1 for subquery SELECT x FROM recursive_set_local.local_test
DEBUG: generating subplan 49_2 for subquery SELECT x FROM recursive_set_local.test
DEBUG: Creating router plan
DEBUG: Plan is router executable
DEBUG: generating subplan 48_3 for subquery SELECT x FROM (SELECT intermediate_result.x FROM read_intermediate_result('48_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer)) foo WHERE (x OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.x FROM read_intermediate_result('48_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer)))
DEBUG: generating subplan 48_4 for subquery SELECT x FROM recursive_set_local.test
DEBUG: generating subplan 49_3 for subquery SELECT x FROM (SELECT intermediate_result.x FROM read_intermediate_result('49_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer)) foo WHERE (x OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.x FROM read_intermediate_result('49_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer)))
DEBUG: generating subplan 49_4 for subquery SELECT x FROM recursive_set_local.test
DEBUG: Creating router plan
DEBUG: Plan is router executable
DEBUG: generating subplan 48_5 for subquery SELECT intermediate_result.x FROM read_intermediate_result('48_4'::text, 'binary'::citus_copy_format) intermediate_result(x integer) UNION SELECT intermediate_result.x FROM read_intermediate_result('48_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer)
DEBUG: Plan 48 query after replacing subqueries and CTEs: SELECT x FROM (SELECT intermediate_result.x FROM read_intermediate_result('48_5'::text, 'binary'::citus_copy_format) intermediate_result(x integer)) u ORDER BY x
DEBUG: generating subplan 49_5 for subquery SELECT intermediate_result.x FROM read_intermediate_result('49_4'::text, 'binary'::citus_copy_format) intermediate_result(x integer) UNION SELECT intermediate_result.x FROM read_intermediate_result('49_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer)
DEBUG: Plan 49 query after replacing subqueries and CTEs: SELECT x FROM (SELECT intermediate_result.x FROM read_intermediate_result('49_5'::text, 'binary'::citus_copy_format) intermediate_result(x integer)) u ORDER BY x
DEBUG: Creating router plan
DEBUG: Plan is router executable
x
@ -315,11 +317,11 @@ DEBUG: pruning merge fetch taskId 11
DETAIL: Creating dependency on merge taskId 20
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 53_1 for subquery SELECT t1.x FROM recursive_set_local.test t1, recursive_set_local.test t2 WHERE (t1.x OPERATOR(pg_catalog.=) t2.y) LIMIT 2
DEBUG: generating subplan 53_2 for subquery SELECT x FROM recursive_set_local.local_test
DEBUG: generating subplan 53_3 for subquery SELECT x FROM recursive_set_local.test
DEBUG: generating subplan 53_4 for subquery SELECT x FROM recursive_set_local.test
DEBUG: Plan 53 query after replacing subqueries and CTEs: SELECT intermediate_result.x FROM read_intermediate_result('53_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer) INTERSECT SELECT intermediate_result.x FROM read_intermediate_result('53_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer) INTERSECT ((SELECT intermediate_result.x FROM read_intermediate_result('53_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer) UNION ALL SELECT intermediate_result.x FROM read_intermediate_result('53_4'::text, 'binary'::citus_copy_format) intermediate_result(x integer)) INTERSECT SELECT i.i FROM generate_series(0, 100) i(i)) ORDER BY 1 DESC
DEBUG: generating subplan 54_1 for subquery SELECT t1.x FROM recursive_set_local.test t1, recursive_set_local.test t2 WHERE (t1.x OPERATOR(pg_catalog.=) t2.y) LIMIT 2
DEBUG: generating subplan 54_2 for subquery SELECT x FROM recursive_set_local.local_test
DEBUG: generating subplan 54_3 for subquery SELECT x FROM recursive_set_local.test
DEBUG: generating subplan 54_4 for subquery SELECT x FROM recursive_set_local.test
DEBUG: Plan 54 query after replacing subqueries and CTEs: SELECT intermediate_result.x FROM read_intermediate_result('54_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer) INTERSECT SELECT intermediate_result.x FROM read_intermediate_result('54_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer) INTERSECT ((SELECT intermediate_result.x FROM read_intermediate_result('54_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer) UNION ALL SELECT intermediate_result.x FROM read_intermediate_result('54_4'::text, 'binary'::citus_copy_format) intermediate_result(x integer)) INTERSECT SELECT i.i FROM generate_series(0, 100) i(i)) ORDER BY 1 DESC
DEBUG: Creating router plan
DEBUG: Plan is router executable
x

View File

@ -510,13 +510,8 @@ DEBUG: generating subplan 101_1 for subquery SELECT x, y FROM recursive_union.t
DEBUG: generating subplan 101_2 for subquery SELECT x, y FROM recursive_union.test ORDER BY x
DEBUG: Creating router plan
DEBUG: Plan is router executable
<<<<<<< HEAD
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 (SELECT x_1.x FROM generate_series(1, 10) x_1(x)) x USING (x)) ORDER BY u.x, u.y
=======
DEBUG: generating subplan 101_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('101_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) EXCEPT SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('101_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)
DEBUG: Plan 101 query after replacing subqueries and CTEs: SELECT u.x, u.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('101_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
>>>>>>> e2f99a04... Recursively plan inner parts of recurring tuple joins
DEBUG: Plan 101 query after replacing subqueries and CTEs: SELECT u.x, u.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('101_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u JOIN (SELECT x_1.x FROM generate_series(1, 10) x_1(x)) x USING (x)) ORDER BY u.x, u.y
DEBUG: Creating router plan
DEBUG: Plan is router executable
x | y

View File

@ -115,6 +115,8 @@ FROM
DEBUG: push down of limit count: 5
DEBUG: generating subplan 14_1 for subquery SELECT users_table.value_2 FROM public.users_table, public.events_table WHERE ((users_table.user_id OPERATOR(pg_catalog.=) events_table.user_id) AND (events_table.event_type OPERATOR(pg_catalog.=) ANY (ARRAY[1, 2, 3, 4]))) LIMIT 5
DEBUG: Plan 14 query after replacing subqueries and CTEs: SELECT foo.value_2 FROM ((SELECT intermediate_result.value_2 FROM read_intermediate_result('14_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) foo LEFT JOIN (SELECT users_table.value_2 FROM public.users_table, public.events_table WHERE ((users_table.user_id OPERATOR(pg_catalog.=) events_table.user_id) AND (events_table.event_type OPERATOR(pg_catalog.=) ANY (ARRAY[5, 6, 7, 8])))) bar ON ((foo.value_2 OPERATOR(pg_catalog.=) bar.value_2)))
DEBUG: generating subplan 14_2 for subquery SELECT users_table.value_2 FROM public.users_table, public.events_table WHERE ((users_table.user_id OPERATOR(pg_catalog.=) events_table.user_id) AND (events_table.event_type OPERATOR(pg_catalog.=) ANY (ARRAY[5, 6, 7, 8])))
DEBUG: Plan 14 query after replacing subqueries and CTEs: SELECT foo.value_2 FROM ((SELECT intermediate_result.value_2 FROM read_intermediate_result('14_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) foo LEFT JOIN (SELECT intermediate_result.value_2 FROM read_intermediate_result('14_2'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) bar ON ((foo.value_2 OPERATOR(pg_catalog.=) bar.value_2)))
ERROR: cannot pushdown the subquery
DETAIL: Complex subqueries and CTEs cannot be in the outer part of the outer join
-- Aggregates in subquery without partition column can be planned recursively

View File

@ -44,8 +44,8 @@ FROM (SELECT 1 AS id,
3 AS value_3) AS tt1
WHERE id IN (SELECT user_id
FROM events_table);
DEBUG: generating subplan 6_1 for subquery SELECT user_id FROM public.events_table
DEBUG: Plan 6 query after replacing subqueries and CTEs: SELECT id, value_1, value_3 FROM (SELECT 1 AS id, 2 AS value_1, 3 AS value_3) tt1 WHERE (id OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.user_id FROM read_intermediate_result('6_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)))
DEBUG: generating subplan 6_1 for subquery SELECT user_id, NULL::timestamp without time zone AS "time", NULL::integer AS event_type, NULL::integer AS value_2, NULL::double precision AS value_3, NULL::bigint AS value_4 FROM public.events_table WHERE true
DEBUG: Plan 6 query after replacing subqueries and CTEs: SELECT id, value_1, value_3 FROM (SELECT 1 AS id, 2 AS value_1, 3 AS value_3) tt1 WHERE (id OPERATOR(pg_catalog.=) ANY (SELECT events_table.user_id FROM (SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.event_type, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('6_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, event_type integer, value_2 integer, value_3 double precision, value_4 bigint)) events_table(user_id, "time", event_type, value_2, value_3, value_4)))
id | value_1 | value_3
----+---------+---------
1 | 2 | 3
@ -580,8 +580,8 @@ IN
)
ORDER BY
generate_series ASC;
DEBUG: generating subplan 63_1 for subquery SELECT value_2 FROM public.events_table
DEBUG: Plan 63 query after replacing subqueries and CTEs: SELECT generate_series FROM (SELECT generate_series.generate_series FROM generate_series(1, 10) generate_series(generate_series)) gst WHERE (generate_series OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.value_2 FROM read_intermediate_result('63_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer))) ORDER BY generate_series
DEBUG: generating subplan 63_1 for subquery SELECT NULL::integer AS user_id, NULL::timestamp without time zone AS "time", NULL::integer AS event_type, value_2, NULL::double precision AS value_3, NULL::bigint AS value_4 FROM public.events_table WHERE true
DEBUG: Plan 63 query after replacing subqueries and CTEs: SELECT generate_series FROM (SELECT generate_series.generate_series FROM generate_series(1, 10) generate_series(generate_series)) gst WHERE (generate_series OPERATOR(pg_catalog.=) ANY (SELECT events_table.value_2 FROM (SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.event_type, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('63_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, event_type integer, value_2 integer, value_3 double precision, value_4 bigint)) events_table(user_id, "time", event_type, value_2, value_3, value_4))) ORDER BY generate_series
generate_series
-----------------
1
@ -618,8 +618,9 @@ IN
)
ORDER BY
generate_series ASC;
DEBUG: generating subplan 65_1 for subquery SELECT user_id FROM public.users_table WHERE (user_id OPERATOR(pg_catalog.=) ANY (SELECT generate_series.generate_series FROM generate_series(1, 3) generate_series(generate_series)))
DEBUG: Plan 65 query after replacing subqueries and CTEs: SELECT generate_series FROM (SELECT generate_series.generate_series FROM generate_series(1, 10) generate_series(generate_series)) gst WHERE (generate_series OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.user_id FROM read_intermediate_result('65_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer))) ORDER BY generate_series
DEBUG: generating subplan 65_1 for subquery SELECT user_id, NULL::timestamp without time zone AS "time", NULL::integer AS value_1, NULL::integer AS value_2, NULL::double precision AS value_3, NULL::bigint AS value_4 FROM public.users_table WHERE true
DEBUG: generating subplan 65_2 for subquery SELECT user_id FROM (SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.value_1, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('65_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, value_1 integer, value_2 integer, value_3 double precision, value_4 bigint)) users_table(user_id, "time", value_1, value_2, value_3, value_4) WHERE (user_id OPERATOR(pg_catalog.=) ANY (SELECT generate_series.generate_series FROM generate_series(1, 3) generate_series(generate_series)))
DEBUG: Plan 65 query after replacing subqueries and CTEs: SELECT generate_series FROM (SELECT generate_series.generate_series FROM generate_series(1, 10) generate_series(generate_series)) gst WHERE (generate_series OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.user_id FROM read_intermediate_result('65_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer))) ORDER BY generate_series
generate_series
-----------------
1
@ -646,9 +647,9 @@ IN
user_id
FROM
users_table);
DEBUG: generating subplan 67_1 for subquery SELECT id, value_1 FROM subquery_in_where.local_table
DEBUG: generating subplan 67_2 for subquery SELECT user_id FROM public.users_table
DEBUG: Plan 67 query after replacing subqueries and CTEs: SELECT id, value_1 FROM (SELECT intermediate_result.id, intermediate_result.value_1 FROM read_intermediate_result('67_1'::text, 'binary'::citus_copy_format) intermediate_result(id integer, value_1 integer)) sub_table WHERE (id OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.user_id FROM read_intermediate_result('67_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)))
DEBUG: generating subplan 68_1 for subquery SELECT id, value_1 FROM subquery_in_where.local_table
DEBUG: generating subplan 68_2 for subquery SELECT user_id FROM public.users_table
DEBUG: Plan 68 query after replacing subqueries and CTEs: SELECT id, value_1 FROM (SELECT intermediate_result.id, intermediate_result.value_1 FROM read_intermediate_result('68_1'::text, 'binary'::citus_copy_format) intermediate_result(id integer, value_1 integer)) sub_table WHERE (id OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.user_id FROM read_intermediate_result('68_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)))
id | value_1
----+---------
1 | 1
@ -675,10 +676,10 @@ IN
id
FROM
local_table);
DEBUG: generating subplan 69_1 for subquery SELECT id FROM subquery_in_where.local_table
DEBUG: generating subplan 70_1 for subquery SELECT id FROM subquery_in_where.local_table
DEBUG: push down of limit count: 10
DEBUG: generating subplan 69_2 for subquery SELECT user_id, "time", value_1, value_2, value_3, value_4 FROM public.users_table ORDER BY user_id LIMIT 10
DEBUG: Plan 69 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.value_1, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('69_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, value_1 integer, value_2 integer, value_3 double precision, value_4 bigint)) sub_table WHERE (user_id OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.id FROM read_intermediate_result('69_1'::text, 'binary'::citus_copy_format) intermediate_result(id integer)))
DEBUG: generating subplan 70_2 for subquery SELECT user_id, "time", value_1, value_2, value_3, value_4 FROM public.users_table ORDER BY user_id LIMIT 10
DEBUG: Plan 70 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.value_1, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('70_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, value_1 integer, value_2 integer, value_3 double precision, value_4 bigint)) sub_table WHERE (user_id OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.id FROM read_intermediate_result('70_1'::text, 'binary'::citus_copy_format) intermediate_result(id integer)))
count
-------
10

View File

@ -149,12 +149,15 @@ FROM
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_right_reference b
ON (l_custkey = r_custkey AND l_custkey = -1 /* nonexistant */);
-- Right join should be disallowed in this case
SET client_min_messages TO DEBUG1;
-- Right join should be allowed in this case
-- since the table in the inner part can be recursively
-- planned
SELECT
min(r_custkey), max(r_custkey)
FROM
multi_outer_join_left_hash a RIGHT JOIN multi_outer_join_right_reference b ON (l_custkey = r_custkey);
SET client_min_messages TO LOG;
-- Reverse right join should be same as left join
SELECT
@ -243,13 +246,15 @@ FROM
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_right_reference b
ON (l_custkey = r_custkey AND r_custkey = 21);
-- Right join should not be allowed in this case
SET client_min_messages TO DEBUG;
-- Right join should be allowed in this case
-- since the table in the inner part can be recursively
-- planned
SELECT
min(r_custkey), max(r_custkey)
FROM
multi_outer_join_left_hash a RIGHT JOIN multi_outer_join_right_reference b ON (l_custkey = r_custkey);
SET client_min_messages TO LOG;
-- Reverse right join should be same as left join
SELECT
@ -279,6 +284,8 @@ WHERE
r1.r_custkey is NULL;
-- Three way join 2-1-1 (broadcast + broadcast join) should work
-- after #2481 since we're hitting aggressive outer join checks
SET client_min_messages TO DEBUG;
SELECT
l_custkey, r_custkey, t_custkey
FROM
@ -286,6 +293,7 @@ FROM
LEFT JOIN multi_outer_join_right_reference r1 ON (l1.l_custkey = r1.r_custkey)
LEFT JOIN multi_outer_join_third_reference t1 ON (r1.r_custkey = t1.t_custkey)
ORDER BY 1;
SET client_min_messages TO LOG;
-- Right join with single shard right most table should error out
SELECT

View File

@ -198,13 +198,28 @@ FROM
20 | 0
(1 row)
-- Right join should be disallowed in this case
SET client_min_messages TO DEBUG1;
-- Right join should be allowed in this case
-- since the table in the inner part can be recursively
-- planned
SELECT
min(r_custkey), max(r_custkey)
FROM
multi_outer_join_left_hash a RIGHT JOIN multi_outer_join_right_reference b ON (l_custkey = r_custkey);
<<<<<<< HEAD
ERROR: cannot pushdown the subquery
DETAIL: There exist a reference table in the outer part of the outer join
=======
LOG: join order: [ "multi_outer_join_left_hash" ]
DEBUG: generating subplan 12_1 for subquery SELECT l_custkey, NULL::character varying(25) AS l_name, NULL::character varying(40) AS l_address, NULL::integer AS l_nationkey, NULL::character(15) AS l_phone, NULL::numeric(15,2) AS l_acctbal, NULL::character(10) AS l_mktsegment, NULL::character varying(117) AS l_comment FROM public.multi_outer_join_left_hash a WHERE true
DEBUG: Plan 12 query after replacing subqueries and CTEs: SELECT min(b.r_custkey) AS min, max(b.r_custkey) AS max FROM ((SELECT intermediate_result.l_custkey, intermediate_result.l_name, intermediate_result.l_address, intermediate_result.l_nationkey, intermediate_result.l_phone, intermediate_result.l_acctbal, intermediate_result.l_mktsegment, intermediate_result.l_comment FROM read_intermediate_result('12_1'::text, 'binary'::citus_copy_format) intermediate_result(l_custkey integer, l_name character varying(25), l_address character varying(40), l_nationkey integer, l_phone character(15), l_acctbal numeric(15,2), l_mktsegment character(10), l_comment character varying(117))) multi_outer_join_left_hash(l_custkey, l_name, l_address, l_nationkey, l_phone, l_acctbal, l_mktsegment, l_comment) RIGHT JOIN public.multi_outer_join_right_reference b ON ((multi_outer_join_left_hash.l_custkey OPERATOR(pg_catalog.=) b.r_custkey)))
min | max
-----+-----
1 | 15
(1 row)
SET client_min_messages TO LOG;
>>>>>>> d9d1dfbf... respect the regression tests for recursively plan inner parts of recurring tuple joins
-- Reverse right join should be same as left join
SELECT
min(l_custkey), max(l_custkey)
@ -313,13 +328,30 @@ FROM
25 | 1
(1 row)
-- Right join should not be allowed in this case
SET client_min_messages TO DEBUG;
-- Right join should be allowed in this case
-- since the table in the inner part can be recursively
-- planned
SELECT
min(r_custkey), max(r_custkey)
FROM
multi_outer_join_left_hash a RIGHT JOIN multi_outer_join_right_reference b ON (l_custkey = r_custkey);
<<<<<<< HEAD
ERROR: cannot pushdown the subquery
DETAIL: There exist a reference table in the outer part of the outer join
=======
LOG: join order: [ "multi_outer_join_left_hash" ]
DEBUG: generating subplan 22_1 for subquery SELECT l_custkey, NULL::character varying(25) AS l_name, NULL::character varying(40) AS l_address, NULL::integer AS l_nationkey, NULL::character(15) AS l_phone, NULL::numeric(15,2) AS l_acctbal, NULL::character(10) AS l_mktsegment, NULL::character varying(117) AS l_comment FROM public.multi_outer_join_left_hash a WHERE true
DEBUG: Plan 22 query after replacing subqueries and CTEs: SELECT min(b.r_custkey) AS min, max(b.r_custkey) AS max FROM ((SELECT intermediate_result.l_custkey, intermediate_result.l_name, intermediate_result.l_address, intermediate_result.l_nationkey, intermediate_result.l_phone, intermediate_result.l_acctbal, intermediate_result.l_mktsegment, intermediate_result.l_comment FROM read_intermediate_result('22_1'::text, 'binary'::citus_copy_format) intermediate_result(l_custkey integer, l_name character varying(25), l_address character varying(40), l_nationkey integer, l_phone character(15), l_acctbal numeric(15,2), l_mktsegment character(10), l_comment character varying(117))) multi_outer_join_left_hash(l_custkey, l_name, l_address, l_nationkey, l_phone, l_acctbal, l_mktsegment, l_comment) RIGHT JOIN public.multi_outer_join_right_reference b ON ((multi_outer_join_left_hash.l_custkey OPERATOR(pg_catalog.=) b.r_custkey)))
DEBUG: Creating router plan
DEBUG: Plan is router executable
min | max
-----+-----
11 | 30
(1 row)
SET client_min_messages TO LOG;
>>>>>>> d9d1dfbf... respect the regression tests for recursively plan inner parts of recurring tuple joins
-- Reverse right join should be same as left join
SELECT
min(l_custkey), max(l_custkey)
@ -351,6 +383,8 @@ WHERE
r1.r_custkey is NULL;
ERROR: complex joins are only supported when all distributed tables are joined on their distribution columns with equal operator
-- Three way join 2-1-1 (broadcast + broadcast join) should work
-- after #2481 since we're hitting aggressive outer join checks
SET client_min_messages TO DEBUG;
SELECT
l_custkey, r_custkey, t_custkey
FROM
@ -358,6 +392,7 @@ FROM
LEFT JOIN multi_outer_join_right_reference r1 ON (l1.l_custkey = r1.r_custkey)
LEFT JOIN multi_outer_join_third_reference t1 ON (r1.r_custkey = t1.t_custkey)
ORDER BY 1;
<<<<<<< HEAD
l_custkey | r_custkey | t_custkey
-----------+-----------+-----------
1 | |
@ -387,6 +422,15 @@ ORDER BY 1;
30 | 30 | 30
(25 rows)
=======
DEBUG: Creating router plan
DEBUG: Plan is router executable
DEBUG: generating subplan 27_1 for subquery SELECT t_custkey, NULL::character varying(25) AS t_name, NULL::character varying(40) AS t_address, NULL::integer AS t_nationkey, NULL::character(15) AS t_phone, NULL::numeric(15,2) AS t_acctbal, NULL::character(10) AS t_mktsegment, NULL::character varying(117) AS t_comment FROM public.multi_outer_join_third_reference t1 WHERE true
DEBUG: Plan 27 query after replacing subqueries and CTEs: SELECT l1.l_custkey, r1.r_custkey, multi_outer_join_third_reference.t_custkey FROM ((public.multi_outer_join_left_hash l1 LEFT JOIN public.multi_outer_join_right_reference r1 ON ((l1.l_custkey OPERATOR(pg_catalog.=) r1.r_custkey))) LEFT JOIN (SELECT intermediate_result.t_custkey, intermediate_result.t_name, intermediate_result.t_address, intermediate_result.t_nationkey, intermediate_result.t_phone, intermediate_result.t_acctbal, intermediate_result.t_mktsegment, intermediate_result.t_comment FROM read_intermediate_result('27_1'::text, 'binary'::citus_copy_format) intermediate_result(t_custkey integer, t_name character varying(25), t_address character varying(40), t_nationkey integer, t_phone character(15), t_acctbal numeric(15,2), t_mktsegment character(10), t_comment character varying(117))) multi_outer_join_third_reference(t_custkey, t_name, t_address, t_nationkey, t_phone, t_acctbal, t_mktsegment, t_comment) ON ((r1.r_custkey OPERATOR(pg_catalog.=) multi_outer_join_third_reference.t_custkey))) ORDER BY l1.l_custkey
ERROR: cannot pushdown the subquery
DETAIL: There exist a reference table in the outer part of the outer join
SET client_min_messages TO LOG;
>>>>>>> d9d1dfbf... respect the regression tests for recursively plan inner parts of recurring tuple joins
-- Right join with single shard right most table should error out
SELECT
l_custkey, r_custkey, t_custkey

View File

@ -26,8 +26,8 @@ SELECT count(*) FROM customer, orders WHERE c_custkey = o_custkey;
-- currently not exercised, but we are adding this test to catch this bug when
-- we start supporting outer joins.
SELECT c_custkey
FROM (customer LEFT OUTER JOIN orders ON (c_custkey = o_custkey)) AS
test(c_custkey, c_nationkey)
INNER JOIN lineitem ON (test.c_custkey = l_orderkey)
LIMIT 10;
--SELECT c_custkey
--FROM (customer LEFT OUTER JOIN orders ON (c_custkey = o_custkey)) AS
-- test(c_custkey, c_nationkey)
-- INNER JOIN lineitem ON (test.c_custkey = l_orderkey)
--LIMIT 10;

View File

@ -43,20 +43,29 @@ SELECT subquery_1.user_id FROM
ON user_buy_test_table.user_id > users_ref_test_table.id) subquery_1
ORDER BY 1;
-- Shouldn't work, reference table at the outer side is not allowed
SET client_min_messages TO DEBUG;
-- Should work because we can recursively plan the distributed relation on the
-- inner part of the outer join
SELECT * FROM
(SELECT random() FROM users_ref_test_table LEFT JOIN user_buy_test_table
ON users_ref_test_table.id = user_buy_test_table.user_id) subquery_1;
(SELECT users_ref_test_table.id FROM users_ref_test_table LEFT JOIN user_buy_test_table
ON users_ref_test_table.id = user_buy_test_table.user_id) subquery_1 ORDER BY 1 DESC;
RESET client_min_messages;
-- Should work, reference table at the inner side is allowed
SELECT count(*) FROM
(SELECT random() FROM users_ref_test_table RIGHT JOIN user_buy_test_table
ON user_buy_test_table.user_id = users_ref_test_table.id) subquery_1;
-- Shouldn't work, reference table at the outer side is not allowed
SELECT * FROM
SET client_min_messages TO DEBUG;
-- Should work because we can recursively plan the distributed relation on the
-- inner part of the outer join
SELECT count(*) FROM
(SELECT random() FROM user_buy_test_table RIGHT JOIN users_ref_test_table
ON user_buy_test_table.user_id = users_ref_test_table.id) subquery_1;
RESET client_min_messages;
-- Equi join test with reference table on non-partition keys
SELECT count(*) FROM
@ -167,7 +176,9 @@ SELECT count(*) FROM
SELECT count(*) FROM user_buy_test_table LEFT JOIN (SELECT * FROM generate_series(1,10) id) users_ref_test_table
ON user_buy_test_table.item_id = users_ref_test_table.id;
-- table function cannot be the outer relationship in an outer join
SET client_min_messages TO DEBUG;
-- table function can be the outer relationship in an outer join
-- since the inner side is recursively planned
SELECT count(*) FROM
(SELECT random() FROM user_buy_test_table RIGHT JOIN generate_series(1,10) AS users_ref_test_table(id)
ON user_buy_test_table.item_id > users_ref_test_table.id) subquery_1;
@ -175,6 +186,8 @@ SELECT count(*) FROM
SELECT count(*) FROM user_buy_test_table RIGHT JOIN (SELECT * FROM generate_series(1,10) id) users_ref_test_table
ON user_buy_test_table.item_id = users_ref_test_table.id;
RESET client_min_messages;
-- volatile functions can be used as table expressions through recursive planning
SET client_min_messages TO DEBUG;
@ -209,10 +222,15 @@ ON user_buy_test_table.item_id = users_ref_test_table.id;
SELECT count(*) FROM user_buy_test_table LEFT JOIN (SELECT 5 AS id) users_ref_test_table
ON user_buy_test_table.item_id = users_ref_test_table.id;
-- subquery without FROM cannot be the outer relationship in an outer join
SET client_min_messages TO DEBUG1;
-- subquery without FROM can be the outer relationship in an outer join
-- since the inner part can be recursively planned
SELECT count(*) FROM user_buy_test_table RIGHT JOIN (SELECT 5 AS id) users_ref_test_table
ON user_buy_test_table.item_id = users_ref_test_table.id;
RESET client_min_messages;
-- can perform a union with subquery without FROM
-- with pulling data to coordinator
SET client_min_messages TO DEBUG;
@ -301,8 +319,12 @@ FROM
) as foo
GROUP BY user_id ORDER BY 2 DESC LIMIT 10;
-- should not be able to pushdown since reference table is in the
-- direct outer part of the left join
SET client_min_messages TO DEBUG1;
-- although the inner part of an outer join with reference table is
-- recursively planned, we still hit the agressive outer join checks
-- (recurring tuple Left Join recurring tuple) errors
SELECT
user_id, sum(value_1)
FROM
@ -314,13 +336,17 @@ FROM
) as foo
GROUP BY user_id ORDER BY 2 DESC LIMIT 10;
-- should not be able to pushdown since reference table is in the
-- direct outer part of the left join wrapped into a subquery
-- should be able to pushdown since reference table is in the
-- direct outer part of the left join is recursively planned
-- and the final query becomes a router query
SELECT
*
users_table.time, users_table.value_2
FROM
(SELECT *, random() FROM events_reference_table) as ref_all LEFT JOIN users_table
ON (users_table.user_id = ref_all.value_2);
ON (users_table.user_id = ref_all.value_2)
ORDER BY 1, 2 DESC LIMIT 6;
RESET client_min_messages;
-- should not be able to pushdown since reference table is in the
-- outer part of the left join
@ -627,8 +653,9 @@ count(*) AS cnt, "generated_group_field"
cnt DESC, generated_group_field ASC
LIMIT 10;
-- RIGHT JOINs used with INNER JOINs should error out since reference table exist in the
-- right side of the RIGHT JOIN.
-- RIGHT JOINs used with INNER JOINs should work out since reference table exist in the
-- right side of the RIGHT JOIN and the inner subquery is recursively planned
SET client_min_messages TO DEBUG1;
SELECT
count(*) AS cnt, "generated_group_field"
FROM
@ -666,6 +693,8 @@ count(*) AS cnt, "generated_group_field"
cnt DESC, generated_group_field ASC
LIMIT 10;
RESET client_min_messages;
-- right join where the inner part of the join includes a reference table
-- joined with hash partitioned table using non-equi join
SELECT user_id, sum(array_length(events_table, 1)), length(hasdone_event), hasdone_event
@ -986,14 +1015,15 @@ INNER JOIN
GROUP BY types
ORDER BY types;
SET client_min_messages TO DEBUG1;
-- just a sanity check that we don't allow this if the reference table is on the
-- left part of the left join
-- left part of the left join, we can still recursively plan the inner side
SELECT count(*) FROM
(SELECT random() FROM users_ref_test_table LEFT JOIN user_buy_test_table
ON user_buy_test_table.item_id > users_ref_test_table.id) subquery_1;
-- we do allow non equi join among subqueries via recursive planning
SET client_min_messages TO DEBUG1;
SELECT count(*) FROM
(SELECT user_buy_test_table.user_id, random() FROM user_buy_test_table LEFT JOIN users_ref_test_table
ON user_buy_test_table.item_id > users_ref_test_table.id) subquery_1,

View File

@ -38,8 +38,12 @@ GROUP BY user_id
ORDER BY user_id
LIMIT 3;
-- subqueries in WHERE with NOT EXISTS operator, should not work since
-- there is a correlated subquery in WHERE clause
SET client_min_messages TO DEBUG1;
-- although the subquery in WHERE with NOT EXISTS operator (e.g., semi-join)
-- is correlated with the reference table, since events_table can be
-- recursively planned the whole query becomes a router query
SELECT
user_id
FROM
@ -55,8 +59,10 @@ WHERE
)
LIMIT 3;
-- immutable functions are also treated as reference tables, query should not
-- work since there is a correlated subquery in the WHERE clause
-- immutable functions are also treated as reference tables thus
-- although the subquery in WHERE with NOT EXISTS operator (e.g., semi-join)
-- is correlated with the immutable function, since events_table can be
-- recursively planned the whole query becomes a router query
SELECT
user_id
FROM
@ -70,10 +76,13 @@ WHERE
WHERE
users_reference_table.user_id = events_table.user_id
)
ORDER BY 1
LIMIT 3;
-- subqueries without FROM are also treated as reference tables, query should not
-- work since there is a correlated subquery in the WHERE clause
-- subqueries without FROM are also treated as reference tables thus
-- although the subquery in WHERE with NOT EXISTS operator (e.g., semi-join)
-- is correlated with the subquery, since events_table can be
-- recursively planned the whole query becomes a router query
SELECT
user_id
FROM
@ -89,6 +98,8 @@ WHERE
)
LIMIT 3;
RESET client_min_messages;
-- join with distributed table prevents FROM from recurring
SELECT
DISTINCT user_id