mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
support IN in CrossToInnerJoin push down
This commit is contained in:
parent
15e31d5a8c
commit
333c9aeecc
@ -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;
|
||||
@ -202,6 +209,26 @@ private:
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t checkIdentifier(const ASTIdentifier & identifier)
|
||||
{
|
||||
size_t best_match = 0;
|
||||
size_t berst_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;
|
||||
berst_table_pos = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (best_match && tables[berst_table_pos].canAttachOnExpression())
|
||||
return berst_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