From e5a5502b168494fc5e24f44249bbe095d27c6571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?mehmet=20furkan=20=C5=9Fahin?= Date: Thu, 12 Apr 2018 12:58:30 +0300 Subject: [PATCH] Adds support for multiple ANDs in Having This PR adds support for multiple AND expressions in Having for pushdown planner. We simply make a call to make_ands_explicit from MultiLogicalPlanOptimize for the having qual in workerExtendedOpNode. --- .../planner/multi_logical_optimizer.c | 13 ++++++ .../expected/multi_having_pushdown.out | 45 +++++++++++++++++++ .../regress/sql/multi_having_pushdown.sql | 23 ++++++++++ 3 files changed, 81 insertions(+) diff --git a/src/backend/distributed/planner/multi_logical_optimizer.c b/src/backend/distributed/planner/multi_logical_optimizer.c index a040eafa6..e8973ca78 100644 --- a/src/backend/distributed/planner/multi_logical_optimizer.c +++ b/src/backend/distributed/planner/multi_logical_optimizer.c @@ -2133,6 +2133,19 @@ WorkerExtendedOpNode(MultiExtendedOp *originalOpNode, (groupedByDisjointPartitionColumn || pushDownWindowFunction)) { workerExtendedOpNode->havingQual = originalOpNode->havingQual; + + /* + * We converted the having expression to a list in subquery pushdown + * planner. However, this query cannot be parsed as it is in the worker. + * We should convert this back to being explicit for worker query + * so that it can be parsed when it hits to the standard planner in + * worker. + */ + if (IsA(workerExtendedOpNode->havingQual, List)) + { + workerExtendedOpNode->havingQual = + (Node *) make_ands_explicit((List *) workerExtendedOpNode->havingQual); + } } return workerExtendedOpNode; diff --git a/src/test/regress/expected/multi_having_pushdown.out b/src/test/regress/expected/multi_having_pushdown.out index 1cd5839ce..cb19b6540 100644 --- a/src/test/regress/expected/multi_having_pushdown.out +++ b/src/test/regress/expected/multi_having_pushdown.out @@ -183,3 +183,48 @@ EXPLAIN (COSTS FALSE) DROP TABLE lineitem_hash; DROP TABLE orders_hash; +SELECT max(value_1) +FROM users_table +GROUP BY user_id +HAVING max(value_2) > 4 AND min(value_2) < 1 +ORDER BY 1; + max +----- + 4 + 5 + 5 +(3 rows) + +SELECT max(value_1) +FROM users_table +GROUP BY user_id +HAVING max(value_2) > 4 AND min(value_2) < 1 OR count(*) > 10 +ORDER BY 1; + max +----- + 4 + 5 + 5 + 5 +(4 rows) + +SELECT max(value_1) +FROM users_table +GROUP BY user_id +HAVING max(value_2) > 4 AND min(value_2) < 1 AND count(*) > 20 +ORDER BY 1; + max +----- + 5 + 5 +(2 rows) + +SELECT max(value_1) +FROM users_table +GROUP BY user_id +HAVING max(value_2) > 0 AND count(*) FILTER (WHERE value_3=2) > 3 AND min(value_2) IN (0,1,2,3); + max +----- + 5 +(1 row) + diff --git a/src/test/regress/sql/multi_having_pushdown.sql b/src/test/regress/sql/multi_having_pushdown.sql index 0abfcf1d8..7394c357b 100644 --- a/src/test/regress/sql/multi_having_pushdown.sql +++ b/src/test/regress/sql/multi_having_pushdown.sql @@ -55,3 +55,26 @@ EXPLAIN (COSTS FALSE) DROP TABLE lineitem_hash; DROP TABLE orders_hash; + +SELECT max(value_1) +FROM users_table +GROUP BY user_id +HAVING max(value_2) > 4 AND min(value_2) < 1 +ORDER BY 1; + +SELECT max(value_1) +FROM users_table +GROUP BY user_id +HAVING max(value_2) > 4 AND min(value_2) < 1 OR count(*) > 10 +ORDER BY 1; + +SELECT max(value_1) +FROM users_table +GROUP BY user_id +HAVING max(value_2) > 4 AND min(value_2) < 1 AND count(*) > 20 +ORDER BY 1; + +SELECT max(value_1) +FROM users_table +GROUP BY user_id +HAVING max(value_2) > 0 AND count(*) FILTER (WHERE value_3=2) > 3 AND min(value_2) IN (0,1,2,3); \ No newline at end of file