@@ -3180,6 +3180,133 @@ mod tests {
3180
3180
) ;
3181
3181
}
3182
3182
3183
+ #[ test]
3184
+ fn test_row_lineage_append_branch ( ) {
3185
+ // Appends to a branch should still change last-row-id even if not on main, these changes
3186
+ // should also affect commits to main
3187
+
3188
+ let branch = "some_branch" ;
3189
+
3190
+ // Start with V3 metadata to support row lineage
3191
+ let base = builder_without_changes ( FormatVersion :: V3 )
3192
+ . build ( )
3193
+ . unwrap ( )
3194
+ . metadata ;
3195
+
3196
+ // Initial next_row_id should be 0
3197
+ assert_eq ! ( base. next_row_id( ) , 0 ) ;
3198
+
3199
+ // Write to Branch - append 30 rows
3200
+ let branch_snapshot_1 = Snapshot :: builder ( )
3201
+ . with_snapshot_id ( 1 )
3202
+ . with_timestamp_ms ( base. last_updated_ms + 1 )
3203
+ . with_sequence_number ( 0 )
3204
+ . with_schema_id ( 0 )
3205
+ . with_manifest_list ( "foo" )
3206
+ . with_parent_snapshot_id ( None )
3207
+ . with_summary ( Summary {
3208
+ operation : Operation :: Append ,
3209
+ additional_properties : HashMap :: new ( ) ,
3210
+ } )
3211
+ . with_row_range ( base. next_row_id ( ) , 30 )
3212
+ . build ( ) ;
3213
+
3214
+ let table_after_branch_1 = base
3215
+ . into_builder ( None )
3216
+ . set_branch_snapshot ( branch_snapshot_1. clone ( ) , branch)
3217
+ . unwrap ( )
3218
+ . build ( )
3219
+ . unwrap ( )
3220
+ . metadata ;
3221
+
3222
+ // Current snapshot should be null (no main branch snapshot yet)
3223
+ assert ! ( table_after_branch_1. current_snapshot( ) . is_none( ) ) ;
3224
+
3225
+ // Branch snapshot should have first_row_id = 0
3226
+ let branch_ref = table_after_branch_1. refs . get ( branch) . unwrap ( ) ;
3227
+ let branch_snap_1 = table_after_branch_1
3228
+ . snapshots
3229
+ . get ( & branch_ref. snapshot_id )
3230
+ . unwrap ( ) ;
3231
+ assert_eq ! ( branch_snap_1. first_row_id( ) , Some ( 0 ) ) ;
3232
+
3233
+ // Next row id should be 30
3234
+ assert_eq ! ( table_after_branch_1. next_row_id( ) , 30 ) ;
3235
+
3236
+ // Write to Main - append 28 rows
3237
+ let main_snapshot = Snapshot :: builder ( )
3238
+ . with_snapshot_id ( 2 )
3239
+ . with_timestamp_ms ( table_after_branch_1. last_updated_ms + 1 )
3240
+ . with_sequence_number ( 1 )
3241
+ . with_schema_id ( 0 )
3242
+ . with_manifest_list ( "bar" )
3243
+ . with_parent_snapshot_id ( None )
3244
+ . with_summary ( Summary {
3245
+ operation : Operation :: Append ,
3246
+ additional_properties : HashMap :: new ( ) ,
3247
+ } )
3248
+ . with_row_range ( table_after_branch_1. next_row_id ( ) , 28 )
3249
+ . build ( ) ;
3250
+
3251
+ let table_after_main = table_after_branch_1
3252
+ . into_builder ( None )
3253
+ . add_snapshot ( main_snapshot. clone ( ) )
3254
+ . unwrap ( )
3255
+ . set_ref ( MAIN_BRANCH , SnapshotReference {
3256
+ snapshot_id : main_snapshot. snapshot_id ( ) ,
3257
+ retention : SnapshotRetention :: Branch {
3258
+ min_snapshots_to_keep : None ,
3259
+ max_snapshot_age_ms : None ,
3260
+ max_ref_age_ms : None ,
3261
+ } ,
3262
+ } )
3263
+ . unwrap ( )
3264
+ . build ( )
3265
+ . unwrap ( )
3266
+ . metadata ;
3267
+
3268
+ // Main snapshot should have first_row_id = 30
3269
+ let current_snapshot = table_after_main. current_snapshot ( ) . unwrap ( ) ;
3270
+ assert_eq ! ( current_snapshot. first_row_id( ) , Some ( 30 ) ) ;
3271
+
3272
+ // Next row id should be 58 (30 + 28)
3273
+ assert_eq ! ( table_after_main. next_row_id( ) , 58 ) ;
3274
+
3275
+ // Write again to branch - append 21 rows
3276
+ let branch_snapshot_2 = Snapshot :: builder ( )
3277
+ . with_snapshot_id ( 3 )
3278
+ . with_timestamp_ms ( table_after_main. last_updated_ms + 1 )
3279
+ . with_sequence_number ( 2 )
3280
+ . with_schema_id ( 0 )
3281
+ . with_manifest_list ( "baz" )
3282
+ . with_parent_snapshot_id ( Some ( branch_snapshot_1. snapshot_id ( ) ) )
3283
+ . with_summary ( Summary {
3284
+ operation : Operation :: Append ,
3285
+ additional_properties : HashMap :: new ( ) ,
3286
+ } )
3287
+ . with_row_range ( table_after_main. next_row_id ( ) , 21 )
3288
+ . build ( ) ;
3289
+
3290
+ let table_after_branch_2 = table_after_main
3291
+ . into_builder ( None )
3292
+ . set_branch_snapshot ( branch_snapshot_2. clone ( ) , branch)
3293
+ . unwrap ( )
3294
+ . build ( )
3295
+ . unwrap ( )
3296
+ . metadata ;
3297
+
3298
+ // Branch snapshot should have first_row_id = 58 (30 + 28)
3299
+ let branch_ref_2 = table_after_branch_2. refs . get ( branch) . unwrap ( ) ;
3300
+ let branch_snap_2 = table_after_branch_2
3301
+ . snapshots
3302
+ . get ( & branch_ref_2. snapshot_id )
3303
+ . unwrap ( ) ;
3304
+ assert_eq ! ( branch_snap_2. first_row_id( ) , Some ( 58 ) ) ;
3305
+
3306
+ // Next row id should be 79 (30 + 28 + 21)
3307
+ assert_eq ! ( table_after_branch_2. next_row_id( ) , 79 ) ;
3308
+ }
3309
+
3183
3310
#[ test]
3184
3311
fn test_encryption_keys ( ) {
3185
3312
let builder = builder_without_changes ( FormatVersion :: V2 ) ;
0 commit comments