Skip to content

Commit 38a45e4

Browse files
committed
Join for tables
1 parent cf4d137 commit 38a45e4

File tree

4 files changed

+43
-17
lines changed

4 files changed

+43
-17
lines changed

src/Planner/PlannerJoinTree.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1370,7 +1370,7 @@ JoinTreeQueryPlan buildQueryPlanForTableExpression(QueryTreeNodePtr table_expres
13701370
/// Overall, IStorage::read -> FetchColumns returns normal column names (except Distributed, which is inconsistent)
13711371
/// Interpreter::getQueryPlan -> FetchColumns returns identifiers (why?) and this the reason for the bug ^ in Distributed
13721372
/// Hopefully there is no other case when we read from Distributed up to FetchColumns.
1373-
if (table_node && table_node->getStorage()->isRemote() && select_query_options.to_stage == QueryProcessingStage::FetchColumns)
1373+
if (table_node && table_node->getStorage()->isRemote())
13741374
updated_actions_dag_outputs.push_back(output_node);
13751375
else if (table_function_node && table_function_node->getStorage()->isRemote())
13761376
updated_actions_dag_outputs.push_back(output_node);

src/Storages/IStorageCluster.cpp

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
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

135140
private:
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;

src/Storages/extractTableFunctionFromSelectQuery.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ ASTPtr extractTableFunctionASTPtrFromSelectQuery(ASTPtr & query)
2626
return table_expression ? table_expression->table_function : nullptr;
2727
}
2828

29+
ASTPtr extractTableASTPtrFromSelectQuery(ASTPtr & query)
30+
{
31+
auto table_expression = extractTableExpressionASTPtrFromSelectQuery(query);
32+
return table_expression ? table_expression->database_and_table_name : nullptr;
33+
}
34+
2935
ASTFunction * extractTableFunctionFromSelectQuery(ASTPtr & query)
3036
{
3137
auto table_function_ast = extractTableFunctionASTPtrFromSelectQuery(query);

src/Storages/extractTableFunctionFromSelectQuery.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ struct ASTTableExpression;
1010

1111
ASTTableExpression * extractTableExpressionASTPtrFromSelectQuery(ASTPtr & query);
1212
ASTPtr extractTableFunctionASTPtrFromSelectQuery(ASTPtr & query);
13+
ASTPtr extractTableASTPtrFromSelectQuery(ASTPtr & query);
1314
ASTFunction * extractTableFunctionFromSelectQuery(ASTPtr & query);
1415
ASTExpressionList * extractTableFunctionArgumentsFromSelectQuery(ASTPtr & query);
1516

0 commit comments

Comments
 (0)