2011-08-28 02:22:23 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
2013-01-07 00:57:43 +00:00
|
|
|
|
#include <boost/noncopyable.hpp>
|
|
|
|
|
|
2011-08-28 02:22:23 +00:00
|
|
|
|
#include <Poco/SharedPtr.h>
|
2010-03-01 16:59:51 +00:00
|
|
|
|
|
|
|
|
|
#include <DB/Core/Block.h>
|
2014-03-19 10:45:13 +00:00
|
|
|
|
#include <DB/Storages/IStorage.h>
|
2010-03-01 16:59:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
2011-08-28 02:22:23 +00:00
|
|
|
|
using Poco::SharedPtr;
|
|
|
|
|
|
2013-02-16 14:55:14 +00:00
|
|
|
|
/** Коллбэк для отслеживания прогресса выполнения запроса.
|
|
|
|
|
* Используется в IProfilingBlockInputStream и Context-е.
|
|
|
|
|
* Функция принимает количество строк в последнем блоке, количество байт в последнем блоке.
|
|
|
|
|
* Следует иметь ввиду, что колбэк может вызываться из разных потоков.
|
|
|
|
|
*/
|
2014-03-10 09:33:18 +00:00
|
|
|
|
typedef std::function<void(size_t, size_t)> ProgressCallback;
|
2013-02-16 14:55:14 +00:00
|
|
|
|
|
2011-08-28 02:22:23 +00:00
|
|
|
|
|
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:
|
2011-09-04 21:23:19 +00:00
|
|
|
|
typedef SharedPtr<IBlockInputStream> BlockInputStreamPtr;
|
|
|
|
|
typedef std::vector<BlockInputStreamPtr> BlockInputStreams;
|
|
|
|
|
|
2014-03-19 10:45:13 +00:00
|
|
|
|
IBlockInputStream() {}
|
2013-01-23 17:38:03 +00:00
|
|
|
|
|
2010-03-01 16:59:51 +00:00
|
|
|
|
/** Прочитать следующий блок.
|
|
|
|
|
* Если блоков больше нет - вернуть пустой блок (для которого operator bool возвращает false).
|
|
|
|
|
*/
|
|
|
|
|
virtual Block read() = 0;
|
|
|
|
|
|
2011-10-31 06:37:12 +00:00
|
|
|
|
/** Прочитать что-нибудь перед началом всех данных или после конца всех данных.
|
2013-09-13 20:33:09 +00:00
|
|
|
|
* В функции readSuffix можно реализовать финализацию, которая может привести к исключению.
|
2013-11-25 10:46:25 +00:00
|
|
|
|
* readPrefix() должна вызываться до первого вызова read().
|
2013-12-27 13:22:32 +00:00
|
|
|
|
* readSuffix() должна вызываться после того, как read() вернула пустой блок, или после вызова cancel(), но не во время выполнения read().
|
2011-10-31 06:37:12 +00:00
|
|
|
|
*/
|
|
|
|
|
virtual void readPrefix() {}
|
|
|
|
|
virtual void readSuffix() {}
|
|
|
|
|
|
2010-03-01 16:59:51 +00:00
|
|
|
|
virtual ~IBlockInputStream() {}
|
2011-09-04 21:23:19 +00:00
|
|
|
|
|
|
|
|
|
/** Для вывода дерева преобразований потока данных (плана выполнения запроса).
|
|
|
|
|
*/
|
|
|
|
|
virtual String getName() const = 0;
|
2012-03-05 02:34:20 +00:00
|
|
|
|
virtual String getShortName() const; /// То же самое, но без BlockInputStream на конце.
|
2011-09-04 21:23:19 +00:00
|
|
|
|
|
2013-05-03 10:20:53 +00:00
|
|
|
|
/** Уникальный идентификатор части конвейера выполнения запроса.
|
|
|
|
|
* Источники с одинаковым идентификатором считаются идентичными
|
|
|
|
|
* (выдающими одинаковые данные), и могут быть заменены на один источник
|
|
|
|
|
* при одновременном выполнении сразу нескольких запросов.
|
|
|
|
|
* Если источник нельзя склеивать ни с каким другим - верните в качестве идентификатора адрес объекта.
|
|
|
|
|
*/
|
|
|
|
|
virtual String getID() const = 0;
|
|
|
|
|
|
2011-09-04 21:23:19 +00:00
|
|
|
|
BlockInputStreams & getChildren() { return children; }
|
2012-03-05 02:34:20 +00:00
|
|
|
|
|
2012-06-25 03:42:08 +00:00
|
|
|
|
void dumpTree(std::ostream & ostr, size_t indent = 0, size_t multiplier = 1);
|
2012-03-05 02:34:20 +00:00
|
|
|
|
void dumpTreeWithProfile(std::ostream & ostr, size_t indent = 0);
|
2011-09-04 21:23:19 +00:00
|
|
|
|
|
2012-03-09 04:45:27 +00:00
|
|
|
|
/// Получить листовые источники (не считая этот).
|
|
|
|
|
BlockInputStreams getLeaves();
|
|
|
|
|
|
2012-08-23 23:49:28 +00:00
|
|
|
|
/// Получить количество строк и байт, прочитанных в листовых источниках.
|
|
|
|
|
void getLeafRowsBytes(size_t & rows, size_t & bytes);
|
|
|
|
|
|
2012-12-25 20:36:35 +00:00
|
|
|
|
/** Проверить глубину конвейера.
|
|
|
|
|
* Если задано max_depth и глубина больше - кинуть исключение.
|
|
|
|
|
*/
|
|
|
|
|
size_t checkDepth(size_t max_depth) const;
|
|
|
|
|
|
2014-03-19 10:45:13 +00:00
|
|
|
|
/** Не давать изменить таблицу, пока жив поток блоков.
|
|
|
|
|
*/
|
|
|
|
|
void addTableLock(const IStorage::TableStructureReadLockPtr & lock) { table_locks.push_back(lock); }
|
2013-05-04 05:20:07 +00:00
|
|
|
|
|
2014-02-23 02:27:09 +00:00
|
|
|
|
protected:
|
2014-03-19 10:45:13 +00:00
|
|
|
|
IStorage::TableStructureReadLocks table_locks;
|
2012-03-09 04:45:27 +00:00
|
|
|
|
|
2014-02-23 02:27:09 +00:00
|
|
|
|
BlockInputStreams children;
|
|
|
|
|
|
2012-03-09 04:45:27 +00:00
|
|
|
|
private:
|
2014-04-08 07:31:51 +00:00
|
|
|
|
void getLeavesImpl(BlockInputStreams & res, BlockInputStreamPtr this_shared_ptr = nullptr);
|
2012-12-25 20:36:35 +00:00
|
|
|
|
|
2012-12-26 20:29:28 +00:00
|
|
|
|
size_t checkDepthImpl(size_t max_depth, size_t level) const;
|
2013-05-04 05:20:07 +00:00
|
|
|
|
|
|
|
|
|
/** Получить текст, который идентифицирует этот источник и всё поддерево.
|
|
|
|
|
* В отличие от getID - без учёта параметров.
|
|
|
|
|
*/
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|