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 2f6b2dbdc48 [opt](Nereids) add where Null rule to create empty 
relation as where false (#38135) (#38361)
2f6b2dbdc48 is described below

commit 2f6b2dbdc489a51cad92a6a7d2f04348e0862e33
Author: LiBinfeng <46676950+libinfeng...@users.noreply.github.com>
AuthorDate: Fri Jul 26 14:50:06 2024 +0800

    [opt](Nereids) add where Null rule to create empty relation as where false 
(#38135) (#38361)
    
    pick from master #38135
    
    explain shape plan select * from table2 where Null; explain shape plan
    select * from table2 where false; in this case, null literal can be
    regard as same as false literal
---
 .../nereids/rules/rewrite/EliminateFilter.java     |   8 +-
 .../nereids/rules/rewrite/EliminateFilterTest.java |  12 +++
 .../data/empty_relation/eliminate_empty.out        |  67 ++++++++++++++
 .../suites/empty_relation/eliminate_empty.groovy   | 103 ++++++++++++++++++++-
 .../test_simplify_comparison.groovy                |  20 +---
 5 files changed, 187 insertions(+), 23 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/EliminateFilter.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/EliminateFilter.java
index ef9e418f58d..1413faf3bb0 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/EliminateFilter.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/EliminateFilter.java
@@ -24,6 +24,7 @@ import 
org.apache.doris.nereids.rules.expression.rules.FoldConstantRule;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.Slot;
 import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
 import org.apache.doris.nereids.trees.plans.Plan;
 import org.apache.doris.nereids.trees.plans.logical.LogicalEmptyRelation;
 import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
@@ -43,12 +44,13 @@ public class EliminateFilter implements RewriteRuleFactory {
     @Override
     public List<Rule> buildRules() {
         return ImmutableList.of(logicalFilter().when(
-                filter -> ExpressionUtils.containsType(filter.getConjuncts(), 
BooleanLiteral.class))
+                filter -> ExpressionUtils.containsType(filter.getConjuncts(), 
BooleanLiteral.class)
+                || ExpressionUtils.containsType(filter.getConjuncts(), 
NullLiteral.class))
                 .thenApply(ctx -> {
                     LogicalFilter<Plan> filter = ctx.root;
                     ImmutableSet.Builder<Expression> newConjuncts = 
ImmutableSet.builder();
                     for (Expression expression : filter.getConjuncts()) {
-                        if (expression == BooleanLiteral.FALSE) {
+                        if (expression == BooleanLiteral.FALSE || 
expression.isNullLiteral()) {
                             return new 
LogicalEmptyRelation(ctx.statementContext.getNextRelationId(),
                                     filter.getOutput());
                         } else if (expression != BooleanLiteral.TRUE) {
@@ -75,7 +77,7 @@ public class EliminateFilter implements RewriteRuleFactory {
                         Expression newExpr = 
ExpressionUtils.replace(expression, replaceMap);
                         Expression foldExpression = 
FoldConstantRule.evaluate(newExpr, context);
 
-                        if (foldExpression == BooleanLiteral.FALSE) {
+                        if (foldExpression == BooleanLiteral.FALSE || 
expression.isNullLiteral()) {
                             return new LogicalEmptyRelation(
                                     ctx.statementContext.getNextRelationId(), 
filter.getOutput());
                         } else if (foldExpression != BooleanLiteral.TRUE) {
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/EliminateFilterTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/EliminateFilterTest.java
index cbdc95db559..d3d1316eaac 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/EliminateFilterTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/EliminateFilterTest.java
@@ -23,6 +23,7 @@ import org.apache.doris.nereids.trees.expressions.GreaterThan;
 import org.apache.doris.nereids.trees.expressions.Or;
 import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
 import org.apache.doris.nereids.trees.expressions.literal.Literal;
+import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
 import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
 import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
 import org.apache.doris.nereids.util.LogicalPlanBuilder;
@@ -50,6 +51,17 @@ class EliminateFilterTest implements 
MemoPatternMatchSupported {
                 .matches(logicalEmptyRelation());
     }
 
+    @Test
+    void testEliminateFilterNull() {
+        LogicalPlan filterNull = new LogicalPlanBuilder(scan1)
+                .filter(NullLiteral.INSTANCE)
+                .build();
+
+        PlanChecker.from(MemoTestUtils.createConnectContext(), filterNull)
+                .applyTopDown(new EliminateFilter())
+                .matches(logicalEmptyRelation());
+    }
+
     @Test
     void testEliminateFilterTrue() {
         LogicalPlan filterTrue = new LogicalPlanBuilder(scan1)
diff --git a/regression-test/data/empty_relation/eliminate_empty.out 
b/regression-test/data/empty_relation/eliminate_empty.out
index ca0d2a4641a..56917b8042d 100644
--- a/regression-test/data/empty_relation/eliminate_empty.out
+++ b/regression-test/data/empty_relation/eliminate_empty.out
@@ -70,6 +70,73 @@ PhysicalResultSink
 
 -- !except_empty_data --
 
+-- !null_join --
+PhysicalResultSink
+--PhysicalEmptyRelation
+
+-- !null_explain_union_empty_data --
+PhysicalResultSink
+--PhysicalDistribute[DistributionSpecGather]
+----hashAgg[LOCAL]
+------PhysicalProject
+--------PhysicalOlapScan[nation]
+
+-- !null_union_empty_data --
+1
+
+-- !null_explain_union_empty_empty --
+PhysicalResultSink
+--PhysicalEmptyRelation
+
+-- !null_union_empty_empty --
+
+-- !null_union_emtpy_onerow --
+10
+
+-- !null_explain_intersect_data_empty --
+PhysicalResultSink
+--PhysicalEmptyRelation
+
+-- !null_explain_intersect_empty_data --
+PhysicalResultSink
+--PhysicalEmptyRelation
+
+-- !null_explain_except_data_empty --
+PhysicalResultSink
+--PhysicalDistribute[DistributionSpecGather]
+----PhysicalProject
+------hashAgg[LOCAL]
+--------PhysicalProject
+----------PhysicalOlapScan[nation]
+
+-- !null_explain_except_data_empty_data --
+PhysicalResultSink
+--PhysicalDistribute[DistributionSpecGather]
+----PhysicalExcept
+------PhysicalDistribute[DistributionSpecHash]
+--------PhysicalProject
+----------PhysicalOlapScan[nation]
+------PhysicalDistribute[DistributionSpecHash]
+--------PhysicalProject
+----------filter(( not (n_nationkey = 1)))
+------------PhysicalOlapScan[nation]
+
+-- !null_except_data_empty_data --
+1
+
+-- !null_explain_except_empty_data --
+PhysicalResultSink
+--PhysicalEmptyRelation
+
+-- !null_intersect_data_empty --
+
+-- !null_intersect_empty_data --
+
+-- !null_except_data_empty --
+1
+
+-- !null_except_empty_data --
+
 -- !prune_partition1 --
 PhysicalResultSink
 --PhysicalEmptyRelation
diff --git a/regression-test/suites/empty_relation/eliminate_empty.groovy 
b/regression-test/suites/empty_relation/eliminate_empty.groovy
index ffe3fe17cd5..af3ec156e08 100644
--- a/regression-test/suites/empty_relation/eliminate_empty.groovy
+++ b/regression-test/suites/empty_relation/eliminate_empty.groovy
@@ -131,6 +131,107 @@ suite("eliminate_empty") {
         select r_regionkey from region where false except select n_nationkey 
from nation  
     """
 
+    qt_null_join """
+        explain shape plan
+        select * 
+        from 
+            nation 
+            join 
+            (select * from region where Null) R
+    """
+
+    qt_null_explain_union_empty_data """
+        explain shape plan
+        select * 
+        from (select n_nationkey from nation union select r_regionkey from 
region where Null) T
+    """
+    qt_null_union_empty_data """
+        select * 
+        from (select n_nationkey from nation union select r_regionkey from 
region where Null) T
+    """
+
+    qt_null_explain_union_empty_empty """
+        explain shape plan
+        select * 
+        from (
+                select n_nationkey from nation where Null 
+                union 
+                select r_regionkey from region where Null
+            ) T
+    """
+    qt_null_union_empty_empty """
+        select * 
+        from (
+                select n_nationkey from nation where Null 
+                union 
+                select r_regionkey from region where Null
+            ) T
+    """
+    qt_null_union_emtpy_onerow """
+        select *
+        from (
+            select n_nationkey from nation where Null 
+                union
+            select 10
+                union
+            select 10
+        )T
+        """
+
+    qt_null_explain_intersect_data_empty """
+        explain shape plan
+        select n_nationkey from nation intersect select r_regionkey from 
region where Null
+    """
+
+    qt_null_explain_intersect_empty_data """
+        explain shape plan
+        select r_regionkey from region where Null intersect select n_nationkey 
from nation  
+    """
+
+    qt_null_explain_except_data_empty """
+        explain shape plan
+        select n_nationkey from nation except select r_regionkey from region 
where Null
+    """
+
+    qt_null_explain_except_data_empty_data """
+        explain shape plan
+        select n_nationkey from nation 
+        except 
+        select r_regionkey from region where Null
+        except
+        select n_nationkey from nation where n_nationkey != 1;
+    """
+
+    qt_null_except_data_empty_data """
+        select n_nationkey from nation 
+        except 
+        select r_regionkey from region where Null
+        except
+        select n_nationkey from nation where n_nationkey != 1;
+    """
+
+    qt_null_explain_except_empty_data """
+        explain shape plan
+        select r_regionkey from region where Null except select n_nationkey 
from nation  
+    """
+
+
+    qt_null_intersect_data_empty """
+        select n_nationkey from nation intersect select r_regionkey from 
region where Null
+    """
+
+    qt_null_intersect_empty_data """
+        select r_regionkey from region where Null intersect select n_nationkey 
from nation  
+    """
+
+    qt_null_except_data_empty """
+        select n_nationkey from nation except select r_regionkey from region 
where Null
+    """
+
+    qt_null_except_empty_data """
+        select r_regionkey from region where Null except select n_nationkey 
from nation  
+    """
+
     sql """
     drop table if exists eliminate_partition_prune;
     """
@@ -218,4 +319,4 @@ suite("eliminate_empty") {
         sql """drop table if exists table_5_undef_partitions2_keys3"""
         sql """drop table if exists table_10_undef_partitions2_keys3"""
     }
-}
\ No newline at end of file
+}
diff --git 
a/regression-test/suites/nereids_syntax_p0/test_simplify_comparison.groovy 
b/regression-test/suites/nereids_syntax_p0/test_simplify_comparison.groovy
index a5b3ef28e4d..86b1402c682 100644
--- a/regression-test/suites/nereids_syntax_p0/test_simplify_comparison.groovy
+++ b/regression-test/suites/nereids_syntax_p0/test_simplify_comparison.groovy
@@ -89,15 +89,6 @@ suite("test_simplify_comparison") {
         contains "CAST"
     }
 
-    explain {
-        sql "verbose select * from simple_test_table_t where a = cast(1.1 as 
double) and b = cast(1.1 as double) and c = cast(1.1 as double) and d = 
cast(1.1 as double);"
-        contains "a[#0] IS NULL"
-        contains "b[#1] IS NULL"
-        contains "c[#2] IS NULL"
-        contains "d[#3] IS NULL"
-        contains "AND NULL"
-    }
-
     explain {
         sql "verbose select * from simple_test_table_t where e = cast(1.1 as 
double);"
         contains "CAST(e[#4] AS DOUBLE) = 1.1"
@@ -205,15 +196,6 @@ suite("test_simplify_comparison") {
         contains "CAST"
     }
 
-    explain {
-        sql "verbose select * from simple_test_table_t where a = 1.1 and b = 
1.1 and c = 1.1 and d = 1.1;"
-        contains "a[#0] IS NULL"
-        contains "b[#1] IS NULL"
-        contains "c[#2] IS NULL"
-        contains "d[#3] IS NULL"
-        contains "AND NULL"
-    }
-
     explain {
         sql "verbose select * from simple_test_table_t where e = 1.1;"
         contains "CAST(e[#4] AS DOUBLE) = 1.1"
@@ -272,4 +254,4 @@ suite("test_simplify_comparison") {
     }
     qt_select1 """select * from simple_test_table_t where cast(a as 
decimal(5,1)) = 10.0;"""
     qt_select2 """select a.col1, cast(a.col1 as decimal(7,2)) col3, case when 
a.col1 is null then 15 when cast(a.col1 as decimal(7,2)) < -99997.99 then 18 
when cast(a.col1 as decimal(7,2)) < 1.001 then 3 else -55 end col2 from (select 
1 as col1) a;"""
-}
\ No newline at end of file
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to