This is an automated email from the ASF dual-hosted git repository. hui pushed a commit to branch lmh/SupportQueryWithView in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 5a4f368eb3033fa896fa0f1fcf77e780595af248 Author: liuminghui233 <[email protected]> AuthorDate: Sat May 27 23:19:15 2023 +0800 refactor expression analyzer --- .../visitor/GetSourcePathsVisitor.java | 4 + .../db/mpp/plan/analyze/ExpressionAnalyzer.java | 74 ++++------- .../iotdb/db/mpp/plan/analyze/ExpressionUtils.java | 137 ++++----------------- .../visitor/ExpressionAnalyzeVisitor.java | 2 +- .../visitor/GetMeasurementExpressionVisitor.java | 16 ++- .../expression/visitor/ReconstructVisitor.java | 3 +- .../RemoveWildcardAndViewInExpressionVisitor.java | 95 -------------- .../RemoveWildcardAndViewInFilterVisitor.java | 109 ---------------- .../BindSchemaForExpressionVisitor.java} | 94 +++++++++++--- .../BindSchemaForPredicateVisitor.java} | 30 +++-- .../{ => cartesian}/CartesianProductVisitor.java | 5 +- ...atDeviceAndBindSchemaForExpressionVisitor.java} | 32 ++++- ...catDeviceAndBindSchemaForPredicateVisitor.java} | 30 ++++- .../ConcatExpressionWithSuffixPathsVisitor.java | 2 +- .../mpp/plan/analyze/ExpressionAnalyzerTest.java | 4 +- 15 files changed, 222 insertions(+), 415 deletions(-) diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/visitor/GetSourcePathsVisitor.java b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/visitor/GetSourcePathsVisitor.java index 321742fdf4c..1874234a39f 100644 --- a/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/visitor/GetSourcePathsVisitor.java +++ b/server/src/main/java/org/apache/iotdb/db/metadata/view/viewExpression/visitor/GetSourcePathsVisitor.java @@ -36,6 +36,10 @@ import java.util.List; /** Use this visitor to find all the paths of time series used in one expression. */ public class GetSourcePathsVisitor extends ViewExpressionVisitor<List<PartialPath>, Void> { + public static List<PartialPath> getSourcePaths(ViewExpression viewExpression) { + return new GetSourcePathsVisitor().process(viewExpression, null); + } + @Override public List<PartialPath> visitExpression(ViewExpression expression, Void context) { return new ArrayList<>(); diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionAnalyzer.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionAnalyzer.java index 8525bedf97a..06025abc88a 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionAnalyzer.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionAnalyzer.java @@ -46,16 +46,14 @@ import org.apache.iotdb.db.mpp.plan.expression.unary.UnaryExpression; import org.apache.iotdb.db.mpp.plan.expression.visitor.BindTypeForTimeSeriesOperandVisitor; import org.apache.iotdb.db.mpp.plan.expression.visitor.CollectAggregationExpressionsVisitor; import org.apache.iotdb.db.mpp.plan.expression.visitor.CollectSourceExpressionsVisitor; -import org.apache.iotdb.db.mpp.plan.expression.visitor.ConcatDeviceAndRemoveWildcardVisitor; -import org.apache.iotdb.db.mpp.plan.expression.visitor.ConcatExpressionWithSuffixPathsVisitor; import org.apache.iotdb.db.mpp.plan.expression.visitor.GetMeasurementExpressionVisitor; import org.apache.iotdb.db.mpp.plan.expression.visitor.RemoveAliasFromExpressionVisitor; -import org.apache.iotdb.db.mpp.plan.expression.visitor.RemoveWildcardAndViewInExpressionVisitor; -import org.apache.iotdb.db.mpp.plan.expression.visitor.RemoveWildcardAndViewInFilterVisitor; -import org.apache.iotdb.db.mpp.plan.expression.visitor.RemoveWildcardInExpressionVisitor; -import org.apache.iotdb.db.mpp.plan.expression.visitor.RemoveWildcardInFilterByDeviceVisitor; -import org.apache.iotdb.db.mpp.plan.expression.visitor.RemoveWildcardInFilterVisitor; import org.apache.iotdb.db.mpp.plan.expression.visitor.ReplaceRawPathWithGroupedPathVisitor; +import org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian.BindSchemaForExpressionVisitor; +import org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian.BindSchemaForPredicateVisitor; +import org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian.ConcatDeviceAndBindSchemaForExpressionVisitor; +import org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian.ConcatDeviceAndBindSchemaForPredicateVisitor; +import org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian.ConcatExpressionWithSuffixPathsVisitor; import org.apache.iotdb.db.mpp.plan.statement.component.ResultColumn; import org.apache.iotdb.tsfile.common.constant.TsFileConstant; import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; @@ -404,18 +402,6 @@ public class ExpressionAnalyzer { } } - /** - * Bind schema ({@link PartialPath} -> {@link MeasurementPath}) and removes wildcards in - * Expression. - * - * @param schemaTree interface for querying schema information - * @return the expression list after binding schema - */ - public static List<Expression> removeWildcardInExpression( - Expression expression, ISchemaTree schemaTree) { - return new RemoveWildcardInExpressionVisitor().process(expression, schemaTree); - } - /** * Bind schema ({@link PartialPath} -> {@link MeasurementPath}) and removes wildcards in * Expression. And all logical view will be replaced. @@ -424,33 +410,17 @@ public class ExpressionAnalyzer { * @return the expression list after binding schema and whether there is logical view in * expressions */ - public static List<Expression> removeWildcardAndViewInExpression( + public static List<Expression> bindSchemaForExpression( Expression expression, Analysis analysis, ISchemaTree schemaTree) { - RemoveWildcardAndViewInExpressionVisitor removeWildcardAndViewInExpressionVisitor = - new RemoveWildcardAndViewInExpressionVisitor(); - List<Expression> expressions = - removeWildcardAndViewInExpressionVisitor.process(expression, schemaTree); - analysis.setHasViewsInQuery( - removeWildcardAndViewInExpressionVisitor.isHasProcessedLogicalView()); + BindSchemaForExpressionVisitor bindSchemaForExpressionVisitor = + new BindSchemaForExpressionVisitor(); + BindSchemaForExpressionVisitor.Context context = + new BindSchemaForExpressionVisitor.Context(schemaTree); + List<Expression> expressions = bindSchemaForExpressionVisitor.process(expression, context); + analysis.setHasViewsInQuery(context.isHasProcessedLogicalView()); return expressions; } - /** - * Concat suffix path in WHERE and HAVING clause with the prefix path in the FROM clause. And - * then, bind schema ({@link PartialPath} -> {@link MeasurementPath}) and removes wildcards in - * Expression. - * - * @param prefixPaths prefix paths in the FROM clause - * @param schemaTree interface for querying schema information - * @return the expression list with full path and after binding schema - */ - public static List<Expression> removeWildcardInFilter( - Expression predicate, List<PartialPath> prefixPaths, ISchemaTree schemaTree, boolean isRoot) { - return new RemoveWildcardInFilterVisitor() - .process( - predicate, new RemoveWildcardInFilterVisitor.Context(prefixPaths, schemaTree, isRoot)); - } - /** * Concat suffix path in WHERE and HAVING clause with the prefix path in the FROM clause. And * then, bind schema ({@link PartialPath} -> {@link MeasurementPath}) and removes wildcards in @@ -460,11 +430,11 @@ public class ExpressionAnalyzer { * @param schemaTree interface for querying schema information * @return the expression list with full path and after binding schema */ - public static List<Expression> removeWildcardAndViewInFilter( + public static List<Expression> bindSchemaForPredicate( Expression predicate, List<PartialPath> prefixPaths, ISchemaTree schemaTree, boolean isRoot) { - return new RemoveWildcardAndViewInFilterVisitor() + return new BindSchemaForPredicateVisitor() .process( - predicate, new RemoveWildcardInFilterVisitor.Context(prefixPaths, schemaTree, isRoot)); + predicate, new BindSchemaForPredicateVisitor.Context(prefixPaths, schemaTree, isRoot)); } public static Expression replaceRawPathWithGroupedPath( @@ -481,11 +451,12 @@ public class ExpressionAnalyzer { * @param devicePath device path in the FROM clause * @return expression list with full path and after binding schema */ - public static List<Expression> concatDeviceAndRemoveWildcard( + public static List<Expression> concatDeviceAndBindSchemaForExpression( Expression expression, PartialPath devicePath, ISchemaTree schemaTree) { - return new ConcatDeviceAndRemoveWildcardVisitor() + return new ConcatDeviceAndBindSchemaForExpressionVisitor() .process( - expression, new ConcatDeviceAndRemoveWildcardVisitor.Context(devicePath, schemaTree)); + expression, + new ConcatDeviceAndBindSchemaForExpressionVisitor.Context(devicePath, schemaTree)); } /** @@ -494,12 +465,13 @@ public class ExpressionAnalyzer { * * @return the expression list with full path and after binding schema */ - public static List<Expression> removeWildcardInFilterByDevice( + public static List<Expression> concatDeviceAndBindSchemaForPredicate( Expression predicate, PartialPath devicePath, ISchemaTree schemaTree, boolean isWhere) { - return new RemoveWildcardInFilterByDeviceVisitor() + return new ConcatDeviceAndBindSchemaForPredicateVisitor() .process( predicate, - new RemoveWildcardInFilterByDeviceVisitor.Context(devicePath, schemaTree, isWhere)); + new ConcatDeviceAndBindSchemaForPredicateVisitor.Context( + devicePath, schemaTree, isWhere)); } /** diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionUtils.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionUtils.java index 921c012d5be..025919d39c3 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionUtils.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionUtils.java @@ -22,19 +22,8 @@ package org.apache.iotdb.db.mpp.plan.analyze; import org.apache.iotdb.commons.path.PartialPath; 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.binary.AdditionExpression; -import org.apache.iotdb.db.mpp.plan.expression.binary.DivisionExpression; -import org.apache.iotdb.db.mpp.plan.expression.binary.EqualToExpression; -import org.apache.iotdb.db.mpp.plan.expression.binary.GreaterEqualExpression; -import org.apache.iotdb.db.mpp.plan.expression.binary.GreaterThanExpression; -import org.apache.iotdb.db.mpp.plan.expression.binary.LessEqualExpression; -import org.apache.iotdb.db.mpp.plan.expression.binary.LessThanExpression; +import org.apache.iotdb.db.mpp.plan.expression.binary.BinaryExpression; import org.apache.iotdb.db.mpp.plan.expression.binary.LogicAndExpression; -import org.apache.iotdb.db.mpp.plan.expression.binary.LogicOrExpression; -import org.apache.iotdb.db.mpp.plan.expression.binary.ModuloExpression; -import org.apache.iotdb.db.mpp.plan.expression.binary.MultiplicationExpression; -import org.apache.iotdb.db.mpp.plan.expression.binary.NonEqualExpression; -import org.apache.iotdb.db.mpp.plan.expression.binary.SubtractionExpression; import org.apache.iotdb.db.mpp.plan.expression.binary.WhenThenExpression; import org.apache.iotdb.db.mpp.plan.expression.leaf.ConstantOperand; import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand; @@ -42,12 +31,7 @@ import org.apache.iotdb.db.mpp.plan.expression.leaf.TimestampOperand; import org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression; import org.apache.iotdb.db.mpp.plan.expression.other.CaseWhenThenExpression; import org.apache.iotdb.db.mpp.plan.expression.ternary.BetweenExpression; -import org.apache.iotdb.db.mpp.plan.expression.unary.InExpression; -import org.apache.iotdb.db.mpp.plan.expression.unary.IsNullExpression; -import org.apache.iotdb.db.mpp.plan.expression.unary.LikeExpression; -import org.apache.iotdb.db.mpp.plan.expression.unary.LogicNotExpression; -import org.apache.iotdb.db.mpp.plan.expression.unary.NegationExpression; -import org.apache.iotdb.db.mpp.plan.expression.unary.RegularExpression; +import org.apache.iotdb.db.mpp.plan.expression.ternary.TernaryExpression; import org.apache.iotdb.db.mpp.plan.expression.unary.UnaryExpression; import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; import org.apache.iotdb.tsfile.read.filter.TimeFilter; @@ -63,7 +47,7 @@ public class ExpressionUtils { List<? extends PartialPath> actualPaths) { List<Expression> resultExpressions = new ArrayList<>(); for (PartialPath actualPath : actualPaths) { - resultExpressions.add(new TimeSeriesOperand(actualPath)); + resultExpressions.add(reconstructTimeSeriesOperand(actualPath)); } return resultExpressions; } @@ -76,19 +60,16 @@ public class ExpressionUtils { FunctionExpression expression, List<List<Expression>> childExpressionsList) { List<Expression> resultExpressions = new ArrayList<>(); for (List<Expression> functionExpressions : childExpressionsList) { - resultExpressions.add( - new FunctionExpression( - expression.getFunctionName(), - expression.getFunctionAttributes(), - functionExpressions)); + resultExpressions.add(reconstructFunctionExpression(expression, functionExpressions)); } return resultExpressions; } public static Expression reconstructFunctionExpression( FunctionExpression expression, List<Expression> childExpressions) { - return new FunctionExpression( - expression.getFunctionName(), expression.getFunctionAttributes(), childExpressions); + FunctionExpression copiedFunctionExpression = (FunctionExpression) expression.copy(); + copiedFunctionExpression.setExpressions(childExpressions); + return copiedFunctionExpression; } public static List<Expression> reconstructUnaryExpressions( @@ -111,98 +92,34 @@ public class ExpressionUtils { public static Expression reconstructUnaryExpression( UnaryExpression expression, Expression childExpression) { - switch (expression.getExpressionType()) { - case IS_NULL: - return new IsNullExpression(childExpression, ((IsNullExpression) expression).isNot()); - case IN: - return new InExpression( - childExpression, - ((InExpression) expression).isNotIn(), - ((InExpression) expression).getValues()); - case LIKE: - return new LikeExpression( - childExpression, - ((LikeExpression) expression).getPatternString(), - ((LikeExpression) expression).getPattern()); - case LOGIC_NOT: - return new LogicNotExpression(childExpression); - - case NEGATION: - return new NegationExpression(childExpression); - - case REGEXP: - return new RegularExpression( - childExpression, - ((RegularExpression) expression).getPatternString(), - ((RegularExpression) expression).getPattern()); - - default: - throw new IllegalArgumentException( - "unsupported expression type: " + expression.getExpressionType()); - } + UnaryExpression copiedUnaryExpression = (UnaryExpression) expression.copy(); + copiedUnaryExpression.setExpression(childExpression); + return copiedUnaryExpression; } public static List<Expression> reconstructBinaryExpressions( - ExpressionType expressionType, + BinaryExpression expression, List<Expression> leftExpressions, List<Expression> rightExpressions) { List<Expression> resultExpressions = new ArrayList<>(); for (Expression le : leftExpressions) { for (Expression re : rightExpressions) { - resultExpressions.add(reconstructBinaryExpression(expressionType, le, re)); + resultExpressions.add(reconstructBinaryExpression(expression, le, re)); } } return resultExpressions; } public static Expression reconstructBinaryExpression( - ExpressionType expressionType, Expression leftExpression, Expression rightExpression) { - switch (expressionType) { - case ADDITION: - return new AdditionExpression(leftExpression, rightExpression); - - case SUBTRACTION: - return new SubtractionExpression(leftExpression, rightExpression); - case MULTIPLICATION: - return new MultiplicationExpression(leftExpression, rightExpression); - case DIVISION: - return new DivisionExpression(leftExpression, rightExpression); - case MODULO: - return new ModuloExpression(leftExpression, rightExpression); - - case LESS_THAN: - return new LessThanExpression(leftExpression, rightExpression); - case LESS_EQUAL: - return new LessEqualExpression(leftExpression, rightExpression); - - case GREATER_THAN: - return new GreaterThanExpression(leftExpression, rightExpression); - - case GREATER_EQUAL: - return new GreaterEqualExpression(leftExpression, rightExpression); - - case EQUAL_TO: - return new EqualToExpression(leftExpression, rightExpression); - - case NON_EQUAL: - return new NonEqualExpression(leftExpression, rightExpression); - - case LOGIC_AND: - return new LogicAndExpression(leftExpression, rightExpression); - - case LOGIC_OR: - return new LogicOrExpression(leftExpression, rightExpression); - - case WHEN_THEN: - return new WhenThenExpression(leftExpression, rightExpression); - - default: - throw new IllegalArgumentException("unsupported expression type: " + expressionType); - } + BinaryExpression expression, Expression leftExpression, Expression rightExpression) { + BinaryExpression copiedBinaryExpression = (BinaryExpression) expression.copy(); + copiedBinaryExpression.setLeftExpression(leftExpression); + copiedBinaryExpression.setRightExpression(rightExpression); + return copiedBinaryExpression; } public static List<Expression> reconstructTernaryExpressions( - Expression expression, + TernaryExpression expression, List<Expression> firstExpressions, List<Expression> secondExpressions, List<Expression> thirdExpressions) { @@ -217,21 +134,15 @@ public class ExpressionUtils { } public static Expression reconstructTernaryExpression( - Expression expression, + TernaryExpression expression, Expression firstExpression, Expression secondExpression, Expression thirdExpression) { - switch (expression.getExpressionType()) { - case BETWEEN: - return new BetweenExpression( - firstExpression, - secondExpression, - thirdExpression, - ((BetweenExpression) expression).isNotBetween()); - default: - throw new IllegalArgumentException( - "unsupported expression type: " + expression.getExpressionType()); - } + TernaryExpression copiedTernaryExpression = (TernaryExpression) expression.copy(); + copiedTernaryExpression.setFirstExpression(firstExpression); + copiedTernaryExpression.setFirstExpression(secondExpression); + copiedTernaryExpression.setThirdExpression(thirdExpression); + return copiedTernaryExpression; } /** diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ExpressionAnalyzeVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ExpressionAnalyzeVisitor.java index fdb5f34df30..8f9b346fa6b 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ExpressionAnalyzeVisitor.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ExpressionAnalyzeVisitor.java @@ -31,7 +31,7 @@ public abstract class ExpressionAnalyzeVisitor<R, C> extends ExpressionVisitor<R "unsupported expression type: " + expression.getExpressionType()); } - List<R> getResultsFromChild(Expression expression, C context) { + protected List<R> getResultsFromChild(Expression expression, C context) { return expression.getExpressions().stream() .map(child -> this.process(child, context)) .collect(Collectors.toList()); diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/GetMeasurementExpressionVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/GetMeasurementExpressionVisitor.java index a47c88a2742..60f346163d0 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/GetMeasurementExpressionVisitor.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/GetMeasurementExpressionVisitor.java @@ -29,6 +29,18 @@ import java.util.ArrayList; import java.util.List; public class GetMeasurementExpressionVisitor extends ReconstructVisitor<Void> { + + @Override + public Expression process(Expression expression, Void context) { + Expression newExpression = expression.accept(this, context); + + if (expression.getViewPath() != null) { + PartialPath viewPath = expression.getViewPath(); + newExpression.setViewPath(new PartialPath(viewPath.getMeasurement(), false)); + } + return newExpression; + } + @Override public Expression visitFunctionExpression(FunctionExpression functionExpression, Void context) { List<Expression> childExpressions = new ArrayList<>(); @@ -36,8 +48,8 @@ public class GetMeasurementExpressionVisitor extends ReconstructVisitor<Void> { childExpressions.add(process(suffixExpression, null)); } return new FunctionExpression( - ((FunctionExpression) functionExpression).getFunctionName(), - ((FunctionExpression) functionExpression).getFunctionAttributes(), + functionExpression.getFunctionName(), + functionExpression.getFunctionAttributes(), childExpressions); } diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ReconstructVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ReconstructVisitor.java index 83f2ad01d87..52e96f770e9 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ReconstructVisitor.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ReconstructVisitor.java @@ -48,8 +48,7 @@ public abstract class ReconstructVisitor<C> extends ExpressionAnalyzeVisitor<Exp @Override public Expression visitBinaryExpression(BinaryExpression binaryExpression, C context) { List<Expression> childResults = getResultsFromChild(binaryExpression, context); - return reconstructBinaryExpression( - binaryExpression.getExpressionType(), childResults.get(0), childResults.get(1)); + return reconstructBinaryExpression(binaryExpression, childResults.get(0), childResults.get(1)); } @Override diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardAndViewInExpressionVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardAndViewInExpressionVisitor.java deleted file mode 100644 index 303df8ce695..00000000000 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardAndViewInExpressionVisitor.java +++ /dev/null @@ -1,95 +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.mpp.plan.expression.visitor; - -import org.apache.iotdb.commons.path.MeasurementPath; -import org.apache.iotdb.commons.path.PartialPath; -import org.apache.iotdb.commons.schema.view.LogicalViewSchema; -import org.apache.iotdb.commons.schema.view.viewExpression.ViewExpression; -import org.apache.iotdb.db.metadata.view.viewExpression.visitor.TransformToExpressionVisitor; -import org.apache.iotdb.db.mpp.common.schematree.ISchemaTree; -import org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils; -import org.apache.iotdb.db.mpp.plan.expression.Expression; -import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand; -import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema; - -import java.util.ArrayList; -import java.util.List; - -public class RemoveWildcardAndViewInExpressionVisitor extends RemoveWildcardInExpressionVisitor { - private final TransformToExpressionVisitor transformToExpressionVisitor; - - private final CompleteMeasurementSchemaVisitor completeMeasurementSchemaVisitor; - - boolean hasProcessedLogicalView; - - public RemoveWildcardAndViewInExpressionVisitor() { - super(); - this.transformToExpressionVisitor = new TransformToExpressionVisitor(); - this.completeMeasurementSchemaVisitor = new CompleteMeasurementSchemaVisitor(); - this.hasProcessedLogicalView = false; - } - - public boolean isHasProcessedLogicalView() { - return this.hasProcessedLogicalView; - } - - private Expression transformViewPath(MeasurementPath measurementPath, ISchemaTree schemaTree) { - IMeasurementSchema measurementSchema = measurementPath.getMeasurementSchema(); - if (measurementSchema.isLogicalView()) { - ViewExpression viewExpression = ((LogicalViewSchema) measurementSchema).getExpression(); - // complete measurementPaths in expressions. - Expression expression = this.transformToExpressionVisitor.process(viewExpression, null); - expression = this.completeMeasurementSchemaVisitor.process(expression, schemaTree); - return expression; - } else { - throw new RuntimeException( - new UnsupportedOperationException( - "Can not construct expression using non view path in transformViewPath!")); - } - } - - @Override - public List<Expression> visitTimeSeriesOperand( - TimeSeriesOperand timeSeriesOperand, ISchemaTree schemaTree) { - PartialPath timeSeriesOperandPath = timeSeriesOperand.getPath(); - List<MeasurementPath> actualPaths = - schemaTree.searchMeasurementPaths(timeSeriesOperandPath).left; - // process logical view - List<MeasurementPath> nonViewActualPaths = new ArrayList<>(); - List<MeasurementPath> viewPaths = new ArrayList<>(); - for (MeasurementPath measurementPath : actualPaths) { - if (measurementPath.getMeasurementSchema().isLogicalView()) { - this.hasProcessedLogicalView = true; - viewPaths.add(measurementPath); - } else { - nonViewActualPaths.add(measurementPath); - } - } - List<Expression> reconstructTimeSeriesOperands = - ExpressionUtils.reconstructTimeSeriesOperands(nonViewActualPaths); - // handle logical views - for (MeasurementPath measurementPath : viewPaths) { - Expression replacedExpression = this.transformViewPath(measurementPath, schemaTree); - replacedExpression.setViewPathOfThisExpression(measurementPath); - reconstructTimeSeriesOperands.add(replacedExpression); - } - return reconstructTimeSeriesOperands; - } -} diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardAndViewInFilterVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardAndViewInFilterVisitor.java deleted file mode 100644 index 550f5ac7299..00000000000 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardAndViewInFilterVisitor.java +++ /dev/null @@ -1,109 +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.mpp.plan.expression.visitor; - -import org.apache.iotdb.commons.path.MeasurementPath; -import org.apache.iotdb.commons.path.PartialPath; -import org.apache.iotdb.commons.schema.view.LogicalViewSchema; -import org.apache.iotdb.commons.schema.view.viewExpression.ViewExpression; -import org.apache.iotdb.db.constant.SqlConstant; -import org.apache.iotdb.db.metadata.view.viewExpression.visitor.TransformToExpressionVisitor; -import org.apache.iotdb.db.mpp.common.schematree.ISchemaTree; -import org.apache.iotdb.db.mpp.plan.expression.Expression; -import org.apache.iotdb.db.mpp.plan.expression.leaf.NullOperand; -import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand; -import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import static org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.reconstructTimeSeriesOperands; - -public class RemoveWildcardAndViewInFilterVisitor extends RemoveWildcardInFilterVisitor { - - private final TransformToExpressionVisitor transformToExpressionVisitor; - - private final CompleteMeasurementSchemaVisitor completeMeasurementSchemaVisitor; - - boolean hasProcessedLogicalView; - - public RemoveWildcardAndViewInFilterVisitor() { - super(); - this.transformToExpressionVisitor = new TransformToExpressionVisitor(); - this.completeMeasurementSchemaVisitor = new CompleteMeasurementSchemaVisitor(); - this.hasProcessedLogicalView = false; - } - - public boolean isHasProcessedLogicalView() { - return this.hasProcessedLogicalView; - } - - private Expression transformViewPath(MeasurementPath measurementPath, ISchemaTree schemaTree) { - IMeasurementSchema measurementSchema = measurementPath.getMeasurementSchema(); - if (measurementSchema.isLogicalView()) { - ViewExpression viewExpression = ((LogicalViewSchema) measurementSchema).getExpression(); - // complete measurementPaths in expressions. - Expression expression = this.transformToExpressionVisitor.process(viewExpression, null); - expression = this.completeMeasurementSchemaVisitor.process(expression, schemaTree); - return expression; - } else { - throw new RuntimeException( - new UnsupportedOperationException( - "Can not construct expression using non view path in transformViewPath!")); - } - } - - @Override - public List<Expression> visitTimeSeriesOperand(TimeSeriesOperand predicate, Context context) { - PartialPath filterPath = predicate.getPath(); - List<PartialPath> concatPaths = new ArrayList<>(); - if (!filterPath.getFirstNode().equals(SqlConstant.ROOT)) { - context.getPrefixPaths().forEach(prefix -> concatPaths.add(prefix.concatPath(filterPath))); - } else { - // do nothing in the case of "where root.d1.s1 > 5" - concatPaths.add(filterPath); - } - - List<MeasurementPath> nonViewPathList = new ArrayList<>(); - List<MeasurementPath> viewPathList = new ArrayList<>(); - for (PartialPath concatPath : concatPaths) { - List<MeasurementPath> actualPaths = - context.getSchemaTree().searchMeasurementPaths(concatPath).left; - if (actualPaths.isEmpty()) { - return Collections.singletonList(new NullOperand()); - } - for (MeasurementPath measurementPath : actualPaths) { - if (measurementPath.getMeasurementSchema().isLogicalView()) { - viewPathList.add(measurementPath); - } else { - nonViewPathList.add(measurementPath); - } - } - } - List<Expression> reconstructTimeSeriesOperands = reconstructTimeSeriesOperands(nonViewPathList); - for (MeasurementPath measurementPath : viewPathList) { - Expression replacedExpression = - this.transformViewPath(measurementPath, context.getSchemaTree()); - replacedExpression.setViewPathOfThisExpression(measurementPath); - reconstructTimeSeriesOperands.add(replacedExpression); - } - return reconstructTimeSeriesOperands; - } -} diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardInExpressionVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/BindSchemaForExpressionVisitor.java similarity index 50% rename from server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardInExpressionVisitor.java rename to server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/BindSchemaForExpressionVisitor.java index 353c567bc84..19de729a60e 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardInExpressionVisitor.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/BindSchemaForExpressionVisitor.java @@ -17,16 +17,22 @@ * under the License. */ -package org.apache.iotdb.db.mpp.plan.expression.visitor; +package org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian; import org.apache.iotdb.commons.path.MeasurementPath; import org.apache.iotdb.commons.path.PartialPath; +import org.apache.iotdb.commons.schema.view.LogicalViewSchema; +import org.apache.iotdb.commons.schema.view.viewExpression.ViewExpression; +import org.apache.iotdb.db.metadata.view.viewExpression.visitor.TransformToExpressionVisitor; import org.apache.iotdb.db.mpp.common.schematree.ISchemaTree; +import org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils; import org.apache.iotdb.db.mpp.plan.expression.Expression; 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.leaf.TimestampOperand; import org.apache.iotdb.db.mpp.plan.expression.multi.FunctionExpression; +import org.apache.iotdb.db.mpp.plan.expression.visitor.CompleteMeasurementSchemaVisitor; +import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema; import java.util.ArrayList; import java.util.Collections; @@ -34,19 +40,20 @@ import java.util.List; import static org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.cartesianProduct; import static org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.reconstructFunctionExpressions; -import static org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.reconstructTimeSeriesOperands; import static org.apache.iotdb.db.utils.TypeInferenceUtils.bindTypeForAggregationNonSeriesInputExpressions; -public class RemoveWildcardInExpressionVisitor extends CartesianProductVisitor<ISchemaTree> { +public class BindSchemaForExpressionVisitor + extends CartesianProductVisitor<BindSchemaForExpressionVisitor.Context> { + @Override public List<Expression> visitFunctionExpression( - FunctionExpression functionExpression, ISchemaTree schemaTree) { + FunctionExpression functionExpression, Context context) { // One by one, remove the wildcards from the input expressions. In most cases, an expression // will produce multiple expressions after removing the wildcards. We use extendedExpressions // to collect the produced expressions. List<List<Expression>> extendedExpressions = new ArrayList<>(); for (Expression originExpression : functionExpression.getExpressions()) { - List<Expression> actualExpressions = process(originExpression, schemaTree); + List<Expression> actualExpressions = process(originExpression, context); if (actualExpressions.isEmpty()) { // Let's ignore the eval of the function which has at least one non-existence series as // input. See IOTDB-1212: https://github.com/apache/iotdb/pull/3101 @@ -61,9 +68,7 @@ public class RemoveWildcardInExpressionVisitor extends CartesianProductVisitor<I if (functionExpression.isBuiltInAggregationFunctionExpression()) { List<Expression> children = functionExpression.getExpressions(); bindTypeForAggregationNonSeriesInputExpressions( - ((FunctionExpression) functionExpression).getFunctionName(), - children, - extendedExpressions); + functionExpression.getFunctionName(), children, extendedExpressions); break; } } @@ -73,27 +78,82 @@ public class RemoveWildcardInExpressionVisitor extends CartesianProductVisitor<I List<List<Expression>> childExpressionsList = new ArrayList<>(); cartesianProduct(extendedExpressions, childExpressionsList, 0, new ArrayList<>()); - return reconstructFunctionExpressions( - (FunctionExpression) functionExpression, childExpressionsList); + return reconstructFunctionExpressions(functionExpression, childExpressionsList); } @Override public List<Expression> visitTimeSeriesOperand( - TimeSeriesOperand timeSeriesOperand, ISchemaTree schemaTree) { - PartialPath path = timeSeriesOperand.getPath(); - List<MeasurementPath> actualPaths = schemaTree.searchMeasurementPaths(path).left; - return reconstructTimeSeriesOperands(actualPaths); + TimeSeriesOperand timeSeriesOperand, Context context) { + PartialPath timeSeriesOperandPath = timeSeriesOperand.getPath(); + List<MeasurementPath> actualPaths = + context.getSchemaTree().searchMeasurementPaths(timeSeriesOperandPath).left; + // process logical view + List<MeasurementPath> nonViewActualPaths = new ArrayList<>(); + List<MeasurementPath> viewPaths = new ArrayList<>(); + for (MeasurementPath measurementPath : actualPaths) { + if (measurementPath.getMeasurementSchema().isLogicalView()) { + context.setHasProcessedLogicalView(); + viewPaths.add(measurementPath); + } else { + nonViewActualPaths.add(measurementPath); + } + } + List<Expression> reconstructTimeSeriesOperands = + ExpressionUtils.reconstructTimeSeriesOperands(nonViewActualPaths); + // handle logical views + for (MeasurementPath measurementPath : viewPaths) { + Expression replacedExpression = transformViewPath(measurementPath, context.getSchemaTree()); + replacedExpression.setViewPath(measurementPath); + reconstructTimeSeriesOperands.add(replacedExpression); + } + return reconstructTimeSeriesOperands; } @Override public List<Expression> visitTimeStampOperand( - TimestampOperand timestampOperand, ISchemaTree context) { + TimestampOperand timestampOperand, Context context) { return Collections.singletonList(timestampOperand); } @Override - public List<Expression> visitConstantOperand( - ConstantOperand constantOperand, ISchemaTree context) { + public List<Expression> visitConstantOperand(ConstantOperand constantOperand, Context context) { return Collections.singletonList(constantOperand); } + + public static Expression transformViewPath( + MeasurementPath measurementPath, ISchemaTree schemaTree) { + IMeasurementSchema measurementSchema = measurementPath.getMeasurementSchema(); + if (measurementSchema.isLogicalView()) { + ViewExpression viewExpression = ((LogicalViewSchema) measurementSchema).getExpression(); + // complete measurementPaths in expressions. + Expression expression = new TransformToExpressionVisitor().process(viewExpression, null); + expression = new CompleteMeasurementSchemaVisitor().process(expression, schemaTree); + return expression; + } else { + throw new RuntimeException( + new UnsupportedOperationException( + "Can not construct expression using non view path in transformViewPath!")); + } + } + + public static class Context { + private final ISchemaTree schemaTree; + private boolean isHasProcessedLogicalView = false; + + public Context(ISchemaTree schemaTree) { + this.schemaTree = schemaTree; + } + + public ISchemaTree getSchemaTree() { + return schemaTree; + } + + public boolean isHasProcessedLogicalView() { + return isHasProcessedLogicalView; + } + + public void setHasProcessedLogicalView() { + isHasProcessedLogicalView = true; + } + } } diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardInFilterVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/BindSchemaForPredicateVisitor.java similarity index 82% rename from server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardInFilterVisitor.java rename to server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/BindSchemaForPredicateVisitor.java index 5d7d3bdb31d..a9c17d8276c 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardInFilterVisitor.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/BindSchemaForPredicateVisitor.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.iotdb.db.mpp.plan.expression.visitor; +package org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian; import org.apache.iotdb.commons.path.MeasurementPath; import org.apache.iotdb.commons.path.PartialPath; @@ -40,10 +40,12 @@ import static org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.cartesianProd import static org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.reconstructBinaryExpressions; import static org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.reconstructFunctionExpressions; import static org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.reconstructTimeSeriesOperands; +import static org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian.BindSchemaForExpressionVisitor.transformViewPath; import static org.apache.iotdb.db.utils.TypeInferenceUtils.bindTypeForAggregationNonSeriesInputExpressions; -public class RemoveWildcardInFilterVisitor - extends CartesianProductVisitor<RemoveWildcardInFilterVisitor.Context> { +public class BindSchemaForPredicateVisitor + extends CartesianProductVisitor<BindSchemaForPredicateVisitor.Context> { + @Override public List<Expression> visitBinaryExpression( BinaryExpression binaryExpression, Context context) { @@ -56,8 +58,7 @@ public class RemoveWildcardInFilterVisitor resultExpressions.addAll(rightExpressions); return resultExpressions; } - return reconstructBinaryExpressions( - binaryExpression.getExpressionType(), leftExpressions, rightExpressions); + return reconstructBinaryExpressions(binaryExpression, leftExpressions, rightExpressions); } @Override @@ -96,16 +97,29 @@ public class RemoveWildcardInFilterVisitor concatPaths.add(filterPath); } - List<PartialPath> noStarPaths = new ArrayList<>(); + List<MeasurementPath> nonViewPathList = new ArrayList<>(); + List<MeasurementPath> viewPathList = new ArrayList<>(); for (PartialPath concatPath : concatPaths) { List<MeasurementPath> actualPaths = context.getSchemaTree().searchMeasurementPaths(concatPath).left; if (actualPaths.isEmpty()) { return Collections.singletonList(new NullOperand()); } - noStarPaths.addAll(actualPaths); + for (MeasurementPath measurementPath : actualPaths) { + if (measurementPath.getMeasurementSchema().isLogicalView()) { + viewPathList.add(measurementPath); + } else { + nonViewPathList.add(measurementPath); + } + } + } + List<Expression> reconstructTimeSeriesOperands = reconstructTimeSeriesOperands(nonViewPathList); + for (MeasurementPath measurementPath : viewPathList) { + Expression replacedExpression = transformViewPath(measurementPath, context.getSchemaTree()); + replacedExpression.setViewPath(measurementPath); + reconstructTimeSeriesOperands.add(replacedExpression); } - return reconstructTimeSeriesOperands(noStarPaths); + return reconstructTimeSeriesOperands; } @Override diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/CartesianProductVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/CartesianProductVisitor.java similarity index 94% rename from server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/CartesianProductVisitor.java rename to server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/CartesianProductVisitor.java index 7d824b0e25d..6830b8cf2e8 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/CartesianProductVisitor.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/CartesianProductVisitor.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.iotdb.db.mpp.plan.expression.visitor; +package org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian; import org.apache.iotdb.db.mpp.plan.expression.Expression; import org.apache.iotdb.db.mpp.plan.expression.binary.BinaryExpression; @@ -25,6 +25,7 @@ import org.apache.iotdb.db.mpp.plan.expression.leaf.NullOperand; import org.apache.iotdb.db.mpp.plan.expression.other.CaseWhenThenExpression; import org.apache.iotdb.db.mpp.plan.expression.ternary.TernaryExpression; import org.apache.iotdb.db.mpp.plan.expression.unary.UnaryExpression; +import org.apache.iotdb.db.mpp.plan.expression.visitor.ExpressionAnalyzeVisitor; import java.util.ArrayList; import java.util.Collections; @@ -52,7 +53,7 @@ public abstract class CartesianProductVisitor<C> public List<Expression> visitBinaryExpression(BinaryExpression binaryExpression, C context) { List<List<Expression>> childResultsList = getResultsFromChild(binaryExpression, context); return reconstructBinaryExpressions( - binaryExpression.getExpressionType(), childResultsList.get(0), childResultsList.get(1)); + binaryExpression, childResultsList.get(0), childResultsList.get(1)); } @Override diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ConcatDeviceAndRemoveWildcardVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/ConcatDeviceAndBindSchemaForExpressionVisitor.java similarity index 76% rename from server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ConcatDeviceAndRemoveWildcardVisitor.java rename to server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/ConcatDeviceAndBindSchemaForExpressionVisitor.java index a9f1b50ad2b..6a944fae99f 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ConcatDeviceAndRemoveWildcardVisitor.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/ConcatDeviceAndBindSchemaForExpressionVisitor.java @@ -17,11 +17,12 @@ * under the License. */ -package org.apache.iotdb.db.mpp.plan.expression.visitor; +package org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian; import org.apache.iotdb.commons.path.MeasurementPath; import org.apache.iotdb.commons.path.PartialPath; import org.apache.iotdb.db.mpp.common.schematree.ISchemaTree; +import org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils; import org.apache.iotdb.db.mpp.plan.expression.Expression; import org.apache.iotdb.db.mpp.plan.expression.leaf.ConstantOperand; import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand; @@ -34,11 +35,11 @@ import java.util.List; import static org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.cartesianProduct; import static org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.reconstructFunctionExpressions; -import static org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.reconstructTimeSeriesOperands; +import static org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian.BindSchemaForExpressionVisitor.transformViewPath; import static org.apache.iotdb.db.utils.TypeInferenceUtils.bindTypeForAggregationNonSeriesInputExpressions; -public class ConcatDeviceAndRemoveWildcardVisitor - extends CartesianProductVisitor<ConcatDeviceAndRemoveWildcardVisitor.Context> { +public class ConcatDeviceAndBindSchemaForExpressionVisitor + extends CartesianProductVisitor<ConcatDeviceAndBindSchemaForExpressionVisitor.Context> { @Override public List<Expression> visitFunctionExpression( FunctionExpression functionExpression, Context context) { @@ -77,8 +78,27 @@ public class ConcatDeviceAndRemoveWildcardVisitor if (actualPaths.isEmpty()) { return Collections.emptyList(); } - List<PartialPath> noStarPaths = new ArrayList<>(actualPaths); - return reconstructTimeSeriesOperands(noStarPaths); + + // process logical view + List<MeasurementPath> nonViewActualPaths = new ArrayList<>(); + List<MeasurementPath> viewPaths = new ArrayList<>(); + for (MeasurementPath measurementPath : actualPaths) { + if (measurementPath.getMeasurementSchema().isLogicalView()) { + // this.hasProcessedLogicalView = true; + viewPaths.add(measurementPath); + } else { + nonViewActualPaths.add(measurementPath); + } + } + List<Expression> reconstructTimeSeriesOperands = + ExpressionUtils.reconstructTimeSeriesOperands(nonViewActualPaths); + // handle logical views + for (MeasurementPath measurementPath : viewPaths) { + Expression replacedExpression = transformViewPath(measurementPath, context.getSchemaTree()); + replacedExpression.setViewPath(measurementPath); + reconstructTimeSeriesOperands.add(replacedExpression); + } + return reconstructTimeSeriesOperands; } @Override diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardInFilterByDeviceVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/ConcatDeviceAndBindSchemaForPredicateVisitor.java similarity index 76% rename from server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardInFilterByDeviceVisitor.java rename to server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/ConcatDeviceAndBindSchemaForPredicateVisitor.java index 4dfb8c1617a..a4d8f21eb23 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/RemoveWildcardInFilterByDeviceVisitor.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/ConcatDeviceAndBindSchemaForPredicateVisitor.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.iotdb.db.mpp.plan.expression.visitor; +package org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian; import org.apache.iotdb.commons.path.MeasurementPath; import org.apache.iotdb.commons.path.PartialPath; @@ -37,9 +37,10 @@ import java.util.List; import static org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.cartesianProduct; import static org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.reconstructFunctionExpressions; import static org.apache.iotdb.db.mpp.plan.analyze.ExpressionUtils.reconstructTimeSeriesOperands; +import static org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian.BindSchemaForExpressionVisitor.transformViewPath; -public class RemoveWildcardInFilterByDeviceVisitor - extends CartesianProductVisitor<RemoveWildcardInFilterByDeviceVisitor.Context> { +public class ConcatDeviceAndBindSchemaForPredicateVisitor + extends CartesianProductVisitor<ConcatDeviceAndBindSchemaForPredicateVisitor.Context> { @Override public List<Expression> visitFunctionExpression(FunctionExpression predicate, Context context) { if (predicate.isBuiltInAggregationFunctionExpression() && context.isWhere()) { @@ -58,12 +59,29 @@ public class RemoveWildcardInFilterByDeviceVisitor public List<Expression> visitTimeSeriesOperand(TimeSeriesOperand predicate, Context context) { PartialPath measurement = predicate.getPath(); PartialPath concatPath = context.getDevicePath().concatPath(measurement); - List<MeasurementPath> noStarPaths = + + List<MeasurementPath> nonViewPathList = new ArrayList<>(); + List<MeasurementPath> viewPathList = new ArrayList<>(); + List<MeasurementPath> actualPaths = context.getSchemaTree().searchMeasurementPaths(concatPath).left; - if (noStarPaths.isEmpty()) { + if (actualPaths.isEmpty()) { return Collections.singletonList(new NullOperand()); } - return reconstructTimeSeriesOperands(noStarPaths); + for (MeasurementPath measurementPath : actualPaths) { + if (measurementPath.getMeasurementSchema().isLogicalView()) { + viewPathList.add(measurementPath); + } else { + nonViewPathList.add(measurementPath); + } + } + + List<Expression> reconstructTimeSeriesOperands = reconstructTimeSeriesOperands(nonViewPathList); + for (MeasurementPath measurementPath : viewPathList) { + Expression replacedExpression = transformViewPath(measurementPath, context.getSchemaTree()); + replacedExpression.setViewPath(measurementPath); + reconstructTimeSeriesOperands.add(replacedExpression); + } + return reconstructTimeSeriesOperands; } @Override diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ConcatExpressionWithSuffixPathsVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/ConcatExpressionWithSuffixPathsVisitor.java similarity index 98% rename from server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ConcatExpressionWithSuffixPathsVisitor.java rename to server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/ConcatExpressionWithSuffixPathsVisitor.java index a8e565e7dae..1bfdaebf1ac 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/ConcatExpressionWithSuffixPathsVisitor.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/expression/visitor/cartesian/ConcatExpressionWithSuffixPathsVisitor.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.iotdb.db.mpp.plan.expression.visitor; +package org.apache.iotdb.db.mpp.plan.expression.visitor.cartesian; import org.apache.iotdb.commons.path.PartialPath; import org.apache.iotdb.commons.path.PathPatternTree; diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionAnalyzerTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionAnalyzerTest.java index 1672ff9dbd4..511748f0a50 100644 --- a/server/src/test/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionAnalyzerTest.java +++ b/server/src/test/java/org/apache/iotdb/db/mpp/plan/analyze/ExpressionAnalyzerTest.java @@ -51,7 +51,7 @@ public class ExpressionAnalyzerTest { gt(timeSeries("root.sg.d2.s1"), intValue("1")), gt(timeSeries("root.sg.d1.s2"), intValue("1")), gt(timeSeries("root.sg.d2.s2"), intValue("1"))), - ExpressionAnalyzer.removeWildcardAndViewInFilter( + ExpressionAnalyzer.bindSchemaForPredicate( and(gt(timeSeries("s1"), intValue("1")), gt(timeSeries("s2"), intValue("1"))), prefixPaths, fakeSchemaTree, @@ -75,7 +75,7 @@ public class ExpressionAnalyzerTest { and( gt(timeSeries("root.sg.d2.s1"), intValue("1")), gt(timeSeries("root.sg.d2.s2"), intValue("1"))))), - ExpressionAnalyzer.removeWildcardAndViewInFilter( + ExpressionAnalyzer.bindSchemaForPredicate( count(and(gt(timeSeries("s1"), intValue("1")), gt(timeSeries("s2"), intValue("1")))), prefixPaths, fakeSchemaTree,
