@@ -48,6 +48,9 @@ type AutoIncrementTracker struct {
48
48
sequences * sync.Map // map[string]uint64
49
49
mm * mutexmap.MutexMap
50
50
lockMode LockMode
51
+ init sync.Once
52
+ wg * sync.WaitGroup
53
+ initErr error
51
54
}
52
55
53
56
var _ globalstate.AutoIncrementTracker = & AutoIncrementTracker {}
@@ -61,8 +64,10 @@ func NewAutoIncrementTracker(ctx context.Context, dbName string, roots ...doltdb
61
64
dbName : dbName ,
62
65
sequences : & sync.Map {},
63
66
mm : mutexmap .NewMutexMap (),
67
+ wg : & sync.WaitGroup {},
68
+ init : sync.Once {},
64
69
}
65
- ait .InitWithRoots (ctx , roots ... )
70
+ ait .runInitWithRootsAsync (ctx , roots ... )
66
71
return & ait , nil
67
72
}
68
73
@@ -76,13 +81,22 @@ func loadAutoIncValue(sequences *sync.Map, tableName string) uint64 {
76
81
}
77
82
78
83
// Current returns the next value to be generated in the auto increment sequence for the table named
79
- func (a * AutoIncrementTracker ) Current (tableName string ) uint64 {
80
- return loadAutoIncValue (a .sequences , tableName )
84
+ func (a * AutoIncrementTracker ) Current (tableName string ) (uint64 , error ) {
85
+ err := a .waitForInit ()
86
+ if err != nil {
87
+ return 0 , err
88
+ }
89
+ return loadAutoIncValue (a .sequences , tableName ), nil
81
90
}
82
91
83
92
// Next returns the next auto increment value for the table named using the provided value from an insert (which may
84
93
// be null or 0, in which case it will be generated from the sequence).
85
94
func (a * AutoIncrementTracker ) Next (tbl string , insertVal interface {}) (uint64 , error ) {
95
+ err := a .waitForInit ()
96
+ if err != nil {
97
+ return 0 , err
98
+ }
99
+
86
100
tbl = strings .ToLower (tbl )
87
101
88
102
given , err := CoerceAutoIncrementValue (insertVal )
@@ -113,6 +127,10 @@ func (a *AutoIncrementTracker) Next(tbl string, insertVal interface{}) (uint64,
113
127
}
114
128
115
129
func (a * AutoIncrementTracker ) CoerceAutoIncrementValue (val interface {}) (uint64 , error ) {
130
+ err := a .waitForInit ()
131
+ if err != nil {
132
+ return 0 , err
133
+ }
116
134
return CoerceAutoIncrementValue (val )
117
135
}
118
136
@@ -140,6 +158,11 @@ func CoerceAutoIncrementValue(val interface{}) (uint64, error) {
140
158
// table. Otherwise, the update is silently disregarded. So far this matches the MySQL behavior, but Dolt uses the
141
159
// maximum value for this table across all branches.
142
160
func (a * AutoIncrementTracker ) Set (ctx * sql.Context , tableName string , table * doltdb.Table , ws ref.WorkingSetRef , newAutoIncVal uint64 ) (* doltdb.Table , error ) {
161
+ err := a .waitForInit ()
162
+ if err != nil {
163
+ return nil , err
164
+ }
165
+
143
166
tableName = strings .ToLower (tableName )
144
167
145
168
release := a .mm .Lock (tableName )
@@ -338,16 +361,27 @@ func getMaxIndexValue(ctx context.Context, indexData durable.Index) (uint64, err
338
361
}
339
362
340
363
// AddNewTable initializes a new table with an auto increment column to the tracker, as necessary
341
- func (a * AutoIncrementTracker ) AddNewTable (tableName string ) {
364
+ func (a * AutoIncrementTracker ) AddNewTable (tableName string ) error {
365
+ err := a .waitForInit ()
366
+ if err != nil {
367
+ return err
368
+ }
369
+
342
370
tableName = strings .ToLower (tableName )
343
371
// only initialize the sequence for this table if no other branch has such a table
344
372
a .sequences .LoadOrStore (tableName , uint64 (1 ))
373
+ return nil
345
374
}
346
375
347
376
// DropTable drops the table with the name given.
348
377
// To establish the new auto increment value, callers must also pass all other working sets in scope that may include
349
378
// a table with the same name, omitting the working set that just deleted the table named.
350
379
func (a * AutoIncrementTracker ) DropTable (ctx * sql.Context , tableName string , wses ... * doltdb.WorkingSet ) error {
380
+ err := a .waitForInit ()
381
+ if err != nil {
382
+ return err
383
+ }
384
+
351
385
tableName = strings .ToLower (tableName )
352
386
353
387
release := a .mm .Lock (tableName )
@@ -389,6 +423,11 @@ func (a *AutoIncrementTracker) DropTable(ctx *sql.Context, tableName string, wse
389
423
}
390
424
391
425
func (a * AutoIncrementTracker ) AcquireTableLock (ctx * sql.Context , tableName string ) (func (), error ) {
426
+ err := a .waitForInit ()
427
+ if err != nil {
428
+ return nil , err
429
+ }
430
+
392
431
_ , i , _ := sql .SystemVariables .GetGlobal ("innodb_autoinc_lock_mode" )
393
432
lockMode := LockMode (i .(int64 ))
394
433
if lockMode == LockMode_Interleaved {
@@ -398,7 +437,22 @@ func (a *AutoIncrementTracker) AcquireTableLock(ctx *sql.Context, tableName stri
398
437
return a .mm .Lock (tableName ), nil
399
438
}
400
439
401
- func (a * AutoIncrementTracker ) InitWithRoots (ctx context.Context , roots ... doltdb.Rootish ) error {
440
+ func (a * AutoIncrementTracker ) waitForInit () error {
441
+ a .wg .Wait ()
442
+ return a .initErr
443
+ }
444
+
445
+ func (a * AutoIncrementTracker ) runInitWithRootsAsync (ctx context.Context , roots ... doltdb.Rootish ) {
446
+ a .init .Do (func () {
447
+ a .wg .Add (1 )
448
+ go func () {
449
+ defer a .wg .Done ()
450
+ a .initErr = a .initWithRoots (ctx , roots ... )
451
+ }()
452
+ })
453
+ }
454
+
455
+ func (a * AutoIncrementTracker ) initWithRoots (ctx context.Context , roots ... doltdb.Rootish ) error {
402
456
eg , egCtx := errgroup .WithContext (ctx )
403
457
eg .SetLimit (128 )
404
458
@@ -435,3 +489,8 @@ func (a *AutoIncrementTracker) InitWithRoots(ctx context.Context, roots ...doltd
435
489
436
490
return eg .Wait ()
437
491
}
492
+
493
+ func (a * AutoIncrementTracker ) InitWithRoots (ctx context.Context , roots ... doltdb.Rootish ) error {
494
+ a .runInitWithRootsAsync (ctx , roots ... )
495
+ return a .waitForInit ()
496
+ }
0 commit comments