[fix](planner)scan node should project all required expr from parent node (#26886)

This commit is contained in:
starocean999
2023-11-23 09:44:21 +08:00
committed by GitHub
parent 179d4ab754
commit 5b8aaf96d2
8 changed files with 161 additions and 30 deletions

View File

@ -146,6 +146,24 @@ public class TupleDescriptor {
return result;
}
public ArrayList<SlotId> getMaterializedSlotIds() {
ArrayList<SlotId> result = Lists.newArrayList();
for (SlotDescriptor slot : slots) {
if (slot.isMaterialized()) {
result.add(slot.getId());
}
}
return result;
}
public ArrayList<SlotId> getAllSlotIds() {
ArrayList<SlotId> result = Lists.newArrayList();
for (SlotDescriptor slot : slots) {
result.add(slot.getId());
}
return result;
}
/**
* Return slot descriptor corresponding to column referenced in the context
* of tupleDesc, or null if no such reference exists.

View File

@ -94,12 +94,12 @@ public class HashJoinNode extends JoinNodeBase {
if (joinOp.equals(JoinOperator.LEFT_ANTI_JOIN) || joinOp.equals(JoinOperator.LEFT_SEMI_JOIN)
|| joinOp.equals(JoinOperator.NULL_AWARE_LEFT_ANTI_JOIN)) {
tupleIds.addAll(outer.getTupleIds());
tupleIds.addAll(outer.getOutputTupleIds());
} else if (joinOp.equals(JoinOperator.RIGHT_ANTI_JOIN) || joinOp.equals(JoinOperator.RIGHT_SEMI_JOIN)) {
tupleIds.addAll(inner.getTupleIds());
tupleIds.addAll(inner.getOutputTupleIds());
} else {
tupleIds.addAll(outer.getTupleIds());
tupleIds.addAll(inner.getTupleIds());
tupleIds.addAll(outer.getOutputTupleIds());
tupleIds.addAll(inner.getOutputTupleIds());
}
for (Expr eqJoinPredicate : eqJoinConjuncts) {

View File

@ -77,12 +77,12 @@ public abstract class JoinNodeBase extends PlanNode {
joinOp = innerRef.getJoinOp();
if (joinOp.equals(JoinOperator.FULL_OUTER_JOIN)) {
nullableTupleIds.addAll(outer.getTupleIds());
nullableTupleIds.addAll(inner.getTupleIds());
nullableTupleIds.addAll(outer.getOutputTupleIds());
nullableTupleIds.addAll(inner.getOutputTupleIds());
} else if (joinOp.equals(JoinOperator.LEFT_OUTER_JOIN)) {
nullableTupleIds.addAll(inner.getTupleIds());
nullableTupleIds.addAll(inner.getOutputTupleIds());
} else if (joinOp.equals(JoinOperator.RIGHT_OUTER_JOIN)) {
nullableTupleIds.addAll(outer.getTupleIds());
nullableTupleIds.addAll(outer.getOutputTupleIds());
}
this.isMark = this.innerRef != null && innerRef.isMark();
}

View File

@ -54,6 +54,7 @@ import org.apache.doris.thrift.TScanRangeLocation;
import org.apache.doris.thrift.TScanRangeLocations;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Range;
@ -64,6 +65,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -84,6 +86,9 @@ public abstract class ScanNode extends PlanNode {
protected List<TScanRangeLocations> scanRangeLocations = Lists.newArrayList();
protected PartitionInfo partitionsInfo = null;
// create a mapping between output slot's id and project expr
Map<SlotId, Expr> outputSlotToProjectExpr = new HashMap<>();
public ScanNode(PlanNodeId id, TupleDescriptor desc, String planNodeName, StatisticalType statisticalType) {
super(id, desc.getId().asList(), planNodeName, statisticalType);
this.desc = desc;
@ -603,6 +608,7 @@ public abstract class ScanNode extends PlanNode {
}
newRhs.add(new SlotRef(slotDesc));
allOutputSlotIds.add(slotDesc.getId());
outputSlotToProjectExpr.put(slotDesc.getId(), rhsExpr);
} else {
newRhs.add(rhs.get(i));
}
@ -614,6 +620,45 @@ public abstract class ScanNode extends PlanNode {
}
}
@Override
public void initOutputSlotIds(Set<SlotId> requiredSlotIdSet, Analyzer analyzer) {
if (outputTupleDesc != null && requiredSlotIdSet != null) {
Preconditions.checkNotNull(outputSmap);
ArrayList<SlotId> materializedSlotIds = outputTupleDesc.getMaterializedSlotIds();
Preconditions.checkState(projectList != null && projectList.size() <= materializedSlotIds.size(),
"projectList's size should be less than materializedSlotIds's size");
boolean hasNewSlot = false;
if (projectList.size() < materializedSlotIds.size()) {
// need recreate projectList based on materializedSlotIds
hasNewSlot = true;
}
// find new project expr from outputSmap based on requiredSlotIdSet
ArrayList<SlotId> allSlots = outputTupleDesc.getAllSlotIds();
for (SlotId slotId : requiredSlotIdSet) {
if (!materializedSlotIds.contains(slotId) && allSlots.contains(slotId)) {
SlotDescriptor slot = outputTupleDesc.getSlot(slotId.asInt());
for (Expr expr : outputSmap.getRhs()) {
if (expr instanceof SlotRef && ((SlotRef) expr).getSlotId() == slotId) {
slot.setIsMaterialized(true);
outputSlotToProjectExpr.put(slotId, expr.getSrcSlotRef());
hasNewSlot = true;
}
}
}
}
if (hasNewSlot) {
// recreate the project list
projectList.clear();
materializedSlotIds = outputTupleDesc.getMaterializedSlotIds();
for (SlotId slotId : materializedSlotIds) {
projectList.add(outputSlotToProjectExpr.get(slotId));
}
}
}
}
public List<TupleId> getOutputTupleIds() {
if (outputTupleDesc != null) {
return Lists.newArrayList(outputTupleDesc.getId());