2013-09-15 10:53:10 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <DB/Interpreters/SplittingAggregator.h>
|
|
|
|
|
#include <DB/DataStreams/IProfilingBlockInputStream.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
using Poco::SharedPtr;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SplittingAggregatingBlockInputStream : public IProfilingBlockInputStream
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
SplittingAggregatingBlockInputStream(
|
2013-11-04 00:49:37 +00:00
|
|
|
|
BlockInputStreamPtr input_, const ColumnNumbers & keys_, AggregateDescriptions & aggregates_, size_t threads_,
|
2014-02-17 23:56:45 +00:00
|
|
|
|
bool with_totals_, bool separate_totals_, bool final_, size_t max_rows_to_group_by_, OverflowMode group_by_overflow_mode_)
|
2013-11-04 00:49:37 +00:00
|
|
|
|
: started(false), separate_totals(separate_totals_), final(final_),
|
|
|
|
|
aggregator(new SplittingAggregator(keys_, aggregates_, threads_, with_totals_, max_rows_to_group_by_, group_by_overflow_mode_)),
|
|
|
|
|
current_result(results.end())
|
2013-09-15 10:53:10 +00:00
|
|
|
|
{
|
|
|
|
|
children.push_back(input_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** keys берутся из GROUP BY части запроса
|
|
|
|
|
* Агрегатные функции ищутся везде в выражении.
|
|
|
|
|
* Столбцы, соответствующие keys и аргументам агрегатных функций, уже должны быть вычислены.
|
|
|
|
|
*/
|
|
|
|
|
SplittingAggregatingBlockInputStream(
|
2013-11-04 00:49:37 +00:00
|
|
|
|
BlockInputStreamPtr input_, const Names & key_names, const AggregateDescriptions & aggregates, size_t threads_,
|
2014-02-17 23:56:45 +00:00
|
|
|
|
bool with_totals_, bool separate_totals_, bool final_, size_t max_rows_to_group_by_, OverflowMode group_by_overflow_mode_)
|
2013-11-04 00:49:37 +00:00
|
|
|
|
: started(false), separate_totals(separate_totals_), final(final_),
|
|
|
|
|
aggregator(new SplittingAggregator(key_names, aggregates, threads_, with_totals_, max_rows_to_group_by_, group_by_overflow_mode_)),
|
|
|
|
|
current_result(results.end())
|
2013-09-15 10:53:10 +00:00
|
|
|
|
{
|
|
|
|
|
children.push_back(input_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String getName() const { return "SplittingAggregatingBlockInputStream"; }
|
|
|
|
|
|
|
|
|
|
String getID() const
|
|
|
|
|
{
|
|
|
|
|
std::stringstream res;
|
|
|
|
|
res << "SplittingAggregating(" << children.back()->getID() << ", " << aggregator->getID() << ")";
|
|
|
|
|
return res.str();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
Block readImpl()
|
|
|
|
|
{
|
|
|
|
|
if (!started)
|
|
|
|
|
{
|
|
|
|
|
started = true;
|
|
|
|
|
|
|
|
|
|
ManyAggregatedDataVariants data;
|
|
|
|
|
aggregator->execute(children.back(), data);
|
|
|
|
|
|
|
|
|
|
if (isCancelled())
|
|
|
|
|
return Block();
|
|
|
|
|
|
2013-11-03 23:35:18 +00:00
|
|
|
|
aggregator->convertToBlocks(data, results, final);
|
2013-09-15 10:53:10 +00:00
|
|
|
|
current_result = results.begin();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (current_result == results.end())
|
|
|
|
|
return Block();
|
|
|
|
|
|
|
|
|
|
Block res = *current_result;
|
|
|
|
|
++current_result;
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool started;
|
2013-11-04 00:49:37 +00:00
|
|
|
|
bool separate_totals; /// TODO
|
2013-11-03 23:35:18 +00:00
|
|
|
|
bool final;
|
2013-09-15 10:53:10 +00:00
|
|
|
|
SharedPtr<SplittingAggregator> aggregator;
|
|
|
|
|
Blocks results;
|
|
|
|
|
Blocks::iterator current_result;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
}
|