some decimal field improvements CLICKHOUSE-3765

This commit is contained in:
chertus 2018-08-24 19:35:00 +03:00
parent 2e65f4922f
commit 53ec40eeee
6 changed files with 56 additions and 10 deletions

View File

@ -278,8 +278,17 @@ void ColumnVector<T>::getExtremes(Field & min, Field & max) const
if (size == 0)
{
min = typename NearestFieldType<T>::Type(0);
max = typename NearestFieldType<T>::Type(0);
if constexpr (IsDecimalNumber<T>)
{
min = typename NearestFieldType<T>::Type(0, data.getScale());
max = typename NearestFieldType<T>::Type(0, data.getScale());
}
else
{
min = typename NearestFieldType<T>::Type(0);
max = typename NearestFieldType<T>::Type(0);
}
return;
}
@ -313,8 +322,16 @@ void ColumnVector<T>::getExtremes(Field & min, Field & max) const
cur_max = x;
}
min = typename NearestFieldType<T>::Type(cur_min);
max = typename NearestFieldType<T>::Type(cur_max);
if constexpr (IsDecimalNumber<T>)
{
min = typename NearestFieldType<T>::Type(cur_min, data.getScale());
max = typename NearestFieldType<T>::Type(cur_max, data.getScale());
}
else
{
min = typename NearestFieldType<T>::Type(cur_min);
max = typename NearestFieldType<T>::Type(cur_max);
}
}
/// Explicit template instantiations - to avoid code bloat in headers.

View File

@ -38,7 +38,7 @@ class DecimalField
public:
static constexpr UInt32 wrongScale() { return std::numeric_limits<UInt32>::max(); }
DecimalField(T value, UInt32 scale_ = wrongScale())
DecimalField(T value, UInt32 scale_)
: dec(value),
scale(scale_)
{}

View File

@ -76,11 +76,17 @@ const ColumnConst * checkAndGetColumnConstStringOrFixedString(const IColumn * co
/// Transform anything to Field.
template <typename T>
inline Field toField(const T & x)
inline std::enable_if_t<!IsDecimalNumber<T>, Field> toField(const T & x)
{
return Field(typename NearestFieldType<T>::Type(x));
}
template <typename T>
inline std::enable_if_t<IsDecimalNumber<T>, Field> toField(const T & x, UInt32 scale)
{
return Field(typename NearestFieldType<T>::Type(x, scale));
}
Columns convertConstTupleToConstantElements(const ColumnConst & column);

View File

@ -1227,14 +1227,16 @@ public:
auto res = OpImpl::constant_constant(
col_left->template getValue<T0>(), col_right->template getValue<T1>(), scale_a, scale_b);
block.getByPosition(result).column =
ResultDataType(type.getPrecision(), type.getScale()).createColumnConst(col_left->size(), toField(res));
ResultDataType(type.getPrecision(), type.getScale()).createColumnConst(
col_left->size(), toField(res, type.getScale()));
}
else
{
auto res = OpImpl::XOverflow::constant_constant(
col_left->template getValue<T0>(), col_right->template getValue<T1>(), scale_a, scale_b);
block.getByPosition(result).column =
ResultDataType(type.getPrecision(), type.getScale()).createColumnConst(col_left->size(), toField(res));
ResultDataType(type.getPrecision(), type.getScale()).createColumnConst(
col_left->size(), toField(res, type.getScale()));
}
}
else

View File

@ -84,7 +84,7 @@ static Field convertIntToDecimalType(const Field & from, const To & type)
throw Exception("Number is too much to place in " + type.getName(), ErrorCodes::ARGUMENT_OUT_OF_BOUND);
FieldType scaled_value = type.getScaleMultiplier() * value;
return Field(typename NearestFieldType<FieldType>::Type(scaled_value));
return Field(typename NearestFieldType<FieldType>::Type(scaled_value, type.getScale()));
}
@ -95,7 +95,7 @@ static Field convertStringToDecimalType(const Field & from, const DataTypeDecima
const String & str_value = from.get<String>();
T value = type.parseFromString(str_value);
return Field(typename NearestFieldType<FieldType>::Type(value));
return Field(typename NearestFieldType<FieldType>::Type(value, type.getScale()));
}

View File

@ -0,0 +1,21 @@
SET allow_experimental_decimal_type = 1;
CREATE DATABASE IF NOT EXISTS test;
DROP TABLE IF EXISTS test.decimal;
CREATE TABLE IF NOT EXISTS test.decimal
(
d1 DECIMAL(9, 8),
d2 DECIMAL(18, 8),
d3 DECIMAL(38, 8)
)
ENGINE = MergeTree
PARTITION BY toInt32(d1)
ORDER BY (d2, d3);
INSERT INTO test.decimal (d1, d2, d3)
SELECT toDecimal32(number % 10, 8), toDecimal64(number, 8), toDecimal128(number, 8) FROM system.numbers LIMIT 50;
SELECT count() FROM test.decimal WHERE d1 = 1;
--SELECT * FROM test.decimal WHERE d1 <= toDecimal32(2, 8) ORDER BY d2 DESC;
DROP TABLE test.decimal;