This is an automated email from the ASF dual-hosted git repository. hui pushed a commit to branch lmh/checkWhere1.0 in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 92fd6a9d729ca00ebfdd2765580f057b276c9fe4 Author: liuminghui233 <[email protected]> AuthorDate: Sun Dec 11 18:43:40 2022 +0800 [IOTDB-5161] Add output type check for WHERE & HAVING clause (#8381) (cherry picked from commit 14d4cc1d7d2d94c0bcde4f811d2071538539ab24) --- .../java/org/apache/iotdb/db/it/IoTDBFilterIT.java | 17 ++++++++++ .../iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java | 38 ++++++++++++++++++---- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBFilterIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBFilterIT.java index 50d352ae61..7a64a5592e 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBFilterIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBFilterIT.java @@ -35,6 +35,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import static org.apache.iotdb.db.it.utils.TestUtils.assertTestFail; import static org.apache.iotdb.db.it.utils.TestUtils.resultSetEqualTest; import static org.apache.iotdb.itbase.constant.TestConstant.TIMESTAMP_STR; import static org.apache.iotdb.itbase.constant.TestConstant.count; @@ -194,4 +195,20 @@ public class IoTDBFilterIT { fail(throwable.getMessage()); } } + + @Test + public void testMismatchedDataTypes() { + assertTestFail( + "select s1 from root.sg1.d1 where s1;", + "The output type of the expression in WHERE clause should be BOOLEAN, actual data type: FLOAT."); + assertTestFail( + "select count(s1) from root.sg1.d1 group by ([0, 40), 5ms) having count(s1) + 1;", + "The output type of the expression in HAVING clause should be BOOLEAN, actual data type: DOUBLE."); + assertTestFail( + "select s1 from root.sg1.d1 where s1 align by device;", + "The output type of the expression in WHERE clause should be BOOLEAN, actual data type: FLOAT."); + assertTestFail( + "select count(s1) from root.sg1.d1 group by ([0, 40), 5ms) having count(s1) + 1 align by device;", + "The output type of the expression in HAVING clause should be BOOLEAN, actual data type: DOUBLE."); + } } diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java index aff917599b..81910ef650 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java @@ -569,8 +569,13 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext> Expression havingExpression = ExpressionUtils.constructQueryFilter( conJunctions.stream().distinct().collect(Collectors.toList())); - analyzeExpression(analysis, havingExpression); - + TSDataType outputType = analyzeExpression(analysis, havingExpression); + if (outputType != TSDataType.BOOLEAN) { + throw new SemanticException( + String.format( + "The output type of the expression in HAVING clause should be BOOLEAN, actual data type: %s.", + outputType)); + } analysis.setHavingExpression(havingExpression); } @@ -610,7 +615,13 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext> } havingExpression = ExpressionUtils.constructQueryFilter(new ArrayList<>(conJunctions)); - analyzeExpression(analysis, havingExpression); + TSDataType outputType = analyzeExpression(analysis, havingExpression); + if (outputType != TSDataType.BOOLEAN) { + throw new SemanticException( + String.format( + "The output type of the expression in HAVING clause should be BOOLEAN, actual data type: %s.", + outputType)); + } analysis.setHavingExpression(havingExpression); } @@ -962,8 +973,16 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext> } throw e; } + + TSDataType outputType = analyzeExpression(analysis, whereExpression); + if (outputType != TSDataType.BOOLEAN) { + throw new SemanticException( + String.format( + "The output type of the expression in WHERE clause should be BOOLEAN, actual data type: %s.", + outputType)); + } + deviceToWhereExpression.put(devicePath.getFullPath(), whereExpression); - analyzeExpression(analysis, whereExpression); } analysis.setDeviceToWhereExpression(deviceToWhereExpression); } @@ -982,7 +1001,13 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext> Expression whereExpression = ExpressionUtils.constructQueryFilter( conJunctions.stream().distinct().collect(Collectors.toList())); - analyzeExpression(analysis, whereExpression); + TSDataType outputType = analyzeExpression(analysis, whereExpression); + if (outputType != TSDataType.BOOLEAN) { + throw new SemanticException( + String.format( + "The output type of the expression in WHERE clause should be BOOLEAN, actual data type: %s.", + outputType)); + } analysis.setWhereExpression(whereExpression); } @@ -1093,8 +1118,9 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext> analysis.setMergeOrderParameter(new OrderByParameter(queryStatement.getSortItemList())); } - private void analyzeExpression(Analysis analysis, Expression expression) { + private TSDataType analyzeExpression(Analysis analysis, Expression expression) { ExpressionTypeAnalyzer.analyzeExpression(analysis, expression); + return analysis.getType(expression); } private void analyzeGroupBy(Analysis analysis, QueryStatement queryStatement) {
