mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-23 10:10:50 +00:00
dbms: Server: feature development [#METR-14875]
This commit is contained in:
parent
ef9a1c4388
commit
dc296a4822
@ -67,6 +67,8 @@ const std::unordered_set<String> injective_function_names
|
|||||||
|
|
||||||
void ExpressionAnalyzer::init()
|
void ExpressionAnalyzer::init()
|
||||||
{
|
{
|
||||||
|
optimizeOrChains();
|
||||||
|
|
||||||
select_query = typeid_cast<ASTSelectQuery *>(&*ast);
|
select_query = typeid_cast<ASTSelectQuery *>(&*ast);
|
||||||
|
|
||||||
addStorageAliases();
|
addStorageAliases();
|
||||||
@ -77,8 +79,6 @@ void ExpressionAnalyzer::init()
|
|||||||
/// Common subexpression elimination. Rewrite rules.
|
/// Common subexpression elimination. Rewrite rules.
|
||||||
normalizeTree();
|
normalizeTree();
|
||||||
|
|
||||||
optimizeOrChains();
|
|
||||||
|
|
||||||
/// GROUP BY injective function elimination.
|
/// GROUP BY injective function elimination.
|
||||||
optimizeGroupBy();
|
optimizeGroupBy();
|
||||||
|
|
||||||
@ -468,14 +468,14 @@ void ExpressionAnalyzer::normalizeTreeImpl(ASTPtr & ast, MapOfASTs & finished_as
|
|||||||
|
|
||||||
struct OrWithIdentifier
|
struct OrWithIdentifier
|
||||||
{
|
{
|
||||||
OrWithIdentifier(ASTFunction * or_function_, IAST * parent_, ASTIdentifier * identifier_)
|
OrWithIdentifier(ASTFunction * or_function_, IAST * parent_, const std::string & identifier_)
|
||||||
: or_function(or_function_), parent(parent_), identifier(identifier_)
|
: or_function(or_function_), parent(parent_), identifier(identifier_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTFunction * or_function;
|
ASTFunction * or_function;
|
||||||
IAST * parent;
|
IAST * parent;
|
||||||
ASTIdentifier * identifier;
|
const std::string & identifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator<(const OrWithIdentifier & lhs, const OrWithIdentifier & rhs)
|
bool operator<(const OrWithIdentifier & lhs, const OrWithIdentifier & rhs)
|
||||||
@ -508,7 +508,8 @@ ASTFunctionPtr createInExpression(const OrWithIdentifier & or_with_identifier, c
|
|||||||
ASTPtr value_list = new ASTExpressionList;
|
ASTPtr value_list = new ASTExpressionList;
|
||||||
for (auto function : equal_function_list)
|
for (auto function : equal_function_list)
|
||||||
{
|
{
|
||||||
auto literal = static_cast<ASTLiteral *>(&*(function->children[1]));
|
auto expr = static_cast<ASTExpressionList *>(&*(function->children[0]));
|
||||||
|
auto literal = static_cast<ASTLiteral *>(&*(expr->children[1]));
|
||||||
value_list->children.push_back(literal->clone());
|
value_list->children.push_back(literal->clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,7 +518,8 @@ ASTFunctionPtr createInExpression(const OrWithIdentifier & or_with_identifier, c
|
|||||||
tuple_function->arguments = value_list;
|
tuple_function->arguments = value_list;
|
||||||
tuple_function->children.push_back(tuple_function->arguments);
|
tuple_function->children.push_back(tuple_function->arguments);
|
||||||
|
|
||||||
ASTPtr identifier = or_with_identifier.identifier->clone();
|
Poco::SharedPtr<ASTIdentifier> identifier = new ASTIdentifier;
|
||||||
|
identifier->name = or_with_identifier.identifier;
|
||||||
|
|
||||||
ASTPtr in_expr = new ASTExpressionList;
|
ASTPtr in_expr = new ASTExpressionList;
|
||||||
in_expr->children.push_back(identifier);
|
in_expr->children.push_back(identifier);
|
||||||
@ -556,36 +558,36 @@ void ExpressionAnalyzer::optimizeOrChains()
|
|||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
ASTFunction * function = typeid_cast<ASTFunction *>(&*node);
|
ASTFunction * function = typeid_cast<ASTFunction *>(&*node);
|
||||||
if ((function == nullptr) || (function->name != "or") || (function->children.size() != 1))
|
if ((function != nullptr) && (function->name == "or") && (function->children.size() == 1))
|
||||||
continue;
|
|
||||||
|
|
||||||
ASTExpressionList * expression_list = typeid_cast<ASTExpressionList *>(&*(function->children[0]));
|
|
||||||
if (expression_list == nullptr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/// Цепочка элементов выражения OR.
|
|
||||||
for (auto child : expression_list->children)
|
|
||||||
{
|
{
|
||||||
ASTFunction * equals = typeid_cast<ASTFunction *>(&*child);
|
ASTExpressionList * expression_list = typeid_cast<ASTExpressionList *>(&*(function->children[0]));
|
||||||
if ((equals == nullptr) || (equals->name != "equals") || (equals->children.size() != 1))
|
if (expression_list != nullptr)
|
||||||
continue;
|
{
|
||||||
|
/// Цепочка элементов выражения OR.
|
||||||
ASTExpressionList * equals_expression_list = typeid_cast<ASTExpressionList *>(&*(equals->children[0]));
|
for (auto child : expression_list->children)
|
||||||
if ((equals_expression_list == nullptr) || (equals_expression_list->children.size() != 2))
|
{
|
||||||
continue;
|
ASTFunction * equals = typeid_cast<ASTFunction *>(&*child);
|
||||||
|
if ((equals != nullptr) && (equals->name == "equals") && (equals->children.size() == 1))
|
||||||
// Равенство c = xk
|
{
|
||||||
ASTIdentifier * identifier = typeid_cast<ASTIdentifier *>(&*(equals_expression_list->children[0]));
|
ASTExpressionList * equals_expression_list = typeid_cast<ASTExpressionList *>(&*(equals->children[0]));
|
||||||
if (identifier == nullptr)
|
if ((equals_expression_list != nullptr) && (equals_expression_list->children.size() == 2))
|
||||||
continue;
|
{
|
||||||
|
// Равенство c = xk
|
||||||
ASTLiteral * literal = typeid_cast<ASTLiteral *>(&*(equals_expression_list->children[1]));
|
ASTIdentifier * identifier = typeid_cast<ASTIdentifier *>(&*(equals_expression_list->children[0]));
|
||||||
if (literal == nullptr)
|
if (identifier != nullptr)
|
||||||
continue;
|
{
|
||||||
|
ASTLiteral * literal = typeid_cast<ASTLiteral *>(&*(equals_expression_list->children[1]));
|
||||||
OrWithIdentifier pp(function, parent.get(), identifier);
|
if (literal != nullptr)
|
||||||
equal_function_map[pp].push_back(equals);
|
{
|
||||||
found = true;
|
OrWithIdentifier pp(function, parent.get(), identifier->name);
|
||||||
|
equal_function_map[pp].push_back(equals);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
@ -614,10 +616,13 @@ void ExpressionAnalyzer::optimizeOrChains()
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool check = true;
|
bool check = true;
|
||||||
auto first_literal = static_cast<ASTLiteral *>(&*(equal_function_list[0]->children[1]));
|
auto first_expr = static_cast<ASTExpressionList *>(&*(equal_function_list[0]->children[0]));
|
||||||
|
auto first_literal = static_cast<ASTLiteral *>(&*(first_expr->children[1]));
|
||||||
for (size_t i = 1; i < equal_function_list.size(); ++i)
|
for (size_t i = 1; i < equal_function_list.size(); ++i)
|
||||||
{
|
{
|
||||||
auto literal = static_cast<ASTLiteral *>(&*(equal_function_list[i]->children[1]));
|
auto expr = static_cast<ASTExpressionList *>(&*(equal_function_list[i]->children[0]));
|
||||||
|
auto literal = static_cast<ASTLiteral *>(&*(expr->children[1]));
|
||||||
|
|
||||||
if (literal->type != first_literal->type)
|
if (literal->type != first_literal->type)
|
||||||
check = false;
|
check = false;
|
||||||
}
|
}
|
||||||
@ -662,6 +667,11 @@ void ExpressionAnalyzer::optimizeOrChains()
|
|||||||
parent->children.push_back(children[0]);
|
parent->children.push_back(children[0]);
|
||||||
auto it = std::remove(parent->children.begin(), parent->children.end(), or_function);
|
auto it = std::remove(parent->children.begin(), parent->children.end(), or_function);
|
||||||
parent->children.erase(it, parent->children.end());
|
parent->children.erase(it, parent->children.end());
|
||||||
|
|
||||||
|
/// Если узел OR был корнем выражения WHERE, то следует обновить этот корень.
|
||||||
|
auto select = typeid_cast<ASTSelectQuery *>(&*ast);
|
||||||
|
if (or_function == select->where_expression.get())
|
||||||
|
select->where_expression = children[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user