From 333c9aeeccbe10d0cdc437be15ab15820676bb47 Mon Sep 17 00:00:00 2001 From: chertus Date: Thu, 23 May 2019 19:01:17 +0300 Subject: [PATCH] support IN in CrossToInnerJoin push down --- .../Interpreters/CrossToInnerJoinVisitor.cpp | 27 +++++++++++++++++++ .../0_stateless/00863_comma_join_in.reference | 3 +++ .../0_stateless/00863_comma_join_in.sql | 21 +++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00863_comma_join_in.reference create mode 100644 dbms/tests/queries/0_stateless/00863_comma_join_in.sql diff --git a/dbms/src/Interpreters/CrossToInnerJoinVisitor.cpp b/dbms/src/Interpreters/CrossToInnerJoinVisitor.cpp index ba97ca0186b..468f96c8352 100644 --- a/dbms/src/Interpreters/CrossToInnerJoinVisitor.cpp +++ b/dbms/src/Interpreters/CrossToInnerJoinVisitor.cpp @@ -4,6 +4,7 @@ #include #include #include +#include // for functionIsInOperator #include #include #include @@ -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()) + 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; diff --git a/dbms/tests/queries/0_stateless/00863_comma_join_in.reference b/dbms/tests/queries/0_stateless/00863_comma_join_in.reference new file mode 100644 index 00000000000..01e79c32a8c --- /dev/null +++ b/dbms/tests/queries/0_stateless/00863_comma_join_in.reference @@ -0,0 +1,3 @@ +1 +2 +3 diff --git a/dbms/tests/queries/0_stateless/00863_comma_join_in.sql b/dbms/tests/queries/0_stateless/00863_comma_join_in.sql new file mode 100644 index 00000000000..d67217ccc41 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00863_comma_join_in.sql @@ -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;