mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 07:31:57 +00:00
Merge pull request #5396 from 4ertus2/ast
Support IN in CrossToInnerJoin push down predicates
This commit is contained in:
commit
9e24c8d19a
@ -4,6 +4,7 @@
|
||||
#include <Interpreters/CrossToInnerJoinVisitor.h>
|
||||
#include <Interpreters/DatabaseAndTableWithAlias.h>
|
||||
#include <Interpreters/IdentifierSemantic.h>
|
||||
#include <Interpreters/QueryNormalizer.h> // for functionIsInOperator
|
||||
#include <Parsers/ASTSelectQuery.h>
|
||||
#include <Parsers/ASTTablesInSelectQuery.h>
|
||||
#include <Parsers/ASTIdentifier.h>
|
||||
@ -120,6 +121,12 @@ public:
|
||||
{
|
||||
/// leave other comparisons as is
|
||||
}
|
||||
else if (functionIsInOperator(node.name)) /// IN, NOT IN
|
||||
{
|
||||
if (auto ident = node.arguments->children.at(0)->as<ASTIdentifier>())
|
||||
if (size_t min_table = checkIdentifier(*ident))
|
||||
asts_to_join_on[min_table].push_back(ast);
|
||||
}
|
||||
else
|
||||
{
|
||||
ands_only = false;
|
||||
@ -173,7 +180,7 @@ private:
|
||||
/// @return table position to attach expression to or 0.
|
||||
size_t checkIdentifiers(const ASTIdentifier & left, const ASTIdentifier & right)
|
||||
{
|
||||
/// {best_match, berst_table_pos}
|
||||
/// {best_match, best_table_pos}
|
||||
std::pair<size_t, size_t> left_best{0, 0};
|
||||
std::pair<size_t, size_t> right_best{0, 0};
|
||||
|
||||
@ -202,6 +209,26 @@ private:
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t checkIdentifier(const ASTIdentifier & identifier)
|
||||
{
|
||||
size_t best_match = 0;
|
||||
size_t best_table_pos = 0;
|
||||
|
||||
for (size_t i = 0; i < tables.size(); ++i)
|
||||
{
|
||||
size_t match = IdentifierSemantic::canReferColumnToTable(identifier, tables[i].table);
|
||||
if (match > best_match)
|
||||
{
|
||||
best_match = match;
|
||||
best_table_pos = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (best_match && tables[best_table_pos].canAttachOnExpression())
|
||||
return best_table_pos;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
using CheckExpressionMatcher = OneTypeMatcher<CheckExpressionVisitorData, false>;
|
||||
|
@ -0,0 +1,3 @@
|
||||
1
|
||||
2
|
||||
3
|
21
dbms/tests/queries/0_stateless/00863_comma_join_in.sql
Normal file
21
dbms/tests/queries/0_stateless/00863_comma_join_in.sql
Normal file
@ -0,0 +1,21 @@
|
||||
drop table if exists test1;
|
||||
drop table if exists test2;
|
||||
drop table if exists test3;
|
||||
|
||||
create table test1 (id UInt64, code String) engine = Memory;
|
||||
create table test3 (id UInt64, code String) engine = Memory;
|
||||
create table test2 (id UInt64, code String, test1_id UInt64, test3_id UInt64) engine = Memory;
|
||||
|
||||
insert into test1 (id, code) select number, toString(number) FROM numbers(100000);
|
||||
insert into test3 (id, code) select number, toString(number) FROM numbers(100000);
|
||||
insert into test2 (id, code, test1_id, test3_id) select number, toString(number), number, number FROM numbers(100000);
|
||||
|
||||
select test2.id
|
||||
from test1, test2, test3
|
||||
where test1.code in ('1', '2', '3')
|
||||
and test2.test1_id = test1.id
|
||||
and test2.test3_id = test3.id;
|
||||
|
||||
drop table test1;
|
||||
drop table test2;
|
||||
drop table test3;
|
Loading…
Reference in New Issue
Block a user