korlov42 commented on code in PR #4422: URL: https://github.com/apache/ignite-3/pull/4422#discussion_r1774634137
########## modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeSystemTest.java: ########## @@ -168,5 +169,135 @@ private static Stream<Arguments> deriveAvgTypeArguments() { native2relationalType(typeFactory, NativeTypes.DOUBLE) ) ); - } + } + + @ParameterizedTest(name = "op={0} {1}") + @MethodSource("deriveDivTypeArguments") + void deriveDivType(NativeType type1, NativeType type2, NativeType expected) { + RelDataType relType1 = native2relationalType(Commons.typeFactory(), type1); + RelDataType relType2 = native2relationalType(Commons.typeFactory(), type2); + RelDataType relExpected = native2relationalType(Commons.typeFactory(), expected); + + RelDataType actual = typeSystem.deriveDecimalDivideType(Commons.typeFactory(), relType1, relType2); + assertThat(actual, Matchers.equalTo(relExpected)); + } + + @ParameterizedTest(name = "op={0} {1}") + @MethodSource("deriveMultTypeArguments") + void deriveMultType(NativeType type1, NativeType type2, NativeType expected) { + RelDataType relType1 = native2relationalType(Commons.typeFactory(), type1); + RelDataType relType2 = native2relationalType(Commons.typeFactory(), type2); + RelDataType relExpected = native2relationalType(Commons.typeFactory(), expected); + + RelDataType actual = typeSystem.deriveDecimalMultiplyType(Commons.typeFactory(), relType1, relType2); + assertThat(actual, Matchers.equalTo(relExpected)); + } + + @ParameterizedTest(name = "op={0} {1}") + @MethodSource("deriveAddTypeArguments") + void deriveAddType(NativeType type1, NativeType type2, NativeType expected) { + RelDataType relType1 = native2relationalType(Commons.typeFactory(), type1); + RelDataType relType2 = native2relationalType(Commons.typeFactory(), type2); + RelDataType relExpected = native2relationalType(Commons.typeFactory(), expected); + + RelDataType actual = typeSystem.deriveDecimalPlusType(Commons.typeFactory(), relType1, relType2); + assertThat(actual, Matchers.equalTo(relExpected)); + } + + private static Stream<Arguments> deriveDivTypeArguments() { + IgniteTypeSystem typeSystem = IgniteTypeSystem.INSTANCE; + + return Stream.of( + Arguments.of(NativeTypes.INT8, NativeTypes.INT8, NativeTypes.INT16), + Arguments.of(NativeTypes.INT8, NativeTypes.INT16, NativeTypes.INT16), + Arguments.of(NativeTypes.INT8, NativeTypes.INT32, NativeTypes.INT16), + Arguments.of(NativeTypes.INT8, NativeTypes.INT64, NativeTypes.INT16), + + Arguments.of(NativeTypes.INT16, NativeTypes.INT8, NativeTypes.INT32), + Arguments.of(NativeTypes.INT16, NativeTypes.INT16, NativeTypes.INT32), + Arguments.of(NativeTypes.INT16, NativeTypes.INT32, NativeTypes.INT32), + Arguments.of(NativeTypes.INT16, NativeTypes.INT64, NativeTypes.INT32), + + Arguments.of(NativeTypes.INT32, NativeTypes.INT8, NativeTypes.INT64), + Arguments.of(NativeTypes.INT32, NativeTypes.INT16, NativeTypes.INT64), + Arguments.of(NativeTypes.INT32, NativeTypes.INT32, NativeTypes.INT64), + Arguments.of(NativeTypes.INT32, NativeTypes.INT64, NativeTypes.INT64), + + Arguments.of(NativeTypes.INT64, NativeTypes.INT8, + NativeTypes.decimalOf(typeSystem.getMaxPrecision(SqlTypeName.DECIMAL), 0)), Review Comment: let's introduce constant for DECIMAL_MAX_0 ########## modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeSystemTest.java: ########## @@ -168,5 +169,135 @@ private static Stream<Arguments> deriveAvgTypeArguments() { native2relationalType(typeFactory, NativeTypes.DOUBLE) ) ); - } + } + + @ParameterizedTest(name = "op={0} {1}") + @MethodSource("deriveDivTypeArguments") + void deriveDivType(NativeType type1, NativeType type2, NativeType expected) { + RelDataType relType1 = native2relationalType(Commons.typeFactory(), type1); + RelDataType relType2 = native2relationalType(Commons.typeFactory(), type2); + RelDataType relExpected = native2relationalType(Commons.typeFactory(), expected); + + RelDataType actual = typeSystem.deriveDecimalDivideType(Commons.typeFactory(), relType1, relType2); + assertThat(actual, Matchers.equalTo(relExpected)); + } + + @ParameterizedTest(name = "op={0} {1}") + @MethodSource("deriveMultTypeArguments") + void deriveMultType(NativeType type1, NativeType type2, NativeType expected) { + RelDataType relType1 = native2relationalType(Commons.typeFactory(), type1); + RelDataType relType2 = native2relationalType(Commons.typeFactory(), type2); + RelDataType relExpected = native2relationalType(Commons.typeFactory(), expected); + + RelDataType actual = typeSystem.deriveDecimalMultiplyType(Commons.typeFactory(), relType1, relType2); + assertThat(actual, Matchers.equalTo(relExpected)); + } + + @ParameterizedTest(name = "op={0} {1}") + @MethodSource("deriveAddTypeArguments") + void deriveAddType(NativeType type1, NativeType type2, NativeType expected) { + RelDataType relType1 = native2relationalType(Commons.typeFactory(), type1); + RelDataType relType2 = native2relationalType(Commons.typeFactory(), type2); + RelDataType relExpected = native2relationalType(Commons.typeFactory(), expected); + + RelDataType actual = typeSystem.deriveDecimalPlusType(Commons.typeFactory(), relType1, relType2); + assertThat(actual, Matchers.equalTo(relExpected)); + } + + private static Stream<Arguments> deriveDivTypeArguments() { + IgniteTypeSystem typeSystem = IgniteTypeSystem.INSTANCE; + + return Stream.of( + Arguments.of(NativeTypes.INT8, NativeTypes.INT8, NativeTypes.INT16), + Arguments.of(NativeTypes.INT8, NativeTypes.INT16, NativeTypes.INT16), + Arguments.of(NativeTypes.INT8, NativeTypes.INT32, NativeTypes.INT16), + Arguments.of(NativeTypes.INT8, NativeTypes.INT64, NativeTypes.INT16), + + Arguments.of(NativeTypes.INT16, NativeTypes.INT8, NativeTypes.INT32), + Arguments.of(NativeTypes.INT16, NativeTypes.INT16, NativeTypes.INT32), + Arguments.of(NativeTypes.INT16, NativeTypes.INT32, NativeTypes.INT32), + Arguments.of(NativeTypes.INT16, NativeTypes.INT64, NativeTypes.INT32), + + Arguments.of(NativeTypes.INT32, NativeTypes.INT8, NativeTypes.INT64), + Arguments.of(NativeTypes.INT32, NativeTypes.INT16, NativeTypes.INT64), + Arguments.of(NativeTypes.INT32, NativeTypes.INT32, NativeTypes.INT64), + Arguments.of(NativeTypes.INT32, NativeTypes.INT64, NativeTypes.INT64), + + Arguments.of(NativeTypes.INT64, NativeTypes.INT8, + NativeTypes.decimalOf(typeSystem.getMaxPrecision(SqlTypeName.DECIMAL), 0)), + Arguments.of(NativeTypes.INT64, NativeTypes.INT16, + NativeTypes.decimalOf(typeSystem.getMaxPrecision(SqlTypeName.DECIMAL), 0)), + Arguments.of(NativeTypes.INT64, NativeTypes.INT32, + NativeTypes.decimalOf(typeSystem.getMaxPrecision(SqlTypeName.DECIMAL), 0)), + Arguments.of(NativeTypes.INT64, NativeTypes.INT64, + NativeTypes.decimalOf(typeSystem.getMaxPrecision(SqlTypeName.DECIMAL), 0)) + ); + } + + + private static Stream<Arguments> deriveMultTypeArguments() { Review Comment: argument for multiplication and addition seems to be identical. Does it make sense leave only one set of arguments? ########## modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/type/IgniteTypeSystem.java: ########## @@ -82,6 +86,84 @@ public int getDefaultPrecision(SqlTypeName typeName) { } } + /** + * Extend passed type to the nearest bigger. + * TINYINT -> SMALLINT + * SMALLINT -> INTEGER + * INTEGER -> BIGINT + * BIGINT -> DECIMAL + * + * @param typeFactory Type factory. + * @param type Type need to be extended. + * @param nullable Nullability flag. + * @return Extended type. + */ + private static RelDataType extendType(RelDataTypeFactory typeFactory, RelDataType type, boolean nullable) { + switch (type.getSqlTypeName()) { + case TINYINT: + return typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.SMALLINT), + nullable); + case SMALLINT: + return typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.INTEGER), + nullable); + case INTEGER: + return typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.BIGINT), + nullable); + case BIGINT: + return typeFactory.createTypeWithNullability( + typeFactory.createSqlType( + SqlTypeName.DECIMAL, + typeFactory.getTypeSystem().getMaxPrecision(SqlTypeName.DECIMAL), Review Comment: > will return with non zero scale "177.00000" vs "177" and it not expected why do you say "it's not expected"? it's literally what you've changed in this patch :) Before this patch chain of math operation results in a least restrictive type among operands, now result type is bumped every time. Given an expression like this `(a+b+c+d+e)/5` (from the first failed statement from mentioned script), before this patch final operation was `(int) / (int)` which results in another int. Now it's `(decimal) / (int)`, and to know resulting type you should check `org.apache.calcite.rel.type.RelDataTypeSystem#deriveDecimalDivideType` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: notifications-unsubscr...@ignite.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org