@@ -803,40 +803,37 @@ Result<::avro::NodePtr> CreateRecordNodeWithFieldIds(const ::avro::NodePtr& orig
803803 }
804804 }
805805
806- if (nested_field) {
807- // Check if field_id is present
808- if (!nested_field->field_id .has_value ()) {
809- return InvalidSchema (" Field ID is missing for field '{}' in nested mapping" ,
810- field_name);
811- }
806+ if (!nested_field) {
807+ return InvalidSchema (" Field '{}' not found in nested mapping" , field_name);
808+ }
812809
813- // Preserve existing custom attributes for this field
814- ::avro::CustomAttributes attributes;
815- if (i < original_node->customAttributes ()) {
816- // Copy all existing attributes from the original node
817- const auto & original_attrs = original_node->customAttributesAt (i);
818- const auto & existing_attrs = original_attrs.attributes ();
819- for (const auto & attr_pair : existing_attrs) {
820- // Copy each existing attribute to preserve original metadata
821- attributes.addAttribute (attr_pair.first , attr_pair.second , false );
822- }
810+ if (!nested_field->field_id .has_value ()) {
811+ return InvalidSchema (" Field ID is missing for field '{}' in nested mapping" ,
812+ field_name);
813+ }
814+
815+ // Preserve existing custom attributes for this field
816+ ::avro::CustomAttributes attributes;
817+ if (i < original_node->customAttributes ()) {
818+ // Copy all existing attributes from the original node
819+ for (const auto & attr_pair : original_node->customAttributesAt (i).attributes ()) {
820+ // Copy each existing attribute to preserve original metadata
821+ attributes.addAttribute (attr_pair.first , attr_pair.second , /* addQuote=*/ false );
823822 }
823+ }
824824
825- // Add field ID attribute to the new node (preserving existing attributes)
826- attributes.addAttribute (std::string (kFieldIdProp ),
827- std::to_string (nested_field->field_id .value ()), false );
825+ // Add field ID attribute to the new node (preserving existing attributes)
826+ attributes.addAttribute (std::string (kFieldIdProp ),
827+ std::to_string (nested_field->field_id .value ()),
828+ /* addQuote=*/ false );
828829
829- new_record_node->addCustomAttributesForField (attributes);
830+ new_record_node->addCustomAttributesForField (attributes);
830831
831- // Recursively apply field IDs to nested fields
832- ICEBERG_ASSIGN_OR_RAISE (auto new_nested_node,
833- MakeAvroNodeWithFieldIds (field_node, *nested_field));
834- new_record_node->addName (field_name);
835- new_record_node->addLeaf (new_nested_node);
836- } else {
837- // If no nested field found, this is an error
838- return InvalidSchema (" Field '{}' not found in nested mapping" , field_name);
839- }
832+ // Recursively apply field IDs to nested fields
833+ ICEBERG_ASSIGN_OR_RAISE (auto new_nested_node,
834+ MakeAvroNodeWithFieldIds (field_node, *nested_field));
835+ new_record_node->addName (field_name);
836+ new_record_node->addLeaf (new_nested_node);
840837 }
841838
842839 return new_record_node;
@@ -858,39 +855,29 @@ Result<::avro::NodePtr> CreateArrayNodeWithFieldIds(const ::avro::NodePtr& origi
858855 return new_array_node;
859856 }
860857
861- // For regular arrays, try to find element field ID from nested mapping
862- const MappedField* element_field = nullptr ;
863- if (field.nested_mapping ) {
864- auto fields_span = field.nested_mapping ->fields ();
865- for (const auto & f : fields_span) {
866- if (f.names .find (std::string (kElement )) != f.names .end ()) {
867- element_field = &f;
868- break ;
869- }
870- }
858+ // For regular arrays, use the first field from nested mapping as element field
859+ if (!field.nested_mapping || field.nested_mapping ->fields ().empty ()) {
860+ return InvalidSchema (" Array type requires nested mapping with element field" );
871861 }
872862
873- if (element_field) {
874- // Check if field_id is present
875- if (!element_field->field_id .has_value ()) {
876- return InvalidSchema (" Field ID is missing for element field in array" );
877- }
863+ const auto & element_field = field.nested_mapping ->fields ()[0 ];
878864
879- ICEBERG_ASSIGN_OR_RAISE (
880- auto new_element_node,
881- MakeAvroNodeWithFieldIds (original_node->leafAt (0 ), *element_field));
882- new_array_node->addLeaf (new_element_node);
883-
884- // Add element field ID as custom attribute
885- ::avro::CustomAttributes element_attributes;
886- element_attributes.addAttribute (std::string (kFieldIdProp ),
887- std::to_string (*element_field->field_id ), false );
888- new_array_node->addCustomAttributesForField (element_attributes);
889- } else {
890- // If no element field found, this is an error
891- return InvalidSchema (" Element field not found in nested mapping for array" );
865+ if (!element_field.field_id .has_value ()) {
866+ return InvalidSchema (" Field ID is missing for element field in array" );
892867 }
893868
869+ ICEBERG_ASSIGN_OR_RAISE (
870+ auto new_element_node,
871+ MakeAvroNodeWithFieldIds (original_node->leafAt (0 ), element_field));
872+ new_array_node->addLeaf (new_element_node);
873+
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);
880+
894881 return new_array_node;
895882}
896883
@@ -908,45 +895,25 @@ Result<::avro::NodePtr> CreateMapNodeWithFieldIds(const ::avro::NodePtr& origina
908895 return InvalidSchema (" Map type requires nested mapping for key and value fields" );
909896 }
910897
911- // Find key and value field mappings by name
912- std::optional<int32_t > key_id = field.nested_mapping ->Id (" key" );
913- std::optional<int32_t > value_id = field.nested_mapping ->Id (" value" );
914-
915- if (!key_id || !value_id) {
916- return InvalidSchema (" Map type requires both 'key' and 'value' field mappings" );
917- }
918-
919- std::optional<MappedFieldConstRef> key_field_ref = field.nested_mapping ->Field (*key_id);
920- std::optional<MappedFieldConstRef> value_field_ref =
921- field.nested_mapping ->Field (*value_id);
922-
923- if (!key_field_ref || !value_field_ref) {
924- return InvalidSchema (" Map type requires both key and value field mappings" );
898+ // For map types, use the first two fields from nested mapping as key and value
899+ if (!field.nested_mapping || field.nested_mapping ->fields ().size () < 2 ) {
900+ return InvalidSchema (" Map type requires nested mapping with key and value fields" );
925901 }
926902
927- const auto & key_mapped_field = key_field_ref-> get () ;
928- const auto & value_mapped_field = value_field_ref-> get () ;
903+ const auto & key_mapped_field = field. nested_mapping -> fields ()[ 0 ] ;
904+ const auto & value_mapped_field = field. nested_mapping -> fields ()[ 1 ] ;
929905
930906 if (!key_mapped_field.field_id || !value_mapped_field.field_id ) {
931907 return InvalidSchema (" Map key and value fields must have field IDs" );
932908 }
933909
934- // Create key field with mapped field ID
935- MappedField key_field;
936- key_field.field_id = *key_mapped_field.field_id ;
937- key_field.nested_mapping = key_mapped_field.nested_mapping ;
938-
939- // Create value field with mapped field ID
940- MappedField value_field;
941- value_field.field_id = *value_mapped_field.field_id ;
942- value_field.nested_mapping = value_mapped_field.nested_mapping ;
943-
944910 // Add key and value nodes
945- ICEBERG_ASSIGN_OR_RAISE (auto new_key_node,
946- MakeAvroNodeWithFieldIds (original_node->leafAt (0 ), key_field));
911+ ICEBERG_ASSIGN_OR_RAISE (
912+ auto new_key_node,
913+ MakeAvroNodeWithFieldIds (original_node->leafAt (0 ), key_mapped_field));
947914 ICEBERG_ASSIGN_OR_RAISE (
948915 auto new_value_node,
949- MakeAvroNodeWithFieldIds (original_node->leafAt (1 ), value_field ));
916+ MakeAvroNodeWithFieldIds (original_node->leafAt (1 ), value_mapped_field ));
950917 new_map_node->addLeaf (new_key_node);
951918 new_map_node->addLeaf (new_value_node);
952919
@@ -958,19 +925,21 @@ Result<::avro::NodePtr> CreateMapNodeWithFieldIds(const ::avro::NodePtr& origina
958925 for (const auto & attr_pair : existing_attrs) {
959926 // Copy each existing attribute to preserve original metadata
960927 ::avro::CustomAttributes attributes;
961- attributes.addAttribute (attr_pair.first , attr_pair.second , false );
928+ attributes.addAttribute (attr_pair.first , attr_pair.second , /* addQuote= */ false );
962929 new_map_node->addCustomAttributesForField (attributes);
963930 }
964931 }
965932
966933 ::avro::CustomAttributes key_attributes;
967- key_attributes.addAttribute (std::string (kFieldIdProp ),
968- std::to_string (*key_mapped_field.field_id ), false );
934+ key_attributes.addAttribute (std::string (kKeyIdProp ),
935+ std::to_string (*key_mapped_field.field_id ),
936+ /* addQuote=*/ false );
969937 new_map_node->addCustomAttributesForField (key_attributes);
970938
971939 ::avro::CustomAttributes value_attributes;
972- value_attributes.addAttribute (std::string (kFieldIdProp ),
973- std::to_string (*value_mapped_field.field_id ), false );
940+ value_attributes.addAttribute (std::string (kValueIdProp ),
941+ std::to_string (*value_mapped_field.field_id ),
942+ /* addQuote=*/ false );
974943 new_map_node->addCustomAttributesForField (value_attributes);
975944
976945 return new_map_node;
0 commit comments