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
This commit is contained in:
@ -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) {
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;"""
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user