2011-08-28 02:22:23 +00:00
|
|
|
#pragma once
|
|
|
|
|
2017-01-21 04:24:28 +00:00
|
|
|
#include <vector>
|
|
|
|
#include <memory>
|
2018-02-23 18:55:54 +00:00
|
|
|
#include <mutex>
|
2018-04-17 14:26:07 +00:00
|
|
|
#include <shared_mutex>
|
2017-01-21 04:24:28 +00:00
|
|
|
#include <functional>
|
2013-01-07 00:57:43 +00:00
|
|
|
#include <boost/noncopyable.hpp>
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <Core/Block.h>
|
2017-04-07 19:47:21 +00:00
|
|
|
#include <Core/SortDescription.h>
|
2010-03-01 16:59:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2016-05-28 12:22:22 +00:00
|
|
|
|
|
|
|
class IBlockInputStream;
|
|
|
|
|
|
|
|
using BlockInputStreamPtr = std::shared_ptr<IBlockInputStream>;
|
|
|
|
using BlockInputStreams = std::vector<BlockInputStreamPtr>;
|
|
|
|
|
2017-01-21 04:24:28 +00:00
|
|
|
class TableStructureReadLock;
|
|
|
|
|
|
|
|
using TableStructureReadLockPtr = std::shared_ptr<TableStructureReadLock>;
|
|
|
|
using TableStructureReadLocks = std::vector<TableStructureReadLockPtr>;
|
2017-02-02 15:54:27 +00:00
|
|
|
using TableStructureReadLocksList = std::list<TableStructureReadLockPtr>;
|
2017-01-21 04:24:28 +00:00
|
|
|
|
|
|
|
struct Progress;
|
|
|
|
|
2017-04-07 20:21:58 +00:00
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int OUTPUT_IS_NOT_SORTED;
|
2017-10-03 14:52:08 +00:00
|
|
|
extern const int NOT_IMPLEMENTED;
|
2017-04-07 20:21:58 +00:00
|
|
|
}
|
2017-01-21 04:24:28 +00:00
|
|
|
|
2011-08-28 02:22:23 +00:00
|
|
|
|
2017-05-13 22:19:04 +00:00
|
|
|
/** Callback to track the progress of the query.
|
|
|
|
* Used in IProfilingBlockInputStream and Context.
|
|
|
|
* The function takes the number of rows in the last block, the number of bytes in the last block.
|
|
|
|
* Note that the callback can be called from different threads.
|
2013-02-16 14:55:14 +00:00
|
|
|
*/
|
2016-05-28 10:35:44 +00:00
|
|
|
using ProgressCallback = std::function<void(const Progress & progress)>;
|
2013-02-16 14:55:14 +00:00
|
|
|
|
2011-08-28 02:22:23 +00:00
|
|
|
|
2017-05-13 22:19:04 +00:00
|
|
|
/** The stream interface for reading data by blocks from the database.
|
|
|
|
* Relational operations are supposed to be done also as implementations of this interface.
|
2010-03-01 16:59:51 +00:00
|
|
|
*/
|
2013-01-07 00:57:43 +00:00
|
|
|
class IBlockInputStream : private boost::noncopyable
|
2010-03-01 16:59:51 +00:00
|
|
|
{
|
|
|
|
public:
|
2017-04-01 07:20:54 +00:00
|
|
|
IBlockInputStream() {}
|
2014-10-25 18:33:52 +00:00
|
|
|
|
2018-01-06 18:10:44 +00:00
|
|
|
/** Get data structure of the stream in a form of "header" block (it is also called "sample block").
|
2018-01-09 00:19:58 +00:00
|
|
|
* Header block contains column names, data types, columns of size 0. Constant columns must have corresponding values.
|
2018-01-06 18:10:44 +00:00
|
|
|
* It is guaranteed that method "read" returns blocks of exactly that structure.
|
|
|
|
*/
|
2018-02-18 03:23:48 +00:00
|
|
|
virtual Block getHeader() const = 0;
|
2018-01-06 18:10:44 +00:00
|
|
|
|
2017-05-13 22:19:04 +00:00
|
|
|
/** Read next block.
|
|
|
|
* If there are no more blocks, return an empty block (for which operator `bool` returns false).
|
2017-09-10 01:39:40 +00:00
|
|
|
* NOTE: Only one thread can read from one instance of IBlockInputStream simultaneously.
|
|
|
|
* This also applies for readPrefix, readSuffix.
|
2017-04-01 07:20:54 +00:00
|
|
|
*/
|
|
|
|
virtual Block read() = 0;
|
2010-03-01 16:59:51 +00:00
|
|
|
|
2017-05-13 22:19:04 +00:00
|
|
|
/** Get information about the last block received.
|
2017-04-01 07:20:54 +00:00
|
|
|
*/
|
|
|
|
virtual BlockExtraInfo getBlockExtraInfo() const
|
|
|
|
{
|
|
|
|
throw Exception("Method getBlockExtraInfo is not supported by the data stream " + getName(), ErrorCodes::NOT_IMPLEMENTED);
|
|
|
|
}
|
2015-10-12 14:53:16 +00:00
|
|
|
|
2017-05-13 22:19:04 +00:00
|
|
|
/** Read something before starting all data or after the end of all data.
|
|
|
|
* In the `readSuffix` function, you can implement a finalization that can lead to an exception.
|
|
|
|
* readPrefix() must be called before the first call to read().
|
|
|
|
* readSuffix() should be called after read() returns an empty block, or after a call to cancel(), but not during read() execution.
|
2017-04-01 07:20:54 +00:00
|
|
|
*/
|
|
|
|
virtual void readPrefix() {}
|
|
|
|
virtual void readSuffix() {}
|
2011-10-31 06:37:12 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
virtual ~IBlockInputStream() {}
|
2011-09-04 21:23:19 +00:00
|
|
|
|
2017-05-13 22:19:04 +00:00
|
|
|
/** To output the data stream transformation tree (query execution plan).
|
2017-04-01 07:20:54 +00:00
|
|
|
*/
|
|
|
|
virtual String getName() const = 0;
|
2011-09-04 21:23:19 +00:00
|
|
|
|
2017-04-10 14:50:55 +00:00
|
|
|
/// If this stream generates data in grouped by some keys, return true.
|
|
|
|
virtual bool isGroupedOutput() const { return false; }
|
2017-04-07 20:21:58 +00:00
|
|
|
/// If this stream generates data in order by some keys, return true.
|
2017-04-07 19:47:21 +00:00
|
|
|
virtual bool isSortedOutput() const { return false; }
|
2017-04-10 14:50:55 +00:00
|
|
|
/// In case of isGroupedOutput or isSortedOutput, return corresponding SortDescription
|
2017-04-07 20:21:58 +00:00
|
|
|
virtual const SortDescription & getSortDescription() const { throw Exception("Output of " + getName() + " is not sorted", ErrorCodes::OUTPUT_IS_NOT_SORTED); }
|
2017-04-07 19:47:21 +00:00
|
|
|
|
2018-02-23 10:43:24 +00:00
|
|
|
/** Must be called before read, readPrefix.
|
|
|
|
*/
|
2017-04-01 07:20:54 +00:00
|
|
|
void dumpTree(std::ostream & ostr, size_t indent = 0, size_t multiplier = 1);
|
2011-09-04 21:23:19 +00:00
|
|
|
|
2017-05-13 22:19:04 +00:00
|
|
|
/** Check the depth of the pipeline.
|
|
|
|
* If max_depth is specified and the `depth` is greater - throw an exception.
|
2018-02-23 10:43:24 +00:00
|
|
|
* Must be called before read, readPrefix.
|
2017-04-01 07:20:54 +00:00
|
|
|
*/
|
|
|
|
size_t checkDepth(size_t max_depth) const;
|
2012-12-25 20:36:35 +00:00
|
|
|
|
2017-05-13 22:19:04 +00:00
|
|
|
/** Do not allow to change the table while the blocks stream is alive.
|
2017-04-01 07:20:54 +00:00
|
|
|
*/
|
|
|
|
void addTableLock(const TableStructureReadLockPtr & lock) { table_locks.push_back(lock); }
|
2013-05-04 05:20:07 +00:00
|
|
|
|
2012-03-09 04:45:27 +00:00
|
|
|
|
2018-02-23 10:43:24 +00:00
|
|
|
template <typename F>
|
|
|
|
void forEachChild(F && f)
|
|
|
|
{
|
2018-04-17 14:26:07 +00:00
|
|
|
/// NOTE: Acquire a read lock, therefore f() should be thread safe
|
|
|
|
std::shared_lock lock(children_mutex);
|
|
|
|
|
2018-02-23 10:43:24 +00:00
|
|
|
for (auto & child : children)
|
|
|
|
if (f(*child))
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2017-04-01 07:20:54 +00:00
|
|
|
BlockInputStreams children;
|
2018-04-17 14:26:07 +00:00
|
|
|
std::shared_mutex children_mutex;
|
2014-02-23 02:27:09 +00:00
|
|
|
|
2012-03-09 04:45:27 +00:00
|
|
|
private:
|
2018-02-23 10:43:24 +00:00
|
|
|
TableStructureReadLocks table_locks;
|
2012-12-25 20:36:35 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
size_t checkDepthImpl(size_t max_depth, size_t level) const;
|
2013-05-04 05:20:07 +00:00
|
|
|
|
2018-02-19 19:18:51 +00:00
|
|
|
/// Get text with names of this source and the entire subtree.
|
2017-04-01 07:20:54 +00:00
|
|
|
String getTreeID() const;
|
2010-03-01 16:59:51 +00:00
|
|
|
};
|
|
|
|
|
2011-08-28 02:22:23 +00:00
|
|
|
|
2010-03-01 16:59:51 +00:00
|
|
|
}
|
|
|
|
|