From f2cd222f196cbb285fba8284cb1bbfe70d8df62b Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Mon, 16 Dec 2024 15:54:53 +0000 Subject: [PATCH] Fix Not-ready Set in JOIN ON (IN subquery) with old analyzer. --- src/Interpreters/ExpressionAnalyzer.cpp | 7 ++++--- src/Interpreters/ExpressionAnalyzer.h | 2 +- src/Interpreters/GlobalSubqueriesVisitor.h | 2 +- src/Interpreters/TableJoin.cpp | 6 ++++-- src/Interpreters/TableJoin.h | 4 +++- .../0_stateless/02841_not_ready_set_join_on.reference | 2 ++ tests/queries/0_stateless/02841_not_ready_set_join_on.sql | 3 +++ 7 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 tests/queries/0_stateless/02841_not_ready_set_join_on.reference create mode 100644 tests/queries/0_stateless/02841_not_ready_set_join_on.sql diff --git a/src/Interpreters/ExpressionAnalyzer.cpp b/src/Interpreters/ExpressionAnalyzer.cpp index 58224239723..24c36998a40 100644 --- a/src/Interpreters/ExpressionAnalyzer.cpp +++ b/src/Interpreters/ExpressionAnalyzer.cpp @@ -1073,12 +1073,13 @@ static std::shared_ptr chooseJoinAlgorithm( static std::unique_ptr buildJoinedPlan( ContextPtr context, + PreparedSetsPtr prepared_sets, const ASTTablesInSelectQueryElement & join_element, TableJoin & analyzed_join, SelectQueryOptions query_options) { /// Actions which need to be calculated on joined block. - auto joined_block_actions = analyzed_join.createJoinedBlockActions(context); + auto joined_block_actions = analyzed_join.createJoinedBlockActions(context, std::move(prepared_sets)); NamesWithAliases required_columns_with_aliases = analyzed_join.getRequiredColumns( Block(joined_block_actions.getResultColumns()), joined_block_actions.getRequiredColumns().getNames()); @@ -1184,7 +1185,7 @@ JoinPtr SelectQueryExpressionAnalyzer::makeJoin( if (auto storage = analyzed_join->getStorageJoin()) { - auto joined_block_actions = analyzed_join->createJoinedBlockActions(getContext()); + auto joined_block_actions = analyzed_join->createJoinedBlockActions(getContext(), getPreparedSets()); NamesWithAliases required_columns_with_aliases = analyzed_join->getRequiredColumns( Block(joined_block_actions.getResultColumns()), joined_block_actions.getRequiredColumns().getNames()); @@ -1197,7 +1198,7 @@ JoinPtr SelectQueryExpressionAnalyzer::makeJoin( return storage->getJoinLocked(analyzed_join, getContext(), original_right_column_names); } - joined_plan = buildJoinedPlan(getContext(), join_element, *analyzed_join, query_options); + joined_plan = buildJoinedPlan(getContext(), getPreparedSets(), join_element, *analyzed_join, query_options); const ColumnsWithTypeAndName & right_columns = joined_plan->getCurrentHeader().getColumnsWithTypeAndName(); std::tie(left_convert_actions, right_convert_actions) = analyzed_join->createConvertingActions(left_columns, right_columns); diff --git a/src/Interpreters/ExpressionAnalyzer.h b/src/Interpreters/ExpressionAnalyzer.h index 5e3e1f81ca1..818a8e1d64a 100644 --- a/src/Interpreters/ExpressionAnalyzer.h +++ b/src/Interpreters/ExpressionAnalyzer.h @@ -126,7 +126,7 @@ public: * That is, you need to call getSetsWithSubqueries after all calls of `append*` or `getActions` * and create all the returned sets before performing the actions. */ - PreparedSetsPtr getPreparedSets() { return prepared_sets; } + PreparedSetsPtr & getPreparedSets() { return prepared_sets; } /// Get intermediates for tests const ExpressionAnalyzerData & getAnalyzedData() const { return *this; } diff --git a/src/Interpreters/GlobalSubqueriesVisitor.h b/src/Interpreters/GlobalSubqueriesVisitor.h index e1d5f9b62a7..bfbc6152b38 100644 --- a/src/Interpreters/GlobalSubqueriesVisitor.h +++ b/src/Interpreters/GlobalSubqueriesVisitor.h @@ -300,7 +300,7 @@ private: /// This code is partial copy-paste from ExpressionAnalyzer. if (data.table_join) { - auto joined_block_actions = data.table_join->createJoinedBlockActions(data.getContext()); + auto joined_block_actions = data.table_join->createJoinedBlockActions(data.getContext(), data.prepared_sets); NamesWithAliases required_columns_with_aliases = data.table_join->getRequiredColumns( Block(joined_block_actions.getResultColumns()), joined_block_actions.getRequiredColumns().getNames()); diff --git a/src/Interpreters/TableJoin.cpp b/src/Interpreters/TableJoin.cpp index 4c0ff66afd6..2697e29473d 100644 --- a/src/Interpreters/TableJoin.cpp +++ b/src/Interpreters/TableJoin.cpp @@ -1012,11 +1012,13 @@ bool TableJoin::allowParallelHashJoin() const return true; } -ActionsDAG TableJoin::createJoinedBlockActions(ContextPtr context) const +ActionsDAG TableJoin::createJoinedBlockActions(ContextPtr context, PreparedSetsPtr prepared_sets) const { ASTPtr expression_list = rightKeysList(); auto syntax_result = TreeRewriter(context).analyze(expression_list, columnsFromJoinedTable()); - return ExpressionAnalyzer(expression_list, syntax_result, context).getActionsDAG(true, false); + ExpressionAnalyzer analyzer(expression_list, syntax_result, context); + analyzer.getPreparedSets() = std::move(prepared_sets); + return analyzer.getActionsDAG(true, false); } size_t TableJoin::getMaxMemoryUsage() const diff --git a/src/Interpreters/TableJoin.h b/src/Interpreters/TableJoin.h index 7f3dd0d54cd..07df6467475 100644 --- a/src/Interpreters/TableJoin.h +++ b/src/Interpreters/TableJoin.h @@ -47,6 +47,8 @@ struct Settings; class IVolume; using VolumePtr = std::shared_ptr; +class PreparedSets; +using PreparedSetsPtr = std::shared_ptr; class TableJoin { public: @@ -280,7 +282,7 @@ public: void assertEnableEnalyzer() const; TemporaryDataOnDiskScopePtr getTempDataOnDisk() { return tmp_data ? tmp_data->childScope(CurrentMetrics::TemporaryFilesForJoin) : nullptr; } - ActionsDAG createJoinedBlockActions(ContextPtr context) const; + ActionsDAG createJoinedBlockActions(ContextPtr context, PreparedSetsPtr prepared_sets) const; const std::vector & getEnabledJoinAlgorithms() const { return join_algorithm; } diff --git a/tests/queries/0_stateless/02841_not_ready_set_join_on.reference b/tests/queries/0_stateless/02841_not_ready_set_join_on.reference new file mode 100644 index 00000000000..e6099305fcc --- /dev/null +++ b/tests/queries/0_stateless/02841_not_ready_set_join_on.reference @@ -0,0 +1,2 @@ +42 42 +42 42 diff --git a/tests/queries/0_stateless/02841_not_ready_set_join_on.sql b/tests/queries/0_stateless/02841_not_ready_set_join_on.sql new file mode 100644 index 00000000000..698e6f5c0b6 --- /dev/null +++ b/tests/queries/0_stateless/02841_not_ready_set_join_on.sql @@ -0,0 +1,3 @@ +with l_t as (select 42 as key) select * from l_t inner join numbers(50) as r_t on l_t.key = r_t.number and r_t.number in (select number * 2 from numbers(1e3)) settings allow_experimental_analyzer=0; +with l_t as (select 42 as key) select * from l_t inner join numbers(50) as r_t on l_t.key = r_t.number and r_t.number in (select number * 2 from numbers(1e3)) settings allow_experimental_analyzer=1; +