[Bug][Fold constant] remove reanalyze in get constant expr (#6400)

fix #6399
This commit is contained in:
qiye
2021-08-11 16:38:30 +08:00
committed by GitHub
parent 708b6c529e
commit 3fa3dfbeda
2 changed files with 74 additions and 6 deletions

View File

@ -188,14 +188,10 @@ public class FoldConstantsRule implements ExprRewriteRule {
* @param analyzer
* @throws AnalysisException
*/
private void getConstExpr(Expr expr, Map<String,TExpr> constExprMap, Map<String, Expr> oriConstMap,
// public only for unit test
public void getConstExpr(Expr expr, Map<String,TExpr> constExprMap, Map<String, Expr> oriConstMap,
Analyzer analyzer, Map<String, Expr> sysVarMap, Map<String, Expr> infoFnMap)
throws AnalysisException {
// Analyze constant exprs, if necessary. Note that the 'expr' may become non-constant
// after analysis (e.g., aggregate functions).
if (!expr.isAnalyzed()) {
expr.analyze(analyzer);
}
if (expr.isConstant()) {
// Do not constant fold cast(null as dataType) because we cannot preserve the
// cast-to-types and that can lead to query failures, e.g., CTAS

View File

@ -19,9 +19,12 @@ package org.apache.doris.analysis;
import com.google.common.collect.Lists;
import org.apache.doris.catalog.Type;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.Config;
import org.apache.doris.common.UserException;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.rewrite.FoldConstantsRule;
import org.apache.doris.thrift.TExpr;
import org.apache.doris.utframe.DorisAssert;
import org.apache.doris.utframe.UtFrameUtils;
import org.junit.AfterClass;
@ -55,6 +58,7 @@ public class QueryStmtTest {
" `siteid` int(11) NULL DEFAULT \"10\" COMMENT \"\",\n" +
" `citycode` smallint(6) NULL COMMENT \"\",\n" +
" `username` varchar(32) NULL DEFAULT \"\" COMMENT \"\",\n" +
" `workDateTime` datetime NOT NULL COMMENT \"\",\n" +
" `pv` bigint(20) NULL DEFAULT \"0\" COMMENT \"\"\n" +
") ENGINE=OLAP\n" +
"UNIQUE KEY(`siteid`, `citycode`, `username`)\n" +
@ -75,6 +79,7 @@ public class QueryStmtTest {
@Test
public void testCollectExprs() throws Exception {
ConnectContext ctx = UtFrameUtils.createDefaultCtx();
Analyzer analyzer = new Analyzer(ctx.getCatalog(), ctx);
String sql = "SELECT CASE\n" +
" WHEN (\n" +
" SELECT COUNT(*) / 2\n" +
@ -93,6 +98,8 @@ public class QueryStmtTest {
Map<String, Expr> exprsMap = new HashMap<>();
stmt.collectExprs(exprsMap);
Assert.assertEquals(4, exprsMap.size());
Map<String, TExpr> constMap = getConstantExprMap(exprsMap, analyzer);
Assert.assertEquals(0, constMap.size());
sql = "SELECT username\n" +
"FROM db1.table1\n" +
@ -112,6 +119,9 @@ public class QueryStmtTest {
exprsMap.clear();
stmt.collectExprs(exprsMap);
Assert.assertEquals(7, exprsMap.size());
constMap.clear();
constMap = getConstantExprMap(exprsMap, analyzer);
Assert.assertEquals(3, constMap.size());
sql = "select\n" +
" avg(t1.k4)\n" +
@ -181,6 +191,9 @@ public class QueryStmtTest {
exprsMap.clear();
stmt.collectExprs(exprsMap);
Assert.assertEquals(2, exprsMap.size());
constMap.clear();
constMap = getConstantExprMap(exprsMap, analyzer);
Assert.assertEquals(0, constMap.size());
sql = "SELECT k1 FROM db1.baseall GROUP BY k1 HAVING EXISTS(SELECT k4 FROM db1.tbl1 GROUP BY k4 " +
"HAVING SUM(k4) = k4);";
@ -188,6 +201,9 @@ public class QueryStmtTest {
exprsMap.clear();
stmt.collectExprs(exprsMap);
Assert.assertEquals(4, exprsMap.size());
constMap.clear();
constMap = getConstantExprMap(exprsMap, analyzer);
Assert.assertEquals(0, constMap.size());
// inline view
sql = "select a.k1, b.now from (select k1,k2 from db1.baseall)a, (select now() as now)b";
@ -195,6 +211,41 @@ public class QueryStmtTest {
exprsMap.clear();
stmt.collectExprs(exprsMap);
Assert.assertEquals(5, exprsMap.size());
constMap.clear();
constMap = getConstantExprMap(exprsMap, analyzer);
Assert.assertEquals(1, constMap.size());
// expr in subquery associate with column in grandparent level
sql = "WITH aa AS\n" +
" (SELECT DATE_FORMAT(workDateTime, '%Y-%m') mon,\n" +
" siteid\n" +
" FROM db1.table1\n" +
" WHERE workDateTime >= concat(year(now())-1, '-01-01 00:00:00')\n" +
" AND workDateTime < now()\n" +
" GROUP BY siteid,\n" +
" DATE_FORMAT(workDateTime, '%Y-%m')),\n" +
" bb AS\n" +
" (SELECT mon,\n" +
" count(DISTINCT siteid) total\n" +
" FROM aa\n" +
" GROUP BY mon),\n" +
" cc AS\n" +
" (SELECT mon,\n" +
" count(DISTINCT siteid) num\n" +
" FROM aa\n" +
" GROUP BY mon)\n" +
"SELECT bb.mon,\n" +
" round(cc.num / bb.total, 4) rate\n" +
"FROM bb\n" +
"LEFT JOIN cc ON cc.mon = bb.mon\n" +
"ORDER BY mon;";
stmt = (QueryStmt) UtFrameUtils.parseAndAnalyzeStmt(sql, ctx);
exprsMap.clear();
stmt.collectExprs(exprsMap);
Assert.assertEquals(17, exprsMap.size());
constMap.clear();
constMap = getConstantExprMap(exprsMap, analyzer);
Assert.assertEquals(4, constMap.size());
}
@Test
@ -297,4 +348,25 @@ public class QueryStmtTest {
stmt.castResultExprs(origResultTypes);
stmt.setColLabels(origColLabels);
}
/**
* get constant expr from exprMap
* @param exprMap
* @param analyzer
* @return
* @throws AnalysisException
*/
private Map<String, TExpr> getConstantExprMap(Map<String, Expr> exprMap, Analyzer analyzer) throws AnalysisException {
FoldConstantsRule rule = (FoldConstantsRule) FoldConstantsRule.INSTANCE;
Map<String, TExpr> resultMap = new HashMap<>();
for (Map.Entry<String, Expr> entry : exprMap.entrySet()){
Map<String, TExpr> constMap = new HashMap<>();
Map<String, Expr> oriConstMap = new HashMap<>();
Map<String, Expr> sysVarMap = new HashMap<>();
Map<String, Expr> infoFnMap = new HashMap<>();
rule.getConstExpr(entry.getValue(), constMap, oriConstMap, analyzer, sysVarMap, infoFnMap);
resultMap.putAll(constMap);
}
return resultMap;
}
}