V1 manifest lists written by Java lose added/existing/deleted file counts
I maintainer di solito rispondono entro 4 giorni
@kacper-li-airspace-intelligence ci sta già lavorando.
Dal 14/10/2026.
- #3447 di @kacper-li-airspace-intelligence — aperta
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 72/100
Direzione di ricerca
Inizia dalla struct ManifestFileV1 e da MANIFEST_LIST_AVRO_SCHEMA_V1 nel codice della manifest list, poi confrontali con ManifestFileV2, che ha già alias per entrambi i nomi dei contatori. Esegui la riproduzione nella issue, che analizza una manifest list V1 con i nomi dei campi di Java tramite ManifestList::parse_with_version(_, FormatVersion::V1). È completato quando i tre contatori dei file vengono analizzati come Some e un test usa i nomi V1 di Java. La issue indica che questo dipende da #3224 (V1 legge con lo schema del writer), quindi verifica prima questo punto. I contatori sono Some
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Apache Iceberg Rust version
main (1270e329b)
Describe the bug
Java writes V1 manifest lists with the field names added_files_count, existing_files_count and deleted_files_count (V1Metadata.MANIFEST_LIST_SCHEMA, ManifestFile), which are the names in the spec. ManifestFileV1 and MANIFEST_LIST_AVRO_SCHEMA_V1 only know the older added_data_files_count names, so ManifestList::parse_with_version(_, FormatVersion::V1) returns None for all three counts. Fields with the same name in both, such as added_rows_count, parse correctly. Reading the same bytes as V2 returns the counts, because ManifestFileV2 has aliases for both names.
The spec treats a null count as non-zero, so scan planning stays correct, but the counts are lost. FastAppendAction::existing_manifest copies these entries into the next manifest list, so a fast append on such a table writes the nulls back.
To Reproduce
Write one manifest list entry with Java's V1 field names and parse it:
use apache_avro::types::Record;
use apache_avro::{Schema, Writer};
use iceberg::spec::{FormatVersion, ManifestList};
let opt = |n: &str, t: &str| format!(r#"{{"name":"{n}","type":["null","{t}"],"default":null}}"#);
let schema = Schema::parse_str(&format!(
r#"{{"type":"record","name":"manifest_file","fields":[
{{"name":"manifest_path","type":"string"}},{{"name":"manifest_length","type":"long"}},
{{"name":"partition_spec_id","type":"int"}},{{"name":"added_snapshot_id","type":"long"}},
{},{},{},{},{},{},{}]}}"#,
opt("added_files_count", "int"), opt("existing_files_count", "int"), opt("deleted_files_count", "int"),
opt("added_rows_count", "long"), opt("existing_rows_count", "long"), opt("deleted_rows_count", "long"),
opt("key_metadata", "bytes"),
)).unwrap();
let mut writer = Writer::new(&schema, Vec::new()).unwrap();
let mut record = Record::new(&schema).unwrap();
record.put("manifest_path", "s3://t/m.avro");
record.put("manifest_length", 1i64);
record.put("partition_spec_id", 0i32);
record.put("added_snapshot_id", 1i64);
record.put("added_files_count", Some(3i32));
record.put("existing_files_count", Some(0i32));
record.put("deleted_files_count", Some(0i32));
record.put("added_rows_count", Some(9i64));
record.put("existing_rows_count", Some(0i64));
record.put("deleted_rows_count", Some(0i64));
record.put("key_metadata", None::<Vec<u8>>);
writer.append_value(record).unwrap();
let bs = writer.into_inner().unwrap();
let list = ManifestList::parse_with_version(&bs, FormatVersion::V1).unwrap();
let entry = &list.entries()[0];
// added_files_count, existing_files_count, deleted_files_count: None
// added_rows_count: Some(9)
Expected behavior
V1 parsing returns Some(3), Some(0) and Some(0) for the three file counts. Once V1 reads against the writer schema (#3224), adding #[serde(alias = ...)] for added_files_count, existing_files_count and deleted_files_count to ManifestFileV1, as ManifestFileV2 already does, fixes it. The fix should come with a test that uses Java's V1 names.
Willingness to contribute
I can contribute a fix for this bug independently
Related
- Reported in review of #3224: https://github.com/apache/iceberg-rust/pull/3224#discussion_r4259833708
- Lingua principale
- Rust
- Stelle
- 1.4k
- Fork
- 612
- Merge medio
- 4g 1h
- PR unite (30g)
- 63
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di apache/iceberg-rust
-
REST create_table omits partition spec-id; Java-based servers (Polaris) reject itForse già presa @ahlag l’ha presa 8 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
apache/iceberg-rust#3469 · 1 commento ·
I maintainer di solito rispondono entro 4 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
apache/iceberg-rust#3359 ·
I maintainer di solito rispondono entro 4 giorni
-
Row filter keeps every row for `<` and `<=` on a null column that is missing from the data fileForse già presa @mattfaltyn l’ha presa 3 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
apache/iceberg-rust#3355 · 1 reazione ·
I maintainer di solito rispondono entro 4 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
apache/iceberg-rust#3348 ·
I maintainer di solito rispondono entro 4 giorni
-
datafusion
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
apache/iceberg-rust#3324 · 1 reazione ·
I maintainer di solito rispondono entro 4 giorni
Tutte le issue di apache/iceberg-rust
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
manuscript-lang/manuscript#1364 ·
I maintainer di solito rispondono entro 1 giorno
-
`printf "%o"` prints decimalAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
fable-compiler/Fable#5157 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 73/100
I maintainer di solito rispondono entro 1 giorno
-
C-bug needs-triage O-UEFI T-libs
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
移动端宽屏适配Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 64/100
I maintainer di solito rispondono entro 1 giorno