This is an automated email from the ASF dual-hosted git repository.
zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-go.git
The following commit(s) were added to refs/heads/main by this push:
new 3194e442 fix(arrow-go/flightsql): route QueryContext through active
transaction (#692)
3194e442 is described below
commit 3194e4424057e0788cc71c261798a36034b34217
Author: wjywbs <[email protected]>
AuthorDate: Mon Mar 9 00:35:21 2026 -0400
fix(arrow-go/flightsql): route QueryContext through active transaction
(#692)
I used GPT-5.3-Codex to generate this patch to fix #667. I have reviewed
the outputs.
---
### Rationale for this change
`database/sql` queries executed via
`tx.QueryContext`/`tx.QueryRowContext` were not consistently bound to
the active Flight SQL transaction when no query arguments were provided.
The driver always used `c.client.Execute(...)`, which bypassed
transaction context and could not see uncommitted transactional state
(e.g., tables created inside the transaction).
### What changes are included in this PR?
- Updated `Connection.QueryContext` in the Flight SQL Go driver to use:
- `c.txn.Execute(...)` when `c.txn` is active and valid.
- `c.client.Execute(...)` otherwise.
- This aligns zero-argument query execution semantics with transactional
expectations in `database/sql`.
### Are these changes tested?
Yes.
- Added/used regression coverage in driver tests:
- `TestTxQueryContextUsesTransaction`
- Validation confirms:
- test fails when the fix is removed (cannot see tx-local table),
- test passes when the fix is applied.
### Are there any user-facing changes?
Yes, behavior is corrected for users of the Go Flight SQL `database/sql`
driver:
- `tx.QueryContext` / `tx.QueryRowContext` (including zero-arg queries)
now execute within the active transaction as expected.
- No API or configuration changes.
---
arrow/flight/flightsql/driver/driver.go | 10 +++++-
arrow/flight/flightsql/driver/driver_test.go | 46 ++++++++++++++++++++++++++++
2 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/arrow/flight/flightsql/driver/driver.go
b/arrow/flight/flightsql/driver/driver.go
index d039408d..ee78614b 100644
--- a/arrow/flight/flightsql/driver/driver.go
+++ b/arrow/flight/flightsql/driver/driver.go
@@ -505,7 +505,15 @@ func (c *Connection) QueryContext(ctx context.Context,
query string, args []driv
defer cancel()
}
- info, err := c.client.Execute(execCtx, query)
+ var (
+ info *flight.FlightInfo
+ err error
+ )
+ if c.txn != nil && c.txn.ID().IsValid() {
+ info, err = c.txn.Execute(execCtx, query)
+ } else {
+ info, err = c.client.Execute(execCtx, query)
+ }
if err != nil {
return nil, err
}
diff --git a/arrow/flight/flightsql/driver/driver_test.go
b/arrow/flight/flightsql/driver/driver_test.go
index 90329d06..8d0bd721 100644
--- a/arrow/flight/flightsql/driver/driver_test.go
+++ b/arrow/flight/flightsql/driver/driver_test.go
@@ -1505,6 +1505,52 @@ func (s *SqlTestSuite) TestTxRollback() {
wg.Wait()
}
+func (s *SqlTestSuite) TestTxQueryContextUsesTransaction() {
+ t := s.T()
+
+ // Create and start the server
+ server, addr, err := s.createServer()
+ require.NoError(t, err)
+
+ var wg sync.WaitGroup
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ require.NoError(s.T(), s.startServer(server))
+ }()
+ defer s.stopServer(server)
+ time.Sleep(100 * time.Millisecond)
+
+ // Configure client
+ cfg := s.Config
+ cfg.Address = addr
+ db, err := sql.Open("flightsql", cfg.DSN())
+ require.NoError(t, err)
+ defer db.Close()
+
+ ctx := context.Background()
+ tx, err := db.BeginTx(ctx, nil)
+ require.NoError(t, err)
+
+ // Create table and insert one row inside the transaction.
+ _, err = tx.ExecContext(ctx, fmt.Sprintf(s.Statements["create table"],
s.TableName))
+ require.NoError(t, err)
+ _, err = tx.ExecContext(ctx, fmt.Sprintf(s.Statements["insert"],
s.TableName, "inside-tx", 123))
+ require.NoError(t, err)
+
+ // This zero-argument query must execute inside the active transaction.
+ var count int
+ err = tx.QueryRowContext(ctx, fmt.Sprintf("SELECT COUNT(*) FROM %s",
s.TableName)).Scan(&count)
+ require.NoError(t, err)
+ require.Equal(t, 1, count)
+
+ require.NoError(t, tx.Rollback())
+
+ // Tear-down server
+ s.stopServer(server)
+ wg.Wait()
+}
+
func (s *SqlTestSuite) TestTxCommit() {
t := s.T()