You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by yi...@apache.org on 2023/07/08 14:25:21 UTC
[doris] 03/04: f
This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-1.2-lts
in repository https://gitbox.apache.org/repos/asf/doris.git
commit bb9925e0e2ecf833a0674a054c3c9cf644613957
Author: yiguolei <yi...@gmail.com>
AuthorDate: Fri Jul 7 17:16:51 2023 +0800
f
---
.../apache/doris/analysis/ExprSubstitutionMap.java | 28 +++++++----
.../org/apache/doris/planner/JoinNodeBase.java | 58 ++++++++++++----------
2 files changed, 51 insertions(+), 35 deletions(-)
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ExprSubstitutionMap.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ExprSubstitutionMap.java
index 65f9d2f8e0..b8008fde77 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ExprSubstitutionMap.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ExprSubstitutionMap.java
@@ -33,11 +33,15 @@ import java.util.Objects;
/**
* Map of expression substitutions: lhs[i] gets substituted with rhs[i].
- * To support expression substitution across query blocks, rhs exprs must already be
- * analyzed when added to this map. Otherwise, analysis of a SlotRef may fail after
- * substitution, e.g., because the table it refers to is in a different query block
+ * To support expression substitution across query blocks, rhs exprs must
+ * already be
+ * analyzed when added to this map. Otherwise, analysis of a SlotRef may fail
+ * after
+ * substitution, e.g., because the table it refers to is in a different query
+ * block
* that is not visible.
- * See Expr.substitute() and related functions for details on the actual substitution.
+ * See Expr.substitute() and related functions for details on the actual
+ * substitution.
*/
public final class ExprSubstitutionMap {
private static final Logger LOG = LogManager.getLogger(ExprSubstitutionMap.class);
@@ -62,7 +66,8 @@ public final class ExprSubstitutionMap {
}
/**
- * Add an expr mapping. The rhsExpr must be analyzed to support correct substitution
+ * Add an expr mapping. The rhsExpr must be analyzed to support correct
+ * substitution
* across query blocks. It is not required that the lhsExpr is analyzed.
*/
public void put(Expr lhsExpr, Expr rhsExpr) {
@@ -132,7 +137,7 @@ public final class ExprSubstitutionMap {
}
/**
- * Return a map which is equivalent to applying f followed by g,
+ * Return a map which is equivalent to applying f followed by g,
* i.e., g(f()).
* Always returns a non-null map.
*/
@@ -208,7 +213,8 @@ public final class ExprSubstitutionMap {
/**
* Returns the replace of two substitution maps.
- * f [A.id, B.id] [A.age, B.age] [A.name, B.name] g [A.id, C.id] [B.age, C.age] [A.address, C.address]
+ * f [A.id, B.id] [A.age, B.age] [A.name, B.name] g [A.id, C.id] [B.age, C.age]
+ * [A.address, C.address]
* return: [A.id, C,id] [A.age, C.age] [A.name, B.name] [A.address, C.address]
*/
public static ExprSubstitutionMap composeAndReplace(ExprSubstitutionMap f, ExprSubstitutionMap g, Analyzer analyzer)
@@ -304,11 +310,13 @@ public final class ExprSubstitutionMap {
}
/**
- * Verifies the internal state of this smap: Checks that the lhs_ has no duplicates,
+ * Verifies the internal state of this smap: Checks that the lhs_ has no
+ * duplicates,
* and that all rhs exprs are analyzed.
*/
private void verify() {
- // This method is very very time consuming, especially when planning large complex query.
+ // This method is very very time consuming, especially when planning large
+ // complex query.
// So disable it by default.
if (LOG.isDebugEnabled()) {
for (int i = 0; i < lhs.size(); ++i) {
@@ -340,7 +348,7 @@ public final class ExprSubstitutionMap {
Preconditions.checkState(lhs.size() == rhs.size(), "lhs and rhs must be same size");
for (int i = 0; i < rhs.size(); i++) {
if (rhs.get(i) instanceof SlotRef) {
- ((SlotRef) rhs.get(i)).getDesc().setIsNullable(lhs.get(i).isNullable());
+ ((SlotRef) rhs.get(i)).getDesc().setIsNullable(lhs.get(i).isNullable() || ((SlotRef) rhs.get(i)).getDesc().getIsNullable());
}
}
}
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 19921125e3..bdf5c0f161 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
@@ -158,21 +158,22 @@ public abstract class JoinNodeBase extends PlanNode {
int leftNullableNumber = 0;
int rightNullableNumber = 0;
if (copyLeft) {
- //cross join do not have OutputTblRefIds
+ // cross join do not have OutputTblRefIds
List<TupleId> srcTupleIds = getChild(0) instanceof JoinNodeBase ? getChild(0).getOutputTupleIds()
: getChild(0).getOutputTblRefIds();
for (TupleDescriptor leftTupleDesc : analyzer.getDescTbl().getTupleDesc(srcTupleIds)) {
- // if the child is cross join node, the only way to get the correct nullable info of its output slots
+ // if the child is cross join node, the only way to get the correct nullable
+ // info of its output slots
// is to check if the output tuple ids are outer joined or not.
// then pass this nullable info to hash join node will be correct.
- boolean needSetToNullable =
- getChild(0) instanceof JoinNodeBase && analyzer.isOuterJoined(leftTupleDesc.getId());
+ boolean needSetToNullable = getChild(0) instanceof JoinNodeBase
+ && analyzer.isOuterJoined(leftTupleDesc.getId());
for (SlotDescriptor leftSlotDesc : leftTupleDesc.getSlots()) {
if (!isMaterializedByChild(leftSlotDesc, getChild(0).getOutputSmap())) {
continue;
}
- SlotDescriptor outputSlotDesc =
- analyzer.getDescTbl().copySlotDescriptor(vOutputTupleDesc, leftSlotDesc);
+ SlotDescriptor outputSlotDesc = analyzer.getDescTbl().copySlotDescriptor(vOutputTupleDesc,
+ leftSlotDesc);
if (leftNullable) {
outputSlotDesc.setIsNullable(true);
leftNullableNumber++;
@@ -188,14 +189,14 @@ public abstract class JoinNodeBase extends PlanNode {
List<TupleId> srcTupleIds = getChild(1) instanceof JoinNodeBase ? getChild(1).getOutputTupleIds()
: getChild(1).getOutputTblRefIds();
for (TupleDescriptor rightTupleDesc : analyzer.getDescTbl().getTupleDesc(srcTupleIds)) {
- boolean needSetToNullable =
- getChild(1) instanceof JoinNodeBase && analyzer.isOuterJoined(rightTupleDesc.getId());
+ boolean needSetToNullable = getChild(1) instanceof JoinNodeBase
+ && analyzer.isOuterJoined(rightTupleDesc.getId());
for (SlotDescriptor rightSlotDesc : rightTupleDesc.getSlots()) {
if (!isMaterializedByChild(rightSlotDesc, getChild(1).getOutputSmap())) {
continue;
}
- SlotDescriptor outputSlotDesc =
- analyzer.getDescTbl().copySlotDescriptor(vOutputTupleDesc, rightSlotDesc);
+ SlotDescriptor outputSlotDesc = analyzer.getDescTbl().copySlotDescriptor(vOutputTupleDesc,
+ rightSlotDesc);
if (rightNullable) {
outputSlotDesc.setIsNullable(true);
rightNullableNumber++;
@@ -211,8 +212,7 @@ public abstract class JoinNodeBase extends PlanNode {
// add mark slot if needed
if (isMarkJoin() && analyzer.needPopUpMarkTuple(innerRef)) {
SlotDescriptor markSlot = analyzer.getMarkTuple(innerRef).getSlots().get(0);
- SlotDescriptor outputSlotDesc =
- analyzer.getDescTbl().copySlotDescriptor(vOutputTupleDesc, markSlot);
+ SlotDescriptor outputSlotDesc = analyzer.getDescTbl().copySlotDescriptor(vOutputTupleDesc, markSlot);
srcTblRefToOutputTupleSmap.put(new SlotRef(markSlot), new SlotRef(outputSlotDesc));
}
@@ -313,8 +313,10 @@ public abstract class JoinNodeBase extends PlanNode {
}
}
- // be may be possible to output correct row number without any column data in future
- // but for now, in order to have correct output row number, should keep at least one slot.
+ // be may be possible to output correct row number without any column data in
+ // future
+ // but for now, in order to have correct output row number, should keep at least
+ // one slot.
// use first materialized slot if outputSlotIds is empty.
if (outputSlotIds.isEmpty() && firstMaterializedSlotId != null) {
outputSlotIds.add(firstMaterializedSlotId);
@@ -359,7 +361,8 @@ public abstract class JoinNodeBase extends PlanNode {
vIntermediateTupleDescList = new ArrayList<>();
vIntermediateTupleDescList.add(vIntermediateLeftTupleDesc);
vIntermediateTupleDescList.add(vIntermediateRightTupleDesc);
- // if join type is MARK, add mark tuple to intermediate tuple. mark slot will be generated after join.
+ // if join type is MARK, add mark tuple to intermediate tuple. mark slot will be
+ // generated after join.
if (isMarkJoin()) {
TupleDescriptor markTuple = analyzer.getMarkTuple(innerRef);
if (markTuple != null) {
@@ -395,8 +398,8 @@ public abstract class JoinNodeBase extends PlanNode {
for (TupleDescriptor tupleDescriptor : analyzer.getDescTbl()
.getTupleDesc(getChild(0).getOutputTupleIds())) {
for (SlotDescriptor slotDescriptor : tupleDescriptor.getMaterializedSlots()) {
- SlotDescriptor intermediateSlotDesc =
- analyzer.getDescTbl().copySlotDescriptor(vIntermediateLeftTupleDesc, slotDescriptor);
+ SlotDescriptor intermediateSlotDesc = analyzer.getDescTbl()
+ .copySlotDescriptor(vIntermediateLeftTupleDesc, slotDescriptor);
if (leftNullable) {
intermediateSlotDesc.setIsNullable(true);
}
@@ -411,8 +414,8 @@ public abstract class JoinNodeBase extends PlanNode {
for (TupleDescriptor tupleDescriptor : analyzer.getDescTbl()
.getTupleDesc(getChild(1).getOutputTupleIds())) {
for (SlotDescriptor slotDescriptor : tupleDescriptor.getMaterializedSlots()) {
- SlotDescriptor intermediateSlotDesc =
- analyzer.getDescTbl().copySlotDescriptor(vIntermediateRightTupleDesc, slotDescriptor);
+ SlotDescriptor intermediateSlotDesc = analyzer.getDescTbl()
+ .copySlotDescriptor(vIntermediateRightTupleDesc, slotDescriptor);
if (rightNullable) {
intermediateSlotDesc.setIsNullable(true);
}
@@ -423,7 +426,8 @@ public abstract class JoinNodeBase extends PlanNode {
vIntermediateRightTupleDesc.computeMemLayout();
// 3. replace srcExpr by intermediate tuple
Preconditions.checkState(vSrcToOutputSMap != null);
- // Set `preserveRootTypes` to true because we should keep the consistent for types. See Issue-11314.
+ // Set `preserveRootTypes` to true because we should keep the consistent for
+ // types. See Issue-11314.
vSrcToOutputSMap.substituteLhs(originToIntermediateSmap, analyzer, true);
// 4. replace other conjuncts and conjuncts
computeOtherConjuncts(analyzer, originToIntermediateSmap);
@@ -438,7 +442,7 @@ public abstract class JoinNodeBase extends PlanNode {
List<Expr> exprs = vSrcToOutputSMap.getLhs();
ArrayList<SlotDescriptor> slots = vOutputTupleDesc.getSlots();
for (int i = 0; i < slots.size(); i++) {
- slots.get(i).setIsNullable(exprs.get(i).isNullable());
+ slots.get(i).setIsNullable(exprs.get(i).isNullable() || slots.get(i).getIsNullable());
}
vSrcToOutputSMap.reCalculateNullableInfoForSlotInRhs();
}
@@ -509,7 +513,8 @@ public abstract class JoinNodeBase extends PlanNode {
/**
* If parent wants to get join node tupleids,
* it will call this function instead of read properties directly.
- * The reason is that the tuple id of vOutputTupleDesc the real output tuple id for join node.
+ * The reason is that the tuple id of vOutputTupleDesc the real output tuple id
+ * for join node.
* <p>
* If you read the properties of @tupleids directly instead of this function,
* it reads the input id of the current node.
@@ -606,12 +611,15 @@ public abstract class JoinNodeBase extends PlanNode {
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
+ // add a new slot for projection result and add the project expr to
+ // vSrcToOutputSMap
SlotDescriptor slotDesc = analyzer.addSlotDescriptor(vOutputTupleDesc);
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
+ // 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
rhsExpr = rhsExpr.substitute(tmpSmap);
vSrcToOutputSMap.getLhs().add(rhsExpr);
SlotRef slotRef = new SlotRef(slotDesc);
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org