3131#include < Analyzer/QueryTreeBuilder.h>
3232#include < Analyzer/QueryNode.h>
3333#include < Analyzer/ColumnNode.h>
34+ #include < Analyzer/JoinNode.h>
3435#include < Analyzer/InDepthQueryTreeVisitor.h>
3536#include < Storages/StorageDistributed.h>
3637#include < TableFunctions/TableFunctionFactory.h>
@@ -112,7 +113,7 @@ class SearcherVisitor : public InDepthQueryTreeVisitorWithContext<SearcherVisito
112113 using Base = InDepthQueryTreeVisitorWithContext<SearcherVisitor>;
113114 using Base::Base;
114115
115- explicit SearcherVisitor (QueryTreeNodeType type_ , ContextPtr context) : Base(context), type(type_ ) {}
116+ explicit SearcherVisitor (std::unordered_set< QueryTreeNodeType> types_ , ContextPtr context) : Base(context), types(types_ ) {}
116117
117118 bool needChildVisit (QueryTreeNodePtr &, QueryTreeNodePtr & /* child*/ )
118119 {
@@ -126,15 +127,20 @@ class SearcherVisitor : public InDepthQueryTreeVisitorWithContext<SearcherVisito
126127
127128 auto node_type = node->getNodeType ();
128129
129- if (node_type == type)
130+ if (types.contains (node_type))
131+ {
130132 passed_node = node;
133+ passed_type = node_type;
134+ }
131135 }
132136
133137 QueryTreeNodePtr getNode () const { return passed_node; }
138+ std::optional<QueryTreeNodeType> getType () const { return passed_type; }
134139
135140private:
136- QueryTreeNodeType type ;
141+ std::unordered_set< QueryTreeNodeType> types ;
137142 QueryTreeNodePtr passed_node;
143+ std::optional<QueryTreeNodeType> passed_type;
138144};
139145
140146/*
@@ -219,25 +225,36 @@ void IStorageCluster::updateQueryWithJoinToSendIfNeeded(
219225 auto modified_query_tree = query_tree->clone ();
220226 bool need_modify = false ;
221227
222- SearcherVisitor table_function_searcher (QueryTreeNodeType::TABLE_FUNCTION, context);
228+ SearcherVisitor table_function_searcher ({ QueryTreeNodeType::TABLE, QueryTreeNodeType:: TABLE_FUNCTION} , context);
223229 table_function_searcher.visit (query_tree);
224230 auto table_function_node = table_function_searcher.getNode ();
225231 if (!table_function_node)
226232 throw Exception (ErrorCodes::LOGICAL_ERROR, " Can't find table function node" );
227233
228234 if (has_join)
229235 {
230- auto table_function = extractTableFunctionASTPtrFromSelectQuery (query_to_send);
231- auto query_tree_distributed = buildTableFunctionQueryTree (table_function, context);
232- auto & table_function_ast = table_function->as <ASTFunction &>();
233- query_tree_distributed->setAlias (table_function_ast.alias );
236+ QueryTreeNodePtr query_tree_distributed;
237+
238+ auto & query_node = modified_query_tree->as <QueryNode &>();
239+
240+ if (table_function_searcher.getType ().value () == QueryTreeNodeType::TABLE_FUNCTION)
241+ {
242+ auto table_function = extractTableFunctionASTPtrFromSelectQuery (query_to_send);
243+ query_tree_distributed = buildTableFunctionQueryTree (table_function, context);
244+ auto & table_function_ast = table_function->as <ASTFunction &>();
245+ query_tree_distributed->setAlias (table_function_ast.alias );
246+ }
247+ else
248+ {
249+ auto join_node = query_node.getJoinTree ();
250+ query_tree_distributed = join_node->as <JoinNode>()->getLeftTableExpression ()->clone ();
251+ }
234252
235253 // Find add used columns from table function to make proper projection list
236254 CollectUsedColumnsForSourceVisitor collector (table_function_node, context);
237255 collector.visit (query_tree);
238256 const auto & columns = collector.getColumns ();
239257
240- auto & query_node = modified_query_tree->as <QueryNode &>();
241258 query_node.resolveProjectionColumns (columns);
242259 auto column_nodes_to_select = std::make_shared<ListNode>();
243260 column_nodes_to_select->getNodes ().reserve (columns.size ());
@@ -501,25 +518,27 @@ QueryProcessingStage::Enum IStorageCluster::getQueryProcessingStage(
501518 throw Exception (ErrorCodes::NOT_IMPLEMENTED,
502519 " object_storage_cluster_join_mode!='allow' is not supported without allow_experimental_analyzer=true" );
503520
504- SearcherVisitor join_searcher (QueryTreeNodeType::JOIN, context);
521+ SearcherVisitor join_searcher ({ QueryTreeNodeType::JOIN} , context);
505522 join_searcher.visit (query_info.query_tree );
506523 if (join_searcher.getNode ())
507524 has_join = true ;
508525
509- SearcherVisitor table_function_searcher (QueryTreeNodeType::TABLE_FUNCTION, context);
526+ SearcherVisitor table_function_searcher ({ QueryTreeNodeType::TABLE, QueryTreeNodeType:: TABLE_FUNCTION} , context);
510527 table_function_searcher.visit (query_info.query_tree );
511528 auto table_function_node = table_function_searcher.getNode ();
512529 if (!table_function_node)
513- throw Exception (ErrorCodes::LOGICAL_ERROR, " Can't find table function node" );
530+ throw Exception (ErrorCodes::LOGICAL_ERROR, " Can't find table or table function node" );
514531
515- CollectUsedColumnsForSourceVisitor collector_where (table_function_node, context, true );
516532 auto & query_node = query_info.query_tree ->as <QueryNode &>();
517533 if (query_node.hasWhere ())
534+ {
535+ CollectUsedColumnsForSourceVisitor collector_where (table_function_node, context, true );
518536 collector_where.visit (query_node.getWhere ());
519537
520- // Can't use 'WHERE' on remote node if it contains columns from other sources
521- if (!collector_where.getColumns ().empty ())
522- has_local_columns_in_where = true ;
538+ // Can't use 'WHERE' on remote node if it contains columns from other sources
539+ if (!collector_where.getColumns ().empty ())
540+ has_local_columns_in_where = true ;
541+ }
523542
524543 if (has_join || has_local_columns_in_where)
525544 return QueryProcessingStage::Enum::FetchColumns;
0 commit comments