Skip to content

Commit

Permalink
[fix](nereids) set operation's result type is wrong if decimal overfl…
Browse files Browse the repository at this point in the history
…ows (apache#27872)

pick from master apache#27870
  • Loading branch information
starocean999 authored and eldenmoon committed Dec 3, 2023
1 parent 3135f5f commit b51dc70
Showing 1 changed file with 28 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.apache.doris.nereids.trees.plans.logical;

import org.apache.doris.catalog.ScalarType;
import org.apache.doris.catalog.Type;
import org.apache.doris.nereids.memo.GroupExpression;
import org.apache.doris.nereids.properties.LogicalProperties;
Expand Down Expand Up @@ -137,10 +138,7 @@ private List<List<NamedExpression>> castCommonDataTypeOutputs() {
for (int i = 0; i < child(0).getOutput().size(); ++i) {
Slot left = child(0).getOutput().get(i);
Slot right = child(1).getOutput().get(i);
DataType compatibleType = DataType.fromCatalogType(Type.getAssignmentCompatibleType(
left.getDataType().toCatalogDataType(),
right.getDataType().toCatalogDataType(),
false));
DataType compatibleType = getAssignmentCompatibleType(left.getDataType(), right.getDataType());
Expression newLeft = TypeCoercionUtils.castIfNotSameType(left, compatibleType);
Expression newRight = TypeCoercionUtils.castIfNotSameType(right, compatibleType);
if (newLeft instanceof Cast) {
Expand Down Expand Up @@ -211,4 +209,30 @@ public abstract LogicalSetOperation withChildrenAndTheirOutputs(
public int getArity() {
return children.size();
}

private DataType getAssignmentCompatibleType(DataType left, DataType right) {
if (left.isNullType()) {
return right;
}
if (right.isNullType()) {
return left;
}
if (left.equals(right)) {
return left;
}
Type resultType = Type.getAssignmentCompatibleType(left.toCatalogDataType(),
right.toCatalogDataType(), false);
if (resultType.isDecimalV3()) {
int oldPrecision = resultType.getPrecision();
int oldScale = resultType.getDecimalDigits();
int integerPart = oldPrecision - oldScale;
int maxPrecision = ScalarType.MAX_DECIMAL128_PRECISION;
if (oldPrecision > maxPrecision) {
int newScale = maxPrecision - integerPart;
resultType =
ScalarType.createDecimalType(maxPrecision, newScale < 0 ? 0 : newScale);
}
}
return DataType.fromCatalogType(resultType);
}
}

0 comments on commit b51dc70

Please sign in to comment.