mirror of https://github.com/citusdata/citus.git
Remove assertion for subqueries in WHERE clause ANDed with FALSE
In the code, we had the assumption that if restriction information is NULL, it means that we cannot have any disributetd tables in the subquery. However, for subqueries in WHERE clause, that is not the case when the subquery is ANDed with FALSE. In that case, Citus operates on the originalQuery (which doesn't go through the standard_planner()), and rely on the restriction information generated by standard_plannner(). As Postgres is smart enough to no generate restriction information for subqueries ANDed with FALSE, we hit the assertion.pull/3816/head
parent
6bcf6d3411
commit
f9d4a9cf38
|
@ -191,12 +191,16 @@ SubqueryColocated(Query *subquery, ColocatedJoinChecker *checker)
|
||||||
/*
|
/*
|
||||||
* There are no relations in the input subquery, such as a subquery
|
* There are no relations in the input subquery, such as a subquery
|
||||||
* that consist of only intermediate results or without FROM
|
* that consist of only intermediate results or without FROM
|
||||||
* clause.
|
* clause or subquery in WHERE clause anded with FALSE.
|
||||||
|
*
|
||||||
|
* Note that for the subquery in WHERE clause, the input original
|
||||||
|
* subquery (a.k.a., which didn't go through standard_planner()) may
|
||||||
|
* contain distributed relations, but postgres is smart enough to
|
||||||
|
* not generate the restriction information. That's the reason for
|
||||||
|
* not asserting non-existence of distributed relations.
|
||||||
*/
|
*/
|
||||||
if (list_length(filteredRestrictionList) == 0)
|
if (list_length(filteredRestrictionList) == 0)
|
||||||
{
|
{
|
||||||
Assert(!FindNodeCheck((Node *) subquery, IsDistributedTableRTE));
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -634,6 +634,64 @@ DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT generate_seri
|
||||||
3
|
3
|
||||||
(3 rows)
|
(3 rows)
|
||||||
|
|
||||||
|
-- non-colocated subquery in WHERE clause ANDed with false
|
||||||
|
SELECT count(*)
|
||||||
|
FROM users_Table
|
||||||
|
WHERE (FALSE AND EXISTS (SELECT * FROM events_table));
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- multiple non-colocated subqueries in WHERE clause ANDed with false
|
||||||
|
SELECT count(*)
|
||||||
|
FROM users_Table
|
||||||
|
WHERE value_1 IN
|
||||||
|
(SELECT value_1
|
||||||
|
FROM users_Table) OR (FALSE AND EXISTS (SELECT * FROM events_table));
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT value_1 FROM public.users_table
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM public.users_table WHERE ((value_1 OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.value_1 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(value_1 integer))) OR (false AND (EXISTS (SELECT events_table.user_id, events_table."time", events_table.event_type, events_table.value_2, events_table.value_3, events_table.value_4 FROM public.events_table))))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
101
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- multiple non-colocated subqueries in WHERE clause ANDed with false
|
||||||
|
SELECT count(*)
|
||||||
|
FROM users_Table
|
||||||
|
WHERE value_1 IN
|
||||||
|
(SELECT value_1
|
||||||
|
FROM users_Table) AND (FALSE AND EXISTS (SELECT * FROM events_table));
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- non-colocated subquery in WHERE clause ANDed with true
|
||||||
|
SELECT count(*)
|
||||||
|
FROM users_Table
|
||||||
|
WHERE (TRUE AND EXISTS (SELECT * FROM events_table));
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT user_id, "time", event_type, value_2, value_3, value_4 FROM public.events_table
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM public.users_table WHERE (true AND (EXISTS (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('XXX_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))))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
101
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- multiple non-colocated subqueries in WHERE clause ANDed with true
|
||||||
|
SELECT count(*)
|
||||||
|
FROM users_Table
|
||||||
|
WHERE value_1 IN
|
||||||
|
(SELECT value_1
|
||||||
|
FROM users_Table) OR (EXISTS (SELECT * FROM events_table));
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT value_1 FROM public.users_table
|
||||||
|
DEBUG: generating subplan XXX_2 for subquery SELECT user_id, "time", event_type, value_2, value_3, value_4 FROM public.events_table
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM public.users_table WHERE ((value_1 OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.value_1 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(value_1 integer))) OR (EXISTS (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('XXX_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))))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
101
|
||||||
|
(1 row)
|
||||||
|
|
||||||
-- Local tables also planned recursively, so using it as part of the FROM clause
|
-- Local tables also planned recursively, so using it as part of the FROM clause
|
||||||
-- make the clause recurring
|
-- make the clause recurring
|
||||||
CREATE TABLE local_table(id int, value_1 int);
|
CREATE TABLE local_table(id int, value_1 int);
|
||||||
|
|
|
@ -471,6 +471,37 @@ IN
|
||||||
ORDER BY
|
ORDER BY
|
||||||
generate_series ASC;
|
generate_series ASC;
|
||||||
|
|
||||||
|
-- non-colocated subquery in WHERE clause ANDed with false
|
||||||
|
SELECT count(*)
|
||||||
|
FROM users_Table
|
||||||
|
WHERE (FALSE AND EXISTS (SELECT * FROM events_table));
|
||||||
|
|
||||||
|
-- multiple non-colocated subqueries in WHERE clause ANDed with false
|
||||||
|
SELECT count(*)
|
||||||
|
FROM users_Table
|
||||||
|
WHERE value_1 IN
|
||||||
|
(SELECT value_1
|
||||||
|
FROM users_Table) OR (FALSE AND EXISTS (SELECT * FROM events_table));
|
||||||
|
|
||||||
|
-- multiple non-colocated subqueries in WHERE clause ANDed with false
|
||||||
|
SELECT count(*)
|
||||||
|
FROM users_Table
|
||||||
|
WHERE value_1 IN
|
||||||
|
(SELECT value_1
|
||||||
|
FROM users_Table) AND (FALSE AND EXISTS (SELECT * FROM events_table));
|
||||||
|
|
||||||
|
-- non-colocated subquery in WHERE clause ANDed with true
|
||||||
|
SELECT count(*)
|
||||||
|
FROM users_Table
|
||||||
|
WHERE (TRUE AND EXISTS (SELECT * FROM events_table));
|
||||||
|
|
||||||
|
-- multiple non-colocated subqueries in WHERE clause ANDed with true
|
||||||
|
SELECT count(*)
|
||||||
|
FROM users_Table
|
||||||
|
WHERE value_1 IN
|
||||||
|
(SELECT value_1
|
||||||
|
FROM users_Table) OR (EXISTS (SELECT * FROM events_table));
|
||||||
|
|
||||||
-- Local tables also planned recursively, so using it as part of the FROM clause
|
-- Local tables also planned recursively, so using it as part of the FROM clause
|
||||||
-- make the clause recurring
|
-- make the clause recurring
|
||||||
CREATE TABLE local_table(id int, value_1 int);
|
CREATE TABLE local_table(id int, value_1 int);
|
||||||
|
|
Loading…
Reference in New Issue