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 1ab5ad3fcb [IOTDB-3504] Fix inferTypes, return value and column label
of IN/LIKE… (#6301)
1ab5ad3fcb is described below
commit 1ab5ad3fcb33cd339c15def4e065595b29f52ab9
Author: Weihao Li <[email protected]>
AuthorDate: Tue Jun 21 09:19:31 2022 +0800
[IOTDB-3504] Fix inferTypes, return value and column label of IN/LIKE…
(#6301)
---
docs/UserGuide/Query-Data/Query-Filter.md | 3 +-
docs/UserGuide/Query-Data/Select-Expression.md | 39 ++++++++++++++++++++--
docs/zh/UserGuide/Query-Data/Query-Filter.md | 3 +-
docs/zh/UserGuide/Query-Data/Select-Expression.md | 38 +++++++++++++++++++--
.../db/mpp/plan/expression/ExpressionType.java | 4 +--
.../db/mpp/plan/expression/unary/InExpression.java | 24 ++++++++++---
.../mpp/plan/expression/unary/LikeExpression.java | 6 ++++
.../plan/expression/unary/RegularExpression.java | 6 ++++
.../dag/transformer/unary/InTransformer.java | 36 ++++----------------
.../dag/transformer/unary/RegularTransformer.java | 6 +---
10 files changed, 116 insertions(+), 49 deletions(-)
diff --git a/docs/UserGuide/Query-Data/Query-Filter.md
b/docs/UserGuide/Query-Data/Query-Filter.md
index 4321d1c0b4..68cc31fce2 100644
--- a/docs/UserGuide/Query-Data/Query-Filter.md
+++ b/docs/UserGuide/Query-Data/Query-Filter.md
@@ -26,8 +26,9 @@ In IoTDB query statements, two filter conditions, **time
filter** and **value fi
The supported operators are as follows:
- Comparison operators: greater than (`>`), greater than or equal ( `>=`),
equal ( `=` or `==`), not equal ( `!=` or `<>`), less than or equal ( `<=`),
less than ( `<`).
-- Range contains operator: contains ( `IN` ).
- Logical operators: and ( `AND` or `&` or `&&`), or ( `OR` or `|` or `||`),
not ( `NOT` or `!`).
+- Range contains operator: contains ( `IN` ).
+- String matches operator: `LIKE`, `REGEXP`.
## Time Filter
diff --git a/docs/UserGuide/Query-Data/Select-Expression.md
b/docs/UserGuide/Query-Data/Select-Expression.md
index d97fc85622..73f52dd981 100644
--- a/docs/UserGuide/Query-Data/Select-Expression.md
+++ b/docs/UserGuide/Query-Data/Select-Expression.md
@@ -109,6 +109,7 @@ It costs 0.014s
```
## Compare Expression
+### Operators
#### Unary Logical Operators
Supported operator `!`
@@ -124,7 +125,7 @@ Supported operators `>`, `>=`, `<`, `<=`, `==`, `!=`
Supported input data types: `INT32`, `INT64`, `FLOAT` and `DOUBLE`
-It will transform all type to `DOUBLE` then do computation.
+Note: It will transform all type to `DOUBLE` then do computation.
Output data type: `BOOLEAN`
@@ -138,14 +139,31 @@ Output data type: `BOOLEAN`
Note: Only when the left operand and the right operand under a certain
timestamp are both `BOOLEAN` type, the binary logic operation will have an
output value.
+#### IN Operators
+
+Supported operator `IN`
+
+Supported input data types: `All Types`
+
+Output data type: `BOOLEAN`
+
+#### String Match Operators
+
+Supported operators `LIKE`, `REGEXP`
+
+Supported input data types: `TEXT`
+
+Output data type: `BOOLEAN`
+
### Example
+
+Input1:
```sql
select a, b, a > 10, a <= b, !(a <= b), a > 10 && a > b from root.test;
```
-Output:
+Output1:
```
-IoTDB> select a, b, a > 10, a <= b, !(a <= b), a > 10 && a > b from root.test;
+-----------------------------+-----------+-----------+----------------+--------------------------+---------------------------+------------------------------------------------+
| Time|root.test.a|root.test.b|root.test.a >
10|root.test.a <= root.test.b|!root.test.a <= root.test.b|(root.test.a > 10) &
(root.test.a > root.test.b)|
+-----------------------------+-----------+-----------+----------------+--------------------------+---------------------------+------------------------------------------------+
@@ -158,6 +176,21 @@ IoTDB> select a, b, a > 10, a <= b, !(a <= b), a > 10 && a
> b from root.test;
+-----------------------------+-----------+-----------+----------------+--------------------------+---------------------------+------------------------------------------------+
```
+Input2:
+```sql
+select a, b, a in (1, 2), b like '1%', b regexp '[0-2]' from root.test;
+```
+
+Output2:
+```
++-----------------------------+-----------+-----------+--------------------+-------------------------+--------------------------+
+| Time|root.test.a|root.test.b|root.test.a IN
(1,2)|root.test.b LIKE '^1.*?$'|root.test.b REGEXP '[0-2]'|
++-----------------------------+-----------+-----------+--------------------+-------------------------+--------------------------+
+|1970-01-01T08:00:00.001+08:00| 1| 111test111| true|
true| true|
+|1970-01-01T08:00:00.003+08:00| 3| 333test333| false|
false| false|
++-----------------------------+-----------+-----------+--------------------+-------------------------+--------------------------+
+```
+
## Priority of Operators
|priority|operator |meaning |
diff --git a/docs/zh/UserGuide/Query-Data/Query-Filter.md
b/docs/zh/UserGuide/Query-Data/Query-Filter.md
index aac9b820ba..9237a020f0 100644
--- a/docs/zh/UserGuide/Query-Data/Query-Filter.md
+++ b/docs/zh/UserGuide/Query-Data/Query-Filter.md
@@ -26,8 +26,9 @@
支持的运算符如下:
- 比较运算符:大于(`>`)、大于等于( `>=`)、等于( `=` 或 `==`)、不等于( `!=` 或 `<>`)、小于等于( `<=`)、小于(
`<`)。
-- 范围包含运算符:包含( `IN` )。
- 逻辑运算符:与( `AND` 或 `&` 或 `&&`)、或( `OR` 或 `|` 或 `||`)、非( `NOT` 或 `!`)。
+- 范围包含运算符:包含( `IN` )。
+- 字符串匹配运算符:`LIKE`, `REGEXP`。
## 时间过滤条件
diff --git a/docs/zh/UserGuide/Query-Data/Select-Expression.md
b/docs/zh/UserGuide/Query-Data/Select-Expression.md
index 5758f601fc..c41e7de066 100644
--- a/docs/zh/UserGuide/Query-Data/Select-Expression.md
+++ b/docs/zh/UserGuide/Query-Data/Select-Expression.md
@@ -111,6 +111,7 @@ It costs 0.014s
```
## 逻辑运算查询
+### 运算符
#### 一元逻辑运算符
支持运算符 `!`
@@ -126,7 +127,7 @@ It costs 0.014s
输入数据类型: `INT32`, `INT64`, `FLOAT`, `DOUBLE`
-会将所有数据转换为`DOUBLE`类型后进行比较。`==`和`!=`可以直接比较两个`BOOLEAN`
+注意:会将所有数据转换为`DOUBLE`类型后进行比较。`==`和`!=`可以直接比较两个`BOOLEAN`
返回类型:`BOOLEAN`
@@ -140,12 +141,28 @@ It costs 0.014s
注意:当某个时间戳下左操作数和右操作数都为`BOOLEAN`类型时,二元逻辑操作才会有输出结果
+#### IN 运算符
+
+支持运算符 `IN`
+
+输入数据类型:`All Types`
+
+返回类型 `BOOLEAN`
+
+#### 字符串匹配运算符
+
+支持运算符 `LIKE`, `REGEXP`
+
+输入数据类型:`TEXT`
+
+返回类型:`BOOLEAN`
+
### 使用示例
-例如:
+输入1:
```sql
select a, b, a > 10, a <= b, !(a <= b), a > 10 && a > b from root.test;
```
-输出:
+输出1:
```
IoTDB> select a, b, a > 10, a <= b, !(a <= b), a > 10 && a > b from root.test;
+-----------------------------+-----------+-----------+----------------+--------------------------+---------------------------+------------------------------------------------+
@@ -160,6 +177,21 @@ IoTDB> select a, b, a > 10, a <= b, !(a <= b), a > 10 && a
> b from root.test;
+-----------------------------+-----------+-----------+----------------+--------------------------+---------------------------+------------------------------------------------+
```
+输入2:
+```sql
+select a, b, a in (1, 2), b like '1%', b regexp '[0-2]' from root.test;
+```
+
+输出2:
+```
++-----------------------------+-----------+-----------+--------------------+-------------------------+--------------------------+
+| Time|root.test.a|root.test.b|root.test.a IN
(1,2)|root.test.b LIKE '^1.*?$'|root.test.b REGEXP '[0-2]'|
++-----------------------------+-----------+-----------+--------------------+-------------------------+--------------------------+
+|1970-01-01T08:00:00.001+08:00| 1| 111test111| true|
true| true|
+|1970-01-01T08:00:00.003+08:00| 3| 333test333| false|
false| false|
++-----------------------------+-----------+-----------+--------------------+-------------------------+--------------------------+
+```
+
## 运算符优先级
|优先级 |运算符 |含义 |
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/ExpressionType.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/ExpressionType.java
index 4d3352da2b..95daf6b892 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/ExpressionType.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/ExpressionType.java
@@ -41,8 +41,8 @@ public enum ExpressionType {
LESS_EQUAL((short) 11, (short) 600),
LESS_THAN((short) 12, (short) 600),
- REGEXP((short) 13, (short) 500),
- LIKE((short) 14, (short) 500),
+ LIKE((short) 13, (short) 500),
+ REGEXP((short) 14, (short) 500),
IN((short) 15, (short) 400),
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/InExpression.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/InExpression.java
index 70da42ee0f..47aa0dd53e 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/InExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/InExpression.java
@@ -22,6 +22,9 @@ package org.apache.iotdb.db.mpp.plan.expression.unary;
import org.apache.iotdb.db.mpp.plan.analyze.TypeProvider;
import org.apache.iotdb.db.mpp.plan.expression.Expression;
import org.apache.iotdb.db.mpp.plan.expression.ExpressionType;
+import org.apache.iotdb.db.mpp.plan.expression.leaf.ConstantOperand;
+import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
+import org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression;
import org.apache.iotdb.db.mpp.transformation.api.LayerPointReader;
import org.apache.iotdb.db.mpp.transformation.dag.transformer.Transformer;
import
org.apache.iotdb.db.mpp.transformation.dag.transformer.unary.InTransformer;
@@ -65,20 +68,33 @@ public class InExpression extends UnaryExpression {
@Override
public TSDataType inferTypes(TypeProvider typeProvider) {
+ final String expressionString = toString();
+ if (!typeProvider.containsTypeInfoOf(expressionString)) {
+ expression.inferTypes(typeProvider);
+ typeProvider.setType(expressionString, TSDataType.BOOLEAN);
+ }
return TSDataType.BOOLEAN;
}
@Override
protected String getExpressionStringInternal() {
- StringBuilder valuesStringBuilder = new StringBuilder();
+ StringBuilder stringBuilder = new StringBuilder();
+ if (expression instanceof FunctionExpression
+ || expression instanceof ConstantOperand
+ || expression instanceof TimeSeriesOperand) {
+ stringBuilder.append(expression).append(" IN (");
+ } else {
+ stringBuilder.append('(').append(expression).append(')').append(" IN (");
+ }
Iterator<String> iterator = values.iterator();
if (iterator.hasNext()) {
- valuesStringBuilder.append(iterator.next());
+ stringBuilder.append(iterator.next());
}
while (iterator.hasNext()) {
- valuesStringBuilder.append(", ").append(iterator.next());
+ stringBuilder.append(',').append(iterator.next());
}
- return expression + " IN (" + valuesStringBuilder + ")";
+ stringBuilder.append(')');
+ return stringBuilder.toString();
}
@Override
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LikeExpression.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LikeExpression.java
index fbc9383532..d14b2c30a3 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LikeExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/LikeExpression.java
@@ -122,6 +122,12 @@ public class LikeExpression extends UnaryExpression {
@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.BOOLEAN);
+ }
return TSDataType.BOOLEAN;
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/RegularExpression.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/RegularExpression.java
index 27db1fb519..aee30c1a3f 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/RegularExpression.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/unary/RegularExpression.java
@@ -79,6 +79,12 @@ public class RegularExpression extends UnaryExpression {
@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.BOOLEAN);
+ }
return TSDataType.BOOLEAN;
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/transformer/unary/InTransformer.java
b/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/transformer/unary/InTransformer.java
index 86c7337fd8..c921c454bf 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/transformer/unary/InTransformer.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/transformer/unary/InTransformer.java
@@ -96,51 +96,27 @@ public class InTransformer extends UnaryTransformer {
switch (layerPointReaderDataType) {
case INT32:
int intValue = layerPointReader.currentInt();
- if (satisfy.of(intValue)) {
- cachedBoolean = true;
- } else {
- currentNull = true;
- }
+ cachedBoolean = satisfy.of(intValue);
break;
case INT64:
long longValue = layerPointReader.currentLong();
- if (satisfy.of(longValue)) {
- cachedBoolean = true;
- } else {
- currentNull = true;
- }
+ cachedBoolean = satisfy.of(longValue);
break;
case FLOAT:
float floatValue = layerPointReader.currentFloat();
- if (satisfy.of(floatValue)) {
- cachedBoolean = true;
- } else {
- currentNull = true;
- }
+ cachedBoolean = satisfy.of(floatValue);
break;
case DOUBLE:
double doubleValue = layerPointReader.currentDouble();
- if (satisfy.of(doubleValue)) {
- cachedBoolean = true;
- } else {
- currentNull = true;
- }
+ cachedBoolean = satisfy.of(doubleValue);
break;
case BOOLEAN:
boolean booleanValue = layerPointReader.currentBoolean();
- if (satisfy.of(booleanValue)) {
- cachedBoolean = true;
- } else {
- currentNull = true;
- }
+ cachedBoolean = satisfy.of(booleanValue);
break;
case TEXT:
Binary binaryValue = layerPointReader.currentBinary();
- if (satisfy.of(binaryValue.getStringValue())) {
- cachedBoolean = true;
- } else {
- currentNull = true;
- }
+ cachedBoolean = satisfy.of(binaryValue.getStringValue());
break;
default:
throw new QueryProcessException("unsupported data type: " +
layerPointReader.getDataType());
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/transformer/unary/RegularTransformer.java
b/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/transformer/unary/RegularTransformer.java
index a3a47cb880..73dfbb4888 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/transformer/unary/RegularTransformer.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/transformer/unary/RegularTransformer.java
@@ -50,10 +50,6 @@ public class RegularTransformer extends UnaryTransformer {
@Override
protected void transformAndCache() throws QueryProcessException, IOException
{
Binary binary = layerPointReader.currentBinary();
- if (pattern.matcher(binary.getStringValue()).find()) {
- cachedBoolean = true;
- } else {
- currentNull = true;
- }
+ cachedBoolean = pattern.matcher(binary.getStringValue()).find();
}
}