bug: concurrent migration data race in ent/atlas
- Dominant language
- Go
- Stars
- 17.2k
- Forks
- 1k
- PR merge metrics
- No merged PRs in 30d
Description
- [x] The issue is present in the latest release.
- [x] I have searched the [issues](https://github.com/ent/ent/issues) of this repository and believe that this is not a duplicate.
## Current Behavior 😯
Commit [397ebe9](https://github.com/ent/ent/commit/397ebe9f39af0f5481eb27c58dd9a97e8bfc089c) added `schema.Table.mu` and locking around `Atlas.setupTables` to allow concurrent migrations without copying generated tables.
However, concurrent migrations still report data races when they use the shared generated schema tables, even if each migration targets a unique SQLite database (e.g. in-memory database).
## Expected Behavior 🤔
Concurrent migrations using separate databases should be race-free when the generated schema tables are shared.
## Steps to Reproduce 🕹
Our tests create a unique in-memory SQLite (modernc) database for every test, so there is an empty database state:
```go
func NewClient(tb testing.TB) *ent.Client {
tb.Helper()
db, err := database.OpenDSN(ctx, uniqueMemoryDSN())
if err != nil {
tb.Fatal(err)
}
if err := database.Migrate(ctx, db); err != nil {
tb.Fatal(err)
}
return db
}
```
Tests run in parallel, so multiple calls to `database.Migrate` execute concurrently against different databases.
Example of some of these races
```console
go test -race ./internal/...
==================
WARNING: DATA RACE
Write at 0x00000394aa38 by goroutine 27:
entgo.io/ent/dialect/sql/schema.(*Atlas).setupTables()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:1100 +0x7ef
entgo.io/ent/dialect/sql/schema.(*Atlas).Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:107 +0x70
github.com/lrstanley/moroi/internal/database/ent/migrate.Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:58 +0x1b2
github.com/lrstanley/moroi/internal/database/ent/migrate.(*Schema).Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:49 +0x91
github.com/lrstanley/moroi/internal/database.Migrate()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/client.go:94 +0x195
github.com/lrstanley/moroi/internal/database/schematests.NewClient()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/schematests/core.go:46 +0x144
github.com/lrstanley/moroi/internal/auth_test.TestLookupRevokedAPIKey()
/home/liam/go/src/github.com/lrstanley/moroi/internal/auth/apikey_test.go:131 +0x4f
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:2258 +0x38
Previous read at 0x00000394aa38 by goroutine 24:
entgo.io/ent/dialect/sql/schema.(*Atlas).realm()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:908 +0x1512
entgo.io/ent/dialect/sql/schema.(*Atlas).StateReader.func1()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:535 +0x616
ariga.io/atlas/sql/migrate.StateReaderFunc.ReadState()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/migrate/migrate.go:149 +0x558
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:692 +0x45e
ariga.io/atlas/sql/sqlite.(*inspect).InspectSchema()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/driver.go:451 +0x5d0
ariga.io/atlas/sql/sqlite.(*inspect).databases()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/inspect.go:344 +0x225
ariga.io/atlas/sql/sqlite.(*inspect).InspectSchema()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/driver.go:432 +0x158
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:671 +0x32b
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:671 +0x32b
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:622 +0x116f
entgo.io/ent/dialect/sql.ScanOne()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:19 +0x5c
entgo.io/ent/dialect/sql.ScanInt64()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:44 +0x5d
entgo.io/ent/dialect/sql.ScanInt()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:52 +0x31d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:134 +0x327
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.(*SQLite).init()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/sqlite.go:68 +0x78
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:614 +0xdd0
entgo.io/ent/dialect/sql.ScanInt64()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:44 +0x5d
entgo.io/ent/dialect/sql.ScanInt()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:52 +0x31d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:134 +0x327
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.(*SQLite).init()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/sqlite.go:68 +0x78
entgo.io/ent/dialect/sql/schema.(*Atlas).entDialect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:1134 +0x307
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:598 +0x9be
entgo.io/ent/dialect/sql/schema.(*Atlas).create-fm()
:1 +0x5c
entgo.io/ent/dialect/sql/schema.CreateFunc.Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:124 +0x5c
entgo.io/ent/dialect/sql/schema.(*Atlas).Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:112 +0x1ad
github.com/lrstanley/moroi/internal/database/ent/migrate.Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:58 +0x1b2
github.com/lrstanley/moroi/internal/database/ent/migrate.(*Schema).Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:49 +0x91
github.com/lrstanley/moroi/internal/database.Migrate()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/client.go:94 +0x195
github.com/lrstanley/moroi/internal/database/schematests.NewClient()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/schematests/core.go:46 +0x144
github.com/lrstanley/moroi/internal/auth_test.TestCreateAndLookupAPIKey()
/home/liam/go/src/github.com/lrstanley/moroi/internal/auth/apikey_test.go:42 +0x52
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:2258 +0x38
Goroutine 27 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:2258 +0xb12
testing.runTests.func1()
/usr/local/go/src/testing/testing.go:2742 +0x84
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.runTests()
/usr/local/go/src/testing/testing.go:2740 +0x9e9
testing.(*M).Run()
/usr/local/go/src/testing/testing.go:2600 +0xf44
main.main()
_testmain.go:82 +0x164
Goroutine 24 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:2258 +0xb12
testing.runTests.func1()
/usr/local/go/src/testing/testing.go:2742 +0x84
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.runTests()
/usr/local/go/src/testing/testing.go:2740 +0x9e9
testing.(*M).Run()
/usr/local/go/src/testing/testing.go:2600 +0xf44
main.main()
_testmain.go:82 +0x164
==================
==================
WARNING: DATA RACE
Write at 0x00000394a400 by goroutine 27:
entgo.io/ent/dialect/sql/schema.(*Atlas).setupTables()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:1089 +0x2fe
entgo.io/ent/dialect/sql/schema.(*Atlas).Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:107 +0x70
github.com/lrstanley/moroi/internal/database/ent/migrate.Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:58 +0x1b2
github.com/lrstanley/moroi/internal/database/ent/migrate.(*Schema).Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:49 +0x91
github.com/lrstanley/moroi/internal/database.Migrate()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/client.go:94 +0x195
github.com/lrstanley/moroi/internal/database/schematests.NewClient()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/schematests/core.go:46 +0x144
github.com/lrstanley/moroi/internal/auth_test.TestLookupRevokedAPIKey()
/home/liam/go/src/github.com/lrstanley/moroi/internal/auth/apikey_test.go:131 +0x4f
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:2258 +0x38
Previous read at 0x00000394a400 by goroutine 24:
entgo.io/ent/dialect/sql/schema.(*Atlas).aIndexes()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:1063 +0x427
entgo.io/ent/dialect/sql/schema.(*Atlas).realm()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:896 +0x1072
entgo.io/ent/dialect/sql/schema.(*Atlas).StateReader.func1()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:535 +0x616
ariga.io/atlas/sql/migrate.StateReaderFunc.ReadState()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/migrate/migrate.go:149 +0x558
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:692 +0x45e
ariga.io/atlas/sql/sqlite.(*inspect).InspectSchema()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/driver.go:451 +0x5d0
ariga.io/atlas/sql/sqlite.(*inspect).databases()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/inspect.go:344 +0x225
ariga.io/atlas/sql/sqlite.(*inspect).InspectSchema()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/driver.go:432 +0x158
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:671 +0x32b
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:671 +0x32b
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:622 +0x116f
entgo.io/ent/dialect/sql.ScanOne()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:19 +0x5c
entgo.io/ent/dialect/sql.ScanInt64()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:44 +0x5d
entgo.io/ent/dialect/sql.ScanInt()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:52 +0x31d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:134 +0x327
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.(*SQLite).init()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/sqlite.go:68 +0x78
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:614 +0xdd0
entgo.io/ent/dialect/sql.ScanInt64()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:44 +0x5d
entgo.io/ent/dialect/sql.ScanInt()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:52 +0x31d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:134 +0x327
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.(*SQLite).init()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/sqlite.go:68 +0x78
entgo.io/ent/dialect/sql/schema.(*Atlas).entDialect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:1134 +0x307
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:598 +0x9be
entgo.io/ent/dialect/sql/schema.(*Atlas).create-fm()
:1 +0x5c
entgo.io/ent/dialect/sql/schema.CreateFunc.Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:124 +0x5c
entgo.io/ent/dialect/sql/schema.(*Atlas).Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:112 +0x1ad
github.com/lrstanley/moroi/internal/database/ent/migrate.Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:58 +0x1b2
github.com/lrstanley/moroi/internal/database/ent/migrate.(*Schema).Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:49 +0x91
github.com/lrstanley/moroi/internal/database.Migrate()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/client.go:94 +0x195
github.com/lrstanley/moroi/internal/database/schematests.NewClient()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/schematests/core.go:46 +0x144
github.com/lrstanley/moroi/internal/auth_test.TestCreateAndLookupAPIKey()
/home/liam/go/src/github.com/lrstanley/moroi/internal/auth/apikey_test.go:42 +0x52
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:2258 +0x38
Goroutine 27 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:2258 +0xb12
testing.runTests.func1()
/usr/local/go/src/testing/testing.go:2742 +0x84
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.runTests()
/usr/local/go/src/testing/testing.go:2740 +0x9e9
testing.(*M).Run()
/usr/local/go/src/testing/testing.go:2600 +0xf44
main.main()
_testmain.go:82 +0x164
Goroutine 24 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:2258 +0xb12
testing.runTests.func1()
/usr/local/go/src/testing/testing.go:2742 +0x84
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.runTests()
/usr/local/go/src/testing/testing.go:2740 +0x9e9
testing.(*M).Run()
/usr/local/go/src/testing/testing.go:2600 +0xf44
main.main()
_testmain.go:82 +0x164
==================
==================
WARNING: DATA RACE
Write at 0x00000394a7c8 by goroutine 37:
entgo.io/ent/dialect/sql/schema.(*Atlas).setupTables()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:1100 +0x7ef
entgo.io/ent/dialect/sql/schema.(*Atlas).Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:107 +0x70
github.com/lrstanley/moroi/internal/database/ent/migrate.Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:58 +0x1b2
github.com/lrstanley/moroi/internal/database/ent/migrate.(*Schema).Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:49 +0x91
github.com/lrstanley/moroi/internal/database.Migrate()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/client.go:94 +0x195
github.com/lrstanley/moroi/internal/database/schematests.NewClient()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/schematests/core.go:46 +0x144
github.com/lrstanley/moroi/internal/auth_test.newService()
/home/liam/go/src/github.com/lrstanley/moroi/internal/auth/service_test.go:19 +0x4e
github.com/lrstanley/moroi/internal/auth_test.TestServiceClear()
/home/liam/go/src/github.com/lrstanley/moroi/internal/auth/session_test.go:132 +0x4b
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:2258 +0x38
Previous read at 0x00000394a7c8 by goroutine 26:
entgo.io/ent/dialect/sql/schema.(*Atlas).realm()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:908 +0x1512
entgo.io/ent/dialect/sql/schema.(*Atlas).StateReader.func1()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:535 +0x616
ariga.io/atlas/sql/migrate.StateReaderFunc.ReadState()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/migrate/migrate.go:149 +0x558
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:692 +0x45e
ariga.io/atlas/sql/sqlite.(*inspect).InspectSchema()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/driver.go:451 +0x5d0
ariga.io/atlas/sql/sqlite.(*inspect).databases()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/inspect.go:344 +0x225
ariga.io/atlas/sql/sqlite.(*inspect).InspectSchema()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/driver.go:432 +0x158
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:671 +0x32b
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:671 +0x32b
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:622 +0x116f
entgo.io/ent/dialect/sql.ScanOne()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:19 +0x5c
entgo.io/ent/dialect/sql.ScanInt64()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:44 +0x5d
entgo.io/ent/dialect/sql.ScanInt()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:52 +0x31d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:134 +0x327
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.(*SQLite).init()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/sqlite.go:68 +0x78
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:614 +0xdd0
entgo.io/ent/dialect/sql.ScanInt64()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:44 +0x5d
entgo.io/ent/dialect/sql.ScanInt()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:52 +0x31d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:134 +0x327
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.(*SQLite).init()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/sqlite.go:68 +0x78
entgo.io/ent/dialect/sql/schema.(*Atlas).entDialect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:1134 +0x307
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:598 +0x9be
entgo.io/ent/dialect/sql/schema.(*Atlas).create-fm()
:1 +0x5c
entgo.io/ent/dialect/sql/schema.CreateFunc.Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:124 +0x5c
entgo.io/ent/dialect/sql/schema.(*Atlas).Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:112 +0x1ad
github.com/lrstanley/moroi/internal/database/ent/migrate.Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:58 +0x1b2
github.com/lrstanley/moroi/internal/database/ent/migrate.(*Schema).Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:49 +0x91
github.com/lrstanley/moroi/internal/database.Migrate()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/client.go:94 +0x195
github.com/lrstanley/moroi/internal/database/schematests.NewClient()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/schematests/core.go:46 +0x144
github.com/lrstanley/moroi/internal/auth_test.TestCreateAPIKeyRejectsPastExpiry()
/home/liam/go/src/github.com/lrstanley/moroi/internal/auth/apikey_test.go:114 +0x4f
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:2258 +0x38
Goroutine 37 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:2258 +0xb12
testing.runTests.func1()
/usr/local/go/src/testing/testing.go:2742 +0x84
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.runTests()
/usr/local/go/src/testing/testing.go:2740 +0x9e9
testing.(*M).Run()
/usr/local/go/src/testing/testing.go:2600 +0xf44
main.main()
_testmain.go:82 +0x164
Goroutine 26 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:2258 +0xb12
testing.runTests.func1()
/usr/local/go/src/testing/testing.go:2742 +0x84
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.runTests()
/usr/local/go/src/testing/testing.go:2740 +0x9e9
testing.(*M).Run()
/usr/local/go/src/testing/testing.go:2600 +0xf44
main.main()
_testmain.go:82 +0x164
==================
==================
WARNING: DATA RACE
Write at 0x00000394a400 by goroutine 37:
entgo.io/ent/dialect/sql/schema.(*Atlas).setupTables()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:1089 +0x2fe
entgo.io/ent/dialect/sql/schema.(*Atlas).Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:107 +0x70
github.com/lrstanley/moroi/internal/database/ent/migrate.Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:58 +0x1b2
github.com/lrstanley/moroi/internal/database/ent/migrate.(*Schema).Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:49 +0x91
github.com/lrstanley/moroi/internal/database.Migrate()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/client.go:94 +0x195
github.com/lrstanley/moroi/internal/database/schematests.NewClient()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/schematests/core.go:46 +0x144
github.com/lrstanley/moroi/internal/auth_test.newService()
/home/liam/go/src/github.com/lrstanley/moroi/internal/auth/service_test.go:19 +0x4e
github.com/lrstanley/moroi/internal/auth_test.TestServiceClear()
/home/liam/go/src/github.com/lrstanley/moroi/internal/auth/session_test.go:132 +0x4b
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:2258 +0x38
Previous read at 0x00000394a400 by goroutine 26:
entgo.io/ent/dialect/sql/schema.(*Atlas).aIndexes()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:1063 +0x427
entgo.io/ent/dialect/sql/schema.(*Atlas).realm()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:896 +0x1072
entgo.io/ent/dialect/sql/schema.(*Atlas).StateReader.func1()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:535 +0x616
ariga.io/atlas/sql/migrate.StateReaderFunc.ReadState()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/migrate/migrate.go:149 +0x558
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:692 +0x45e
ariga.io/atlas/sql/sqlite.(*inspect).InspectSchema()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/driver.go:451 +0x5d0
ariga.io/atlas/sql/sqlite.(*inspect).databases()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/inspect.go:344 +0x225
ariga.io/atlas/sql/sqlite.(*inspect).InspectSchema()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/driver.go:432 +0x158
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:671 +0x32b
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:671 +0x32b
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:622 +0x116f
entgo.io/ent/dialect/sql.ScanOne()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:19 +0x5c
entgo.io/ent/dialect/sql.ScanInt64()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:44 +0x5d
entgo.io/ent/dialect/sql.ScanInt()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:52 +0x31d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:134 +0x327
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.(*SQLite).init()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/sqlite.go:68 +0x78
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:614 +0xdd0
entgo.io/ent/dialect/sql.ScanInt64()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:44 +0x5d
entgo.io/ent/dialect/sql.ScanInt()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:52 +0x31d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:134 +0x327
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.(*SQLite).init()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/sqlite.go:68 +0x78
entgo.io/ent/dialect/sql/schema.(*Atlas).entDialect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:1134 +0x307
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:598 +0x9be
entgo.io/ent/dialect/sql/schema.(*Atlas).create-fm()
:1 +0x5c
entgo.io/ent/dialect/sql/schema.CreateFunc.Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:124 +0x5c
entgo.io/ent/dialect/sql/schema.(*Atlas).Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:112 +0x1ad
github.com/lrstanley/moroi/internal/database/ent/migrate.Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:58 +0x1b2
github.com/lrstanley/moroi/internal/database/ent/migrate.(*Schema).Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:49 +0x91
github.com/lrstanley/moroi/internal/database.Migrate()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/client.go:94 +0x195
github.com/lrstanley/moroi/internal/database/schematests.NewClient()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/schematests/core.go:46 +0x144
github.com/lrstanley/moroi/internal/auth_test.TestCreateAPIKeyRejectsPastExpiry()
/home/liam/go/src/github.com/lrstanley/moroi/internal/auth/apikey_test.go:114 +0x4f
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:2258 +0x38
Goroutine 37 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:2258 +0xb12
testing.runTests.func1()
/usr/local/go/src/testing/testing.go:2742 +0x84
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.runTests()
/usr/local/go/src/testing/testing.go:2740 +0x9e9
testing.(*M).Run()
/usr/local/go/src/testing/testing.go:2600 +0xf44
main.main()
_testmain.go:82 +0x164
Goroutine 26 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:2258 +0xb12
testing.runTests.func1()
/usr/local/go/src/testing/testing.go:2742 +0x84
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.runTests()
/usr/local/go/src/testing/testing.go:2740 +0x9e9
testing.(*M).Run()
/usr/local/go/src/testing/testing.go:2600 +0xf44
main.main()
_testmain.go:82 +0x164
==================
==================
WARNING: DATA RACE
Write at 0x00000394a7c8 by goroutine 32:
entgo.io/ent/dialect/sql/schema.(*Atlas).setupTables()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:1100 +0x7ef
entgo.io/ent/dialect/sql/schema.(*Atlas).Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:107 +0x70
github.com/lrstanley/moroi/internal/database/ent/migrate.Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:58 +0x1b2
github.com/lrstanley/moroi/internal/database/ent/migrate.(*Schema).Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:49 +0x91
github.com/lrstanley/moroi/internal/database.Migrate()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/client.go:94 +0x195
github.com/lrstanley/moroi/internal/database/schematests.NewClient()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/schematests/core.go:46 +0x144
github.com/lrstanley/moroi/internal/auth_test.TestServiceRejectsInvalidSessionKeys()
/home/liam/go/src/github.com/lrstanley/moroi/internal/auth/service_test.go:155 +0x52
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:2258 +0x38
Previous read at 0x00000394a7c8 by goroutine 27:
entgo.io/ent/dialect/sql/schema.(*Atlas).realm()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:908 +0x1512
entgo.io/ent/dialect/sql/schema.(*Atlas).StateReader.func1()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:535 +0x616
ariga.io/atlas/sql/migrate.StateReaderFunc.ReadState()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/migrate/migrate.go:149 +0x558
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:692 +0x45e
ariga.io/atlas/sql/sqlite.(*inspect).InspectSchema()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/driver.go:451 +0x5d0
ariga.io/atlas/sql/sqlite.(*inspect).databases()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/inspect.go:344 +0x225
ariga.io/atlas/sql/sqlite.(*inspect).InspectSchema()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/driver.go:432 +0x158
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:671 +0x32b
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:671 +0x32b
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:622 +0x116f
entgo.io/ent/dialect/sql.ScanOne()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:19 +0x5c
entgo.io/ent/dialect/sql.ScanInt64()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:44 +0x5d
entgo.io/ent/dialect/sql.ScanInt()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:52 +0x31d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:134 +0x327
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.(*SQLite).init()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/sqlite.go:68 +0x78
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:614 +0xdd0
entgo.io/ent/dialect/sql.ScanInt64()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:44 +0x5d
entgo.io/ent/dialect/sql.ScanInt()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:52 +0x31d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:134 +0x327
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.(*SQLite).init()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/sqlite.go:68 +0x78
entgo.io/ent/dialect/sql/schema.(*Atlas).entDialect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:1134 +0x307
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:598 +0x9be
entgo.io/ent/dialect/sql/schema.(*Atlas).create-fm()
:1 +0x5c
entgo.io/ent/dialect/sql/schema.CreateFunc.Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:124 +0x5c
entgo.io/ent/dialect/sql/schema.(*Atlas).Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:112 +0x1ad
github.com/lrstanley/moroi/internal/database/ent/migrate.Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:58 +0x1b2
github.com/lrstanley/moroi/internal/database/ent/migrate.(*Schema).Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:49 +0x91
github.com/lrstanley/moroi/internal/database.Migrate()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/client.go:94 +0x195
github.com/lrstanley/moroi/internal/database/schematests.NewClient()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/schematests/core.go:46 +0x144
github.com/lrstanley/moroi/internal/auth_test.TestLookupRevokedAPIKey()
/home/liam/go/src/github.com/lrstanley/moroi/internal/auth/apikey_test.go:131 +0x4f
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:2258 +0x38
Goroutine 32 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:2258 +0xb12
testing.runTests.func1()
/usr/local/go/src/testing/testing.go:2742 +0x84
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.runTests()
/usr/local/go/src/testing/testing.go:2740 +0x9e9
testing.(*M).Run()
/usr/local/go/src/testing/testing.go:2600 +0xf44
main.main()
_testmain.go:82 +0x164
Goroutine 27 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:2258 +0xb12
testing.runTests.func1()
/usr/local/go/src/testing/testing.go:2742 +0x84
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.runTests()
/usr/local/go/src/testing/testing.go:2740 +0x9e9
testing.(*M).Run()
/usr/local/go/src/testing/testing.go:2600 +0xf44
main.main()
_testmain.go:82 +0x164
==================
--- FAIL: TestServiceWriteAndAuthContext (0.12s)
testing.go:1865: race detected during execution of test
--- FAIL: TestCreateAndLookupAPIKey (0.15s)
testing.go:1865: race detected during execution of test
--- FAIL: TestCreateAPIKeyRejectsPastExpiry (0.16s)
testing.go:1865: race detected during execution of test
--- FAIL: TestBearerOverridesCookie (0.16s)
testing.go:1865: race detected during execution of test
--- FAIL: TestServiceClear (0.17s)
testing.go:1865: race detected during execution of test
--- FAIL: TestLookupExpiredAPIKey (0.18s)
testing.go:1865: race detected during execution of test
--- FAIL: TestLookupRevokedAPIKey (0.19s)
testing.go:1865: race detected during execution of test
--- FAIL: TestServiceRejectsInvalidSessionKeys (0.21s)
testing.go:1865: race detected during execution of test
--- FAIL: TestVerifyPassword (0.10s)
testing.go:1865: race detected during execution of test
--- FAIL: TestServiceSetupIsAtomic (0.42s)
testing.go:1865: race detected during execution of test
--- FAIL: TestServiceInitialization (0.54s)
testing.go:1865: race detected during execution of test
--- FAIL: TestServiceSetupAndAuthenticate (0.68s)
testing.go:1865: race detected during execution of test
FAIL
FAIL github.com/lrstanley/moroi/internal/auth 0.895s
? github.com/lrstanley/moroi/internal/database [no test files]
? github.com/lrstanley/moroi/internal/database/ent [no test files]
? github.com/lrstanley/moroi/internal/database/ent/apikey [no test files]
? github.com/lrstanley/moroi/internal/database/ent/asset [no test files]
? github.com/lrstanley/moroi/internal/database/ent/download [no test files]
? github.com/lrstanley/moroi/internal/database/ent/downloaditem [no test files]
? github.com/lrstanley/moroi/internal/database/ent/downloadlog [no test files]
? github.com/lrstanley/moroi/internal/database/ent/downloadprogress [no test files]
? github.com/lrstanley/moroi/internal/database/ent/enttest [no test files]
? github.com/lrstanley/moroi/internal/database/ent/hook [no test files]
? github.com/lrstanley/moroi/internal/database/ent/intercept [no test files]
? github.com/lrstanley/moroi/internal/database/ent/migrate [no test files]
? github.com/lrstanley/moroi/internal/database/ent/predicate [no test files]
? github.com/lrstanley/moroi/internal/database/ent/rest [no test files]
? github.com/lrstanley/moroi/internal/database/ent/runtime [no test files]
? github.com/lrstanley/moroi/internal/database/ent/setting [no test files]
? github.com/lrstanley/moroi/internal/database/ent/template [no test files]
? github.com/lrstanley/moroi/internal/database/schema [no test files]
==================
WARNING: DATA RACE
Write at 0x0000037e60d8 by goroutine 21:
entgo.io/ent/dialect/sql/schema.(*Atlas).setupTables()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:1100 +0x7ef
entgo.io/ent/dialect/sql/schema.(*Atlas).Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:107 +0x70
github.com/lrstanley/moroi/internal/database/ent/migrate.Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:58 +0x1b2
github.com/lrstanley/moroi/internal/database/ent/migrate.(*Schema).Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:49 +0x91
github.com/lrstanley/moroi/internal/database.Migrate()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/client.go:94 +0x195
github.com/lrstanley/moroi/internal/database/schematests.NewClient()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/schematests/core.go:46 +0x144
github.com/lrstanley/moroi/internal/database/schematests.TestAPIKeyCreate()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/schematests/apikey_test.go:18 +0x52
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:2258 +0x38
Previous read at 0x0000037e60d8 by goroutine 36:
entgo.io/ent/dialect/sql/schema.(*Atlas).realm()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:908 +0x1512
entgo.io/ent/dialect/sql/schema.(*Atlas).StateReader.func1()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:535 +0x616
ariga.io/atlas/sql/migrate.StateReaderFunc.ReadState()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/migrate/migrate.go:149 +0x558
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:692 +0x45e
ariga.io/atlas/sql/sqlite.(*inspect).InspectSchema()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/driver.go:451 +0x5d0
ariga.io/atlas/sql/sqlite.(*inspect).databases()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/inspect.go:344 +0x225
ariga.io/atlas/sql/sqlite.(*inspect).InspectSchema()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/driver.go:432 +0x158
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:671 +0x32b
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:671 +0x32b
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:622 +0x116f
entgo.io/ent/dialect/sql.ScanOne()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:19 +0x5c
entgo.io/ent/dialect/sql.ScanInt64()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:44 +0x5d
entgo.io/ent/dialect/sql.ScanInt()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:52 +0x31d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:134 +0x327
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.(*SQLite).init()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/sqlite.go:68 +0x78
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:614 +0xdd0
entgo.io/ent/dialect/sql.ScanInt64()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:44 +0x5d
entgo.io/ent/dialect/sql.ScanInt()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:52 +0x31d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:134 +0x327
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.(*SQLite).init()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/sqlite.go:68 +0x78
entgo.io/ent/dialect/sql/schema.(*Atlas).entDialect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:1134 +0x307
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:598 +0x9be
entgo.io/ent/dialect/sql/schema.(*Atlas).create-fm()
:1 +0x5c
entgo.io/ent/dialect/sql/schema.CreateFunc.Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:124 +0x5c
entgo.io/ent/dialect/sql/schema.(*Atlas).Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:112 +0x1ad
github.com/lrstanley/moroi/internal/database/ent/migrate.Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:58 +0x1b2
github.com/lrstanley/moroi/internal/database/ent/migrate.(*Schema).Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:49 +0x91
github.com/lrstanley/moroi/internal/database.Migrate()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/client.go:94 +0x195
github.com/lrstanley/moroi/internal/database/schematests.NewClient()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/schematests/core.go:46 +0x144
github.com/lrstanley/moroi/internal/database/schematests.TestTemplateFlagConfigReject()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/schematests/template_test.go:111 +0x4f
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:2258 +0x38
Goroutine 21 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:2258 +0xb12
testing.runTests.func1()
/usr/local/go/src/testing/testing.go:2742 +0x84
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.runTests()
/usr/local/go/src/testing/testing.go:2740 +0x9e9
testing.(*M).Run()
/usr/local/go/src/testing/testing.go:2600 +0xf44
main.main()
_testmain.go:80 +0x164
Goroutine 36 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:2258 +0xb12
testing.runTests.func1()
/usr/local/go/src/testing/testing.go:2742 +0x84
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.runTests()
/usr/local/go/src/testing/testing.go:2740 +0x9e9
testing.(*M).Run()
/usr/local/go/src/testing/testing.go:2600 +0xf44
main.main()
_testmain.go:80 +0x164
==================
==================
WARNING: DATA RACE
Write at 0x0000037e5aa0 by goroutine 21:
entgo.io/ent/dialect/sql/schema.(*Atlas).setupTables()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:1089 +0x2fe
entgo.io/ent/dialect/sql/schema.(*Atlas).Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:107 +0x70
github.com/lrstanley/moroi/internal/database/ent/migrate.Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:58 +0x1b2
github.com/lrstanley/moroi/internal/database/ent/migrate.(*Schema).Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:49 +0x91
github.com/lrstanley/moroi/internal/database.Migrate()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/client.go:94 +0x195
github.com/lrstanley/moroi/internal/database/schematests.NewClient()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/schematests/core.go:46 +0x144
github.com/lrstanley/moroi/internal/database/schematests.TestAPIKeyCreate()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/schematests/apikey_test.go:18 +0x52
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:2258 +0x38
Previous read at 0x0000037e5aa0 by goroutine 36:
entgo.io/ent/dialect/sql/schema.(*Atlas).aIndexes()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:1063 +0x427
entgo.io/ent/dialect/sql/schema.(*Atlas).realm()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:896 +0x1072
entgo.io/ent/dialect/sql/schema.(*Atlas).StateReader.func1()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:535 +0x616
ariga.io/atlas/sql/migrate.StateReaderFunc.ReadState()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/migrate/migrate.go:149 +0x558
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:692 +0x45e
ariga.io/atlas/sql/sqlite.(*inspect).InspectSchema()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/driver.go:451 +0x5d0
ariga.io/atlas/sql/sqlite.(*inspect).databases()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/inspect.go:344 +0x225
ariga.io/atlas/sql/sqlite.(*inspect).InspectSchema()
/home/liam/go/pkg/mod/ariga.io/atlas@v1.3.0/sql/sqlite/driver.go:432 +0x158
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:671 +0x32b
entgo.io/ent/dialect/sql/schema.(*Atlas).planInspect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:671 +0x32b
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:622 +0x116f
entgo.io/ent/dialect/sql.ScanOne()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:19 +0x5c
entgo.io/ent/dialect/sql.ScanInt64()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:44 +0x5d
entgo.io/ent/dialect/sql.ScanInt()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:52 +0x31d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:134 +0x327
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.(*SQLite).init()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/sqlite.go:68 +0x78
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:614 +0xdd0
entgo.io/ent/dialect/sql.ScanInt64()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:44 +0x5d
entgo.io/ent/dialect/sql.ScanInt()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/scan.go:52 +0x31d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:134 +0x327
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.exist()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:130 +0x12d
entgo.io/ent/dialect/sql/schema.(*SQLite).init()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/sqlite.go:68 +0x78
entgo.io/ent/dialect/sql/schema.(*Atlas).entDialect()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:1134 +0x307
entgo.io/ent/dialect/sql/schema.(*Atlas).create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:598 +0x9be
entgo.io/ent/dialect/sql/schema.(*Atlas).create-fm()
:1 +0x5c
entgo.io/ent/dialect/sql/schema.CreateFunc.Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/migrate.go:124 +0x5c
entgo.io/ent/dialect/sql/schema.(*Atlas).Create()
/home/liam/go/pkg/mod/entgo.io/ent@v0.14.6/dialect/sql/schema/atlas.go:112 +0x1ad
github.com/lrstanley/moroi/internal/database/ent/migrate.Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:58 +0x1b2
github.com/lrstanley/moroi/internal/database/ent/migrate.(*Schema).Create()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/ent/migrate/migrate.go:49 +0x91
github.com/lrstanley/moroi/internal/database.Migrate()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/client.go:94 +0x195
github.com/lrstanley/moroi/internal/database/schematests.NewClient()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/schematests/core.go:46 +0x144
github.com/lrstanley/moroi/internal/database/schematests.TestTemplateFlagConfigReject()
/home/liam/go/src/github.com/lrstanley/moroi/internal/database/schematests/template_test.go:111 +0x4f
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:2258 +0x38
Goroutine 21 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:2258 +0xb12
testing.runTests.func1()
/usr/local/go/src/testing/testing.go:2742 +0x84
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.runTests()
/usr/local/go/src/testing/testing.go:2740 +0x9e9
testing.(*M).Run()
/usr/local/go/src/testing/testing.go:2600 +0xf44
main.main()
_testmain.go:80 +0x164
Goroutine 36 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:2258 +0xb12
testing.runTests.func1()
/usr/local/go/src/testing/testing.go:2742 +0x84
testing.tRunner()
/usr/local/go/src/testing/testing.go:2193 +0x21c
testing.runTests()
/usr/local/go/src/testing/testing.go:2740 +0x9e9
testing.(*M).Run()
/usr/local/go/src/testing/testing.go:2600 +0xf44
main.main()
_testmain.go:80 +0x164
==================
--- FAIL: TestTemplateFlagConfigReject (0.13s)
testing.go:1865: race detected during execution of test
--- FAIL: TestTemplateHostnameRegex (0.13s)
testing.go:1865: race detected during execution of test
--- FAIL: TestTemplateSeed (0.13s)
testing.go:1865: race detected during execution of test
--- FAIL: TestDownloadStatusHook (0.14s)
testing.go:1865: race detected during execution of test
--- FAIL: TestTemplateCreateBulk (0.15s)
testing.go:1865: race detected during execution of test
--- FAIL: TestTemplateJSONTextValueRoundTrip (0.16s)
testing.go:1865: race detected during execution of test
--- FAIL: TestAPIKeyCreate (0.17s)
testing.go:1865: race detected during execution of test
--- FAIL: TestDownloadProgressUniqueFilename (0.17s)
testing.go:1865: race detected during execution of test
--- FAIL: TestDownloadRetryHookNormalizesChildren (0.17s)
testing.go:1865: race detected during execution of test
--- FAIL: TestDownloadDeleteRejectsActiveDownload (0.17s)
testing.go:1865: race detected during execution of test
--- FAIL: TestTemplateDefaultUniqueness (0.19s)
testing.go:1865: race detected during execution of test
--- FAIL: TestDownloadBuildsFlagsSnapshot (0.19s)
testing.go:1865: race detected during execution of test
FAIL
FAIL github.com/lrstanley/moroi/internal/database/schematests 0.319s
```
The mutex added in `397ebe9` protects mutations within `setupTables`, but it is released before the rest of the migration proceeds. A concurrent migration can therefore:
1. Finish `setupTables`.
2. Begin reading the shared table descriptors during `realm` or `aIndexes`.
3. Allow another migration to enter `setupTables` and mutate those same descriptors.
The database connections are independent, so this does not appear to be SQLite database contention-related.
Serializing the complete `Schema.Create` call with a process-wide mutex eliminates the race for me, for now, though less ideal:
```go
migrateMu.Lock()
defer migrateMu.Unlock()
return db.Schema.Create(ctx, opts...)
```
## Your Environment 🌎
- Ent: `v0.14.6`
- Atlas: `v1.3.0`
- Go: `1.27.1`
- SQLite driver: `modernc.org/sqlite v1.58.0`
Contributor guide
Research direction
Start in dialect/sql/schema/atlas.go, especially Atlas.setupTables, realm, aIndexes, and the migration path shown in the race trace. Reproduce with the reported concurrent SQLite migrations and go test -race ./internal/...; done means separate-database migrations using shared generated schema tables complete without race reports.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, sqlite
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100