[committed] Avoid right shifting signed value on ext-dce.cc
[official-gcc.git] / libgo / go / database / sql / sql_test.go
bloba921dd5a849b13d359e59f8af355563beb785af5
1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package sql
7 import (
8 "context"
9 "database/sql/driver"
10 "errors"
11 "fmt"
12 "math/rand"
13 "reflect"
14 "runtime"
15 "strings"
16 "sync"
17 "sync/atomic"
18 "testing"
19 "time"
22 func init() {
23 type dbConn struct {
24 db *DB
25 c *driverConn
27 freedFrom := make(map[dbConn]string)
28 var mu sync.Mutex
29 getFreedFrom := func(c dbConn) string {
30 mu.Lock()
31 defer mu.Unlock()
32 return freedFrom[c]
34 setFreedFrom := func(c dbConn, s string) {
35 mu.Lock()
36 defer mu.Unlock()
37 freedFrom[c] = s
39 putConnHook = func(db *DB, c *driverConn) {
40 idx := -1
41 for i, v := range db.freeConn {
42 if v == c {
43 idx = i
44 break
47 if idx >= 0 {
48 // print before panic, as panic may get lost due to conflicting panic
49 // (all goroutines asleep) elsewhere, since we might not unlock
50 // the mutex in freeConn here.
51 println("double free of conn. conflicts are:\nA) " + getFreedFrom(dbConn{db, c}) + "\n\nand\nB) " + stack())
52 panic("double free of conn.")
54 setFreedFrom(dbConn{db, c}, stack())
58 // pollDuration is an arbitrary interval to wait between checks when polling for
59 // a condition to occur.
60 const pollDuration = 5 * time.Millisecond
62 const fakeDBName = "foo"
64 var chrisBirthday = time.Unix(123456789, 0)
66 func newTestDB(t testing.TB, name string) *DB {
67 return newTestDBConnector(t, &fakeConnector{name: fakeDBName}, name)
70 func newTestDBConnector(t testing.TB, fc *fakeConnector, name string) *DB {
71 fc.name = fakeDBName
72 db := OpenDB(fc)
73 if _, err := db.Exec("WIPE"); err != nil {
74 t.Fatalf("exec wipe: %v", err)
76 if name == "people" {
77 exec(t, db, "CREATE|people|name=string,age=int32,photo=blob,dead=bool,bdate=datetime")
78 exec(t, db, "INSERT|people|name=Alice,age=?,photo=APHOTO", 1)
79 exec(t, db, "INSERT|people|name=Bob,age=?,photo=BPHOTO", 2)
80 exec(t, db, "INSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
82 if name == "magicquery" {
83 // Magic table name and column, known by fakedb_test.go.
84 exec(t, db, "CREATE|magicquery|op=string,millis=int32")
85 exec(t, db, "INSERT|magicquery|op=sleep,millis=10")
87 if name == "tx_status" {
88 // Magic table name and column, known by fakedb_test.go.
89 exec(t, db, "CREATE|tx_status|tx_status=string")
90 exec(t, db, "INSERT|tx_status|tx_status=invalid")
92 return db
95 func TestOpenDB(t *testing.T) {
96 db := OpenDB(dsnConnector{dsn: fakeDBName, driver: fdriver})
97 if db.Driver() != fdriver {
98 t.Fatalf("OpenDB should return the driver of the Connector")
102 func TestDriverPanic(t *testing.T) {
103 // Test that if driver panics, database/sql does not deadlock.
104 db, err := Open("test", fakeDBName)
105 if err != nil {
106 t.Fatalf("Open: %v", err)
108 expectPanic := func(name string, f func()) {
109 defer func() {
110 err := recover()
111 if err == nil {
112 t.Fatalf("%s did not panic", name)
118 expectPanic("Exec Exec", func() { db.Exec("PANIC|Exec|WIPE") })
119 exec(t, db, "WIPE") // check not deadlocked
120 expectPanic("Exec NumInput", func() { db.Exec("PANIC|NumInput|WIPE") })
121 exec(t, db, "WIPE") // check not deadlocked
122 expectPanic("Exec Close", func() { db.Exec("PANIC|Close|WIPE") })
123 exec(t, db, "WIPE") // check not deadlocked
124 exec(t, db, "PANIC|Query|WIPE") // should run successfully: Exec does not call Query
125 exec(t, db, "WIPE") // check not deadlocked
127 exec(t, db, "CREATE|people|name=string,age=int32,photo=blob,dead=bool,bdate=datetime")
129 expectPanic("Query Query", func() { db.Query("PANIC|Query|SELECT|people|age,name|") })
130 expectPanic("Query NumInput", func() { db.Query("PANIC|NumInput|SELECT|people|age,name|") })
131 expectPanic("Query Close", func() {
132 rows, err := db.Query("PANIC|Close|SELECT|people|age,name|")
133 if err != nil {
134 t.Fatal(err)
136 rows.Close()
138 db.Query("PANIC|Exec|SELECT|people|age,name|") // should run successfully: Query does not call Exec
139 exec(t, db, "WIPE") // check not deadlocked
142 func exec(t testing.TB, db *DB, query string, args ...any) {
143 t.Helper()
144 _, err := db.Exec(query, args...)
145 if err != nil {
146 t.Fatalf("Exec of %q: %v", query, err)
150 func closeDB(t testing.TB, db *DB) {
151 if e := recover(); e != nil {
152 fmt.Printf("Panic: %v\n", e)
153 panic(e)
155 defer setHookpostCloseConn(nil)
156 setHookpostCloseConn(func(_ *fakeConn, err error) {
157 if err != nil {
158 t.Errorf("Error closing fakeConn: %v", err)
161 db.mu.Lock()
162 for i, dc := range db.freeConn {
163 if n := len(dc.openStmt); n > 0 {
164 // Just a sanity check. This is legal in
165 // general, but if we make the tests clean up
166 // their statements first, then we can safely
167 // verify this is always zero here, and any
168 // other value is a leak.
169 t.Errorf("while closing db, freeConn %d/%d had %d open stmts; want 0", i, len(db.freeConn), n)
172 db.mu.Unlock()
174 err := db.Close()
175 if err != nil {
176 t.Fatalf("error closing DB: %v", err)
179 var numOpen int
180 if !waitCondition(t, func() bool {
181 numOpen = db.numOpenConns()
182 return numOpen == 0
183 }) {
184 t.Fatalf("%d connections still open after closing DB", numOpen)
188 // numPrepares assumes that db has exactly 1 idle conn and returns
189 // its count of calls to Prepare
190 func numPrepares(t *testing.T, db *DB) int {
191 if n := len(db.freeConn); n != 1 {
192 t.Fatalf("free conns = %d; want 1", n)
194 return db.freeConn[0].ci.(*fakeConn).numPrepare
197 func (db *DB) numDeps() int {
198 db.mu.Lock()
199 defer db.mu.Unlock()
200 return len(db.dep)
203 // Dependencies are closed via a goroutine, so this polls waiting for
204 // numDeps to fall to want, waiting up to nearly the test's deadline.
205 func (db *DB) numDepsPoll(t *testing.T, want int) int {
206 var n int
207 waitCondition(t, func() bool {
208 n = db.numDeps()
209 return n <= want
211 return n
214 func (db *DB) numFreeConns() int {
215 db.mu.Lock()
216 defer db.mu.Unlock()
217 return len(db.freeConn)
220 func (db *DB) numOpenConns() int {
221 db.mu.Lock()
222 defer db.mu.Unlock()
223 return db.numOpen
226 // clearAllConns closes all connections in db.
227 func (db *DB) clearAllConns(t *testing.T) {
228 db.SetMaxIdleConns(0)
230 if g, w := db.numFreeConns(), 0; g != w {
231 t.Errorf("free conns = %d; want %d", g, w)
234 if n := db.numDepsPoll(t, 0); n > 0 {
235 t.Errorf("number of dependencies = %d; expected 0", n)
236 db.dumpDeps(t)
240 func (db *DB) dumpDeps(t *testing.T) {
241 for fc := range db.dep {
242 db.dumpDep(t, 0, fc, map[finalCloser]bool{})
246 func (db *DB) dumpDep(t *testing.T, depth int, dep finalCloser, seen map[finalCloser]bool) {
247 seen[dep] = true
248 indent := strings.Repeat(" ", depth)
249 ds := db.dep[dep]
250 for k := range ds {
251 t.Logf("%s%T (%p) waiting for -> %T (%p)", indent, dep, dep, k, k)
252 if fc, ok := k.(finalCloser); ok {
253 if !seen[fc] {
254 db.dumpDep(t, depth+1, fc, seen)
260 func TestQuery(t *testing.T) {
261 db := newTestDB(t, "people")
262 defer closeDB(t, db)
263 prepares0 := numPrepares(t, db)
264 rows, err := db.Query("SELECT|people|age,name|")
265 if err != nil {
266 t.Fatalf("Query: %v", err)
268 type row struct {
269 age int
270 name string
272 got := []row{}
273 for rows.Next() {
274 var r row
275 err = rows.Scan(&r.age, &r.name)
276 if err != nil {
277 t.Fatalf("Scan: %v", err)
279 got = append(got, r)
281 err = rows.Err()
282 if err != nil {
283 t.Fatalf("Err: %v", err)
285 want := []row{
286 {age: 1, name: "Alice"},
287 {age: 2, name: "Bob"},
288 {age: 3, name: "Chris"},
290 if !reflect.DeepEqual(got, want) {
291 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
294 // And verify that the final rows.Next() call, which hit EOF,
295 // also closed the rows connection.
296 if n := db.numFreeConns(); n != 1 {
297 t.Fatalf("free conns after query hitting EOF = %d; want 1", n)
299 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
300 t.Errorf("executed %d Prepare statements; want 1", prepares)
304 // TestQueryContext tests canceling the context while scanning the rows.
305 func TestQueryContext(t *testing.T) {
306 db := newTestDB(t, "people")
307 defer closeDB(t, db)
308 prepares0 := numPrepares(t, db)
310 ctx, cancel := context.WithCancel(context.Background())
311 defer cancel()
313 rows, err := db.QueryContext(ctx, "SELECT|people|age,name|")
314 if err != nil {
315 t.Fatalf("Query: %v", err)
317 type row struct {
318 age int
319 name string
321 got := []row{}
322 index := 0
323 for rows.Next() {
324 if index == 2 {
325 cancel()
326 waitForRowsClose(t, rows)
328 var r row
329 err = rows.Scan(&r.age, &r.name)
330 if err != nil {
331 if index == 2 {
332 break
334 t.Fatalf("Scan: %v", err)
336 if index == 2 && err != context.Canceled {
337 t.Fatalf("Scan: %v; want context.Canceled", err)
339 got = append(got, r)
340 index++
342 select {
343 case <-ctx.Done():
344 if err := ctx.Err(); err != context.Canceled {
345 t.Fatalf("context err = %v; want context.Canceled", err)
347 default:
348 t.Fatalf("context err = nil; want context.Canceled")
350 want := []row{
351 {age: 1, name: "Alice"},
352 {age: 2, name: "Bob"},
354 if !reflect.DeepEqual(got, want) {
355 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
358 // And verify that the final rows.Next() call, which hit EOF,
359 // also closed the rows connection.
360 waitForRowsClose(t, rows)
361 waitForFree(t, db, 1)
362 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
363 t.Errorf("executed %d Prepare statements; want 1", prepares)
367 func waitCondition(t testing.TB, fn func() bool) bool {
368 timeout := 5 * time.Second
370 type deadliner interface {
371 Deadline() (time.Time, bool)
373 if td, ok := t.(deadliner); ok {
374 if deadline, ok := td.Deadline(); ok {
375 timeout = time.Until(deadline)
376 timeout = timeout * 19 / 20 // Give 5% headroom for cleanup and error-reporting.
380 deadline := time.Now().Add(timeout)
381 for {
382 if fn() {
383 return true
385 if time.Until(deadline) < pollDuration {
386 return false
388 time.Sleep(pollDuration)
392 // waitForFree checks db.numFreeConns until either it equals want or
393 // the maxWait time elapses.
394 func waitForFree(t *testing.T, db *DB, want int) {
395 var numFree int
396 if !waitCondition(t, func() bool {
397 numFree = db.numFreeConns()
398 return numFree == want
399 }) {
400 t.Fatalf("free conns after hitting EOF = %d; want %d", numFree, want)
404 func waitForRowsClose(t *testing.T, rows *Rows) {
405 if !waitCondition(t, func() bool {
406 rows.closemu.RLock()
407 defer rows.closemu.RUnlock()
408 return rows.closed
409 }) {
410 t.Fatal("failed to close rows")
414 // TestQueryContextWait ensures that rows and all internal statements are closed when
415 // a query context is closed during execution.
416 func TestQueryContextWait(t *testing.T) {
417 db := newTestDB(t, "people")
418 defer closeDB(t, db)
419 prepares0 := numPrepares(t, db)
421 ctx, cancel := context.WithCancel(context.Background())
422 defer cancel()
424 // This will trigger the *fakeConn.Prepare method which will take time
425 // performing the query. The ctxDriverPrepare func will check the context
426 // after this and close the rows and return an error.
427 c, err := db.Conn(ctx)
428 if err != nil {
429 t.Fatal(err)
432 c.dc.ci.(*fakeConn).waiter = func(c context.Context) {
433 cancel()
434 <-ctx.Done()
436 _, err = c.QueryContext(ctx, "SELECT|people|age,name|")
437 c.Close()
438 if err != context.Canceled {
439 t.Fatalf("expected QueryContext to error with context deadline exceeded but returned %v", err)
442 // Verify closed rows connection after error condition.
443 waitForFree(t, db, 1)
444 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
445 t.Fatalf("executed %d Prepare statements; want 1", prepares)
449 // TestTxContextWait tests the transaction behavior when the tx context is canceled
450 // during execution of the query.
451 func TestTxContextWait(t *testing.T) {
452 db := newTestDB(t, "people")
453 defer closeDB(t, db)
455 ctx, cancel := context.WithCancel(context.Background())
457 tx, err := db.BeginTx(ctx, nil)
458 if err != nil {
459 t.Fatal(err)
461 tx.keepConnOnRollback = false
463 tx.dc.ci.(*fakeConn).waiter = func(c context.Context) {
464 cancel()
465 <-ctx.Done()
467 // This will trigger the *fakeConn.Prepare method which will take time
468 // performing the query. The ctxDriverPrepare func will check the context
469 // after this and close the rows and return an error.
470 _, err = tx.QueryContext(ctx, "SELECT|people|age,name|")
471 if err != context.Canceled {
472 t.Fatalf("expected QueryContext to error with context canceled but returned %v", err)
475 waitForFree(t, db, 0)
478 // TestTxContextWaitNoDiscard is the same as TestTxContextWait, but should not discard
479 // the final connection.
480 func TestTxContextWaitNoDiscard(t *testing.T) {
481 db := newTestDB(t, "people")
482 defer closeDB(t, db)
484 ctx, cancel := context.WithTimeout(context.Background(), 15*time.Millisecond)
485 defer cancel()
487 tx, err := db.BeginTx(ctx, nil)
488 if err != nil {
489 // Guard against the context being canceled before BeginTx completes.
490 if err == context.DeadlineExceeded {
491 t.Skip("tx context canceled prior to first use")
493 t.Fatal(err)
496 // This will trigger the *fakeConn.Prepare method which will take time
497 // performing the query. The ctxDriverPrepare func will check the context
498 // after this and close the rows and return an error.
499 _, err = tx.QueryContext(ctx, "WAIT|1s|SELECT|people|age,name|")
500 if err != context.DeadlineExceeded {
501 t.Fatalf("expected QueryContext to error with context deadline exceeded but returned %v", err)
504 waitForFree(t, db, 1)
507 // TestUnsupportedOptions checks that the database fails when a driver that
508 // doesn't implement ConnBeginTx is used with non-default options and an
509 // un-cancellable context.
510 func TestUnsupportedOptions(t *testing.T) {
511 db := newTestDB(t, "people")
512 defer closeDB(t, db)
513 _, err := db.BeginTx(context.Background(), &TxOptions{
514 Isolation: LevelSerializable, ReadOnly: true,
516 if err == nil {
517 t.Fatal("expected error when using unsupported options, got nil")
521 func TestMultiResultSetQuery(t *testing.T) {
522 db := newTestDB(t, "people")
523 defer closeDB(t, db)
524 prepares0 := numPrepares(t, db)
525 rows, err := db.Query("SELECT|people|age,name|;SELECT|people|name|")
526 if err != nil {
527 t.Fatalf("Query: %v", err)
529 type row1 struct {
530 age int
531 name string
533 type row2 struct {
534 name string
536 got1 := []row1{}
537 for rows.Next() {
538 var r row1
539 err = rows.Scan(&r.age, &r.name)
540 if err != nil {
541 t.Fatalf("Scan: %v", err)
543 got1 = append(got1, r)
545 err = rows.Err()
546 if err != nil {
547 t.Fatalf("Err: %v", err)
549 want1 := []row1{
550 {age: 1, name: "Alice"},
551 {age: 2, name: "Bob"},
552 {age: 3, name: "Chris"},
554 if !reflect.DeepEqual(got1, want1) {
555 t.Errorf("mismatch.\n got1: %#v\nwant: %#v", got1, want1)
558 if !rows.NextResultSet() {
559 t.Errorf("expected another result set")
562 got2 := []row2{}
563 for rows.Next() {
564 var r row2
565 err = rows.Scan(&r.name)
566 if err != nil {
567 t.Fatalf("Scan: %v", err)
569 got2 = append(got2, r)
571 err = rows.Err()
572 if err != nil {
573 t.Fatalf("Err: %v", err)
575 want2 := []row2{
576 {name: "Alice"},
577 {name: "Bob"},
578 {name: "Chris"},
580 if !reflect.DeepEqual(got2, want2) {
581 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got2, want2)
583 if rows.NextResultSet() {
584 t.Errorf("expected no more result sets")
587 // And verify that the final rows.Next() call, which hit EOF,
588 // also closed the rows connection.
589 waitForFree(t, db, 1)
590 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
591 t.Errorf("executed %d Prepare statements; want 1", prepares)
595 func TestQueryNamedArg(t *testing.T) {
596 db := newTestDB(t, "people")
597 defer closeDB(t, db)
598 prepares0 := numPrepares(t, db)
599 rows, err := db.Query(
600 // Ensure the name and age parameters only match on placeholder name, not position.
601 "SELECT|people|age,name|name=?name,age=?age",
602 Named("age", 2),
603 Named("name", "Bob"),
605 if err != nil {
606 t.Fatalf("Query: %v", err)
608 type row struct {
609 age int
610 name string
612 got := []row{}
613 for rows.Next() {
614 var r row
615 err = rows.Scan(&r.age, &r.name)
616 if err != nil {
617 t.Fatalf("Scan: %v", err)
619 got = append(got, r)
621 err = rows.Err()
622 if err != nil {
623 t.Fatalf("Err: %v", err)
625 want := []row{
626 {age: 2, name: "Bob"},
628 if !reflect.DeepEqual(got, want) {
629 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
632 // And verify that the final rows.Next() call, which hit EOF,
633 // also closed the rows connection.
634 if n := db.numFreeConns(); n != 1 {
635 t.Fatalf("free conns after query hitting EOF = %d; want 1", n)
637 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
638 t.Errorf("executed %d Prepare statements; want 1", prepares)
642 func TestPoolExhaustOnCancel(t *testing.T) {
643 if testing.Short() {
644 t.Skip("long test")
647 max := 3
648 var saturate, saturateDone sync.WaitGroup
649 saturate.Add(max)
650 saturateDone.Add(max)
652 donePing := make(chan bool)
653 state := 0
655 // waiter will be called for all queries, including
656 // initial setup queries. The state is only assigned when
657 // no queries are made.
659 // Only allow the first batch of queries to finish once the
660 // second batch of Ping queries have finished.
661 waiter := func(ctx context.Context) {
662 switch state {
663 case 0:
664 // Nothing. Initial database setup.
665 case 1:
666 saturate.Done()
667 select {
668 case <-ctx.Done():
669 case <-donePing:
671 case 2:
674 db := newTestDBConnector(t, &fakeConnector{waiter: waiter}, "people")
675 defer closeDB(t, db)
677 db.SetMaxOpenConns(max)
679 // First saturate the connection pool.
680 // Then start new requests for a connection that is canceled after it is requested.
682 state = 1
683 for i := 0; i < max; i++ {
684 go func() {
685 rows, err := db.Query("SELECT|people|name,photo|")
686 if err != nil {
687 t.Errorf("Query: %v", err)
688 return
690 rows.Close()
691 saturateDone.Done()
695 saturate.Wait()
696 if t.Failed() {
697 t.FailNow()
699 state = 2
701 // Now cancel the request while it is waiting.
702 ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
703 defer cancel()
705 for i := 0; i < max; i++ {
706 ctxReq, cancelReq := context.WithCancel(ctx)
707 go func() {
708 time.Sleep(100 * time.Millisecond)
709 cancelReq()
711 err := db.PingContext(ctxReq)
712 if err != context.Canceled {
713 t.Fatalf("PingContext (Exhaust): %v", err)
716 close(donePing)
717 saturateDone.Wait()
719 // Now try to open a normal connection.
720 err := db.PingContext(ctx)
721 if err != nil {
722 t.Fatalf("PingContext (Normal): %v", err)
726 func TestRowsColumns(t *testing.T) {
727 db := newTestDB(t, "people")
728 defer closeDB(t, db)
729 rows, err := db.Query("SELECT|people|age,name|")
730 if err != nil {
731 t.Fatalf("Query: %v", err)
733 cols, err := rows.Columns()
734 if err != nil {
735 t.Fatalf("Columns: %v", err)
737 want := []string{"age", "name"}
738 if !reflect.DeepEqual(cols, want) {
739 t.Errorf("got %#v; want %#v", cols, want)
741 if err := rows.Close(); err != nil {
742 t.Errorf("error closing rows: %s", err)
746 func TestRowsColumnTypes(t *testing.T) {
747 db := newTestDB(t, "people")
748 defer closeDB(t, db)
749 rows, err := db.Query("SELECT|people|age,name|")
750 if err != nil {
751 t.Fatalf("Query: %v", err)
753 tt, err := rows.ColumnTypes()
754 if err != nil {
755 t.Fatalf("ColumnTypes: %v", err)
758 types := make([]reflect.Type, len(tt))
759 for i, tp := range tt {
760 st := tp.ScanType()
761 if st == nil {
762 t.Errorf("scantype is null for column %q", tp.Name())
763 continue
765 types[i] = st
767 values := make([]any, len(tt))
768 for i := range values {
769 values[i] = reflect.New(types[i]).Interface()
771 ct := 0
772 for rows.Next() {
773 err = rows.Scan(values...)
774 if err != nil {
775 t.Fatalf("failed to scan values in %v", err)
777 if ct == 1 {
778 if age := *values[0].(*int32); age != 2 {
779 t.Errorf("Expected 2, got %v", age)
781 if name := *values[1].(*string); name != "Bob" {
782 t.Errorf("Expected Bob, got %v", name)
785 ct++
787 if ct != 3 {
788 t.Errorf("expected 3 rows, got %d", ct)
791 if err := rows.Close(); err != nil {
792 t.Errorf("error closing rows: %s", err)
796 func TestQueryRow(t *testing.T) {
797 db := newTestDB(t, "people")
798 defer closeDB(t, db)
799 var name string
800 var age int
801 var birthday time.Time
803 err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age)
804 if err == nil || !strings.Contains(err.Error(), "expected 2 destination arguments") {
805 t.Errorf("expected error from wrong number of arguments; actually got: %v", err)
808 err = db.QueryRow("SELECT|people|bdate|age=?", 3).Scan(&birthday)
809 if err != nil || !birthday.Equal(chrisBirthday) {
810 t.Errorf("chris birthday = %v, err = %v; want %v", birthday, err, chrisBirthday)
813 err = db.QueryRow("SELECT|people|age,name|age=?", 2).Scan(&age, &name)
814 if err != nil {
815 t.Fatalf("age QueryRow+Scan: %v", err)
817 if name != "Bob" {
818 t.Errorf("expected name Bob, got %q", name)
820 if age != 2 {
821 t.Errorf("expected age 2, got %d", age)
824 err = db.QueryRow("SELECT|people|age,name|name=?", "Alice").Scan(&age, &name)
825 if err != nil {
826 t.Fatalf("name QueryRow+Scan: %v", err)
828 if name != "Alice" {
829 t.Errorf("expected name Alice, got %q", name)
831 if age != 1 {
832 t.Errorf("expected age 1, got %d", age)
835 var photo []byte
836 err = db.QueryRow("SELECT|people|photo|name=?", "Alice").Scan(&photo)
837 if err != nil {
838 t.Fatalf("photo QueryRow+Scan: %v", err)
840 want := []byte("APHOTO")
841 if !reflect.DeepEqual(photo, want) {
842 t.Errorf("photo = %q; want %q", photo, want)
846 func TestRowErr(t *testing.T) {
847 db := newTestDB(t, "people")
849 err := db.QueryRowContext(context.Background(), "SELECT|people|bdate|age=?", 3).Err()
850 if err != nil {
851 t.Errorf("Unexpected err = %v; want %v", err, nil)
854 ctx, cancel := context.WithCancel(context.Background())
855 cancel()
857 err = db.QueryRowContext(ctx, "SELECT|people|bdate|age=?", 3).Err()
858 exp := "context canceled"
859 if err == nil || !strings.Contains(err.Error(), exp) {
860 t.Errorf("Expected err = %v; got %v", exp, err)
864 func TestTxRollbackCommitErr(t *testing.T) {
865 db := newTestDB(t, "people")
866 defer closeDB(t, db)
868 tx, err := db.Begin()
869 if err != nil {
870 t.Fatal(err)
872 err = tx.Rollback()
873 if err != nil {
874 t.Errorf("expected nil error from Rollback; got %v", err)
876 err = tx.Commit()
877 if err != ErrTxDone {
878 t.Errorf("expected %q from Commit; got %q", ErrTxDone, err)
881 tx, err = db.Begin()
882 if err != nil {
883 t.Fatal(err)
885 err = tx.Commit()
886 if err != nil {
887 t.Errorf("expected nil error from Commit; got %v", err)
889 err = tx.Rollback()
890 if err != ErrTxDone {
891 t.Errorf("expected %q from Rollback; got %q", ErrTxDone, err)
895 func TestStatementErrorAfterClose(t *testing.T) {
896 db := newTestDB(t, "people")
897 defer closeDB(t, db)
898 stmt, err := db.Prepare("SELECT|people|age|name=?")
899 if err != nil {
900 t.Fatalf("Prepare: %v", err)
902 err = stmt.Close()
903 if err != nil {
904 t.Fatalf("Close: %v", err)
906 var name string
907 err = stmt.QueryRow("foo").Scan(&name)
908 if err == nil {
909 t.Errorf("expected error from QueryRow.Scan after Stmt.Close")
913 func TestStatementQueryRow(t *testing.T) {
914 db := newTestDB(t, "people")
915 defer closeDB(t, db)
916 stmt, err := db.Prepare("SELECT|people|age|name=?")
917 if err != nil {
918 t.Fatalf("Prepare: %v", err)
920 defer stmt.Close()
921 var age int
922 for n, tt := range []struct {
923 name string
924 want int
926 {"Alice", 1},
927 {"Bob", 2},
928 {"Chris", 3},
930 if err := stmt.QueryRow(tt.name).Scan(&age); err != nil {
931 t.Errorf("%d: on %q, QueryRow/Scan: %v", n, tt.name, err)
932 } else if age != tt.want {
933 t.Errorf("%d: age=%d, want %d", n, age, tt.want)
938 type stubDriverStmt struct {
939 err error
942 func (s stubDriverStmt) Close() error {
943 return s.err
946 func (s stubDriverStmt) NumInput() int {
947 return -1
950 func (s stubDriverStmt) Exec(args []driver.Value) (driver.Result, error) {
951 return nil, nil
954 func (s stubDriverStmt) Query(args []driver.Value) (driver.Rows, error) {
955 return nil, nil
958 // golang.org/issue/12798
959 func TestStatementClose(t *testing.T) {
960 want := errors.New("STMT ERROR")
962 tests := []struct {
963 stmt *Stmt
964 msg string
966 {&Stmt{stickyErr: want}, "stickyErr not propagated"},
967 {&Stmt{cg: &Tx{}, cgds: &driverStmt{Locker: &sync.Mutex{}, si: stubDriverStmt{want}}}, "driverStmt.Close() error not propagated"},
969 for _, test := range tests {
970 if err := test.stmt.Close(); err != want {
971 t.Errorf("%s. Got stmt.Close() = %v, want = %v", test.msg, err, want)
976 // golang.org/issue/3734
977 func TestStatementQueryRowConcurrent(t *testing.T) {
978 db := newTestDB(t, "people")
979 defer closeDB(t, db)
980 stmt, err := db.Prepare("SELECT|people|age|name=?")
981 if err != nil {
982 t.Fatalf("Prepare: %v", err)
984 defer stmt.Close()
986 const n = 10
987 ch := make(chan error, n)
988 for i := 0; i < n; i++ {
989 go func() {
990 var age int
991 err := stmt.QueryRow("Alice").Scan(&age)
992 if err == nil && age != 1 {
993 err = fmt.Errorf("unexpected age %d", age)
995 ch <- err
998 for i := 0; i < n; i++ {
999 if err := <-ch; err != nil {
1000 t.Error(err)
1005 // just a test of fakedb itself
1006 func TestBogusPreboundParameters(t *testing.T) {
1007 db := newTestDB(t, "foo")
1008 defer closeDB(t, db)
1009 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1010 _, err := db.Prepare("INSERT|t1|name=?,age=bogusconversion")
1011 if err == nil {
1012 t.Fatalf("expected error")
1014 if err.Error() != `fakedb: invalid conversion to int32 from "bogusconversion"` {
1015 t.Errorf("unexpected error: %v", err)
1019 func TestExec(t *testing.T) {
1020 db := newTestDB(t, "foo")
1021 defer closeDB(t, db)
1022 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1023 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1024 if err != nil {
1025 t.Errorf("Stmt, err = %v, %v", stmt, err)
1027 defer stmt.Close()
1029 type execTest struct {
1030 args []any
1031 wantErr string
1033 execTests := []execTest{
1034 // Okay:
1035 {[]any{"Brad", 31}, ""},
1036 {[]any{"Brad", int64(31)}, ""},
1037 {[]any{"Bob", "32"}, ""},
1038 {[]any{7, 9}, ""},
1040 // Invalid conversions:
1041 {[]any{"Brad", int64(0xFFFFFFFF)}, "sql: converting argument $2 type: sql/driver: value 4294967295 overflows int32"},
1042 {[]any{"Brad", "strconv fail"}, `sql: converting argument $2 type: sql/driver: value "strconv fail" can't be converted to int32`},
1044 // Wrong number of args:
1045 {[]any{}, "sql: expected 2 arguments, got 0"},
1046 {[]any{1, 2, 3}, "sql: expected 2 arguments, got 3"},
1048 for n, et := range execTests {
1049 _, err := stmt.Exec(et.args...)
1050 errStr := ""
1051 if err != nil {
1052 errStr = err.Error()
1054 if errStr != et.wantErr {
1055 t.Errorf("stmt.Execute #%d: for %v, got error %q, want error %q",
1056 n, et.args, errStr, et.wantErr)
1061 func TestTxPrepare(t *testing.T) {
1062 db := newTestDB(t, "")
1063 defer closeDB(t, db)
1064 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1065 tx, err := db.Begin()
1066 if err != nil {
1067 t.Fatalf("Begin = %v", err)
1069 stmt, err := tx.Prepare("INSERT|t1|name=?,age=?")
1070 if err != nil {
1071 t.Fatalf("Stmt, err = %v, %v", stmt, err)
1073 defer stmt.Close()
1074 _, err = stmt.Exec("Bobby", 7)
1075 if err != nil {
1076 t.Fatalf("Exec = %v", err)
1078 err = tx.Commit()
1079 if err != nil {
1080 t.Fatalf("Commit = %v", err)
1082 // Commit() should have closed the statement
1083 if !stmt.closed {
1084 t.Fatal("Stmt not closed after Commit")
1088 func TestTxStmt(t *testing.T) {
1089 db := newTestDB(t, "")
1090 defer closeDB(t, db)
1091 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1092 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1093 if err != nil {
1094 t.Fatalf("Stmt, err = %v, %v", stmt, err)
1096 defer stmt.Close()
1097 tx, err := db.Begin()
1098 if err != nil {
1099 t.Fatalf("Begin = %v", err)
1101 txs := tx.Stmt(stmt)
1102 defer txs.Close()
1103 _, err = txs.Exec("Bobby", 7)
1104 if err != nil {
1105 t.Fatalf("Exec = %v", err)
1107 err = tx.Commit()
1108 if err != nil {
1109 t.Fatalf("Commit = %v", err)
1111 // Commit() should have closed the statement
1112 if !txs.closed {
1113 t.Fatal("Stmt not closed after Commit")
1117 func TestTxStmtPreparedOnce(t *testing.T) {
1118 db := newTestDB(t, "")
1119 defer closeDB(t, db)
1120 exec(t, db, "CREATE|t1|name=string,age=int32")
1122 prepares0 := numPrepares(t, db)
1124 // db.Prepare increments numPrepares.
1125 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1126 if err != nil {
1127 t.Fatalf("Stmt, err = %v, %v", stmt, err)
1129 defer stmt.Close()
1131 tx, err := db.Begin()
1132 if err != nil {
1133 t.Fatalf("Begin = %v", err)
1136 txs1 := tx.Stmt(stmt)
1137 txs2 := tx.Stmt(stmt)
1139 _, err = txs1.Exec("Go", 7)
1140 if err != nil {
1141 t.Fatalf("Exec = %v", err)
1143 txs1.Close()
1145 _, err = txs2.Exec("Gopher", 8)
1146 if err != nil {
1147 t.Fatalf("Exec = %v", err)
1149 txs2.Close()
1151 err = tx.Commit()
1152 if err != nil {
1153 t.Fatalf("Commit = %v", err)
1156 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
1157 t.Errorf("executed %d Prepare statements; want 1", prepares)
1161 func TestTxStmtClosedRePrepares(t *testing.T) {
1162 db := newTestDB(t, "")
1163 defer closeDB(t, db)
1164 exec(t, db, "CREATE|t1|name=string,age=int32")
1166 prepares0 := numPrepares(t, db)
1168 // db.Prepare increments numPrepares.
1169 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1170 if err != nil {
1171 t.Fatalf("Stmt, err = %v, %v", stmt, err)
1173 tx, err := db.Begin()
1174 if err != nil {
1175 t.Fatalf("Begin = %v", err)
1177 err = stmt.Close()
1178 if err != nil {
1179 t.Fatalf("stmt.Close() = %v", err)
1181 // tx.Stmt increments numPrepares because stmt is closed.
1182 txs := tx.Stmt(stmt)
1183 if txs.stickyErr != nil {
1184 t.Fatal(txs.stickyErr)
1186 if txs.parentStmt != nil {
1187 t.Fatal("expected nil parentStmt")
1189 _, err = txs.Exec(`Eric`, 82)
1190 if err != nil {
1191 t.Fatalf("txs.Exec = %v", err)
1194 err = txs.Close()
1195 if err != nil {
1196 t.Fatalf("txs.Close = %v", err)
1199 tx.Rollback()
1201 if prepares := numPrepares(t, db) - prepares0; prepares != 2 {
1202 t.Errorf("executed %d Prepare statements; want 2", prepares)
1206 func TestParentStmtOutlivesTxStmt(t *testing.T) {
1207 db := newTestDB(t, "")
1208 defer closeDB(t, db)
1209 exec(t, db, "CREATE|t1|name=string,age=int32")
1211 // Make sure everything happens on the same connection.
1212 db.SetMaxOpenConns(1)
1214 prepares0 := numPrepares(t, db)
1216 // db.Prepare increments numPrepares.
1217 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1218 if err != nil {
1219 t.Fatalf("Stmt, err = %v, %v", stmt, err)
1221 defer stmt.Close()
1222 tx, err := db.Begin()
1223 if err != nil {
1224 t.Fatalf("Begin = %v", err)
1226 txs := tx.Stmt(stmt)
1227 if len(stmt.css) != 1 {
1228 t.Fatalf("len(stmt.css) = %v; want 1", len(stmt.css))
1230 err = txs.Close()
1231 if err != nil {
1232 t.Fatalf("txs.Close() = %v", err)
1234 err = tx.Rollback()
1235 if err != nil {
1236 t.Fatalf("tx.Rollback() = %v", err)
1238 // txs must not be valid.
1239 _, err = txs.Exec("Suzan", 30)
1240 if err == nil {
1241 t.Fatalf("txs.Exec(), expected err")
1243 // Stmt must still be valid.
1244 _, err = stmt.Exec("Janina", 25)
1245 if err != nil {
1246 t.Fatalf("stmt.Exec() = %v", err)
1249 if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
1250 t.Errorf("executed %d Prepare statements; want 1", prepares)
1254 // Test that tx.Stmt called with a statement already
1255 // associated with tx as argument re-prepares the same
1256 // statement again.
1257 func TestTxStmtFromTxStmtRePrepares(t *testing.T) {
1258 db := newTestDB(t, "")
1259 defer closeDB(t, db)
1260 exec(t, db, "CREATE|t1|name=string,age=int32")
1261 prepares0 := numPrepares(t, db)
1262 // db.Prepare increments numPrepares.
1263 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1264 if err != nil {
1265 t.Fatalf("Stmt, err = %v, %v", stmt, err)
1267 defer stmt.Close()
1269 tx, err := db.Begin()
1270 if err != nil {
1271 t.Fatalf("Begin = %v", err)
1273 txs1 := tx.Stmt(stmt)
1275 // tx.Stmt(txs1) increments numPrepares because txs1 already
1276 // belongs to a transaction (albeit the same transaction).
1277 txs2 := tx.Stmt(txs1)
1278 if txs2.stickyErr != nil {
1279 t.Fatal(txs2.stickyErr)
1281 if txs2.parentStmt != nil {
1282 t.Fatal("expected nil parentStmt")
1284 _, err = txs2.Exec(`Eric`, 82)
1285 if err != nil {
1286 t.Fatal(err)
1289 err = txs1.Close()
1290 if err != nil {
1291 t.Fatalf("txs1.Close = %v", err)
1293 err = txs2.Close()
1294 if err != nil {
1295 t.Fatalf("txs1.Close = %v", err)
1297 err = tx.Rollback()
1298 if err != nil {
1299 t.Fatalf("tx.Rollback = %v", err)
1302 if prepares := numPrepares(t, db) - prepares0; prepares != 2 {
1303 t.Errorf("executed %d Prepare statements; want 2", prepares)
1307 // Issue: https://golang.org/issue/2784
1308 // This test didn't fail before because we got lucky with the fakedb driver.
1309 // It was failing, and now not, in github.com/bradfitz/go-sql-test
1310 func TestTxQuery(t *testing.T) {
1311 db := newTestDB(t, "")
1312 defer closeDB(t, db)
1313 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1314 exec(t, db, "INSERT|t1|name=Alice")
1316 tx, err := db.Begin()
1317 if err != nil {
1318 t.Fatal(err)
1320 defer tx.Rollback()
1322 r, err := tx.Query("SELECT|t1|name|")
1323 if err != nil {
1324 t.Fatal(err)
1326 defer r.Close()
1328 if !r.Next() {
1329 if r.Err() != nil {
1330 t.Fatal(r.Err())
1332 t.Fatal("expected one row")
1335 var x string
1336 err = r.Scan(&x)
1337 if err != nil {
1338 t.Fatal(err)
1342 func TestTxQueryInvalid(t *testing.T) {
1343 db := newTestDB(t, "")
1344 defer closeDB(t, db)
1346 tx, err := db.Begin()
1347 if err != nil {
1348 t.Fatal(err)
1350 defer tx.Rollback()
1352 _, err = tx.Query("SELECT|t1|name|")
1353 if err == nil {
1354 t.Fatal("Error expected")
1358 // Tests fix for issue 4433, that retries in Begin happen when
1359 // conn.Begin() returns ErrBadConn
1360 func TestTxErrBadConn(t *testing.T) {
1361 db, err := Open("test", fakeDBName+";badConn")
1362 if err != nil {
1363 t.Fatalf("Open: %v", err)
1365 if _, err := db.Exec("WIPE"); err != nil {
1366 t.Fatalf("exec wipe: %v", err)
1368 defer closeDB(t, db)
1369 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1370 stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1371 if err != nil {
1372 t.Fatalf("Stmt, err = %v, %v", stmt, err)
1374 defer stmt.Close()
1375 tx, err := db.Begin()
1376 if err != nil {
1377 t.Fatalf("Begin = %v", err)
1379 txs := tx.Stmt(stmt)
1380 defer txs.Close()
1381 _, err = txs.Exec("Bobby", 7)
1382 if err != nil {
1383 t.Fatalf("Exec = %v", err)
1385 err = tx.Commit()
1386 if err != nil {
1387 t.Fatalf("Commit = %v", err)
1391 func TestConnQuery(t *testing.T) {
1392 db := newTestDB(t, "people")
1393 defer closeDB(t, db)
1395 ctx, cancel := context.WithCancel(context.Background())
1396 defer cancel()
1397 conn, err := db.Conn(ctx)
1398 if err != nil {
1399 t.Fatal(err)
1401 conn.dc.ci.(*fakeConn).skipDirtySession = true
1402 defer conn.Close()
1404 var name string
1405 err = conn.QueryRowContext(ctx, "SELECT|people|name|age=?", 3).Scan(&name)
1406 if err != nil {
1407 t.Fatal(err)
1409 if name != "Chris" {
1410 t.Fatalf("unexpected result, got %q want Chris", name)
1413 err = conn.PingContext(ctx)
1414 if err != nil {
1415 t.Fatal(err)
1419 func TestConnRaw(t *testing.T) {
1420 db := newTestDB(t, "people")
1421 defer closeDB(t, db)
1423 ctx, cancel := context.WithCancel(context.Background())
1424 defer cancel()
1425 conn, err := db.Conn(ctx)
1426 if err != nil {
1427 t.Fatal(err)
1429 conn.dc.ci.(*fakeConn).skipDirtySession = true
1430 defer conn.Close()
1432 sawFunc := false
1433 err = conn.Raw(func(dc any) error {
1434 sawFunc = true
1435 if _, ok := dc.(*fakeConn); !ok {
1436 return fmt.Errorf("got %T want *fakeConn", dc)
1438 return nil
1440 if err != nil {
1441 t.Fatal(err)
1443 if !sawFunc {
1444 t.Fatal("Raw func not called")
1447 func() {
1448 defer func() {
1449 x := recover()
1450 if x == nil {
1451 t.Fatal("expected panic")
1453 conn.closemu.Lock()
1454 closed := conn.dc == nil
1455 conn.closemu.Unlock()
1456 if !closed {
1457 t.Fatal("expected connection to be closed after panic")
1460 err = conn.Raw(func(dc any) error {
1461 panic("Conn.Raw panic should return an error")
1463 t.Fatal("expected panic from Raw func")
1467 func TestCursorFake(t *testing.T) {
1468 db := newTestDB(t, "people")
1469 defer closeDB(t, db)
1471 ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
1472 defer cancel()
1474 exec(t, db, "CREATE|peoplecursor|list=table")
1475 exec(t, db, "INSERT|peoplecursor|list=people!name!age")
1477 rows, err := db.QueryContext(ctx, `SELECT|peoplecursor|list|`)
1478 if err != nil {
1479 t.Fatal(err)
1481 defer rows.Close()
1483 if !rows.Next() {
1484 t.Fatal("no rows")
1486 var cursor = &Rows{}
1487 err = rows.Scan(cursor)
1488 if err != nil {
1489 t.Fatal(err)
1491 defer cursor.Close()
1493 const expectedRows = 3
1494 var currentRow int64
1496 var n int64
1497 var s string
1498 for cursor.Next() {
1499 currentRow++
1500 err = cursor.Scan(&s, &n)
1501 if err != nil {
1502 t.Fatal(err)
1504 if n != currentRow {
1505 t.Errorf("expected number(Age)=%d, got %d", currentRow, n)
1508 if currentRow != expectedRows {
1509 t.Errorf("expected %d rows, got %d rows", expectedRows, currentRow)
1513 func TestInvalidNilValues(t *testing.T) {
1514 var date1 time.Time
1515 var date2 int
1517 tests := []struct {
1518 name string
1519 input any
1520 expectedError string
1523 name: "time.Time",
1524 input: &date1,
1525 expectedError: `sql: Scan error on column index 0, name "bdate": unsupported Scan, storing driver.Value type <nil> into type *time.Time`,
1528 name: "int",
1529 input: &date2,
1530 expectedError: `sql: Scan error on column index 0, name "bdate": converting NULL to int is unsupported`,
1534 for _, tt := range tests {
1535 t.Run(tt.name, func(t *testing.T) {
1536 db := newTestDB(t, "people")
1537 defer closeDB(t, db)
1539 ctx, cancel := context.WithCancel(context.Background())
1540 defer cancel()
1541 conn, err := db.Conn(ctx)
1542 if err != nil {
1543 t.Fatal(err)
1545 conn.dc.ci.(*fakeConn).skipDirtySession = true
1546 defer conn.Close()
1548 err = conn.QueryRowContext(ctx, "SELECT|people|bdate|age=?", 1).Scan(tt.input)
1549 if err == nil {
1550 t.Fatal("expected error when querying nil column, but succeeded")
1552 if err.Error() != tt.expectedError {
1553 t.Fatalf("Expected error: %s\nReceived: %s", tt.expectedError, err.Error())
1556 err = conn.PingContext(ctx)
1557 if err != nil {
1558 t.Fatal(err)
1564 func TestConnTx(t *testing.T) {
1565 db := newTestDB(t, "people")
1566 defer closeDB(t, db)
1568 ctx, cancel := context.WithCancel(context.Background())
1569 defer cancel()
1570 conn, err := db.Conn(ctx)
1571 if err != nil {
1572 t.Fatal(err)
1574 conn.dc.ci.(*fakeConn).skipDirtySession = true
1575 defer conn.Close()
1577 tx, err := conn.BeginTx(ctx, nil)
1578 if err != nil {
1579 t.Fatal(err)
1581 insertName, insertAge := "Nancy", 33
1582 _, err = tx.ExecContext(ctx, "INSERT|people|name=?,age=?,photo=APHOTO", insertName, insertAge)
1583 if err != nil {
1584 t.Fatal(err)
1586 err = tx.Commit()
1587 if err != nil {
1588 t.Fatal(err)
1591 var selectName string
1592 err = conn.QueryRowContext(ctx, "SELECT|people|name|age=?", insertAge).Scan(&selectName)
1593 if err != nil {
1594 t.Fatal(err)
1596 if selectName != insertName {
1597 t.Fatalf("got %q want %q", selectName, insertName)
1601 // TestConnIsValid verifies that a database connection that should be discarded,
1602 // is actually discarded and does not re-enter the connection pool.
1603 // If the IsValid method from *fakeConn is removed, this test will fail.
1604 func TestConnIsValid(t *testing.T) {
1605 db := newTestDB(t, "people")
1606 defer closeDB(t, db)
1608 db.SetMaxOpenConns(1)
1610 ctx := context.Background()
1612 c, err := db.Conn(ctx)
1613 if err != nil {
1614 t.Fatal(err)
1617 err = c.Raw(func(raw any) error {
1618 dc := raw.(*fakeConn)
1619 dc.stickyBad = true
1620 return nil
1622 if err != nil {
1623 t.Fatal(err)
1625 c.Close()
1627 if len(db.freeConn) > 0 && db.freeConn[0].ci.(*fakeConn).stickyBad {
1628 t.Fatal("bad connection returned to pool; expected bad connection to be discarded")
1632 // Tests fix for issue 2542, that we release a lock when querying on
1633 // a closed connection.
1634 func TestIssue2542Deadlock(t *testing.T) {
1635 db := newTestDB(t, "people")
1636 closeDB(t, db)
1637 for i := 0; i < 2; i++ {
1638 _, err := db.Query("SELECT|people|age,name|")
1639 if err == nil {
1640 t.Fatalf("expected error")
1645 // From golang.org/issue/3865
1646 func TestCloseStmtBeforeRows(t *testing.T) {
1647 db := newTestDB(t, "people")
1648 defer closeDB(t, db)
1650 s, err := db.Prepare("SELECT|people|name|")
1651 if err != nil {
1652 t.Fatal(err)
1655 r, err := s.Query()
1656 if err != nil {
1657 s.Close()
1658 t.Fatal(err)
1661 err = s.Close()
1662 if err != nil {
1663 t.Fatal(err)
1666 r.Close()
1669 // Tests fix for issue 2788, that we bind nil to a []byte if the
1670 // value in the column is sql null
1671 func TestNullByteSlice(t *testing.T) {
1672 db := newTestDB(t, "")
1673 defer closeDB(t, db)
1674 exec(t, db, "CREATE|t|id=int32,name=nullstring")
1675 exec(t, db, "INSERT|t|id=10,name=?", nil)
1677 var name []byte
1679 err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name)
1680 if err != nil {
1681 t.Fatal(err)
1683 if name != nil {
1684 t.Fatalf("name []byte should be nil for null column value, got: %#v", name)
1687 exec(t, db, "INSERT|t|id=11,name=?", "bob")
1688 err = db.QueryRow("SELECT|t|name|id=?", 11).Scan(&name)
1689 if err != nil {
1690 t.Fatal(err)
1692 if string(name) != "bob" {
1693 t.Fatalf("name []byte should be bob, got: %q", string(name))
1697 func TestPointerParamsAndScans(t *testing.T) {
1698 db := newTestDB(t, "")
1699 defer closeDB(t, db)
1700 exec(t, db, "CREATE|t|id=int32,name=nullstring")
1702 bob := "bob"
1703 var name *string
1705 name = &bob
1706 exec(t, db, "INSERT|t|id=10,name=?", name)
1707 name = nil
1708 exec(t, db, "INSERT|t|id=20,name=?", name)
1710 err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name)
1711 if err != nil {
1712 t.Fatalf("querying id 10: %v", err)
1714 if name == nil {
1715 t.Errorf("id 10's name = nil; want bob")
1716 } else if *name != "bob" {
1717 t.Errorf("id 10's name = %q; want bob", *name)
1720 err = db.QueryRow("SELECT|t|name|id=?", 20).Scan(&name)
1721 if err != nil {
1722 t.Fatalf("querying id 20: %v", err)
1724 if name != nil {
1725 t.Errorf("id 20 = %q; want nil", *name)
1729 func TestQueryRowClosingStmt(t *testing.T) {
1730 db := newTestDB(t, "people")
1731 defer closeDB(t, db)
1732 var name string
1733 var age int
1734 err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age, &name)
1735 if err != nil {
1736 t.Fatal(err)
1738 if len(db.freeConn) != 1 {
1739 t.Fatalf("expected 1 free conn")
1741 fakeConn := db.freeConn[0].ci.(*fakeConn)
1742 if made, closed := fakeConn.stmtsMade, fakeConn.stmtsClosed; made != closed {
1743 t.Errorf("statement close mismatch: made %d, closed %d", made, closed)
1747 var atomicRowsCloseHook atomic.Value // of func(*Rows, *error)
1749 func init() {
1750 rowsCloseHook = func() func(*Rows, *error) {
1751 fn, _ := atomicRowsCloseHook.Load().(func(*Rows, *error))
1752 return fn
1756 func setRowsCloseHook(fn func(*Rows, *error)) {
1757 if fn == nil {
1758 // Can't change an atomic.Value back to nil, so set it to this
1759 // no-op func instead.
1760 fn = func(*Rows, *error) {}
1762 atomicRowsCloseHook.Store(fn)
1765 // Test issue 6651
1766 func TestIssue6651(t *testing.T) {
1767 db := newTestDB(t, "people")
1768 defer closeDB(t, db)
1770 var v string
1772 want := "error in rows.Next"
1773 rowsCursorNextHook = func(dest []driver.Value) error {
1774 return fmt.Errorf(want)
1776 defer func() { rowsCursorNextHook = nil }()
1778 err := db.QueryRow("SELECT|people|name|").Scan(&v)
1779 if err == nil || err.Error() != want {
1780 t.Errorf("error = %q; want %q", err, want)
1782 rowsCursorNextHook = nil
1784 want = "error in rows.Close"
1785 setRowsCloseHook(func(rows *Rows, err *error) {
1786 *err = fmt.Errorf(want)
1788 defer setRowsCloseHook(nil)
1789 err = db.QueryRow("SELECT|people|name|").Scan(&v)
1790 if err == nil || err.Error() != want {
1791 t.Errorf("error = %q; want %q", err, want)
1795 type nullTestRow struct {
1796 nullParam any
1797 notNullParam any
1798 scanNullVal any
1801 type nullTestSpec struct {
1802 nullType string
1803 notNullType string
1804 rows [6]nullTestRow
1807 func TestNullStringParam(t *testing.T) {
1808 spec := nullTestSpec{"nullstring", "string", [6]nullTestRow{
1809 {NullString{"aqua", true}, "", NullString{"aqua", true}},
1810 {NullString{"brown", false}, "", NullString{"", false}},
1811 {"chartreuse", "", NullString{"chartreuse", true}},
1812 {NullString{"darkred", true}, "", NullString{"darkred", true}},
1813 {NullString{"eel", false}, "", NullString{"", false}},
1814 {"foo", NullString{"black", false}, nil},
1816 nullTestRun(t, spec)
1819 func TestNullInt64Param(t *testing.T) {
1820 spec := nullTestSpec{"nullint64", "int64", [6]nullTestRow{
1821 {NullInt64{31, true}, 1, NullInt64{31, true}},
1822 {NullInt64{-22, false}, 1, NullInt64{0, false}},
1823 {22, 1, NullInt64{22, true}},
1824 {NullInt64{33, true}, 1, NullInt64{33, true}},
1825 {NullInt64{222, false}, 1, NullInt64{0, false}},
1826 {0, NullInt64{31, false}, nil},
1828 nullTestRun(t, spec)
1831 func TestNullInt32Param(t *testing.T) {
1832 spec := nullTestSpec{"nullint32", "int32", [6]nullTestRow{
1833 {NullInt32{31, true}, 1, NullInt32{31, true}},
1834 {NullInt32{-22, false}, 1, NullInt32{0, false}},
1835 {22, 1, NullInt32{22, true}},
1836 {NullInt32{33, true}, 1, NullInt32{33, true}},
1837 {NullInt32{222, false}, 1, NullInt32{0, false}},
1838 {0, NullInt32{31, false}, nil},
1840 nullTestRun(t, spec)
1843 func TestNullInt16Param(t *testing.T) {
1844 spec := nullTestSpec{"nullint16", "int16", [6]nullTestRow{
1845 {NullInt16{31, true}, 1, NullInt16{31, true}},
1846 {NullInt16{-22, false}, 1, NullInt16{0, false}},
1847 {22, 1, NullInt16{22, true}},
1848 {NullInt16{33, true}, 1, NullInt16{33, true}},
1849 {NullInt16{222, false}, 1, NullInt16{0, false}},
1850 {0, NullInt16{31, false}, nil},
1852 nullTestRun(t, spec)
1855 func TestNullByteParam(t *testing.T) {
1856 spec := nullTestSpec{"nullbyte", "byte", [6]nullTestRow{
1857 {NullByte{31, true}, 1, NullByte{31, true}},
1858 {NullByte{0, false}, 1, NullByte{0, false}},
1859 {22, 1, NullByte{22, true}},
1860 {NullByte{33, true}, 1, NullByte{33, true}},
1861 {NullByte{222, false}, 1, NullByte{0, false}},
1862 {0, NullByte{31, false}, nil},
1864 nullTestRun(t, spec)
1867 func TestNullFloat64Param(t *testing.T) {
1868 spec := nullTestSpec{"nullfloat64", "float64", [6]nullTestRow{
1869 {NullFloat64{31.2, true}, 1, NullFloat64{31.2, true}},
1870 {NullFloat64{13.1, false}, 1, NullFloat64{0, false}},
1871 {-22.9, 1, NullFloat64{-22.9, true}},
1872 {NullFloat64{33.81, true}, 1, NullFloat64{33.81, true}},
1873 {NullFloat64{222, false}, 1, NullFloat64{0, false}},
1874 {10, NullFloat64{31.2, false}, nil},
1876 nullTestRun(t, spec)
1879 func TestNullBoolParam(t *testing.T) {
1880 spec := nullTestSpec{"nullbool", "bool", [6]nullTestRow{
1881 {NullBool{false, true}, true, NullBool{false, true}},
1882 {NullBool{true, false}, false, NullBool{false, false}},
1883 {true, true, NullBool{true, true}},
1884 {NullBool{true, true}, false, NullBool{true, true}},
1885 {NullBool{true, false}, true, NullBool{false, false}},
1886 {true, NullBool{true, false}, nil},
1888 nullTestRun(t, spec)
1891 func TestNullTimeParam(t *testing.T) {
1892 t0 := time.Time{}
1893 t1 := time.Date(2000, 1, 1, 8, 9, 10, 11, time.UTC)
1894 t2 := time.Date(2010, 1, 1, 8, 9, 10, 11, time.UTC)
1895 spec := nullTestSpec{"nulldatetime", "datetime", [6]nullTestRow{
1896 {NullTime{t1, true}, t2, NullTime{t1, true}},
1897 {NullTime{t1, false}, t2, NullTime{t0, false}},
1898 {t1, t2, NullTime{t1, true}},
1899 {NullTime{t1, true}, t2, NullTime{t1, true}},
1900 {NullTime{t1, false}, t2, NullTime{t0, false}},
1901 {t2, NullTime{t1, false}, nil},
1903 nullTestRun(t, spec)
1906 func nullTestRun(t *testing.T, spec nullTestSpec) {
1907 db := newTestDB(t, "")
1908 defer closeDB(t, db)
1909 exec(t, db, fmt.Sprintf("CREATE|t|id=int32,name=string,nullf=%s,notnullf=%s", spec.nullType, spec.notNullType))
1911 // Inserts with db.Exec:
1912 exec(t, db, "INSERT|t|id=?,name=?,nullf=?,notnullf=?", 1, "alice", spec.rows[0].nullParam, spec.rows[0].notNullParam)
1913 exec(t, db, "INSERT|t|id=?,name=?,nullf=?,notnullf=?", 2, "bob", spec.rows[1].nullParam, spec.rows[1].notNullParam)
1915 // Inserts with a prepared statement:
1916 stmt, err := db.Prepare("INSERT|t|id=?,name=?,nullf=?,notnullf=?")
1917 if err != nil {
1918 t.Fatalf("prepare: %v", err)
1920 defer stmt.Close()
1921 if _, err := stmt.Exec(3, "chris", spec.rows[2].nullParam, spec.rows[2].notNullParam); err != nil {
1922 t.Errorf("exec insert chris: %v", err)
1924 if _, err := stmt.Exec(4, "dave", spec.rows[3].nullParam, spec.rows[3].notNullParam); err != nil {
1925 t.Errorf("exec insert dave: %v", err)
1927 if _, err := stmt.Exec(5, "eleanor", spec.rows[4].nullParam, spec.rows[4].notNullParam); err != nil {
1928 t.Errorf("exec insert eleanor: %v", err)
1931 // Can't put null val into non-null col
1932 if _, err := stmt.Exec(6, "bob", spec.rows[5].nullParam, spec.rows[5].notNullParam); err == nil {
1933 t.Errorf("expected error inserting nil val with prepared statement Exec")
1936 _, err = db.Exec("INSERT|t|id=?,name=?,nullf=?", 999, nil, nil)
1937 if err == nil {
1938 // TODO: this test fails, but it's just because
1939 // fakeConn implements the optional Execer interface,
1940 // so arguably this is the correct behavior. But
1941 // maybe I should flesh out the fakeConn.Exec
1942 // implementation so this properly fails.
1943 // t.Errorf("expected error inserting nil name with Exec")
1946 paramtype := reflect.TypeOf(spec.rows[0].nullParam)
1947 bindVal := reflect.New(paramtype).Interface()
1949 for i := 0; i < 5; i++ {
1950 id := i + 1
1951 if err := db.QueryRow("SELECT|t|nullf|id=?", id).Scan(bindVal); err != nil {
1952 t.Errorf("id=%d Scan: %v", id, err)
1954 bindValDeref := reflect.ValueOf(bindVal).Elem().Interface()
1955 if !reflect.DeepEqual(bindValDeref, spec.rows[i].scanNullVal) {
1956 t.Errorf("id=%d got %#v, want %#v", id, bindValDeref, spec.rows[i].scanNullVal)
1961 // golang.org/issue/4859
1962 func TestQueryRowNilScanDest(t *testing.T) {
1963 db := newTestDB(t, "people")
1964 defer closeDB(t, db)
1965 var name *string // nil pointer
1966 err := db.QueryRow("SELECT|people|name|").Scan(name)
1967 want := `sql: Scan error on column index 0, name "name": destination pointer is nil`
1968 if err == nil || err.Error() != want {
1969 t.Errorf("error = %q; want %q", err.Error(), want)
1973 func TestIssue4902(t *testing.T) {
1974 db := newTestDB(t, "people")
1975 defer closeDB(t, db)
1977 driver := db.Driver().(*fakeDriver)
1978 opens0 := driver.openCount
1980 var stmt *Stmt
1981 var err error
1982 for i := 0; i < 10; i++ {
1983 stmt, err = db.Prepare("SELECT|people|name|")
1984 if err != nil {
1985 t.Fatal(err)
1987 err = stmt.Close()
1988 if err != nil {
1989 t.Fatal(err)
1993 opens := driver.openCount - opens0
1994 if opens > 1 {
1995 t.Errorf("opens = %d; want <= 1", opens)
1996 t.Logf("db = %#v", db)
1997 t.Logf("driver = %#v", driver)
1998 t.Logf("stmt = %#v", stmt)
2002 // Issue 3857
2003 // This used to deadlock.
2004 func TestSimultaneousQueries(t *testing.T) {
2005 db := newTestDB(t, "people")
2006 defer closeDB(t, db)
2008 tx, err := db.Begin()
2009 if err != nil {
2010 t.Fatal(err)
2012 defer tx.Rollback()
2014 r1, err := tx.Query("SELECT|people|name|")
2015 if err != nil {
2016 t.Fatal(err)
2018 defer r1.Close()
2020 r2, err := tx.Query("SELECT|people|name|")
2021 if err != nil {
2022 t.Fatal(err)
2024 defer r2.Close()
2027 func TestMaxIdleConns(t *testing.T) {
2028 db := newTestDB(t, "people")
2029 defer closeDB(t, db)
2031 tx, err := db.Begin()
2032 if err != nil {
2033 t.Fatal(err)
2035 tx.Commit()
2036 if got := len(db.freeConn); got != 1 {
2037 t.Errorf("freeConns = %d; want 1", got)
2040 db.SetMaxIdleConns(0)
2042 if got := len(db.freeConn); got != 0 {
2043 t.Errorf("freeConns after set to zero = %d; want 0", got)
2046 tx, err = db.Begin()
2047 if err != nil {
2048 t.Fatal(err)
2050 tx.Commit()
2051 if got := len(db.freeConn); got != 0 {
2052 t.Errorf("freeConns = %d; want 0", got)
2056 func TestMaxOpenConns(t *testing.T) {
2057 if testing.Short() {
2058 t.Skip("skipping in short mode")
2060 defer setHookpostCloseConn(nil)
2061 setHookpostCloseConn(func(_ *fakeConn, err error) {
2062 if err != nil {
2063 t.Errorf("Error closing fakeConn: %v", err)
2067 db := newTestDB(t, "magicquery")
2068 defer closeDB(t, db)
2070 driver := db.Driver().(*fakeDriver)
2072 // Force the number of open connections to 0 so we can get an accurate
2073 // count for the test
2074 db.clearAllConns(t)
2076 driver.mu.Lock()
2077 opens0 := driver.openCount
2078 closes0 := driver.closeCount
2079 driver.mu.Unlock()
2081 db.SetMaxIdleConns(10)
2082 db.SetMaxOpenConns(10)
2084 stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?")
2085 if err != nil {
2086 t.Fatal(err)
2089 // Start 50 parallel slow queries.
2090 const (
2091 nquery = 50
2092 sleepMillis = 25
2093 nbatch = 2
2095 var wg sync.WaitGroup
2096 for batch := 0; batch < nbatch; batch++ {
2097 for i := 0; i < nquery; i++ {
2098 wg.Add(1)
2099 go func() {
2100 defer wg.Done()
2101 var op string
2102 if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows {
2103 t.Error(err)
2107 // Wait for the batch of queries above to finish before starting the next round.
2108 wg.Wait()
2111 if g, w := db.numFreeConns(), 10; g != w {
2112 t.Errorf("free conns = %d; want %d", g, w)
2115 if n := db.numDepsPoll(t, 20); n > 20 {
2116 t.Errorf("number of dependencies = %d; expected <= 20", n)
2117 db.dumpDeps(t)
2120 driver.mu.Lock()
2121 opens := driver.openCount - opens0
2122 closes := driver.closeCount - closes0
2123 driver.mu.Unlock()
2125 if opens > 10 {
2126 t.Logf("open calls = %d", opens)
2127 t.Logf("close calls = %d", closes)
2128 t.Errorf("db connections opened = %d; want <= 10", opens)
2129 db.dumpDeps(t)
2132 if err := stmt.Close(); err != nil {
2133 t.Fatal(err)
2136 if g, w := db.numFreeConns(), 10; g != w {
2137 t.Errorf("free conns = %d; want %d", g, w)
2140 if n := db.numDepsPoll(t, 10); n > 10 {
2141 t.Errorf("number of dependencies = %d; expected <= 10", n)
2142 db.dumpDeps(t)
2145 db.SetMaxOpenConns(5)
2147 if g, w := db.numFreeConns(), 5; g != w {
2148 t.Errorf("free conns = %d; want %d", g, w)
2151 if n := db.numDepsPoll(t, 5); n > 5 {
2152 t.Errorf("number of dependencies = %d; expected 0", n)
2153 db.dumpDeps(t)
2156 db.SetMaxOpenConns(0)
2158 if g, w := db.numFreeConns(), 5; g != w {
2159 t.Errorf("free conns = %d; want %d", g, w)
2162 if n := db.numDepsPoll(t, 5); n > 5 {
2163 t.Errorf("number of dependencies = %d; expected 0", n)
2164 db.dumpDeps(t)
2167 db.clearAllConns(t)
2170 // Issue 9453: tests that SetMaxOpenConns can be lowered at runtime
2171 // and affects the subsequent release of connections.
2172 func TestMaxOpenConnsOnBusy(t *testing.T) {
2173 defer setHookpostCloseConn(nil)
2174 setHookpostCloseConn(func(_ *fakeConn, err error) {
2175 if err != nil {
2176 t.Errorf("Error closing fakeConn: %v", err)
2180 db := newTestDB(t, "magicquery")
2181 defer closeDB(t, db)
2183 db.SetMaxOpenConns(3)
2185 ctx := context.Background()
2187 conn0, err := db.conn(ctx, cachedOrNewConn)
2188 if err != nil {
2189 t.Fatalf("db open conn fail: %v", err)
2192 conn1, err := db.conn(ctx, cachedOrNewConn)
2193 if err != nil {
2194 t.Fatalf("db open conn fail: %v", err)
2197 conn2, err := db.conn(ctx, cachedOrNewConn)
2198 if err != nil {
2199 t.Fatalf("db open conn fail: %v", err)
2202 if g, w := db.numOpen, 3; g != w {
2203 t.Errorf("free conns = %d; want %d", g, w)
2206 db.SetMaxOpenConns(2)
2207 if g, w := db.numOpen, 3; g != w {
2208 t.Errorf("free conns = %d; want %d", g, w)
2211 conn0.releaseConn(nil)
2212 conn1.releaseConn(nil)
2213 if g, w := db.numOpen, 2; g != w {
2214 t.Errorf("free conns = %d; want %d", g, w)
2217 conn2.releaseConn(nil)
2218 if g, w := db.numOpen, 2; g != w {
2219 t.Errorf("free conns = %d; want %d", g, w)
2223 // Issue 10886: tests that all connection attempts return when more than
2224 // DB.maxOpen connections are in flight and the first DB.maxOpen fail.
2225 func TestPendingConnsAfterErr(t *testing.T) {
2226 const (
2227 maxOpen = 2
2228 tryOpen = maxOpen*2 + 2
2231 // No queries will be run.
2232 db, err := Open("test", fakeDBName)
2233 if err != nil {
2234 t.Fatalf("Open: %v", err)
2236 defer closeDB(t, db)
2237 defer func() {
2238 for k, v := range db.lastPut {
2239 t.Logf("%p: %v", k, v)
2243 db.SetMaxOpenConns(maxOpen)
2244 db.SetMaxIdleConns(0)
2246 errOffline := errors.New("db offline")
2248 defer func() { setHookOpenErr(nil) }()
2250 errs := make(chan error, tryOpen)
2252 var opening sync.WaitGroup
2253 opening.Add(tryOpen)
2255 setHookOpenErr(func() error {
2256 // Wait for all connections to enqueue.
2257 opening.Wait()
2258 return errOffline
2261 for i := 0; i < tryOpen; i++ {
2262 go func() {
2263 opening.Done() // signal one connection is in flight
2264 _, err := db.Exec("will never run")
2265 errs <- err
2269 opening.Wait() // wait for all workers to begin running
2271 const timeout = 5 * time.Second
2272 to := time.NewTimer(timeout)
2273 defer to.Stop()
2275 // check that all connections fail without deadlock
2276 for i := 0; i < tryOpen; i++ {
2277 select {
2278 case err := <-errs:
2279 if got, want := err, errOffline; got != want {
2280 t.Errorf("unexpected err: got %v, want %v", got, want)
2282 case <-to.C:
2283 t.Fatalf("orphaned connection request(s), still waiting after %v", timeout)
2287 // Wait a reasonable time for the database to close all connections.
2288 tick := time.NewTicker(3 * time.Millisecond)
2289 defer tick.Stop()
2290 for {
2291 select {
2292 case <-tick.C:
2293 db.mu.Lock()
2294 if db.numOpen == 0 {
2295 db.mu.Unlock()
2296 return
2298 db.mu.Unlock()
2299 case <-to.C:
2300 // Closing the database will check for numOpen and fail the test.
2301 return
2306 func TestSingleOpenConn(t *testing.T) {
2307 db := newTestDB(t, "people")
2308 defer closeDB(t, db)
2310 db.SetMaxOpenConns(1)
2312 rows, err := db.Query("SELECT|people|name|")
2313 if err != nil {
2314 t.Fatal(err)
2316 if err = rows.Close(); err != nil {
2317 t.Fatal(err)
2319 // shouldn't deadlock
2320 rows, err = db.Query("SELECT|people|name|")
2321 if err != nil {
2322 t.Fatal(err)
2324 if err = rows.Close(); err != nil {
2325 t.Fatal(err)
2329 func TestStats(t *testing.T) {
2330 db := newTestDB(t, "people")
2331 stats := db.Stats()
2332 if got := stats.OpenConnections; got != 1 {
2333 t.Errorf("stats.OpenConnections = %d; want 1", got)
2336 tx, err := db.Begin()
2337 if err != nil {
2338 t.Fatal(err)
2340 tx.Commit()
2342 closeDB(t, db)
2343 stats = db.Stats()
2344 if got := stats.OpenConnections; got != 0 {
2345 t.Errorf("stats.OpenConnections = %d; want 0", got)
2349 func TestConnMaxLifetime(t *testing.T) {
2350 t0 := time.Unix(1000000, 0)
2351 offset := time.Duration(0)
2353 nowFunc = func() time.Time { return t0.Add(offset) }
2354 defer func() { nowFunc = time.Now }()
2356 db := newTestDB(t, "magicquery")
2357 defer closeDB(t, db)
2359 driver := db.Driver().(*fakeDriver)
2361 // Force the number of open connections to 0 so we can get an accurate
2362 // count for the test
2363 db.clearAllConns(t)
2365 driver.mu.Lock()
2366 opens0 := driver.openCount
2367 closes0 := driver.closeCount
2368 driver.mu.Unlock()
2370 db.SetMaxIdleConns(10)
2371 db.SetMaxOpenConns(10)
2373 tx, err := db.Begin()
2374 if err != nil {
2375 t.Fatal(err)
2378 offset = time.Second
2379 tx2, err := db.Begin()
2380 if err != nil {
2381 t.Fatal(err)
2384 tx.Commit()
2385 tx2.Commit()
2387 driver.mu.Lock()
2388 opens := driver.openCount - opens0
2389 closes := driver.closeCount - closes0
2390 driver.mu.Unlock()
2392 if opens != 2 {
2393 t.Errorf("opens = %d; want 2", opens)
2395 if closes != 0 {
2396 t.Errorf("closes = %d; want 0", closes)
2398 if g, w := db.numFreeConns(), 2; g != w {
2399 t.Errorf("free conns = %d; want %d", g, w)
2402 // Expire first conn
2403 offset = 11 * time.Second
2404 db.SetConnMaxLifetime(10 * time.Second)
2405 if err != nil {
2406 t.Fatal(err)
2409 tx, err = db.Begin()
2410 if err != nil {
2411 t.Fatal(err)
2413 tx2, err = db.Begin()
2414 if err != nil {
2415 t.Fatal(err)
2417 tx.Commit()
2418 tx2.Commit()
2420 // Give connectionCleaner chance to run.
2421 waitCondition(t, func() bool {
2422 driver.mu.Lock()
2423 opens = driver.openCount - opens0
2424 closes = driver.closeCount - closes0
2425 driver.mu.Unlock()
2427 return closes == 1
2430 if opens != 3 {
2431 t.Errorf("opens = %d; want 3", opens)
2433 if closes != 1 {
2434 t.Errorf("closes = %d; want 1", closes)
2437 if s := db.Stats(); s.MaxLifetimeClosed != 1 {
2438 t.Errorf("MaxLifetimeClosed = %d; want 1 %#v", s.MaxLifetimeClosed, s)
2442 // golang.org/issue/5323
2443 func TestStmtCloseDeps(t *testing.T) {
2444 if testing.Short() {
2445 t.Skip("skipping in short mode")
2447 defer setHookpostCloseConn(nil)
2448 setHookpostCloseConn(func(_ *fakeConn, err error) {
2449 if err != nil {
2450 t.Errorf("Error closing fakeConn: %v", err)
2454 db := newTestDB(t, "magicquery")
2455 defer closeDB(t, db)
2457 driver := db.Driver().(*fakeDriver)
2459 driver.mu.Lock()
2460 opens0 := driver.openCount
2461 closes0 := driver.closeCount
2462 driver.mu.Unlock()
2463 openDelta0 := opens0 - closes0
2465 stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?")
2466 if err != nil {
2467 t.Fatal(err)
2470 // Start 50 parallel slow queries.
2471 const (
2472 nquery = 50
2473 sleepMillis = 25
2474 nbatch = 2
2476 var wg sync.WaitGroup
2477 for batch := 0; batch < nbatch; batch++ {
2478 for i := 0; i < nquery; i++ {
2479 wg.Add(1)
2480 go func() {
2481 defer wg.Done()
2482 var op string
2483 if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows {
2484 t.Error(err)
2488 // Wait for the batch of queries above to finish before starting the next round.
2489 wg.Wait()
2492 if g, w := db.numFreeConns(), 2; g != w {
2493 t.Errorf("free conns = %d; want %d", g, w)
2496 if n := db.numDepsPoll(t, 4); n > 4 {
2497 t.Errorf("number of dependencies = %d; expected <= 4", n)
2498 db.dumpDeps(t)
2501 driver.mu.Lock()
2502 opens := driver.openCount - opens0
2503 closes := driver.closeCount - closes0
2504 openDelta := (driver.openCount - driver.closeCount) - openDelta0
2505 driver.mu.Unlock()
2507 if openDelta > 2 {
2508 t.Logf("open calls = %d", opens)
2509 t.Logf("close calls = %d", closes)
2510 t.Logf("open delta = %d", openDelta)
2511 t.Errorf("db connections opened = %d; want <= 2", openDelta)
2512 db.dumpDeps(t)
2515 if !waitCondition(t, func() bool {
2516 return len(stmt.css) <= nquery
2517 }) {
2518 t.Errorf("len(stmt.css) = %d; want <= %d", len(stmt.css), nquery)
2521 if err := stmt.Close(); err != nil {
2522 t.Fatal(err)
2525 if g, w := db.numFreeConns(), 2; g != w {
2526 t.Errorf("free conns = %d; want %d", g, w)
2529 if n := db.numDepsPoll(t, 2); n > 2 {
2530 t.Errorf("number of dependencies = %d; expected <= 2", n)
2531 db.dumpDeps(t)
2534 db.clearAllConns(t)
2537 // golang.org/issue/5046
2538 func TestCloseConnBeforeStmts(t *testing.T) {
2539 db := newTestDB(t, "people")
2540 defer closeDB(t, db)
2542 defer setHookpostCloseConn(nil)
2543 setHookpostCloseConn(func(_ *fakeConn, err error) {
2544 if err != nil {
2545 t.Errorf("Error closing fakeConn: %v; from %s", err, stack())
2546 db.dumpDeps(t)
2547 t.Errorf("DB = %#v", db)
2551 stmt, err := db.Prepare("SELECT|people|name|")
2552 if err != nil {
2553 t.Fatal(err)
2556 if len(db.freeConn) != 1 {
2557 t.Fatalf("expected 1 freeConn; got %d", len(db.freeConn))
2559 dc := db.freeConn[0]
2560 if dc.closed {
2561 t.Errorf("conn shouldn't be closed")
2564 if n := len(dc.openStmt); n != 1 {
2565 t.Errorf("driverConn num openStmt = %d; want 1", n)
2567 err = db.Close()
2568 if err != nil {
2569 t.Errorf("db Close = %v", err)
2571 if !dc.closed {
2572 t.Errorf("after db.Close, driverConn should be closed")
2574 if n := len(dc.openStmt); n != 0 {
2575 t.Errorf("driverConn num openStmt = %d; want 0", n)
2578 err = stmt.Close()
2579 if err != nil {
2580 t.Errorf("Stmt close = %v", err)
2583 if !dc.closed {
2584 t.Errorf("conn should be closed")
2586 if dc.ci != nil {
2587 t.Errorf("after Stmt Close, driverConn's Conn interface should be nil")
2591 // golang.org/issue/5283: don't release the Rows' connection in Close
2592 // before calling Stmt.Close.
2593 func TestRowsCloseOrder(t *testing.T) {
2594 db := newTestDB(t, "people")
2595 defer closeDB(t, db)
2597 db.SetMaxIdleConns(0)
2598 setStrictFakeConnClose(t)
2599 defer setStrictFakeConnClose(nil)
2601 rows, err := db.Query("SELECT|people|age,name|")
2602 if err != nil {
2603 t.Fatal(err)
2605 err = rows.Close()
2606 if err != nil {
2607 t.Fatal(err)
2611 func TestRowsImplicitClose(t *testing.T) {
2612 db := newTestDB(t, "people")
2613 defer closeDB(t, db)
2615 rows, err := db.Query("SELECT|people|age,name|")
2616 if err != nil {
2617 t.Fatal(err)
2620 want, fail := 2, errors.New("fail")
2621 r := rows.rowsi.(*rowsCursor)
2622 r.errPos, r.err = want, fail
2624 got := 0
2625 for rows.Next() {
2626 got++
2628 if got != want {
2629 t.Errorf("got %d rows, want %d", got, want)
2631 if err := rows.Err(); err != fail {
2632 t.Errorf("got error %v, want %v", err, fail)
2634 if !r.closed {
2635 t.Errorf("r.closed is false, want true")
2639 func TestStmtCloseOrder(t *testing.T) {
2640 db := newTestDB(t, "people")
2641 defer closeDB(t, db)
2643 db.SetMaxIdleConns(0)
2644 setStrictFakeConnClose(t)
2645 defer setStrictFakeConnClose(nil)
2647 _, err := db.Query("SELECT|non_existent|name|")
2648 if err == nil {
2649 t.Fatal("Querying non-existent table should fail")
2653 // Test cases where there's more than maxBadConnRetries bad connections in the
2654 // pool (issue 8834)
2655 func TestManyErrBadConn(t *testing.T) {
2656 manyErrBadConnSetup := func(first ...func(db *DB)) *DB {
2657 db := newTestDB(t, "people")
2659 for _, f := range first {
2660 f(db)
2663 nconn := maxBadConnRetries + 1
2664 db.SetMaxIdleConns(nconn)
2665 db.SetMaxOpenConns(nconn)
2666 // open enough connections
2667 func() {
2668 for i := 0; i < nconn; i++ {
2669 rows, err := db.Query("SELECT|people|age,name|")
2670 if err != nil {
2671 t.Fatal(err)
2673 defer rows.Close()
2677 db.mu.Lock()
2678 defer db.mu.Unlock()
2679 if db.numOpen != nconn {
2680 t.Fatalf("unexpected numOpen %d (was expecting %d)", db.numOpen, nconn)
2681 } else if len(db.freeConn) != nconn {
2682 t.Fatalf("unexpected len(db.freeConn) %d (was expecting %d)", len(db.freeConn), nconn)
2684 for _, conn := range db.freeConn {
2685 conn.Lock()
2686 conn.ci.(*fakeConn).stickyBad = true
2687 conn.Unlock()
2689 return db
2692 // Query
2693 db := manyErrBadConnSetup()
2694 defer closeDB(t, db)
2695 rows, err := db.Query("SELECT|people|age,name|")
2696 if err != nil {
2697 t.Fatal(err)
2699 if err = rows.Close(); err != nil {
2700 t.Fatal(err)
2703 // Exec
2704 db = manyErrBadConnSetup()
2705 defer closeDB(t, db)
2706 _, err = db.Exec("INSERT|people|name=Julia,age=19")
2707 if err != nil {
2708 t.Fatal(err)
2711 // Begin
2712 db = manyErrBadConnSetup()
2713 defer closeDB(t, db)
2714 tx, err := db.Begin()
2715 if err != nil {
2716 t.Fatal(err)
2718 if err = tx.Rollback(); err != nil {
2719 t.Fatal(err)
2722 // Prepare
2723 db = manyErrBadConnSetup()
2724 defer closeDB(t, db)
2725 stmt, err := db.Prepare("SELECT|people|age,name|")
2726 if err != nil {
2727 t.Fatal(err)
2729 if err = stmt.Close(); err != nil {
2730 t.Fatal(err)
2733 // Stmt.Exec
2734 db = manyErrBadConnSetup(func(db *DB) {
2735 stmt, err = db.Prepare("INSERT|people|name=Julia,age=19")
2736 if err != nil {
2737 t.Fatal(err)
2740 defer closeDB(t, db)
2741 _, err = stmt.Exec()
2742 if err != nil {
2743 t.Fatal(err)
2745 if err = stmt.Close(); err != nil {
2746 t.Fatal(err)
2749 // Stmt.Query
2750 db = manyErrBadConnSetup(func(db *DB) {
2751 stmt, err = db.Prepare("SELECT|people|age,name|")
2752 if err != nil {
2753 t.Fatal(err)
2756 defer closeDB(t, db)
2757 rows, err = stmt.Query()
2758 if err != nil {
2759 t.Fatal(err)
2761 if err = rows.Close(); err != nil {
2762 t.Fatal(err)
2764 if err = stmt.Close(); err != nil {
2765 t.Fatal(err)
2768 // Conn
2769 db = manyErrBadConnSetup()
2770 defer closeDB(t, db)
2771 ctx, cancel := context.WithCancel(context.Background())
2772 defer cancel()
2773 conn, err := db.Conn(ctx)
2774 if err != nil {
2775 t.Fatal(err)
2777 conn.dc.ci.(*fakeConn).skipDirtySession = true
2778 err = conn.Close()
2779 if err != nil {
2780 t.Fatal(err)
2783 // Ping
2784 db = manyErrBadConnSetup()
2785 defer closeDB(t, db)
2786 err = db.PingContext(ctx)
2787 if err != nil {
2788 t.Fatal(err)
2792 // Issue 34775: Ensure that a Tx cannot commit after a rollback.
2793 func TestTxCannotCommitAfterRollback(t *testing.T) {
2794 db := newTestDB(t, "tx_status")
2795 defer closeDB(t, db)
2797 // First check query reporting is correct.
2798 var txStatus string
2799 err := db.QueryRow("SELECT|tx_status|tx_status|").Scan(&txStatus)
2800 if err != nil {
2801 t.Fatal(err)
2803 if g, w := txStatus, "autocommit"; g != w {
2804 t.Fatalf("tx_status=%q, wanted %q", g, w)
2807 ctx, cancel := context.WithCancel(context.Background())
2808 defer cancel()
2810 tx, err := db.BeginTx(ctx, nil)
2811 if err != nil {
2812 t.Fatal(err)
2815 // Ignore dirty session for this test.
2816 // A failing test should trigger the dirty session flag as well,
2817 // but that isn't exactly what this should test for.
2818 tx.txi.(*fakeTx).c.skipDirtySession = true
2820 defer tx.Rollback()
2822 err = tx.QueryRow("SELECT|tx_status|tx_status|").Scan(&txStatus)
2823 if err != nil {
2824 t.Fatal(err)
2826 if g, w := txStatus, "transaction"; g != w {
2827 t.Fatalf("tx_status=%q, wanted %q", g, w)
2830 // 1. Begin a transaction.
2831 // 2. (A) Start a query, (B) begin Tx rollback through a ctx cancel.
2832 // 3. Check if 2.A has committed in Tx (pass) or outside of Tx (fail).
2833 sendQuery := make(chan struct{})
2834 // The Tx status is returned through the row results, ensure
2835 // that the rows results are not canceled.
2836 bypassRowsAwaitDone = true
2837 hookTxGrabConn = func() {
2838 cancel()
2839 <-sendQuery
2841 rollbackHook = func() {
2842 close(sendQuery)
2844 defer func() {
2845 hookTxGrabConn = nil
2846 rollbackHook = nil
2847 bypassRowsAwaitDone = false
2850 err = tx.QueryRow("SELECT|tx_status|tx_status|").Scan(&txStatus)
2851 if err != nil {
2852 // A failure here would be expected if skipDirtySession was not set to true above.
2853 t.Fatal(err)
2855 if g, w := txStatus, "transaction"; g != w {
2856 t.Fatalf("tx_status=%q, wanted %q", g, w)
2860 // Issue 40985 transaction statement deadlock while context cancel.
2861 func TestTxStmtDeadlock(t *testing.T) {
2862 db := newTestDB(t, "people")
2863 defer closeDB(t, db)
2865 ctx, cancel := context.WithCancel(context.Background())
2866 defer cancel()
2867 tx, err := db.BeginTx(ctx, nil)
2868 if err != nil {
2869 t.Fatal(err)
2872 stmt, err := tx.Prepare("SELECT|people|name,age|age=?")
2873 if err != nil {
2874 t.Fatal(err)
2876 cancel()
2877 // Run number of stmt queries to reproduce deadlock from context cancel
2878 for i := 0; i < 1e3; i++ {
2879 // Encounter any close related errors (e.g. ErrTxDone, stmt is closed)
2880 // is expected due to context cancel.
2881 _, err = stmt.Query(1)
2882 if err != nil {
2883 break
2886 _ = tx.Rollback()
2889 // Issue32530 encounters an issue where a connection may
2890 // expire right after it comes out of a used connection pool
2891 // even when a new connection is requested.
2892 func TestConnExpiresFreshOutOfPool(t *testing.T) {
2893 execCases := []struct {
2894 expired bool
2895 badReset bool
2897 {false, false},
2898 {true, false},
2899 {false, true},
2902 t0 := time.Unix(1000000, 0)
2903 offset := time.Duration(0)
2904 offsetMu := sync.RWMutex{}
2906 nowFunc = func() time.Time {
2907 offsetMu.RLock()
2908 defer offsetMu.RUnlock()
2909 return t0.Add(offset)
2911 defer func() { nowFunc = time.Now }()
2913 ctx, cancel := context.WithCancel(context.Background())
2914 defer cancel()
2916 db := newTestDB(t, "magicquery")
2917 defer closeDB(t, db)
2919 db.SetMaxOpenConns(1)
2921 for _, ec := range execCases {
2922 ec := ec
2923 name := fmt.Sprintf("expired=%t,badReset=%t", ec.expired, ec.badReset)
2924 t.Run(name, func(t *testing.T) {
2925 db.clearAllConns(t)
2927 db.SetMaxIdleConns(1)
2928 db.SetConnMaxLifetime(10 * time.Second)
2930 conn, err := db.conn(ctx, alwaysNewConn)
2931 if err != nil {
2932 t.Fatal(err)
2935 afterPutConn := make(chan struct{})
2936 waitingForConn := make(chan struct{})
2938 go func() {
2939 defer close(afterPutConn)
2941 conn, err := db.conn(ctx, alwaysNewConn)
2942 if err == nil {
2943 db.putConn(conn, err, false)
2944 } else {
2945 t.Errorf("db.conn: %v", err)
2948 go func() {
2949 defer close(waitingForConn)
2951 for {
2952 if t.Failed() {
2953 return
2955 db.mu.Lock()
2956 ct := len(db.connRequests)
2957 db.mu.Unlock()
2958 if ct > 0 {
2959 return
2961 time.Sleep(pollDuration)
2965 <-waitingForConn
2967 if t.Failed() {
2968 return
2971 offsetMu.Lock()
2972 if ec.expired {
2973 offset = 11 * time.Second
2974 } else {
2975 offset = time.Duration(0)
2977 offsetMu.Unlock()
2979 conn.ci.(*fakeConn).stickyBad = ec.badReset
2981 db.putConn(conn, err, true)
2983 <-afterPutConn
2988 // TestIssue20575 ensures the Rows from query does not block
2989 // closing a transaction. Ensure Rows is closed while closing a trasaction.
2990 func TestIssue20575(t *testing.T) {
2991 db := newTestDB(t, "people")
2992 defer closeDB(t, db)
2994 tx, err := db.Begin()
2995 if err != nil {
2996 t.Fatal(err)
2998 ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
2999 defer cancel()
3000 _, err = tx.QueryContext(ctx, "SELECT|people|age,name|")
3001 if err != nil {
3002 t.Fatal(err)
3004 // Do not close Rows from QueryContext.
3005 err = tx.Rollback()
3006 if err != nil {
3007 t.Fatal(err)
3009 select {
3010 default:
3011 case <-ctx.Done():
3012 t.Fatal("timeout: failed to rollback query without closing rows:", ctx.Err())
3016 // TestIssue20622 tests closing the transaction before rows is closed, requires
3017 // the race detector to fail.
3018 func TestIssue20622(t *testing.T) {
3019 db := newTestDB(t, "people")
3020 defer closeDB(t, db)
3022 ctx, cancel := context.WithCancel(context.Background())
3023 defer cancel()
3025 tx, err := db.BeginTx(ctx, nil)
3026 if err != nil {
3027 t.Fatal(err)
3030 rows, err := tx.Query("SELECT|people|age,name|")
3031 if err != nil {
3032 t.Fatal(err)
3035 count := 0
3036 for rows.Next() {
3037 count++
3038 var age int
3039 var name string
3040 if err := rows.Scan(&age, &name); err != nil {
3041 t.Fatal("scan failed", err)
3044 if count == 1 {
3045 cancel()
3047 time.Sleep(100 * time.Millisecond)
3049 rows.Close()
3050 tx.Commit()
3053 // golang.org/issue/5718
3054 func TestErrBadConnReconnect(t *testing.T) {
3055 db := newTestDB(t, "foo")
3056 defer closeDB(t, db)
3057 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
3059 simulateBadConn := func(name string, hook *func() bool, op func() error) {
3060 broken, retried := false, false
3061 numOpen := db.numOpen
3063 // simulate a broken connection on the first try
3064 *hook = func() bool {
3065 if !broken {
3066 broken = true
3067 return true
3069 retried = true
3070 return false
3073 if err := op(); err != nil {
3074 t.Errorf(name+": %v", err)
3075 return
3078 if !broken || !retried {
3079 t.Error(name + ": Failed to simulate broken connection")
3081 *hook = nil
3083 if numOpen != db.numOpen {
3084 t.Errorf(name+": leaked %d connection(s)!", db.numOpen-numOpen)
3085 numOpen = db.numOpen
3089 // db.Exec
3090 dbExec := func() error {
3091 _, err := db.Exec("INSERT|t1|name=?,age=?,dead=?", "Gordon", 3, true)
3092 return err
3094 simulateBadConn("db.Exec prepare", &hookPrepareBadConn, dbExec)
3095 simulateBadConn("db.Exec exec", &hookExecBadConn, dbExec)
3097 // db.Query
3098 dbQuery := func() error {
3099 rows, err := db.Query("SELECT|t1|age,name|")
3100 if err == nil {
3101 err = rows.Close()
3103 return err
3105 simulateBadConn("db.Query prepare", &hookPrepareBadConn, dbQuery)
3106 simulateBadConn("db.Query query", &hookQueryBadConn, dbQuery)
3108 // db.Prepare
3109 simulateBadConn("db.Prepare", &hookPrepareBadConn, func() error {
3110 stmt, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?")
3111 if err != nil {
3112 return err
3114 stmt.Close()
3115 return nil
3118 // Provide a way to force a re-prepare of a statement on next execution
3119 forcePrepare := func(stmt *Stmt) {
3120 stmt.css = nil
3123 // stmt.Exec
3124 stmt1, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?")
3125 if err != nil {
3126 t.Fatalf("prepare: %v", err)
3128 defer stmt1.Close()
3129 // make sure we must prepare the stmt first
3130 forcePrepare(stmt1)
3132 stmtExec := func() error {
3133 _, err := stmt1.Exec("Gopher", 3, false)
3134 return err
3136 simulateBadConn("stmt.Exec prepare", &hookPrepareBadConn, stmtExec)
3137 simulateBadConn("stmt.Exec exec", &hookExecBadConn, stmtExec)
3139 // stmt.Query
3140 stmt2, err := db.Prepare("SELECT|t1|age,name|")
3141 if err != nil {
3142 t.Fatalf("prepare: %v", err)
3144 defer stmt2.Close()
3145 // make sure we must prepare the stmt first
3146 forcePrepare(stmt2)
3148 stmtQuery := func() error {
3149 rows, err := stmt2.Query()
3150 if err == nil {
3151 err = rows.Close()
3153 return err
3155 simulateBadConn("stmt.Query prepare", &hookPrepareBadConn, stmtQuery)
3156 simulateBadConn("stmt.Query exec", &hookQueryBadConn, stmtQuery)
3159 // golang.org/issue/11264
3160 func TestTxEndBadConn(t *testing.T) {
3161 db := newTestDB(t, "foo")
3162 defer closeDB(t, db)
3163 db.SetMaxIdleConns(0)
3164 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
3165 db.SetMaxIdleConns(1)
3167 simulateBadConn := func(name string, hook *func() bool, op func() error) {
3168 broken := false
3169 numOpen := db.numOpen
3171 *hook = func() bool {
3172 if !broken {
3173 broken = true
3175 return broken
3178 if err := op(); !errors.Is(err, driver.ErrBadConn) {
3179 t.Errorf(name+": %v", err)
3180 return
3183 if !broken {
3184 t.Error(name + ": Failed to simulate broken connection")
3186 *hook = nil
3188 if numOpen != db.numOpen {
3189 t.Errorf(name+": leaked %d connection(s)!", db.numOpen-numOpen)
3193 // db.Exec
3194 dbExec := func(endTx func(tx *Tx) error) func() error {
3195 return func() error {
3196 tx, err := db.Begin()
3197 if err != nil {
3198 return err
3200 _, err = tx.Exec("INSERT|t1|name=?,age=?,dead=?", "Gordon", 3, true)
3201 if err != nil {
3202 return err
3204 return endTx(tx)
3207 simulateBadConn("db.Tx.Exec commit", &hookCommitBadConn, dbExec((*Tx).Commit))
3208 simulateBadConn("db.Tx.Exec rollback", &hookRollbackBadConn, dbExec((*Tx).Rollback))
3210 // db.Query
3211 dbQuery := func(endTx func(tx *Tx) error) func() error {
3212 return func() error {
3213 tx, err := db.Begin()
3214 if err != nil {
3215 return err
3217 rows, err := tx.Query("SELECT|t1|age,name|")
3218 if err == nil {
3219 err = rows.Close()
3220 } else {
3221 return err
3223 return endTx(tx)
3226 simulateBadConn("db.Tx.Query commit", &hookCommitBadConn, dbQuery((*Tx).Commit))
3227 simulateBadConn("db.Tx.Query rollback", &hookRollbackBadConn, dbQuery((*Tx).Rollback))
3230 type concurrentTest interface {
3231 init(t testing.TB, db *DB)
3232 finish(t testing.TB)
3233 test(t testing.TB) error
3236 type concurrentDBQueryTest struct {
3237 db *DB
3240 func (c *concurrentDBQueryTest) init(t testing.TB, db *DB) {
3241 c.db = db
3244 func (c *concurrentDBQueryTest) finish(t testing.TB) {
3245 c.db = nil
3248 func (c *concurrentDBQueryTest) test(t testing.TB) error {
3249 rows, err := c.db.Query("SELECT|people|name|")
3250 if err != nil {
3251 t.Error(err)
3252 return err
3254 var name string
3255 for rows.Next() {
3256 rows.Scan(&name)
3258 rows.Close()
3259 return nil
3262 type concurrentDBExecTest struct {
3263 db *DB
3266 func (c *concurrentDBExecTest) init(t testing.TB, db *DB) {
3267 c.db = db
3270 func (c *concurrentDBExecTest) finish(t testing.TB) {
3271 c.db = nil
3274 func (c *concurrentDBExecTest) test(t testing.TB) error {
3275 _, err := c.db.Exec("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
3276 if err != nil {
3277 t.Error(err)
3278 return err
3280 return nil
3283 type concurrentStmtQueryTest struct {
3284 db *DB
3285 stmt *Stmt
3288 func (c *concurrentStmtQueryTest) init(t testing.TB, db *DB) {
3289 c.db = db
3290 var err error
3291 c.stmt, err = db.Prepare("SELECT|people|name|")
3292 if err != nil {
3293 t.Fatal(err)
3297 func (c *concurrentStmtQueryTest) finish(t testing.TB) {
3298 if c.stmt != nil {
3299 c.stmt.Close()
3300 c.stmt = nil
3302 c.db = nil
3305 func (c *concurrentStmtQueryTest) test(t testing.TB) error {
3306 rows, err := c.stmt.Query()
3307 if err != nil {
3308 t.Errorf("error on query: %v", err)
3309 return err
3312 var name string
3313 for rows.Next() {
3314 rows.Scan(&name)
3316 rows.Close()
3317 return nil
3320 type concurrentStmtExecTest struct {
3321 db *DB
3322 stmt *Stmt
3325 func (c *concurrentStmtExecTest) init(t testing.TB, db *DB) {
3326 c.db = db
3327 var err error
3328 c.stmt, err = db.Prepare("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?")
3329 if err != nil {
3330 t.Fatal(err)
3334 func (c *concurrentStmtExecTest) finish(t testing.TB) {
3335 if c.stmt != nil {
3336 c.stmt.Close()
3337 c.stmt = nil
3339 c.db = nil
3342 func (c *concurrentStmtExecTest) test(t testing.TB) error {
3343 _, err := c.stmt.Exec(3, chrisBirthday)
3344 if err != nil {
3345 t.Errorf("error on exec: %v", err)
3346 return err
3348 return nil
3351 type concurrentTxQueryTest struct {
3352 db *DB
3353 tx *Tx
3356 func (c *concurrentTxQueryTest) init(t testing.TB, db *DB) {
3357 c.db = db
3358 var err error
3359 c.tx, err = c.db.Begin()
3360 if err != nil {
3361 t.Fatal(err)
3365 func (c *concurrentTxQueryTest) finish(t testing.TB) {
3366 if c.tx != nil {
3367 c.tx.Rollback()
3368 c.tx = nil
3370 c.db = nil
3373 func (c *concurrentTxQueryTest) test(t testing.TB) error {
3374 rows, err := c.db.Query("SELECT|people|name|")
3375 if err != nil {
3376 t.Error(err)
3377 return err
3379 var name string
3380 for rows.Next() {
3381 rows.Scan(&name)
3383 rows.Close()
3384 return nil
3387 type concurrentTxExecTest struct {
3388 db *DB
3389 tx *Tx
3392 func (c *concurrentTxExecTest) init(t testing.TB, db *DB) {
3393 c.db = db
3394 var err error
3395 c.tx, err = c.db.Begin()
3396 if err != nil {
3397 t.Fatal(err)
3401 func (c *concurrentTxExecTest) finish(t testing.TB) {
3402 if c.tx != nil {
3403 c.tx.Rollback()
3404 c.tx = nil
3406 c.db = nil
3409 func (c *concurrentTxExecTest) test(t testing.TB) error {
3410 _, err := c.tx.Exec("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
3411 if err != nil {
3412 t.Error(err)
3413 return err
3415 return nil
3418 type concurrentTxStmtQueryTest struct {
3419 db *DB
3420 tx *Tx
3421 stmt *Stmt
3424 func (c *concurrentTxStmtQueryTest) init(t testing.TB, db *DB) {
3425 c.db = db
3426 var err error
3427 c.tx, err = c.db.Begin()
3428 if err != nil {
3429 t.Fatal(err)
3431 c.stmt, err = c.tx.Prepare("SELECT|people|name|")
3432 if err != nil {
3433 t.Fatal(err)
3437 func (c *concurrentTxStmtQueryTest) finish(t testing.TB) {
3438 if c.stmt != nil {
3439 c.stmt.Close()
3440 c.stmt = nil
3442 if c.tx != nil {
3443 c.tx.Rollback()
3444 c.tx = nil
3446 c.db = nil
3449 func (c *concurrentTxStmtQueryTest) test(t testing.TB) error {
3450 rows, err := c.stmt.Query()
3451 if err != nil {
3452 t.Errorf("error on query: %v", err)
3453 return err
3456 var name string
3457 for rows.Next() {
3458 rows.Scan(&name)
3460 rows.Close()
3461 return nil
3464 type concurrentTxStmtExecTest struct {
3465 db *DB
3466 tx *Tx
3467 stmt *Stmt
3470 func (c *concurrentTxStmtExecTest) init(t testing.TB, db *DB) {
3471 c.db = db
3472 var err error
3473 c.tx, err = c.db.Begin()
3474 if err != nil {
3475 t.Fatal(err)
3477 c.stmt, err = c.tx.Prepare("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?")
3478 if err != nil {
3479 t.Fatal(err)
3483 func (c *concurrentTxStmtExecTest) finish(t testing.TB) {
3484 if c.stmt != nil {
3485 c.stmt.Close()
3486 c.stmt = nil
3488 if c.tx != nil {
3489 c.tx.Rollback()
3490 c.tx = nil
3492 c.db = nil
3495 func (c *concurrentTxStmtExecTest) test(t testing.TB) error {
3496 _, err := c.stmt.Exec(3, chrisBirthday)
3497 if err != nil {
3498 t.Errorf("error on exec: %v", err)
3499 return err
3501 return nil
3504 type concurrentRandomTest struct {
3505 tests []concurrentTest
3508 func (c *concurrentRandomTest) init(t testing.TB, db *DB) {
3509 c.tests = []concurrentTest{
3510 new(concurrentDBQueryTest),
3511 new(concurrentDBExecTest),
3512 new(concurrentStmtQueryTest),
3513 new(concurrentStmtExecTest),
3514 new(concurrentTxQueryTest),
3515 new(concurrentTxExecTest),
3516 new(concurrentTxStmtQueryTest),
3517 new(concurrentTxStmtExecTest),
3519 for _, ct := range c.tests {
3520 ct.init(t, db)
3524 func (c *concurrentRandomTest) finish(t testing.TB) {
3525 for _, ct := range c.tests {
3526 ct.finish(t)
3530 func (c *concurrentRandomTest) test(t testing.TB) error {
3531 ct := c.tests[rand.Intn(len(c.tests))]
3532 return ct.test(t)
3535 func doConcurrentTest(t testing.TB, ct concurrentTest) {
3536 maxProcs, numReqs := 1, 500
3537 if testing.Short() {
3538 maxProcs, numReqs = 4, 50
3540 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
3542 db := newTestDB(t, "people")
3543 defer closeDB(t, db)
3545 ct.init(t, db)
3546 defer ct.finish(t)
3548 var wg sync.WaitGroup
3549 wg.Add(numReqs)
3551 reqs := make(chan bool)
3552 defer close(reqs)
3554 for i := 0; i < maxProcs*2; i++ {
3555 go func() {
3556 for range reqs {
3557 err := ct.test(t)
3558 if err != nil {
3559 wg.Done()
3560 continue
3562 wg.Done()
3567 for i := 0; i < numReqs; i++ {
3568 reqs <- true
3571 wg.Wait()
3574 func TestIssue6081(t *testing.T) {
3575 db := newTestDB(t, "people")
3576 defer closeDB(t, db)
3578 drv := db.Driver().(*fakeDriver)
3579 drv.mu.Lock()
3580 opens0 := drv.openCount
3581 closes0 := drv.closeCount
3582 drv.mu.Unlock()
3584 stmt, err := db.Prepare("SELECT|people|name|")
3585 if err != nil {
3586 t.Fatal(err)
3588 setRowsCloseHook(func(rows *Rows, err *error) {
3589 *err = driver.ErrBadConn
3591 defer setRowsCloseHook(nil)
3592 for i := 0; i < 10; i++ {
3593 rows, err := stmt.Query()
3594 if err != nil {
3595 t.Fatal(err)
3597 rows.Close()
3599 if n := len(stmt.css); n > 1 {
3600 t.Errorf("len(css slice) = %d; want <= 1", n)
3602 stmt.Close()
3603 if n := len(stmt.css); n != 0 {
3604 t.Errorf("len(css slice) after Close = %d; want 0", n)
3607 drv.mu.Lock()
3608 opens := drv.openCount - opens0
3609 closes := drv.closeCount - closes0
3610 drv.mu.Unlock()
3611 if opens < 9 {
3612 t.Errorf("opens = %d; want >= 9", opens)
3614 if closes < 9 {
3615 t.Errorf("closes = %d; want >= 9", closes)
3619 // TestIssue18429 attempts to stress rolling back the transaction from a
3620 // context cancel while simultaneously calling Tx.Rollback. Rolling back from a
3621 // context happens concurrently so tx.rollback and tx.Commit must guard against
3622 // double entry.
3624 // In the test, a context is canceled while the query is in process so
3625 // the internal rollback will run concurrently with the explicitly called
3626 // Tx.Rollback.
3628 // The addition of calling rows.Next also tests
3629 // Issue 21117.
3630 func TestIssue18429(t *testing.T) {
3631 db := newTestDB(t, "people")
3632 defer closeDB(t, db)
3634 ctx := context.Background()
3635 sem := make(chan bool, 20)
3636 var wg sync.WaitGroup
3638 const milliWait = 30
3640 for i := 0; i < 100; i++ {
3641 sem <- true
3642 wg.Add(1)
3643 go func() {
3644 defer func() {
3645 <-sem
3646 wg.Done()
3648 qwait := (time.Duration(rand.Intn(milliWait)) * time.Millisecond).String()
3650 ctx, cancel := context.WithTimeout(ctx, time.Duration(rand.Intn(milliWait))*time.Millisecond)
3651 defer cancel()
3653 tx, err := db.BeginTx(ctx, nil)
3654 if err != nil {
3655 return
3657 // This is expected to give a cancel error most, but not all the time.
3658 // Test failure will happen with a panic or other race condition being
3659 // reported.
3660 rows, _ := tx.QueryContext(ctx, "WAIT|"+qwait+"|SELECT|people|name|")
3661 if rows != nil {
3662 var name string
3663 // Call Next to test Issue 21117 and check for races.
3664 for rows.Next() {
3665 // Scan the buffer so it is read and checked for races.
3666 rows.Scan(&name)
3668 rows.Close()
3670 // This call will race with the context cancel rollback to complete
3671 // if the rollback itself isn't guarded.
3672 tx.Rollback()
3675 wg.Wait()
3678 // TestIssue20160 attempts to test a short context life on a stmt Query.
3679 func TestIssue20160(t *testing.T) {
3680 db := newTestDB(t, "people")
3681 defer closeDB(t, db)
3683 ctx := context.Background()
3684 sem := make(chan bool, 20)
3685 var wg sync.WaitGroup
3687 const milliWait = 30
3689 stmt, err := db.PrepareContext(ctx, "SELECT|people|name|")
3690 if err != nil {
3691 t.Fatal(err)
3693 defer stmt.Close()
3695 for i := 0; i < 100; i++ {
3696 sem <- true
3697 wg.Add(1)
3698 go func() {
3699 defer func() {
3700 <-sem
3701 wg.Done()
3703 ctx, cancel := context.WithTimeout(ctx, time.Duration(rand.Intn(milliWait))*time.Millisecond)
3704 defer cancel()
3706 // This is expected to give a cancel error most, but not all the time.
3707 // Test failure will happen with a panic or other race condition being
3708 // reported.
3709 rows, _ := stmt.QueryContext(ctx)
3710 if rows != nil {
3711 rows.Close()
3715 wg.Wait()
3718 // TestIssue18719 closes the context right before use. The sql.driverConn
3719 // will nil out the ci on close in a lock, but if another process uses it right after
3720 // it will panic with on the nil ref.
3722 // See https://golang.org/cl/35550 .
3723 func TestIssue18719(t *testing.T) {
3724 db := newTestDB(t, "people")
3725 defer closeDB(t, db)
3727 ctx, cancel := context.WithCancel(context.Background())
3728 defer cancel()
3730 tx, err := db.BeginTx(ctx, nil)
3731 if err != nil {
3732 t.Fatal(err)
3735 hookTxGrabConn = func() {
3736 cancel()
3738 // Wait for the context to cancel and tx to rollback.
3739 for tx.isDone() == false {
3740 time.Sleep(pollDuration)
3743 defer func() { hookTxGrabConn = nil }()
3745 // This call will grab the connection and cancel the context
3746 // after it has done so. Code after must deal with the canceled state.
3747 _, err = tx.QueryContext(ctx, "SELECT|people|name|")
3748 if err != nil {
3749 t.Fatalf("expected error %v but got %v", nil, err)
3752 // Rows may be ignored because it will be closed when the context is canceled.
3754 // Do not explicitly rollback. The rollback will happen from the
3755 // canceled context.
3757 cancel()
3760 func TestIssue20647(t *testing.T) {
3761 db := newTestDB(t, "people")
3762 defer closeDB(t, db)
3764 ctx, cancel := context.WithCancel(context.Background())
3765 defer cancel()
3767 conn, err := db.Conn(ctx)
3768 if err != nil {
3769 t.Fatal(err)
3771 conn.dc.ci.(*fakeConn).skipDirtySession = true
3772 defer conn.Close()
3774 stmt, err := conn.PrepareContext(ctx, "SELECT|people|name|")
3775 if err != nil {
3776 t.Fatal(err)
3778 defer stmt.Close()
3780 rows1, err := stmt.QueryContext(ctx)
3781 if err != nil {
3782 t.Fatal("rows1", err)
3784 defer rows1.Close()
3786 rows2, err := stmt.QueryContext(ctx)
3787 if err != nil {
3788 t.Fatal("rows2", err)
3790 defer rows2.Close()
3792 if rows1.dc != rows2.dc {
3793 t.Fatal("stmt prepared on Conn does not use same connection")
3797 func TestConcurrency(t *testing.T) {
3798 list := []struct {
3799 name string
3800 ct concurrentTest
3802 {"Query", new(concurrentDBQueryTest)},
3803 {"Exec", new(concurrentDBExecTest)},
3804 {"StmtQuery", new(concurrentStmtQueryTest)},
3805 {"StmtExec", new(concurrentStmtExecTest)},
3806 {"TxQuery", new(concurrentTxQueryTest)},
3807 {"TxExec", new(concurrentTxExecTest)},
3808 {"TxStmtQuery", new(concurrentTxStmtQueryTest)},
3809 {"TxStmtExec", new(concurrentTxStmtExecTest)},
3810 {"Random", new(concurrentRandomTest)},
3812 for _, item := range list {
3813 t.Run(item.name, func(t *testing.T) {
3814 doConcurrentTest(t, item.ct)
3819 func TestConnectionLeak(t *testing.T) {
3820 db := newTestDB(t, "people")
3821 defer closeDB(t, db)
3822 // Start by opening defaultMaxIdleConns
3823 rows := make([]*Rows, defaultMaxIdleConns)
3824 // We need to SetMaxOpenConns > MaxIdleConns, so the DB can open
3825 // a new connection and we can fill the idle queue with the released
3826 // connections.
3827 db.SetMaxOpenConns(len(rows) + 1)
3828 for ii := range rows {
3829 r, err := db.Query("SELECT|people|name|")
3830 if err != nil {
3831 t.Fatal(err)
3833 r.Next()
3834 if err := r.Err(); err != nil {
3835 t.Fatal(err)
3837 rows[ii] = r
3839 // Now we have defaultMaxIdleConns busy connections. Open
3840 // a new one, but wait until the busy connections are released
3841 // before returning control to DB.
3842 drv := db.Driver().(*fakeDriver)
3843 drv.waitCh = make(chan struct{}, 1)
3844 drv.waitingCh = make(chan struct{}, 1)
3845 var wg sync.WaitGroup
3846 wg.Add(1)
3847 go func() {
3848 r, err := db.Query("SELECT|people|name|")
3849 if err != nil {
3850 t.Error(err)
3851 return
3853 r.Close()
3854 wg.Done()
3856 // Wait until the goroutine we've just created has started waiting.
3857 <-drv.waitingCh
3858 // Now close the busy connections. This provides a connection for
3859 // the blocked goroutine and then fills up the idle queue.
3860 for _, v := range rows {
3861 v.Close()
3863 // At this point we give the new connection to DB. This connection is
3864 // now useless, since the idle queue is full and there are no pending
3865 // requests. DB should deal with this situation without leaking the
3866 // connection.
3867 drv.waitCh <- struct{}{}
3868 wg.Wait()
3871 func TestStatsMaxIdleClosedZero(t *testing.T) {
3872 db := newTestDB(t, "people")
3873 defer closeDB(t, db)
3875 db.SetMaxOpenConns(1)
3876 db.SetMaxIdleConns(1)
3877 db.SetConnMaxLifetime(0)
3879 preMaxIdleClosed := db.Stats().MaxIdleClosed
3881 for i := 0; i < 10; i++ {
3882 rows, err := db.Query("SELECT|people|name|")
3883 if err != nil {
3884 t.Fatal(err)
3886 rows.Close()
3889 st := db.Stats()
3890 maxIdleClosed := st.MaxIdleClosed - preMaxIdleClosed
3891 t.Logf("MaxIdleClosed: %d", maxIdleClosed)
3892 if maxIdleClosed != 0 {
3893 t.Fatal("expected 0 max idle closed conns, got: ", maxIdleClosed)
3897 func TestStatsMaxIdleClosedTen(t *testing.T) {
3898 db := newTestDB(t, "people")
3899 defer closeDB(t, db)
3901 db.SetMaxOpenConns(1)
3902 db.SetMaxIdleConns(0)
3903 db.SetConnMaxLifetime(0)
3905 preMaxIdleClosed := db.Stats().MaxIdleClosed
3907 for i := 0; i < 10; i++ {
3908 rows, err := db.Query("SELECT|people|name|")
3909 if err != nil {
3910 t.Fatal(err)
3912 rows.Close()
3915 st := db.Stats()
3916 maxIdleClosed := st.MaxIdleClosed - preMaxIdleClosed
3917 t.Logf("MaxIdleClosed: %d", maxIdleClosed)
3918 if maxIdleClosed != 10 {
3919 t.Fatal("expected 0 max idle closed conns, got: ", maxIdleClosed)
3923 // testUseConns uses count concurrent connections with 1 nanosecond apart.
3924 // Returns the returnedAt time of the final connection.
3925 func testUseConns(t *testing.T, count int, tm time.Time, db *DB) time.Time {
3926 conns := make([]*Conn, count)
3927 ctx := context.Background()
3928 for i := range conns {
3929 tm = tm.Add(time.Nanosecond)
3930 nowFunc = func() time.Time {
3931 return tm
3933 c, err := db.Conn(ctx)
3934 if err != nil {
3935 t.Error(err)
3937 conns[i] = c
3940 for i := len(conns) - 1; i >= 0; i-- {
3941 tm = tm.Add(time.Nanosecond)
3942 nowFunc = func() time.Time {
3943 return tm
3945 if err := conns[i].Close(); err != nil {
3946 t.Error(err)
3950 return tm
3953 func TestMaxIdleTime(t *testing.T) {
3954 usedConns := 5
3955 reusedConns := 2
3956 list := []struct {
3957 wantMaxIdleTime time.Duration
3958 wantMaxLifetime time.Duration
3959 wantNextCheck time.Duration
3960 wantIdleClosed int64
3961 wantMaxIdleClosed int64
3962 timeOffset time.Duration
3963 secondTimeOffset time.Duration
3966 time.Millisecond,
3968 time.Millisecond - time.Nanosecond,
3969 int64(usedConns - reusedConns),
3970 int64(usedConns - reusedConns),
3971 10 * time.Millisecond,
3975 // Want to close some connections via max idle time and one by max lifetime.
3976 time.Millisecond,
3977 // nowFunc() - MaxLifetime should be 1 * time.Nanosecond in connectionCleanerRunLocked.
3978 // This guarantees that first opened connection is to be closed.
3979 // Thus it is timeOffset + secondTimeOffset + 3 (+2 for Close while reusing conns and +1 for Conn).
3980 10*time.Millisecond + 100*time.Nanosecond + 3*time.Nanosecond,
3981 time.Nanosecond,
3982 // Closed all not reused connections and extra one by max lifetime.
3983 int64(usedConns - reusedConns + 1),
3984 int64(usedConns - reusedConns),
3985 10 * time.Millisecond,
3986 // Add second offset because otherwise connections are expired via max lifetime in Close.
3987 100 * time.Nanosecond,
3990 time.Hour,
3992 time.Second,
3995 10 * time.Millisecond,
3998 baseTime := time.Unix(0, 0)
3999 defer func() {
4000 nowFunc = time.Now
4002 for _, item := range list {
4003 nowFunc = func() time.Time {
4004 return baseTime
4006 t.Run(fmt.Sprintf("%v", item.wantMaxIdleTime), func(t *testing.T) {
4007 db := newTestDB(t, "people")
4008 defer closeDB(t, db)
4010 db.SetMaxOpenConns(usedConns)
4011 db.SetMaxIdleConns(usedConns)
4012 db.SetConnMaxIdleTime(item.wantMaxIdleTime)
4013 db.SetConnMaxLifetime(item.wantMaxLifetime)
4015 preMaxIdleClosed := db.Stats().MaxIdleTimeClosed
4017 // Busy usedConns.
4018 testUseConns(t, usedConns, baseTime, db)
4020 tm := baseTime.Add(item.timeOffset)
4022 // Reuse connections which should never be considered idle
4023 // and exercises the sorting for issue 39471.
4024 tm = testUseConns(t, reusedConns, tm, db)
4026 tm = tm.Add(item.secondTimeOffset)
4027 nowFunc = func() time.Time {
4028 return tm
4031 db.mu.Lock()
4032 nc, closing := db.connectionCleanerRunLocked(time.Second)
4033 if nc != item.wantNextCheck {
4034 t.Errorf("got %v; want %v next check duration", nc, item.wantNextCheck)
4037 // Validate freeConn order.
4038 var last time.Time
4039 for _, c := range db.freeConn {
4040 if last.After(c.returnedAt) {
4041 t.Error("freeConn is not ordered by returnedAt")
4042 break
4044 last = c.returnedAt
4047 db.mu.Unlock()
4048 for _, c := range closing {
4049 c.Close()
4051 if g, w := int64(len(closing)), item.wantIdleClosed; g != w {
4052 t.Errorf("got: %d; want %d closed conns", g, w)
4055 st := db.Stats()
4056 maxIdleClosed := st.MaxIdleTimeClosed - preMaxIdleClosed
4057 if g, w := maxIdleClosed, item.wantMaxIdleClosed; g != w {
4058 t.Errorf("got: %d; want %d max idle closed conns", g, w)
4064 type nvcDriver struct {
4065 fakeDriver
4066 skipNamedValueCheck bool
4069 func (d *nvcDriver) Open(dsn string) (driver.Conn, error) {
4070 c, err := d.fakeDriver.Open(dsn)
4071 fc := c.(*fakeConn)
4072 fc.db.allowAny = true
4073 return &nvcConn{fc, d.skipNamedValueCheck}, err
4076 type nvcConn struct {
4077 *fakeConn
4078 skipNamedValueCheck bool
4081 type decimalInt struct {
4082 value int
4085 type doNotInclude struct{}
4087 var _ driver.NamedValueChecker = &nvcConn{}
4089 func (c *nvcConn) CheckNamedValue(nv *driver.NamedValue) error {
4090 if c.skipNamedValueCheck {
4091 return driver.ErrSkip
4093 switch v := nv.Value.(type) {
4094 default:
4095 return driver.ErrSkip
4096 case Out:
4097 switch ov := v.Dest.(type) {
4098 default:
4099 return errors.New("unknown NameValueCheck OUTPUT type")
4100 case *string:
4101 *ov = "from-server"
4102 nv.Value = "OUT:*string"
4104 return nil
4105 case decimalInt, []int64:
4106 return nil
4107 case doNotInclude:
4108 return driver.ErrRemoveArgument
4112 func TestNamedValueChecker(t *testing.T) {
4113 Register("NamedValueCheck", &nvcDriver{})
4114 db, err := Open("NamedValueCheck", "")
4115 if err != nil {
4116 t.Fatal(err)
4118 defer db.Close()
4120 ctx, cancel := context.WithCancel(context.Background())
4121 defer cancel()
4123 _, err = db.ExecContext(ctx, "WIPE")
4124 if err != nil {
4125 t.Fatal("exec wipe", err)
4128 _, err = db.ExecContext(ctx, "CREATE|keys|dec1=any,str1=string,out1=string,array1=any")
4129 if err != nil {
4130 t.Fatal("exec create", err)
4133 o1 := ""
4134 _, err = db.ExecContext(ctx, "INSERT|keys|dec1=?A,str1=?,out1=?O1,array1=?", Named("A", decimalInt{123}), "hello", Named("O1", Out{Dest: &o1}), []int64{42, 128, 707}, doNotInclude{})
4135 if err != nil {
4136 t.Fatal("exec insert", err)
4138 var (
4139 str1 string
4140 dec1 decimalInt
4141 arr1 []int64
4143 err = db.QueryRowContext(ctx, "SELECT|keys|dec1,str1,array1|").Scan(&dec1, &str1, &arr1)
4144 if err != nil {
4145 t.Fatal("select", err)
4148 list := []struct{ got, want any }{
4149 {o1, "from-server"},
4150 {dec1, decimalInt{123}},
4151 {str1, "hello"},
4152 {arr1, []int64{42, 128, 707}},
4155 for index, item := range list {
4156 if !reflect.DeepEqual(item.got, item.want) {
4157 t.Errorf("got %#v wanted %#v for index %d", item.got, item.want, index)
4162 func TestNamedValueCheckerSkip(t *testing.T) {
4163 Register("NamedValueCheckSkip", &nvcDriver{skipNamedValueCheck: true})
4164 db, err := Open("NamedValueCheckSkip", "")
4165 if err != nil {
4166 t.Fatal(err)
4168 defer db.Close()
4170 ctx, cancel := context.WithCancel(context.Background())
4171 defer cancel()
4173 _, err = db.ExecContext(ctx, "WIPE")
4174 if err != nil {
4175 t.Fatal("exec wipe", err)
4178 _, err = db.ExecContext(ctx, "CREATE|keys|dec1=any")
4179 if err != nil {
4180 t.Fatal("exec create", err)
4183 _, err = db.ExecContext(ctx, "INSERT|keys|dec1=?A", Named("A", decimalInt{123}))
4184 if err == nil {
4185 t.Fatalf("expected error with bad argument, got %v", err)
4189 func TestOpenConnector(t *testing.T) {
4190 Register("testctx", &fakeDriverCtx{})
4191 db, err := Open("testctx", "people")
4192 if err != nil {
4193 t.Fatal(err)
4195 defer db.Close()
4197 c, ok := db.connector.(*fakeConnector)
4198 if !ok {
4199 t.Fatal("not using *fakeConnector")
4202 if err := db.Close(); err != nil {
4203 t.Fatal(err)
4206 if !c.closed {
4207 t.Fatal("connector is not closed")
4211 type ctxOnlyDriver struct {
4212 fakeDriver
4215 func (d *ctxOnlyDriver) Open(dsn string) (driver.Conn, error) {
4216 conn, err := d.fakeDriver.Open(dsn)
4217 if err != nil {
4218 return nil, err
4220 return &ctxOnlyConn{fc: conn.(*fakeConn)}, nil
4223 var (
4224 _ driver.Conn = &ctxOnlyConn{}
4225 _ driver.QueryerContext = &ctxOnlyConn{}
4226 _ driver.ExecerContext = &ctxOnlyConn{}
4229 type ctxOnlyConn struct {
4230 fc *fakeConn
4232 queryCtxCalled bool
4233 execCtxCalled bool
4236 func (c *ctxOnlyConn) Begin() (driver.Tx, error) {
4237 return c.fc.Begin()
4240 func (c *ctxOnlyConn) Close() error {
4241 return c.fc.Close()
4244 // Prepare is still part of the Conn interface, so while it isn't used
4245 // must be defined for compatibility.
4246 func (c *ctxOnlyConn) Prepare(q string) (driver.Stmt, error) {
4247 panic("not used")
4250 func (c *ctxOnlyConn) PrepareContext(ctx context.Context, q string) (driver.Stmt, error) {
4251 return c.fc.PrepareContext(ctx, q)
4254 func (c *ctxOnlyConn) QueryContext(ctx context.Context, q string, args []driver.NamedValue) (driver.Rows, error) {
4255 c.queryCtxCalled = true
4256 return c.fc.QueryContext(ctx, q, args)
4259 func (c *ctxOnlyConn) ExecContext(ctx context.Context, q string, args []driver.NamedValue) (driver.Result, error) {
4260 c.execCtxCalled = true
4261 return c.fc.ExecContext(ctx, q, args)
4264 // TestQueryExecContextOnly ensures drivers only need to implement QueryContext
4265 // and ExecContext methods.
4266 func TestQueryExecContextOnly(t *testing.T) {
4267 // Ensure connection does not implement non-context interfaces.
4268 var connType driver.Conn = &ctxOnlyConn{}
4269 if _, ok := connType.(driver.Execer); ok {
4270 t.Fatalf("%T must not implement driver.Execer", connType)
4272 if _, ok := connType.(driver.Queryer); ok {
4273 t.Fatalf("%T must not implement driver.Queryer", connType)
4276 Register("ContextOnly", &ctxOnlyDriver{})
4277 db, err := Open("ContextOnly", "")
4278 if err != nil {
4279 t.Fatal(err)
4281 defer db.Close()
4283 ctx, cancel := context.WithCancel(context.Background())
4284 defer cancel()
4286 conn, err := db.Conn(ctx)
4287 if err != nil {
4288 t.Fatal("db.Conn", err)
4290 defer conn.Close()
4291 coc := conn.dc.ci.(*ctxOnlyConn)
4292 coc.fc.skipDirtySession = true
4294 _, err = conn.ExecContext(ctx, "WIPE")
4295 if err != nil {
4296 t.Fatal("exec wipe", err)
4299 _, err = conn.ExecContext(ctx, "CREATE|keys|v1=string")
4300 if err != nil {
4301 t.Fatal("exec create", err)
4303 expectedValue := "value1"
4304 _, err = conn.ExecContext(ctx, "INSERT|keys|v1=?", expectedValue)
4305 if err != nil {
4306 t.Fatal("exec insert", err)
4308 rows, err := conn.QueryContext(ctx, "SELECT|keys|v1|")
4309 if err != nil {
4310 t.Fatal("query select", err)
4312 v1 := ""
4313 for rows.Next() {
4314 err = rows.Scan(&v1)
4315 if err != nil {
4316 t.Fatal("rows scan", err)
4319 rows.Close()
4321 if v1 != expectedValue {
4322 t.Fatalf("expected %q, got %q", expectedValue, v1)
4325 if !coc.execCtxCalled {
4326 t.Error("ExecContext not called")
4328 if !coc.queryCtxCalled {
4329 t.Error("QueryContext not called")
4333 type alwaysErrScanner struct{}
4335 var errTestScanWrap = errors.New("errTestScanWrap")
4337 func (alwaysErrScanner) Scan(any) error {
4338 return errTestScanWrap
4341 // Issue 38099: Ensure that Rows.Scan properly wraps underlying errors.
4342 func TestRowsScanProperlyWrapsErrors(t *testing.T) {
4343 db := newTestDB(t, "people")
4344 defer closeDB(t, db)
4346 rows, err := db.Query("SELECT|people|age|")
4347 if err != nil {
4348 t.Fatalf("Query: %v", err)
4351 var res alwaysErrScanner
4353 for rows.Next() {
4354 err = rows.Scan(&res)
4355 if err == nil {
4356 t.Fatal("expecting back an error")
4358 if !errors.Is(err, errTestScanWrap) {
4359 t.Fatalf("errors.Is mismatch\n%v\nWant: %v", err, errTestScanWrap)
4361 // Ensure that error substring matching still correctly works.
4362 if !strings.Contains(err.Error(), errTestScanWrap.Error()) {
4363 t.Fatalf("Error %v does not contain %v", err, errTestScanWrap)
4368 // badConn implements a bad driver.Conn, for TestBadDriver.
4369 // The Exec method panics.
4370 type badConn struct{}
4372 func (bc badConn) Prepare(query string) (driver.Stmt, error) {
4373 return nil, errors.New("badConn Prepare")
4376 func (bc badConn) Close() error {
4377 return nil
4380 func (bc badConn) Begin() (driver.Tx, error) {
4381 return nil, errors.New("badConn Begin")
4384 func (bc badConn) Exec(query string, args []driver.Value) (driver.Result, error) {
4385 panic("badConn.Exec")
4388 // badDriver is a driver.Driver that uses badConn.
4389 type badDriver struct{}
4391 func (bd badDriver) Open(name string) (driver.Conn, error) {
4392 return badConn{}, nil
4395 // Issue 15901.
4396 func TestBadDriver(t *testing.T) {
4397 Register("bad", badDriver{})
4398 db, err := Open("bad", "ignored")
4399 if err != nil {
4400 t.Fatal(err)
4402 defer func() {
4403 if r := recover(); r == nil {
4404 t.Error("expected panic")
4405 } else {
4406 if want := "badConn.Exec"; r.(string) != want {
4407 t.Errorf("panic was %v, expected %v", r, want)
4411 defer db.Close()
4412 db.Exec("ignored")
4415 type pingDriver struct {
4416 fails bool
4419 type pingConn struct {
4420 badConn
4421 driver *pingDriver
4424 var pingError = errors.New("Ping failed")
4426 func (pc pingConn) Ping(ctx context.Context) error {
4427 if pc.driver.fails {
4428 return pingError
4430 return nil
4433 var _ driver.Pinger = pingConn{}
4435 func (pd *pingDriver) Open(name string) (driver.Conn, error) {
4436 return pingConn{driver: pd}, nil
4439 func TestPing(t *testing.T) {
4440 driver := &pingDriver{}
4441 Register("ping", driver)
4443 db, err := Open("ping", "ignored")
4444 if err != nil {
4445 t.Fatal(err)
4448 if err := db.Ping(); err != nil {
4449 t.Errorf("err was %#v, expected nil", err)
4450 return
4453 driver.fails = true
4454 if err := db.Ping(); err != pingError {
4455 t.Errorf("err was %#v, expected pingError", err)
4459 // Issue 18101.
4460 func TestTypedString(t *testing.T) {
4461 db := newTestDB(t, "people")
4462 defer closeDB(t, db)
4464 type Str string
4465 var scanned Str
4467 err := db.QueryRow("SELECT|people|name|name=?", "Alice").Scan(&scanned)
4468 if err != nil {
4469 t.Fatal(err)
4471 expected := Str("Alice")
4472 if scanned != expected {
4473 t.Errorf("expected %+v, got %+v", expected, scanned)
4477 func BenchmarkConcurrentDBExec(b *testing.B) {
4478 b.ReportAllocs()
4479 ct := new(concurrentDBExecTest)
4480 for i := 0; i < b.N; i++ {
4481 doConcurrentTest(b, ct)
4485 func BenchmarkConcurrentStmtQuery(b *testing.B) {
4486 b.ReportAllocs()
4487 ct := new(concurrentStmtQueryTest)
4488 for i := 0; i < b.N; i++ {
4489 doConcurrentTest(b, ct)
4493 func BenchmarkConcurrentStmtExec(b *testing.B) {
4494 b.ReportAllocs()
4495 ct := new(concurrentStmtExecTest)
4496 for i := 0; i < b.N; i++ {
4497 doConcurrentTest(b, ct)
4501 func BenchmarkConcurrentTxQuery(b *testing.B) {
4502 b.ReportAllocs()
4503 ct := new(concurrentTxQueryTest)
4504 for i := 0; i < b.N; i++ {
4505 doConcurrentTest(b, ct)
4509 func BenchmarkConcurrentTxExec(b *testing.B) {
4510 b.ReportAllocs()
4511 ct := new(concurrentTxExecTest)
4512 for i := 0; i < b.N; i++ {
4513 doConcurrentTest(b, ct)
4517 func BenchmarkConcurrentTxStmtQuery(b *testing.B) {
4518 b.ReportAllocs()
4519 ct := new(concurrentTxStmtQueryTest)
4520 for i := 0; i < b.N; i++ {
4521 doConcurrentTest(b, ct)
4525 func BenchmarkConcurrentTxStmtExec(b *testing.B) {
4526 b.ReportAllocs()
4527 ct := new(concurrentTxStmtExecTest)
4528 for i := 0; i < b.N; i++ {
4529 doConcurrentTest(b, ct)
4533 func BenchmarkConcurrentRandom(b *testing.B) {
4534 b.ReportAllocs()
4535 ct := new(concurrentRandomTest)
4536 for i := 0; i < b.N; i++ {
4537 doConcurrentTest(b, ct)
4541 func BenchmarkManyConcurrentQueries(b *testing.B) {
4542 b.ReportAllocs()
4543 // To see lock contention in Go 1.4, 16~ cores and 128~ goroutines are required.
4544 const parallelism = 16
4546 db := newTestDB(b, "magicquery")
4547 defer closeDB(b, db)
4548 db.SetMaxIdleConns(runtime.GOMAXPROCS(0) * parallelism)
4550 stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?")
4551 if err != nil {
4552 b.Fatal(err)
4554 defer stmt.Close()
4556 b.SetParallelism(parallelism)
4557 b.RunParallel(func(pb *testing.PB) {
4558 for pb.Next() {
4559 rows, err := stmt.Query("sleep", 1)
4560 if err != nil {
4561 b.Error(err)
4562 return
4564 rows.Close()