This is an automated email from the ASF dual-hosted git repository.
rong pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new 487cc2d84e [IOTDB-3145] Support data type inferring in Expressions
(#5900)
487cc2d84e is described below
commit 487cc2d84e8b1848f694ff6d99ca33ec4921f41f
Author: Steve Yurong Su <[email protected]>
AuthorDate: Sun May 15 00:16:19 2022 +0800
[IOTDB-3145] Support data type inferring in Expressions (#5900)
Support data type inferring in Expressions
Support comparing BOOLEAN and TEXT
---
.../iotdb/db/integration/IoTDBArithmeticIT.java | 2 +-
.../iotdb/db/mpp/plan/analyze/TypeProvider.java | 4 +
.../iotdb/db/query/expression/Expression.java | 35 ++++++---
.../expression/binary/AdditionExpression.java | 2 +-
.../binary/ArithmeticBinaryExpression.java | 60 +++++++++++++++
.../expression/binary/CompareBinaryExpression.java | 85 ++++++++++++++++++++++
.../expression/binary/DivisionExpression.java | 2 +-
.../query/expression/binary/EqualToExpression.java | 2 +-
.../expression/binary/GreaterEqualExpression.java | 2 +-
.../expression/binary/GreaterThanExpression.java | 2 +-
.../expression/binary/LessEqualExpression.java | 2 +-
.../expression/binary/LessThanExpression.java | 2 +-
.../expression/binary/LogicAndExpression.java | 2 +-
...rExpression.java => LogicBinaryExpression.java} | 35 ++++-----
.../query/expression/binary/LogicOrExpression.java | 2 +-
.../query/expression/binary/ModuloExpression.java | 2 +-
.../binary/MultiplicationExpression.java | 2 +-
.../expression/binary/NonEqualExpression.java | 2 +-
.../expression/binary/SubtractionExpression.java | 2 +-
.../db/query/expression/leaf/ConstantOperand.java | 7 ++
.../query/expression/leaf/TimeSeriesOperand.java | 7 ++
.../db/query/expression/leaf/TimestampOperand.java | 7 ++
.../query/expression/multi/FunctionExpression.java | 33 +++++++++
.../db/query/expression/unary/InExpression.java | 11 +++
.../db/query/expression/unary/LikeExpression.java | 14 ++++
.../query/expression/unary/LogicNotExpression.java | 14 ++++
.../query/expression/unary/NegationExpression.java | 20 +++++
.../query/expression/unary/RegularExpression.java | 14 ++++
.../api/customizer/parameter/UDFParameters.java | 12 +++
.../query/udf/core/executor/UDTFTypeInferrer.java | 68 +++++++++++++++++
.../binary/ArithmeticBinaryTransformer.java | 9 ++-
.../binary/CompareBinaryTransformer.java | 60 ++++++++++++---
.../binary/CompareEqualToTransformer.java | 27 +++----
.../binary/CompareGreaterEqualTransformer.java | 17 ++++-
.../binary/CompareGreaterThanTransformer.java | 17 ++++-
.../binary/CompareLessEqualTransformer.java | 17 ++++-
.../binary/CompareLessThanTransformer.java | 17 ++++-
.../binary/CompareNonEqualTransformer.java | 26 +++----
.../transformer/binary/LogicBinaryTransformer.java | 10 +--
39 files changed, 552 insertions(+), 102 deletions(-)
diff --git
a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBArithmeticIT.java
b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBArithmeticIT.java
index 709494a978..f82d9ccb47 100644
---
a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBArithmeticIT.java
+++
b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBArithmeticIT.java
@@ -281,7 +281,7 @@ public class IoTDBArithmeticIT {
Statement statement = connection.createStatement()) {
statement.executeQuery("select s1 + s6 from root.sg.d1");
} catch (SQLException throwable) {
- assertTrue(throwable.getMessage().contains("Unsupported data type:
TEXT"));
+ assertTrue(throwable.getMessage().contains("Unsupported dataType:
TEXT"));
}
}
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/TypeProvider.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/TypeProvider.java
index 34d8acfc9a..6c70c44e2d 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/TypeProvider.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/TypeProvider.java
@@ -55,6 +55,10 @@ public class TypeProvider {
this.typeMap.put(path, dataType);
}
+ public boolean containsTypeInfoOf(String path) {
+ return typeMap.containsKey(path);
+ }
+
public void serialize(ByteBuffer byteBuffer) {
ReadWriteIOUtils.write(typeMap.size(), byteBuffer);
for (Map.Entry<String, TSDataType> entry : typeMap.entrySet()) {
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/Expression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/Expression.java
index 14d5007739..4dceb6106e 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/Expression.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/Expression.java
@@ -22,6 +22,8 @@ package org.apache.iotdb.db.query.expression;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.exception.sql.SemanticException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
import org.apache.iotdb.db.query.expression.binary.AdditionExpression;
import org.apache.iotdb.db.query.expression.binary.DivisionExpression;
@@ -56,6 +58,7 @@ import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.time.ZoneId;
+import java.util.Arrays;
import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;
@@ -108,6 +111,24 @@ public abstract class Expression {
public abstract void constructUdfExecutors(
Map<String, UDTFExecutor> expressionName2Executor, ZoneId zoneId);
+
/////////////////////////////////////////////////////////////////////////////////////////////////
+ // type inference
+
/////////////////////////////////////////////////////////////////////////////////////////////////
+ public abstract TSDataType inferTypes(TypeProvider typeProvider);
+
+ protected static void checkInputExpressionDataType(
+ String expressionString, TSDataType actual, TSDataType... expected) {
+ for (TSDataType type : expected) {
+ if (actual.equals(type)) {
+ return;
+ }
+ }
+ throw new SemanticException(
+ String.format(
+ "Invalid input expression data type. expression: %s, actual data
type: %s, expected data type(s): %s.",
+ expressionString, actual.name(), Arrays.toString(expected)));
+ }
+
/////////////////////////////////////////////////////////////////////////////////////////////////
// For expression evaluation DAG building
/////////////////////////////////////////////////////////////////////////////////////////////////
@@ -127,15 +148,6 @@ public abstract class Expression {
LayerMemoryAssigner memoryAssigner)
throws QueryProcessException, IOException;
-
/////////////////////////////////////////////////////////////////////////////////////////////////
- // getExpressions: returning DIRECT children expressions
-
/////////////////////////////////////////////////////////////////////////////////////////////////
-
- /**
- * returns the DIRECT children expressions if it has any, otherwise an EMPTY
list will be returned
- */
- public abstract List<Expression> getExpressions();
-
/////////////////////////////////////////////////////////////////////////////////////////////////
// isConstantOperand
/////////////////////////////////////////////////////////////////////////////////////////////////
@@ -246,6 +258,11 @@ public abstract class Expression {
}
}
+ /**
+ * returns the DIRECT children expressions if it has any, otherwise an EMPTY
list will be returned
+ */
+ public abstract List<Expression> getExpressions();
+
/////////////////////////////////////////////////////////////////////////////////////////////////
// serialize & deserialize
/////////////////////////////////////////////////////////////////////////////////////////////////
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/AdditionExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/AdditionExpression.java
index 6ec5ce8399..6fd5e698fc 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/AdditionExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/AdditionExpression.java
@@ -27,7 +27,7 @@ import
org.apache.iotdb.db.query.udf.core.transformer.binary.ArithmeticBinaryTra
import java.nio.ByteBuffer;
-public class AdditionExpression extends BinaryExpression {
+public class AdditionExpression extends ArithmeticBinaryExpression {
public AdditionExpression(Expression leftExpression, Expression
rightExpression) {
super(leftExpression, rightExpression);
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/ArithmeticBinaryExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/ArithmeticBinaryExpression.java
new file mode 100644
index 0000000000..185a8ce617
--- /dev/null
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/ArithmeticBinaryExpression.java
@@ -0,0 +1,60 @@
+/*
+ * 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.query.expression.binary;
+
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
+import org.apache.iotdb.db.query.expression.Expression;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+
+import java.nio.ByteBuffer;
+
+public abstract class ArithmeticBinaryExpression extends BinaryExpression {
+
+ protected ArithmeticBinaryExpression(Expression leftExpression, Expression
rightExpression) {
+ super(leftExpression, rightExpression);
+ }
+
+ protected ArithmeticBinaryExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ }
+
+ @Override
+ public final TSDataType inferTypes(TypeProvider typeProvider) {
+ final String expressionString = toString();
+ if (!typeProvider.containsTypeInfoOf(expressionString)) {
+ checkInputExpressionDataType(
+ leftExpression.toString(),
+ leftExpression.inferTypes(typeProvider),
+ TSDataType.INT32,
+ TSDataType.INT64,
+ TSDataType.FLOAT,
+ TSDataType.DOUBLE);
+ checkInputExpressionDataType(
+ rightExpression.toString(),
+ rightExpression.inferTypes(typeProvider),
+ TSDataType.INT32,
+ TSDataType.INT64,
+ TSDataType.FLOAT,
+ TSDataType.DOUBLE);
+ typeProvider.setType(expressionString, TSDataType.DOUBLE);
+ }
+ return TSDataType.DOUBLE;
+ }
+}
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/CompareBinaryExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/CompareBinaryExpression.java
new file mode 100644
index 0000000000..66f795faa1
--- /dev/null
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/CompareBinaryExpression.java
@@ -0,0 +1,85 @@
+/*
+ * 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.query.expression.binary;
+
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
+import org.apache.iotdb.db.query.expression.Expression;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+
+import java.nio.ByteBuffer;
+
+public abstract class CompareBinaryExpression extends BinaryExpression {
+
+ protected CompareBinaryExpression(Expression leftExpression, Expression
rightExpression) {
+ super(leftExpression, rightExpression);
+ }
+
+ protected CompareBinaryExpression(ByteBuffer byteBuffer) {
+ super(byteBuffer);
+ }
+
+ @Override
+ public TSDataType inferTypes(TypeProvider typeProvider) {
+ final String expressionString = toString();
+
+ if (!typeProvider.containsTypeInfoOf(expressionString)) {
+ final TSDataType leftExpressionDataType =
leftExpression.inferTypes(typeProvider);
+ final TSDataType rightExpressionDataType =
rightExpression.inferTypes(typeProvider);
+
+ if (!leftExpressionDataType.equals(rightExpressionDataType)) {
+ final String leftExpressionString = leftExpression.toString();
+ final String rightExpressionString = rightExpression.toString();
+
+ if (TSDataType.BOOLEAN.equals(leftExpressionDataType)
+ || TSDataType.BOOLEAN.equals(rightExpressionDataType)) {
+ checkInputExpressionDataType(
+ leftExpressionString, leftExpressionDataType,
TSDataType.BOOLEAN);
+ checkInputExpressionDataType(
+ rightExpressionString, rightExpressionDataType,
TSDataType.BOOLEAN);
+ } else if (TSDataType.TEXT.equals(leftExpressionDataType)
+ || TSDataType.TEXT.equals(rightExpressionDataType)) {
+ checkInputExpressionDataType(
+ leftExpressionString, leftExpressionDataType, TSDataType.TEXT);
+ checkInputExpressionDataType(
+ rightExpressionString, rightExpressionDataType, TSDataType.TEXT);
+ } else {
+ checkInputExpressionDataType(
+ leftExpressionString,
+ leftExpressionDataType,
+ TSDataType.INT32,
+ TSDataType.INT64,
+ TSDataType.FLOAT,
+ TSDataType.DOUBLE);
+ checkInputExpressionDataType(
+ rightExpressionString,
+ rightExpressionDataType,
+ TSDataType.INT32,
+ TSDataType.INT64,
+ TSDataType.FLOAT,
+ TSDataType.DOUBLE);
+ }
+ }
+
+ typeProvider.setType(expressionString, TSDataType.BOOLEAN);
+ }
+
+ return TSDataType.BOOLEAN;
+ }
+}
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/DivisionExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/DivisionExpression.java
index 5ba106f459..8eb9308d91 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/DivisionExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/DivisionExpression.java
@@ -27,7 +27,7 @@ import
org.apache.iotdb.db.query.udf.core.transformer.binary.ArithmeticDivisionT
import java.nio.ByteBuffer;
-public class DivisionExpression extends BinaryExpression {
+public class DivisionExpression extends ArithmeticBinaryExpression {
public DivisionExpression(Expression leftExpression, Expression
rightExpression) {
super(leftExpression, rightExpression);
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/EqualToExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/EqualToExpression.java
index aa85becd07..d966284402 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/EqualToExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/EqualToExpression.java
@@ -27,7 +27,7 @@ import
org.apache.iotdb.db.query.udf.core.transformer.binary.CompareEqualToTrans
import java.nio.ByteBuffer;
-public class EqualToExpression extends BinaryExpression {
+public class EqualToExpression extends CompareBinaryExpression {
public EqualToExpression(Expression leftExpression, Expression
rightExpression) {
super(leftExpression, rightExpression);
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterEqualExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterEqualExpression.java
index 0364212ac8..6d06a29284 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterEqualExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterEqualExpression.java
@@ -27,7 +27,7 @@ import
org.apache.iotdb.db.query.udf.core.transformer.binary.CompareGreaterEqual
import java.nio.ByteBuffer;
-public class GreaterEqualExpression extends BinaryExpression {
+public class GreaterEqualExpression extends CompareBinaryExpression {
public GreaterEqualExpression(Expression leftExpression, Expression
rightExpression) {
super(leftExpression, rightExpression);
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterThanExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterThanExpression.java
index 56589b5e10..6a574f68e9 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterThanExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/GreaterThanExpression.java
@@ -27,7 +27,7 @@ import
org.apache.iotdb.db.query.udf.core.transformer.binary.CompareGreaterThanT
import java.nio.ByteBuffer;
-public class GreaterThanExpression extends BinaryExpression {
+public class GreaterThanExpression extends CompareBinaryExpression {
public GreaterThanExpression(Expression leftExpression, Expression
rightExpression) {
super(leftExpression, rightExpression);
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessEqualExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessEqualExpression.java
index 599a05f67b..a0fff83b49 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessEqualExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessEqualExpression.java
@@ -27,7 +27,7 @@ import
org.apache.iotdb.db.query.udf.core.transformer.binary.CompareLessEqualTra
import java.nio.ByteBuffer;
-public class LessEqualExpression extends BinaryExpression {
+public class LessEqualExpression extends CompareBinaryExpression {
public LessEqualExpression(Expression leftExpression, Expression
rightExpression) {
super(leftExpression, rightExpression);
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessThanExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessThanExpression.java
index 1852771e8e..8f49780392 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessThanExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LessThanExpression.java
@@ -27,7 +27,7 @@ import
org.apache.iotdb.db.query.udf.core.transformer.binary.CompareLessThanTran
import java.nio.ByteBuffer;
-public class LessThanExpression extends BinaryExpression {
+public class LessThanExpression extends CompareBinaryExpression {
public LessThanExpression(Expression leftExpression, Expression
rightExpression) {
super(leftExpression, rightExpression);
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicAndExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicAndExpression.java
index 35f19c258b..26ac76b3c2 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicAndExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicAndExpression.java
@@ -27,7 +27,7 @@ import
org.apache.iotdb.db.query.udf.core.transformer.binary.LogicBinaryTransfor
import java.nio.ByteBuffer;
-public class LogicAndExpression extends BinaryExpression {
+public class LogicAndExpression extends LogicBinaryExpression {
public LogicAndExpression(Expression leftExpression, Expression
rightExpression) {
super(leftExpression, rightExpression);
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicOrExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicBinaryExpression.java
similarity index 53%
copy from
server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicOrExpression.java
copy to
server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicBinaryExpression.java
index ee0609ae16..9ad7e20bfa 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicOrExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicBinaryExpression.java
@@ -19,37 +19,32 @@
package org.apache.iotdb.db.query.expression.binary;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
import org.apache.iotdb.db.query.expression.Expression;
-import org.apache.iotdb.db.query.expression.ExpressionType;
-import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
-import
org.apache.iotdb.db.query.udf.core.transformer.binary.LogicBinaryTransformer;
-import
org.apache.iotdb.db.query.udf.core.transformer.binary.LogicOrTransformer;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import java.nio.ByteBuffer;
-public class LogicOrExpression extends BinaryExpression {
+public abstract class LogicBinaryExpression extends BinaryExpression {
- public LogicOrExpression(Expression leftExpression, Expression
rightExpression) {
+ protected LogicBinaryExpression(Expression leftExpression, Expression
rightExpression) {
super(leftExpression, rightExpression);
}
- public LogicOrExpression(ByteBuffer byteBuffer) {
+ protected LogicBinaryExpression(ByteBuffer byteBuffer) {
super(byteBuffer);
}
@Override
- protected LogicBinaryTransformer constructTransformer(
- LayerPointReader leftParentLayerPointReader, LayerPointReader
rightParentLayerPointReader) {
- return new LogicOrTransformer(leftParentLayerPointReader,
rightParentLayerPointReader);
- }
-
- @Override
- protected String operator() {
- return "|";
- }
-
- @Override
- public ExpressionType getExpressionType() {
- return ExpressionType.LOGIC_OR;
+ public final TSDataType inferTypes(TypeProvider typeProvider) {
+ final String expressionString = toString();
+ if (!typeProvider.containsTypeInfoOf(expressionString)) {
+ checkInputExpressionDataType(
+ leftExpression.toString(), leftExpression.inferTypes(typeProvider),
TSDataType.BOOLEAN);
+ checkInputExpressionDataType(
+ rightExpression.toString(),
rightExpression.inferTypes(typeProvider), TSDataType.BOOLEAN);
+ typeProvider.setType(expressionString, TSDataType.BOOLEAN);
+ }
+ return TSDataType.BOOLEAN;
}
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicOrExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicOrExpression.java
index ee0609ae16..eff1d56357 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicOrExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/LogicOrExpression.java
@@ -27,7 +27,7 @@ import
org.apache.iotdb.db.query.udf.core.transformer.binary.LogicOrTransformer;
import java.nio.ByteBuffer;
-public class LogicOrExpression extends BinaryExpression {
+public class LogicOrExpression extends LogicBinaryExpression {
public LogicOrExpression(Expression leftExpression, Expression
rightExpression) {
super(leftExpression, rightExpression);
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/ModuloExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/ModuloExpression.java
index e43f23f3c5..39f4738aca 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/ModuloExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/ModuloExpression.java
@@ -27,7 +27,7 @@ import
org.apache.iotdb.db.query.udf.core.transformer.binary.ArithmeticModuloTra
import java.nio.ByteBuffer;
-public class ModuloExpression extends BinaryExpression {
+public class ModuloExpression extends ArithmeticBinaryExpression {
public ModuloExpression(Expression leftExpression, Expression
rightExpression) {
super(leftExpression, rightExpression);
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/MultiplicationExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/MultiplicationExpression.java
index d5b15dc55d..6b72d5a2d2 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/MultiplicationExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/MultiplicationExpression.java
@@ -27,7 +27,7 @@ import
org.apache.iotdb.db.query.udf.core.transformer.binary.ArithmeticMultiplic
import java.nio.ByteBuffer;
-public class MultiplicationExpression extends BinaryExpression {
+public class MultiplicationExpression extends ArithmeticBinaryExpression {
public MultiplicationExpression(Expression leftExpression, Expression
rightExpression) {
super(leftExpression, rightExpression);
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/NonEqualExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/NonEqualExpression.java
index 6c9337fa57..542d4a7c25 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/NonEqualExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/NonEqualExpression.java
@@ -27,7 +27,7 @@ import
org.apache.iotdb.db.query.udf.core.transformer.binary.CompareNonEqualTran
import java.nio.ByteBuffer;
-public class NonEqualExpression extends BinaryExpression {
+public class NonEqualExpression extends CompareBinaryExpression {
public NonEqualExpression(Expression leftExpression, Expression
rightExpression) {
super(leftExpression, rightExpression);
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/SubtractionExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/SubtractionExpression.java
index 3e31ad9039..372d56cc73 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/binary/SubtractionExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/binary/SubtractionExpression.java
@@ -27,7 +27,7 @@ import
org.apache.iotdb.db.query.udf.core.transformer.binary.ArithmeticSubtracti
import java.nio.ByteBuffer;
-public class SubtractionExpression extends BinaryExpression {
+public class SubtractionExpression extends ArithmeticBinaryExpression {
public SubtractionExpression(Expression leftExpression, Expression
rightExpression) {
super(leftExpression, rightExpression);
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/ConstantOperand.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/ConstantOperand.java
index d92c8021c3..7acd877fc0 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/ConstantOperand.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/ConstantOperand.java
@@ -21,6 +21,7 @@ package org.apache.iotdb.db.query.expression.leaf;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
import org.apache.iotdb.db.query.expression.Expression;
import org.apache.iotdb.db.query.expression.ExpressionType;
@@ -91,6 +92,12 @@ public class ConstantOperand extends LeafOperand {
// Do nothing
}
+ @Override
+ public TSDataType inferTypes(TypeProvider typeProvider) {
+ typeProvider.setType(toString(), dataType);
+ return dataType;
+ }
+
@Override
public void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
// Do nothing
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimeSeriesOperand.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimeSeriesOperand.java
index 11a6b72912..5d896a932f 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimeSeriesOperand.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimeSeriesOperand.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
import org.apache.iotdb.db.exception.query.QueryProcessException;
import org.apache.iotdb.db.metadata.path.PathDeserializeUtil;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
import org.apache.iotdb.db.query.expression.Expression;
import org.apache.iotdb.db.query.expression.ExpressionType;
@@ -87,6 +88,11 @@ public class TimeSeriesOperand extends LeafOperand {
pathSet.add(path);
}
+ @Override
+ public TSDataType inferTypes(TypeProvider typeProvider) {
+ return typeProvider.getType(toString());
+ }
+
@Override
public void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
inputColumnIndex = udtfPlan.getReaderIndexByExpressionName(toString());
@@ -125,6 +131,7 @@ public class TimeSeriesOperand extends LeafOperand {
return expressionIntermediateLayerMap.get(this);
}
+ @Override
public String getExpressionStringInternal() {
return path.isMeasurementAliasExists() ? path.getFullPathWithAlias() :
path.getFullPath();
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimestampOperand.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimestampOperand.java
index 73c77a2b37..bb473451b7 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimestampOperand.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/leaf/TimestampOperand.java
@@ -22,6 +22,7 @@ package org.apache.iotdb.db.query.expression.leaf;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
import org.apache.iotdb.db.query.expression.Expression;
import org.apache.iotdb.db.query.expression.ExpressionType;
@@ -75,6 +76,12 @@ public class TimestampOperand extends LeafOperand {
pathSet.add(TIMESTAMP_PARTIAL_PATH);
}
+ @Override
+ public TSDataType inferTypes(TypeProvider typeProvider) {
+ typeProvider.setType(toString(), TSDataType.INT64);
+ return TSDataType.INT64;
+ }
+
@Override
public void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
// do nothing
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/multi/FunctionExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/multi/FunctionExpression.java
index b2bd93b05c..0ec226403f 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/multi/FunctionExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/multi/FunctionExpression.java
@@ -23,6 +23,8 @@ import org.apache.iotdb.commons.conf.IoTDBConstant;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.exception.sql.SemanticException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
import org.apache.iotdb.db.qp.constant.SQLConstant;
import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
import org.apache.iotdb.db.qp.strategy.optimizer.ConcatPathOptimizer;
@@ -32,6 +34,7 @@ import
org.apache.iotdb.db.query.expression.leaf.TimeSeriesOperand;
import org.apache.iotdb.db.query.udf.api.customizer.strategy.AccessStrategy;
import org.apache.iotdb.db.query.udf.core.executor.UDTFContext;
import org.apache.iotdb.db.query.udf.core.executor.UDTFExecutor;
+import org.apache.iotdb.db.query.udf.core.executor.UDTFTypeInferrer;
import org.apache.iotdb.db.query.udf.core.layer.IntermediateLayer;
import org.apache.iotdb.db.query.udf.core.layer.LayerMemoryAssigner;
import
org.apache.iotdb.db.query.udf.core.layer.MultiInputColumnIntermediateLayer;
@@ -43,6 +46,7 @@ import
org.apache.iotdb.db.query.udf.core.transformer.multi.UDFQueryRowTransform
import
org.apache.iotdb.db.query.udf.core.transformer.multi.UDFQueryRowWindowTransformer;
import
org.apache.iotdb.db.query.udf.core.transformer.multi.UDFQueryTransformer;
import
org.apache.iotdb.db.query.udf.core.transformer.unary.TransparentTransformer;
+import org.apache.iotdb.db.utils.TypeInferenceUtils;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
@@ -238,6 +242,35 @@ public class FunctionExpression extends Expression {
expressionName2Executor.put(expressionString, new UDTFExecutor(this,
zoneId));
}
+ @Override
+ public TSDataType inferTypes(TypeProvider typeProvider) {
+ final String expressionString = toString();
+
+ if (!typeProvider.containsTypeInfoOf(expressionString)) {
+ for (Expression expression : expressions) {
+ expression.inferTypes(typeProvider);
+ }
+
+ if (isTimeSeriesGeneratingFunctionExpression()) {
+ typeProvider.setType(
+ expressionString, new
UDTFTypeInferrer(this).inferOutputType(typeProvider));
+ } else {
+ if (expressions.size() != 1) {
+ throw new SemanticException(
+ String.format(
+ "Builtin aggregation function only accepts 1 input
expression. Actual %d input expressions.",
+ expressions.size()));
+ }
+ typeProvider.setType(
+ expressionString,
+ TypeInferenceUtils.getAggrDataType(
+ functionName,
typeProvider.getType(expressions.get(0).toString())));
+ }
+ }
+
+ return typeProvider.getType(expressionString);
+ }
+
@Override
public void bindInputLayerColumnIndexWithExpression(UDTFPlan udtfPlan) {
for (Expression expression : expressions) {
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/InExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/InExpression.java
index 9f329b3728..979d4c2bbc 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/InExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/InExpression.java
@@ -19,11 +19,13 @@
package org.apache.iotdb.db.query.expression.unary;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
import org.apache.iotdb.db.query.expression.Expression;
import org.apache.iotdb.db.query.expression.ExpressionType;
import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
import org.apache.iotdb.db.query.udf.core.transformer.Transformer;
import org.apache.iotdb.db.query.udf.core.transformer.unary.InTransformer;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
import java.nio.ByteBuffer;
@@ -59,6 +61,15 @@ public class InExpression extends UnaryExpression {
return values;
}
+ @Override
+ public TSDataType inferTypes(TypeProvider typeProvider) {
+ final String expressionString = toString();
+ if (!typeProvider.containsTypeInfoOf(expressionString)) {
+ typeProvider.setType(expressionString,
expression.inferTypes(typeProvider));
+ }
+ return typeProvider.getType(expressionString);
+ }
+
@Override
protected String getExpressionStringInternal() {
StringBuilder valuesStringBuilder = new StringBuilder();
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/LikeExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/LikeExpression.java
index 2d91ac0720..0e94037e72 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/LikeExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/LikeExpression.java
@@ -19,11 +19,14 @@
package org.apache.iotdb.db.query.expression.unary;
+import org.apache.iotdb.db.exception.sql.SemanticException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
import org.apache.iotdb.db.query.expression.Expression;
import org.apache.iotdb.db.query.expression.ExpressionType;
import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
import org.apache.iotdb.db.query.udf.core.transformer.Transformer;
import org.apache.iotdb.db.query.udf.core.transformer.unary.RegularTransformer;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
import java.nio.ByteBuffer;
@@ -115,6 +118,17 @@ public class LikeExpression extends UnaryExpression {
return stringBuilder.toString();
}
+ @Override
+ public TSDataType inferTypes(TypeProvider typeProvider) throws
SemanticException {
+ final String expressionString = toString();
+ if (!typeProvider.containsTypeInfoOf(expressionString)) {
+ checkInputExpressionDataType(
+ expression.toString(), expression.inferTypes(typeProvider),
TSDataType.TEXT);
+ typeProvider.setType(expressionString, TSDataType.TEXT);
+ }
+ return TSDataType.TEXT;
+ }
+
@Override
protected String getExpressionStringInternal() {
return expression + " LIKE '" + pattern + "'";
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/LogicNotExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/LogicNotExpression.java
index 2c22a52841..a538e4a028 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/LogicNotExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/LogicNotExpression.java
@@ -19,6 +19,8 @@
package org.apache.iotdb.db.query.expression.unary;
+import org.apache.iotdb.db.exception.sql.SemanticException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
import org.apache.iotdb.db.query.expression.Expression;
import org.apache.iotdb.db.query.expression.ExpressionType;
import org.apache.iotdb.db.query.expression.leaf.ConstantOperand;
@@ -27,6 +29,7 @@ import
org.apache.iotdb.db.query.expression.multi.FunctionExpression;
import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
import org.apache.iotdb.db.query.udf.core.transformer.Transformer;
import
org.apache.iotdb.db.query.udf.core.transformer.unary.LogicNotTransformer;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import java.nio.ByteBuffer;
@@ -50,6 +53,17 @@ public class LogicNotExpression extends UnaryExpression {
return new LogicNotExpression(childExpression);
}
+ @Override
+ public TSDataType inferTypes(TypeProvider typeProvider) throws
SemanticException {
+ final String expressionString = toString();
+ if (!typeProvider.containsTypeInfoOf(expressionString)) {
+ checkInputExpressionDataType(
+ expression.toString(), expression.inferTypes(typeProvider),
TSDataType.BOOLEAN);
+ typeProvider.setType(expressionString, TSDataType.BOOLEAN);
+ }
+ return TSDataType.BOOLEAN;
+ }
+
@Override
public String getExpressionStringInternal() {
return expression instanceof FunctionExpression
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/NegationExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/NegationExpression.java
index 8e12a85a57..6d8c111078 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/NegationExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/NegationExpression.java
@@ -19,6 +19,8 @@
package org.apache.iotdb.db.query.expression.unary;
+import org.apache.iotdb.db.exception.sql.SemanticException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
import org.apache.iotdb.db.query.expression.Expression;
import org.apache.iotdb.db.query.expression.ExpressionType;
import org.apache.iotdb.db.query.expression.leaf.ConstantOperand;
@@ -27,6 +29,7 @@ import
org.apache.iotdb.db.query.expression.multi.FunctionExpression;
import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
import org.apache.iotdb.db.query.udf.core.transformer.Transformer;
import
org.apache.iotdb.db.query.udf.core.transformer.unary.ArithmeticNegationTransformer;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import java.nio.ByteBuffer;
@@ -50,6 +53,23 @@ public class NegationExpression extends UnaryExpression {
return new NegationExpression(childExpression);
}
+ @Override
+ public TSDataType inferTypes(TypeProvider typeProvider) throws
SemanticException {
+ final String expressionString = toString();
+ if (!typeProvider.containsTypeInfoOf(expressionString)) {
+ TSDataType inputExpressionType = expression.inferTypes(typeProvider);
+ checkInputExpressionDataType(
+ expression.toString(),
+ inputExpressionType,
+ TSDataType.INT32,
+ TSDataType.INT64,
+ TSDataType.FLOAT,
+ TSDataType.DOUBLE);
+ typeProvider.setType(expressionString, inputExpressionType);
+ }
+ return typeProvider.getType(expressionString);
+ }
+
@Override
public String getExpressionStringInternal() {
return expression instanceof TimeSeriesOperand
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/RegularExpression.java
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/RegularExpression.java
index f6027a9c8e..a8b30f0d5a 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/RegularExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/RegularExpression.java
@@ -19,11 +19,14 @@
package org.apache.iotdb.db.query.expression.unary;
+import org.apache.iotdb.db.exception.sql.SemanticException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
import org.apache.iotdb.db.query.expression.Expression;
import org.apache.iotdb.db.query.expression.ExpressionType;
import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
import org.apache.iotdb.db.query.udf.core.transformer.Transformer;
import org.apache.iotdb.db.query.udf.core.transformer.unary.RegularTransformer;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
import org.apache.commons.lang3.Validate;
@@ -72,6 +75,17 @@ public class RegularExpression extends UnaryExpression {
return new RegularExpression(childExpression, patternString, pattern);
}
+ @Override
+ public TSDataType inferTypes(TypeProvider typeProvider) throws
SemanticException {
+ final String expressionString = toString();
+ if (!typeProvider.containsTypeInfoOf(expressionString)) {
+ checkInputExpressionDataType(
+ expression.toString(), expression.inferTypes(typeProvider),
TSDataType.TEXT);
+ typeProvider.setType(expressionString, TSDataType.TEXT);
+ }
+ return TSDataType.TEXT;
+ }
+
@Override
protected String getExpressionStringInternal() {
return expression + " REGEXP '" + patternString + "'";
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/udf/api/customizer/parameter/UDFParameters.java
b/server/src/main/java/org/apache/iotdb/db/query/udf/api/customizer/parameter/UDFParameters.java
index 5f057ccf8d..9b9b6640f0 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/udf/api/customizer/parameter/UDFParameters.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/udf/api/customizer/parameter/UDFParameters.java
@@ -22,6 +22,7 @@ package
org.apache.iotdb.db.query.udf.api.customizer.parameter;
import org.apache.iotdb.commons.exception.MetadataException;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
import org.apache.iotdb.db.query.expression.Expression;
import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
import org.apache.iotdb.db.query.udf.api.UDTF;
@@ -63,6 +64,17 @@ public class UDFParameters {
}
}
+ public UDFParameters(FunctionExpression functionExpression, TypeProvider
typeProvider)
+ throws QueryProcessException {
+ expressions = functionExpression.getExpressions();
+ paths = functionExpression.getPaths();
+ attributes = functionExpression.getFunctionAttributes();
+ dataTypes = new ArrayList<>();
+ for (Expression expression : expressions) {
+ dataTypes.add(typeProvider.getType(expression.toString()));
+ }
+ }
+
public List<Expression> getExpressions() {
return expressions;
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/executor/UDTFTypeInferrer.java
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/executor/UDTFTypeInferrer.java
new file mode 100644
index 0000000000..ca7233906a
--- /dev/null
+++
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/executor/UDTFTypeInferrer.java
@@ -0,0 +1,68 @@
+/*
+ * 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.query.udf.core.executor;
+
+import org.apache.iotdb.db.exception.sql.SemanticException;
+import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
+import org.apache.iotdb.db.query.expression.multi.FunctionExpression;
+import org.apache.iotdb.db.query.udf.api.UDTF;
+import org.apache.iotdb.db.query.udf.api.customizer.config.UDTFConfigurations;
+import
org.apache.iotdb.db.query.udf.api.customizer.parameter.UDFParameterValidator;
+import org.apache.iotdb.db.query.udf.api.customizer.parameter.UDFParameters;
+import org.apache.iotdb.db.query.udf.service.UDFRegistrationService;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.time.ZoneId;
+
+public class UDTFTypeInferrer {
+
+ private static final Logger LOGGER =
LoggerFactory.getLogger(UDTFTypeInferrer.class);
+
+ protected final FunctionExpression expression;
+
+ public UDTFTypeInferrer(FunctionExpression expression) {
+ this.expression = expression;
+ }
+
+ public TSDataType inferOutputType(TypeProvider typeProvider) {
+ try {
+ UDTF udtf = (UDTF)
UDFRegistrationService.getInstance().reflect(expression);
+
+ UDFParameters parameters = new UDFParameters(expression, typeProvider);
+ udtf.validate(new UDFParameterValidator(parameters));
+
+ // use ZoneId.systemDefault() because UDF's data type is ZoneId
independent
+ UDTFConfigurations configurations = new
UDTFConfigurations(ZoneId.systemDefault());
+ udtf.beforeStart(parameters, configurations);
+
+ udtf.beforeDestroy();
+
+ return configurations.getOutputDataType();
+ } catch (Exception e) {
+ LOGGER.warn("Error occurred during inferring UDF data type", e);
+ throw new SemanticException(
+ String.format("Error occurred during inferring UDF data type: %s",
System.lineSeparator())
+ + e);
+ }
+ }
+}
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/ArithmeticBinaryTransformer.java
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/ArithmeticBinaryTransformer.java
index 29a17a1ee1..751fc534d6 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/ArithmeticBinaryTransformer.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/ArithmeticBinaryTransformer.java
@@ -35,11 +35,12 @@ public abstract class ArithmeticBinaryTransformer extends
BinaryTransformer {
@Override
protected void checkType() {
- if (leftPointReaderDataType == TSDataType.BOOLEAN) {
- throw new
UnSupportedDataTypeException(leftPointReader.getDataType().toString());
+ if (leftPointReaderDataType == TSDataType.BOOLEAN
+ || rightPointReaderDataType == TSDataType.BOOLEAN) {
+ throw new UnSupportedDataTypeException(TSDataType.BOOLEAN.name());
}
- if (rightPointReaderDataType == TSDataType.BOOLEAN) {
- throw new
UnSupportedDataTypeException(rightPointReader.getDataType().toString());
+ if (leftPointReaderDataType == TSDataType.TEXT || rightPointReaderDataType
== TSDataType.TEXT) {
+ throw new UnSupportedDataTypeException(TSDataType.TEXT.name());
}
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareBinaryTransformer.java
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareBinaryTransformer.java
index 90f506ddd7..42b42e1058 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareBinaryTransformer.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareBinaryTransformer.java
@@ -25,35 +25,73 @@ import
org.apache.iotdb.tsfile.exception.write.UnSupportedDataTypeException;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import java.io.IOException;
+import java.util.Objects;
public abstract class CompareBinaryTransformer extends BinaryTransformer {
+ @FunctionalInterface
+ protected interface Evaluator {
+
+ boolean evaluate() throws QueryProcessException, IOException;
+ }
+
+ protected final Evaluator evaluator;
+
protected CompareBinaryTransformer(
LayerPointReader leftPointReader, LayerPointReader rightPointReader)
throws UnSupportedDataTypeException {
super(leftPointReader, rightPointReader);
+ evaluator =
+ TSDataType.TEXT.equals(leftPointReaderDataType)
+ ? constructTextEvaluator()
+ : constructNumberEvaluator();
+ }
+
+ protected abstract Evaluator constructNumberEvaluator();
+
+ protected abstract Evaluator constructTextEvaluator();
+
+ protected static int compare(CharSequence cs1, CharSequence cs2) {
+ if (Objects.requireNonNull(cs1) == Objects.requireNonNull(cs2)) {
+ return 0;
+ }
+
+ if (cs1.getClass() == cs2.getClass() && cs1 instanceof Comparable) {
+ return ((Comparable<Object>) cs1).compareTo(cs2);
+ }
+
+ for (int i = 0, len = Math.min(cs1.length(), cs2.length()); i < len; i++) {
+ char a = cs1.charAt(i);
+ char b = cs2.charAt(i);
+ if (a != b) {
+ return a - b;
+ }
+ }
+
+ return cs1.length() - cs2.length();
}
@Override
- protected void checkType() {
- if (leftPointReaderDataType == TSDataType.BOOLEAN) {
- throw new
UnSupportedDataTypeException(leftPointReader.getDataType().toString());
+ protected final void checkType() {
+ if (leftPointReaderDataType.equals(rightPointReaderDataType)) {
+ return;
+ }
+
+ if (leftPointReaderDataType.equals(TSDataType.BOOLEAN)
+ || rightPointReaderDataType.equals(TSDataType.BOOLEAN)) {
+ throw new UnSupportedDataTypeException(TSDataType.BOOLEAN.toString());
}
- if (rightPointReaderDataType == TSDataType.BOOLEAN) {
- throw new
UnSupportedDataTypeException(rightPointReader.getDataType().toString());
+ if (leftPointReaderDataType.equals(TSDataType.TEXT)
+ || rightPointReaderDataType.equals(TSDataType.TEXT)) {
+ throw new UnSupportedDataTypeException(TSDataType.TEXT.toString());
}
}
@Override
protected final void transformAndCache() throws QueryProcessException,
IOException {
- cachedBoolean =
- evaluate(
- castCurrentValueToDoubleOperand(leftPointReader,
leftPointReaderDataType),
- castCurrentValueToDoubleOperand(rightPointReader,
rightPointReaderDataType));
+ cachedBoolean = evaluator.evaluate();
}
- abstract boolean evaluate(double leftOperand, double rightOperand);
-
@Override
public TSDataType getDataType() {
return TSDataType.BOOLEAN;
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareEqualToTransformer.java
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareEqualToTransformer.java
index 8484df276c..af6b2c8d65 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareEqualToTransformer.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareEqualToTransformer.java
@@ -20,8 +20,6 @@
package org.apache.iotdb.db.query.udf.core.transformer.binary;
import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
-import org.apache.iotdb.tsfile.exception.write.UnSupportedDataTypeException;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
public class CompareEqualToTransformer extends CompareBinaryTransformer {
@@ -31,21 +29,20 @@ public class CompareEqualToTransformer extends
CompareBinaryTransformer {
}
@Override
- protected void checkType() {
- if ((leftPointReaderDataType == TSDataType.BOOLEAN
- && rightPointReaderDataType != TSDataType.BOOLEAN)
- || (leftPointReaderDataType != TSDataType.BOOLEAN
- && rightPointReaderDataType == TSDataType.BOOLEAN)) {
- throw new UnSupportedDataTypeException(
- "left: "
- + leftPointReaderDataType.toString()
- + ", right: "
- + rightPointReaderDataType.toString());
- }
+ protected Evaluator constructNumberEvaluator() {
+ return () ->
+ Double.compare(
+ castCurrentValueToDoubleOperand(leftPointReader,
leftPointReaderDataType),
+ castCurrentValueToDoubleOperand(rightPointReader,
rightPointReaderDataType))
+ == 0;
}
@Override
- protected boolean evaluate(double leftOperand, double rightOperand) {
- return Double.compare(leftOperand, rightOperand) == 0;
+ protected Evaluator constructTextEvaluator() {
+ return () ->
+ compare(
+ leftPointReader.currentBinary().getStringValue(),
+ rightPointReader.currentBinary().getStringValue())
+ == 0;
}
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareGreaterEqualTransformer.java
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareGreaterEqualTransformer.java
index 7854143cff..1e98bfe423 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareGreaterEqualTransformer.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareGreaterEqualTransformer.java
@@ -29,7 +29,20 @@ public class CompareGreaterEqualTransformer extends
CompareBinaryTransformer {
}
@Override
- protected boolean evaluate(double leftOperand, double rightOperand) {
- return Double.compare(leftOperand, rightOperand) >= 0;
+ protected Evaluator constructNumberEvaluator() {
+ return () ->
+ Double.compare(
+ castCurrentValueToDoubleOperand(leftPointReader,
leftPointReaderDataType),
+ castCurrentValueToDoubleOperand(rightPointReader,
rightPointReaderDataType))
+ >= 0;
+ }
+
+ @Override
+ protected Evaluator constructTextEvaluator() {
+ return () ->
+ compare(
+ leftPointReader.currentBinary().getStringValue(),
+ rightPointReader.currentBinary().getStringValue())
+ >= 0;
}
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareGreaterThanTransformer.java
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareGreaterThanTransformer.java
index 627c4b17bf..9e7a5ea3ba 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareGreaterThanTransformer.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareGreaterThanTransformer.java
@@ -29,7 +29,20 @@ public class CompareGreaterThanTransformer extends
CompareBinaryTransformer {
}
@Override
- protected boolean evaluate(double leftOperand, double rightOperand) {
- return Double.compare(leftOperand, rightOperand) > 0;
+ protected Evaluator constructNumberEvaluator() {
+ return () ->
+ Double.compare(
+ castCurrentValueToDoubleOperand(leftPointReader,
leftPointReaderDataType),
+ castCurrentValueToDoubleOperand(rightPointReader,
rightPointReaderDataType))
+ > 0;
+ }
+
+ @Override
+ protected Evaluator constructTextEvaluator() {
+ return () ->
+ compare(
+ leftPointReader.currentBinary().getStringValue(),
+ rightPointReader.currentBinary().getStringValue())
+ > 0;
}
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareLessEqualTransformer.java
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareLessEqualTransformer.java
index 2b00dca3fb..0c53e86949 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareLessEqualTransformer.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareLessEqualTransformer.java
@@ -29,7 +29,20 @@ public class CompareLessEqualTransformer extends
CompareBinaryTransformer {
}
@Override
- protected boolean evaluate(double leftOperand, double rightOperand) {
- return Double.compare(leftOperand, rightOperand) <= 0;
+ protected Evaluator constructNumberEvaluator() {
+ return () ->
+ Double.compare(
+ castCurrentValueToDoubleOperand(leftPointReader,
leftPointReaderDataType),
+ castCurrentValueToDoubleOperand(rightPointReader,
rightPointReaderDataType))
+ <= 0;
+ }
+
+ @Override
+ protected Evaluator constructTextEvaluator() {
+ return () ->
+ compare(
+ leftPointReader.currentBinary().getStringValue(),
+ rightPointReader.currentBinary().getStringValue())
+ <= 0;
}
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareLessThanTransformer.java
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareLessThanTransformer.java
index ea2ebeded5..9e77e2aa21 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareLessThanTransformer.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareLessThanTransformer.java
@@ -29,7 +29,20 @@ public class CompareLessThanTransformer extends
CompareBinaryTransformer {
}
@Override
- protected boolean evaluate(double leftOperand, double rightOperand) {
- return Double.compare(leftOperand, rightOperand) < 0;
+ protected Evaluator constructNumberEvaluator() {
+ return () ->
+ Double.compare(
+ castCurrentValueToDoubleOperand(leftPointReader,
leftPointReaderDataType),
+ castCurrentValueToDoubleOperand(rightPointReader,
rightPointReaderDataType))
+ < 0;
+ }
+
+ @Override
+ protected Evaluator constructTextEvaluator() {
+ return () ->
+ compare(
+ leftPointReader.currentBinary().getStringValue(),
+ rightPointReader.currentBinary().getStringValue())
+ < 0;
}
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareNonEqualTransformer.java
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareNonEqualTransformer.java
index 795b011bdc..024c54deb5 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareNonEqualTransformer.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/CompareNonEqualTransformer.java
@@ -21,7 +21,6 @@ package org.apache.iotdb.db.query.udf.core.transformer.binary;
import org.apache.iotdb.db.query.udf.core.reader.LayerPointReader;
import org.apache.iotdb.tsfile.exception.write.UnSupportedDataTypeException;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
public class CompareNonEqualTransformer extends CompareBinaryTransformer {
@@ -32,21 +31,20 @@ public class CompareNonEqualTransformer extends
CompareBinaryTransformer {
}
@Override
- protected void checkType() {
- if ((leftPointReaderDataType == TSDataType.BOOLEAN
- && rightPointReaderDataType != TSDataType.BOOLEAN)
- || (leftPointReaderDataType != TSDataType.BOOLEAN
- && rightPointReaderDataType == TSDataType.BOOLEAN)) {
- throw new UnSupportedDataTypeException(
- "left: "
- + leftPointReaderDataType.toString()
- + ", right: "
- + rightPointReaderDataType.toString());
- }
+ protected Evaluator constructNumberEvaluator() {
+ return () ->
+ Double.compare(
+ castCurrentValueToDoubleOperand(leftPointReader,
leftPointReaderDataType),
+ castCurrentValueToDoubleOperand(rightPointReader,
rightPointReaderDataType))
+ != 0;
}
@Override
- protected boolean evaluate(double leftOperand, double rightOperand) {
- return Double.compare(leftOperand, rightOperand) != 0;
+ protected Evaluator constructTextEvaluator() {
+ return () ->
+ compare(
+ leftPointReader.currentBinary().getStringValue(),
+ rightPointReader.currentBinary().getStringValue())
+ != 0;
}
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/LogicBinaryTransformer.java
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/LogicBinaryTransformer.java
index d8e1a36012..7eee752775 100644
---
a/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/LogicBinaryTransformer.java
+++
b/server/src/main/java/org/apache/iotdb/db/query/udf/core/transformer/binary/LogicBinaryTransformer.java
@@ -35,13 +35,9 @@ public abstract class LogicBinaryTransformer extends
BinaryTransformer {
@Override
protected void checkType() {
- if (leftPointReaderDataType != TSDataType.BOOLEAN) {
- throw new UnSupportedDataTypeException(
- "Unsupported data type: " +
leftPointReader.getDataType().toString());
- }
- if (rightPointReaderDataType != TSDataType.BOOLEAN) {
- throw new UnSupportedDataTypeException(
- "Unsupported data type: " +
rightPointReader.getDataType().toString());
+ if (leftPointReaderDataType != TSDataType.BOOLEAN
+ || rightPointReaderDataType != TSDataType.BOOLEAN) {
+ throw new UnSupportedDataTypeException("Unsupported data type: " +
TSDataType.BOOLEAN);
}
}