@@ -1743,19 +1743,26 @@ bool hasTableExpressionInJoinTree(const QueryTreeNodePtr & join_tree_node, const
17431743 if (node_to_process == table_expression)
17441744 return true ;
17451745
1746- if (node_to_process->getNodeType () == QueryTreeNodeType::JOIN)
1746+ auto node_type = node_to_process->getNodeType ();
1747+
1748+ if (node_type == QueryTreeNodeType::JOIN)
17471749 {
17481750 const auto & join_node = node_to_process->as <JoinNode &>();
17491751 nodes_to_process.push_back (join_node.getLeftTableExpression ());
17501752 nodes_to_process.push_back (join_node.getRightTableExpression ());
17511753 }
1752-
1753- if (node_to_process->getNodeType () == QueryTreeNodeType::CROSS_JOIN)
1754+ else if (node_type == QueryTreeNodeType::CROSS_JOIN)
17541755 {
17551756 const auto & join_node = node_to_process->as <CrossJoinNode &>();
17561757 for (const auto & expr : join_node.getTableExpressions ())
17571758 nodes_to_process.push_back (expr);
17581759 }
1760+ else if (node_type == QueryTreeNodeType::ARRAY_JOIN)
1761+ {
1762+ const auto & array_join_node = node_to_process->as <ArrayJoinNode &>();
1763+ nodes_to_process.push_back (array_join_node.getTableExpression ());
1764+ }
1765+
17591766 }
17601767 return false ;
17611768}
@@ -2203,6 +2210,8 @@ QueryAnalyzer::QueryTreeNodesWithNames QueryAnalyzer::resolveUnqualifiedMatcher(
22032210 table_expression_columns,
22042211 scope);
22052212
2213+ updateMatchedColumnsFromJoinUsing (matched_column_nodes_with_names, table_expression, scope);
2214+
22062215 table_expressions_column_nodes_with_names_stack.push_back (std::move (matched_column_nodes_with_names));
22072216 }
22082217
@@ -5202,6 +5211,58 @@ void QueryAnalyzer::resolveCrossJoin(QueryTreeNodePtr & cross_join_node, Identif
52025211 }
52035212}
52045213
5214+ static NameSet getColumnsFromTableExpression (const QueryTreeNodePtr & table_expression)
5215+ {
5216+ NameSet existing_columns;
5217+ switch (table_expression->getNodeType ())
5218+ {
5219+ case QueryTreeNodeType::TABLE: {
5220+ const auto * table_node = table_expression->as <TableNode>();
5221+ chassert (table_node);
5222+
5223+ auto get_column_options = GetColumnsOptions (GetColumnsOptions::AllPhysical).withSubcolumns ();
5224+ for (const auto & column : table_node->getStorageSnapshot ()->getColumns (get_column_options))
5225+ existing_columns.insert (column.name );
5226+
5227+ return existing_columns;
5228+ }
5229+ case QueryTreeNodeType::TABLE_FUNCTION: {
5230+ const auto * table_function_node = table_expression->as <TableFunctionNode>();
5231+ chassert (table_function_node);
5232+
5233+ auto get_column_options = GetColumnsOptions (GetColumnsOptions::AllPhysical).withSubcolumns ();
5234+ for (const auto & column : table_function_node->getStorageSnapshot ()->getColumns (get_column_options))
5235+ existing_columns.insert (column.name );
5236+
5237+ return existing_columns;
5238+ }
5239+ case QueryTreeNodeType::QUERY: {
5240+ const auto * query_node = table_expression->as <QueryNode>();
5241+ chassert (query_node);
5242+
5243+ for (const auto & column : query_node->getProjectionColumns ())
5244+ existing_columns.insert (column.name );
5245+
5246+ return existing_columns;
5247+ }
5248+ case QueryTreeNodeType::UNION: {
5249+ const auto * union_node = table_expression->as <UnionNode>();
5250+ chassert (union_node);
5251+
5252+ for (const auto & column : union_node->computeProjectionColumns ())
5253+ existing_columns.insert (column.name );
5254+
5255+ return existing_columns;
5256+ }
5257+ default :
5258+ throw Exception (
5259+ ErrorCodes::LOGICAL_ERROR,
5260+ " Expected TableNode, TableFunctionNode, QueryNode or UnionNode, got {}: {}" ,
5261+ table_expression->getNodeTypeName (),
5262+ table_expression->formatASTForErrorMessage ());
5263+ }
5264+ }
5265+
52055266// / Resolve join node in scope
52065267void QueryAnalyzer::resolveJoin (QueryTreeNodePtr & join_node, IdentifierResolveScope & scope, QueryExpressionsAliasVisitor & expressions_visitor)
52075268{
@@ -5286,11 +5347,15 @@ void QueryAnalyzer::resolveJoin(QueryTreeNodePtr & join_node, IdentifierResolveS
52865347 const auto & resolved_nodes = left_subquery->getProjection ().getNodes ();
52875348 if (resolved_nodes.size () == 1 )
52885349 {
5350+ // / Added column should not conflict with existing column names
5351+ NameSet existing_columns = getColumnsFromTableExpression (left_table_expression);
5352+
5353+ NameAndTypePair column_name_type (identifier_full_name_, resolved_nodes.front ()->getResultType ());
5354+ while (existing_columns.contains (column_name_type.name ))
5355+ column_name_type.name = " _" + column_name_type.name ;
5356+
52895357 // / Create ColumnNode with expression from parent projection
5290- return std::make_shared<ColumnNode>(
5291- NameAndTypePair{identifier_full_name_, resolved_nodes.front ()->getResultType ()},
5292- resolved_nodes.front (),
5293- left_table_expression);
5358+ return std::make_shared<ColumnNode>(std::move (column_name_type), resolved_nodes.front (), left_table_expression);
52945359 }
52955360 }
52965361 }
@@ -5324,7 +5389,7 @@ void QueryAnalyzer::resolveJoin(QueryTreeNodePtr & join_node, IdentifierResolveS
53245389 {
53255390 String extra_message;
53265391 const QueryNode * query_node = scope.scope_node ? scope.scope_node ->as <QueryNode>() : nullptr ;
5327- if (settings[Setting::analyzer_compatibility_join_using_top_level_identifier] && query_node)
5392+ if (! settings[Setting::analyzer_compatibility_join_using_top_level_identifier] && query_node)
53285393 {
53295394 for (const auto & projection_node : query_node->getProjection ().getNodes ())
53305395 {
0 commit comments