diff --git a/src/Core/Settings.h b/src/Core/Settings.h index 9bb9ad30f15..2ddd1e003ca 100644 --- a/src/Core/Settings.h +++ b/src/Core/Settings.h @@ -503,6 +503,7 @@ class IColumn; M(Bool, output_format_write_statistics, true, "Write statistics about read rows, bytes, time elapsed in suitable output formats.", 0) \ M(Bool, output_format_pretty_row_numbers, false, "Add row numbers before each row for pretty output format", 0) \ M(Bool, insert_distributed_one_random_shard, false, "If setting is enabled, inserting into distributed table will choose a random shard to write when there is no sharding key", 0) \ + M(Bool, cross_to_inner_join_rewrite, true, "Use inner join instead of comma/cross join if possible", 0) \ // End of FORMAT_FACTORY_SETTINGS diff --git a/src/Interpreters/CrossToInnerJoinVisitor.cpp b/src/Interpreters/CrossToInnerJoinVisitor.cpp index 4d06ad31c03..fc2747af8eb 100644 --- a/src/Interpreters/CrossToInnerJoinVisitor.cpp +++ b/src/Interpreters/CrossToInnerJoinVisitor.cpp @@ -326,21 +326,21 @@ void CrossToInnerJoinMatcher::visit(ASTSelectQuery & select, ASTPtr &, Data & da /// CROSS to INNER - if (!select.where()) - return; - - std::map> asts_to_join_on; - bool can_move_where = canMoveExpressionToJoinOn( - select.where(), joined_tables, data.tables_with_columns, data.aliases, asts_to_join_on); - if (can_move_where) + if (select.where() && data.cross_to_inner_join_rewrite) { - for (size_t i = 1; i < joined_tables.size(); ++i) + std::map> asts_to_join_on; + bool can_move_where + = canMoveExpressionToJoinOn(select.where(), joined_tables, data.tables_with_columns, data.aliases, asts_to_join_on); + if (can_move_where) { - const auto & expr_it = asts_to_join_on.find(i); - if (expr_it != asts_to_join_on.end()) + for (size_t i = 1; i < joined_tables.size(); ++i) { - if (joined_tables[i].rewriteCrossToInner(makeOnExpression(expr_it->second))) - data.done = true; + const auto & expr_it = asts_to_join_on.find(i); + if (expr_it != asts_to_join_on.end()) + { + if (joined_tables[i].rewriteCrossToInner(makeOnExpression(expr_it->second))) + data.done = true; + } } } } diff --git a/src/Interpreters/CrossToInnerJoinVisitor.h b/src/Interpreters/CrossToInnerJoinVisitor.h index 7cd5c93b1e3..885cf8162c1 100644 --- a/src/Interpreters/CrossToInnerJoinVisitor.h +++ b/src/Interpreters/CrossToInnerJoinVisitor.h @@ -19,6 +19,7 @@ public: const Aliases & aliases; const String current_database; bool done = false; + bool cross_to_inner_join_rewrite = true; }; static bool needChildVisit(ASTPtr &, const ASTPtr &); diff --git a/src/Interpreters/InterpreterSelectQuery.cpp b/src/Interpreters/InterpreterSelectQuery.cpp index 84de6fa4e6c..37d54e01a71 100644 --- a/src/Interpreters/InterpreterSelectQuery.cpp +++ b/src/Interpreters/InterpreterSelectQuery.cpp @@ -197,7 +197,7 @@ static Context getSubqueryContext(const Context & context) return subquery_context; } -static void rewriteMultipleJoins(ASTPtr & query, const TablesWithColumns & tables, const String & database) +static void rewriteMultipleJoins(ASTPtr & query, const TablesWithColumns & tables, const String & database, const Settings & settings) { ASTSelectQuery & select = query->as(); @@ -207,6 +207,7 @@ static void rewriteMultipleJoins(ASTPtr & query, const TablesWithColumns & table QueryAliasesNoSubqueriesVisitor(aliases).visit(select.select()); CrossToInnerJoinVisitor::Data cross_to_inner{tables, aliases, database}; + cross_to_inner.cross_to_inner_join_rewrite = settings.cross_to_inner_join_rewrite; CrossToInnerJoinVisitor(cross_to_inner).visit(query); JoinToSubqueryTransformVisitor::Data join_to_subs_data{tables, aliases}; @@ -324,7 +325,7 @@ InterpreterSelectQuery::InterpreterSelectQuery( /// Rewrite JOINs if (!has_input && joined_tables.tablesCount() > 1) { - rewriteMultipleJoins(query_ptr, joined_tables.tablesWithColumns(), context->getCurrentDatabase()); + rewriteMultipleJoins(query_ptr, joined_tables.tablesWithColumns(), context->getCurrentDatabase(), context->getSettingsRef()); joined_tables.reset(getSelectQuery()); joined_tables.resolveTables();