未验证 提交 2afd123e 编写于 作者: A Artem Zuikov 提交者: GitHub

Refactoring: extract TreeOptimizer from SyntaxAnalyzer (#12645)

上级 a663bc76
...@@ -118,7 +118,7 @@ std::ostream & operator<<(std::ostream & stream, const ExpressionActions & what) ...@@ -118,7 +118,7 @@ std::ostream & operator<<(std::ostream & stream, const ExpressionActions & what)
return stream; return stream;
} }
std::ostream & operator<<(std::ostream & stream, const SyntaxAnalyzerResult & what) std::ostream & operator<<(std::ostream & stream, const TreeRewriterResult & what)
{ {
stream << "SyntaxAnalyzerResult{"; stream << "SyntaxAnalyzerResult{";
stream << "storage=" << what.storage << "; "; stream << "storage=" << what.storage << "; ";
......
...@@ -46,8 +46,8 @@ std::ostream & operator<<(std::ostream & stream, const ExpressionAction & what); ...@@ -46,8 +46,8 @@ std::ostream & operator<<(std::ostream & stream, const ExpressionAction & what);
class ExpressionActions; class ExpressionActions;
std::ostream & operator<<(std::ostream & stream, const ExpressionActions & what); std::ostream & operator<<(std::ostream & stream, const ExpressionActions & what);
struct SyntaxAnalyzerResult; struct TreeRewriterResult;
std::ostream & operator<<(std::ostream & stream, const SyntaxAnalyzerResult & what); std::ostream & operator<<(std::ostream & stream, const TreeRewriterResult & what);
} }
/// some operator<< should be declared before operator<<(... std::shared_ptr<>) /// some operator<< should be declared before operator<<(... std::shared_ptr<>)
......
#include <DataStreams/TTLBlockInputStream.h> #include <DataStreams/TTLBlockInputStream.h>
#include <DataTypes/DataTypeDate.h> #include <DataTypes/DataTypeDate.h>
#include <Interpreters/inplaceBlockConversions.h> #include <Interpreters/inplaceBlockConversions.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Interpreters/ExpressionAnalyzer.h> #include <Interpreters/ExpressionAnalyzer.h>
#include <Columns/ColumnConst.h> #include <Columns/ColumnConst.h>
#include <Interpreters/addTypeConversionToAST.h> #include <Interpreters/addTypeConversionToAST.h>
...@@ -67,7 +67,7 @@ TTLBlockInputStream::TTLBlockInputStream( ...@@ -67,7 +67,7 @@ TTLBlockInputStream::TTLBlockInputStream(
if (!default_expr_list->children.empty()) if (!default_expr_list->children.empty())
{ {
auto syntax_result = SyntaxAnalyzer(storage.global_context).analyze(default_expr_list, metadata_snapshot->getColumns().getAllPhysical()); auto syntax_result = TreeRewriter(storage.global_context).analyze(default_expr_list, metadata_snapshot->getColumns().getAllPhysical());
defaults_expression = ExpressionAnalyzer{default_expr_list, syntax_result, storage.global_context}.getActions(true); defaults_expression = ExpressionAnalyzer{default_expr_list, syntax_result, storage.global_context}.getActions(true);
} }
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
namespace DB namespace DB
{ {
class ASTFunction;
/// Extract constant arguments out of aggregate functions from child functions /// Extract constant arguments out of aggregate functions from child functions
/// 'sum(a * 2)' -> 'sum(a) * 2' /// 'sum(a * 2)' -> 'sum(a) * 2'
/// Rewrites: sum([multiply|divide]) -> [multiply|divide](sum) /// Rewrites: sum([multiply|divide]) -> [multiply|divide](sum)
......
...@@ -130,7 +130,7 @@ bool sanitizeBlock(Block & block, bool throw_if_cannot_create_column) ...@@ -130,7 +130,7 @@ bool sanitizeBlock(Block & block, bool throw_if_cannot_create_column)
ExpressionAnalyzer::ExpressionAnalyzer( ExpressionAnalyzer::ExpressionAnalyzer(
const ASTPtr & query_, const ASTPtr & query_,
const SyntaxAnalyzerResultPtr & syntax_analyzer_result_, const TreeRewriterResultPtr & syntax_analyzer_result_,
const Context & context_, const Context & context_,
size_t subquery_depth_, size_t subquery_depth_,
bool do_global) bool do_global)
...@@ -523,7 +523,7 @@ static JoinPtr tryGetStorageJoin(std::shared_ptr<TableJoin> analyzed_join) ...@@ -523,7 +523,7 @@ static JoinPtr tryGetStorageJoin(std::shared_ptr<TableJoin> analyzed_join)
static ExpressionActionsPtr createJoinedBlockActions(const Context & context, const TableJoin & analyzed_join) static ExpressionActionsPtr createJoinedBlockActions(const Context & context, const TableJoin & analyzed_join)
{ {
ASTPtr expression_list = analyzed_join.rightKeysList(); ASTPtr expression_list = analyzed_join.rightKeysList();
auto syntax_result = SyntaxAnalyzer(context).analyze(expression_list, analyzed_join.columnsFromJoinedTable()); auto syntax_result = TreeRewriter(context).analyze(expression_list, analyzed_join.columnsFromJoinedTable());
return ExpressionAnalyzer(expression_list, syntax_result, context).getActions(true, false); return ExpressionAnalyzer(expression_list, syntax_result, context).getActions(true, false);
} }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include <DataStreams/IBlockStream_fwd.h> #include <DataStreams/IBlockStream_fwd.h>
#include <Columns/FilterDescription.h> #include <Columns/FilterDescription.h>
#include <Interpreters/AggregateDescription.h> #include <Interpreters/AggregateDescription.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Interpreters/SubqueryForSet.h> #include <Interpreters/SubqueryForSet.h>
#include <Parsers/IAST_fwd.h> #include <Parsers/IAST_fwd.h>
#include <Storages/IStorage_fwd.h> #include <Storages/IStorage_fwd.h>
...@@ -82,7 +82,7 @@ public: ...@@ -82,7 +82,7 @@ public:
/// auto actions = ExpressionAnalyzer(query, syntax, context).getActions(); /// auto actions = ExpressionAnalyzer(query, syntax, context).getActions();
ExpressionAnalyzer( ExpressionAnalyzer(
const ASTPtr & query_, const ASTPtr & query_,
const SyntaxAnalyzerResultPtr & syntax_analyzer_result_, const TreeRewriterResultPtr & syntax_analyzer_result_,
const Context & context_) const Context & context_)
: ExpressionAnalyzer(query_, syntax_analyzer_result_, context_, 0, false) : ExpressionAnalyzer(query_, syntax_analyzer_result_, context_, 0, false)
{} {}
...@@ -112,7 +112,7 @@ public: ...@@ -112,7 +112,7 @@ public:
protected: protected:
ExpressionAnalyzer( ExpressionAnalyzer(
const ASTPtr & query_, const ASTPtr & query_,
const SyntaxAnalyzerResultPtr & syntax_analyzer_result_, const TreeRewriterResultPtr & syntax_analyzer_result_,
const Context & context_, const Context & context_,
size_t subquery_depth_, size_t subquery_depth_,
bool do_global_); bool do_global_);
...@@ -122,7 +122,7 @@ protected: ...@@ -122,7 +122,7 @@ protected:
const ExtractedSettings settings; const ExtractedSettings settings;
size_t subquery_depth; size_t subquery_depth;
SyntaxAnalyzerResultPtr syntax; TreeRewriterResultPtr syntax;
const ConstStoragePtr & storage() const { return syntax->storage; } /// The main table in FROM clause, if exists. const ConstStoragePtr & storage() const { return syntax->storage; } /// The main table in FROM clause, if exists.
const TableJoin & analyzedJoin() const { return *syntax->analyzed_join; } const TableJoin & analyzedJoin() const { return *syntax->analyzed_join; }
...@@ -231,7 +231,7 @@ public: ...@@ -231,7 +231,7 @@ public:
SelectQueryExpressionAnalyzer( SelectQueryExpressionAnalyzer(
const ASTPtr & query_, const ASTPtr & query_,
const SyntaxAnalyzerResultPtr & syntax_analyzer_result_, const TreeRewriterResultPtr & syntax_analyzer_result_,
const Context & context_, const Context & context_,
const StorageMetadataPtr & metadata_snapshot_, const StorageMetadataPtr & metadata_snapshot_,
const NameSet & required_result_columns_ = {}, const NameSet & required_result_columns_ = {},
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <Parsers/ASTSelectQuery.h> #include <Parsers/ASTSelectQuery.h>
#include <Parsers/ASTSetQuery.h> #include <Parsers/ASTSetQuery.h>
#include <Parsers/ASTTablesInSelectQuery.h> #include <Parsers/ASTTablesInSelectQuery.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/IAST.h> #include <Parsers/IAST.h>
#include <Common/typeid_cast.h> #include <Common/typeid_cast.h>
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <Interpreters/Context.h> #include <Interpreters/Context.h>
#include <Interpreters/DDLWorker.h> #include <Interpreters/DDLWorker.h>
#include <Interpreters/ExpressionAnalyzer.h> #include <Interpreters/ExpressionAnalyzer.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Interpreters/InterpreterCreateQuery.h> #include <Interpreters/InterpreterCreateQuery.h>
#include <Interpreters/InterpreterSelectWithUnionQuery.h> #include <Interpreters/InterpreterSelectWithUnionQuery.h>
#include <Interpreters/InterpreterInsertQuery.h> #include <Interpreters/InterpreterInsertQuery.h>
......
...@@ -131,7 +131,7 @@ String InterpreterSelectQuery::generateFilterActions( ...@@ -131,7 +131,7 @@ String InterpreterSelectQuery::generateFilterActions(
table_expr->children.push_back(table_expr->database_and_table_name); table_expr->children.push_back(table_expr->database_and_table_name);
/// Using separate expression analyzer to prevent any possible alias injection /// Using separate expression analyzer to prevent any possible alias injection
auto syntax_result = SyntaxAnalyzer(*context).analyzeSelect(query_ast, SyntaxAnalyzerResult({}, storage, metadata_snapshot)); auto syntax_result = TreeRewriter(*context).analyzeSelect(query_ast, TreeRewriterResult({}, storage, metadata_snapshot));
SelectQueryExpressionAnalyzer analyzer(query_ast, syntax_result, *context, metadata_snapshot); SelectQueryExpressionAnalyzer analyzer(query_ast, syntax_result, *context, metadata_snapshot);
actions = analyzer.simpleSelectActions(); actions = analyzer.simpleSelectActions();
...@@ -311,9 +311,9 @@ InterpreterSelectQuery::InterpreterSelectQuery( ...@@ -311,9 +311,9 @@ InterpreterSelectQuery::InterpreterSelectQuery(
if (view) if (view)
view->replaceWithSubquery(getSelectQuery(), view_table, metadata_snapshot); view->replaceWithSubquery(getSelectQuery(), view_table, metadata_snapshot);
syntax_analyzer_result = SyntaxAnalyzer(*context).analyzeSelect( syntax_analyzer_result = TreeRewriter(*context).analyzeSelect(
query_ptr, query_ptr,
SyntaxAnalyzerResult(source_header.getNamesAndTypesList(), storage, metadata_snapshot), TreeRewriterResult(source_header.getNamesAndTypesList(), storage, metadata_snapshot),
options, joined_tables.tablesWithColumns(), required_result_column_names, table_join); options, joined_tables.tablesWithColumns(), required_result_column_names, table_join);
/// Save scalar sub queries's results in the query context /// Save scalar sub queries's results in the query context
...@@ -1194,7 +1194,7 @@ void InterpreterSelectQuery::executeFetchColumns( ...@@ -1194,7 +1194,7 @@ void InterpreterSelectQuery::executeFetchColumns(
= ext::map<NameSet>(required_columns_after_prewhere, [](const auto & it) { return it.name; }); = ext::map<NameSet>(required_columns_after_prewhere, [](const auto & it) { return it.name; });
} }
auto syntax_result = SyntaxAnalyzer(*context).analyze(required_columns_all_expr, required_columns_after_prewhere, storage, metadata_snapshot); auto syntax_result = TreeRewriter(*context).analyze(required_columns_all_expr, required_columns_after_prewhere, storage, metadata_snapshot);
alias_actions = ExpressionAnalyzer(required_columns_all_expr, syntax_result, *context).getActions(true); alias_actions = ExpressionAnalyzer(required_columns_all_expr, syntax_result, *context).getActions(true);
/// The set of required columns could be added as a result of adding an action to calculate ALIAS. /// The set of required columns could be added as a result of adding an action to calculate ALIAS.
...@@ -1225,7 +1225,7 @@ void InterpreterSelectQuery::executeFetchColumns( ...@@ -1225,7 +1225,7 @@ void InterpreterSelectQuery::executeFetchColumns(
prewhere_info->prewhere_actions = std::move(new_actions); prewhere_info->prewhere_actions = std::move(new_actions);
auto analyzed_result auto analyzed_result
= SyntaxAnalyzer(*context).analyze(required_columns_from_prewhere_expr, metadata_snapshot->getColumns().getAllPhysical()); = TreeRewriter(*context).analyze(required_columns_from_prewhere_expr, metadata_snapshot->getColumns().getAllPhysical());
prewhere_info->alias_actions prewhere_info->alias_actions
= ExpressionAnalyzer(required_columns_from_prewhere_expr, analyzed_result, *context).getActions(true, false); = ExpressionAnalyzer(required_columns_from_prewhere_expr, analyzed_result, *context).getActions(true, false);
......
...@@ -26,8 +26,8 @@ class InterpreterSelectWithUnionQuery; ...@@ -26,8 +26,8 @@ class InterpreterSelectWithUnionQuery;
class Context; class Context;
class QueryPlan; class QueryPlan;
struct SyntaxAnalyzerResult; struct TreeRewriterResult;
using SyntaxAnalyzerResultPtr = std::shared_ptr<const SyntaxAnalyzerResult>; using TreeRewriterResultPtr = std::shared_ptr<const TreeRewriterResult>;
/** Interprets the SELECT query. Returns the stream of blocks with the results of the query before `to_stage` stage. /** Interprets the SELECT query. Returns the stream of blocks with the results of the query before `to_stage` stage.
...@@ -161,7 +161,7 @@ private: ...@@ -161,7 +161,7 @@ private:
SelectQueryOptions options; SelectQueryOptions options;
ASTPtr query_ptr; ASTPtr query_ptr;
std::shared_ptr<Context> context; std::shared_ptr<Context> context;
SyntaxAnalyzerResultPtr syntax_analyzer_result; TreeRewriterResultPtr syntax_analyzer_result;
std::unique_ptr<SelectQueryExpressionAnalyzer> query_analyzer; std::unique_ptr<SelectQueryExpressionAnalyzer> query_analyzer;
SelectQueryInfo query_info; SelectQueryInfo query_info;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include <Interpreters/InDepthNodeVisitor.h> #include <Interpreters/InDepthNodeVisitor.h>
#include <Interpreters/InterpreterSelectQuery.h> #include <Interpreters/InterpreterSelectQuery.h>
#include <Interpreters/MutationsInterpreter.h> #include <Interpreters/MutationsInterpreter.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Storages/MergeTree/MergeTreeData.h> #include <Storages/MergeTree/MergeTreeData.h>
#include <DataStreams/FilterBlockInputStream.h> #include <DataStreams/FilterBlockInputStream.h>
#include <DataStreams/ExpressionBlockInputStream.h> #include <DataStreams/ExpressionBlockInputStream.h>
...@@ -321,7 +321,7 @@ ASTPtr MutationsInterpreter::prepare(bool dry_run) ...@@ -321,7 +321,7 @@ ASTPtr MutationsInterpreter::prepare(bool dry_run)
if (column.default_desc.kind == ColumnDefaultKind::Materialized) if (column.default_desc.kind == ColumnDefaultKind::Materialized)
{ {
auto query = column.default_desc.expression->clone(); auto query = column.default_desc.expression->clone();
auto syntax_result = SyntaxAnalyzer(context).analyze(query, all_columns); auto syntax_result = TreeRewriter(context).analyze(query, all_columns);
for (const String & dependency : syntax_result->requiredSourceColumns()) for (const String & dependency : syntax_result->requiredSourceColumns())
{ {
if (updated_columns.count(dependency)) if (updated_columns.count(dependency))
...@@ -418,7 +418,7 @@ ASTPtr MutationsInterpreter::prepare(bool dry_run) ...@@ -418,7 +418,7 @@ ASTPtr MutationsInterpreter::prepare(bool dry_run)
throw Exception("Unknown index: " + command.index_name, ErrorCodes::BAD_ARGUMENTS); throw Exception("Unknown index: " + command.index_name, ErrorCodes::BAD_ARGUMENTS);
auto query = (*it).expression_list_ast->clone(); auto query = (*it).expression_list_ast->clone();
auto syntax_result = SyntaxAnalyzer(context).analyze(query, all_columns); auto syntax_result = TreeRewriter(context).analyze(query, all_columns);
const auto required_columns = syntax_result->requiredSourceColumns(); const auto required_columns = syntax_result->requiredSourceColumns();
for (const auto & column : required_columns) for (const auto & column : required_columns)
dependencies.emplace(column, ColumnDependency::SKIP_INDEX); dependencies.emplace(column, ColumnDependency::SKIP_INDEX);
...@@ -584,7 +584,7 @@ ASTPtr MutationsInterpreter::prepareInterpreterSelectQuery(std::vector<Stage> & ...@@ -584,7 +584,7 @@ ASTPtr MutationsInterpreter::prepareInterpreterSelectQuery(std::vector<Stage> &
for (const String & column : stage.output_columns) for (const String & column : stage.output_columns)
all_asts->children.push_back(std::make_shared<ASTIdentifier>(column)); all_asts->children.push_back(std::make_shared<ASTIdentifier>(column));
auto syntax_result = SyntaxAnalyzer(context).analyze(all_asts, all_columns); auto syntax_result = TreeRewriter(context).analyze(all_asts, all_columns);
if (context.hasQueryContext()) if (context.hasQueryContext())
for (const auto & it : syntax_result->getScalars()) for (const auto & it : syntax_result->getScalars())
context.getQueryContext().addScalar(it.first, it.second); context.getQueryContext().addScalar(it.first, it.second);
......
...@@ -41,7 +41,7 @@ class TableJoin ...@@ -41,7 +41,7 @@ class TableJoin
* It's possible to use name `expr(t2 columns)`. * It's possible to use name `expr(t2 columns)`.
*/ */
friend class SyntaxAnalyzer; friend class TreeRewriter;
const SizeLimits size_limits; const SizeLimits size_limits;
const size_t default_max_bytes = 0; const size_t default_max_bytes = 0;
......
#include <Core/Settings.h>
#include <Interpreters/TreeOptimizer.h>
#include <Interpreters/OptimizeIfChains.h>
#include <Interpreters/OptimizeIfWithConstantConditionVisitor.h>
#include <Interpreters/ArithmeticOperationsInAgrFuncOptimize.h>
#include <Interpreters/DuplicateDistinctVisitor.h>
#include <Interpreters/DuplicateOrderByVisitor.h>
#include <Interpreters/GroupByFunctionKeysVisitor.h>
#include <Interpreters/AggregateFunctionOfGroupByKeysVisitor.h>
#include <Interpreters/AnyInputOptimize.h>
#include <Interpreters/RemoveInjectiveFunctionsVisitor.h>
#include <Interpreters/RedundantFunctionsInOrderByVisitor.h>
#include <Interpreters/MonotonicityCheckVisitor.h>
#include <Interpreters/ConvertStringsToEnumVisitor.h>
#include <Interpreters/PredicateExpressionsOptimizer.h>
#include <Interpreters/Context.h>
#include <Interpreters/ExternalDictionariesLoader.h>
#include <Parsers/ASTExpressionList.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTLiteral.h>
#include <Parsers/ASTOrderByElement.h>
#include <Parsers/ASTSelectQuery.h>
#include <Parsers/ASTTablesInSelectQuery.h>
#include <Functions/FunctionFactory.h>
namespace DB
{
namespace ErrorCodes
{
extern const int LOGICAL_ERROR;
}
namespace
{
const std::unordered_set<String> possibly_injective_function_names
{
"dictGet",
"dictGetString",
"dictGetUInt8",
"dictGetUInt16",
"dictGetUInt32",
"dictGetUInt64",
"dictGetInt8",
"dictGetInt16",
"dictGetInt32",
"dictGetInt64",
"dictGetFloat32",
"dictGetFloat64",
"dictGetDate",
"dictGetDateTime"
};
/** You can not completely remove GROUP BY. Because if there were no aggregate functions, then it turns out that there will be no aggregation.
* Instead, leave `GROUP BY const`.
* Next, see deleting the constants in the analyzeAggregation method.
*/
void appendUnusedGroupByColumn(ASTSelectQuery * select_query, const NameSet & source_columns)
{
/// You must insert a constant that is not the name of the column in the table. Such a case is rare, but it happens.
UInt64 unused_column = 0;
String unused_column_name = toString(unused_column);
while (source_columns.count(unused_column_name))
{
++unused_column;
unused_column_name = toString(unused_column);
}
select_query->setExpression(ASTSelectQuery::Expression::GROUP_BY, std::make_shared<ASTExpressionList>());
select_query->groupBy()->children.emplace_back(std::make_shared<ASTLiteral>(UInt64(unused_column)));
}
/// Eliminates injective function calls and constant expressions from group by statement.
void optimizeGroupBy(ASTSelectQuery * select_query, const NameSet & source_columns, const Context & context)
{
const FunctionFactory & function_factory = FunctionFactory::instance();
if (!select_query->groupBy())
{
// If there is a HAVING clause without GROUP BY, make sure we have some aggregation happen.
if (select_query->having())
appendUnusedGroupByColumn(select_query, source_columns);
return;
}
const auto is_literal = [] (const ASTPtr & ast) -> bool
{
return ast->as<ASTLiteral>();
};
auto & group_exprs = select_query->groupBy()->children;
/// removes expression at index idx by making it last one and calling .pop_back()
const auto remove_expr_at_index = [&group_exprs] (const size_t idx)
{
if (idx < group_exprs.size() - 1)
std::swap(group_exprs[idx], group_exprs.back());
group_exprs.pop_back();
};
/// iterate over each GROUP BY expression, eliminate injective function calls and literals
for (size_t i = 0; i < group_exprs.size();)
{
if (const auto * function = group_exprs[i]->as<ASTFunction>())
{
/// assert function is injective
if (possibly_injective_function_names.count(function->name))
{
/// do not handle semantic errors here
if (function->arguments->children.size() < 2)
{
++i;
continue;
}
const auto * dict_name_ast = function->arguments->children[0]->as<ASTLiteral>();
const auto * attr_name_ast = function->arguments->children[1]->as<ASTLiteral>();
if (!dict_name_ast || !attr_name_ast)
{
++i;
continue;
}
const auto & dict_name = dict_name_ast->value.safeGet<String>();
const auto & attr_name = attr_name_ast->value.safeGet<String>();
const auto & dict_ptr = context.getExternalDictionariesLoader().getDictionary(dict_name);
if (!dict_ptr->isInjective(attr_name))
{
++i;
continue;
}
}
else if (!function_factory.get(function->name, context)->isInjective(Block{}))
{
++i;
continue;
}
/// copy shared pointer to args in order to ensure lifetime
auto args_ast = function->arguments;
/** remove function call and take a step back to ensure
* next iteration does not skip not yet processed data
*/
remove_expr_at_index(i);
/// copy non-literal arguments
std::remove_copy_if(
std::begin(args_ast->children), std::end(args_ast->children),
std::back_inserter(group_exprs), is_literal
);
}
else if (is_literal(group_exprs[i]))
{
remove_expr_at_index(i);
}
else
{
/// if neither a function nor literal - advance to next expression
++i;
}
}
if (group_exprs.empty())
appendUnusedGroupByColumn(select_query, source_columns);
}
struct GroupByKeysInfo
{
std::unordered_set<String> key_names; ///set of keys' short names
bool has_identifier = false;
bool has_function = false;
bool has_possible_collision = false;
};
GroupByKeysInfo getGroupByKeysInfo(ASTs & group_keys)
{
GroupByKeysInfo data;
///filling set with short names of keys
for (auto & group_key : group_keys)
{
if (group_key->as<ASTFunction>())
data.has_function = true;
if (auto * group_key_ident = group_key->as<ASTIdentifier>())
{
data.has_identifier = true;
if (data.key_names.count(group_key_ident->shortName()))
{
///There may be a collision between different tables having similar variables.
///Due to the fact that we can't track these conflicts yet,
///it's better to disable some optimizations to avoid elimination necessary keys.
data.has_possible_collision = true;
}
data.key_names.insert(group_key_ident->shortName());
}
else if (auto * group_key_func = group_key->as<ASTFunction>())
{
data.key_names.insert(group_key_func->getColumnName());
}
else
{
data.key_names.insert(group_key->getColumnName());
}
}
return data;
}
///eliminate functions of other GROUP BY keys
void optimizeGroupByFunctionKeys(ASTSelectQuery * select_query)
{
if (!select_query->groupBy())
return;
auto grp_by = select_query->groupBy();
auto & group_keys = grp_by->children;
ASTs modified; ///result
GroupByKeysInfo group_by_keys_data = getGroupByKeysInfo(group_keys);
if (!group_by_keys_data.has_function || group_by_keys_data.has_possible_collision)
return;
GroupByFunctionKeysVisitor::Data visitor_data{group_by_keys_data.key_names};
GroupByFunctionKeysVisitor(visitor_data).visit(grp_by);
modified.reserve(group_keys.size());
///filling the result
for (auto & group_key : group_keys)
{
if (auto * group_key_func = group_key->as<ASTFunction>())
{
if (group_by_keys_data.key_names.count(group_key_func->getColumnName()))
modified.push_back(group_key);
continue;
}
if (auto * group_key_ident = group_key->as<ASTIdentifier>())
{
if (group_by_keys_data.key_names.count(group_key_ident->shortName()))
modified.push_back(group_key);
continue;
}
else
{
if (group_by_keys_data.key_names.count(group_key->getColumnName()))
modified.push_back(group_key);
}
}
///modifying the input
grp_by->children = modified;
}
/// Eliminates min/max/any-aggregators of functions of GROUP BY keys
void optimizeAggregateFunctionsOfGroupByKeys(ASTSelectQuery * select_query)
{
if (!select_query->groupBy())
return;
auto grp_by = select_query->groupBy();
auto & group_keys = grp_by->children;
GroupByKeysInfo group_by_keys_data = getGroupByKeysInfo(group_keys);
auto select = select_query->select();
SelectAggregateFunctionOfGroupByKeysVisitor::Data visitor_data{group_by_keys_data.key_names};
SelectAggregateFunctionOfGroupByKeysVisitor(visitor_data).visit(select);
}
/// Remove duplicate items from ORDER BY.
void optimizeDuplicatesInOrderBy(const ASTSelectQuery * select_query)
{
if (!select_query->orderBy())
return;
/// Make unique sorting conditions.
using NameAndLocale = std::pair<String, String>;
std::set<NameAndLocale> elems_set;
ASTs & elems = select_query->orderBy()->children;
ASTs unique_elems;
unique_elems.reserve(elems.size());
for (const auto & elem : elems)
{
String name = elem->children.front()->getColumnName();
const auto & order_by_elem = elem->as<ASTOrderByElement &>();
if (elems_set.emplace(name, order_by_elem.collation ? order_by_elem.collation->getColumnName() : "").second)
unique_elems.emplace_back(elem);
}
if (unique_elems.size() < elems.size())
elems = std::move(unique_elems);
}
/// Optimize duplicate ORDER BY and DISTINCT
void optimizeDuplicateOrderByAndDistinct(ASTPtr & query, const Context & context)
{
DuplicateOrderByVisitor::Data order_by_data{context};
DuplicateOrderByVisitor(order_by_data).visit(query);
DuplicateDistinctVisitor::Data distinct_data{};
DuplicateDistinctVisitor(distinct_data).visit(query);
}
/// Replace monotonous functions in ORDER BY if they don't participate in GROUP BY expression,
/// has a single argument and not an aggregate functions.
void optimizeMonotonousFunctionsInOrderBy(ASTSelectQuery * select_query, const Context & context,
const TablesWithColumns & tables_with_columns)
{
auto order_by = select_query->orderBy();
if (!order_by)
return;
std::unordered_set<String> group_by_hashes;
if (auto group_by = select_query->groupBy())
{
for (auto & elem : group_by->children)
{
auto hash = elem->getTreeHash();
String key = toString(hash.first) + '_' + toString(hash.second);
group_by_hashes.insert(key);
}
}
for (auto & child : order_by->children)
{
auto * order_by_element = child->as<ASTOrderByElement>();
auto & ast_func = order_by_element->children[0];
if (!ast_func->as<ASTFunction>())
continue;
MonotonicityCheckVisitor::Data data{tables_with_columns, context, group_by_hashes};
MonotonicityCheckVisitor(data).visit(ast_func);
if (!data.isRejected())
{
ast_func = data.identifier->clone();
ast_func->setAlias("");
if (!data.monotonicity.is_positive)
order_by_element->direction *= -1;
}
}
}
/// If ORDER BY has argument x followed by f(x) transfroms it to ORDER BY x.
/// Optimize ORDER BY x, y, f(x), g(x, y), f(h(x)), t(f(x), g(x)) into ORDER BY x, y
/// in case if f(), g(), h(), t() are deterministic (in scope of query).
/// Don't optimize ORDER BY f(x), g(x), x even if f(x) is bijection for x or g(x).
void optimizeRedundantFunctionsInOrderBy(const ASTSelectQuery * select_query, const Context & context)
{
const auto & order_by = select_query->orderBy();
if (!order_by)
return;
std::unordered_set<String> prev_keys;
ASTs modified;
modified.reserve(order_by->children.size());
for (auto & order_by_element : order_by->children)
{
/// Order by contains ASTOrderByElement as children and meaning item only as a grand child.
ASTPtr & name_or_function = order_by_element->children[0];
if (name_or_function->as<ASTFunction>())
{
if (!prev_keys.empty())
{
RedundantFunctionsInOrderByVisitor::Data data{prev_keys, context};
RedundantFunctionsInOrderByVisitor(data).visit(name_or_function);
if (data.redundant)
continue;
}
}
/// @note Leave duplicate keys unchanged. They would be removed in optimizeDuplicatesInOrderBy()
if (auto * identifier = name_or_function->as<ASTIdentifier>())
prev_keys.emplace(getIdentifierName(identifier));
modified.push_back(order_by_element);
}
if (modified.size() < order_by->children.size())
order_by->children = std::move(modified);
}
/// Remove duplicate items from LIMIT BY.
void optimizeLimitBy(const ASTSelectQuery * select_query)
{
if (!select_query->limitBy())
return;
std::set<String> elems_set;
ASTs & elems = select_query->limitBy()->children;
ASTs unique_elems;
unique_elems.reserve(elems.size());
for (const auto & elem : elems)
{
if (elems_set.emplace(elem->getColumnName()).second)
unique_elems.emplace_back(elem);
}
if (unique_elems.size() < elems.size())
elems = std::move(unique_elems);
}
/// Remove duplicated columns from USING(...).
void optimizeUsing(const ASTSelectQuery * select_query)
{
if (!select_query->join())
return;
const auto * table_join = select_query->join()->table_join->as<ASTTableJoin>();
if (!(table_join && table_join->using_expression_list))
return;
ASTs & expression_list = table_join->using_expression_list->children;
ASTs uniq_expressions_list;
std::set<String> expressions_names;
for (const auto & expression : expression_list)
{
auto expression_name = expression->getAliasOrColumnName();
if (expressions_names.find(expression_name) == expressions_names.end())
{
uniq_expressions_list.push_back(expression);
expressions_names.insert(expression_name);
}
}
if (uniq_expressions_list.size() < expression_list.size())
expression_list = uniq_expressions_list;
}
void optimizeAggregationFunctions(ASTPtr & query)
{
/// Move arithmetic operations out of aggregation functions
ArithmeticOperationsInAgrFuncVisitor::Data data;
ArithmeticOperationsInAgrFuncVisitor(data).visit(query);
}
void optimizeAnyInput(ASTPtr & query)
{
/// Removing arithmetic operations from functions
AnyInputVisitor::Data data = {};
AnyInputVisitor(data).visit(query);
}
void optimizeInjectiveFunctionsInsideUniq(ASTPtr & query, const Context & context)
{
RemoveInjectiveFunctionsVisitor::Data data = {context};
RemoveInjectiveFunctionsVisitor(data).visit(query);
}
void transformIfStringsIntoEnum(ASTPtr & query)
{
std::unordered_set<String> function_names = {"if", "transform"};
std::unordered_set<String> used_as_argument;
FindUsedFunctionsVisitor::Data used_data{function_names, used_as_argument};
FindUsedFunctionsVisitor(used_data).visit(query);
ConvertStringsToEnumVisitor::Data convert_data{used_as_argument};
ConvertStringsToEnumVisitor(convert_data).visit(query);
}
}
void TreeOptimizer::optimizeIf(ASTPtr & query, Aliases & aliases, bool if_chain_to_multiif)
{
/// Optimize if with constant condition after constants was substituted instead of scalar subqueries.
OptimizeIfWithConstantConditionVisitor(aliases).visit(query);
if (if_chain_to_multiif)
OptimizeIfChainsVisitor().visit(query);
}
void TreeOptimizer::apply(ASTPtr & query, Aliases & aliases, const NameSet & source_columns_set,
const std::vector<TableWithColumnNamesAndTypes> & tables_with_columns,
const Context & context, bool & rewrite_subqueries)
{
const auto & settings = context.getSettingsRef();
auto * select_query = query->as<ASTSelectQuery>();
if (!select_query)
throw Exception("Select analyze for not select asts.", ErrorCodes::LOGICAL_ERROR);
optimizeIf(query, aliases, settings.optimize_if_chain_to_multiif);
/// Move arithmetic operations out of aggregation functions
if (settings.optimize_arithmetic_operations_in_aggregate_functions)
optimizeAggregationFunctions(query);
/// Push the predicate expression down to the subqueries.
rewrite_subqueries = PredicateExpressionsOptimizer(context, tables_with_columns, settings).optimize(*select_query);
/// GROUP BY injective function elimination.
optimizeGroupBy(select_query, source_columns_set, context);
/// GROUP BY functions of other keys elimination.
if (settings.optimize_group_by_function_keys)
optimizeGroupByFunctionKeys(select_query);
///Move all operations out of any function
if (settings.optimize_move_functions_out_of_any)
optimizeAnyInput(query);
/// Remove injective functions inside uniq
if (settings.optimize_injective_functions_inside_uniq)
optimizeInjectiveFunctionsInsideUniq(query, context);
/// Eliminate min/max/any aggregators of functions of GROUP BY keys
if (settings.optimize_aggregators_of_group_by_keys)
optimizeAggregateFunctionsOfGroupByKeys(select_query);
/// Remove duplicate items from ORDER BY.
optimizeDuplicatesInOrderBy(select_query);
/// Remove duplicate ORDER BY and DISTINCT from subqueries.
if (settings.optimize_duplicate_order_by_and_distinct)
optimizeDuplicateOrderByAndDistinct(query, context);
/// Remove functions from ORDER BY if its argument is also in ORDER BY
if (settings.optimize_redundant_functions_in_order_by)
optimizeRedundantFunctionsInOrderBy(select_query, context);
/// Replace monotonous functions with its argument
if (settings.optimize_monotonous_functions_in_order_by)
optimizeMonotonousFunctionsInOrderBy(select_query, context, tables_with_columns);
/// If function "if" has String-type arguments, transform them into enum
if (settings.optimize_if_transform_strings_to_enum)
transformIfStringsIntoEnum(query);
/// Remove duplicated elements from LIMIT BY clause.
optimizeLimitBy(select_query);
/// Remove duplicated columns from USING(...).
optimizeUsing(select_query);
}
}
#pragma once
#include <Parsers/IAST_fwd.h>
#include <Interpreters/Aliases.h>
#include <Interpreters/DatabaseAndTableWithAlias.h>
namespace DB
{
class Context;
/// Part of of Tree Rewriter (SyntaxAnalyzer) that optimizes AST.
/// Query should be ready to execute either before either after it. But resulting query could be faster.
class TreeOptimizer
{
public:
static void apply(ASTPtr & query, Aliases & aliases, const NameSet & source_columns_set,
const std::vector<TableWithColumnNamesAndTypes> & tables_with_columns,
const Context & context, bool & rewrite_subqueries);
static void optimizeIf(ASTPtr & query, Aliases & aliases, bool if_chain_to_multiif);
};
}
...@@ -20,7 +20,7 @@ using Scalars = std::map<String, Block>; ...@@ -20,7 +20,7 @@ using Scalars = std::map<String, Block>;
struct StorageInMemoryMetadata; struct StorageInMemoryMetadata;
using StorageMetadataPtr = std::shared_ptr<const StorageInMemoryMetadata>; using StorageMetadataPtr = std::shared_ptr<const StorageInMemoryMetadata>;
struct SyntaxAnalyzerResult struct TreeRewriterResult
{ {
ConstStoragePtr storage; ConstStoragePtr storage;
StorageMetadataPtr metadata_snapshot; StorageMetadataPtr metadata_snapshot;
...@@ -56,7 +56,7 @@ struct SyntaxAnalyzerResult ...@@ -56,7 +56,7 @@ struct SyntaxAnalyzerResult
/// Results of scalar sub queries /// Results of scalar sub queries
Scalars scalars; Scalars scalars;
SyntaxAnalyzerResult( TreeRewriterResult(
const NamesAndTypesList & source_columns_, const NamesAndTypesList & source_columns_,
ConstStoragePtr storage_ = {}, ConstStoragePtr storage_ = {},
const StorageMetadataPtr & metadata_snapshot_ = {}, const StorageMetadataPtr & metadata_snapshot_ = {},
...@@ -74,29 +74,26 @@ struct SyntaxAnalyzerResult ...@@ -74,29 +74,26 @@ struct SyntaxAnalyzerResult
const Scalars & getScalars() const { return scalars; } const Scalars & getScalars() const { return scalars; }
}; };
using SyntaxAnalyzerResultPtr = std::shared_ptr<const SyntaxAnalyzerResult>; using TreeRewriterResultPtr = std::shared_ptr<const TreeRewriterResult>;
/// AST syntax analysis. /// Tree Rewriter in terms of CMU slides @sa https://15721.courses.cs.cmu.edu/spring2020/slides/19-optimizer1.pdf
/// Optimises AST tree and collect information for further expression analysis. ///
/// Optimises AST tree and collect information for further expression analysis in ExpressionAnalyzer.
/// Result AST has the following invariants: /// Result AST has the following invariants:
/// * all aliases are substituted /// * all aliases are substituted
/// * qualified names are translated /// * qualified names are translated
/// * scalar subqueries are executed replaced with constants /// * scalar subqueries are executed replaced with constants
/// * unneeded columns are removed from SELECT clause /// * unneeded columns are removed from SELECT clause
/// * duplicated columns are removed from ORDER BY, LIMIT BY, USING(...). /// * duplicated columns are removed from ORDER BY, LIMIT BY, USING(...).
/// Motivation: class TreeRewriter
/// * group most of the AST-changing operations in single place
/// * avoid AST rewriting in ExpressionAnalyzer
/// * decompose ExpressionAnalyzer
class SyntaxAnalyzer
{ {
public: public:
SyntaxAnalyzer(const Context & context_) TreeRewriter(const Context & context_)
: context(context_) : context(context_)
{} {}
/// Analyze and rewrite not select query /// Analyze and rewrite not select query
SyntaxAnalyzerResultPtr analyze( TreeRewriterResultPtr analyze(
ASTPtr & query, ASTPtr & query,
const NamesAndTypesList & source_columns_, const NamesAndTypesList & source_columns_,
ConstStoragePtr storage = {}, ConstStoragePtr storage = {},
...@@ -104,9 +101,9 @@ public: ...@@ -104,9 +101,9 @@ public:
bool allow_aggregations = false) const; bool allow_aggregations = false) const;
/// Analyze and rewrite select query /// Analyze and rewrite select query
SyntaxAnalyzerResultPtr analyzeSelect( TreeRewriterResultPtr analyzeSelect(
ASTPtr & query, ASTPtr & query,
SyntaxAnalyzerResult && result, TreeRewriterResult && result,
const SelectQueryOptions & select_options = {}, const SelectQueryOptions & select_options = {},
const std::vector<TableWithColumnNamesAndTypes> & tables_with_columns = {}, const std::vector<TableWithColumnNamesAndTypes> & tables_with_columns = {},
const Names & required_result_columns = {}, const Names & required_result_columns = {},
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include <Interpreters/convertFieldToType.h> #include <Interpreters/convertFieldToType.h>
#include <Interpreters/ExpressionActions.h> #include <Interpreters/ExpressionActions.h>
#include <Interpreters/ExpressionAnalyzer.h> #include <Interpreters/ExpressionAnalyzer.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Parsers/ASTFunction.h> #include <Parsers/ASTFunction.h>
#include <Parsers/ASTIdentifier.h> #include <Parsers/ASTIdentifier.h>
#include <Parsers/ASTLiteral.h> #include <Parsers/ASTLiteral.h>
...@@ -36,7 +36,7 @@ std::pair<Field, std::shared_ptr<const IDataType>> evaluateConstantExpression(co ...@@ -36,7 +36,7 @@ std::pair<Field, std::shared_ptr<const IDataType>> evaluateConstantExpression(co
ReplaceQueryParameterVisitor param_visitor(context.getQueryParameters()); ReplaceQueryParameterVisitor param_visitor(context.getQueryParameters());
param_visitor.visit(ast); param_visitor.visit(ast);
String name = ast->getColumnName(); String name = ast->getColumnName();
auto syntax_result = SyntaxAnalyzer(context).analyze(ast, source_columns); auto syntax_result = TreeRewriter(context).analyze(ast, source_columns);
ExpressionActionsPtr expr_for_constant_folding = ExpressionAnalyzer(ast, syntax_result, context).getConstActions(); ExpressionActionsPtr expr_for_constant_folding = ExpressionAnalyzer(ast, syntax_result, context).getConstActions();
/// There must be at least one column in the block so that it knows the number of rows. /// There must be at least one column in the block so that it knows the number of rows.
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include <Core/Block.h> #include <Core/Block.h>
#include <Parsers/queryToString.h> #include <Parsers/queryToString.h>
#include <Storages/ColumnDefault.h> #include <Storages/ColumnDefault.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Interpreters/ExpressionAnalyzer.h> #include <Interpreters/ExpressionAnalyzer.h>
#include <Interpreters/ExpressionActions.h> #include <Interpreters/ExpressionActions.h>
#include <Parsers/ASTExpressionList.h> #include <Parsers/ASTExpressionList.h>
...@@ -98,7 +98,7 @@ void executeExpressionsOnBlock( ...@@ -98,7 +98,7 @@ void executeExpressionsOnBlock(
if (!save_unneeded_columns) if (!save_unneeded_columns)
{ {
auto syntax_result = SyntaxAnalyzer(context).analyze(expr_list, block.getNamesAndTypesList()); auto syntax_result = TreeRewriter(context).analyze(expr_list, block.getNamesAndTypesList());
ExpressionAnalyzer{expr_list, syntax_result, context}.getActions(true)->execute(block); ExpressionAnalyzer{expr_list, syntax_result, context}.getActions(true)->execute(block);
return; return;
} }
...@@ -107,7 +107,7 @@ void executeExpressionsOnBlock( ...@@ -107,7 +107,7 @@ void executeExpressionsOnBlock(
* we are going to operate on a copy instead of the original block */ * we are going to operate on a copy instead of the original block */
Block copy_block{block}; Block copy_block{block};
auto syntax_result = SyntaxAnalyzer(context).analyze(expr_list, block.getNamesAndTypesList()); auto syntax_result = TreeRewriter(context).analyze(expr_list, block.getNamesAndTypesList());
auto expression_analyzer = ExpressionAnalyzer{expr_list, syntax_result, context}; auto expression_analyzer = ExpressionAnalyzer{expr_list, syntax_result, context};
auto required_source_columns = syntax_result->requiredSourceColumns(); auto required_source_columns = syntax_result->requiredSourceColumns();
auto rows_was = copy_block.rows(); auto rows_was = copy_block.rows();
......
...@@ -134,7 +134,6 @@ SRCS( ...@@ -134,7 +134,6 @@ SRCS(
SortedBlocksWriter.cpp SortedBlocksWriter.cpp
StorageID.cpp StorageID.cpp
SubqueryForSet.cpp SubqueryForSet.cpp
SyntaxAnalyzer.cpp
SystemLog.cpp SystemLog.cpp
TableJoin.cpp TableJoin.cpp
TablesStatus.cpp TablesStatus.cpp
...@@ -142,6 +141,8 @@ SRCS( ...@@ -142,6 +141,8 @@ SRCS(
ThreadStatusExt.cpp ThreadStatusExt.cpp
TraceLog.cpp TraceLog.cpp
TranslateQualifiedNamesVisitor.cpp TranslateQualifiedNamesVisitor.cpp
TreeOptimizer.cpp
TreeRewriter.cpp
) )
END() END()
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include <Interpreters/ExpressionAnalyzer.h> #include <Interpreters/ExpressionAnalyzer.h>
#include <Interpreters/ReplaceQueryParameterVisitor.h> #include <Interpreters/ReplaceQueryParameterVisitor.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Interpreters/Context.h> #include <Interpreters/Context.h>
#include <Interpreters/convertFieldToType.h> #include <Interpreters/convertFieldToType.h>
#include <Interpreters/ExpressionActions.h> #include <Interpreters/ExpressionActions.h>
...@@ -303,7 +303,7 @@ ConstantExpressionTemplate::TemplateStructure::TemplateStructure(LiteralsInfo & ...@@ -303,7 +303,7 @@ ConstantExpressionTemplate::TemplateStructure::TemplateStructure(LiteralsInfo &
addNodesToCastResult(result_type, expression, null_as_default); addNodesToCastResult(result_type, expression, null_as_default);
auto syntax_result = SyntaxAnalyzer(context).analyze(expression, literals.getNamesAndTypesList()); auto syntax_result = TreeRewriter(context).analyze(expression, literals.getNamesAndTypesList());
result_column_name = expression->getColumnName(); result_column_name = expression->getColumnName();
actions_on_literals = ExpressionAnalyzer(expression, syntax_result, context).getActions(false); actions_on_literals = ExpressionAnalyzer(expression, syntax_result, context).getActions(false);
} }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include <Interpreters/ExpressionActions.h> #include <Interpreters/ExpressionActions.h>
#include <Interpreters/addTypeConversionToAST.h> #include <Interpreters/addTypeConversionToAST.h>
#include <Interpreters/ExpressionAnalyzer.h> #include <Interpreters/ExpressionAnalyzer.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Interpreters/RenameColumnVisitor.h> #include <Interpreters/RenameColumnVisitor.h>
#include <Parsers/ASTAlterQuery.h> #include <Parsers/ASTAlterQuery.h>
#include <Parsers/ASTColumnDeclaration.h> #include <Parsers/ASTColumnDeclaration.h>
...@@ -853,7 +853,7 @@ void AlterCommands::validate(const StorageInMemoryMetadata & metadata, const Con ...@@ -853,7 +853,7 @@ void AlterCommands::validate(const StorageInMemoryMetadata & metadata, const Con
if (default_expression) if (default_expression)
{ {
ASTPtr query = default_expression->clone(); ASTPtr query = default_expression->clone();
auto syntax_result = SyntaxAnalyzer(context).analyze(query, all_columns.getAll()); auto syntax_result = TreeRewriter(context).analyze(query, all_columns.getAll());
const auto actions = ExpressionAnalyzer(query, syntax_result, context).getActions(true); const auto actions = ExpressionAnalyzer(query, syntax_result, context).getActions(true);
const auto required_columns = actions->getRequiredColumns(); const auto required_columns = actions->getRequiredColumns();
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <Core/Defines.h> #include <Core/Defines.h>
#include <Compression/CompressionFactory.h> #include <Compression/CompressionFactory.h>
#include <Interpreters/ExpressionAnalyzer.h> #include <Interpreters/ExpressionAnalyzer.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Interpreters/ExpressionActions.h> #include <Interpreters/ExpressionActions.h>
...@@ -477,7 +477,7 @@ Block validateColumnsDefaultsAndGetSampleBlock(ASTPtr default_expr_list, const N ...@@ -477,7 +477,7 @@ Block validateColumnsDefaultsAndGetSampleBlock(ASTPtr default_expr_list, const N
try try
{ {
auto syntax_analyzer_result = SyntaxAnalyzer(context).analyze(default_expr_list, all_columns); auto syntax_analyzer_result = TreeRewriter(context).analyze(default_expr_list, all_columns);
const auto actions = ExpressionAnalyzer(default_expr_list, syntax_analyzer_result, context).getActions(true); const auto actions = ExpressionAnalyzer(default_expr_list, syntax_analyzer_result, context).getActions(true);
for (const auto & action : actions->getActions()) for (const auto & action : actions->getActions())
if (action.type == ExpressionAction::Type::JOIN || action.type == ExpressionAction::Type::ARRAY_JOIN) if (action.type == ExpressionAction::Type::JOIN || action.type == ExpressionAction::Type::ARRAY_JOIN)
......
...@@ -45,10 +45,10 @@ ConstraintsExpressions ConstraintsDescription::getExpressions(const DB::Context ...@@ -45,10 +45,10 @@ ConstraintsExpressions ConstraintsDescription::getExpressions(const DB::Context
res.reserve(constraints.size()); res.reserve(constraints.size());
for (const auto & constraint : constraints) for (const auto & constraint : constraints)
{ {
// SyntaxAnalyzer::analyze has query as non-const argument so to avoid accidental query changes we clone it // TreeRewriter::analyze has query as non-const argument so to avoid accidental query changes we clone it
auto * constraint_ptr = constraint->as<ASTConstraintDeclaration>(); auto * constraint_ptr = constraint->as<ASTConstraintDeclaration>();
ASTPtr expr = constraint_ptr->expr->clone(); ASTPtr expr = constraint_ptr->expr->clone();
auto syntax_result = SyntaxAnalyzer(context).analyze(expr, source_columns_); auto syntax_result = TreeRewriter(context).analyze(expr, source_columns_);
res.push_back(ExpressionAnalyzer(constraint_ptr->expr->clone(), syntax_result, context).getActions(false)); res.push_back(ExpressionAnalyzer(constraint_ptr->expr->clone(), syntax_result, context).getActions(false));
} }
return res; return res;
......
#include <Interpreters/ExpressionAnalyzer.h> #include <Interpreters/ExpressionAnalyzer.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Storages/IndicesDescription.h> #include <Storages/IndicesDescription.h>
#include <Parsers/ASTIndexDeclaration.h> #include <Parsers/ASTIndexDeclaration.h>
...@@ -90,7 +90,7 @@ IndexDescription IndexDescription::getIndexFromAST(const ASTPtr & definition_ast ...@@ -90,7 +90,7 @@ IndexDescription IndexDescription::getIndexFromAST(const ASTPtr & definition_ast
ASTPtr expr_list = extractKeyExpressionList(index_definition->expr->clone()); ASTPtr expr_list = extractKeyExpressionList(index_definition->expr->clone());
result.expression_list_ast = expr_list->clone(); result.expression_list_ast = expr_list->clone();
auto syntax = SyntaxAnalyzer(context).analyze(expr_list, columns.getAllPhysical()); auto syntax = TreeRewriter(context).analyze(expr_list, columns.getAllPhysical());
result.expression = ExpressionAnalyzer(expr_list, syntax, context).getActions(true); result.expression = ExpressionAnalyzer(expr_list, syntax, context).getActions(true);
Block block_without_columns = result.expression->getSampleBlock(); Block block_without_columns = result.expression->getSampleBlock();
...@@ -166,7 +166,7 @@ ExpressionActionsPtr IndicesDescription::getSingleExpressionForIndices(const Col ...@@ -166,7 +166,7 @@ ExpressionActionsPtr IndicesDescription::getSingleExpressionForIndices(const Col
for (const auto & index_expr : index.expression_list_ast->children) for (const auto & index_expr : index.expression_list_ast->children)
combined_expr_list->children.push_back(index_expr->clone()); combined_expr_list->children.push_back(index_expr->clone());
auto syntax_result = SyntaxAnalyzer(context).analyze(combined_expr_list, columns.getAllPhysical()); auto syntax_result = TreeRewriter(context).analyze(combined_expr_list, columns.getAllPhysical());
return ExpressionAnalyzer(combined_expr_list, syntax_result, context).getActions(false); return ExpressionAnalyzer(combined_expr_list, syntax_result, context).getActions(false);
} }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include <Parsers/ASTIdentifier.h> #include <Parsers/ASTIdentifier.h>
#include <Interpreters/ExpressionActions.h> #include <Interpreters/ExpressionActions.h>
#include <Interpreters/ExpressionAnalyzer.h> #include <Interpreters/ExpressionAnalyzer.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Storages/extractKeyExpressionList.h> #include <Storages/extractKeyExpressionList.h>
...@@ -107,7 +107,7 @@ KeyDescription KeyDescription::getSortingKeyFromAST( ...@@ -107,7 +107,7 @@ KeyDescription KeyDescription::getSortingKeyFromAST(
{ {
auto expr = result.expression_list_ast->clone(); auto expr = result.expression_list_ast->clone();
auto syntax_result = SyntaxAnalyzer(context).analyze(expr, columns.getAllPhysical()); auto syntax_result = TreeRewriter(context).analyze(expr, columns.getAllPhysical());
/// In expression we also need to store source columns /// In expression we also need to store source columns
result.expression = ExpressionAnalyzer(expr, syntax_result, context).getActions(false); result.expression = ExpressionAnalyzer(expr, syntax_result, context).getActions(false);
/// In sample block we use just key columns /// In sample block we use just key columns
......
#include <Storages/MergeTree/KeyCondition.h> #include <Storages/MergeTree/KeyCondition.h>
#include <Storages/MergeTree/BoolMask.h> #include <Storages/MergeTree/BoolMask.h>
#include <DataTypes/DataTypesNumber.h> #include <DataTypes/DataTypesNumber.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Interpreters/ExpressionAnalyzer.h> #include <Interpreters/ExpressionAnalyzer.h>
#include <Interpreters/ExpressionActions.h> #include <Interpreters/ExpressionActions.h>
#include <Interpreters/misc.h> #include <Interpreters/misc.h>
...@@ -348,7 +348,7 @@ inline bool Range::less(const Field & lhs, const Field & rhs) { return applyVisi ...@@ -348,7 +348,7 @@ inline bool Range::less(const Field & lhs, const Field & rhs) { return applyVisi
* For index to work when something like "WHERE Date = toDate(now())" is written. * For index to work when something like "WHERE Date = toDate(now())" is written.
*/ */
Block KeyCondition::getBlockWithConstants( Block KeyCondition::getBlockWithConstants(
const ASTPtr & query, const SyntaxAnalyzerResultPtr & syntax_analyzer_result, const Context & context) const ASTPtr & query, const TreeRewriterResultPtr & syntax_analyzer_result, const Context & context)
{ {
Block result Block result
{ {
......
...@@ -302,7 +302,7 @@ public: ...@@ -302,7 +302,7 @@ public:
const ASTPtr & expr, Block & block_with_constants, Field & out_value, DataTypePtr & out_type); const ASTPtr & expr, Block & block_with_constants, Field & out_value, DataTypePtr & out_type);
static Block getBlockWithConstants( static Block getBlockWithConstants(
const ASTPtr & query, const SyntaxAnalyzerResultPtr & syntax_analyzer_result, const Context & context); const ASTPtr & query, const TreeRewriterResultPtr & syntax_analyzer_result, const Context & context);
static std::optional<Range> applyMonotonicFunctionsChainToRange( static std::optional<Range> applyMonotonicFunctionsChainToRange(
Range key_range, Range key_range,
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <IO/WriteBufferFromString.h> #include <IO/WriteBufferFromString.h>
#include <Interpreters/ExpressionAnalyzer.h> #include <Interpreters/ExpressionAnalyzer.h>
#include <Interpreters/PartLog.h> #include <Interpreters/PartLog.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Interpreters/Context.h> #include <Interpreters/Context.h>
#include <Parsers/ASTFunction.h> #include <Parsers/ASTFunction.h>
#include <Parsers/ASTLiteral.h> #include <Parsers/ASTLiteral.h>
...@@ -339,7 +339,7 @@ void MergeTreeData::checkProperties( ...@@ -339,7 +339,7 @@ void MergeTreeData::checkProperties(
if (!added_key_column_expr_list->children.empty()) if (!added_key_column_expr_list->children.empty())
{ {
auto syntax = SyntaxAnalyzer(global_context).analyze(added_key_column_expr_list, all_columns); auto syntax = TreeRewriter(global_context).analyze(added_key_column_expr_list, all_columns);
Names used_columns = syntax->requiredSourceColumns(); Names used_columns = syntax->requiredSourceColumns();
NamesAndTypesList deleted_columns; NamesAndTypesList deleted_columns;
...@@ -404,7 +404,7 @@ ExpressionActionsPtr getCombinedIndicesExpression( ...@@ -404,7 +404,7 @@ ExpressionActionsPtr getCombinedIndicesExpression(
for (const auto & index_expr : index.expression_list_ast->children) for (const auto & index_expr : index.expression_list_ast->children)
combined_expr_list->children.push_back(index_expr->clone()); combined_expr_list->children.push_back(index_expr->clone());
auto syntax_result = SyntaxAnalyzer(context).analyze(combined_expr_list, columns.getAllPhysical()); auto syntax_result = TreeRewriter(context).analyze(combined_expr_list, columns.getAllPhysical());
return ExpressionAnalyzer(combined_expr_list, syntax_result, context).getActions(false); return ExpressionAnalyzer(combined_expr_list, syntax_result, context).getActions(false);
} }
......
...@@ -1562,7 +1562,7 @@ std::set<MergeTreeIndexPtr> MergeTreeDataMergerMutator::getIndicesToRecalculate( ...@@ -1562,7 +1562,7 @@ std::set<MergeTreeIndexPtr> MergeTreeDataMergerMutator::getIndicesToRecalculate(
if (!indices_to_recalc.empty() && input_stream) if (!indices_to_recalc.empty() && input_stream)
{ {
auto indices_recalc_syntax = SyntaxAnalyzer(context).analyze(indices_recalc_expr_list, input_stream->getHeader().getNamesAndTypesList()); auto indices_recalc_syntax = TreeRewriter(context).analyze(indices_recalc_expr_list, input_stream->getHeader().getNamesAndTypesList());
auto indices_recalc_expr = ExpressionAnalyzer( auto indices_recalc_expr = ExpressionAnalyzer(
indices_recalc_expr_list, indices_recalc_expr_list,
indices_recalc_syntax, context).getActions(false); indices_recalc_syntax, context).getActions(false);
......
...@@ -518,7 +518,7 @@ Pipes MergeTreeDataSelectExecutor::readFromParts( ...@@ -518,7 +518,7 @@ Pipes MergeTreeDataSelectExecutor::readFromParts(
} }
ASTPtr query = filter_function; ASTPtr query = filter_function;
auto syntax_result = SyntaxAnalyzer(context).analyze(query, available_real_columns); auto syntax_result = TreeRewriter(context).analyze(query, available_real_columns);
filter_expression = ExpressionAnalyzer(filter_function, syntax_result, context).getActions(false); filter_expression = ExpressionAnalyzer(filter_function, syntax_result, context).getActions(false);
if (!select.final()) if (!select.final())
...@@ -651,7 +651,7 @@ Pipes MergeTreeDataSelectExecutor::readFromParts( ...@@ -651,7 +651,7 @@ Pipes MergeTreeDataSelectExecutor::readFromParts(
auto order_key_prefix_ast = metadata_snapshot->getSortingKey().expression_list_ast->clone(); auto order_key_prefix_ast = metadata_snapshot->getSortingKey().expression_list_ast->clone();
order_key_prefix_ast->children.resize(prefix_size); order_key_prefix_ast->children.resize(prefix_size);
auto syntax_result = SyntaxAnalyzer(context).analyze(order_key_prefix_ast, metadata_snapshot->getColumns().getAllPhysical()); auto syntax_result = TreeRewriter(context).analyze(order_key_prefix_ast, metadata_snapshot->getColumns().getAllPhysical());
auto sorting_key_prefix_expr = ExpressionAnalyzer(order_key_prefix_ast, syntax_result, context).getActions(false); auto sorting_key_prefix_expr = ExpressionAnalyzer(order_key_prefix_ast, syntax_result, context).getActions(false);
res = spreadMarkRangesAmongStreamsWithOrder( res = spreadMarkRangesAmongStreamsWithOrder(
......
#include <Storages/MergeTree/MergeTreeIndexBloomFilter.h> #include <Storages/MergeTree/MergeTreeIndexBloomFilter.h>
#include <Storages/MergeTree/MergeTreeData.h> #include <Storages/MergeTree/MergeTreeData.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Interpreters/ExpressionAnalyzer.h> #include <Interpreters/ExpressionAnalyzer.h>
#include <Core/Types.h> #include <Core/Types.h>
#include <ext/bit_cast.h> #include <ext/bit_cast.h>
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <IO/ReadHelpers.h> #include <IO/ReadHelpers.h>
#include <Interpreters/ExpressionActions.h> #include <Interpreters/ExpressionActions.h>
#include <Interpreters/ExpressionAnalyzer.h> #include <Interpreters/ExpressionAnalyzer.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Interpreters/misc.h> #include <Interpreters/misc.h>
#include <Storages/MergeTree/MergeTreeData.h> #include <Storages/MergeTree/MergeTreeData.h>
#include <Storages/MergeTree/RPNBuilder.h> #include <Storages/MergeTree/RPNBuilder.h>
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include <Interpreters/ExpressionActions.h> #include <Interpreters/ExpressionActions.h>
#include <Interpreters/ExpressionAnalyzer.h> #include <Interpreters/ExpressionAnalyzer.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Poco/Logger.h> #include <Poco/Logger.h>
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include <Interpreters/ExpressionActions.h> #include <Interpreters/ExpressionActions.h>
#include <Interpreters/ExpressionAnalyzer.h> #include <Interpreters/ExpressionAnalyzer.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Parsers/ASTIdentifier.h> #include <Parsers/ASTIdentifier.h>
#include <Parsers/ASTFunction.h> #include <Parsers/ASTFunction.h>
...@@ -265,7 +265,7 @@ MergeTreeIndexConditionSet::MergeTreeIndexConditionSet( ...@@ -265,7 +265,7 @@ MergeTreeIndexConditionSet::MergeTreeIndexConditionSet(
/// Working with UInt8: last bit = can be true, previous = can be false (Like src/Storages/MergeTree/BoolMask.h). /// Working with UInt8: last bit = can be true, previous = can be false (Like src/Storages/MergeTree/BoolMask.h).
traverseAST(expression_ast); traverseAST(expression_ast);
auto syntax_analyzer_result = SyntaxAnalyzer(context).analyze( auto syntax_analyzer_result = TreeRewriter(context).analyze(
expression_ast, index_sample_block.getNamesAndTypesList()); expression_ast, index_sample_block.getNamesAndTypesList());
actions = ExpressionAnalyzer(expression_ast, syntax_analyzer_result, context).getActions(true); actions = ExpressionAnalyzer(expression_ast, syntax_analyzer_result, context).getActions(true);
} }
......
...@@ -16,7 +16,7 @@ namespace ErrorCodes ...@@ -16,7 +16,7 @@ namespace ErrorCodes
ReadInOrderOptimizer::ReadInOrderOptimizer( ReadInOrderOptimizer::ReadInOrderOptimizer(
const ManyExpressionActions & elements_actions_, const ManyExpressionActions & elements_actions_,
const SortDescription & required_sort_description_, const SortDescription & required_sort_description_,
const SyntaxAnalyzerResultPtr & syntax_result) const TreeRewriterResultPtr & syntax_result)
: elements_actions(elements_actions_) : elements_actions(elements_actions_)
, required_sort_description(required_sort_description_) , required_sort_description(required_sort_description_)
{ {
......
...@@ -18,7 +18,7 @@ public: ...@@ -18,7 +18,7 @@ public:
ReadInOrderOptimizer( ReadInOrderOptimizer(
const ManyExpressionActions & elements_actions, const ManyExpressionActions & elements_actions,
const SortDescription & required_sort_description, const SortDescription & required_sort_description,
const SyntaxAnalyzerResultPtr & syntax_result); const TreeRewriterResultPtr & syntax_result);
InputOrderInfoPtr getInputOrder(const StoragePtr & storage, const StorageMetadataPtr & metadata_snapshot) const; InputOrderInfoPtr getInputOrder(const StoragePtr & storage, const StorageMetadataPtr & metadata_snapshot) const;
......
...@@ -57,8 +57,8 @@ using PrewhereInfoPtr = std::shared_ptr<PrewhereInfo>; ...@@ -57,8 +57,8 @@ using PrewhereInfoPtr = std::shared_ptr<PrewhereInfo>;
using FilterInfoPtr = std::shared_ptr<FilterInfo>; using FilterInfoPtr = std::shared_ptr<FilterInfo>;
using InputOrderInfoPtr = std::shared_ptr<const InputOrderInfo>; using InputOrderInfoPtr = std::shared_ptr<const InputOrderInfo>;
struct SyntaxAnalyzerResult; struct TreeRewriterResult;
using SyntaxAnalyzerResultPtr = std::shared_ptr<const SyntaxAnalyzerResult>; using TreeRewriterResultPtr = std::shared_ptr<const TreeRewriterResult>;
class ReadInOrderOptimizer; class ReadInOrderOptimizer;
using ReadInOrderOptimizerPtr = std::shared_ptr<const ReadInOrderOptimizer>; using ReadInOrderOptimizerPtr = std::shared_ptr<const ReadInOrderOptimizer>;
...@@ -73,7 +73,7 @@ struct SelectQueryInfo ...@@ -73,7 +73,7 @@ struct SelectQueryInfo
ASTPtr query; ASTPtr query;
ASTPtr view_query; /// Optimized VIEW query ASTPtr view_query; /// Optimized VIEW query
SyntaxAnalyzerResultPtr syntax_analyzer_result; TreeRewriterResultPtr syntax_analyzer_result;
PrewhereInfoPtr prewhere_info; PrewhereInfoPtr prewhere_info;
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#include <Interpreters/InterpreterDescribeQuery.h> #include <Interpreters/InterpreterDescribeQuery.h>
#include <Interpreters/InterpreterSelectQuery.h> #include <Interpreters/InterpreterSelectQuery.h>
#include <Interpreters/TranslateQualifiedNamesVisitor.h> #include <Interpreters/TranslateQualifiedNamesVisitor.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Interpreters/Context.h> #include <Interpreters/Context.h>
#include <Interpreters/createBlockSelector.h> #include <Interpreters/createBlockSelector.h>
#include <Interpreters/evaluateConstantExpression.h> #include <Interpreters/evaluateConstantExpression.h>
...@@ -185,7 +185,7 @@ std::string makeFormattedListOfShards(const ClusterPtr & cluster) ...@@ -185,7 +185,7 @@ std::string makeFormattedListOfShards(const ClusterPtr & cluster)
ExpressionActionsPtr buildShardingKeyExpression(const ASTPtr & sharding_key, const Context & context, const NamesAndTypesList & columns, bool project) ExpressionActionsPtr buildShardingKeyExpression(const ASTPtr & sharding_key, const Context & context, const NamesAndTypesList & columns, bool project)
{ {
ASTPtr query = sharding_key; ASTPtr query = sharding_key;
auto syntax_result = SyntaxAnalyzer(context).analyze(query, columns); auto syntax_result = TreeRewriter(context).analyze(query, columns);
return ExpressionAnalyzer(query, syntax_result, context).getActions(project); return ExpressionAnalyzer(query, syntax_result, context).getActions(project);
} }
...@@ -235,7 +235,7 @@ void replaceConstantExpressions( ...@@ -235,7 +235,7 @@ void replaceConstantExpressions(
ConstStoragePtr storage, ConstStoragePtr storage,
const StorageMetadataPtr & metadata_snapshot) const StorageMetadataPtr & metadata_snapshot)
{ {
auto syntax_result = SyntaxAnalyzer(context).analyze(node, columns, storage, metadata_snapshot); auto syntax_result = TreeRewriter(context).analyze(node, columns, storage, metadata_snapshot);
Block block_with_constants = KeyCondition::getBlockWithConstants(node, syntax_result, context); Block block_with_constants = KeyCondition::getBlockWithConstants(node, syntax_result, context);
InDepthNodeVisitor<ReplacingConstantExpressionsMatcher, true> visitor(block_with_constants); InDepthNodeVisitor<ReplacingConstantExpressionsMatcher, true> visitor(block_with_constants);
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include <Storages/StorageFactory.h> #include <Storages/StorageFactory.h>
#include <Storages/VirtualColumnUtils.h> #include <Storages/VirtualColumnUtils.h>
#include <Storages/AlterCommands.h> #include <Storages/AlterCommands.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Interpreters/ExpressionActions.h> #include <Interpreters/ExpressionActions.h>
#include <Interpreters/evaluateConstantExpression.h> #include <Interpreters/evaluateConstantExpression.h>
#include <Interpreters/InterpreterSelectQuery.h> #include <Interpreters/InterpreterSelectQuery.h>
...@@ -472,7 +472,7 @@ void StorageMerge::convertingSourceStream( ...@@ -472,7 +472,7 @@ void StorageMerge::convertingSourceStream(
NamesAndTypesList source_columns = metadata_snapshot->getSampleBlock().getNamesAndTypesList(); NamesAndTypesList source_columns = metadata_snapshot->getSampleBlock().getNamesAndTypesList();
auto virtual_column = *getVirtuals().tryGetByName("_table"); auto virtual_column = *getVirtuals().tryGetByName("_table");
source_columns.emplace_back(NameAndTypePair{virtual_column.name, virtual_column.type}); source_columns.emplace_back(NameAndTypePair{virtual_column.name, virtual_column.type});
auto syntax_result = SyntaxAnalyzer(context).analyze(where_expression, source_columns); auto syntax_result = TreeRewriter(context).analyze(where_expression, source_columns);
ExpressionActionsPtr actions = ExpressionAnalyzer{where_expression, syntax_result, context}.getActions(false, false); ExpressionActionsPtr actions = ExpressionAnalyzer{where_expression, syntax_result, context}.getActions(false, false);
Names required_columns = actions->getRequiredColumns(); Names required_columns = actions->getRequiredColumns();
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include <Functions/IFunction.h> #include <Functions/IFunction.h>
#include <Interpreters/ExpressionAnalyzer.h> #include <Interpreters/ExpressionAnalyzer.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Parsers/ASTExpressionList.h> #include <Parsers/ASTExpressionList.h>
#include <Parsers/ASTFunction.h> #include <Parsers/ASTFunction.h>
#include <Parsers/ASTTTLElement.h> #include <Parsers/ASTTTLElement.h>
...@@ -143,7 +143,7 @@ TTLDescription TTLDescription::getTTLFromAST( ...@@ -143,7 +143,7 @@ TTLDescription TTLDescription::getTTLFromAST(
result.expression_ast = definition_ast->clone(); result.expression_ast = definition_ast->clone();
auto ttl_ast = result.expression_ast->clone(); auto ttl_ast = result.expression_ast->clone();
auto syntax_analyzer_result = SyntaxAnalyzer(context).analyze(ttl_ast, columns.getAllPhysical()); auto syntax_analyzer_result = TreeRewriter(context).analyze(ttl_ast, columns.getAllPhysical());
result.expression = ExpressionAnalyzer(ttl_ast, syntax_analyzer_result, context).getActions(false); result.expression = ExpressionAnalyzer(ttl_ast, syntax_analyzer_result, context).getActions(false);
result.result_column = ttl_ast->getColumnName(); result.result_column = ttl_ast->getColumnName();
...@@ -162,7 +162,7 @@ TTLDescription TTLDescription::getTTLFromAST( ...@@ -162,7 +162,7 @@ TTLDescription TTLDescription::getTTLFromAST(
{ {
if (ASTPtr where_expr_ast = ttl_element->where()) if (ASTPtr where_expr_ast = ttl_element->where())
{ {
auto where_syntax_result = SyntaxAnalyzer(context).analyze(where_expr_ast, columns.getAllPhysical()); auto where_syntax_result = TreeRewriter(context).analyze(where_expr_ast, columns.getAllPhysical());
result.where_expression = ExpressionAnalyzer(where_expr_ast, where_syntax_result, context).getActions(false); result.where_expression = ExpressionAnalyzer(where_expr_ast, where_syntax_result, context).getActions(false);
result.where_result_column = where_expr_ast->getColumnName(); result.where_result_column = where_expr_ast->getColumnName();
} }
...@@ -220,7 +220,7 @@ TTLDescription TTLDescription::getTTLFromAST( ...@@ -220,7 +220,7 @@ TTLDescription TTLDescription::getTTLFromAST(
if (value->as<ASTFunction>()) if (value->as<ASTFunction>())
{ {
auto syntax_result = SyntaxAnalyzer(context).analyze(value, columns.getAllPhysical(), {}, {}, true); auto syntax_result = TreeRewriter(context).analyze(value, columns.getAllPhysical(), {}, {}, true);
auto expr_actions = ExpressionAnalyzer(value, syntax_result, context).getActions(false); auto expr_actions = ExpressionAnalyzer(value, syntax_result, context).getActions(false);
for (const auto & column : expr_actions->getRequiredColumns()) for (const auto & column : expr_actions->getRequiredColumns())
{ {
...@@ -249,7 +249,7 @@ TTLDescription TTLDescription::getTTLFromAST( ...@@ -249,7 +249,7 @@ TTLDescription TTLDescription::getTTLFromAST(
for (auto [name, value] : aggregations) for (auto [name, value] : aggregations)
{ {
auto syntax_result = SyntaxAnalyzer(context).analyze(value, columns.getAllPhysical(), {}, {}, true); auto syntax_result = TreeRewriter(context).analyze(value, columns.getAllPhysical(), {}, {}, true);
auto expr_analyzer = ExpressionAnalyzer(value, syntax_result, context); auto expr_analyzer = ExpressionAnalyzer(value, syntax_result, context);
TTLAggregateDescription set_part; TTLAggregateDescription set_part;
......
#include <Core/NamesAndTypes.h> #include <Core/NamesAndTypes.h>
#include <Interpreters/Context.h> #include <Interpreters/Context.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Interpreters/ExpressionAnalyzer.h> #include <Interpreters/ExpressionAnalyzer.h>
#include <Interpreters/ExpressionActions.h> #include <Interpreters/ExpressionActions.h>
#include <Interpreters/IdentifierSemantic.h> #include <Interpreters/IdentifierSemantic.h>
...@@ -118,7 +118,7 @@ void filterBlockWithQuery(const ASTPtr & query, Block & block, const Context & c ...@@ -118,7 +118,7 @@ void filterBlockWithQuery(const ASTPtr & query, Block & block, const Context & c
return; return;
/// Let's analyze and calculate the expression. /// Let's analyze and calculate the expression.
auto syntax_result = SyntaxAnalyzer(context).analyze(expression_ast, block.getNamesAndTypesList()); auto syntax_result = TreeRewriter(context).analyze(expression_ast, block.getNamesAndTypesList());
ExpressionAnalyzer analyzer(expression_ast, syntax_result, context); ExpressionAnalyzer analyzer(expression_ast, syntax_result, context);
ExpressionActionsPtr actions = analyzer.getActions(false); ExpressionActionsPtr actions = analyzer.getActions(false);
......
...@@ -56,7 +56,7 @@ static void check(const std::string & query, const std::string & expected, const ...@@ -56,7 +56,7 @@ static void check(const std::string & query, const std::string & expected, const
ParserSelectQuery parser; ParserSelectQuery parser;
ASTPtr ast = parseQuery(parser, query, 1000, 1000); ASTPtr ast = parseQuery(parser, query, 1000, 1000);
SelectQueryInfo query_info; SelectQueryInfo query_info;
query_info.syntax_analyzer_result = SyntaxAnalyzer(context).analyzeSelect(ast, columns); query_info.syntax_analyzer_result = TreeRewriter(context).analyzeSelect(ast, columns);
query_info.query = ast; query_info.query = ast;
std::string transformed_query = transformQueryForExternalDatabase(query_info, columns, IdentifierQuotingStyle::DoubleQuotes, "test", "table", context); std::string transformed_query = transformQueryForExternalDatabase(query_info, columns, IdentifierQuotingStyle::DoubleQuotes, "test", "table", context);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include <Parsers/ASTLiteral.h> #include <Parsers/ASTLiteral.h>
#include <Parsers/ASTSelectQuery.h> #include <Parsers/ASTSelectQuery.h>
#include <Parsers/ASTExpressionList.h> #include <Parsers/ASTExpressionList.h>
#include <Interpreters/SyntaxAnalyzer.h> #include <Interpreters/TreeRewriter.h>
#include <Interpreters/InDepthNodeVisitor.h> #include <Interpreters/InDepthNodeVisitor.h>
#include <IO/WriteBufferFromString.h> #include <IO/WriteBufferFromString.h>
#include <Storages/transformQueryForExternalDatabase.h> #include <Storages/transformQueryForExternalDatabase.h>
...@@ -91,7 +91,7 @@ public: ...@@ -91,7 +91,7 @@ public:
void replaceConstantExpressions(ASTPtr & node, const Context & context, const NamesAndTypesList & all_columns) void replaceConstantExpressions(ASTPtr & node, const Context & context, const NamesAndTypesList & all_columns)
{ {
auto syntax_result = SyntaxAnalyzer(context).analyze(node, all_columns); auto syntax_result = TreeRewriter(context).analyze(node, all_columns);
Block block_with_constants = KeyCondition::getBlockWithConstants(node, syntax_result, context); Block block_with_constants = KeyCondition::getBlockWithConstants(node, syntax_result, context);
InDepthNodeVisitor<ReplacingConstantExpressionsMatcherNumOrStr, true> visitor(block_with_constants); InDepthNodeVisitor<ReplacingConstantExpressionsMatcherNumOrStr, true> visitor(block_with_constants);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册