@@ -73,6 +73,26 @@ type blockingAllocateStore struct {
7373 release chan struct {}
7474}
7575
76+ type deadlineCheckingForceSetOffsetStore struct {
77+ IncrValueStore
78+ deadline chan time.Time
79+ }
80+
81+ func (s * deadlineCheckingForceSetOffsetStore ) ForceSetOffset (
82+ ctx context.Context ,
83+ tableID uint64 ,
84+ colName string ,
85+ offset uint64 ,
86+ txnOp client.TxnOperator ,
87+ ) error {
88+ deadline , ok := ctx .Deadline ()
89+ if ! ok {
90+ return errors .New ("ForceSetOffset context has no deadline" )
91+ }
92+ s .deadline <- deadline
93+ return s .IncrValueStore .ForceSetOffset (ctx , tableID , colName , offset , txnOp )
94+ }
95+
7696func (s * blockingAllocateStore ) blockNext () (<- chan struct {}, func ()) {
7797 s .mu .Lock ()
7898 defer s .mu .Unlock ()
@@ -501,9 +521,16 @@ func TestMemStoreSetOffsetReturnsError(t *testing.T) {
501521 require .Error (t , store .SetOffset (ctx , 0 , "missing_col" , 77 , nil ))
502522
503523 op := ops [0 ]
524+ require .Error (t , store .SetOffset (ctx , 1 , def [0 ].ColName , 77 , op ))
525+ store .Lock ()
526+ _ , exists := store .uncommitted [string (op .Txn ().ID )]
527+ store .Unlock ()
528+ require .False (t , exists )
529+
504530 require .NoError (t , store .SetOffset (ctx , 0 , def [0 ].ColName , 88 , op ))
505531 store .Lock ()
506- require .Equal (t , uint64 (88 ), store .caches [0 ][0 ].Offset )
532+ require .Equal (t , uint64 (0 ), store .caches [0 ][0 ].Offset )
533+ require .Equal (t , uint64 (88 ), store .uncommitted [string (op .Txn ().ID )][0 ][0 ].Offset )
507534 store .Unlock ()
508535 })
509536}
@@ -736,9 +763,6 @@ func TestSetOffsetRollbackKeepsCommittedOffsetAndSafelyRebuildsCache(t *testing.
736763
737764 alterTxn , err := tc .New (ctx , timestamp.Timestamp {})
738765 require .NoError (t , err )
739- // The mem store models the SQL transaction's private view by copying the
740- // committed auto-increment row into this transaction.
741- require .NoError (t , store .Create (ctx , 0 , committedCols , alterTxn ))
742766 require .NoError (t , s .SetOffset (ctx , 0 , def [0 ].ColName , 50 , alterTxn ))
743767
744768 store .Lock ()
@@ -780,7 +804,6 @@ func TestSetOffsetTransactionUsesPendingOffsetForInsert(t *testing.T) {
780804
781805 alterTxn , err := tc .New (ctx , timestamp.Timestamp {})
782806 require .NoError (t , err )
783- require .NoError (t , store .Create (ctx , 0 , def , alterTxn ))
784807 require .NoError (t , s .SetOffset (ctx , 0 , def [0 ].ColName , 999 , alterTxn ))
785808
786809 input := newTestVector [uint64 ](1 , types .New (types .T_uint64 , 0 , 0 ), nil , nil )
@@ -883,7 +906,6 @@ func TestSetOffsetWithoutInsertDoesNotReservePrivateRange(t *testing.T) {
883906
884907 alterTxn , err := tc .New (ctx , timestamp.Timestamp {})
885908 require .NoError (t , err )
886- require .NoError (t , store .Create (ctx , 0 , def , alterTxn ))
887909 require .NoError (t , s .SetOffset (ctx , 0 , def [0 ].ColName , 999 , alterTxn ))
888910
889911 store .Lock ()
@@ -1431,8 +1453,6 @@ func TestTwoServicesKeepStaleRangesAcrossTransactionalReset(t *testing.T) {
14311453
14321454 alterTxn , err := tc .New (ctx , timestamp.Timestamp {})
14331455 require .NoError (t , err )
1434- // The memory store models the ALTER transaction's private metadata row.
1435- require .NoError (t , store .Create (ctx , 0 , def , alterTxn ))
14361456 require .NoError (t , cn1 .SetOffset (ctx , 0 , def [0 ].ColName , effectiveOffset , alterTxn ))
14371457 require .NoError (t , alterTxn .Commit (ctx ))
14381458
@@ -1715,6 +1735,23 @@ func TestCanceledSetOffsetDoesNotRunQueuedForceUpdate(t *testing.T) {
17151735 })
17161736}
17171737
1738+ func TestForceSetOffsetUsesBoundedContext (t * testing.T ) {
1739+ ctx := defines .AttachAccountId (context .Background (), catalog .System_Account )
1740+ store := & deadlineCheckingForceSetOffsetStore {
1741+ IncrValueStore : NewMemStore (),
1742+ deadline : make (chan time.Time , 1 ),
1743+ }
1744+ require .NoError (t , store .Create (ctx , 0 , newTestTableDef (1 ), nil ))
1745+ allocator := newValueAllocator ("" , store ).(* allocator )
1746+ defer allocator .close ()
1747+
1748+ require .NoError (t , allocator .forceSetOffset (ctx , 0 , "auto_0" , 99 , nil ))
1749+ deadline := <- store .deadline
1750+ remaining := time .Until (deadline )
1751+ require .Positive (t , remaining )
1752+ require .LessOrEqual (t , remaining , defaultForceSetOffsetTimeout )
1753+ }
1754+
17181755func TestRetiredTableCacheCannotQueueAllocation (t * testing.T ) {
17191756 allocator := & countingAllocator {}
17201757 col := & columnCache {
@@ -1852,6 +1889,42 @@ func TestMemStoreForceSetOffsetLowerThanCurrent(t *testing.T) {
18521889 })
18531890}
18541891
1892+ func TestMemStoreForceSetOffsetCreatesTransactionPrivateState (t * testing.T ) {
1893+ client .RunTxnTests (func (tc client.TxnClient , _ rpc.TxnSender ) {
1894+ ctx , cancel := context .WithTimeout (defines .AttachAccountId (context .Background (), catalog .System_Account ), 10 * time .Second )
1895+ defer cancel ()
1896+ store := NewMemStore ().(* memStore )
1897+ def := newTestTableDef (1 )
1898+ createTxn , err := tc .New (ctx , timestamp.Timestamp {})
1899+ require .NoError (t , err )
1900+ require .NoError (t , store .Create (ctx , 0 , def , createTxn ))
1901+ require .NoError (t , createTxn .Commit (ctx ))
1902+ require .NoError (t , store .ForceSetOffset (ctx , 0 , def [0 ].ColName , 10 , nil ))
1903+
1904+ rollbackTxn , err := tc .New (ctx , timestamp.Timestamp {})
1905+ require .NoError (t , err )
1906+ require .NoError (t , store .ForceSetOffset (ctx , 0 , def [0 ].ColName , 99 , rollbackTxn ))
1907+ store .Lock ()
1908+ require .Equal (t , uint64 (10 ), store .caches [0 ][0 ].Offset )
1909+ require .Equal (t , uint64 (99 ), store .uncommitted [string (rollbackTxn .Txn ().ID )][0 ][0 ].Offset )
1910+ store .Unlock ()
1911+ require .NoError (t , rollbackTxn .Rollback (ctx ))
1912+ store .Lock ()
1913+ require .Equal (t , uint64 (10 ), store .caches [0 ][0 ].Offset )
1914+ _ , exists := store .uncommitted [string (rollbackTxn .Txn ().ID )]
1915+ store .Unlock ()
1916+ require .False (t , exists )
1917+
1918+ commitTxn , err := tc .New (ctx , timestamp.Timestamp {})
1919+ require .NoError (t , err )
1920+ require .NoError (t , store .ForceSetOffset (ctx , 0 , def [0 ].ColName , 77 , commitTxn ))
1921+ require .NoError (t , commitTxn .Commit (ctx ))
1922+ store .Lock ()
1923+ require .Equal (t , uint64 (77 ), store .caches [0 ][0 ].Offset )
1924+ store .Unlock ()
1925+ })
1926+ }
1927+
18551928func runServiceTests (
18561929 t * testing.T ,
18571930 n int ,
0 commit comments