Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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 {
Expand All @@ -1568,7 +1588,11 @@ private static InMultiColumnTransformer constructInColumnTransformer(
Set<Float> 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));
}
Expand All @@ -1578,7 +1602,11 @@ private static InMultiColumnTransformer constructInColumnTransformer(
Set<Double> 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));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -948,6 +950,12 @@ protected Type visitDoubleLiteral(
return setExpressionType(node, DOUBLE);
}

@Override
protected Type visitFloatLiteral(
FloatLiteral node, StackableAstVisitorContext<Context> context) {
return setExpressionType(node, FLOAT);
}

@Override
protected Type visitDecimalLiteral(
DecimalLiteral node, StackableAstVisitorContext<Context> context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -163,30 +164,38 @@ public static <T extends Comparable<T>> 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);
}
}

Expand Down Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down
Loading