diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnFE.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnFE.java index 5338bf7df9b2ef..297479104b9404 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnFE.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnFE.java @@ -284,8 +284,11 @@ public Expression visitGreaterThan(GreaterThan greaterThan, ExpressionRewriteCon if (checkedExpr.isPresent()) { return checkedExpr.get(); } - return BooleanLiteral.of(((ComparableLiteral) greaterThan.left()) - .compareTo((ComparableLiteral) greaterThan.right()) > 0); + if (greaterThan.left() instanceof ComparableLiteral && greaterThan.right() instanceof ComparableLiteral) { + return BooleanLiteral.of(((ComparableLiteral) greaterThan.left()) + .compareTo((ComparableLiteral) greaterThan.right()) > 0); + } + return greaterThan; } @Override @@ -295,8 +298,12 @@ public Expression visitGreaterThanEqual(GreaterThanEqual greaterThanEqual, Expre if (checkedExpr.isPresent()) { return checkedExpr.get(); } - return BooleanLiteral.of(((ComparableLiteral) greaterThanEqual.left()) - .compareTo((ComparableLiteral) greaterThanEqual.right()) >= 0); + if (greaterThanEqual.left() instanceof ComparableLiteral + && greaterThanEqual.right() instanceof ComparableLiteral) { + return BooleanLiteral.of(((ComparableLiteral) greaterThanEqual.left()) + .compareTo((ComparableLiteral) greaterThanEqual.right()) >= 0); + } + return greaterThanEqual; } @Override @@ -306,8 +313,11 @@ public Expression visitLessThan(LessThan lessThan, ExpressionRewriteContext cont if (checkedExpr.isPresent()) { return checkedExpr.get(); } - return BooleanLiteral.of(((ComparableLiteral) lessThan.left()) - .compareTo((ComparableLiteral) lessThan.right()) < 0); + if (lessThan.left() instanceof ComparableLiteral && lessThan.right() instanceof ComparableLiteral) { + return BooleanLiteral.of(((ComparableLiteral) lessThan.left()) + .compareTo((ComparableLiteral) lessThan.right()) < 0); + } + return lessThan; } @Override @@ -317,8 +327,12 @@ public Expression visitLessThanEqual(LessThanEqual lessThanEqual, ExpressionRewr if (checkedExpr.isPresent()) { return checkedExpr.get(); } - return BooleanLiteral.of(((ComparableLiteral) lessThanEqual.left()) - .compareTo((ComparableLiteral) lessThanEqual.right()) <= 0); + if (lessThanEqual.left() instanceof ComparableLiteral + && lessThanEqual.right() instanceof ComparableLiteral) { + return BooleanLiteral.of(((ComparableLiteral) lessThanEqual.left()) + .compareTo((ComparableLiteral) lessThanEqual.right()) <= 0); + } + return lessThanEqual; } @Override diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java index 9f46a7970a2c72..63bad87f90d660 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java @@ -31,6 +31,9 @@ import org.apache.doris.nereids.trees.expressions.Divide; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.GreaterThan; +import org.apache.doris.nereids.trees.expressions.GreaterThanEqual; +import org.apache.doris.nereids.trees.expressions.LessThan; +import org.apache.doris.nereids.trees.expressions.LessThanEqual; import org.apache.doris.nereids.trees.expressions.Multiply; import org.apache.doris.nereids.trees.expressions.Slot; import org.apache.doris.nereids.trees.expressions.SlotReference; @@ -115,6 +118,7 @@ import org.apache.doris.nereids.trees.expressions.literal.Literal; import org.apache.doris.nereids.trees.expressions.literal.NullLiteral; import org.apache.doris.nereids.trees.expressions.literal.StringLiteral; +import org.apache.doris.nereids.trees.expressions.literal.TimeV2Literal; import org.apache.doris.nereids.trees.expressions.literal.TinyIntLiteral; import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral; import org.apache.doris.nereids.trees.plans.RelationId; @@ -265,6 +269,44 @@ void testNotPredicateFold() { assertRewriteAfterTypeCoercion("not (1 + 5) / 2 + (10 - 1) * 3 > 3 * 5 + 1", "false"); } + @Test + void testComparisonFoldWithNonComparableLiteral() { + executor = new ExpressionRuleExecutor(ImmutableList.of( + bottomUp(FoldConstantRuleOnFE.VISITOR_INSTANCE) + )); + + Expression analyzed = ExpressionAnalyzer.analyzeFunction(null, null, + PARSER.parseExpression("curtime() >= '20:00:00'")); + Expression rewritten = executor.rewrite(analyzed, context); + Assertions.assertTrue(rewritten instanceof GreaterThanEqual); + Assertions.assertTrue(rewritten.child(0) instanceof TimeV2Literal); + Assertions.assertTrue(rewritten.child(1) instanceof TimeV2Literal); + + analyzed = ExpressionAnalyzer.analyzeFunction(null, null, + PARSER.parseExpression("curtime() > '20:00:00'")); + rewritten = executor.rewrite(analyzed, context); + Assertions.assertTrue(rewritten instanceof GreaterThan); + Assertions.assertTrue(rewritten.child(0) instanceof TimeV2Literal); + Assertions.assertTrue(rewritten.child(1) instanceof TimeV2Literal); + + analyzed = ExpressionAnalyzer.analyzeFunction(null, null, + PARSER.parseExpression("curtime() <= '20:00:00'")); + rewritten = executor.rewrite(analyzed, context); + Assertions.assertTrue(rewritten instanceof LessThanEqual); + Assertions.assertTrue(rewritten.child(0) instanceof TimeV2Literal); + Assertions.assertTrue(rewritten.child(1) instanceof TimeV2Literal); + + analyzed = ExpressionAnalyzer.analyzeFunction(null, null, + PARSER.parseExpression("curtime() < '20:00:00'")); + rewritten = executor.rewrite(analyzed, context); + Assertions.assertTrue(rewritten instanceof LessThan); + Assertions.assertTrue(rewritten.child(0) instanceof TimeV2Literal); + Assertions.assertTrue(rewritten.child(1) instanceof TimeV2Literal); + + assertRewriteAfterTypeCoercion("curtime() = '20:00:00'", "false"); + assertRewriteAfterTypeCoercion("curtime() <=> '20:00:00'", "false"); + } + @Test void testCastFold() { executor = new ExpressionRuleExecutor(ImmutableList.of(