[fix](nereids)subquery unnest need handle subquery in Not expr correnctly (#28713)
This commit is contained in:
@ -23,6 +23,7 @@ import org.apache.doris.nereids.rules.Rule;
|
||||
import org.apache.doris.nereids.rules.RuleType;
|
||||
import org.apache.doris.nereids.trees.TreeNode;
|
||||
import org.apache.doris.nereids.trees.expressions.Alias;
|
||||
import org.apache.doris.nereids.trees.expressions.And;
|
||||
import org.apache.doris.nereids.trees.expressions.BinaryOperator;
|
||||
import org.apache.doris.nereids.trees.expressions.Exists;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
@ -30,6 +31,7 @@ import org.apache.doris.nereids.trees.expressions.InSubquery;
|
||||
import org.apache.doris.nereids.trees.expressions.ListQuery;
|
||||
import org.apache.doris.nereids.trees.expressions.MarkJoinSlotReference;
|
||||
import org.apache.doris.nereids.trees.expressions.NamedExpression;
|
||||
import org.apache.doris.nereids.trees.expressions.Not;
|
||||
import org.apache.doris.nereids.trees.expressions.Or;
|
||||
import org.apache.doris.nereids.trees.expressions.ScalarSubquery;
|
||||
import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
@ -38,7 +40,6 @@ import org.apache.doris.nereids.trees.expressions.SubqueryExpr;
|
||||
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;
|
||||
import org.apache.doris.nereids.trees.plans.algebra.Aggregate;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalApply;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
|
||||
@ -73,7 +74,8 @@ public class SubqueryToApply implements AnalysisRuleFactory {
|
||||
RuleType.FILTER_SUBQUERY_TO_APPLY.build(
|
||||
logicalFilter().thenApply(ctx -> {
|
||||
LogicalFilter<Plan> filter = ctx.root;
|
||||
|
||||
boolean shouldOutputMarkJoinSlot = filter.getConjuncts().stream()
|
||||
.anyMatch(expr -> shouldOutputMarkJoinSlot(expr, SearchState.SearchNot));
|
||||
ImmutableList<Set<SubqueryExpr>> subqueryExprsList = filter.getConjuncts().stream()
|
||||
.<Set<SubqueryExpr>>map(e -> e.collect(SubqueryToApply::canConvertToSupply))
|
||||
.collect(ImmutableList.toImmutableList());
|
||||
@ -98,7 +100,7 @@ public class SubqueryToApply implements AnalysisRuleFactory {
|
||||
// first step: Replace the subquery of predicate in LogicalFilter
|
||||
// second step: Replace subquery with LogicalApply
|
||||
ReplaceSubquery replaceSubquery = new ReplaceSubquery(
|
||||
ctx.statementContext, false);
|
||||
ctx.statementContext, shouldOutputMarkJoinSlot);
|
||||
SubqueryContext context = new SubqueryContext(subqueryExprs);
|
||||
Expression conjunct = replaceSubquery.replace(oldConjuncts.get(i), context);
|
||||
|
||||
@ -343,7 +345,7 @@ public class SubqueryToApply implements AnalysisRuleFactory {
|
||||
&& hasTopLevelAggWithoutGroupBy(exists.getQueryPlan());
|
||||
}
|
||||
|
||||
private boolean hasTopLevelAggWithoutGroupBy(Plan plan) {
|
||||
private static boolean hasTopLevelAggWithoutGroupBy(Plan plan) {
|
||||
if (plan instanceof LogicalAggregate) {
|
||||
return ((LogicalAggregate) plan).getGroupByExpressions().isEmpty();
|
||||
} else if (plan instanceof LogicalProject || plan instanceof LogicalSort) {
|
||||
@ -427,7 +429,7 @@ public class SubqueryToApply implements AnalysisRuleFactory {
|
||||
// it will always consider the returned result to be true
|
||||
boolean needCreateMarkJoinSlot = isMarkJoin || shouldOutputMarkJoinSlot;
|
||||
MarkJoinSlotReference markJoinSlotReference = null;
|
||||
if (exists.getQueryPlan().anyMatch(Aggregate.class::isInstance) && needCreateMarkJoinSlot) {
|
||||
if (hasTopLevelAggWithoutGroupBy(exists.getQueryPlan()) && needCreateMarkJoinSlot) {
|
||||
markJoinSlotReference =
|
||||
new MarkJoinSlotReference(statementContext.generateColumnName(), true);
|
||||
} else if (needCreateMarkJoinSlot) {
|
||||
@ -505,4 +507,27 @@ public class SubqueryToApply implements AnalysisRuleFactory {
|
||||
|
||||
}
|
||||
|
||||
private enum SearchState {
|
||||
SearchNot,
|
||||
SearchAnd,
|
||||
SearchExistsOrInSubquery
|
||||
}
|
||||
|
||||
private boolean shouldOutputMarkJoinSlot(Expression expr, SearchState searchState) {
|
||||
if (searchState == SearchState.SearchNot && expr instanceof Not) {
|
||||
if (shouldOutputMarkJoinSlot(((Not) expr).child(), SearchState.SearchAnd)) {
|
||||
return true;
|
||||
}
|
||||
} else if (searchState == SearchState.SearchAnd && expr instanceof And) {
|
||||
for (Expression child : expr.children()) {
|
||||
if (shouldOutputMarkJoinSlot(child, SearchState.SearchExistsOrInSubquery)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (searchState == SearchState.SearchExistsOrInSubquery
|
||||
&& (expr instanceof InSubquery || expr instanceof Exists)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user