Skip to content

Commit f344ac2

Browse files
fix avro schema util
1 parent c9ff700 commit f344ac2

1 file changed

Lines changed: 76 additions & 22 deletions

File tree

src/iceberg/avro/avro_schema_util.cc

Lines changed: 76 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,25 @@ Result<::avro::NodePtr> CreateArrayNodeWithFieldIds(const ::avro::NodePtr& origi
852852
ICEBERG_ASSIGN_OR_RAISE(auto new_element_node,
853853
MakeAvroNodeWithFieldIds(original_node->leafAt(0), field));
854854
new_array_node->addLeaf(new_element_node);
855+
856+
// Check and add custom attributes
857+
if (original_node->customAttributes() > 0) {
858+
::avro::CustomAttributes merged_attributes;
859+
const auto& original_attrs = original_node->customAttributesAt(0);
860+
const auto& existing_attrs = original_attrs.attributes();
861+
for (const auto& attr_pair : existing_attrs) {
862+
// Skip element-id as we might set it differently
863+
if (attr_pair.first != kElementIdProp) {
864+
merged_attributes.addAttribute(attr_pair.first, attr_pair.second,
865+
/*addQuote=*/false);
866+
}
867+
}
868+
// Add merged attributes if we found any
869+
if (merged_attributes.attributes().size() > 0) {
870+
new_array_node->addCustomAttributesForField(merged_attributes);
871+
}
872+
}
873+
855874
return new_array_node;
856875
}
857876

@@ -871,12 +890,29 @@ Result<::avro::NodePtr> CreateArrayNodeWithFieldIds(const ::avro::NodePtr& origi
871890
MakeAvroNodeWithFieldIds(original_node->leafAt(0), element_field));
872891
new_array_node->addLeaf(new_element_node);
873892

874-
// Add element field ID as custom attribute
875-
::avro::CustomAttributes element_attributes;
876-
element_attributes.addAttribute(std::string(kElementIdProp),
877-
std::to_string(*element_field.field_id),
878-
/*addQuote=*/false);
879-
new_array_node->addCustomAttributesForField(element_attributes);
893+
// Create merged custom attributes with element field ID
894+
::avro::CustomAttributes merged_attributes;
895+
896+
// First add our element field ID (highest priority)
897+
merged_attributes.addAttribute(std::string(kElementIdProp),
898+
std::to_string(*element_field.field_id),
899+
/*addQuote=*/false);
900+
901+
// Then merge any custom attributes from original node (except element-id)
902+
if (original_node->customAttributes() > 0) {
903+
const auto& original_attrs = original_node->customAttributesAt(0);
904+
const auto& existing_attrs = original_attrs.attributes();
905+
for (const auto& attr_pair : existing_attrs) {
906+
// Skip element-id as we've already set it above
907+
if (attr_pair.first != kElementIdProp) {
908+
merged_attributes.addAttribute(attr_pair.first, attr_pair.second,
909+
/*addQuote=*/false);
910+
}
911+
}
912+
}
913+
914+
// Add all attributes at once
915+
new_array_node->addCustomAttributesForField(merged_attributes);
880916

881917
return new_array_node;
882918
}
@@ -917,29 +953,47 @@ Result<::avro::NodePtr> CreateMapNodeWithFieldIds(const ::avro::NodePtr& origina
917953
new_map_node->addLeaf(new_key_node);
918954
new_map_node->addLeaf(new_value_node);
919955

920-
// Preserve existing custom attributes from the original node and add field ID
921-
// attributes Copy existing attributes from the original node (if any)
922-
if (original_node->customAttributes() > 0) {
923-
const auto& original_attrs = original_node->customAttributesAt(0);
924-
const auto& existing_attrs = original_attrs.attributes();
925-
for (const auto& attr_pair : existing_attrs) {
926-
// Copy each existing attribute to preserve original metadata
927-
::avro::CustomAttributes attributes;
928-
attributes.addAttribute(attr_pair.first, attr_pair.second, /*addQuote=*/false);
929-
new_map_node->addCustomAttributesForField(attributes);
930-
}
931-
}
932-
956+
// Create key and value attributes
933957
::avro::CustomAttributes key_attributes;
958+
::avro::CustomAttributes value_attributes;
959+
960+
// Add required field IDs
934961
key_attributes.addAttribute(std::string(kKeyIdProp),
935962
std::to_string(*key_mapped_field.field_id),
936963
/*addQuote=*/false);
937-
new_map_node->addCustomAttributesForField(key_attributes);
938-
939-
::avro::CustomAttributes value_attributes;
940964
value_attributes.addAttribute(std::string(kValueIdProp),
941965
std::to_string(*value_mapped_field.field_id),
942966
/*addQuote=*/false);
967+
968+
// Merge custom attributes from original node if they exist
969+
if (original_node->customAttributes() > 0) {
970+
// Merge attributes for key (index 0)
971+
const auto& original_key_attrs = original_node->customAttributesAt(0);
972+
const auto& existing_key_attrs = original_key_attrs.attributes();
973+
for (const auto& attr_pair : existing_key_attrs) {
974+
// Skip if it's the key ID property we're already setting
975+
if (attr_pair.first != kKeyIdProp) {
976+
key_attributes.addAttribute(attr_pair.first, attr_pair.second,
977+
/*addQuote=*/false);
978+
}
979+
}
980+
981+
// Merge attributes for value (index 1)
982+
if (original_node->customAttributes() > 1) {
983+
const auto& original_value_attrs = original_node->customAttributesAt(1);
984+
const auto& existing_value_attrs = original_value_attrs.attributes();
985+
for (const auto& attr_pair : existing_value_attrs) {
986+
// Skip if it's the value ID property we're already setting
987+
if (attr_pair.first != kValueIdProp) {
988+
value_attributes.addAttribute(attr_pair.first, attr_pair.second,
989+
/*addQuote=*/false);
990+
}
991+
}
992+
}
993+
}
994+
995+
// Add the merged attributes to the new map node
996+
new_map_node->addCustomAttributesForField(key_attributes);
943997
new_map_node->addCustomAttributesForField(value_attributes);
944998

945999
return new_map_node;

0 commit comments

Comments
 (0)