This is an automated email from the ASF dual-hosted git repository.
alexpl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new 7cb667184d1 IGNITE-23408 SQL Calcite: Fix 'typeof' function behaviour
when operand throws an error - Fixes #11636.
7cb667184d1 is described below
commit 7cb667184d1663c47aaeb315dd26110c878cae62
Author: Vladimir Steshin <[email protected]>
AuthorDate: Fri Nov 1 17:18:26 2024 +0300
IGNITE-23408 SQL Calcite: Fix 'typeof' function behaviour when operand
throws an error - Fixes #11636.
Signed-off-by: Aleksey Plekhanov <[email protected]>
---
.../query/calcite/exec/exp/IgniteSqlFunctions.java | 5 +++++
.../query/calcite/exec/exp/RexImpTable.java | 20 +++++++++++++++++++-
.../processors/query/calcite/util/IgniteMethod.java | 5 ++++-
.../query/calcite/integration/FunctionsTest.java | 2 ++
4 files changed, 30 insertions(+), 2 deletions(-)
diff --git
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctions.java
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctions.java
index d7ecedf0f09..d4157bf0972 100644
---
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctions.java
+++
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteSqlFunctions.java
@@ -190,6 +190,11 @@ public class IgniteSqlFunctions {
return leastOrGreatest(true, arg0, arg1);
}
+ /** @return The second argument and ignores the first. */
+ public static Object skipFirstArgument(Object v1, Object v2) {
+ return v2;
+ }
+
/** GREATEST2. */
public static Object greatest2(Object arg0, Object arg1) {
return leastOrGreatest(false, arg0, arg1);
diff --git
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexImpTable.java
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexImpTable.java
index 39025437fe8..e2f587882f8 100644
---
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexImpTable.java
+++
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexImpTable.java
@@ -1703,7 +1703,7 @@ public class RexImpTable {
else if (op == TYPEOF) {
assert call.getOperands().size() == 1 : call.getOperands();
- return
Expressions.constant(call.getOperands().get(0).getType().toString());
+ return typeOfImplementor().implement(translator, call,
NullAs.NOT_POSSIBLE);
}
else if (op == QUERY_ENGINE)
return
Expressions.constant(CalciteQueryEngineConfiguration.ENGINE_NAME);
@@ -1714,6 +1714,24 @@ public class RexImpTable {
}
}
+ /** */
+ private static CallImplementor typeOfImplementor() {
+ return createImplementor((translator, call, translatedOperands) -> {
+ Method method = IgniteMethod.SKIP_FIRST_ARGUMENT.method();
+
+ RexNode operand = call.getOperands().get(0);
+ String operandType = operand.getType().toString();
+
+ List<Expression> finalOperands = new ArrayList<>(2);
+ // The first argument is an arbitrary expression (must be
evaluated).
+ // The second argument is a type of the first expression (a
constant).
+ finalOperands.add(translatedOperands.get(0));
+ finalOperands.add(Expressions.constant(operandType));
+
+ return Expressions.call(method, finalOperands);
+ }, NullPolicy.NONE, false);
+ }
+
/** Implementor for the {@code NOT} operator. */
private static class NotImplementor extends AbstractRexCallImplementor {
/** */
diff --git
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/IgniteMethod.java
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/IgniteMethod.java
index 0dc58233a37..5b48750adfb 100644
---
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/IgniteMethod.java
+++
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/IgniteMethod.java
@@ -95,7 +95,10 @@ public enum IgniteMethod {
GREATEST2(IgniteSqlFunctions.class, "greatest2", Object.class,
Object.class),
/** See {@link Objects#equals(Object, Object)} */
- IS_NOT_DISTINCT_FROM(Objects.class, "equals", Object.class, Object.class);
+ IS_NOT_DISTINCT_FROM(Objects.class, "equals", Object.class, Object.class),
+
+ /** See {@link IgniteSqlFunctions#skipFirstArgument(Object, Object)}. **/
+ SKIP_FIRST_ARGUMENT(IgniteSqlFunctions.class, "skipFirstArgument",
Object.class, Object.class);
/** */
private final Method method;
diff --git
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/FunctionsTest.java
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/FunctionsTest.java
index c7eaa949949..f0bf58b661a 100644
---
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/FunctionsTest.java
+++
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/FunctionsTest.java
@@ -243,6 +243,8 @@ public class FunctionsTest extends
AbstractBasicIntegrationTest {
assertQuery("SELECT
TYPEOF(NULL::VARCHAR(100))").returns("VARCHAR(100)").check();
assertThrows("SELECT TYPEOF()", SqlValidatorException.class, "Invalid
number of arguments");
assertThrows("SELECT TYPEOF(1, 2)", SqlValidatorException.class,
"Invalid number of arguments");
+ assertThrows("SELECT TYPEOF(CAST('NONE' as INTEGER))",
IgniteSQLException.class,
+ "is neither a decimal digit number, decimal point");
}
/** */