diff --git a/src/backend/distributed/planner/query_pushdown_planning.c b/src/backend/distributed/planner/query_pushdown_planning.c index c70f1bb50..76ee0b9f4 100644 --- a/src/backend/distributed/planner/query_pushdown_planning.c +++ b/src/backend/distributed/planner/query_pushdown_planning.c @@ -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); } diff --git a/src/test/regress/expected/ch_bench_subquery_repartition.out b/src/test/regress/expected/ch_bench_subquery_repartition.out index 371829fc1..b6c56cc39 100644 --- a/src/test/regress/expected/ch_bench_subquery_repartition.out +++ b/src/test/regress/expected/ch_bench_subquery_repartition.out @@ -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 diff --git a/src/test/regress/sql/ch_bench_subquery_repartition.sql b/src/test/regress/sql/ch_bench_subquery_repartition.sql index 04e7e23fa..1821972d0 100644 --- a/src/test/regress/sql/ch_bench_subquery_repartition.sql +++ b/src/test/regress/sql/ch_bench_subquery_repartition.sql @@ -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