This is an automated email from the ASF dual-hosted git repository.

englefly pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-2.0 by this push:
     new 6525aeff33a [opt](Nereids) add where Null rule to create empty 
relation as where false (#38135) (#38362)
6525aeff33a is described below

commit 6525aeff33a124c093bb1ef0ff8e42e183e77d1c
Author: LiBinfeng <46676950+libinfeng...@users.noreply.github.com>
AuthorDate: Mon Aug 5 13:49:20 2024 +0800

    [opt](Nereids) add where Null rule to create empty relation as where false 
(#38135) (#38362)
    
    cherry-pick: #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
    
    ## Proposed changes
    
    Issue Number: close #xxx
    
    <!--Describe your changes.-->
---
 .../nereids/rules/rewrite/EliminateFilter.java     |   8 +-
 .../nereids/rules/rewrite/EliminateFilterTest.java |  12 ++
 .../data/empty_relation/eliminate_empty.out        |  89 +++++++++++++
 .../suites/empty_relation/eliminate_empty.groovy   | 139 ++++++++++++++++++++-
 .../test_multi_range_partition.groovy              |   8 +-
 .../test_simplify_comparison.groovy                |  18 ---
 6 files changed, 248 insertions(+), 26 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 2f46c43ecff..157555d5591 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
@@ -25,6 +25,7 @@ import org.apache.doris.nereids.trees.expressions.Alias;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.NamedExpression;
 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;
@@ -45,12 +46,13 @@ public class EliminateFilter implements RewriteRuleFactory {
     @Override
     public List<Rule> buildRules() {
         return ImmutableList.of(logicalFilter().when(
-                filter -> 
filter.getConjuncts().stream().anyMatch(BooleanLiteral.class::isInstance))
+                filter -> 
filter.getConjuncts().stream().anyMatch(BooleanLiteral.class::isInstance)
+                || 
filter.getConjuncts().stream().anyMatch(NullLiteral.class::isInstance))
                 .thenApply(ctx -> {
                     LogicalFilter<Plan> filter = ctx.root;
                     ImmutableSet.Builder 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) {
@@ -80,7 +82,7 @@ public class EliminateFilter implements RewriteRuleFactory {
                         Expression foldExpression =
                                 FoldConstantRule.INSTANCE.rewrite(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 9f35a0c0253..6b4b85d3f80 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
@@ -18,6 +18,7 @@
 package org.apache.doris.nereids.rules.rewrite;
 
 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.logical.LogicalPlan;
 import org.apache.doris.nereids.util.LogicalPlanBuilder;
 import org.apache.doris.nereids.util.MemoPatternMatchSupported;
@@ -42,6 +43,17 @@ class EliminateFilterTest implements 
MemoPatternMatchSupported {
                 .matches(logicalEmptyRelation());
     }
 
+    @Test
+    void testEliminateFilterNull() {
+        LogicalPlan filterNull = new 
LogicalPlanBuilder(PlanConstructor.newLogicalOlapScan(0, "t1", 0))
+                .filter(NullLiteral.INSTANCE)
+                .build();
+
+        PlanChecker.from(MemoTestUtils.createConnectContext(), filterNull)
+                .applyTopDown(new EliminateFilter())
+                .matches(logicalEmptyRelation());
+    }
+
     @Test
     void testEliminateFilterTrue() {
         LogicalPlan filterTrue = new 
LogicalPlanBuilder(PlanConstructor.newLogicalOlapScan(0, "t1", 0))
diff --git a/regression-test/data/empty_relation/eliminate_empty.out 
b/regression-test/data/empty_relation/eliminate_empty.out
index f01d0a947ee..acb17696ebf 100644
--- a/regression-test/data/empty_relation/eliminate_empty.out
+++ b/regression-test/data/empty_relation/eliminate_empty.out
@@ -70,6 +70,95 @@ PhysicalResultSink
 
 -- !except_empty_data --
 
+-- !null_join --
+PhysicalResultSink
+--PhysicalEmptyRelation
+
+-- !null_explain_union_empty_data --
+PhysicalResultSink
+--PhysicalDistribute
+----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
+----PhysicalProject
+------hashAgg[LOCAL]
+--------PhysicalProject
+----------PhysicalOlapScan[nation]
+
+-- !null_explain_except_data_empty_data --
+PhysicalResultSink
+--PhysicalDistribute
+----PhysicalExcept
+------PhysicalDistribute
+--------PhysicalProject
+----------PhysicalOlapScan[nation]
+------PhysicalDistribute
+--------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
+--PhysicalDistribute
+----PhysicalProject
+------hashAgg[GLOBAL]
+--------PhysicalDistribute
+----------hashAgg[LOCAL]
+------------PhysicalProject
+--------------filter((eliminate_partition_prune.k1 = 100))
+----------------PhysicalOlapScan[eliminate_partition_prune]
+
+-- !prune_partition2 --
+PhysicalResultSink
+--PhysicalDistribute
+----PhysicalProject
+------hashAgg[GLOBAL]
+--------PhysicalDistribute
+----------hashAgg[LOCAL]
+------------PhysicalProject
+--------------filter((eliminate_partition_prune.k1 = 100))
+----------------PhysicalOlapScan[eliminate_partition_prune]
+
 -- !join_with_empty_child --
 2      8       e       v       3
 4      7               at      2
diff --git a/regression-test/suites/empty_relation/eliminate_empty.groovy 
b/regression-test/suites/empty_relation/eliminate_empty.groovy
index dc602a466c7..8d5f1baea7b 100644
--- a/regression-test/suites/empty_relation/eliminate_empty.groovy
+++ b/regression-test/suites/empty_relation/eliminate_empty.groovy
@@ -128,6 +128,143 @@ 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;
+    """
+    sql """
+    CREATE TABLE `eliminate_partition_prune` (
+    `k1` int(11) NULL COMMENT "",
+    `k2` int(11) NULL COMMENT "",
+    `k3` int(11) NULL COMMENT ""
+    ) 
+    PARTITION BY RANGE(`k1`, `k2`)
+    (PARTITION p1 VALUES LESS THAN ("3", "1"),
+    PARTITION p2 VALUES [("3", "1"), ("7", "10")),
+    PARTITION p3 VALUES [("7", "10"), ("10", "15")))
+    DISTRIBUTED BY HASH(`k1`) BUCKETS 10
+    PROPERTIES ('replication_num' = '1');
+    """
+
+    
+    qt_prune_partition1 """
+        explain shape plan
+        select sum(k2)
+        from
+        (select * from eliminate_partition_prune where k1=100) T
+        group by k3;
+        """
+    sql """
+        insert into eliminate_partition_prune values (7, 0, 0)
+        """
+    qt_prune_partition2 """
+        explain shape plan
+        select sum(k2)
+        from
+        (select * from eliminate_partition_prune where k1=100) T
+        group by k3;
+        """
+
     sql """drop table if exists table_5_undef_partitions2_keys3"""
     sql """drop table if exists table_10_undef_partitions2_keys3"""
 
@@ -179,4 +316,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_rules_p0/partition_prune/test_multi_range_partition.groovy
 
b/regression-test/suites/nereids_rules_p0/partition_prune/test_multi_range_partition.groovy
index d82eaa19eb6..1c6a68eb85c 100644
--- 
a/regression-test/suites/nereids_rules_p0/partition_prune/test_multi_range_partition.groovy
+++ 
b/regression-test/suites/nereids_rules_p0/partition_prune/test_multi_range_partition.groovy
@@ -169,12 +169,12 @@ suite("test_multi_range_partition") {
 
     explain {
         sql "select * from pt where k1=7 and k2 in (null);"
-        contains "partitions=0/3"
+        contains "VEMPTYSET"
     }
 
     explain {
         sql "select * from pt where k1=7 and k2 not in (null);"
-        contains "partitions=0/3"
+        contains "VEMPTYSET"
     }
     
     explain {
@@ -189,13 +189,13 @@ suite("test_multi_range_partition") {
 
     explain {
         sql "select * from pt where k2 in (null);"
-        contains "partitions=0/3"
+        contains "VEMPTYSET"
     }
 
     // p1/p2/p3 NOT pruned
     explain {
         sql "select * from pt where k2 not in (null)"
-        contains "partitions=0/3"
+        contains "VEMPTYSET"
     }
 
     explain {
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 70dffc3a1dc..b0e98d37bb6 100644
--- a/regression-test/suites/nereids_syntax_p0/test_simplify_comparison.groovy
+++ b/regression-test/suites/nereids_syntax_p0/test_simplify_comparison.groovy
@@ -88,15 +88,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"
@@ -204,15 +195,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"


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

Reply via email to