This is an automated email from the ASF dual-hosted git repository.

jooger pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new 3279ae75f9 IGNITE-22448: Sql. Incorrect error message when aggregate 
function is called with UUID type. (#4006)
3279ae75f9 is described below

commit 3279ae75f9060a8c8a296bec749a88d66b3abe7f
Author: Max Zhuravkov <[email protected]>
AuthorDate: Wed Jul 3 14:39:13 2024 +0300

    IGNITE-22448: Sql. Incorrect error message when aggregate function is 
called with UUID type. (#4006)
---
 .../sql/aggregate/aggregates/test_avg.test         |  7 +--
 .../sql/aggregate/aggregates/test_sum.test         |  9 ++++
 .../sql/engine/prepare/IgniteSqlValidator.java     | 50 ++++++++++++++++++++++
 .../sql/engine/sql/fun/IgniteSqlOperatorTable.java | 16 +++++++
 .../internal/sql/engine/util/IgniteResource.java   |  4 ++
 5 files changed, 83 insertions(+), 3 deletions(-)

diff --git 
a/modules/sql-engine/src/integrationTest/sql/aggregate/aggregates/test_avg.test 
b/modules/sql-engine/src/integrationTest/sql/aggregate/aggregates/test_avg.test
index 74d6709e52..f826aab99f 100644
--- 
a/modules/sql-engine/src/integrationTest/sql/aggregate/aggregates/test_avg.test
+++ 
b/modules/sql-engine/src/integrationTest/sql/aggregate/aggregates/test_avg.test
@@ -62,7 +62,8 @@ SELECT AVG('100')
 statement error: Cannot apply 'AVG' to arguments of type 'AVG(<DATE>)'. 
Supported form(s): 'AVG(<NUMERIC>)'
 SELECT AVG('2011-01-01'::DATE)
 
-# TODO https://issues.apache.org/jira/browse/IGNITE-22448 incorrect error 
message
-# Update error message the issue is fixed. Current error: Unable to optimize 
plan due to internal error
-statement error
+statement error: Cannot apply 'AVG' to arguments of type 'AVG(<UUID>)'. 
Supported form(s): 'AVG(<NUMERIC>)'
 SELECT AVG('c4a0327c-44be-416d-ae90-75c05079789f'::UUID)
+
+statement error: Cannot apply 'AVG' to arguments of type 'AVG(<UUID>)'. 
Supported form(s): 'AVG(<NUMERIC>)'
+SELECT AVG(c) FROM (VALUES ('c4a0327c-44be-416d-ae90-75c05079789f'::UUID)) t(c)
diff --git 
a/modules/sql-engine/src/integrationTest/sql/aggregate/aggregates/test_sum.test 
b/modules/sql-engine/src/integrationTest/sql/aggregate/aggregates/test_sum.test
index 8a0b889dec..09bb8fdfc6 100644
--- 
a/modules/sql-engine/src/integrationTest/sql/aggregate/aggregates/test_sum.test
+++ 
b/modules/sql-engine/src/integrationTest/sql/aggregate/aggregates/test_sum.test
@@ -79,3 +79,12 @@ DECIMAL(32767, 0)
 # this is too big for a bigint
 statement error
 SELECT SUM(b)::BIGINT FROM bigints
+
+statement error: Cannot apply 'SUM' to arguments of type 'SUM(<DATE>)'. 
Supported form(s): 'SUM(<NUMERIC>)'
+SELECT SUM('2011-01-01'::DATE)
+
+statement error: Cannot apply 'SUM' to arguments of type 'SUM(<UUID>)'. 
Supported form(s): 'SUM(<NUMERIC>)'
+SELECT SUM('c4a0327c-44be-416d-ae90-75c05079789f'::UUID)
+
+statement error: Cannot apply 'SUM' to arguments of type 'SUM(<UUID>)'. 
Supported form(s): 'SUM(<NUMERIC>)'
+SELECT SUM(c) FROM (VALUES ('c4a0327c-44be-416d-ae90-75c05079789f'::UUID)) t(c)
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlValidator.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlValidator.java
index 832af32cf2..db4340c866 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlValidator.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/IgniteSqlValidator.java
@@ -52,6 +52,7 @@ import org.apache.calcite.sql.SqlCallBinding;
 import org.apache.calcite.sql.SqlDelete;
 import org.apache.calcite.sql.SqlDynamicParam;
 import org.apache.calcite.sql.SqlExplain;
+import org.apache.calcite.sql.SqlFunction;
 import org.apache.calcite.sql.SqlIdentifier;
 import org.apache.calcite.sql.SqlInsert;
 import org.apache.calcite.sql.SqlJoin;
@@ -81,6 +82,7 @@ import org.apache.calcite.sql.validate.SqlValidatorUtil;
 import org.apache.ignite.internal.sql.engine.schema.IgniteDataSource;
 import org.apache.ignite.internal.sql.engine.schema.IgniteSystemView;
 import org.apache.ignite.internal.sql.engine.schema.IgniteTable;
+import org.apache.ignite.internal.sql.engine.sql.fun.IgniteSqlOperatorTable;
 import org.apache.ignite.internal.sql.engine.type.IgniteCustomType;
 import 
org.apache.ignite.internal.sql.engine.type.IgniteCustomTypeCoercionRules;
 import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
@@ -526,6 +528,54 @@ public class IgniteSqlValidator extends SqlValidatorImpl {
         super.validateAggregateParams(aggCall, filter, null, orderList, scope);
     }
 
+    /** {@inheritDoc} */
+    @Override
+    public void validateCall(
+            SqlCall call,
+            SqlValidatorScope scope
+    ) {
+        super.validateCall(call, scope);
+
+        SqlOperator operator = call.getOperator();
+
+        // IgniteCustomType:
+        // Since custom data types use ANY that is a catch all type for type 
checkers,
+        // if a function is called with custom data type argument does not 
belong to CUSTOM_TYPE_FUNCTIONS,
+        // then this should be considered a validation error.
+
+        if (call.getOperandList().isEmpty()
+                || !(operator instanceof SqlFunction)
+                || 
IgniteSqlOperatorTable.CUSTOM_TYPE_FUNCTIONS.contains(operator)) {
+            return;
+        }
+
+        for (SqlNode node : call.getOperandList()) {
+            RelDataType type = getValidatedNodeTypeIfKnown(node);
+            // Argument type is not known yet (alias) or it is not a custom 
data type.
+            if ((!(type instanceof IgniteCustomType))) {
+                continue;
+            }
+
+            String name = call.getOperator().getName();
+
+            // Call to getAllowedSignatures throws NPE, if operandTypeChecker 
is null.
+            if (operator.getOperandTypeChecker() != null) {
+                // If signatures are available, then return:
+                // Cannot apply 'F' to arguments of type 'F(<ARG_TYPE>)'. 
Supported form(s): 'F(<TYPE>)'
+                String allowedSignatures = operator.getAllowedSignatures();
+                throw newValidationError(call,
+                        RESOURCE.canNotApplyOp2Type(name,
+                                call.getCallSignature(this, scope),
+                                allowedSignatures));
+            } else {
+                // Otherwise return an error w/o supported forms:
+                // Cannot apply 'F' to arguments of type 'F(<ARG_TYPE>)'
+                throw newValidationError(call, 
IgniteResource.INSTANCE.canNotApplyOp2Type(name,
+                        call.getCallSignature(this, scope)));
+            }
+        }
+    }
+
     /** {@inheritDoc} */
     @Override
     public RelDataType deriveType(SqlValidatorScope scope, SqlNode expr) {
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/IgniteSqlOperatorTable.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/IgniteSqlOperatorTable.java
index c6bf7b562e..5430bfa60c 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/IgniteSqlOperatorTable.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/sql/fun/IgniteSqlOperatorTable.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.sql.engine.sql.fun;
 
+import java.util.List;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
 import org.apache.calcite.sql.SqlBasicFunction;
@@ -175,6 +176,21 @@ public class IgniteSqlOperatorTable extends 
ReflectiveSqlOperatorTable {
     /** Singleton instance. */
     public static final IgniteSqlOperatorTable INSTANCE = new 
IgniteSqlOperatorTable();
 
+    /** IgniteCustomType: A list of functions supported by all custom data 
types. */
+    public static final List<SqlFunction> CUSTOM_TYPE_FUNCTIONS = List.of(
+            SqlStdOperatorTable.CAST,
+            SqlStdOperatorTable.COALESCE,
+            SqlStdOperatorTable.NULLIF,
+            TYPEOF,
+            SqlStdOperatorTable.COUNT,
+            SqlStdOperatorTable.MIN,
+            SqlStdOperatorTable.MAX,
+            SqlStdOperatorTable.ANY_VALUE,
+            SqlStdOperatorTable.SOME,
+            SqlStdOperatorTable.SINGLE_VALUE,
+            SqlStdOperatorTable.EVERY
+    );
+
     /**
      * Default constructor.
      */
diff --git 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/IgniteResource.java
 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/IgniteResource.java
index 405c48a197..ea95ab312f 100644
--- 
a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/IgniteResource.java
+++ 
b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/util/IgniteResource.java
@@ -24,6 +24,7 @@ import java.util.Arrays;
 import java.util.List;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.runtime.Resources;
+import org.apache.calcite.runtime.Resources.BaseMessage;
 import org.apache.calcite.runtime.Resources.ExInst;
 import org.apache.calcite.sql.SqlCallBinding;
 import org.apache.calcite.sql.SqlKind;
@@ -88,6 +89,9 @@ public interface IgniteResource {
             + "has incompatible types in this context: ''{1}'' to ''{2}''")
     Resources.ExInst<SqlValidatorException> 
naturalOrUsingColumnNotCompatible(int num, String type1, String type2);
 
+    @BaseMessage("Cannot apply ''{0}'' to arguments of type {1}.")
+    ExInst<SqlValidatorException> canNotApplyOp2Type(String a0, String a1);
+
     /** Constructs a signature string to use in error messages. */
     static String makeSignature(SqlCallBinding binding, RelDataType... 
operandTypes) {
         return makeSignature(binding, Arrays.asList(operandTypes));

Reply via email to