Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -142,45 +142,55 @@ public Plan visitLogicalRepeat(LogicalRepeat<? extends Plan> repeat, Map<ExprId,
@Override
public Plan visitLogicalSetOperation(LogicalSetOperation setOperation, Map<ExprId, Slot> replaceMap) {
setOperation = (LogicalSetOperation) super.visit(setOperation, replaceMap);
if (setOperation.children().isEmpty()) {
return setOperation;
}
List<Boolean> inputNullable = setOperation.child(0).getOutput().stream()
.map(ExpressionTrait::nullable).collect(Collectors.toList());
ImmutableList.Builder<List<SlotReference>> newChildrenOutputs = ImmutableList.builder();
for (int i = 0; i < setOperation.arity(); i++) {
List<Slot> childOutput = setOperation.child(i).getOutput();
List<SlotReference> setChildOutput = setOperation.getRegularChildOutput(i);
ImmutableList.Builder<SlotReference> newChildOutputs = ImmutableList.builder();
for (int j = 0; j < setChildOutput.size(); j++) {
for (Slot slot : childOutput) {
if (slot.getExprId().equals(setChildOutput.get(j).getExprId())) {
inputNullable.set(j, slot.nullable() || inputNullable.get(j));
newChildOutputs.add((SlotReference) slot);
break;
List<Boolean> inputNullable = null;
if (!setOperation.children().isEmpty()) {
inputNullable = setOperation.child(0).getOutput().stream()
.map(ExpressionTrait::nullable).collect(Collectors.toList());
for (int i = 0; i < setOperation.arity(); i++) {
List<Slot> childOutput = setOperation.child(i).getOutput();
List<SlotReference> setChildOutput = setOperation.getRegularChildOutput(i);
ImmutableList.Builder<SlotReference> newChildOutputs = ImmutableList.builder();
for (int j = 0; j < setChildOutput.size(); j++) {
for (Slot slot : childOutput) {
if (slot.getExprId().equals(setChildOutput.get(j).getExprId())) {
inputNullable.set(j, slot.nullable() || inputNullable.get(j));
newChildOutputs.add((SlotReference) slot);
break;
}
}
}
newChildrenOutputs.add(newChildOutputs.build());
}
newChildrenOutputs.add(newChildOutputs.build());
}
if (setOperation instanceof LogicalUnion) {
LogicalUnion logicalUnion = (LogicalUnion) setOperation;
if (!logicalUnion.getConstantExprsList().isEmpty() && setOperation.children().isEmpty()) {
int outputSize = logicalUnion.getConstantExprsList().get(0).size();
// create the inputNullable list and fill it with all FALSE values
inputNullable = Lists.newArrayListWithCapacity(outputSize);
for (int i = 0; i < outputSize; i++) {
inputNullable.add(false);
}
}
for (List<NamedExpression> constantExprs : logicalUnion.getConstantExprsList()) {
for (int j = 0; j < constantExprs.size(); j++) {
if (constantExprs.get(j).nullable()) {
inputNullable.set(j, true);
}
inputNullable.set(j, inputNullable.get(j) || constantExprs.get(j).nullable());
}
}
}
if (inputNullable == null) {
// this is a fail-safe
// means there is no children and having no getConstantExprsList
// no way to update the nullable flag, so just do nothing
return setOperation;
}
List<NamedExpression> outputs = setOperation.getOutputs();
List<NamedExpression> newOutputs = Lists.newArrayListWithCapacity(outputs.size());
for (int i = 0; i < inputNullable.size(); i++) {
NamedExpression ne = outputs.get(i);
Slot slot = ne instanceof Alias ? (Slot) ((Alias) ne).child() : (Slot) ne;
if (inputNullable.get(i)) {
slot = slot.withNullable(true);
}
slot = slot.withNullable(inputNullable.get(i));
newOutputs.add(ne instanceof Alias ? (NamedExpression) ne.withChildren(slot) : slot);
}
newOutputs.forEach(o -> replaceMap.put(o.getExprId(), o.toSlot()));
Expand Down
18 changes: 18 additions & 0 deletions regression-test/suites/nereids_syntax_p0/adjust_nullable.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,23 @@ suite("adjust_nullable") {
sql """
drop table if exists table_8_undef_undef;
"""

sql """
drop table if exists orders_2_x;
"""

sql """CREATE TABLE `orders_2_x` (
`o_orderdate` DATE not NULL
) ENGINE=OLAP
DUPLICATE KEY(`o_orderdate`)
DISTRIBUTED BY HASH(`o_orderdate`) BUCKETS 96
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);"""

explain {
sql(" select cast('2023-10-17' as date ) from orders_2_x union all select '2023-10-17' from orders_2_x;")
notContains("nullable=true")
}
}