This is an automated email from the ASF dual-hosted git repository. starocean999 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new 9c7ec37fde7 [fix](nereids)NullSafeEqualToEqual rule should keep <=> unchanged if it has none-literal child (#36521) 9c7ec37fde7 is described below commit 9c7ec37fde7e7a9631846ee1cd712ee7db3a7a9a Author: starocean999 <40539150+starocean...@users.noreply.github.com> AuthorDate: Thu Jun 20 18:05:19 2024 +0800 [fix](nereids)NullSafeEqualToEqual rule should keep <=> unchanged if it has none-literal child (#36521) convert: expr <=> null to expr is null null <=> null to true null <=> 1 to false literal <=> literal to literal = literal ( 1 <=> 2 to 1 = 2 ) others are unchanged. --- .../rules/expression/ExpressionOptimization.java | 2 ++ .../expression/rules/NullSafeEqualToEqual.java | 24 +++++--------- .../expression/rules/NullSafeEqualToEqualTest.java | 38 +++++++++++++++++----- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionOptimization.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionOptimization.java index 828592bbba3..abf57057601 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionOptimization.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionOptimization.java @@ -23,6 +23,7 @@ import org.apache.doris.nereids.rules.expression.rules.DateFunctionRewrite; import org.apache.doris.nereids.rules.expression.rules.DistinctPredicatesRule; import org.apache.doris.nereids.rules.expression.rules.ExtractCommonFactorRule; import org.apache.doris.nereids.rules.expression.rules.LikeToEqualRewrite; +import org.apache.doris.nereids.rules.expression.rules.NullSafeEqualToEqual; import org.apache.doris.nereids.rules.expression.rules.OrToIn; import org.apache.doris.nereids.rules.expression.rules.SimplifyComparisonPredicate; import org.apache.doris.nereids.rules.expression.rules.SimplifyDecimalV3Comparison; @@ -51,6 +52,7 @@ public class ExpressionOptimization extends ExpressionRewrite { ArrayContainToArrayOverlap.INSTANCE, CaseWhenToIf.INSTANCE, TopnToMax.INSTANCE, + NullSafeEqualToEqual.INSTANCE, LikeToEqualRewrite.INSTANCE ) ); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/NullSafeEqualToEqual.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/NullSafeEqualToEqual.java index dda109a42e0..16c4663a1ed 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/NullSafeEqualToEqual.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/NullSafeEqualToEqual.java @@ -24,17 +24,16 @@ import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.IsNull; import org.apache.doris.nereids.trees.expressions.NullSafeEqual; import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral; -import org.apache.doris.nereids.trees.expressions.literal.NullLiteral; import com.google.common.collect.ImmutableList; import java.util.List; /** - * convert "<=>" to "=", if both sides are not nullable * convert "A <=> null" to "A is null" * null <=> null : true * null <=> 1 : false + * 1 <=> 2 : 1 = 2 */ public class NullSafeEqualToEqual implements ExpressionPatternRuleFactory { public static final NullSafeEqualToEqual INSTANCE = new NullSafeEqualToEqual(); @@ -47,19 +46,14 @@ public class NullSafeEqualToEqual implements ExpressionPatternRuleFactory { } private static Expression rewrite(NullSafeEqual nullSafeEqual) { - if (nullSafeEqual.left() instanceof NullLiteral) { - if (nullSafeEqual.right().nullable()) { - return new IsNull(nullSafeEqual.right()); - } else { - return BooleanLiteral.FALSE; - } - } else if (nullSafeEqual.right() instanceof NullLiteral) { - if (nullSafeEqual.left().nullable()) { - return new IsNull(nullSafeEqual.left()); - } else { - return BooleanLiteral.FALSE; - } - } else if (!nullSafeEqual.left().nullable() && !nullSafeEqual.right().nullable()) { + // because the nullable info hasn't been finalized yet, the optimization is limited + if (nullSafeEqual.left().isNullLiteral() && nullSafeEqual.right().isNullLiteral()) { + return BooleanLiteral.TRUE; + } else if (nullSafeEqual.left().isNullLiteral()) { + return nullSafeEqual.right().isLiteral() ? BooleanLiteral.FALSE : new IsNull(nullSafeEqual.right()); + } else if (nullSafeEqual.right().isNullLiteral()) { + return nullSafeEqual.left().isLiteral() ? BooleanLiteral.FALSE : new IsNull(nullSafeEqual.left()); + } else if (nullSafeEqual.left().isLiteral() && nullSafeEqual.right().isLiteral()) { return new EqualTo(nullSafeEqual.left(), nullSafeEqual.right()); } return nullSafeEqual; diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/NullSafeEqualToEqualTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/NullSafeEqualToEqualTest.java index db1186738da..8da25e92e7e 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/NullSafeEqualToEqualTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/NullSafeEqualToEqualTest.java @@ -24,6 +24,7 @@ import org.apache.doris.nereids.trees.expressions.IsNull; import org.apache.doris.nereids.trees.expressions.NullSafeEqual; import org.apache.doris.nereids.trees.expressions.SlotReference; import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral; +import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral; import org.apache.doris.nereids.trees.expressions.literal.NullLiteral; import org.apache.doris.nereids.types.StringType; @@ -32,7 +33,7 @@ import org.junit.jupiter.api.Test; class NullSafeEqualToEqualTest extends ExpressionRewriteTestHelper { - // "A<=> Null" to "A is null" + // "A <=> Null" to "A is null" @Test void testNullSafeEqualToIsNull() { executor = new ExpressionRuleExecutor(ImmutableList.of( @@ -40,21 +41,31 @@ class NullSafeEqualToEqualTest extends ExpressionRewriteTestHelper { )); SlotReference slot = new SlotReference("a", StringType.INSTANCE, true); assertRewrite(new NullSafeEqual(slot, NullLiteral.INSTANCE), new IsNull(slot)); + slot = new SlotReference("a", StringType.INSTANCE, false); + assertRewrite(new NullSafeEqual(slot, NullLiteral.INSTANCE), new IsNull(slot)); } - // "A<=> Null" to "False", when A is not nullable + // "0 <=> Null" to false @Test void testNullSafeEqualToFalse() { executor = new ExpressionRuleExecutor(ImmutableList.of( bottomUp(NullSafeEqualToEqual.INSTANCE) )); - SlotReference slot = new SlotReference("a", StringType.INSTANCE, false); - assertRewrite(new NullSafeEqual(slot, NullLiteral.INSTANCE), BooleanLiteral.FALSE); + assertRewrite(new NullSafeEqual(new IntegerLiteral(0), NullLiteral.INSTANCE), BooleanLiteral.FALSE); + } + + // "NULL <=> Null" to false + @Test + void testNullSafeEqualToTrue() { + executor = new ExpressionRuleExecutor(ImmutableList.of( + bottomUp(NullSafeEqualToEqual.INSTANCE) + )); + assertRewrite(new NullSafeEqual(NullLiteral.INSTANCE, NullLiteral.INSTANCE), BooleanLiteral.TRUE); } // "A(nullable)<=>B" not changed @Test - void testNullSafeEqualNotChangedLeft() { + void testNullSafeEqualNotChangedLeftNullable() { executor = new ExpressionRuleExecutor(ImmutableList.of( bottomUp(NullSafeEqualToEqual.INSTANCE) )); @@ -65,7 +76,7 @@ class NullSafeEqualToEqualTest extends ExpressionRewriteTestHelper { // "A<=>B(nullable)" not changed @Test - void testNullSafeEqualNotChangedRight() { + void testNullSafeEqualNotChangedRightNullable() { executor = new ExpressionRuleExecutor(ImmutableList.of( bottomUp(NullSafeEqualToEqual.INSTANCE) )); @@ -74,14 +85,25 @@ class NullSafeEqualToEqualTest extends ExpressionRewriteTestHelper { assertRewrite(new NullSafeEqual(a, b), new NullSafeEqual(a, b)); } - // "A<=>B" changed + // "A<=>B" not changed @Test - void testNullSafeEqualToEqual() { + void testNullSafeEqualNotChangedBothNullable() { executor = new ExpressionRuleExecutor(ImmutableList.of( bottomUp(NullSafeEqualToEqual.INSTANCE) )); SlotReference a = new SlotReference("a", StringType.INSTANCE, false); SlotReference b = new SlotReference("b", StringType.INSTANCE, false); + assertRewrite(new NullSafeEqual(a, b), new NullSafeEqual(a, b)); + } + + // "1 <=> 0" to "1 = 0" + @Test + void testNullSafeEqualToEqual() { + executor = new ExpressionRuleExecutor(ImmutableList.of( + bottomUp(NullSafeEqualToEqual.INSTANCE) + )); + IntegerLiteral a = new IntegerLiteral(0); + IntegerLiteral b = new IntegerLiteral(1); assertRewrite(new NullSafeEqual(a, b), new EqualTo(a, b)); } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org