From b4e18e22220d9a17fec77a878b884e0e607b2638 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 30 Dec 2016 03:15:50 +0300 Subject: [PATCH] Cut dependendy (code must depend on Functions only via FunctionFactory) [#METR-2944]. --- .../DB/DataStreams/PrettyBlockOutputStream.h | 9 ++-- .../PrettyCompactBlockOutputStream.h | 4 +- .../PrettyCompactMonoBlockOutputStream.h | 4 +- .../PrettySpaceBlockOutputStream.h | 4 +- .../DB/DataStreams/VerticalRowOutputStream.h | 23 +++++----- .../DB/Functions/FunctionsMiscellaneous.h | 18 -------- dbms/src/DataStreams/FormatFactory.cpp | 18 ++++---- .../DataStreams/PrettyBlockOutputStream.cpp | 43 ++++++++++++------ .../DataStreams/VerticalRowOutputStream.cpp | 45 +++++++++++++------ 9 files changed, 93 insertions(+), 75 deletions(-) diff --git a/dbms/include/DB/DataStreams/PrettyBlockOutputStream.h b/dbms/include/DB/DataStreams/PrettyBlockOutputStream.h index d26772b9282..4887c79fb4f 100644 --- a/dbms/include/DB/DataStreams/PrettyBlockOutputStream.h +++ b/dbms/include/DB/DataStreams/PrettyBlockOutputStream.h @@ -7,6 +7,7 @@ namespace DB { class WriteBuffer; +class Context; /** Выводит результат в виде красивых таблиц. @@ -15,7 +16,7 @@ class PrettyBlockOutputStream : public IBlockOutputStream { public: /// no_escapes - не использовать ANSI escape sequences - для отображения в браузере, а не в консоли. - PrettyBlockOutputStream(WriteBuffer & ostr_, bool no_escapes_, size_t max_rows_); + PrettyBlockOutputStream(WriteBuffer & ostr_, bool no_escapes_, size_t max_rows_, const Context & context_); void write(const Block & block) override; void writeSuffix() override; @@ -36,13 +37,15 @@ protected: WriteBuffer & ostr; size_t max_rows; - size_t total_rows; - size_t terminal_width; + size_t total_rows = 0; + size_t terminal_width = 0; bool no_escapes; Block totals; Block extremes; + + const Context & context; }; } diff --git a/dbms/include/DB/DataStreams/PrettyCompactBlockOutputStream.h b/dbms/include/DB/DataStreams/PrettyCompactBlockOutputStream.h index bd61842f5eb..52e174f099a 100644 --- a/dbms/include/DB/DataStreams/PrettyCompactBlockOutputStream.h +++ b/dbms/include/DB/DataStreams/PrettyCompactBlockOutputStream.h @@ -11,8 +11,8 @@ namespace DB class PrettyCompactBlockOutputStream : public PrettyBlockOutputStream { public: - PrettyCompactBlockOutputStream(WriteBuffer & ostr_, bool no_escapes_, size_t max_rows_) - : PrettyBlockOutputStream(ostr_, no_escapes_, max_rows_) {} + PrettyCompactBlockOutputStream(WriteBuffer & ostr_, bool no_escapes_, size_t max_rows_, const Context & context_) + : PrettyBlockOutputStream(ostr_, no_escapes_, max_rows_, context_) {} void write(const Block & block) override; diff --git a/dbms/include/DB/DataStreams/PrettyCompactMonoBlockOutputStream.h b/dbms/include/DB/DataStreams/PrettyCompactMonoBlockOutputStream.h index 85dcbce80e2..6f8f5a56df0 100644 --- a/dbms/include/DB/DataStreams/PrettyCompactMonoBlockOutputStream.h +++ b/dbms/include/DB/DataStreams/PrettyCompactMonoBlockOutputStream.h @@ -12,8 +12,8 @@ namespace DB class PrettyCompactMonoBlockOutputStream : public PrettyCompactBlockOutputStream { public: - PrettyCompactMonoBlockOutputStream(WriteBuffer & ostr_, bool no_escapes_, size_t max_rows_) - : PrettyCompactBlockOutputStream(ostr_, no_escapes_, max_rows_) {} + PrettyCompactMonoBlockOutputStream(WriteBuffer & ostr_, bool no_escapes_, size_t max_rows_, const Context & context_) + : PrettyCompactBlockOutputStream(ostr_, no_escapes_, max_rows_, context_) {} void write(const Block & block) override; void writeSuffix() override; diff --git a/dbms/include/DB/DataStreams/PrettySpaceBlockOutputStream.h b/dbms/include/DB/DataStreams/PrettySpaceBlockOutputStream.h index 97cba4915bc..7bc70999283 100644 --- a/dbms/include/DB/DataStreams/PrettySpaceBlockOutputStream.h +++ b/dbms/include/DB/DataStreams/PrettySpaceBlockOutputStream.h @@ -11,8 +11,8 @@ namespace DB class PrettySpaceBlockOutputStream : public PrettyBlockOutputStream { public: - PrettySpaceBlockOutputStream(WriteBuffer & ostr_, bool no_escapes_, size_t max_rows_) - : PrettyBlockOutputStream(ostr_, no_escapes_, max_rows_) {} + PrettySpaceBlockOutputStream(WriteBuffer & ostr_, bool no_escapes_, size_t max_rows_, const Context & context_) + : PrettyBlockOutputStream(ostr_, no_escapes_, max_rows_, context_) {} void write(const Block & block) override; void writeSuffix() override; diff --git a/dbms/include/DB/DataStreams/VerticalRowOutputStream.h b/dbms/include/DB/DataStreams/VerticalRowOutputStream.h index 3e5812eb6b5..1c66d82eb0c 100644 --- a/dbms/include/DB/DataStreams/VerticalRowOutputStream.h +++ b/dbms/include/DB/DataStreams/VerticalRowOutputStream.h @@ -9,14 +9,16 @@ namespace DB { class WriteBuffer; +class Context; -/** Поток для вывода данных в формате "каждое значение на своей строке". +/** Stream to output data in format "each value in separate row". + * Usable to show few rows with many columns. */ class VerticalRowOutputStream : public IRowOutputStream { public: - VerticalRowOutputStream(WriteBuffer & ostr_, const Block & sample_); + VerticalRowOutputStream(WriteBuffer & ostr_, const Block & sample_, const Context & context); void writeField(const IColumn & column, const IDataType & type, size_t row_num) override; void writeRowStartDelimiter() override; @@ -29,22 +31,21 @@ protected: WriteBuffer & ostr; const Block sample; - Names names; - size_t field_number; - size_t row_number; + size_t field_number = 0; + size_t row_number = 0; - using Pads_t = std::vector; - Pads_t pads; + using NamesAndPaddings = std::vector; + NamesAndPaddings names_and_paddings; }; -/** То же самое, но строки выводятся без экранирования. +/** Same but values are printed without escaping. */ -class VerticalRawRowOutputStream : public VerticalRowOutputStream +class VerticalRawRowOutputStream final : public VerticalRowOutputStream { public: - VerticalRawRowOutputStream(WriteBuffer & ostr_, const Block & sample_) - : VerticalRowOutputStream(ostr_, sample_) {} + VerticalRawRowOutputStream(WriteBuffer & ostr_, const Block & sample_, const Context & context) + : VerticalRowOutputStream(ostr_, sample_, context) {} protected: void writeValue(const IColumn & column, const IDataType & type, size_t row_num) const override; diff --git a/dbms/include/DB/Functions/FunctionsMiscellaneous.h b/dbms/include/DB/Functions/FunctionsMiscellaneous.h index 7bdac63e4e0..91f07ca30a7 100644 --- a/dbms/include/DB/Functions/FunctionsMiscellaneous.h +++ b/dbms/include/DB/Functions/FunctionsMiscellaneous.h @@ -75,24 +75,6 @@ namespace ErrorCodes */ -static inline UInt64 stringWidth(const UInt8 * pos, const UInt8 * end) -{ - UInt64 res = 0; - for (; pos < end; ++pos) - { - if (*pos == '\b' || *pos == '\f' || *pos == '\n' || *pos == '\r' || *pos == '\t' || *pos == '\0' || *pos == '\'' || *pos == '\\') - ++res; - if (*pos <= 0x7F || *pos >= 0xC0) - ++res; - } - return res; -} - -static inline void stringWidthConstant(const String & data, UInt64 & res) -{ - res = stringWidth(reinterpret_cast(data.data()), reinterpret_cast(data.data()) + data.size()); -} - class FunctionCurrentDatabase : public IFunction { const String db_name; diff --git a/dbms/src/DataStreams/FormatFactory.cpp b/dbms/src/DataStreams/FormatFactory.cpp index 57e96dc4ef0..febf63d2ddd 100644 --- a/dbms/src/DataStreams/FormatFactory.cpp +++ b/dbms/src/DataStreams/FormatFactory.cpp @@ -120,23 +120,23 @@ static BlockOutputStreamPtr getOutputImpl(const String & name, WriteBuffer & buf else if (name == "CSVWithNames") return std::make_shared(std::make_shared(buf, sample, true)); else if (name == "Pretty") - return std::make_shared(buf, false, settings.output_format_pretty_max_rows); + return std::make_shared(buf, false, settings.output_format_pretty_max_rows, context); else if (name == "PrettyCompact") - return std::make_shared(buf, false, settings.output_format_pretty_max_rows); + return std::make_shared(buf, false, settings.output_format_pretty_max_rows, context); else if (name == "PrettyCompactMonoBlock") - return std::make_shared(buf, false, settings.output_format_pretty_max_rows); + return std::make_shared(buf, false, settings.output_format_pretty_max_rows, context); else if (name == "PrettySpace") - return std::make_shared(buf, false, settings.output_format_pretty_max_rows); + return std::make_shared(buf, false, settings.output_format_pretty_max_rows, context); else if (name == "PrettyNoEscapes") - return std::make_shared(buf, true, settings.output_format_pretty_max_rows); + return std::make_shared(buf, true, settings.output_format_pretty_max_rows, context); else if (name == "PrettyCompactNoEscapes") - return std::make_shared(buf, true, settings.output_format_pretty_max_rows); + return std::make_shared(buf, true, settings.output_format_pretty_max_rows, context); else if (name == "PrettySpaceNoEscapes") - return std::make_shared(buf, true, settings.output_format_pretty_max_rows); + return std::make_shared(buf, true, settings.output_format_pretty_max_rows, context); else if (name == "Vertical") - return std::make_shared(std::make_shared(buf, sample)); + return std::make_shared(std::make_shared(buf, sample, context)); else if (name == "VerticalRaw") - return std::make_shared(std::make_shared(buf, sample)); + return std::make_shared(std::make_shared(buf, sample, context)); else if (name == "Values") return std::make_shared(std::make_shared(buf)); else if (name == "JSON") diff --git a/dbms/src/DataStreams/PrettyBlockOutputStream.cpp b/dbms/src/DataStreams/PrettyBlockOutputStream.cpp index 8a2ba14d542..94d3baa445c 100644 --- a/dbms/src/DataStreams/PrettyBlockOutputStream.cpp +++ b/dbms/src/DataStreams/PrettyBlockOutputStream.cpp @@ -1,15 +1,18 @@ #include #include -#include +#include +#include +#include #include +#include namespace DB { -PrettyBlockOutputStream::PrettyBlockOutputStream(WriteBuffer & ostr_, bool no_escapes_, size_t max_rows_) - : ostr(ostr_), max_rows(max_rows_), total_rows(0), terminal_width(0), no_escapes(no_escapes_) +PrettyBlockOutputStream::PrettyBlockOutputStream(WriteBuffer & ostr_, bool no_escapes_, size_t max_rows_, const Context & context_) + : ostr(ostr_), max_rows(max_rows_), no_escapes(no_escapes_), context(context_) { struct winsize w; if (0 == ioctl(STDOUT_FILENO, TIOCGWINSZ, &w)) @@ -31,20 +34,19 @@ void PrettyBlockOutputStream::calculateWidths(Block & block, Widths_t & max_widt max_widths.resize(columns); name_widths.resize(columns); - FunctionVisibleWidth visible_width_func; - DataTypePtr visible_width_type = std::make_shared(); + FunctionPtr visible_width_func = FunctionFactory::instance().get("visibleWidth", context); - /// Вычислим ширину всех значений + /// Calculate widths of all values. for (size_t i = 0; i < columns; ++i) { ColumnWithTypeAndName column; - column.type = visible_width_type; - column.name = "visibleWidth(" + block.getByPosition(i).name + ")"; + column.type = std::make_shared(); + column.name = "visibleWidth(" + block.unsafeGetByPosition(i).name + ")"; size_t result_number = block.columns(); block.insert(column); - visible_width_func.execute(block, {i}, result_number); + visible_width_func->execute(block, {i}, result_number); column.column = block.getByPosition(result_number).column; if (const ColumnUInt64 * col = typeid_cast(&*column.column)) @@ -63,13 +65,26 @@ void PrettyBlockOutputStream::calculateWidths(Block & block, Widths_t & max_widt } else throw Exception("Illegal column " + column.column->getName() - + " of result of function " + visible_width_func.getName(), + + " of result of function " + visible_width_func->getName(), ErrorCodes::ILLEGAL_COLUMN); - /// И не только значений, но и их имён - stringWidthConstant(block.getByPosition(i).name, name_widths[i]); - if (name_widths[i] > max_widths[i]) - max_widths[i] = name_widths[i]; + /// And also calculate widths for names of columns. + { + const String & name = block.unsafeGetByPosition(i).name; + + Block block_with_name + { + { std::make_shared(1, name), std::make_shared(), "name" }, + { nullptr, std::make_shared(), "width" } + }; + + visible_width_func->execute(block_with_name, {0}, 1); + + name_widths[i] = typeid_cast(*block_with_name.unsafeGetByPosition(1).column).getData(); + + if (name_widths[i] > max_widths[i]) + max_widths[i] = name_widths[i]; + } } } diff --git a/dbms/src/DataStreams/VerticalRowOutputStream.cpp b/dbms/src/DataStreams/VerticalRowOutputStream.cpp index e0841e792f1..9de8cdb624c 100644 --- a/dbms/src/DataStreams/VerticalRowOutputStream.cpp +++ b/dbms/src/DataStreams/VerticalRowOutputStream.cpp @@ -1,33 +1,53 @@ -#include +#include +#include +#include +#include #include - #include namespace DB { -VerticalRowOutputStream::VerticalRowOutputStream(WriteBuffer & ostr_, const Block & sample_) - : ostr(ostr_), sample(sample_), field_number(0), row_number(0) +VerticalRowOutputStream::VerticalRowOutputStream(WriteBuffer & ostr_, const Block & sample_, const Context & context) + : ostr(ostr_), sample(sample_) { size_t columns = sample.columns(); - names.resize(columns); using Widths_t = std::vector; Widths_t name_widths(columns); size_t max_name_width = 0; + FunctionPtr visible_width_func = FunctionFactory::instance().get("visibleWidth", context); + for (size_t i = 0; i < columns; ++i) { - names[i] = sample.getByPosition(i).name; - stringWidthConstant(names[i], name_widths[i]); + { + Block block_with_name + { + { std::make_shared(1, sample.unsafeGetByPosition(i).name), std::make_shared(), "name" }, + { nullptr, std::make_shared(), "width" } + }; + + visible_width_func->execute(block_with_name, {0}, 1); + + name_widths[i] = (*block_with_name.unsafeGetByPosition(1).column)[0].get(); + } + if (name_widths[i] > max_name_width) max_name_width = name_widths[i]; } - pads.resize(columns); + names_and_paddings.resize(columns); for (size_t i = 0; i < columns; ++i) - pads[i] = String(max_name_width - name_widths[i], ' '); + { + WriteBufferFromString out(names_and_paddings[i]); + writeEscapedString(sample.unsafeGetByPosition(i).name, out); + writeCString(": ", out); + } + + for (size_t i = 0; i < columns; ++i) + names_and_paddings[i].resize(max_name_width + strlen(": "), ' '); } @@ -39,13 +59,10 @@ void VerticalRowOutputStream::flush() void VerticalRowOutputStream::writeField(const IColumn & column, const IDataType & type, size_t row_num) { - writeEscapedString(names[field_number], ostr); - writeCString(": ", ostr); - writeString(pads[field_number], ostr); - + writeString(names_and_paddings[field_number], ostr); writeValue(column, type, row_num); - writeChar('\n', ostr); + ++field_number; }