This is an automated email from the ASF dual-hosted git repository.

panxiaolei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new f4ed52906a [Feature](Materialized-View) change mv rewrite from bottom 
up to up bottom && Compatible with old … (#16750)
f4ed52906a is described below

commit f4ed52906ac5783858f22a5e10e318b4bea986f2
Author: Pxl <pxl...@qq.com>
AuthorDate: Wed Feb 15 17:24:46 2023 +0800

    [Feature](Materialized-View) change mv rewrite from bottom up to up bottom 
&& Compatible with old … (#16750)
    
    1.change mv rewrite from bottom up to up bottom
    2.compatible with old version mv
    3.restore some ut codes (but disable)
    4. fix some ut introduced by [fix](planner)fix bug for missing slot #16601 
and [Feature](Materialized-View) support multiple slot on one column in 
materialized view #16378
---
 .../doris/analysis/CreateMaterializedViewStmt.java |  17 ++
 .../java/org/apache/doris/analysis/QueryStmt.java  |   1 +
 .../main/java/org/apache/doris/catalog/Column.java |  12 ++
 .../doris/catalog/MaterializedIndexMeta.java       |  52 +++++-
 .../java/org/apache/doris/catalog/OlapTable.java   |   6 +-
 .../main/java/org/apache/doris/catalog/Table.java  |   2 +-
 .../apache/doris/planner/SingleNodePlanner.java    |   4 +-
 .../org/apache/doris/rewrite/ExprRewriter.java     |  72 +++++++--
 .../doris/rewrite/mvrewrite/ExprToSlotRefRule.java |   2 +-
 .../planner/MaterializedViewFunctionTest.java      |   3 +-
 .../planner/MaterializedViewSelectorTest.java      | 177 +++++++++++++++++++++
 11 files changed, 322 insertions(+), 26 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMaterializedViewStmt.java
 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMaterializedViewStmt.java
index 5fe8244019..76c86c62b3 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMaterializedViewStmt.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMaterializedViewStmt.java
@@ -496,6 +496,23 @@ public class CreateMaterializedViewStmt extends DdlStmt {
         return name;
     }
 
+    public static String oldmvColumnBreaker(String name) {
+        if (name.startsWith(MATERIALIZED_VIEW_NAME_PREFIX)) {
+            // mv_count_k2 -> k2
+            name = name.substring(MATERIALIZED_VIEW_NAME_PREFIX.length());
+            for (String prefix : FN_NAME_TO_PATTERN.keySet()) {
+                if (name.startsWith(prefix)) {
+                    return name.substring(prefix.length() + 1);
+                }
+            }
+        }
+        if (name.startsWith(MATERIALIZED_VIEW_NAME_PREFIX)) {
+            // mv_k2 -> k2
+            return 
mvColumnBreaker(name.substring(MATERIALIZED_VIEW_NAME_PREFIX.length()));
+        }
+        return name;
+    }
+
     public static boolean isMVColumn(String name) {
         return isMVColumnAggregate(name) || isMVColumnNormal(name);
     }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/QueryStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/QueryStmt.java
index 2181d30fd3..3564cb2927 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/QueryStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/QueryStmt.java
@@ -281,6 +281,7 @@ public abstract class QueryStmt extends StatementBase 
implements Queriable {
         ExprRewriter rewriter = analyzer.getMVExprRewriter();
         rewriter.reset();
         rewriter.setDisableTuplesMVRewriter(disableTuplesMVRewriter);
+        rewriter.setUpBottom();
 
         Expr result = rewriter.rewrite(expr, analyzer);
         if (result != expr) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Column.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Column.java
index 3c0da6dab2..2a1f5de023 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Column.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Column.java
@@ -111,6 +111,7 @@ public class Column implements Writable, 
GsonPostProcessable {
     // so the define expr in RollupJob must be analyzed.
     // In other cases, such as define expr in `MaterializedIndexMeta`, it may 
not be analyzed after being replayed.
     private Expr defineExpr; // use to define column in materialize view
+    private String defineName = null;
     @SerializedName(value = "visible")
     private boolean visible;
     @SerializedName(value = "defaultValueExprDef")
@@ -236,6 +237,17 @@ public class Column implements Writable, 
GsonPostProcessable {
         this.children.add(column);
     }
 
+    public void setDefineName(String defineName) {
+        this.defineName = defineName;
+    }
+
+    public String getDefineName() {
+        if (defineName != null) {
+            return defineName;
+        }
+        return name;
+    }
+
     public void setName(String newName) {
         this.name = newName;
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/MaterializedIndexMeta.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/MaterializedIndexMeta.java
index a45ebdbfca..455a86b88e 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/MaterializedIndexMeta.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/MaterializedIndexMeta.java
@@ -19,6 +19,7 @@ package org.apache.doris.catalog;
 
 import org.apache.doris.analysis.CreateMaterializedViewStmt;
 import org.apache.doris.analysis.Expr;
+import org.apache.doris.analysis.SlotRef;
 import org.apache.doris.analysis.SqlParser;
 import org.apache.doris.analysis.SqlScanner;
 import org.apache.doris.common.io.Text;
@@ -40,6 +41,7 @@ import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.io.StringReader;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -136,14 +138,62 @@ public class MaterializedIndexMeta implements Writable, 
GsonPostProcessable {
         return schemaVersion;
     }
 
-    private void setColumnsDefineExpr(Map<String, Expr> 
columnNameToDefineExpr) {
+    private void setColumnsDefineExpr(Map<String, Expr> 
columnNameToDefineExpr) throws IOException {
         for (Map.Entry<String, Expr> entry : 
columnNameToDefineExpr.entrySet()) {
+            boolean match = false;
             for (Column column : schema) {
                 if (column.getName().equals(entry.getKey())) {
                     column.setDefineExpr(entry.getValue());
+                    match = true;
                     break;
                 }
             }
+
+            if (!match) {
+                // Compatibility code for older versions of mv
+                // store_id -> mv_store_id
+                // sale_amt -> mva_SUM__`sale_amt`
+                // mv_count_sale_amt -> mva_SUM__CASE WHEN `sale_amt` IS NULL 
THEN 0 ELSE 1 END
+                List<SlotRef> slots = new ArrayList<>();
+                entry.getValue().collect(SlotRef.class, slots);
+                if (slots.size() > 1) {
+                    throw new IOException("DefineExpr have multiple slot in 
MaterializedIndex, Expr=" + entry.getKey());
+                }
+
+                String name = 
MaterializedIndexMeta.normalizeName(slots.get(0).toSqlWithoutTbl());
+                Column matchedColumn = null;
+
+                String columnList = "[";
+                for (Column column : schema) {
+                    if (columnList.length() != 1) {
+                        columnList += ", ";
+                    }
+                    columnList += column.getName();
+                }
+                columnList += "]";
+
+                for (Column column : schema) {
+                    if 
(CreateMaterializedViewStmt.oldmvColumnBreaker(column.getName()).equals(name)) {
+                        if (matchedColumn == null) {
+                            matchedColumn = column;
+                        } else {
+                            LOG.warn("DefineExpr match multiple column in 
MaterializedIndex, ExprName=" + entry.getKey()
+                                    + ", Expr=" + 
entry.getValue().toSqlWithoutTbl() + ", Slot=" + name
+                                    + ", Columns=" + columnList);
+                        }
+                    }
+                }
+                if (matchedColumn != null) {
+                    LOG.debug("trans old MV, MV: {},  DefineExpr:{}, 
DefineName:{}",
+                            matchedColumn.getName(), 
entry.getValue().toSqlWithoutTbl(), entry.getKey());
+                    matchedColumn.setDefineExpr(entry.getValue());
+                    matchedColumn.setDefineName(entry.getKey());
+                } else {
+                    LOG.warn("DefineExpr does not match any column in 
MaterializedIndex, ExprName=" + entry.getKey()
+                            + ", Expr=" + entry.getValue().toSqlWithoutTbl() + 
", Slot=" + name
+                            + ", Columns=" + columnList);
+                }
+            }
         }
     }
 
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
index b6bfa3edb8..e570274625 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
@@ -333,9 +333,9 @@ public class OlapTable extends Table {
         }
         for (MaterializedIndexMeta indexMeta : indexIdToMeta.values()) {
             for (Column column : indexMeta.getSchema()) {
-                if (!nameToColumn.containsKey(column.getName())) {
+                if (!nameToColumn.containsKey(column.getDefineName())) {
                     fullSchema.add(column);
-                    nameToColumn.put(column.getName(), column);
+                    nameToColumn.put(column.getDefineName(), column);
                 }
             }
         }
@@ -403,7 +403,7 @@ public class OlapTable extends Table {
     public Column getVisibleColumn(String columnName) {
         for (MaterializedIndexMeta meta : getVisibleIndexIdToMeta().values()) {
             for (Column column : meta.getSchema()) {
-                if (MaterializedIndexMeta.matchColumnName(column.getName(), 
columnName)) {
+                if 
(MaterializedIndexMeta.matchColumnName(column.getDefineName(), columnName)) {
                     return column;
                 }
             }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java
index 9ba5253883..3f8597f1e0 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java
@@ -124,7 +124,7 @@ public abstract class Table extends MetaObject implements 
Writable, TableIf {
         this.nameToColumn = Maps.newTreeMap(String.CASE_INSENSITIVE_ORDER);
         if (this.fullSchema != null) {
             for (Column col : this.fullSchema) {
-                nameToColumn.put(col.getName(), col);
+                nameToColumn.put(col.getDefineName(), col);
             }
         } else {
             // Only view in with-clause have null base
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java
index 318ebb270c..619ee2efe5 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java
@@ -1193,10 +1193,10 @@ public class SingleNodePlanner {
             // create left-deep sequence of binary hash joins; assign node ids 
as we go along
             TableRef tblRef = selectStmt.getTableRefs().get(0);
             materializeTableResultForCrossJoinOrCountStar(tblRef, analyzer);
-            if (selectStmt.getSelectList().getItems().size() == 1) {
+            if (selectStmt.getResultExprs().size() == 1) {
                 final List<SlotId> slotIds = Lists.newArrayList();
                 final List<TupleId> tupleIds = Lists.newArrayList();
-                Expr resultExprSelected = 
selectStmt.getSelectList().getItems().get(0).getExpr();
+                Expr resultExprSelected =  selectStmt.getResultExprs().get(0);
                 if (resultExprSelected != null && resultExprSelected 
instanceof SlotRef) {
                     resultExprSelected.getIds(tupleIds, slotIds);
                     for (SlotId id : slotIds) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/rewrite/ExprRewriter.java 
b/fe/fe-core/src/main/java/org/apache/doris/rewrite/ExprRewriter.java
index 7ffb42c0e7..43e9994a1e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/rewrite/ExprRewriter.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/rewrite/ExprRewriter.java
@@ -34,10 +34,12 @@ import java.util.Map;
 import java.util.Set;
 
 /**
- * Helper class that drives the transformation of Exprs according to a given 
list of
+ * Helper class that drives the transformation of Exprs according to a given
+ * list of
  * ExprRewriteRules. The rules are applied as follows:
- * - a single rule is applied repeatedly to the Expr and all its children in a 
bottom-up
- *   fashion until there are no more changes
+ * - a single rule is applied repeatedly to the Expr and all its children in a
+ * bottom-up
+ * fashion until there are no more changes
  * - the rule list is applied repeatedly until no rule has made any changes
  * - the rules are applied in the order they appear in the rule list
  * Keeps track of how many transformations were applied.
@@ -51,11 +53,13 @@ import java.util.Set;
  * Doris match different Rewriter framework execution.
  */
 public class ExprRewriter {
+    private boolean useUpBottom = false;
     private int numChanges = 0;
     private final List<ExprRewriteRule> rules;
 
     // The type of clause that executes the rule.
-    // This type is only used in InferFiltersRule, RewriteDateLiteralRule, 
other rules are not used
+    // This type is only used in InferFiltersRule, RewriteDateLiteralRule, 
other
+    // rules are not used
     public enum ClauseType {
         INNER_JOIN_CLAUSE,
         LEFT_OUTER_JOIN_CLAUSE,
@@ -71,18 +75,27 @@ public class ExprRewriter {
 
         public static ClauseType fromJoinType(JoinOperator joinOp) {
             switch (joinOp) {
-                case INNER_JOIN: return INNER_JOIN_CLAUSE;
-                case LEFT_OUTER_JOIN: return LEFT_OUTER_JOIN_CLAUSE;
-                case RIGHT_OUTER_JOIN: return RIGHT_OUTER_JOIN_CLAUSE;
-                case FULL_OUTER_JOIN: return FULL_OUTER_JOIN_CLAUSE;
-                case LEFT_SEMI_JOIN: return LEFT_SEMI_JOIN_CLAUSE;
-                case RIGHT_SEMI_JOIN: return RIGHT_SEMI_JOIN_CLAUSE;
+                case INNER_JOIN:
+                    return INNER_JOIN_CLAUSE;
+                case LEFT_OUTER_JOIN:
+                    return LEFT_OUTER_JOIN_CLAUSE;
+                case RIGHT_OUTER_JOIN:
+                    return RIGHT_OUTER_JOIN_CLAUSE;
+                case FULL_OUTER_JOIN:
+                    return FULL_OUTER_JOIN_CLAUSE;
+                case LEFT_SEMI_JOIN:
+                    return LEFT_SEMI_JOIN_CLAUSE;
+                case RIGHT_SEMI_JOIN:
+                    return RIGHT_SEMI_JOIN_CLAUSE;
                 case NULL_AWARE_LEFT_ANTI_JOIN:
                 case LEFT_ANTI_JOIN:
                     return LEFT_ANTI_JOIN_CLAUSE;
-                case RIGHT_ANTI_JOIN: return RIGHT_ANTI_JOIN_CLAUSE;
-                case CROSS_JOIN: return CROSS_JOIN_CLAUSE;
-                default: return OTHER_CLAUSE;
+                case RIGHT_ANTI_JOIN:
+                    return RIGHT_ANTI_JOIN_CLAUSE;
+                case CROSS_JOIN:
+                    return CROSS_JOIN_CLAUSE;
+                default:
+                    return OTHER_CLAUSE;
             }
         }
 
@@ -126,6 +139,10 @@ public class ExprRewriter {
         }
     }
 
+    public void setUpBottom() {
+        useUpBottom = true;
+    }
+
     public Expr rewrite(Expr expr, Analyzer analyzer) throws AnalysisException 
{
         ClauseType clauseType = ClauseType.OTHER_CLAUSE;
         return rewrite(expr, analyzer, clauseType);
@@ -138,7 +155,8 @@ public class ExprRewriter {
         do {
             oldNumChanges = numChanges;
             for (ExprRewriteRule rule : rules) {
-                // when foldConstantByBe is on, fold all constant expr by BE 
instead of applying FoldConstantsRule in FE
+                // when foldConstantByBe is on, fold all constant expr by BE 
instead of applying
+                // FoldConstantsRule in FE
                 if (rule instanceof FoldConstantsRule && 
analyzer.safeIsEnableFoldConstantByBe()) {
                     continue;
                 }
@@ -181,7 +199,8 @@ public class ExprRewriter {
     }
 
     /**
-     * Applies 'rule' on the Expr tree rooted at 'expr' until there are no 
more changes.
+     * Applies 'rule' on the Expr tree rooted at 'expr' until there are no more
+     * changes.
      * Returns the transformed Expr or 'expr' if there were no changes.
      */
     private Expr applyRuleRepeatedly(Expr expr, ExprRewriteRule rule, Analyzer 
analyzer, ClauseType clauseType)
@@ -190,11 +209,20 @@ public class ExprRewriter {
         Expr rewrittenExpr = expr;
         do {
             oldNumChanges = numChanges;
-            rewrittenExpr = applyRuleBottomUp(rewrittenExpr, rule, analyzer, 
clauseType);
+            rewrittenExpr = applyRule(rewrittenExpr, rule, analyzer, 
clauseType);
         } while (oldNumChanges != numChanges);
         return rewrittenExpr;
     }
 
+    private Expr applyRule(Expr expr, ExprRewriteRule rule, Analyzer analyzer, 
ClauseType clauseType)
+            throws AnalysisException {
+        if (useUpBottom) {
+            return applyRuleUpBottom(expr, rule, analyzer, clauseType);
+        } else {
+            return applyRuleBottomUp(expr, rule, analyzer, clauseType);
+        }
+    }
+
     /**
      * Applies 'rule' on 'expr' and all its children in a bottom-up fashion.
      * Returns the transformed Expr or 'expr' if there were no changes.
@@ -211,6 +239,18 @@ public class ExprRewriter {
         return rewrittenExpr;
     }
 
+    private Expr applyRuleUpBottom(Expr expr, ExprRewriteRule rule, Analyzer 
analyzer, ClauseType clauseType)
+            throws AnalysisException {
+        Expr rewrittenExpr = rule.apply(expr, analyzer, clauseType);
+        if (rewrittenExpr != expr) {
+            ++numChanges;
+        }
+        for (int i = 0; i < expr.getChildren().size(); ++i) {
+            expr.setChild(i, applyRuleUpBottom(expr.getChild(i), rule, 
analyzer, clauseType));
+        }
+        return rewrittenExpr;
+    }
+
     public void rewriteList(List<Expr> exprs, Analyzer analyzer) throws 
AnalysisException {
         for (int i = 0; i < exprs.size(); ++i) {
             exprs.set(i, rewrite(exprs.get(i), analyzer));
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/rewrite/mvrewrite/ExprToSlotRefRule.java
 
b/fe/fe-core/src/main/java/org/apache/doris/rewrite/mvrewrite/ExprToSlotRefRule.java
index 3d58c68fd5..ea03d0af62 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/rewrite/mvrewrite/ExprToSlotRefRule.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/rewrite/mvrewrite/ExprToSlotRefRule.java
@@ -267,7 +267,7 @@ public class ExprToSlotRefRule implements ExprRewriteRule {
     private Expr rewriteExpr(TableName tableName, Column mvColumn, Analyzer 
analyzer) {
         Preconditions.checkNotNull(mvColumn);
         Preconditions.checkNotNull(tableName);
-        SlotRef mvSlotRef = new SlotRef(tableName, mvColumn.getName());
+        SlotRef mvSlotRef = new SlotRef(tableName, mvColumn.getDefineName());
         mvSlotRef.analyzeNoThrow(analyzer);
         return mvSlotRef;
     }
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/planner/MaterializedViewFunctionTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/planner/MaterializedViewFunctionTest.java
index 60a813b2cf..501e203ae3 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/planner/MaterializedViewFunctionTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/planner/MaterializedViewFunctionTest.java
@@ -550,8 +550,7 @@ public class MaterializedViewFunctionTest {
         
dorisAssert.withMaterializedView(createEmpsMVsql).query(query).explainContains(QUERY_USE_EMPS_MV,
 2);
     }
 
-    // Can not support match multiple mv now
-    //@Test
+    @Test
     public void testMultiMVMultiUsage() throws Exception {
         String createEmpsMVSql01 = "create materialized view emp_mv_01 as 
select deptno, empid, salary "
                 + "from " + EMPS_TABLE_NAME + " order by deptno;";
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/planner/MaterializedViewSelectorTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/planner/MaterializedViewSelectorTest.java
index 2e8e2ebc2e..7767fc71ab 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/planner/MaterializedViewSelectorTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/planner/MaterializedViewSelectorTest.java
@@ -156,6 +156,137 @@ public class MaterializedViewSelectorTest {
         
Assert.assertTrue("MAX".equalsIgnoreCase(aggregatedColumn2.getFnName().getFunction()));
     }
 
+    @Disabled
+    public void testCheckCompensatingPredicates(@Injectable SelectStmt 
selectStmt, @Injectable Analyzer analyzer,
+            @Injectable MaterializedIndexMeta indexMeta1,
+            @Injectable MaterializedIndexMeta indexMeta2,
+            @Injectable MaterializedIndexMeta indexMeta3,
+            @Injectable MaterializedIndexMeta indexMeta4, @Injectable SlotRef 
slotRef1, @Injectable SlotRef slotRef2) {
+        Set<String> tableAColumnNames = Sets.newHashSet();
+        tableAColumnNames.add("C1");
+        Map<Long, MaterializedIndexMeta> candidateIndexIdToSchema = 
Maps.newHashMap();
+        List<Column> index1Columns = Lists.newArrayList();
+        Column index1Column1 = new Column("c1", Type.INT, true, null, true, 
"", "");
+        index1Columns.add(index1Column1);
+        index1Column1.setDefineExpr(slotRef1);
+        candidateIndexIdToSchema.put(new Long(1), indexMeta1);
+        List<Column> index2Columns = Lists.newArrayList();
+        Column index2Column1 = new Column("c1", Type.INT, false, 
AggregateType.NONE, true, "", "");
+        index2Columns.add(index2Column1);
+        index2Column1.setDefineExpr(slotRef1);
+        candidateIndexIdToSchema.put(new Long(2), indexMeta2);
+        List<Column> index3Columns = Lists.newArrayList();
+        Column index3Column1 = new Column("c1", Type.INT, false, 
AggregateType.SUM, true, "", "");
+        index3Column1.setDefineExpr(slotRef1);
+        index3Columns.add(index3Column1);
+        candidateIndexIdToSchema.put(new Long(3), indexMeta3);
+        List<Column> index4Columns = Lists.newArrayList();
+        Column index4Column2 = new Column("c2", Type.INT, true, null, true, 
"", "");
+        index4Column2.setDefineExpr(slotRef2);
+        index4Columns.add(index4Column2);
+        candidateIndexIdToSchema.put(new Long(4), indexMeta4);
+
+        List<Expr> whereList = Lists.newArrayList();
+        whereList.add(slotRef1);
+        new Expectations() {
+            {
+                selectStmt.getAggInfo();
+                result = null;
+                selectStmt.getWhereClause();
+                result = whereList;
+                indexMeta1.getSchema();
+                result = index1Columns;
+                indexMeta2.getSchema();
+                result = index2Columns;
+                indexMeta3.getSchema();
+                result = index3Columns;
+                indexMeta4.getSchema();
+                result = index4Columns;
+                slotRef1.toSqlWithoutTbl();
+                result = "c1";
+            }
+        };
+
+        MaterializedViewSelector selector = new 
MaterializedViewSelector(selectStmt, analyzer);
+        try {
+            Deencapsulation.invoke(selector, "checkCompensatingPredicates", 
tableAColumnNames,
+                    candidateIndexIdToSchema);
+        } catch (Exception e) {
+            e.printStackTrace();
+            Assert.fail(e.getMessage());
+        }
+
+        Assert.assertEquals(2, candidateIndexIdToSchema.size());
+        Assert.assertTrue(candidateIndexIdToSchema.keySet().contains(new 
Long(1)));
+        Assert.assertTrue(candidateIndexIdToSchema.keySet().contains(new 
Long(2)));
+    }
+
+    @Disabled
+    public void testCheckGrouping(@Injectable SelectStmt selectStmt, 
@Injectable Analyzer analyzer,
+            @Injectable OlapTable table,
+            @Injectable MaterializedIndexMeta indexMeta1,
+            @Injectable MaterializedIndexMeta indexMeta2,
+            @Injectable MaterializedIndexMeta indexMeta3, @Injectable SlotRef 
slotRef1, @Injectable SlotRef slotRef2) {
+        Set<String> tableAColumnNames = Sets.newHashSet();
+        tableAColumnNames.add("C1");
+        Map<Long, MaterializedIndexMeta> candidateIndexIdToSchema = 
Maps.newHashMap();
+        List<Column> index1Columns = Lists.newArrayList();
+        Column index1Column1 = new Column("c2", Type.INT, true, null, true, 
"", "");
+        index1Column1.setDefineExpr(slotRef2);
+        index1Columns.add(index1Column1);
+        candidateIndexIdToSchema.put(new Long(1), indexMeta1);
+        List<Column> index2Columns = Lists.newArrayList();
+        Column index2Column1 = new Column("c1", Type.INT, true, null, true, 
"", "");
+        index2Column1.setDefineExpr(slotRef1);
+        index2Columns.add(index2Column1);
+        Column index2Column2 = new Column("c2", Type.INT, false, 
AggregateType.SUM, true, "", "");
+        index2Column2.setDefineExpr(slotRef2);
+        index2Columns.add(index2Column2);
+        candidateIndexIdToSchema.put(new Long(2), indexMeta2);
+        List<Column> index3Columns = Lists.newArrayList();
+        Column index3Column1 = new Column("c2", Type.INT, true, null, true, 
"", "");
+        index3Column1.setDefineExpr(slotRef2);
+        index3Columns.add(index3Column1);
+        Column index3Column2 = new Column("c1", Type.INT, false, 
AggregateType.SUM, true, "", "");
+        index3Column1.setDefineExpr(slotRef1);
+        index3Columns.add(index3Column2);
+        candidateIndexIdToSchema.put(new Long(3), indexMeta3);
+        List<Expr> groupingList = Lists.newArrayList();
+        groupingList.add(slotRef1);
+        List<Expr> aggList = Lists.newArrayList();
+        new Expectations() {
+            {
+                selectStmt.getAggInfo().getGroupingExprs();
+                result = groupingList;
+                selectStmt.getAggInfo().getAggregateExprs();
+                result = aggList;
+                indexMeta1.getSchema();
+                result = index1Columns;
+                indexMeta1.getKeysType();
+                result = KeysType.DUP_KEYS;
+                indexMeta2.getSchema();
+                result = index2Columns;
+                indexMeta3.getSchema();
+                result = index3Columns;
+                slotRef1.toSqlWithoutTbl();
+                result = "c1";
+            }
+        };
+
+        try {
+            MaterializedViewSelector selector = new 
MaterializedViewSelector(selectStmt, analyzer);
+            Deencapsulation.setField(selector, "isSPJQuery", false);
+            Deencapsulation.invoke(selector, "checkGrouping", table, 
tableAColumnNames, candidateIndexIdToSchema);
+        } catch (Exception e) {
+            e.printStackTrace();
+            Assert.fail(e.getMessage());
+        }
+
+        Assert.assertEquals(2, candidateIndexIdToSchema.size());
+        Assert.assertTrue(candidateIndexIdToSchema.keySet().contains(new 
Long(1)));
+        Assert.assertTrue(candidateIndexIdToSchema.keySet().contains(new 
Long(2)));
+    }
+
     @Disabled
     public void testCheckAggregationFunction(@Injectable SelectStmt 
selectStmt, @Injectable Analyzer analyzer,
             @Injectable OlapTable table,
@@ -213,6 +344,52 @@ public class MaterializedViewSelectorTest {
         Assert.assertTrue(candidateIndexIdToSchema.keySet().contains(new 
Long(3)));
     }
 
+    @Disabled
+    public void testCheckOutputColumns(@Injectable SelectStmt selectStmt, 
@Injectable Analyzer analyzer,
+            @Injectable MaterializedIndexMeta indexMeta1,
+            @Injectable MaterializedIndexMeta indexMeta2,
+            @Injectable MaterializedIndexMeta indexMeta3) {
+        Map<Long, MaterializedIndexMeta> candidateIndexIdToSchema = 
Maps.newHashMap();
+        List<Column> index1Columns = Lists.newArrayList();
+        Column index1Column1 = new Column("c2", Type.INT, true, null, true, 
"", "");
+        index1Columns.add(index1Column1);
+        candidateIndexIdToSchema.put(new Long(1), indexMeta1);
+        List<Column> index2Columns = Lists.newArrayList();
+        Column index2Column1 = new Column("c1", Type.INT, true, null, true, 
"", "");
+        index2Columns.add(index2Column1);
+        Column index2Column2 = new Column("c2", Type.INT, false, 
AggregateType.NONE, true, "", "");
+        index2Columns.add(index2Column2);
+        candidateIndexIdToSchema.put(new Long(2), indexMeta2);
+        List<Column> index3Columns = Lists.newArrayList();
+        Column index3Column1 = new Column("C2", Type.INT, true, null, true, 
"", "");
+        index3Columns.add(index3Column1);
+        Column index3Column2 = new Column("c1", Type.INT, false, 
AggregateType.SUM, true, "", "");
+        index3Columns.add(index3Column2);
+        candidateIndexIdToSchema.put(new Long(3), indexMeta3);
+        new Expectations() {
+            {
+                selectStmt.getAggInfo();
+                result = null;
+                indexMeta1.getSchema();
+                result = index1Columns;
+                indexMeta2.getSchema();
+                result = index2Columns;
+                indexMeta3.getSchema();
+                result = index3Columns;
+            }
+        };
+
+        MaterializedViewSelector selector = new 
MaterializedViewSelector(selectStmt, analyzer);
+        Set<String> columnNamesInQueryOutput = Sets.newHashSet();
+        columnNamesInQueryOutput.add("c1");
+        columnNamesInQueryOutput.add("c2");
+        Deencapsulation.invoke(selector, "checkOutputColumns", 
columnNamesInQueryOutput,
+                               candidateIndexIdToSchema);
+        Assert.assertEquals(2, candidateIndexIdToSchema.size());
+        Assert.assertTrue(candidateIndexIdToSchema.keySet().contains(new 
Long(2)));
+        Assert.assertTrue(candidateIndexIdToSchema.keySet().contains(new 
Long(3)));
+    }
+
     @Test
     public void testCompensateIndex(@Injectable SelectStmt selectStmt, 
@Injectable Analyzer analyzer,
             @Injectable OlapTable table) {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to