diff --git a/fe/fe-core/src/main/java/org/apache/doris/rewrite/FoldConstantsRule.java b/fe/fe-core/src/main/java/org/apache/doris/rewrite/FoldConstantsRule.java index 6042ad8bf0..05c78ffeb2 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/rewrite/FoldConstantsRule.java +++ b/fe/fe-core/src/main/java/org/apache/doris/rewrite/FoldConstantsRule.java @@ -188,14 +188,10 @@ public class FoldConstantsRule implements ExprRewriteRule { * @param analyzer * @throws AnalysisException */ - private void getConstExpr(Expr expr, Map constExprMap, Map oriConstMap, + // public only for unit test + public void getConstExpr(Expr expr, Map constExprMap, Map oriConstMap, Analyzer analyzer, Map sysVarMap, Map 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 diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/QueryStmtTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/QueryStmtTest.java index 77048d63af..c405fbba6a 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/QueryStmtTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/QueryStmtTest.java @@ -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 exprsMap = new HashMap<>(); stmt.collectExprs(exprsMap); Assert.assertEquals(4, exprsMap.size()); + Map 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 getConstantExprMap(Map exprMap, Analyzer analyzer) throws AnalysisException { + FoldConstantsRule rule = (FoldConstantsRule) FoldConstantsRule.INSTANCE; + Map resultMap = new HashMap<>(); + for (Map.Entry entry : exprMap.entrySet()){ + Map constMap = new HashMap<>(); + Map oriConstMap = new HashMap<>(); + Map sysVarMap = new HashMap<>(); + Map infoFnMap = new HashMap<>(); + rule.getConstExpr(entry.getValue(), constMap, oriConstMap, analyzer, sysVarMap, infoFnMap); + resultMap.putAll(constMap); + } + return resultMap; + } }