Skip to content

Commit 8b1890e

Browse files
Try to fix test.
1 parent e72161f commit 8b1890e

File tree

3 files changed

+66
-18
lines changed

3 files changed

+66
-18
lines changed

src/Analyzer/Resolve/IdentifierResolveScope.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ struct IdentifierResolveScope
147147
/// Table column name to column node. Valid only during table ALIAS columns resolve.
148148
ColumnNameToColumnNodeMap column_name_to_column_node;
149149

150+
std::list<std::unordered_map<std::string, ColumnNodePtr> *> join_using_columns;
151+
150152
/// CTE name to query node
151153
std::unordered_map<std::string, QueryTreeNodePtr> cte_name_to_query_node;
152154

src/Analyzer/Resolve/IdentifierResolver.cpp

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <Analyzer/Resolve/TypoCorrection.h>
3131

3232
#include <Core/Settings.h>
33+
#include <iostream>
3334

3435
namespace DB
3536
{
@@ -329,6 +330,21 @@ bool IdentifierResolver::tryBindIdentifierToAliases(const IdentifierLookup & ide
329330
return scope.aliases.find(identifier_lookup, ScopeAliases::FindOption::FIRST_NAME) != nullptr;
330331
}
331332

333+
bool IdentifierResolver::tryBindIdentifierToJoinUsingColumn(const IdentifierLookup & identifier_lookup, const IdentifierResolveScope & scope)
334+
{
335+
for (const auto * join_using : scope.join_using_columns)
336+
{
337+
for (const auto & [using_column_name, _] : *join_using)
338+
{
339+
// std::cerr << identifier_lookup.identifier.getFullName() << " <===========> " << using_column_name << std::endl;
340+
if (identifier_lookup.identifier.getFullName() == using_column_name)
341+
return true;
342+
}
343+
}
344+
345+
return false;
346+
}
347+
332348
/** Resolve identifier from table columns.
333349
*
334350
* 1. If table column nodes are empty or identifier is not expression lookup return nullptr.
@@ -634,11 +650,15 @@ IdentifierResolveResult IdentifierResolver::tryResolveIdentifierFromStorage(
634650
tryBindIdentifierToTableExpressions(column_identifier_lookup, table_expression_node, scope))
635651
break;
636652

653+
if (tryBindIdentifierToJoinUsingColumn(column_identifier_lookup, scope))
654+
break;
655+
637656
qualified_identifier = std::move(qualified_identifier_with_removed_part);
638657
}
639658

640659
auto qualified_identifier_full_name = qualified_identifier.getFullName();
641660
node_to_projection_name.emplace(result_expression, std::move(qualified_identifier_full_name));
661+
// std::cerr << "resolved from storage : " << qualified_identifier.getFullName() << " as " << result_expression->dumpTree() << std::endl;
642662

643663
return { .resolved_identifier = result_expression, .resolve_place = IdentifierResolvePlace::JOIN_TREE };
644664
}
@@ -857,8 +877,36 @@ IdentifierResolveResult IdentifierResolver::tryResolveIdentifierFromJoin(const I
857877
IdentifierResolveScope & scope)
858878
{
859879
const auto & from_join_node = table_expression_node->as<const JoinNode &>();
860-
auto left_resolved_identifier = tryResolveIdentifierFromJoinTreeNode(identifier_lookup, from_join_node.getLeftTableExpression(), scope).resolved_identifier;
861-
auto right_resolved_identifier = tryResolveIdentifierFromJoinTreeNode(identifier_lookup, from_join_node.getRightTableExpression(), scope).resolved_identifier;
880+
JoinKind join_kind = from_join_node.getKind();
881+
882+
bool join_node_in_resolve_process = scope.table_expressions_in_resolve_process.contains(table_expression_node.get());
883+
std::unordered_map<std::string, ColumnNodePtr> join_using_column_name_to_column_node;
884+
885+
if (!join_node_in_resolve_process && from_join_node.isUsingJoinExpression())
886+
{
887+
auto & join_using_list = from_join_node.getJoinExpression()->as<ListNode &>();
888+
for (auto & join_using_node : join_using_list.getNodes())
889+
{
890+
auto & column_node = join_using_node->as<ColumnNode &>();
891+
join_using_column_name_to_column_node.emplace(column_node.getColumnName(), std::static_pointer_cast<ColumnNode>(join_using_node));
892+
}
893+
}
894+
895+
auto try_resolve_identifier_from_join_tree_node = [&](const QueryTreeNodePtr & join_tree_node, bool may_be_override_by_using_column)
896+
{
897+
if (may_be_override_by_using_column && !join_using_column_name_to_column_node.empty())
898+
scope.join_using_columns.push_back(&join_using_column_name_to_column_node);
899+
900+
auto res = tryResolveIdentifierFromJoinTreeNode(identifier_lookup, join_tree_node, scope);
901+
902+
if (may_be_override_by_using_column && !join_using_column_name_to_column_node.empty())
903+
scope.join_using_columns.pop_back();
904+
905+
return std::move(res.resolved_identifier);
906+
};
907+
908+
auto left_resolved_identifier = try_resolve_identifier_from_join_tree_node(from_join_node.getLeftTableExpression(), join_kind == JoinKind::Right);
909+
auto right_resolved_identifier = try_resolve_identifier_from_join_tree_node(from_join_node.getRightTableExpression(), join_kind != JoinKind::Right);
862910

863911
if (!identifier_lookup.isExpressionLookup())
864912
{
@@ -875,20 +923,6 @@ IdentifierResolveResult IdentifierResolver::tryResolveIdentifierFromJoin(const I
875923
};
876924
}
877925

878-
bool join_node_in_resolve_process = scope.table_expressions_in_resolve_process.contains(table_expression_node.get());
879-
880-
std::unordered_map<std::string, ColumnNodePtr> join_using_column_name_to_column_node;
881-
882-
if (!join_node_in_resolve_process && from_join_node.isUsingJoinExpression())
883-
{
884-
auto & join_using_list = from_join_node.getJoinExpression()->as<ListNode &>();
885-
for (auto & join_using_node : join_using_list.getNodes())
886-
{
887-
auto & column_node = join_using_node->as<ColumnNode &>();
888-
join_using_column_name_to_column_node.emplace(column_node.getColumnName(), std::static_pointer_cast<ColumnNode>(join_using_node));
889-
}
890-
}
891-
892926
auto check_nested_column_not_in_using = [&join_using_column_name_to_column_node, &identifier_lookup](const QueryTreeNodePtr & node)
893927
{
894928
/** tldr: When an identifier is resolved into the function `nested` or `getSubcolumn`, and
@@ -950,8 +984,6 @@ IdentifierResolveResult IdentifierResolver::tryResolveIdentifierFromJoin(const I
950984
std::optional<JoinTableSide> resolved_side;
951985
QueryTreeNodePtr resolved_identifier;
952986

953-
JoinKind join_kind = from_join_node.getKind();
954-
955987
auto convert_resolved_result_type_if_needed = [](
956988
const QueryTreeNodePtr & resolved_identifier_candidate,
957989
const std::unordered_map<std::string, ColumnNodePtr> & using_column_name_to_column_node,
@@ -964,12 +996,16 @@ IdentifierResolveResult IdentifierResolver::tryResolveIdentifierFromJoin(const I
964996
if (using_column_node_it != using_column_name_to_column_node.end() &&
965997
!using_column_node_it->second->getColumnType()->equals(*resolved_column.getColumnType()))
966998
{
999+
// std::cerr << "... fixing type for " << resolved_column.dumpTree() << std::endl;
9671000
auto resolved_column_clone = std::static_pointer_cast<ColumnNode>(resolved_column.clone());
9681001
resolved_column_clone->setColumnType(using_column_node_it->second->getColumnType());
9691002

9701003
auto projection_name_it = projection_name_mapping.find(resolved_identifier_candidate);
9711004
if (projection_name_it != projection_name_mapping.end())
1005+
{
9721006
projection_name_mapping[resolved_column_clone] = projection_name_it->second;
1007+
// std::cerr << ".. upd name " << projection_name_it->second << " for col " << resolved_column_clone->dumpTree() << std::endl;
1008+
}
9731009

9741010
resolve_result = std::move(resolved_column_clone);
9751011

@@ -983,6 +1019,10 @@ IdentifierResolveResult IdentifierResolver::tryResolveIdentifierFromJoin(const I
9831019
if (auto missed_subcolumn_identifier = checkIsMissedObjectJSONSubcolumn(left_resolved_identifier, right_resolved_identifier))
9841020
return { .resolved_identifier = missed_subcolumn_identifier, .resolve_place = IdentifierResolvePlace::JOIN_TREE };
9851021

1022+
1023+
// for (const auto & [k, v] : join_using_column_name_to_column_node)
1024+
// std::cerr << k << " -> " << v->dumpTree() << std::endl;
1025+
9861026
if (left_resolved_identifier && right_resolved_identifier)
9871027
{
9881028
auto using_column_node_it = join_using_column_name_to_column_node.end();
@@ -1092,10 +1132,12 @@ IdentifierResolveResult IdentifierResolver::tryResolveIdentifierFromJoin(const I
10921132
auto nullable_resolved_identifier = convertJoinedColumnTypeToNullIfNeeded(resolved_identifier, join_kind, resolved_side, scope);
10931133
if (nullable_resolved_identifier)
10941134
{
1135+
// std::cerr << ".. convert to null " << nullable_resolved_identifier->dumpTree() << std::endl;
10951136
resolved_identifier = nullable_resolved_identifier;
10961137
/// Set the same projection name for new nullable node
10971138
if (projection_name_it != node_to_projection_name.end())
10981139
{
1140+
// std::cerr << "... upd name for null " << projection_name_it->second << " -> " << resolved_identifier->dumpTree() << std::endl;
10991141
node_to_projection_name.emplace(resolved_identifier, projection_name_it->second);
11001142
}
11011143
}

src/Analyzer/Resolve/IdentifierResolver.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ class IdentifierResolver
4848
const IdentifierLookup & identifier_lookup,
4949
const IdentifierResolveScope & scope);
5050

51+
static bool tryBindIdentifierToJoinUsingColumn(
52+
const IdentifierLookup & identifier_lookup,
53+
const IdentifierResolveScope & scope);
54+
5155
static bool tryBindIdentifierToTableExpression(
5256
const IdentifierLookup & identifier_lookup,
5357
const QueryTreeNodePtr & table_expression_node,

0 commit comments

Comments
 (0)