This is an automated email from the ASF dual-hosted git repository.
morrysnow pushed a commit to branch branch-3.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-3.1 by this push:
new 7e9fb782675 branch-3.1: [refactor](Nereids) remove ListQuery
expression #50894 (#57709)
7e9fb782675 is described below
commit 7e9fb782675ad1340e96809de3c6004ce75a47eb
Author: morrySnow <[email protected]>
AuthorDate: Thu Nov 6 11:57:46 2025 +0800
branch-3.1: [refactor](Nereids) remove ListQuery expression #50894 (#57709)
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: [email protected]
For additional commands, e-mail: [email protected]