mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
add missing array functions for Decimals
This commit is contained in:
parent
5548c3328d
commit
a8a283ffdc
@ -1,5 +1,7 @@
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <DataTypes/DataTypesDecimal.h>
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <Columns/ColumnDecimal.h>
|
||||
#include <Functions/array/FunctionArrayMapped.h>
|
||||
#include <Functions/FunctionFactory.h>
|
||||
|
||||
@ -27,16 +29,23 @@ struct ArrayCompactImpl
|
||||
template <typename T>
|
||||
static bool executeType(const ColumnPtr & mapped, const ColumnArray & array, ColumnPtr & res_ptr)
|
||||
{
|
||||
const ColumnVector<T> * src_values_column = checkAndGetColumn<ColumnVector<T>>(mapped.get());
|
||||
using ColVecType = std::conditional_t<IsDecimalNumber<T>, ColumnDecimal<T>, ColumnVector<T>>;
|
||||
|
||||
const ColVecType * src_values_column = checkAndGetColumn<ColVecType>(mapped.get());
|
||||
|
||||
if (!src_values_column)
|
||||
return false;
|
||||
|
||||
const IColumn::Offsets & src_offsets = array.getOffsets();
|
||||
const typename ColumnVector<T>::Container & src_values = src_values_column->getData();
|
||||
const typename ColVecType::Container & src_values = src_values_column->getData();
|
||||
|
||||
auto res_values_column = ColumnVector<T>::create(src_values.size());
|
||||
typename ColumnVector<T>::Container & res_values = res_values_column->getData();
|
||||
typename ColVecType::MutablePtr res_values_column;
|
||||
if constexpr (IsDecimalNumber<T>)
|
||||
res_values_column = ColVecType::create(src_values.size(), src_values.getScale());
|
||||
else
|
||||
res_values_column = ColVecType::create(src_values.size());
|
||||
|
||||
typename ColVecType::Container & res_values = res_values_column->getData();
|
||||
size_t src_offsets_size = src_offsets.size();
|
||||
auto res_offsets_column = ColumnArray::ColumnOffsets::create(src_offsets_size);
|
||||
IColumn::Offsets & res_offsets = res_offsets_column->getData();
|
||||
@ -129,7 +138,10 @@ struct ArrayCompactImpl
|
||||
executeType< Int32 >(mapped, array, res) ||
|
||||
executeType< Int64 >(mapped, array, res) ||
|
||||
executeType<Float32>(mapped, array, res) ||
|
||||
executeType<Float64>(mapped, array, res)))
|
||||
executeType<Float64>(mapped, array, res)) ||
|
||||
executeType<Decimal32>(mapped, array, res) ||
|
||||
executeType<Decimal64>(mapped, array, res) ||
|
||||
executeType<Decimal128>(mapped, array, res))
|
||||
{
|
||||
executeGeneric(mapped, array, res);
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <DataTypes/DataTypesDecimal.h>
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <Columns/ColumnDecimal.h>
|
||||
#include "FunctionArrayMapped.h"
|
||||
#include <Functions/FunctionFactory.h>
|
||||
|
||||
@ -31,6 +33,13 @@ struct ArrayCumSumImpl
|
||||
if (which.isFloat())
|
||||
return std::make_shared<DataTypeArray>(std::make_shared<DataTypeFloat64>());
|
||||
|
||||
if (which.isDecimal())
|
||||
{
|
||||
UInt32 scale = getDecimalScale(*expression_return);
|
||||
DataTypePtr nested = std::make_shared<DataTypeDecimal<Decimal128>>(maxDecimalPrecision<Decimal128>(), scale);
|
||||
return std::make_shared<DataTypeArray>(nested);
|
||||
}
|
||||
|
||||
throw Exception("arrayCumSum cannot add values of type " + expression_return->getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
}
|
||||
|
||||
@ -38,11 +47,15 @@ struct ArrayCumSumImpl
|
||||
template <typename Element, typename Result>
|
||||
static bool executeType(const ColumnPtr & mapped, const ColumnArray & array, ColumnPtr & res_ptr)
|
||||
{
|
||||
const ColumnVector<Element> * column = checkAndGetColumn<ColumnVector<Element>>(&*mapped);
|
||||
using ColVecType = std::conditional_t<IsDecimalNumber<Element>, ColumnDecimal<Element>, ColumnVector<Element>>;
|
||||
using ColVecResult = std::conditional_t<IsDecimalNumber<Result>, ColumnDecimal<Result>, ColumnVector<Result>>;
|
||||
|
||||
const ColVecType * column = checkAndGetColumn<ColVecType>(&*mapped);
|
||||
const typename ColVecType::Container & data = column->getData();
|
||||
|
||||
if (!column)
|
||||
{
|
||||
const ColumnConst * column_const = checkAndGetColumnConst<ColumnVector<Element>>(&*mapped);
|
||||
const ColumnConst * column_const = checkAndGetColumnConst<ColVecType>(&*mapped);
|
||||
|
||||
if (!column_const)
|
||||
return false;
|
||||
@ -50,8 +63,13 @@ struct ArrayCumSumImpl
|
||||
const Element x = column_const->template getValue<Element>();
|
||||
const IColumn::Offsets & offsets = array.getOffsets();
|
||||
|
||||
auto res_nested = ColumnVector<Result>::create();
|
||||
typename ColumnVector<Result>::Container & res_values = res_nested->getData();
|
||||
typename ColVecResult::MutablePtr res_nested;
|
||||
if constexpr (IsDecimalNumber<Element>)
|
||||
res_nested = ColVecResult::create(0, data.getScale());
|
||||
else
|
||||
res_nested = ColVecResult::create();
|
||||
|
||||
typename ColVecResult::Container & res_values = res_nested->getData();
|
||||
res_values.resize(column_const->size());
|
||||
|
||||
size_t pos = 0;
|
||||
@ -73,10 +91,14 @@ struct ArrayCumSumImpl
|
||||
}
|
||||
|
||||
const IColumn::Offsets & offsets = array.getOffsets();
|
||||
const typename ColumnVector<Element>::Container & data = column->getData();
|
||||
|
||||
auto res_nested = ColumnVector<Result>::create();
|
||||
typename ColumnVector<Result>::Container & res_values = res_nested->getData();
|
||||
typename ColVecResult::MutablePtr res_nested;
|
||||
if constexpr (IsDecimalNumber<Element>)
|
||||
res_nested = ColVecResult::create(0, data.getScale());
|
||||
else
|
||||
res_nested = ColVecResult::create();
|
||||
|
||||
typename ColVecResult::Container & res_values = res_nested->getData();
|
||||
res_values.resize(data.size());
|
||||
|
||||
size_t pos = 0;
|
||||
@ -110,7 +132,10 @@ struct ArrayCumSumImpl
|
||||
executeType< Int32, Int64>(mapped, array, res) ||
|
||||
executeType< Int64, Int64>(mapped, array, res) ||
|
||||
executeType<Float32,Float64>(mapped, array, res) ||
|
||||
executeType<Float64,Float64>(mapped, array, res))
|
||||
executeType<Float64,Float64>(mapped, array, res) ||
|
||||
executeType<Decimal32, Decimal128>(mapped, array, res) ||
|
||||
executeType<Decimal64, Decimal128>(mapped, array, res) ||
|
||||
executeType<Decimal128, Decimal128>(mapped, array, res))
|
||||
return res;
|
||||
else
|
||||
throw Exception("Unexpected column for arrayCumSum: " + mapped->getName(), ErrorCodes::ILLEGAL_COLUMN);
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <DataTypes/DataTypesDecimal.h>
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <Columns/ColumnDecimal.h>
|
||||
#include "FunctionArrayMapped.h"
|
||||
#include <Functions/FunctionFactory.h>
|
||||
|
||||
@ -34,6 +36,13 @@ struct ArrayCumSumNonNegativeImpl
|
||||
if (which.isFloat())
|
||||
return std::make_shared<DataTypeArray>(std::make_shared<DataTypeFloat64>());
|
||||
|
||||
if (which.isDecimal())
|
||||
{
|
||||
UInt32 scale = getDecimalScale(*expression_return);
|
||||
DataTypePtr nested = std::make_shared<DataTypeDecimal<Decimal128>>(maxDecimalPrecision<Decimal128>(), scale);
|
||||
return std::make_shared<DataTypeArray>(nested);
|
||||
}
|
||||
|
||||
throw Exception("arrayCumSumNonNegativeImpl cannot add values of type " + expression_return->getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
}
|
||||
|
||||
@ -41,16 +50,24 @@ struct ArrayCumSumNonNegativeImpl
|
||||
template <typename Element, typename Result>
|
||||
static bool executeType(const ColumnPtr & mapped, const ColumnArray & array, ColumnPtr & res_ptr)
|
||||
{
|
||||
const ColumnVector<Element> * column = checkAndGetColumn<ColumnVector<Element>>(&*mapped);
|
||||
using ColVecType = std::conditional_t<IsDecimalNumber<Element>, ColumnDecimal<Element>, ColumnVector<Element>>;
|
||||
using ColVecResult = std::conditional_t<IsDecimalNumber<Result>, ColumnDecimal<Result>, ColumnVector<Result>>;
|
||||
|
||||
const ColVecType * column = checkAndGetColumn<ColVecType>(&*mapped);
|
||||
|
||||
if (!column)
|
||||
return false;
|
||||
|
||||
const IColumn::Offsets & offsets = array.getOffsets();
|
||||
const typename ColumnVector<Element>::Container & data = column->getData();
|
||||
const typename ColVecType::Container & data = column->getData();
|
||||
|
||||
auto res_nested = ColumnVector<Result>::create();
|
||||
typename ColumnVector<Result>::Container & res_values = res_nested->getData();
|
||||
typename ColVecResult::MutablePtr res_nested;
|
||||
if constexpr (IsDecimalNumber<Element>)
|
||||
res_nested = ColVecResult::create(0, data.getScale());
|
||||
else
|
||||
res_nested = ColVecResult::create();
|
||||
|
||||
typename ColVecResult::Container & res_values = res_nested->getData();
|
||||
res_values.resize(data.size());
|
||||
|
||||
size_t pos = 0;
|
||||
@ -60,7 +77,7 @@ struct ArrayCumSumNonNegativeImpl
|
||||
// skip empty arrays
|
||||
if (pos < offsets[i])
|
||||
{
|
||||
accum_sum = data[pos] > 0 ? data[pos] : 0;
|
||||
accum_sum = data[pos] > 0 ? data[pos] : Element(0);
|
||||
res_values[pos] = accum_sum;
|
||||
for (++pos; pos < offsets[i]; ++pos)
|
||||
{
|
||||
@ -90,7 +107,10 @@ struct ArrayCumSumNonNegativeImpl
|
||||
executeType< Int32, Int64>(mapped, array, res) ||
|
||||
executeType< Int64, Int64>(mapped, array, res) ||
|
||||
executeType<Float32,Float64>(mapped, array, res) ||
|
||||
executeType<Float64,Float64>(mapped, array, res))
|
||||
executeType<Float64,Float64>(mapped, array, res) ||
|
||||
executeType<Decimal32, Decimal128>(mapped, array, res) ||
|
||||
executeType<Decimal64, Decimal128>(mapped, array, res) ||
|
||||
executeType<Decimal128, Decimal128>(mapped, array, res))
|
||||
return res;
|
||||
else
|
||||
throw Exception("Unexpected column for arrayCumSumNonNegativeImpl: " + mapped->getName(), ErrorCodes::ILLEGAL_COLUMN);
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <DataTypes/DataTypesDecimal.h>
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <Columns/ColumnDecimal.h>
|
||||
#include "FunctionArrayMapped.h"
|
||||
#include <Functions/FunctionFactory.h>
|
||||
|
||||
@ -37,6 +39,9 @@ struct ArrayDifferenceImpl
|
||||
if (which.isFloat32() || which.isFloat64())
|
||||
return std::make_shared<DataTypeArray>(std::make_shared<DataTypeFloat64>());
|
||||
|
||||
if (which.isDecimal())
|
||||
return std::make_shared<DataTypeArray>(expression_return);
|
||||
|
||||
throw Exception("arrayDifference cannot process values of type " + expression_return->getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
}
|
||||
|
||||
@ -44,16 +49,24 @@ struct ArrayDifferenceImpl
|
||||
template <typename Element, typename Result>
|
||||
static bool executeType(const ColumnPtr & mapped, const ColumnArray & array, ColumnPtr & res_ptr)
|
||||
{
|
||||
const ColumnVector<Element> * column = checkAndGetColumn<ColumnVector<Element>>(&*mapped);
|
||||
using ColVecType = std::conditional_t<IsDecimalNumber<Element>, ColumnDecimal<Element>, ColumnVector<Element>>;
|
||||
using ColVecResult = std::conditional_t<IsDecimalNumber<Result>, ColumnDecimal<Result>, ColumnVector<Result>>;
|
||||
|
||||
const ColVecType * column = checkAndGetColumn<ColVecType>(&*mapped);
|
||||
|
||||
if (!column)
|
||||
return false;
|
||||
|
||||
const IColumn::Offsets & offsets = array.getOffsets();
|
||||
const typename ColumnVector<Element>::Container & data = column->getData();
|
||||
const typename ColVecType::Container & data = column->getData();
|
||||
|
||||
auto res_nested = ColumnVector<Result>::create();
|
||||
typename ColumnVector<Result>::Container & res_values = res_nested->getData();
|
||||
typename ColVecResult::MutablePtr res_nested;
|
||||
if constexpr (IsDecimalNumber<Element>)
|
||||
res_nested = ColVecResult::create(0, data.getScale());
|
||||
else
|
||||
res_nested = ColVecResult::create();
|
||||
|
||||
typename ColVecResult::Container & res_values = res_nested->getData();
|
||||
res_values.resize(data.size());
|
||||
|
||||
size_t pos = 0;
|
||||
@ -87,7 +100,10 @@ struct ArrayDifferenceImpl
|
||||
executeType< Int32, Int64>(mapped, array, res) ||
|
||||
executeType< Int64, Int64>(mapped, array, res) ||
|
||||
executeType<Float32,Float64>(mapped, array, res) ||
|
||||
executeType<Float64,Float64>(mapped, array, res))
|
||||
executeType<Float64,Float64>(mapped, array, res) ||
|
||||
executeType<Decimal32, Decimal32>(mapped, array, res) ||
|
||||
executeType<Decimal64, Decimal64>(mapped, array, res) ||
|
||||
executeType<Decimal128, Decimal128>(mapped, array, res))
|
||||
return res;
|
||||
else
|
||||
throw Exception("Unexpected column for arrayDifference: " + mapped->getName(), ErrorCodes::ILLEGAL_COLUMN);
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <DataTypes/DataTypesDecimal.h>
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <Columns/ColumnDecimal.h>
|
||||
#include "FunctionArrayMapped.h"
|
||||
#include <Functions/FunctionFactory.h>
|
||||
|
||||
@ -31,25 +33,40 @@ struct ArraySumImpl
|
||||
if (which.isFloat())
|
||||
return std::make_shared<DataTypeFloat64>();
|
||||
|
||||
if (which.isDecimal())
|
||||
{
|
||||
UInt32 scale = getDecimalScale(*expression_return);
|
||||
return std::make_shared<DataTypeDecimal<Decimal128>>(maxDecimalPrecision<Decimal128>(), scale);
|
||||
}
|
||||
|
||||
throw Exception("arraySum cannot add values of type " + expression_return->getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
}
|
||||
|
||||
template <typename Element, typename Result>
|
||||
static bool executeType(const ColumnPtr & mapped, const ColumnArray::Offsets & offsets, ColumnPtr & res_ptr)
|
||||
{
|
||||
const ColumnVector<Element> * column = checkAndGetColumn<ColumnVector<Element>>(&*mapped);
|
||||
using ColVecType = std::conditional_t<IsDecimalNumber<Element>, ColumnDecimal<Element>, ColumnVector<Element>>;
|
||||
using ColVecResult = std::conditional_t<IsDecimalNumber<Result>, ColumnDecimal<Result>, ColumnVector<Result>>;
|
||||
|
||||
const ColVecType * column = checkAndGetColumn<ColVecType>(&*mapped);
|
||||
const typename ColVecType::Container & data = column->getData();
|
||||
|
||||
if (!column)
|
||||
{
|
||||
const ColumnConst * column_const = checkAndGetColumnConst<ColumnVector<Element>>(&*mapped);
|
||||
const ColumnConst * column_const = checkAndGetColumnConst<ColVecType>(&*mapped);
|
||||
|
||||
if (!column_const)
|
||||
return false;
|
||||
|
||||
const Element x = column_const->template getValue<Element>();
|
||||
|
||||
auto res_column = ColumnVector<Result>::create(offsets.size());
|
||||
typename ColumnVector<Result>::Container & res = res_column->getData();
|
||||
typename ColVecResult::MutablePtr res_column;
|
||||
if constexpr (IsDecimalNumber<Element>)
|
||||
res_column = ColVecResult::create(offsets.size(), data.getScale());
|
||||
else
|
||||
res_column = ColVecResult::create(offsets.size());
|
||||
|
||||
typename ColVecResult::Container & res = res_column->getData();
|
||||
|
||||
size_t pos = 0;
|
||||
for (size_t i = 0; i < offsets.size(); ++i)
|
||||
@ -62,9 +79,13 @@ struct ArraySumImpl
|
||||
return true;
|
||||
}
|
||||
|
||||
const typename ColumnVector<Element>::Container & data = column->getData();
|
||||
auto res_column = ColumnVector<Result>::create(offsets.size());
|
||||
typename ColumnVector<Result>::Container & res = res_column->getData();
|
||||
typename ColVecResult::MutablePtr res_column;
|
||||
if constexpr (IsDecimalNumber<Element>)
|
||||
res_column = ColVecResult::create(offsets.size(), data.getScale());
|
||||
else
|
||||
res_column = ColVecResult::create(offsets.size());
|
||||
|
||||
typename ColVecResult::Container & res = res_column->getData();
|
||||
|
||||
size_t pos = 0;
|
||||
for (size_t i = 0; i < offsets.size(); ++i)
|
||||
@ -95,7 +116,10 @@ struct ArraySumImpl
|
||||
executeType< Int32, Int64>(mapped, offsets, res) ||
|
||||
executeType< Int64, Int64>(mapped, offsets, res) ||
|
||||
executeType<Float32,Float64>(mapped, offsets, res) ||
|
||||
executeType<Float64,Float64>(mapped, offsets, res))
|
||||
executeType<Float64,Float64>(mapped, offsets, res) ||
|
||||
executeType<Decimal32, Decimal128>(mapped, offsets, res) ||
|
||||
executeType<Decimal64, Decimal128>(mapped, offsets, res) ||
|
||||
executeType<Decimal128, Decimal128>(mapped, offsets, res))
|
||||
return res;
|
||||
else
|
||||
throw Exception("Unexpected column for arraySum: " + mapped->getName(), ErrorCodes::ILLEGAL_COLUMN);
|
||||
|
@ -0,0 +1,20 @@
|
||||
[0.0000,1.0000] Array(Decimal(9, 4))
|
||||
[0.00000000,1.00000000] Array(Decimal(18, 8))
|
||||
[0.00000000,1.00000000] Array(Decimal(38, 8))
|
||||
-
|
||||
1.0000 Decimal(38, 4)
|
||||
1.00000000 Decimal(38, 8)
|
||||
1.00000000 Decimal(38, 8)
|
||||
-
|
||||
[1.0000,2.0000] Array(Decimal(38, 4))
|
||||
[1.00000000,2.00000000] Array(Decimal(38, 8))
|
||||
[1.00000000,2.00000000] Array(Decimal(38, 8))
|
||||
-
|
||||
[1.0000,2.0000] Array(Decimal(38, 4))
|
||||
[1.00000000,2.00000000] Array(Decimal(38, 8))
|
||||
[1.00000000,2.00000000] Array(Decimal(38, 8))
|
||||
-
|
||||
[1.0000] Array(Decimal(9, 4))
|
||||
[1.00000000] Array(Decimal(18, 8))
|
||||
[1.00000000] Array(Decimal(38, 8))
|
||||
-
|
@ -0,0 +1,20 @@
|
||||
SELECT arrayDifference([toDecimal32(0.0,4), toDecimal32(1.0,4)]) x, toTypeName(x);
|
||||
SELECT arrayDifference([toDecimal64(0.0,8), toDecimal64(1.0,8)]) x, toTypeName(x);
|
||||
SELECT arrayDifference([toDecimal128(0.0,8), toDecimal128(1.0,8)]) x, toTypeName(x);
|
||||
SELECT '-';
|
||||
SELECT arraySum([toDecimal32(0.0,4), toDecimal32(1.0,4)]) x, toTypeName(x);
|
||||
SELECT arraySum([toDecimal64(0.0,8), toDecimal64(1.0,8)]) x, toTypeName(x);
|
||||
SELECT arraySum([toDecimal128(0.0,8), toDecimal128(1.0,8)]) x, toTypeName(x);
|
||||
SELECT '-';
|
||||
SELECT arrayCumSum([toDecimal32(1.0,4), toDecimal32(1.0,4)]) x, toTypeName(x);
|
||||
SELECT arrayCumSum([toDecimal64(1.0,8), toDecimal64(1.0,8)]) x, toTypeName(x);
|
||||
SELECT arrayCumSum([toDecimal128(1.0,8), toDecimal128(1.0,8)]) x, toTypeName(x);
|
||||
SELECT '-';
|
||||
SELECT arrayCumSumNonNegative([toDecimal32(1.0,4), toDecimal32(1.0,4)]) x, toTypeName(x);
|
||||
SELECT arrayCumSumNonNegative([toDecimal64(1.0,8), toDecimal64(1.0,8)]) x, toTypeName(x);
|
||||
SELECT arrayCumSumNonNegative([toDecimal128(1.0,8), toDecimal128(1.0,8)]) x, toTypeName(x);
|
||||
SELECT '-';
|
||||
SELECT arrayCompact([toDecimal32(1.0,4), toDecimal32(1.0,4)]) x, toTypeName(x);
|
||||
SELECT arrayCompact([toDecimal64(1.0,8), toDecimal64(1.0,8)]) x, toTypeName(x);
|
||||
SELECT arrayCompact([toDecimal128(1.0,8), toDecimal128(1.0,8)]) x, toTypeName(x);
|
||||
SELECT '-';
|
Loading…
Reference in New Issue
Block a user