[fix](planner)scan node should project all required expr from parent node (#26886)
This commit is contained in:
@ -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.
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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());
|
||||
|
||||
Reference in New Issue
Block a user