From c4f348619db3d54b76d09d58f62b0ad6e90dfa7c Mon Sep 17 00:00:00 2001 From: Alexey Arno Date: Wed, 17 Aug 2016 16:38:33 +0300 Subject: [PATCH] dbms: cleanup [#METR-19266] --- .../DB/Functions/FunctionsMiscellaneous.h | 9 +++ .../DataStreams/PrettyBlockOutputStream.cpp | 43 ++---------- .../PrettyCompactBlockOutputStream.cpp | 51 ++------------ dbms/src/Functions/FunctionsMiscellaneous.cpp | 70 +++++++++++++++++++ 4 files changed, 88 insertions(+), 85 deletions(-) diff --git a/dbms/include/DB/Functions/FunctionsMiscellaneous.h b/dbms/include/DB/Functions/FunctionsMiscellaneous.h index d8754b3b33c..5d26c548e22 100644 --- a/dbms/include/DB/Functions/FunctionsMiscellaneous.h +++ b/dbms/include/DB/Functions/FunctionsMiscellaneous.h @@ -165,6 +165,11 @@ public: static constexpr auto name = "visibleWidth"; static FunctionPtr create(const Context & context) { return std::make_shared(); } + bool hasSpecialSupportForNulls() const override + { + return true; + } + /// Получить имя функции. String getName() const override { @@ -184,6 +189,10 @@ public: /// Выполнить функцию над блоком. void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override; + +private: + /// Internal version of visibleWidth. + void perform(Block & block, const ColumnNumbers & arguments, size_t result); }; diff --git a/dbms/src/DataStreams/PrettyBlockOutputStream.cpp b/dbms/src/DataStreams/PrettyBlockOutputStream.cpp index 18243aa1bca..25e0c56b600 100644 --- a/dbms/src/DataStreams/PrettyBlockOutputStream.cpp +++ b/dbms/src/DataStreams/PrettyBlockOutputStream.cpp @@ -3,8 +3,6 @@ #include #include -#include -#include namespace DB @@ -47,51 +45,20 @@ void PrettyBlockOutputStream::calculateWidths(Block & block, Widths_t & max_widt column.column = block.getByPosition(i + columns).column; - auto has_null_value = [](const ColumnPtr & col, size_t row) - { - if (col->isNullable()) - { - const ColumnNullable & nullable_col = static_cast(*col); - if (nullable_col.isNullAt(row)) - return true; - } - else if (col->isNull()) - return true; - - return false; - }; - - IColumn * observed_col; - if (column.column->isNullable()) - { - ColumnNullable & nullable_col = static_cast(*column.column); - observed_col = nullable_col.getNestedColumn().get(); - } - else - observed_col = column.column.get(); - - if (const ColumnUInt64 * col = typeid_cast(observed_col)) + if (const ColumnUInt64 * col = typeid_cast(&*column.column)) { const ColumnUInt64::Container_t & res = col->getData(); for (size_t j = 0; j < rows; ++j) - { - size_t cur_width; - if (has_null_value(block.getByPosition(i).column, j)) - cur_width = NullSymbol::Escaped::length; - else - cur_width = res[j]; - - if (cur_width > max_widths[i]) - max_widths[i] = cur_width; - } + if (res[j] > max_widths[i]) + max_widths[i] = res[j]; } - else if (const ColumnConstUInt64 * col = typeid_cast(observed_col)) + else if (const ColumnConstUInt64 * col = typeid_cast(&*column.column)) { UInt64 res = col->getData(); max_widths[i] = res; } else - throw Exception("Illegal column " + observed_col->getName() + throw Exception("Illegal column " + column.column->getName() + " of result of function " + visible_width_func.getName(), ErrorCodes::ILLEGAL_COLUMN); diff --git a/dbms/src/DataStreams/PrettyCompactBlockOutputStream.cpp b/dbms/src/DataStreams/PrettyCompactBlockOutputStream.cpp index 55c8a07041d..333cf5e8960 100644 --- a/dbms/src/DataStreams/PrettyCompactBlockOutputStream.cpp +++ b/dbms/src/DataStreams/PrettyCompactBlockOutputStream.cpp @@ -2,8 +2,6 @@ #include #include -#include -#include namespace DB @@ -81,20 +79,6 @@ void PrettyCompactBlockOutputStream::writeRow( const Widths_t & max_widths, const Widths_t & name_widths) { - auto has_null_value = [](const ColumnPtr & col, size_t row) - { - if (col->isNullable()) - { - const ColumnNullable & nullable_col = static_cast(*col); - if (nullable_col.isNullAt(row)) - return true; - } - else if (col->isNull()) - return true; - - return false; - }; - size_t columns = max_widths.size(); writeCString("│ ", ostr); @@ -106,46 +90,19 @@ void PrettyCompactBlockOutputStream::writeRow( const ColumnWithTypeAndName & col = block.getByPosition(j); - size_t width; - - if (has_null_value(col.column, row_id)) - width = NullSymbol::Escaped::length; - else - { - ColumnPtr res_col = block.getByPosition(columns + j).column; - - IColumn * observed_col; - if (res_col->isNullable()) - { - ColumnNullable & nullable_col = static_cast(*res_col); - observed_col = nullable_col.getNestedColumn().get(); - } - else - observed_col = res_col.get(); - - if (const ColumnUInt64 * concrete_col = typeid_cast(observed_col)) - { - const ColumnUInt64::Container_t & res = concrete_col->getData(); - width = res[row_id]; - } - else if (const ColumnConstUInt64 * concrete_col = typeid_cast(observed_col)) - { - UInt64 res = concrete_col->getData(); - width = res; - } - else - throw Exception{"Illegal column " + observed_col->getName(), ErrorCodes::ILLEGAL_COLUMN}; - } - if (col.type->isNumeric()) { + size_t width = get((*block.getByPosition(columns + j).column)[row_id]); for (size_t k = 0; k < max_widths[j] - width; ++k) writeChar(' ', ostr); + col.type->serializeTextEscaped(*col.column.get(), row_id, ostr); } else { col.type->serializeTextEscaped(*col.column.get(), row_id, ostr); + + size_t width = get((*block.getByPosition(columns + j).column)[row_id]); for (size_t k = 0; k < max_widths[j] - width; ++k) writeChar(' ', ostr); } diff --git a/dbms/src/Functions/FunctionsMiscellaneous.cpp b/dbms/src/Functions/FunctionsMiscellaneous.cpp index af13ce17b19..ecb31b9f973 100644 --- a/dbms/src/Functions/FunctionsMiscellaneous.cpp +++ b/dbms/src/Functions/FunctionsMiscellaneous.cpp @@ -4,6 +4,9 @@ #include #include #include +#include +#include +#include #include @@ -173,6 +176,73 @@ namespace VisibleWidth void FunctionVisibleWidth::executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) +{ + auto & element = block.getByPosition(arguments[0]); + + auto & res_element = block.getByPosition(result); + auto & res_col = res_element.column; + + size_t row_count = block.rowsInFirstColumn(); + + if (element.column->isNull()) + { + /// The input column has the Null type. + res_col = std::make_shared(row_count, NullSymbol::Escaped::length); + } + else if (element.column->isNullable()) + { + /// Perform visibleWidth on a block that holds the nested column + /// of the input column. + auto & nullable_col = static_cast(*element.column); + auto & nested_col = nullable_col.getNestedColumn(); + + auto & nullable_type = static_cast(*element.type); + auto & nested_type = nullable_type.getNestedType(); + + Block block_with_nested_col = + { + { + nested_col, + nested_type, + element.name + }, + + { + nullptr, + res_element.type, + "" + } + }; + + perform(block_with_nested_col, {0, 1}, 1); + + /// Create the result. If any row of the input column holds a NULL value, + /// we assign the corresponding row of the result the length of the NULL + /// symbol. + res_col = std::make_shared(row_count); + auto & res_data = static_cast(*res_col).getData(); + + const auto & src = static_cast( + *block_with_nested_col.unsafeGetByPosition(1).column + ).getData(); + + for (size_t row = 0; row < row_count; ++row) + { + if (nullable_col.isNullAt(row)) + res_data[row] = NullSymbol::Escaped::length; + else + res_data[row] = src[row]; + } + } + else + { + /// The input column has an ordinary type. + perform(block, arguments, result); + } +} + + +void FunctionVisibleWidth::perform(Block & block, const ColumnNumbers & arguments, size_t result) { const ColumnPtr column = block.getByPosition(arguments[0]).column; const DataTypePtr type = block.getByPosition(arguments[0]).type;