2019-09-13 12:34:05 +00:00
|
|
|
#pragma once
|
|
|
|
#include <DataStreams/IBlockInputStream.h>
|
2019-10-20 09:12:42 +00:00
|
|
|
#include <Processors/Pipe.h>
|
2020-03-19 13:45:19 +00:00
|
|
|
#include <Processors/RowsBeforeLimitCounter.h>
|
2019-09-13 12:34:05 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2019-10-04 15:40:05 +00:00
|
|
|
class ISourceWithProgress;
|
|
|
|
|
2019-10-10 14:16:15 +00:00
|
|
|
/// It's a wrapper from processors tree-shaped pipeline to block input stream.
|
|
|
|
/// Execute all processors in a single thread, by in-order tree traverse.
|
2019-10-21 16:26:29 +00:00
|
|
|
/// Also, support for progress and quotas.
|
|
|
|
class TreeExecutorBlockInputStream : public IBlockInputStream
|
2019-09-13 12:34:05 +00:00
|
|
|
{
|
|
|
|
public:
|
2019-10-10 14:16:15 +00:00
|
|
|
/// Last processor in list must be a tree root.
|
|
|
|
/// It is checked that
|
|
|
|
/// * processors form a tree
|
|
|
|
/// * all processors are attainable from root
|
|
|
|
/// * there is no other connected processors
|
2020-01-30 16:17:46 +00:00
|
|
|
explicit TreeExecutorBlockInputStream(Pipe pipe) : output_port(pipe.getPort())
|
2019-10-20 09:12:42 +00:00
|
|
|
{
|
2020-01-30 16:17:46 +00:00
|
|
|
for (auto & table_lock : pipe.getTableLocks())
|
|
|
|
addTableLock(table_lock);
|
|
|
|
|
|
|
|
for (auto & storage : pipe.getStorageHolders())
|
|
|
|
storage_holders.emplace_back(storage);
|
|
|
|
|
|
|
|
for (auto & context : pipe.getContexts())
|
|
|
|
interpreter_context.emplace_back(context);
|
|
|
|
|
2020-02-03 15:35:35 +00:00
|
|
|
totals_port = pipe.getTotalsPort();
|
2020-01-30 16:17:46 +00:00
|
|
|
processors = std::move(pipe).detachProcessors();
|
2019-10-20 09:12:42 +00:00
|
|
|
init();
|
|
|
|
}
|
2019-09-13 12:34:05 +00:00
|
|
|
|
2020-02-18 13:16:30 +00:00
|
|
|
String getName() const override { return "TreeExecutor"; }
|
2019-09-13 12:34:05 +00:00
|
|
|
Block getHeader() const override { return root->getOutputs().front().getHeader(); }
|
|
|
|
|
2019-10-04 15:40:05 +00:00
|
|
|
/// This methods does not affect TreeExecutor as IBlockInputStream itself.
|
|
|
|
/// They just passed to all SourceWithProgress processors.
|
|
|
|
void setProgressCallback(const ProgressCallback & callback) final;
|
|
|
|
void setProcessListElement(QueryStatus * elem) final;
|
|
|
|
void setLimits(const LocalLimits & limits_) final;
|
2020-03-07 17:37:38 +00:00
|
|
|
void setQuota(const std::shared_ptr<const EnabledQuota> & quota_) final;
|
2019-10-04 15:40:05 +00:00
|
|
|
void addTotalRowsApprox(size_t value) final;
|
|
|
|
|
2019-09-13 12:34:05 +00:00
|
|
|
protected:
|
|
|
|
Block readImpl() override;
|
|
|
|
|
|
|
|
private:
|
2019-10-20 09:12:42 +00:00
|
|
|
OutputPort & output_port;
|
2020-02-03 15:35:35 +00:00
|
|
|
OutputPort * totals_port = nullptr;
|
2019-09-13 12:34:05 +00:00
|
|
|
Processors processors;
|
|
|
|
IProcessor * root = nullptr;
|
2019-10-20 09:12:42 +00:00
|
|
|
std::unique_ptr<InputPort> input_port;
|
2020-02-03 15:35:35 +00:00
|
|
|
std::unique_ptr<InputPort> input_totals_port;
|
2020-03-19 13:45:19 +00:00
|
|
|
RowsBeforeLimitCounterPtr rows_before_limit_at_least;
|
2019-09-13 12:34:05 +00:00
|
|
|
|
2019-10-04 15:40:05 +00:00
|
|
|
/// Remember sources that support progress.
|
|
|
|
std::vector<ISourceWithProgress *> sources_with_progress;
|
|
|
|
|
2020-01-28 16:59:28 +00:00
|
|
|
QueryStatus * process_list_element = nullptr;
|
|
|
|
|
2019-09-13 12:34:05 +00:00
|
|
|
void init();
|
2019-10-10 14:16:15 +00:00
|
|
|
/// Execute tree step-by-step until root returns next chunk or execution is finished.
|
2020-02-03 15:35:35 +00:00
|
|
|
void execute(bool on_totals);
|
2020-01-30 16:17:46 +00:00
|
|
|
|
2020-03-19 13:45:19 +00:00
|
|
|
void initRowsBeforeLimit();
|
2020-02-18 10:37:57 +00:00
|
|
|
|
2020-01-30 16:17:46 +00:00
|
|
|
/// Moved from pipe.
|
|
|
|
std::vector<std::shared_ptr<Context>> interpreter_context;
|
|
|
|
std::vector<StoragePtr> storage_holders;
|
2019-09-13 12:34:05 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|