3939from pydantic import Field , PrivateAttr , model_validator
4040
4141from pyiceberg .exceptions import ResolveError
42- from pyiceberg .typedef import EMPTY_DICT , IcebergBaseModel , StructProtocol
42+ from pyiceberg .typedef import EMPTY_DICT , IcebergBaseModel , StructProtocol , TableVersion
4343from pyiceberg .types import (
4444 BinaryType ,
4545 BooleanType ,
@@ -1622,7 +1622,10 @@ def _project_map(map_type: MapType, value_result: IcebergType) -> MapType:
16221622
16231623
16241624@singledispatch
1625- def promote (file_type : IcebergType , read_type : IcebergType ) -> IcebergType :
1625+ def promote (file_type : IcebergType , read_type : IcebergType , format_version : Optional [TableVersion ] = None ) -> IcebergType :
1626+ from pyiceberg .table import TableProperties
1627+
1628+ format_version = format_version or TableProperties .DEFAULT_FORMAT_VERSION
16261629 """Promotes reading a file type to a read type.
16271630
16281631 Args:
@@ -1692,6 +1695,22 @@ def _(file_type: FixedType, read_type: IcebergType) -> IcebergType:
16921695 raise ResolveError (f"Cannot promote { file_type } to { read_type } " )
16931696
16941697
1698+ @promote .register (DateType )
1699+ def _ (file_type : DateType , read_type : IcebergType , format_version : Optional [TableVersion ] = None ) -> IcebergType :
1700+ from pyiceberg .table import TableProperties
1701+
1702+ format_version = format_version or TableProperties .DEFAULT_FORMAT_VERSION
1703+ if format_version < 3 :
1704+ raise ResolveError ("DateType promotions can only occur on v3 tables." )
1705+
1706+ if isinstance (read_type , TimestampType ):
1707+ return read_type
1708+ elif isinstance (read_type , TimestampNanoType ):
1709+ return read_type
1710+ else :
1711+ raise ResolveError (f"Cannot promote { file_type } to { read_type } " )
1712+
1713+
16951714@promote .register (UnknownType )
16961715def _ (file_type : UnknownType , read_type : IcebergType ) -> IcebergType :
16971716 # Per V3 Spec, "Unknown" can be promoted to any Primitive type
@@ -1701,7 +1720,12 @@ def _(file_type: UnknownType, read_type: IcebergType) -> IcebergType:
17011720 raise ResolveError (f"Cannot promote { file_type } to { read_type } " )
17021721
17031722
1704- def _check_schema_compatible (requested_schema : Schema , provided_schema : Schema ) -> None :
1723+ def _check_schema_compatible (
1724+ requested_schema : Schema , provided_schema : Schema , format_version : Optional [TableVersion ] = None
1725+ ) -> None :
1726+ from pyiceberg .table import TableProperties
1727+
1728+ format_version = format_version or TableProperties .DEFAULT_FORMAT_VERSION
17051729 """
17061730 Check if the `provided_schema` is compatible with `requested_schema`.
17071731
@@ -1715,17 +1739,19 @@ def _check_schema_compatible(requested_schema: Schema, provided_schema: Schema)
17151739 Raises:
17161740 ValueError: If the schemas are not compatible.
17171741 """
1718- pre_order_visit (requested_schema , _SchemaCompatibilityVisitor (provided_schema ))
1742+ pre_order_visit (requested_schema , _SchemaCompatibilityVisitor (provided_schema , format_version = format_version ))
17191743
17201744
17211745class _SchemaCompatibilityVisitor (PreOrderSchemaVisitor [bool ]):
17221746 provided_schema : Schema
1747+ format_version : TableVersion
17231748
1724- def __init__ (self , provided_schema : Schema ):
1749+ def __init__ (self , provided_schema : Schema , format_version : TableVersion ):
17251750 from rich .console import Console
17261751 from rich .table import Table as RichTable
17271752
17281753 self .provided_schema = provided_schema
1754+ self .format_version = format_version
17291755 self .rich_table = RichTable (show_header = True , header_style = "bold" )
17301756 self .rich_table .add_column ("" )
17311757 self .rich_table .add_column ("Table field" )
@@ -1766,7 +1792,7 @@ def _is_field_compatible(self, lhs: NestedField) -> bool:
17661792 try :
17671793 # If type can be promoted to the requested schema
17681794 # it is considered compatible
1769- promote (rhs .field_type , lhs .field_type )
1795+ promote (rhs .field_type , lhs .field_type , format_version = self . format_version )
17701796 self .rich_table .add_row ("✅" , str (lhs ), str (rhs ))
17711797 return True
17721798 except ResolveError :
0 commit comments