mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-04 13:32:13 +00:00
Handle not plain where tree in StorageMerge modifySelect
This commit is contained in:
parent
1c5c1946df
commit
735154c81a
@ -81,56 +81,6 @@ private:
|
|||||||
ASTTableJoin * join = nullptr;
|
ASTTableJoin * join = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Collect all identifiers from ast
|
|
||||||
class IdentifiersCollector
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using ASTIdentPtr = const ASTIdentifier *;
|
|
||||||
using ASTIdentifiers = std::vector<ASTIdentPtr>;
|
|
||||||
struct Data
|
|
||||||
{
|
|
||||||
ASTIdentifiers idents;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void visit(const ASTPtr & node, Data & data)
|
|
||||||
{
|
|
||||||
if (const auto * ident = node->as<ASTIdentifier>())
|
|
||||||
data.idents.push_back(ident);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool needChildVisit(const ASTPtr &, const ASTPtr &)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ASTIdentifiers collect(const ASTPtr & node)
|
|
||||||
{
|
|
||||||
IdentifiersCollector::Data ident_data;
|
|
||||||
ConstInDepthNodeVisitor<IdentifiersCollector, true> ident_visitor(ident_data);
|
|
||||||
ident_visitor.visit(node);
|
|
||||||
return ident_data.idents;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Split expression `expr_1 AND expr_2 AND ... AND expr_n` into vector `[expr_1, expr_2, ..., expr_n]`
|
|
||||||
void collectConjunctions(const ASTPtr & node, std::vector<ASTPtr> & members)
|
|
||||||
{
|
|
||||||
if (const auto * func = node->as<ASTFunction>(); func && func->name == NameAnd::name)
|
|
||||||
{
|
|
||||||
for (const auto & child : func->arguments->children)
|
|
||||||
collectConjunctions(child, members);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
members.push_back(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<ASTPtr> collectConjunctions(const ASTPtr & node)
|
|
||||||
{
|
|
||||||
std::vector<ASTPtr> members;
|
|
||||||
collectConjunctions(node, members);
|
|
||||||
return members;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isAllowedToRewriteCrossJoin(const ASTPtr & node, const Aliases & aliases)
|
bool isAllowedToRewriteCrossJoin(const ASTPtr & node, const Aliases & aliases)
|
||||||
{
|
{
|
||||||
if (node->as<ASTFunction>())
|
if (node->as<ASTFunction>())
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
#include <Interpreters/IdentifierSemantic.h>
|
#include <Interpreters/IdentifierSemantic.h>
|
||||||
#include <Interpreters/StorageID.h>
|
#include <Interpreters/StorageID.h>
|
||||||
|
|
||||||
|
#include <Parsers/ASTFunction.h>
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -313,4 +315,22 @@ std::optional<size_t> IdentifierMembershipCollector::getIdentsMembership(ASTPtr
|
|||||||
return IdentifierSemantic::getIdentsMembership(ast, tables, aliases);
|
return IdentifierSemantic::getIdentsMembership(ast, tables, aliases);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void collectConjunctions(const ASTPtr & node, std::vector<ASTPtr> & members)
|
||||||
|
{
|
||||||
|
if (const auto * func = node->as<ASTFunction>(); func && func->name == "and")
|
||||||
|
{
|
||||||
|
for (const auto & child : func->arguments->children)
|
||||||
|
collectConjunctions(child, members);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
members.push_back(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ASTPtr> collectConjunctions(const ASTPtr & node)
|
||||||
|
{
|
||||||
|
std::vector<ASTPtr> members;
|
||||||
|
collectConjunctions(node, members);
|
||||||
|
return members;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -107,4 +107,7 @@ private:
|
|||||||
Aliases aliases;
|
Aliases aliases;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Split expression `expr_1 AND expr_2 AND ... AND expr_n` into vector `[expr_1, expr_2, ..., expr_n]`
|
||||||
|
std::vector<ASTPtr> collectConjunctions(const ASTPtr & node);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -71,15 +71,14 @@ TreeRewriterResult modifySelect(ASTSelectQuery & select, const TreeRewriterResul
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
const size_t left_table_pos = 0;
|
const size_t left_table_pos = 0;
|
||||||
if (const auto * conjunctions = where->as<ASTFunction>(); conjunctions && conjunctions->name == "and")
|
/// Test each argument of `and` function and select ones related to only left table
|
||||||
{
|
|
||||||
/// Test each argument of `and` function and select related to only left table
|
|
||||||
std::shared_ptr<ASTFunction> new_conj = makeASTFunction("and");
|
std::shared_ptr<ASTFunction> new_conj = makeASTFunction("and");
|
||||||
for (const auto & node : conjunctions->arguments->children)
|
for (const auto & node : collectConjunctions(where))
|
||||||
{
|
{
|
||||||
if (membership_collector.getIdentsMembership(node) == left_table_pos)
|
if (membership_collector.getIdentsMembership(node) == left_table_pos)
|
||||||
new_conj->arguments->children.push_back(std::move(node));
|
new_conj->arguments->children.push_back(std::move(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_conj->arguments->children.empty())
|
if (new_conj->arguments->children.empty())
|
||||||
/// No identifiers from left table
|
/// No identifiers from left table
|
||||||
query.setExpression(expr, {});
|
query.setExpression(expr, {});
|
||||||
@ -89,13 +88,6 @@ TreeRewriterResult modifySelect(ASTSelectQuery & select, const TreeRewriterResul
|
|||||||
else
|
else
|
||||||
/// Set new expression
|
/// Set new expression
|
||||||
query.setExpression(expr, std::move(new_conj));
|
query.setExpression(expr, std::move(new_conj));
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/// Remove whole expression if not match to left table
|
|
||||||
if (membership_collector.getIdentsMembership(where) != left_table_pos)
|
|
||||||
query.setExpression(expr, {});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
replace_where(select,ASTSelectQuery::Expression::WHERE);
|
replace_where(select,ASTSelectQuery::Expression::WHERE);
|
||||||
replace_where(select,ASTSelectQuery::Expression::PREWHERE);
|
replace_where(select,ASTSelectQuery::Expression::PREWHERE);
|
||||||
|
@ -2,3 +2,4 @@
|
|||||||
1 4
|
1 4
|
||||||
1 4
|
1 4
|
||||||
1 4
|
1 4
|
||||||
|
1 4
|
||||||
|
@ -14,6 +14,7 @@ SET force_primary_key = 1;
|
|||||||
|
|
||||||
SELECT * FROM foo_merge WHERE Val = 3 AND Id = 3;
|
SELECT * FROM foo_merge WHERE Val = 3 AND Id = 3;
|
||||||
SELECT count(), X FROM foo_merge JOIN t2 USING Val WHERE Val = 3 AND Id = 3 AND t2.X == 4 GROUP BY X;
|
SELECT count(), X FROM foo_merge JOIN t2 USING Val WHERE Val = 3 AND Id = 3 AND t2.X == 4 GROUP BY X;
|
||||||
|
SELECT count(), X FROM foo_merge JOIN t2 USING Val WHERE Val = 3 AND (Id = 3 AND t2.X == 4) GROUP BY X;
|
||||||
SELECT count(), X FROM foo_merge JOIN t2 USING Val WHERE Val = 3 AND Id = 3 GROUP BY X;
|
SELECT count(), X FROM foo_merge JOIN t2 USING Val WHERE Val = 3 AND Id = 3 GROUP BY X;
|
||||||
SELECT count(), X FROM (SELECT * FROM foo_merge) f JOIN t2 USING Val WHERE Val = 3 AND Id = 3 GROUP BY X;
|
SELECT count(), X FROM (SELECT * FROM foo_merge) f JOIN t2 USING Val WHERE Val = 3 AND Id = 3 GROUP BY X;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user