blob: 025fdf0258e9b869d2b4bacaca3f09ba1d7a092e [file] [log] [blame]
/*
* 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.expression.multi.builtin.helper;
import org.apache.iotdb.db.exception.sql.SemanticException;
import org.apache.iotdb.db.queryengine.plan.expression.multi.FunctionExpression;
import org.apache.iotdb.db.queryengine.plan.expression.multi.builtin.BuiltInScalarFunctionHelper;
import org.apache.iotdb.db.queryengine.transformation.api.LayerPointReader;
import org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
import org.apache.iotdb.db.queryengine.transformation.dag.column.unary.scalar.CastFunctionColumnTransformer;
import org.apache.iotdb.db.queryengine.transformation.dag.transformer.Transformer;
import org.apache.iotdb.db.queryengine.transformation.dag.transformer.unary.scalar.CastFunctionTransformer;
import org.apache.tsfile.enums.TSDataType;
import org.apache.tsfile.read.common.type.TypeFactory;
import java.util.Map;
import static org.apache.iotdb.db.utils.constant.SqlConstant.CAST_TYPE;
public class CastFunctionHelper implements BuiltInScalarFunctionHelper {
@Override
public void checkBuiltInScalarFunctionInputDataType(TSDataType tsDataType)
throws SemanticException {
// needn't check
}
@Override
public TSDataType getBuiltInScalarFunctionReturnType(FunctionExpression functionExpression) {
if (!functionExpression.getFunctionAttributes().containsKey(CAST_TYPE)) {
throw new SemanticException("Function Cast must specify a target data type.");
}
return TSDataType.valueOf(
functionExpression.getFunctionAttributes().get(CAST_TYPE).toUpperCase());
}
@Override
public ColumnTransformer getBuiltInScalarFunctionColumnTransformer(
FunctionExpression expression, ColumnTransformer columnTransformer) {
return new CastFunctionColumnTransformer(
TypeFactory.getType(this.getBuiltInScalarFunctionReturnType(expression)),
columnTransformer);
}
@Override
public Transformer getBuiltInScalarFunctionTransformer(
FunctionExpression expression, LayerPointReader layerPointReader) {
return new CastFunctionTransformer(
layerPointReader, this.getBuiltInScalarFunctionReturnType(expression));
}
@Override
public void appendFunctionAttributes(
boolean hasExpression, StringBuilder builder, Map<String, String> functionAttributes) {
// Cast has only one attribute
builder.append(" AS ");
builder.append(functionAttributes.entrySet().iterator().next().getValue());
}
public static int castLongToInt(long value) {
if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) {
throw new SemanticException(
String.format("long value %d is out of range of integer value.", value));
}
return (int) value;
}
public static int castFloatToInt(float value) {
if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) {
throw new SemanticException(
String.format("Float value %f is out of range of integer value.", value));
}
return Math.round(value);
}
public static long castFloatToLong(float value) {
if (value > Long.MAX_VALUE || value < Long.MIN_VALUE) {
throw new SemanticException(
String.format("Float value %f is out of range of long value.", value));
}
return Math.round((double) value);
}
public static int castDoubleToInt(double value) {
if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) {
throw new SemanticException(
String.format("Double value %f is out of range of integer value.", value));
}
return Math.round((float) value);
}
public static long castDoubleToLong(double value) {
if (value > Long.MAX_VALUE || value < Long.MIN_VALUE) {
throw new SemanticException(
String.format("Double value %f is out of range of long value.", value));
}
return Math.round(value);
}
public static float castDoubleToFloat(double value) {
if (value > Float.MAX_VALUE || value < -Float.MAX_VALUE) {
throw new SemanticException(
String.format("Double value %f is out of range of float value.", value));
}
return (float) value;
}
public static float castTextToFloat(String value) {
float f = Float.parseFloat(value);
if (f == Float.POSITIVE_INFINITY || f == Float.NEGATIVE_INFINITY) {
throw new SemanticException(
String.format("Text value %s is out of range of float value.", value));
}
return f;
}
public static Double castTextToDouble(String value) {
double d = Double.parseDouble(value);
if (d == Double.POSITIVE_INFINITY || d == Double.NEGATIVE_INFINITY) {
throw new SemanticException(
String.format("Text value %s is out of range of double value.", value));
}
return d;
}
public static boolean castTextToBoolean(String value) {
String lowerCase = value.toLowerCase();
if (lowerCase.equals("true")) {
return true;
} else if (lowerCase.equals("false")) {
return false;
} else {
throw new SemanticException(String.format("Invalid text input for boolean type: %s", value));
}
}
}