This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-python.git
The following commit(s) were added to refs/heads/main by this push:
new 2ed79b696 Add inspect regression test for bounds after type promotion
(#4314)
2ed79b696 is described below
commit 2ed79b696120467c4733c52a55c8302a9a2052d9
Author: David <[email protected]>
AuthorDate: Mon Nov 9 19:48:37 2026 +0000
Add inspect regression test for bounds after type promotion (#4314)
Bounds written before an int->long or float->double promotion keep their
4-byte encoding. #3293 fixed decoding them, but only covered the metrics
evaluators. Cover the inspect metadata tables too, so the crash reported
in #3744 can't regress.
Closes #3744
---
tests/table/test_inspect.py | 34 +++++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/tests/table/test_inspect.py b/tests/table/test_inspect.py
index 2404eadc7..306579754 100644
--- a/tests/table/test_inspect.py
+++ b/tests/table/test_inspect.py
@@ -29,7 +29,7 @@ from pyiceberg.table.inspect import InspectTable,
_readable_bound
from pyiceberg.table.snapshots import Snapshot
from pyiceberg.transforms import IdentityTransform
from pyiceberg.typedef import Record
-from pyiceberg.types import NestedField, StringType
+from pyiceberg.types import DoubleType, FloatType, IntegerType, LongType,
NestedField, PrimitiveType, StringType
from tests.catalog.test_base import InMemoryCatalog
@@ -106,3 +106,35 @@ def
test_inspect_manifests_preserves_empty_string_bounds(catalog: InMemoryCatalo
partition_summary =
tbl.inspect.manifests().to_pydict()["partition_summaries"][0][0]
assert partition_summary["lower_bound"] == ""
assert partition_summary["upper_bound"] == ""
+
+
+def test_inspect_bounds_after_type_promotion(catalog: InMemoryCatalog) -> None:
+ # Promotion does not rewrite existing files, so their bounds keep the
narrower 4-byte encoding
+ # while the current schema type is the 8-byte one.
+ cases: list[tuple[str, PrimitiveType, PrimitiveType, pa.DataType,
list[float]]] = [
+ ("int_to_long", IntegerType(), LongType(), pa.int32(), [1, 2]),
+ ("float_to_double", FloatType(), DoubleType(), pa.float32(), [1.5,
2.5]),
+ ]
+ for name, file_type, promoted_type, arrow_type, values in cases:
+ schema = Schema(NestedField(1, "v", file_type, required=False))
+ spec = PartitionSpec(PartitionField(1, 1000, IdentityTransform(), "v"))
+ tbl = catalog.create_table(f"default.{name}", schema,
partition_spec=spec)
+ tbl.append(pa.table({"v": values}, schema=pa.schema([pa.field("v",
arrow_type, nullable=True)])))
+
+ with tbl.update_schema() as update:
+ update.update_column("v", field_type=promoted_type)
+
+ for files_table in [
+ tbl.inspect.entries(),
+ tbl.inspect.files(),
+ tbl.inspect.data_files(),
+ tbl.inspect.all_files(),
+ tbl.inspect.all_data_files(),
+ ]:
+ metrics = [m["v"] for m in
files_table.to_pydict()["readable_metrics"]]
+ assert sorted(m["lower_bound"] for m in metrics) == values, name
+ assert sorted(m["upper_bound"] for m in metrics) == values, name
+
+ partition_summaries =
tbl.inspect.manifests().to_pydict()["partition_summaries"][0]
+ assert partition_summaries[0]["lower_bound"] == str(values[0]), name
+ assert partition_summaries[0]["upper_bound"] == str(values[-1]), name