You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by mo...@apache.org on 2025/11/05 03:01:14 UTC
(doris) branch pick_50894 created (now 8630e41d92d)
This is an automated email from the ASF dual-hosted git repository.
morrysnow pushed a change to branch pick_50894
in repository https://gitbox.apache.org/repos/asf/doris.git
at 8630e41d92d branch-3.1: [refactor](Nereids) remove ListQuery expression #50894
This branch includes the following new commits:
new 8630e41d92d branch-3.1: [refactor](Nereids) remove ListQuery expression #50894
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org
(doris) 01/01: branch-3.1: [refactor](Nereids) remove ListQuery expression #50894
Posted by mo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
morrysnow pushed a commit to branch pick_50894
in repository https://gitbox.apache.org/repos/asf/doris.git
commit 8630e41d92de2b29b244b685d7c51e90988a5601
Author: morrySnow <zh...@selectdb.com>
AuthorDate: Thu May 15 11:38:40 2025 +0800
branch-3.1: [refactor](Nereids) remove ListQuery expression #50894
picked from #50894
---
.../doris/nereids/parser/LogicalPlanBuilder.java | 3 +-
.../nereids/rules/analysis/CheckAfterBind.java | 2 +-
.../nereids/rules/analysis/ExpressionAnalyzer.java | 19 +++---
.../nereids/rules/analysis/SubExprAnalyzer.java | 5 +-
.../nereids/rules/analysis/SubqueryToApply.java | 15 ++---
.../nereids/trees/copier/ExpressionDeepCopier.java | 16 +----
.../doris/nereids/trees/expressions/Exists.java | 7 +-
.../nereids/trees/expressions/InSubquery.java | 73 ++++++++-------------
.../doris/nereids/trees/expressions/ListQuery.java | 76 ----------------------
.../nereids/trees/expressions/SubqueryExpr.java | 26 +++-----
.../expressions/visitor/ExpressionVisitor.java | 5 --
.../doris/nereids/util/TypeCoercionUtils.java | 8 +--
.../subquery/test_subquery_in_project.groovy | 5 ++
13 files changed, 69 insertions(+), 191 deletions(-)
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
index a01b73ec9af..ce8fb4314f1 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
@@ -275,7 +275,6 @@ import org.apache.doris.nereids.trees.expressions.IsNull;
import org.apache.doris.nereids.trees.expressions.LessThan;
import org.apache.doris.nereids.trees.expressions.LessThanEqual;
import org.apache.doris.nereids.trees.expressions.Like;
-import org.apache.doris.nereids.trees.expressions.ListQuery;
import org.apache.doris.nereids.trees.expressions.MatchAll;
import org.apache.doris.nereids.trees.expressions.MatchAny;
import org.apache.doris.nereids.trees.expressions.MatchPhrase;
@@ -3388,7 +3387,7 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
} else {
outExpression = new InSubquery(
valueExpression,
- new ListQuery(typedVisit(ctx.query())),
+ typedVisit(ctx.query()),
ctx.NOT() != null
);
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/CheckAfterBind.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/CheckAfterBind.java
index e90e868a510..e0395668e7d 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/CheckAfterBind.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/CheckAfterBind.java
@@ -56,7 +56,7 @@ public class CheckAfterBind implements AnalysisRuleFactory {
Set<Expression> havingConjuncts = having.getConjuncts();
for (Expression predicate : havingConjuncts) {
if (predicate instanceof InSubquery) {
- if (((InSubquery) predicate).getListQuery().getDataType().isObjectType()) {
+ if (((InSubquery) predicate).getSubqueryOutput().getDataType().isObjectType()) {
throw new AnalysisException(Type.OnlyMetricTypeErrorMsg);
}
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/ExpressionAnalyzer.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/ExpressionAnalyzer.java
index 51fee5c1bba..c2dce7f591e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/ExpressionAnalyzer.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/ExpressionAnalyzer.java
@@ -55,7 +55,6 @@ import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.InPredicate;
import org.apache.doris.nereids.trees.expressions.InSubquery;
import org.apache.doris.nereids.trees.expressions.IntegralDivide;
-import org.apache.doris.nereids.trees.expressions.ListQuery;
import org.apache.doris.nereids.trees.expressions.Match;
import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.Not;
@@ -747,17 +746,21 @@ public class ExpressionAnalyzer extends SubExprAnalyzer<ExpressionRewriteContext
// compareExpr already analyze when invoke super.visitInSubquery
Expression newCompareExpr = inSubquery.getCompareExpr();
- // but ListQuery does not analyze
- Expression newListQuery = inSubquery.getListQuery().accept(this, context);
+ Optional<Expression> typeCoercionExpr = inSubquery.getTypeCoercionExpr();
- ComparisonPredicate afterTypeCoercion = (ComparisonPredicate) TypeCoercionUtils.processComparisonPredicate(
- new EqualTo(newCompareExpr, newListQuery));
- if (newListQuery.getDataType().isBitmapType()) {
+ // ATTN: support a trick usage of Doris: integral type in bitmap union column. For example:
+ // SELECT 1 IN (SELECT bitmap_empty() FROM DUAL);
+ if (inSubquery.getSubqueryOutput().getDataType().isBitmapType()) {
if (!newCompareExpr.getDataType().isBigIntType()) {
newCompareExpr = new Cast(newCompareExpr, BigIntType.INSTANCE);
}
} else {
+ ComparisonPredicate afterTypeCoercion = (ComparisonPredicate) TypeCoercionUtils.processComparisonPredicate(
+ new EqualTo(newCompareExpr, inSubquery.getSubqueryOutput()));
newCompareExpr = afterTypeCoercion.left();
+ if (afterTypeCoercion.right() != inSubquery.getSubqueryOutput()) {
+ typeCoercionExpr = Optional.of(afterTypeCoercion.right());
+ }
}
if (getScope().getOuterScope().isPresent()) {
Scope outerScope = getScope().getOuterScope().get();
@@ -769,8 +772,8 @@ public class ExpressionAnalyzer extends SubExprAnalyzer<ExpressionRewriteContext
}
}
}
- return new InSubquery(newCompareExpr, (ListQuery) afterTypeCoercion.right(),
- inSubquery.getCorrelateSlots(), ((ListQuery) afterTypeCoercion.right()).getTypeCoercionExpr(),
+ return new InSubquery(newCompareExpr, inSubquery.getQueryPlan(),
+ inSubquery.getCorrelateSlots(), typeCoercionExpr,
inSubquery.isNot());
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SubExprAnalyzer.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SubExprAnalyzer.java
index e0d809c9f1a..fb0b742f444 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SubExprAnalyzer.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SubExprAnalyzer.java
@@ -24,7 +24,6 @@ import org.apache.doris.nereids.trees.expressions.Alias;
import org.apache.doris.nereids.trees.expressions.Exists;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.InSubquery;
-import org.apache.doris.nereids.trees.expressions.ListQuery;
import org.apache.doris.nereids.trees.expressions.Not;
import org.apache.doris.nereids.trees.expressions.ScalarSubquery;
import org.apache.doris.nereids.trees.expressions.Slot;
@@ -75,7 +74,7 @@ class SubExprAnalyzer<T> extends DefaultExpressionRewriter<T> {
new Exists(((Exists) child).getQueryPlan(), true), context);
} else if (child instanceof InSubquery) {
return visitInSubquery(new InSubquery(((InSubquery) child).getCompareExpr(),
- ((InSubquery) child).getListQuery(), true), context);
+ ((InSubquery) child).getQueryPlan(), true), context);
}
return visit(not, context);
}
@@ -114,7 +113,7 @@ class SubExprAnalyzer<T> extends DefaultExpressionRewriter<T> {
return new InSubquery(
expr.getCompareExpr().accept(this, context),
- new ListQuery(analyzedResult.getLogicalPlan()),
+ analyzedResult.getLogicalPlan(),
analyzedResult.getCorrelatedSlots(), expr.isNot());
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SubqueryToApply.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SubqueryToApply.java
index c0a62e0c991..2e41a88c62f 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SubqueryToApply.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/SubqueryToApply.java
@@ -25,7 +25,6 @@ import org.apache.doris.nereids.rules.Rule;
import org.apache.doris.nereids.rules.RuleType;
import org.apache.doris.nereids.rules.expression.ExpressionRewriteContext;
import org.apache.doris.nereids.rules.expression.rules.TrySimplifyPredicateWithMarkJoinSlot;
-import org.apache.doris.nereids.trees.TreeNode;
import org.apache.doris.nereids.trees.expressions.Alias;
import org.apache.doris.nereids.trees.expressions.CompoundPredicate;
import org.apache.doris.nereids.trees.expressions.Exists;
@@ -33,7 +32,6 @@ import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.InSubquery;
import org.apache.doris.nereids.trees.expressions.IsNull;
import org.apache.doris.nereids.trees.expressions.LessThanEqual;
-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.Or;
@@ -226,7 +224,7 @@ public class SubqueryToApply implements AnalysisRuleFactory {
}
ImmutableList<Set<SubqueryExpr>> subqueryExprsList = subqueryConjuncts.stream()
- .<Set<SubqueryExpr>>map(e -> e.collect(SubqueryToApply::canConvertToSupply))
+ .<Set<SubqueryExpr>>map(e -> e.collect(SubqueryExpr.class::isInstance))
.collect(ImmutableList.toImmutableList());
ImmutableList.Builder<Expression> newConjuncts = new ImmutableList.Builder<>();
LogicalPlan applyPlan;
@@ -286,16 +284,11 @@ public class SubqueryToApply implements AnalysisRuleFactory {
);
}
- private static boolean canConvertToSupply(TreeNode<Expression> expression) {
- // The subquery except ListQuery can be converted to Supply
- return expression instanceof SubqueryExpr && !(expression instanceof ListQuery);
- }
-
private static boolean isValidSubqueryConjunct(Expression expression) {
// only support 1 subquery expr in the expression
// don't support expression like subquery1 or subquery2
return expression
- .collectToList(SubqueryToApply::canConvertToSupply)
+ .collectToList(SubqueryExpr.class::isInstance)
.size() == 1;
}
@@ -322,7 +315,7 @@ public class SubqueryToApply implements AnalysisRuleFactory {
Set<Slot> rightOutputSlots = rightChild.getOutputSet();
for (int i = 0; i < size; ++i) {
Expression expression = subqueryConjuncts.get(i);
- List<SubqueryExpr> subqueryExprs = expression.collectToList(SubqueryToApply::canConvertToSupply);
+ List<SubqueryExpr> subqueryExprs = expression.collectToList(SubqueryExpr.class::isInstance);
RelatedInfo relatedInfo = RelatedInfo.UnSupported;
if (subqueryExprs.size() == 1) {
SubqueryExpr subqueryExpr = subqueryExprs.get(0);
@@ -748,7 +741,7 @@ public class SubqueryToApply implements AnalysisRuleFactory {
boolean hasSubqueryExpr = false;
ImmutableList.Builder<Set<SubqueryExpr>> subqueryExprsListBuilder = ImmutableList.builder();
for (Expression expression : exprs) {
- Set<SubqueryExpr> subqueries = expression.collect(SubqueryToApply::canConvertToSupply);
+ Set<SubqueryExpr> subqueries = expression.collect(SubqueryExpr.class::isInstance);
hasSubqueryExpr |= !subqueries.isEmpty();
subqueryExprsListBuilder.add(subqueries);
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/ExpressionDeepCopier.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/ExpressionDeepCopier.java
index 60a5603f9a2..db9f4306f16 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/ExpressionDeepCopier.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/ExpressionDeepCopier.java
@@ -23,7 +23,6 @@ import org.apache.doris.nereids.trees.expressions.Exists;
import org.apache.doris.nereids.trees.expressions.ExprId;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.InSubquery;
-import org.apache.doris.nereids.trees.expressions.ListQuery;
import org.apache.doris.nereids.trees.expressions.ScalarSubquery;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.SlotReference;
@@ -131,27 +130,16 @@ public class ExpressionDeepCopier extends DefaultExpressionRewriter<DeepCopierCo
return new Exists(logicalPlan, correlateSlots, typeCoercionExpr, exists.isNot());
}
- @Override
- public Expression visitListQuery(ListQuery listQuery, DeepCopierContext context) {
- LogicalPlan logicalPlan = LogicalPlanDeepCopier.INSTANCE.deepCopy(listQuery.getQueryPlan(), context);
- List<Slot> correlateSlots = listQuery.getCorrelateSlots().stream()
- .map(s -> (Slot) s.accept(this, context))
- .collect(Collectors.toList());
- Optional<Expression> typeCoercionExpr = listQuery.getTypeCoercionExpr()
- .map(c -> c.accept(this, context));
- return new ListQuery(logicalPlan, correlateSlots, typeCoercionExpr);
- }
-
@Override
public Expression visitInSubquery(InSubquery in, DeepCopierContext context) {
+ LogicalPlan logicalPlan = LogicalPlanDeepCopier.INSTANCE.deepCopy(in.getQueryPlan(), context);
Expression compareExpr = in.getCompareExpr().accept(this, context);
List<Slot> correlateSlots = in.getCorrelateSlots().stream()
.map(s -> (Slot) s.accept(this, context))
.collect(Collectors.toList());
Optional<Expression> typeCoercionExpr = in.getTypeCoercionExpr()
.map(c -> c.accept(this, context));
- ListQuery listQuery = (ListQuery) in.getListQuery().accept(this, context);
- return new InSubquery(compareExpr, listQuery, correlateSlots, typeCoercionExpr, in.isNot());
+ return new InSubquery(compareExpr, logicalPlan, correlateSlots, typeCoercionExpr, in.isNot());
}
@Override
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Exists.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Exists.java
index dc5a348bec6..c95882a71e2 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Exists.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Exists.java
@@ -18,12 +18,14 @@
package org.apache.doris.nereids.trees.expressions;
import org.apache.doris.nereids.exceptions.UnboundException;
+import org.apache.doris.nereids.trees.expressions.shape.LeafExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
import org.apache.doris.nereids.types.BooleanType;
import org.apache.doris.nereids.types.DataType;
import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.Objects;
@@ -32,13 +34,12 @@ import java.util.Optional;
/**
* Exists subquery expression.
*/
-public class Exists extends SubqueryExpr {
+public class Exists extends SubqueryExpr implements LeafExpression {
private final boolean isNot;
public Exists(LogicalPlan subquery, boolean isNot) {
- super(Objects.requireNonNull(subquery, "subquery can not be null"));
- this.isNot = isNot;
+ this(subquery, ImmutableList.of(), Optional.empty(), isNot);
}
public Exists(LogicalPlan subquery, List<Slot> correlateSlots, boolean isNot) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/InSubquery.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/InSubquery.java
index 89b51e37465..6b77700a4c8 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/InSubquery.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/InSubquery.java
@@ -18,13 +18,14 @@
package org.apache.doris.nereids.trees.expressions;
import org.apache.doris.nereids.exceptions.UnboundException;
+import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
import org.apache.doris.nereids.types.BooleanType;
import org.apache.doris.nereids.types.DataType;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
+import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.Objects;
@@ -33,20 +34,15 @@ import java.util.Optional;
/**
* In predicate expression.
*/
-public class InSubquery extends SubqueryExpr {
+public class InSubquery extends SubqueryExpr implements UnaryExpression {
- private final Expression compareExpr;
- private final ListQuery listQuery;
private final boolean isNot;
- public InSubquery(Expression compareExpression, ListQuery listQuery, boolean isNot) {
- super(Objects.requireNonNull(listQuery.getQueryPlan(), "subquery can not be null"));
- this.compareExpr = Objects.requireNonNull(compareExpression, "compareExpr can not be null");
- this.listQuery = Objects.requireNonNull(listQuery, "listQuery can not be null");
- this.isNot = isNot;
+ public InSubquery(Expression compareExpression, LogicalPlan listQuery, boolean isNot) {
+ this(compareExpression, listQuery, ImmutableList.of(), Optional.empty(), isNot);
}
- public InSubquery(Expression compareExpr, ListQuery listQuery, List<Slot> correlateSlots, boolean isNot) {
+ public InSubquery(Expression compareExpr, LogicalPlan listQuery, List<Slot> correlateSlots, boolean isNot) {
this(compareExpr, listQuery, correlateSlots, Optional.empty(), isNot);
}
@@ -54,15 +50,11 @@ public class InSubquery extends SubqueryExpr {
* InSubquery Constructor.
*/
public InSubquery(Expression compareExpr,
- ListQuery listQuery,
- List<Slot> correlateSlots,
- Optional<Expression> typeCoercionExpr,
- boolean isNot) {
- super(Objects.requireNonNull(listQuery.getQueryPlan(), "subquery can not be null"),
- Objects.requireNonNull(correlateSlots, "correlateSlots can not be null"),
- typeCoercionExpr);
- this.compareExpr = Objects.requireNonNull(compareExpr, "compareExpr can not be null");
- this.listQuery = Objects.requireNonNull(listQuery, "listQuery can not be null");
+ LogicalPlan listQuery,
+ List<Slot> correlateSlots,
+ Optional<Expression> typeCoercionExpr,
+ boolean isNot) {
+ super(listQuery, correlateSlots, typeCoercionExpr, compareExpr);
this.isNot = isNot;
}
@@ -73,17 +65,17 @@ public class InSubquery extends SubqueryExpr {
@Override
public boolean nullable() throws UnboundException {
- return super.nullable() || this.compareExpr.nullable();
+ return super.nullable() || this.child().nullable();
}
@Override
public String computeToSql() {
- return this.compareExpr.toSql() + " IN (" + super.computeToSql() + ")";
+ return this.child().toSql() + " IN (" + super.computeToSql() + ")";
}
@Override
public String toString() {
- return this.compareExpr + " IN (INSUBQUERY) " + super.toString();
+ return this.child() + " IN (INSUBQUERY) " + super.toString();
}
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
@@ -91,27 +83,17 @@ public class InSubquery extends SubqueryExpr {
}
public Expression getCompareExpr() {
- return this.compareExpr;
+ return this.child();
}
public boolean isNot() {
return isNot;
}
- public ListQuery getListQuery() {
- return listQuery;
- }
-
@Override
public InSubquery withChildren(List<Expression> children) {
- Preconditions.checkArgument(children.size() == 2);
- Preconditions.checkArgument(children.get(1) instanceof ListQuery);
- return new InSubquery(children.get(0), (ListQuery) children.get(1), correlateSlots, typeCoercionExpr, isNot);
- }
-
- @Override
- public List<Expression> children() {
- return Lists.newArrayList(compareExpr, listQuery);
+ Preconditions.checkArgument(children.size() == 1);
+ return new InSubquery(children.get(0), queryPlan, correlateSlots, typeCoercionExpr, isNot);
}
@Override
@@ -119,29 +101,28 @@ public class InSubquery extends SubqueryExpr {
if (!super.equals(o)) {
return false;
}
- InSubquery inSubquery = (InSubquery) o;
- return super.equals(inSubquery)
- && Objects.equals(this.compareExpr, inSubquery.getCompareExpr())
- && Objects.equals(this.listQuery, inSubquery.listQuery)
- && this.isNot == inSubquery.isNot;
+ InSubquery other = (InSubquery) o;
+ return super.equals(other)
+ && Objects.equals(this.child(), other.getCompareExpr())
+ && this.isNot == other.isNot;
}
@Override
public int computeHashCode() {
- return Objects.hash(this.compareExpr, this.listQuery, this.isNot);
+ return Objects.hash(super.computeHashCode(), this.child(), this.isNot);
}
@Override
public Expression withTypeCoercion(DataType dataType) {
- return new InSubquery(compareExpr, listQuery, correlateSlots,
- dataType == listQuery.queryPlan.getOutput().get(0).getDataType()
- ? Optional.of(listQuery.queryPlan.getOutput().get(0))
- : Optional.of(new Cast(listQuery.queryPlan.getOutput().get(0), dataType)),
+ return new InSubquery(child(), queryPlan, correlateSlots,
+ dataType.equals(queryPlan.getOutput().get(0).getDataType())
+ ? Optional.of(queryPlan.getOutput().get(0))
+ : Optional.of(new Cast(queryPlan.getOutput().get(0), dataType)),
isNot);
}
@Override
public InSubquery withSubquery(LogicalPlan subquery) {
- return new InSubquery(compareExpr, listQuery.withSubquery(subquery), correlateSlots, typeCoercionExpr, isNot);
+ return new InSubquery(child(), subquery, correlateSlots, typeCoercionExpr, isNot);
}
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ListQuery.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ListQuery.java
deleted file mode 100644
index 16dade740b9..00000000000
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ListQuery.java
+++ /dev/null
@@ -1,76 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.doris.nereids.trees.expressions;
-
-import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
-import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
-import org.apache.doris.nereids.types.DataType;
-
-import com.google.common.base.Preconditions;
-
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-
-/**
- * Encapsulate LogicalPlan as Expression.
- * just for subquery.
- */
-public class ListQuery extends SubqueryExpr {
-
- public ListQuery(LogicalPlan subquery) {
- super(Objects.requireNonNull(subquery, "subquery can not be null"));
- }
-
- public ListQuery(LogicalPlan subquery, List<Slot> correlateSlots, Optional<Expression> typeCoercionExpr) {
- super(subquery, correlateSlots, typeCoercionExpr);
- }
-
- @Override
- public DataType getDataType() {
- Preconditions.checkArgument(queryPlan.getOutput().size() == 1);
- return typeCoercionExpr.orElse(queryPlan.getOutput().get(0)).getDataType();
- }
-
- @Override
- public String computeToSql() {
- return " (LISTQUERY) " + super.computeToSql();
- }
-
- @Override
- public String toString() {
- return " (LISTQUERY) " + super.toString();
- }
-
- public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
- return visitor.visitListQuery(this, context);
- }
-
- @Override
- public Expression withTypeCoercion(DataType dataType) {
- return new ListQuery(queryPlan, correlateSlots,
- dataType == queryPlan.getOutput().get(0).getDataType()
- ? Optional.of(queryPlan.getOutput().get(0))
- : Optional.of(new Cast(queryPlan.getOutput().get(0), dataType)));
- }
-
- @Override
- public ListQuery withSubquery(LogicalPlan subquery) {
- return new ListQuery(subquery, correlateSlots, typeCoercionExpr);
- }
-}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SubqueryExpr.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SubqueryExpr.java
index 2011aa9607d..b0b59cf9148 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SubqueryExpr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SubqueryExpr.java
@@ -18,7 +18,6 @@
package org.apache.doris.nereids.trees.expressions;
import org.apache.doris.nereids.exceptions.UnboundException;
-import org.apache.doris.nereids.trees.expressions.shape.LeafExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
import org.apache.doris.nereids.types.DataType;
@@ -33,21 +32,23 @@ import java.util.Optional;
/**
* Subquery Expression.
*/
-public abstract class SubqueryExpr extends Expression implements LeafExpression {
+public abstract class SubqueryExpr extends Expression {
protected final LogicalPlan queryPlan;
protected final List<Slot> correlateSlots;
protected final Optional<Expression> typeCoercionExpr;
- protected SubqueryExpr(LogicalPlan subquery) {
+ protected SubqueryExpr(LogicalPlan subquery, List<Slot> correlateSlots,
+ Optional<Expression> typeCoercionExpr) {
super(ImmutableList.of());
this.queryPlan = Objects.requireNonNull(subquery, "subquery can not be null");
- this.correlateSlots = ImmutableList.of();
- this.typeCoercionExpr = Optional.empty();
+ this.correlateSlots = ImmutableList.copyOf(correlateSlots);
+ this.typeCoercionExpr = typeCoercionExpr;
}
- protected SubqueryExpr(LogicalPlan subquery, List<Slot> correlateSlots, Optional<Expression> typeCoercionExpr) {
- super(ImmutableList.of());
+ protected SubqueryExpr(LogicalPlan subquery, List<Slot> correlateSlots,
+ Optional<Expression> typeCoercionExpr, Expression child) {
+ super(ImmutableList.of(Objects.requireNonNull(child, "child can not be null")));
this.queryPlan = Objects.requireNonNull(subquery, "subquery can not be null");
this.correlateSlots = ImmutableList.copyOf(correlateSlots);
this.typeCoercionExpr = typeCoercionExpr;
@@ -65,10 +66,6 @@ public abstract class SubqueryExpr extends Expression implements LeafExpression
return typeCoercionExpr.orElseGet(() -> queryPlan.getOutput().get(0));
}
- public Expression getSubqueryOutput(LogicalPlan queryPlan) {
- return typeCoercionExpr.orElseGet(() -> queryPlan.getOutput().get(0));
- }
-
@Override
public DataType getDataType() throws UnboundException {
throw new UnboundException("getDataType");
@@ -115,10 +112,7 @@ public abstract class SubqueryExpr extends Expression implements LeafExpression
@Override
public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
+ if (!super.equals(o)) {
return false;
}
SubqueryExpr other = (SubqueryExpr) o;
@@ -129,7 +123,7 @@ public abstract class SubqueryExpr extends Expression implements LeafExpression
@Override
public int computeHashCode() {
- return Objects.hash(queryPlan, correlateSlots, typeCoercionExpr);
+ return Objects.hash(super.computeHashCode(), queryPlan, correlateSlots, typeCoercionExpr);
}
public List<Slot> getOutput() {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ExpressionVisitor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ExpressionVisitor.java
index 406d0835610..c159589e6db 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ExpressionVisitor.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ExpressionVisitor.java
@@ -52,7 +52,6 @@ import org.apache.doris.nereids.trees.expressions.IntegralDivide;
import org.apache.doris.nereids.trees.expressions.IsNull;
import org.apache.doris.nereids.trees.expressions.LessThan;
import org.apache.doris.nereids.trees.expressions.LessThanEqual;
-import org.apache.doris.nereids.trees.expressions.ListQuery;
import org.apache.doris.nereids.trees.expressions.MarkJoinSlotReference;
import org.apache.doris.nereids.trees.expressions.Match;
import org.apache.doris.nereids.trees.expressions.MatchAll;
@@ -429,10 +428,6 @@ public abstract class ExpressionVisitor<R, C>
return visitSubqueryExpr(scalar, context);
}
- public R visitListQuery(ListQuery listQuery, C context) {
- return visitSubqueryExpr(listQuery, context);
- }
-
public R visitGroupingScalarFunction(GroupingScalarFunction groupingScalarFunction, C context) {
return visit(groupingScalarFunction, context);
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java
index fd98f2e02bb..0efaca36630 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java
@@ -450,7 +450,7 @@ public class TypeCoercionUtils {
public static Expression castIfNotSameType(Expression input, DataType targetType) {
if (input.isNullLiteral()) {
return new NullLiteral(targetType);
- } else if (input.getDataType().equals(targetType) || isSubqueryAndDataTypeIsBitmap(input)
+ } else if (input.getDataType().equals(targetType)
|| (input.getDataType().isStringLikeType()) && targetType.isStringLikeType()) {
return input;
} else {
@@ -473,7 +473,7 @@ public class TypeCoercionUtils {
public static Expression castIfNotSameTypeStrict(Expression input, DataType targetType) {
if (input.isNullLiteral()) {
return new NullLiteral(targetType);
- } else if (input.getDataType().equals(targetType) || isSubqueryAndDataTypeIsBitmap(input)) {
+ } else if (input.getDataType().equals(targetType)) {
return input;
} else {
checkCanCastTo(input.getDataType(), targetType);
@@ -481,10 +481,6 @@ public class TypeCoercionUtils {
}
}
- private static boolean isSubqueryAndDataTypeIsBitmap(Expression input) {
- return input instanceof SubqueryExpr && input.getDataType().isBitmapType();
- }
-
private static boolean canCastTo(DataType input, DataType target) {
return Type.canCastTo(input.toCatalogDataType(), target.toCatalogDataType());
}
diff --git a/regression-test/suites/nereids_p0/subquery/test_subquery_in_project.groovy b/regression-test/suites/nereids_p0/subquery/test_subquery_in_project.groovy
index 32802dbb7a1..e078081b079 100644
--- a/regression-test/suites/nereids_p0/subquery/test_subquery_in_project.groovy
+++ b/regression-test/suites/nereids_p0/subquery/test_subquery_in_project.groovy
@@ -41,6 +41,11 @@ suite("test_subquery_in_project") {
sql """ insert into test_sql values (1,'2020-09-09',2,3);"""
+ // in subquery with normalize agg, cast(abs(age) as int) should extract from upper project.
+ sql """
+ SELECT CAST(abs(age) AS int) IN (SELECT age FROM test_sql) FROM test_sql GROUP BY CAST(abs(age) AS int);
+ """
+
qt_sql1 """
select (select age from test_sql) col from test_sql order by col;
"""
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org