in fe/fe-common/src/main/java/org/apache/doris/catalog/ScalarType.java [1000:1153]
public static ScalarType getAssignmentCompatibleType(
ScalarType t1, ScalarType t2, boolean strict, boolean enableDecimal256) {
if (!t1.isValid() || !t2.isValid()) {
return INVALID;
}
if (t1.equals(t2)) {
return t1;
}
if (t1.isNull()) {
return t2;
}
if (t2.isNull()) {
return t1;
}
boolean t1IsHLL = t1.type == PrimitiveType.HLL;
boolean t2IsHLL = t2.type == PrimitiveType.HLL;
if (t1IsHLL || t2IsHLL) {
if (t1IsHLL && t2IsHLL) {
return createHllType();
}
return INVALID;
}
boolean t1IsBitMap = t1.type == PrimitiveType.BITMAP;
boolean t2IsBitMap = t2.type == PrimitiveType.BITMAP;
if (t1IsBitMap || t2IsBitMap) {
if (t1IsBitMap && t2IsBitMap) {
return BITMAP;
}
return INVALID;
}
// for cast all type
if (t1.type == PrimitiveType.ALL || t2.type == PrimitiveType.ALL) {
return Type.ALL;
}
if (t1.isStringType() || t2.isStringType()) {
if (t1.type == PrimitiveType.STRING || t2.type == PrimitiveType.STRING) {
return createStringType();
}
int minLength = Math.min(t1.len, t2.len);
if (minLength < 0) {
// If < 0 which means max length, use firstly
return createVarcharType(minLength);
}
int length = Math.max(t1.len, t2.len);
return createVarcharType(length == 0 ? MAX_VARCHAR_LENGTH : length);
}
if (((t1.isDecimalV3() || t1.isDecimalV2()) && (t2.isDateV2() || t2.isDate()))
|| ((t2.isDecimalV3() || t2.isDecimalV2()) && (t1.isDateV2() || t1.isDate()))) {
return Type.DOUBLE;
}
if (t1.isDecimalV2() && t2.isDecimalV2()) {
return getAssignmentCompatibleDecimalV2Type(t1, t2);
}
if ((t1.isDecimalV3() && t2.isDecimalV2()) || (t2.isDecimalV3() && t1.isDecimalV2())) {
int scale = Math.max(t1.scale, t2.scale);
int integerPart = Math.max(t1.precision - t1.scale, t2.precision - t2.scale);
return ScalarType.createDecimalV3Type(integerPart + scale, scale);
}
if (t1.isDecimalV2() || t2.isDecimalV2()) {
if (t1.isFloatingPointType() || t2.isFloatingPointType()) {
return Type.DOUBLE;
}
return t1.isDecimalV2() ? t1 : t2;
}
if (t1.isDecimalV3() || t2.isDecimalV3()) {
if (t1.isFloatingPointType() || t2.isFloatingPointType()) {
return t1.isFloatingPointType() ? t1 : t2;
} else if (t1.isBoolean() || t2.isBoolean()) {
return t1.isDecimalV3()
? ScalarType.createDecimalV3Type(
Math.max(t1.precision - t1.scale, 1) + Math.max(t1.scale, 0),
Math.max(t1.scale, 0)) :
ScalarType.createDecimalV3Type(
Math.max(t2.precision - t2.scale, 1) + Math.max(t2.scale, 0),
Math.max(t2.scale, 0));
}
}
if ((t1.isDecimalV3() && t2.isFixedPointType())
|| (t2.isDecimalV3() && t1.isFixedPointType())) {
int precision;
int scale;
ScalarType intType;
if (t1.isDecimalV3()) {
precision = t1.precision;
scale = t1.scale;
intType = t2;
} else {
precision = t2.precision;
scale = t2.scale;
intType = t1;
}
int integerPart = precision - scale;
if (intType.isScalarType(PrimitiveType.TINYINT)
|| intType.isScalarType(PrimitiveType.SMALLINT)) {
integerPart = Math.max(integerPart, new BigDecimal(Short.MAX_VALUE).precision());
} else if (intType.isScalarType(PrimitiveType.INT)) {
integerPart = Math.max(integerPart, new BigDecimal(Integer.MAX_VALUE).precision());
} else {
integerPart = ScalarType.MAX_DECIMAL128_PRECISION - scale;
}
if (scale + integerPart <= ScalarType.MAX_DECIMAL128_PRECISION) {
return ScalarType.createDecimalV3Type(scale + integerPart, scale);
} else {
if (enableDecimal256) {
return ScalarType.createDecimalV3Type(scale + integerPart, scale);
} else {
return Type.DOUBLE;
}
}
}
if (t1.isDecimalV3() && t2.isDecimalV3()) {
ScalarType finalType = ScalarType.createDecimalV3Type(Math.max(t1.decimalPrecision() - t1.decimalScale(),
t2.decimalPrecision() - t2.decimalScale()) + Math.max(t1.decimalScale(),
t2.decimalScale()), Math.max(t1.decimalScale(), t2.decimalScale()));
if (finalType.getPrecision() > MAX_PRECISION) {
finalType = ScalarType.createDecimalV3Type(MAX_PRECISION, finalType.getScalarScale());
}
return finalType;
}
PrimitiveType smallerType =
(t1.type.ordinal() < t2.type.ordinal() ? t1.type : t2.type);
PrimitiveType largerType =
(t1.type.ordinal() > t2.type.ordinal() ? t1.type : t2.type);
PrimitiveType result = null;
if (t1.isDatetimeV2() && t2.isDatetimeV2()) {
return t1.scale > t2.scale ? t1 : t2;
}
if ((t1.isDatetimeV2() || t1.isDateV2()) && (t2.isDatetimeV2() || t2.isDateV2())) {
return t1.isDatetimeV2() ? t1 : t2;
}
if (strict) {
result = strictCompatibilityMatrix[smallerType.ordinal()][largerType.ordinal()];
}
if (result == null) {
result = compatibilityMatrix[smallerType.ordinal()][largerType.ordinal()];
}
Preconditions.checkNotNull(result);
if (result == PrimitiveType.DECIMALV2) {
return Type.MAX_DECIMALV2_TYPE;
}
return createType(result);
}