Fix bug causing errors when planning a query with multiple subq… (#3389)

Our checks to find subqueries in the rewritten query were not sufficient. When
multiple subqueries are present in the original query and some would be
replaced by a join, we could miss other subqueries that were not rewritten.
This in turn caused us not to go into the subquery planner, causing some
queries that were planning fine before to suddenly not plan anymore.

This was a regression introduced by #3171.
pull/3393/head
Jelte Fennema 2020-01-16 19:01:13 +01:00 committed by GitHub
commit 062bda29fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 100 additions and 6 deletions

View File

@ -281,21 +281,23 @@ JoinTreeContainsSubqueryWalker(Node *joinTreeNode, void *context)
bool
WhereOrHavingClauseContainsSubquery(Query *query)
{
FromExpr *joinTree = query->jointree;
if (FindNodeCheck(query->havingQual, IsNodeSubquery))
{
return true;
}
if (!joinTree)
if (!query->jointree)
{
return false;
}
Node *queryQuals = joinTree->quals;
return FindNodeCheck(queryQuals, IsNodeSubquery);
/*
* We search the whole jointree here, not just the quals. The reason for
* this is that the fromlist can contain other FromExpr nodes again or
* JoinExpr nodes that also have quals. If that's the case we need to check
* those as well if they contain andy subqueries.
*/
return FindNodeCheck((Node *) query->jointree, IsNodeSubquery);
}

View File

@ -133,6 +133,53 @@ select s_i_id
s_i_id not in (select i_im_id from item)
AND s_i_id = ol_i_id;
ERROR: complex joins are only supported when all distributed tables are co-located and joined on their distribution columns
-- Multiple subqueries are supported IN and a NOT IN when no repartition join
-- is necessary and the IN subquery returns unique results
select s_i_id
from stock
where
s_i_id in (select i_id from item)
AND s_i_id not in (select i_im_id from item);
s_i_id
---------------------------------------------------------------------
(0 rows)
-- Subquery + repartion is not supported when it contains both an IN and a NOT IN
-- where both subqueries return unique results
select s_i_id
from stock, order_line
where
s_i_id in (select i_id from item)
AND s_i_id not in (select i_id from item)
AND s_i_id = ol_i_id;
ERROR: complex joins are only supported when all distributed tables are co-located and joined on their distribution columns
-- Subquery + repartion is not supported when it contains both an IN and a NOT IN
-- where the IN subquery returns unique results and the NOT IN returns non unique results
select s_i_id
from stock, order_line
where
s_i_id in (select i_id from item)
AND s_i_id not in (select i_im_id from item)
AND s_i_id = ol_i_id;
ERROR: complex joins are only supported when all distributed tables are co-located and joined on their distribution columns
-- Subquery + repartion is not supported when it contains both an IN and a NOT IN
-- where the IN subquery returns non unique results and the NOT IN returns unique results
select s_i_id
from stock, order_line
where
s_i_id in (select i_im_id from item)
AND s_i_id not in (select i_id from item)
AND s_i_id = ol_i_id;
ERROR: complex joins are only supported when all distributed tables are co-located and joined on their distribution columns
-- Subquery + repartion is not supported when it contains both an IN and a NOT IN
-- where both subqueries return non unique results
select s_i_id
from stock, order_line
where
s_i_id in (select i_im_id from item)
AND s_i_id not in (select i_im_id from item)
AND s_i_id = ol_i_id;
ERROR: complex joins are only supported when all distributed tables are co-located and joined on their distribution columns
-- Actual CHbenCHmark query is supported
select su_name, su_address
from supplier, nation

View File

@ -112,6 +112,51 @@ select s_i_id
s_i_id not in (select i_im_id from item)
AND s_i_id = ol_i_id;
-- Multiple subqueries are supported IN and a NOT IN when no repartition join
-- is necessary and the IN subquery returns unique results
select s_i_id
from stock
where
s_i_id in (select i_id from item)
AND s_i_id not in (select i_im_id from item);
-- Subquery + repartion is not supported when it contains both an IN and a NOT IN
-- where both subqueries return unique results
select s_i_id
from stock, order_line
where
s_i_id in (select i_id from item)
AND s_i_id not in (select i_id from item)
AND s_i_id = ol_i_id;
-- Subquery + repartion is not supported when it contains both an IN and a NOT IN
-- where the IN subquery returns unique results and the NOT IN returns non unique results
select s_i_id
from stock, order_line
where
s_i_id in (select i_id from item)
AND s_i_id not in (select i_im_id from item)
AND s_i_id = ol_i_id;
-- Subquery + repartion is not supported when it contains both an IN and a NOT IN
-- where the IN subquery returns non unique results and the NOT IN returns unique results
select s_i_id
from stock, order_line
where
s_i_id in (select i_im_id from item)
AND s_i_id not in (select i_id from item)
AND s_i_id = ol_i_id;
-- Subquery + repartion is not supported when it contains both an IN and a NOT IN
-- where both subqueries return non unique results
select s_i_id
from stock, order_line
where
s_i_id in (select i_im_id from item)
AND s_i_id not in (select i_im_id from item)
AND s_i_id = ol_i_id;
-- Actual CHbenCHmark query is supported
select su_name, su_address