summaryrefslogtreecommitdiffstats
path: root/llgo/third_party/gofrontend/libgo/go/database
diff options
context:
space:
mode:
Diffstat (limited to 'llgo/third_party/gofrontend/libgo/go/database')
-rw-r--r--llgo/third_party/gofrontend/libgo/go/database/sql/convert_test.go37
-rw-r--r--llgo/third_party/gofrontend/libgo/go/database/sql/fakedb_test.go24
-rw-r--r--llgo/third_party/gofrontend/libgo/go/database/sql/sql.go220
-rw-r--r--llgo/third_party/gofrontend/libgo/go/database/sql/sql_test.go84
4 files changed, 244 insertions, 121 deletions
diff --git a/llgo/third_party/gofrontend/libgo/go/database/sql/convert_test.go b/llgo/third_party/gofrontend/libgo/go/database/sql/convert_test.go
index 6e248301283..98af9fb64c5 100644
--- a/llgo/third_party/gofrontend/libgo/go/database/sql/convert_test.go
+++ b/llgo/third_party/gofrontend/libgo/go/database/sql/convert_test.go
@@ -283,6 +283,26 @@ func TestValueConverters(t *testing.T) {
// Tests that assigning to RawBytes doesn't allocate (and also works).
func TestRawBytesAllocs(t *testing.T) {
+ var tests = []struct {
+ name string
+ in interface{}
+ want string
+ }{
+ {"uint64", uint64(12345678), "12345678"},
+ {"uint32", uint32(1234), "1234"},
+ {"uint16", uint16(12), "12"},
+ {"uint8", uint8(1), "1"},
+ {"uint", uint(123), "123"},
+ {"int", int(123), "123"},
+ {"int8", int8(1), "1"},
+ {"int16", int16(12), "12"},
+ {"int32", int32(1234), "1234"},
+ {"int64", int64(12345678), "12345678"},
+ {"float32", float32(1.5), "1.5"},
+ {"float64", float64(64), "64"},
+ {"bool", false, "false"},
+ }
+
buf := make(RawBytes, 10)
test := func(name string, in interface{}, want string) {
if err := convertAssign(&buf, in); err != nil {
@@ -301,20 +321,11 @@ func TestRawBytesAllocs(t *testing.T) {
t.Fatalf("%s: got %q (len %d); want %q (len %d)", name, buf, len(buf), want, len(want))
}
}
+
n := testing.AllocsPerRun(100, func() {
- test("uint64", uint64(12345678), "12345678")
- test("uint32", uint32(1234), "1234")
- test("uint16", uint16(12), "12")
- test("uint8", uint8(1), "1")
- test("uint", uint(123), "123")
- test("int", int(123), "123")
- test("int8", int8(1), "1")
- test("int16", int16(12), "12")
- test("int32", int32(1234), "1234")
- test("int64", int64(12345678), "12345678")
- test("float32", float32(1.5), "1.5")
- test("float64", float64(64), "64")
- test("bool", false, "false")
+ for _, tt := range tests {
+ test(tt.name, tt.in, tt.want)
+ }
})
// The numbers below are only valid for 64-bit interface word sizes,
diff --git a/llgo/third_party/gofrontend/libgo/go/database/sql/fakedb_test.go b/llgo/third_party/gofrontend/libgo/go/database/sql/fakedb_test.go
index c7db0dd77b3..a993fd46ede 100644
--- a/llgo/third_party/gofrontend/libgo/go/database/sql/fakedb_test.go
+++ b/llgo/third_party/gofrontend/libgo/go/database/sql/fakedb_test.go
@@ -10,6 +10,7 @@ import (
"fmt"
"io"
"log"
+ "sort"
"strconv"
"strings"
"sync"
@@ -126,6 +127,29 @@ func init() {
Register("test", fdriver)
}
+func contains(list []string, y string) bool {
+ for _, x := range list {
+ if x == y {
+ return true
+ }
+ }
+ return false
+}
+
+type Dummy struct {
+ driver.Driver
+}
+
+func TestDrivers(t *testing.T) {
+ unregisterAllDrivers()
+ Register("test", fdriver)
+ Register("invalid", Dummy{})
+ all := Drivers()
+ if len(all) < 2 || !sort.StringsAreSorted(all) || !contains(all, "test") || !contains(all, "invalid") {
+ t.Fatalf("Drivers = %v, want sorted list with at least [invalid, test]", all)
+ }
+}
+
// Supports dsn forms:
// <dbname>
// <dbname>;<opts> (only currently supported option is `badConn`,
diff --git a/llgo/third_party/gofrontend/libgo/go/database/sql/sql.go b/llgo/third_party/gofrontend/libgo/go/database/sql/sql.go
index 765b80c60a2..6e6f246aeec 100644
--- a/llgo/third_party/gofrontend/libgo/go/database/sql/sql.go
+++ b/llgo/third_party/gofrontend/libgo/go/database/sql/sql.go
@@ -13,12 +13,12 @@
package sql
import (
- "container/list"
"database/sql/driver"
"errors"
"fmt"
"io"
"runtime"
+ "sort"
"sync"
)
@@ -37,6 +37,21 @@ func Register(name string, driver driver.Driver) {
drivers[name] = driver
}
+func unregisterAllDrivers() {
+ // For tests.
+ drivers = make(map[string]driver.Driver)
+}
+
+// Drivers returns a sorted list of the names of the registered drivers.
+func Drivers() []string {
+ var list []string
+ for name := range drivers {
+ list = append(list, name)
+ }
+ sort.Strings(list)
+ return list
+}
+
// RawBytes is a byte slice that holds a reference to memory owned by
// the database itself. After a Scan into a RawBytes, the slice is only
// valid until the next call to Next, Scan, or Close.
@@ -198,8 +213,8 @@ type DB struct {
dsn string
mu sync.Mutex // protects following fields
- freeConn *list.List // of *driverConn
- connRequests *list.List // of connRequest
+ freeConn []*driverConn
+ connRequests []chan connRequest
numOpen int
pendingOpens int
// Used to signal the need for new connections
@@ -232,9 +247,6 @@ type driverConn struct {
inUse bool
onPut []func() // code (with db.mu held) run when conn is next returned
dbmuClosed bool // same as closed, but guarded by db.mu, for connIfFree
- // This is the Element returned by db.freeConn.PushFront(conn).
- // It's used by connIfFree to remove the conn from the freeConn list.
- listElem *list.Element
}
func (dc *driverConn) releaseConn(err error) {
@@ -437,8 +449,6 @@ func Open(driverName, dataSourceName string) (*DB, error) {
openerCh: make(chan struct{}, connectionRequestQueueSize),
lastPut: make(map[*driverConn]string),
}
- db.freeConn = list.New()
- db.connRequests = list.New()
go db.connectionOpener()
return db, nil
}
@@ -469,17 +479,13 @@ func (db *DB) Close() error {
}
close(db.openerCh)
var err error
- fns := make([]func() error, 0, db.freeConn.Len())
- for db.freeConn.Front() != nil {
- dc := db.freeConn.Front().Value.(*driverConn)
- dc.listElem = nil
+ fns := make([]func() error, 0, len(db.freeConn))
+ for _, dc := range db.freeConn {
fns = append(fns, dc.closeDBLocked())
- db.freeConn.Remove(db.freeConn.Front())
}
+ db.freeConn = nil
db.closed = true
- for db.connRequests.Front() != nil {
- req := db.connRequests.Front().Value.(connRequest)
- db.connRequests.Remove(db.connRequests.Front())
+ for _, req := range db.connRequests {
close(req)
}
db.mu.Unlock()
@@ -527,11 +533,11 @@ func (db *DB) SetMaxIdleConns(n int) {
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())
- closing = append(closing, dc)
+ idleCount := len(db.freeConn)
+ maxIdle := db.maxIdleConnsLocked()
+ if idleCount > maxIdle {
+ closing = db.freeConn[maxIdle:]
+ db.freeConn = db.freeConn[:maxIdle]
}
db.mu.Unlock()
for _, c := range closing {
@@ -564,7 +570,7 @@ func (db *DB) SetMaxOpenConns(n int) {
// If there are connRequests and the connection limit hasn't been reached,
// then tell the connectionOpener to open new connections.
func (db *DB) maybeOpenNewConnections() {
- numRequests := db.connRequests.Len() - db.pendingOpens
+ numRequests := len(db.connRequests) - db.pendingOpens
if db.maxOpen > 0 {
numCanOpen := db.maxOpen - (db.numOpen + db.pendingOpens)
if numRequests > numCanOpen {
@@ -580,7 +586,7 @@ func (db *DB) maybeOpenNewConnections() {
// Runs in a separate goroutine, opens new connections when requested.
func (db *DB) connectionOpener() {
- for _ = range db.openerCh {
+ for range db.openerCh {
db.openNewConnection()
}
}
@@ -616,7 +622,10 @@ func (db *DB) openNewConnection() {
// connRequest represents one request for a new connection
// When there are no idle connections available, DB.conn will create
// a new connRequest and put it on the db.connRequests list.
-type connRequest chan<- interface{} // takes either a *driverConn or an error
+type connRequest struct {
+ conn *driverConn
+ err error
+}
var errDBClosed = errors.New("sql: database is closed")
@@ -630,32 +639,21 @@ func (db *DB) conn() (*driverConn, error) {
// If db.maxOpen > 0 and the number of open connections is over the limit
// and there are no free connection, make a request and wait.
- if db.maxOpen > 0 && db.numOpen >= db.maxOpen && db.freeConn.Len() == 0 {
+ if db.maxOpen > 0 && db.numOpen >= db.maxOpen && len(db.freeConn) == 0 {
// Make the connRequest channel. It's buffered so that the
// connectionOpener doesn't block while waiting for the req to be read.
- ch := make(chan interface{}, 1)
- req := connRequest(ch)
- db.connRequests.PushBack(req)
+ req := make(chan connRequest, 1)
+ db.connRequests = append(db.connRequests, req)
db.maybeOpenNewConnections()
db.mu.Unlock()
- ret, ok := <-ch
- if !ok {
- return nil, errDBClosed
- }
- switch ret.(type) {
- case *driverConn:
- return ret.(*driverConn), nil
- case error:
- return nil, ret.(error)
- default:
- panic("sql: Unexpected type passed through connRequest.ch")
- }
+ ret := <-req
+ return ret.conn, ret.err
}
- if f := db.freeConn.Front(); f != nil {
- conn := f.Value.(*driverConn)
- conn.listElem = nil
- db.freeConn.Remove(f)
+ if c := len(db.freeConn); c > 0 {
+ conn := db.freeConn[0]
+ copy(db.freeConn, db.freeConn[1:])
+ db.freeConn = db.freeConn[:c-1]
conn.inUse = true
db.mu.Unlock()
return conn, nil
@@ -702,9 +700,15 @@ func (db *DB) connIfFree(wanted *driverConn) (*driverConn, error) {
if wanted.inUse {
return nil, errConnBusy
}
- if wanted.listElem != nil {
- db.freeConn.Remove(wanted.listElem)
- wanted.listElem = nil
+ idx := -1
+ for ii, v := range db.freeConn {
+ if v == wanted {
+ idx = ii
+ break
+ }
+ }
+ if idx >= 0 {
+ db.freeConn = append(db.freeConn[:idx], db.freeConn[idx+1:]...)
wanted.inUse = true
return wanted, nil
}
@@ -793,18 +797,23 @@ func (db *DB) putConn(dc *driverConn, err error) {
// If a connRequest was fulfilled or the *driverConn was placed in the
// freeConn list, then true is returned, otherwise false is returned.
func (db *DB) putConnDBLocked(dc *driverConn, err error) bool {
- if db.connRequests.Len() > 0 {
- req := db.connRequests.Front().Value.(connRequest)
- db.connRequests.Remove(db.connRequests.Front())
- if err != nil {
- req <- err
- } else {
+ if c := len(db.connRequests); c > 0 {
+ req := db.connRequests[0]
+ // This copy is O(n) but in practice faster than a linked list.
+ // TODO: consider compacting it down less often and
+ // moving the base instead?
+ copy(db.connRequests, db.connRequests[1:])
+ db.connRequests = db.connRequests[:c-1]
+ if err == nil {
dc.inUse = true
- req <- dc
+ }
+ req <- connRequest{
+ conn: dc,
+ err: err,
}
return true
- } else if err == nil && !db.closed && db.maxIdleConnsLocked() > db.freeConn.Len() {
- dc.listElem = db.freeConn.PushFront(dc)
+ } else if err == nil && !db.closed && db.maxIdleConnsLocked() > len(db.freeConn) {
+ db.freeConn = append(db.freeConn, dc)
return true
}
return false
@@ -1050,6 +1059,13 @@ type Tx struct {
// or Rollback. once done, all operations fail with
// ErrTxDone.
done bool
+
+ // All Stmts prepared for this transaction. These will be closed after the
+ // transaction has been committed or rolled back.
+ stmts struct {
+ sync.Mutex
+ v []*Stmt
+ }
}
var ErrTxDone = errors.New("sql: Transaction has already been committed or rolled back")
@@ -1071,6 +1087,15 @@ func (tx *Tx) grabConn() (*driverConn, error) {
return tx.dc, nil
}
+// Closes all Stmts prepared for this transaction.
+func (tx *Tx) closePrepared() {
+ tx.stmts.Lock()
+ for _, stmt := range tx.stmts.v {
+ stmt.Close()
+ }
+ tx.stmts.Unlock()
+}
+
// Commit commits the transaction.
func (tx *Tx) Commit() error {
if tx.done {
@@ -1078,8 +1103,12 @@ func (tx *Tx) Commit() error {
}
defer tx.close()
tx.dc.Lock()
- defer tx.dc.Unlock()
- return tx.txi.Commit()
+ err := tx.txi.Commit()
+ tx.dc.Unlock()
+ if err != driver.ErrBadConn {
+ tx.closePrepared()
+ }
+ return err
}
// Rollback aborts the transaction.
@@ -1089,8 +1118,12 @@ func (tx *Tx) Rollback() error {
}
defer tx.close()
tx.dc.Lock()
- defer tx.dc.Unlock()
- return tx.txi.Rollback()
+ err := tx.txi.Rollback()
+ tx.dc.Unlock()
+ if err != driver.ErrBadConn {
+ tx.closePrepared()
+ }
+ return err
}
// Prepare creates a prepared statement for use within a transaction.
@@ -1134,6 +1167,9 @@ func (tx *Tx) Prepare(query string) (*Stmt, error) {
},
query: query,
}
+ tx.stmts.Lock()
+ tx.stmts.v = append(tx.stmts.v, stmt)
+ tx.stmts.Unlock()
return stmt, nil
}
@@ -1162,7 +1198,7 @@ func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
dc.Lock()
si, err := dc.ci.Prepare(stmt.query)
dc.Unlock()
- return &Stmt{
+ txs := &Stmt{
db: tx.db,
tx: tx,
txsi: &driverStmt{
@@ -1172,6 +1208,10 @@ func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
query: stmt.query,
stickyErr: err,
}
+ tx.stmts.Lock()
+ tx.stmts.v = append(tx.stmts.v, txs)
+ tx.stmts.Unlock()
+ return txs
}
// Exec executes a query that doesn't return rows.
@@ -1333,15 +1373,12 @@ func (s *Stmt) connStmt() (ci *driverConn, releaseConn func(error), si driver.St
return ci, releaseConn, s.txsi.si, nil
}
- var cs connStmt
- match := false
for i := 0; i < len(s.css); i++ {
v := s.css[i]
_, err := s.db.connIfFree(v.dc)
if err == nil {
- match = true
- cs = v
- break
+ s.mu.Unlock()
+ return v.dc, v.dc.releaseConn, v.si, nil
}
if err == errConnClosed {
// Lazily remove dead conn from our freelist.
@@ -1353,28 +1390,41 @@ func (s *Stmt) connStmt() (ci *driverConn, releaseConn func(error), si driver.St
}
s.mu.Unlock()
- // Make a new conn if all are busy.
- // TODO(bradfitz): or wait for one? make configurable later?
- if !match {
- dc, err := s.db.conn()
- if err != nil {
- return nil, nil, nil, err
- }
- dc.Lock()
- si, err := dc.prepareLocked(s.query)
- dc.Unlock()
- if err != nil {
- s.db.putConn(dc, err)
- return nil, nil, nil, err
+ // If all connections are busy, either wait for one to become available (if
+ // we've already hit the maximum number of open connections) or create a
+ // new one.
+ //
+ // TODO(bradfitz): or always wait for one? make configurable later?
+ dc, err := s.db.conn()
+ if err != nil {
+ return nil, nil, nil, err
+ }
+
+ // Do another pass over the list to see whether this statement has
+ // already been prepared on the connection assigned to us.
+ s.mu.Lock()
+ for _, v := range s.css {
+ if v.dc == dc {
+ s.mu.Unlock()
+ return dc, dc.releaseConn, v.si, nil
}
- s.mu.Lock()
- cs = connStmt{dc, si}
- s.css = append(s.css, cs)
- s.mu.Unlock()
}
+ s.mu.Unlock()
+
+ // No luck; we need to prepare the statement on this connection
+ dc.Lock()
+ si, err = dc.prepareLocked(s.query)
+ dc.Unlock()
+ if err != nil {
+ s.db.putConn(dc, err)
+ return nil, nil, nil, err
+ }
+ s.mu.Lock()
+ cs := connStmt{dc, si}
+ s.css = append(s.css, cs)
+ s.mu.Unlock()
- conn := cs.dc
- return conn, conn.releaseConn, cs.si, nil
+ return dc, dc.releaseConn, si, nil
}
// Query executes a prepared query statement with the given arguments
diff --git a/llgo/third_party/gofrontend/libgo/go/database/sql/sql_test.go b/llgo/third_party/gofrontend/libgo/go/database/sql/sql_test.go
index 7971f149174..34efdf254c6 100644
--- a/llgo/third_party/gofrontend/libgo/go/database/sql/sql_test.go
+++ b/llgo/third_party/gofrontend/libgo/go/database/sql/sql_test.go
@@ -24,7 +24,14 @@ func init() {
}
freedFrom := make(map[dbConn]string)
putConnHook = func(db *DB, c *driverConn) {
- if c.listElem != nil {
+ idx := -1
+ for i, v := range db.freeConn {
+ if v == c {
+ idx = i
+ break
+ }
+ }
+ if idx >= 0 {
// print before panic, as panic may get lost due to conflicting panic
// (all goroutines asleep) elsewhere, since we might not unlock
// the mutex in freeConn here.
@@ -79,15 +86,14 @@ func closeDB(t testing.TB, db *DB) {
t.Errorf("Error closing fakeConn: %v", err)
}
})
- for node, i := db.freeConn.Front(), 0; node != nil; node, i = node.Next(), i+1 {
- dc := node.Value.(*driverConn)
+ for i, dc := range db.freeConn {
if n := len(dc.openStmt); n > 0 {
// Just a sanity check. This is legal in
// general, but if we make the tests clean up
// their statements first, then we can safely
// verify this is always zero here, and any
// other value is a leak.
- t.Errorf("while closing db, freeConn %d/%d had %d open stmts; want 0", i, db.freeConn.Len(), n)
+ t.Errorf("while closing db, freeConn %d/%d had %d open stmts; want 0", i, len(db.freeConn), n)
}
}
err := db.Close()
@@ -105,10 +111,10 @@ func closeDB(t testing.TB, 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 := db.freeConn.Len(); n != 1 {
+ if n := len(db.freeConn); n != 1 {
t.Fatalf("free conns = %d; want 1", n)
}
- return (db.freeConn.Front().Value.(*driverConn)).ci.(*fakeConn).numPrepare
+ return db.freeConn[0].ci.(*fakeConn).numPrepare
}
func (db *DB) numDeps() int {
@@ -133,7 +139,7 @@ func (db *DB) numDepsPollUntil(want int, d time.Duration) int {
func (db *DB) numFreeConns() int {
db.mu.Lock()
defer db.mu.Unlock()
- return db.freeConn.Len()
+ return len(db.freeConn)
}
func (db *DB) dumpDeps(t *testing.T) {
@@ -435,6 +441,33 @@ func TestExec(t *testing.T) {
}
}
+func TestTxPrepare(t *testing.T) {
+ db := newTestDB(t, "")
+ defer closeDB(t, db)
+ exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
+ tx, err := db.Begin()
+ if err != nil {
+ t.Fatalf("Begin = %v", err)
+ }
+ stmt, err := tx.Prepare("INSERT|t1|name=?,age=?")
+ if err != nil {
+ t.Fatalf("Stmt, err = %v, %v", stmt, err)
+ }
+ defer stmt.Close()
+ _, err = stmt.Exec("Bobby", 7)
+ if err != nil {
+ t.Fatalf("Exec = %v", err)
+ }
+ err = tx.Commit()
+ if err != nil {
+ t.Fatalf("Commit = %v", err)
+ }
+ // Commit() should have closed the statement
+ if !stmt.closed {
+ t.Fatal("Stmt not closed after Commit")
+ }
+}
+
func TestTxStmt(t *testing.T) {
db := newTestDB(t, "")
defer closeDB(t, db)
@@ -458,6 +491,10 @@ func TestTxStmt(t *testing.T) {
if err != nil {
t.Fatalf("Commit = %v", err)
}
+ // Commit() should have closed the statement
+ if !txs.closed {
+ t.Fatal("Stmt not closed after Commit")
+ }
}
// Issue: http://golang.org/issue/2784
@@ -650,10 +687,10 @@ func TestQueryRowClosingStmt(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- if db.freeConn.Len() != 1 {
+ if len(db.freeConn) != 1 {
t.Fatalf("expected 1 free conn")
}
- fakeConn := (db.freeConn.Front().Value.(*driverConn)).ci.(*fakeConn)
+ fakeConn := db.freeConn[0].ci.(*fakeConn)
if made, closed := fakeConn.stmtsMade, fakeConn.stmtsClosed; made != closed {
t.Errorf("statement close mismatch: made %d, closed %d", made, closed)
}
@@ -878,13 +915,13 @@ func TestMaxIdleConns(t *testing.T) {
t.Fatal(err)
}
tx.Commit()
- if got := db.freeConn.Len(); got != 1 {
+ if got := len(db.freeConn); got != 1 {
t.Errorf("freeConns = %d; want 1", got)
}
db.SetMaxIdleConns(0)
- if got := db.freeConn.Len(); got != 0 {
+ if got := len(db.freeConn); got != 0 {
t.Errorf("freeConns after set to zero = %d; want 0", got)
}
@@ -893,7 +930,7 @@ func TestMaxIdleConns(t *testing.T) {
t.Fatal(err)
}
tx.Commit()
- if got := db.freeConn.Len(); got != 0 {
+ if got := len(db.freeConn); got != 0 {
t.Errorf("freeConns = %d; want 0", got)
}
}
@@ -1180,10 +1217,10 @@ func TestCloseConnBeforeStmts(t *testing.T) {
t.Fatal(err)
}
- if db.freeConn.Len() != 1 {
- t.Fatalf("expected 1 freeConn; got %d", db.freeConn.Len())
+ if len(db.freeConn) != 1 {
+ t.Fatalf("expected 1 freeConn; got %d", len(db.freeConn))
}
- dc := db.freeConn.Front().Value.(*driverConn)
+ dc := db.freeConn[0]
if dc.closed {
t.Errorf("conn shouldn't be closed")
}
@@ -1342,6 +1379,11 @@ func TestErrBadConnReconnect(t *testing.T) {
return nil
})
+ // Provide a way to force a re-prepare of a statement on next execution
+ forcePrepare := func(stmt *Stmt) {
+ stmt.css = nil
+ }
+
// stmt.Exec
stmt1, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?")
if err != nil {
@@ -1349,9 +1391,7 @@ func TestErrBadConnReconnect(t *testing.T) {
}
defer stmt1.Close()
// make sure we must prepare the stmt first
- for _, cs := range stmt1.css {
- cs.dc.inUse = true
- }
+ forcePrepare(stmt1)
stmtExec := func() error {
_, err := stmt1.Exec("Gopher", 3, false)
@@ -1367,9 +1407,7 @@ func TestErrBadConnReconnect(t *testing.T) {
}
defer stmt2.Close()
// make sure we must prepare the stmt first
- for _, cs := range stmt2.css {
- cs.dc.inUse = true
- }
+ forcePrepare(stmt2)
stmtQuery := func() error {
rows, err := stmt2.Query()
@@ -1708,7 +1746,7 @@ func doConcurrentTest(t testing.TB, ct concurrentTest) {
for i := 0; i < maxProcs*2; i++ {
go func() {
- for _ = range reqs {
+ for range reqs {
err := ct.test(t)
if err != nil {
wg.Done()
@@ -1750,7 +1788,7 @@ func manyConcurrentQueries(t testing.TB) {
for i := 0; i < maxProcs*2; i++ {
go func() {
- for _ = range reqs {
+ for range reqs {
rows, err := stmt.Query()
if err != nil {
t.Errorf("error on query: %v", err)
OpenPOWER on IntegriCloud