diff --git a/ydb/library/yql/core/type_ann/type_ann_pg.cpp b/ydb/library/yql/core/type_ann/type_ann_pg.cpp index 56237c8abcd7..04e6d45bce42 100644 --- a/ydb/library/yql/core/type_ann/type_ann_pg.cpp +++ b/ydb/library/yql/core/type_ann/type_ann_pg.cpp @@ -1823,7 +1823,7 @@ bool ScanColumns(TExprNode::TPtr root, TInputs& inputs, const THashSet& } } - if (x.Order && x.Order->IsDuplicated(TString(node->Tail().Content()))) { + if (x.Order && x.Order->IsDuplicatedIgnoreCase(TString(node->Tail().Content()))) { ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(node->Pos()), TStringBuilder() << "Column reference is ambiguous: " << node->Tail().Content())); isError = true; diff --git a/ydb/library/yql/core/ut/yql_column_order_ut.cpp b/ydb/library/yql/core/ut/yql_column_order_ut.cpp index 9af0fb4f6989..38e012b5dfda 100644 --- a/ydb/library/yql/core/ut/yql_column_order_ut.cpp +++ b/ydb/library/yql/core/ut/yql_column_order_ut.cpp @@ -32,6 +32,13 @@ Y_UNIT_TEST_SUITE(TYqlColumnOrder) { UNIT_ASSERT_EQUAL(order.AddColumn("a_generated_2_generated_2"), "a_generated_2_generated_2_generated_2"); } + Y_UNIT_TEST(ColumnOrderCaseSensetive) { + TColumnOrder order; + UNIT_ASSERT_EQUAL(order.AddColumn("a"), "a"); + UNIT_ASSERT_EQUAL(order.AddColumn("A"), "A"); + UNIT_ASSERT_EQUAL(order.IsDuplicatedIgnoreCase("a"), true); + } + Y_UNIT_TEST(ColumnOrderGeneratedMatchOverVectorCtor) { TColumnOrder order(TVector{"a", "a", "a_generated_2", "a_generated_2_generated_2"}); TVector got(order.begin(), order.end()); diff --git a/ydb/library/yql/core/yql_type_annotation.cpp b/ydb/library/yql/core/yql_type_annotation.cpp index b565f615650c..92eed308c1b2 100644 --- a/ydb/library/yql/core/yql_type_annotation.cpp +++ b/ydb/library/yql/core/yql_type_annotation.cpp @@ -137,11 +137,12 @@ TColumnOrder::TColumnOrder(const TVector& order) { TString TColumnOrder::AddColumn(const TString& name) { auto lcase = to_lower(name); - if (uint64_t count = ++UseCount_[lcase]; count > 1) { + ++UseCountLcase_[lcase]; + if (uint64_t count = ++UseCount_[name]; count > 1) { TString generated = name + "_generated_" + ToString(count); GeneratedToOriginal_[generated] = name; Order_.emplace_back(name, generated); - ++UseCount_[to_lower(generated)]; + ++UseCount_[generated]; return generated; } Order_.emplace_back(name, name); @@ -149,20 +150,19 @@ TString TColumnOrder::AddColumn(const TString& name) { return name; } -bool TColumnOrder::IsDuplicated(const TString& name) const { - auto it = UseCount_.find(to_lower(name)); +bool TColumnOrder::IsDuplicatedIgnoreCase(const TString& name) const { + auto it = UseCountLcase_.find(to_lower(name)); return it != UseCount_.end() && it->second > 1; } void TColumnOrder::Shrink(size_t remain) { for (size_t i = remain; i < Order_.size(); ++i) { - auto logicalLcase = to_lower(Order_[i].LogicalName); - if (!--UseCount_[logicalLcase]) { - UseCount_.erase(logicalLcase); + --UseCountLcase_[to_lower(Order_[i].LogicalName)]; + if (!--UseCount_[Order_[i].LogicalName]) { + UseCount_.erase(Order_[i].LogicalName); } - auto physicalLcase = to_lower(Order_[i].PhysicalName); - if (!--UseCount_[physicalLcase]) { - UseCount_.erase(physicalLcase); + if (!--UseCount_[Order_[i].PhysicalName]) { + UseCount_.erase(Order_[i].PhysicalName); } GeneratedToOriginal_.erase(Order_[i].PhysicalName); } diff --git a/ydb/library/yql/core/yql_type_annotation.h b/ydb/library/yql/core/yql_type_annotation.h index dbc63d61d5f3..2c4c32aa9122 100644 --- a/ydb/library/yql/core/yql_type_annotation.h +++ b/ydb/library/yql/core/yql_type_annotation.h @@ -170,7 +170,7 @@ class TColumnOrder { explicit TColumnOrder(const TVector& order); TString AddColumn(const TString& name); - bool IsDuplicated(const TString& name) const; + bool IsDuplicatedIgnoreCase(const TString& name) const; void Shrink(size_t remain); @@ -213,6 +213,7 @@ class TColumnOrder { private: THashMap GeneratedToOriginal_; THashMap UseCount_; + THashMap UseCountLcase_; // (name, generated_name) TVector Order_; };