From 32fb253238c6c3a43e2cec1236f43133c0da02c8 Mon Sep 17 00:00:00 2001 From: Cool6689 <3322351820@qq.com> Date: Thu, 20 Nov 2025 21:23:46 +0800 Subject: [PATCH 1/4] Rewriting tree model mathematical operators --- .../iotdb/db/it/query/IoTDBArithmeticIT.java | 240 +++++++++++++++++- .../plan/analyze/ExpressionTypeAnalyzer.java | 87 ++++--- .../visitor/ColumnTransformerVisitor.java | 58 ++--- .../plan/planner/OperatorTreeGenerator.java | 3 + .../function/arithmetic/AdditionResolver.java | 58 +++++ .../function/arithmetic/DivisionResolver.java | 43 ++++ .../function/arithmetic/ModulusResolver.java | 43 ++++ .../arithmetic/MultiplicationResolver.java | 43 ++++ .../arithmetic/SubtractionResolver.java | 50 ++++ 9 files changed, 557 insertions(+), 68 deletions(-) diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBArithmeticIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBArithmeticIT.java index 6c54b7f187535..36acc6a9bea3a 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBArithmeticIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBArithmeticIT.java @@ -59,11 +59,13 @@ public class IoTDBArithmeticIT { "CREATE TIMESERIES root.sg.d1.s6 WITH DATATYPE=TEXT, ENCODING=PLAIN", "CREATE TIMESERIES root.sg.d1.s7 WITH DATATYPE=INT32, ENCODING=PLAIN", "CREATE TIMESERIES root.sg.d1.s8 WITH DATATYPE=INT32, ENCODING=PLAIN", - "insert into root.sg.d1(time, s1, s2, s3, s4, s5, s6, s7) values (1, 1, 1, 1, 1, false, '1', 1)", - "insert into root.sg.d1(time, s1, s2, s3, s4, s5, s6, s8) values (2, 2, 2, 2, 2, false, '2', 2)", - "insert into root.sg.d1(time, s1, s2, s3, s4, s5, s6, s7) values (3, 3, 3, 3, 3, true, '3', 3)", - "insert into root.sg.d1(time, s1, s2, s3, s4, s5, s6, s8) values (4, 4, 4, 4, 4, true, '4', 4)", - "insert into root.sg.d1(time, s1, s2, s3, s4, s5, s6, s7, s8) values (5, 5, 5, 5, 5, true, '5', 5, 5)", + "CREATE TIMESERIES root.sg.d1.s9 WITH DATATYPE=DATE, ENCODING=PLAIN", + "CREATE TIMESERIES root.sg.d1.s10 WITH DATATYPE=TIMESTAMP, ENCODING=PLAIN", + "insert into root.sg.d1(time, s1, s2, s3, s4, s5, s6, s7, s9, s10) values (1, 1, 1, 1, 1, false, '1', 1, '2024-01-01', 10)", + "insert into root.sg.d1(time, s1, s2, s3, s4, s5, s6, s8, s9, s10) values (2, 2, 2, 2, 2, false, '2', 2, '2024-02-01', 20)", + "insert into root.sg.d1(time, s1, s2, s3, s4, s5, s6, s7, s9, s10) values (3, 3, 3, 3, 3, true, '3', 3, '2024-03-01', 30)", + "insert into root.sg.d1(time, s1, s2, s3, s4, s5, s6, s8, s9, s10) values (4, 4, 4, 4, 4, true, '4', 4, '2024-04-01', 40)", + "insert into root.sg.d1(time, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10) values (5, 5, 5, 5, 5, true, '5', 5, 5, '2024-05-01', 50)", }; @BeforeClass @@ -151,6 +153,44 @@ public void testArithmeticUnary() { } } + @Test + public void testTimestampNegation() { + try (Connection connection = EnvFactory.getEnv().getConnection(); + Statement statement = connection.createStatement()) { + ResultSet resultSet = statement.executeQuery("select -s10 from root.sg.d1"); + + String[] expected = { + "1969-12-31T23:59:59.990Z", + "1969-12-31T23:59:59.980Z", + "1969-12-31T23:59:59.970Z", + "1969-12-31T23:59:59.960Z", + "1969-12-31T23:59:59.950Z" + }; + + for (String expectedValue : expected) { + resultSet.next(); + assertEquals(expectedValue, resultSet.getString(2)); + } + } catch (SQLException throwable) { + fail(throwable.getMessage()); + } + } + + @Test + public void testUnaryWrongType() { + try (Connection connection = EnvFactory.getEnv().getConnection(); + Statement statement = connection.createStatement()) { + tsAssertTestFail( + statement, "select -s5 from root.sg.d1", "Invalid input expression data type"); + tsAssertTestFail( + statement, "select -s6 from root.sg.d1", "Invalid input expression data type"); + tsAssertTestFail( + statement, "select -s9 from root.sg.d1", "Invalid input expression data type"); + } catch (SQLException throwable) { + fail(throwable.getMessage()); + } + } + @Test public void testHybridQuery() { try (Connection connection = EnvFactory.getEnv().getConnection(); @@ -241,4 +281,194 @@ public void testNot() { fail(); } } + + @Test + public void testDateAndTimestampArithmetic() { + try (Connection connection = EnvFactory.getEnv().getConnection(); + Statement statement = connection.createStatement()) { + + String sql = + "select s1+s9,s1+s10,s2+s9,s2+s10,s9+s1,s9+s2,s10+s1,s10+s2,s9-s1,s9-s2,s10-s1,s10-s2 from root.sg.d1"; + ResultSet resultSet = statement.executeQuery(sql); + + int[][] expectedResults = { + {20240101, 11, 20240101, 11, 20240101, 20240101, 11, 11, 20231231, 20231231, 9, 9}, + {20240201, 22, 20240201, 22, 20240201, 20240201, 22, 22, 20240131, 20240131, 18, 18}, + {20240301, 33, 20240301, 33, 20240301, 20240301, 33, 33, 20240229, 20240229, 27, 27}, + {20240401, 44, 20240401, 44, 20240401, 20240401, 44, 44, 20240331, 20240331, 36, 36}, + {20240501, 55, 20240501, 55, 20240501, 20240501, 55, 55, 20240430, 20240430, 45, 45} + }; + + for (int[] expectedResult : expectedResults) { + resultSet.next(); + for (int i = 0; i < expectedResult.length; i++) { + assertEquals(expectedResult[i], resultSet.getInt(i + 2)); + } + } + } catch (SQLException throwable) { + fail(throwable.getMessage()); + } + } + + @Test + public void testDivisionByZero() { + try (Connection connection = EnvFactory.getEnv().getConnection(); + Statement statement = connection.createStatement()) { + tsAssertTestFail(statement, "select s1/0 from root.sg.d1", "Division by zero"); + tsAssertTestFail(statement, "select s2/0 from root.sg.d1", "Division by zero"); + tsAssertTestFail(statement, "select s1%0 from root.sg.d1", "Division by zero"); + tsAssertTestFail(statement, "select s2%0 from root.sg.d1", "Division by zero"); + } catch (SQLException throwable) { + fail(throwable.getMessage()); + } + } + + @Test + public void testFloatDivisionByZero() { + try (Connection connection = EnvFactory.getEnv().getConnection(); + Statement statement = connection.createStatement()) { + ResultSet resultSet = + statement.executeQuery("select s3/0.0,0.0/s3,0.0/-s3,-s3/0.0 from root.sg.d1"); + + String[] expected = {"Infinity", "0.0", "-0.0", "-Infinity"}; + + for (int i = 0; i < 5; i++) { + resultSet.next(); + for (int j = 0; j < expected.length; j++) { + assertEquals(expected[j], resultSet.getString(j + 2)); + } + } + } catch (SQLException throwable) { + fail(throwable.getMessage()); + } + } + + @Test + public void testDoubleModuloByZero() { + try (Connection connection = EnvFactory.getEnv().getConnection(); + Statement statement = connection.createStatement()) { + ResultSet resultSet = + statement.executeQuery("select s4%0.0,0.0%s4,0.0%-s4,-s4%0.0 from root.sg.d1"); + + String[] expected = {"NaN", "0.0", "0.0", "NaN"}; + + for (int i = 0; i < 5; i++) { + resultSet.next(); + for (int j = 0; j < expected.length; j++) { + assertEquals(expected[j], resultSet.getString(j + 2)); + } + } + } catch (SQLException throwable) { + fail(throwable.getMessage()); + } + } + + @Test + public void testBinaryWrongType() { + try (Connection connection = EnvFactory.getEnv().getConnection(); + Statement statement = connection.createStatement()) { + tsAssertTestFail(statement, "select s9 * s1 from root.sg.d1", "Invalid"); + tsAssertTestFail(statement, "select s9 / s1 from root.sg.d1", "Invalid"); + tsAssertTestFail(statement, "select s9 % s1 from root.sg.d1", "Invalid"); + tsAssertTestFail(statement, "select s10 * s1 from root.sg.d1", "Invalid"); + tsAssertTestFail(statement, "select s10 / s1 from root.sg.d1", "Invalid"); + tsAssertTestFail(statement, "select s10 % s1 from root.sg.d1", "Invalid"); + } catch (SQLException throwable) { + fail(throwable.getMessage()); + } + } + + @Test + public void testOverflow() { + try (Connection connection = EnvFactory.getEnv().getConnection(); + Statement statement = connection.createStatement()) { + + String[][] timeseries = { + {"s1", "INT32"}, + {"s2", "INT64"}, + {"s3", "INT64"}, + {"s7", "INT32"}, + {"s8", "INT32"}, + {"s10", "TIMESTAMP"} + }; + for (String[] ts : timeseries) { + statement.execute( + String.format( + "CREATE TIMESERIES root.sg.d2.%s WITH DATATYPE=%s, ENCODING=PLAIN", ts[0], ts[1])); + } + + statement.execute( + String.format( + "insert into root.sg.d2(time, s1, s2, s3, s7, s8, s10) values (1, %d, %d, %d, %d, %d, %d)", + Integer.MAX_VALUE / 2 + 1, + Long.MAX_VALUE / 2 + 1, + Long.MIN_VALUE / 2 - 1, + Integer.MAX_VALUE / 2 + 1, + Integer.MIN_VALUE / 2 - 1, + Long.MAX_VALUE / 2 + 1)); + statement.execute( + String.format( + "insert into root.sg.d2(time, s1, s2, s7, s8) values (2, %d, %d, %d, %d)", + Integer.MIN_VALUE / 2 - 1, + Long.MIN_VALUE / 2 - 1, + Integer.MIN_VALUE / 2 - 1, + Integer.MAX_VALUE / 2 + 1)); + + tsAssertTestFail( + statement, "select s1+s7 from root.sg.d2 where time=1", "int Addition overflow"); + tsAssertTestFail( + statement, "select s1-s8 from root.sg.d2 where time=2", "int Subtraction overflow"); + tsAssertTestFail( + statement, "select s1*s7 from root.sg.d2 where time=1", "int Multiplication overflow"); + + tsAssertTestFail( + statement, "select s2+s2 from root.sg.d2 where time=1", "long Addition overflow"); + tsAssertTestFail( + statement, "select s3-s2 from root.sg.d2 where time=1", "long Subtraction overflow"); + + tsAssertTestFail( + statement, + String.format("select s10+%d from root.sg.d2 where time=1", Long.MAX_VALUE), + "long Addition overflow"); + tsAssertTestFail( + statement, + String.format("select s10-(%d) from root.sg.d2 where time=1", Long.MIN_VALUE), + "long Subtraction overflow"); + + } catch (SQLException throwable) { + fail(throwable.getMessage()); + } + } + + @Test + public void testDateOutOfRange() { + try (Connection connection = EnvFactory.getEnv().getConnection(); + Statement statement = connection.createStatement()) { + statement.execute("CREATE TIMESERIES root.sg.d3.date WITH DATATYPE=DATE, ENCODING=PLAIN"); + statement.execute("insert into root.sg.d3(time, date) values (1, '9999-12-31')"); + statement.execute("insert into root.sg.d3(time, date) values (2, '1000-01-01')"); + + tsAssertTestFail( + statement, + "select date + 86400000 from root.sg.d3 where time = 1", + "Year must be between 1000 and 9999"); + tsAssertTestFail( + statement, + "select date - 86400000 from root.sg.d3 where time = 2", + "Year must be between 1000 and 9999"); + } catch (SQLException throwable) { + fail(throwable.getMessage()); + } + } + + private void tsAssertTestFail(Statement statement, String sql, String expectedErrorMsg) { + try { + statement.executeQuery(sql); + fail("Expected exception with message: " + expectedErrorMsg); + } catch (SQLException e) { + assertTrue( + "Expected error message '" + expectedErrorMsg + "' but got: " + e.getMessage(), + e.getMessage().contains(expectedErrorMsg)); + } + } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionTypeAnalyzer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionTypeAnalyzer.java index adc80c7bb1522..627ae71c7aedf 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionTypeAnalyzer.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionTypeAnalyzer.java @@ -41,6 +41,11 @@ import org.apache.iotdb.db.queryengine.plan.expression.unary.NegationExpression; import org.apache.iotdb.db.queryengine.plan.expression.unary.RegularExpression; import org.apache.iotdb.db.queryengine.plan.expression.visitor.ExpressionVisitor; +import org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.AdditionResolver; +import org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.DivisionResolver; +import org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.ModulusResolver; +import org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.MultiplicationResolver; +import org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.SubtractionResolver; import org.apache.iotdb.db.queryengine.transformation.dag.udf.UDAFInformationInferrer; import org.apache.iotdb.db.queryengine.transformation.dag.udf.UDTFInformationInferrer; import org.apache.iotdb.db.utils.TypeInferenceUtils; @@ -54,6 +59,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -217,46 +223,61 @@ public TSDataType visitLogicNotExpression( @Override public TSDataType visitNegationExpression( NegationExpression negationExpression, Function context) { - TSDataType inputExpressionType = process(negationExpression.getExpression(), context); - checkInputExpressionDataType( - negationExpression.getExpression().getExpressionString(), - inputExpressionType, - TSDataType.INT32, - TSDataType.INT64, - TSDataType.FLOAT, - TSDataType.DOUBLE); - return setExpressionType(negationExpression, inputExpressionType); + TSDataType operandType = process(negationExpression.getExpression(), context); + + if (operandType != TSDataType.INT32 + && operandType != TSDataType.INT64 + && operandType != TSDataType.FLOAT + && operandType != TSDataType.DOUBLE + && operandType != TSDataType.TIMESTAMP) { + throw new SemanticException( + String.format( + "Invalid input expression data type. Do not support %s operation for %s.", + ExpressionType.NEGATION, operandType)); + } + + return setExpressionType(negationExpression, operandType); } @Override public TSDataType visitArithmeticBinaryExpression( ArithmeticBinaryExpression arithmeticBinaryExpression, Function context) { - checkInputExpressionDataType( - arithmeticBinaryExpression.getLeftExpression().getExpressionString(), - process(arithmeticBinaryExpression.getLeftExpression(), context), - TSDataType.INT32, - TSDataType.INT64, - TSDataType.FLOAT, - TSDataType.DOUBLE); - checkInputExpressionDataType( - arithmeticBinaryExpression.getRightExpression().getExpressionString(), - process(arithmeticBinaryExpression.getRightExpression(), context), - TSDataType.INT32, - TSDataType.INT64, - TSDataType.FLOAT, - TSDataType.DOUBLE); - if ((arithmeticBinaryExpression.getExpressionType() == ExpressionType.DIVISION - || arithmeticBinaryExpression.getExpressionType() == ExpressionType.MODULO) - && isExpressionDataTypeSatisfy( - arithmeticBinaryExpression.getLeftExpression(), TSDataType.INT64, TSDataType.INT32) - && isExpressionDataTypeSatisfy( - arithmeticBinaryExpression.getRightExpression(), - TSDataType.INT64, - TSDataType.INT32)) { - return setExpressionType(arithmeticBinaryExpression, TSDataType.INT64); + TSDataType leftType = process(arithmeticBinaryExpression.getLeftExpression(), context); + TSDataType rightType = process(arithmeticBinaryExpression.getRightExpression(), context); + + ExpressionType operatorType = arithmeticBinaryExpression.getExpressionType(); + + Optional resultTypeOpt; + switch (operatorType) { + case ADDITION: + resultTypeOpt = AdditionResolver.inferType(leftType, rightType); + break; + case SUBTRACTION: + resultTypeOpt = SubtractionResolver.inferType(leftType, rightType); + break; + case MULTIPLICATION: + resultTypeOpt = MultiplicationResolver.inferType(leftType, rightType); + break; + case DIVISION: + resultTypeOpt = DivisionResolver.inferType(leftType, rightType); + break; + case MODULO: + resultTypeOpt = ModulusResolver.inferType(leftType, rightType); + break; + default: + resultTypeOpt = Optional.empty(); + break; } - return setExpressionType(arithmeticBinaryExpression, TSDataType.DOUBLE); + + if (!resultTypeOpt.isPresent()) { + throw new SemanticException( + String.format( + "Invalid input expression data type. Do not support %s operation for %s and %s.", + operatorType, leftType, rightType)); + } + + return setExpressionType(arithmeticBinaryExpression, resultTypeOpt.get()); } @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ColumnTransformerVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ColumnTransformerVisitor.java index 9bdee1e4788b3..bae8318bb4856 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ColumnTransformerVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/ColumnTransformerVisitor.java @@ -20,6 +20,7 @@ package org.apache.iotdb.db.queryengine.plan.expression.visitor; import org.apache.iotdb.db.queryengine.common.NodeRef; +import org.apache.iotdb.db.queryengine.common.SessionInfo; import org.apache.iotdb.db.queryengine.plan.analyze.TypeProvider; import org.apache.iotdb.db.queryengine.plan.expression.Expression; import org.apache.iotdb.db.queryengine.plan.expression.binary.BinaryExpression; @@ -41,11 +42,7 @@ import org.apache.iotdb.db.queryengine.plan.planner.plan.parameter.InputLocation; import org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.TreeCaseWhenThenColumnTransformer; -import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.ArithmeticAdditionColumnTransformer; -import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.ArithmeticDivisionColumnTransformer; -import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.ArithmeticModuloColumnTransformer; -import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.ArithmeticMultiplicationColumnTransformer; -import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.ArithmeticSubtractionColumnTransformer; +import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.ArithmeticColumnTransformerApi; import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.CompareEqualToColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.CompareGreaterEqualColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.CompareGreaterThanColumnTransformer; @@ -54,8 +51,6 @@ import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.CompareNonEqualColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.LogicAndColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.LogicOrColumnTransformer; -import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.LongDivisionLongColumnTransformer; -import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.LongModulusLongColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.ConstantColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.IdentityColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.LeafColumnTransformer; @@ -63,7 +58,6 @@ import org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.TimeColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.multi.MappableUDFColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.ternary.BetweenColumnTransformer; -import org.apache.iotdb.db.queryengine.transformation.dag.column.unary.ArithmeticNegationColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.unary.InColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.unary.IsNullColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.unary.LikeColumnTransformer; @@ -79,6 +73,7 @@ import org.apache.tsfile.read.common.type.Type; import org.apache.tsfile.read.common.type.TypeFactory; +import java.time.ZoneId; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -86,7 +81,6 @@ import static org.apache.iotdb.db.queryengine.plan.expression.ExpressionType.BETWEEN; import static org.apache.tsfile.enums.TSDataType.UNKNOWN; -import static org.apache.tsfile.read.common.type.LongType.INT64; /** Responsible for constructing {@link ColumnTransformer} through Expression. */ public class ColumnTransformerVisitor @@ -161,7 +155,8 @@ public ColumnTransformer visitBinaryExpression( binaryExpression, leftColumnTransformer, rightColumnTransformer, - TypeFactory.getType(context.getType(binaryExpression)))); + TypeFactory.getType(context.getType(binaryExpression)), + context.getZoneId())); } } @@ -445,7 +440,7 @@ private ColumnTransformer getConcreteUnaryColumnTransformer( case LOGIC_NOT: return new LogicNotColumnTransformer(returnType, childColumnTransformer); case NEGATION: - return new ArithmeticNegationColumnTransformer(returnType, childColumnTransformer); + return ArithmeticColumnTransformerApi.getNegationTransformer(childColumnTransformer); case LIKE: LikeExpression likeExpression = (LikeExpression) expression; LikePattern pattern = @@ -465,31 +460,25 @@ private ColumnTransformer getConcreteBinaryColumnTransformer( Expression expression, ColumnTransformer leftColumnTransformer, ColumnTransformer rightColumnTransformer, - Type returnType) { + Type returnType, + ZoneId zoneId) { + switch (expression.getExpressionType()) { case ADDITION: - return new ArithmeticAdditionColumnTransformer( - returnType, leftColumnTransformer, rightColumnTransformer); + return ArithmeticColumnTransformerApi.getAdditionTransformer( + leftColumnTransformer, rightColumnTransformer, zoneId); case SUBTRACTION: - return new ArithmeticSubtractionColumnTransformer( - returnType, leftColumnTransformer, rightColumnTransformer); + return ArithmeticColumnTransformerApi.getSubtractionTransformer( + leftColumnTransformer, rightColumnTransformer, zoneId); case MULTIPLICATION: - return new ArithmeticMultiplicationColumnTransformer( - returnType, leftColumnTransformer, rightColumnTransformer); + return ArithmeticColumnTransformerApi.getMultiplicationTransformer( + leftColumnTransformer, rightColumnTransformer, zoneId); case DIVISION: - if (returnType == INT64) { - return new LongDivisionLongColumnTransformer( - returnType, leftColumnTransformer, rightColumnTransformer); - } - return new ArithmeticDivisionColumnTransformer( - returnType, leftColumnTransformer, rightColumnTransformer); + return ArithmeticColumnTransformerApi.getDivisionTransformer( + leftColumnTransformer, rightColumnTransformer, zoneId); case MODULO: - if (returnType == INT64) { - return new LongModulusLongColumnTransformer( - returnType, leftColumnTransformer, rightColumnTransformer); - } - return new ArithmeticModuloColumnTransformer( - returnType, leftColumnTransformer, rightColumnTransformer); + return ArithmeticColumnTransformerApi.getModulusTransformer( + leftColumnTransformer, rightColumnTransformer, zoneId); case EQUAL_TO: return new CompareEqualToColumnTransformer( returnType, leftColumnTransformer, rightColumnTransformer); @@ -541,6 +530,9 @@ private ColumnTransformer getConcreteTernaryTransformer( } public static class ColumnTransformerVisitorContext { + // SessionInfo for getting ZoneId + SessionInfo sessionInfo; + // UDTFContext of expression UDTFContext udtfContext; @@ -570,6 +562,7 @@ public static class ColumnTransformerVisitorContext { @SuppressWarnings("squid:S107") public ColumnTransformerVisitorContext( + SessionInfo sessionInfo, UDTFContext udtfContext, Map, TSDataType> expressionTypes, List leafList, @@ -580,6 +573,7 @@ public ColumnTransformerVisitorContext( List inputDataTypes, int originSize, TypeProvider typeProvider) { + this.sessionInfo = sessionInfo; this.udtfContext = udtfContext; this.expressionTypes = expressionTypes; this.leafList = leafList; @@ -614,5 +608,9 @@ public TSDataType getType(Expression expression) { public TypeProvider getTypeProvider() { return this.typeProvider; } + + public ZoneId getZoneId() { + return sessionInfo.getZoneId(); + } } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java index 581641591837b..2129ff4ee07e7 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java @@ -1556,6 +1556,7 @@ public Operator visitTransform(TransformNode node, LocalExecutionPlanContext con ColumnTransformerVisitor visitor = new ColumnTransformerVisitor(); ColumnTransformerVisitor.ColumnTransformerVisitorContext projectColumnTransformerContext = new ColumnTransformerVisitor.ColumnTransformerVisitorContext( + context.getDriverContext().getFragmentInstanceContext().getSessionInfo(), projectContext, expressionTypes, projectLeafColumnTransformerList, @@ -1712,6 +1713,7 @@ private Operator constructFilterOperator( ColumnTransformerVisitor.ColumnTransformerVisitorContext filterColumnTransformerContext = new ColumnTransformerVisitor.ColumnTransformerVisitorContext( + context.getDriverContext().getFragmentInstanceContext().getSessionInfo(), filterContext, expressionTypes, filterLeafColumnTransformerList, @@ -1738,6 +1740,7 @@ private Operator constructFilterOperator( ColumnTransformerVisitor.ColumnTransformerVisitorContext projectColumnTransformerContext = new ColumnTransformerVisitor.ColumnTransformerVisitorContext( + context.getDriverContext().getFragmentInstanceContext().getSessionInfo(), projectContext, expressionTypes, projectLeafColumnTransformerList, diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/AdditionResolver.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/AdditionResolver.java index c0b70691fb897..3f03fbfe6509c 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/AdditionResolver.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/AdditionResolver.java @@ -19,6 +19,7 @@ package org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic; +import org.apache.tsfile.enums.TSDataType; import org.apache.tsfile.read.common.type.Type; import java.util.Collections; @@ -39,6 +40,9 @@ public class AdditionResolver { private static final Map> CONDITION_MAP = new HashMap<>(); + private static final Map> CONDITION_MAP_TREE = + new HashMap<>(); + static { addCondition(INT32, INT32, INT32); addCondition(INT32, INT64, INT64); @@ -82,16 +86,70 @@ public class AdditionResolver { addCondition(UNKNOWN, DOUBLE, DOUBLE); addCondition(UNKNOWN, DATE, DATE); addCondition(UNKNOWN, TIMESTAMP, TIMESTAMP); + + addConditionTS(TSDataType.INT32, TSDataType.INT32, TSDataType.INT32); + addConditionTS(TSDataType.INT32, TSDataType.INT64, TSDataType.INT64); + addConditionTS(TSDataType.INT32, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.INT32, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.INT32, TSDataType.DATE, TSDataType.DATE); + addConditionTS(TSDataType.INT32, TSDataType.TIMESTAMP, TSDataType.TIMESTAMP); + addConditionTS(TSDataType.INT32, TSDataType.UNKNOWN, TSDataType.INT32); + + addConditionTS(TSDataType.INT64, TSDataType.INT32, TSDataType.INT64); + addConditionTS(TSDataType.INT64, TSDataType.INT64, TSDataType.INT64); + addConditionTS(TSDataType.INT64, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.INT64, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.INT64, TSDataType.DATE, TSDataType.DATE); + addConditionTS(TSDataType.INT64, TSDataType.TIMESTAMP, TSDataType.TIMESTAMP); + addConditionTS(TSDataType.INT64, TSDataType.UNKNOWN, TSDataType.INT64); + + addConditionTS(TSDataType.FLOAT, TSDataType.INT32, TSDataType.FLOAT); + addConditionTS(TSDataType.FLOAT, TSDataType.INT64, TSDataType.FLOAT); + addConditionTS(TSDataType.FLOAT, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.FLOAT, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.FLOAT, TSDataType.UNKNOWN, TSDataType.FLOAT); + + addConditionTS(TSDataType.DOUBLE, TSDataType.INT32, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.INT64, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.FLOAT, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.UNKNOWN, TSDataType.DOUBLE); + + addConditionTS(TSDataType.DATE, TSDataType.INT32, TSDataType.DATE); + addConditionTS(TSDataType.DATE, TSDataType.INT64, TSDataType.DATE); + addConditionTS(TSDataType.DATE, TSDataType.UNKNOWN, TSDataType.DATE); + + addConditionTS(TSDataType.TIMESTAMP, TSDataType.INT32, TSDataType.TIMESTAMP); + addConditionTS(TSDataType.TIMESTAMP, TSDataType.INT64, TSDataType.TIMESTAMP); + addConditionTS(TSDataType.TIMESTAMP, TSDataType.UNKNOWN, TSDataType.TIMESTAMP); + + addConditionTS(TSDataType.UNKNOWN, TSDataType.INT32, TSDataType.INT32); + addConditionTS(TSDataType.UNKNOWN, TSDataType.INT64, TSDataType.INT64); + addConditionTS(TSDataType.UNKNOWN, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.UNKNOWN, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.UNKNOWN, TSDataType.DATE, TSDataType.DATE); + addConditionTS(TSDataType.UNKNOWN, TSDataType.TIMESTAMP, TSDataType.TIMESTAMP); } private static void addCondition(Type condition1, Type condition2, Type result) { CONDITION_MAP.computeIfAbsent(condition1, k -> new HashMap<>()).put(condition2, result); } + private static void addConditionTS(TSDataType left, TSDataType right, TSDataType result) { + CONDITION_MAP_TREE.computeIfAbsent(left, k -> new HashMap<>()).put(right, result); + } + public static Optional checkConditions(List argumentTypes) { return Optional.ofNullable( CONDITION_MAP .getOrDefault(argumentTypes.get(0), Collections.emptyMap()) .getOrDefault(argumentTypes.get(1), null)); } + + public static Optional inferType(TSDataType leftType, TSDataType rightType) { + return Optional.ofNullable( + CONDITION_MAP_TREE + .getOrDefault(leftType, Collections.emptyMap()) + .getOrDefault(rightType, null)); + } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/DivisionResolver.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/DivisionResolver.java index b73ab852457f5..c02fbcce6bded 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/DivisionResolver.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/DivisionResolver.java @@ -19,6 +19,7 @@ package org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic; +import org.apache.tsfile.enums.TSDataType; import org.apache.tsfile.read.common.type.Type; import java.util.Collections; @@ -36,6 +37,8 @@ public class DivisionResolver { private static final Map> CONDITION_MAP = new HashMap<>(); + private static final Map> CONDITION_MAP_TREE = + new HashMap<>(); static { addCondition(INT32, INT32, INT32); @@ -66,16 +69,56 @@ public class DivisionResolver { addCondition(UNKNOWN, INT64, INT64); addCondition(UNKNOWN, FLOAT, FLOAT); addCondition(UNKNOWN, DOUBLE, DOUBLE); + + addConditionTS(TSDataType.INT32, TSDataType.INT32, TSDataType.INT32); + addConditionTS(TSDataType.INT32, TSDataType.INT64, TSDataType.INT64); + addConditionTS(TSDataType.INT32, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.INT32, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.INT32, TSDataType.UNKNOWN, TSDataType.INT32); + + addConditionTS(TSDataType.INT64, TSDataType.INT32, TSDataType.INT64); + addConditionTS(TSDataType.INT64, TSDataType.INT64, TSDataType.INT64); + addConditionTS(TSDataType.INT64, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.INT64, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.INT64, TSDataType.UNKNOWN, TSDataType.INT64); + + addConditionTS(TSDataType.FLOAT, TSDataType.INT32, TSDataType.FLOAT); + addConditionTS(TSDataType.FLOAT, TSDataType.INT64, TSDataType.FLOAT); + addConditionTS(TSDataType.FLOAT, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.FLOAT, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.FLOAT, TSDataType.UNKNOWN, TSDataType.FLOAT); + + addConditionTS(TSDataType.DOUBLE, TSDataType.INT32, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.INT64, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.FLOAT, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.UNKNOWN, TSDataType.DOUBLE); + + addConditionTS(TSDataType.UNKNOWN, TSDataType.INT32, TSDataType.INT32); + addConditionTS(TSDataType.UNKNOWN, TSDataType.INT64, TSDataType.INT64); + addConditionTS(TSDataType.UNKNOWN, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.UNKNOWN, TSDataType.DOUBLE, TSDataType.DOUBLE); } private static void addCondition(Type condition1, Type condition2, Type result) { CONDITION_MAP.computeIfAbsent(condition1, k -> new HashMap<>()).put(condition2, result); } + private static void addConditionTS(TSDataType left, TSDataType right, TSDataType result) { + CONDITION_MAP_TREE.computeIfAbsent(left, k -> new HashMap<>()).put(right, result); + } + public static Optional checkConditions(List argumentTypes) { return Optional.ofNullable( CONDITION_MAP .getOrDefault(argumentTypes.get(0), Collections.emptyMap()) .getOrDefault(argumentTypes.get(1), null)); } + + public static Optional inferType(TSDataType leftType, TSDataType rightType) { + return Optional.ofNullable( + CONDITION_MAP_TREE + .getOrDefault(leftType, Collections.emptyMap()) + .getOrDefault(rightType, null)); + } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/ModulusResolver.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/ModulusResolver.java index 1953381ac5a6a..8f0b2375f9784 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/ModulusResolver.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/ModulusResolver.java @@ -19,6 +19,7 @@ package org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic; +import org.apache.tsfile.enums.TSDataType; import org.apache.tsfile.read.common.type.Type; import java.util.Collections; @@ -36,6 +37,8 @@ public class ModulusResolver { private static final Map> CONDITION_MAP = new HashMap<>(); + private static final Map> CONDITION_MAP_TREE = + new HashMap<>(); static { addCondition(INT32, INT32, INT32); @@ -66,16 +69,56 @@ public class ModulusResolver { addCondition(UNKNOWN, INT64, INT64); addCondition(UNKNOWN, FLOAT, FLOAT); addCondition(UNKNOWN, DOUBLE, DOUBLE); + + addConditionTS(TSDataType.INT32, TSDataType.INT32, TSDataType.INT32); + addConditionTS(TSDataType.INT32, TSDataType.INT64, TSDataType.INT64); + addConditionTS(TSDataType.INT32, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.INT32, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.INT32, TSDataType.UNKNOWN, TSDataType.INT32); + + addConditionTS(TSDataType.INT64, TSDataType.INT32, TSDataType.INT64); + addConditionTS(TSDataType.INT64, TSDataType.INT64, TSDataType.INT64); + addConditionTS(TSDataType.INT64, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.INT64, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.INT64, TSDataType.UNKNOWN, TSDataType.INT64); + + addConditionTS(TSDataType.FLOAT, TSDataType.INT32, TSDataType.FLOAT); + addConditionTS(TSDataType.FLOAT, TSDataType.INT64, TSDataType.FLOAT); + addConditionTS(TSDataType.FLOAT, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.FLOAT, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.FLOAT, TSDataType.UNKNOWN, TSDataType.FLOAT); + + addConditionTS(TSDataType.DOUBLE, TSDataType.INT32, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.INT64, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.FLOAT, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.UNKNOWN, TSDataType.DOUBLE); + + addConditionTS(TSDataType.UNKNOWN, TSDataType.INT32, TSDataType.INT32); + addConditionTS(TSDataType.UNKNOWN, TSDataType.INT64, TSDataType.INT64); + addConditionTS(TSDataType.UNKNOWN, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.UNKNOWN, TSDataType.DOUBLE, TSDataType.DOUBLE); } private static void addCondition(Type condition1, Type condition2, Type result) { CONDITION_MAP.computeIfAbsent(condition1, k -> new HashMap<>()).put(condition2, result); } + private static void addConditionTS(TSDataType left, TSDataType right, TSDataType result) { + CONDITION_MAP_TREE.computeIfAbsent(left, k -> new HashMap<>()).put(right, result); + } + public static Optional checkConditions(List argumentTypes) { return Optional.ofNullable( CONDITION_MAP .getOrDefault(argumentTypes.get(0), Collections.emptyMap()) .getOrDefault(argumentTypes.get(1), null)); } + + public static Optional inferType(TSDataType leftType, TSDataType rightType) { + return Optional.ofNullable( + CONDITION_MAP_TREE + .getOrDefault(leftType, Collections.emptyMap()) + .getOrDefault(rightType, null)); + } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/MultiplicationResolver.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/MultiplicationResolver.java index f9ca05a2d8e84..a0cab6dd32ddd 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/MultiplicationResolver.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/MultiplicationResolver.java @@ -19,6 +19,7 @@ package org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic; +import org.apache.tsfile.enums.TSDataType; import org.apache.tsfile.read.common.type.Type; import java.util.Collections; @@ -36,6 +37,8 @@ public class MultiplicationResolver { private static final Map> CONDITION_MAP = new HashMap<>(); + private static final Map> CONDITION_MAP_TREE = + new HashMap<>(); static { addCondition(INT32, INT32, INT32); @@ -66,16 +69,56 @@ public class MultiplicationResolver { addCondition(UNKNOWN, INT64, INT64); addCondition(UNKNOWN, FLOAT, FLOAT); addCondition(UNKNOWN, DOUBLE, DOUBLE); + + addConditionTS(TSDataType.INT32, TSDataType.INT32, TSDataType.INT32); + addConditionTS(TSDataType.INT32, TSDataType.INT64, TSDataType.INT64); + addConditionTS(TSDataType.INT32, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.INT32, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.INT32, TSDataType.UNKNOWN, TSDataType.INT32); + + addConditionTS(TSDataType.INT64, TSDataType.INT32, TSDataType.INT64); + addConditionTS(TSDataType.INT64, TSDataType.INT64, TSDataType.INT64); + addConditionTS(TSDataType.INT64, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.INT64, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.INT64, TSDataType.UNKNOWN, TSDataType.INT64); + + addConditionTS(TSDataType.FLOAT, TSDataType.INT32, TSDataType.FLOAT); + addConditionTS(TSDataType.FLOAT, TSDataType.INT64, TSDataType.FLOAT); + addConditionTS(TSDataType.FLOAT, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.FLOAT, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.FLOAT, TSDataType.UNKNOWN, TSDataType.FLOAT); + + addConditionTS(TSDataType.DOUBLE, TSDataType.INT32, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.INT64, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.FLOAT, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.UNKNOWN, TSDataType.DOUBLE); + + addConditionTS(TSDataType.UNKNOWN, TSDataType.INT32, TSDataType.INT32); + addConditionTS(TSDataType.UNKNOWN, TSDataType.INT64, TSDataType.INT64); + addConditionTS(TSDataType.UNKNOWN, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.UNKNOWN, TSDataType.DOUBLE, TSDataType.DOUBLE); } private static void addCondition(Type condition1, Type condition2, Type result) { CONDITION_MAP.computeIfAbsent(condition1, k -> new HashMap<>()).put(condition2, result); } + private static void addConditionTS(TSDataType left, TSDataType right, TSDataType result) { + CONDITION_MAP_TREE.computeIfAbsent(left, k -> new HashMap<>()).put(right, result); + } + public static Optional checkConditions(List argumentTypes) { return Optional.ofNullable( CONDITION_MAP .getOrDefault(argumentTypes.get(0), Collections.emptyMap()) .getOrDefault(argumentTypes.get(1), null)); } + + public static Optional inferType(TSDataType leftType, TSDataType rightType) { + return Optional.ofNullable( + CONDITION_MAP_TREE + .getOrDefault(leftType, Collections.emptyMap()) + .getOrDefault(rightType, null)); + } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/SubtractionResolver.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/SubtractionResolver.java index a6b040168172d..00955d93731f2 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/SubtractionResolver.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/SubtractionResolver.java @@ -19,6 +19,7 @@ package org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic; +import org.apache.tsfile.enums.TSDataType; import org.apache.tsfile.read.common.type.Type; import java.util.Collections; @@ -39,6 +40,9 @@ public class SubtractionResolver { private static final Map> CONDITION_MAP = new HashMap<>(); + private static final Map> CONDITION_MAP_TREE = + new HashMap<>(); + static { addCondition(INT32, INT32, INT32); addCondition(INT32, INT64, INT64); @@ -74,16 +78,62 @@ public class SubtractionResolver { addCondition(UNKNOWN, INT64, INT64); addCondition(UNKNOWN, FLOAT, FLOAT); addCondition(UNKNOWN, DOUBLE, DOUBLE); + + addConditionTS(TSDataType.INT32, TSDataType.INT32, TSDataType.INT32); + addConditionTS(TSDataType.INT32, TSDataType.INT64, TSDataType.INT64); + addConditionTS(TSDataType.INT32, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.INT32, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.INT32, TSDataType.UNKNOWN, TSDataType.INT32); + + addConditionTS(TSDataType.INT64, TSDataType.INT32, TSDataType.INT64); + addConditionTS(TSDataType.INT64, TSDataType.INT64, TSDataType.INT64); + addConditionTS(TSDataType.INT64, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.INT64, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.INT64, TSDataType.UNKNOWN, TSDataType.INT64); + + addConditionTS(TSDataType.FLOAT, TSDataType.INT32, TSDataType.FLOAT); + addConditionTS(TSDataType.FLOAT, TSDataType.INT64, TSDataType.FLOAT); + addConditionTS(TSDataType.FLOAT, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.FLOAT, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.FLOAT, TSDataType.UNKNOWN, TSDataType.FLOAT); + + addConditionTS(TSDataType.DOUBLE, TSDataType.INT32, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.INT64, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.FLOAT, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.DOUBLE, TSDataType.DOUBLE); + addConditionTS(TSDataType.DOUBLE, TSDataType.UNKNOWN, TSDataType.DOUBLE); + + addConditionTS(TSDataType.DATE, TSDataType.INT32, TSDataType.DATE); + addConditionTS(TSDataType.DATE, TSDataType.INT64, TSDataType.DATE); + + addConditionTS(TSDataType.TIMESTAMP, TSDataType.INT32, TSDataType.TIMESTAMP); + addConditionTS(TSDataType.TIMESTAMP, TSDataType.INT64, TSDataType.TIMESTAMP); + + addConditionTS(TSDataType.UNKNOWN, TSDataType.INT32, TSDataType.INT32); + addConditionTS(TSDataType.UNKNOWN, TSDataType.INT64, TSDataType.INT64); + addConditionTS(TSDataType.UNKNOWN, TSDataType.FLOAT, TSDataType.FLOAT); + addConditionTS(TSDataType.UNKNOWN, TSDataType.DOUBLE, TSDataType.DOUBLE); } private static void addCondition(Type condition1, Type condition2, Type result) { CONDITION_MAP.computeIfAbsent(condition1, k -> new HashMap<>()).put(condition2, result); } + private static void addConditionTS(TSDataType left, TSDataType right, TSDataType result) { + CONDITION_MAP_TREE.computeIfAbsent(left, k -> new HashMap<>()).put(right, result); + } + public static Optional checkConditions(List argumentTypes) { return Optional.ofNullable( CONDITION_MAP .getOrDefault(argumentTypes.get(0), Collections.emptyMap()) .getOrDefault(argumentTypes.get(1), null)); } + + public static Optional inferType(TSDataType leftType, TSDataType rightType) { + return Optional.ofNullable( + CONDITION_MAP_TREE + .getOrDefault(leftType, Collections.emptyMap()) + .getOrDefault(rightType, null)); + } } From a026201bd4f46faf81e309914b7e9069fd8ee7ee Mon Sep 17 00:00:00 2001 From: Cool6689 <3322351820@qq.com> Date: Sat, 22 Nov 2025 01:57:13 +0800 Subject: [PATCH 2/4] Rewriting tree model mathematical operators --- .../iotdb/db/it/query/IoTDBArithmeticIT.java | 83 +++++-------------- 1 file changed, 23 insertions(+), 60 deletions(-) diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBArithmeticIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBArithmeticIT.java index 36acc6a9bea3a..8cbd0ac9d7d02 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBArithmeticIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBArithmeticIT.java @@ -37,6 +37,7 @@ import java.util.ArrayList; import java.util.List; +import static org.apache.iotdb.db.it.utils.TestUtils.assertTestFail; import static org.apache.iotdb.db.it.utils.TestUtils.prepareData; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -178,17 +179,9 @@ public void testTimestampNegation() { @Test public void testUnaryWrongType() { - try (Connection connection = EnvFactory.getEnv().getConnection(); - Statement statement = connection.createStatement()) { - tsAssertTestFail( - statement, "select -s5 from root.sg.d1", "Invalid input expression data type"); - tsAssertTestFail( - statement, "select -s6 from root.sg.d1", "Invalid input expression data type"); - tsAssertTestFail( - statement, "select -s9 from root.sg.d1", "Invalid input expression data type"); - } catch (SQLException throwable) { - fail(throwable.getMessage()); - } + assertTestFail("select -s5 from root.sg.d1", "Invalid input expression data type"); + assertTestFail("select -s6 from root.sg.d1", "Invalid input expression data type"); + assertTestFail("select -s9 from root.sg.d1", "Invalid input expression data type"); } @Test @@ -312,15 +305,10 @@ public void testDateAndTimestampArithmetic() { @Test public void testDivisionByZero() { - try (Connection connection = EnvFactory.getEnv().getConnection(); - Statement statement = connection.createStatement()) { - tsAssertTestFail(statement, "select s1/0 from root.sg.d1", "Division by zero"); - tsAssertTestFail(statement, "select s2/0 from root.sg.d1", "Division by zero"); - tsAssertTestFail(statement, "select s1%0 from root.sg.d1", "Division by zero"); - tsAssertTestFail(statement, "select s2%0 from root.sg.d1", "Division by zero"); - } catch (SQLException throwable) { - fail(throwable.getMessage()); - } + assertTestFail("select s1/0 from root.sg.d1", "Division by zero"); + assertTestFail("select s2/0 from root.sg.d1", "Division by zero"); + assertTestFail("select s1%0 from root.sg.d1", "Division by zero"); + assertTestFail("select s2%0 from root.sg.d1", "Division by zero"); } @Test @@ -365,17 +353,12 @@ public void testDoubleModuloByZero() { @Test public void testBinaryWrongType() { - try (Connection connection = EnvFactory.getEnv().getConnection(); - Statement statement = connection.createStatement()) { - tsAssertTestFail(statement, "select s9 * s1 from root.sg.d1", "Invalid"); - tsAssertTestFail(statement, "select s9 / s1 from root.sg.d1", "Invalid"); - tsAssertTestFail(statement, "select s9 % s1 from root.sg.d1", "Invalid"); - tsAssertTestFail(statement, "select s10 * s1 from root.sg.d1", "Invalid"); - tsAssertTestFail(statement, "select s10 / s1 from root.sg.d1", "Invalid"); - tsAssertTestFail(statement, "select s10 % s1 from root.sg.d1", "Invalid"); - } catch (SQLException throwable) { - fail(throwable.getMessage()); - } + assertTestFail("select s9 * s1 from root.sg.d1", "Invalid"); + assertTestFail("select s9 / s1 from root.sg.d1", "Invalid"); + assertTestFail("select s9 % s1 from root.sg.d1", "Invalid"); + assertTestFail("select s10 * s1 from root.sg.d1", "Invalid"); + assertTestFail("select s10 / s1 from root.sg.d1", "Invalid"); + assertTestFail("select s10 % s1 from root.sg.d1", "Invalid"); } @Test @@ -414,24 +397,17 @@ public void testOverflow() { Integer.MIN_VALUE / 2 - 1, Integer.MAX_VALUE / 2 + 1)); - tsAssertTestFail( - statement, "select s1+s7 from root.sg.d2 where time=1", "int Addition overflow"); - tsAssertTestFail( - statement, "select s1-s8 from root.sg.d2 where time=2", "int Subtraction overflow"); - tsAssertTestFail( - statement, "select s1*s7 from root.sg.d2 where time=1", "int Multiplication overflow"); + assertTestFail("select s1+s7 from root.sg.d2 where time=1", "int Addition overflow"); + assertTestFail("select s1-s8 from root.sg.d2 where time=2", "int Subtraction overflow"); + assertTestFail("select s1*s7 from root.sg.d2 where time=1", "int Multiplication overflow"); - tsAssertTestFail( - statement, "select s2+s2 from root.sg.d2 where time=1", "long Addition overflow"); - tsAssertTestFail( - statement, "select s3-s2 from root.sg.d2 where time=1", "long Subtraction overflow"); + assertTestFail("select s2+s2 from root.sg.d2 where time=1", "long Addition overflow"); + assertTestFail("select s3-s2 from root.sg.d2 where time=1", "long Subtraction overflow"); - tsAssertTestFail( - statement, + assertTestFail( String.format("select s10+%d from root.sg.d2 where time=1", Long.MAX_VALUE), "long Addition overflow"); - tsAssertTestFail( - statement, + assertTestFail( String.format("select s10-(%d) from root.sg.d2 where time=1", Long.MIN_VALUE), "long Subtraction overflow"); @@ -448,27 +424,14 @@ public void testDateOutOfRange() { statement.execute("insert into root.sg.d3(time, date) values (1, '9999-12-31')"); statement.execute("insert into root.sg.d3(time, date) values (2, '1000-01-01')"); - tsAssertTestFail( - statement, + assertTestFail( "select date + 86400000 from root.sg.d3 where time = 1", "Year must be between 1000 and 9999"); - tsAssertTestFail( - statement, + assertTestFail( "select date - 86400000 from root.sg.d3 where time = 2", "Year must be between 1000 and 9999"); } catch (SQLException throwable) { fail(throwable.getMessage()); } } - - private void tsAssertTestFail(Statement statement, String sql, String expectedErrorMsg) { - try { - statement.executeQuery(sql); - fail("Expected exception with message: " + expectedErrorMsg); - } catch (SQLException e) { - assertTrue( - "Expected error message '" + expectedErrorMsg + "' but got: " + e.getMessage(), - e.getMessage().contains(expectedErrorMsg)); - } - } } From 328b3d701e6e11f1c57510ec9f585ea980b2d54f Mon Sep 17 00:00:00 2001 From: Cool6689 <3322351820@qq.com> Date: Wed, 3 Dec 2025 22:52:23 +0800 Subject: [PATCH 3/4] Refactor arithmetic operation tests to use integer types instead of doubles --- .../org/apache/iotdb/db/it/IoTDBFilterIT.java | 4 +- .../iotdb/db/it/IoTDBNestedQueryIT.java | 20 ++-- .../db/it/aggregation/maxby/IoTDBMaxByIT.java | 6 +- .../db/it/aggregation/minby/IoTDBMinByIT.java | 6 +- ...lignByDeviceWithTemplateAggregationIT.java | 16 +-- .../it/aligned/IoTDBPredicatePushDownIT.java | 98 +++++++++---------- .../db/it/query/IoTDBCaseWhenThenIT.java | 16 +-- .../iotdb/db/it/udaf/IoTDBUDAFMiscIT.java | 2 +- .../db/it/udf/IoTDBUDFWindowQueryIT.java | 8 +- .../db/it/udf/IoTDBUDTFHybridQueryIT.java | 10 +- .../IoTDBWithoutNullAllFilterIT.java | 48 ++++----- .../IoTDBWithoutNullAnyFilterIT.java | 48 ++++----- .../function/arithmetic/AdditionResolver.java | 52 ++-------- .../function/arithmetic/DivisionResolver.java | 38 ++----- .../function/arithmetic/ModulusResolver.java | 38 ++----- .../arithmetic/MultiplicationResolver.java | 38 ++----- .../arithmetic/SubtractionResolver.java | 44 ++------- .../queryengine/plan/analyze/AnalyzeTest.java | 10 +- 18 files changed, 196 insertions(+), 306 deletions(-) diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBFilterIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBFilterIT.java index b8dd88ea9d715..b9d72d7e903a5 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBFilterIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBFilterIT.java @@ -203,13 +203,13 @@ public void testMismatchedDataTypes() { "The output type of the expression in WHERE clause should be BOOLEAN, actual data type: DOUBLE."); assertTestFail( "select count(s1) from root.sg1.d1 group by ([0, 40), 5ms) having count(s1) + 1;", - "The output type of the expression in HAVING clause should be BOOLEAN, actual data type: DOUBLE."); + "The output type of the expression in HAVING clause should be BOOLEAN, actual data type: INT64."); assertTestFail( "select s1 from root.sg1.d1 where s1 align by device;", "The output type of the expression in WHERE clause should be BOOLEAN, actual data type: DOUBLE."); assertTestFail( "select count(s1) from root.sg1.d1 group by ([0, 40), 5ms) having count(s1) + 1 align by device;", - "The output type of the expression in HAVING clause should be BOOLEAN, actual data type: DOUBLE."); + "The output type of the expression in HAVING clause should be BOOLEAN, actual data type: INT64."); } @Test diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBNestedQueryIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBNestedQueryIT.java index 24df10c1ba97a..d9b214078c860 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBNestedQueryIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBNestedQueryIT.java @@ -496,10 +496,10 @@ public void testDistributiveLaw() { Assert.assertTrue(rs.next()); Assert.assertEquals(i, rs.getLong(1)); Assert.assertEquals(i, rs.getInt(2)); - Assert.assertEquals(2 * i + 2.0D, rs.getDouble(3), 0.01); - Assert.assertEquals(2 * i + 2.0D, rs.getDouble(4), 0.01); - Assert.assertEquals(i / 2.0D + 0.5D, rs.getDouble(5), 0.01); - Assert.assertEquals((i / 2) + 1 / 2, rs.getDouble(6), 0.01); + Assert.assertEquals((i + 1) * 2, rs.getLong(3)); + Assert.assertEquals(i * 2 + 1 * 2, rs.getLong(4)); + Assert.assertEquals((i + 1) / 2, rs.getLong(5)); + Assert.assertEquals(i / 2 + 1 / 2, rs.getLong(6)); } Assert.assertFalse(rs.next()); } @@ -524,9 +524,9 @@ public void testOrderOfArithmeticOperations() { for (int i = 1; i <= ITERATION_TIMES; i++) { Assert.assertTrue(rs.next()); Assert.assertEquals(i, rs.getLong(1)); - Assert.assertEquals(2 * i + 2.0D, rs.getDouble(2), 0.01); - Assert.assertEquals(2 * i + 3.0D, rs.getDouble(3), 0.01); - Assert.assertEquals(3 * i + 3.0D, rs.getDouble(4), 0.01); + Assert.assertEquals(1 + i * 2 + 1, rs.getLong(2)); + Assert.assertEquals((1 + i) * 2 + 1, rs.getLong(3)); + Assert.assertEquals((1 + i) * (2 + 1), rs.getLong(4)); } Assert.assertFalse(rs.next()); } @@ -536,9 +536,9 @@ public void testOrderOfArithmeticOperations() { for (int i = 1; i <= ITERATION_TIMES; i++) { Assert.assertTrue(rs.next()); Assert.assertEquals(i, rs.getLong(1)); - Assert.assertEquals(1.0D - i / 2 + 1, rs.getDouble(2), 0.01); - Assert.assertEquals(1.5 - i / 2.0D, rs.getDouble(3), 0.01); - Assert.assertEquals((1.0D / 3.0D) * (1.0D - i), rs.getDouble(4), 0.01); + Assert.assertEquals(1 - i / 2 + 1, rs.getLong(2)); + Assert.assertEquals((1 - i) / 2 + 1, rs.getLong(3)); + Assert.assertEquals((1 - i) / (2 + 1), rs.getLong(4)); } Assert.assertFalse(rs.next()); } diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/maxby/IoTDBMaxByIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/maxby/IoTDBMaxByIT.java index 540c8bc66719e..9675ab783cc47 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/maxby/IoTDBMaxByIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/maxby/IoTDBMaxByIT.java @@ -301,7 +301,7 @@ public void testMaxByWithExpression() { "max_by(root.db.d1.x5, -cos(sin(root.db.d1.y2 / 10)))", "max_by(REPLACE(root.db.d1.x6, '3', '4'), -cos(sin(root.db.d1.y2 / 10)))", }; - String[] retArray = new String[] {"0.0,1.3333333333333333,2.0,2.0,false,2,"}; + String[] retArray = new String[] {"0,1.3333333333333333,2.0,2.0,false,2,"}; String y = "-cos(sin(y2 / 10))"; resultSetEqualTest( String.format( @@ -331,8 +331,8 @@ public void testMaxByWithAlignByDevice() { }; String[] retArray = new String[] { - "root.db.d1,0.0,1.3333333333333333,2.0,2.0,false,2,", - "root.db.d2,0.0,1.3333333333333333,2.0,2.0,false,2," + "root.db.d1,0,1.3333333333333333,2.0,2.0,false,2,", + "root.db.d2,0,1.3333333333333333,2.0,2.0,false,2," }; String y = "-cos(sin(y2 / 10))"; resultSetEqualTest( diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/minby/IoTDBMinByIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/minby/IoTDBMinByIT.java index 2d8bb1db5c86a..4ce985fe11daf 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/minby/IoTDBMinByIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/minby/IoTDBMinByIT.java @@ -300,7 +300,7 @@ public void testMaxByWithExpression() { "min_by(root.db.d1.x5, -cos(sin(root.db.d1.y2 / 10)))", "min_by(REPLACE(root.db.d1.x6, '3', '4'), -cos(sin(root.db.d1.y2 / 10)))", }; - String[] retArray = new String[] {"0.0,1.3333333333333333,2.0,2.0,false,2,"}; + String[] retArray = new String[] {"0,1.3333333333333333,2.0,2.0,false,2,"}; String y = "-cos(sin(y2 / 10))"; resultSetEqualTest( String.format( @@ -330,8 +330,8 @@ public void testMaxByWithAlignByDevice() { }; String[] retArray = new String[] { - "root.db.d1,0.0,1.3333333333333333,2.0,2.0,false,2,", - "root.db.d2,0.0,1.3333333333333333,2.0,2.0,false,2," + "root.db.d1,0,1.3333333333333333,2.0,2.0,false,2,", + "root.db.d2,0,1.3333333333333333,2.0,2.0,false,2," }; String y = "-cos(sin(y2 / 10))"; resultSetEqualTest( diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/alignbydevice/IoTDBAlignByDeviceWithTemplateAggregationIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/alignbydevice/IoTDBAlignByDeviceWithTemplateAggregationIT.java index 38f2a9616464b..1b7b1bf339747 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/alignbydevice/IoTDBAlignByDeviceWithTemplateAggregationIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/alignbydevice/IoTDBAlignByDeviceWithTemplateAggregationIT.java @@ -217,9 +217,9 @@ public void filterTest() { new String[] {"Device,max_time(s1),count(s1),last_value(s2),count(s1) + last_value(s3)"}; retArray = new String[] { - "root.sg1.d2,1314000000001,4,false,1319.0,", - "root.sg1.d3,1314000000002,2,false,1318.0,", - "root.sg1.d4,5,1,false,5556.0,", + "root.sg1.d2,1314000000001,4,false,1319,", + "root.sg1.d3,1314000000002,2,false,1318,", + "root.sg1.d4,5,1,false,5556,", }; resultSetEqualTest( "SELECT max_time(s1), count(s1), last_value(s2), count(s1)+last_value(s3) FROM root.sg1.** where s3+1=1316 or s2=false having avg(s1)+sum(s3)>5 align by device;", @@ -227,9 +227,9 @@ public void filterTest() { retArray); retArray = new String[] { - "root.sg2.d2,1314000000001,4,false,1319.0,", - "root.sg2.d3,1314000000002,2,false,1318.0,", - "root.sg2.d4,5,1,false,5556.0,", + "root.sg2.d2,1314000000001,4,false,1319,", + "root.sg2.d3,1314000000002,2,false,1318,", + "root.sg2.d4,5,1,false,5556,", }; resultSetEqualTest( "SELECT max_time(s1), count(s1), last_value(s2), count(s1)+last_value(s3) FROM root.sg2.** where s3+1=1316 or s2=false having avg(s1)+sum(s3)>5 align by device;", @@ -650,7 +650,7 @@ public void wildCardTest() { expectedHeader = new String[] {"Device,count(s3) + 1,count(s1) + 1,count(s2) + 1"}; retArray = new String[] { - "root.sg1.d2,5.0,5.0,5.0,", + "root.sg1.d2,5,5,5,", }; resultSetEqualTest( "SELECT count(*)+1 FROM root.sg1.** where s2=false having count(s3+s1) > 2 align by device;", @@ -658,7 +658,7 @@ public void wildCardTest() { retArray); retArray = new String[] { - "root.sg2.d2,5.0,5.0,5.0,", + "root.sg2.d2,5,5,5,", }; resultSetEqualTest( "SELECT count(*)+1 FROM root.sg2.** where s2=false having count(s3+s1) > 2 align by device;", diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/aligned/IoTDBPredicatePushDownIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/aligned/IoTDBPredicatePushDownIT.java index f9639d3ea2d2c..3329024391aa5 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/aligned/IoTDBPredicatePushDownIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/aligned/IoTDBPredicatePushDownIT.java @@ -114,23 +114,23 @@ public void testAlignedRawDataAlignByTime2() { String expectedHeader1 = "Time,root.sg1.d1.s2,root.sg1.d1.s3 + 1,"; String[] retArray1 = new String[] { - "3,null,30001.0,", - "13,130000,130001.0,", - "16,16,17.0,", - "17,17,18.0,", - "18,18,19.0,", - "19,19,20.0,", - "20,20,21.0,", - "21,null,22.0,", - "22,null,23.0,", - "23,null,230001.0,", - "24,null,25.0,", - "25,null,26.0,", - "26,null,27.0,", - "27,null,28.0,", - "28,null,29.0,", - "29,null,30.0,", - "30,null,31.0,", + "3,null,30001,", + "13,130000,130001,", + "16,16,17,", + "17,17,18,", + "18,18,19,", + "19,19,20,", + "20,20,21,", + "21,null,22,", + "22,null,23,", + "23,null,230001,", + "24,null,25,", + "25,null,26,", + "26,null,27,", + "27,null,28,", + "28,null,29,", + "29,null,30,", + "30,null,31,", }; resultSetEqualTest( "select s2, s3 + 1 from root.sg1.d1 where s3 + 1 > 16", expectedHeader1, retArray1); @@ -536,38 +536,38 @@ public void testRawDataAlignByDevice2() { String expectedHeader = "Time,Device,s2,s3 + 1,"; String[] retArray = new String[] { - "3,root.sg1.d1,null,30001.0,", - "13,root.sg1.d1,130000,130001.0,", - "16,root.sg1.d1,16,17.0,", - "17,root.sg1.d1,17,18.0,", - "18,root.sg1.d1,18,19.0,", - "19,root.sg1.d1,19,20.0,", - "20,root.sg1.d1,20,21.0,", - "21,root.sg1.d1,null,22.0,", - "22,root.sg1.d1,null,23.0,", - "23,root.sg1.d1,null,230001.0,", - "24,root.sg1.d1,null,25.0,", - "25,root.sg1.d1,null,26.0,", - "26,root.sg1.d1,null,27.0,", - "27,root.sg1.d1,null,28.0,", - "28,root.sg1.d1,null,29.0,", - "29,root.sg1.d1,null,30.0,", - "30,root.sg1.d1,null,31.0,", - "16,root.sg1.d2,16,17.0,", - "17,root.sg1.d2,17,18.0,", - "18,root.sg1.d2,18,19.0,", - "19,root.sg1.d2,19,20.0,", - "20,root.sg1.d2,20,21.0,", - "21,root.sg1.d2,null,22.0,", - "22,root.sg1.d2,null,23.0,", - "23,root.sg1.d2,null,24.0,", - "24,root.sg1.d2,null,25.0,", - "25,root.sg1.d2,null,26.0,", - "26,root.sg1.d2,null,27.0,", - "27,root.sg1.d2,null,28.0,", - "28,root.sg1.d2,null,29.0,", - "29,root.sg1.d2,null,30.0,", - "30,root.sg1.d2,null,31.0,", + "3,root.sg1.d1,null,30001,", + "13,root.sg1.d1,130000,130001,", + "16,root.sg1.d1,16,17,", + "17,root.sg1.d1,17,18,", + "18,root.sg1.d1,18,19,", + "19,root.sg1.d1,19,20,", + "20,root.sg1.d1,20,21,", + "21,root.sg1.d1,null,22,", + "22,root.sg1.d1,null,23,", + "23,root.sg1.d1,null,230001,", + "24,root.sg1.d1,null,25,", + "25,root.sg1.d1,null,26,", + "26,root.sg1.d1,null,27,", + "27,root.sg1.d1,null,28,", + "28,root.sg1.d1,null,29,", + "29,root.sg1.d1,null,30,", + "30,root.sg1.d1,null,31,", + "16,root.sg1.d2,16,17,", + "17,root.sg1.d2,17,18,", + "18,root.sg1.d2,18,19,", + "19,root.sg1.d2,19,20,", + "20,root.sg1.d2,20,21,", + "21,root.sg1.d2,null,22,", + "22,root.sg1.d2,null,23,", + "23,root.sg1.d2,null,24,", + "24,root.sg1.d2,null,25,", + "25,root.sg1.d2,null,26,", + "26,root.sg1.d2,null,27,", + "27,root.sg1.d2,null,28,", + "28,root.sg1.d2,null,29,", + "29,root.sg1.d2,null,30,", + "30,root.sg1.d2,null,31,", }; resultSetEqualTest( "select s2, s3 + 1 from root.sg1.d1, root.sg1.d2 where s3 + 1 > 16 align by device", diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBCaseWhenThenIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBCaseWhenThenIT.java index a88b89e90b5da..cfbbf40f7f216 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBCaseWhenThenIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBCaseWhenThenIT.java @@ -154,7 +154,7 @@ public void testKind1InputTypeRestrict() { // WHEN clause must return BOOLEAN String sql = "select case when s1+1 then 20 else 22 end from root.sg.d1"; String msg = - "701: The expression in the WHEN clause must return BOOLEAN. expression: root.sg.d1.s1 + 1, actual data type: DOUBLE."; + "701: The expression in the WHEN clause must return BOOLEAN. expression: root.sg.d1.s1 + 1, actual data type: INT64."; assertTestFail(sql, msg); } @@ -493,8 +493,8 @@ public void testKind1UseOtherOperation() { new String[] { "0,root.sg.d1,null,", "1000000,root.sg.d1,11.0,", - "20000000,root.sg.d1,21.0,", - "210000000,root.sg.d1,32.0,", + "20000000,root.sg.d1,21,", + "210000000,root.sg.d1,32,", }; resultSetEqualTest(sql, expectHeader, retArray); @@ -543,10 +543,10 @@ public void testKind2UseOtherOperation() { }; retArray = new String[] { - "0,root.sg.d1,-1.0,", + "0,root.sg.d1,-1,", "1000000,root.sg.d1,11.0,", - "20000000,root.sg.d1,21.0,", - "210000000,root.sg.d1,32.0,", + "20000000,root.sg.d1,21,", + "210000000,root.sg.d1,32,", }; resultSetEqualTest(sql, expectHeader, retArray); @@ -734,7 +734,7 @@ public void testKind1MultipleTimeseries() { }; String[] retArray = new String[] { - "0,0.0,0.0,", "1000000,121.0,11.0,", "20000000,484.0,66.0,", "210000000,1089.0,77.0,", + "0,0,0.0,", "1000000,121,11.0,", "20000000,484,66.0,", "210000000,1089,77.0,", }; resultSetEqualTest(sql, expectedHeader, retArray); @@ -773,7 +773,7 @@ public void testKind2MultipleTimeseries() { }; String[] retArray = new String[] { - "0,0.0,44.0,", "1000000,121.0,11.0,", "20000000,484.0,66.0,", "210000000,1089.0,77.0,", + "0,0,44.0,", "1000000,121,11.0,", "20000000,484,66.0,", "210000000,1089,77.0,", }; resultSetEqualTest(sql, expectedHeader, retArray); diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/udaf/IoTDBUDAFMiscIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/udaf/IoTDBUDAFMiscIT.java index fc4bbf588157a..3f2fbe58aa903 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/udaf/IoTDBUDAFMiscIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/udaf/IoTDBUDAFMiscIT.java @@ -106,7 +106,7 @@ public void mixUDAFAndUDTFTest() throws Exception { @Test public void UDAFAsOperandTest() throws Exception { - String[] expected = new String[] {"6.0"}; + String[] expected = new String[] {"6"}; try (Connection connection = EnvFactory.getEnv().getConnection(); Statement statement = connection.createStatement()) { diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDFWindowQueryIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDFWindowQueryIT.java index c543d4e6bd10a..03956afb9e0f4 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDFWindowQueryIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDFWindowQueryIT.java @@ -735,7 +735,7 @@ public void testSizeWindowUDFWithConstants() { Statement statement = connection.createStatement()) { String query = - "SELECT accumulator(s1 + 1, 'access'='size', 'windowSize'='1000') FROM root.vehicle.d1"; + "SELECT accumulator(s1 + 1.0, 'access'='size', 'windowSize'='1000') FROM root.vehicle.d1"; try (ResultSet rs = statement.executeQuery(query)) { int time = 0; int value = 500500; @@ -750,7 +750,7 @@ public void testSizeWindowUDFWithConstants() { } query = - "SELECT 1 + accumulator(s1 + 1, 'access'='size', 'windowSize'='1000') FROM root.vehicle.d1"; + "SELECT 1 + accumulator(s1 + 1.0, 'access'='size', 'windowSize'='1000') FROM root.vehicle.d1"; try (ResultSet rs = statement.executeQuery(query)) { int time = 0; double value = 500501D; @@ -775,7 +775,7 @@ public void testTimeWindowUDFWithConstants() { Statement statement = connection.createStatement()) { String query = "SELECT accumulator(" - + "s1 + 1, " + + "s1 + 1.0, " + "'access'='time', " + "'timeInterval'='1000', " + "'slidingStep'='1000', " @@ -796,7 +796,7 @@ public void testTimeWindowUDFWithConstants() { query = "SELECT 1 + accumulator(" - + "s1 + 1, " + + "s1 + 1.0, " + "'access'='time', " + "'timeInterval'='1000', " + "'slidingStep'='1000', " diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDTFHybridQueryIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDTFHybridQueryIT.java index 93e7a09bb51af..cbcbec61df51b 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDTFHybridQueryIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDTFHybridQueryIT.java @@ -159,11 +159,11 @@ public void testUserDefinedBuiltInHybridAggregationQuery2() { public void testUserDefinedFunctionFillFunctionHybridQuery() { String[] retArray = new String[] { - "0,0.0,1.0,3.14", - "1,0.8414709848078965,2.0,3.14", - "2,0.9092974268256817,3.0,2.0", - "3,0.1411200080598672,4.0,3.0", - "4,-0.7568024953079282,5.0,3.14", + "0,0.0,1,3.14", + "1,0.8414709848078965,2,3.14", + "2,0.9092974268256817,3,2.0", + "3,0.1411200080598672,4,3.0", + "4,-0.7568024953079282,5,3.14", "7,3.14,3.14,7.0", "8,3.14,3.14,8.0", "9,3.14,3.14,9.0" diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/withoutNull/IoTDBWithoutNullAllFilterIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/withoutNull/IoTDBWithoutNullAllFilterIT.java index a5506836764f1..58f9d30d994e3 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/withoutNull/IoTDBWithoutNullAllFilterIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/withoutNull/IoTDBWithoutNullAllFilterIT.java @@ -391,42 +391,42 @@ public void withExpressionQueryTest() { System.out.println("withExpressionQueryTest"); String[] retArray1 = new String[] { - "1,1,-1,1,1,2.0,0.0,1.0,1,0", - "2,2,-2,2,2,4.0,0.0,4.0,1,0", - "5,5,-5,5,5,10.0,0.0,25.0,1,0", - "6,6,-6,6,6,12.0,0.0,36.0,1,0", - "9,9,-9,9,9,18.0,0.0,81.0,1,0", - "10,10,-10,10,10,20.0,0.0,100.0,1,0" + "1,1,-1,1,1,2,0,1,1,0", + "2,2,-2,2,2,4,0,4,1,0", + "5,5,-5,5,5,10,0,25,1,0", + "6,6,-6,6,6,12,0,36,1,0", + "9,9,-9,9,9,18,0,81,1,0", + "10,10,-10,10,10,20,0,100,1,0" }; String[] retArray2 = new String[] { - "1,1,-1,1,1,2.0,0.0,1.0,1,0", - "2,2,-2,2,2,4.0,0.0,4.0,1,0", - "5,5,-5,5,5,10.0,0.0,25.0,1,0", - "6,6,-6,6,6,12.0,0.0,36.0,1,0", + "1,1,-1,1,1,2,0,1,1,0", + "2,2,-2,2,2,4,0,4,1,0", + "5,5,-5,5,5,10,0,25,1,0", + "6,6,-6,6,6,12,0,36,1,0", "8,8,-8,null,null,null,null,null,null,null", - "9,9,-9,9,9,18.0,0.0,81.0,1,0", - "10,10,-10,10,10,20.0,0.0,100.0,1,0" + "9,9,-9,9,9,18,0,81,1,0", + "10,10,-10,10,10,20,0,100,1,0" }; String[] retArray3 = new String[] { - "1,1,-1,1,1,2.0,0.0,1.0,1,0", - "2,2,-2,2,2,4.0,0.0,4.0,1,0", - "5,5,-5,5,5,10.0,0.0,25.0,1,0", - "6,6,-6,6,6,12.0,0.0,36.0,1,0", + "1,1,-1,1,1,2,0,1,1,0", + "2,2,-2,2,2,4,0,4,1,0", + "5,5,-5,5,5,10,0,25,1,0", + "6,6,-6,6,6,12,0,36,1,0", "8,8,-8,null,null,null,null,null,null,null", - "9,9,-9,9,9,18.0,0.0,81.0,1,0", - "10,10,-10,10,10,20.0,0.0,100.0,1,0" + "9,9,-9,9,9,18,0,81,1,0", + "10,10,-10,10,10,20,0,100,1,0" }; String[] retArray4 = new String[] { - "1,1,-1,1,1,2.0,0.0,1.0,1,0", - "2,2,-2,2,2,4.0,0.0,4.0,1,0", - "5,5,-5,5,5,10.0,0.0,25.0,1,0", - "6,6,-6,6,6,12.0,0.0,36.0,1,0", + "1,1,-1,1,1,2,0,1,1,0", + "2,2,-2,2,2,4,0,4,1,0", + "5,5,-5,5,5,10,0,25,1,0", + "6,6,-6,6,6,12,0,36,1,0", "8,8,-8,null,null,null,null,null,null,null", - "9,9,-9,9,9,18.0,0.0,81.0,1,0", - "10,10,-10,10,10,20.0,0.0,100.0,1,0" + "9,9,-9,9,9,18,0,81,1,0", + "10,10,-10,10,10,20,0,100,1,0" }; try (Connection connection = EnvFactory.getEnv().getConnection(); Statement statement = connection.createStatement()) { diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/withoutNull/IoTDBWithoutNullAnyFilterIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/withoutNull/IoTDBWithoutNullAnyFilterIT.java index 6d307dc96d855..f55b7b68433e9 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/withoutNull/IoTDBWithoutNullAnyFilterIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/withoutNull/IoTDBWithoutNullAnyFilterIT.java @@ -356,39 +356,39 @@ public void withExpressionQueryTest() { System.out.println("withExpressionQueryTest"); String[] retArray1 = new String[] { - "1,1,-1,1,1,2.0,0.0,1.0,1,0", - "2,2,-2,2,2,4.0,0.0,4.0,1,0", - "5,5,-5,5,5,10.0,0.0,25.0,1,0", - "6,6,-6,6,6,12.0,0.0,36.0,1,0", - "9,9,-9,9,9,18.0,0.0,81.0,1,0", - "10,10,-10,10,10,20.0,0.0,100.0,1,0" + "1,1,-1,1,1,2,0,1,1,0", + "2,2,-2,2,2,4,0,4,1,0", + "5,5,-5,5,5,10,0,25,1,0", + "6,6,-6,6,6,12,0,36,1,0", + "9,9,-9,9,9,18,0,81,1,0", + "10,10,-10,10,10,20,0,100,1,0" }; String[] retArray2 = new String[] { - "1,1,-1,1,1,2.0,0.0,1.0,1,0", - "2,2,-2,2,2,4.0,0.0,4.0,1,0", - "5,5,-5,5,5,10.0,0.0,25.0,1,0", - "6,6,-6,6,6,12.0,0.0,36.0,1,0", - "9,9,-9,9,9,18.0,0.0,81.0,1,0", - "10,10,-10,10,10,20.0,0.0,100.0,1,0" + "1,1,-1,1,1,2,0,1,1,0", + "2,2,-2,2,2,4,0,4,1,0", + "5,5,-5,5,5,10,0,25,1,0", + "6,6,-6,6,6,12,0,36,1,0", + "9,9,-9,9,9,18,0,81,1,0", + "10,10,-10,10,10,20,0,100,1,0" }; String[] retArray3 = new String[] { - "1,1,-1,1,1,2.0,0.0,1.0,1,0", - "2,2,-2,2,2,4.0,0.0,4.0,1,0", - "5,5,-5,5,5,10.0,0.0,25.0,1,0", - "6,6,-6,6,6,12.0,0.0,36.0,1,0", - "9,9,-9,9,9,18.0,0.0,81.0,1,0", - "10,10,-10,10,10,20.0,0.0,100.0,1,0" + "1,1,-1,1,1,2,0,1,1,0", + "2,2,-2,2,2,4,0,4,1,0", + "5,5,-5,5,5,10,0,25,1,0", + "6,6,-6,6,6,12,0,36,1,0", + "9,9,-9,9,9,18,0,81,1,0", + "10,10,-10,10,10,20,0,100,1,0" }; String[] retArray4 = new String[] { - "1,1,-1,1,1,2.0,0.0,1.0,1,0", - "2,2,-2,2,2,4.0,0.0,4.0,1,0", - "5,5,-5,5,5,10.0,0.0,25.0,1,0", - "6,6,-6,6,6,12.0,0.0,36.0,1,0", - "9,9,-9,9,9,18.0,0.0,81.0,1,0", - "10,10,-10,10,10,20.0,0.0,100.0,1,0" + "1,1,-1,1,1,2,0,1,1,0", + "2,2,-2,2,2,4,0,4,1,0", + "5,5,-5,5,5,10,0,25,1,0", + "6,6,-6,6,6,12,0,36,1,0", + "9,9,-9,9,9,18,0,81,1,0", + "10,10,-10,10,10,20,0,100,1,0" }; try (Connection connection = EnvFactory.getEnv().getConnection(); Statement statement = connection.createStatement()) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/AdditionResolver.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/AdditionResolver.java index 3f03fbfe6509c..352cec2a61ece 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/AdditionResolver.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/AdditionResolver.java @@ -19,6 +19,8 @@ package org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic; +import org.apache.iotdb.db.queryengine.plan.relational.type.InternalTypeManager; + import org.apache.tsfile.enums.TSDataType; import org.apache.tsfile.read.common.type.Type; @@ -87,48 +89,14 @@ public class AdditionResolver { addCondition(UNKNOWN, DATE, DATE); addCondition(UNKNOWN, TIMESTAMP, TIMESTAMP); - addConditionTS(TSDataType.INT32, TSDataType.INT32, TSDataType.INT32); - addConditionTS(TSDataType.INT32, TSDataType.INT64, TSDataType.INT64); - addConditionTS(TSDataType.INT32, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.INT32, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.INT32, TSDataType.DATE, TSDataType.DATE); - addConditionTS(TSDataType.INT32, TSDataType.TIMESTAMP, TSDataType.TIMESTAMP); - addConditionTS(TSDataType.INT32, TSDataType.UNKNOWN, TSDataType.INT32); - - addConditionTS(TSDataType.INT64, TSDataType.INT32, TSDataType.INT64); - addConditionTS(TSDataType.INT64, TSDataType.INT64, TSDataType.INT64); - addConditionTS(TSDataType.INT64, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.INT64, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.INT64, TSDataType.DATE, TSDataType.DATE); - addConditionTS(TSDataType.INT64, TSDataType.TIMESTAMP, TSDataType.TIMESTAMP); - addConditionTS(TSDataType.INT64, TSDataType.UNKNOWN, TSDataType.INT64); - - addConditionTS(TSDataType.FLOAT, TSDataType.INT32, TSDataType.FLOAT); - addConditionTS(TSDataType.FLOAT, TSDataType.INT64, TSDataType.FLOAT); - addConditionTS(TSDataType.FLOAT, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.FLOAT, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.FLOAT, TSDataType.UNKNOWN, TSDataType.FLOAT); - - addConditionTS(TSDataType.DOUBLE, TSDataType.INT32, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.INT64, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.FLOAT, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.UNKNOWN, TSDataType.DOUBLE); - - addConditionTS(TSDataType.DATE, TSDataType.INT32, TSDataType.DATE); - addConditionTS(TSDataType.DATE, TSDataType.INT64, TSDataType.DATE); - addConditionTS(TSDataType.DATE, TSDataType.UNKNOWN, TSDataType.DATE); - - addConditionTS(TSDataType.TIMESTAMP, TSDataType.INT32, TSDataType.TIMESTAMP); - addConditionTS(TSDataType.TIMESTAMP, TSDataType.INT64, TSDataType.TIMESTAMP); - addConditionTS(TSDataType.TIMESTAMP, TSDataType.UNKNOWN, TSDataType.TIMESTAMP); - - addConditionTS(TSDataType.UNKNOWN, TSDataType.INT32, TSDataType.INT32); - addConditionTS(TSDataType.UNKNOWN, TSDataType.INT64, TSDataType.INT64); - addConditionTS(TSDataType.UNKNOWN, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.UNKNOWN, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.UNKNOWN, TSDataType.DATE, TSDataType.DATE); - addConditionTS(TSDataType.UNKNOWN, TSDataType.TIMESTAMP, TSDataType.TIMESTAMP); + for (Map.Entry> leftEntry : CONDITION_MAP.entrySet()) { + TSDataType leftTs = InternalTypeManager.getTSDataType(leftEntry.getKey()); + for (Map.Entry rightEntry : leftEntry.getValue().entrySet()) { + TSDataType rightTs = InternalTypeManager.getTSDataType(rightEntry.getKey()); + TSDataType resultTs = InternalTypeManager.getTSDataType(rightEntry.getValue()); + addConditionTS(leftTs, rightTs, resultTs); + } + } } private static void addCondition(Type condition1, Type condition2, Type result) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/DivisionResolver.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/DivisionResolver.java index c02fbcce6bded..794a3b0e03855 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/DivisionResolver.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/DivisionResolver.java @@ -19,6 +19,8 @@ package org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic; +import org.apache.iotdb.db.queryengine.plan.relational.type.InternalTypeManager; + import org.apache.tsfile.enums.TSDataType; import org.apache.tsfile.read.common.type.Type; @@ -70,34 +72,14 @@ public class DivisionResolver { addCondition(UNKNOWN, FLOAT, FLOAT); addCondition(UNKNOWN, DOUBLE, DOUBLE); - addConditionTS(TSDataType.INT32, TSDataType.INT32, TSDataType.INT32); - addConditionTS(TSDataType.INT32, TSDataType.INT64, TSDataType.INT64); - addConditionTS(TSDataType.INT32, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.INT32, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.INT32, TSDataType.UNKNOWN, TSDataType.INT32); - - addConditionTS(TSDataType.INT64, TSDataType.INT32, TSDataType.INT64); - addConditionTS(TSDataType.INT64, TSDataType.INT64, TSDataType.INT64); - addConditionTS(TSDataType.INT64, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.INT64, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.INT64, TSDataType.UNKNOWN, TSDataType.INT64); - - addConditionTS(TSDataType.FLOAT, TSDataType.INT32, TSDataType.FLOAT); - addConditionTS(TSDataType.FLOAT, TSDataType.INT64, TSDataType.FLOAT); - addConditionTS(TSDataType.FLOAT, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.FLOAT, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.FLOAT, TSDataType.UNKNOWN, TSDataType.FLOAT); - - addConditionTS(TSDataType.DOUBLE, TSDataType.INT32, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.INT64, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.FLOAT, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.UNKNOWN, TSDataType.DOUBLE); - - addConditionTS(TSDataType.UNKNOWN, TSDataType.INT32, TSDataType.INT32); - addConditionTS(TSDataType.UNKNOWN, TSDataType.INT64, TSDataType.INT64); - addConditionTS(TSDataType.UNKNOWN, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.UNKNOWN, TSDataType.DOUBLE, TSDataType.DOUBLE); + for (Map.Entry> leftEntry : CONDITION_MAP.entrySet()) { + TSDataType leftTs = InternalTypeManager.getTSDataType(leftEntry.getKey()); + for (Map.Entry rightEntry : leftEntry.getValue().entrySet()) { + TSDataType rightTs = InternalTypeManager.getTSDataType(rightEntry.getKey()); + TSDataType resultTs = InternalTypeManager.getTSDataType(rightEntry.getValue()); + addConditionTS(leftTs, rightTs, resultTs); + } + } } private static void addCondition(Type condition1, Type condition2, Type result) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/ModulusResolver.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/ModulusResolver.java index 8f0b2375f9784..0f382fe5c48ab 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/ModulusResolver.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/ModulusResolver.java @@ -19,6 +19,8 @@ package org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic; +import org.apache.iotdb.db.queryengine.plan.relational.type.InternalTypeManager; + import org.apache.tsfile.enums.TSDataType; import org.apache.tsfile.read.common.type.Type; @@ -70,34 +72,14 @@ public class ModulusResolver { addCondition(UNKNOWN, FLOAT, FLOAT); addCondition(UNKNOWN, DOUBLE, DOUBLE); - addConditionTS(TSDataType.INT32, TSDataType.INT32, TSDataType.INT32); - addConditionTS(TSDataType.INT32, TSDataType.INT64, TSDataType.INT64); - addConditionTS(TSDataType.INT32, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.INT32, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.INT32, TSDataType.UNKNOWN, TSDataType.INT32); - - addConditionTS(TSDataType.INT64, TSDataType.INT32, TSDataType.INT64); - addConditionTS(TSDataType.INT64, TSDataType.INT64, TSDataType.INT64); - addConditionTS(TSDataType.INT64, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.INT64, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.INT64, TSDataType.UNKNOWN, TSDataType.INT64); - - addConditionTS(TSDataType.FLOAT, TSDataType.INT32, TSDataType.FLOAT); - addConditionTS(TSDataType.FLOAT, TSDataType.INT64, TSDataType.FLOAT); - addConditionTS(TSDataType.FLOAT, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.FLOAT, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.FLOAT, TSDataType.UNKNOWN, TSDataType.FLOAT); - - addConditionTS(TSDataType.DOUBLE, TSDataType.INT32, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.INT64, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.FLOAT, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.UNKNOWN, TSDataType.DOUBLE); - - addConditionTS(TSDataType.UNKNOWN, TSDataType.INT32, TSDataType.INT32); - addConditionTS(TSDataType.UNKNOWN, TSDataType.INT64, TSDataType.INT64); - addConditionTS(TSDataType.UNKNOWN, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.UNKNOWN, TSDataType.DOUBLE, TSDataType.DOUBLE); + for (Map.Entry> leftEntry : CONDITION_MAP.entrySet()) { + TSDataType leftTs = InternalTypeManager.getTSDataType(leftEntry.getKey()); + for (Map.Entry rightEntry : leftEntry.getValue().entrySet()) { + TSDataType rightTs = InternalTypeManager.getTSDataType(rightEntry.getKey()); + TSDataType resultTs = InternalTypeManager.getTSDataType(rightEntry.getValue()); + addConditionTS(leftTs, rightTs, resultTs); + } + } } private static void addCondition(Type condition1, Type condition2, Type result) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/MultiplicationResolver.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/MultiplicationResolver.java index a0cab6dd32ddd..f253fe934fca3 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/MultiplicationResolver.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/MultiplicationResolver.java @@ -19,6 +19,8 @@ package org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic; +import org.apache.iotdb.db.queryengine.plan.relational.type.InternalTypeManager; + import org.apache.tsfile.enums.TSDataType; import org.apache.tsfile.read.common.type.Type; @@ -70,34 +72,14 @@ public class MultiplicationResolver { addCondition(UNKNOWN, FLOAT, FLOAT); addCondition(UNKNOWN, DOUBLE, DOUBLE); - addConditionTS(TSDataType.INT32, TSDataType.INT32, TSDataType.INT32); - addConditionTS(TSDataType.INT32, TSDataType.INT64, TSDataType.INT64); - addConditionTS(TSDataType.INT32, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.INT32, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.INT32, TSDataType.UNKNOWN, TSDataType.INT32); - - addConditionTS(TSDataType.INT64, TSDataType.INT32, TSDataType.INT64); - addConditionTS(TSDataType.INT64, TSDataType.INT64, TSDataType.INT64); - addConditionTS(TSDataType.INT64, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.INT64, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.INT64, TSDataType.UNKNOWN, TSDataType.INT64); - - addConditionTS(TSDataType.FLOAT, TSDataType.INT32, TSDataType.FLOAT); - addConditionTS(TSDataType.FLOAT, TSDataType.INT64, TSDataType.FLOAT); - addConditionTS(TSDataType.FLOAT, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.FLOAT, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.FLOAT, TSDataType.UNKNOWN, TSDataType.FLOAT); - - addConditionTS(TSDataType.DOUBLE, TSDataType.INT32, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.INT64, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.FLOAT, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.UNKNOWN, TSDataType.DOUBLE); - - addConditionTS(TSDataType.UNKNOWN, TSDataType.INT32, TSDataType.INT32); - addConditionTS(TSDataType.UNKNOWN, TSDataType.INT64, TSDataType.INT64); - addConditionTS(TSDataType.UNKNOWN, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.UNKNOWN, TSDataType.DOUBLE, TSDataType.DOUBLE); + for (Map.Entry> leftEntry : CONDITION_MAP.entrySet()) { + TSDataType leftTs = InternalTypeManager.getTSDataType(leftEntry.getKey()); + for (Map.Entry rightEntry : leftEntry.getValue().entrySet()) { + TSDataType rightTs = InternalTypeManager.getTSDataType(rightEntry.getKey()); + TSDataType resultTs = InternalTypeManager.getTSDataType(rightEntry.getValue()); + addConditionTS(leftTs, rightTs, resultTs); + } + } } private static void addCondition(Type condition1, Type condition2, Type result) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/SubtractionResolver.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/SubtractionResolver.java index 00955d93731f2..d8744bcd67774 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/SubtractionResolver.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/SubtractionResolver.java @@ -19,6 +19,8 @@ package org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic; +import org.apache.iotdb.db.queryengine.plan.relational.type.InternalTypeManager; + import org.apache.tsfile.enums.TSDataType; import org.apache.tsfile.read.common.type.Type; @@ -79,40 +81,14 @@ public class SubtractionResolver { addCondition(UNKNOWN, FLOAT, FLOAT); addCondition(UNKNOWN, DOUBLE, DOUBLE); - addConditionTS(TSDataType.INT32, TSDataType.INT32, TSDataType.INT32); - addConditionTS(TSDataType.INT32, TSDataType.INT64, TSDataType.INT64); - addConditionTS(TSDataType.INT32, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.INT32, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.INT32, TSDataType.UNKNOWN, TSDataType.INT32); - - addConditionTS(TSDataType.INT64, TSDataType.INT32, TSDataType.INT64); - addConditionTS(TSDataType.INT64, TSDataType.INT64, TSDataType.INT64); - addConditionTS(TSDataType.INT64, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.INT64, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.INT64, TSDataType.UNKNOWN, TSDataType.INT64); - - addConditionTS(TSDataType.FLOAT, TSDataType.INT32, TSDataType.FLOAT); - addConditionTS(TSDataType.FLOAT, TSDataType.INT64, TSDataType.FLOAT); - addConditionTS(TSDataType.FLOAT, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.FLOAT, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.FLOAT, TSDataType.UNKNOWN, TSDataType.FLOAT); - - addConditionTS(TSDataType.DOUBLE, TSDataType.INT32, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.INT64, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.FLOAT, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.DOUBLE, TSDataType.DOUBLE); - addConditionTS(TSDataType.DOUBLE, TSDataType.UNKNOWN, TSDataType.DOUBLE); - - addConditionTS(TSDataType.DATE, TSDataType.INT32, TSDataType.DATE); - addConditionTS(TSDataType.DATE, TSDataType.INT64, TSDataType.DATE); - - addConditionTS(TSDataType.TIMESTAMP, TSDataType.INT32, TSDataType.TIMESTAMP); - addConditionTS(TSDataType.TIMESTAMP, TSDataType.INT64, TSDataType.TIMESTAMP); - - addConditionTS(TSDataType.UNKNOWN, TSDataType.INT32, TSDataType.INT32); - addConditionTS(TSDataType.UNKNOWN, TSDataType.INT64, TSDataType.INT64); - addConditionTS(TSDataType.UNKNOWN, TSDataType.FLOAT, TSDataType.FLOAT); - addConditionTS(TSDataType.UNKNOWN, TSDataType.DOUBLE, TSDataType.DOUBLE); + for (Map.Entry> leftEntry : CONDITION_MAP.entrySet()) { + TSDataType leftTs = InternalTypeManager.getTSDataType(leftEntry.getKey()); + for (Map.Entry rightEntry : leftEntry.getValue().entrySet()) { + TSDataType rightTs = InternalTypeManager.getTSDataType(rightEntry.getKey()); + TSDataType resultTs = InternalTypeManager.getTSDataType(rightEntry.getValue()); + addConditionTS(leftTs, rightTs, resultTs); + } + } } private static void addCondition(Type condition1, Type condition2, Type result) { diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeTest.java index 542a3db907d99..1753617624475 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeTest.java @@ -116,7 +116,7 @@ public void testRawDataQuery() { Arrays.asList( new ColumnHeader("root.sg.d1.s1", TSDataType.INT32, null), new ColumnHeader("root.sg.d1.s2", TSDataType.DOUBLE, "root.sg.d1.status"), - new ColumnHeader("root.sg.d1.s1 + 1", TSDataType.DOUBLE, "t")), + new ColumnHeader("root.sg.d1.s1 + 1", TSDataType.INT64, "t")), false)); alignByTimeAnalysisEqualTest(actualAnalysis, expectedAnalysis); @@ -177,9 +177,9 @@ public void testRawDataQuery() { Arrays.asList( new ColumnHeader("root.sg.d1.s1", TSDataType.INT32, null), new ColumnHeader("root.sg.d1.s1 / 2", TSDataType.INT64, null), - new ColumnHeader("root.sg.d1.s1 * 3", TSDataType.DOUBLE, null), + new ColumnHeader("root.sg.d1.s1 * 3", TSDataType.INT64, null), new ColumnHeader("root.sg.d1.s1 % 4", TSDataType.INT64, null), - new ColumnHeader("root.sg.d1.s1 - 5", TSDataType.DOUBLE, null)), + new ColumnHeader("root.sg.d1.s1 - 5", TSDataType.INT64, null)), false)); alignByTimeAnalysisEqualTest(actualAnalysis, expectedAnalysis); } catch (Exception e) { @@ -267,7 +267,7 @@ public void testAggregationQuery() { expectedAnalysis.setRespDatasetHeader( new DatasetHeader( Collections.singletonList( - new ColumnHeader("count(root.sg.d1.s1 + 1) + 1", TSDataType.DOUBLE, "t")), + new ColumnHeader("count(root.sg.d1.s1 + 1) + 1", TSDataType.INT64, "t")), false)); alignByTimeAnalysisEqualTest(actualAnalysis, expectedAnalysis); @@ -548,7 +548,7 @@ public void testAggregationQueryAlignByDevice() { new DatasetHeader( Arrays.asList( new ColumnHeader("Device", TSDataType.TEXT), - new ColumnHeader("count(s1 + 1) + 1", TSDataType.DOUBLE, null)), + new ColumnHeader("count(s1 + 1) + 1", TSDataType.INT64, null)), false)); alignByDeviceAnalysisEqualTest(actualAnalysis, expectedAnalysis); From be5ee757342d1f0f419583ad2d8bb95e48eb8700 Mon Sep 17 00:00:00 2001 From: Cool6689 <3322351820@qq.com> Date: Mon, 8 Dec 2025 16:40:47 +0800 Subject: [PATCH 4/4] Refactor arithmetic operation tests to use integer types instead of doubles --- .../db/it/aggregation/maxby/IoTDBMaxByIT.java | 7 ++--- .../db/it/aggregation/minby/IoTDBMinByIT.java | 7 ++--- .../db/it/udf/IoTDBUDTFHybridQueryIT.java | 26 +++++++++---------- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/maxby/IoTDBMaxByIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/maxby/IoTDBMaxByIT.java index 9675ab783cc47..524f087a0670d 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/maxby/IoTDBMaxByIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/maxby/IoTDBMaxByIT.java @@ -301,7 +301,7 @@ public void testMaxByWithExpression() { "max_by(root.db.d1.x5, -cos(sin(root.db.d1.y2 / 10)))", "max_by(REPLACE(root.db.d1.x6, '3', '4'), -cos(sin(root.db.d1.y2 / 10)))", }; - String[] retArray = new String[] {"0,1.3333333333333333,2.0,2.0,false,2,"}; + String[] retArray = new String[] {"0,1,2.0,2.0,false,2,"}; String y = "-cos(sin(y2 / 10))"; resultSetEqualTest( String.format( @@ -330,10 +330,7 @@ public void testMaxByWithAlignByDevice() { "max_by(REPLACE(x6, '3', '4'), -cos(sin(y2 / 10)))", }; String[] retArray = - new String[] { - "root.db.d1,0,1.3333333333333333,2.0,2.0,false,2,", - "root.db.d2,0,1.3333333333333333,2.0,2.0,false,2," - }; + new String[] {"root.db.d1,0,1,2.0,2.0,false,2,", "root.db.d2,0,1,2.0,2.0,false,2,"}; String y = "-cos(sin(y2 / 10))"; resultSetEqualTest( String.format( diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/minby/IoTDBMinByIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/minby/IoTDBMinByIT.java index 4ce985fe11daf..6c9d596c337ee 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/minby/IoTDBMinByIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/minby/IoTDBMinByIT.java @@ -300,7 +300,7 @@ public void testMaxByWithExpression() { "min_by(root.db.d1.x5, -cos(sin(root.db.d1.y2 / 10)))", "min_by(REPLACE(root.db.d1.x6, '3', '4'), -cos(sin(root.db.d1.y2 / 10)))", }; - String[] retArray = new String[] {"0,1.3333333333333333,2.0,2.0,false,2,"}; + String[] retArray = new String[] {"0,1,2.0,2.0,false,2,"}; String y = "-cos(sin(y2 / 10))"; resultSetEqualTest( String.format( @@ -329,10 +329,7 @@ public void testMaxByWithAlignByDevice() { "min_by(REPLACE(x6, '3', '4'), -cos(sin(y2 / 10)))", }; String[] retArray = - new String[] { - "root.db.d1,0,1.3333333333333333,2.0,2.0,false,2,", - "root.db.d2,0,1.3333333333333333,2.0,2.0,false,2," - }; + new String[] {"root.db.d1,0,1,2.0,2.0,false,2,", "root.db.d2,0,1,2.0,2.0,false,2,"}; String y = "-cos(sin(y2 / 10))"; resultSetEqualTest( String.format( diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDTFHybridQueryIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDTFHybridQueryIT.java index cbcbec61df51b..291288348477c 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDTFHybridQueryIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDTFHybridQueryIT.java @@ -19,13 +19,21 @@ package org.apache.iotdb.db.it.udf; +import static org.apache.iotdb.itbase.constant.TestConstant.TIMESTAMP_STR; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; import org.apache.iotdb.commons.schema.column.ColumnHeaderConstant; import org.apache.iotdb.it.env.EnvFactory; import org.apache.iotdb.it.framework.IoTDBTestRunner; import org.apache.iotdb.itbase.category.ClusterIT; import org.apache.iotdb.itbase.category.LocalStandaloneIT; import org.apache.iotdb.itbase.constant.UDFTestConstant; - import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Ignore; @@ -33,16 +41,6 @@ import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import static org.apache.iotdb.itbase.constant.TestConstant.TIMESTAMP_STR; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - @RunWith(IoTDBTestRunner.class) @Category({LocalStandaloneIT.class, ClusterIT.class}) public class IoTDBUDTFHybridQueryIT { @@ -164,9 +162,9 @@ public void testUserDefinedFunctionFillFunctionHybridQuery() { "2,0.9092974268256817,3,2.0", "3,0.1411200080598672,4,3.0", "4,-0.7568024953079282,5,3.14", - "7,3.14,3.14,7.0", - "8,3.14,3.14,8.0", - "9,3.14,3.14,9.0" + "7,3.14,null,7.0", + "8,3.14,null,8.0", + "9,3.14,null,9.0" }; try (Connection connection = EnvFactory.getEnv().getConnection();