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);