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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]