mirror of
https://github.com/golang/go
synced 2024-11-25 13:27:57 -07:00
database/sql: fix typo bug resulting in double-Prepare
Bug reported by Blake Mizerany found while writing his new Postgres driver. R=golang-dev, blake.mizerany CC=golang-dev https://golang.org/cl/5754057
This commit is contained in:
parent
97b13acb67
commit
48eacd90a8
@ -82,6 +82,7 @@ type fakeConn struct {
|
|||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
stmtsMade int
|
stmtsMade int
|
||||||
stmtsClosed int
|
stmtsClosed int
|
||||||
|
numPrepare int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *fakeConn) incrStat(v *int) {
|
func (c *fakeConn) incrStat(v *int) {
|
||||||
@ -339,6 +340,7 @@ func (c *fakeConn) prepareInsert(stmt *fakeStmt, parts []string) (driver.Stmt, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *fakeConn) Prepare(query string) (driver.Stmt, error) {
|
func (c *fakeConn) Prepare(query string) (driver.Stmt, error) {
|
||||||
|
c.numPrepare++
|
||||||
if c.db == nil {
|
if c.db == nil {
|
||||||
panic("nil c.db; conn = " + fmt.Sprintf("%#v", c))
|
panic("nil c.db; conn = " + fmt.Sprintf("%#v", c))
|
||||||
}
|
}
|
||||||
|
@ -700,7 +700,7 @@ func (s *Stmt) connStmt() (ci driver.Conn, releaseConn func(), si driver.Stmt, e
|
|||||||
for _, v := range s.css {
|
for _, v := range s.css {
|
||||||
// TODO(bradfitz): lazily clean up entries in this
|
// TODO(bradfitz): lazily clean up entries in this
|
||||||
// list with dead conns while enumerating
|
// list with dead conns while enumerating
|
||||||
if _, match = s.db.connIfFree(cs.ci); match {
|
if _, match = s.db.connIfFree(v.ci); match {
|
||||||
cs = v
|
cs = v
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -47,9 +47,19 @@ func closeDB(t *testing.T, db *DB) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// numPrepares assumes that db has exactly 1 idle conn and returns
|
||||||
|
// its count of calls to Prepare
|
||||||
|
func numPrepares(t *testing.T, db *DB) int {
|
||||||
|
if n := len(db.freeConn); n != 1 {
|
||||||
|
t.Fatalf("free conns = %d; want 1", n)
|
||||||
|
}
|
||||||
|
return db.freeConn[0].(*fakeConn).numPrepare
|
||||||
|
}
|
||||||
|
|
||||||
func TestQuery(t *testing.T) {
|
func TestQuery(t *testing.T) {
|
||||||
db := newTestDB(t, "people")
|
db := newTestDB(t, "people")
|
||||||
defer closeDB(t, db)
|
defer closeDB(t, db)
|
||||||
|
prepares0 := numPrepares(t, db)
|
||||||
rows, err := db.Query("SELECT|people|age,name|")
|
rows, err := db.Query("SELECT|people|age,name|")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Query: %v", err)
|
t.Fatalf("Query: %v", err)
|
||||||
@ -83,7 +93,10 @@ func TestQuery(t *testing.T) {
|
|||||||
// And verify that the final rows.Next() call, which hit EOF,
|
// And verify that the final rows.Next() call, which hit EOF,
|
||||||
// also closed the rows connection.
|
// also closed the rows connection.
|
||||||
if n := len(db.freeConn); n != 1 {
|
if n := len(db.freeConn); n != 1 {
|
||||||
t.Errorf("free conns after query hitting EOF = %d; want 1", n)
|
t.Fatalf("free conns after query hitting EOF = %d; want 1", n)
|
||||||
|
}
|
||||||
|
if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
|
||||||
|
t.Errorf("executed %d Prepare statements; want 1", prepares)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user