[Bug] Fix the problem that the result of query from the view is incorrect (#5860) (#5897)

Fix an issue where the priority of CompoundPredicates in created view does not match the expectation.
This commit is contained in:
luozenglin
2021-05-27 22:04:33 +08:00
committed by GitHub
parent 0f4a39f82d
commit d958bbedc9
5 changed files with 45 additions and 41 deletions

View File

@ -75,8 +75,7 @@ public class CompoundPredicate extends Predicate {
Preconditions.checkState(op == Operator.NOT);
return "NOT " + getChild(0).toSql();
} else {
return "(" + getChild(0).toSql() + ")" + " " + op.toString() + " " + "(" + getChild(
1).toSql() + ")";
return getChild(0).toSql() + " " + op.toString() + " " + getChild(1).toSql();
}
}

View File

@ -687,9 +687,13 @@ public class SelectStmt extends QueryStmt {
} else {
// rebuild CompoundPredicate if found duplicate predicate will build (predicate) and (.. or ..) predicate in
// step 1: will build (.. or ..)
result = CollectionUtils.isNotEmpty(cloneExprs) ? new CompoundPredicate(CompoundPredicate.Operator.AND,
temp.get(0), makeCompound(temp.subList(1, temp.size()), CompoundPredicate.Operator.OR))
: makeCompound(temp, CompoundPredicate.Operator.OR);
if (CollectionUtils.isNotEmpty(cloneExprs)) {
result = new CompoundPredicate(CompoundPredicate.Operator.AND, temp.get(0),
makeCompound(temp.subList(1, temp.size()), CompoundPredicate.Operator.OR));
result.setPrintSqlInParens(true);
} else {
result = makeCompound(temp, CompoundPredicate.Operator.OR);
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("equal ors: " + result.toSql());
@ -711,6 +715,7 @@ public class SelectStmt extends QueryStmt {
for (int i = 2; i < exprs.size(); ++i) {
result = new CompoundPredicate(op, result.clone(), exprs.get(i));
}
result.setPrintSqlInParens(true);
return result;
}

View File

@ -53,6 +53,7 @@ public class SelectStmtTest {
@BeforeClass
public static void setUp() throws Exception {
Config.enable_batch_delete_by_default = true;
Config.enable_http_server_v2 = false;
UtFrameUtils.createMinDorisCluster(runningDir);
String createTblStmtStr = "create table db1.tbl1(k1 varchar(32), k2 varchar(32), k3 varchar(32), k4 int) "
+ "AGGREGATE KEY(k1, k2,k3,k4) distributed by hash(k1) buckets 3 properties('replication_num' = '1');";
@ -186,7 +187,7 @@ public class SelectStmtTest {
"k1 > (select min(k1) from db1.tbl1) then \"empty\" else \"p_test\" end a from db1.tbl1";
SelectStmt stmt4 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql4, ctx);
stmt4.rewriteExprs(new Analyzer(ctx.getCatalog(), ctx).getExprRewriter());
Assert.assertTrue(stmt4.toSql().contains(" (`k1` < `$a$1`.`$c$1`) AND (`k1` > `$a$2`.`$c$2`) "));
Assert.assertTrue(stmt4.toSql().contains("`k1` < `$a$1`.`$c$1` AND `k1` > `$a$2`.`$c$2`"));
String sql5 = "select case when k1 < (select max(k1) from db1.tbl1) is null " +
"then \"empty\" else \"p_test\" end a from db1.tbl1";
@ -264,16 +265,16 @@ public class SelectStmtTest {
" );";
SelectStmt stmt = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql, ctx);
stmt.rewriteExprs(new Analyzer(ctx.getCatalog(), ctx).getExprRewriter());
String rewritedFragment1 = "(((`t1`.`k2` = `t4`.`k2`) AND (`t3`.`k3` = `t1`.`k3`)) AND ((((((`t3`.`k1` = 'D')" +
" AND (`t4`.`k3` = '2 yr Degree')) AND ((`t1`.`k4` >= 100.00) AND (`t1`.`k4` <= 150.00))) AND" +
" (`t4`.`k4` = 3)) OR ((((`t3`.`k1` = 'S') AND (`t4`.`k3` = 'Secondary')) AND ((`t1`.`k4` >= 50.00)" +
" AND (`t1`.`k4` <= 100.00))) AND (`t4`.`k4` = 1))) OR ((((`t3`.`k1` = 'W') AND " +
"(`t4`.`k3` = 'Advanced Degree')) AND ((`t1`.`k4` >= 150.00) AND (`t1`.`k4` <= 200.00)))" +
" AND (`t4`.`k4` = 1))))";
String rewritedFragment2 = "(((`t1`.`k1` = `t5`.`k1`) AND (`t5`.`k2` = 'United States')) AND" +
" ((((`t5`.`k3` IN ('CO', 'IL', 'MN')) AND ((`t1`.`k4` >= 100) AND (`t1`.`k4` <= 200)))" +
" OR ((`t5`.`k3` IN ('OH', 'MT', 'NM')) AND ((`t1`.`k4` >= 150) AND (`t1`.`k4` <= 300))))" +
" OR ((`t5`.`k3` IN ('TX', 'MO', 'MI')) AND ((`t1`.`k4` >= 50) AND (`t1`.`k4` <= 250)))))";
String rewritedFragment1 = "((`t1`.`k2` = `t4`.`k2` AND `t3`.`k3` = `t1`.`k3`) " +
"AND ((`t3`.`k1` = 'D' AND `t4`.`k3` = '2 yr Degree' " +
"AND `t1`.`k4` >= 100.00 AND `t1`.`k4` <= 150.00 AND `t4`.`k4` = 3) " +
"OR (`t3`.`k1` = 'S' AND `t4`.`k3` = 'Secondary' AND `t1`.`k4` >= 50.00 " +
"AND `t1`.`k4` <= 100.00 AND `t4`.`k4` = 1) OR (`t3`.`k1` = 'W' AND `t4`.`k3` = 'Advanced Degree' " +
"AND `t1`.`k4` >= 150.00 AND `t1`.`k4` <= 200.00 AND `t4`.`k4` = 1)))";
String rewritedFragment2 = "((`t1`.`k1` = `t5`.`k1` AND `t5`.`k2` = 'United States') " +
"AND ((`t5`.`k3` IN ('CO', 'IL', 'MN') AND `t1`.`k4` >= 100 AND `t1`.`k4` <= 200) " +
"OR (`t5`.`k3` IN ('OH', 'MT', 'NM') AND `t1`.`k4` >= 150 AND `t1`.`k4` <= 300) OR (`t5`.`k3` IN " +
"('TX', 'MO', 'MI') AND `t1`.`k4` >= 50 AND `t1`.`k4` <= 250)))";
Assert.assertTrue(stmt.toSql().contains(rewritedFragment1));
Assert.assertTrue(stmt.toSql().contains(rewritedFragment2));
@ -305,12 +306,11 @@ public class SelectStmtTest {
")";
SelectStmt stmt2 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql2, ctx);
stmt2.rewriteExprs(new Analyzer(ctx.getCatalog(), ctx).getExprRewriter());
String fragment3 = "(((((`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)))) OR ((((`t1`.`k1` = `t2`.`k1`) AND " +
"(`t2`.`k2` = 'United States')) AND (`t2`.`k3` IN ('TX', 'MO', 'MI'))) AND ((`t1`.`k4` >= 50)" +
" AND (`t1`.`k4` <= 250)))";
String fragment3 = "((`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) " +
"OR (`t1`.`k1` = `t2`.`k1` AND `t2`.`k2` = 'United States' AND `t2`.`k3` IN ('TX', 'MO', 'MI') " +
"AND `t1`.`k4` >= 50 AND `t1`.`k4` <= 250))";
Assert.assertTrue(stmt2.toSql().contains(fragment3));
String sql3 = "select\n" +
@ -322,8 +322,8 @@ public class SelectStmtTest {
" t1.k1 = t2.k3 or t1.k1 = t2.k3 or t1.k1 = t2.k3";
SelectStmt stmt3 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql3, ctx);
stmt3.rewriteExprs(new Analyzer(ctx.getCatalog(), ctx).getExprRewriter());
Assert.assertFalse(stmt3.toSql().contains("((`t1`.`k1` = `t2`.`k3`) OR (`t1`.`k1` = `t2`.`k3`)) OR" +
" (`t1`.`k1` = `t2`.`k3`)"));
Assert.assertFalse(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" +
@ -334,7 +334,7 @@ public class SelectStmtTest {
" 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.getCatalog(), 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" +
@ -345,7 +345,7 @@ public class SelectStmtTest {
" t2.k1 is not null or t1.k1 is not null or t1.k1 is not null";
SelectStmt stmt5 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql5, ctx);
stmt5.rewriteExprs(new Analyzer(ctx.getCatalog(), ctx).getExprRewriter());
Assert.assertTrue(stmt5.toSql().contains("(`t2`.`k1` IS NOT NULL) OR (`t1`.`k1` IS NOT NULL)"));
Assert.assertTrue(stmt5.toSql().contains("`t2`.`k1` IS NOT NULL OR `t1`.`k1` IS NOT NULL"));
Assert.assertEquals(2, stmt5.toSql().split(" OR ").length);
String sql6 = "select\n" +
@ -357,7 +357,7 @@ public class SelectStmtTest {
" t2.k1 is not null or t1.k1 is not null and t1.k1 is not null";
SelectStmt stmt6 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql6, ctx);
stmt6.rewriteExprs(new Analyzer(ctx.getCatalog(), ctx).getExprRewriter());
Assert.assertTrue(stmt6.toSql().contains("(`t2`.`k1` IS NOT NULL) OR (`t1`.`k1` IS NOT NULL)"));
Assert.assertTrue(stmt6.toSql().contains("`t2`.`k1` IS NOT NULL OR `t1`.`k1` IS NOT NULL"));
Assert.assertEquals(2, stmt6.toSql().split(" OR ").length);
String sql7 = "select\n" +
@ -369,8 +369,8 @@ public class SelectStmtTest {
" t2.k1 is not null or t1.k1 is not null and t1.k2 is not null";
SelectStmt stmt7 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql7, ctx);
stmt7.rewriteExprs(new Analyzer(ctx.getCatalog(), ctx).getExprRewriter());
Assert.assertTrue(stmt7.toSql().contains("(`t2`.`k1` IS NOT NULL) OR ((`t1`.`k1` IS NOT NULL) " +
"AND (`t1`.`k2` IS NOT NULL))"));
Assert.assertTrue(stmt7.toSql().contains("`t2`.`k1` IS NOT NULL OR (`t1`.`k1` IS NOT NULL " +
"AND `t1`.`k2` IS NOT NULL)"));
String sql8 = "select\n" +
" avg(t1.k4)\n" +
@ -381,14 +381,14 @@ public class SelectStmtTest {
" t2.k1 is not null and t1.k1 is not null and t1.k1 is not null";
SelectStmt stmt8 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql8, ctx);
stmt8.rewriteExprs(new Analyzer(ctx.getCatalog(), ctx).getExprRewriter());
Assert.assertTrue(stmt8.toSql().contains("((`t2`.`k1` IS NOT NULL) AND (`t1`.`k1` IS NOT NULL))" +
" AND (`t1`.`k1` IS NOT NULL)"));
Assert.assertTrue(stmt8.toSql().contains("`t2`.`k1` IS NOT NULL AND `t1`.`k1` IS NOT NULL" +
" AND `t1`.`k1` IS NOT NULL"));
String sql9 = "select * from db1.tbl1 where (k1='shutdown' and k4<1) or (k1='switchOff' and k4>=1)";
SelectStmt stmt9 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql9, ctx);
stmt9.rewriteExprs(new Analyzer(ctx.getCatalog(), ctx).getExprRewriter());
Assert.assertTrue(stmt9.toSql().contains("((`k1` = 'shutdown') AND (`k4` < 1))" +
" OR ((`k1` = 'switchOff') AND (`k4` >= 1))"));
Assert.assertTrue(stmt9.toSql().contains("(`k1` = 'shutdown' AND `k4` < 1)" +
" OR (`k1` = 'switchOff' AND `k4` >= 1)"));
}
@Test

View File

@ -80,7 +80,7 @@ public class SqlModeTest {
if (!(expr instanceof CompoundPredicate)) {
Assert.fail();
}
Assert.assertEquals("(('a') OR ('b')) OR ('c')", expr.toSql());
Assert.assertEquals("'a' OR 'b' OR 'c'", expr.toSql());
}
@Test

View File

@ -539,7 +539,7 @@ public class PartitionCacheTest {
cache.rewriteSelectStmt(newRangeList);
sql = ca.getRewriteStmt().getWhereClause().toSql();
Assert.assertEquals(sql, "(`date` >= 20200114) AND (`date` <= 20200115)");
Assert.assertEquals(sql, "`date` >= 20200114 AND `date` <= 20200115");
} catch (Exception e) {
LOG.warn("ex={}", e);
Assert.fail(e.getMessage());
@ -578,7 +578,7 @@ public class PartitionCacheTest {
hitRange = range.buildDiskPartitionRange(newRangeList);
cache.rewriteSelectStmt(newRangeList);
sql = ca.getRewriteStmt().getWhereClause().toSql();
Assert.assertEquals(sql,"(`eventdate` >= '2020-01-14') AND (`eventdate` <= '2020-01-15')");
Assert.assertEquals(sql,"`eventdate` >= '2020-01-14' AND `eventdate` <= '2020-01-15'");
} catch(Exception e){
LOG.warn("ex={}",e);
Assert.fail(e.getMessage());
@ -703,7 +703,7 @@ public class PartitionCacheTest {
cache.rewriteSelectStmt(newRangeList);
sql = ca.getRewriteStmt().getWhereClause().toSql();
Assert.assertEquals(sql, "(`eventdate` >= '2020-01-13') AND (`eventdate` <= '2020-01-15')");
Assert.assertEquals(sql, "`eventdate` >= '2020-01-13' AND `eventdate` <= '2020-01-15'");
List<PartitionRange.PartitionSingle> updateRangeList = range.buildUpdatePartitionRange();
Assert.assertEquals(updateRangeList.size(), 2);
@ -749,7 +749,7 @@ public class PartitionCacheTest {
cache.rewriteSelectStmt(newRangeList);
sql = ca.getRewriteStmt().getWhereClause().toSql();
LOG.warn("MultiPredicate={}", sql);
Assert.assertEquals(sql,"((`eventdate` > '2020-01-13') AND (`eventdate` < '2020-01-16')) AND (`eventid` = 1)");
Assert.assertEquals(sql,"`eventdate` > '2020-01-13' AND `eventdate` < '2020-01-16' AND `eventid` = 1");
} catch(Exception e){
LOG.warn("multi ex={}",e);
Assert.fail(e.getMessage());
@ -791,8 +791,8 @@ public class PartitionCacheTest {
cache.rewriteSelectStmt(newRangeList);
sql = ca.getRewriteStmt().getWhereClause().toSql();
LOG.warn("Join rewrite={}", sql);
Assert.assertEquals(sql,"((`appevent`.`eventdate` >= '2020-01-14')" +
" AND (`appevent`.`eventdate` <= '2020-01-15')) AND (`eventid` = 1)");
Assert.assertEquals(sql,"`appevent`.`eventdate` >= '2020-01-14'" +
" AND `appevent`.`eventdate` <= '2020-01-15' AND `eventid` = 1");
} catch(Exception e){
LOG.warn("Join ex={}",e);
Assert.fail(e.getMessage());
@ -837,7 +837,7 @@ public class PartitionCacheTest {
LOG.warn("Sub rewrite={}", sql);
Assert.assertEquals(sql,"SELECT <slot 7> `eventdate` AS `eventdate`, <slot 8> sum(`pv`) AS `sum(``pv``)` FROM (" +
"SELECT <slot 3> `eventdate` AS `eventdate`, <slot 4> count(`userid`) AS `pv` FROM `testCluster:testDb`.`appevent` WHERE " +
"((`eventdate` > '2020-01-13') AND (`eventdate` < '2020-01-16')) AND (`eventid` = 1) GROUP BY `eventdate`) tbl GROUP BY `eventdate`");
"`eventdate` > '2020-01-13' AND `eventdate` < '2020-01-16' AND `eventid` = 1 GROUP BY `eventdate`) tbl GROUP BY `eventdate`");
} catch(Exception e){
LOG.warn("sub ex={}",e);
Assert.fail(e.getMessage());