From ef6d5c757129f250c7fe5b0ac31d97b672196f73 Mon Sep 17 00:00:00 2001 From: eren Date: Fri, 18 Mar 2016 14:21:27 +0200 Subject: [PATCH] Fix spurious NOTICE messages with ANY/ALL Fixes issue #258 Prior to this change, Citus gives a deceptive NOTICE message when a query including ANY or ALL on a non-partition column is issued on a hash partitioned table. Let the github_events table be hash-distributed on repo_id column. Then, issuing this query: SELECT count(*) FROM github_events WHERE event_id = ANY ('{1,2,3}') Gives this message: NOTICE: cannot use shard pruning with ANY (array expression) HINT: Consider rewriting the expression with OR clauses. Note that since event_id is not the partition column, shard pruning would not be applied in any case. However, the NOTICE message would be valid and be given if the ANY clause would have been applied on repo_id column. Reviewer: Murat Tuncer --- .../planner/multi_physical_planner.c | 21 ++++++++++++++-- .../regress/expected/multi_hash_pruning.out | 25 ++++++++++++++++--- src/test/regress/sql/multi_hash_pruning.sql | 12 ++++++++- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/backend/distributed/planner/multi_physical_planner.c b/src/backend/distributed/planner/multi_physical_planner.c index 9c43f34c1..c9525c5dd 100644 --- a/src/backend/distributed/planner/multi_physical_planner.c +++ b/src/backend/distributed/planner/multi_physical_planner.c @@ -2896,8 +2896,25 @@ HashableClauseMutator(Node *originalNode, Var *partitionColumn) } else if (IsA(originalNode, ScalarArrayOpExpr)) { - ereport(NOTICE, (errmsg("cannot use shard pruning with ANY (array expression)"), - errhint("Consider rewriting the expression with OR clauses."))); + ScalarArrayOpExpr *arrayOperatorExpression = (ScalarArrayOpExpr *) originalNode; + Node *leftOpExpression = linitial(arrayOperatorExpression->args); + Node *strippedLeftOpExpression = strip_implicit_coercions(leftOpExpression); + char *operatorName = get_opname(arrayOperatorExpression->opno); + int equalsCompare = strncmp(operatorName, EQUAL_OPERATOR_STRING, NAMEDATALEN); + bool usingEqualityOperator = (equalsCompare == 0); + + /* + * Citus cannot prune hash-distributed shards with ANY/ALL. We show a NOTICE + * if the expression is ANY/ALL performed on the partition column with equality. + */ + if (usingEqualityOperator && strippedLeftOpExpression != NULL && + equal(strippedLeftOpExpression, partitionColumn)) + { + ereport(NOTICE, (errmsg("cannot use shard pruning with " + "ANY/ALL (array expression)"), + errhint("Consider rewriting the expression with " + "OR/AND clauses."))); + } } /* diff --git a/src/test/regress/expected/multi_hash_pruning.out b/src/test/regress/expected/multi_hash_pruning.out index bec70984f..782360c04 100644 --- a/src/test/regress/expected/multi_hash_pruning.out +++ b/src/test/regress/expected/multi_hash_pruning.out @@ -175,11 +175,30 @@ DEBUG: predicate pruning for shardId 111 explain statements for distributed queries are currently unsupported (1 row) --- Check that we don't support pruning for ANY (array expression) +-- Check that we don't support pruning for ANY (array expression) and give +-- a notice message when used with the partition column +EXPLAIN SELECT count(*) FROM orders_hash_partitioned + WHERE o_orderkey = ANY ('{1,2,3}'); +NOTICE: cannot use shard pruning with ANY/ALL (array expression) +HINT: Consider rewriting the expression with OR/AND clauses. + QUERY PLAN +---------------------------------------------------------------------- + explain statements for distributed queries are currently unsupported +(1 row) + +-- Check that we don't show the message if the operator is not +-- equality operator +EXPLAIN SELECT count(*) FROM orders_hash_partitioned + WHERE o_orderkey < ALL ('{1,2,3}'); + QUERY PLAN +---------------------------------------------------------------------- + explain statements for distributed queries are currently unsupported +(1 row) + +-- Check that we don't give a spurious hint message when non-partition +-- columns are used with ANY/IN/ALL EXPLAIN SELECT count(*) FROM orders_hash_partitioned WHERE o_orderkey = 1 OR o_totalprice IN (2, 5); -NOTICE: cannot use shard pruning with ANY (array expression) -HINT: Consider rewriting the expression with OR clauses. QUERY PLAN ---------------------------------------------------------------------- explain statements for distributed queries are currently unsupported diff --git a/src/test/regress/sql/multi_hash_pruning.sql b/src/test/regress/sql/multi_hash_pruning.sql index 6cdd6a504..c70ede12b 100644 --- a/src/test/regress/sql/multi_hash_pruning.sql +++ b/src/test/regress/sql/multi_hash_pruning.sql @@ -91,8 +91,18 @@ EXPLAIN SELECT count(*) FROM EXPLAIN SELECT count(*) FROM orders_hash_partitioned WHERE o_orderkey = abs(-1); --- Check that we don't support pruning for ANY (array expression) +-- Check that we don't support pruning for ANY (array expression) and give +-- a notice message when used with the partition column +EXPLAIN SELECT count(*) FROM orders_hash_partitioned + WHERE o_orderkey = ANY ('{1,2,3}'); +-- Check that we don't show the message if the operator is not +-- equality operator +EXPLAIN SELECT count(*) FROM orders_hash_partitioned + WHERE o_orderkey < ALL ('{1,2,3}'); + +-- Check that we don't give a spurious hint message when non-partition +-- columns are used with ANY/IN/ALL EXPLAIN SELECT count(*) FROM orders_hash_partitioned WHERE o_orderkey = 1 OR o_totalprice IN (2, 5);