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 d3d50e49bf [IOTDB-4893] modify the data type check of IN operation 
(#7979)
d3d50e49bf is described below

commit d3d50e49bfc697157c43b2abd8730f89c0aacbd8
Author: Weihao Li <[email protected]>
AuthorDate: Tue Nov 15 18:47:33 2022 +0800

    [IOTDB-4893] modify the data type check of IN operation (#7979)
---
 docs/UserGuide/Query-Data/Select-Expression.md     |  7 ++++
 docs/zh/UserGuide/Query-Data/Select-Expression.md  |  7 ++++
 .../org/apache/iotdb/db/it/query/IoTDBInIT.java    | 23 ++++++++++++-
 .../dag/column/unary/InColumnTransformer.java      | 40 +++++++++++++++++++---
 4 files changed, 71 insertions(+), 6 deletions(-)

diff --git a/docs/UserGuide/Query-Data/Select-Expression.md 
b/docs/UserGuide/Query-Data/Select-Expression.md
index 9ae1f0d4b5..0a02f59624 100644
--- a/docs/UserGuide/Query-Data/Select-Expression.md
+++ b/docs/UserGuide/Query-Data/Select-Expression.md
@@ -147,6 +147,13 @@ Supported input data types: `All Types`
 
 Output data type: `BOOLEAN`
 
+Note: Please ensure the value strings in set can be cast to the DataType of 
Operand
+> Example: 
+> 
+>`s1 in (1, 2, 3, 'test')`, DataType of `s1` is `INT32`
+> 
+> We will throw Exception because `'test'` cannot be cast to `INT32`
+
 #### String Match Operators
 
 Supported operators `LIKE`, `REGEXP`
diff --git a/docs/zh/UserGuide/Query-Data/Select-Expression.md 
b/docs/zh/UserGuide/Query-Data/Select-Expression.md
index 034a799ff6..d02f8492c7 100644
--- a/docs/zh/UserGuide/Query-Data/Select-Expression.md
+++ b/docs/zh/UserGuide/Query-Data/Select-Expression.md
@@ -149,6 +149,13 @@ It costs 0.014s
 
 返回类型 `BOOLEAN`
 
+注意: 请确保集合中的值串可以被转为操作数的类型
+> 例如:
+>
+>`s1 in (1, 2, 3, 'test')`,`s1`的数据类型是`INT32`
+>
+> 我们将会抛出异常,因为`'test'`不能被转为`INT32`类型
+
 #### 字符串匹配运算符
 
 支持运算符 `LIKE`, `REGEXP`
diff --git 
a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBInIT.java 
b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBInIT.java
index f2c35bbbac..b83dccfdf7 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBInIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBInIT.java
@@ -42,6 +42,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import static org.apache.iotdb.db.it.utils.TestUtils.assertTestFail;
 import static org.junit.Assert.fail;
 
 @RunWith(IoTDBTestRunner.class)
@@ -66,7 +67,12 @@ public class IoTDBInIT {
         "insert into root.sg.d2.s1(timestamp,qrcode) 
values(1509465780000,'qrcode002')",
         "insert into root.sg.d2.s1(timestamp,qrcode) 
values(1509465840000,'qrcode003')",
         "insert into root.sg.d2.s1(timestamp,qrcode) 
values(1509465900000,'qrcode004')",
-        "insert into root.sg.d2.s1(timestamp,qrcode) 
values(1509465960000,'qrcode005')"
+        "insert into root.sg.d2.s1(timestamp,qrcode) 
values(1509465960000,'qrcode005')",
+        "create timeseries root.test.s1 with datatype=INT32,encoding=PLAIN",
+        "create timeseries root.test.s2 with datatype=INT64,encoding=PLAIN",
+        "create timeseries root.test.s3 with datatype=FLOAT,encoding=PLAIN",
+        "create timeseries root.test.s4 with datatype=DOUBLE,encoding=PLAIN",
+        "create timeseries root.test.s5 with datatype=BOOLEAN,encoding=PLAIN",
       };
 
   @BeforeClass
@@ -94,6 +100,21 @@ public class IoTDBInIT {
     }
   }
 
+  @Test
+  public void testCastException() {
+    assertTestFail(
+        "select * from root.** where s1 in (\"test\")", "400: \"test\" cannot 
be cast to [INT32]");
+    assertTestFail(
+        "select * from root.** where s2 in (\"test\")", "400: \"test\" cannot 
be cast to [INT64]");
+    assertTestFail(
+        "select * from root.** where s3 in (\"test\")", "400: \"test\" cannot 
be cast to [FLOAT]");
+    assertTestFail(
+        "select * from root.** where s4 in (\"test\")", "400: \"test\" cannot 
be cast to [DOUBLE]");
+    assertTestFail(
+        "select * from root.** where s5 in (\"test\")",
+        "400: \"test\" cannot be cast to [BOOLEAN]");
+  }
+
   /** Test for IOTDB-1540 */
   @Test
   public void selectWithStarTest1() {
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/column/unary/InColumnTransformer.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/column/unary/InColumnTransformer.java
index b53e02e59b..0e456acff6 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/column/unary/InColumnTransformer.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/column/unary/InColumnTransformer.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.mpp.transformation.dag.column.unary;
 
+import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.mpp.transformation.dag.column.ColumnTransformer;
 import org.apache.iotdb.tsfile.read.common.block.column.Column;
 import org.apache.iotdb.tsfile.read.common.block.column.ColumnBuilder;
@@ -95,31 +96,51 @@ public class InColumnTransformer extends 
UnaryColumnTransformer {
       case INT32:
         intSet = new HashSet<>();
         for (String value : values) {
-          intSet.add(Integer.valueOf(value));
+          try {
+            intSet.add(Integer.valueOf(value));
+          } catch (IllegalArgumentException e) {
+            throw new SemanticException(
+                String.format("\"%s\" cannot be cast to [%s]", value, 
childType));
+          }
         }
         break;
       case INT64:
         longSet = new HashSet<>();
         for (String value : values) {
-          longSet.add(Long.valueOf(value));
+          try {
+            longSet.add(Long.valueOf(value));
+          } catch (IllegalArgumentException e) {
+            throw new SemanticException(
+                String.format("\"%s\" cannot be cast to [%s]", value, 
childType));
+          }
         }
         break;
       case FLOAT:
         floatSet = new HashSet<>();
         for (String value : values) {
-          floatSet.add(Float.valueOf(value));
+          try {
+            floatSet.add(Float.valueOf(value));
+          } catch (IllegalArgumentException e) {
+            throw new SemanticException(
+                String.format("\"%s\" cannot be cast to [%s]", value, 
childType));
+          }
         }
         break;
       case DOUBLE:
         doubleSet = new HashSet<>();
         for (String value : values) {
-          doubleSet.add(Double.valueOf(value));
+          try {
+            doubleSet.add(Double.valueOf(value));
+          } catch (IllegalArgumentException e) {
+            throw new SemanticException(
+                String.format("\"%s\" cannot be cast to [%s]", value, 
childType));
+          }
         }
         break;
       case BOOLEAN:
         booleanSet = new HashSet<>();
         for (String value : values) {
-          booleanSet.add(Boolean.valueOf(value));
+          booleanSet.add(strictCastToBool(value));
         }
         break;
       case BINARY:
@@ -130,6 +151,15 @@ public class InColumnTransformer extends 
UnaryColumnTransformer {
     }
   }
 
+  private boolean strictCastToBool(String s) {
+    if ("true".equalsIgnoreCase(s)) {
+      return true;
+    } else if ("false".equalsIgnoreCase(s)) {
+      return false;
+    }
+    throw new SemanticException(String.format("\"%s\" cannot be cast to 
[BOOLEAN]", s));
+  }
+
   private interface Satisfy {
 
     boolean of(int intValue);

Reply via email to