2011-08-09 19:19:25 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
2011-08-13 23:03:07 +00:00
|
|
|
|
#include <set>
|
|
|
|
|
|
2011-08-09 19:19:25 +00:00
|
|
|
|
#include <Poco/SharedPtr.h>
|
|
|
|
|
|
|
|
|
|
#include <DB/Parsers/IAST.h>
|
|
|
|
|
#include <DB/Interpreters/Context.h>
|
2011-09-24 20:32:41 +00:00
|
|
|
|
#include <DB/Interpreters/Aggregator.h>
|
2011-08-09 19:19:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/** Интерпретирует выражение из синтаксического дерева,
|
|
|
|
|
* в котором присутствуют имена столбцов, константы и обычные функции.
|
|
|
|
|
*/
|
2012-12-27 17:43:41 +00:00
|
|
|
|
class Expression : private boost::noncopyable
|
2011-08-09 19:19:25 +00:00
|
|
|
|
{
|
|
|
|
|
public:
|
2011-12-12 06:15:34 +00:00
|
|
|
|
Expression(const ASTPtr & ast_, const Context & context_) : ast(ast_), context(context_)
|
2011-08-09 19:19:25 +00:00
|
|
|
|
{
|
2011-11-06 04:21:09 +00:00
|
|
|
|
createAliasesDict(ast);
|
2011-08-12 18:27:39 +00:00
|
|
|
|
addSemantic(ast);
|
|
|
|
|
glueTree(ast);
|
2011-08-09 19:19:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
2011-08-28 05:13:24 +00:00
|
|
|
|
/** Получить список столбцов, которых необходимо прочитать из таблицы, чтобы выполнить выражение.
|
|
|
|
|
*/
|
|
|
|
|
Names getRequiredColumns();
|
|
|
|
|
|
2012-08-22 20:29:01 +00:00
|
|
|
|
/** Преобразовать подзапросы или перечисления значений в секции IN в множества.
|
|
|
|
|
* Выполняет подзапросы, если требуется.
|
2012-08-23 23:51:51 +00:00
|
|
|
|
* Заменяет узлы ASTSubquery на узлы ASTSet.
|
|
|
|
|
* Следует вызывать перед execute, если в выражении могут быть множества.
|
2012-08-22 20:29:01 +00:00
|
|
|
|
*/
|
2012-12-26 20:29:28 +00:00
|
|
|
|
void makeSets(size_t subquery_depth = 0);
|
2012-08-22 20:29:01 +00:00
|
|
|
|
|
2012-08-24 20:40:34 +00:00
|
|
|
|
/** Выполнить подзапросы не в секциях IN и FROM и преобразовать их в константы.
|
|
|
|
|
* Поддерживаются только независимые подзапросы.
|
|
|
|
|
* Следует вызывать перед execute, если в выражении могут быть скалярные подзапросы.
|
|
|
|
|
* Заменяет узлы ASTSubquery на узлы ASTLiteral или tuple.
|
|
|
|
|
*/
|
2012-12-26 20:29:28 +00:00
|
|
|
|
void resolveScalarSubqueries(size_t subquery_depth = 0);
|
2012-08-24 20:40:34 +00:00
|
|
|
|
|
2011-08-09 19:19:25 +00:00
|
|
|
|
/** Выполнить выражение над блоком. Блок должен содержать все столбцы - идентификаторы.
|
2011-08-12 18:27:39 +00:00
|
|
|
|
* Функция добавляет в блок новые столбцы - результаты вычислений.
|
2011-08-28 02:22:23 +00:00
|
|
|
|
* part_id - какую часть выражения вычислять.
|
2012-07-21 03:45:48 +00:00
|
|
|
|
* Если указано only_consts - то вычисляются только выражения, зависящие от констант.
|
2012-10-25 20:20:46 +00:00
|
|
|
|
* Если указано clear_temporaries - удалить временные столбцы из блока, которые больше не понадобятся ни для каких вычислений.
|
2011-08-09 19:19:25 +00:00
|
|
|
|
*/
|
2012-07-21 03:45:48 +00:00
|
|
|
|
void execute(Block & block, unsigned part_id = 0, bool only_consts = false);
|
2011-08-28 02:22:23 +00:00
|
|
|
|
|
2012-10-25 20:20:46 +00:00
|
|
|
|
/** Убрать из блока столбцы, которые больше не нужны.
|
|
|
|
|
*/
|
|
|
|
|
void clearTemporaries(Block & block);
|
|
|
|
|
|
2011-08-28 02:22:23 +00:00
|
|
|
|
/** Взять из блока с промежуточными результатами вычислений только столбцы, представляющие собой конечный результат.
|
2011-11-06 04:21:09 +00:00
|
|
|
|
* Переименовать их в алиасы, если они заданы и если параметр without_duplicates_and_aliases = false.
|
2011-08-28 02:22:23 +00:00
|
|
|
|
* Вернуть новый блок, в котором эти столбцы расположены в правильном порядке.
|
|
|
|
|
*/
|
2011-11-06 04:21:09 +00:00
|
|
|
|
Block projectResult(Block & block, bool without_duplicates_and_aliases = false, unsigned part_id = 0, ASTPtr subtree = NULL);
|
2011-08-09 19:19:25 +00:00
|
|
|
|
|
2011-08-14 00:49:30 +00:00
|
|
|
|
/** Получить список типов столбцов результата.
|
|
|
|
|
*/
|
|
|
|
|
DataTypes getReturnTypes();
|
|
|
|
|
|
2011-10-30 05:19:41 +00:00
|
|
|
|
/** Получить блок-образец, содержащий имена и типы столбцов результата.
|
|
|
|
|
*/
|
|
|
|
|
Block getSampleBlock();
|
|
|
|
|
|
2011-09-24 20:32:41 +00:00
|
|
|
|
/** Получить список ключей агрегирования и описаний агрегатных функций, если в запросе есть GROUP BY.
|
|
|
|
|
*/
|
|
|
|
|
void getAggregateInfo(Names & key_names, AggregateDescriptions & aggregates);
|
|
|
|
|
|
2011-09-25 03:37:09 +00:00
|
|
|
|
/** Есть ли в выражении агрегатные функции.
|
|
|
|
|
*/
|
|
|
|
|
bool hasAggregates();
|
|
|
|
|
|
|
|
|
|
/** Пометить то, что должно быть вычислено до агрегирования одним part_id,
|
|
|
|
|
* а то, что должно быть вычислено после агрегирования, а также сами агрегатные функции - другим part_id.
|
|
|
|
|
*/
|
2012-08-27 05:13:14 +00:00
|
|
|
|
void markBeforeAggregation(unsigned before_part_id);
|
|
|
|
|
|
|
|
|
|
/** Получить информацию об операции arrayJoin, если она есть.
|
|
|
|
|
* Если есть - в column_name будет записано имя столбца, находящегося внутри arrayJoin.
|
|
|
|
|
*/
|
|
|
|
|
bool getArrayJoinInfo(String & column_name);
|
|
|
|
|
|
|
|
|
|
/** Пометить то, что должно быть вычислено до применения операции arrayJoin.
|
|
|
|
|
*/
|
|
|
|
|
void markBeforeArrayJoin(unsigned part_id);
|
2011-09-25 03:37:09 +00:00
|
|
|
|
|
2011-08-09 19:19:25 +00:00
|
|
|
|
private:
|
2011-08-12 18:27:39 +00:00
|
|
|
|
ASTPtr ast;
|
2012-12-27 17:40:54 +00:00
|
|
|
|
const Context context;
|
2011-08-09 19:19:25 +00:00
|
|
|
|
|
2011-08-28 05:13:24 +00:00
|
|
|
|
typedef std::set<String> NamesSet;
|
|
|
|
|
NamesSet required_columns;
|
2011-11-03 20:30:12 +00:00
|
|
|
|
|
2011-11-06 04:21:09 +00:00
|
|
|
|
typedef std::map<String, ASTPtr> Aliases;
|
|
|
|
|
Aliases aliases;
|
2013-02-06 14:20:18 +00:00
|
|
|
|
|
|
|
|
|
typedef std::set<ASTPtr> SetOfASTs;
|
|
|
|
|
typedef std::map<ASTPtr, ASTPtr> MapOfASTs;
|
2011-11-06 04:21:09 +00:00
|
|
|
|
|
2011-11-03 20:30:12 +00:00
|
|
|
|
|
|
|
|
|
NamesAndTypesList::const_iterator findColumn(const String & name);
|
2011-11-06 04:21:09 +00:00
|
|
|
|
|
|
|
|
|
/** Создать словарь алиасов.
|
|
|
|
|
*/
|
|
|
|
|
void createAliasesDict(ASTPtr & ast);
|
|
|
|
|
|
2011-08-28 08:50:27 +00:00
|
|
|
|
/** Для узлов - звёздочек - раскрыть их в список всех столбцов.
|
2013-02-06 14:20:18 +00:00
|
|
|
|
* Для узлов - литералов - прописать их типы данных и подставить алиасы.
|
2011-09-25 05:07:47 +00:00
|
|
|
|
* Для узлов - функций - прописать ссылки на функции, заменить имена на канонические, прописать и проверить типы.
|
2011-08-09 19:19:25 +00:00
|
|
|
|
* Для узлов - идентификаторов - прописать ссылки на их типы.
|
2011-09-25 05:07:47 +00:00
|
|
|
|
* Проверить, что все функции применимы для типов их аргументов.
|
2011-08-09 19:19:25 +00:00
|
|
|
|
*/
|
2011-08-28 08:50:27 +00:00
|
|
|
|
void addSemantic(ASTPtr & ast);
|
2013-02-06 14:20:18 +00:00
|
|
|
|
void addSemanticImpl(ASTPtr & ast, MapOfASTs & finished_asts, SetOfASTs & current_asts);
|
2011-08-09 19:19:25 +00:00
|
|
|
|
|
|
|
|
|
/** Склеить одинаковые узлы в синтаксическом дереве (превращая его в направленный ациклический граф).
|
|
|
|
|
* Это означает, в том числе то, что функции с одними и теми же аргументами, будут выполняться только один раз.
|
|
|
|
|
* Например, выражение rand(), rand() вернёт два идентичных столбца.
|
|
|
|
|
* Поэтому, все функции, в которых такое поведение нежелательно, должны содержать дополнительный параметр "тег".
|
|
|
|
|
*/
|
2011-08-12 18:27:39 +00:00
|
|
|
|
void glueTree(ASTPtr ast);
|
|
|
|
|
|
|
|
|
|
typedef std::map<String, ASTPtr> Subtrees;
|
|
|
|
|
|
|
|
|
|
void glueTreeImpl(ASTPtr ast, Subtrees & Subtrees);
|
|
|
|
|
|
2012-07-21 03:45:48 +00:00
|
|
|
|
void executeImpl(ASTPtr ast, Block & block, unsigned part_id, bool only_consts);
|
2011-08-13 23:03:07 +00:00
|
|
|
|
|
2011-09-04 05:14:52 +00:00
|
|
|
|
void collectFinalColumns(ASTPtr ast, Block & src, Block & dst, bool without_duplicates, unsigned part_id);
|
2011-08-14 00:49:30 +00:00
|
|
|
|
|
|
|
|
|
void getReturnTypesImpl(ASTPtr ast, DataTypes & res);
|
2011-09-24 20:32:41 +00:00
|
|
|
|
|
2011-10-30 05:19:41 +00:00
|
|
|
|
void getSampleBlockImpl(ASTPtr ast, Block & res);
|
|
|
|
|
|
2011-09-25 03:37:09 +00:00
|
|
|
|
void getAggregateInfoImpl(ASTPtr ast, Names & key_names, AggregateDescriptions & aggregates, NamesSet & processed);
|
|
|
|
|
|
|
|
|
|
bool hasAggregatesImpl(ASTPtr ast);
|
|
|
|
|
|
2012-08-27 05:13:14 +00:00
|
|
|
|
void markBeforeAggregationImpl(ASTPtr ast, unsigned before_part_id, bool below = false);
|
2012-08-22 20:29:01 +00:00
|
|
|
|
|
2012-12-26 20:29:28 +00:00
|
|
|
|
void makeSetsImpl(ASTPtr ast, size_t subquery_depth);
|
2012-08-24 19:42:03 +00:00
|
|
|
|
|
2012-12-26 20:29:28 +00:00
|
|
|
|
void resolveScalarSubqueriesImpl(ASTPtr & ast, size_t subquery_depth);
|
2012-08-24 20:40:34 +00:00
|
|
|
|
|
2012-08-27 05:13:14 +00:00
|
|
|
|
bool getArrayJoinInfoImpl(ASTPtr ast, String & column_name);
|
|
|
|
|
|
|
|
|
|
void markBeforeArrayJoinImpl(ASTPtr ast, unsigned part_id, bool below = false);
|
|
|
|
|
|
2012-10-25 20:20:46 +00:00
|
|
|
|
typedef std::set<std::string> NeedColumns;
|
|
|
|
|
|
|
|
|
|
void clearTemporariesImpl(ASTPtr ast, Block & block);
|
|
|
|
|
|
|
|
|
|
void collectNeedColumns(ASTPtr ast, Block & block, NeedColumns & need_columns, bool top_level = true, bool all_children_need = false);
|
|
|
|
|
|
2012-08-24 19:42:03 +00:00
|
|
|
|
/// Получить тип у функции, идентификатора или литерала.
|
|
|
|
|
DataTypePtr getType(ASTPtr ast);
|
2011-08-09 19:19:25 +00:00
|
|
|
|
};
|
|
|
|
|
|
2012-05-09 13:12:38 +00:00
|
|
|
|
typedef SharedPtr<Expression> ExpressionPtr;
|
|
|
|
|
|
2011-08-09 19:19:25 +00:00
|
|
|
|
|
|
|
|
|
}
|