Skip to content

Commit ca077d0

Browse files
Fokkokevinjqliu
authored andcommitted
Allow union of {int,long}, {float,double}, etc (apache#1283)
* Allow union of `{int,long}`, `{float,double}`, etc * Thanks Kevin! Co-authored-by: Kevin Liu <[email protected]> * Thanks Kevin! Co-authored-by: Kevin Liu <[email protected]> * MOAR tests * lint * Make the tests happy * Remove redundant test --------- Co-authored-by: Kevin Liu <[email protected]>
1 parent 826ec74 commit ca077d0

File tree

2 files changed

+43
-4
lines changed

2 files changed

+43
-4
lines changed

pyiceberg/table/update/schema.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,13 @@ def _update_column(self, field: NestedField, existing_field: NestedField) -> Non
770770
self.update_schema.make_column_optional(full_name)
771771

772772
if field.field_type.is_primitive and field.field_type != existing_field.field_type:
773-
self.update_schema.update_column(full_name, field_type=field.field_type)
773+
try:
774+
# If the current type is wider than the new type, then
775+
# we perform a noop
776+
_ = promote(field.field_type, existing_field.field_type)
777+
except ResolveError:
778+
# If this is not the case, perform the type evolution
779+
self.update_schema.update_column(full_name, field_type=field.field_type)
774780

775781
if field.doc is not None and field.doc != existing_field.doc:
776782
self.update_schema.update_column(full_name, doc=field.doc)

tests/test_schema.py

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,17 @@ def test_detect_invalid_top_level_maps() -> None:
11891189
_ = UpdateSchema(transaction=None, schema=current_schema).union_by_name(new_schema)._apply() # type: ignore
11901190

11911191

1192+
def test_allow_double_to_float() -> None:
1193+
current_schema = Schema(NestedField(field_id=1, name="aCol", field_type=DoubleType(), required=False))
1194+
new_schema = Schema(NestedField(field_id=1, name="aCol", field_type=FloatType(), required=False))
1195+
1196+
applied = UpdateSchema(transaction=None, schema=current_schema).union_by_name(new_schema)._apply() # type: ignore
1197+
1198+
assert applied.as_struct() == current_schema.as_struct()
1199+
assert len(applied.fields) == 1
1200+
assert isinstance(applied.fields[0].field_type, DoubleType)
1201+
1202+
11921203
def test_promote_float_to_double() -> None:
11931204
current_schema = Schema(NestedField(field_id=1, name="aCol", field_type=FloatType(), required=False))
11941205
new_schema = Schema(NestedField(field_id=1, name="aCol", field_type=DoubleType(), required=False))
@@ -1200,11 +1211,33 @@ def test_promote_float_to_double() -> None:
12001211
assert isinstance(applied.fields[0].field_type, DoubleType)
12011212

12021213

1203-
def test_detect_invalid_promotion_double_to_float() -> None:
1204-
current_schema = Schema(NestedField(field_id=1, name="aCol", field_type=DoubleType(), required=False))
1214+
def test_allow_long_to_int() -> None:
1215+
current_schema = Schema(NestedField(field_id=1, name="aCol", field_type=LongType(), required=False))
1216+
new_schema = Schema(NestedField(field_id=1, name="aCol", field_type=IntegerType(), required=False))
1217+
1218+
applied = UpdateSchema(transaction=None, schema=current_schema).union_by_name(new_schema)._apply() # type: ignore
1219+
1220+
assert applied.as_struct() == current_schema.as_struct()
1221+
assert len(applied.fields) == 1
1222+
assert isinstance(applied.fields[0].field_type, LongType)
1223+
1224+
1225+
def test_promote_int_to_long() -> None:
1226+
current_schema = Schema(NestedField(field_id=1, name="aCol", field_type=IntegerType(), required=False))
1227+
new_schema = Schema(NestedField(field_id=1, name="aCol", field_type=LongType(), required=False))
1228+
1229+
applied = UpdateSchema(transaction=None, schema=current_schema).union_by_name(new_schema)._apply() # type: ignore
1230+
1231+
assert applied.as_struct() == new_schema.as_struct()
1232+
assert len(applied.fields) == 1
1233+
assert isinstance(applied.fields[0].field_type, LongType)
1234+
1235+
1236+
def test_detect_invalid_promotion_string_to_float() -> None:
1237+
current_schema = Schema(NestedField(field_id=1, name="aCol", field_type=StringType(), required=False))
12051238
new_schema = Schema(NestedField(field_id=1, name="aCol", field_type=FloatType(), required=False))
12061239

1207-
with pytest.raises(ValidationError, match="Cannot change column type: aCol: double -> float"):
1240+
with pytest.raises(ValidationError, match="Cannot change column type: aCol: string -> float"):
12081241
_ = UpdateSchema(transaction=None, schema=current_schema).union_by_name(new_schema)._apply() # type: ignore
12091242

12101243

0 commit comments

Comments
 (0)