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 d014958937..2451b72be5 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 @@ -218,50 +218,83 @@ public class FoldConstantRuleOnFE extends AbstractExpressionRewriteRule { @Override public Expression visitAnd(And and, ExpressionRewriteContext context) { List nonTrueLiteral = Lists.newArrayList(); + int nullCount = 0; for (Expression e : and.children()) { e = e.accept(this, context); if (BooleanLiteral.FALSE.equals(e)) { return BooleanLiteral.FALSE; } else if (e instanceof NullLiteral) { - return e; + nullCount++; + nonTrueLiteral.add(e); } else if (!BooleanLiteral.TRUE.equals(e)) { nonTrueLiteral.add(e); } } - if (nonTrueLiteral.isEmpty()) { - return BooleanLiteral.TRUE; + + if (nullCount == 0) { + switch (nonTrueLiteral.size()) { + case 0: + // true and true + return BooleanLiteral.TRUE; + case 1: + // true and x + return nonTrueLiteral.get(0); + default: + // x and y + return and.withChildren(nonTrueLiteral); + } + } else if (nullCount == 1) { + if (nonTrueLiteral.size() == 1) { + // null and true + return new NullLiteral(BooleanType.INSTANCE); + } + // null and x + return and.withChildren(nonTrueLiteral); + } else { + // null and null + return new NullLiteral(BooleanType.INSTANCE); } - if (nonTrueLiteral.size() == 1) { - return nonTrueLiteral.get(0); - } - return and.withChildren(nonTrueLiteral); } @Override public Expression visitOr(Or or, ExpressionRewriteContext context) { List nonFalseLiteral = Lists.newArrayList(); - boolean hasNull = false; + int nullCount = 0; for (Expression e : or.children()) { e = e.accept(this, context); if (BooleanLiteral.TRUE.equals(e)) { return BooleanLiteral.TRUE; } else if (e instanceof NullLiteral) { - hasNull = true; + nullCount++; + nonFalseLiteral.add(e); } else if (!BooleanLiteral.FALSE.equals(e)) { nonFalseLiteral.add(e); } } - if (nonFalseLiteral.isEmpty()) { - if (hasNull) { - return new NullLiteral(BooleanType.INSTANCE); - } else { - return BooleanLiteral.FALSE; + + if (nullCount == 0) { + switch (nonFalseLiteral.size()) { + case 0: + // false or false + return BooleanLiteral.FALSE; + case 1: + // false or x + return nonFalseLiteral.get(0); + default: + // x or y + return or.withChildren(nonFalseLiteral); } + } else if (nullCount == 1) { + if (nonFalseLiteral.size() == 1) { + // null or false + return new NullLiteral(BooleanType.INSTANCE); + } + // null or x + return or.withChildren(nonFalseLiteral); + } else { + // null or null + return new NullLiteral(BooleanType.INSTANCE); } - if (nonFalseLiteral.size() == 1) { - return nonFalseLiteral.get(0); - } - return or.withChildren(nonFalseLiteral); } @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 a38a20bf92..8f66c9fc30 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 @@ -112,10 +112,14 @@ public class FoldConstantTest extends ExpressionRewriteTestHelper { assertRewriteAfterTypeCoercion("true and null", "null"); assertRewriteAfterTypeCoercion("false and null", "false"); + assertRewriteAfterTypeCoercion("null and IA is null", "null and IA is null"); assertRewriteAfterTypeCoercion("true or null", "true"); assertRewriteAfterTypeCoercion("false or null", "null"); + assertRewriteAfterTypeCoercion("null or IA is null", "null or IA is null"); assertRewriteAfterTypeCoercion("null and null", "null"); + assertRewriteAfterTypeCoercion("null or null", "null"); + } @Test