exp/sql: fix statement leak

Also verified in external test suite that this fixes MySQL
resource exhaustion problems, and also exposed a double-free
bug in the gosqlite3 driver (where gosqlite3 either got lucky
before, or was working around this bug)

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5544057
This commit is contained in:
Brad Fitzpatrick 2012-01-13 15:25:07 -08:00
parent 0575cd9de4
commit 1c441e259f
3 changed files with 48 additions and 6 deletions

View file

@ -243,8 +243,13 @@ func (db *DB) Query(query string, args ...interface{}) (*Rows, error) {
if err != nil {
return nil, err
}
defer stmt.Close()
return stmt.Query(args...)
rows, err := stmt.Query(args...)
if err != nil {
stmt.Close()
return nil, err
}
rows.closeStmt = stmt
return rows, nil
}
// QueryRow executes a query that is expected to return at most one row.
@ -706,9 +711,10 @@ type Rows struct {
releaseConn func()
rowsi driver.Rows
closed bool
lastcols []interface{}
lasterr error
closed bool
lastcols []interface{}
lasterr error
closeStmt *Stmt // if non-nil, statement to Close on close
}
// Next prepares the next result row for reading with the Scan method.
@ -789,6 +795,9 @@ func (rs *Rows) Close() error {
rs.closed = true
err := rs.rowsi.Close()
rs.releaseConn()
if rs.closeStmt != nil {
rs.closeStmt.Close()
}
return err
}