@@ -629,15 +629,20 @@ Result<FieldProjection> ProjectNested(const Type& expected_type,
629629 const ::avro::NodePtr& avro_node,
630630 bool prune_source);
631631
632- Result<FieldProjection> ProjectField (const Type& expected_type ,
632+ Result<FieldProjection> ProjectField (const SchemaField& expected_field ,
633633 const ::avro::NodePtr& avro_node,
634634 size_t source_index, bool prune_source) {
635+ const Type& expected_type = *expected_field.type ();
635636 ::avro::NodePtr field_node;
636637 ICEBERG_RETURN_UNEXPECTED (UnwrapUnion (avro_node, &field_node));
637638
638639 FieldProjection projection;
639640 if (expected_type.type_id () == TypeId::kUnknown ||
640641 field_node->type () == ::avro::AVRO_NULL ) {
642+ if (!expected_field.optional ()) {
643+ return InvalidSchema (" Cannot project required field with ID: {} as null" ,
644+ expected_field.field_id ());
645+ }
641646 projection.kind = FieldProjection::Kind::kNull ;
642647 return projection;
643648 }
@@ -688,9 +693,9 @@ Result<FieldProjection> ProjectStruct(const StructType& struct_type,
688693 FieldProjection child_projection;
689694
690695 if (auto iter = node_info_map.find (field_id); iter != node_info_map.cend ()) {
691- ICEBERG_ASSIGN_OR_RAISE (
692- child_projection, ProjectField (* expected_field. type () , iter->second .field_node ,
693- iter->second .local_index , prune_source));
696+ ICEBERG_ASSIGN_OR_RAISE (child_projection,
697+ ProjectField (expected_field, iter->second .field_node ,
698+ iter->second .local_index , prune_source));
694699 } else if (MetadataColumns::IsMetadataColumn (field_id)) {
695700 child_projection.kind = FieldProjection::Kind::kMetadata ;
696701 } else if (expected_field.optional ()) {
@@ -728,8 +733,8 @@ Result<FieldProjection> ProjectList(const ListType& list_type,
728733
729734 FieldProjection element_projection;
730735 ICEBERG_ASSIGN_OR_RAISE (element_projection,
731- ProjectField (* expected_element_field. type ( ),
732- avro_node-> leafAt ( 0 ), size_t {0 }, prune_source));
736+ ProjectField (expected_element_field, avro_node-> leafAt ( 0 ),
737+ size_t {0 }, prune_source));
733738
734739 FieldProjection result;
735740 result.children .emplace_back (std::move (element_projection));
@@ -788,7 +793,7 @@ Result<FieldProjection> ProjectMap(const MapType& map_type,
788793 const auto & expected_sub_field = map_type.fields ()[i];
789794 ICEBERG_ASSIGN_OR_RAISE (
790795 sub_projection,
791- ProjectField (* expected_sub_field. type () , map_node->leafAt (i), i, prune_source));
796+ ProjectField (expected_sub_field, map_node->leafAt (i), i, prune_source));
792797 result.children .emplace_back (std::move (sub_projection));
793798 }
794799
0 commit comments