diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CaseExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CaseExpr.java index 21e5c115a66c36..5bc742f886c981 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CaseExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CaseExpr.java @@ -281,6 +281,18 @@ public static Expr computeCaseExpr(CaseExpr expr) { LiteralExpr caseExpr; int startIndex = 0; int endIndex = expr.getChildren().size(); + + // CastExpr contains SlotRef child should be reset to re-analyze in selectListItem + for (Expr child : expr.getChildren()) { + if (child instanceof CastExpr && (child.contains(SlotRef.class))) { + List castExprList = Lists.newArrayList(); + child.collect(CastExpr.class, castExprList); + for (CastExpr castExpr : castExprList) { + castExpr.resetAnalysisState(); + } + } + } + if (expr.hasCaseExpr()) { // just deal literal here // and avoid `float compute` in java,float should be dealt in be diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java index 83480a9599cbcb..0257e6b6b2b595 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java @@ -207,7 +207,9 @@ public void analyze() throws AnalysisException { @Override public void analyzeImpl(Analyzer analyzer) throws AnalysisException { - Preconditions.checkState(!isImplicit); + if (isImplicit) { + return; + } // When cast target type is string and it's length is default -1, the result length // of cast is decided by child. if (targetTypeDef.getType().isScalarType()) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotRef.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotRef.java index 16793f259f5fd8..ad0606d8dc9a59 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotRef.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotRef.java @@ -93,6 +93,7 @@ public Expr clone() { } public SlotDescriptor getDesc() { + Preconditions.checkState(isAnalyzed); Preconditions.checkNotNull(desc); return desc; } diff --git a/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java b/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java index bc702bd20a6ccf..970a82e8e4838f 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java @@ -917,10 +917,20 @@ public void testConvertCaseWhenToConstant() throws Exception { Assert.assertTrue(StringUtils.containsIgnoreCase(UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "explain " + sql52), "OUTPUT EXPRS: `k7`")); - // 5.3 test different in then expr and else expr, and return CastExpr + // 5.3 test different type in then expr and else expr, and return CastExpr String sql53 = "select case when 2 < 1 then 'all' else k1 end as col53 from test.baseall group by col53"; Assert.assertTrue(StringUtils.containsIgnoreCase(UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "explain " + sql53), - "OUTPUT EXPRS: `k1`")); + "OUTPUT EXPRS: `k1`")); + + // 5.4 test return CastExpr with other SlotRef in selectListItem + String sql54 = "select k2, case when 2 < 1 then 'all' else k1 end as col54, k7 from test.baseall group by k2, col54, k7"; + Assert.assertTrue(StringUtils.containsIgnoreCase(UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "explain " + sql54), + "OUTPUT EXPRS: `k2` | `k1` | `k7`")); + + // 5.5 test return CastExpr> with other SlotRef in selectListItem + String sql55 = "select case when 2 < 1 then 'all' else cast(k1 as int) end as col55, k7 from test.baseall group by col55, k7"; + Assert.assertTrue(StringUtils.containsIgnoreCase(UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "explain " + sql55), + "OUTPUT EXPRS: CAST(`k1` AS INT) | `k7`")); } @Test