This is an automated email from the ASF dual-hosted git repository.
jackietien 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 861339b1558 Support expression in InPredicate & Unify error msg for
type timestamp in round function
861339b1558 is described below
commit 861339b15580a5c6391a636c08c2aa66a6789975
Author: Jackie Tien <[email protected]>
AuthorDate: Tue Aug 27 14:23:32 2024 +0800
Support expression in InPredicate & Unify error msg for type timestamp in
round function
---
.../scalar/IoTDBRoundFunctionTableIT.java | 6 ++
.../it/query/old/query/IoTDBInTableIT.java | 79 ++++++++++++---
.../relational/ColumnTransformerBuilder.java | 107 ++++++++++++++++++++-
.../PredicateCombineIntoTableScanChecker.java | 18 +++-
.../PredicatePushIntoMetadataChecker.java | 3 +-
.../relational/metadata/TableMetadataImpl.java | 15 ++-
.../multi/InBinaryMultiColumnTransformer.java | 59 ++++++++++++
.../multi/InBooleanMultiColumnTransformer.java | 58 +++++++++++
.../multi/InDoubleMultiColumnTransformer.java | 58 +++++++++++
.../multi/InFloatMultiColumnTransformer.java | 58 +++++++++++
.../multi/InInt32MultiColumnTransformer.java | 58 +++++++++++
.../multi/InInt64MultiColumnTransformer.java | 58 +++++++++++
.../dag/column/multi/InMultiColumnTransformer.java | 54 +++++++++++
.../dag/column/unary/InColumnTransformer.java | 41 ++++----
pom.xml | 2 +-
15 files changed, 630 insertions(+), 44 deletions(-)
diff --git
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBRoundFunctionTableIT.java
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBRoundFunctionTableIT.java
index c90e2659d63..25baece8d53 100644
---
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBRoundFunctionTableIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/builtinfunction/scalar/IoTDBRoundFunctionTableIT.java
@@ -309,5 +309,11 @@ public class IoTDBRoundFunctionTableIT {
TSStatusCode.SEMANTIC_ERROR.getStatusCode()
+ ": Scalar function round only supports two numeric data types
[INT32, INT64, FLOAT, DOUBLE]",
DATABASE_NAME);
+
+ tableAssertTestFail(
+ "select round(time) from table1",
+ TSStatusCode.SEMANTIC_ERROR.getStatusCode()
+ + ": Scalar function round only supports two numeric data types
[INT32, INT64, FLOAT, DOUBLE]",
+ DATABASE_NAME);
}
}
diff --git
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/query/IoTDBInTableIT.java
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/query/IoTDBInTableIT.java
index 9a4a5a144f5..018405bcc92 100644
---
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/query/IoTDBInTableIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/query/IoTDBInTableIT.java
@@ -57,19 +57,19 @@ public class IoTDBInTableIT {
new String[] {
"CREATE DATABASE " + DATABASE_NAME,
"USE " + DATABASE_NAME,
- "CREATE TABLE sg(device1 STRING ID, device2 STRING ID, qrcode TEXT
MEASUREMENT)",
- "insert into sg(time,device1,device2,qrcode)
values(1509465600000,'d1','s1','qrcode001')",
- "insert into sg(time,device1,device2,qrcode)
values(1509465660000,'d1','s1','qrcode002')",
- "insert into sg(time,device1,device2,qrcode)
values(1509465720000,'d1','s1','qrcode003')",
- "insert into sg(time,device1,device2,qrcode)
values(1509465780000,'d1','s1','qrcode004')",
- "insert into sg(time,device1,device2,qrcode)
values(1509465720000,'d1','s2','qrcode002')",
- "insert into sg(time,device1,device2,qrcode)
values(1509465780000,'d1','s2','qrcode003')",
- "insert into sg(time,device1,device2,qrcode)
values(1509465840000,'d1','s2','qrcode004')",
- "insert into sg(time,device1,device2,qrcode)
values(1509465900000,'d1','s2','qrcode005')",
- "insert into sg(time,device1,device2,qrcode)
values(1509465780000,'d2','s1','qrcode002')",
- "insert into sg(time,device1,device2,qrcode)
values(1509465840000,'d2','s1','qrcode003')",
- "insert into sg(time,device1,device2,qrcode)
values(1509465900000,'d2','s1','qrcode004')",
- "insert into sg(time,device1,device2,qrcode)
values(1509465960000,'d2','s1','qrcode005')",
+ "CREATE TABLE sg(device1 STRING ID, device2 STRING ID, qrcode TEXT
MEASUREMENT, date_v DATE MEASUREMENT, blob_v BLOB MEASUREMENT)",
+ "insert into sg(time,device1,device2,qrcode,date_v,blob_v)
values(1509465600000,'d1','s1','qrcode001', '2024-08-01', X'abc0')",
+ "insert into sg(time,device1,device2,qrcode,date_v,blob_v)
values(1509465660000,'d1','s1','qrcode002', '2024-08-02', X'abc1')",
+ "insert into sg(time,device1,device2,qrcode,date_v,blob_v)
values(1509465720000,'d1','s1','qrcode003', '2024-08-03', X'abc2')",
+ "insert into sg(time,device1,device2,qrcode,date_v,blob_v)
values(1509465780000,'d1','s1','qrcode004', '2024-08-04', X'abc3')",
+ "insert into sg(time,device1,device2,qrcode,date_v,blob_v)
values(1509465720000,'d1','s2','qrcode002', '2024-08-05', X'abc4')",
+ "insert into sg(time,device1,device2,qrcode,date_v,blob_v)
values(1509465780000,'d1','s2','qrcode003', '2024-08-06', X'abc5')",
+ "insert into sg(time,device1,device2,qrcode,date_v,blob_v)
values(1509465840000,'d1','s2','qrcode004', '2024-08-07', X'abc6')",
+ "insert into sg(time,device1,device2,qrcode,date_v,blob_v)
values(1509465900000,'d1','s2','qrcode005', '2024-08-08', X'abc7')",
+ "insert into sg(time,device1,device2,qrcode,date_v,blob_v)
values(1509465780000,'d2','s1','qrcode002', '2024-08-09', X'abc8')",
+ "insert into sg(time,device1,device2,qrcode,date_v,blob_v)
values(1509465840000,'d2','s1','qrcode003', '2024-08-10', X'abc9')",
+ "insert into sg(time,device1,device2,qrcode,date_v,blob_v)
values(1509465900000,'d2','s1','qrcode004', '2024-08-11', X'abca')",
+ "insert into sg(time,device1,device2,qrcode,date_v,blob_v)
values(1509465960000,'d2','s1','qrcode005', '2024-08-12', X'abcb')",
"CREATE TABLE table1(device STRING ID, s1 INT32 MEASUREMENT, s2 INT64
MEASUREMENT, s3 FLOAT MEASUREMENT, s4 DOUBLE MEASUREMENT, s5 BOOLEAN
MEASUREMENT)",
};
@@ -132,7 +132,7 @@ public class IoTDBInTableIT {
statement.execute("USE " + DATABASE_NAME);
try (ResultSet resultSet =
statement.executeQuery(
- "select * from sg where qrcode in
('d1','s1','qrcode002','qrcode004') order by device1,device2")) {
+ "select time,device1,device2,qrcode from sg where qrcode in
('d1','s1','qrcode002','qrcode004') order by device1,device2")) {
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
List<Integer> actualIndexToExpectedIndexList =
checkHeader(
@@ -158,6 +158,57 @@ public class IoTDBInTableIT {
}
Assert.assertEquals(6, cnt);
}
+
+ // DATE IN
+ try (ResultSet resultSet =
+ statement.executeQuery(
+ "select date_v from sg where date_v in (CAST('2024-08-05' AS
DATE), CAST('2024-08-12' AS DATE), CAST('2024-08-22' AS DATE)) order by
date_v")) {
+ ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
+ checkHeader(
+ resultSetMetaData,
+ "date_v,",
+ new int[] {
+ Types.DATE,
+ });
+
+ int cnt = 0;
+ String expectedString = "2024-08-05,2024-08-12,";
+ StringBuilder actualBuilder = new StringBuilder();
+ while (resultSet.next()) {
+ for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
+ actualBuilder.append(resultSet.getString(i)).append(",");
+ }
+ cnt++;
+ }
+ Assert.assertEquals(expectedString, actualBuilder.toString());
+ Assert.assertEquals(2, cnt);
+ }
+
+ // BLOB IN
+ try (ResultSet resultSet =
+ statement.executeQuery(
+ "select blob_v from sg where blob_v in (X'abc3', X'abca',
X'bbbb') order by blob_v")) {
+ ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
+ checkHeader(
+ resultSetMetaData,
+ "blob_v,",
+ new int[] {
+ Types.BLOB,
+ });
+
+ String expectedString = "0xabc3,0xabca,";
+ StringBuilder actualBuilder = new StringBuilder();
+ int cnt = 0;
+ while (resultSet.next()) {
+ for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
+ actualBuilder.append(resultSet.getString(i)).append(",");
+ }
+ cnt++;
+ }
+ Assert.assertEquals(expectedString, actualBuilder.toString());
+ Assert.assertEquals(2, cnt);
+ }
+
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
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 19fe9b2edb3..bdaa1f2ea1c 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
@@ -76,11 +76,17 @@ import
org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.IdentityCo
import
org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.LeafColumnTransformer;
import
org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.NullColumnTransformer;
import
org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.TimeColumnTransformer;
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.multi.InBinaryMultiColumnTransformer;
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.multi.InBooleanMultiColumnTransformer;
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.multi.InDoubleMultiColumnTransformer;
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.multi.InFloatMultiColumnTransformer;
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.multi.InInt32MultiColumnTransformer;
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.multi.InInt64MultiColumnTransformer;
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.multi.InMultiColumnTransformer;
import
org.apache.iotdb.db.queryengine.transformation.dag.column.multi.LogicalAndMultiColumnTransformer;
import
org.apache.iotdb.db.queryengine.transformation.dag.column.multi.LogicalOrMultiColumnTransformer;
import
org.apache.iotdb.db.queryengine.transformation.dag.column.ternary.BetweenColumnTransformer;
import
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.ArithmeticNegationColumnTransformer;
-import
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.InColumnTransformer;
import
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.IsNullColumnTransformer;
import
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.LogicNotColumnTransformer;
import
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.RegularColumnTransformer;
@@ -147,15 +153,18 @@ import
org.apache.tsfile.read.common.block.column.DoubleColumn;
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.Type;
+import org.apache.tsfile.read.common.type.TypeEnum;
import org.apache.tsfile.utils.Binary;
+import org.apache.tsfile.utils.DateUtils;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.Set;
import java.util.stream.Collectors;
-import static com.google.common.base.Preconditions.checkArgument;
import static
org.apache.iotdb.db.queryengine.plan.relational.analyzer.predicate.PredicatePushIntoMetadataChecker.isStringLiteral;
import static
org.apache.iotdb.db.queryengine.plan.relational.type.InternalTypeManager.getTSDataType;
import static
org.apache.iotdb.db.queryengine.plan.relational.type.TypeSignatureTranslator.toTypeSignature;
@@ -928,14 +937,21 @@ public class ColumnTransformerBuilder
context.cache.put(node, identity);
} else {
ColumnTransformer childColumnTransformer = process(node.getValue(),
context);
+ TypeEnum childTypeEnum =
childColumnTransformer.getType().getTypeEnum();
InListExpression inListExpression = (InListExpression)
node.getValueList();
List<Expression> expressionList = inListExpression.getValues();
List<Literal> values = new ArrayList<>();
+ List<ColumnTransformer> valueColumnTransformerList = new ArrayList<>();
+ valueColumnTransformerList.add(childColumnTransformer);
for (Expression expression : expressionList) {
- checkArgument(expression instanceof Literal);
- values.add((Literal) expression);
+ if (expression instanceof Literal) {
+ values.add((Literal) expression);
+ } else {
+ valueColumnTransformerList.add(process(expression, context));
+ }
}
- context.cache.put(node, new InColumnTransformer(BOOLEAN,
childColumnTransformer, values));
+ context.cache.put(
+ node, constructInColumnTransformer(childTypeEnum,
valueColumnTransformerList, values));
}
}
@@ -944,6 +960,87 @@ public class ColumnTransformerBuilder
return res;
}
+ private InMultiColumnTransformer constructInColumnTransformer(
+ TypeEnum childType,
+ List<ColumnTransformer> valueColumnTransformerList,
+ List<Literal> values) {
+ String errorMsg = "\"%s\" cannot be cast to [%s]";
+ switch (childType) {
+ case INT32:
+ Set<Integer> intSet = new HashSet<>();
+ for (Literal value : values) {
+ try {
+ long v = ((LongLiteral) value).getParsedValue();
+ if (v <= Integer.MAX_VALUE && v >= Integer.MIN_VALUE) {
+ intSet.add((int) v);
+ }
+ } catch (IllegalArgumentException e) {
+ throw new SemanticException(String.format(errorMsg, value,
childType));
+ }
+ }
+ return new InInt32MultiColumnTransformer(intSet,
valueColumnTransformerList);
+ case DATE:
+ Set<Integer> dateSet = new HashSet<>();
+ for (Literal value : values) {
+ dateSet.add(DateUtils.parseDateExpressionToInt(((StringLiteral)
value).getValue()));
+ }
+ return new InInt32MultiColumnTransformer(dateSet,
valueColumnTransformerList);
+ case INT64:
+ case TIMESTAMP:
+ Set<Long> longSet = new HashSet<>();
+ for (Literal value : values) {
+ try {
+ longSet.add((((LongLiteral) value).getParsedValue()));
+ } catch (IllegalArgumentException e) {
+ throw new SemanticException(String.format(errorMsg, value,
childType));
+ }
+ }
+ return new InInt64MultiColumnTransformer(longSet,
valueColumnTransformerList);
+ case FLOAT:
+ Set<Float> floatSet = new HashSet<>();
+ for (Literal value : values) {
+ try {
+ floatSet.add((float) ((DoubleLiteral) value).getValue());
+ } catch (IllegalArgumentException e) {
+ throw new SemanticException(String.format(errorMsg, value,
childType));
+ }
+ }
+ return new InFloatMultiColumnTransformer(floatSet,
valueColumnTransformerList);
+ case DOUBLE:
+ Set<Double> doubleSet = new HashSet<>();
+ for (Literal value : values) {
+ try {
+ doubleSet.add(((DoubleLiteral) value).getValue());
+ } catch (IllegalArgumentException e) {
+ throw new SemanticException(String.format(errorMsg, value,
childType));
+ }
+ }
+ return new InDoubleMultiColumnTransformer(doubleSet,
valueColumnTransformerList);
+ case BOOLEAN:
+ Set<Boolean> booleanSet = new HashSet<>();
+ for (Literal value : values) {
+ booleanSet.add(((BooleanLiteral) value).getValue());
+ }
+ return new InBooleanMultiColumnTransformer(booleanSet,
valueColumnTransformerList);
+ case TEXT:
+ case STRING:
+ Set<Binary> stringSet = new HashSet<>();
+ for (Literal value : values) {
+ stringSet.add(
+ new Binary(((StringLiteral) value).getValue(),
TSFileConfig.STRING_CHARSET));
+ }
+ return new InBinaryMultiColumnTransformer(stringSet,
valueColumnTransformerList);
+ case BLOB:
+ Set<Binary> binarySet = new HashSet<>();
+ for (Literal value : values) {
+ binarySet.add(new Binary(((BinaryLiteral) value).getValue()));
+ }
+ return new InBinaryMultiColumnTransformer(binarySet,
valueColumnTransformerList);
+ default:
+ throw new UnsupportedOperationException("unsupported data type: " +
childType);
+ }
+ }
+
@Override
protected ColumnTransformer visitNotExpression(NotExpression node, Context
context) {
if (!context.cache.containsKey(node)) {
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/PredicateCombineIntoTableScanChecker.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/PredicateCombineIntoTableScanChecker.java
index 1d7f74330c2..579f1562876 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/PredicateCombineIntoTableScanChecker.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/predicate/PredicateCombineIntoTableScanChecker.java
@@ -23,10 +23,12 @@ import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BetweenPredicate;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ComparisonExpression;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.IfExpression;
+import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.InListExpression;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.InPredicate;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.IsNotNullPredicate;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.IsNullPredicate;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LikePredicate;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Literal;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LogicalExpression;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.NotExpression;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.NullIfExpression;
@@ -69,7 +71,21 @@ public class PredicateCombineIntoTableScanChecker extends
PredicateVisitor<Boole
@Override
protected Boolean visitInPredicate(InPredicate node, Void context) {
- return isMeasurementColumn(node.getValue());
+ return isMeasurementColumn(node.getValue()) && isInListAllLiteral(node);
+ }
+
+ public static Boolean isInListAllLiteral(InPredicate node) {
+ if (node.getValueList() instanceof InListExpression) {
+ List<Expression> values = ((InListExpression)
node.getValueList()).getValues();
+ for (Expression value : values) {
+ if (!(value instanceof Literal)) {
+ return Boolean.FALSE;
+ }
+ }
+ return Boolean.TRUE;
+ } else {
+ return Boolean.FALSE;
+ }
}
@Override
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 331b3e9db16..c01ba634bfd 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
@@ -38,6 +38,7 @@ import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SymbolReference;
import java.util.List;
import java.util.Set;
+import static
org.apache.iotdb.db.queryengine.plan.relational.analyzer.predicate.PredicateCombineIntoTableScanChecker.isInListAllLiteral;
import static
org.apache.iotdb.db.queryengine.plan.relational.analyzer.predicate.PredicatePushIntoScanChecker.isSymbolReference;
/**
@@ -65,7 +66,7 @@ public class PredicatePushIntoMetadataChecker extends
PredicateVisitor<Boolean,
@Override
protected Boolean visitInPredicate(final InPredicate node, final Void
context) {
- return isIdOrAttributeColumn(node.getValue());
+ return isIdOrAttributeColumn(node.getValue()) && isInListAllLiteral(node);
}
@Override
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
index 1fe3773aee5..1f7cadb111e 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
@@ -159,7 +159,8 @@ public class TableMetadataImpl implements Metadata {
}
return DOUBLE;
} else if
(TableBuiltinScalarFunction.ROUND.getFunctionName().equalsIgnoreCase(functionName))
{
- if (!isOneNumericType(argumentTypes) &&
!isTwoNumericType(argumentTypes)) {
+ if (!isOneSupportedMathNumericType(argumentTypes)
+ && !isTwoSupportedMathNumericType(argumentTypes)) {
throw new SemanticException(
"Scalar function "
+ functionName.toLowerCase(Locale.ENGLISH)
@@ -481,7 +482,7 @@ public class TableMetadataImpl implements Metadata {
case SqlConstant.VARIANCE:
case SqlConstant.VAR_POP:
case SqlConstant.VAR_SAMP:
- if (!isOneNumericType(argumentTypes)) {
+ if (!isOneSupportedMathNumericType(argumentTypes)) {
throw new SemanticException(
String.format(
"Aggregate functions [%s] only support numeric data types
[INT32, INT64, FLOAT, DOUBLE]",
@@ -652,6 +653,16 @@ public class TableMetadataImpl implements Metadata {
return argumentTypes.size() == 1 && isNumericType(argumentTypes.get(0));
}
+ public static boolean isTwoSupportedMathNumericType(List<? extends Type>
argumentTypes) {
+ return argumentTypes.size() == 2
+ && isSupportedMathNumericType(argumentTypes.get(0))
+ && isSupportedMathNumericType(argumentTypes.get(1));
+ }
+
+ public static boolean isOneSupportedMathNumericType(List<? extends Type>
argumentTypes) {
+ return argumentTypes.size() == 1 &&
isSupportedMathNumericType(argumentTypes.get(0));
+ }
+
public static boolean isOneBooleanType(List<? extends Type> argumentTypes) {
return argumentTypes.size() == 1 && BOOLEAN.equals(argumentTypes.get(0));
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InBinaryMultiColumnTransformer.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InBinaryMultiColumnTransformer.java
new file mode 100644
index 00000000000..9491a201ed1
--- /dev/null
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InBinaryMultiColumnTransformer.java
@@ -0,0 +1,59 @@
+/*
+ * 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.transformation.dag.column.multi;
+
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.read.common.type.Type;
+import org.apache.tsfile.utils.Binary;
+
+import java.util.List;
+import java.util.Set;
+
+public class InBinaryMultiColumnTransformer extends InMultiColumnTransformer {
+
+ private final Set<Binary> constantSet;
+
+ public InBinaryMultiColumnTransformer(
+ Set<Binary> constantSet, List<ColumnTransformer> columnTransformerList) {
+ super(columnTransformerList);
+ this.constantSet = constantSet;
+ }
+
+ @Override
+ protected boolean satisfy(List<Column> childrenColumns, int index) {
+ Binary value = childrenColumns.get(0).getBinary(index);
+ if (constantSet.contains(value)) {
+ return true;
+ } else {
+ for (int i = 1, size = childrenColumns.size(); i < size; i++) {
+ Column valueColumn = childrenColumns.get(i);
+ if (!valueColumn.isNull(i)) {
+ Type valueType = columnTransformerList.get(i).getType();
+ if (value.equals(valueType.getBinary(valueColumn, index))) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InBooleanMultiColumnTransformer.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InBooleanMultiColumnTransformer.java
new file mode 100644
index 00000000000..f99bc791b39
--- /dev/null
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InBooleanMultiColumnTransformer.java
@@ -0,0 +1,58 @@
+/*
+ * 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.transformation.dag.column.multi;
+
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.read.common.type.Type;
+
+import java.util.List;
+import java.util.Set;
+
+public class InBooleanMultiColumnTransformer extends InMultiColumnTransformer {
+
+ private final Set<Boolean> constantSet;
+
+ public InBooleanMultiColumnTransformer(
+ Set<Boolean> constantSet, List<ColumnTransformer> columnTransformerList)
{
+ super(columnTransformerList);
+ this.constantSet = constantSet;
+ }
+
+ @Override
+ protected boolean satisfy(List<Column> childrenColumns, int index) {
+ boolean value = childrenColumns.get(0).getBoolean(index);
+ if (constantSet.contains(value)) {
+ return true;
+ } else {
+ for (int i = 1, size = childrenColumns.size(); i < size; i++) {
+ Column valueColumn = childrenColumns.get(i);
+ if (!valueColumn.isNull(i)) {
+ Type valueType = columnTransformerList.get(i).getType();
+ if (valueType.getBoolean(valueColumn, index) == value) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InDoubleMultiColumnTransformer.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InDoubleMultiColumnTransformer.java
new file mode 100644
index 00000000000..482214498b9
--- /dev/null
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InDoubleMultiColumnTransformer.java
@@ -0,0 +1,58 @@
+/*
+ * 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.transformation.dag.column.multi;
+
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.read.common.type.Type;
+
+import java.util.List;
+import java.util.Set;
+
+public class InDoubleMultiColumnTransformer extends InMultiColumnTransformer {
+
+ private final Set<Double> constantSet;
+
+ public InDoubleMultiColumnTransformer(
+ Set<Double> constantSet, List<ColumnTransformer> columnTransformerList) {
+ super(columnTransformerList);
+ this.constantSet = constantSet;
+ }
+
+ @Override
+ protected boolean satisfy(List<Column> childrenColumns, int index) {
+ double value = childrenColumns.get(0).getDouble(index);
+ if (constantSet.contains(value)) {
+ return true;
+ } else {
+ for (int i = 1, size = childrenColumns.size(); i < size; i++) {
+ Column valueColumn = childrenColumns.get(i);
+ if (!valueColumn.isNull(i)) {
+ Type valueType = columnTransformerList.get(i).getType();
+ if (valueType.getDouble(valueColumn, index) == value) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InFloatMultiColumnTransformer.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InFloatMultiColumnTransformer.java
new file mode 100644
index 00000000000..310669c73cf
--- /dev/null
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InFloatMultiColumnTransformer.java
@@ -0,0 +1,58 @@
+/*
+ * 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.transformation.dag.column.multi;
+
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.read.common.type.Type;
+
+import java.util.List;
+import java.util.Set;
+
+public class InFloatMultiColumnTransformer extends InMultiColumnTransformer {
+
+ private final Set<Float> constantSet;
+
+ public InFloatMultiColumnTransformer(
+ Set<Float> constantSet, List<ColumnTransformer> columnTransformerList) {
+ super(columnTransformerList);
+ this.constantSet = constantSet;
+ }
+
+ @Override
+ protected boolean satisfy(List<Column> childrenColumns, int index) {
+ float value = childrenColumns.get(0).getFloat(index);
+ if (constantSet.contains(value)) {
+ return true;
+ } else {
+ for (int i = 1, size = childrenColumns.size(); i < size; i++) {
+ Column valueColumn = childrenColumns.get(i);
+ if (!valueColumn.isNull(i)) {
+ Type valueType = columnTransformerList.get(i).getType();
+ if (valueType.getFloat(valueColumn, index) == value) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InInt32MultiColumnTransformer.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InInt32MultiColumnTransformer.java
new file mode 100644
index 00000000000..ad291426a1c
--- /dev/null
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InInt32MultiColumnTransformer.java
@@ -0,0 +1,58 @@
+/*
+ * 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.transformation.dag.column.multi;
+
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.read.common.type.Type;
+
+import java.util.List;
+import java.util.Set;
+
+public class InInt32MultiColumnTransformer extends InMultiColumnTransformer {
+
+ private final Set<Integer> constantSet;
+
+ public InInt32MultiColumnTransformer(
+ Set<Integer> constantSet, List<ColumnTransformer> columnTransformerList)
{
+ super(columnTransformerList);
+ this.constantSet = constantSet;
+ }
+
+ @Override
+ protected boolean satisfy(List<Column> childrenColumns, int index) {
+ int value = childrenColumns.get(0).getInt(index);
+ if (constantSet.contains(value)) {
+ return true;
+ } else {
+ for (int i = 1, size = childrenColumns.size(); i < size; i++) {
+ Column valueColumn = childrenColumns.get(i);
+ if (!valueColumn.isNull(i)) {
+ Type valueType = columnTransformerList.get(i).getType();
+ if (valueType.getInt(valueColumn, index) == value) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InInt64MultiColumnTransformer.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InInt64MultiColumnTransformer.java
new file mode 100644
index 00000000000..aa3ec1397fb
--- /dev/null
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InInt64MultiColumnTransformer.java
@@ -0,0 +1,58 @@
+/*
+ * 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.transformation.dag.column.multi;
+
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.read.common.type.Type;
+
+import java.util.List;
+import java.util.Set;
+
+public class InInt64MultiColumnTransformer extends InMultiColumnTransformer {
+
+ private final Set<Long> constantSet;
+
+ public InInt64MultiColumnTransformer(
+ Set<Long> constantSet, List<ColumnTransformer> columnTransformerList) {
+ super(columnTransformerList);
+ this.constantSet = constantSet;
+ }
+
+ @Override
+ protected boolean satisfy(List<Column> childrenColumns, int index) {
+ long value = childrenColumns.get(0).getLong(index);
+ if (constantSet.contains(value)) {
+ return true;
+ } else {
+ for (int i = 1, size = childrenColumns.size(); i < size; i++) {
+ Column valueColumn = childrenColumns.get(i);
+ if (!valueColumn.isNull(i)) {
+ Type valueType = columnTransformerList.get(i).getType();
+ if (valueType.getLong(valueColumn, index) == value) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InMultiColumnTransformer.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InMultiColumnTransformer.java
new file mode 100644
index 00000000000..de59bc08bf6
--- /dev/null
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/InMultiColumnTransformer.java
@@ -0,0 +1,54 @@
+/*
+ * 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.transformation.dag.column.multi;
+
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.read.common.type.BooleanType;
+
+import java.util.List;
+
+public abstract class InMultiColumnTransformer extends MultiColumnTransformer {
+
+ protected InMultiColumnTransformer(List<ColumnTransformer>
columnTransformerList) {
+ super(BooleanType.BOOLEAN, columnTransformerList);
+ }
+
+ @Override
+ protected void checkType() {
+ // do nothing
+ }
+
+ @Override
+ protected void doTransform(
+ List<Column> childrenColumns, ColumnBuilder builder, int positionCount) {
+ for (int i = 0; i < positionCount; i++) {
+ if (!childrenColumns.get(0).isNull(i)) {
+ builder.writeBoolean(satisfy(childrenColumns, i));
+ } else {
+ builder.appendNull();
+ }
+ }
+ }
+
+ protected abstract boolean satisfy(List<Column> childrenColumns, int index);
+}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/InColumnTransformer.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/InColumnTransformer.java
index 884b5006f2b..29ef3d09403 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/InColumnTransformer.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/InColumnTransformer.java
@@ -20,6 +20,7 @@
package org.apache.iotdb.db.queryengine.transformation.dag.column.unary;
import org.apache.iotdb.db.exception.sql.SemanticException;
+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.Literal;
@@ -32,11 +33,13 @@ import org.apache.tsfile.block.column.ColumnBuilder;
import org.apache.tsfile.common.conf.TSFileConfig;
import org.apache.tsfile.read.common.type.Type;
import org.apache.tsfile.read.common.type.TypeEnum;
+import org.apache.tsfile.utils.Binary;
import org.apache.tsfile.utils.DateUtils;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.stream.Collectors;
public class InColumnTransformer extends UnaryColumnTransformer {
private final Satisfy satisfy;
@@ -48,7 +51,7 @@ public class InColumnTransformer extends
UnaryColumnTransformer {
private Set<Float> floatSet;
private Set<Double> doubleSet;
private Set<Boolean> booleanSet;
- private Set<String> stringSet;
+ private Set<Binary> stringSet;
public InColumnTransformer(
Type returnType,
@@ -64,17 +67,6 @@ public class InColumnTransformer extends
UnaryColumnTransformer {
initTypedSet(values);
}
- public InColumnTransformer(
- Type returnType, ColumnTransformer childColumnTransformer, List<Literal>
values) {
- super(returnType, childColumnTransformer);
- satisfy = new InSatisfy();
- this.childType =
- childColumnTransformer.getType() == null
- ? null
- : childColumnTransformer.getType().getTypeEnum();
- initTypedSet(values);
- }
-
@Override
protected void doTransform(Column column, ColumnBuilder columnBuilder) {
for (int i = 0, n = column.getPositionCount(); i < n; i++) {
@@ -99,9 +91,8 @@ public class InColumnTransformer extends
UnaryColumnTransformer {
break;
case STRING:
case TEXT:
- returnType.writeBoolean(
- columnBuilder,
-
satisfy.of(column.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET)));
+ case BLOB:
+ returnType.writeBoolean(columnBuilder,
satisfy.of(column.getBinary(i)));
break;
default:
throw new UnsupportedOperationException("unsupported data type: "
+ childType);
@@ -167,7 +158,10 @@ public class InColumnTransformer extends
UnaryColumnTransformer {
break;
case TEXT:
case STRING:
- stringSet = values;
+ stringSet =
+ values.stream()
+ .map(v -> new Binary(v, TSFileConfig.STRING_CHARSET))
+ .collect(Collectors.toSet());
break;
default:
throw new UnsupportedOperationException("unsupported data type: " +
childType);
@@ -237,7 +231,14 @@ public class InColumnTransformer extends
UnaryColumnTransformer {
case STRING:
stringSet = new HashSet<>();
for (Literal value : values) {
- stringSet.add(((StringLiteral) value).getValue());
+ stringSet.add(
+ new Binary(((StringLiteral) value).getValue(),
TSFileConfig.STRING_CHARSET));
+ }
+ break;
+ case BLOB:
+ stringSet = new HashSet<>();
+ for (Literal value : values) {
+ stringSet.add(new Binary(((BinaryLiteral) value).getValue()));
}
break;
default:
@@ -266,7 +267,7 @@ public class InColumnTransformer extends
UnaryColumnTransformer {
boolean of(boolean booleanValue);
- boolean of(String stringValue);
+ boolean of(Binary stringValue);
}
private class InSatisfy implements Satisfy {
@@ -297,7 +298,7 @@ public class InColumnTransformer extends
UnaryColumnTransformer {
}
@Override
- public boolean of(String stringValue) {
+ public boolean of(Binary stringValue) {
return stringSet.contains(stringValue);
}
}
@@ -330,7 +331,7 @@ public class InColumnTransformer extends
UnaryColumnTransformer {
}
@Override
- public boolean of(String stringValue) {
+ public boolean of(Binary stringValue) {
return !stringSet.contains(stringValue);
}
}
diff --git a/pom.xml b/pom.xml
index 4d2adc4fb73..5ab34f3b5c5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -166,7 +166,7 @@
<thrift.version>0.14.1</thrift.version>
<xz.version>1.9</xz.version>
<zstd-jni.version>1.5.6-3</zstd-jni.version>
- <tsfile.version>1.2.0-b31fb57c-SNAPSHOT</tsfile.version>
+ <tsfile.version>1.2.0-20a94fb3-SNAPSHOT</tsfile.version>
</properties>
<!--
if we claim dependencies in dependencyManagement, then we do not claim