rdblue commented on code in PR #6437: URL: https://github.com/apache/iceberg/pull/6437#discussion_r1059516840
########## python/pyiceberg/schema.py: ########## @@ -1046,3 +1055,79 @@ def _project_map(map_type: MapType, value_result: IcebergType) -> MapType: value_type=value_result, value_required=map_type.value_required, ) + + +@singledispatch +def promote(file_type: IcebergType, read_type: IcebergType) -> IcebergType: + """Promotes reading a file type to a read type + + Args: + file_type (IcebergType): The type of the Avro file + read_type (IcebergType): The requested read type + + Raises: + ResolveException: If attempting to resolve an unrecognized object type + """ + raise ResolveException(f"Cannot promote {file_type} to {read_type}") + + +@promote.register(IntegerType) +def _(file_type: IntegerType, read_type: IcebergType) -> IcebergType: + if isinstance(read_type, LongType): + # Ints/Longs are binary compatible in Avro, so this is okay + return read_type + else: + raise ResolveException(f"Cannot promote an int to {read_type}") + + +@promote.register(FloatType) +def _(file_type: FloatType, read_type: IcebergType) -> IcebergType: + if isinstance(read_type, DoubleType): + # A double type is wider + return read_type + else: + raise ResolveException(f"Cannot promote an float to {read_type}") + + +@promote.register(StringType) +def _(file_type: StringType, read_type: IcebergType) -> IcebergType: + if isinstance(read_type, BinaryType): + return read_type + else: + raise ResolveException(f"Cannot promote an string to {read_type}") + + +@promote.register(BinaryType) +def _(file_type: BinaryType, read_type: IcebergType) -> IcebergType: + if isinstance(read_type, StringType): + return read_type + else: + raise ResolveException(f"Cannot promote an binary to {read_type}") + + +@promote.register(DecimalType) +def _(file_type: DecimalType, read_type: IcebergType) -> IcebergType: + if isinstance(read_type, DecimalType): + if file_type.precision <= read_type.precision and file_type.scale == file_type.scale: + return read_type + else: + raise ResolveException(f"Cannot reduce precision from {file_type} to {read_type}") + else: + raise ResolveException(f"Cannot promote an decimal to {read_type}") + + +@promote.register(StructType) +def _(file_type: StructType, read_type: IcebergType) -> IcebergType: Review Comment: I don't think that we want to do this. For nested structures, visitors should handle the logic. Type promotion should just be for primitive types. I handled this in the code above by checking whether the type was primitive before calling. I think that's better than trying to add logic to implement promotion, which is not defined for structs. -- 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: issues-unsubscr...@iceberg.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: issues-unsubscr...@iceberg.apache.org For additional commands, e-mail: issues-h...@iceberg.apache.org