Merge pull request #8144 from 4ertus2/decimal

Decimal specializations for min/max
This commit is contained in:
alexey-milovidov 2019-12-12 18:18:14 +03:00 committed by GitHub
commit 29b2e26074
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 71 additions and 6 deletions

View File

@ -4,6 +4,7 @@
#include <IO/ReadHelpers.h>
#include <Columns/ColumnVector.h>
#include <Columns/ColumnDecimal.h>
#include <Columns/ColumnString.h>
#include <DataTypes/IDataType.h>
#include <common/StringRef.h>
@ -26,6 +27,7 @@ struct SingleValueDataFixed
{
private:
using Self = SingleValueDataFixed;
using ColVecType = std::conditional_t<IsDecimalNumber<T>, ColumnDecimal<T>, ColumnVector<T>>;
bool has_value = false; /// We need to remember if at least one value has been passed. This is necessary for AggregateFunctionIf.
T value;
@ -39,9 +41,9 @@ public:
void insertResultInto(IColumn & to) const
{
if (has())
assert_cast<ColumnVector<T> &>(to).getData().push_back(value);
assert_cast<ColVecType &>(to).getData().push_back(value);
else
assert_cast<ColumnVector<T> &>(to).insertDefault();
assert_cast<ColVecType &>(to).insertDefault();
}
void write(WriteBuffer & buf, const IDataType & /*data_type*/) const
@ -62,7 +64,7 @@ public:
void change(const IColumn & column, size_t row_num, Arena *)
{
has_value = true;
value = assert_cast<const ColumnVector<T> &>(column).getData()[row_num];
value = assert_cast<const ColVecType &>(column).getData()[row_num];
}
/// Assuming to.has()
@ -113,7 +115,7 @@ public:
bool changeIfLess(const IColumn & column, size_t row_num, Arena * arena)
{
if (!has() || assert_cast<const ColumnVector<T> &>(column).getData()[row_num] < value)
if (!has() || assert_cast<const ColVecType &>(column).getData()[row_num] < value)
{
change(column, row_num, arena);
return true;
@ -135,7 +137,7 @@ public:
bool changeIfGreater(const IColumn & column, size_t row_num, Arena * arena)
{
if (!has() || assert_cast<const ColumnVector<T> &>(column).getData()[row_num] > value)
if (!has() || assert_cast<const ColVecType &>(column).getData()[row_num] > value)
{
change(column, row_num, arena);
return true;
@ -162,7 +164,7 @@ public:
bool isEqualTo(const IColumn & column, size_t row_num) const
{
return has() && assert_cast<const ColumnVector<T> &>(column).getData()[row_num] == value;
return has() && assert_cast<const ColVecType &>(column).getData()[row_num] == value;
}
};

View File

@ -32,6 +32,12 @@ static IAggregateFunction * createAggregateFunctionSingleValue(const String & na
return new AggregateFunctionTemplate<Data<SingleValueDataFixed<DataTypeDate::FieldType>>, false>(argument_type);
if (which.idx == TypeIndex::DateTime)
return new AggregateFunctionTemplate<Data<SingleValueDataFixed<DataTypeDateTime::FieldType>>, false>(argument_type);
if (which.idx == TypeIndex::Decimal32)
return new AggregateFunctionTemplate<Data<SingleValueDataFixed<Decimal32>>, false>(argument_type);
if (which.idx == TypeIndex::Decimal64)
return new AggregateFunctionTemplate<Data<SingleValueDataFixed<Decimal64>>, false>(argument_type);
if (which.idx == TypeIndex::Decimal128)
return new AggregateFunctionTemplate<Data<SingleValueDataFixed<Decimal128>>, false>(argument_type);
if (which.idx == TypeIndex::String)
return new AggregateFunctionTemplate<Data<SingleValueDataString>, true>(argument_type);
@ -54,6 +60,12 @@ static IAggregateFunction * createAggregateFunctionArgMinMaxSecond(const DataTyp
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<DataTypeDate::FieldType>>>, false>(res_type, val_type);
if (which.idx == TypeIndex::DateTime)
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<DataTypeDateTime::FieldType>>>, false>(res_type, val_type);
if (which.idx == TypeIndex::Decimal32)
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<Decimal32>>>, false>(res_type, val_type);
if (which.idx == TypeIndex::Decimal64)
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<Decimal64>>>, false>(res_type, val_type);
if (which.idx == TypeIndex::Decimal128)
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<Decimal128>>>, false>(res_type, val_type);
if (which.idx == TypeIndex::String)
return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataString>>, true>(res_type, val_type);
@ -80,6 +92,12 @@ static IAggregateFunction * createAggregateFunctionArgMinMax(const String & name
return createAggregateFunctionArgMinMaxSecond<MinMaxData, SingleValueDataFixed<DataTypeDate::FieldType>>(res_type, val_type);
if (which.idx == TypeIndex::DateTime)
return createAggregateFunctionArgMinMaxSecond<MinMaxData, SingleValueDataFixed<DataTypeDateTime::FieldType>>(res_type, val_type);
if (which.idx == TypeIndex::Decimal32)
return createAggregateFunctionArgMinMaxSecond<MinMaxData, SingleValueDataFixed<Decimal32>>(res_type, val_type);
if (which.idx == TypeIndex::Decimal64)
return createAggregateFunctionArgMinMaxSecond<MinMaxData, SingleValueDataFixed<Decimal64>>(res_type, val_type);
if (which.idx == TypeIndex::Decimal128)
return createAggregateFunctionArgMinMaxSecond<MinMaxData, SingleValueDataFixed<Decimal128>>(res_type, val_type);
if (which.idx == TypeIndex::String)
return createAggregateFunctionArgMinMaxSecond<MinMaxData, SingleValueDataString>(res_type, val_type);

View File

@ -0,0 +1,45 @@
<test>
<type>loop</type>
<create_query>CREATE TABLE t (x UInt64, d32 Decimal32(3), d64 Decimal64(4), d128 Decimal128(5)) ENGINE = Memory</create_query>
<fill_query>INSERT INTO t SELECT number AS x, x AS d32, x AS d64, x d128 FROM numbers(1000000)</fill_query>
<drop_query>DROP TABLE IF EXISTS t</drop_query>
<stop_conditions>
<all_of>
<iterations>10</iterations>
</all_of>
</stop_conditions>
<main_metric>
<rows_per_second />
</main_metric>
<query>SELECT min(d32), max(d32), argMin(x, d32), argMax(x, d32) FROM t</query>
<query>SELECT min(d64), max(d64), argMin(x, d64), argMax(x, d64) FROM t</query>
<query>SELECT min(d128), max(d128), argMin(x, d128), argMax(x, d128) FROM t</query>
<query>SELECT avg(d32), sum(d32), sumWithOverflow(d32) FROM t</query>
<query>SELECT avg(d64), sum(d64), sumWithOverflow(d64) FROM t</query>
<query>SELECT avg(d128), sum(d128), sumWithOverflow(d128) FROM t</query>
<query>SELECT uniq(d32), uniqCombined(d32), uniqExact(d32), uniqHLL12(d32) FROM t</query>
<query>SELECT uniq(d64), uniqCombined(d64), uniqExact(d64), uniqHLL12(d64) FROM t</query>
<query>SELECT uniq(d128), uniqCombined(d128), uniqExact(d128), uniqHLL12(d128) FROM t</query>
<query>SELECT median(d32), medianExact(d32), medianExactWeighted(d32, 2) FROM t</query>
<query>SELECT median(d64), medianExact(d64), medianExactWeighted(d64, 2) FROM t</query>
<query>SELECT median(d128), medianExact(d128), medianExactWeighted(d128, 2) FROM t</query>
<query>SELECT quantile(d32), quantileExact(d32), quantileExactWeighted(d32, 2) FROM t</query>
<query>SELECT quantile(d64), quantileExact(d64), quantileExactWeighted(d64, 2) FROM t</query>
<query>SELECT quantile(d128), quantileExact(d128), quantileExactWeighted(d128, 2) FROM t</query>
<query>SELECT quantilesExact(0.1, 0.9)(d32), quantilesExactWeighted(0.1, 0.9)(d32, 2) FROM t</query>
<query>SELECT quantilesExact(0.1, 0.9)(d64), quantilesExactWeighted(0.1, 0.9)(d64, 2) FROM t</query>
<query>SELECT quantilesExact(0.1, 0.9)(d128), quantilesExactWeighted(0.1, 0.9)(d128, 2) FROM t</query>
<query>SELECT varPop(d32), varSamp(d32), stddevPop(d32) FROM t</query>
<query>SELECT varPop(d64), varSamp(d64), stddevPop(d64) FROM t</query>
<query>SELECT varPop(d128), varSamp(d128), stddevPop(d128) FROM t</query>
</test>