diff --git a/dbms/src/Functions/FunctionsHigherOrder.cpp b/dbms/src/Functions/FunctionsHigherOrder.cpp index 0c93b64b9c7..567a80f195b 100644 --- a/dbms/src/Functions/FunctionsHigherOrder.cpp +++ b/dbms/src/Functions/FunctionsHigherOrder.cpp @@ -16,6 +16,8 @@ void registerFunctionsHigherOrder(FunctionFactory & factory) factory.registerFunction(); factory.registerFunction(); factory.registerFunction(); + factory.registerFunction(); + } } diff --git a/dbms/src/Functions/FunctionsHigherOrder.h b/dbms/src/Functions/FunctionsHigherOrder.h index 8d7b7d3b976..b02653b5320 100644 --- a/dbms/src/Functions/FunctionsHigherOrder.h +++ b/dbms/src/Functions/FunctionsHigherOrder.h @@ -60,18 +60,37 @@ struct ArrayCumSumImpl static bool needExpression() { return false; } static bool needOneArray() { return true; } - static DataTypePtr getReturnType(const DataTypePtr & /*expression_return*/, const DataTypePtr & array_element) + static DataTypePtr getReturnType(const DataTypePtr & expression_return, const DataTypePtr & /*array_element*/) { - return std::make_shared(array_element); + //return std::make_shared(array_element); + if (checkDataType(&*expression_return) || + checkDataType(&*expression_return) || + checkDataType(&*expression_return) || + checkDataType(&*expression_return)) + return std::make_shared(std::make_shared()); + + if (checkDataType(&*expression_return) || + checkDataType(&*expression_return) || + checkDataType(&*expression_return) || + checkDataType(&*expression_return)) + return std::make_shared(std::make_shared()); + + if (checkDataType(&*expression_return) || + checkDataType(&*expression_return)) + return std::make_shared(std::make_shared()); + + throw Exception("arraySum cannot add values of type " + expression_return->getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); } template - static bool executeType(const ColumnPtr & mapped, const ColumnArray::Offsets & offsets, ColumnPtr & res_ptr) + static bool executeType(const ColumnPtr & mapped, const ColumnArray & array, ColumnPtr & res_ptr) { const ColumnVector * column = checkAndGetColumn>(&*mapped); - if (!column) + return false; + + /*if (!column) { const ColumnConst * column_const = checkAndGetColumnConst>(&*mapped); @@ -80,70 +99,62 @@ struct ArrayCumSumImpl const Element x = column_const->template getValue(); - auto res = ColumnArray::create() auto res_nested = ColumnVector::create(); ColumnVector::Container & res_values = res_nested->getData(); res_values.resize(offsets.size()); - size_t pos = 0; - for (size_t i = 0; i < offsets.size(); ++i) - { - res[i] = x * (offsets[i] - pos); - pos = offsets[i]; - } - size_t pos = 0; for (size_t i = 0; i < offsets.size(); ++i) { res_values[pos++] = x; for (; pos < offsets[i]; ++pos) { - res_values[pos] = res_values[pos - 1] + x + res_values[pos] = res_values[pos - 1] + x; } } res_ptr = ColumnArray::create(std::move(res_nested), offsets); return true; - } + }*/ + const IColumn::Offsets & offsets = array.getOffsets(); const typename ColumnVector::Container & data = column->getData(); // create output column - auto res = ColumnArray::create() auto res_nested = ColumnVector::create(); - ColumnVector::Container & res_values = res_nested->getData(); - res_values.resize(offsets.size()); + typename ColumnVector::Container & res_values = res_nested->getData(); + res_values.resize(data.size()); // accumulate size_t pos = 0; for (size_t i = 0; i < offsets.size(); ++i) { - res_values[pos++] = data[pos] + res_values[pos] = data[pos]; + ++pos; for (; pos < offsets[i]; ++pos) { - res_values[pos] = res_values[pos - 1] + data[pos - 1] + res_values[pos] = res_values[pos - 1] + data[pos]; } } - res_ptr = ColumnArray::create(std::move(res_nested), offsets); + res_ptr = ColumnArray::create(std::move(res_nested), array.getOffsetsPtr()); return true; } static ColumnPtr execute(const ColumnArray & array, ColumnPtr mapped) { - const IColumn::Offsets & offsets = array.getOffsets(); ColumnPtr res; - if (executeType< UInt8 , UInt64>(mapped, offsets, res) || - executeType< UInt16, UInt64>(mapped, offsets, res) || - executeType< UInt32, UInt64>(mapped, offsets, res) || - executeType< UInt64, UInt64>(mapped, offsets, res) || - executeType< Int8 , Int64>(mapped, offsets, res) || - executeType< Int16, Int64>(mapped, offsets, res) || - executeType< Int32, Int64>(mapped, offsets, res) || - executeType< Int64, Int64>(mapped, offsets, res) || - executeType(mapped, offsets, res) || - executeType(mapped, offsets, res)) + if (executeType< UInt8 , UInt64>(mapped, array, res) || + executeType< UInt16, UInt64>(mapped, array, res) || + executeType< UInt32, UInt64>(mapped, array, res) || + executeType< UInt64, UInt64>(mapped, array, res) || + executeType< Int8 , Int64>(mapped, array, res) || + executeType< Int16, Int64>(mapped, array, res) || + executeType< Int32, Int64>(mapped, array, res) || + executeType< Int64, Int64>(mapped, array, res) || + executeType(mapped, array, res) || + executeType(mapped, array, res)) return res; else throw Exception("Unexpected column for arrayCumSum: " + mapped->getName());