This is an automated email from the ASF dual-hosted git repository.

lihaopeng pushed a commit to branch branch-1.2-lts
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-1.2-lts by this push:
     new 2ebe5ef5cf [fix](fe)project should be done inside subquery (#18012)
2ebe5ef5cf is described below

commit 2ebe5ef5cf6c19e065ea77db2469d1b75474b1ec
Author: starocean999 <40539150+starocean...@users.noreply.github.com>
AuthorDate: Wed Mar 22 10:41:56 2023 +0800

    [fix](fe)project should be done inside subquery (#18012)
---
 .../org/apache/doris/analysis/SlotDescriptor.java  |  6 ++-
 .../org/apache/doris/planner/JoinNodeBase.java     | 12 ++---
 .../apache/doris/planner/NestedLoopJoinNode.java   |  4 +-
 .../java/org/apache/doris/planner/ScanNode.java    | 56 ++++++++++++++++++++++
 .../java/org/apache/doris/planner/SelectNode.java  |  3 +-
 5 files changed, 71 insertions(+), 10 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotDescriptor.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotDescriptor.java
index f4a67fe167..b68ea31778 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotDescriptor.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotDescriptor.java
@@ -80,7 +80,7 @@ public class SlotDescriptor {
         this.isMultiRef = false;
     }
 
-    SlotDescriptor(SlotId id, TupleDescriptor parent, SlotDescriptor src) {
+    public SlotDescriptor(SlotId id, TupleDescriptor parent, SlotDescriptor 
src) {
         this.id = id;
         this.parent = parent;
         this.byteOffset = src.byteOffset;
@@ -154,6 +154,10 @@ public class SlotDescriptor {
         this.originType = column.getOriginType();
     }
 
+    public void setSrcColumn(Column column) {
+        this.column = column;
+    }
+
     public boolean isMaterialized() {
         return isMaterialized;
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/JoinNodeBase.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/JoinNodeBase.java
index 5d81033362..21ef809f31 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/JoinNodeBase.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/JoinNodeBase.java
@@ -593,19 +593,19 @@ public abstract class JoinNodeBase extends PlanNode {
                 Lists.newArrayList(vSrcToOutputSMap.getLhs()));
         List<Expr> newRhs = Lists.newArrayList();
         boolean bSmapChanged = false;
-        for (Expr expr : smap.getRhs()) {
-            if (expr instanceof SlotRef) {
-                newRhs.add(expr);
+        for (Expr rhsExpr : smap.getRhs()) {
+            if (rhsExpr instanceof SlotRef || 
!rhsExpr.isBound(vOutputTupleDesc.getId())) {
+                newRhs.add(rhsExpr);
             } else {
                 // we need do project in the join node
                 // add a new slot for projection result and add the project 
expr to vSrcToOutputSMap
                 SlotDescriptor slotDesc = 
analyzer.addSlotDescriptor(vOutputTupleDesc);
-                slotDesc.initFromExpr(expr);
+                slotDesc.initFromExpr(rhsExpr);
                 slotDesc.setIsMaterialized(true);
                 // the project expr is from smap, which use the slots of hash 
join node's output tuple
                 // we need substitute it to make sure the project expr use 
slots from intermediate tuple
-                expr.substitute(tmpSmap);
-                vSrcToOutputSMap.getLhs().add(expr);
+                rhsExpr = rhsExpr.substitute(tmpSmap);
+                vSrcToOutputSMap.getLhs().add(rhsExpr);
                 SlotRef slotRef = new SlotRef(slotDesc);
                 vSrcToOutputSMap.getRhs().add(slotRef);
                 newRhs.add(slotRef);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/planner/NestedLoopJoinNode.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/NestedLoopJoinNode.java
index 4f4f0dfded..421c534860 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/NestedLoopJoinNode.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/NestedLoopJoinNode.java
@@ -70,8 +70,8 @@ public class NestedLoopJoinNode extends JoinNodeBase {
 
     public NestedLoopJoinNode(PlanNodeId id, PlanNode outer, PlanNode inner, 
TableRef innerRef) {
         super(id, "NESTED LOOP JOIN", StatisticalType.NESTED_LOOP_JOIN_NODE, 
outer, inner, innerRef);
-        tupleIds.addAll(outer.getTupleIds());
-        tupleIds.addAll(inner.getTupleIds());
+        tupleIds.addAll(outer.getOutputTupleIds());
+        tupleIds.addAll(inner.getOutputTupleIds());
     }
 
     public boolean canParallelize() {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/ScanNode.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/ScanNode.java
index ac368176ed..5862667a06 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/ScanNode.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/ScanNode.java
@@ -24,14 +24,17 @@ import org.apache.doris.analysis.Analyzer;
 import org.apache.doris.analysis.BinaryPredicate;
 import org.apache.doris.analysis.CompoundPredicate;
 import org.apache.doris.analysis.Expr;
+import org.apache.doris.analysis.ExprSubstitutionMap;
 import org.apache.doris.analysis.InPredicate;
 import org.apache.doris.analysis.IsNullPredicate;
 import org.apache.doris.analysis.LiteralExpr;
 import org.apache.doris.analysis.NullLiteral;
 import org.apache.doris.analysis.PredicateUtils;
 import org.apache.doris.analysis.SlotDescriptor;
+import org.apache.doris.analysis.SlotId;
 import org.apache.doris.analysis.SlotRef;
 import org.apache.doris.analysis.TupleDescriptor;
+import org.apache.doris.analysis.TupleId;
 import org.apache.doris.catalog.Column;
 import org.apache.doris.catalog.PrimitiveType;
 import org.apache.doris.common.UserException;
@@ -52,6 +55,7 @@ import org.apache.logging.log4j.Logger;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * Representation of the common elements of all scan nodes.
@@ -478,4 +482,56 @@ public abstract class ScanNode extends PlanNode {
                 desc.getTable().getName()).add("keyRanges", "").addValue(
                 super.debugString()).toString();
     }
+
+    public void setOutputSmap(ExprSubstitutionMap smap, Analyzer analyzer) {
+        outputSmap = smap;
+        if (smap.getRhs().stream().anyMatch(expr -> !(expr instanceof 
SlotRef))) {
+            if (outputTupleDesc == null) {
+                outputTupleDesc = 
analyzer.getDescTbl().createTupleDescriptor("OlapScanNode");
+            }
+            if (projectList == null) {
+                projectList = Lists.newArrayList();
+            }
+            // setOutputSmap may be called multiple times
+            // this happens if the olap table is in the most inner sub-query 
block in the cascades sub-queries
+            // create a tmpSmap for the later setOutputSmap call
+            ExprSubstitutionMap tmpSmap = new ExprSubstitutionMap(
+                    
Lists.newArrayList(outputTupleDesc.getSlots().stream().map(slot -> new 
SlotRef(slot)).collect(
+                            Collectors.toList())), 
Lists.newArrayList(projectList));
+            Set<SlotId> allOutputSlotIds = 
outputTupleDesc.getSlots().stream().map(slot -> slot.getId())
+                    .collect(Collectors.toSet());
+            List<Expr> newRhs = Lists.newArrayList();
+            List<Expr> rhs = smap.getRhs();
+            for (int i = 0; i < smap.size(); ++i) {
+                Expr rhsExpr = rhs.get(i);
+                if (!(rhsExpr instanceof SlotRef) || 
!(allOutputSlotIds.contains(((SlotRef) rhsExpr).getSlotId()))) {
+                    rhsExpr = rhsExpr.substitute(tmpSmap);
+                    if (rhsExpr.isBound(desc.getId())) {
+                        SlotDescriptor slotDesc = 
analyzer.addSlotDescriptor(outputTupleDesc);
+                        slotDesc.initFromExpr(rhsExpr);
+                        if (rhsExpr instanceof SlotRef) {
+                            slotDesc.setSrcColumn(((SlotRef) 
rhsExpr).getColumn());
+                        }
+                        slotDesc.setIsMaterialized(true);
+                        slotDesc.materializeSrcExpr();
+                        projectList.add(rhsExpr);
+                        newRhs.add(new SlotRef(slotDesc));
+                        allOutputSlotIds.add(slotDesc.getId());
+                    } else {
+                        newRhs.add(rhs.get(i));
+                    }
+                } else {
+                    newRhs.add(rhsExpr);
+                }
+            }
+            outputSmap.updateRhsExprs(newRhs);
+        }
+    }
+
+    public List<TupleId> getOutputTupleIds() {
+        if (outputTupleDesc != null) {
+            return Lists.newArrayList(outputTupleDesc.getId());
+        }
+        return tupleIds;
+    }
 }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/SelectNode.java 
b/fe/fe-core/src/main/java/org/apache/doris/planner/SelectNode.java
index 2baa6e6f13..6d78b5cb48 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/SelectNode.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/SelectNode.java
@@ -32,6 +32,7 @@ import org.apache.doris.thrift.TPlanNodeType;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -41,7 +42,7 @@ public class SelectNode extends PlanNode {
     private static final Logger LOG = LogManager.getLogger(SelectNode.class);
 
     protected SelectNode(PlanNodeId id, PlanNode child, List<Expr> conjuncts) {
-        super(id, child.getTupleIds(), "SELECT", StatisticalType.SELECT_NODE);
+        super(id, new ArrayList<>(child.getOutputTupleIds()), "SELECT", 
StatisticalType.SELECT_NODE);
         addChild(child);
         this.tblRefIds = child.tblRefIds;
         this.nullableTupleIds = child.nullableTupleIds;


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

Reply via email to