This is an automated email from the ASF dual-hosted git repository.
korlov 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 ffb7a424f2 IGNITE-20000: Add planner test to verify numeric type
coercion in binary arithmetic (#2583)
ffb7a424f2 is described below
commit ffb7a424f262b39b903050bbb52a826c356a4917
Author: ygerzhedovich <[email protected]>
AuthorDate: Wed Sep 20 13:29:18 2023 +0300
IGNITE-20000: Add planner test to verify numeric type coercion in binary
arithmetic (#2583)
---
README.md | 4 +-
.../planner/datatypes/BaseTypeCoercionTest.java | 185 +++++
.../NumericBinaryOperationsTypeCoercionTest.java | 830 +++++++++++++++++++++
.../NumericComparisonTypeCoercionTest.java | 146 +---
.../sql/engine/planner/datatypes/utils/Types.java | 3 +
5 files changed, 1023 insertions(+), 145 deletions(-)
diff --git a/README.md b/README.md
index 2b05d118cf..66971bdd2c 100644
--- a/README.md
+++ b/README.md
@@ -61,8 +61,8 @@ In SQL interactive mode user can simply type SQL commands in
CLI:
```sql
CREATE TABLE IF NOT EXISTS Person (id int primary key, city varchar, name
varchar, age int, company varchar);
-INSERT INTO Person (id, city, name, age, company) VALUES ('1', 'London', 'John
Doe', '42', 'Apache');
-INSERT INTO Person (id, city, name, age, company) VALUES ('2', 'New York',
'Jane Doe', '36', 'Apache');
+INSERT INTO Person (id, city, name, age, company) VALUES (1, 'London', 'John
Doe', 42, 'Apache');
+INSERT INTO Person (id, city, name, age, company) VALUES (2, 'New York', 'Jane
Doe', 36, 'Apache');
SELECT * FROM Person;
```
diff --git
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/datatypes/BaseTypeCoercionTest.java
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/datatypes/BaseTypeCoercionTest.java
new file mode 100644
index 0000000000..1cba1b38e5
--- /dev/null
+++
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/datatypes/BaseTypeCoercionTest.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.sql.engine.planner.datatypes;
+
+import static org.apache.ignite.lang.IgniteStringFormatter.format;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.instanceOf;
+
+import java.util.Arrays;
+import java.util.stream.Stream;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexCall;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.type.SqlTypeUtil;
+import org.apache.ignite.internal.schema.NativeType;
+import org.apache.ignite.internal.sql.engine.framework.TestBuilders;
+import org.apache.ignite.internal.sql.engine.planner.AbstractPlannerTest;
+import
org.apache.ignite.internal.sql.engine.planner.datatypes.utils.NumericPair;
+import org.apache.ignite.internal.sql.engine.planner.datatypes.utils.TypePair;
+import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
+import
org.apache.ignite.internal.sql.engine.rel.ProjectableFilterableTableScan;
+import org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
+import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
+import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
+import org.apache.ignite.internal.sql.engine.util.Commons;
+import org.apache.ignite.internal.sql.engine.util.TypeUtils;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.junit.jupiter.params.provider.Arguments;
+
+abstract class BaseTypeCoercionTest extends AbstractPlannerTest {
+
+ static Stream<Arguments> allNumericPairs() {
+ return Arrays.stream(NumericPair.values()).map(Arguments::of);
+ }
+
+ static IgniteSchema createSchemaWithTwoColumnTable(NativeType c1,
NativeType c2) {
+ return createSchema(
+ TestBuilders.table()
+ .name("T")
+ .distribution(IgniteDistributions.single())
+ .addColumn("C1", c1)
+ .addColumn("C2", c2)
+ .build()
+ );
+ }
+
+ static Matcher<IgniteRel> operandMatcher(Matcher<RexNode> first,
Matcher<RexNode> second) {
+ return new BaseMatcher<>() {
+ @Override
+ public boolean matches(Object actual) {
+ RexNode comparison = ((ProjectableFilterableTableScan)
actual).projects().get(0);
+
+ assertThat(comparison, instanceOf(RexCall.class));
+
+ RexCall comparisonCall = (RexCall) comparison;
+
+ RexNode leftOperand = comparisonCall.getOperands().get(0);
+ RexNode rightOperand = comparisonCall.getOperands().get(1);
+
+ assertThat(leftOperand, first);
+ assertThat(rightOperand, second);
+
+ return true;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+
+ }
+ };
+ }
+
+ /**
+ * Creates a matcher to verify that given expression has expected return
type, but it is not CAST operator.
+ *
+ * @param type Expected return type.
+ * @return A matcher.
+ */
+ static Matcher<RexNode> ofTypeWithoutCast(NativeType type) {
+ IgniteTypeFactory typeFactory = Commons.typeFactory();
+ RelDataType sqlType = TypeUtils.native2relationalType(typeFactory,
type);
+
+ return new BaseMatcher<>() {
+ @Override
+ public boolean matches(Object actual) {
+ return SqlTypeUtil.equalSansNullability(typeFactory,
((RexNode) actual).getType(), sqlType)
+ && !((RexNode) actual).isA(SqlKind.CAST);
+ }
+
+ @Override
+ public void describeMismatch(Object item, Description description)
{
+ description.appendText("was ").appendValue(item).appendText("
of type " + ((RexNode) item).getType());
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText(format("Operand of type {} that is not
CAST", sqlType));
+ }
+ };
+ }
+
+ /**
+ * Creates a matcher to verify that given expression is CAST operator with
expected return type.
+ *
+ * @param type Expected return type.
+ * @return A matcher.
+ */
+ static Matcher<RexNode> castTo(NativeType type) {
+ IgniteTypeFactory typeFactory = Commons.typeFactory();
+ RelDataType sqlType = TypeUtils.native2relationalType(typeFactory,
type);
+
+ return new BaseMatcher<>() {
+ @Override
+ public boolean matches(Object actual) {
+ return actual instanceof RexCall
+ && ((RexNode) actual).isA(SqlKind.CAST)
+ && SqlTypeUtil.equalSansNullability(typeFactory,
((RexNode) actual).getType(), sqlType);
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("Operand that is CAST(..):" + sqlType);
+ }
+
+ @Override
+ public void describeMismatch(Object item, Description description)
{
+ description.appendText("was ").appendValue(item).appendText("
of type " + ((RexNode) item).getType());
+ }
+ };
+ }
+
+ static TestCaseBuilder forTypePair(TypePair typePair) {
+ return new TestCaseBuilder(typePair);
+ }
+
+ /**
+ * Not really a builder, but provides DSL-like API to describe test case.
+ */
+ static class TestCaseBuilder {
+ private final TypePair pair;
+ private Matcher<RexNode> firstOpMatcher;
+
+ private TestCaseBuilder(TypePair pair) {
+ this.pair = pair;
+ }
+
+ TestCaseBuilder firstOpMatches(Matcher<RexNode> operandMatcher) {
+ firstOpMatcher = operandMatcher;
+
+ return this;
+ }
+
+ TestCaseBuilder firstOpBeSame() {
+ firstOpMatcher = ofTypeWithoutCast(pair.first());
+
+ return this;
+ }
+
+ Arguments secondOpMatches(Matcher<RexNode> operandMatcher) {
+ return Arguments.of(pair, firstOpMatcher, operandMatcher);
+ }
+
+ Arguments secondOpBeSame() {
+ return Arguments.of(pair, firstOpMatcher,
ofTypeWithoutCast(pair.second()));
+ }
+ }
+}
diff --git
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/datatypes/NumericBinaryOperationsTypeCoercionTest.java
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/datatypes/NumericBinaryOperationsTypeCoercionTest.java
new file mode 100644
index 0000000000..da3b47e13a
--- /dev/null
+++
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/datatypes/NumericBinaryOperationsTypeCoercionTest.java
@@ -0,0 +1,830 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.sql.engine.planner.datatypes;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.util.EnumSet;
+import java.util.List;
+import java.util.stream.Stream;
+import org.apache.calcite.rex.RexNode;
+import
org.apache.ignite.internal.sql.engine.planner.datatypes.utils.NumericPair;
+import org.apache.ignite.internal.sql.engine.planner.datatypes.utils.TypePair;
+import org.apache.ignite.internal.sql.engine.planner.datatypes.utils.Types;
+import org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+/**
+ * A set of test to verify behavior of type coercion for binary arithmetic,
when operands belongs to the NUMERIC type family.
+ *
+ * <p>This tests aim to help to understand in which cases implicit cast will
be added to which operand when does arithmetic with a given
+ * numeric type pair.
+ */
+public class NumericBinaryOperationsTypeCoercionTest extends
BaseTypeCoercionTest {
+
+ // No any type changes for `addition` operation from planner perspective.
+ @ParameterizedTest
+ @MethodSource("allNumericPairs")
+ public void additionOp(NumericPair pair) throws Exception {
+ IgniteSchema schema = createSchemaWithTwoColumnTable(pair.first(),
pair.second());
+
+ Matcher<RexNode> first = ofTypeWithoutCast(pair.first());
+ Matcher<RexNode> second = ofTypeWithoutCast(pair.second());
+
+ assertPlan("SELECT c1 + c2 FROM t", schema, operandMatcher(first,
second)::matches, List.of());
+ assertPlan("SELECT c2 + c1 FROM t", schema, operandMatcher(second,
first)::matches, List.of());
+ }
+
+ // No any type changes for `subtraction` operation from planner
perspective.
+ @ParameterizedTest
+ @MethodSource("allNumericPairs")
+ public void subtractionOp(NumericPair pair) throws Exception {
+ IgniteSchema schema = createSchemaWithTwoColumnTable(pair.first(),
pair.second());
+
+ Matcher<RexNode> first = ofTypeWithoutCast(pair.first());
+ Matcher<RexNode> second = ofTypeWithoutCast(pair.second());
+
+ assertPlan("SELECT c1 - c2 FROM t", schema, operandMatcher(first,
second)::matches, List.of());
+ assertPlan("SELECT c2 - c1 FROM t", schema, operandMatcher(second,
first)::matches, List.of());
+ }
+
+ // No any type changes for `division` operation from planner perspective.
+ @ParameterizedTest
+ @MethodSource("allNumericPairs")
+ public void divisionOp(NumericPair pair) throws Exception {
+ IgniteSchema schema = createSchemaWithTwoColumnTable(pair.first(),
pair.second());
+
+ Matcher<RexNode> first = ofTypeWithoutCast(pair.first());
+ Matcher<RexNode> second = ofTypeWithoutCast(pair.second());
+
+ assertPlan("SELECT c1 / c2 FROM t", schema, operandMatcher(first,
second)::matches, List.of());
+ assertPlan("SELECT c2 / c1 FROM t", schema, operandMatcher(second,
first)::matches, List.of());
+ }
+
+ // No any type changes for `multiplication` operation from planner
perspective.
+ @ParameterizedTest
+ @MethodSource("allNumericPairs")
+ public void multiplicationOp(NumericPair pair) throws Exception {
+ IgniteSchema schema = createSchemaWithTwoColumnTable(pair.first(),
pair.second());
+
+ Matcher<RexNode> first = ofTypeWithoutCast(pair.first());
+ Matcher<RexNode> second = ofTypeWithoutCast(pair.second());
+
+ assertPlan("SELECT c1 * c2 FROM t", schema, operandMatcher(first,
second)::matches, List.of());
+ assertPlan("SELECT c2 * c1 FROM t", schema, operandMatcher(second,
first)::matches, List.of());
+ }
+
+ //Have the following casts for modulo operation:
+ // REAL datatype always casts to DECIMAL(14,7)
+ // DOUBLE datatype always casts to DECIMAL(30,15)
+ // Any other types with no any changes
+ @ParameterizedTest
+ @MethodSource("moduloArgs")
+ public void moduloOp(
+ TypePair typePair,
+ Matcher<RexNode> firstOperandMatcher,
+ Matcher<RexNode> secondOperandMatcher
+ ) throws Exception {
+ IgniteSchema schema = createSchemaWithTwoColumnTable(typePair.first(),
typePair.second());
+
+ assertPlan("SELECT c1 % c2 FROM t", schema,
operandMatcher(firstOperandMatcher, secondOperandMatcher)::matches, List.of());
+ assertPlan("SELECT c2 % c1 FROM t", schema,
operandMatcher(secondOperandMatcher, firstOperandMatcher)::matches, List.of());
+ }
+
+ /**
+ * This test ensures that {@link #moduloArgs()} doesn't miss any type pair
from {@link NumericPair}.
+ */
+ @Test
+ void moduloArgsIncludesAllTypePairs() {
+ EnumSet<NumericPair> remainingPairs = EnumSet.allOf(NumericPair.class);
+
+ moduloArgs().map(Arguments::get).map(arg -> (NumericPair)
arg[0]).forEach(remainingPairs::remove);
+
+ assertThat(remainingPairs, Matchers.empty());
+ }
+
+ private static Stream<Arguments> moduloArgs() {
+ return Stream.of(
+ forTypePair(NumericPair.TINYINT_TINYINT)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.TINYINT_SMALLINT)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.TINYINT_INT)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.TINYINT_BIGINT)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.TINYINT_NUMBER_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.TINYINT_NUMBER_2)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.TINYINT_NUMBER_5)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.TINYINT_DECIMAL_1_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.TINYINT_DECIMAL_2_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.TINYINT_DECIMAL_4_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.TINYINT_DECIMAL_2_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.TINYINT_DECIMAL_3_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.TINYINT_DECIMAL_5_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.TINYINT_DECIMAL_5_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.TINYINT_DECIMAL_6_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.TINYINT_DECIMAL_8_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.TINYINT_REAL)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_14_7)),
+
+ forTypePair(NumericPair.TINYINT_DOUBLE)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_30_15)),
+
+
+ forTypePair(NumericPair.SMALLINT_SMALLINT)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.SMALLINT_INT)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.SMALLINT_BIGINT)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.SMALLINT_NUMBER_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.SMALLINT_NUMBER_2)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.SMALLINT_NUMBER_5)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.SMALLINT_DECIMAL_1_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.SMALLINT_DECIMAL_2_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.SMALLINT_DECIMAL_4_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.SMALLINT_DECIMAL_2_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.SMALLINT_DECIMAL_3_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.SMALLINT_DECIMAL_5_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.SMALLINT_DECIMAL_5_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.SMALLINT_DECIMAL_6_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.SMALLINT_DECIMAL_8_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.SMALLINT_REAL)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_14_7)),
+
+ forTypePair(NumericPair.SMALLINT_DOUBLE)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_30_15)),
+
+
+ forTypePair(NumericPair.INT_INT)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.INT_BIGINT)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.INT_NUMBER_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.INT_NUMBER_2)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.INT_NUMBER_5)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.INT_DECIMAL_1_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.INT_DECIMAL_2_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.INT_DECIMAL_4_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.INT_DECIMAL_2_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.INT_DECIMAL_3_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.INT_DECIMAL_5_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.INT_DECIMAL_5_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.INT_DECIMAL_6_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.INT_DECIMAL_8_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.INT_REAL)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_14_7)),
+
+ forTypePair(NumericPair.INT_DOUBLE)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_30_15)),
+
+
+ forTypePair(NumericPair.BIGINT_BIGINT)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.BIGINT_NUMBER_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.BIGINT_NUMBER_2)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.BIGINT_NUMBER_5)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.BIGINT_DECIMAL_1_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.BIGINT_DECIMAL_2_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.BIGINT_DECIMAL_4_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.BIGINT_DECIMAL_2_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.BIGINT_DECIMAL_3_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.BIGINT_DECIMAL_5_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.BIGINT_DECIMAL_5_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.BIGINT_DECIMAL_6_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.BIGINT_DECIMAL_8_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.BIGINT_REAL)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_14_7)),
+
+ forTypePair(NumericPair.BIGINT_DOUBLE)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_30_15)),
+
+
+ forTypePair(NumericPair.NUMBER_1_NUMBER_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_1_NUMBER_2)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_1_NUMBER_5)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_1_DECIMAL_1_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_1_DECIMAL_2_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_1_DECIMAL_4_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_1_DECIMAL_2_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_1_DECIMAL_3_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_1_DECIMAL_5_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_1_DECIMAL_5_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_1_DECIMAL_6_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_1_DECIMAL_8_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_1_REAL)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_14_7)),
+
+ forTypePair(NumericPair.NUMBER_1_DOUBLE)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_30_15)),
+
+
+ forTypePair(NumericPair.NUMBER_2_NUMBER_2)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_2_NUMBER_5)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_2_DECIMAL_1_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_2_DECIMAL_2_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_2_DECIMAL_4_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_2_DECIMAL_2_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_2_DECIMAL_3_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_2_DECIMAL_5_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_2_DECIMAL_5_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_2_DECIMAL_6_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_2_DECIMAL_8_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_2_REAL)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_14_7)),
+
+ forTypePair(NumericPair.NUMBER_2_DOUBLE)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_30_15)),
+
+
+ forTypePair(NumericPair.NUMBER_5_NUMBER_5)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_5_DECIMAL_1_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_5_DECIMAL_2_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_5_DECIMAL_4_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_5_DECIMAL_2_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_5_DECIMAL_3_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_5_DECIMAL_5_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_5_DECIMAL_5_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_5_DECIMAL_6_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_5_DECIMAL_8_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.NUMBER_5_REAL)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_14_7)),
+
+ forTypePair(NumericPair.NUMBER_5_DOUBLE)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_30_15)),
+
+
+ forTypePair(NumericPair.DECIMAL_1_0_DECIMAL_1_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_1_0_DECIMAL_2_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_1_0_DECIMAL_4_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_1_0_DECIMAL_2_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_1_0_DECIMAL_3_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_1_0_DECIMAL_5_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_1_0_DECIMAL_5_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_1_0_DECIMAL_6_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_1_0_DECIMAL_8_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_1_0_REAL)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_14_7)),
+
+ forTypePair(NumericPair.DECIMAL_1_0_DOUBLE)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_30_15)),
+
+
+ forTypePair(NumericPair.DECIMAL_2_1_DECIMAL_2_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_2_1_DECIMAL_4_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_2_1_DECIMAL_2_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_2_1_DECIMAL_3_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_2_1_DECIMAL_5_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_2_1_DECIMAL_5_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_2_1_DECIMAL_6_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_2_1_DECIMAL_8_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_2_1_REAL)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_14_7)),
+
+ forTypePair(NumericPair.DECIMAL_2_1_DOUBLE)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_30_15)),
+
+
+ forTypePair(NumericPair.DECIMAL_4_3_DECIMAL_4_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_4_3_DECIMAL_2_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_4_3_DECIMAL_3_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_4_3_DECIMAL_5_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_4_3_DECIMAL_5_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_4_3_DECIMAL_6_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_4_3_DECIMAL_8_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_4_3_REAL)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_14_7)),
+
+ forTypePair(NumericPair.DECIMAL_4_3_DOUBLE)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_30_15)),
+
+
+ forTypePair(NumericPair.DECIMAL_2_0_DECIMAL_2_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_2_0_DECIMAL_3_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_2_0_DECIMAL_5_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_2_0_DECIMAL_5_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_2_0_DECIMAL_6_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_2_0_DECIMAL_8_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_2_0_REAL)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_14_7)),
+
+ forTypePair(NumericPair.DECIMAL_2_0_DOUBLE)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_30_15)),
+
+
+ forTypePair(NumericPair.DECIMAL_3_1_DECIMAL_3_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_3_1_DECIMAL_5_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_3_1_DECIMAL_5_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_3_1_DECIMAL_6_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_3_1_DECIMAL_8_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_3_1_REAL)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_14_7)),
+
+ forTypePair(NumericPair.DECIMAL_3_1_DOUBLE)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_30_15)),
+
+
+ forTypePair(NumericPair.DECIMAL_5_3_DECIMAL_5_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_5_3_DECIMAL_5_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_5_3_DECIMAL_6_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_5_3_DECIMAL_8_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_5_3_REAL)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_14_7)),
+
+ forTypePair(NumericPair.DECIMAL_5_3_DOUBLE)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_30_15)),
+
+
+ forTypePair(NumericPair.DECIMAL_5_0_DECIMAL_5_0)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_5_0_DECIMAL_6_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_5_0_DECIMAL_8_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_5_0_REAL)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_14_7)),
+
+ forTypePair(NumericPair.DECIMAL_5_0_DOUBLE)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_30_15)),
+
+
+ forTypePair(NumericPair.DECIMAL_6_1_DECIMAL_6_1)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_6_1_DECIMAL_8_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_6_1_REAL)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_14_7)),
+
+ forTypePair(NumericPair.DECIMAL_6_1_DOUBLE)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_30_15)),
+
+
+ forTypePair(NumericPair.DECIMAL_8_3_DECIMAL_8_3)
+ .firstOpBeSame()
+ .secondOpBeSame(),
+
+ forTypePair(NumericPair.DECIMAL_8_3_REAL)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_14_7)),
+
+ forTypePair(NumericPair.DECIMAL_8_3_DOUBLE)
+ .firstOpBeSame()
+ .secondOpMatches(castTo(Types.DECIMAL_30_15)),
+
+
+ forTypePair(NumericPair.REAL_REAL)
+ .firstOpMatches(castTo(Types.DECIMAL_14_7))
+ .secondOpMatches(castTo((Types.DECIMAL_14_7))),
+
+ forTypePair(NumericPair.REAL_DOUBLE)
+ .firstOpMatches(castTo(Types.DECIMAL_14_7))
+ .secondOpMatches(castTo(Types.DECIMAL_30_15)),
+
+
+ forTypePair(NumericPair.DOUBLE_DOUBLE)
+ .firstOpMatches(castTo(Types.DECIMAL_30_15))
+ .secondOpMatches(castTo(Types.DECIMAL_30_15))
+ );
+ }
+}
diff --git
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/datatypes/NumericComparisonTypeCoercionTest.java
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/datatypes/NumericComparisonTypeCoercionTest.java
index abd9b6c783..3475e6256d 100644
---
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/datatypes/NumericComparisonTypeCoercionTest.java
+++
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/datatypes/NumericComparisonTypeCoercionTest.java
@@ -17,34 +17,17 @@
package org.apache.ignite.internal.sql.engine.planner.datatypes;
-import static org.apache.ignite.lang.IgniteStringFormatter.format;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.instanceOf;
import java.util.EnumSet;
import java.util.List;
import java.util.stream.Stream;
-import org.apache.calcite.rel.type.RelDataType;
-import org.apache.calcite.rex.RexCall;
import org.apache.calcite.rex.RexNode;
-import org.apache.calcite.sql.SqlKind;
-import org.apache.calcite.sql.type.SqlTypeUtil;
-import org.apache.ignite.internal.schema.NativeType;
import org.apache.ignite.internal.schema.NativeTypes;
-import org.apache.ignite.internal.sql.engine.framework.TestBuilders;
-import org.apache.ignite.internal.sql.engine.planner.AbstractPlannerTest;
import
org.apache.ignite.internal.sql.engine.planner.datatypes.utils.NumericPair;
import org.apache.ignite.internal.sql.engine.planner.datatypes.utils.TypePair;
import org.apache.ignite.internal.sql.engine.planner.datatypes.utils.Types;
-import org.apache.ignite.internal.sql.engine.rel.IgniteRel;
-import
org.apache.ignite.internal.sql.engine.rel.ProjectableFilterableTableScan;
import org.apache.ignite.internal.sql.engine.schema.IgniteSchema;
-import org.apache.ignite.internal.sql.engine.trait.IgniteDistributions;
-import org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory;
-import org.apache.ignite.internal.sql.engine.util.Commons;
-import org.apache.ignite.internal.sql.engine.util.TypeUtils;
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
@@ -53,12 +36,11 @@ import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
/**
- * A set of test to verify behavior of type coercion for binary comparison,
when operands belongs
- * to the NUMERIC type family.
+ * A set of test to verify behavior of type coercion for binary comparison,
when operands belongs to the NUMERIC type family.
*
- * <p>This tests aim to help to understand in which cases implicit cast will
be added to which operand.
+ * <p>This tests aim to help to understand in which cases implicit cast will
be added to which operand.
*/
-public class NumericComparisonTypeCoercionTest extends AbstractPlannerTest {
+public class NumericComparisonTypeCoercionTest extends BaseTypeCoercionTest {
private static Stream<Arguments> args() {
return Stream.of(
forTypePair(NumericPair.TINYINT_TINYINT)
@@ -840,126 +822,4 @@ public class NumericComparisonTypeCoercionTest extends
AbstractPlannerTest {
assertThat(remainingPairs, Matchers.empty());
}
-
- private static IgniteSchema createSchemaWithTwoColumnTable(NativeType c1,
NativeType c2) {
- return createSchema(
- TestBuilders.table()
- .name("T")
- .distribution(IgniteDistributions.single())
- .addColumn("C1", c1)
- .addColumn("C2", c2)
- .build()
- );
- }
-
- private static Matcher<IgniteRel> operandMatcher(Matcher<RexNode> first,
Matcher<RexNode> second) {
- return new BaseMatcher<IgniteRel>() {
- @Override
- public boolean matches(Object actual) {
- RexNode comparison = ((ProjectableFilterableTableScan)
actual).projects().get(0);
-
- assertThat(comparison, instanceOf(RexCall.class));
-
- RexCall comparisonCall = (RexCall) comparison;
-
- RexNode leftOperand = comparisonCall.getOperands().get(0);
- RexNode rightOperand = comparisonCall.getOperands().get(1);
-
- assertThat(leftOperand, first);
- assertThat(rightOperand, second);
-
- return true;
- }
-
- @Override
- public void describeTo(Description description) {
-
- }
- };
- }
-
- /**
- * Creates a matcher to verify that given expression has expected return
type, but it is not CAST operator.
- *
- * @param type Expected return type.
- * @return A matcher.
- */
- private static Matcher<RexNode> ofTypeWithoutCast(NativeType type) {
- IgniteTypeFactory typeFactory = Commons.typeFactory();
- RelDataType sqlType = TypeUtils.native2relationalType(typeFactory,
type);
-
- return new BaseMatcher<RexNode>() {
- @Override
- public boolean matches(Object actual) {
- return SqlTypeUtil.equalSansNullability(typeFactory,
((RexNode) actual).getType(), sqlType)
- && !((RexNode) actual).isA(SqlKind.CAST);
- }
-
- @Override
- public void describeMismatch(Object item, Description description)
{
- description.appendText("was ").appendValue(item).appendText("
of type " + ((RexNode) item).getType());
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText(format("Operand of type {} that is not
CAST", sqlType));
- }
- };
- }
-
- /**
- * Creates a matcher to verify that given expression is CAST operator with
expected return type.
- *
- * @param type Expected return type.
- * @return A matcher.
- */
- private static Matcher<RexNode> castTo(NativeType type) {
- IgniteTypeFactory typeFactory = Commons.typeFactory();
- RelDataType sqlType = TypeUtils.native2relationalType(typeFactory,
type);
-
- return new BaseMatcher<RexNode>() {
- @Override
- public boolean matches(Object actual) {
- return actual instanceof RexCall
- && ((RexNode) actual).isA(SqlKind.CAST)
- && SqlTypeUtil.equalSansNullability(typeFactory,
((RexNode) actual).getType(), sqlType);
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText("Operand that is CAST(..):" + sqlType);
- }
-
- @Override
- public void describeMismatch(Object item, Description description)
{
- description.appendText("was ").appendValue(item).appendText("
of type " + ((RexNode) item).getType());
- }
- };
- }
-
- private static TestCaseBuilder forTypePair(TypePair typePair) {
- return new TestCaseBuilder(typePair);
- }
-
- /**
- * Not really a builder, but provides DSL-like API to describe test case.
- */
- static class TestCaseBuilder {
- private final TypePair pair;
- private Matcher<RexNode> firstOpMatcher;
-
- private TestCaseBuilder(TypePair pair) {
- this.pair = pair;
- }
-
- TestCaseBuilder firstOpMatches(Matcher<RexNode> operandMatcher) {
- firstOpMatcher = operandMatcher;
-
- return this;
- }
-
- Arguments secondOpMatches(Matcher<RexNode> operandMatcher) {
- return Arguments.of(pair, firstOpMatcher, operandMatcher);
- }
- }
}
diff --git
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/datatypes/utils/Types.java
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/datatypes/utils/Types.java
index 6f8efc4ff2..71f4f83f53 100644
---
a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/datatypes/utils/Types.java
+++
b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/planner/datatypes/utils/Types.java
@@ -42,6 +42,9 @@ public final class Types {
public static final NativeType DECIMAL_6_1 = NativeTypes.decimalOf(6, 1);
public static final NativeType DECIMAL_8_3 = NativeTypes.decimalOf(8, 3);
+ public static final NativeType DECIMAL_14_7 = NativeTypes.decimalOf(14, 7);
+ public static final NativeType DECIMAL_30_15 = NativeTypes.decimalOf(30,
15);
+
private Types() {
throw new AssertionError("Should not be called");
}