This is an automated email from the ASF dual-hosted git repository.
morrysnow pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.1 by this push:
new 64a94e883de [fix](nereids)NullSafeEqualToEqual rule should keep <=>
unchanged if it has none-literal child (#36523)
64a94e883de is described below
commit 64a94e883de82748a3ef400b7487012f3d9b30a9
Author: starocean999 <[email protected]>
AuthorDate: Thu Jun 20 17:55:36 2024 +0800
[fix](nereids)NullSafeEqualToEqual rule should keep <=> unchanged if it has
none-literal child (#36523)
pick from master #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.
---
.../expression/rules/NullSafeEqualToEqual.java | 26 +++++++--------
.../expression/rules/NullSafeEqualToEqualTest.java | 38 +++++++++++++++++-----
2 files changed, 41 insertions(+), 23 deletions(-)
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 e8eedb1e198..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,15 +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 any side is 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();
@@ -45,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: [email protected]
For additional commands, e-mail: [email protected]