From a1bbdf2d44ca0c026d40de7ebff48eccc9d5f7ff Mon Sep 17 00:00:00 2001 From: Onder Kalaci Date: Thu, 28 Dec 2017 10:04:58 +0200 Subject: [PATCH] Outer joins should also use subquery pushdown planner if join clause is not supported This change allows unsupported clauses to go through query pushdown planner instead of erroring out as we already do for non-outer joins. --- .../planner/multi_logical_planner.c | 6 +- src/test/regress/expected/multi_subquery.out | 93 +++++++++++++++++++ src/test/regress/sql/multi_subquery.sql | 53 +++++++++++ 3 files changed, 149 insertions(+), 3 deletions(-) diff --git a/src/backend/distributed/planner/multi_logical_planner.c b/src/backend/distributed/planner/multi_logical_planner.c index d9fbfa839..89cb0ff2d 100644 --- a/src/backend/distributed/planner/multi_logical_planner.c +++ b/src/backend/distributed/planner/multi_logical_planner.c @@ -224,7 +224,7 @@ MultiLogicalPlanCreate(Query *originalQuery, Query *queryTree, static bool ShouldUseSubqueryPushDown(Query *originalQuery, Query *rewrittenQuery) { - List *whereClauseList = NIL; + List *qualifierList = NIL; /* * We check the existence of subqueries in FROM clause on the modified query @@ -260,8 +260,8 @@ ShouldUseSubqueryPushDown(Query *originalQuery, Query *rewrittenQuery) * Some unsupported join clauses in logical planner * may be supported by subquery pushdown planner. */ - whereClauseList = WhereClauseList(rewrittenQuery->jointree); - if (DeferErrorIfUnsupportedClause(whereClauseList) != NULL) + qualifierList = QualifierList(rewrittenQuery->jointree); + if (DeferErrorIfUnsupportedClause(qualifierList) != NULL) { return true; } diff --git a/src/test/regress/expected/multi_subquery.out b/src/test/regress/expected/multi_subquery.out index 53f41d0fc..283117669 100644 --- a/src/test/regress/expected/multi_subquery.out +++ b/src/test/regress/expected/multi_subquery.out @@ -390,6 +390,99 @@ WHERE ORDER BY l_orderkey DESC LIMIT 10; ERROR: complex joins are only supported when all distributed tables are joined on their distribution columns with equal operator +-- outer joins on reference tables with functions works +SELECT DISTINCT ON (t1.user_id) t1.user_id, t2.value_1, t2.value_2, t2.value_3 +FROM events_table t1 +LEFT JOIN users_reference_table t2 ON t1.user_id = trunc(t2.user_id) +ORDER BY 1 DESC, 2 DESC, 3 DESC, 4 DESC +LIMIT 5; + user_id | value_1 | value_2 | value_3 +---------+---------+---------+--------- + 6 | 5 | 2 | 0 + 5 | 5 | 5 | 1 + 4 | 5 | 4 | 1 + 3 | 5 | 5 | 3 + 2 | 4 | 4 | 5 +(5 rows) + +-- outer joins on reference tables with simple expressions should work +SELECT DISTINCT ON (t1.user_id) t1.user_id, t2.value_1, t2.value_2, t2.value_3 +FROM events_table t1 +LEFT JOIN users_reference_table t2 ON t1.user_id > t2.user_id +ORDER BY 1 DESC, 2 DESC, 3 DESC, 4 DESC +LIMIT 5; + user_id | value_1 | value_2 | value_3 +---------+---------+---------+--------- + 6 | 5 | 5 | 3 + 5 | 5 | 5 | 3 + 4 | 5 | 5 | 3 + 3 | 5 | 4 | 3 + 2 | 5 | 4 | 3 +(5 rows) + +-- outer joins on distributed tables with simple expressions should not work +SELECT DISTINCT ON (t1.user_id) t1.user_id, t2.value_1, t2.value_2, t2.value_3 +FROM events_table t1 +LEFT JOIN users_table t2 ON t1.user_id > t2.user_id +ORDER BY 1 DESC, 2 DESC, 3 DESC, 4 DESC +LIMIT 5; +ERROR: complex joins are only supported when all distributed tables are joined on their distribution columns with equal operator +-- outer joins on reference tables with expressions should work +SELECT DISTINCT ON (t1.user_id) t1.user_id, t2.value_1, t2.value_2, t2.value_3 +FROM events_table t1 +LEFT JOIN users_reference_table t2 ON t1.user_id = (CASE WHEN t2.user_id > 3 THEN 3 ELSE t2.user_id END) +ORDER BY 1 DESC, 2 DESC, 3 DESC, 4 DESC +LIMIT 5; + user_id | value_1 | value_2 | value_3 +---------+---------+---------+--------- + 6 | | | + 5 | | | + 4 | | | + 3 | 5 | 5 | 3 + 2 | 4 | 4 | 5 +(5 rows) + +-- outer joins on distributed tables and reference tables with expressions should work +SELECT DISTINCT ON (t1.user_id) t1.user_id, t2.value_1, t2.value_2, t2.value_3 + FROM + users_table t0 LEFT JOIN + events_table t1 ON t0.user_id = t1.user_id + LEFT JOIN users_reference_table t2 ON t1.user_id = trunc(t2.user_id) + ORDER BY 1 DESC, 2 DESC, 3 DESC, 4 DESC + LIMIT 5; + user_id | value_1 | value_2 | value_3 +---------+---------+---------+--------- + 6 | 5 | 2 | 0 + 5 | 5 | 5 | 1 + 4 | 5 | 4 | 1 + 3 | 5 | 5 | 3 + 2 | 4 | 4 | 5 +(5 rows) + +-- outer joins on distributed tables with expressions should not work +SELECT DISTINCT ON (t1.user_id) t1.user_id, t2.value_1, t2.value_2, t2.value_3 + FROM + users_table t0 LEFT JOIN + events_table t1 ON t0.user_id = trunc(t1.user_id) + LEFT JOIN users_reference_table t2 ON t1.user_id = trunc(t2.user_id) + ORDER BY 1 DESC, 2 DESC, 3 DESC, 4 DESC + LIMIT 5; +ERROR: complex joins are only supported when all distributed tables are joined on their distribution columns with equal operator +-- inner joins on reference tables with functions works +SELECT DISTINCT ON (t1.user_id) t1.user_id, t2.value_1, t2.value_2, t2.value_3 +FROM events_table t1 +JOIN users_reference_table t2 ON t1.user_id = trunc(t2.user_id) +ORDER BY 1 DESC, 2 DESC, 3 DESC, 4 DESC +LIMIT 5; + user_id | value_1 | value_2 | value_3 +---------+---------+---------+--------- + 6 | 5 | 2 | 0 + 5 | 5 | 5 | 1 + 4 | 5 | 4 | 1 + 3 | 5 | 5 | 3 + 2 | 4 | 4 | 5 +(5 rows) + -- distinct queries work SELECT DISTINCT l_orderkey FROM diff --git a/src/test/regress/sql/multi_subquery.sql b/src/test/regress/sql/multi_subquery.sql index 223f03aca..070162447 100644 --- a/src/test/regress/sql/multi_subquery.sql +++ b/src/test/regress/sql/multi_subquery.sql @@ -279,6 +279,59 @@ WHERE ORDER BY l_orderkey DESC LIMIT 10; +-- outer joins on reference tables with functions works +SELECT DISTINCT ON (t1.user_id) t1.user_id, t2.value_1, t2.value_2, t2.value_3 +FROM events_table t1 +LEFT JOIN users_reference_table t2 ON t1.user_id = trunc(t2.user_id) +ORDER BY 1 DESC, 2 DESC, 3 DESC, 4 DESC +LIMIT 5; + +-- outer joins on reference tables with simple expressions should work +SELECT DISTINCT ON (t1.user_id) t1.user_id, t2.value_1, t2.value_2, t2.value_3 +FROM events_table t1 +LEFT JOIN users_reference_table t2 ON t1.user_id > t2.user_id +ORDER BY 1 DESC, 2 DESC, 3 DESC, 4 DESC +LIMIT 5; + +-- outer joins on distributed tables with simple expressions should not work +SELECT DISTINCT ON (t1.user_id) t1.user_id, t2.value_1, t2.value_2, t2.value_3 +FROM events_table t1 +LEFT JOIN users_table t2 ON t1.user_id > t2.user_id +ORDER BY 1 DESC, 2 DESC, 3 DESC, 4 DESC +LIMIT 5; + +-- outer joins on reference tables with expressions should work +SELECT DISTINCT ON (t1.user_id) t1.user_id, t2.value_1, t2.value_2, t2.value_3 +FROM events_table t1 +LEFT JOIN users_reference_table t2 ON t1.user_id = (CASE WHEN t2.user_id > 3 THEN 3 ELSE t2.user_id END) +ORDER BY 1 DESC, 2 DESC, 3 DESC, 4 DESC +LIMIT 5; + +-- outer joins on distributed tables and reference tables with expressions should work +SELECT DISTINCT ON (t1.user_id) t1.user_id, t2.value_1, t2.value_2, t2.value_3 + FROM + users_table t0 LEFT JOIN + events_table t1 ON t0.user_id = t1.user_id + LEFT JOIN users_reference_table t2 ON t1.user_id = trunc(t2.user_id) + ORDER BY 1 DESC, 2 DESC, 3 DESC, 4 DESC + LIMIT 5; + +-- outer joins on distributed tables with expressions should not work +SELECT DISTINCT ON (t1.user_id) t1.user_id, t2.value_1, t2.value_2, t2.value_3 + FROM + users_table t0 LEFT JOIN + events_table t1 ON t0.user_id = trunc(t1.user_id) + LEFT JOIN users_reference_table t2 ON t1.user_id = trunc(t2.user_id) + ORDER BY 1 DESC, 2 DESC, 3 DESC, 4 DESC + LIMIT 5; + +-- inner joins on reference tables with functions works +SELECT DISTINCT ON (t1.user_id) t1.user_id, t2.value_1, t2.value_2, t2.value_3 +FROM events_table t1 +JOIN users_reference_table t2 ON t1.user_id = trunc(t2.user_id) +ORDER BY 1 DESC, 2 DESC, 3 DESC, 4 DESC +LIMIT 5; + -- distinct queries work SELECT DISTINCT l_orderkey FROM