[Feature](materialized-view) support visitBitmapUnion mv rewrite (#29200)

* support visitBitmapUnion rewrite

* add case
This commit is contained in:
Pxl
2023-12-28 14:56:33 +08:00
committed by GitHub
parent 29a7c0d677
commit c98489fc09
3 changed files with 86 additions and 24 deletions

View File

@ -52,7 +52,6 @@ import org.apache.doris.nereids.trees.expressions.functions.agg.Ndv;
import org.apache.doris.nereids.trees.expressions.functions.agg.Sum;
import org.apache.doris.nereids.trees.expressions.functions.combinator.MergeCombinator;
import org.apache.doris.nereids.trees.expressions.functions.combinator.StateCombinator;
import org.apache.doris.nereids.trees.expressions.functions.scalar.BitmapHash;
import org.apache.doris.nereids.trees.expressions.functions.scalar.HllHash;
import org.apache.doris.nereids.trees.expressions.functions.scalar.ToBitmap;
import org.apache.doris.nereids.trees.expressions.functions.scalar.ToBitmapWithCheck;
@ -1282,6 +1281,66 @@ public class SelectMaterializedIndexWithAggregate extends AbstractSelectMaterial
return count;
}
/**
* bitmap_union(to_bitmap(col)) ->
* bitmap_union(mva_BITMAP_UNION__to_bitmap_with_check(col))
*/
@Override
public Expression visitBitmapUnion(BitmapUnion bitmapUnion, RewriteContext context) {
Expression result = visitAggregateFunction(bitmapUnion, context);
if (result != bitmapUnion) {
return result;
}
if (bitmapUnion.child() instanceof ToBitmap) {
ToBitmap toBitmap = (ToBitmap) bitmapUnion.child();
Optional<Slot> slotOpt = ExpressionUtils.extractSlotOrCastOnSlot(toBitmap.child());
if (slotOpt.isPresent()) {
String bitmapUnionColumn = normalizeName(CreateMaterializedViewStmt
.mvColumnBuilder(AggregateType.BITMAP_UNION, CreateMaterializedViewStmt
.mvColumnBuilder(new ToBitmapWithCheck(toBitmap.child()).toSql())));
Column mvColumn = context.checkContext.getColumn(bitmapUnionColumn);
// has bitmap_union column
if (mvColumn != null && context.checkContext.valueNameToColumn.containsValue(mvColumn)) {
Slot bitmapUnionSlot = context.checkContext.scan.getOutputByIndex(context.checkContext.index)
.stream().filter(s -> bitmapUnionColumn.equalsIgnoreCase(normalizeName(s.getName())))
.findFirst().orElseThrow(
() -> new AnalysisException("cannot find bitmap union slot when select mv"));
context.exprRewriteMap.slotMap.put(slotOpt.get(), bitmapUnionSlot);
context.exprRewriteMap.projectExprMap.put(toBitmap, bitmapUnionSlot);
BitmapUnion newBitmapUnion = new BitmapUnion(bitmapUnionSlot);
context.exprRewriteMap.aggFuncMap.put(bitmapUnion, newBitmapUnion);
return newBitmapUnion;
}
}
} else {
Expression child = bitmapUnion.child();
String bitmapUnionColumn = normalizeName(CreateMaterializedViewStmt.mvColumnBuilder(
AggregateType.BITMAP_UNION, CreateMaterializedViewStmt.mvColumnBuilder(child.toSql())));
Column mvColumn = context.checkContext.getColumn(bitmapUnionColumn);
// has bitmap_union column
if (mvColumn != null && context.checkContext.valueNameToColumn.containsValue(mvColumn)) {
Slot bitmapUnionSlot = context.checkContext.scan.getOutputByIndex(context.checkContext.index)
.stream().filter(s -> bitmapUnionColumn.equalsIgnoreCase(normalizeName(s.getName())))
.findFirst()
.orElseThrow(() -> new AnalysisException("cannot find bitmap union slot when select mv"));
if (child instanceof Slot) {
context.exprRewriteMap.slotMap.put((Slot) child, bitmapUnionSlot);
}
context.exprRewriteMap.projectExprMap.put(child, bitmapUnionSlot);
BitmapUnion newBitmapUnion = new BitmapUnion(bitmapUnionSlot);
context.exprRewriteMap.aggFuncMap.put(bitmapUnion, newBitmapUnion);
return newBitmapUnion;
}
}
return bitmapUnion;
}
/**
* bitmap_union_count(to_bitmap(col)) -> bitmap_union_count(mva_BITMAP_UNION__to_bitmap_with_check(col))
*/
@ -1318,32 +1377,26 @@ public class SelectMaterializedIndexWithAggregate extends AbstractSelectMaterial
return newBitmapUnionCount;
}
}
} else if (bitmapUnionCount.child() instanceof BitmapHash) {
BitmapHash bitmapHash = (BitmapHash) bitmapUnionCount.child();
Optional<Slot> slotOpt = ExpressionUtils.extractSlotOrCastOnSlot(bitmapHash.child());
if (slotOpt.isPresent()) {
String bitmapUnionCountColumn = normalizeName(
CreateMaterializedViewStmt.mvColumnBuilder(AggregateType.BITMAP_UNION,
CreateMaterializedViewStmt.mvColumnBuilder(bitmapHash.toSql())));
} else {
Expression child = bitmapUnionCount.child();
String bitmapUnionCountColumn = normalizeName(CreateMaterializedViewStmt.mvColumnBuilder(
AggregateType.BITMAP_UNION, CreateMaterializedViewStmt.mvColumnBuilder(child.toSql())));
Column mvColumn = context.checkContext.getColumn(bitmapUnionCountColumn);
// has bitmap_union_count column
if (mvColumn != null && context.checkContext.valueNameToColumn.containsValue(mvColumn)) {
Column mvColumn = context.checkContext.getColumn(bitmapUnionCountColumn);
// has bitmap_union_count column
if (mvColumn != null && context.checkContext.valueNameToColumn.containsValue(mvColumn)) {
Slot bitmapUnionCountSlot = context.checkContext.scan
.getOutputByIndex(context.checkContext.index)
.stream()
.filter(s -> bitmapUnionCountColumn.equalsIgnoreCase(normalizeName(s.getName())))
.findFirst()
.orElseThrow(() -> new AnalysisException(
"cannot find bitmap union count slot when select mv"));
context.exprRewriteMap.slotMap.put(slotOpt.get(), bitmapUnionCountSlot);
context.exprRewriteMap.projectExprMap.put(bitmapHash, bitmapUnionCountSlot);
BitmapUnionCount newBitmapUnionCount = new BitmapUnionCount(bitmapUnionCountSlot);
context.exprRewriteMap.aggFuncMap.put(bitmapUnionCount, newBitmapUnionCount);
return newBitmapUnionCount;
Slot bitmapUnionCountSlot = context.checkContext.scan.getOutputByIndex(context.checkContext.index)
.stream().filter(s -> bitmapUnionCountColumn.equalsIgnoreCase(normalizeName(s.getName())))
.findFirst().orElseThrow(
() -> new AnalysisException("cannot find bitmap union count slot when select mv"));
if (child instanceof Slot) {
context.exprRewriteMap.slotMap.put((Slot) child, bitmapUnionCountSlot);
}
context.exprRewriteMap.projectExprMap.put(child, bitmapUnionCountSlot);
BitmapUnionCount newBitmapUnionCount = new BitmapUnionCount(bitmapUnionCountSlot);
context.exprRewriteMap.aggFuncMap.put(bitmapUnionCount, newBitmapUnionCount);
return newBitmapUnionCount;
}
}

View File

@ -7,3 +7,6 @@
-- !select_mv --
1 2
-- !select_mv --
1 2

View File

@ -47,4 +47,10 @@ suite ("testBitmapUnionInQuery") {
contains "(user_tags_mv)"
}
qt_select_mv "select user_id, bitmap_union_count(to_bitmap(tag_id)) a from user_tags group by user_id having a>1 order by a;"
explain {
sql("select user_id, bitmap_count(bitmap_union(to_bitmap(tag_id))) a from user_tags group by user_id having a>1 order by a;")
contains "(user_tags_mv)"
}
qt_select_mv "select user_id, bitmap_count(bitmap_union(to_bitmap(tag_id))) a from user_tags group by user_id having a>1 order by a;"
}