This is an automated email from the ASF dual-hosted git repository.
morrysnow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 67302d84219 [fix](nereids) fix simplify compare predicate cause by
loss precision or cast null (#55884)
67302d84219 is described below
commit 67302d84219c3b8a1beb505c17b8dd976b56bf65
Author: yujun <[email protected]>
AuthorDate: Tue Sep 16 16:47:50 2025 +0800
[fix](nereids) fix simplify compare predicate cause by loss precision or
cast null (#55884)
### What problem does this PR solve?
simplify compare predicate have bug:
1. `cast(integer as double) cmp double` may cause error due to int to
double may losss precision;
for `cast(c_bigint as double) compare double literal`, will simplify it
to `c_bigint compare integer like literal`,
but notice that, only value between [-2^53 + 1, 2^53 - 1] can integer
<=> double conversion be one to one,
for example, for sql `cast(c_bigint as double) =
cast('1000000000000000000.0' as double)`, we can't simplify it to
`c_bigint = 1000000000000000000` because the actual range for c_bigint
is [999999999999999936, 1000000000000000064].
mysql> select cast(999999999999999936 as double);
+------------------------------------+
| cast(999999999999999936 as double) |
+------------------------------------+
| 1e+18 |
+------------------------------------+
1 row in set (0.01 sec)
mysql> select cast(1000000000000000064 as double);
+-------------------------------------+
| cast(1000000000000000064 as double) |
+-------------------------------------+
| 1e+18 |
+-------------------------------------+
1 row in set (0.00 sec)
so we need check the right literal's bound
2. `cast(integer/decimal as decimal) cmp decimal literal` may cause
error due to cast may generate null. for `cast(slot as decimalX)`, if
the casted slot is integer or decimal, and its range > decimal X's range
or its range == decimal X's range and its scale > decimal X's scale,
then the cast maybe null, so don't simplify this predicate.
for example: `cast(1234 as decimal(6, 3))` will evaluate to null,
`cast(9.99 as decimal(2, 1))` will be null
mysql> select cast(1234 as decimal(6, 3));
+------------------------------+
| cast(1234 as decimal(6, 3)) |
+------------------------------+
| NULL |
+------------------------------+
1 row in set (0.01 sec)
mysql> select cast(9.99 as decimal(2, 1));
+------------------------------+
| cast(9.99 as decimal(2, 1)) |
+------------------------------+
| NULL |
+------------------------------+
1 row in set (0.01 sec)
so for sql `cast(col as decimal(4, 1)) < 999.8`, if col is int or
decimal(5, 0) like type we can't simplify it to `col < 1000` because the
cast result may be null (example col = -10000)
---
.../rules/SimplifyComparisonPredicate.java | 78 +++++++---
.../doris/nereids/trees/expressions/Cast.java | 12 +-
.../org/apache/doris/nereids/types/BigIntType.java | 5 +
.../apache/doris/nereids/types/IntegerType.java | 5 +
.../apache/doris/nereids/types/LargeIntType.java | 5 +
.../apache/doris/nereids/types/SmallIntType.java | 5 +
.../apache/doris/nereids/types/TinyIntType.java | 5 +
.../doris/nereids/types/coercion/IntegralType.java | 7 +
.../rules/SimplifyComparisonPredicateTest.java | 146 ++++++++++++++-----
...simplify_comparison_predicate_int_vs_double.out | Bin 0 -> 6124 bytes
...plify_comparison_predicate_int_vs_double.groovy | 161 +++++++++++++++++++++
11 files changed, 362 insertions(+), 67 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicate.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicate.java
index c8328a5c913..7c3c4d6c4c6 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicate.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicate.java
@@ -60,6 +60,7 @@ import org.apache.doris.nereids.types.IntegerType;
import org.apache.doris.nereids.types.SmallIntType;
import org.apache.doris.nereids.types.TinyIntType;
import org.apache.doris.nereids.types.coercion.DateLikeType;
+import org.apache.doris.nereids.types.coercion.IntegralType;
import org.apache.doris.nereids.util.ExpressionUtils;
import org.apache.doris.nereids.util.TypeCoercionUtils;
@@ -80,6 +81,11 @@ import java.util.Optional;
public class SimplifyComparisonPredicate implements
ExpressionPatternRuleFactory {
public static SimplifyComparisonPredicate INSTANCE = new
SimplifyComparisonPredicate();
+ public static final int MAX_INT_TO_FLOAT_NO_LOSS = 1 << 24;
+ public static final int MIN_INT_TO_FLOAT_NO_LOSS =
-MAX_INT_TO_FLOAT_NO_LOSS;
+ public static final long MAX_LONG_TO_DOUBLE_NO_LOSS = 1L << 53;
+ public static final long MIN_LONG_TO_DOUBLE_NO_LOSS =
-MAX_LONG_TO_DOUBLE_NO_LOSS;
+
@Override
public List<ExpressionPatternMatcher<? extends Expression>> buildRules() {
return ImmutableList.of(
@@ -400,19 +406,25 @@ public class SimplifyComparisonPredicate implements
ExpressionPatternRuleFactory
if (left instanceof Cast && right instanceof DecimalV3Literal) {
Cast cast = (Cast) left;
left = cast.child();
+ DecimalV3Type castDataType = (DecimalV3Type) cast.getDataType();
DecimalV3Literal literal = (DecimalV3Literal) right;
if (left.getDataType().isDecimalV3Type()) {
+ DecimalV3Type leftType = (DecimalV3Type) left.getDataType();
+ if (castDataType.getRange() < leftType.getRange()
+ || (castDataType.getRange() == leftType.getRange()
+ && castDataType.getScale() <
leftType.getScale())) {
+ // for cast(col as decimal(m2, n2)) cmp literal,
+ // if cast-to can not hold col's integer part, the cast
result maybe null, don't process it.
+ return comparisonPredicate;
+ }
Optional<Expression> toSmallerDecimalDataTypeExpr =
convertDecimalToSmallerDecimalV3Type(
comparisonPredicate, cast, literal);
if (toSmallerDecimalDataTypeExpr.isPresent()) {
return toSmallerDecimalDataTypeExpr.get();
}
- DecimalV3Type leftType = (DecimalV3Type) left.getDataType();
DecimalV3Type literalType = (DecimalV3Type)
literal.getDataType();
- if (cast.getDataType().isDecimalV3Type()
- && ((DecimalV3Type) cast.getDataType()).getScale() >=
leftType.getScale()
- && leftType.getScale() < literalType.getScale()) {
+ if (castDataType.getScale() >= leftType.getScale() &&
leftType.getScale() < literalType.getScale()) {
int toScale = ((DecimalV3Type)
left.getDataType()).getScale();
if (comparisonPredicate instanceof EqualTo) {
try {
@@ -457,9 +469,17 @@ public class SimplifyComparisonPredicate implements
ExpressionPatternRuleFactory
private static Expression processIntegerDecimalLiteralComparison(
ComparisonPredicate comparisonPredicate, Expression left,
BigDecimal literal) {
// we only process isIntegerLikeType, which are tinyint, smallint,
int, bigint
+ // for `cast(c_int as decimal(m, n)) cmp literal`,
+ // if c_int's range is wider than decimal's range, cast result maybe
null, don't process it.
+ DataType castDataType = comparisonPredicate.left().getDataType();
+ if (castDataType.isDecimalV3Type()
+ && ((DecimalV3Type) castDataType).getRange() < ((IntegralType)
left.getDataType()).range()) {
+ return comparisonPredicate;
+ }
if (literal.compareTo(new BigDecimal(Long.MIN_VALUE)) >= 0
&& literal.compareTo(new BigDecimal(Long.MAX_VALUE)) <= 0) {
literal = literal.stripTrailingZeros();
+ Optional<BigDecimal> roundLiteralOpt = Optional.empty();
if (literal.scale() > 0) {
if (comparisonPredicate instanceof EqualTo) {
// TODO: the ideal way is to return an If expr like:
@@ -473,21 +493,22 @@ public class SimplifyComparisonPredicate implements
ExpressionPatternRuleFactory
return BooleanLiteral.of(false);
} else if (comparisonPredicate instanceof GreaterThan
|| comparisonPredicate instanceof LessThanEqual) {
- return TypeCoercionUtils
- .processComparisonPredicate((ComparisonPredicate)
comparisonPredicate
- .withChildren(left,
convertDecimalToIntegerLikeLiteral(
- literal.setScale(0,
RoundingMode.FLOOR))));
+ roundLiteralOpt = Optional.of(literal.setScale(0,
RoundingMode.FLOOR));
} else if (comparisonPredicate instanceof LessThan
|| comparisonPredicate instanceof GreaterThanEqual) {
+ roundLiteralOpt = Optional.of(literal.setScale(0,
RoundingMode.CEILING));
+ }
+ } else {
+ roundLiteralOpt = Optional.of(literal);
+ }
+ if (roundLiteralOpt.isPresent()) {
+ Optional<IntegerLikeLiteral> integerLikeLiteralOpt
+ =
convertDecimalToIntegerLikeLiteral(roundLiteralOpt.get(), castDataType);
+ if (integerLikeLiteralOpt.isPresent()) {
return TypeCoercionUtils
.processComparisonPredicate((ComparisonPredicate)
comparisonPredicate
- .withChildren(left,
convertDecimalToIntegerLikeLiteral(
- literal.setScale(0,
RoundingMode.CEILING))));
+ .withChildren(left,
integerLikeLiteralOpt.get()));
}
- } else {
- return TypeCoercionUtils
- .processComparisonPredicate((ComparisonPredicate)
comparisonPredicate
- .withChildren(left,
convertDecimalToIntegerLikeLiteral(literal)));
}
}
return comparisonPredicate;
@@ -615,20 +636,39 @@ public class SimplifyComparisonPredicate implements
ExpressionPatternRuleFactory
return Optional.empty();
}
- private static IntegerLikeLiteral
convertDecimalToIntegerLikeLiteral(BigDecimal decimal) {
+ private static Optional<IntegerLikeLiteral>
convertDecimalToIntegerLikeLiteral(BigDecimal decimal,
+ DataType castDataType) {
Preconditions.checkArgument(decimal.scale() <= 0
&& decimal.compareTo(new BigDecimal(Long.MIN_VALUE)) >= 0
&& decimal.compareTo(new BigDecimal(Long.MAX_VALUE)) <= 0,
"decimal literal must have 0 scale and in range
[Long.MIN_VALUE, Long.MAX_VALUE]");
long val = decimal.longValue();
+ // for integer like convert to float, only [-2^24, 2^24] can convert
to float without loss of precision,
+ // but here need to exclude the boundary value, because
+ // cast(2^24 as float) = cast(2^24 + 1 as float) = 2^24 =
MAX_INT_TO_FLOAT_NO_LOSS,
+ // so for cast(c_int as float) = 2^24, we can't simplify it to c_int =
2^24,
+ // c_int can be 2^24 + 1. The same for -2^24
+ if (castDataType.isFloatType()
+ && (val <= MIN_INT_TO_FLOAT_NO_LOSS || val >=
MAX_INT_TO_FLOAT_NO_LOSS)) {
+ return Optional.empty();
+ }
+ // for long convert to double, only [-2^53, 2^53] can convert to
double without loss of precision,
+ // but here need to exclude the boundary value, because
+ // cast(2^53 as double) = cast(2^53 + 1 as double) = 2^53 =
MAX_LONG_TO_DOUBLE_NO_LOSS,
+ // so for cast(c_bigint as double) = 2^53, we can't simplify it to
c_bigint = 2^53,
+ // c_bigint can be 2^53 + 1. The same for -2^53
+ if (castDataType.isDoubleType()
+ && (val <= MIN_LONG_TO_DOUBLE_NO_LOSS || val >=
MAX_LONG_TO_DOUBLE_NO_LOSS)) {
+ return Optional.empty();
+ }
if (val >= Byte.MIN_VALUE && val <= Byte.MAX_VALUE) {
- return new TinyIntLiteral((byte) val);
+ return Optional.of(new TinyIntLiteral((byte) val));
} else if (val >= Short.MIN_VALUE && val <= Short.MAX_VALUE) {
- return new SmallIntLiteral((short) val);
+ return Optional.of(new SmallIntLiteral((short) val));
} else if (val >= Integer.MIN_VALUE && val <= Integer.MAX_VALUE) {
- return new IntegerLiteral((int) val);
+ return Optional.of(new IntegerLiteral((int) val));
} else {
- return new BigIntLiteral(val);
+ return Optional.of(new BigIntLiteral(val));
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Cast.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Cast.java
index ab40a0fc9ea..e9fa1dcb0ac 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Cast.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Cast.java
@@ -49,16 +49,12 @@ public class Cast extends Expression implements
UnaryExpression, Monotonic {
private final DataType targetType;
- public Cast(Expression child, DataType targetType, boolean isExplicitType)
{
- super(ImmutableList.of(child));
- this.targetType = Objects.requireNonNull(targetType, "targetType can
not be null");
- this.isExplicitType = isExplicitType;
+ public Cast(Expression child, DataType targetType) {
+ this(child, targetType, false);
}
- public Cast(Expression child, DataType targetType) {
- super(ImmutableList.of(child));
- this.targetType = Objects.requireNonNull(targetType, "targetType can
not be null");
- this.isExplicitType = false;
+ public Cast(Expression child, DataType targetType, boolean isExplicitType)
{
+ this(ImmutableList.of(child), targetType, isExplicitType);
}
private Cast(List<Expression> child, DataType targetType, boolean
isExplicitType) {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/BigIntType.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/BigIntType.java
index 767db0e89a9..f654b9f271b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/BigIntType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/BigIntType.java
@@ -62,4 +62,9 @@ public class BigIntType extends IntegralType implements
Int64OrLessType {
public int width() {
return WIDTH;
}
+
+ @Override
+ public int range() {
+ return RANGE;
+ }
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/IntegerType.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/IntegerType.java
index 2b22c167d46..7b47ff90b72 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/IntegerType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/IntegerType.java
@@ -62,4 +62,9 @@ public class IntegerType extends IntegralType implements
Int32OrLessType {
public int width() {
return WIDTH;
}
+
+ @Override
+ public int range() {
+ return RANGE;
+ }
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/LargeIntType.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/LargeIntType.java
index 78a9369bd26..22e88206c6a 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/LargeIntType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/LargeIntType.java
@@ -71,4 +71,9 @@ public class LargeIntType extends IntegralType {
public int width() {
return WIDTH;
}
+
+ @Override
+ public int range() {
+ return RANGE;
+ }
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/SmallIntType.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/SmallIntType.java
index 4272052cd1a..ad2743a4a7e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/SmallIntType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/SmallIntType.java
@@ -62,4 +62,9 @@ public class SmallIntType extends IntegralType implements
Int16OrLessType {
public int width() {
return WIDTH;
}
+
+ @Override
+ public int range() {
+ return RANGE;
+ }
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/TinyIntType.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/TinyIntType.java
index 30259582127..075cb945db2 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/TinyIntType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/TinyIntType.java
@@ -62,4 +62,9 @@ public class TinyIntType extends IntegralType implements
Int16OrLessType {
public int width() {
return WIDTH;
}
+
+ @Override
+ public int range() {
+ return RANGE;
+ }
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/coercion/IntegralType.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/coercion/IntegralType.java
index 656c6f660f2..b1e58805388 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/coercion/IntegralType.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/coercion/IntegralType.java
@@ -20,6 +20,8 @@ package org.apache.doris.nereids.types.coercion;
import org.apache.doris.nereids.types.BigIntType;
import org.apache.doris.nereids.types.DataType;
+import org.apache.commons.lang3.NotImplementedException;
+
/**
* Abstract class for all integral data type in Nereids.
*/
@@ -45,4 +47,9 @@ public class IntegralType extends NumericType {
public boolean widerThan(IntegralType other) {
return this.width() > other.width();
}
+
+ // The maximum number of digits that Integer can represent.
+ public int range() {
+ throw new NotImplementedException("should be implemented by derived
class");
+ }
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicateTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicateTest.java
index 74f569f52c3..b5ad2dda3d4 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicateTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/rules/SimplifyComparisonPredicateTest.java
@@ -596,6 +596,49 @@ class SimplifyComparisonPredicateTest extends
ExpressionRewriteTestHelper {
new LessThan(bigIntSlot, new BigIntLiteral(13L)));
assertRewrite(new LessThanEqual(new Cast(bigIntSlot,
DoubleType.INSTANCE), new DoubleLiteral(12.3f)),
new LessThanEqual(bigIntSlot, new BigIntLiteral(12L)));
+
+ // int and float literal near no loss bound
+ float noLossBoundF = 16777216.0f; // 2^24
+ assertRewrite(new EqualTo(new Cast(intSlot, FloatType.INSTANCE), new
FloatLiteral(-noLossBoundF)),
+ new EqualTo(new Cast(intSlot, FloatType.INSTANCE), new
FloatLiteral(-noLossBoundF)));
+ assertRewrite(new EqualTo(new Cast(intSlot, FloatType.INSTANCE), new
FloatLiteral(-16777215.0f)),
+ new EqualTo(intSlot, new IntegerLiteral(-16777215)));
+ assertRewrite(new EqualTo(new Cast(intSlot, FloatType.INSTANCE), new
FloatLiteral(16777215.0f)),
+ new EqualTo(intSlot, new IntegerLiteral(16777215)));
+ assertRewrite(new EqualTo(new Cast(intSlot, FloatType.INSTANCE), new
FloatLiteral(noLossBoundF)),
+ new EqualTo(new Cast(intSlot, FloatType.INSTANCE), new
FloatLiteral(noLossBoundF)));
+
+ // big int and double literal near no loss bound
+ double noLossBoundD = 9007199254740992.0;
+ assertRewrite(new EqualTo(new Cast(bigIntSlot, DoubleType.INSTANCE),
new DoubleLiteral(-noLossBoundD)),
+ new EqualTo(new Cast(bigIntSlot, DoubleType.INSTANCE), new
DoubleLiteral(-noLossBoundD)));
+ assertRewrite(new EqualTo(new Cast(bigIntSlot, DoubleType.INSTANCE),
new DoubleLiteral(-9007199254740991.0)),
+ new EqualTo(bigIntSlot, new
BigIntLiteral(-9007199254740991L)));
+ assertRewrite(new EqualTo(new Cast(bigIntSlot, DoubleType.INSTANCE),
new DoubleLiteral(9007199254740991.0)),
+ new EqualTo(bigIntSlot, new BigIntLiteral(9007199254740991L)));
+ assertRewrite(new EqualTo(new Cast(bigIntSlot, DoubleType.INSTANCE),
new DoubleLiteral(noLossBoundD)),
+ new EqualTo(new Cast(bigIntSlot, DoubleType.INSTANCE), new
DoubleLiteral(noLossBoundD)));
+ }
+
+ @Test
+ void testFloatNoLossBound() {
+
checkIntConvertFloatLikeLossBound(SimplifyComparisonPredicate.MIN_INT_TO_FLOAT_NO_LOSS,
true);
+
checkIntConvertFloatLikeLossBound(SimplifyComparisonPredicate.MAX_INT_TO_FLOAT_NO_LOSS,
true);
+
checkIntConvertFloatLikeLossBound(SimplifyComparisonPredicate.MIN_LONG_TO_DOUBLE_NO_LOSS,
false);
+
checkIntConvertFloatLikeLossBound(SimplifyComparisonPredicate.MAX_LONG_TO_DOUBLE_NO_LOSS,
false);
+ }
+
+ private void checkIntConvertFloatLikeLossBound(long bound, boolean
isFloat) {
+ for (int i = 0; i < 100000; i++) {
+ long v = (Math.abs(bound) - i) * Long.signum(bound);
+ long vCast = isFloat ? (long) ((float) v) : (long) ((double) v);
+ Assertions.assertEquals(v, vCast);
+ }
+
+ long firstOutBound = (Math.abs(bound) + 1) * Long.signum(bound);
+ long firstOutBoundCast = isFloat ? (long) ((float) firstOutBound) :
(long) ((double) firstOutBound);
+ Assertions.assertNotEquals(firstOutBound, firstOutBoundCast);
+ Assertions.assertEquals(bound, firstOutBoundCast);
}
@Test
@@ -610,95 +653,110 @@ class SimplifyComparisonPredicateTest extends
ExpressionRewriteTestHelper {
Expression bigIntSlot = new SlotReference("a", BigIntType.INSTANCE);
// tiny int, literal not exceeds data type limit
- assertRewrite(new EqualTo(new Cast(tinyIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.0"))),
+ DecimalV3Type tinyDecimalType = DecimalV3Type.createDecimalV3Type(4,
1);
+ assertRewrite(new EqualTo(new Cast(tinyIntSlot, tinyDecimalType), new
DecimalV3Literal(tinyDecimalType, new BigDecimal("12.0"))),
new EqualTo(tinyIntSlot, new TinyIntLiteral((byte) 12)));
- assertRewrite(new EqualTo(new Cast(tinyIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new EqualTo(new Cast(tinyIntSlot, tinyDecimalType), new
DecimalV3Literal(tinyDecimalType, new BigDecimal("12.3"))),
ExpressionUtils.falseOrNull(tinyIntSlot));
- assertRewrite(new NullSafeEqual(new Cast(tinyIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new NullSafeEqual(new Cast(tinyIntSlot,
tinyDecimalType), new DecimalV3Literal(tinyDecimalType, new
BigDecimal("12.3"))),
BooleanLiteral.FALSE);
- assertRewrite(new GreaterThan(new Cast(tinyIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new GreaterThan(new Cast(tinyIntSlot, tinyDecimalType),
new DecimalV3Literal(tinyDecimalType, new BigDecimal("12.3"))),
new GreaterThan(tinyIntSlot, new TinyIntLiteral((byte) 12)));
- assertRewrite(new GreaterThanEqual(new Cast(tinyIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new GreaterThanEqual(new Cast(tinyIntSlot,
tinyDecimalType), new DecimalV3Literal(tinyDecimalType, new
BigDecimal("12.3"))),
new GreaterThanEqual(tinyIntSlot, new TinyIntLiteral((byte)
13)));
- assertRewrite(new LessThan(new Cast(tinyIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new LessThan(new Cast(tinyIntSlot, tinyDecimalType), new
DecimalV3Literal(tinyDecimalType, new BigDecimal("12.3"))),
new LessThan(tinyIntSlot, new TinyIntLiteral((byte) 13)));
- assertRewrite(new LessThanEqual(new Cast(tinyIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new LessThanEqual(new Cast(tinyIntSlot,
tinyDecimalType), new DecimalV3Literal(tinyDecimalType, new
BigDecimal("12.3"))),
new LessThanEqual(tinyIntSlot, new TinyIntLiteral((byte) 12)));
// tiny int, literal exceeds data type limit
- assertRewrite(new EqualTo(new Cast(tinyIntSlot,
DecimalV3Type.createDecimalV3Type(4, 1)), new DecimalV3Literal(new
BigDecimal("200.0"))),
+ assertRewrite(new EqualTo(new Cast(tinyIntSlot, tinyDecimalType), new
DecimalV3Literal(new BigDecimal("200.0"))),
ExpressionUtils.falseOrNull(tinyIntSlot));
- assertRewrite(new EqualTo(new Cast(tinyIntSlot,
DecimalV3Type.createDecimalV3Type(4, 1)), new DecimalV3Literal(new
BigDecimal("200.3"))),
+ assertRewrite(new EqualTo(new Cast(tinyIntSlot, tinyDecimalType), new
DecimalV3Literal(new BigDecimal("200.3"))),
ExpressionUtils.falseOrNull(tinyIntSlot));
- assertRewrite(new NullSafeEqual(new Cast(tinyIntSlot,
DecimalV3Type.createDecimalV3Type(4, 1)), new DecimalV3Literal(new
BigDecimal("200.3"))),
+ assertRewrite(new NullSafeEqual(new Cast(tinyIntSlot,
tinyDecimalType), new DecimalV3Literal(new BigDecimal("200.3"))),
BooleanLiteral.FALSE);
- assertRewrite(new GreaterThan(new Cast(tinyIntSlot,
DecimalV3Type.createDecimalV3Type(4, 1)), new DecimalV3Literal(new
BigDecimal("200.3"))),
+ assertRewrite(new GreaterThan(new Cast(tinyIntSlot, tinyDecimalType),
new DecimalV3Literal(new BigDecimal("200.3"))),
ExpressionUtils.falseOrNull(tinyIntSlot));
- assertRewrite(new GreaterThanEqual(new Cast(tinyIntSlot,
DecimalV3Type.createDecimalV3Type(4, 1)), new DecimalV3Literal(new
BigDecimal("200.3"))),
+ assertRewrite(new GreaterThanEqual(new Cast(tinyIntSlot,
tinyDecimalType), new DecimalV3Literal(new BigDecimal("200.3"))),
ExpressionUtils.falseOrNull(tinyIntSlot));
- assertRewrite(new LessThan(new Cast(tinyIntSlot,
DecimalV3Type.createDecimalV3Type(4, 1)), new DecimalV3Literal(new
BigDecimal("200.3"))),
+ assertRewrite(new LessThan(new Cast(tinyIntSlot, tinyDecimalType), new
DecimalV3Literal(new BigDecimal("200.3"))),
ExpressionUtils.trueOrNull(tinyIntSlot));
- assertRewrite(new LessThanEqual(new Cast(tinyIntSlot,
DecimalV3Type.createDecimalV3Type(4, 1)), new DecimalV3Literal(new
BigDecimal("200.3"))),
+ assertRewrite(new LessThanEqual(new Cast(tinyIntSlot,
tinyDecimalType), new DecimalV3Literal(new BigDecimal("200.3"))),
ExpressionUtils.trueOrNull(tinyIntSlot));
// small int
- assertRewrite(new EqualTo(new Cast(smallIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.0"))),
+ DecimalV3Type smallDecimalType = DecimalV3Type.createDecimalV3Type(6,
1);
+ assertRewrite(new EqualTo(new Cast(smallIntSlot, smallDecimalType),
new DecimalV3Literal(smallDecimalType, new BigDecimal("12.0"))),
new EqualTo(smallIntSlot, new SmallIntLiteral((short) 12)));
- assertRewrite(new EqualTo(new Cast(smallIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new EqualTo(new Cast(smallIntSlot, smallDecimalType),
new DecimalV3Literal(smallDecimalType, new BigDecimal("12.3"))),
ExpressionUtils.falseOrNull(smallIntSlot));
- assertRewrite(new NullSafeEqual(new Cast(smallIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new NullSafeEqual(new Cast(smallIntSlot,
smallDecimalType), new DecimalV3Literal(smallDecimalType, new
BigDecimal("12.3"))),
BooleanLiteral.FALSE);
- assertRewrite(new GreaterThan(new Cast(smallIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new GreaterThan(new Cast(smallIntSlot,
smallDecimalType), new DecimalV3Literal(smallDecimalType, new
BigDecimal("12.3"))),
new GreaterThan(smallIntSlot, new SmallIntLiteral((short)
12)));
- assertRewrite(new GreaterThanEqual(new Cast(smallIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new GreaterThanEqual(new Cast(smallIntSlot,
smallDecimalType), new DecimalV3Literal(smallDecimalType, new
BigDecimal("12.3"))),
new GreaterThanEqual(smallIntSlot, new SmallIntLiteral((short)
13)));
- assertRewrite(new LessThan(new Cast(smallIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new LessThan(new Cast(smallIntSlot, smallDecimalType),
new DecimalV3Literal(smallDecimalType, new BigDecimal("12.3"))),
new LessThan(smallIntSlot, new SmallIntLiteral((short) 13)));
- assertRewrite(new LessThanEqual(new Cast(smallIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new LessThanEqual(new Cast(smallIntSlot,
smallDecimalType), new DecimalV3Literal(smallDecimalType, new
BigDecimal("12.3"))),
new LessThanEqual(smallIntSlot, new SmallIntLiteral((short)
12)));
// int
- assertRewrite(new EqualTo(new Cast(intSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.0"))),
+ DecimalV3Type intDecimalType = DecimalV3Type.createDecimalV3Type(11,
1);
+ assertRewrite(new EqualTo(new Cast(intSlot, intDecimalType), new
DecimalV3Literal(intDecimalType, new BigDecimal("12.0"))),
new EqualTo(intSlot, new IntegerLiteral(12)));
- assertRewrite(new EqualTo(new Cast(intSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new EqualTo(new Cast(intSlot, intDecimalType), new
DecimalV3Literal(intDecimalType, new BigDecimal("12.3"))),
ExpressionUtils.falseOrNull(intSlot));
- assertRewrite(new NullSafeEqual(new Cast(intSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new NullSafeEqual(new Cast(intSlot, intDecimalType), new
DecimalV3Literal(intDecimalType, new BigDecimal("12.3"))),
BooleanLiteral.FALSE);
- assertRewrite(new GreaterThan(new Cast(intSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new GreaterThan(new Cast(intSlot, intDecimalType), new
DecimalV3Literal(intDecimalType, new BigDecimal("12.3"))),
new GreaterThan(intSlot, new IntegerLiteral(12)));
- assertRewrite(new GreaterThanEqual(new Cast(intSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new GreaterThanEqual(new Cast(intSlot, intDecimalType),
new DecimalV3Literal(intDecimalType, new BigDecimal("12.3"))),
new GreaterThanEqual(intSlot, new IntegerLiteral(13)));
- assertRewrite(new LessThan(new Cast(intSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new LessThan(new Cast(intSlot, intDecimalType), new
DecimalV3Literal(intDecimalType, new BigDecimal("12.3"))),
new LessThan(intSlot, new IntegerLiteral(13)));
- assertRewrite(new LessThanEqual(new Cast(intSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new LessThanEqual(new Cast(intSlot, intDecimalType), new
DecimalV3Literal(intDecimalType, new BigDecimal("12.3"))),
new LessThanEqual(intSlot, new IntegerLiteral(12)));
// big int
- assertRewrite(new EqualTo(new Cast(bigIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.0"))),
+ DecimalV3Type bigDecimalType = DecimalV3Type.createDecimalV3Type(20,
1);
+ assertRewrite(new EqualTo(new Cast(bigIntSlot, bigDecimalType), new
DecimalV3Literal(bigDecimalType, new BigDecimal("12.0"))),
new EqualTo(bigIntSlot, new BigIntLiteral(12L)));
- assertRewrite(new EqualTo(new Cast(bigIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new EqualTo(new Cast(bigIntSlot, bigDecimalType), new
DecimalV3Literal(bigDecimalType, new BigDecimal("12.3"))),
ExpressionUtils.falseOrNull(bigIntSlot));
- assertRewrite(new NullSafeEqual(new Cast(bigIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new NullSafeEqual(new Cast(bigIntSlot, bigDecimalType),
new DecimalV3Literal(bigDecimalType, new BigDecimal("12.3"))),
BooleanLiteral.FALSE);
- assertRewrite(new GreaterThan(new Cast(bigIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new GreaterThan(new Cast(bigIntSlot, bigDecimalType),
new DecimalV3Literal(bigDecimalType, new BigDecimal("12.3"))),
new GreaterThan(bigIntSlot, new BigIntLiteral(12L)));
- assertRewrite(new GreaterThanEqual(new Cast(bigIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new GreaterThanEqual(new Cast(bigIntSlot,
bigDecimalType), new DecimalV3Literal(bigDecimalType, new BigDecimal("12.3"))),
new GreaterThanEqual(bigIntSlot, new BigIntLiteral(13L)));
- assertRewrite(new LessThan(new Cast(bigIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new LessThan(new Cast(bigIntSlot, bigDecimalType), new
DecimalV3Literal(bigDecimalType, new BigDecimal("12.3"))),
new LessThan(bigIntSlot, new BigIntLiteral(13L)));
- assertRewrite(new LessThanEqual(new Cast(bigIntSlot,
DecimalV3Type.createDecimalV3Type(3, 1)), new DecimalV3Literal(new
BigDecimal("12.3"))),
+ assertRewrite(new LessThanEqual(new Cast(bigIntSlot, bigDecimalType),
new DecimalV3Literal(bigDecimalType, new BigDecimal("12.3"))),
new LessThanEqual(bigIntSlot, new BigIntLiteral(12L)));
- assertRewrite(new LessThan(new Cast(bigIntSlot,
DecimalV3Type.createDecimalV3Type(20, 1)), new DecimalV3Literal(new
BigDecimal("-9223372036854775808.1"))),
+ assertRewrite(new LessThan(new Cast(bigIntSlot, bigDecimalType), new
DecimalV3Literal(new BigDecimal("-9223372036854775808.1"))),
ExpressionUtils.falseOrNull(bigIntSlot));
- assertRewrite(new GreaterThanEqual(new Cast(bigIntSlot,
DecimalV3Type.createDecimalV3Type(20, 1)), new DecimalV3Literal(new
BigDecimal("-9223372036854775808.1"))),
+ assertRewrite(new GreaterThanEqual(new Cast(bigIntSlot,
bigDecimalType), new DecimalV3Literal(new
BigDecimal("-9223372036854775808.1"))),
ExpressionUtils.trueOrNull(bigIntSlot));
- assertRewrite(new LessThan(new Cast(bigIntSlot,
DecimalV3Type.createDecimalV3Type(20, 1)), new DecimalV3Literal(new
BigDecimal("-9223372036854775807.1"))),
+ assertRewrite(new LessThan(new Cast(bigIntSlot, bigDecimalType), new
DecimalV3Literal(new BigDecimal("-9223372036854775807.1"))),
new LessThan(bigIntSlot, new
BigIntLiteral(-9223372036854775807L)));
- assertRewrite(new GreaterThanEqual(new Cast(bigIntSlot,
DecimalV3Type.createDecimalV3Type(20, 1)), new DecimalV3Literal(new
BigDecimal("9223372036854775807.1"))),
+ assertRewrite(new GreaterThanEqual(new Cast(bigIntSlot,
bigDecimalType), new DecimalV3Literal(new BigDecimal("9223372036854775807.1"))),
ExpressionUtils.falseOrNull(bigIntSlot));
- assertRewrite(new LessThan(new Cast(bigIntSlot,
DecimalV3Type.createDecimalV3Type(20, 1)), new DecimalV3Literal(new
BigDecimal("9223372036854775806.1"))),
+ assertRewrite(new LessThan(new Cast(bigIntSlot, bigDecimalType), new
DecimalV3Literal(new BigDecimal("9223372036854775806.1"))),
new LessThan(bigIntSlot, new
BigIntLiteral(9223372036854775807L)));
+
+ // do not convert cast(int as decimal) if decimal's range < int's range
+ DecimalV3Type noConvertDecimalType =
DecimalV3Type.createDecimalV3Type(3, 1);
+ assertRewrite(new EqualTo(new Cast(tinyIntSlot, noConvertDecimalType),
new DecimalV3Literal(new BigDecimal("12.0"))),
+ new EqualTo(new Cast(tinyIntSlot, noConvertDecimalType), new
DecimalV3Literal(new BigDecimal("12.0"))));
+ assertRewrite(new EqualTo(new Cast(smallIntSlot,
noConvertDecimalType), new DecimalV3Literal(new BigDecimal("12.0"))),
+ new EqualTo(new Cast(smallIntSlot, noConvertDecimalType), new
DecimalV3Literal(new BigDecimal("12.0"))));
+ assertRewrite(new EqualTo(new Cast(intSlot, noConvertDecimalType), new
DecimalV3Literal(new BigDecimal("12.0"))),
+ new EqualTo(new Cast(intSlot, noConvertDecimalType), new
DecimalV3Literal(new BigDecimal("12.0"))));
+ assertRewrite(new EqualTo(new Cast(bigIntSlot, noConvertDecimalType),
new DecimalV3Literal(new BigDecimal("12.0"))),
+ new EqualTo(new Cast(bigIntSlot, noConvertDecimalType), new
DecimalV3Literal(new BigDecimal("12.0"))));
}
@Test
@@ -861,6 +919,14 @@ class SimplifyComparisonPredicateTest extends
ExpressionRewriteTestHelper {
Assertions.assertInstanceOf(DecimalV3Literal.class,
rewrittenExpression.child(1));
Assertions.assertEquals(new BigDecimal("1.20000"),
((DecimalV3Literal) rewrittenExpression.child(1)).getValue());
+
+ // don't convert for cast(b as decimal) if b's range > decimal's range
+ // or b's range = decimal's range and b's scale < decimal's scale
+ SlotReference decimalSlot = new SlotReference("slot",
DecimalV3Type.createDecimalV3Type(5, 2), true);
+ assertRewrite(new EqualTo(new Cast(decimalSlot,
DecimalV3Type.createDecimalV3Type(7, 5)), new DecimalV3Literal(new
BigDecimal("12.34567"))),
+ new EqualTo(new Cast(decimalSlot,
DecimalV3Type.createDecimalV3Type(7, 5)), new DecimalV3Literal(new
BigDecimal("12.34567"))));
+ assertRewrite(new EqualTo(new Cast(decimalSlot,
DecimalV3Type.createDecimalV3Type(4, 1)), new DecimalV3Literal(new
BigDecimal("123.4"))),
+ new EqualTo(new Cast(decimalSlot,
DecimalV3Type.createDecimalV3Type(4, 1)), new DecimalV3Literal(new
BigDecimal("123.4"))));
}
private enum RangeLimitResult {
diff --git
a/regression-test/data/nereids_rules_p0/expression/test_simplify_comparison_predicate_int_vs_double.out
b/regression-test/data/nereids_rules_p0/expression/test_simplify_comparison_predicate_int_vs_double.out
new file mode 100644
index 00000000000..59ae6df0d90
Binary files /dev/null and
b/regression-test/data/nereids_rules_p0/expression/test_simplify_comparison_predicate_int_vs_double.out
differ
diff --git
a/regression-test/suites/nereids_rules_p0/expression/test_simplify_comparison_predicate_int_vs_double.groovy
b/regression-test/suites/nereids_rules_p0/expression/test_simplify_comparison_predicate_int_vs_double.groovy
new file mode 100644
index 00000000000..cfe0b435ef2
--- /dev/null
+++
b/regression-test/suites/nereids_rules_p0/expression/test_simplify_comparison_predicate_int_vs_double.groovy
@@ -0,0 +1,161 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+//
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+suite('test_simplify_comparison_predicate_int_vs_double') {
+ sql """
+ set runtime_filter_mode='OFF';
+ set disable_join_reorder=false;
+ set ignore_shape_nodes='PhysicalDistribute';
+
+ drop table if exists
tbl1_test_simplify_comparison_predicate_int_vs_double force;
+ drop table if exists
tbl2_test_simplify_comparison_predicate_int_vs_double force;
+
+ create table tbl1_test_simplify_comparison_predicate_int_vs_double
+ (k1 int, c_s varchar(100)) properties('replication_num' =
'1');
+ create table tbl2_test_simplify_comparison_predicate_int_vs_double
+ (k2 int, c_bigint bigint, c_decimal decimal(6, 3))
properties('replication_num' = '1');
+
+ insert into tbl1_test_simplify_comparison_predicate_int_vs_double
values
+ (100, "870479087484055553"),
+ (101,"870479087484055554");
+ insert into tbl2_test_simplify_comparison_predicate_int_vs_double
values
+ (200, 870479087484055553, 999.999);
+ """
+
+
+ explainAndOrderResult 'cast_bigint_as_double', """
+ select *
+ from tbl1_test_simplify_comparison_predicate_int_vs_double t1
+ left join tbl2_test_simplify_comparison_predicate_int_vs_double t2
+ on t1.c_s = t2.c_bigint
+ where t1.c_s = '870479087484055553'
+ """
+
+ for (def delimit : [-(1L<<24), 1L<<24]) {
+ for (def diff : [-10, 0, 10]) {
+ def tag = "float_${delimit}_${diff}".replace('-', 'neg')
+ "qt_${tag}" """
+ explain shape plan
+ select c_bigint
+ from tbl2_test_simplify_comparison_predicate_int_vs_double
+ where cast(c_bigint as float) = cast('${delimit + diff}' as
float)
+ """
+ }
+ }
+
+ for (def delimit : [-(1L<<53), 1L<<53]) {
+ for (def diff : [-10, 0, 10]) {
+ def tag = "double_${delimit}_${diff}".replace('-', 'neg')
+ "qt_${tag}" """
+ explain shape plan
+ select c_bigint
+ from tbl2_test_simplify_comparison_predicate_int_vs_double
+ where cast(c_bigint as double) = cast('${delimit + diff}' as
double)
+ """
+
+ tag = "float_${delimit}_${diff}".replace('-', 'neg')
+ "qt_${tag}" """
+ explain shape plan
+ select c_bigint
+ from tbl2_test_simplify_comparison_predicate_int_vs_double
+ where cast(c_bigint as float) = cast('${delimit + diff}' as
float)
+ """
+ }
+ }
+
+ sql "set enable_strict_cast=false"
+
+ explainAndOrderResult 'int_vs_double_1', """
+ select *
+ from tbl2_test_simplify_comparison_predicate_int_vs_double
+ where c_bigint > 123.456
+ """
+
+ explainAndOrderResult 'int_vs_double_2', """
+ select *
+ from tbl2_test_simplify_comparison_predicate_int_vs_double
+ where cast(c_bigint as decimal(7, 3)) > 123.456
+ """
+
+ explainAndOrderResult 'decimal_vs_decimal_1', """
+ select *
+ from tbl2_test_simplify_comparison_predicate_int_vs_double
+ where c_decimal > 123.4567
+ """
+
+ explainAndOrderResult 'decimal_vs_decimal_2', """
+ select *
+ from tbl2_test_simplify_comparison_predicate_int_vs_double
+ where cast(c_decimal as decimal(3,1)) > cast(12.3 as decimal(5, 1))
+ """
+
+ explainAndOrderResult 'decimal_vs_decimal_3', """
+ select *
+ from tbl2_test_simplify_comparison_predicate_int_vs_double
+ where cast(c_decimal as decimal(5,2)) > cast(123.45 as decimal(5, 2))
+ """
+
+ sql "set enable_strict_cast=true"
+
+ explainAndOrderResult 'int_vs_double_3', """
+ select *
+ from tbl2_test_simplify_comparison_predicate_int_vs_double
+ where c_bigint > 123.456
+ """
+
+ explainAndOrderResult 'decimal_vs_decimal_4', """
+ select *
+ from tbl2_test_simplify_comparison_predicate_int_vs_double
+ where c_decimal > 123.4567
+ """
+
+ test {
+ sql """
+ select *
+ from tbl2_test_simplify_comparison_predicate_int_vs_double
+ where cast(c_bigint as decimal(7, 3)) > 123.456
+ """
+
+ exception 'Arithmetic overflow when converting value'
+ }
+
+ test {
+ sql """
+ select *
+ from tbl2_test_simplify_comparison_predicate_int_vs_double
+ where cast(c_decimal as decimal(3,1)) > cast(12.3 as decimal(5, 1))
+ """
+
+ exception 'Arithmetic overflow when converting value'
+ }
+
+ test {
+ sql """
+ select *
+ from tbl2_test_simplify_comparison_predicate_int_vs_double
+ where cast(c_decimal as decimal(5,2)) > cast(123.45 as decimal(5, 2))
+ """
+
+ exception 'Arithmetic overflow when converting value'
+ }
+
+ sql """
+ drop table if exists
tbl1_test_simplify_comparison_predicate_int_vs_double force;
+ drop table if exists
tbl2_test_simplify_comparison_predicate_int_vs_double force;
+ """
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]