From 58fec71f0f9f9c827893976753f35216094853e0 Mon Sep 17 00:00:00 2001 From: Alexey Arno Date: Mon, 19 Sep 2016 19:57:52 +0300 Subject: [PATCH] dbms: Server: Do not pay attention to this commit. [#METR-19266] --- dbms/include/DB/Functions/FunctionsArray.h | 12 ++- dbms/src/Functions/FunctionsArray.cpp | 87 ++++++++++++++++++---- 2 files changed, 81 insertions(+), 18 deletions(-) diff --git a/dbms/include/DB/Functions/FunctionsArray.h b/dbms/include/DB/Functions/FunctionsArray.h index 2f52d4b9d74..465afc810c1 100644 --- a/dbms/include/DB/Functions/FunctionsArray.h +++ b/dbms/include/DB/Functions/FunctionsArray.h @@ -1266,15 +1266,21 @@ private: template bool executeNumber( const IColumn & src_data, const ColumnArray::Offsets_t & src_offsets, - IColumn & res_data_col); + IColumn & res_data_col, + const ColumnNullable * nullable_col, + ColumnNullable * nullable_res_col); bool executeFixedString( const IColumn & src_data, const ColumnArray::Offsets_t & src_offsets, - IColumn & res_data_col); + IColumn & res_data_col, + const ColumnNullable * nullable_col, + ColumnNullable * nullable_res_col); bool executeString( const IColumn & src_data, const ColumnArray::Offsets_t & src_array_offsets, - IColumn & res_data_col); + IColumn & res_data_col, + const ColumnNullable * nullable_col, + ColumnNullable * nullable_res_col); }; diff --git a/dbms/src/Functions/FunctionsArray.cpp b/dbms/src/Functions/FunctionsArray.cpp index 60288fbf888..b20a20c25ac 100644 --- a/dbms/src/Functions/FunctionsArray.cpp +++ b/dbms/src/Functions/FunctionsArray.cpp @@ -30,6 +30,7 @@ void registerFunctionsArray(FunctionFactory & factory) factory.registerFunction(); factory.registerFunction(); factory.registerFunction(); + factory.registerFunction(); } /// Implementation of FunctionArray. @@ -2394,18 +2395,38 @@ void FunctionArrayReverse::executeImpl(Block & block, const ColumnNumbers & argu IColumn & res_data = res.getData(); res.getOffsetsColumn() = array->getOffsetsColumn(); - if (!( executeNumber (src_data, offsets, res_data) - || executeNumber (src_data, offsets, res_data) - || executeNumber (src_data, offsets, res_data) - || executeNumber (src_data, offsets, res_data) - || executeNumber (src_data, offsets, res_data) - || executeNumber (src_data, offsets, res_data) - || executeNumber (src_data, offsets, res_data) - || executeNumber (src_data, offsets, res_data) - || executeNumber (src_data, offsets, res_data) - || executeNumber (src_data, offsets, res_data) - || executeString (src_data, offsets, res_data) - || executeFixedString (src_data, offsets, res_data))) + const ColumnNullable * nullable_col = nullptr; + ColumnNullable * nullable_res_col = nullptr; + + const IColumn * inner_col; + IColumn * inner_res_col; + + if (src_data.isNullable()) + { + nullable_col = static_cast(&src_data); + inner_col = nullable_col->getNestedColumn().get(); + + nullable_res_col = static_cast(&res_data); + inner_res_col = nullable_res_col->getNestedColumn().get(); + } + else + { + inner_col = &src_data; + inner_res_col = &res_data; + } + + if (!( executeNumber (*inner_col, offsets, *inner_res_col, nullable_col, nullable_res_col) + || executeNumber (*inner_col, offsets, *inner_res_col, nullable_col, nullable_res_col) + || executeNumber (*inner_col, offsets, *inner_res_col, nullable_col, nullable_res_col) + || executeNumber (*inner_col, offsets, *inner_res_col, nullable_col, nullable_res_col) + || executeNumber (*inner_col, offsets, *inner_res_col, nullable_col, nullable_res_col) + || executeNumber (*inner_col, offsets, *inner_res_col, nullable_col, nullable_res_col) + || executeNumber (*inner_col, offsets, *inner_res_col, nullable_col, nullable_res_col) + || executeNumber (*inner_col, offsets, *inner_res_col, nullable_col, nullable_res_col) + || executeNumber (*inner_col, offsets, *inner_res_col, nullable_col, nullable_res_col) + || executeNumber (*inner_col, offsets, *inner_res_col, nullable_col, nullable_res_col) + || executeString (*inner_col, offsets, *inner_res_col, nullable_col, nullable_res_col) + || executeFixedString (*inner_col, offsets, *inner_res_col, nullable_col, nullable_res_col))) throw Exception("Illegal column " + block.getByPosition(arguments[0]).column->getName() + " of first argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN); @@ -2437,7 +2458,9 @@ bool FunctionArrayReverse::executeConst(Block & block, const ColumnNumbers & arg template bool FunctionArrayReverse::executeNumber( const IColumn & src_data, const ColumnArray::Offsets_t & src_offsets, - IColumn & res_data_col) + IColumn & res_data_col, + const ColumnNullable * nullable_col, + ColumnNullable * nullable_res_col) { if (const ColumnVector * src_data_concrete = typeid_cast *>(&src_data)) { @@ -2468,6 +2491,36 @@ bool FunctionArrayReverse::executeNumber( src_prev_offset = src_offsets[i]; } + /// XXX Refactor the code below. + if ((nullable_col != nullptr) && (nullable_res_col != nullptr)) + { + const auto & src_null_map = static_cast(*nullable_col->getNullValuesByteMap()).getData(); + auto & res_null_map = static_cast(*nullable_res_col->getNullValuesByteMap()).getData(); + res_null_map.resize(src_data.size()); + + ColumnArray::Offset_t src_prev_offset = 0; + + for (size_t i = 0; i < size; ++i) + { + const UInt8 * src = &src_null_map[src_prev_offset]; + const UInt8 * src_end = &src_null_map[src_offsets[i]]; + + if (src == src_end) + continue; + + UInt8 * dst = &res_null_map[src_offsets[i] - 1]; + + while (src < src_end) + { + *dst = *src; + ++src; + --dst; + } + + src_prev_offset = src_offsets[i]; + } + } + return true; } else @@ -2476,7 +2529,9 @@ bool FunctionArrayReverse::executeNumber( bool FunctionArrayReverse::executeFixedString( const IColumn & src_data, const ColumnArray::Offsets_t & src_offsets, - IColumn & res_data_col) + IColumn & res_data_col, + const ColumnNullable * nullable_col, + ColumnNullable * nullable_res_col) { if (const ColumnFixedString * src_data_concrete = typeid_cast(&src_data)) { @@ -2516,7 +2571,9 @@ bool FunctionArrayReverse::executeFixedString( bool FunctionArrayReverse::executeString( const IColumn & src_data, const ColumnArray::Offsets_t & src_array_offsets, - IColumn & res_data_col) + IColumn & res_data_col, + const ColumnNullable * nullable_col, + ColumnNullable * nullable_res_col) { if (const ColumnString * src_data_concrete = typeid_cast(&src_data)) {