2626#include " iceberg/util/formatter.h" // IWYU pragma: keep
2727#include " iceberg/util/macros.h"
2828#include " iceberg/util/visit_type.h"
29+
2930namespace iceberg {
30- class IdVisitor {
31+ class IdToFieldVisitor {
3132 public:
32- explicit IdVisitor (
33+ explicit IdToFieldVisitor (
3334 std::unordered_map<int32_t , std::reference_wrapper<const SchemaField>>&
3435 id_to_field);
3536 Status Visit (const Type& type);
@@ -38,9 +39,10 @@ class IdVisitor {
3839 private:
3940 std::unordered_map<int32_t , std::reference_wrapper<const SchemaField>>& id_to_field_;
4041};
42+
4143class NametoIdVisitor {
4244 public:
43- explicit NametoIdVisitor (std::unordered_map<std::string, size_t >& name_to_id,
45+ explicit NametoIdVisitor (std::unordered_map<std::string, int32_t >& name_to_id,
4446 bool case_sensitive_ = true );
4547 Status Visit (const ListType& type, const std::string& path,
4648 const std::string& short_path);
@@ -50,13 +52,14 @@ class NametoIdVisitor {
5052 const std::string& short_path);
5153 Status Visit (const PrimitiveType& type, const std::string& path,
5254 const std::string& short_path);
53- static std::string GetPath ( const std::string& last_path, const std::string& field_name,
54- bool case_sensitive = true );
55+ static std::string BuildPath ( std::string_view prefix, std::string_view field_name,
56+ bool case_sensitive );
5557
5658 private:
5759 bool case_sensitive_;
58- std::unordered_map<std::string, size_t >& name_to_id_;
60+ std::unordered_map<std::string, int32_t >& name_to_id_;
5961};
62+
6063Schema::Schema (std::vector<SchemaField> fields, std::optional<int32_t > schema_id)
6164 : StructType(std::move(fields)), schema_id_(schema_id) {}
6265
@@ -100,7 +103,7 @@ Result<Status> Schema::InitIdToIndexMap() const {
100103 if (!id_to_field_.empty ()) {
101104 return {};
102105 }
103- IdVisitor visitor (id_to_field_);
106+ IdToFieldVisitor visitor (id_to_field_);
104107 ICEBERG_RETURN_UNEXPECTED (VisitTypeInline (*this , &visitor));
105108 return {};
106109}
@@ -135,18 +138,18 @@ Result<std::optional<std::reference_wrapper<const SchemaField>>> Schema::FindFie
135138 return it->second ;
136139}
137140
138- IdVisitor::IdVisitor (
141+ IdToFieldVisitor::IdToFieldVisitor (
139142 std::unordered_map<int32_t , std::reference_wrapper<const SchemaField>>& id_to_field)
140143 : id_to_field_(id_to_field) {}
141144
142- Status IdVisitor ::Visit (const Type& type) {
145+ Status IdToFieldVisitor ::Visit (const Type& type) {
143146 if (type.is_nested ()) {
144147 ICEBERG_RETURN_UNEXPECTED (VisitNestedType (type));
145148 }
146149 return {};
147150}
148151
149- Status IdVisitor ::VisitNestedType (const Type& type) {
152+ Status IdToFieldVisitor ::VisitNestedType (const Type& type) {
150153 const auto & nested = iceberg::internal::checked_cast<const NestedType&>(type);
151154 const auto & fields = nested.fields ();
152155 for (const auto & field : fields) {
@@ -156,59 +159,58 @@ Status IdVisitor::VisitNestedType(const Type& type) {
156159 return {};
157160}
158161
159- NametoIdVisitor::NametoIdVisitor (std::unordered_map<std::string, size_t >& name_to_id,
162+ NametoIdVisitor::NametoIdVisitor (std::unordered_map<std::string, int32_t >& name_to_id,
160163 bool case_sensitive)
161164 : name_to_id_(name_to_id), case_sensitive_(case_sensitive) {}
162165
163166Status NametoIdVisitor::Visit (const ListType& type, const std::string& path,
164167 const std::string& short_path) {
165168 const auto & field = type.fields ()[0 ];
166- std::string full_path = GetPath (path, std::string ( field.name () ), case_sensitive_);
167- std::string short_full_path ;
169+ std::string new_path = BuildPath (path, field.name (), case_sensitive_);
170+ std::string new_short_path ;
168171 if (field.type ()->type_id () == TypeId::kStruct ) {
169- short_full_path = short_path;
172+ new_short_path = short_path;
170173 } else {
171- short_full_path = GetPath (short_path, std::string ( field.name () ), case_sensitive_);
174+ new_short_path = BuildPath (short_path, field.name (), case_sensitive_);
172175 }
173- name_to_id_[full_path ] = field.field_id ();
174- name_to_id_.emplace (short_full_path , field.field_id ());
176+ name_to_id_[new_path ] = field.field_id ();
177+ name_to_id_.emplace (new_short_path , field.field_id ());
175178 ICEBERG_RETURN_UNEXPECTED (
176- VisitTypeInline (*field.type (), this , full_path, short_full_path ));
179+ VisitTypeInline (*field.type (), this , new_path, new_short_path ));
177180 return {};
178181}
179182
180183Status NametoIdVisitor::Visit (const MapType& type, const std::string& path,
181184 const std::string& short_path) {
182- std::string full_path, short_full_path ;
185+ std::string new_path, new_short_path ;
183186 const auto & fields = type.fields ();
184187 for (const auto & field : fields) {
185- full_path = GetPath (path, std::string ( field.name () ), case_sensitive_);
188+ new_path = BuildPath (path, field.name (), case_sensitive_);
186189 if (field.name () == MapType::kValueName &&
187190 field.type ()->type_id () == TypeId::kStruct ) {
188- short_full_path = short_path;
191+ new_short_path = short_path;
189192 } else {
190- short_full_path = GetPath (path, std::string ( field.name () ), case_sensitive_);
193+ new_short_path = BuildPath (short_path, field.name (), case_sensitive_);
191194 }
192- name_to_id_[full_path ] = field.field_id ();
193- name_to_id_.emplace (short_full_path , field.field_id ());
195+ name_to_id_[new_path ] = field.field_id ();
196+ name_to_id_.emplace (new_short_path , field.field_id ());
194197 ICEBERG_RETURN_UNEXPECTED (
195- VisitTypeInline (*field.type (), this , full_path, short_full_path ));
198+ VisitTypeInline (*field.type (), this , new_path, new_short_path ));
196199 }
197200 return {};
198201}
199202
200203Status NametoIdVisitor::Visit (const StructType& type, const std::string& path,
201204 const std::string& short_path) {
202205 const auto & fields = type.fields ();
203- std::string full_path, short_full_path ;
206+ std::string new_path, new_short_path ;
204207 for (const auto & field : fields) {
205- full_path =
206- NametoIdVisitor::GetPath (path, std::string (field.name ()), case_sensitive_);
207- short_full_path = GetPath (short_path, std::string (field.name ()), case_sensitive_);
208- name_to_id_[full_path] = field.field_id ();
209- name_to_id_.emplace (short_full_path, field.field_id ());
208+ new_path = BuildPath (path, field.name (), case_sensitive_);
209+ new_short_path = BuildPath (short_path, field.name (), case_sensitive_);
210+ name_to_id_[new_path] = field.field_id ();
211+ name_to_id_.emplace (new_short_path, field.field_id ());
210212 ICEBERG_RETURN_UNEXPECTED (
211- VisitTypeInline (*field.type (), this , full_path, short_full_path ));
213+ VisitTypeInline (*field.type (), this , new_path, new_short_path ));
212214 }
213215 return {};
214216}
@@ -218,13 +220,14 @@ Status NametoIdVisitor::Visit(const PrimitiveType& type, const std::string& path
218220 return {};
219221}
220222
221- std::string NametoIdVisitor::GetPath ( const std::string& last_path,
222- const std::string& field_name, bool case_sensitive) {
223+ std::string NametoIdVisitor::BuildPath ( std::string_view last_path,
224+ std::string_view field_name, bool case_sensitive) {
223225 if (case_sensitive) {
224- return last_path.empty () ? field_name : last_path + " ." + field_name;
226+ return last_path.empty () ? std::string (field_name)
227+ : std::string (last_path) + " ." + std::string (field_name);
225228 }
226229 std::string lower_name (field_name);
227230 std::ranges::transform (lower_name, lower_name.begin (), ::tolower);
228- return last_path.empty () ? lower_name : last_path + " ." + lower_name;
231+ return last_path.empty () ? lower_name : std::string ( last_path) + " ." + lower_name;
229232}
230233} // namespace iceberg
0 commit comments