zhengshiJ commented on code in PR #11454:
URL: https://github.com/apache/doris/pull/11454#discussion_r961283463


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindSlotReference.java:
##########
@@ -319,4 +338,153 @@ public List<Slot> getSlots() {
             return (List) children();
         }
     }
+
+    /**
+     * Use the visitor to iterate sub expression.
+     */
+    private static class SubExprAnalyzer<C> extends 
DefaultExpressionRewriter<C> {
+        private final Scope scope;
+        private final CascadesContext cascadesContext;
+
+        public SubExprAnalyzer(Scope scope, CascadesContext cascadesContext) {
+            this.scope = scope;
+            this.cascadesContext = cascadesContext;
+        }
+
+        @Override
+        public Expression visitNot(Not not, C context) {
+            Expression child = not.child();
+            if (child instanceof Exists) {
+                return visitExistsSubquery(
+                        new Exists(((Exists) child).getQueryPlan(), true), 
context);
+            } else if (child instanceof InSubquery) {
+                return visitInSubquery(new InSubquery(((InSubquery) 
child).getCompareExpr(),
+                        ((InSubquery) child).getListQuery(), true), context);
+            }
+            return visit(not, context);
+        }
+
+        @Override
+        public Expression visitExistsSubquery(Exists exists, C context) {
+            AnalyzedResult analyzedResult = analyzeSubquery(exists);
+
+            return new Exists(analyzedResult.getLogicalPlan(),
+                    getSlots(exists, analyzedResult), exists.isNot());
+        }
+
+        @Override
+        public Expression visitInSubquery(InSubquery expr, C context) {
+            AnalyzedResult analyzedResult = analyzeSubquery(expr);
+
+            checkOutputColumn(analyzedResult.getLogicalPlan());
+            checkHasGroupBy(analyzedResult);
+
+            return new InSubquery(
+                    expr.getCompareExpr().accept(this, context),
+                    new ListQuery(analyzedResult.getLogicalPlan()),
+                    getSlots(expr, analyzedResult), expr.isNot());
+        }
+
+        @Override
+        public Expression visitScalarSubquery(ScalarSubquery scalar, C 
context) {
+            AnalyzedResult analyzedResult = analyzeSubquery(scalar);
+
+            checkOutputColumn(analyzedResult.getLogicalPlan());
+            checkRootIsAgg(analyzedResult);
+            checkHasGroupBy(analyzedResult);
+
+            return new ScalarSubquery(analyzedResult.getLogicalPlan(), 
getSlots(scalar, analyzedResult));
+        }
+
+        private void checkOutputColumn(LogicalPlan plan) {
+            if (plan.getOutput().size() != 1) {
+                throw new AnalysisException("Multiple columns returned by 
subquery are not yet supported. Found "
+                        + plan.getOutput().size());
+            }
+        }
+
+        private void checkRootIsAgg(AnalyzedResult analyzedResult) {
+            if (!analyzedResult.isCorrelated()) {
+                return;
+            }
+            if (!analyzedResult.rootIsAgg()) {
+                throw new AnalysisException("The select item in correlated 
subquery of binary predicate "
+                        + "should only be sum, min, max, avg and count. 
Current subquery: "
+                        + analyzedResult.getLogicalPlan());
+            }
+        }
+
+        private void checkHasGroupBy(AnalyzedResult analyzedResult) {
+            if (!analyzedResult.isCorrelated()) {
+                return;
+            }
+            if (analyzedResult.hasGroupBy()) {
+                throw new AnalysisException("Unsupported correlated subquery 
with grouping and/or aggregation "
+                        + analyzedResult.getLogicalPlan());
+            }
+        }
+
+        private AnalyzedResult analyzeSubquery(SubqueryExpr expr) {
+            CascadesContext subqueryContext = new Memo(expr.getQueryPlan())
+                    
.newCascadesContext((cascadesContext.getStatementContext()));
+            Scope subqueryScope = genScopeWithSubquery(expr);
+            subqueryContext
+                    .newAnalyzer(Optional.of(subqueryScope))
+                    .analyze();
+            return new AnalyzedResult((LogicalPlan) 
subqueryContext.getMemo().copyOut(false),
+                    subqueryScope.getCorrelatedSlots(expr));
+        }
+
+        private Scope genScopeWithSubquery(SubqueryExpr expr) {
+            return new Scope(getScope().getOuterScope(),
+                    getScope().getSlots(),
+                    Optional.ofNullable(expr));
+        }
+
+        private List<Slot> getSlots(SubqueryExpr subqueryExpr, AnalyzedResult 
analyzedResult) {
+            return analyzedResult.getCorrelatedSlots().isEmpty()
+                    ? subqueryExpr.getCorrelateSlots() : 
analyzedResult.getCorrelatedSlots();

Review Comment:
   done



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalApply.java:
##########
@@ -29,48 +33,84 @@
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
 
 /**
- * Apply Node for subquery.
  * Use this node to display the subquery in the relational algebra tree.
- * refer to "Orthogonal Optimization of Subqueries and Aggregation"
- *
- * @param <LEFT_CHILD_TYPE> input
- * @param <RIGHT_CHILD_TYPE> subquery
+ * @param <LEFT_CHILD_TYPE> input.
+ * @param <RIGHT_CHILD_TYPE> subquery.
  */
 public class LogicalApply<LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE 
extends Plan>
         extends LogicalBinary<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
-    // correlation : subqueries and outer associated columns
-    private final List<Expression> correlation;
+    // correlation column
+    private final List<Expression> correlationSlot;
+    // original subquery
+    private final SubqueryExpr subqueryExpr;
+    // correlation Conjunction
+    private final Optional<Expression> correlationFilter;
+
+    /**
+     * Constructor.
+     */
+    public LogicalApply(Optional<GroupExpression> groupExpression,
+            Optional<LogicalProperties> logicalProperties,
+            LEFT_CHILD_TYPE leftChild, RIGHT_CHILD_TYPE rightChild, 
List<Expression> correlationSlot,
+            SubqueryExpr subqueryExpr, Optional<Expression> correlationFilter) 
{
+        super(PlanType.LOGICAL_APPLY, groupExpression, logicalProperties, 
leftChild, rightChild);
+        this.correlationSlot = correlationSlot == null ? new ArrayList<>() : 
ImmutableList.copyOf(correlationSlot);

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to