in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/PredicateUtils.java [74:185]
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)) {
// time filter don't support LIKE and 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 = checkBetweenConstantSatisfy(secondExpression, thirdExpression);
} else if (secondExpression.getExpressionType().equals(ExpressionType.TIMESTAMP)) {
isTimeFilter = checkBetweenConstantSatisfy(firstExpression, thirdExpression);
} else if (thirdExpression.getExpressionType().equals(ExpressionType.TIMESTAMP)) {
isTimeFilter = checkBetweenConstantSatisfy(secondExpression, firstExpression);
}
if (isTimeFilter) {
return new Pair<>(predicate, false);
}
return new Pair<>(null, true);
} else if (predicate.getExpressionType().equals(ExpressionType.IS_NULL)) {
// time filter don't support 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 if (ExpressionType.FUNCTION.equals(predicate.getExpressionType())) {
return new Pair<>(null, true);
} else {
throw new UnknownExpressionTypeException(predicate.getExpressionType());
}
}