Skip to content

Commit

Permalink
[Feature](materialized-view) support some case unmached to materializ…
Browse files Browse the repository at this point in the history
…ed-view (apache#30036)

same column appears in key and value like select id,count(id) group by id;
complex expr in sum select sum(if(xxx));
  • Loading branch information
BiteTheDDDDt authored Jan 18, 2024
1 parent 4f74b2a commit 41672f2
Show file tree
Hide file tree
Showing 33 changed files with 187 additions and 153 deletions.
5 changes: 5 additions & 0 deletions fe/fe-core/src/main/cup/sql_parser.cup
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,11 @@ import_column_descs ::=
columns.add(column);
RESULT = columns;
:}
| import_column_descs:columns COMMA LPAREN import_column_desc:column RPAREN
{:
columns.add(column);
RESULT = columns;
:}
;

import_column_desc ::=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ public boolean isUnequivalence() {
// for restoring
public BinaryPredicate() {
super();
printSqlInParens = true;
}

public BinaryPredicate(Operator op, Expr e1, Expr e2) {
Expand All @@ -169,6 +170,7 @@ public BinaryPredicate(Operator op, Expr e1, Expr e2) {
children.add(e1);
Preconditions.checkNotNull(e2);
children.add(e2);
printSqlInParens = true;
}

public BinaryPredicate(Operator op, Expr e1, Expr e2, Type retType, NullableMode nullableMode) {
Expand All @@ -181,13 +183,15 @@ public BinaryPredicate(Operator op, Expr e1, Expr e2, Type retType, NullableMode
children.add(e2);
fn = new Function(new FunctionName(op.name), Lists.newArrayList(e1.getType(), e2.getType()), retType,
false, true, nullableMode);
printSqlInParens = true;
}

protected BinaryPredicate(BinaryPredicate other) {
super(other);
op = other.op;
slotIsleft = other.slotIsleft;
isInferred = other.isInferred;
printSqlInParens = true;
}

public boolean isInferred() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,7 @@ private AggRewriteResult rewriteAgg(MaterializedIndex index,
}
if (isInputSlotsContainsNone(
predicates.stream().filter(e -> !indexConjuncts.contains(e.toSql())).collect(Collectors.toList()),
slotsToReplace) && isInputSlotsContainsNone(groupingExprs, slotsToReplace)) {
slotsToReplace)) {
ImmutableSet<Slot> newRequiredSlots = requiredScanOutput.stream()
.map(slot -> (Slot) ExpressionUtils.replace(slot, slotMap)).collect(ImmutableSet.toImmutableSet());
return new AggRewriteResult(index, true, newRequiredSlots, exprRewriteMap);
Expand Down Expand Up @@ -1522,8 +1522,7 @@ public Expression visitSum(Sum sum, RewriteContext context) {
if (result != sum) {
return result;
}
Optional<Slot> slotOpt = ExpressionUtils.extractSlotOrCastOnSlot(sum.child(0));
if (!sum.isDistinct() && slotOpt.isPresent()) {
if (!sum.isDistinct()) {
Expression expr = castIfNeed(sum.child(), BigIntType.INSTANCE);
String sumColumn = normalizeName(CreateMaterializedViewStmt.mvColumnBuilder(AggregateType.SUM,
CreateMaterializedViewStmt.mvColumnBuilder(expr.toSql())));
Expand All @@ -1532,7 +1531,9 @@ 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.slotMap.put(slotOpt.get(), sumSlot);
for (Slot slot : sum.child().getInputSlots()) {
context.exprRewriteMap.slotMap.put(slot, sumSlot);
}
context.exprRewriteMap.projectExprMap.put(sum.child(), sumSlot);
Sum newSum = new Sum(sumSlot);
context.exprRewriteMap.aggFuncMap.put(sum, newSum);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,23 +63,23 @@ public void testNormal() throws UserException {
labelStringLiteral);
CancelExportStmt stmt = new CancelExportStmt(null, labelBinaryPredicate);
stmt.analyze(analyzer);
Assertions.assertEquals("CANCEL EXPORT FROM testDb WHERE `label` = 'doris_test_label'",
Assertions.assertEquals("CANCEL EXPORT FROM testDb WHERE (`label` = 'doris_test_label')",
stmt.toString());

SlotRef labelSlotRefUpper = new SlotRef(null, "LABEL");
BinaryPredicate labelBinaryPredicateUpper = new BinaryPredicate(BinaryPredicate.Operator.EQ, labelSlotRefUpper,
labelStringLiteral);
CancelExportStmt stmtUpper = new CancelExportStmt(null, labelBinaryPredicateUpper);
stmtUpper.analyze(analyzer);
Assertions.assertEquals("CANCEL EXPORT FROM testDb WHERE `LABEL` = 'doris_test_label'",
Assertions.assertEquals("CANCEL EXPORT FROM testDb WHERE (`LABEL` = 'doris_test_label')",
stmtUpper.toString());

StringLiteral stateStringLiteral = new StringLiteral("PENDING");
BinaryPredicate stateBinaryPredicate = new BinaryPredicate(BinaryPredicate.Operator.EQ, stateSlotRef,
stateStringLiteral);
stmt = new CancelExportStmt(null, stateBinaryPredicate);
stmt.analyze(analyzer);
Assertions.assertEquals("CANCEL EXPORT FROM testDb WHERE `state` = 'PENDING'", stmt.toString());
Assertions.assertEquals("CANCEL EXPORT FROM testDb WHERE (`state` = 'PENDING')", stmt.toString());

LikePredicate labelLikePredicate = new LikePredicate(LikePredicate.Operator.LIKE, labelSlotRef,
labelStringLiteral);
Expand All @@ -93,15 +93,15 @@ public void testNormal() throws UserException {
stmt = new CancelExportStmt(null, compoundAndPredicate);
stmt.analyze(analyzer);
Assertions.assertEquals(
"CANCEL EXPORT FROM testDb WHERE `label` = 'doris_test_label' AND `state` = 'PENDING'",
"CANCEL EXPORT FROM testDb WHERE (`label` = 'doris_test_label') AND (`state` = 'PENDING')",
stmt.toString());

CompoundPredicate compoundOrPredicate = new CompoundPredicate(Operator.OR, labelBinaryPredicate,
stateBinaryPredicate);
stmt = new CancelExportStmt(null, compoundOrPredicate);
stmt.analyze(analyzer);
Assertions.assertEquals(
"CANCEL EXPORT FROM testDb WHERE `label` = 'doris_test_label' OR `state` = 'PENDING'",
"CANCEL EXPORT FROM testDb WHERE (`label` = 'doris_test_label') OR (`state` = 'PENDING')",
stmt.toString());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,23 @@ public void testNormal() throws UserException {
labelStringLiteral);
CancelLoadStmt stmt = new CancelLoadStmt(null, labelBinaryPredicate);
stmt.analyze(analyzer);
Assertions.assertEquals("CANCEL LOAD FROM testDb WHERE `label` = 'doris_test_label'",
Assertions.assertEquals("CANCEL LOAD FROM testDb WHERE (`label` = 'doris_test_label')",
stmt.toString());

SlotRef labelSlotRefUpper = new SlotRef(null, "LABEL");
BinaryPredicate labelBinaryPredicateUpper = new BinaryPredicate(BinaryPredicate.Operator.EQ, labelSlotRefUpper,
labelStringLiteral);
CancelLoadStmt stmtUpper = new CancelLoadStmt(null, labelBinaryPredicateUpper);
stmtUpper.analyze(analyzer);
Assertions.assertEquals("CANCEL LOAD FROM testDb WHERE `LABEL` = 'doris_test_label'",
Assertions.assertEquals("CANCEL LOAD FROM testDb WHERE (`LABEL` = 'doris_test_label')",
stmtUpper.toString());

StringLiteral stateStringLiteral = new StringLiteral("LOADING");
BinaryPredicate stateBinaryPredicate = new BinaryPredicate(BinaryPredicate.Operator.EQ, stateSlotRef,
stateStringLiteral);
stmt = new CancelLoadStmt(null, stateBinaryPredicate);
stmt.analyze(analyzer);
Assertions.assertEquals("CANCEL LOAD FROM testDb WHERE `state` = 'LOADING'", stmt.toString());
Assertions.assertEquals("CANCEL LOAD FROM testDb WHERE (`state` = 'LOADING')", stmt.toString());

LikePredicate labelLikePredicate = new LikePredicate(LikePredicate.Operator.LIKE, labelSlotRef,
labelStringLiteral);
Expand All @@ -94,15 +94,15 @@ public void testNormal() throws UserException {
stmt = new CancelLoadStmt(null, compoundAndPredicate);
stmt.analyze(analyzer);
Assertions.assertEquals(
"CANCEL LOAD FROM testDb WHERE `label` = 'doris_test_label' AND `state` = 'LOADING'",
"CANCEL LOAD FROM testDb WHERE (`label` = 'doris_test_label') AND (`state` = 'LOADING')",
stmt.toString());

CompoundPredicate compoundOrPredicate = new CompoundPredicate(Operator.OR, labelBinaryPredicate,
stateBinaryPredicate);
stmt = new CancelLoadStmt(null, compoundOrPredicate);
stmt.analyze(analyzer);
Assertions.assertEquals(
"CANCEL LOAD FROM testDb WHERE `label` = 'doris_test_label' OR `state` = 'LOADING'",
"CANCEL LOAD FROM testDb WHERE (`label` = 'doris_test_label') OR (`state` = 'LOADING')",
stmt.toString());

// test match
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,9 @@ public void testNormal() throws AnalysisException {
desc = new DataDescription("testTable", null, Lists.newArrayList("abc.txt"),
Lists.newArrayList("col1", "col2"), new Separator(","), "csv", null, false, null, null, whereExpr, LoadTask.MergeType.MERGE, whereExpr, null, null);
desc.analyze("testDb");
Assert.assertEquals("MERGE DATA INFILE ('abc.txt') INTO TABLE testTable COLUMNS TERMINATED BY ',' FORMAT AS 'csv' (col1, col2) WHERE 1 = 1 DELETE ON 1 = 1", desc.toString());
Assert.assertEquals("1 = 1", desc.getWhereExpr().toSql());
Assert.assertEquals("1 = 1", desc.getDeleteCondition().toSql());
Assert.assertEquals("MERGE DATA INFILE ('abc.txt') INTO TABLE testTable COLUMNS TERMINATED BY ',' FORMAT AS 'csv' (col1, col2) WHERE (1 = 1) DELETE ON (1 = 1)", desc.toString());
Assert.assertEquals("(1 = 1)", desc.getWhereExpr().toSql());
Assert.assertEquals("(1 = 1)", desc.getDeleteCondition().toSql());
Assert.assertEquals(",", desc.getColumnSeparator());

desc = new DataDescription("testTable", null, Lists.newArrayList("abc.txt", "bcd.txt"),
Expand Down Expand Up @@ -168,7 +168,7 @@ public void testNormal() throws AnalysisException {
.newArrayList((Expr) predicate));
desc.analyze("testDb");
String sql = "APPEND DATA INFILE ('abc.txt') INTO TABLE testTable PARTITIONS (p1, p2) (k2, k3)"
+ " SET (`k1` = alignment_timestamp('day', `k2`))";
+ " SET ((`k1` = alignment_timestamp('day', `k2`)))";
Assert.assertEquals(sql, desc.toString());

// replace_value func
Expand All @@ -183,7 +183,7 @@ public void testNormal() throws AnalysisException {
false, Lists.newArrayList((Expr) predicate));
desc.analyze("testDb");
sql = "APPEND DATA INFILE ('abc.txt') INTO TABLE testTable PARTITIONS (p1, p2) (k2, k3)"
+ " SET (`k1` = replace_value('-', '10'))";
+ " SET ((`k1` = replace_value('-', '10')))";
Assert.assertEquals(sql, desc.toString());

// replace_value null
Expand All @@ -198,7 +198,7 @@ public void testNormal() throws AnalysisException {
.newArrayList((Expr) predicate));
desc.analyze("testDb");
sql = "APPEND DATA INFILE ('abc.txt') INTO TABLE testTable PARTITIONS (p1, p2) (k2, k3)"
+ " SET (`k1` = replace_value('', NULL))";
+ " SET ((`k1` = replace_value('', NULL)))";
Assert.assertEquals(sql, desc.toString());

// data from table and set bitmap_dict
Expand All @@ -210,7 +210,7 @@ public void testNormal() throws AnalysisException {
"testHiveTable", false, Lists.newArrayList(predicate),
null, LoadTask.MergeType.APPEND, null, null);
desc.analyze("testDb");
sql = "APPEND DATA FROM TABLE testHiveTable INTO TABLE testTable PARTITIONS (p1, p2) SET (`k1` = bitmap_dict(`k2`))";
sql = "APPEND DATA FROM TABLE testHiveTable INTO TABLE testTable PARTITIONS (p1, p2) SET ((`k1` = bitmap_dict(`k2`)))";
Assert.assertEquals(sql, desc.toSql());

Map<String, String> properties = Maps.newHashMap();
Expand Down Expand Up @@ -409,7 +409,7 @@ public void testMysqlLoadData() throws AnalysisException {
+ "COLUMNS TERMINATED BY '010203' "
+ "LINES TERMINATED BY '040506' "
+ "(k1, k2, v1) "
+ "SET (`k1` = bitmap_dict('day', `k2`))";
+ "SET ((`k1` = bitmap_dict('day', `k2`)))";
Assert.assertEquals(sql, desc.toSql());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ public void getMethodTest() {
Assert.assertEquals("testDb", deleteStmt.getDbName());
Assert.assertEquals("testTbl", deleteStmt.getTableName());
Assert.assertEquals(Lists.newArrayList("partition"), deleteStmt.getPartitionNames());
Assert.assertEquals("DELETE FROM `testDb`.`testTbl` PARTITION (partition) WHERE `k1` = 'abc'",
Assert.assertEquals("DELETE FROM `testDb`.`testTbl` PARTITION (partition) WHERE (`k1` = 'abc')",
deleteStmt.toSql());

deleteStmt = new DeleteStmt(new TableName(internalCtl, "testDb", "testTbl"), null, wherePredicate);
Assert.assertEquals("DELETE FROM `testDb`.`testTbl` WHERE `k1` = 'abc'",
Assert.assertEquals("DELETE FROM `testDb`.`testTbl` WHERE (`k1` = 'abc')",
deleteStmt.toSql());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,9 +301,9 @@ public void testDeduplicateOrs() throws Exception {
String commonExpr2 = "`t3`.`k3` = `t1`.`k3`";
String commonExpr3 = "`t1`.`k1` = `t5`.`k1`";
String commonExpr4 = "t5`.`k2` = 'United States'";
String betweenExpanded1 = "CAST(CAST(`t1`.`k4` AS DECIMALV3(12, 2)) AS INT) >= 100 AND CAST(CAST(`t1`.`k4` AS DECIMALV3(12, 2)) AS INT) <= 150";
String betweenExpanded2 = "CAST(CAST(`t1`.`k4` AS DECIMALV3(12, 2)) AS INT) >= 50 AND CAST(CAST(`t1`.`k4` AS DECIMALV3(12, 2)) AS INT) <= 100";
String betweenExpanded3 = "`t1`.`k4` >= 50 AND `t1`.`k4` <= 250";
String betweenExpanded1 = "(CAST(CAST(`t1`.`k4` AS DECIMALV3(12, 2)) AS INT) >= 100) AND (CAST(CAST(`t1`.`k4` AS DECIMALV3(12, 2)) AS INT) <= 150)";
String betweenExpanded2 = "(CAST(CAST(`t1`.`k4` AS DECIMALV3(12, 2)) AS INT) >= 50) AND (CAST(CAST(`t1`.`k4` AS DECIMALV3(12, 2)) AS INT) <= 100)";
String betweenExpanded3 = "(`t1`.`k4` >= 50) AND (`t1`.`k4` <= 250)";

String rewrittenSql = stmt.toSql();
Assert.assertTrue(rewrittenSql.contains(commonExpr1));
Expand Down Expand Up @@ -347,17 +347,17 @@ public void testDeduplicateOrs() throws Exception {
SelectStmt stmt2 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql2, ctx);
stmt2.rewriteExprs(new Analyzer(ctx.getEnv(), ctx).getExprRewriter());
String fragment3 =
"(((`t1`.`k4` >= 50 AND `t1`.`k4` <= 300) AND `t2`.`k2` IN ('United States', 'United States1') "
"((((`t1`.`k4` >= 50) AND (`t1`.`k4` <= 300)) AND `t2`.`k2` IN ('United States', 'United States1') "
+ "AND `t2`.`k3` IN ('CO', 'IL', 'MN', 'OH', 'MT', 'NM', 'TX', 'MO', 'MI')) "
+ "AND `t1`.`k1` = `t2`.`k3` AND `t2`.`k2` = 'United States' "
+ "AND `t2`.`k3` IN ('CO', 'IL', 'MN') AND `t1`.`k4` >= 100 AND `t1`.`k4` <= 200 "
+ "AND (`t1`.`k1` = `t2`.`k3`) AND (`t2`.`k2` = 'United States') "
+ "AND `t2`.`k3` IN ('CO', 'IL', 'MN') AND (`t1`.`k4` >= 100) AND (`t1`.`k4` <= 200) "
+ "OR "
+ "`t1`.`k1` = `t2`.`k1` AND `t2`.`k2` = 'United States1' "
+ "AND `t2`.`k3` IN ('OH', 'MT', 'NM') AND `t1`.`k4` >= 150 AND `t1`.`k4` <= 300 "
+ "(`t1`.`k1` = `t2`.`k1`) AND (`t2`.`k2` = 'United States1') "
+ "AND `t2`.`k3` IN ('OH', 'MT', 'NM') AND (`t1`.`k4` >= 150) AND (`t1`.`k4` <= 300) "
+ "OR "
+ "`t1`.`k1` = `t2`.`k1` AND `t2`.`k2` = 'United States' "
+ "(`t1`.`k1` = `t2`.`k1`) AND (`t2`.`k2` = 'United States') "
+ "AND `t2`.`k3` IN ('TX', 'MO', 'MI') "
+ "AND `t1`.`k4` >= 50 AND `t1`.`k4` <= 250)";
+ "AND (`t1`.`k4` >= 50) AND (`t1`.`k4` <= 250))";
Assert.assertTrue(stmt2.toSql().contains(fragment3));

String sql3 = "select\n"
Expand All @@ -370,7 +370,7 @@ public void testDeduplicateOrs() throws Exception {
SelectStmt stmt3 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql3, ctx);
stmt3.rewriteExprs(new Analyzer(ctx.getEnv(), ctx).getExprRewriter());
Assert.assertFalse(
stmt3.toSql().contains("`t1`.`k1` = `t2`.`k3` OR `t1`.`k1` = `t2`.`k3` OR" + " `t1`.`k1` = `t2`.`k3`"));
stmt3.toSql().contains("(`t1`.`k1` = `t2`.`k3`) OR (`t1`.`k1` = `t2`.`k3`) OR" + " (`t1`.`k1` = `t2`.`k3`)"));

String sql4 = "select\n"
+ " avg(t1.k4)\n"
Expand All @@ -381,7 +381,7 @@ public void testDeduplicateOrs() throws Exception {
+ " t1.k1 = t2.k2 or t1.k1 = t2.k3 or t1.k1 = t2.k3";
SelectStmt stmt4 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql4, ctx);
stmt4.rewriteExprs(new Analyzer(ctx.getEnv(), ctx).getExprRewriter());
Assert.assertTrue(stmt4.toSql().contains("`t1`.`k1` = `t2`.`k2` OR `t1`.`k1` = `t2`.`k3`"));
Assert.assertTrue(stmt4.toSql().contains("(`t1`.`k1` = `t2`.`k2`) OR (`t1`.`k1` = `t2`.`k3`)"));

String sql5 = "select\n"
+ " avg(t1.k4)\n"
Expand Down Expand Up @@ -435,7 +435,7 @@ public void testDeduplicateOrs() throws Exception {
SelectStmt stmt9 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql9, ctx);
stmt9.rewriteExprs(new Analyzer(ctx.getEnv(), ctx).getExprRewriter());
Assert.assertTrue(
stmt9.toSql().contains("`k1` = 'shutdown' AND `k4` < 1 OR `k1` = 'switchOff' AND `k4` >= 1"));
stmt9.toSql().contains("(`k1` = 'shutdown') AND (`k4` < 1) OR (`k1` = 'switchOff') AND (`k4` >= 1)"));
}

@Test
Expand Down Expand Up @@ -528,21 +528,21 @@ public void testDeleteSign() throws Exception {
String sql1 = "SELECT /*+ SET_VAR(enable_nereids_planner=true, ENABLE_FALLBACK_TO_ORIGINAL_PLANNER=false) */ * FROM db1.table1 LEFT ANTI JOIN db1.table2 ON db1.table1.siteid = db1.table2.siteid;";
String explain = dorisAssert.query(sql1).explainQuery();
Assert.assertTrue(explain
.contains("PREDICATES: __DORIS_DELETE_SIGN__ = 0"));
.contains("__DORIS_DELETE_SIGN__ = 0"));
Assert.assertFalse(explain.contains("other predicates:"));
String sql2 = "SELECT /*+ SET_VAR(enable_nereids_planner=false) */ * FROM db1.table1 JOIN db1.table2 ON db1.table1.siteid = db1.table2.siteid;";
explain = dorisAssert.query(sql2).explainQuery();
Assert.assertTrue(explain
.contains("PREDICATES: `db1`.`table1`.`__DORIS_DELETE_SIGN__` = 0"));
.contains("`db1`.`table1`.`__DORIS_DELETE_SIGN__` = 0"));
Assert.assertTrue(explain
.contains("PREDICATES: `db1`.`table2`.`__DORIS_DELETE_SIGN__` = 0"));
.contains("`db1`.`table2`.`__DORIS_DELETE_SIGN__` = 0"));
Assert.assertFalse(explain.contains("other predicates:"));
String sql3 = "SELECT /*+ SET_VAR(enable_nereids_planner=false) */ * FROM db1.table1";
Assert.assertTrue(dorisAssert.query(sql3).explainQuery()
.contains("PREDICATES: `db1`.`table1`.`__DORIS_DELETE_SIGN__` = 0"));
.contains("`db1`.`table1`.`__DORIS_DELETE_SIGN__` = 0"));
String sql4 = " SELECT /*+ SET_VAR(enable_nereids_planner=false) */ * FROM db1.table1 table2";
Assert.assertTrue(dorisAssert.query(sql4).explainQuery()
.contains("PREDICATES: `table2`.`__DORIS_DELETE_SIGN__` = 0"));
.contains("`table2`.`__DORIS_DELETE_SIGN__` = 0"));
new MockUp<Util>() {
@Mock
public boolean showHiddenColumns() {
Expand Down
Loading

0 comments on commit 41672f2

Please sign in to comment.