[fix](Nereids) exists should not return null (#29435)
This commit is contained in:
@ -37,6 +37,7 @@ import org.apache.doris.nereids.trees.expressions.ScalarSubquery;
|
||||
import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.expressions.SlotReference;
|
||||
import org.apache.doris.nereids.trees.expressions.SubqueryExpr;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.scalar.Nvl;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.visitor.DefaultExpressionRewriter;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
@ -442,7 +443,7 @@ public class SubqueryToApply implements AnalysisRuleFactory {
|
||||
MarkJoinSlotReference markJoinSlotReference =
|
||||
new MarkJoinSlotReference(statementContext.generateColumnName());
|
||||
context.setSubqueryToMarkJoinSlot(exists, Optional.of(markJoinSlotReference));
|
||||
return markJoinSlotReference;
|
||||
return new Nvl(markJoinSlotReference, BooleanLiteral.FALSE);
|
||||
} else {
|
||||
return BooleanLiteral.TRUE;
|
||||
}
|
||||
|
||||
@ -45,27 +45,27 @@ import java.util.ArrayList;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Convert Existsapply to LogicalJoin.
|
||||
* Convert ExistsApply to LogicalJoin.
|
||||
* <p>
|
||||
* Exists
|
||||
* Correlated -> LEFT_SEMI_JOIN
|
||||
* apply LEFT_SEMI_JOIN(Correlated Predicate)
|
||||
* / \ --> / \
|
||||
* input queryPlan input queryPlan
|
||||
*
|
||||
* <p>
|
||||
* UnCorrelated -> CROSS_JOIN(limit(1))
|
||||
* apply CROSS_JOIN
|
||||
* / \ --> / \
|
||||
* input queryPlan input limit(1)
|
||||
* |
|
||||
* queryPlan
|
||||
*
|
||||
* <p>
|
||||
* Not Exists
|
||||
* Correlated -> LEFT_ANTI_JOIN
|
||||
* apply LEFT_ANTI_JOIN(Correlated Predicate)
|
||||
* / \ --> / \
|
||||
* input queryPlan input queryPlan
|
||||
*
|
||||
* <p>
|
||||
* UnCorrelated -> CROSS_JOIN(Count(*))
|
||||
* Filter(count(*) = 0)
|
||||
* |
|
||||
@ -89,29 +89,24 @@ public class ExistsApplyToJoin extends OneRewriteRuleFactory {
|
||||
}).toRule(RuleType.EXISTS_APPLY_TO_JOIN);
|
||||
}
|
||||
|
||||
private Plan correlatedToJoin(LogicalApply apply) {
|
||||
private Plan correlatedToJoin(LogicalApply<?, ?> apply) {
|
||||
Optional<Expression> correlationFilter = apply.getCorrelationFilter();
|
||||
Expression predicate = correlationFilter.get();
|
||||
if (((Exists) apply.getSubqueryExpr()).isNot()) {
|
||||
return new LogicalJoin<>(JoinType.LEFT_ANTI_JOIN, ExpressionUtils.EMPTY_CONDITION,
|
||||
predicate != null
|
||||
? ExpressionUtils.extractConjunction(predicate)
|
||||
: ExpressionUtils.EMPTY_CONDITION,
|
||||
correlationFilter.map(ExpressionUtils::extractConjunction).orElse(ExpressionUtils.EMPTY_CONDITION),
|
||||
new DistributeHint(DistributeType.NONE),
|
||||
apply.getMarkJoinSlotReference(),
|
||||
apply.children());
|
||||
} else {
|
||||
return new LogicalJoin<>(JoinType.LEFT_SEMI_JOIN, ExpressionUtils.EMPTY_CONDITION,
|
||||
predicate != null
|
||||
? ExpressionUtils.extractConjunction(predicate)
|
||||
: ExpressionUtils.EMPTY_CONDITION,
|
||||
correlationFilter.map(ExpressionUtils::extractConjunction).orElse(ExpressionUtils.EMPTY_CONDITION),
|
||||
new DistributeHint(DistributeType.NONE),
|
||||
apply.getMarkJoinSlotReference(),
|
||||
apply.children());
|
||||
}
|
||||
}
|
||||
|
||||
private Plan unCorrelatedToJoin(LogicalApply unapply) {
|
||||
private Plan unCorrelatedToJoin(LogicalApply<?, ?> unapply) {
|
||||
if (((Exists) unapply.getSubqueryExpr()).isNot()) {
|
||||
return unCorrelatedNotExist(unapply);
|
||||
} else {
|
||||
@ -119,21 +114,22 @@ public class ExistsApplyToJoin extends OneRewriteRuleFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private Plan unCorrelatedNotExist(LogicalApply unapply) {
|
||||
LogicalLimit newLimit = new LogicalLimit<>(1, 0, LimitPhase.ORIGIN, (LogicalPlan) unapply.right());
|
||||
private Plan unCorrelatedNotExist(LogicalApply<?, ?> unapply) {
|
||||
LogicalLimit<?> newLimit = new LogicalLimit<>(1, 0, LimitPhase.ORIGIN, (LogicalPlan) unapply.right());
|
||||
Alias alias = new Alias(new Count(), "count(*)");
|
||||
LogicalAggregate newAgg = new LogicalAggregate<>(new ArrayList<>(),
|
||||
LogicalAggregate<?> newAgg = new LogicalAggregate<>(new ArrayList<>(),
|
||||
ImmutableList.of(alias), newLimit);
|
||||
LogicalJoin newJoin = new LogicalJoin<>(JoinType.CROSS_JOIN, ExpressionUtils.EMPTY_CONDITION,
|
||||
LogicalJoin<?, ?> newJoin = new LogicalJoin<>(JoinType.CROSS_JOIN, ExpressionUtils.EMPTY_CONDITION,
|
||||
ExpressionUtils.EMPTY_CONDITION,
|
||||
new DistributeHint(DistributeType.NONE), unapply.getMarkJoinSlotReference(),
|
||||
new DistributeHint(DistributeType.NONE),
|
||||
unapply.getMarkJoinSlotReference(),
|
||||
(LogicalPlan) unapply.left(), newAgg);
|
||||
return new LogicalFilter<>(ImmutableSet.of(new EqualTo(newAgg.getOutput().get(0),
|
||||
new IntegerLiteral(0))), newJoin);
|
||||
}
|
||||
|
||||
private Plan unCorrelatedExist(LogicalApply unapply) {
|
||||
LogicalLimit newLimit = new LogicalLimit<>(1, 0, LimitPhase.ORIGIN, (LogicalPlan) unapply.right());
|
||||
private Plan unCorrelatedExist(LogicalApply<?, ?> unapply) {
|
||||
LogicalLimit<?> newLimit = new LogicalLimit<>(1, 0, LimitPhase.ORIGIN, (LogicalPlan) unapply.right());
|
||||
return new LogicalJoin<>(JoinType.CROSS_JOIN, ExpressionUtils.EMPTY_CONDITION,
|
||||
ExpressionUtils.EMPTY_CONDITION,
|
||||
new DistributeHint(DistributeType.NONE), unapply.getMarkJoinSlotReference(),
|
||||
|
||||
@ -164,7 +164,7 @@ public class LogicalApply<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
LogicalApply that = (LogicalApply) o;
|
||||
LogicalApply<?, ?> that = (LogicalApply<?, ?>) o;
|
||||
return Objects.equals(correlationSlot, that.getCorrelationSlot())
|
||||
&& Objects.equals(subqueryExpr, that.getSubqueryExpr())
|
||||
&& Objects.equals(correlationFilter, that.getCorrelationFilter())
|
||||
@ -192,10 +192,11 @@ public class LogicalApply<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends
|
||||
.addAll(correlationSlot)
|
||||
.add(correlationFilter.get())
|
||||
.build();
|
||||
} else {
|
||||
return new ImmutableList.Builder<Expression>()
|
||||
.addAll(correlationSlot)
|
||||
.build();
|
||||
}
|
||||
return new ImmutableList.Builder<Expression>()
|
||||
.addAll(correlationSlot)
|
||||
.build();
|
||||
}
|
||||
|
||||
public LogicalApply<Plan, Plan> withSubqueryExprAndChildren(SubqueryExpr subqueryExpr, List<Plan> children) {
|
||||
|
||||
@ -7,7 +7,7 @@ PhysicalResultSink
|
||||
--------PhysicalTopN[LOCAL_SORT]
|
||||
----------hashAgg[LOCAL]
|
||||
------------PhysicalProject
|
||||
--------------filter(($c$1 OR $c$2))
|
||||
--------------filter((ifnull($c$1, FALSE) OR ifnull($c$2, FALSE)))
|
||||
----------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = catalog_sales.cs_ship_customer_sk)) otherCondition=()
|
||||
------------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = web_sales.ws_bill_customer_sk)) otherCondition=()
|
||||
--------------------PhysicalProject
|
||||
|
||||
@ -9,7 +9,7 @@ PhysicalResultSink
|
||||
------------PhysicalDistribute[DistributionSpecHash]
|
||||
--------------hashAgg[LOCAL]
|
||||
----------------PhysicalProject
|
||||
------------------filter(($c$1 OR $c$2))
|
||||
------------------filter((ifnull($c$1, FALSE) OR ifnull($c$2, FALSE)))
|
||||
--------------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = catalog_sales.cs_ship_customer_sk)) otherCondition=()
|
||||
----------------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = web_sales.ws_bill_customer_sk)) otherCondition=()
|
||||
------------------------PhysicalProject
|
||||
|
||||
@ -9,7 +9,7 @@ PhysicalResultSink
|
||||
------------PhysicalDistribute[DistributionSpecHash]
|
||||
--------------hashAgg[LOCAL]
|
||||
----------------PhysicalProject
|
||||
------------------filter(($c$1 OR $c$2))
|
||||
------------------filter((ifnull($c$1, FALSE) OR ifnull($c$2, FALSE)))
|
||||
--------------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = catalog_sales.cs_ship_customer_sk)) otherCondition=()
|
||||
----------------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = web_sales.ws_bill_customer_sk)) otherCondition=()
|
||||
------------------------PhysicalProject
|
||||
|
||||
@ -9,7 +9,7 @@ PhysicalResultSink
|
||||
------------PhysicalDistribute[DistributionSpecHash]
|
||||
--------------hashAgg[LOCAL]
|
||||
----------------PhysicalProject
|
||||
------------------filter(($c$1 OR $c$2))
|
||||
------------------filter((ifnull($c$1, FALSE) OR ifnull($c$2, FALSE)))
|
||||
--------------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = catalog_sales.cs_ship_customer_sk)) otherCondition=()
|
||||
----------------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = web_sales.ws_bill_customer_sk)) otherCondition=()
|
||||
------------------------PhysicalProject
|
||||
|
||||
@ -9,7 +9,7 @@ PhysicalResultSink
|
||||
------------PhysicalDistribute[DistributionSpecHash]
|
||||
--------------hashAgg[LOCAL]
|
||||
----------------PhysicalProject
|
||||
------------------filter(($c$1 OR $c$2))
|
||||
------------------filter((ifnull($c$1, FALSE) OR ifnull($c$2, FALSE)))
|
||||
--------------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = catalog_sales.cs_ship_customer_sk)) otherCondition=()
|
||||
----------------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = web_sales.ws_bill_customer_sk)) otherCondition=()
|
||||
------------------------PhysicalProject
|
||||
|
||||
@ -9,7 +9,7 @@ PhysicalResultSink
|
||||
------------PhysicalDistribute[DistributionSpecHash]
|
||||
--------------hashAgg[LOCAL]
|
||||
----------------PhysicalProject
|
||||
------------------filter(($c$1 OR $c$2))
|
||||
------------------filter((ifnull($c$1, FALSE) OR ifnull($c$2, FALSE)))
|
||||
--------------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = catalog_sales.cs_ship_customer_sk)) otherCondition=()
|
||||
----------------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = web_sales.ws_bill_customer_sk)) otherCondition=()
|
||||
------------------------PhysicalProject
|
||||
|
||||
@ -7,7 +7,7 @@ PhysicalResultSink
|
||||
--------PhysicalTopN[LOCAL_SORT]
|
||||
----------hashAgg[LOCAL]
|
||||
------------PhysicalProject
|
||||
--------------filter(($c$1 OR $c$2))
|
||||
--------------filter((ifnull($c$1, FALSE) OR ifnull($c$2, FALSE)))
|
||||
----------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = catalog_sales.cs_ship_customer_sk)) otherCondition=()
|
||||
------------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = web_sales.ws_bill_customer_sk)) otherCondition=()
|
||||
--------------------PhysicalProject
|
||||
|
||||
@ -9,7 +9,7 @@ PhysicalResultSink
|
||||
------------PhysicalDistribute[DistributionSpecHash]
|
||||
--------------hashAgg[LOCAL]
|
||||
----------------PhysicalProject
|
||||
------------------filter(($c$1 OR $c$2))
|
||||
------------------filter((ifnull($c$1, FALSE) OR ifnull($c$2, FALSE)))
|
||||
--------------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = catalog_sales.cs_ship_customer_sk)) otherCondition=()
|
||||
----------------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = web_sales.ws_bill_customer_sk)) otherCondition=()
|
||||
------------------------PhysicalProject
|
||||
|
||||
@ -7,7 +7,7 @@ PhysicalResultSink
|
||||
--------PhysicalTopN[LOCAL_SORT]
|
||||
----------hashAgg[LOCAL]
|
||||
------------PhysicalProject
|
||||
--------------filter(($c$1 OR $c$2))
|
||||
--------------filter((ifnull($c$1, FALSE) OR ifnull($c$2, FALSE)))
|
||||
----------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = catalog_sales.cs_ship_customer_sk)) otherCondition=()
|
||||
------------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = web_sales.ws_bill_customer_sk)) otherCondition=()
|
||||
--------------------PhysicalProject
|
||||
|
||||
@ -9,7 +9,7 @@ PhysicalResultSink
|
||||
------------PhysicalDistribute[DistributionSpecHash]
|
||||
--------------hashAgg[LOCAL]
|
||||
----------------PhysicalProject
|
||||
------------------filter(($c$1 OR $c$2))
|
||||
------------------filter((ifnull($c$1, FALSE) OR ifnull($c$2, FALSE)))
|
||||
--------------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = catalog_sales.cs_ship_customer_sk)) otherCondition=()
|
||||
----------------------hashJoin[LEFT_SEMI_JOIN] hashCondition=((c.c_customer_sk = web_sales.ws_bill_customer_sk)) otherCondition=()
|
||||
------------------------PhysicalProject
|
||||
|
||||
Reference in New Issue
Block a user