* Add test for #4792: customSearchPath data race
This test demonstrates the data race on the customSearchPath slice when
accessed concurrently from multiple goroutines without synchronization.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix#4792: Add mutex protection for customSearchPath slice
The customSearchPath slice was being accessed concurrently from multiple
goroutines without synchronization, causing data races. This fix adds a
dedicated mutex (searchPathMutex) to protect all reads and writes to the
customSearchPath and searchPathPrefix fields.
Changes:
- Added searchPathMutex field to DbClient struct
- Initialize searchPathMutex in NewDbClient constructor
- Protected all customSearchPath writes in SetRequiredSessionSearchPath
- Protected all customSearchPath reads in GetRequiredSessionSearchPath
- Protected all customSearchPath reads in GetCustomSearchPath
- Fixed logging in ensureSessionSearchPath to use already-fetched value
- Updated test to initialize searchPathMutex for proper testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Add tests demonstrating bug #4793: Close() sets sessions=nil without mutex
These tests demonstrate the race condition where Close() sets c.sessions
to nil without holding the mutex, while AcquireSession() tries to access
the map with the mutex held.
Running with -race detects the data race and the test panics with
"assignment to entry in nil map".
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix#4793: Protect sessions map access with mutex in Close()
Acquire sessionsMutex before setting sessions to nil in Close() to prevent
data race with AcquireSession(). Also add nil check in AcquireSession() to
handle the case where Close() has been called.
This prevents the panic "assignment to entry in nil map" when Close() and
AcquireSession() are called concurrently.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Add test for #4808: Race condition on disableTiming field
Add test that verifies disableTiming field uses atomic.Bool instead of
plain bool to prevent race conditions.
The test checks that:
- disableTiming is declared as atomic.Bool
- shouldFetchTiming() uses atomic Load()
- getQueryTiming() uses atomic Store() operations
- Direct assignments that cause races are not present
This test will fail until the implementation is fixed.
* Fix#4808: Use atomic.Bool for disableTiming to prevent race condition
- JSON output format has changed to move the rows to under a `rows` property, with timing information under the `metadata` property
- Update timing display to show rows returned and rows fetched, as well as adding verbose mode which lists all scans
- Use enums for output mode and timing mode - timing is now either `on`, `off` or `verbose`
- Bugfix: ensure error is returned from ExecuteSystemClientCall. Closes#4246
- Execute RefreshConnections asyncronously
- Add connection_state table to indicate the loading state of connections
- Optimise RefreshConnections by cloning connection schemas
- Add locking to ensure only a single instance of RefreshConnections runs
- Start executing queries without waiting for connections to load, add smart error handling to wait for required connection
- Optimise autocomplete for high connection count
- Autocomplete and inspect data available before all conections are refreshed
- Update file watcher to respond to CHMOD, so thaat it pickes up deletion of file contents
Closes#3394Closes#3267
Limit connection lifetime in db connection pool. Closes#2375
Limit connection lifetime in db connection pool. Closes#2375
Limit connection lifetime in db connection pool. Closes#2375
Limit connection lifetime in db connection pool. Closes#2375