From b072f9e861cd4677046e6dde3cf1c6132b8e5dd3 Mon Sep 17 00:00:00 2001 From: FearfulTomcat27 <1471335448@qq.com> Date: Wed, 27 Nov 2024 11:17:22 +0800 Subject: [PATCH] Fix throw exception when compare with null --- .../it/query/old/IoTDBFilterTableIT.java | 24 +++++++++++++++++++ .../function/arithmetic/AdditionResolver.java | 14 +++++++++++ .../function/arithmetic/DivisionResolver.java | 10 ++++++++ .../function/arithmetic/ModulusResolver.java | 10 ++++++++ .../arithmetic/MultiplicationResolver.java | 10 ++++++++ .../arithmetic/SubtractionResolver.java | 10 ++++++++ .../metadata/TableMetadataImpl.java | 17 ++++++++++++- .../column/leaf/NullColumnTransformer.java | 4 +++- ...AbstractCastFunctionColumnTransformer.java | 4 ++-- 9 files changed, 99 insertions(+), 4 deletions(-) diff --git a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/IoTDBFilterTableIT.java b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/IoTDBFilterTableIT.java index e2536adcba0b..b4be0d024cd4 100644 --- a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/IoTDBFilterTableIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/IoTDBFilterTableIT.java @@ -237,4 +237,28 @@ public void testFilterWithUDTF() { fail(throwable.getMessage()); } } + + @Test + public void testCompareWithNull() { + tableResultSetEqualTest( + "select s1 from sg1 where s1 != null", new String[] {"s1"}, new String[] {}, DATABASE_NAME); + tableResultSetEqualTest( + "select s1 from sg1 where s1 <> null", new String[] {"s1"}, new String[] {}, DATABASE_NAME); + tableResultSetEqualTest( + "select s1 from sg1 where s1 = null", new String[] {"s1"}, new String[] {}, DATABASE_NAME); + } + + @Test + public void testCalculateWithNull() { + tableResultSetEqualTest( + "select s1 + null from sg1", + new String[] {"_col0"}, + new String[] {"null,", "null,"}, + DATABASE_NAME); + tableResultSetEqualTest( + "select s1 - null from sg1", + new String[] {"_col0"}, + new String[] {"null,", "null,"}, + DATABASE_NAME); + } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/AdditionResolver.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/AdditionResolver.java index b3d1836e687f..16607dc01ecc 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/AdditionResolver.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/AdditionResolver.java @@ -28,6 +28,7 @@ import static org.apache.tsfile.read.common.type.IntType.INT32; import static org.apache.tsfile.read.common.type.LongType.INT64; import static org.apache.tsfile.read.common.type.TimestampType.TIMESTAMP; +import static org.apache.tsfile.read.common.type.UnknownType.UNKNOWN; public class AdditionResolver { @@ -40,6 +41,7 @@ public class AdditionResolver { addCondition(INT32, DOUBLE, DOUBLE); addCondition(INT32, DATE, DATE); addCondition(INT32, TIMESTAMP, TIMESTAMP); + addCondition(INT32, UNKNOWN, INT32); addCondition(INT64, INT32, INT64); addCondition(INT64, INT64, INT64); @@ -47,22 +49,34 @@ public class AdditionResolver { addCondition(INT64, DOUBLE, DOUBLE); addCondition(INT64, DATE, DATE); addCondition(INT64, TIMESTAMP, TIMESTAMP); + addCondition(INT64, UNKNOWN, INT64); addCondition(FLOAT, INT32, FLOAT); addCondition(FLOAT, INT64, FLOAT); addCondition(FLOAT, FLOAT, FLOAT); addCondition(FLOAT, DOUBLE, DOUBLE); + addCondition(FLOAT, UNKNOWN, FLOAT); addCondition(DOUBLE, INT32, DOUBLE); addCondition(DOUBLE, INT64, DOUBLE); addCondition(DOUBLE, FLOAT, DOUBLE); addCondition(DOUBLE, DOUBLE, DOUBLE); + addCondition(DOUBLE, UNKNOWN, DOUBLE); addCondition(DATE, INT32, DATE); addCondition(DATE, INT64, DATE); + addCondition(DATE, UNKNOWN, DATE); addCondition(TIMESTAMP, INT32, TIMESTAMP); addCondition(TIMESTAMP, INT64, TIMESTAMP); + addCondition(TIMESTAMP, UNKNOWN, TIMESTAMP); + + addCondition(UNKNOWN, INT32, INT32); + addCondition(UNKNOWN, INT64, INT64); + addCondition(UNKNOWN, FLOAT, FLOAT); + addCondition(UNKNOWN, DOUBLE, DOUBLE); + addCondition(UNKNOWN, DATE, DATE); + addCondition(UNKNOWN, TIMESTAMP, TIMESTAMP); } private static void addCondition(Type condition1, Type condition2, Type result) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/DivisionResolver.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/DivisionResolver.java index 0d6bf4664ec9..99fc7e67197a 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/DivisionResolver.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/DivisionResolver.java @@ -26,6 +26,7 @@ import static org.apache.tsfile.read.common.type.FloatType.FLOAT; import static org.apache.tsfile.read.common.type.IntType.INT32; import static org.apache.tsfile.read.common.type.LongType.INT64; +import static org.apache.tsfile.read.common.type.UnknownType.UNKNOWN; public class DivisionResolver { @@ -36,21 +37,30 @@ public class DivisionResolver { addCondition(INT32, INT64, INT64); addCondition(INT32, FLOAT, FLOAT); addCondition(INT32, DOUBLE, DOUBLE); + addCondition(INT32, UNKNOWN, INT32); addCondition(INT64, INT32, INT64); addCondition(INT64, INT64, INT64); addCondition(INT64, FLOAT, FLOAT); addCondition(INT64, DOUBLE, DOUBLE); + addCondition(INT64, UNKNOWN, INT64); addCondition(FLOAT, INT32, FLOAT); addCondition(FLOAT, INT64, FLOAT); addCondition(FLOAT, FLOAT, FLOAT); addCondition(FLOAT, DOUBLE, DOUBLE); + addCondition(FLOAT, UNKNOWN, FLOAT); addCondition(DOUBLE, INT32, DOUBLE); addCondition(DOUBLE, INT64, DOUBLE); addCondition(DOUBLE, FLOAT, DOUBLE); addCondition(DOUBLE, DOUBLE, DOUBLE); + addCondition(DOUBLE, UNKNOWN, DOUBLE); + + addCondition(UNKNOWN, INT32, INT32); + addCondition(UNKNOWN, INT64, INT64); + addCondition(UNKNOWN, FLOAT, FLOAT); + addCondition(UNKNOWN, DOUBLE, DOUBLE); } private static void addCondition(Type condition1, Type condition2, Type result) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/ModulusResolver.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/ModulusResolver.java index c0e777655206..efc1e5397bab 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/ModulusResolver.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/ModulusResolver.java @@ -26,6 +26,7 @@ import static org.apache.tsfile.read.common.type.FloatType.FLOAT; import static org.apache.tsfile.read.common.type.IntType.INT32; import static org.apache.tsfile.read.common.type.LongType.INT64; +import static org.apache.tsfile.read.common.type.UnknownType.UNKNOWN; public class ModulusResolver { @@ -36,21 +37,30 @@ public class ModulusResolver { addCondition(INT32, INT64, INT64); addCondition(INT32, FLOAT, FLOAT); addCondition(INT32, DOUBLE, DOUBLE); + addCondition(INT32, UNKNOWN, INT32); addCondition(INT64, INT32, INT64); addCondition(INT64, INT64, INT64); addCondition(INT64, FLOAT, FLOAT); addCondition(INT64, DOUBLE, DOUBLE); + addCondition(INT64, UNKNOWN, INT64); addCondition(FLOAT, INT32, FLOAT); addCondition(FLOAT, INT64, FLOAT); addCondition(FLOAT, FLOAT, FLOAT); addCondition(FLOAT, DOUBLE, DOUBLE); + addCondition(FLOAT, UNKNOWN, FLOAT); addCondition(DOUBLE, INT32, DOUBLE); addCondition(DOUBLE, INT64, DOUBLE); addCondition(DOUBLE, FLOAT, DOUBLE); addCondition(DOUBLE, DOUBLE, DOUBLE); + addCondition(DOUBLE, UNKNOWN, DOUBLE); + + addCondition(UNKNOWN, INT32, INT32); + addCondition(UNKNOWN, INT64, INT64); + addCondition(UNKNOWN, FLOAT, FLOAT); + addCondition(UNKNOWN, DOUBLE, DOUBLE); } private static void addCondition(Type condition1, Type condition2, Type result) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/MultiplicationResolver.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/MultiplicationResolver.java index 769e0172f8ef..892c961c1603 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/MultiplicationResolver.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/MultiplicationResolver.java @@ -26,6 +26,7 @@ import static org.apache.tsfile.read.common.type.FloatType.FLOAT; import static org.apache.tsfile.read.common.type.IntType.INT32; import static org.apache.tsfile.read.common.type.LongType.INT64; +import static org.apache.tsfile.read.common.type.UnknownType.UNKNOWN; public class MultiplicationResolver { @@ -36,21 +37,30 @@ public class MultiplicationResolver { addCondition(INT32, INT64, INT64); addCondition(INT32, FLOAT, FLOAT); addCondition(INT32, DOUBLE, DOUBLE); + addCondition(INT32, UNKNOWN, INT32); addCondition(INT64, INT32, INT64); addCondition(INT64, INT64, INT64); addCondition(INT64, FLOAT, FLOAT); addCondition(INT64, DOUBLE, DOUBLE); + addCondition(INT64, UNKNOWN, INT64); addCondition(FLOAT, INT32, FLOAT); addCondition(FLOAT, INT64, FLOAT); addCondition(FLOAT, FLOAT, FLOAT); addCondition(FLOAT, DOUBLE, DOUBLE); + addCondition(FLOAT, UNKNOWN, FLOAT); addCondition(DOUBLE, INT32, DOUBLE); addCondition(DOUBLE, INT64, DOUBLE); addCondition(DOUBLE, FLOAT, DOUBLE); addCondition(DOUBLE, DOUBLE, DOUBLE); + addCondition(DOUBLE, UNKNOWN, DOUBLE); + + addCondition(UNKNOWN, INT32, INT32); + addCondition(UNKNOWN, INT64, INT64); + addCondition(UNKNOWN, FLOAT, FLOAT); + addCondition(UNKNOWN, DOUBLE, DOUBLE); } private static void addCondition(Type condition1, Type condition2, Type result) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/SubtractionResolver.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/SubtractionResolver.java index 5b7f4a79022f..38a4d6c36637 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/SubtractionResolver.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/SubtractionResolver.java @@ -28,6 +28,7 @@ import static org.apache.tsfile.read.common.type.IntType.INT32; import static org.apache.tsfile.read.common.type.LongType.INT64; import static org.apache.tsfile.read.common.type.TimestampType.TIMESTAMP; +import static org.apache.tsfile.read.common.type.UnknownType.UNKNOWN; public class SubtractionResolver { @@ -38,27 +39,36 @@ public class SubtractionResolver { addCondition(INT32, INT64, INT64); addCondition(INT32, FLOAT, FLOAT); addCondition(INT32, DOUBLE, DOUBLE); + addCondition(INT32, UNKNOWN, INT32); addCondition(INT64, INT32, INT64); addCondition(INT64, INT64, INT64); addCondition(INT64, FLOAT, FLOAT); addCondition(INT64, DOUBLE, DOUBLE); + addCondition(INT64, UNKNOWN, INT64); addCondition(FLOAT, INT32, FLOAT); addCondition(FLOAT, INT64, FLOAT); addCondition(FLOAT, FLOAT, FLOAT); addCondition(FLOAT, DOUBLE, DOUBLE); + addCondition(FLOAT, UNKNOWN, FLOAT); addCondition(DOUBLE, INT32, DOUBLE); addCondition(DOUBLE, INT64, DOUBLE); addCondition(DOUBLE, FLOAT, DOUBLE); addCondition(DOUBLE, DOUBLE, DOUBLE); + addCondition(DOUBLE, UNKNOWN, DOUBLE); addCondition(DATE, INT32, DATE); addCondition(DATE, INT64, DATE); addCondition(TIMESTAMP, INT32, TIMESTAMP); addCondition(TIMESTAMP, INT64, TIMESTAMP); + + addCondition(UNKNOWN, INT32, INT32); + addCondition(UNKNOWN, INT64, INT64); + addCondition(UNKNOWN, FLOAT, FLOAT); + addCondition(UNKNOWN, DOUBLE, DOUBLE); } private static void addCondition(Type condition1, Type condition2, Type result) { 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 b7e70fa2dbed..9c18397dc595 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 @@ -61,6 +61,9 @@ import static org.apache.iotdb.commons.conf.IoTDBConstant.PATH_ROOT; import static org.apache.iotdb.commons.conf.IoTDBConstant.PATH_SEPARATOR; +import static org.apache.iotdb.db.queryengine.plan.relational.function.OperatorType.EQUAL; +import static org.apache.iotdb.db.queryengine.plan.relational.function.OperatorType.LESS_THAN; +import static org.apache.iotdb.db.queryengine.plan.relational.function.OperatorType.LESS_THAN_OR_EQUAL; import static org.apache.tsfile.read.common.type.BinaryType.TEXT; import static org.apache.tsfile.read.common.type.BooleanType.BOOLEAN; import static org.apache.tsfile.read.common.type.DateType.DATE; @@ -70,6 +73,7 @@ import static org.apache.tsfile.read.common.type.LongType.INT64; import static org.apache.tsfile.read.common.type.StringType.STRING; import static org.apache.tsfile.read.common.type.TimestampType.TIMESTAMP; +import static org.apache.tsfile.read.common.type.UnknownType.UNKNOWN; public class TableMetadataImpl implements Metadata { @@ -786,6 +790,10 @@ public static boolean isTimestampType(Type type) { return TIMESTAMP.equals(type); } + public static boolean isUnknownType(Type type) { + return UNKNOWN.equals(type); + } + public static boolean isIntegerNumber(Type type) { return INT32.equals(type) || INT64.equals(type); } @@ -801,7 +809,10 @@ public static boolean isTwoTypeComparable(List argumentTypes) { } // Boolean type and Binary Type can not be compared with other types - return (isNumericType(left) && isNumericType(right)) || (isCharType(left) && isCharType(right)); + return (isNumericType(left) && isNumericType(right)) + || (isCharType(left) && isCharType(right)) + || (isUnknownType(left) && (isNumericType(right) || isCharType(right))) + || ((isNumericType(left) || isCharType(left)) && isUnknownType(right)); } public static boolean isArithmeticType(Type type) { @@ -819,6 +830,10 @@ public static boolean isTwoTypeCalculable(List argumentTypes) { } Type left = argumentTypes.get(0); Type right = argumentTypes.get(1); + if ((isUnknownType(left) && isArithmeticType(right)) + || (isUnknownType(right) && isArithmeticType(left))) { + return true; + } return isArithmeticType(left) && isArithmeticType(right); } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/NullColumnTransformer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/NullColumnTransformer.java index 21d4dfc166ea..d6cc68ab3ca5 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/NullColumnTransformer.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/leaf/NullColumnTransformer.java @@ -21,10 +21,12 @@ import org.apache.tsfile.read.common.block.column.NullColumn; +import static org.apache.tsfile.read.common.type.UnknownType.UNKNOWN; + public class NullColumnTransformer extends LeafColumnTransformer { public NullColumnTransformer() { - super(null); + super(UNKNOWN); } @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/AbstractCastFunctionColumnTransformer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/AbstractCastFunctionColumnTransformer.java index 19e29bd8c25a..8b0557da3549 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/AbstractCastFunctionColumnTransformer.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/AbstractCastFunctionColumnTransformer.java @@ -48,8 +48,8 @@ protected AbstractCastFunctionColumnTransformer( @Override protected void doTransform(Column column, ColumnBuilder columnBuilder) { - TypeEnum sourceType = childColumnTransformer.getType().getTypeEnum(); Type childType = childColumnTransformer.getType(); + TypeEnum sourceType = childType.getTypeEnum(); for (int i = 0, n = column.getPositionCount(); i < n; i++) { if (!column.isNull(i)) { transform(column, columnBuilder, sourceType, childType, i); @@ -61,8 +61,8 @@ protected void doTransform(Column column, ColumnBuilder columnBuilder) { @Override protected void doTransform(Column column, ColumnBuilder columnBuilder, boolean[] selection) { - TypeEnum sourceType = childColumnTransformer.getType().getTypeEnum(); Type childType = childColumnTransformer.getType(); + TypeEnum sourceType = childType.getTypeEnum(); for (int i = 0, n = column.getPositionCount(); i < n; i++) { if (selection[i] && !column.isNull(i)) { transform(column, columnBuilder, sourceType, childType, i);