@@ -27,10 +27,9 @@ use crate::Result;
2727///
2828/// Must match the serde layout of `IndexManifestEntry`.
2929///
30- /// Note: `_FILE_SIZE` and `_ROW_COUNT` are declared as Avro `long` to match
31- /// Java Paimon's schema, while the Rust `IndexFileMeta` fields are `i32`.
32- /// `serde_avro_fast` transparently coerces between integer widths during
33- /// serialization/deserialization, so the mismatch is intentional.
30+ /// Note: `_FILE_SIZE` is an Avro `long` and Rust `i64`, matching Java Paimon's
31+ /// schema. `_ROW_COUNT` remains an Avro `long` for Java compatibility while
32+ /// the Rust `IndexFileMeta` field is still `i32`.
3433pub const INDEX_MANIFEST_ENTRY_SCHEMA : & str = r#"{
3534 "type": "record",
3635 "name": "org.apache.paimon.avro.generated.record",
@@ -345,6 +344,32 @@ mod tests {
345344 ) ;
346345 }
347346
347+ #[ test]
348+ fn file_size_above_i32_max_round_trips_through_index_manifest ( ) {
349+ let file_size = i64:: from ( i32:: MAX ) + 1 ;
350+ let entry: IndexManifestEntry = serde_json:: from_value ( serde_json:: json!( {
351+ "_VERSION" : 1 ,
352+ "_KIND" : 0 ,
353+ "_PARTITION" : [ 0 , 0 , 0 , 0 ] ,
354+ "_BUCKET" : 0 ,
355+ "_INDEX_TYPE" : "TEST" ,
356+ "_FILE_NAME" : "index" ,
357+ "_FILE_SIZE" : file_size,
358+ "_ROW_COUNT" : 1
359+ } ) )
360+ . unwrap ( ) ;
361+
362+ let bytes = crate :: spec:: to_avro_bytes_with_compression (
363+ INDEX_MANIFEST_ENTRY_SCHEMA ,
364+ std:: slice:: from_ref ( & entry) ,
365+ crate :: spec:: DEFAULT_AVRO_COMPRESSION ,
366+ )
367+ . unwrap ( ) ;
368+
369+ let decoded = IndexManifest :: read_from_bytes ( & bytes) . unwrap ( ) ;
370+ assert_eq ! ( decoded, vec![ entry] ) ;
371+ }
372+
348373 #[ test]
349374 fn legacy_five_field_global_index_decodes_without_source_meta ( ) {
350375 // 5-field _GLOBAL_INDEX schema (pre-#8549): no _SOURCE_META. Identical to
0 commit comments