You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(kernel): never return ErrBadConn on the execute/read path (H1)
toDriverError mapped a NetworkError/Unavailable status to driver.ErrBadConn on
every path, including execute and result-read. On the statement path that is
unsafe: a network failure surfaced *after* the SEA statement was sent may have
committed server-side, and driver.ErrBadConn makes database/sql transparently
re-run the whole statement — a silent duplicate write for a non-idempotent
INSERT/UPDATE/MERGE. This violates Go's own ErrBadConn rule ("never return
ErrBadConn if the server might have performed the operation").
Split classification by path:
- toConnError (session lifecycle: open/close/config — nothing executed) keeps the
bad-conn mapping so the pool evicts a dead session. Safe: no statement ran.
- toStatementError (execute + result read) never returns ErrBadConn; it returns
the KernelError unchanged (sqlstate preserved).
This restores the contract the rest of the stack already honors: the kernel itself
classifies ExecuteStatement as NonIdempotent (retried only on connect-phase
failures, per src/client/retry.rs), and the Thrift backend marks ExecuteStatement
non-retryable. The kernel has already exhausted its safe internal retries by the
time Go sees the error, so a second database/sql-level retry was pure hazard.
Tests: TestToStatementErrorNeverBadConn asserts no ErrBadConn for
network/unavailable/unauthenticated on the statement path; TestToConnError keeps
the session-path eviction behavior.
Co-authored-by: Isaac
Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>
0 commit comments