[opt](Nereids) support cast bewteen numeric and boolean in FE (#29006)

This commit is contained in:
morrySnow
2023-12-26 14:11:34 +08:00
committed by GitHub
parent 00bb099fdd
commit a8688509c9

View File

@ -185,15 +185,15 @@ public abstract class Literal extends Expression implements LeafExpression, Comp
minVal = new BigDecimal(LargeIntType.MIN_VALUE);
} else if (targetType.isFloatType()) {
maxVal = new BigDecimal(Float.MAX_VALUE);
minVal = new BigDecimal(-Float.MAX_VALUE);
minVal = BigDecimal.valueOf(-Float.MAX_VALUE);
} else if (targetType.isDoubleType()) {
maxVal = new BigDecimal(Double.MAX_VALUE);
minVal = new BigDecimal(-Double.MAX_VALUE);
minVal = BigDecimal.valueOf(-Double.MAX_VALUE);
}
if (val.compareTo(maxVal) > 0 || val.compareTo(minVal) < 0) {
throw new AnalysisException(
String.format("{} can't cast to {}", desc, targetType));
String.format("%s can't cast to %s", desc, targetType));
}
}
return uncheckedCastTo(targetType);
@ -209,7 +209,24 @@ public abstract class Literal extends Expression implements LeafExpression, Comp
}
// TODO support string to complex
String desc = getStringValue();
// convert boolean to byte string value to support cast boolean to numeric in FE.
if (this.equals(BooleanLiteral.TRUE)) {
desc = "1";
} else if (this.equals(BooleanLiteral.FALSE)) {
desc = "0";
}
if (targetType.isBooleanType()) {
try {
// convert any non-zero numeric literal to true if target type is boolean
long value = Long.parseLong(desc);
if (value == 0) {
return Literal.of(false);
} else {
return Literal.of(true);
}
} catch (Exception e) {
// ignore
}
if ("0".equals(desc) || "false".equals(desc.toLowerCase(Locale.ROOT))) {
return Literal.of(false);
}
@ -218,11 +235,11 @@ public abstract class Literal extends Expression implements LeafExpression, Comp
}
}
if (targetType.isTinyIntType()) {
return Literal.of(Byte.valueOf(desc).byteValue());
return Literal.of(Byte.valueOf(desc));
} else if (targetType.isSmallIntType()) {
return Literal.of(Short.valueOf(desc).shortValue());
return Literal.of(Short.valueOf(desc));
} else if (targetType.isIntegerType()) {
return Literal.of(Integer.valueOf(desc).intValue());
return Literal.of(Integer.valueOf(desc));
} else if (targetType.isBigIntType()) {
return Literal.of(Long.valueOf(desc));
} else if (targetType.isLargeIntType()) {