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.
pull/1918/head
Onder Kalaci 2017-12-28 10:04:58 +02:00
parent 4e9d4c1bd3
commit a1bbdf2d44
3 changed files with 149 additions and 3 deletions

View File

@ -224,7 +224,7 @@ MultiLogicalPlanCreate(Query *originalQuery, Query *queryTree,
static bool static bool
ShouldUseSubqueryPushDown(Query *originalQuery, Query *rewrittenQuery) ShouldUseSubqueryPushDown(Query *originalQuery, Query *rewrittenQuery)
{ {
List *whereClauseList = NIL; List *qualifierList = NIL;
/* /*
* We check the existence of subqueries in FROM clause on the modified query * 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 * Some unsupported join clauses in logical planner
* may be supported by subquery pushdown planner. * may be supported by subquery pushdown planner.
*/ */
whereClauseList = WhereClauseList(rewrittenQuery->jointree); qualifierList = QualifierList(rewrittenQuery->jointree);
if (DeferErrorIfUnsupportedClause(whereClauseList) != NULL) if (DeferErrorIfUnsupportedClause(qualifierList) != NULL)
{ {
return true; return true;
} }

View File

@ -390,6 +390,99 @@ WHERE
ORDER BY l_orderkey DESC ORDER BY l_orderkey DESC
LIMIT 10; LIMIT 10;
ERROR: complex joins are only supported when all distributed tables are joined on their distribution columns with equal operator 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 -- distinct queries work
SELECT DISTINCT l_orderkey SELECT DISTINCT l_orderkey
FROM FROM

View File

@ -279,6 +279,59 @@ WHERE
ORDER BY l_orderkey DESC ORDER BY l_orderkey DESC
LIMIT 10; 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 -- distinct queries work
SELECT DISTINCT l_orderkey SELECT DISTINCT l_orderkey
FROM FROM