From f4e058eb7a66f9243266fb964cac0ae11dbb8cfb Mon Sep 17 00:00:00 2001 From: BiteTheDDDDt Date: Wed, 17 Apr 2024 16:13:45 +0800 Subject: [PATCH 1/5] support multiple agg function have same base table slot --- .../rules/analysis/BindExpression.java | 2 +- .../AbstractSelectMaterializedIndexRule.java | 19 +-- .../SelectMaterializedIndexWithAggregate.java | 136 ++++++++++-------- .../multi_agg_with_same_slot.out | 48 +++++++ .../mv_p0/mv_percentile/mv_percentile.out | 36 +++++ .../multi_agg_with_same_slot.groovy | 73 ++++++++++ .../mv_p0/mv_percentile/mv_percentile.groovy | 66 +++++++++ 7 files changed, 311 insertions(+), 69 deletions(-) create mode 100644 regression-test/data/mv_p0/multi_agg_with_same_slot/multi_agg_with_same_slot.out create mode 100644 regression-test/data/mv_p0/mv_percentile/mv_percentile.out create mode 100644 regression-test/suites/mv_p0/multi_agg_with_same_slot/multi_agg_with_same_slot.groovy create mode 100644 regression-test/suites/mv_p0/mv_percentile/mv_percentile.groovy diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java index a99de00e378f8a..c2ef5ee18bd9d0 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java @@ -806,7 +806,7 @@ private Plan bindSortWithoutSetOperation(MatchingContext> ctx) /** * For the columns whose output exists in grouping sets, they need to be assigned as nullable. */ - private List adjustNullableForRepeat( + public static List adjustNullableForRepeat( List> groupingSets, List outputs) { Set groupingSetsUsedSlots = groupingSets.stream() diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/AbstractSelectMaterializedIndexRule.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/AbstractSelectMaterializedIndexRule.java index e0518b2c117c4b..1f71420232852f 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/AbstractSelectMaterializedIndexRule.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/AbstractSelectMaterializedIndexRule.java @@ -25,6 +25,7 @@ import org.apache.doris.catalog.MaterializedIndexMeta; import org.apache.doris.catalog.OlapTable; import org.apache.doris.nereids.parser.NereidsParser; +import org.apache.doris.nereids.rules.analysis.BindExpression; import org.apache.doris.nereids.trees.expressions.Alias; import org.apache.doris.nereids.trees.expressions.CaseWhen; import org.apache.doris.nereids.trees.expressions.Cast; @@ -580,20 +581,20 @@ public LogicalAggregate visitLogicalAggregate(LogicalAggregate visitLogicalRepeat(LogicalRepeat repeat, Void ctx) { Plan child = repeat.child(0).accept(this, ctx); List> groupingSets = repeat.getGroupingSets(); - ImmutableList.Builder> newGroupingExprs = ImmutableList.builder(); + List> newGroupingExprs = Lists.newArrayList(); for (List expressions : groupingSets) { - newGroupingExprs.add(expressions.stream() - .map(expr -> new ReplaceExpressionWithMvColumn(slotContext).replace(expr)) - .collect(ImmutableList.toImmutableList()) - ); + newGroupingExprs.add( + expressions.stream().map(expr -> new ReplaceExpressionWithMvColumn(slotContext).replace(expr)) + .collect(ImmutableList.toImmutableList())); } List outputExpressions = repeat.getOutputExpressions(); - List newOutputExpressions = outputExpressions.stream() - .map(expr -> (NamedExpression) new ReplaceExpressionWithMvColumn(slotContext).replace(expr)) - .collect(ImmutableList.toImmutableList()); + List newOutputExpressions = BindExpression.adjustNullableForRepeat(newGroupingExprs, + outputExpressions.stream() + .map(expr -> (NamedExpression) new ReplaceExpressionWithMvColumn(slotContext).replace(expr)) + .collect(ImmutableList.toImmutableList())); - return repeat.withNormalizedExpr(newGroupingExprs.build(), newOutputExpressions, child); + return repeat.withNormalizedExpr(newGroupingExprs, newOutputExpressions, child); } @Override diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java index c84c5212a5b47f..32e7eb53d5672c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java @@ -81,6 +81,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.common.collect.Streams; @@ -207,22 +208,19 @@ public List buildRules() { LogicalOlapScan mvPlan = createLogicalOlapScan(scan, result); SlotContext slotContext = generateBaseScanExprToMvExpr(mvPlan); - List newProjectList = replaceProjectList(project, + List newProjectList = replaceOutput(project.getProjects(), result.exprRewriteMap.projectExprMap); LogicalProject newProject = new LogicalProject<>( generateNewOutputsWithMvOutputs(mvPlan, newProjectList), scan.withMaterializedIndexSelected(result.preAggStatus, result.indexId)); - return new LogicalProject<>( - generateProjectsAlias(agg.getOutputs(), slotContext), - new ReplaceExpressions(slotContext).replace( - new LogicalAggregate<>( - agg.getGroupByExpressions(), - replaceAggOutput(agg, Optional.of(project), Optional.of(newProject), - result.exprRewriteMap), - agg.isNormalized(), - agg.getSourceRepeat(), - newProject - ), mvPlan)); + return new LogicalProject<>(generateProjectsAlias(agg.getOutputs(), slotContext), + new ReplaceExpressions(slotContext) + .replace( + new LogicalAggregate<>(agg.getGroupByExpressions(), + replaceAggOutput(agg, Optional.of(project), + Optional.of(newProject), result.exprRewriteMap), + agg.isNormalized(), agg.getSourceRepeat(), newProject), + mvPlan)); }).toRule(RuleType.MATERIALIZED_INDEX_AGG_PROJECT_SCAN), // filter could push down and project. @@ -274,7 +272,7 @@ public List buildRules() { mvPlanWithoutAgg))); } - List newProjectList = replaceProjectList(project, + List newProjectList = replaceOutput(project.getProjects(), result.exprRewriteMap.projectExprMap); LogicalProject newProject = new LogicalProject<>( generateNewOutputsWithMvOutputs(mvPlan, newProjectList), @@ -322,7 +320,7 @@ public List buildRules() { .map(e -> result.exprRewriteMap.replaceAgg(e)).collect(Collectors.toSet()), filter.getConjuncts()); - List newProjectList = replaceProjectList(project, + List newProjectList = replaceOutput(project.getProjects(), result.exprRewriteMap.projectExprMap); LogicalProject newProject = new LogicalProject<>( generateNewOutputsWithMvOutputs(mvPlan, newProjectList), mvPlan); @@ -358,16 +356,18 @@ public List buildRules() { LogicalOlapScan mvPlan = createLogicalOlapScan(scan, result); SlotContext slotContext = generateBaseScanExprToMvExpr(mvPlan); - return new LogicalProject<>(generateProjectsAlias(agg.getOutputs(), slotContext), - new ReplaceExpressions(slotContext).replace(new LogicalAggregate<>( - agg.getGroupByExpressions(), - replaceAggOutput( - agg, Optional.empty(), Optional.empty(), result.exprRewriteMap), - agg.isNormalized(), agg.getSourceRepeat(), - repeat.withAggOutputAndChild( - replaceRepeatOutput(repeat, result.exprRewriteMap.projectExprMap), - mvPlan)), - mvPlan)); + return new LogicalProject<>(generateProjectsAlias(agg.getOutputs(), slotContext), + new ReplaceExpressions(slotContext) + .replace( + new LogicalAggregate<>(agg.getGroupByExpressions(), + replaceAggOutput(agg, Optional.empty(), Optional.empty(), + result.exprRewriteMap), + agg.isNormalized(), agg.getSourceRepeat(), + repeat.withAggOutputAndChild( + replaceOutput(repeat.getOutputs(), + result.exprRewriteMap.projectExprMap), + mvPlan)), + mvPlan)); }).toRule(RuleType.MATERIALIZED_INDEX_AGG_REPEAT_SCAN), // filter could push down scan. @@ -411,9 +411,10 @@ public List buildRules() { // because the slots to replace // are value columns, which shouldn't appear in filters. repeat.withAggOutputAndChild( - replaceRepeatOutput(repeat, result.exprRewriteMap.projectExprMap), - filter.withChildren(mvPlan)) - ), mvPlan)); + replaceOutput(repeat.getOutputs(), + result.exprRewriteMap.projectExprMap), + filter.withChildren(mvPlan))), + mvPlan)); }).toRule(RuleType.MATERIALIZED_INDEX_AGG_REPEAT_FILTER_SCAN), // column pruning or other projections such as alias, etc. @@ -438,7 +439,7 @@ public List buildRules() { LogicalOlapScan mvPlan = createLogicalOlapScan(scan, result); SlotContext slotContext = generateBaseScanExprToMvExpr(mvPlan); - List newProjectList = replaceProjectList(project, + List newProjectList = replaceOutput(project.getProjects(), result.exprRewriteMap.projectExprMap); LogicalProject newProject = new LogicalProject<>( generateNewOutputsWithMvOutputs(mvPlan, newProjectList), mvPlan); @@ -449,7 +450,7 @@ public List buildRules() { replaceAggOutput(agg, Optional.of(project), Optional.of(newProject), result.exprRewriteMap), agg.isNormalized(), agg.getSourceRepeat(), - repeat.withAggOutputAndChild(replaceRepeatOutput(repeat, + repeat.withAggOutputAndChild(replaceOutput(repeat.getOutputs(), result.exprRewriteMap.projectExprMap), newProject)), mvPlan)); }).toRule(RuleType.MATERIALIZED_INDEX_AGG_REPEAT_PROJECT_SCAN), @@ -487,7 +488,7 @@ public List buildRules() { .map(e -> result.exprRewriteMap.replaceAgg(e)).collect(Collectors.toSet()), filter.getConjuncts()); - List newProjectList = replaceProjectList(project, + List newProjectList = replaceOutput(project.getProjects(), result.exprRewriteMap.projectExprMap); LogicalProject newProject = new LogicalProject<>( generateNewOutputsWithMvOutputs(mvPlan, newProjectList), @@ -499,7 +500,7 @@ public List buildRules() { replaceAggOutput(agg, Optional.of(project), Optional.of(newProject), result.exprRewriteMap), agg.isNormalized(), agg.getSourceRepeat(), - repeat.withAggOutputAndChild(replaceRepeatOutput(repeat, + repeat.withAggOutputAndChild(replaceOutput(repeat.getOutputs(), result.exprRewriteMap.projectExprMap), newProject)), mvPlan)); }).toRule(RuleType.MATERIALIZED_INDEX_AGG_REPEAT_PROJECT_FILTER_SCAN), @@ -535,7 +536,7 @@ public List buildRules() { .map(e -> result.exprRewriteMap.replaceAgg(e)).collect(Collectors.toSet()), filter.getConjuncts()); - List newProjectList = replaceProjectList(project, + List newProjectList = replaceOutput(project.getProjects(), result.exprRewriteMap.projectExprMap); LogicalProject newProject = new LogicalProject<>( generateNewOutputsWithMvOutputs(mvPlan, newProjectList), @@ -547,7 +548,8 @@ public List buildRules() { Optional.of(newProject), result.exprRewriteMap), agg.isNormalized(), agg.getSourceRepeat(), repeat.withAggOutputAndChild( - replaceRepeatOutput(repeat, result.exprRewriteMap.projectExprMap), + replaceOutput(repeat.getOutputs(), + result.exprRewriteMap.projectExprMap), filter.withChildren(newProject))), mvPlan)); }).toRule(RuleType.MATERIALIZED_INDEX_AGG_REPEAT_FILTER_PROJECT_SCAN) @@ -1087,7 +1089,7 @@ private static class ExprRewriteMap { /** * Replace map for expressions in project. */ - public final Map projectExprMap; + public final Map> projectExprMap; /** * Replace map for aggregate functions. */ @@ -1124,6 +1126,13 @@ public Expression replaceAgg(Expression e) { buildStrMap(); return aggFuncStrMap.getOrDefault(e.toSql(), (AggregateFunction) e); } + + public void putIntoProjectExprMap(Expression key, Expression value) { + if (!projectExprMap.containsKey(key)) { + projectExprMap.put(key, Lists.newArrayList()); + } + projectExprMap.get(key).add(value); + } } private static class AggRewriteResult { @@ -1199,7 +1208,7 @@ public Expression visitCount(Count count, RewriteContext context) { .orElseThrow(() -> new AnalysisException( "cannot find bitmap union slot when select mv")); - context.exprRewriteMap.projectExprMap.put(slotOpt.get(), bitmapUnionSlot); + context.exprRewriteMap.putIntoProjectExprMap(slotOpt.get(), bitmapUnionSlot); BitmapUnionCount bitmapUnionCount = new BitmapUnionCount(bitmapUnionSlot); context.exprRewriteMap.aggFuncMap.put(count, bitmapUnionCount); return bitmapUnionCount; @@ -1229,7 +1238,7 @@ public Expression visitCount(Count count, RewriteContext context) { .filter(s -> countColumn.equalsIgnoreCase(normalizeName(s.getName()))).findFirst() .orElseThrow(() -> new AnalysisException("cannot find count slot when select mv")); - context.exprRewriteMap.projectExprMap.put(child, countSlot); + context.exprRewriteMap.putIntoProjectExprMap(child, countSlot); Sum sum = new Sum(countSlot); context.exprRewriteMap.aggFuncMap.put(count, sum); return sum; @@ -1265,7 +1274,7 @@ public Expression visitBitmapUnion(BitmapUnion bitmapUnion, RewriteContext conte .findFirst().orElseThrow( () -> new AnalysisException("cannot find bitmap union slot when select mv")); - context.exprRewriteMap.projectExprMap.put(toBitmap, bitmapUnionSlot); + context.exprRewriteMap.putIntoProjectExprMap(toBitmap, bitmapUnionSlot); BitmapUnion newBitmapUnion = new BitmapUnion(bitmapUnionSlot); context.exprRewriteMap.aggFuncMap.put(bitmapUnion, newBitmapUnion); return newBitmapUnion; @@ -1284,7 +1293,7 @@ public Expression visitBitmapUnion(BitmapUnion bitmapUnion, RewriteContext conte .stream().filter(s -> bitmapUnionColumn.equalsIgnoreCase(normalizeName(s.getName()))) .findFirst() .orElseThrow(() -> new AnalysisException("cannot find bitmap union slot when select mv")); - context.exprRewriteMap.projectExprMap.put(child, bitmapUnionSlot); + context.exprRewriteMap.putIntoProjectExprMap(child, bitmapUnionSlot); BitmapUnion newBitmapUnion = new BitmapUnion(bitmapUnionSlot); context.exprRewriteMap.aggFuncMap.put(bitmapUnion, newBitmapUnion); return newBitmapUnion; @@ -1323,7 +1332,7 @@ public Expression visitBitmapUnionCount(BitmapUnionCount bitmapUnionCount, Rewri .orElseThrow(() -> new AnalysisException( "cannot find bitmap union count slot when select mv")); - context.exprRewriteMap.projectExprMap.put(toBitmap, bitmapUnionCountSlot); + context.exprRewriteMap.putIntoProjectExprMap(toBitmap, bitmapUnionCountSlot); BitmapUnionCount newBitmapUnionCount = new BitmapUnionCount(bitmapUnionCountSlot); context.exprRewriteMap.aggFuncMap.put(bitmapUnionCount, newBitmapUnionCount); return newBitmapUnionCount; @@ -1342,7 +1351,7 @@ public Expression visitBitmapUnionCount(BitmapUnionCount bitmapUnionCount, Rewri .stream().filter(s -> bitmapUnionCountColumn.equalsIgnoreCase(normalizeName(s.getName()))) .findFirst().orElseThrow( () -> new AnalysisException("cannot find bitmap union count slot when select mv")); - context.exprRewriteMap.projectExprMap.put(child, bitmapUnionCountSlot); + context.exprRewriteMap.putIntoProjectExprMap(child, bitmapUnionCountSlot); BitmapUnionCount newBitmapUnionCount = new BitmapUnionCount(bitmapUnionCountSlot); context.exprRewriteMap.aggFuncMap.put(bitmapUnionCount, newBitmapUnionCount); return newBitmapUnionCount; @@ -1378,7 +1387,7 @@ public Expression visitHllUnion(HllUnion hllUnion, RewriteContext context) { .orElseThrow(() -> new AnalysisException( "cannot find hll union slot when select mv")); - context.exprRewriteMap.projectExprMap.put(hllHash, hllUnionSlot); + context.exprRewriteMap.putIntoProjectExprMap(hllHash, hllUnionSlot); HllUnion newHllUnion = new HllUnion(hllUnionSlot); context.exprRewriteMap.aggFuncMap.put(hllUnion, newHllUnion); return newHllUnion; @@ -1415,7 +1424,7 @@ public Expression visitHllUnionAgg(HllUnionAgg hllUnionAgg, RewriteContext conte .orElseThrow(() -> new AnalysisException( "cannot find hll union slot when select mv")); - context.exprRewriteMap.projectExprMap.put(hllHash, hllUnionSlot); + context.exprRewriteMap.putIntoProjectExprMap(hllHash, hllUnionSlot); HllUnionAgg newHllUnionAgg = new HllUnionAgg(hllUnionSlot); context.exprRewriteMap.aggFuncMap.put(hllUnionAgg, newHllUnionAgg); return newHllUnionAgg; @@ -1453,7 +1462,7 @@ public Expression visitNdv(Ndv ndv, RewriteContext context) { .orElseThrow(() -> new AnalysisException( "cannot find hll union slot when select mv")); - context.exprRewriteMap.projectExprMap.put(slotOpt.get(), hllUnionSlot); + context.exprRewriteMap.putIntoProjectExprMap(slotOpt.get(), hllUnionSlot); HllUnionAgg hllUnionAgg = new HllUnionAgg(hllUnionSlot); context.exprRewriteMap.aggFuncMap.put(ndv, hllUnionAgg); return hllUnionAgg; @@ -1477,7 +1486,7 @@ public Expression visitSum(Sum sum, RewriteContext context) { Slot sumSlot = context.checkContext.scan.getOutputByIndex(context.checkContext.index).stream() .filter(s -> sumColumn.equalsIgnoreCase(normalizeName(s.getName()))).findFirst() .orElseThrow(() -> new AnalysisException("cannot find sum slot when select mv")); - context.exprRewriteMap.projectExprMap.put(sum.child(), sumSlot); + context.exprRewriteMap.putIntoProjectExprMap(sum.child(), sumSlot); Sum newSum = new Sum(sumSlot); context.exprRewriteMap.aggFuncMap.put(sum, newSum); return newSum; @@ -1501,9 +1510,8 @@ public Expression visitAggregateFunction(AggregateFunction aggregateFunction, Re .filter(s -> aggStateName.equalsIgnoreCase(normalizeName(s.getName()))).findFirst() .orElseThrow(() -> new AnalysisException("cannot find agg state slot when select mv")); - Set slots = aggregateFunction.collect(SlotReference.class::isInstance); - for (Slot slot : slots) { - context.exprRewriteMap.projectExprMap.put(slot, aggStateSlot); + for (Expression child : aggregateFunction.children()) { + context.exprRewriteMap.putIntoProjectExprMap(child, aggStateSlot); } MergeCombinator mergeCombinator = new MergeCombinator(Arrays.asList(aggStateSlot), aggregateFunction); @@ -1574,19 +1582,29 @@ public Expression visitAggregateFunction(AggregateFunction aggregateFunction, } } - private List replaceProjectList( - LogicalProject project, - Map projectMap) { - return project.getProjects().stream() - .map(expr -> (NamedExpression) ExpressionUtils.replaceNameExpression(expr, projectMap)) - .collect(Collectors.toList()); - } + private List replaceOutput(List outputs, + Map> projectMap) { + Map> strToExprs = Maps.newHashMap(); + for (Expression expr : projectMap.keySet()) { + strToExprs.put(expr.toSql(), projectMap.get(expr)); + } - private List replaceRepeatOutput(LogicalRepeat repeat, - Map projectMap) { - return repeat.getOutputs().stream() - .map(expr -> (NamedExpression) ExpressionUtils.replaceNameExpression(expr, projectMap)) - .collect(Collectors.toList()); + List results = Lists.newArrayList(); + for (NamedExpression expr : outputs) { + results.add(expr); + + if (!strToExprs.containsKey(expr.toSql())) { + continue; + } + for (Expression newExpr : strToExprs.get(expr.toSql())) { + if (newExpr instanceof NamedExpression) { + results.add((NamedExpression) newExpr); + } else { + results.add(new Alias(expr.getExprId(), newExpr, expr.getName())); + } + } + } + return results; } private List nonVirtualGroupByExprs(LogicalAggregate agg) { diff --git a/regression-test/data/mv_p0/multi_agg_with_same_slot/multi_agg_with_same_slot.out b/regression-test/data/mv_p0/multi_agg_with_same_slot/multi_agg_with_same_slot.out new file mode 100644 index 00000000000000..596c82c14c806f --- /dev/null +++ b/regression-test/data/mv_p0/multi_agg_with_same_slot/multi_agg_with_same_slot.out @@ -0,0 +1,48 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !select_star -- +\N 4 \N d 4 +-4 -4 -4 d -4 +1 1 1 a 1 +2 2 2 b 2 +3 -3 \N c -3 + +-- !select_mv -- +\N 4 \N \N +-4 -4 -4.0 -4 +1 1 1.0 1 +2 2 2.0 2 +3 -3 \N \N + +-- !select_mv -- +\N 4 \N \N +-4 -4 -4.0 -4 +1 1 1.0 1 +2 2 2.0 2 +3 -3 \N \N + +-- !select_mv -- +\N \N \N \N +\N \N -0.3333333333333333 2 +\N 4 \N \N +-4 \N -4.0 -4 +-4 -4 -4.0 -4 +1 \N 1.0 1 +1 1 1.0 1 +2 \N 2.0 2 +2 2 2.0 2 +3 \N \N \N +3 -3 \N \N + +-- !select_mv -- +\N \N 4.0 4 +\N \N 0.0 4 +\N 4 4.0 4 +-4 \N -4.0 -4 +-4 -4 -4.0 -4 +1 \N 1.0 1 +1 1 1.0 1 +2 \N 2.0 2 +2 2 2.0 2 +3 \N -3.0 -3 +3 -3 -3.0 -3 + diff --git a/regression-test/data/mv_p0/mv_percentile/mv_percentile.out b/regression-test/data/mv_p0/mv_percentile/mv_percentile.out new file mode 100644 index 00000000000000..32e5595dac73e9 --- /dev/null +++ b/regression-test/data/mv_p0/mv_percentile/mv_percentile.out @@ -0,0 +1,36 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !select_star -- +\N 4 \N d +-4 -4 -4.000000 d +1 1 1.000000 a +2 2 2.000000 b +3 -3 \N c + +-- !select_mv -- +\N 4 \N \N +-4 -4 -4.0 -4.0 +1 1 1.0 1.0 +2 2 2.0 2.0 +3 -3 \N \N + +-- !select_mv -- +\N \N \N \N +\N \N -3.0 1.8 +\N 4 \N \N +-4 \N -4.0 -4.0 +-4 -4 -4.0 -4.0 +1 \N 1.0 1.0 +1 1 1.0 1.0 +2 \N 2.0 2.0 +2 2 2.0 2.0 +3 \N \N \N +3 -3 \N \N + +-- !select_mv -- +\N +\N +-4.0 +-3.0 +1.0 +2.0 + diff --git a/regression-test/suites/mv_p0/multi_agg_with_same_slot/multi_agg_with_same_slot.groovy b/regression-test/suites/mv_p0/multi_agg_with_same_slot/multi_agg_with_same_slot.groovy new file mode 100644 index 00000000000000..689e5ecbdc99da --- /dev/null +++ b/regression-test/suites/mv_p0/multi_agg_with_same_slot/multi_agg_with_same_slot.groovy @@ -0,0 +1,73 @@ +// 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. + +import org.codehaus.groovy.runtime.IOGroovyMethods + +suite ("multi_agg_with_same_slot") { + sql "set enable_fallback_to_original_planner = false" + + sql """DROP TABLE IF EXISTS d_table;""" + + sql """ + create table d_table( + k1 int null, + k2 int not null, + k3 bigint null, + k4 varchar(100) null, + k5 int not null + ) + duplicate key (k1,k2,k3) + distributed BY hash(k1) buckets 3 + properties("replication_num" = "1"); + """ + + sql "insert into d_table select 1,1,1,'a',1;" + sql "insert into d_table select 2,2,2,'b',2;" + sql "insert into d_table select 3,-3,null,'c',-3;" + + createMV("create materialized view kmv as select k1,k2,avg(k3),max(k3) from d_table group by k1,k2;") + createMV("create materialized view kmv2 as select k1,k2,avg(k5),max(k5) from d_table group by k1,k2;") + + sql "insert into d_table select -4,-4,-4,'d',-4;" + sql "insert into d_table(k4,k2,k5) values('d',4,4);" + + qt_select_star "select * from d_table order by k1;" + + explain { + sql("select k1,k2,avg(k3),max(k3) from d_table group by k1,k2 order by 1,2;") + contains "(kmv)" + } + qt_select_mv "select k1,k2,avg(k3),max(k3) from d_table group by k1,k2 order by 1,2;" + + explain { + sql("select k1,k2,avg(k3)+max(k3) from d_table group by k1,k2 order by 1,2;") + contains "(kmv)" + } + qt_select_mv "select k1,k2,avg(k3),max(k3) from d_table group by k1,k2 order by 1,2;" + + explain { + sql("select k1,k2,avg(k3)+max(k3) from d_table group by grouping sets((k1),(k1,k2),()) order by 1,2;") + contains "(kmv)" + } + qt_select_mv "select k1,k2,avg(k3),max(k3) from d_table group by grouping sets((k1),(k1,k2),()) order by 1,2;" + + explain { + sql("select k1,k2,max(k5) from d_table group by grouping sets((k1),(k1,k2),()) order by 1,2;") + contains "(kmv2)" + } + qt_select_mv "select k1,k2,avg(k5),max(k5) from d_table group by grouping sets((k1),(k1,k2),()) order by 1,2;" +} diff --git a/regression-test/suites/mv_p0/mv_percentile/mv_percentile.groovy b/regression-test/suites/mv_p0/mv_percentile/mv_percentile.groovy new file mode 100644 index 00000000000000..bcab4d48babafe --- /dev/null +++ b/regression-test/suites/mv_p0/mv_percentile/mv_percentile.groovy @@ -0,0 +1,66 @@ +// 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. + +import org.codehaus.groovy.runtime.IOGroovyMethods + +suite ("mv_percentile") { + sql "set enable_fallback_to_original_planner = false" + + sql """DROP TABLE IF EXISTS d_table;""" + + sql """ + create table d_table( + k1 int null, + k2 int not null, + k3 decimal(28,6) null, + k4 varchar(100) null + ) + duplicate key (k1,k2,k3) + distributed BY hash(k1) buckets 3 + properties("replication_num" = "1"); + """ + + sql "insert into d_table select 1,1,1,'a';" + sql "insert into d_table select 2,2,2,'b';" + sql "insert into d_table select 3,-3,null,'c';" + + createMV("create materialized view kp as select k1,k2,percentile(k3, 0.1),percentile(k3, 0.9) from d_table group by k1,k2;") + + sql "insert into d_table select -4,-4,-4,'d';" + sql "insert into d_table(k4,k2) values('d',4);" + + qt_select_star "select * from d_table order by k1;" + + explain { + sql("select k1,k2,percentile(k3, 0.1),percentile(k3, 0.9) from d_table group by k1,k2 order by k1,k2;") + contains "(kp)" + } + qt_select_mv "select k1,k2,percentile(k3, 0.1),percentile(k3, 0.9) from d_table group by k1,k2 order by k1,k2;" + + explain { + sql("select k1,k2,percentile(k3, 0.1),percentile(k3, 0.9) from d_table group by grouping sets((k1),(k1,k2),()) order by 1,2;") + contains "(kp)" + } + qt_select_mv "select k1,k2,percentile(k3, 0.1),percentile(k3, 0.9) from d_table group by grouping sets((k1),(k1,k2),()) order by 1,2;" + + + explain { + sql("select percentile(k3, 0.1) from d_table group by grouping sets((k1),()) order by 1;") + contains "(kp)" + } + qt_select_mv "select percentile(k3, 0.1) from d_table group by grouping sets((k1),()) order by 1;" +} From 3377125db74e885eadfd98dddca85199a79bc95d Mon Sep 17 00:00:00 2001 From: BiteTheDDDDt Date: Wed, 17 Apr 2024 16:30:24 +0800 Subject: [PATCH 2/5] format --- .../SelectMaterializedIndexWithAggregate.java | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java index 32e7eb53d5672c..64b0978d722d38 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java @@ -39,7 +39,6 @@ import org.apache.doris.nereids.trees.expressions.NamedExpression; import org.apache.doris.nereids.trees.expressions.Slot; import org.apache.doris.nereids.trees.expressions.SlotNotFromChildren; -import org.apache.doris.nereids.trees.expressions.SlotReference; import org.apache.doris.nereids.trees.expressions.VirtualSlotReference; import org.apache.doris.nereids.trees.expressions.WhenClause; import org.apache.doris.nereids.trees.expressions.functions.agg.AggregateFunction; @@ -340,21 +339,17 @@ public List buildRules() { // only agg above scan // Aggregate(Repeat(Scan)) - logicalAggregate( - logicalRepeat(logicalOlapScan().when(this::shouldSelectIndexWithAgg))).thenApplyNoThrow(ctx -> { - LogicalAggregate> agg = ctx.root; - LogicalRepeat repeat = agg.child(); - LogicalOlapScan scan = repeat.child(); - SelectResult result = select( - scan, - agg.getInputSlots(), - ImmutableSet.of(), - extractAggFunctionAndReplaceSlot(agg, Optional.empty()), - nonVirtualGroupByExprs(agg), - new HashSet<>(agg.getExpressions())); - - LogicalOlapScan mvPlan = createLogicalOlapScan(scan, result); - SlotContext slotContext = generateBaseScanExprToMvExpr(mvPlan); + logicalAggregate(logicalRepeat(logicalOlapScan().when(this::shouldSelectIndexWithAgg))) + .thenApplyNoThrow(ctx -> { + LogicalAggregate> agg = ctx.root; + LogicalRepeat repeat = agg.child(); + LogicalOlapScan scan = repeat.child(); + SelectResult result = select(scan, agg.getInputSlots(), ImmutableSet.of(), + extractAggFunctionAndReplaceSlot(agg, Optional.empty()), + nonVirtualGroupByExprs(agg), new HashSet<>(agg.getExpressions())); + + LogicalOlapScan mvPlan = createLogicalOlapScan(scan, result); + SlotContext slotContext = generateBaseScanExprToMvExpr(mvPlan); return new LogicalProject<>(generateProjectsAlias(agg.getOutputs(), slotContext), new ReplaceExpressions(slotContext) @@ -368,7 +363,7 @@ public List buildRules() { result.exprRewriteMap.projectExprMap), mvPlan)), mvPlan)); - }).toRule(RuleType.MATERIALIZED_INDEX_AGG_REPEAT_SCAN), + }).toRule(RuleType.MATERIALIZED_INDEX_AGG_REPEAT_SCAN), // filter could push down scan. // Aggregate(Repeat(Filter(Scan))) From 2737d15e9663ed895e0f8b6779a44b35d3634388 Mon Sep 17 00:00:00 2001 From: BiteTheDDDDt Date: Wed, 17 Apr 2024 18:09:11 +0800 Subject: [PATCH 3/5] fix --- .../translator/PhysicalPlanTranslator.java | 8 +++--- .../rules/analysis/BindExpression.java | 26 +------------------ .../AbstractSelectMaterializedIndexRule.java | 4 +-- .../SelectMaterializedIndexWithAggregate.java | 4 +++ .../apache/doris/nereids/util/PlanUtils.java | 25 ++++++++++++++++++ .../multi_agg_with_same_slot.out | 2 +- .../multi_agg_with_same_slot.groovy | 4 +-- .../mv_p0/mv_percentile/mv_percentile.groovy | 2 +- 8 files changed, 41 insertions(+), 34 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java index 205cfbd25309d8..e9f364ac88eba0 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java @@ -2230,9 +2230,11 @@ public PlanFragment visitPhysicalRepeat(PhysicalRepeat repeat, P .map(expr -> ExpressionTranslator.translate(expr, context)).collect(ImmutableList.toImmutableList()); // outputSlots's order need same with preRepeatExprs - List outputSlots = Stream.concat( - repeat.getOutputExpressions().stream().filter(output -> flattenGroupingSetExprs.contains(output)), - repeat.getOutputExpressions().stream().filter(output -> !flattenGroupingSetExprs.contains(output))) + List outputSlots = Stream + .concat(repeat.getOutputExpressions().stream() + .filter(output -> flattenGroupingSetExprs.contains(output)), + repeat.getOutputExpressions().stream() + .filter(output -> !flattenGroupingSetExprs.contains(output)).distinct()) .map(NamedExpression::toSlot).collect(ImmutableList.toImmutableList()); // NOTE: we should first translate preRepeatExprs, then generate output tuple, diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java index c2ef5ee18bd9d0..2f184d1f4632ab 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java @@ -646,7 +646,7 @@ private Plan bindRepeat(MatchingContext> ctx) { boundGroupingSetsBuilder.add(boundGroupingSet); } List> boundGroupingSets = boundGroupingSetsBuilder.build(); - List nullableOutput = adjustNullableForRepeat(boundGroupingSets, boundRepeatOutput); + List nullableOutput = PlanUtils.adjustNullableForRepeat(boundGroupingSets, boundRepeatOutput); for (List groupingSet : boundGroupingSets) { checkIfOutputAliasNameDuplicatedForGroupBy(groupingSet, nullableOutput); } @@ -803,30 +803,6 @@ private Plan bindSortWithoutSetOperation(MatchingContext> ctx) return new LogicalSort<>(boundOrderKeys.build(), sort.child()); } - /** - * For the columns whose output exists in grouping sets, they need to be assigned as nullable. - */ - public static List adjustNullableForRepeat( - List> groupingSets, - List outputs) { - Set groupingSetsUsedSlots = groupingSets.stream() - .flatMap(Collection::stream) - .map(Expression::getInputSlots) - .flatMap(Set::stream) - .collect(Collectors.toSet()); - Builder nullableOutputs = ImmutableList.builderWithExpectedSize(outputs.size()); - for (NamedExpression output : outputs) { - Expression nullableOutput = output.rewriteUp(expr -> { - if (expr instanceof Slot && groupingSetsUsedSlots.contains(expr)) { - return ((Slot) expr).withNullable(true); - } - return expr; - }); - nullableOutputs.add((NamedExpression) nullableOutput); - } - return nullableOutputs.build(); - } - private LogicalTVFRelation bindTableValuedFunction(MatchingContext ctx) { UnboundTVFRelation unboundTVFRelation = ctx.root; StatementContext statementContext = ctx.statementContext; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/AbstractSelectMaterializedIndexRule.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/AbstractSelectMaterializedIndexRule.java index 1f71420232852f..03bef1a6b47f81 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/AbstractSelectMaterializedIndexRule.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/AbstractSelectMaterializedIndexRule.java @@ -25,7 +25,6 @@ import org.apache.doris.catalog.MaterializedIndexMeta; import org.apache.doris.catalog.OlapTable; import org.apache.doris.nereids.parser.NereidsParser; -import org.apache.doris.nereids.rules.analysis.BindExpression; import org.apache.doris.nereids.trees.expressions.Alias; import org.apache.doris.nereids.trees.expressions.CaseWhen; import org.apache.doris.nereids.trees.expressions.Cast; @@ -58,6 +57,7 @@ import org.apache.doris.nereids.trees.plans.logical.LogicalRepeat; import org.apache.doris.nereids.trees.plans.visitor.DefaultPlanVisitor; import org.apache.doris.nereids.util.ExpressionUtils; +import org.apache.doris.nereids.util.PlanUtils; import org.apache.doris.planner.PlanNode; import com.google.common.collect.ImmutableList; @@ -589,7 +589,7 @@ public LogicalRepeat visitLogicalRepeat(LogicalRepeat repe } List outputExpressions = repeat.getOutputExpressions(); - List newOutputExpressions = BindExpression.adjustNullableForRepeat(newGroupingExprs, + List newOutputExpressions = PlanUtils.adjustNullableForRepeat(newGroupingExprs, outputExpressions.stream() .map(expr -> (NamedExpression) new ReplaceExpressionWithMvColumn(slotContext).replace(expr)) .collect(ImmutableList.toImmutableList())); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java index 64b0978d722d38..1d01144a09eab8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java @@ -1083,6 +1083,10 @@ private AggRewriteResult rewriteAgg(MaterializedIndex index, private static class ExprRewriteMap { /** * Replace map for expressions in project. + * For example: + * the query have avg(v), stddev_samp(v) + * projectExprMap will contain v -> [mva_GENERIC__avg_state(`v`), mva_GENERIC__stddev_samp_state(CAST(`v` AS DOUBLE))] + * then some LogicalPlan will output [mva_GENERIC__avg_state(`v`), mva_GENERIC__stddev_samp_state(CAST(`v` AS DOUBLE))] to replace column v */ public final Map> projectExprMap; /** diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/PlanUtils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/PlanUtils.java index 3955b2d0f0c6af..9c5e6b318e85d9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/PlanUtils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/PlanUtils.java @@ -45,6 +45,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; /** * Util for plan @@ -91,6 +92,30 @@ public static LogicalAggregate distinct(Plan plan) { } } + /** + * For the columns whose output exists in grouping sets, they need to be assigned as nullable. + */ + public static List adjustNullableForRepeat( + List> groupingSets, + List outputs) { + Set groupingSetsUsedSlots = groupingSets.stream() + .flatMap(Collection::stream) + .map(Expression::getInputSlots) + .flatMap(Set::stream) + .collect(Collectors.toSet()); + Builder nullableOutputs = ImmutableList.builderWithExpectedSize(outputs.size()); + for (NamedExpression output : outputs) { + Expression nullableOutput = output.rewriteUp(expr -> { + if (expr instanceof Slot && groupingSetsUsedSlots.contains(expr)) { + return ((Slot) expr).withNullable(true); + } + return expr; + }); + nullableOutputs.add((NamedExpression) nullableOutput); + } + return nullableOutputs.build(); + } + /** * merge childProjects with parentProjects */ diff --git a/regression-test/data/mv_p0/multi_agg_with_same_slot/multi_agg_with_same_slot.out b/regression-test/data/mv_p0/multi_agg_with_same_slot/multi_agg_with_same_slot.out index 596c82c14c806f..05e88880925e0f 100644 --- a/regression-test/data/mv_p0/multi_agg_with_same_slot/multi_agg_with_same_slot.out +++ b/regression-test/data/mv_p0/multi_agg_with_same_slot/multi_agg_with_same_slot.out @@ -34,8 +34,8 @@ 3 -3 \N \N -- !select_mv -- -\N \N 4.0 4 \N \N 0.0 4 +\N \N 4.0 4 \N 4 4.0 4 -4 \N -4.0 -4 -4 -4 -4.0 -4 diff --git a/regression-test/suites/mv_p0/multi_agg_with_same_slot/multi_agg_with_same_slot.groovy b/regression-test/suites/mv_p0/multi_agg_with_same_slot/multi_agg_with_same_slot.groovy index 689e5ecbdc99da..e92147dc51f0b7 100644 --- a/regression-test/suites/mv_p0/multi_agg_with_same_slot/multi_agg_with_same_slot.groovy +++ b/regression-test/suites/mv_p0/multi_agg_with_same_slot/multi_agg_with_same_slot.groovy @@ -63,11 +63,11 @@ suite ("multi_agg_with_same_slot") { sql("select k1,k2,avg(k3)+max(k3) from d_table group by grouping sets((k1),(k1,k2),()) order by 1,2;") contains "(kmv)" } - qt_select_mv "select k1,k2,avg(k3),max(k3) from d_table group by grouping sets((k1),(k1,k2),()) order by 1,2;" + qt_select_mv "select k1,k2,avg(k3),max(k3) from d_table group by grouping sets((k1),(k1,k2),()) order by 1,2,3;" explain { sql("select k1,k2,max(k5) from d_table group by grouping sets((k1),(k1,k2),()) order by 1,2;") contains "(kmv2)" } - qt_select_mv "select k1,k2,avg(k5),max(k5) from d_table group by grouping sets((k1),(k1,k2),()) order by 1,2;" + qt_select_mv "select k1,k2,avg(k5),max(k5) from d_table group by grouping sets((k1),(k1,k2),()) order by 1,2,3;" } diff --git a/regression-test/suites/mv_p0/mv_percentile/mv_percentile.groovy b/regression-test/suites/mv_p0/mv_percentile/mv_percentile.groovy index bcab4d48babafe..dd6cb453305eeb 100644 --- a/regression-test/suites/mv_p0/mv_percentile/mv_percentile.groovy +++ b/regression-test/suites/mv_p0/mv_percentile/mv_percentile.groovy @@ -55,7 +55,7 @@ suite ("mv_percentile") { sql("select k1,k2,percentile(k3, 0.1),percentile(k3, 0.9) from d_table group by grouping sets((k1),(k1,k2),()) order by 1,2;") contains "(kp)" } - qt_select_mv "select k1,k2,percentile(k3, 0.1),percentile(k3, 0.9) from d_table group by grouping sets((k1),(k1,k2),()) order by 1,2;" + qt_select_mv "select k1,k2,percentile(k3, 0.1),percentile(k3, 0.9) from d_table group by grouping sets((k1),(k1,k2),()) order by 1,2,3;" explain { From bf7c77c1e42c83cd183b9a3f2828874414e15b35 Mon Sep 17 00:00:00 2001 From: BiteTheDDDDt Date: Wed, 17 Apr 2024 18:17:38 +0800 Subject: [PATCH 4/5] format --- .../mv/SelectMaterializedIndexWithAggregate.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java index 1d01144a09eab8..b9f1e1cd4943e1 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java @@ -1082,11 +1082,12 @@ private AggRewriteResult rewriteAgg(MaterializedIndex index, private static class ExprRewriteMap { /** - * Replace map for expressions in project. - * For example: - * the query have avg(v), stddev_samp(v) - * projectExprMap will contain v -> [mva_GENERIC__avg_state(`v`), mva_GENERIC__stddev_samp_state(CAST(`v` AS DOUBLE))] - * then some LogicalPlan will output [mva_GENERIC__avg_state(`v`), mva_GENERIC__stddev_samp_state(CAST(`v` AS DOUBLE))] to replace column v + * Replace map for expressions in project. For example: the query have avg(v), + * stddev_samp(v) projectExprMap will contain + * v -> [mva_GENERIC__avg_state(`v`), mva_GENERIC__stddev_samp_state(CAST(`v` AS DOUBLE))] + * then some LogicalPlan will output + * [mva_GENERIC__avg_state(`v`), mva_GENERIC__stddev_samp_state(CAST(`v` AS DOUBLE))] + * to replace column v */ public final Map> projectExprMap; /** From baf914c954b8d634d436f30fd9e387e33c453e3a Mon Sep 17 00:00:00 2001 From: BiteTheDDDDt Date: Wed, 17 Apr 2024 18:22:24 +0800 Subject: [PATCH 5/5] format --- .../rewrite/mv/SelectMaterializedIndexWithAggregate.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java index b9f1e1cd4943e1..f28b3952fa9309 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/mv/SelectMaterializedIndexWithAggregate.java @@ -1083,11 +1083,10 @@ private AggRewriteResult rewriteAgg(MaterializedIndex index, private static class ExprRewriteMap { /** * Replace map for expressions in project. For example: the query have avg(v), - * stddev_samp(v) projectExprMap will contain - * v -> [mva_GENERIC__avg_state(`v`), mva_GENERIC__stddev_samp_state(CAST(`v` AS DOUBLE))] - * then some LogicalPlan will output - * [mva_GENERIC__avg_state(`v`), mva_GENERIC__stddev_samp_state(CAST(`v` AS DOUBLE))] - * to replace column v + * stddev_samp(v) projectExprMap will contain v -> [mva_GENERIC__avg_state(`v`), + * mva_GENERIC__stddev_samp_state(CAST(`v` AS DOUBLE))] then some LogicalPlan + * will output [mva_GENERIC__avg_state(`v`), + * mva_GENERIC__stddev_samp_state(CAST(`v` AS DOUBLE))] to replace column v */ public final Map> projectExprMap; /**