diff --git a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/scalar/IoTDBCastLiteralFunctionIT.java b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/scalar/IoTDBCastLiteralFunctionIT.java new file mode 100644 index 0000000000000..3072140b70515 --- /dev/null +++ b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/scalar/IoTDBCastLiteralFunctionIT.java @@ -0,0 +1,146 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.iotdb.relational.it.query.recent.scalar; + +import org.apache.iotdb.it.env.EnvFactory; +import org.apache.iotdb.it.framework.IoTDBTestRunner; +import org.apache.iotdb.itbase.category.TableClusterIT; +import org.apache.iotdb.itbase.category.TableLocalStandaloneIT; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; + +import static org.apache.iotdb.db.it.utils.TestUtils.prepareTableData; +import static org.apache.iotdb.db.it.utils.TestUtils.tableResultSetEqualTest; + +@RunWith(IoTDBTestRunner.class) +@Category({TableLocalStandaloneIT.class, TableClusterIT.class}) +public class IoTDBCastLiteralFunctionIT { + + private static final String DATABASE_NAME = "test_cast_float_literal"; + + private static final String[] createSqls = + new String[] { + "CREATE DATABASE " + DATABASE_NAME, + "USE " + DATABASE_NAME, + "CREATE TABLE table_a(time time, device string tag, s_int int32 field)", + "INSERT INTO table_a(time, device, s_int) VALUES (1, 'd1', 100)" + }; + + @BeforeClass + public static void setUp() throws Exception { + EnvFactory.getEnv().initClusterEnvironment(); + prepareTableData(createSqls); + } + + @AfterClass + public static void tearDown() throws Exception { + EnvFactory.getEnv().cleanClusterEnvironment(); + } + + @Test + public void TestLiteralCast() { + String[] expectedHeader = {"_col0"}; + + tableResultSetEqualTest( + "select cast(1.1 as float) from table_a", + expectedHeader, + new String[] {"1.1,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "select cast(1.1 as double) from table_a", + expectedHeader, + new String[] {"1.1,"}, + DATABASE_NAME); + + // case: 1.9 -> 2 (INT32) + tableResultSetEqualTest( + "select cast(1.9 as int32) from table_a", + expectedHeader, + new String[] {"2,"}, + DATABASE_NAME); + + // case: 1.9 -> 2 (INT64) + tableResultSetEqualTest( + "select cast(1.9 as int64) from table_a", + expectedHeader, + new String[] {"2,"}, + DATABASE_NAME); + + // String -> numeric (Parsing) + tableResultSetEqualTest( + "select cast('3.14159' as double) from table_a", + expectedHeader, + new String[] {"3.14159,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "select cast('100' as int32) from table_a", + expectedHeader, + new String[] {"100,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "select cast(123.456 as string) from table_a", + expectedHeader, + new String[] {"123.456,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "select cast(123 as text) from table_a", + expectedHeader, + new String[] {"123,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "select cast(1 as boolean) from table_a", + expectedHeader, + new String[] {"true,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "select cast(0 as boolean) from table_a", + expectedHeader, + new String[] {"false,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "select cast('true' as boolean) from table_a", + expectedHeader, + new String[] {"true,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "select cast(s_int as float) from table_a", + expectedHeader, + new String[] {"100.0,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "select cast(s_int as string) from table_a", + expectedHeader, + new String[] {"100,"}, + DATABASE_NAME); + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/Computation.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/Computation.java index 3d33b0175b42b..33661fd206a57 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/Computation.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/rowpattern/expression/Computation.java @@ -30,6 +30,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DataType; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LogicalExpression; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LongLiteral; @@ -126,6 +127,9 @@ private static Computation parse( } else if (expression instanceof DoubleLiteral) { DoubleLiteral constExpr = (DoubleLiteral) expression; return new ConstantComputation(constExpr.getValue()); + } else if (expression instanceof FloatLiteral) { + FloatLiteral constExpr = (FloatLiteral) expression; + return new ConstantComputation(constExpr.getValue()); } else if (expression instanceof StringLiteral) { StringLiteral constExpr = (StringLiteral) expression; return new ConstantComputation(constExpr.getValue()); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java index 7400aa7fb23fe..cf416a184a9ce 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java @@ -50,6 +50,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Extract; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FunctionCall; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.IfExpression; @@ -206,6 +207,7 @@ import org.apache.tsfile.read.common.block.column.BinaryColumn; import org.apache.tsfile.read.common.block.column.BooleanColumn; import org.apache.tsfile.read.common.block.column.DoubleColumn; +import org.apache.tsfile.read.common.block.column.FloatColumn; import org.apache.tsfile.read.common.block.column.IntColumn; import org.apache.tsfile.read.common.block.column.LongColumn; import org.apache.tsfile.read.common.type.DateType; @@ -509,6 +511,22 @@ protected ColumnTransformer visitDoubleLiteral(DoubleLiteral node, Context conte return res; } + @Override + protected ColumnTransformer visitFloatLiteral(FloatLiteral node, Context context) { + ColumnTransformer res = + context.cache.computeIfAbsent( + node, + e -> { + ConstantColumnTransformer columnTransformer = + new ConstantColumnTransformer( + FLOAT, new FloatColumn(1, Optional.empty(), new float[] {node.getValue()})); + context.leafList.add(columnTransformer); + return columnTransformer; + }); + res.addReferenceCount(); + return res; + } + @Override protected ColumnTransformer visitDecimalLiteral(DecimalLiteral node, Context context) { throw new UnsupportedOperationException(); @@ -1552,6 +1570,8 @@ private static InMultiColumnTransformer constructInColumnTransformer( timestampSet.add(((LongLiteral) value).getParsedValue()); } else if (value instanceof DoubleLiteral) { timestampSet.add((long) ((DoubleLiteral) value).getValue()); + } else if (value instanceof FloatLiteral) { + timestampSet.add((long) ((FloatLiteral) value).getValue()); } else if (value instanceof GenericLiteral) { timestampSet.add(Long.parseLong(((GenericLiteral) value).getValue())); } else { @@ -1568,7 +1588,11 @@ private static InMultiColumnTransformer constructInColumnTransformer( Set floatSet = new HashSet<>(); for (Literal value : values) { try { - floatSet.add((float) ((DoubleLiteral) value).getValue()); + if (value instanceof FloatLiteral) { + floatSet.add(((FloatLiteral) value).getValue()); + } else { + floatSet.add((float) ((DoubleLiteral) value).getValue()); + } } catch (IllegalArgumentException e) { throw new SemanticException(String.format(errorMsg, value, childType)); } @@ -1578,7 +1602,11 @@ private static InMultiColumnTransformer constructInColumnTransformer( Set doubleSet = new HashSet<>(); for (Literal value : values) { try { - doubleSet.add(((DoubleLiteral) value).getValue()); + if (value instanceof FloatLiteral) { + doubleSet.add((double) ((FloatLiteral) value).getValue()); + } else { + doubleSet.add(((DoubleLiteral) value).getValue()); + } } catch (IllegalArgumentException e) { throw new SemanticException(String.format(errorMsg, value, childType)); } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/ExpressionAnalyzer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/ExpressionAnalyzer.java index 663c92ad83e97..4dc2a21f601dc 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/ExpressionAnalyzer.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/ExpressionAnalyzer.java @@ -63,6 +63,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Extract; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FieldReference; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FrameBound; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FunctionCall; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericLiteral; @@ -157,6 +158,7 @@ import static org.apache.tsfile.read.common.type.BlobType.BLOB; import static org.apache.tsfile.read.common.type.BooleanType.BOOLEAN; import static org.apache.tsfile.read.common.type.DoubleType.DOUBLE; +import static org.apache.tsfile.read.common.type.FloatType.FLOAT; import static org.apache.tsfile.read.common.type.IntType.INT32; import static org.apache.tsfile.read.common.type.LongType.INT64; import static org.apache.tsfile.read.common.type.StringType.STRING; @@ -948,6 +950,12 @@ protected Type visitDoubleLiteral( return setExpressionType(node, DOUBLE); } + @Override + protected Type visitFloatLiteral( + FloatLiteral node, StackableAstVisitorContext context) { + return setExpressionType(node, FLOAT); + } + @Override protected Type visitDecimalLiteral( DecimalLiteral node, StackableAstVisitorContext context) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/ConvertPredicateToFilterVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/ConvertPredicateToFilterVisitor.java index b9c4abdad8255..59cf8b43c7c8e 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/ConvertPredicateToFilterVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/ConvertPredicateToFilterVisitor.java @@ -30,6 +30,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Extract; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.IfExpression; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.InListExpression; @@ -163,30 +164,38 @@ public static > Filter constructCompareFilter( Type type = context.getType(Symbol.from(symbolReference)); TSDataType columnDataType = InternalTypeManager.getTSDataType(type); + // the literal could be the floatLiteral, select * from table where s1 > cast(1.1 as float) + // convert the floatLiteral to doubleLiteral + Double floatPoint = null; + if (literal instanceof DoubleLiteral) { + floatPoint = ((DoubleLiteral) literal).getValue(); + } else if (literal instanceof FloatLiteral) { + floatPoint = (double) ((FloatLiteral) literal).getValue(); + } + // when literal is the doubleLiteral type and the columnDataType is INT64 or INT32, // the doubleLiteral has to be converted. - if (literal instanceof DoubleLiteral) { - DoubleLiteral doubleLiteral = (DoubleLiteral) literal; - double doubleLiteralValue = doubleLiteral.getValue(); + if (floatPoint != null) { + double floatPointValue = floatPoint; if (columnDataType == INT64) { - if (doubleLiteralValue > Long.MAX_VALUE) { + if (floatPointValue > Long.MAX_VALUE) { return constructFilterForGreaterThanMax(operator, measurementIndex); } - if (doubleLiteralValue < Long.MIN_VALUE) { + if (floatPointValue < Long.MIN_VALUE) { return constructFilterForLessThanMin(operator, measurementIndex); } - return constructFilterFromDouble(operator, doubleLiteralValue, measurementIndex, type); + return constructFilterFromDouble(operator, floatPointValue, measurementIndex, type); } else if (columnDataType == INT32) { - if (doubleLiteralValue > Integer.MAX_VALUE) { + if (floatPointValue > Integer.MAX_VALUE) { return constructFilterForGreaterThanMax(operator, measurementIndex); } - if (doubleLiteralValue < Integer.MIN_VALUE) { + if (floatPointValue < Integer.MIN_VALUE) { return constructFilterForLessThanMin(operator, measurementIndex); } - return constructFilterFromDouble(operator, doubleLiteralValue, measurementIndex, type); + return constructFilterFromDouble(operator, floatPointValue, measurementIndex, type); } } @@ -572,6 +581,8 @@ public static double getDoubleValue(Expression expression) { return ((DoubleLiteral) expression).getValue(); } else if (expression instanceof LongLiteral) { return ((LongLiteral) expression).getParsedValue(); + } else if (expression instanceof FloatLiteral) { + return ((FloatLiteral) expression).getValue(); } else { throw new IllegalArgumentException("expression should be numeric, actual is " + expression); } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/PredicatePushIntoMetadataChecker.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/PredicatePushIntoMetadataChecker.java index a9cafed879731..1ecbb5704a281 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/PredicatePushIntoMetadataChecker.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/PredicatePushIntoMetadataChecker.java @@ -34,6 +34,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DecimalLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FunctionCall; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.IfExpression; @@ -128,6 +129,11 @@ protected Boolean visitDoubleLiteral(final DoubleLiteral node, final Void contex return true; } + @Override + protected Boolean visitFloatLiteral(final FloatLiteral node, final Void context) { + return true; + } + @Override protected Boolean visitDecimalLiteral(final DecimalLiteral node, final Void context) { return true; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToBlobLiteralVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToBlobLiteralVisitor.java index ed5156876d9e5..8b374825068b8 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToBlobLiteralVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToBlobLiteralVisitor.java @@ -23,6 +23,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BinaryLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BooleanLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Literal; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LongLiteral; @@ -54,6 +55,11 @@ protected Binary visitDoubleLiteral(DoubleLiteral node, Void context) { return null; } + @Override + protected Binary visitFloatLiteral(FloatLiteral node, Void context) { + return null; + } + @Override protected Binary visitStringLiteral(StringLiteral node, Void context) { try { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToBooleanLiteralVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToBooleanLiteralVisitor.java index 628f8284184e0..f2019f0a2ab57 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToBooleanLiteralVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToBooleanLiteralVisitor.java @@ -23,6 +23,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BinaryLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BooleanLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Literal; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LongLiteral; @@ -52,6 +53,11 @@ protected Boolean visitDoubleLiteral(DoubleLiteral node, Void context) { return node.getValue() != 0; } + @Override + protected Boolean visitFloatLiteral(FloatLiteral node, Void context) { + return node.getValue() != 0; + } + @Override protected Boolean visitStringLiteral(StringLiteral node, Void context) { try { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToDateLiteralVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToDateLiteralVisitor.java index a3654aea380b8..f1225a1bf3177 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToDateLiteralVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToDateLiteralVisitor.java @@ -23,6 +23,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BinaryLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BooleanLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Literal; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LongLiteral; @@ -54,6 +55,11 @@ protected Integer visitDoubleLiteral(DoubleLiteral node, Void context) { return (int) node.getValue(); } + @Override + protected Integer visitFloatLiteral(FloatLiteral node, Void context) { + return (int) node.getValue(); + } + @Override protected Integer visitStringLiteral(StringLiteral node, Void context) { try { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToDoubleLiteralVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToDoubleLiteralVisitor.java index 20c33f40b3758..c974ea3a079b0 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToDoubleLiteralVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToDoubleLiteralVisitor.java @@ -23,6 +23,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BinaryLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BooleanLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Literal; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LongLiteral; @@ -52,6 +53,11 @@ protected Double visitDoubleLiteral(DoubleLiteral node, Void context) { return node.getValue(); } + @Override + protected Double visitFloatLiteral(FloatLiteral node, Void context) { + return (double) node.getValue(); + } + @Override protected Double visitStringLiteral(StringLiteral node, Void context) { try { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToFloatLiteralVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToFloatLiteralVisitor.java index b6c2e42c51cd4..e1a1e384594cb 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToFloatLiteralVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToFloatLiteralVisitor.java @@ -23,6 +23,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BinaryLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BooleanLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Literal; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LongLiteral; @@ -52,6 +53,11 @@ protected Float visitDoubleLiteral(DoubleLiteral node, Void context) { return (float) node.getValue(); } + @Override + protected Float visitFloatLiteral(FloatLiteral node, Void context) { + return node.getValue(); + } + @Override protected Float visitStringLiteral(StringLiteral node, Void context) { try { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToInt32LiteralVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToInt32LiteralVisitor.java index 920acc5f046e0..822ef83ba4715 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToInt32LiteralVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToInt32LiteralVisitor.java @@ -23,6 +23,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BinaryLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BooleanLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Literal; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LongLiteral; @@ -52,6 +53,11 @@ protected Integer visitDoubleLiteral(DoubleLiteral node, Void context) { return (int) node.getValue(); } + @Override + protected Integer visitFloatLiteral(FloatLiteral node, Void context) { + return (int) node.getValue(); + } + @Override protected Integer visitStringLiteral(StringLiteral node, Void context) { try { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToInt64LiteralVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToInt64LiteralVisitor.java index a12c14380c0eb..896d4c868e008 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToInt64LiteralVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToInt64LiteralVisitor.java @@ -23,6 +23,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BinaryLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BooleanLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Literal; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LongLiteral; @@ -52,6 +53,11 @@ protected Long visitDoubleLiteral(DoubleLiteral node, Void context) { return (long) node.getValue(); } + @Override + protected Long visitFloatLiteral(FloatLiteral node, Void context) { + return (long) node.getValue(); + } + @Override protected Long visitStringLiteral(StringLiteral node, Void context) { try { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToStringLiteralVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToStringLiteralVisitor.java index e14a58b30bc07..726d817621a53 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToStringLiteralVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToStringLiteralVisitor.java @@ -23,6 +23,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BinaryLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BooleanLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Literal; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LongLiteral; @@ -63,6 +64,11 @@ protected Binary visitDoubleLiteral(DoubleLiteral node, Void context) { return new Binary(String.valueOf(node.getValue()), charset); } + @Override + protected Binary visitFloatLiteral(FloatLiteral node, Void context) { + return new Binary(String.valueOf(node.getValue()), charset); + } + @Override protected Binary visitStringLiteral(StringLiteral node, Void context) { return new Binary(node.getValue(), charset); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToTimestampLiteralVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToTimestampLiteralVisitor.java index 2a6dead013b45..69fd8445a5765 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToTimestampLiteralVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/CastToTimestampLiteralVisitor.java @@ -23,6 +23,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BinaryLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BooleanLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Literal; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LongLiteral; @@ -61,6 +62,11 @@ protected Long visitDoubleLiteral(DoubleLiteral node, Void context) { return (long) node.getValue(); } + @Override + protected Long visitFloatLiteral(FloatLiteral node, Void context) { + return (long) node.getValue(); + } + @Override protected Long visitStringLiteral(StringLiteral node, Void context) { try { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/IrTypeAnalyzer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/IrTypeAnalyzer.java index 455e7e08b888e..61d3ec3c71057 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/IrTypeAnalyzer.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/IrTypeAnalyzer.java @@ -41,6 +41,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Extract; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FunctionCall; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.IfExpression; @@ -83,6 +84,7 @@ import static org.apache.iotdb.db.queryengine.plan.relational.type.TypeSignatureTranslator.toTypeSignature; import static org.apache.tsfile.read.common.type.BooleanType.BOOLEAN; import static org.apache.tsfile.read.common.type.DoubleType.DOUBLE; +import static org.apache.tsfile.read.common.type.FloatType.FLOAT; import static org.apache.tsfile.read.common.type.IntType.INT32; import static org.apache.tsfile.read.common.type.LongType.INT64; import static org.apache.tsfile.read.common.type.UnknownType.UNKNOWN; @@ -369,6 +371,11 @@ protected Type visitDoubleLiteral(DoubleLiteral node, Context context) { return setExpressionType(node, DOUBLE); } + @Override + protected Type visitFloatLiteral(FloatLiteral node, Context context) { + return setExpressionType(node, FLOAT); + } + @Override protected Type visitBooleanLiteral(BooleanLiteral node, Context context) { return setExpressionType(node, BOOLEAN); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LiteralEncoder.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LiteralEncoder.java index 71561c3668f76..dab0584413f85 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LiteralEncoder.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LiteralEncoder.java @@ -24,6 +24,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Cast; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LongLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.NullLiteral; @@ -92,10 +93,14 @@ public Expression toExpression(@Nullable Object object, Type type) { return new LongLiteral(object.toString()); } - if (type.equals(FLOAT) || type.equals(DOUBLE)) { + if (type.equals(DOUBLE)) { return new DoubleLiteral(((Number) object).doubleValue()); } + if (type.equals(FLOAT)) { + return new FloatLiteral(((Number) object).floatValue()); + } + if (isBool(type)) { return new BooleanLiteral(object.toString()); } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LiteralInterpreter.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LiteralInterpreter.java index 2abcf530ca8f7..d43b9baa2a244 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LiteralInterpreter.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LiteralInterpreter.java @@ -26,6 +26,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BooleanLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Literal; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LongLiteral; @@ -54,6 +55,7 @@ public Object evaluate(Expression node, Type type) { if (!(node instanceof Literal)) { throw new IllegalArgumentException("node must be a Literal"); } + // return node.accept(new LiteralVisitor(type), null); return new LiteralVisitor(type).process(node, null); } @@ -84,6 +86,11 @@ protected Double visitDoubleLiteral(DoubleLiteral node, Void context) { return node.getValue(); } + @Override + protected Float visitFloatLiteral(FloatLiteral node, Void context) { + return node.getValue(); + } + @Override protected Binary visitStringLiteral(StringLiteral node, Void context) { return new Binary(node.getValue(), TSFileConfig.STRING_CHARSET); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/PredicateWithUncorrelatedScalarSubqueryReconstructor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/PredicateWithUncorrelatedScalarSubqueryReconstructor.java index cf6772fa1c238..56c4671fd7377 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/PredicateWithUncorrelatedScalarSubqueryReconstructor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/PredicateWithUncorrelatedScalarSubqueryReconstructor.java @@ -34,6 +34,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DereferenceExpression; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FunctionCall; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Identifier; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Literal; @@ -203,7 +204,7 @@ public Optional fetchUncorrelatedSubqueryResultForPredicate( case TIMESTAMP: return Optional.of(new LongLiteral(Long.toString(column.getLong(0)))); case FLOAT: - return Optional.of(new DoubleLiteral(Double.toString(column.getFloat(0)))); + return Optional.of(new FloatLiteral(column.getFloat(0))); case DOUBLE: return Optional.of(new DoubleLiteral(Double.toString(column.getDouble(0)))); case BOOLEAN: diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java index e8e5cce22ca93..13925ae392029 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java @@ -69,6 +69,10 @@ protected R visitDoubleLiteral(DoubleLiteral node, C context) { return visitLiteral(node, context); } + protected R visitFloatLiteral(FloatLiteral node, C context) { + return visitLiteral(node, context); + } + protected R visitDecimalLiteral(DecimalLiteral node, C context) { return visitLiteral(node, context); } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/Expression.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/Expression.java index f4bc64e25523e..26d12beecb139 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/Expression.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/Expression.java @@ -164,6 +164,9 @@ public static Expression deserialize(ByteBuffer byteBuffer) { case 32: expression = new Extract(byteBuffer); break; + case 33: + expression = new FloatLiteral(byteBuffer); + break; default: throw new IllegalArgumentException("Invalid expression type: " + type); } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/FloatLiteral.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/FloatLiteral.java new file mode 100644 index 0000000000000..1611eef84e2a8 --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/FloatLiteral.java @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.iotdb.db.queryengine.plan.relational.sql.ast; + +import org.apache.iotdb.db.exception.sql.SemanticException; + +import org.apache.tsfile.utils.RamUsageEstimator; +import org.apache.tsfile.utils.ReadWriteIOUtils; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; + +import static java.util.Objects.requireNonNull; + +public class FloatLiteral extends Literal { + + private static final long INSTANCE_SIZE = + RamUsageEstimator.shallowSizeOfInstance(FloatLiteral.class); + + private final float value; + + public FloatLiteral(String value) { + super(null); + this.value = Float.parseFloat(requireNonNull(value, "value is null")); + } + + public FloatLiteral(float value) { + super(null); + this.value = value; + } + + public FloatLiteral(NodeLocation location, String value) { + super(null); + throw new SemanticException("Currently the FloatLiteral cannot be created from NodeLocation"); + } + + public float getValue() { + return value; + } + + @Override + public R accept(AstVisitor visitor, C context) { + return visitor.visitFloatLiteral(this, context); + } + + @SuppressWarnings("UnaryPlus") + @Override + public int hashCode() { + return value != +0.0f ? Float.floatToIntBits(value) : 0; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + FloatLiteral that = (FloatLiteral) o; + return Float.compare(that.value, value) == 0; + } + + @Override + public boolean shallowEquals(Node other) { + if (!sameClass(this, other)) { + return false; + } + + return value == ((FloatLiteral) other).value; + } + + @Override + public TableExpressionType getExpressionType() { + return TableExpressionType.FLOAT_LITERAL; + } + + @Override + public void serialize(DataOutputStream stream) throws IOException { + ReadWriteIOUtils.write(this.value, stream); + } + + public FloatLiteral(ByteBuffer byteBuffer) { + super(null); + this.value = ReadWriteIOUtils.readFloat(byteBuffer); + } + + @Override + public Object getTsValue() { + return value; + } + + @Override + public long ramBytesUsed() { + return INSTANCE_SIZE + + AstMemoryEstimationHelper.getEstimatedSizeOfNodeLocation(getLocationInternal()); + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/TableExpressionType.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/TableExpressionType.java index 9d0b7ae0b4aa1..3d66db762b136 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/TableExpressionType.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/TableExpressionType.java @@ -51,7 +51,8 @@ public enum TableExpressionType { CURRENT_DATABASE((short) 29), CURRENT_USER((short) 30), ROW((short) 31), - EXTRACT((short) 32); + EXTRACT((short) 32), + FLOAT_LITERAL((short) 33); TableExpressionType(short type) { this.type = type; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/util/ExpressionFormatter.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/util/ExpressionFormatter.java index 9f1afa6a5f38b..23d1f585a858a 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/util/ExpressionFormatter.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/util/ExpressionFormatter.java @@ -41,6 +41,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Extract; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FieldReference; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FrameBound; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FunctionCall; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericDataType; @@ -233,6 +234,14 @@ protected String visitDoubleLiteral(DoubleLiteral node, Void context) { .orElseGet(() -> doubleFormatter.get().format(node.getValue())); } + // do not use doubleFormatter, to prevent from introducing the precision noise + @Override + protected String visitFloatLiteral(FloatLiteral node, Void context) { + return literalFormatter + .map(formatter -> formatter.apply(node)) + .orElseGet(() -> String.valueOf(node.getValue())); + } + @Override protected String visitDecimalLiteral(DecimalLiteral node, Void context) { return literalFormatter diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/ExpressionVerifier.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/ExpressionVerifier.java index babfd51e60628..bd7fc1adb7555 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/ExpressionVerifier.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/planner/assertions/ExpressionVerifier.java @@ -31,6 +31,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DereferenceExpression; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DoubleLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FloatLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FunctionCall; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.GenericLiteral; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.IfExpression; @@ -138,6 +139,15 @@ protected Boolean visitDoubleLiteral(DoubleLiteral actual, Expression expectedEx return getValueFromLiteral(actual).equals(getValueFromLiteral(expectedExpression)); } + @Override + protected Boolean visitFloatLiteral(FloatLiteral actual, Expression expectedExpression) { + if (!(expectedExpression instanceof FloatLiteral)) { + return false; + } + + return getValueFromLiteral(actual).equals(getValueFromLiteral(expectedExpression)); + } + @Override protected Boolean visitDecimalLiteral(DecimalLiteral actual, Expression expectedExpression) { if (!(expectedExpression instanceof DecimalLiteral)) { @@ -174,6 +184,10 @@ private static String getValueFromLiteral(Node expression) { return String.valueOf(((DoubleLiteral) expression).getValue()); } + if (expression instanceof FloatLiteral) { + return String.valueOf(((FloatLiteral) expression).getValue()); + } + if (expression instanceof DecimalLiteral) { return String.valueOf(((DecimalLiteral) expression).getValue()); }