add a function to process floating point literal comparing with decimal type in IN opertor

This commit is contained in:
lhuang09287750 2022-09-20 03:26:43 +00:00 committed by Vladimir C
parent ba56540c3d
commit 338f41913c
3 changed files with 70 additions and 0 deletions

View File

@ -109,6 +109,22 @@ Field convertDecimalToDecimalType(const Field & from, const DataTypeDecimal<T> &
return DecimalField<T>(value, type.getScale()); return DecimalField<T>(value, type.getScale());
} }
template <typename From, typename T>
Field convertFloatToDecimalType(const Field & from, const DataTypeDecimal<T> & type)
{
From dValue = from.get<From>();
if (!type.canStoreWhole(dValue))
throw Exception("Number is too big to place in " + type.getName(), ErrorCodes::ARGUMENT_OUT_OF_BOUND);
std::stringstream stream;
stream<<dValue;
String sValue = stream.str();
int fromScale = sValue.length()- sValue.find('.') - 1;
auto scaled_value = convertToDecimal<DataTypeNumber<From>, DataTypeDecimal<T>>(dValue, fromScale);
return DecimalField<T>(scaled_value, fromScale);
}
template <typename To> template <typename To>
Field convertDecimalType(const Field & from, const To & type) Field convertDecimalType(const Field & from, const To & type)
{ {
@ -135,6 +151,9 @@ Field convertDecimalType(const Field & from, const To & type)
if (from.getType() == Field::Types::Decimal128) if (from.getType() == Field::Types::Decimal128)
return convertDecimalToDecimalType<Decimal128>(from, type); return convertDecimalToDecimalType<Decimal128>(from, type);
if (from.getType() == Field::Types::Float64)
return convertFloatToDecimalType<Float64>(from, type);
throw Exception(ErrorCodes::TYPE_MISMATCH, "Type mismatch in IN or VALUES section. Expected: {}. Got: {}", throw Exception(ErrorCodes::TYPE_MISMATCH, "Type mismatch in IN or VALUES section. Expected: {}. Got: {}",
type.getName(), from.getType()); type.getName(), from.getType());
} }

View File

@ -0,0 +1,20 @@
0
1
1
0
0
1
1
0
0
1
1
0
0
1
1
0
1
1
1
1

View File

@ -0,0 +1,31 @@
SELECT toDecimal32(1.555,3) IN (1.5551);
SELECT toDecimal32(1.555,3) IN (1.5551,1.555);
SELECT toDecimal32(1.555,3) IN (1.5551,1.555000);
SELECT toDecimal32(1.555,3) IN (1.550,1.5);
SELECT toDecimal64(1.555,3) IN (1.5551);
SELECT toDecimal64(1.555,3) IN (1.5551,1.555);
SELECT toDecimal64(1.555,3) IN (1.5551,1.555000);
SELECT toDecimal64(1.555,3) IN (1.550,1.5);
SELECT toDecimal128(1.555,3) IN (1.5551);
SELECT toDecimal128(1.555,3) IN (1.5551,1.555);
SELECT toDecimal128(1.555,3) IN (1.5551,1.555000);
SELECT toDecimal128(1.555,3) IN (1.550,1.5);
SELECT toDecimal256(1.555,3) IN (1.5551);
SELECT toDecimal256(1.555,3) IN (1.5551,1.555);
SELECT toDecimal256(1.555,3) IN (1.5551,1.555000);
SELECT toDecimal256(1.555,3) IN (1.550,1.5);
DROP TABLE IF EXISTS decimal_in_float_test;
CREATE TABLE decimal_in_float_test ( `a` Decimal(18, 0), `b` Decimal(36, 2) ) ENGINE = Memory;
INSERT INTO decimal_in_float_test VALUES ('33', '44.44');
SELECT count() == 1 FROM decimal_in_float_test WHERE a IN (33);
SELECT count() == 1 FROM decimal_in_float_test WHERE a NOT IN (33.333);
SELECT count() == 1 FROM decimal_in_float_test WHERE b IN (44.44);
SELECT count() == 1 FROM decimal_in_float_test WHERE b NOT IN (44.4,44.444);
DROP TABLE IF EXISTS decimal_in_float_test;