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);