mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
add decimal to decimal convertion in IN
This commit is contained in:
parent
ec22af6da0
commit
187311add0
@ -72,30 +72,33 @@ static Field convertNumericType(const Field & from, const IDataType & type)
|
||||
}
|
||||
|
||||
|
||||
template <typename From, typename To>
|
||||
static Field convertIntToDecimalType(const Field & from, const To & type)
|
||||
template <typename From, typename T>
|
||||
static Field convertIntToDecimalType(const Field & from, const DataTypeDecimal<T> & type)
|
||||
{
|
||||
using FieldType = typename To::FieldType;
|
||||
|
||||
From value = from.get<From>();
|
||||
if (!type.canStoreWhole(value))
|
||||
throw Exception("Number is too much to place in " + type.getName(), ErrorCodes::ARGUMENT_OUT_OF_BOUND);
|
||||
|
||||
FieldType scaled_value = type.getScaleMultiplier() * value;
|
||||
return DecimalField<FieldType>(scaled_value, type.getScale());
|
||||
T scaled_value = type.getScaleMultiplier() * value;
|
||||
return DecimalField<T>(scaled_value, type.getScale());
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
static Field convertStringToDecimalType(const Field & from, const DataTypeDecimal<T> & type)
|
||||
{
|
||||
using FieldType = typename DataTypeDecimal<T>::FieldType;
|
||||
|
||||
const String & str_value = from.get<String>();
|
||||
T value = type.parseFromString(str_value);
|
||||
return DecimalField<FieldType>(value, type.getScale());
|
||||
return DecimalField<T>(value, type.getScale());
|
||||
}
|
||||
|
||||
template <typename From, typename T>
|
||||
static Field convertDecimalToDecimalType(const Field & from, const DataTypeDecimal<T> & type)
|
||||
{
|
||||
auto field = from.get<DecimalField<From>>();
|
||||
T value = convertDecimals<DataTypeDecimal<From>, DataTypeDecimal<T>>(field.getValue(), field.getScale(), type.getScale());
|
||||
return DecimalField<T>(value, type.getScale());
|
||||
}
|
||||
|
||||
template <typename To>
|
||||
static Field convertDecimalType(const Field & from, const To & type)
|
||||
@ -107,6 +110,13 @@ static Field convertDecimalType(const Field & from, const To & type)
|
||||
if (from.getType() == Field::Types::String)
|
||||
return convertStringToDecimalType(from, type);
|
||||
|
||||
if (from.getType() == Field::Types::Decimal32)
|
||||
return convertDecimalToDecimalType<Decimal32>(from, type);
|
||||
if (from.getType() == Field::Types::Decimal64)
|
||||
return convertDecimalToDecimalType<Decimal64>(from, type);
|
||||
if (from.getType() == Field::Types::Decimal128)
|
||||
return convertDecimalToDecimalType<Decimal128>(from, type);
|
||||
|
||||
throw Exception("Type mismatch in IN or VALUES section. Expected: " + type.getName() + ". Got: "
|
||||
+ Field::Types::toString(from.getType()), ErrorCodes::TYPE_MISMATCH);
|
||||
}
|
||||
@ -284,7 +294,12 @@ Field convertFieldToType(const Field & from_value, const IDataType & to_type, co
|
||||
if (auto * low_cardinality_type = typeid_cast<const DataTypeLowCardinality *>(&to_type))
|
||||
return convertFieldToType(from_value, *low_cardinality_type->getDictionaryType(), from_type_hint);
|
||||
else if (auto * nullable_type = typeid_cast<const DataTypeNullable *>(&to_type))
|
||||
return convertFieldToTypeImpl(from_value, *nullable_type->getNestedType(), from_type_hint);
|
||||
{
|
||||
const IDataType & nested_type = *nullable_type->getNestedType();
|
||||
if (from_type_hint && from_type_hint->equals(nested_type))
|
||||
return from_value;
|
||||
return convertFieldToTypeImpl(from_value, nested_type, from_type_hint);
|
||||
}
|
||||
else
|
||||
return convertFieldToTypeImpl(from_value, to_type, from_type_hint);
|
||||
}
|
||||
|
18
dbms/tests/queries/0_stateless/00862_decimal_in.reference
Normal file
18
dbms/tests/queries/0_stateless/00862_decimal_in.reference
Normal file
@ -0,0 +1,18 @@
|
||||
128.00 128.00
|
||||
128.00 128.00
|
||||
128.00 128.00
|
||||
128.00 128.00
|
||||
128.00 128.00
|
||||
128.00 128.00
|
||||
32.00 32.00
|
||||
32.00 32.00
|
||||
32.00 32.00
|
||||
32.00 32.00
|
||||
32.00 32.00
|
||||
32.00 32.00
|
||||
64.00 64.00
|
||||
64.00 64.00
|
||||
64.00 64.00
|
||||
64.00 64.00
|
||||
64.00 64.00
|
||||
64.00 64.00
|
34
dbms/tests/queries/0_stateless/00862_decimal_in.sql
Normal file
34
dbms/tests/queries/0_stateless/00862_decimal_in.sql
Normal file
@ -0,0 +1,34 @@
|
||||
USE test;
|
||||
|
||||
DROP TABLE IF EXISTS temp;
|
||||
CREATE TABLE temp
|
||||
(
|
||||
x Decimal(38,2),
|
||||
y Nullable(Decimal(38,2))
|
||||
) ENGINE = Memory;
|
||||
|
||||
INSERT INTO temp VALUES (32, 32), (64, 64), (128, 128);
|
||||
|
||||
SELECT * FROM temp WHERE x IN (toDecimal128(128, 2));
|
||||
SELECT * FROM temp WHERE y IN (toDecimal128(128, 2));
|
||||
|
||||
SELECT * FROM temp WHERE x IN (toDecimal128(128, 1));
|
||||
SELECT * FROM temp WHERE x IN (toDecimal128(128, 3));
|
||||
SELECT * FROM temp WHERE y IN (toDecimal128(128, 1));
|
||||
SELECT * FROM temp WHERE y IN (toDecimal128(128, 3));
|
||||
|
||||
SELECT * FROM temp WHERE x IN (toDecimal32(32, 1));
|
||||
SELECT * FROM temp WHERE x IN (toDecimal32(32, 2));
|
||||
SELECT * FROM temp WHERE x IN (toDecimal32(32, 3));
|
||||
SELECT * FROM temp WHERE y IN (toDecimal32(32, 1));
|
||||
SELECT * FROM temp WHERE y IN (toDecimal32(32, 2));
|
||||
SELECT * FROM temp WHERE y IN (toDecimal32(32, 3));
|
||||
|
||||
SELECT * FROM temp WHERE x IN (toDecimal64(64, 1));
|
||||
SELECT * FROM temp WHERE x IN (toDecimal64(64, 2));
|
||||
SELECT * FROM temp WHERE x IN (toDecimal64(64, 3));
|
||||
SELECT * FROM temp WHERE y IN (toDecimal64(64, 1));
|
||||
SELECT * FROM temp WHERE y IN (toDecimal64(64, 2));
|
||||
SELECT * FROM temp WHERE y IN (toDecimal64(64, 3));
|
||||
|
||||
DROP TABLE IF EXISTS temp;
|
Loading…
Reference in New Issue
Block a user