[fix](join)fix outer join bug when a subquery as nullable side #11700

This commit is contained in:
starocean999
2022-08-12 11:50:15 +08:00
committed by GitHub
parent 32e451e6ad
commit 6c6328fc6d
4 changed files with 142 additions and 0 deletions

View File

@ -132,6 +132,11 @@ public abstract class AggregateInfoBase {
boolean isGroupingSet = !groupingExprs.isEmpty()
&& groupingExprs.get(groupingExprs.size() - 1) instanceof VirtualSlotRef;
// the agg node may output slots from child outer join node
// to make the agg node create the output tuple desc correctly, we need change the slots' to nullable
// from all outer join nullable side temporarily
// after create the output tuple we need revert the change by call analyzer.changeSlotsToNotNullable(slots)
List<SlotDescriptor> slots = analyzer.changeSlotToNullableOfOuterJoinedTuples();
for (int i = 0; i < exprs.size(); ++i) {
Expr expr = exprs.get(i);
SlotDescriptor slotDesc = analyzer.addSlotDescriptor(result);
@ -177,6 +182,7 @@ public abstract class AggregateInfoBase {
}
}
}
analyzer.changeSlotsToNotNullable(slots);
if (LOG.isTraceEnabled()) {
String prefix = (isOutputTuple ? "result " : "intermediate ");

View File

@ -2330,4 +2330,31 @@ public class Analyzer {
}
return false;
}
/**
* Change all outer joined slots to nullable
* Returns the slots actually be changed from not nullable to nullable
*/
public List<SlotDescriptor> changeSlotToNullableOfOuterJoinedTuples() {
List<SlotDescriptor> result = new ArrayList<>();
for (TupleId id : globalState.outerJoinedTupleIds.keySet()) {
TupleDescriptor tupleDescriptor = globalState.descTbl.getTupleDesc(id);
if (tupleDescriptor != null) {
for (SlotDescriptor desc : tupleDescriptor.getSlots()) {
if (!desc.getIsNullable()) {
desc.setIsNullable(true);
result.add(desc);
}
}
}
}
return result;
}
public void changeSlotsToNotNullable(List<SlotDescriptor> slots) {
for (SlotDescriptor slot : slots) {
slot.setIsNullable(false);
}
}
}