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
 }