diff --git a/dbms/include/DB/DataStreams/ExpressionBlockInputStream.h b/dbms/include/DB/DataStreams/ExpressionBlockInputStream.h index 0333eb8e427..8cc8ef54a67 100644 --- a/dbms/include/DB/DataStreams/ExpressionBlockInputStream.h +++ b/dbms/include/DB/DataStreams/ExpressionBlockInputStream.h @@ -35,6 +35,19 @@ public: return res.str(); } + const Block & getTotals() + { + if (IProfilingBlockInputStream * child = dynamic_cast(&*children.back())) + { + totals = child->getTotals(); + + if (totals) + expression->execute(totals); + } + + return totals; + } + protected: Block readImpl() { diff --git a/dbms/include/DB/DataStreams/IProfilingBlockInputStream.h b/dbms/include/DB/DataStreams/IProfilingBlockInputStream.h index 7f283d05888..2e8da426846 100644 --- a/dbms/include/DB/DataStreams/IProfilingBlockInputStream.h +++ b/dbms/include/DB/DataStreams/IProfilingBlockInputStream.h @@ -77,8 +77,13 @@ public: /// Получить информацию о скорости выполнения. const BlockStreamProfileInfo & getInfo() const; - /// Получить "тотальные" значения. Берёт их из себя или из первого дочернего источника, в котором они есть. Их может не быть. - const Block & getTotals() const; + /** Получить "тотальные" значения. + * Реализация по-умолчанию берёт их из себя или из первого дочернего источника, в котором они есть. + * Переопределённый метод может провести некоторые вычисления. Например, применить выражение к totals дочернего источника. + * Тотальных значений может не быть - тогда возвращается пустой блок. + */ + virtual const Block & getTotals(); + /// То же самое для минимумов и максимумов. const Block & getExtremes() const; diff --git a/dbms/src/DataStreams/IProfilingBlockInputStream.cpp b/dbms/src/DataStreams/IProfilingBlockInputStream.cpp index 21f33ba647e..bbb36892bbe 100644 --- a/dbms/src/DataStreams/IProfilingBlockInputStream.cpp +++ b/dbms/src/DataStreams/IProfilingBlockInputStream.cpp @@ -357,14 +357,14 @@ void IProfilingBlockInputStream::setProgressCallback(ProgressCallback callback) } -const Block & IProfilingBlockInputStream::getTotals() const +const Block & IProfilingBlockInputStream::getTotals() { if (totals) return totals; - for (BlockInputStreams::const_iterator it = children.begin(); it != children.end(); ++it) + for (BlockInputStreams::iterator it = children.begin(); it != children.end(); ++it) { - if (const IProfilingBlockInputStream * child = dynamic_cast(&**it)) + if (IProfilingBlockInputStream * child = dynamic_cast(&**it)) { const Block & res = child->getTotals(); if (res) diff --git a/dbms/src/DataStreams/copyData.cpp b/dbms/src/DataStreams/copyData.cpp index 8249e28e2aa..c78cb41af72 100644 --- a/dbms/src/DataStreams/copyData.cpp +++ b/dbms/src/DataStreams/copyData.cpp @@ -16,7 +16,7 @@ void copyData(IBlockInputStream & from, IBlockOutputStream & to) to.write(block); /// Для вывода дополнительной информации в некоторых форматах. - if (const IProfilingBlockInputStream * input = dynamic_cast(&from)) + if (IProfilingBlockInputStream * input = dynamic_cast(&from)) { if (input->getInfo().hasAppliedLimit()) to.setRowsBeforeLimit(input->getInfo().getRowsBeforeLimit()); diff --git a/dbms/src/Server/TCPHandler.cpp b/dbms/src/Server/TCPHandler.cpp index 5376839c59f..4c3bf04fd3c 100644 --- a/dbms/src/Server/TCPHandler.cpp +++ b/dbms/src/Server/TCPHandler.cpp @@ -279,7 +279,7 @@ void TCPHandler::sendTotals() if (client_revision < DBMS_MIN_REVISION_WITH_TOTALS_EXTREMES) return; - if (const IProfilingBlockInputStream * input = dynamic_cast(&*state.io.in)) + if (IProfilingBlockInputStream * input = dynamic_cast(&*state.io.in)) { const Block & totals = input->getTotals();