database/sql: fix double decrement of numOpen count; test for connection leaks

Add a check at the end of every test to make sure
there are no leaked connections after running a test.

Avoid incorrectly decrementing the number of open connections
when the driver connection ends up it a bad state (numOpen was
decremented twice).

Prevent leaking a Rows struct (which ends up leaking a
connection) in Row.Scan() when a *RawBytes destination is
improperly used.

Close the Rows struct in TestRowsColumns.

Update #6593

R=golang-dev, bradfitz, dave
CC=golang-dev
https://golang.org/cl/14642044
diff --git a/src/pkg/database/sql/sql.go b/src/pkg/database/sql/sql.go
index ae313ca..fe46ff3 100644
--- a/src/pkg/database/sql/sql.go
+++ b/src/pkg/database/sql/sql.go
@@ -504,7 +504,6 @@
 // If n <= 0, no idle connections are retained.
 func (db *DB) SetMaxIdleConns(n int) {
 	db.mu.Lock()
-	defer db.mu.Unlock()
 	if n > 0 {
 		db.maxIdle = n
 	} else {
@@ -515,11 +514,16 @@
 	if db.maxOpen > 0 && db.maxIdleConnsLocked() > db.maxOpen {
 		db.maxIdle = db.maxOpen
 	}
+	var closing []*driverConn
 	for db.freeConn.Len() > db.maxIdleConnsLocked() {
 		dc := db.freeConn.Back().Value.(*driverConn)
 		dc.listElem = nil
 		db.freeConn.Remove(db.freeConn.Back())
-		go dc.Close()
+		closing = append(closing, dc)
+	}
+	db.mu.Unlock()
+	for _, c := range closing {
+		c.Close()
 	}
 }
 
@@ -743,8 +747,8 @@
 	if err == driver.ErrBadConn {
 		// Don't reuse bad connections.
 		// Since the conn is considered bad and is being discarded, treat it
-		// as closed. Decrement the open count.
-		db.numOpen--
+		// as closed. Don't decrement the open count here, finalClose will
+		// take care of that.
 		db.maybeOpenNewConnections()
 		db.mu.Unlock()
 		dc.Close()
@@ -1607,13 +1611,13 @@
 	// from Next will not be modified again." (for instance, if
 	// they were obtained from the network anyway) But for now we
 	// don't care.
+	defer r.rows.Close()
 	for _, dp := range dest {
 		if _, ok := dp.(*RawBytes); ok {
 			return errors.New("sql: RawBytes isn't allowed on Row.Scan")
 		}
 	}
 
-	defer r.rows.Close()
 	if !r.rows.Next() {
 		return ErrNoRows
 	}