[enhancement](Nereids) add type coercion between decimal and integral (#12482)

This commit is contained in:
Kikyou1997
2022-09-09 20:08:03 +08:00
committed by GitHub
parent 2b62ac2fef
commit f80d7bdd5b
3 changed files with 45 additions and 2 deletions

View File

@ -143,6 +143,10 @@ public class TypeCoercionUtils {
if (leftType instanceof NullType && rightType instanceof DecimalType) {
return true;
}
if (leftType instanceof DecimalType && rightType instanceof IntegralType
|| leftType instanceof IntegralType && rightType instanceof DecimalType) {
return true;
}
// TODO: add decimal promotion support
if (!(leftType instanceof DecimalType) && !(rightType instanceof DecimalType) && !leftType.equals(rightType)) {
return true;
@ -189,6 +193,10 @@ public class TypeCoercionUtils {
}
} else if (left instanceof CharacterType || right instanceof CharacterType) {
tightestCommonType = StringType.INSTANCE;
} else if (left instanceof DecimalType && right instanceof IntegralType) {
tightestCommonType = DecimalType.widerDecimalType((DecimalType) left, DecimalType.forType(right));
} else if (left instanceof IntegralType && right instanceof DecimalType) {
tightestCommonType = DecimalType.widerDecimalType((DecimalType) right, DecimalType.forType(left));
}
return Optional.ofNullable(tightestCommonType);
}

View File

@ -24,6 +24,7 @@ import org.apache.doris.nereids.trees.expressions.Cast;
import org.apache.doris.nereids.trees.expressions.Divide;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.InPredicate;
import org.apache.doris.nereids.trees.expressions.LessThanEqual;
import org.apache.doris.nereids.trees.expressions.WhenClause;
import org.apache.doris.nereids.trees.expressions.functions.Avg;
import org.apache.doris.nereids.trees.expressions.functions.Substring;
@ -32,20 +33,25 @@ import org.apache.doris.nereids.trees.expressions.functions.Year;
import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
import org.apache.doris.nereids.trees.expressions.literal.DateLiteral;
import org.apache.doris.nereids.trees.expressions.literal.DecimalLiteral;
import org.apache.doris.nereids.trees.expressions.literal.DoubleLiteral;
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
import org.apache.doris.nereids.trees.expressions.literal.SmallIntLiteral;
import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
import org.apache.doris.nereids.trees.expressions.literal.TinyIntLiteral;
import org.apache.doris.nereids.types.BigIntType;
import org.apache.doris.nereids.types.DecimalType;
import org.apache.doris.nereids.types.DoubleType;
import org.apache.doris.nereids.types.IntegerType;
import org.apache.doris.nereids.types.StringType;
import org.apache.doris.nereids.types.TinyIntType;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
import java.util.List;
public class TypeCoercionTest {
@ -103,6 +109,35 @@ public class TypeCoercionTest {
assertRewrite(expected, expression);
}
@Test
public void testBinaryPredicate() {
Expression left = new DecimalLiteral(new BigDecimal(2.4));
Expression right = new TinyIntLiteral((byte) 2);
Expression lessThanEq = new LessThanEqual(left, right);
Expression rewrittenPred =
new LessThanEqual(
left,
new Cast(right, left.getDataType()));
assertRewrite(rewrittenPred, lessThanEq);
rewrittenPred =
new LessThanEqual(
new Cast(right, left.getDataType()),
left
);
lessThanEq = new LessThanEqual(right, left);
assertRewrite(rewrittenPred, lessThanEq);
left = new DecimalLiteral(new BigDecimal(1));
lessThanEq = new LessThanEqual(left, right);
rewrittenPred =
new LessThanEqual(
new Cast(left, DecimalType.forType(TinyIntType.INSTANCE)),
new Cast(right, DecimalType.forType(TinyIntType.INSTANCE))
);
assertRewrite(rewrittenPred, lessThanEq);
}
@Test
public void testCaseWhenTypeCoercion() {
WhenClause actualWhenClause1 = new WhenClause(new BooleanLiteral(true), new SmallIntLiteral((short) 1));

View File

@ -110,8 +110,8 @@ public class TypeCoercionUtilsTest {
Assertions.assertTrue(TypeCoercionUtils.canHandleTypeCoercion(decimalType, nullType));
Assertions.assertTrue(TypeCoercionUtils.canHandleTypeCoercion(nullType, decimalType));
Assertions.assertTrue(TypeCoercionUtils.canHandleTypeCoercion(smallIntType, integerType));
Assertions.assertFalse(TypeCoercionUtils.canHandleTypeCoercion(integerType, decimalType));
Assertions.assertFalse(TypeCoercionUtils.canHandleTypeCoercion(decimalType, integerType));
Assertions.assertTrue(TypeCoercionUtils.canHandleTypeCoercion(integerType, decimalType));
Assertions.assertTrue(TypeCoercionUtils.canHandleTypeCoercion(decimalType, integerType));
Assertions.assertFalse(TypeCoercionUtils.canHandleTypeCoercion(integerType, integerType));
}