@@ -408,4 +408,45 @@ config:
408
408
const data = await context . getBucketData ( '1#stream|0[]' ) ;
409
409
expect ( data ) . toMatchObject ( [ putOp ( 'test_data' , { id : 't1' } ) ] ) ;
410
410
} ) ;
411
+
412
+ test ( 'replica identity handling' , async ( ) => {
413
+ // This specifically test a case of timestamps being used as part of the replica identity.
414
+ // There was a regression in versions 1.15.0-1.15.5, which this tests for.
415
+ await using context = await WalStreamTestContext . open ( factory ) ;
416
+ const { pool } = context ;
417
+ await context . updateSyncRules ( BASIC_SYNC_RULES ) ;
418
+
419
+ await pool . query ( `DROP TABLE IF EXISTS test_data` ) ;
420
+ await pool . query ( `CREATE TABLE test_data(id uuid primary key, description text, ts timestamptz)` ) ;
421
+ await pool . query ( `ALTER TABLE test_data REPLICA IDENTITY FULL` ) ;
422
+
423
+ const test_id = `a9798b07-84de-4297-9a8e-aafb4dd0282f` ;
424
+
425
+ await pool . query (
426
+ `INSERT INTO test_data(id, description, ts) VALUES('${ test_id } ', 'test1', '2025-01-01T00:00:00Z') returning id as test_id`
427
+ ) ;
428
+
429
+ await context . replicateSnapshot ( ) ;
430
+ await context . startStreaming ( ) ;
431
+
432
+ await pool . query ( `UPDATE test_data SET description = 'test2' WHERE id = '${ test_id } '` ) ;
433
+
434
+ const data = await context . getBucketData ( 'global[]' ) ;
435
+ // For replica identity full, each change changes the id, making it a REMOVE+PUT
436
+ expect ( data ) . toMatchObject ( [
437
+ // Initial insert
438
+ putOp ( 'test_data' , { id : test_id , description : 'test1' } ) ,
439
+ // Update
440
+ removeOp ( 'test_data' , test_id ) ,
441
+ putOp ( 'test_data' , { id : test_id , description : 'test2' } )
442
+ ] ) ;
443
+
444
+ // subkey contains `${table id}/${replica identity}`.
445
+ // table id changes from run to run, but replica identity should always stay constant.
446
+ // This should not change if we make changes to the implementation
447
+ // (unless specifically opting in to new behavior)
448
+ expect ( data [ 0 ] . subkey ) . toContain ( '/c7b3f1a3-ec4d-5d44-b295-c7f2a32bb056' ) ;
449
+ expect ( data [ 1 ] . subkey ) . toContain ( '/c7b3f1a3-ec4d-5d44-b295-c7f2a32bb056' ) ;
450
+ expect ( data [ 2 ] . subkey ) . toContain ( '/984d457a-69f0-559a-a2f9-a511c28b968d' ) ;
451
+ } ) ;
411
452
}
0 commit comments