database/sql: don't close a driver.Conn until its Stmts are closed

Fixes #5046

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/8016044
This commit is contained in:
Brad Fitzpatrick 2013-03-25 16:50:27 -07:00
parent f20f8b8b0a
commit 209f6b1d2c
3 changed files with 137 additions and 20 deletions

View file

@ -65,6 +65,12 @@ func closeDB(t *testing.T, db *DB) {
fmt.Printf("Panic: %v\n", e)
panic(e)
}
defer setHookpostCloseConn(nil)
setHookpostCloseConn(func(_ *fakeConn, err error) {
if err != nil {
t.Errorf("Error closing fakeConn: %v", err)
}
})
err := db.Close()
if err != nil {
t.Fatalf("error closing DB: %v", err)
@ -790,3 +796,51 @@ func TestMaxIdleConns(t *testing.T) {
t.Errorf("freeConns = %d; want 0", got)
}
}
// golang.org/issue/5046
func TestCloseConnBeforeStmts(t *testing.T) {
defer setHookpostCloseConn(nil)
setHookpostCloseConn(func(_ *fakeConn, err error) {
if err != nil {
t.Errorf("Error closing fakeConn: %v", err)
}
})
db := newTestDB(t, "people")
stmt, err := db.Prepare("SELECT|people|name|")
if err != nil {
t.Fatal(err)
}
if len(db.freeConn) != 1 {
t.Fatalf("expected 1 freeConn; got %d", len(db.freeConn))
}
dc := db.freeConn[0]
if dc.closed {
t.Errorf("conn shouldn't be closed")
}
err = db.Close()
if err != nil {
t.Errorf("db Close = %v", err)
}
if !dc.closed {
t.Errorf("after db.Close, driverConn should be closed")
}
if dc.ci == nil {
t.Errorf("after db.Close, driverConn should still have its Conn interface")
}
err = stmt.Close()
if err != nil {
t.Errorf("Stmt close = %v", err)
}
if !dc.closed {
t.Errorf("conn should be closed")
}
if dc.ci != nil {
t.Errorf("after Stmt Close, driverConn's Conn interface should be nil")
}
}