Skip to content

Commit 1705a8a

Browse files
authored
[IOTDB-2679] Support logical operators in select clauses (#5273)
* remove mode change * remove mode change * Split logic and compare expressions * Fix == and != to support boolean type * Add priority description about operators * Add priority description about operators
1 parent c6e47b9 commit 1705a8a

36 files changed

+1872
-130
lines changed

antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ triggerAttributeClause
123123
;
124124

125125
triggerAttribute
126-
: key=STRING_LITERAL OPERATOR_EQ value=STRING_LITERAL
126+
: key=STRING_LITERAL operator_eq value=STRING_LITERAL
127127
;
128128

129129
// Create Continuous Query
@@ -137,7 +137,7 @@ cqSelectIntoClause
137137

138138
cqGroupByTimeClause
139139
: GROUP BY TIME LR_BRACKET DURATION_LITERAL RR_BRACKET
140-
(COMMA LEVEL OPERATOR_EQ INTEGER_LITERAL (COMMA INTEGER_LITERAL)*)?
140+
(COMMA LEVEL operator_eq INTEGER_LITERAL (COMMA INTEGER_LITERAL)*)?
141141
;
142142

143143
resampleClause
@@ -159,7 +159,7 @@ alterClause
159159
;
160160

161161
aliasClause
162-
: ALIAS OPERATOR_EQ identifier
162+
: ALIAS operator_eq identifier
163163
;
164164

165165
// Delete Storage Group
@@ -313,12 +313,12 @@ countDevices
313313

314314
// Count Timeseries
315315
countTimeseries
316-
: COUNT TIMESERIES prefixPath? (GROUP BY LEVEL OPERATOR_EQ INTEGER_LITERAL)?
316+
: COUNT TIMESERIES prefixPath? (GROUP BY LEVEL operator_eq INTEGER_LITERAL)?
317317
;
318318

319319
// Count Nodes
320320
countNodes
321-
: COUNT NODES prefixPath LEVEL OPERATOR_EQ INTEGER_LITERAL
321+
: COUNT NODES prefixPath LEVEL operator_eq INTEGER_LITERAL
322322
;
323323

324324

@@ -377,7 +377,7 @@ orderByTimeClause
377377
groupByTimeClause
378378
: GROUP BY LR_BRACKET timeRange COMMA DURATION_LITERAL (COMMA DURATION_LITERAL)? RR_BRACKET
379379
| GROUP BY LR_BRACKET timeRange COMMA DURATION_LITERAL (COMMA DURATION_LITERAL)? RR_BRACKET
380-
COMMA LEVEL OPERATOR_EQ INTEGER_LITERAL (COMMA INTEGER_LITERAL)*
380+
COMMA LEVEL operator_eq INTEGER_LITERAL (COMMA INTEGER_LITERAL)*
381381
;
382382

383383
groupByFillClause
@@ -386,7 +386,7 @@ groupByFillClause
386386
;
387387

388388
groupByLevelClause
389-
: GROUP BY LEVEL OPERATOR_EQ INTEGER_LITERAL (COMMA INTEGER_LITERAL)*
389+
: GROUP BY LEVEL operator_eq INTEGER_LITERAL (COMMA INTEGER_LITERAL)*
390390
;
391391

392392
fillClause
@@ -662,9 +662,9 @@ loadFile
662662
;
663663

664664
loadFilesClause
665-
: AUTOREGISTER OPERATOR_EQ BOOLEAN_LITERAL (COMMA loadFilesClause)?
666-
| SGLEVEL OPERATOR_EQ INTEGER_LITERAL (COMMA loadFilesClause)?
667-
| VERIFY OPERATOR_EQ BOOLEAN_LITERAL (COMMA loadFilesClause)?
665+
: AUTOREGISTER operator_eq BOOLEAN_LITERAL (COMMA loadFilesClause)?
666+
| SGLEVEL operator_eq INTEGER_LITERAL (COMMA loadFilesClause)?
667+
| VERIFY operator_eq BOOLEAN_LITERAL (COMMA loadFilesClause)?
668668
;
669669

670670
// Remove TsFile
@@ -778,8 +778,11 @@ dateExpression
778778
expression
779779
: LR_BRACKET unaryInBracket=expression RR_BRACKET
780780
| (PLUS | MINUS) unaryAfterSign=expression
781+
| OPERATOR_NOT unaryAfterNot=expression
781782
| leftExpression=expression (STAR | DIV | MOD) rightExpression=expression
782783
| leftExpression=expression (PLUS | MINUS) rightExpression=expression
784+
| leftExpression=expression (OPERATOR_GT | OPERATOR_GTE | OPERATOR_LT | OPERATOR_LTE | OPERATOR_DEQ | OPERATOR_NEQ) rightExpression=expression
785+
| leftExpression=expression (OPERATOR_AND | OPERATOR_OR) rightExpression=expression
783786
| functionName LR_BRACKET expression (COMMA expression)* functionAttribute* RR_BRACKET
784787
| suffixPathCanInExpr
785788
| constant
@@ -791,7 +794,7 @@ functionName
791794
;
792795

793796
functionAttribute
794-
: COMMA functionAttributeKey=STRING_LITERAL OPERATOR_EQ functionAttributeValue=STRING_LITERAL
797+
: COMMA functionAttributeKey=STRING_LITERAL OPERATOR_SEQ functionAttributeValue=STRING_LITERAL
795798
;
796799

797800
containsExpression
@@ -813,12 +816,18 @@ predicate
813816
| (suffixPath | fullPath) (REGEXP | LIKE) STRING_LITERAL
814817
;
815818

819+
operator_eq
820+
: OPERATOR_SEQ
821+
| OPERATOR_DEQ
822+
;
823+
816824
comparisonOperator
817825
: type = OPERATOR_GT
818826
| type = OPERATOR_GTE
819827
| type = OPERATOR_LT
820828
| type = OPERATOR_LTE
821-
| type = OPERATOR_EQ
829+
| type = OPERATOR_DEQ
830+
| type = OPERATOR_SEQ
822831
| type = OPERATOR_NEQ
823832
;
824833

@@ -862,16 +871,16 @@ fromClause
862871
// Attribute Clause
863872

864873
attributeClauses
865-
: alias? WITH DATATYPE OPERATOR_EQ dataType=DATATYPE_VALUE
866-
(COMMA ENCODING OPERATOR_EQ encoding=ENCODING_VALUE)?
867-
(COMMA (COMPRESSOR | COMPRESSION) OPERATOR_EQ compressor=COMPRESSOR_VALUE)?
874+
: alias? WITH DATATYPE operator_eq dataType=DATATYPE_VALUE
875+
(COMMA ENCODING operator_eq encoding=ENCODING_VALUE)?
876+
(COMMA (COMPRESSOR | COMPRESSION) operator_eq compressor=COMPRESSOR_VALUE)?
868877
(COMMA propertyClause)*
869878
tagClause?
870879
attributeClause?
871880
// Simplified version (supported since v0.13)
872-
| alias? WITH? (DATATYPE OPERATOR_EQ)? dataType=DATATYPE_VALUE
873-
(ENCODING OPERATOR_EQ encoding=ENCODING_VALUE)?
874-
((COMPRESSOR | COMPRESSION) OPERATOR_EQ compressor=COMPRESSOR_VALUE)?
881+
| alias? WITH? (DATATYPE operator_eq)? dataType=DATATYPE_VALUE
882+
(ENCODING operator_eq encoding=ENCODING_VALUE)?
883+
((COMPRESSOR | COMPRESSION) operator_eq compressor=COMPRESSOR_VALUE)?
875884
propertyClause*
876885
tagClause?
877886
attributeClause?
@@ -886,7 +895,7 @@ tagClause
886895
;
887896

888897
propertyClause
889-
: name=identifier OPERATOR_EQ value=propertyValue
898+
: name=identifier (OPERATOR_SEQ | OPERATOR_DEQ) value=propertyValue
890899
;
891900

892901
propertyValue

antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,8 @@ MOD : '%';
827827

828828
// Operators. Comparation
829829

830-
OPERATOR_EQ : '=' | '==';
830+
OPERATOR_DEQ : '==';
831+
OPERATOR_SEQ : '=';
831832
OPERATOR_GT : '>';
832833
OPERATOR_GTE : '>=';
833834
OPERATOR_LT : '<';

docs/UserGuide/Query-Data/Select-Expression.md

Lines changed: 80 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,21 @@ A selection expression (`selectExpr`) is a component of a SELECT clause, each `s
2727

2828
```sql
2929
selectClause
30-
: SELECT resultColumn (',' resultColumn)*
31-
;
30+
: SELECT resultColumn (',' resultColumn)*
31+
;
3232

3333
resultColumn
34-
: selectExpr (AS alias)?
34+
: selectExpr (AS alias)?
3535
;
3636

3737
selectExpr
38-
: '(' selectExpr ')'
38+
: '(' selectExpr ')'
3939
| '-' selectExpr
40+
| '!' selectExpr
4041
| selectExpr ('*' | '/' | '%') selectExpr
4142
| selectExpr ('+' | '-') selectExpr
43+
| selectExpr ('>' | '>=' | '<' | '<=' | '==' | '!=') selectExpr
44+
| selectExpr (AND | OR) selectExpr
4245
| functionName '(' selectExpr (',' selectExpr)* functionAttribute* ')'
4346
| timeSeriesSuffixPath
4447
| number
@@ -60,6 +63,7 @@ From this syntax definition, `selectExpr` can contain:
6063

6164
## Arithmetic Query
6265

66+
6367
> Please note that Aligned Timeseries has not been supported in Arithmetic Query yet. An error message is expected if you use Arithmetic Query with Aligned Timeseries selected.
6468
6569
### Operators
@@ -68,7 +72,7 @@ From this syntax definition, `selectExpr` can contain:
6872

6973
Supported operators: `+`, `-`
7074

71-
Supported input data types: `INT32`, `INT64`, `FLOAT` and `DOUBLE`
75+
Supported input data types: `INT32`, `INT64` and `FLOAT`
7276

7377
Output data type: consistent with the input data type
7478

@@ -104,6 +108,77 @@ Total line number = 5
104108
It costs 0.014s
105109
```
106110

111+
## Compare Expression
112+
#### Unary Logical Operators
113+
Supported operator `!`
114+
115+
Supported input data types: `BOOLEAN`
116+
117+
Output data type: `BOOLEAN`
118+
119+
Hint: the priority of `!` is the same as `-`. Remember to use brackets to modify priority.
120+
121+
#### Binary Compare Operators
122+
123+
Supported operators `>`, `>=`, `<`, `<=`, `==`, `!=`
124+
125+
Supported input data types: `INT32`, `INT64`, `FLOAT` and `DOUBLE`
126+
127+
It will transform all type to `DOUBLE` then do computation.
128+
129+
Output data type: `BOOLEAN`
130+
131+
#### Binary Logical Operators
132+
133+
Supported operators AND:`and`,`&`, `&&`; OR:`or`,`|`,`||`
134+
135+
Supported input data types: `BOOLEAN`
136+
137+
Output data type: `BOOLEAN`
138+
139+
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.
140+
141+
### Example
142+
```sql
143+
select a, b, a > 10, a <= b, !(a <= b), a > 10 && a > b from root.test;
144+
```
145+
146+
Output:
147+
```
148+
IoTDB> select a, b, a > 10, a <= b, !(a <= b), a > 10 && a > b from root.test;
149+
+-----------------------------+-----------+-----------+----------------+--------------------------+---------------------------+------------------------------------------------+
150+
| 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)|
151+
+-----------------------------+-----------+-----------+----------------+--------------------------+---------------------------+------------------------------------------------+
152+
|1970-01-01T08:00:00.001+08:00| 23| 10.0| true| false| true| true|
153+
|1970-01-01T08:00:00.002+08:00| 33| 21.0| true| false| true| true|
154+
|1970-01-01T08:00:00.004+08:00| 13| 15.0| true| true| false| false|
155+
|1970-01-01T08:00:00.005+08:00| 26| 0.0| true| false| true| true|
156+
|1970-01-01T08:00:00.008+08:00| 1| 22.0| false| true| false| false|
157+
|1970-01-01T08:00:00.010+08:00| 23| 12.0| true| false| true| true|
158+
+-----------------------------+-----------+-----------+----------------+--------------------------+---------------------------+------------------------------------------------+
159+
```
160+
161+
## Priority of Operators
162+
163+
|priority|operator |meaning |
164+
|:---:|:------------|:------------------|
165+
|1 |`-` |Unary operator negative |
166+
|1 |`+` |Unary operator positive |
167+
|1 |`!` |Unary operator negation |
168+
|2 |`*` |Binary operator multiply |
169+
|2 |`/` |Binary operator division |
170+
|2 |`%` |Binary operator remainder|
171+
|3 |`+` |Binary operator add |
172+
|3 |`-` |Binary operator minus |
173+
|4 |`>` |Binary compare operator greater than|
174+
|4 |`>=` |Binary compare operator greater or equal to|
175+
|4 |`<` |Binary compare operator less than|
176+
|4 |`<=` |Binary compare operator less or equal to|
177+
|4 |`==` |Binary compare operator equal to|
178+
|4 |`!=`/`<>` |Binary compare operator non-equal to|
179+
|5 |`and`/`&`/`&&` |Binary logic operator and|
180+
|5 |`or`/ &#124; / &#124;&#124; |Binary logic operator or|
181+
107182
## Time Series Generating Functions
108183

109184
The time series generating function takes several time series as input and outputs one time series. Unlike the aggregation function, the result set of the time series generating function has a timestamp column.

docs/zh/UserGuide/Query-Data/Select-Expression.md

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,11 @@ resultColumn
3737
selectExpr
3838
: '(' selectExpr ')'
3939
| '-' selectExpr
40+
| '!' selectExpr
4041
| selectExpr ('*' | '/' | '%') selectExpr
4142
| selectExpr ('+' | '-') selectExpr
43+
| selectExpr ('>' | '>=' | '<' | '<=' | '==' | '!=') selectExpr
44+
| selectExpr (AND | OR) selectExpr
4245
| functionName '(' selectExpr (',' selectExpr)* functionAttribute* ')'
4346
| timeSeriesSuffixPath
4447
| number
@@ -54,6 +57,7 @@ selectExpr
5457
- 用户自定义函数,详见 [UDF](../Process-Data/UDF-User-Defined-Function.md)
5558
- 表达式
5659
- 算数运算表达式
60+
- 逻辑运算表达式
5761
- 时间序列查询嵌套表达式
5862
- 聚合查询嵌套表达式
5963
- 数字常量(仅用于表达式)
@@ -68,15 +72,15 @@ selectExpr
6872

6973
支持的运算符:`+`, `-`
7074

71-
输入数据类型要求:`INT32`, `INT64`, `FLOAT` `DOUBLE`
75+
输入数据类型要求:`INT32`, `INT64`, `FLOAT`, `DOUBLE`
7276

7377
输出数据类型:与输入数据类型一致
7478

7579
#### 二元算数运算符
7680

7781
支持的运算符:`+`, `-`, `*`, `/`, `%`
7882

79-
输入数据类型要求:`INT32`, `INT64`, `FLOAT` `DOUBLE`
83+
输入数据类型要求:`INT32`, `INT64`, `FLOAT``DOUBLE`
8084

8185
输出数据类型:`DOUBLE`
8286

@@ -106,6 +110,78 @@ Total line number = 5
106110
It costs 0.014s
107111
```
108112

