Skip to content

Commit 308768d

Browse files
kevinjqliuCopilot
andauthored
Add missing referenced_data_file field to v2 manifests (#3953)
Fix v2 referenced data file schema Add optional referenced_data_file (field 143) to v2 manifests, retain it in existing expectations, and cover a non-null reference using explicit canonical-record projection. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 562d3af commit 308768d

3 files changed

Lines changed: 42 additions & 2 deletions

File tree

‎pyiceberg/manifest.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,13 @@ def __repr__(self) -> str:
306306
required=False,
307307
doc="ID representing sort order for this file",
308308
),
309+
NestedField(
310+
field_id=143,
311+
name="referenced_data_file",
312+
field_type=StringType(),
313+
required=False,
314+
doc="Fully qualified location (URI with FS scheme) of a data file that all deletes reference",
315+
),
309316
),
310317
3: StructType(
311318
NestedField(

‎tests/avro/test_file.py‎

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ def test_write_manifest_entry_with_iceberg_read_with_fastavro_v2() -> None:
208208
with avro.AvroOutputFile[ManifestEntry](
209209
output_file=PyArrowFileIO().new_output(tmp_avro_file),
210210
file_schema=MANIFEST_ENTRY_SCHEMAS[2],
211+
record_schema=MANIFEST_ENTRY_SCHEMAS[3],
211212
schema_name="manifest_entry",
212213
metadata=additional_metadata,
213214
) as out:
@@ -225,12 +226,44 @@ def test_write_manifest_entry_with_iceberg_read_with_fastavro_v2() -> None:
225226
fa_entry = next(it)
226227

227228
v2_entry = todict(entry)
228-
for field in ("first_row_id", "referenced_data_file", "content_offset", "content_size_in_bytes"):
229+
for field in ("first_row_id", "content_offset", "content_size_in_bytes"):
229230
del v2_entry["data_file"][field]
230231

231232
assert v2_entry == fa_entry
232233

233234

235+
def test_write_v2_referenced_data_file_with_fastavro() -> None:
236+
referenced_data_file = "s3://some-path/data-file.parquet"
237+
entry = ManifestEntry.from_args(
238+
status=ManifestEntryStatus.ADDED,
239+
snapshot_id=25,
240+
data_file=DataFile.from_args(
241+
content=DataFileContent.POSITION_DELETES,
242+
file_path="s3://some-path/delete-file.parquet",
243+
file_format=FileFormat.PARQUET,
244+
partition=Record(),
245+
record_count=3,
246+
file_size_in_bytes=47,
247+
referenced_data_file=referenced_data_file,
248+
),
249+
)
250+
251+
with TemporaryDirectory() as tmpdir:
252+
tmp_avro_file = tmpdir + "/manifest_entry.avro"
253+
with avro.AvroOutputFile[ManifestEntry](
254+
output_file=PyArrowFileIO().new_output(tmp_avro_file),
255+
file_schema=MANIFEST_ENTRY_SCHEMAS[2],
256+
record_schema=MANIFEST_ENTRY_SCHEMAS[3],
257+
schema_name="manifest_entry",
258+
) as out:
259+
out.write_block([entry])
260+
261+
with open(tmp_avro_file, "rb") as fo:
262+
fa_entry = next(reader(fo))
263+
264+
assert fa_entry["data_file"]["referenced_data_file"] == referenced_data_file
265+
266+
234267
@pytest.mark.parametrize("format_version", [1, 2])
235268
def test_write_manifest_entry_with_fastavro_read_with_iceberg(format_version: TableVersion) -> None:
236269
data_file_dict = {

‎tests/integration/test_rest_manifest.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ def test_write_sample_manifest(table_test_all_types: Table, compression: AvroCom
112112
wrapped_entry_v2 = copy(entry)
113113
wrapped_entry_v2.data_file = wrapped_data_file_v2_debug
114114
wrapped_entry_v2_dict = todict(wrapped_entry_v2, [field.name for field in test_spec.fields])
115-
for field in ("first_row_id", "referenced_data_file", "content_offset", "content_size_in_bytes"):
115+
for field in ("first_row_id", "content_offset", "content_size_in_bytes"):
116116
del wrapped_entry_v2_dict["data_file"][field]
117117

118118
with TemporaryDirectory() as tmpdir:

0 commit comments

Comments
 (0)