mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
dbms: development [#CONV-2944].
This commit is contained in:
parent
a9228f798a
commit
9b153918e7
@ -1,5 +1,4 @@
|
||||
#ifndef DBMS_CORE_ERROR_CODES_H
|
||||
#define DBMS_CORE_ERROR_CODES_H
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -66,9 +65,8 @@ namespace ErrorCodes
|
||||
TABLE_ALREADY_EXISTS,
|
||||
TABLE_METADATA_ALREADY_EXISTS,
|
||||
ILLEGAL_TYPE_OF_COLUMN_FOR_FILTER,
|
||||
UNKNOWN_TABLE
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -20,7 +20,7 @@ using Poco::SharedPtr;
|
||||
class ExpressionBlockInputStream : public IBlockInputStream
|
||||
{
|
||||
public:
|
||||
ExpressionBlockInputStream(SharedPtr<IBlockInputStream> input_, SharedPtr<Expression> expression_)
|
||||
ExpressionBlockInputStream(BlockInputStreamPtr input_, SharedPtr<Expression> expression_)
|
||||
: input(input_), expression(expression_) {}
|
||||
|
||||
Block read()
|
||||
@ -30,11 +30,11 @@ public:
|
||||
return res;
|
||||
|
||||
expression->execute(res);
|
||||
return res;
|
||||
return expression->projectResult(res);
|
||||
}
|
||||
|
||||
private:
|
||||
SharedPtr<IBlockInputStream> input;
|
||||
BlockInputStreamPtr input;
|
||||
SharedPtr<Expression> expression;
|
||||
};
|
||||
|
||||
|
@ -19,11 +19,11 @@ class FilterBlockInputStream : public IBlockInputStream
|
||||
{
|
||||
public:
|
||||
/// filter_column_ - номер столбца с условиями фильтрации
|
||||
FilterBlockInputStream(SharedPtr<IBlockInputStream> input_, size_t filter_column_);
|
||||
FilterBlockInputStream(BlockInputStreamPtr input_, size_t filter_column_);
|
||||
Block read();
|
||||
|
||||
private:
|
||||
SharedPtr<IBlockInputStream> input;
|
||||
BlockInputStreamPtr input;
|
||||
size_t filter_column;
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#ifndef DBMS_DATA_STREAMS_IBLOCKINPUTSTREAM_H
|
||||
#define DBMS_DATA_STREAMS_IBLOCKINPUTSTREAM_H
|
||||
#pragma once
|
||||
|
||||
#include <Poco/SharedPtr.h>
|
||||
|
||||
#include <DB/Core/Block.h>
|
||||
|
||||
@ -7,6 +8,9 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
using Poco::SharedPtr;
|
||||
|
||||
|
||||
/** Интерфейс потока для чтения данных по блокам из БД.
|
||||
* Реляционные операции предполагается делать также реализациями этого интерфейса.
|
||||
*/
|
||||
@ -22,6 +26,8 @@ public:
|
||||
virtual ~IBlockInputStream() {}
|
||||
};
|
||||
|
||||
|
||||
typedef SharedPtr<IBlockInputStream> BlockInputStreamPtr;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,6 @@
|
||||
#ifndef DBMS_DATA_STREAMS_IBLOCKOUTPUTSTREAM_H
|
||||
#define DBMS_DATA_STREAMS_IBLOCKOUTPUTSTREAM_H
|
||||
#pragma once
|
||||
|
||||
#include <Poco/SharedPtr.h>
|
||||
|
||||
#include <DB/Core/Block.h>
|
||||
|
||||
@ -7,6 +8,9 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
using Poco::SharedPtr;
|
||||
|
||||
|
||||
/** Интерфейс потока для записи данных в БД или в сеть, или в консоль и т. п.
|
||||
*/
|
||||
class IBlockOutputStream
|
||||
@ -20,6 +24,6 @@ public:
|
||||
virtual ~IBlockOutputStream() {}
|
||||
};
|
||||
|
||||
}
|
||||
typedef SharedPtr<IBlockOutputStream> BlockOutputStreamPtr;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
@ -17,11 +17,11 @@ using Poco::SharedPtr;
|
||||
class LimitBlockInputStream : public IBlockInputStream
|
||||
{
|
||||
public:
|
||||
LimitBlockInputStream(SharedPtr<IBlockInputStream> input_, size_t limit_, size_t offset_ = 0);
|
||||
LimitBlockInputStream(BlockInputStreamPtr input_, size_t limit_, size_t offset_ = 0);
|
||||
Block read();
|
||||
|
||||
private:
|
||||
SharedPtr<IBlockInputStream> input;
|
||||
BlockInputStreamPtr input;
|
||||
size_t limit;
|
||||
size_t offset;
|
||||
size_t pos;
|
||||
|
@ -37,7 +37,7 @@ struct BlockStreamProfileInfo
|
||||
class ProfilingBlockInputStream : public IBlockInputStream
|
||||
{
|
||||
public:
|
||||
ProfilingBlockInputStream(SharedPtr<IBlockInputStream> in_)
|
||||
ProfilingBlockInputStream(BlockInputStreamPtr in_)
|
||||
: in(in_) {}
|
||||
|
||||
Block read();
|
||||
@ -45,7 +45,7 @@ public:
|
||||
const BlockStreamProfileInfo & getInfo() const;
|
||||
|
||||
private:
|
||||
SharedPtr<IBlockInputStream> in;
|
||||
BlockInputStreamPtr in;
|
||||
BlockStreamProfileInfo info;
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
#ifndef DBMS_DATA_STREAMS_ROWINPUTSTREAMFROMBLOCKINPUTSTREAM_H
|
||||
#define DBMS_DATA_STREAMS_ROWINPUTSTREAMFROMBLOCKINPUTSTREAM_H
|
||||
|
||||
#include <Poco/SharedPtr.h>
|
||||
#pragma once
|
||||
|
||||
#include <DB/DataStreams/IBlockInputStream.h>
|
||||
#include <DB/DataStreams/IRowInputStream.h>
|
||||
@ -10,8 +7,6 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
using Poco::SharedPtr;
|
||||
|
||||
|
||||
/** Преобразует поток для чтения данных по блокам в поток для чтения данных по строкам.
|
||||
*/
|
||||
@ -30,5 +25,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -26,8 +26,14 @@ public:
|
||||
|
||||
/** Выполнить выражение над блоком. Блок должен содержать все столбцы - идентификаторы.
|
||||
* Функция добавляет в блок новые столбцы - результаты вычислений.
|
||||
* part_id - какую часть выражения вычислять.
|
||||
*/
|
||||
void execute(Block & block);
|
||||
void execute(Block & block, unsigned part_id = 0);
|
||||
|
||||
/** Взять из блока с промежуточными результатами вычислений только столбцы, представляющие собой конечный результат.
|
||||
* Вернуть новый блок, в котором эти столбцы расположены в правильном порядке.
|
||||
*/
|
||||
Block projectResult(Block & block);
|
||||
|
||||
/** Получить список типов столбцов результата.
|
||||
*/
|
||||
@ -61,14 +67,9 @@ private:
|
||||
|
||||
/** Прописать во всех узлах, что они ещё не вычислены.
|
||||
*/
|
||||
void setNotCalculated(ASTPtr ast);
|
||||
void setNotCalculated(ASTPtr ast, unsigned part_id);
|
||||
|
||||
void executeImpl(ASTPtr ast, Block & block);
|
||||
|
||||
/** Взять из блока с промежуточными результатами вычислений только столбцы, представляющие собой конечный результат.
|
||||
* Вернуть новый блок, в котором эти столбцы расположены в правильном порядке.
|
||||
*/
|
||||
Block projectResult(ASTPtr ast, Block & block);
|
||||
void executeImpl(ASTPtr ast, Block & block, unsigned part_id);
|
||||
|
||||
void collectFinalColumns(ASTPtr ast, Block & src, Block & dst);
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
#ifndef DBMS_PARSERS_ASTIDENTIFIER_H
|
||||
#define DBMS_PARSERS_ASTIDENTIFIER_H
|
||||
#pragma once
|
||||
|
||||
#include <DB/DataTypes/IDataType.h>
|
||||
#include <DB/Parsers/IAST.h>
|
||||
@ -13,18 +12,27 @@ namespace DB
|
||||
class ASTIdentifier : public IAST
|
||||
{
|
||||
public:
|
||||
enum Kind
|
||||
{
|
||||
Column,
|
||||
Database,
|
||||
Table,
|
||||
};
|
||||
|
||||
/// имя
|
||||
String name;
|
||||
/// тип
|
||||
|
||||
/// чего идентифицирует этот идентификатор
|
||||
Kind kind;
|
||||
|
||||
/// тип (только для столбцов)
|
||||
DataTypePtr type;
|
||||
|
||||
ASTIdentifier() {}
|
||||
ASTIdentifier(StringRange range_, const String & name_) : IAST(range_), name(name_) {}
|
||||
ASTIdentifier(StringRange range_, const String & name_, Kind kind_ = Column) : IAST(range_), name(name_), kind(kind_) {}
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
String getID() { return "Identifier_" + name; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -23,12 +23,20 @@ public:
|
||||
typedef std::list<SharedPtr<IAST> > ASTs;
|
||||
ASTs children;
|
||||
StringRange range;
|
||||
/// Было ли соответствующее выражение вычислено.
|
||||
|
||||
/** Было ли соответствующее выражение вычислено.
|
||||
* Используется, чтобы при обходе графа выражения, не вычислять несколько раз одни и те же узлы.
|
||||
*/
|
||||
bool calculated;
|
||||
|
||||
/** Идентификатор части выражения. Используется при интерпретации, чтобы вычислять не всё выражение сразу,
|
||||
* а по частям (например, сначала WHERE, потом фильтрация, потом всё остальное).
|
||||
*/
|
||||
unsigned part_id;
|
||||
|
||||
|
||||
IAST() : range(NULL, NULL), calculated(false) {}
|
||||
IAST(StringRange range_) : range(range_), calculated(false) {}
|
||||
IAST() : range(NULL, NULL), calculated(false), part_id(0) {}
|
||||
IAST(StringRange range_) : range(range_), calculated(false), part_id(0) {}
|
||||
virtual ~IAST() {}
|
||||
|
||||
/** Получить текст, который идентифицирует этот элемент. */
|
||||
|
@ -44,7 +44,7 @@ public:
|
||||
* (индексы, блокировки и т. п.)
|
||||
* Возвращает объект, с помощью которого можно последовательно читать данные.
|
||||
*/
|
||||
virtual SharedPtr<IBlockInputStream> read(
|
||||
virtual BlockInputStreamPtr read(
|
||||
const Names & column_names,
|
||||
ASTPtr query,
|
||||
size_t max_block_size = DEFAULT_BLOCK_SIZE)
|
||||
@ -56,7 +56,7 @@ public:
|
||||
* Принимает описание запроса, в котором может содержаться информация о методе записи данных.
|
||||
* Возвращает объект, с помощью которого можно последовательно писать данные.
|
||||
*/
|
||||
virtual SharedPtr<IBlockOutputStream> write(
|
||||
virtual BlockOutputStreamPtr write(
|
||||
ASTPtr query)
|
||||
{
|
||||
throw Exception("Method write() is not supported by storage " + getName(), ErrorCodes::NOT_IMPLEMENTED);
|
||||
|
@ -91,12 +91,12 @@ public:
|
||||
|
||||
const NamesAndTypes & getColumns() const { return *columns; }
|
||||
|
||||
SharedPtr<IBlockInputStream> read(
|
||||
BlockInputStreamPtr read(
|
||||
const Names & column_names,
|
||||
ASTPtr query,
|
||||
size_t max_block_size = DEFAULT_BLOCK_SIZE);
|
||||
|
||||
SharedPtr<IBlockOutputStream> write(
|
||||
BlockOutputStreamPtr write(
|
||||
ASTPtr query);
|
||||
|
||||
private:
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
|
||||
const NamesAndTypes & getColumns() const { return columns; }
|
||||
|
||||
SharedPtr<IBlockInputStream> read(
|
||||
BlockInputStreamPtr read(
|
||||
const Names & column_names,
|
||||
ASTPtr query,
|
||||
size_t max_block_size = DEFAULT_BLOCK_SIZE);
|
||||
|
45
dbms/include/DB/Storages/StorageSystemOne.h
Normal file
45
dbms/include/DB/Storages/StorageSystemOne.h
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <DB/Storages/IStorage.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
|
||||
class OneValueBlockInputStream : public IBlockInputStream
|
||||
{
|
||||
public:
|
||||
OneValueBlockInputStream();
|
||||
Block read();
|
||||
private:
|
||||
bool has_been_read;
|
||||
};
|
||||
|
||||
|
||||
/** Реализует хранилище для системной таблицы One.
|
||||
* Таблица содержит единственный столбец dummy UInt8 и единственную строку со значением 0.
|
||||
* Используется, если в запросе не указана таблица.
|
||||
* Аналог таблицы DUAL в Oracle и MySQL.
|
||||
*/
|
||||
class StorageSystemOne : public IStorage
|
||||
{
|
||||
public:
|
||||
StorageSystemOne(const std::string & name_);
|
||||
|
||||
std::string getName() const { return "SystemOne"; }
|
||||
std::string getTableName() const { return "One"; }
|
||||
|
||||
const NamesAndTypes & getColumns() const { return columns; }
|
||||
|
||||
BlockInputStreamPtr read(
|
||||
const Names & column_names,
|
||||
ASTPtr query,
|
||||
size_t max_block_size = DEFAULT_BLOCK_SIZE);
|
||||
|
||||
private:
|
||||
const std::string name;
|
||||
NamesAndTypes columns;
|
||||
};
|
||||
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
FilterBlockInputStream::FilterBlockInputStream(SharedPtr<IBlockInputStream> input_, size_t filter_column_)
|
||||
FilterBlockInputStream::FilterBlockInputStream(BlockInputStreamPtr input_, size_t filter_column_)
|
||||
: input(input_), filter_column(filter_column_)
|
||||
{
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ namespace DB
|
||||
|
||||
using Poco::SharedPtr;
|
||||
|
||||
LimitBlockInputStream::LimitBlockInputStream(SharedPtr<IBlockInputStream> input_, size_t limit_, size_t offset_)
|
||||
LimitBlockInputStream::LimitBlockInputStream(BlockInputStreamPtr input_, size_t limit_, size_t offset_)
|
||||
: input(input_), limit(limit_), offset(offset_), pos(0)
|
||||
{
|
||||
}
|
||||
|
@ -23,11 +23,14 @@ void Expression::addSemantic(ASTPtr ast)
|
||||
}
|
||||
else if (ASTIdentifier * node = dynamic_cast<ASTIdentifier *>(&*ast))
|
||||
{
|
||||
NamesAndTypes::const_iterator it = context.columns.find(node->name);
|
||||
if (it == context.columns.end())
|
||||
throw Exception("Unknown identifier " + node->name, ErrorCodes::UNKNOWN_IDENTIFIER);
|
||||
if (node->kind == ASTIdentifier::Column)
|
||||
{
|
||||
NamesAndTypes::const_iterator it = context.columns.find(node->name);
|
||||
if (it == context.columns.end())
|
||||
throw Exception("Unknown identifier " + node->name, ErrorCodes::UNKNOWN_IDENTIFIER);
|
||||
|
||||
node->type = it->second;
|
||||
node->type = it->second;
|
||||
}
|
||||
}
|
||||
else if (ASTLiteral * node = dynamic_cast<ASTLiteral *>(&*ast))
|
||||
{
|
||||
@ -104,30 +107,30 @@ void Expression::glueTreeImpl(ASTPtr ast, Subtrees & subtrees)
|
||||
}
|
||||
|
||||
|
||||
void Expression::setNotCalculated(ASTPtr ast)
|
||||
void Expression::setNotCalculated(ASTPtr ast, unsigned part_id)
|
||||
{
|
||||
ast->calculated = false;
|
||||
if (ast->part_id == part_id)
|
||||
ast->calculated = false;
|
||||
for (ASTs::iterator it = ast->children.begin(); it != ast->children.end(); ++it)
|
||||
setNotCalculated(*it);
|
||||
setNotCalculated(*it, part_id);
|
||||
}
|
||||
|
||||
|
||||
void Expression::execute(Block & block)
|
||||
void Expression::execute(Block & block, unsigned part_id)
|
||||
{
|
||||
setNotCalculated(ast);
|
||||
executeImpl(ast, block);
|
||||
block = projectResult(ast, block);
|
||||
setNotCalculated(ast, part_id);
|
||||
executeImpl(ast, block, part_id);
|
||||
}
|
||||
|
||||
|
||||
void Expression::executeImpl(ASTPtr ast, Block & block)
|
||||
void Expression::executeImpl(ASTPtr ast, Block & block, unsigned part_id)
|
||||
{
|
||||
/// Обход в глубину
|
||||
|
||||
for (ASTs::iterator it = ast->children.begin(); it != ast->children.end(); ++it)
|
||||
executeImpl(*it, block);
|
||||
executeImpl(*it, block, part_id);
|
||||
|
||||
if (ast->calculated)
|
||||
if (ast->calculated || ast->part_id != part_id)
|
||||
return;
|
||||
|
||||
/** Столбцы из таблицы уже загружены в блок.
|
||||
@ -186,7 +189,7 @@ void Expression::executeImpl(ASTPtr ast, Block & block)
|
||||
}
|
||||
|
||||
|
||||
Block Expression::projectResult(ASTPtr ast, Block & block)
|
||||
Block Expression::projectResult(Block & block)
|
||||
{
|
||||
Block res;
|
||||
collectFinalColumns(ast, block, res);
|
||||
@ -197,7 +200,10 @@ Block Expression::projectResult(ASTPtr ast, Block & block)
|
||||
void Expression::collectFinalColumns(ASTPtr ast, Block & src, Block & dst)
|
||||
{
|
||||
if (ASTIdentifier * ident = dynamic_cast<ASTIdentifier *>(&*ast))
|
||||
dst.insert(src.getByName(ident->name));
|
||||
{
|
||||
if (ident->kind == ASTIdentifier::Column)
|
||||
dst.insert(src.getByName(ident->name));
|
||||
}
|
||||
else if (dynamic_cast<ASTLiteral *>(&*ast))
|
||||
dst.insert(src.getByName(ast->getTreeID()));
|
||||
else if (ASTFunction * func = dynamic_cast<ASTFunction *>(&*ast))
|
||||
|
@ -179,6 +179,7 @@ int main(int argc, char ** argv)
|
||||
stopwatch.start();
|
||||
|
||||
expression.execute(block);
|
||||
block = expression.projectResult(block);
|
||||
|
||||
stopwatch.stop();
|
||||
std::cout << std::fixed << std::setprecision(2)
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <DB/Parsers/ASTSelectQuery.h>
|
||||
#include <DB/Parsers/ASTIdentifier.h>
|
||||
#include <DB/Parsers/IParserBase.h>
|
||||
#include <DB/Parsers/CommonParsers.h>
|
||||
#include <DB/Parsers/ExpressionElementParsers.h>
|
||||
@ -65,6 +66,9 @@ bool ParserSelectQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & ex
|
||||
|
||||
ws.ignore(pos, end);
|
||||
}
|
||||
|
||||
dynamic_cast<ASTIdentifier &>(*select_query->database).kind = ASTIdentifier::Database;
|
||||
dynamic_cast<ASTIdentifier &>(*select_query->table).kind = ASTIdentifier::Table;
|
||||
}
|
||||
|
||||
/// WHERE expr
|
||||
|
@ -84,7 +84,7 @@ StorageLog::StorageLog(const std::string & path_, const std::string & name_, Sha
|
||||
}
|
||||
|
||||
|
||||
SharedPtr<IBlockInputStream> StorageLog::read(
|
||||
BlockInputStreamPtr StorageLog::read(
|
||||
const Names & column_names,
|
||||
ASTPtr query,
|
||||
size_t max_block_size)
|
||||
@ -94,7 +94,7 @@ SharedPtr<IBlockInputStream> StorageLog::read(
|
||||
}
|
||||
|
||||
|
||||
SharedPtr<IBlockOutputStream> StorageLog::write(
|
||||
BlockOutputStreamPtr StorageLog::write(
|
||||
ASTPtr query)
|
||||
{
|
||||
return new LogBlockOutputStream(*this);
|
||||
|
@ -46,7 +46,7 @@ StorageSystemNumbers::StorageSystemNumbers(const std::string & name_)
|
||||
}
|
||||
|
||||
|
||||
SharedPtr<IBlockInputStream> StorageSystemNumbers::read(
|
||||
BlockInputStreamPtr StorageSystemNumbers::read(
|
||||
const Names & column_names, ASTPtr query, size_t max_block_size)
|
||||
{
|
||||
check(column_names);
|
||||
|
51
dbms/src/Storages/StorageSystemOne.cpp
Normal file
51
dbms/src/Storages/StorageSystemOne.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
#include <DB/Core/Exception.h>
|
||||
#include <DB/Core/ErrorCodes.h>
|
||||
|
||||
#include <DB/Columns/ColumnsNumber.h>
|
||||
|
||||
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
||||
|
||||
#include <DB/Storages/StorageSystemOne.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
|
||||
OneValueBlockInputStream::OneValueBlockInputStream() : has_been_read(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Block OneValueBlockInputStream::read()
|
||||
{
|
||||
Block res;
|
||||
if (has_been_read)
|
||||
return res;
|
||||
|
||||
has_been_read = true;
|
||||
ColumnWithNameAndType col;
|
||||
col.name = "dummy";
|
||||
col.type = new DataTypeUInt8;
|
||||
col.column = new ColumnConstUInt8(0, 1);
|
||||
res.insert(col);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
StorageSystemOne::StorageSystemOne(const std::string & name_)
|
||||
: name(name_)
|
||||
{
|
||||
columns["dummy"] = new DataTypeUInt8;
|
||||
}
|
||||
|
||||
|
||||
BlockInputStreamPtr StorageSystemOne::read(
|
||||
const Names & column_names, ASTPtr query, size_t max_block_size)
|
||||
{
|
||||
check(column_names);
|
||||
return new OneValueBlockInputStream();
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user