113+
## 逻辑运算查询
114+
#### 一元逻辑运算符
115+
支持运算符 `!`
116+
117+
输入数据类型:`BOOLEAN`
118+
119+
输出数据类型:`BOOLEAN`
120+
121+
注意:`!`的优先级很高,记得使用括号调整优先级
122+
123+
#### 二元比较运算符
124+
125+
支持运算符 `>`, `>=`, `<`, `<=`, `==`, `!=`
126+
127+
输入数据类型: `INT32`, `INT64`, `FLOAT`, `DOUBLE`
128+
129+
会将所有数据转换为`DOUBLE`类型后进行比较。`==``!=`可以直接比较两个`BOOLEAN`
130+
131+
返回类型:`BOOLEAN`
132+
133+
#### 二元逻辑运算符
134+
135+
支持运算符 AND:`and`,`&`, `&&`; OR:`or`,`|`,`||`
136+
137+
输入数据类型:`BOOLEAN`
138+
139+
返回类型 `BOOLEAN`
140+
141+
注意:当某个时间戳下左操作数和右操作数都为`BOOLEAN`类型时,二元逻辑操作才会有输出结果
142+
143+
### 使用示例
144+
例如:
145+
```sql
146+
select a, b, a > 10, a <= b, !(a <= b), a > 10 && a > b from root.test;
147+
```
148+
输出:
149+
```
150+
IoTDB> select a, b, a > 10, a <= b, !(a <= b), a > 10 && a > b from root.test;
151+
+-----------------------------+-----------+-----------+----------------+--------------------------+---------------------------+------------------------------------------------+
152+
| 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)|
153+
+-----------------------------+-----------+-----------+----------------+--------------------------+---------------------------+------------------------------------------------+
154+
|1970-01-01T08:00:00.001+08:00| 23| 10.0| true| false| true| true|
155+
|1970-01-01T08:00:00.002+08:00| 33| 21.0| true| false| true| true|
156+
|1970-01-01T08:00:00.004+08:00| 13| 15.0| true| true| false| false|
157+
|1970-01-01T08:00:00.005+08:00| 26| 0.0| true| false| true| true|
158+
|1970-01-01T08:00:00.008+08:00| 1| 22.0| false| true| false| false|
159+
|1970-01-01T08:00:00.010+08:00| 23| 12.0| true| false| true| true|
160+
+-----------------------------+-----------+-----------+----------------+--------------------------+---------------------------+------------------------------------------------+
161+
```
162+
163+
## 运算符优先级
164+
165+
|优先级 |运算符 |含义 |
166+
|-------|-------|-----------|
167+
|1 |`-` |单目运算符负号 |
168+
|1 |`+` |单目运算符正号 |
169+
|1 |`!` |单目运算符取非 |
170+
|2 |`*` |双目运算符乘 |
171+
|2 |`/` |双目运算符除 |
172+
|2 |`%` |双目运算符取余|
173+
|3 |`+` |双目运算符加|
174+
|3 |`-` |双目运算符减|
175+
|4 |`>` |双目比较运算符大于|
176+
|4 |`>=` |双目比较运算符大于等于|
177+
|4 |`<` |双目比较运算符小于|
178+
|4 |`<=` |双目比较运算符小于等于|
179+
|4 |`==` |双目比较运算符等于|
180+
|4 |`!=`/`<>` |双目比较运算符不等于|
181+
|5 |`and`/`&`/`&&`|双目逻辑运算符与|
182+
|5 |`or`/ &#124; / &#124;&#124;|双目逻辑运算符或|
183+
<!--- &#124;即管道符 转义不能用在``里, 表格内不允许使用管道符 -->
184+
109185
## 内置时间序列生成函数
110186

111187
时间序列生成函数可接受若干原始时间序列作为输入,产生一列时间序列输出。与聚合函数不同的是,时间序列生成函数的结果集带有时间戳列。

0 commit comments

Comments
 (0)