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


##########
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]]):

Review Comment:
   Can we unify this with `SchemaPartnerAccessor` that is used in the resolver? 
That one will raise exceptions, but we could either have a flag to disable 
exceptions or we could update the tests to not expect them. I don't actually 
think the exceptions are very useful, since we always expect the structure to 
match.



-- 
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