This is an automated email from the ASF dual-hosted git repository. hui pushed a commit to branch lmh/refactorFilter in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit d5699d9273dea4002c5522d7cf750fbdf43ee939 Author: Minghui Liu <[email protected]> AuthorDate: Sun Nov 19 22:13:39 2023 +0800 add PredicateUtils --- .../db/queryengine/common/MPPQueryContext.java | 4 +- .../fragment/FragmentInstanceContext.java | 4 +- .../queryengine/plan/analyze/AnalyzeVisitor.java | 14 +- .../plan/analyze/ExpressionAnalyzer.java | 232 ------------------ .../queryengine/plan/analyze/ExpressionUtils.java | 62 ----- .../queryengine/plan/analyze/PredicateUtils.java | 270 +++++++++++++++++++++ .../ConvertExpressionToTimeFilterVisitor.java | 25 ++ .../ExtractGlobalTimePredicateVisitor.java | 136 ----------- .../metadata/CreateContinuousQueryStatement.java | 4 +- 9 files changed, 308 insertions(+), 443 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/MPPQueryContext.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/MPPQueryContext.java index 94a5f753d3d..40231951ad0 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/MPPQueryContext.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/MPPQueryContext.java @@ -22,7 +22,7 @@ package org.apache.iotdb.db.queryengine.common; import org.apache.iotdb.common.rpc.thrift.TEndPoint; import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet; import org.apache.iotdb.db.queryengine.plan.analyze.Analysis; -import org.apache.iotdb.db.queryengine.plan.analyze.ExpressionUtils; +import org.apache.iotdb.db.queryengine.plan.analyze.PredicateUtils; import org.apache.iotdb.db.queryengine.plan.analyze.QueryType; import org.apache.iotdb.db.queryengine.plan.analyze.TypeProvider; import org.apache.iotdb.tsfile.read.filter.basic.Filter; @@ -157,7 +157,7 @@ public class MPPQueryContext { public void generateGlobalTimeFilter(Analysis analysis) { this.globalTimeFilter = - ExpressionUtils.convertPredicateToTimeFilter(analysis.getGlobalTimePredicate()); + PredicateUtils.convertPredicateToTimeFilter(analysis.getGlobalTimePredicate()); } public Filter getGlobalTimeFilter() { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/fragment/FragmentInstanceContext.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/fragment/FragmentInstanceContext.java index 3dcaea19f31..7220106705f 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/fragment/FragmentInstanceContext.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/fragment/FragmentInstanceContext.java @@ -25,7 +25,7 @@ import org.apache.iotdb.db.exception.query.QueryProcessException; import org.apache.iotdb.db.queryengine.common.FragmentInstanceId; import org.apache.iotdb.db.queryengine.common.QueryId; import org.apache.iotdb.db.queryengine.common.SessionInfo; -import org.apache.iotdb.db.queryengine.plan.analyze.ExpressionUtils; +import org.apache.iotdb.db.queryengine.plan.analyze.PredicateUtils; import org.apache.iotdb.db.queryengine.plan.expression.Expression; import org.apache.iotdb.db.storageengine.dataregion.IDataRegionForQuery; import org.apache.iotdb.db.storageengine.dataregion.read.QueryDataSource; @@ -153,7 +153,7 @@ public class FragmentInstanceContext extends QueryContext { this.executionEndTime.set(END_TIME_INITIAL_VALUE); this.sessionInfo = sessionInfo; this.dataRegion = dataRegion; - this.globalTimeFilter = ExpressionUtils.convertPredicateToTimeFilter(globalTimePredicate); + this.globalTimeFilter = PredicateUtils.convertPredicateToTimeFilter(globalTimePredicate); this.dataNodeQueryContextMap = dataNodeQueryContextMap; this.dataNodeQueryContext = dataNodeQueryContextMap.get(id.getQueryId()); } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java index 9e1c0757e86..c47883c4ca6 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java @@ -392,14 +392,14 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext> Expression predicate = whereCondition.getPredicate(); Pair<Expression, Boolean> resultPair = - ExpressionAnalyzer.extractGlobalTimePredicate(predicate, true, true); + PredicateUtils.extractGlobalTimePredicate(predicate, true, true); globalTimePredicate = resultPair.left; if (globalTimePredicate != null) { - globalTimePredicate = ExpressionAnalyzer.predicateRemoveNot(globalTimePredicate); + globalTimePredicate = PredicateUtils.predicateRemoveNot(globalTimePredicate); } hasValueFilter = resultPair.right; - predicate = ExpressionAnalyzer.evaluatePredicate(predicate); + predicate = PredicateUtils.simplifyPredicate(predicate); // set where condition to null if predicate is true or time filter. if (!hasValueFilter @@ -753,7 +753,7 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext> schemaTree, true); Expression havingExpression = - ExpressionUtils.constructQueryFilter( + PredicateUtils.combineConjuncts( conJunctions.stream().distinct().collect(Collectors.toList())); havingExpression = normalizeExpression(havingExpression); @@ -816,7 +816,7 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext> } } - havingExpression = ExpressionUtils.constructQueryFilter(new ArrayList<>(conJunctions)); + havingExpression = PredicateUtils.combineConjuncts(new ArrayList<>(conJunctions)); TSDataType outputType = analyzeExpressionType(analysis, havingExpression); if (outputType != TSDataType.BOOLEAN) { throw new SemanticException( @@ -1308,7 +1308,7 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext> schemaTree, true); Expression whereExpression = - ExpressionUtils.constructQueryFilter( + PredicateUtils.combineConjuncts( conJunctions.stream().distinct().collect(Collectors.toList())); whereExpression = normalizeExpression(whereExpression); TSDataType outputType = analyzeExpressionType(analysis, whereExpression); @@ -1323,7 +1323,7 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext> List<Expression> conJunctions = ExpressionAnalyzer.concatDeviceAndBindSchemaForPredicate( queryStatement.getWhereCondition().getPredicate(), devicePath, schemaTree, true); - return ExpressionUtils.constructQueryFilter( + return PredicateUtils.combineConjuncts( conJunctions.stream().distinct().collect(Collectors.toList())); } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionAnalyzer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionAnalyzer.java index df4732eb5a1..08e58bd4cbe 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionAnalyzer.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionAnalyzer.java @@ -29,8 +29,6 @@ import org.apache.iotdb.db.exception.sql.SemanticException; import org.apache.iotdb.db.queryengine.common.header.ColumnHeader; import org.apache.iotdb.db.queryengine.common.schematree.ISchemaTree; import org.apache.iotdb.db.queryengine.plan.expression.Expression; -import org.apache.iotdb.db.queryengine.plan.expression.ExpressionFactory; -import org.apache.iotdb.db.queryengine.plan.expression.ExpressionType; import org.apache.iotdb.db.queryengine.plan.expression.UnknownExpressionTypeException; import org.apache.iotdb.db.queryengine.plan.expression.binary.BinaryExpression; import org.apache.iotdb.db.queryengine.plan.expression.leaf.ConstantOperand; @@ -41,8 +39,6 @@ import org.apache.iotdb.db.queryengine.plan.expression.leaf.TimestampOperand; import org.apache.iotdb.db.queryengine.plan.expression.multi.FunctionExpression; import org.apache.iotdb.db.queryengine.plan.expression.other.CaseWhenThenExpression; import org.apache.iotdb.db.queryengine.plan.expression.ternary.TernaryExpression; -import org.apache.iotdb.db.queryengine.plan.expression.unary.InExpression; -import org.apache.iotdb.db.queryengine.plan.expression.unary.LogicNotExpression; import org.apache.iotdb.db.queryengine.plan.expression.unary.UnaryExpression; import org.apache.iotdb.db.queryengine.plan.expression.visitor.BindTypeForTimeSeriesOperandVisitor; import org.apache.iotdb.db.queryengine.plan.expression.visitor.CollectAggregationExpressionsVisitor; @@ -50,19 +46,15 @@ import org.apache.iotdb.db.queryengine.plan.expression.visitor.CollectSourceExpr import org.apache.iotdb.db.queryengine.plan.expression.visitor.ExpressionNormalizeVisitor; import org.apache.iotdb.db.queryengine.plan.expression.visitor.GetMeasurementExpressionVisitor; import org.apache.iotdb.db.queryengine.plan.expression.visitor.LowercaseNormalizeVisitor; -import org.apache.iotdb.db.queryengine.plan.expression.visitor.RemoveRootPrefixVisitor; import org.apache.iotdb.db.queryengine.plan.expression.visitor.ReplaceRawPathWithGroupedPathVisitor; import org.apache.iotdb.db.queryengine.plan.expression.visitor.cartesian.BindSchemaForExpressionVisitor; import org.apache.iotdb.db.queryengine.plan.expression.visitor.cartesian.BindSchemaForPredicateVisitor; import org.apache.iotdb.db.queryengine.plan.expression.visitor.cartesian.ConcatDeviceAndBindSchemaForExpressionVisitor; import org.apache.iotdb.db.queryengine.plan.expression.visitor.cartesian.ConcatDeviceAndBindSchemaForPredicateVisitor; import org.apache.iotdb.db.queryengine.plan.expression.visitor.cartesian.ConcatExpressionWithSuffixPathsVisitor; -import org.apache.iotdb.db.queryengine.plan.expression.visitor.predicate.ReversePredicateVisitor; import org.apache.iotdb.db.queryengine.plan.statement.component.ResultColumn; import org.apache.iotdb.db.utils.constant.SqlConstant; import org.apache.iotdb.tsfile.common.constant.TsFileConstant; -import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; -import org.apache.iotdb.tsfile.utils.Pair; import java.util.ArrayList; import java.util.Collection; @@ -71,8 +63,6 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; -import static org.apache.iotdb.db.queryengine.plan.analyze.ExpressionUtils.checkConstantSatisfy; - public class ExpressionAnalyzer { private static final String RAW_AGGREGATION_HYBRID_ERROR_MSG = @@ -469,194 +459,6 @@ public class ExpressionAnalyzer { devicePath, schemaTree, isWhere)); } - /** - * Extract global time predicate from query predicate. - * - * @param predicate raw query predicate - * @param canRewrite determined by the father of current expression - * @param isFirstOr whether it is the first LogicOrExpression encountered - * @return global time predicate - */ - public static Pair<Expression, Boolean> extractGlobalTimePredicate( - Expression predicate, boolean canRewrite, boolean isFirstOr) { - if (predicate.getExpressionType().equals(ExpressionType.LOGIC_AND)) { - Pair<Expression, Boolean> leftResultPair = - extractGlobalTimePredicate( - ((BinaryExpression) predicate).getLeftExpression(), canRewrite, isFirstOr); - Pair<Expression, Boolean> rightResultPair = - extractGlobalTimePredicate( - ((BinaryExpression) predicate).getRightExpression(), canRewrite, isFirstOr); - - // rewrite predicate to avoid duplicate calculation on time filter - // If Left-child or Right-child does not contain value filter - // We can set it to true in Predicate Tree - if (canRewrite) { - if (leftResultPair.left != null && !leftResultPair.right) { - ((BinaryExpression) predicate) - .setLeftExpression(new ConstantOperand(TSDataType.BOOLEAN, "true")); - } - if (rightResultPair.left != null && !rightResultPair.right) { - ((BinaryExpression) predicate) - .setRightExpression(new ConstantOperand(TSDataType.BOOLEAN, "true")); - } - } - - if (leftResultPair.left != null && rightResultPair.left != null) { - return new Pair<>( - ExpressionFactory.and(leftResultPair.left, rightResultPair.left), - leftResultPair.right || rightResultPair.right); - } else if (leftResultPair.left != null) { - return new Pair<>(leftResultPair.left, true); - } else if (rightResultPair.left != null) { - return new Pair<>(rightResultPair.left, true); - } - return new Pair<>(null, true); - } else if (predicate.getExpressionType().equals(ExpressionType.LOGIC_OR)) { - Pair<Expression, Boolean> leftResultPair = - extractGlobalTimePredicate( - ((BinaryExpression) predicate).getLeftExpression(), false, false); - Pair<Expression, Boolean> rightResultPair = - extractGlobalTimePredicate( - ((BinaryExpression) predicate).getRightExpression(), false, false); - - if (leftResultPair.left != null && rightResultPair.left != null) { - if (Boolean.TRUE.equals(isFirstOr && !leftResultPair.right && !rightResultPair.right)) { - ((BinaryExpression) predicate) - .setLeftExpression(new ConstantOperand(TSDataType.BOOLEAN, "true")); - ((BinaryExpression) predicate) - .setRightExpression(new ConstantOperand(TSDataType.BOOLEAN, "true")); - } - return new Pair<>( - ExpressionFactory.or(leftResultPair.left, rightResultPair.left), - leftResultPair.right || rightResultPair.right); - } - return new Pair<>(null, true); - } else if (predicate.getExpressionType().equals(ExpressionType.LOGIC_NOT)) { - Pair<Expression, Boolean> childResultPair = - extractGlobalTimePredicate( - ((UnaryExpression) predicate).getExpression(), canRewrite, isFirstOr); - if (childResultPair.left != null) { - return new Pair<>(ExpressionFactory.not(childResultPair.left), childResultPair.right); - } - return new Pair<>(null, true); - } else if (predicate.isCompareBinaryExpression()) { - Expression leftExpression = ((BinaryExpression) predicate).getLeftExpression(); - Expression rightExpression = ((BinaryExpression) predicate).getRightExpression(); - if (checkIsTimeFilter(leftExpression, rightExpression) - || checkIsTimeFilter(rightExpression, leftExpression)) { - return new Pair<>(predicate, false); - } - return new Pair<>(null, true); - } else if (predicate.getExpressionType().equals(ExpressionType.LIKE) - || predicate.getExpressionType().equals(ExpressionType.REGEXP)) { - return new Pair<>(null, true); - } else if (predicate.getExpressionType().equals(ExpressionType.BETWEEN)) { - Expression firstExpression = ((TernaryExpression) predicate).getFirstExpression(); - Expression secondExpression = ((TernaryExpression) predicate).getSecondExpression(); - Expression thirdExpression = ((TernaryExpression) predicate).getThirdExpression(); - - boolean isTimeFilter = false; - if (firstExpression.getExpressionType().equals(ExpressionType.TIMESTAMP)) { - isTimeFilter = checkBetweenExpressionIsTimeFilter(secondExpression, thirdExpression); - } else if (secondExpression.getExpressionType().equals(ExpressionType.TIMESTAMP)) { - isTimeFilter = - checkConstantSatisfy(firstExpression, thirdExpression) - && checkBetweenExpressionIsTimeFilter(predicate, firstExpression); - } else if (thirdExpression.getExpressionType().equals(ExpressionType.TIMESTAMP)) { - isTimeFilter = - checkConstantSatisfy(secondExpression, firstExpression) - && checkBetweenExpressionIsTimeFilter(predicate, firstExpression); - } - if (isTimeFilter) { - return new Pair<>(predicate, false); - } - return new Pair<>(null, true); - } else if (predicate.getExpressionType().equals(ExpressionType.IS_NULL)) { - return new Pair<>(null, true); - } else if (predicate.getExpressionType().equals(ExpressionType.IN)) { - Expression timeExpression = ((InExpression) predicate).getExpression(); - if (timeExpression.getExpressionType().equals(ExpressionType.TIMESTAMP)) { - return new Pair<>(predicate, false); - } - return new Pair<>(null, true); - } else if (predicate.getExpressionType().equals(ExpressionType.TIMESERIES) - || predicate.getExpressionType().equals(ExpressionType.CONSTANT) - || predicate.getExpressionType().equals(ExpressionType.NULL)) { - return new Pair<>(null, true); - } else if (predicate.getExpressionType().equals(ExpressionType.CASE_WHEN_THEN)) { - return new Pair<>(null, true); - } else { - throw new UnknownExpressionTypeException(predicate.getExpressionType()); - } - } - - private static boolean checkIsTimeFilter(Expression timeExpression, Expression valueExpression) { - return timeExpression.getExpressionType().equals(ExpressionType.TIMESTAMP) - && valueExpression instanceof ConstantOperand - && ((ConstantOperand) valueExpression).getDataType() == TSDataType.INT64; - } - - private static boolean checkBetweenExpressionIsTimeFilter( - Expression firstExpression, Expression secondExpression) { - return firstExpression instanceof ConstantOperand - && secondExpression instanceof ConstantOperand - && ((ConstantOperand) firstExpression).getDataType() == TSDataType.INT64 - && ((ConstantOperand) secondExpression).getDataType() == TSDataType.INT64; - } - - public static Expression predicateRemoveNot(Expression predicate) { - if (predicate.getExpressionType().equals(ExpressionType.LOGIC_AND)) { - return ExpressionFactory.and( - predicateRemoveNot(((BinaryExpression) predicate).getLeftExpression()), - predicateRemoveNot(((BinaryExpression) predicate).getRightExpression())); - } else if (predicate.getExpressionType().equals(ExpressionType.LOGIC_OR)) { - return ExpressionFactory.or( - predicateRemoveNot(((BinaryExpression) predicate).getLeftExpression()), - predicateRemoveNot(((BinaryExpression) predicate).getRightExpression())); - } else if (predicate.getExpressionType().equals(ExpressionType.LOGIC_NOT)) { - return reversePredicate(((LogicNotExpression) predicate).getExpression()); - } - return predicate; - } - - private static Expression reversePredicate(Expression predicate) { - return new ReversePredicateVisitor().process(predicate, null); - } - - public static boolean checkIfTimeFilterExist(Expression predicate) { - if (predicate instanceof TernaryExpression) { - return checkIfTimeFilterExist(((TernaryExpression) predicate).getFirstExpression()) - || checkIfTimeFilterExist(((TernaryExpression) predicate).getSecondExpression()) - || checkIfTimeFilterExist(((TernaryExpression) predicate).getThirdExpression()); - } else if (predicate instanceof BinaryExpression) { - return checkIfTimeFilterExist(((BinaryExpression) predicate).getLeftExpression()) - || checkIfTimeFilterExist(((BinaryExpression) predicate).getRightExpression()); - } else if (predicate instanceof UnaryExpression) { - return checkIfTimeFilterExist(((UnaryExpression) predicate).getExpression()); - } else if (predicate instanceof FunctionExpression) { - boolean timeFilterExist = false; - for (Expression childExpression : predicate.getExpressions()) { - timeFilterExist = timeFilterExist || checkIfTimeFilterExist(childExpression); - } - return timeFilterExist; - } else if (predicate instanceof CaseWhenThenExpression) { - for (Expression childExpression : predicate.getExpressions()) { - if (checkIfTimeFilterExist(childExpression)) { - return true; - } - } - return false; - } else if (predicate instanceof TimeSeriesOperand - || predicate instanceof ConstantOperand - || predicate instanceof NullOperand) { - return false; - } else if (predicate instanceof TimestampOperand) { - return true; - } else { - throw new UnknownExpressionTypeException(predicate.getExpressionType()); - } - } - /** * Search for subexpressions that can be queried natively, including all time series. * @@ -737,36 +539,6 @@ public class ExpressionAnalyzer { return new GetMeasurementExpressionVisitor().process(expression, analysis); } - public static Expression evaluatePredicate(Expression predicate) { - if (predicate.getExpressionType().equals(ExpressionType.LOGIC_AND)) { - Expression left = evaluatePredicate(((BinaryExpression) predicate).getLeftExpression()); - Expression right = evaluatePredicate(((BinaryExpression) predicate).getRightExpression()); - boolean isLeftTrue = - left.isConstantOperand() && Boolean.parseBoolean(left.getExpressionString()); - boolean isRightTrue = - right.isConstantOperand() && Boolean.parseBoolean(right.getExpressionString()); - if (isLeftTrue && isRightTrue) { - return new ConstantOperand(TSDataType.BOOLEAN, "true"); - } else if (isLeftTrue) { - return right; - } else if (isRightTrue) { - return left; - } - return predicate; - } else if (predicate.getExpressionType().equals(ExpressionType.LOGIC_OR)) { - Expression left = evaluatePredicate(((BinaryExpression) predicate).getLeftExpression()); - Expression right = evaluatePredicate(((BinaryExpression) predicate).getRightExpression()); - boolean isLeftTrue = - left.isConstantOperand() && Boolean.parseBoolean(left.getExpressionString()); - boolean isRightTrue = - right.isConstantOperand() && Boolean.parseBoolean(right.getExpressionString()); - if (isRightTrue || isLeftTrue) { - return new ConstantOperand(TSDataType.BOOLEAN, "true"); - } - } - return predicate; - } - /** * Bind DataType for TimeSeriesOperand in Expression with according ColumnHeaderName. eg: * @@ -862,8 +634,4 @@ public class ExpressionAnalyzer { throw new UnknownExpressionTypeException(expression.getExpressionType()); } } - - public static Expression removeRootPrefix(Expression expression) { - return new RemoveRootPrefixVisitor().process(expression, null); - } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionUtils.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionUtils.java index 67aa3e09d65..b2fe438bd91 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionUtils.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ExpressionUtils.java @@ -38,7 +38,6 @@ import org.apache.iotdb.db.queryengine.plan.expression.binary.MultiplicationExpr import org.apache.iotdb.db.queryengine.plan.expression.binary.NonEqualExpression; import org.apache.iotdb.db.queryengine.plan.expression.binary.SubtractionExpression; import org.apache.iotdb.db.queryengine.plan.expression.binary.WhenThenExpression; -import org.apache.iotdb.db.queryengine.plan.expression.leaf.ConstantOperand; import org.apache.iotdb.db.queryengine.plan.expression.leaf.TimeSeriesOperand; import org.apache.iotdb.db.queryengine.plan.expression.multi.FunctionExpression; import org.apache.iotdb.db.queryengine.plan.expression.other.CaseWhenThenExpression; @@ -51,11 +50,6 @@ import org.apache.iotdb.db.queryengine.plan.expression.unary.LogicNotExpression; import org.apache.iotdb.db.queryengine.plan.expression.unary.NegationExpression; import org.apache.iotdb.db.queryengine.plan.expression.unary.RegularExpression; import org.apache.iotdb.db.queryengine.plan.expression.unary.UnaryExpression; -import org.apache.iotdb.db.queryengine.plan.expression.visitor.predicate.ConvertExpressionToTimeFilterVisitor; -import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; -import org.apache.iotdb.tsfile.read.filter.basic.Filter; -import org.apache.iotdb.tsfile.read.filter.factory.TimeFilter; -import org.apache.iotdb.tsfile.utils.Pair; import java.util.ArrayList; import java.util.List; @@ -307,60 +301,4 @@ public class ExpressionUtils { } } } - - public static Pair<Filter, Boolean> getPairFromBetweenTimeSecond( - BetweenExpression predicate, Expression expression) { - if (predicate.isNotBetween()) { - return new Pair<>( - TimeFilter.gt(Long.parseLong(((ConstantOperand) expression).getValueString())), false); - - } else { - return new Pair<>( - TimeFilter.ltEq(Long.parseLong(((ConstantOperand) expression).getValueString())), false); - } - } - - public static Pair<Filter, Boolean> getPairFromBetweenTimeThird( - BetweenExpression predicate, Expression expression) { - if (predicate.isNotBetween()) { - return new Pair<>( - TimeFilter.lt(Long.parseLong(((ConstantOperand) expression).getValueString())), false); - - } else { - return new Pair<>( - TimeFilter.gtEq(Long.parseLong(((ConstantOperand) expression).getValueString())), false); - } - } - - public static boolean checkConstantSatisfy( - Expression firstExpression, Expression secondExpression) { - return firstExpression.isConstantOperand() - && secondExpression.isConstantOperand() - && ((ConstantOperand) firstExpression).getDataType() == TSDataType.INT64 - && ((ConstantOperand) secondExpression).getDataType() == TSDataType.INT64 - && (Long.parseLong(((ConstantOperand) firstExpression).getValueString()) - <= Long.parseLong(((ConstantOperand) secondExpression).getValueString())); - } - - public static Expression constructQueryFilter(List<Expression> expressions) { - if (expressions.size() == 1) { - return expressions.get(0); - } - return ExpressionUtils.constructBinaryFilterTreeWithAnd(expressions); - } - - private static Expression constructBinaryFilterTreeWithAnd(List<Expression> expressions) { - // TODO: consider AVL tree - if (expressions.size() == 2) { - return new LogicAndExpression(expressions.get(0), expressions.get(1)); - } else { - return new LogicAndExpression( - expressions.get(0), - constructBinaryFilterTreeWithAnd(expressions.subList(1, expressions.size()))); - } - } - - public static Filter convertPredicateToTimeFilter(Expression predicate) { - return predicate.accept(new ConvertExpressionToTimeFilterVisitor(), null); - } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/PredicateUtils.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/PredicateUtils.java index 6b72c27e9a7..8e24f1f7e37 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/PredicateUtils.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/PredicateUtils.java @@ -21,9 +21,30 @@ package org.apache.iotdb.db.queryengine.plan.analyze; import org.apache.iotdb.commons.path.PartialPath; import org.apache.iotdb.db.queryengine.plan.expression.Expression; +import org.apache.iotdb.db.queryengine.plan.expression.ExpressionFactory; +import org.apache.iotdb.db.queryengine.plan.expression.ExpressionType; +import org.apache.iotdb.db.queryengine.plan.expression.UnknownExpressionTypeException; +import org.apache.iotdb.db.queryengine.plan.expression.binary.BinaryExpression; +import org.apache.iotdb.db.queryengine.plan.expression.binary.LogicAndExpression; +import org.apache.iotdb.db.queryengine.plan.expression.leaf.ConstantOperand; +import org.apache.iotdb.db.queryengine.plan.expression.leaf.NullOperand; +import org.apache.iotdb.db.queryengine.plan.expression.leaf.TimeSeriesOperand; +import org.apache.iotdb.db.queryengine.plan.expression.leaf.TimestampOperand; +import org.apache.iotdb.db.queryengine.plan.expression.multi.FunctionExpression; +import org.apache.iotdb.db.queryengine.plan.expression.other.CaseWhenThenExpression; +import org.apache.iotdb.db.queryengine.plan.expression.ternary.TernaryExpression; +import org.apache.iotdb.db.queryengine.plan.expression.unary.InExpression; +import org.apache.iotdb.db.queryengine.plan.expression.unary.LogicNotExpression; +import org.apache.iotdb.db.queryengine.plan.expression.unary.UnaryExpression; import org.apache.iotdb.db.queryengine.plan.expression.visitor.predicate.ConvertExpressionToFilterVisitor; +import org.apache.iotdb.db.queryengine.plan.expression.visitor.predicate.ConvertExpressionToTimeFilterVisitor; +import org.apache.iotdb.db.queryengine.plan.expression.visitor.predicate.ReversePredicateVisitor; import org.apache.iotdb.db.queryengine.plan.expression.visitor.predicate.SchemaCompatibilityValidator; +import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; import org.apache.iotdb.tsfile.read.filter.basic.Filter; +import org.apache.iotdb.tsfile.utils.Pair; + +import java.util.List; public class PredicateUtils { @@ -31,6 +52,238 @@ public class PredicateUtils { // util class } + /** + * Extract global time predicate from query predicate. + * + * @param predicate raw query predicate + * @param canRewrite determined by the father of current expression + * @param isFirstOr whether it is the first LogicOrExpression encountered + * @return global time predicate + */ + public static Pair<Expression, Boolean> extractGlobalTimePredicate( + Expression predicate, boolean canRewrite, boolean isFirstOr) { + if (predicate.getExpressionType().equals(ExpressionType.LOGIC_AND)) { + Pair<Expression, Boolean> leftResultPair = + extractGlobalTimePredicate( + ((BinaryExpression) predicate).getLeftExpression(), canRewrite, isFirstOr); + Pair<Expression, Boolean> rightResultPair = + extractGlobalTimePredicate( + ((BinaryExpression) predicate).getRightExpression(), canRewrite, isFirstOr); + + // rewrite predicate to avoid duplicate calculation on time filter + // If Left-child or Right-child does not contain value filter + // We can set it to true in Predicate Tree + if (canRewrite) { + if (leftResultPair.left != null && !leftResultPair.right) { + ((BinaryExpression) predicate) + .setLeftExpression(new ConstantOperand(TSDataType.BOOLEAN, "true")); + } + if (rightResultPair.left != null && !rightResultPair.right) { + ((BinaryExpression) predicate) + .setRightExpression(new ConstantOperand(TSDataType.BOOLEAN, "true")); + } + } + + if (leftResultPair.left != null && rightResultPair.left != null) { + return new Pair<>( + ExpressionFactory.and(leftResultPair.left, rightResultPair.left), + leftResultPair.right || rightResultPair.right); + } else if (leftResultPair.left != null) { + return new Pair<>(leftResultPair.left, true); + } else if (rightResultPair.left != null) { + return new Pair<>(rightResultPair.left, true); + } + return new Pair<>(null, true); + } else if (predicate.getExpressionType().equals(ExpressionType.LOGIC_OR)) { + Pair<Expression, Boolean> leftResultPair = + extractGlobalTimePredicate( + ((BinaryExpression) predicate).getLeftExpression(), false, false); + Pair<Expression, Boolean> rightResultPair = + extractGlobalTimePredicate( + ((BinaryExpression) predicate).getRightExpression(), false, false); + + if (leftResultPair.left != null && rightResultPair.left != null) { + if (Boolean.TRUE.equals(isFirstOr && !leftResultPair.right && !rightResultPair.right)) { + ((BinaryExpression) predicate) + .setLeftExpression(new ConstantOperand(TSDataType.BOOLEAN, "true")); + ((BinaryExpression) predicate) + .setRightExpression(new ConstantOperand(TSDataType.BOOLEAN, "true")); + } + return new Pair<>( + ExpressionFactory.or(leftResultPair.left, rightResultPair.left), + leftResultPair.right || rightResultPair.right); + } + return new Pair<>(null, true); + } else if (predicate.getExpressionType().equals(ExpressionType.LOGIC_NOT)) { + Pair<Expression, Boolean> childResultPair = + extractGlobalTimePredicate( + ((UnaryExpression) predicate).getExpression(), canRewrite, isFirstOr); + if (childResultPair.left != null) { + return new Pair<>(ExpressionFactory.not(childResultPair.left), childResultPair.right); + } + return new Pair<>(null, true); + } else if (predicate.isCompareBinaryExpression()) { + Expression leftExpression = ((BinaryExpression) predicate).getLeftExpression(); + Expression rightExpression = ((BinaryExpression) predicate).getRightExpression(); + if (checkIsTimeFilter(leftExpression, rightExpression) + || checkIsTimeFilter(rightExpression, leftExpression)) { + return new Pair<>(predicate, false); + } + return new Pair<>(null, true); + } else if (predicate.getExpressionType().equals(ExpressionType.LIKE) + || predicate.getExpressionType().equals(ExpressionType.REGEXP)) { + return new Pair<>(null, true); + } else if (predicate.getExpressionType().equals(ExpressionType.BETWEEN)) { + Expression firstExpression = ((TernaryExpression) predicate).getFirstExpression(); + Expression secondExpression = ((TernaryExpression) predicate).getSecondExpression(); + Expression thirdExpression = ((TernaryExpression) predicate).getThirdExpression(); + + boolean isTimeFilter = false; + if (firstExpression.getExpressionType().equals(ExpressionType.TIMESTAMP)) { + isTimeFilter = checkBetweenExpressionIsTimeFilter(secondExpression, thirdExpression); + } else if (secondExpression.getExpressionType().equals(ExpressionType.TIMESTAMP)) { + isTimeFilter = + checkConstantSatisfy(firstExpression, thirdExpression) + && checkBetweenExpressionIsTimeFilter(predicate, firstExpression); + } else if (thirdExpression.getExpressionType().equals(ExpressionType.TIMESTAMP)) { + isTimeFilter = + checkConstantSatisfy(secondExpression, firstExpression) + && checkBetweenExpressionIsTimeFilter(predicate, firstExpression); + } + if (isTimeFilter) { + return new Pair<>(predicate, false); + } + return new Pair<>(null, true); + } else if (predicate.getExpressionType().equals(ExpressionType.IS_NULL)) { + return new Pair<>(null, true); + } else if (predicate.getExpressionType().equals(ExpressionType.IN)) { + Expression timeExpression = ((InExpression) predicate).getExpression(); + if (timeExpression.getExpressionType().equals(ExpressionType.TIMESTAMP)) { + return new Pair<>(predicate, false); + } + return new Pair<>(null, true); + } else if (predicate.getExpressionType().equals(ExpressionType.TIMESERIES) + || predicate.getExpressionType().equals(ExpressionType.CONSTANT) + || predicate.getExpressionType().equals(ExpressionType.NULL)) { + return new Pair<>(null, true); + } else if (predicate.getExpressionType().equals(ExpressionType.CASE_WHEN_THEN)) { + return new Pair<>(null, true); + } else { + throw new UnknownExpressionTypeException(predicate.getExpressionType()); + } + } + + private static boolean checkIsTimeFilter(Expression timeExpression, Expression valueExpression) { + return timeExpression.getExpressionType().equals(ExpressionType.TIMESTAMP) + && valueExpression instanceof ConstantOperand + && ((ConstantOperand) valueExpression).getDataType() == TSDataType.INT64; + } + + private static boolean checkBetweenExpressionIsTimeFilter( + Expression firstExpression, Expression secondExpression) { + return firstExpression instanceof ConstantOperand + && secondExpression instanceof ConstantOperand + && ((ConstantOperand) firstExpression).getDataType() == TSDataType.INT64 + && ((ConstantOperand) secondExpression).getDataType() == TSDataType.INT64; + } + + public static boolean checkConstantSatisfy( + Expression firstExpression, Expression secondExpression) { + return firstExpression.isConstantOperand() + && secondExpression.isConstantOperand() + && ((ConstantOperand) firstExpression).getDataType() == TSDataType.INT64 + && ((ConstantOperand) secondExpression).getDataType() == TSDataType.INT64 + && (Long.parseLong(((ConstantOperand) firstExpression).getValueString()) + <= Long.parseLong(((ConstantOperand) secondExpression).getValueString())); + } + + public static boolean checkIfTimeFilterExist(Expression predicate) { + if (predicate instanceof TernaryExpression) { + return checkIfTimeFilterExist(((TernaryExpression) predicate).getFirstExpression()) + || checkIfTimeFilterExist(((TernaryExpression) predicate).getSecondExpression()) + || checkIfTimeFilterExist(((TernaryExpression) predicate).getThirdExpression()); + } else if (predicate instanceof BinaryExpression) { + return checkIfTimeFilterExist(((BinaryExpression) predicate).getLeftExpression()) + || checkIfTimeFilterExist(((BinaryExpression) predicate).getRightExpression()); + } else if (predicate instanceof UnaryExpression) { + return checkIfTimeFilterExist(((UnaryExpression) predicate).getExpression()); + } else if (predicate instanceof FunctionExpression) { + boolean timeFilterExist = false; + for (Expression childExpression : predicate.getExpressions()) { + timeFilterExist = timeFilterExist || checkIfTimeFilterExist(childExpression); + } + return timeFilterExist; + } else if (predicate instanceof CaseWhenThenExpression) { + for (Expression childExpression : predicate.getExpressions()) { + if (checkIfTimeFilterExist(childExpression)) { + return true; + } + } + return false; + } else if (predicate instanceof TimeSeriesOperand + || predicate instanceof ConstantOperand + || predicate instanceof NullOperand) { + return false; + } else if (predicate instanceof TimestampOperand) { + return true; + } else { + throw new UnknownExpressionTypeException(predicate.getExpressionType()); + } + } + + public static Expression predicateRemoveNot(Expression predicate) { + if (predicate.getExpressionType().equals(ExpressionType.LOGIC_AND)) { + return ExpressionFactory.and( + predicateRemoveNot(((BinaryExpression) predicate).getLeftExpression()), + predicateRemoveNot(((BinaryExpression) predicate).getRightExpression())); + } else if (predicate.getExpressionType().equals(ExpressionType.LOGIC_OR)) { + return ExpressionFactory.or( + predicateRemoveNot(((BinaryExpression) predicate).getLeftExpression()), + predicateRemoveNot(((BinaryExpression) predicate).getRightExpression())); + } else if (predicate.getExpressionType().equals(ExpressionType.LOGIC_NOT)) { + return reversePredicate(((LogicNotExpression) predicate).getExpression()); + } + return predicate; + } + + private static Expression reversePredicate(Expression predicate) { + return new ReversePredicateVisitor().process(predicate, null); + } + + public static Expression simplifyPredicate(Expression predicate) { + if (predicate.getExpressionType().equals(ExpressionType.LOGIC_AND)) { + Expression left = simplifyPredicate(((BinaryExpression) predicate).getLeftExpression()); + Expression right = simplifyPredicate(((BinaryExpression) predicate).getRightExpression()); + boolean isLeftTrue = + left.isConstantOperand() && Boolean.parseBoolean(left.getExpressionString()); + boolean isRightTrue = + right.isConstantOperand() && Boolean.parseBoolean(right.getExpressionString()); + if (isLeftTrue && isRightTrue) { + return new ConstantOperand(TSDataType.BOOLEAN, "true"); + } else if (isLeftTrue) { + return right; + } else if (isRightTrue) { + return left; + } + return predicate; + } else if (predicate.getExpressionType().equals(ExpressionType.LOGIC_OR)) { + Expression left = simplifyPredicate(((BinaryExpression) predicate).getLeftExpression()); + Expression right = simplifyPredicate(((BinaryExpression) predicate).getRightExpression()); + boolean isLeftTrue = + left.isConstantOperand() && Boolean.parseBoolean(left.getExpressionString()); + boolean isRightTrue = + right.isConstantOperand() && Boolean.parseBoolean(right.getExpressionString()); + if (isRightTrue || isLeftTrue) { + return new ConstantOperand(TSDataType.BOOLEAN, "true"); + } + } + return predicate; + } + + public static Filter convertPredicateToTimeFilter(Expression predicate) { + return predicate.accept(new ConvertExpressionToTimeFilterVisitor(), null); + } + public static void validateSchemaCompatibility(Expression predicate, PartialPath path) { SchemaCompatibilityValidator.validate(predicate, path); } @@ -38,4 +291,21 @@ public class PredicateUtils { public static Filter convertPredicateToFilter(Expression predicate, TypeProvider typeProvider) { return predicate.accept(new ConvertExpressionToFilterVisitor(), typeProvider); } + + public static Expression combineConjuncts(List<Expression> conjuncts) { + if (conjuncts.size() == 1) { + return conjuncts.get(0); + } + return constructRightDeepTreeWithAnd(conjuncts); + } + + private static Expression constructRightDeepTreeWithAnd(List<Expression> conjuncts) { + // TODO: consider other structures of tree + if (conjuncts.size() == 2) { + return new LogicAndExpression(conjuncts.get(0), conjuncts.get(1)); + } else { + return new LogicAndExpression( + conjuncts.get(0), constructRightDeepTreeWithAnd(conjuncts.subList(1, conjuncts.size()))); + } + } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/predicate/ConvertExpressionToTimeFilterVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/predicate/ConvertExpressionToTimeFilterVisitor.java index 07d6c401302..8facfbff971 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/predicate/ConvertExpressionToTimeFilterVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/predicate/ConvertExpressionToTimeFilterVisitor.java @@ -42,6 +42,7 @@ import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; import org.apache.iotdb.tsfile.read.filter.basic.Filter; import org.apache.iotdb.tsfile.read.filter.factory.FilterFactory; import org.apache.iotdb.tsfile.read.filter.factory.TimeFilter; +import org.apache.iotdb.tsfile.utils.Pair; import org.apache.iotdb.tsfile.utils.TimeDuration; import java.util.LinkedHashSet; @@ -223,6 +224,30 @@ public class ConvertExpressionToTimeFilterVisitor extends PredicateVisitor<Filte : TimeFilter.between(minValue, maxValue); } + public static Pair<Filter, Boolean> getPairFromBetweenTimeSecond( + BetweenExpression predicate, Expression expression) { + if (predicate.isNotBetween()) { + return new Pair<>( + TimeFilter.gt(Long.parseLong(((ConstantOperand) expression).getValueString())), false); + + } else { + return new Pair<>( + TimeFilter.ltEq(Long.parseLong(((ConstantOperand) expression).getValueString())), false); + } + } + + public static Pair<Filter, Boolean> getPairFromBetweenTimeThird( + BetweenExpression predicate, Expression expression) { + if (predicate.isNotBetween()) { + return new Pair<>( + TimeFilter.lt(Long.parseLong(((ConstantOperand) expression).getValueString())), false); + + } else { + return new Pair<>( + TimeFilter.gtEq(Long.parseLong(((ConstantOperand) expression).getValueString())), false); + } + } + @Override public Filter visitGroupByTimeExpression( GroupByTimeExpression groupByTimeExpression, Void context) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/predicate/ExtractGlobalTimePredicateVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/predicate/ExtractGlobalTimePredicateVisitor.java deleted file mode 100644 index 2a1b6e6b968..00000000000 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/visitor/predicate/ExtractGlobalTimePredicateVisitor.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.iotdb.db.queryengine.plan.expression.visitor.predicate; - -import org.apache.iotdb.db.queryengine.plan.expression.Expression; -import org.apache.iotdb.db.queryengine.plan.expression.binary.EqualToExpression; -import org.apache.iotdb.db.queryengine.plan.expression.binary.GreaterEqualExpression; -import org.apache.iotdb.db.queryengine.plan.expression.binary.GreaterThanExpression; -import org.apache.iotdb.db.queryengine.plan.expression.binary.LessEqualExpression; -import org.apache.iotdb.db.queryengine.plan.expression.binary.LessThanExpression; -import org.apache.iotdb.db.queryengine.plan.expression.binary.LogicAndExpression; -import org.apache.iotdb.db.queryengine.plan.expression.binary.LogicOrExpression; -import org.apache.iotdb.db.queryengine.plan.expression.binary.NonEqualExpression; -import org.apache.iotdb.db.queryengine.plan.expression.other.GroupByTimeExpression; -import org.apache.iotdb.db.queryengine.plan.expression.ternary.BetweenExpression; -import org.apache.iotdb.db.queryengine.plan.expression.unary.InExpression; -import org.apache.iotdb.db.queryengine.plan.expression.unary.IsNullExpression; -import org.apache.iotdb.db.queryengine.plan.expression.unary.LikeExpression; -import org.apache.iotdb.db.queryengine.plan.expression.unary.LogicNotExpression; -import org.apache.iotdb.db.queryengine.plan.expression.unary.RegularExpression; - -/** Extract global time predicate from query predicate. */ -public class ExtractGlobalTimePredicateVisitor - extends PredicateVisitor<Expression, ExtractGlobalTimePredicateVisitor.Context> { - - @Override - public Expression visitInExpression(InExpression inExpression, Context context) { - return null; - } - - @Override - public Expression visitGroupByTimeExpression( - GroupByTimeExpression groupByTimeExpression, Context context) { - return null; - } - - @Override - public Expression visitIsNullExpression(IsNullExpression isNullExpression, Context context) { - return null; - } - - @Override - public Expression visitLikeExpression(LikeExpression likeExpression, Context context) { - return null; - } - - @Override - public Expression visitRegularExpression(RegularExpression regularExpression, Context context) { - return null; - } - - @Override - public Expression visitLogicNotExpression( - LogicNotExpression logicNotExpression, Context context) { - return null; - } - - @Override - public Expression visitLogicAndExpression( - LogicAndExpression logicAndExpression, Context context) { - return null; - } - - @Override - public Expression visitLogicOrExpression(LogicOrExpression logicOrExpression, Context context) { - return null; - } - - @Override - public Expression visitEqualToExpression(EqualToExpression equalToExpression, Context context) { - return null; - } - - @Override - public Expression visitNonEqualExpression( - NonEqualExpression nonEqualExpression, Context context) { - return null; - } - - @Override - public Expression visitGreaterThanExpression( - GreaterThanExpression greaterThanExpression, Context context) { - return null; - } - - @Override - public Expression visitGreaterEqualExpression( - GreaterEqualExpression greaterEqualExpression, Context context) { - return null; - } - - @Override - public Expression visitLessThanExpression( - LessThanExpression lessThanExpression, Context context) { - return null; - } - - @Override - public Expression visitLessEqualExpression( - LessEqualExpression lessEqualExpression, Context context) { - return null; - } - - @Override - public Expression visitBetweenExpression(BetweenExpression betweenExpression, Context context) { - return null; - } - - protected static class Context { - - boolean hasValueFilter = false; - - // determined by the father of current expression - boolean canRewrite = false; - - // whether it is the first LogicOrExpression encountered - boolean isFirstOr = true; - } -} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/CreateContinuousQueryStatement.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/CreateContinuousQueryStatement.java index 9b5f76a26b1..032c34e86ff 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/CreateContinuousQueryStatement.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/CreateContinuousQueryStatement.java @@ -26,7 +26,7 @@ import org.apache.iotdb.commons.path.PartialPath; import org.apache.iotdb.db.auth.AuthorityChecker; import org.apache.iotdb.db.conf.IoTDBDescriptor; import org.apache.iotdb.db.exception.sql.SemanticException; -import org.apache.iotdb.db.queryengine.plan.analyze.ExpressionAnalyzer; +import org.apache.iotdb.db.queryengine.plan.analyze.PredicateUtils; import org.apache.iotdb.db.queryengine.plan.analyze.QueryType; import org.apache.iotdb.db.queryengine.plan.statement.IConfigStatement; import org.apache.iotdb.db.queryengine.plan.statement.Statement; @@ -220,7 +220,7 @@ public class CreateContinuousQueryStatement extends Statement implements IConfig "CQ: Specifying time range in GROUP BY TIME clause is prohibited."); } if (queryBodyStatement.getWhereCondition() != null - && ExpressionAnalyzer.checkIfTimeFilterExist( + && PredicateUtils.checkIfTimeFilterExist( queryBodyStatement.getWhereCondition().getPredicate())) { throw new SemanticException("CQ: Specifying time filters in the query body is prohibited."); }
