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
diff --git a/src/pkg/exp/sql/sql.go b/src/pkg/exp/sql/sql.go
index a076fcd..4e68c3e 100644
--- a/src/pkg/exp/sql/sql.go
+++ b/src/pkg/exp/sql/sql.go
@@ -243,8 +243,13 @@
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 @@
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 @@
rs.closed = true
err := rs.rowsi.Close()
rs.releaseConn()
+ if rs.closeStmt != nil {
+ rs.closeStmt.Close()
+ }
return err
}