Fokko commented on code in PR #6515:
URL: https://github.com/apache/iceberg/pull/6515#discussion_r1060905337


##########
python/pyiceberg/schema.py:
##########
@@ -1350,3 +1349,98 @@ def _(file_type: DecimalType, read_type: IcebergType) -> 
IcebergType:
             raise ResolveError(f"Cannot reduce precision from {file_type} to 
{read_type}")
     else:
         raise ResolveError(f"Cannot promote an decimal to {read_type}")
+
+
+def check_schema_compatibility(requested_schema: Schema, file_schema: Schema) 
-> Schema:
+    return visit_with_partner(requested_schema, file_schema, 
_RequiredFieldVisitor(), _PartnerSchemaAccessor(file_schema))
+
+
+class _RequiredFieldVisitor(SchemaWithPartnerVisitor[Union[Schema, 
IcebergType], Union[Schema, IcebergType]]):
+    def schema(
+        self, schema: Schema, schema_partner: Optional[Union[Schema, 
IcebergType]], struct_result: Union[Schema, IcebergType]
+    ) -> Union[Schema, IcebergType]:
+        return schema
+
+    def struct(
+        self,
+        struct: StructType,
+        struct_partner: Optional[Union[Schema, IcebergType]],
+        field_results: List[Union[Schema, IcebergType]],
+    ) -> Union[Schema, IcebergType]:
+        assert len(struct.fields) == len(field_results)
+
+        if struct_partner is not None:
+            if isinstance(struct_partner, Schema):
+                struct_partner = struct_partner.as_struct()
+            if not isinstance(struct_partner, StructType):
+                raise ValueError(f"Expected StructType, got: {struct_partner}")
+            struct_partner_ids = {field.field_id for field in 
struct_partner.fields}
+            for field in field_results:
+                assert isinstance(field, NestedField)
+                # The field does not exist in the partner_struct
+                if field.field_id not in struct_partner_ids and field.required:
+                    raise ResolveError(f"Field is required, and could not be 
found in the file: {field}")
+
+        return struct
+
+    def field(
+        self, field: NestedField, field_partner: Optional[Union[Schema, 
IcebergType]], field_result: Union[Schema, IcebergType]
+    ) -> Union[Schema, IcebergType]:
+        return field
+
+    def list(
+        self, list_type: ListType, list_partner: Optional[Union[Schema, 
IcebergType]], element_result: Union[Schema, IcebergType]
+    ) -> Union[Schema, IcebergType]:
+        if list_partner is not None and not isinstance(list_partner, ListType):
+            raise ValueError(f"Expected ListType, got: {list_partner}")
+
+        return list_type
+
+    def map(
+        self,
+        map_type: MapType,
+        map_partner: Optional[Union[Schema, IcebergType]],
+        key_result: Union[Schema, IcebergType],
+        value_result: Union[Schema, IcebergType],
+    ) -> Union[Schema, IcebergType]:
+        if map_type is not None and not isinstance(map_type, MapType):
+            raise ValueError(f"Expected MapType, got: {map_type}")
+
+        return map_type
+
+    def primitive(
+        self, primitive: PrimitiveType, primitive_partner: 
Optional[Union[Schema, IcebergType]]
+    ) -> Union[Schema, IcebergType]:
+        if primitive_partner and primitive_partner != primitive:
+            return promote(primitive_partner, primitive)
+        else:
+            return primitive
+
+
+class _PartnerSchemaAccessor(PartnerAccessor[Union[Schema, IcebergType]]):
+    partner_schema: Schema
+
+    def __init__(self, partner_schema: Schema) -> None:
+        self.partner_schema = partner_schema
+
+    def schema_partner(self, partner: Optional[Union[Schema, IcebergType]]) -> 
Optional[Union[Schema, IcebergType]]:
+        return partner
+
+    def field_partner(
+        self, partner_struct: Optional[Union[Schema, IcebergType]], field_id: 
int, _: str
+    ) -> Optional[Union[Schema, IcebergType]]:
+        if partner_struct is not None:
+            try:
+                return self.partner_schema.find_field(field_id).field_type

Review Comment:
   Ah, great catch!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to