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.
4
5package sql
6
7import (
8	"context"
9	"database/sql/driver"
10	"errors"
11	"fmt"
12	"internal/race"
13	"internal/testenv"
14	"math/rand"
15	"reflect"
16	"runtime"
17	"slices"
18	"strings"
19	"sync"
20	"sync/atomic"
21	"testing"
22	"time"
23)
24
25func init() {
26	type dbConn struct {
27		db *DB
28		c  *driverConn
29	}
30	freedFrom := make(map[dbConn]string)
31	var mu sync.Mutex
32	getFreedFrom := func(c dbConn) string {
33		mu.Lock()
34		defer mu.Unlock()
35		return freedFrom[c]
36	}
37	setFreedFrom := func(c dbConn, s string) {
38		mu.Lock()
39		defer mu.Unlock()
40		freedFrom[c] = s
41	}
42	putConnHook = func(db *DB, c *driverConn) {
43		if slices.Contains(db.freeConn, c) {
44			// print before panic, as panic may get lost due to conflicting panic
45			// (all goroutines asleep) elsewhere, since we might not unlock
46			// the mutex in freeConn here.
47			println("double free of conn. conflicts are:\nA) " + getFreedFrom(dbConn{db, c}) + "\n\nand\nB) " + stack())
48			panic("double free of conn.")
49		}
50		setFreedFrom(dbConn{db, c}, stack())
51	}
52}
53
54// pollDuration is an arbitrary interval to wait between checks when polling for
55// a condition to occur.
56const pollDuration = 5 * time.Millisecond
57
58const fakeDBName = "foo"
59
60var chrisBirthday = time.Unix(123456789, 0)
61
62func newTestDB(t testing.TB, name string) *DB {
63	return newTestDBConnector(t, &fakeConnector{name: fakeDBName}, name)
64}
65
66func newTestDBConnector(t testing.TB, fc *fakeConnector, name string) *DB {
67	fc.name = fakeDBName
68	db := OpenDB(fc)
69	if _, err := db.Exec("WIPE"); err != nil {
70		t.Fatalf("exec wipe: %v", err)
71	}
72	if name == "people" {
73		exec(t, db, "CREATE|people|name=string,age=int32,photo=blob,dead=bool,bdate=datetime")
74		exec(t, db, "INSERT|people|name=Alice,age=?,photo=APHOTO", 1)
75		exec(t, db, "INSERT|people|name=Bob,age=?,photo=BPHOTO", 2)
76		exec(t, db, "INSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
77	}
78	if name == "magicquery" {
79		// Magic table name and column, known by fakedb_test.go.
80		exec(t, db, "CREATE|magicquery|op=string,millis=int32")
81		exec(t, db, "INSERT|magicquery|op=sleep,millis=10")
82	}
83	if name == "tx_status" {
84		// Magic table name and column, known by fakedb_test.go.
85		exec(t, db, "CREATE|tx_status|tx_status=string")
86		exec(t, db, "INSERT|tx_status|tx_status=invalid")
87	}
88	return db
89}
90
91func TestOpenDB(t *testing.T) {
92	db := OpenDB(dsnConnector{dsn: fakeDBName, driver: fdriver})
93	if db.Driver() != fdriver {
94		t.Fatalf("OpenDB should return the driver of the Connector")
95	}
96}
97
98func TestDriverPanic(t *testing.T) {
99	// Test that if driver panics, database/sql does not deadlock.
100	db, err := Open("test", fakeDBName)
101	if err != nil {
102		t.Fatalf("Open: %v", err)
103	}
104	expectPanic := func(name string, f func()) {
105		defer func() {
106			err := recover()
107			if err == nil {
108				t.Fatalf("%s did not panic", name)
109			}
110		}()
111		f()
112	}
113
114	expectPanic("Exec Exec", func() { db.Exec("PANIC|Exec|WIPE") })
115	exec(t, db, "WIPE") // check not deadlocked
116	expectPanic("Exec NumInput", func() { db.Exec("PANIC|NumInput|WIPE") })
117	exec(t, db, "WIPE") // check not deadlocked
118	expectPanic("Exec Close", func() { db.Exec("PANIC|Close|WIPE") })
119	exec(t, db, "WIPE")             // check not deadlocked
120	exec(t, db, "PANIC|Query|WIPE") // should run successfully: Exec does not call Query
121	exec(t, db, "WIPE")             // check not deadlocked
122
123	exec(t, db, "CREATE|people|name=string,age=int32,photo=blob,dead=bool,bdate=datetime")
124
125	expectPanic("Query Query", func() { db.Query("PANIC|Query|SELECT|people|age,name|") })
126	expectPanic("Query NumInput", func() { db.Query("PANIC|NumInput|SELECT|people|age,name|") })
127	expectPanic("Query Close", func() {
128		rows, err := db.Query("PANIC|Close|SELECT|people|age,name|")
129		if err != nil {
130			t.Fatal(err)
131		}
132		rows.Close()
133	})
134	db.Query("PANIC|Exec|SELECT|people|age,name|") // should run successfully: Query does not call Exec
135	exec(t, db, "WIPE")                            // check not deadlocked
136}
137
138func exec(t testing.TB, db *DB, query string, args ...any) {
139	t.Helper()
140	_, err := db.Exec(query, args...)
141	if err != nil {
142		t.Fatalf("Exec of %q: %v", query, err)
143	}
144}
145
146func closeDB(t testing.TB, db *DB) {
147	if e := recover(); e != nil {
148		fmt.Printf("Panic: %v\n", e)
149		panic(e)
150	}
151	defer setHookpostCloseConn(nil)
152	setHookpostCloseConn(func(_ *fakeConn, err error) {
153		if err != nil {
154			t.Errorf("Error closing fakeConn: %v", err)
155		}
156	})
157	db.mu.Lock()
158	for i, dc := range db.freeConn {
159		if n := len(dc.openStmt); n > 0 {
160			// Just a sanity check. This is legal in
161			// general, but if we make the tests clean up
162			// their statements first, then we can safely
163			// verify this is always zero here, and any
164			// other value is a leak.
165			t.Errorf("while closing db, freeConn %d/%d had %d open stmts; want 0", i, len(db.freeConn), n)
166		}
167	}
168	db.mu.Unlock()
169
170	err := db.Close()
171	if err != nil {
172		t.Fatalf("error closing DB: %v", err)
173	}
174
175	var numOpen int
176	if !waitCondition(t, func() bool {
177		numOpen = db.numOpenConns()
178		return numOpen == 0
179	}) {
180		t.Fatalf("%d connections still open after closing DB", numOpen)
181	}
182}
183
184// numPrepares assumes that db has exactly 1 idle conn and returns
185// its count of calls to Prepare
186func numPrepares(t *testing.T, db *DB) int {
187	if n := len(db.freeConn); n != 1 {
188		t.Fatalf("free conns = %d; want 1", n)
189	}
190	return db.freeConn[0].ci.(*fakeConn).numPrepare
191}
192
193func (db *DB) numDeps() int {
194	db.mu.Lock()
195	defer db.mu.Unlock()
196	return len(db.dep)
197}
198
199// Dependencies are closed via a goroutine, so this polls waiting for
200// numDeps to fall to want, waiting up to nearly the test's deadline.
201func (db *DB) numDepsPoll(t *testing.T, want int) int {
202	var n int
203	waitCondition(t, func() bool {
204		n = db.numDeps()
205		return n <= want
206	})
207	return n
208}
209
210func (db *DB) numFreeConns() int {
211	db.mu.Lock()
212	defer db.mu.Unlock()
213	return len(db.freeConn)
214}
215
216func (db *DB) numOpenConns() int {
217	db.mu.Lock()
218	defer db.mu.Unlock()
219	return db.numOpen
220}
221
222// clearAllConns closes all connections in db.
223func (db *DB) clearAllConns(t *testing.T) {
224	db.SetMaxIdleConns(0)
225
226	if g, w := db.numFreeConns(), 0; g != w {
227		t.Errorf("free conns = %d; want %d", g, w)
228	}
229
230	if n := db.numDepsPoll(t, 0); n > 0 {
231		t.Errorf("number of dependencies = %d; expected 0", n)
232		db.dumpDeps(t)
233	}
234}
235
236func (db *DB) dumpDeps(t *testing.T) {
237	for fc := range db.dep {
238		db.dumpDep(t, 0, fc, map[finalCloser]bool{})
239	}
240}
241
242func (db *DB) dumpDep(t *testing.T, depth int, dep finalCloser, seen map[finalCloser]bool) {
243	seen[dep] = true
244	indent := strings.Repeat("  ", depth)
245	ds := db.dep[dep]
246	for k := range ds {
247		t.Logf("%s%T (%p) waiting for -> %T (%p)", indent, dep, dep, k, k)
248		if fc, ok := k.(finalCloser); ok {
249			if !seen[fc] {
250				db.dumpDep(t, depth+1, fc, seen)
251			}
252		}
253	}
254}
255
256func TestQuery(t *testing.T) {
257	db := newTestDB(t, "people")
258	defer closeDB(t, db)
259	prepares0 := numPrepares(t, db)
260	rows, err := db.Query("SELECT|people|age,name|")
261	if err != nil {
262		t.Fatalf("Query: %v", err)
263	}
264	defer rows.Close()
265	type row struct {
266		age  int
267		name string
268	}
269	got := []row{}
270	for rows.Next() {
271		var r row
272		err = rows.Scan(&r.age, &r.name)
273		if err != nil {
274			t.Fatalf("Scan: %v", err)
275		}
276		got = append(got, r)
277	}
278	err = rows.Err()
279	if err != nil {
280		t.Fatalf("Err: %v", err)
281	}
282	want := []row{
283		{age: 1, name: "Alice"},
284		{age: 2, name: "Bob"},
285		{age: 3, name: "Chris"},
286	}
287	if !slices.Equal(got, want) {
288		t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
289	}
290
291	// And verify that the final rows.Next() call, which hit EOF,
292	// also closed the rows connection.
293	if n := db.numFreeConns(); n != 1 {
294		t.Fatalf("free conns after query hitting EOF = %d; want 1", n)
295	}
296	if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
297		t.Errorf("executed %d Prepare statements; want 1", prepares)
298	}
299}
300
301// TestQueryContext tests canceling the context while scanning the rows.
302func TestQueryContext(t *testing.T) {
303	db := newTestDB(t, "people")
304	defer closeDB(t, db)
305	prepares0 := numPrepares(t, db)
306
307	ctx, cancel := context.WithCancel(context.Background())
308	defer cancel()
309
310	rows, err := db.QueryContext(ctx, "SELECT|people|age,name|")
311	if err != nil {
312		t.Fatalf("Query: %v", err)
313	}
314	type row struct {
315		age  int
316		name string
317	}
318	got := []row{}
319	index := 0
320	for rows.Next() {
321		if index == 2 {
322			cancel()
323			waitForRowsClose(t, rows)
324		}
325		var r row
326		err = rows.Scan(&r.age, &r.name)
327		if err != nil {
328			if index == 2 {
329				break
330			}
331			t.Fatalf("Scan: %v", err)
332		}
333		if index == 2 && err != context.Canceled {
334			t.Fatalf("Scan: %v; want context.Canceled", err)
335		}
336		got = append(got, r)
337		index++
338	}
339	select {
340	case <-ctx.Done():
341		if err := ctx.Err(); err != context.Canceled {
342			t.Fatalf("context err = %v; want context.Canceled", err)
343		}
344	default:
345		t.Fatalf("context err = nil; want context.Canceled")
346	}
347	want := []row{
348		{age: 1, name: "Alice"},
349		{age: 2, name: "Bob"},
350	}
351	if !slices.Equal(got, want) {
352		t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
353	}
354
355	// And verify that the final rows.Next() call, which hit EOF,
356	// also closed the rows connection.
357	waitForRowsClose(t, rows)
358	waitForFree(t, db, 1)
359	if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
360		t.Errorf("executed %d Prepare statements; want 1", prepares)
361	}
362}
363
364func waitCondition(t testing.TB, fn func() bool) bool {
365	timeout := 5 * time.Second
366
367	type deadliner interface {
368		Deadline() (time.Time, bool)
369	}
370	if td, ok := t.(deadliner); ok {
371		if deadline, ok := td.Deadline(); ok {
372			timeout = time.Until(deadline)
373			timeout = timeout * 19 / 20 // Give 5% headroom for cleanup and error-reporting.
374		}
375	}
376
377	deadline := time.Now().Add(timeout)
378	for {
379		if fn() {
380			return true
381		}
382		if time.Until(deadline) < pollDuration {
383			return false
384		}
385		time.Sleep(pollDuration)
386	}
387}
388
389// waitForFree checks db.numFreeConns until either it equals want or
390// the maxWait time elapses.
391func waitForFree(t *testing.T, db *DB, want int) {
392	var numFree int
393	if !waitCondition(t, func() bool {
394		numFree = db.numFreeConns()
395		return numFree == want
396	}) {
397		t.Fatalf("free conns after hitting EOF = %d; want %d", numFree, want)
398	}
399}
400
401func waitForRowsClose(t *testing.T, rows *Rows) {
402	if !waitCondition(t, func() bool {
403		rows.closemu.RLock()
404		defer rows.closemu.RUnlock()
405		return rows.closed
406	}) {
407		t.Fatal("failed to close rows")
408	}
409}
410
411// TestQueryContextWait ensures that rows and all internal statements are closed when
412// a query context is closed during execution.
413func TestQueryContextWait(t *testing.T) {
414	db := newTestDB(t, "people")
415	defer closeDB(t, db)
416	prepares0 := numPrepares(t, db)
417
418	ctx, cancel := context.WithCancel(context.Background())
419	defer cancel()
420
421	// This will trigger the *fakeConn.Prepare method which will take time
422	// performing the query. The ctxDriverPrepare func will check the context
423	// after this and close the rows and return an error.
424	c, err := db.Conn(ctx)
425	if err != nil {
426		t.Fatal(err)
427	}
428
429	c.dc.ci.(*fakeConn).waiter = func(c context.Context) {
430		cancel()
431		<-ctx.Done()
432	}
433	_, err = c.QueryContext(ctx, "SELECT|people|age,name|")
434	c.Close()
435	if err != context.Canceled {
436		t.Fatalf("expected QueryContext to error with context deadline exceeded but returned %v", err)
437	}
438
439	// Verify closed rows connection after error condition.
440	waitForFree(t, db, 1)
441	if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
442		t.Fatalf("executed %d Prepare statements; want 1", prepares)
443	}
444}
445
446// TestTxContextWait tests the transaction behavior when the tx context is canceled
447// during execution of the query.
448func TestTxContextWait(t *testing.T) {
449	testContextWait(t, false)
450}
451
452// TestTxContextWaitNoDiscard is the same as TestTxContextWait, but should not discard
453// the final connection.
454func TestTxContextWaitNoDiscard(t *testing.T) {
455	testContextWait(t, true)
456}
457
458func testContextWait(t *testing.T, keepConnOnRollback bool) {
459	db := newTestDB(t, "people")
460	defer closeDB(t, db)
461
462	ctx, cancel := context.WithCancel(context.Background())
463
464	tx, err := db.BeginTx(ctx, nil)
465	if err != nil {
466		t.Fatal(err)
467	}
468	tx.keepConnOnRollback = keepConnOnRollback
469
470	tx.dc.ci.(*fakeConn).waiter = func(c context.Context) {
471		cancel()
472		<-ctx.Done()
473	}
474	// This will trigger the *fakeConn.Prepare method which will take time
475	// performing the query. The ctxDriverPrepare func will check the context
476	// after this and close the rows and return an error.
477	_, err = tx.QueryContext(ctx, "SELECT|people|age,name|")
478	if err != context.Canceled {
479		t.Fatalf("expected QueryContext to error with context canceled but returned %v", err)
480	}
481
482	if keepConnOnRollback {
483		waitForFree(t, db, 1)
484	} else {
485		waitForFree(t, db, 0)
486	}
487}
488
489// TestUnsupportedOptions checks that the database fails when a driver that
490// doesn't implement ConnBeginTx is used with non-default options and an
491// un-cancellable context.
492func TestUnsupportedOptions(t *testing.T) {
493	db := newTestDB(t, "people")
494	defer closeDB(t, db)
495	_, err := db.BeginTx(context.Background(), &TxOptions{
496		Isolation: LevelSerializable, ReadOnly: true,
497	})
498	if err == nil {
499		t.Fatal("expected error when using unsupported options, got nil")
500	}
501}
502
503func TestMultiResultSetQuery(t *testing.T) {
504	db := newTestDB(t, "people")
505	defer closeDB(t, db)
506	prepares0 := numPrepares(t, db)
507	rows, err := db.Query("SELECT|people|age,name|;SELECT|people|name|")
508	if err != nil {
509		t.Fatalf("Query: %v", err)
510	}
511	type row1 struct {
512		age  int
513		name string
514	}
515	type row2 struct {
516		name string
517	}
518	got1 := []row1{}
519	for rows.Next() {
520		var r row1
521		err = rows.Scan(&r.age, &r.name)
522		if err != nil {
523			t.Fatalf("Scan: %v", err)
524		}
525		got1 = append(got1, r)
526	}
527	err = rows.Err()
528	if err != nil {
529		t.Fatalf("Err: %v", err)
530	}
531	want1 := []row1{
532		{age: 1, name: "Alice"},
533		{age: 2, name: "Bob"},
534		{age: 3, name: "Chris"},
535	}
536	if !slices.Equal(got1, want1) {
537		t.Errorf("mismatch.\n got1: %#v\nwant: %#v", got1, want1)
538	}
539
540	if !rows.NextResultSet() {
541		t.Errorf("expected another result set")
542	}
543
544	got2 := []row2{}
545	for rows.Next() {
546		var r row2
547		err = rows.Scan(&r.name)
548		if err != nil {
549			t.Fatalf("Scan: %v", err)
550		}
551		got2 = append(got2, r)
552	}
553	err = rows.Err()
554	if err != nil {
555		t.Fatalf("Err: %v", err)
556	}
557	want2 := []row2{
558		{name: "Alice"},
559		{name: "Bob"},
560		{name: "Chris"},
561	}
562	if !slices.Equal(got2, want2) {
563		t.Errorf("mismatch.\n got: %#v\nwant: %#v", got2, want2)
564	}
565	if rows.NextResultSet() {
566		t.Errorf("expected no more result sets")
567	}
568
569	// And verify that the final rows.Next() call, which hit EOF,
570	// also closed the rows connection.
571	waitForFree(t, db, 1)
572	if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
573		t.Errorf("executed %d Prepare statements; want 1", prepares)
574	}
575}
576
577func TestQueryNamedArg(t *testing.T) {
578	db := newTestDB(t, "people")
579	defer closeDB(t, db)
580	prepares0 := numPrepares(t, db)
581	rows, err := db.Query(
582		// Ensure the name and age parameters only match on placeholder name, not position.
583		"SELECT|people|age,name|name=?name,age=?age",
584		Named("age", 2),
585		Named("name", "Bob"),
586	)
587	if err != nil {
588		t.Fatalf("Query: %v", err)
589	}
590	type row struct {
591		age  int
592		name string
593	}
594	got := []row{}
595	for rows.Next() {
596		var r row
597		err = rows.Scan(&r.age, &r.name)
598		if err != nil {
599			t.Fatalf("Scan: %v", err)
600		}
601		got = append(got, r)
602	}
603	err = rows.Err()
604	if err != nil {
605		t.Fatalf("Err: %v", err)
606	}
607	want := []row{
608		{age: 2, name: "Bob"},
609	}
610	if !slices.Equal(got, want) {
611		t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
612	}
613
614	// And verify that the final rows.Next() call, which hit EOF,
615	// also closed the rows connection.
616	if n := db.numFreeConns(); n != 1 {
617		t.Fatalf("free conns after query hitting EOF = %d; want 1", n)
618	}
619	if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
620		t.Errorf("executed %d Prepare statements; want 1", prepares)
621	}
622}
623
624func TestPoolExhaustOnCancel(t *testing.T) {
625	if testing.Short() {
626		t.Skip("long test")
627	}
628
629	max := 3
630	var saturate, saturateDone sync.WaitGroup
631	saturate.Add(max)
632	saturateDone.Add(max)
633
634	donePing := make(chan bool)
635	state := 0
636
637	// waiter will be called for all queries, including
638	// initial setup queries. The state is only assigned when
639	// no queries are made.
640	//
641	// Only allow the first batch of queries to finish once the
642	// second batch of Ping queries have finished.
643	waiter := func(ctx context.Context) {
644		switch state {
645		case 0:
646			// Nothing. Initial database setup.
647		case 1:
648			saturate.Done()
649			select {
650			case <-ctx.Done():
651			case <-donePing:
652			}
653		case 2:
654		}
655	}
656	db := newTestDBConnector(t, &fakeConnector{waiter: waiter}, "people")
657	defer closeDB(t, db)
658
659	db.SetMaxOpenConns(max)
660
661	// First saturate the connection pool.
662	// Then start new requests for a connection that is canceled after it is requested.
663
664	state = 1
665	for i := 0; i < max; i++ {
666		go func() {
667			rows, err := db.Query("SELECT|people|name,photo|")
668			if err != nil {
669				t.Errorf("Query: %v", err)
670				return
671			}
672			rows.Close()
673			saturateDone.Done()
674		}()
675	}
676
677	saturate.Wait()
678	if t.Failed() {
679		t.FailNow()
680	}
681	state = 2
682
683	// Now cancel the request while it is waiting.
684	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
685	defer cancel()
686
687	for i := 0; i < max; i++ {
688		ctxReq, cancelReq := context.WithCancel(ctx)
689		go func() {
690			time.Sleep(100 * time.Millisecond)
691			cancelReq()
692		}()
693		err := db.PingContext(ctxReq)
694		if err != context.Canceled {
695			t.Fatalf("PingContext (Exhaust): %v", err)
696		}
697	}
698	close(donePing)
699	saturateDone.Wait()
700
701	// Now try to open a normal connection.
702	err := db.PingContext(ctx)
703	if err != nil {
704		t.Fatalf("PingContext (Normal): %v", err)
705	}
706}
707
708func TestRowsColumns(t *testing.T) {
709	db := newTestDB(t, "people")
710	defer closeDB(t, db)
711	rows, err := db.Query("SELECT|people|age,name|")
712	if err != nil {
713		t.Fatalf("Query: %v", err)
714	}
715	cols, err := rows.Columns()
716	if err != nil {
717		t.Fatalf("Columns: %v", err)
718	}
719	want := []string{"age", "name"}
720	if !slices.Equal(cols, want) {
721		t.Errorf("got %#v; want %#v", cols, want)
722	}
723	if err := rows.Close(); err != nil {
724		t.Errorf("error closing rows: %s", err)
725	}
726}
727
728func TestRowsColumnTypes(t *testing.T) {
729	db := newTestDB(t, "people")
730	defer closeDB(t, db)
731	rows, err := db.Query("SELECT|people|age,name|")
732	if err != nil {
733		t.Fatalf("Query: %v", err)
734	}
735	tt, err := rows.ColumnTypes()
736	if err != nil {
737		t.Fatalf("ColumnTypes: %v", err)
738	}
739
740	types := make([]reflect.Type, len(tt))
741	for i, tp := range tt {
742		st := tp.ScanType()
743		if st == nil {
744			t.Errorf("scantype is null for column %q", tp.Name())
745			continue
746		}
747		types[i] = st
748	}
749	values := make([]any, len(tt))
750	for i := range values {
751		values[i] = reflect.New(types[i]).Interface()
752	}
753	ct := 0
754	for rows.Next() {
755		err = rows.Scan(values...)
756		if err != nil {
757			t.Fatalf("failed to scan values in %v", err)
758		}
759		if ct == 1 {
760			if age := *values[0].(*int32); age != 2 {
761				t.Errorf("Expected 2, got %v", age)
762			}
763			if name := *values[1].(*string); name != "Bob" {
764				t.Errorf("Expected Bob, got %v", name)
765			}
766		}
767		ct++
768	}
769	if ct != 3 {
770		t.Errorf("expected 3 rows, got %d", ct)
771	}
772
773	if err := rows.Close(); err != nil {
774		t.Errorf("error closing rows: %s", err)
775	}
776}
777
778func TestQueryRow(t *testing.T) {
779	db := newTestDB(t, "people")
780	defer closeDB(t, db)
781	var name string
782	var age int
783	var birthday time.Time
784
785	err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age)
786	if err == nil || !strings.Contains(err.Error(), "expected 2 destination arguments") {
787		t.Errorf("expected error from wrong number of arguments; actually got: %v", err)
788	}
789
790	err = db.QueryRow("SELECT|people|bdate|age=?", 3).Scan(&birthday)
791	if err != nil || !birthday.Equal(chrisBirthday) {
792		t.Errorf("chris birthday = %v, err = %v; want %v", birthday, err, chrisBirthday)
793	}
794
795	err = db.QueryRow("SELECT|people|age,name|age=?", 2).Scan(&age, &name)
796	if err != nil {
797		t.Fatalf("age QueryRow+Scan: %v", err)
798	}
799	if name != "Bob" {
800		t.Errorf("expected name Bob, got %q", name)
801	}
802	if age != 2 {
803		t.Errorf("expected age 2, got %d", age)
804	}
805
806	err = db.QueryRow("SELECT|people|age,name|name=?", "Alice").Scan(&age, &name)
807	if err != nil {
808		t.Fatalf("name QueryRow+Scan: %v", err)
809	}
810	if name != "Alice" {
811		t.Errorf("expected name Alice, got %q", name)
812	}
813	if age != 1 {
814		t.Errorf("expected age 1, got %d", age)
815	}
816
817	var photo []byte
818	err = db.QueryRow("SELECT|people|photo|name=?", "Alice").Scan(&photo)
819	if err != nil {
820		t.Fatalf("photo QueryRow+Scan: %v", err)
821	}
822	want := []byte("APHOTO")
823	if !slices.Equal(photo, want) {
824		t.Errorf("photo = %q; want %q", photo, want)
825	}
826}
827
828func TestRowErr(t *testing.T) {
829	db := newTestDB(t, "people")
830
831	err := db.QueryRowContext(context.Background(), "SELECT|people|bdate|age=?", 3).Err()
832	if err != nil {
833		t.Errorf("Unexpected err = %v; want %v", err, nil)
834	}
835
836	ctx, cancel := context.WithCancel(context.Background())
837	cancel()
838
839	err = db.QueryRowContext(ctx, "SELECT|people|bdate|age=?", 3).Err()
840	exp := "context canceled"
841	if err == nil || !strings.Contains(err.Error(), exp) {
842		t.Errorf("Expected err = %v; got %v", exp, err)
843	}
844}
845
846func TestTxRollbackCommitErr(t *testing.T) {
847	db := newTestDB(t, "people")
848	defer closeDB(t, db)
849
850	tx, err := db.Begin()
851	if err != nil {
852		t.Fatal(err)
853	}
854	err = tx.Rollback()
855	if err != nil {
856		t.Errorf("expected nil error from Rollback; got %v", err)
857	}
858	err = tx.Commit()
859	if err != ErrTxDone {
860		t.Errorf("expected %q from Commit; got %q", ErrTxDone, err)
861	}
862
863	tx, err = db.Begin()
864	if err != nil {
865		t.Fatal(err)
866	}
867	err = tx.Commit()
868	if err != nil {
869		t.Errorf("expected nil error from Commit; got %v", err)
870	}
871	err = tx.Rollback()
872	if err != ErrTxDone {
873		t.Errorf("expected %q from Rollback; got %q", ErrTxDone, err)
874	}
875}
876
877func TestStatementErrorAfterClose(t *testing.T) {
878	db := newTestDB(t, "people")
879	defer closeDB(t, db)
880	stmt, err := db.Prepare("SELECT|people|age|name=?")
881	if err != nil {
882		t.Fatalf("Prepare: %v", err)
883	}
884	err = stmt.Close()
885	if err != nil {
886		t.Fatalf("Close: %v", err)
887	}
888	var name string
889	err = stmt.QueryRow("foo").Scan(&name)
890	if err == nil {
891		t.Errorf("expected error from QueryRow.Scan after Stmt.Close")
892	}
893}
894
895func TestStatementQueryRow(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)
901	}
902	defer stmt.Close()
903	var age int
904	for n, tt := range []struct {
905		name string
906		want int
907	}{
908		{"Alice", 1},
909		{"Bob", 2},
910		{"Chris", 3},
911	} {
912		if err := stmt.QueryRow(tt.name).Scan(&age); err != nil {
913			t.Errorf("%d: on %q, QueryRow/Scan: %v", n, tt.name, err)
914		} else if age != tt.want {
915			t.Errorf("%d: age=%d, want %d", n, age, tt.want)
916		}
917	}
918}
919
920type stubDriverStmt struct {
921	err error
922}
923
924func (s stubDriverStmt) Close() error {
925	return s.err
926}
927
928func (s stubDriverStmt) NumInput() int {
929	return -1
930}
931
932func (s stubDriverStmt) Exec(args []driver.Value) (driver.Result, error) {
933	return nil, nil
934}
935
936func (s stubDriverStmt) Query(args []driver.Value) (driver.Rows, error) {
937	return nil, nil
938}
939
940// golang.org/issue/12798
941func TestStatementClose(t *testing.T) {
942	want := errors.New("STMT ERROR")
943
944	tests := []struct {
945		stmt *Stmt
946		msg  string
947	}{
948		{&Stmt{stickyErr: want}, "stickyErr not propagated"},
949		{&Stmt{cg: &Tx{}, cgds: &driverStmt{Locker: &sync.Mutex{}, si: stubDriverStmt{want}}}, "driverStmt.Close() error not propagated"},
950	}
951	for _, test := range tests {
952		if err := test.stmt.Close(); err != want {
953			t.Errorf("%s. Got stmt.Close() = %v, want = %v", test.msg, err, want)
954		}
955	}
956}
957
958// golang.org/issue/3734
959func TestStatementQueryRowConcurrent(t *testing.T) {
960	db := newTestDB(t, "people")
961	defer closeDB(t, db)
962	stmt, err := db.Prepare("SELECT|people|age|name=?")
963	if err != nil {
964		t.Fatalf("Prepare: %v", err)
965	}
966	defer stmt.Close()
967
968	const n = 10
969	ch := make(chan error, n)
970	for i := 0; i < n; i++ {
971		go func() {
972			var age int
973			err := stmt.QueryRow("Alice").Scan(&age)
974			if err == nil && age != 1 {
975				err = fmt.Errorf("unexpected age %d", age)
976			}
977			ch <- err
978		}()
979	}
980	for i := 0; i < n; i++ {
981		if err := <-ch; err != nil {
982			t.Error(err)
983		}
984	}
985}
986
987// just a test of fakedb itself
988func TestBogusPreboundParameters(t *testing.T) {
989	db := newTestDB(t, "foo")
990	defer closeDB(t, db)
991	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
992	_, err := db.Prepare("INSERT|t1|name=?,age=bogusconversion")
993	if err == nil {
994		t.Fatalf("expected error")
995	}
996	if err.Error() != `fakedb: invalid conversion to int32 from "bogusconversion"` {
997		t.Errorf("unexpected error: %v", err)
998	}
999}
1000
1001func TestExec(t *testing.T) {
1002	db := newTestDB(t, "foo")
1003	defer closeDB(t, db)
1004	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1005	stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1006	if err != nil {
1007		t.Errorf("Stmt, err = %v, %v", stmt, err)
1008	}
1009	defer stmt.Close()
1010
1011	type execTest struct {
1012		args    []any
1013		wantErr string
1014	}
1015	execTests := []execTest{
1016		// Okay:
1017		{[]any{"Brad", 31}, ""},
1018		{[]any{"Brad", int64(31)}, ""},
1019		{[]any{"Bob", "32"}, ""},
1020		{[]any{7, 9}, ""},
1021
1022		// Invalid conversions:
1023		{[]any{"Brad", int64(0xFFFFFFFF)}, "sql: converting argument $2 type: sql/driver: value 4294967295 overflows int32"},
1024		{[]any{"Brad", "strconv fail"}, `sql: converting argument $2 type: sql/driver: value "strconv fail" can't be converted to int32`},
1025
1026		// Wrong number of args:
1027		{[]any{}, "sql: expected 2 arguments, got 0"},
1028		{[]any{1, 2, 3}, "sql: expected 2 arguments, got 3"},
1029	}
1030	for n, et := range execTests {
1031		_, err := stmt.Exec(et.args...)
1032		errStr := ""
1033		if err != nil {
1034			errStr = err.Error()
1035		}
1036		if errStr != et.wantErr {
1037			t.Errorf("stmt.Execute #%d: for %v, got error %q, want error %q",
1038				n, et.args, errStr, et.wantErr)
1039		}
1040	}
1041}
1042
1043func TestTxPrepare(t *testing.T) {
1044	db := newTestDB(t, "")
1045	defer closeDB(t, db)
1046	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1047	tx, err := db.Begin()
1048	if err != nil {
1049		t.Fatalf("Begin = %v", err)
1050	}
1051	stmt, err := tx.Prepare("INSERT|t1|name=?,age=?")
1052	if err != nil {
1053		t.Fatalf("Stmt, err = %v, %v", stmt, err)
1054	}
1055	defer stmt.Close()
1056	_, err = stmt.Exec("Bobby", 7)
1057	if err != nil {
1058		t.Fatalf("Exec = %v", err)
1059	}
1060	err = tx.Commit()
1061	if err != nil {
1062		t.Fatalf("Commit = %v", err)
1063	}
1064	// Commit() should have closed the statement
1065	if !stmt.closed {
1066		t.Fatal("Stmt not closed after Commit")
1067	}
1068}
1069
1070func TestTxStmt(t *testing.T) {
1071	db := newTestDB(t, "")
1072	defer closeDB(t, db)
1073	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1074	stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1075	if err != nil {
1076		t.Fatalf("Stmt, err = %v, %v", stmt, err)
1077	}
1078	defer stmt.Close()
1079	tx, err := db.Begin()
1080	if err != nil {
1081		t.Fatalf("Begin = %v", err)
1082	}
1083	txs := tx.Stmt(stmt)
1084	defer txs.Close()
1085	_, err = txs.Exec("Bobby", 7)
1086	if err != nil {
1087		t.Fatalf("Exec = %v", err)
1088	}
1089	err = tx.Commit()
1090	if err != nil {
1091		t.Fatalf("Commit = %v", err)
1092	}
1093	// Commit() should have closed the statement
1094	if !txs.closed {
1095		t.Fatal("Stmt not closed after Commit")
1096	}
1097}
1098
1099func TestTxStmtPreparedOnce(t *testing.T) {
1100	db := newTestDB(t, "")
1101	defer closeDB(t, db)
1102	exec(t, db, "CREATE|t1|name=string,age=int32")
1103
1104	prepares0 := numPrepares(t, db)
1105
1106	// db.Prepare increments numPrepares.
1107	stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1108	if err != nil {
1109		t.Fatalf("Stmt, err = %v, %v", stmt, err)
1110	}
1111	defer stmt.Close()
1112
1113	tx, err := db.Begin()
1114	if err != nil {
1115		t.Fatalf("Begin = %v", err)
1116	}
1117
1118	txs1 := tx.Stmt(stmt)
1119	txs2 := tx.Stmt(stmt)
1120
1121	_, err = txs1.Exec("Go", 7)
1122	if err != nil {
1123		t.Fatalf("Exec = %v", err)
1124	}
1125	txs1.Close()
1126
1127	_, err = txs2.Exec("Gopher", 8)
1128	if err != nil {
1129		t.Fatalf("Exec = %v", err)
1130	}
1131	txs2.Close()
1132
1133	err = tx.Commit()
1134	if err != nil {
1135		t.Fatalf("Commit = %v", err)
1136	}
1137
1138	if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
1139		t.Errorf("executed %d Prepare statements; want 1", prepares)
1140	}
1141}
1142
1143func TestTxStmtClosedRePrepares(t *testing.T) {
1144	db := newTestDB(t, "")
1145	defer closeDB(t, db)
1146	exec(t, db, "CREATE|t1|name=string,age=int32")
1147
1148	prepares0 := numPrepares(t, db)
1149
1150	// db.Prepare increments numPrepares.
1151	stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1152	if err != nil {
1153		t.Fatalf("Stmt, err = %v, %v", stmt, err)
1154	}
1155	tx, err := db.Begin()
1156	if err != nil {
1157		t.Fatalf("Begin = %v", err)
1158	}
1159	err = stmt.Close()
1160	if err != nil {
1161		t.Fatalf("stmt.Close() = %v", err)
1162	}
1163	// tx.Stmt increments numPrepares because stmt is closed.
1164	txs := tx.Stmt(stmt)
1165	if txs.stickyErr != nil {
1166		t.Fatal(txs.stickyErr)
1167	}
1168	if txs.parentStmt != nil {
1169		t.Fatal("expected nil parentStmt")
1170	}
1171	_, err = txs.Exec(`Eric`, 82)
1172	if err != nil {
1173		t.Fatalf("txs.Exec = %v", err)
1174	}
1175
1176	err = txs.Close()
1177	if err != nil {
1178		t.Fatalf("txs.Close = %v", err)
1179	}
1180
1181	tx.Rollback()
1182
1183	if prepares := numPrepares(t, db) - prepares0; prepares != 2 {
1184		t.Errorf("executed %d Prepare statements; want 2", prepares)
1185	}
1186}
1187
1188func TestParentStmtOutlivesTxStmt(t *testing.T) {
1189	db := newTestDB(t, "")
1190	defer closeDB(t, db)
1191	exec(t, db, "CREATE|t1|name=string,age=int32")
1192
1193	// Make sure everything happens on the same connection.
1194	db.SetMaxOpenConns(1)
1195
1196	prepares0 := numPrepares(t, db)
1197
1198	// db.Prepare increments numPrepares.
1199	stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1200	if err != nil {
1201		t.Fatalf("Stmt, err = %v, %v", stmt, err)
1202	}
1203	defer stmt.Close()
1204	tx, err := db.Begin()
1205	if err != nil {
1206		t.Fatalf("Begin = %v", err)
1207	}
1208	txs := tx.Stmt(stmt)
1209	if len(stmt.css) != 1 {
1210		t.Fatalf("len(stmt.css) = %v; want 1", len(stmt.css))
1211	}
1212	err = txs.Close()
1213	if err != nil {
1214		t.Fatalf("txs.Close() = %v", err)
1215	}
1216	err = tx.Rollback()
1217	if err != nil {
1218		t.Fatalf("tx.Rollback() = %v", err)
1219	}
1220	// txs must not be valid.
1221	_, err = txs.Exec("Suzan", 30)
1222	if err == nil {
1223		t.Fatalf("txs.Exec(), expected err")
1224	}
1225	// Stmt must still be valid.
1226	_, err = stmt.Exec("Janina", 25)
1227	if err != nil {
1228		t.Fatalf("stmt.Exec() = %v", err)
1229	}
1230
1231	if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
1232		t.Errorf("executed %d Prepare statements; want 1", prepares)
1233	}
1234}
1235
1236// Test that tx.Stmt called with a statement already
1237// associated with tx as argument re-prepares the same
1238// statement again.
1239func TestTxStmtFromTxStmtRePrepares(t *testing.T) {
1240	db := newTestDB(t, "")
1241	defer closeDB(t, db)
1242	exec(t, db, "CREATE|t1|name=string,age=int32")
1243	prepares0 := numPrepares(t, db)
1244	// db.Prepare increments numPrepares.
1245	stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1246	if err != nil {
1247		t.Fatalf("Stmt, err = %v, %v", stmt, err)
1248	}
1249	defer stmt.Close()
1250
1251	tx, err := db.Begin()
1252	if err != nil {
1253		t.Fatalf("Begin = %v", err)
1254	}
1255	txs1 := tx.Stmt(stmt)
1256
1257	// tx.Stmt(txs1) increments numPrepares because txs1 already
1258	// belongs to a transaction (albeit the same transaction).
1259	txs2 := tx.Stmt(txs1)
1260	if txs2.stickyErr != nil {
1261		t.Fatal(txs2.stickyErr)
1262	}
1263	if txs2.parentStmt != nil {
1264		t.Fatal("expected nil parentStmt")
1265	}
1266	_, err = txs2.Exec(`Eric`, 82)
1267	if err != nil {
1268		t.Fatal(err)
1269	}
1270
1271	err = txs1.Close()
1272	if err != nil {
1273		t.Fatalf("txs1.Close = %v", err)
1274	}
1275	err = txs2.Close()
1276	if err != nil {
1277		t.Fatalf("txs1.Close = %v", err)
1278	}
1279	err = tx.Rollback()
1280	if err != nil {
1281		t.Fatalf("tx.Rollback = %v", err)
1282	}
1283
1284	if prepares := numPrepares(t, db) - prepares0; prepares != 2 {
1285		t.Errorf("executed %d Prepare statements; want 2", prepares)
1286	}
1287}
1288
1289// Issue: https://golang.org/issue/2784
1290// This test didn't fail before because we got lucky with the fakedb driver.
1291// It was failing, and now not, in github.com/bradfitz/go-sql-test
1292func TestTxQuery(t *testing.T) {
1293	db := newTestDB(t, "")
1294	defer closeDB(t, db)
1295	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1296	exec(t, db, "INSERT|t1|name=Alice")
1297
1298	tx, err := db.Begin()
1299	if err != nil {
1300		t.Fatal(err)
1301	}
1302	defer tx.Rollback()
1303
1304	r, err := tx.Query("SELECT|t1|name|")
1305	if err != nil {
1306		t.Fatal(err)
1307	}
1308	defer r.Close()
1309
1310	if !r.Next() {
1311		if r.Err() != nil {
1312			t.Fatal(r.Err())
1313		}
1314		t.Fatal("expected one row")
1315	}
1316
1317	var x string
1318	err = r.Scan(&x)
1319	if err != nil {
1320		t.Fatal(err)
1321	}
1322}
1323
1324func TestTxQueryInvalid(t *testing.T) {
1325	db := newTestDB(t, "")
1326	defer closeDB(t, db)
1327
1328	tx, err := db.Begin()
1329	if err != nil {
1330		t.Fatal(err)
1331	}
1332	defer tx.Rollback()
1333
1334	_, err = tx.Query("SELECT|t1|name|")
1335	if err == nil {
1336		t.Fatal("Error expected")
1337	}
1338}
1339
1340// Tests fix for issue 4433, that retries in Begin happen when
1341// conn.Begin() returns ErrBadConn
1342func TestTxErrBadConn(t *testing.T) {
1343	db, err := Open("test", fakeDBName+";badConn")
1344	if err != nil {
1345		t.Fatalf("Open: %v", err)
1346	}
1347	if _, err := db.Exec("WIPE"); err != nil {
1348		t.Fatalf("exec wipe: %v", err)
1349	}
1350	defer closeDB(t, db)
1351	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
1352	stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
1353	if err != nil {
1354		t.Fatalf("Stmt, err = %v, %v", stmt, err)
1355	}
1356	defer stmt.Close()
1357	tx, err := db.Begin()
1358	if err != nil {
1359		t.Fatalf("Begin = %v", err)
1360	}
1361	txs := tx.Stmt(stmt)
1362	defer txs.Close()
1363	_, err = txs.Exec("Bobby", 7)
1364	if err != nil {
1365		t.Fatalf("Exec = %v", err)
1366	}
1367	err = tx.Commit()
1368	if err != nil {
1369		t.Fatalf("Commit = %v", err)
1370	}
1371}
1372
1373func TestConnQuery(t *testing.T) {
1374	db := newTestDB(t, "people")
1375	defer closeDB(t, db)
1376
1377	ctx, cancel := context.WithCancel(context.Background())
1378	defer cancel()
1379	conn, err := db.Conn(ctx)
1380	if err != nil {
1381		t.Fatal(err)
1382	}
1383	conn.dc.ci.(*fakeConn).skipDirtySession = true
1384	defer conn.Close()
1385
1386	var name string
1387	err = conn.QueryRowContext(ctx, "SELECT|people|name|age=?", 3).Scan(&name)
1388	if err != nil {
1389		t.Fatal(err)
1390	}
1391	if name != "Chris" {
1392		t.Fatalf("unexpected result, got %q want Chris", name)
1393	}
1394
1395	err = conn.PingContext(ctx)
1396	if err != nil {
1397		t.Fatal(err)
1398	}
1399}
1400
1401func TestConnRaw(t *testing.T) {
1402	db := newTestDB(t, "people")
1403	defer closeDB(t, db)
1404
1405	ctx, cancel := context.WithCancel(context.Background())
1406	defer cancel()
1407	conn, err := db.Conn(ctx)
1408	if err != nil {
1409		t.Fatal(err)
1410	}
1411	conn.dc.ci.(*fakeConn).skipDirtySession = true
1412	defer conn.Close()
1413
1414	sawFunc := false
1415	err = conn.Raw(func(dc any) error {
1416		sawFunc = true
1417		if _, ok := dc.(*fakeConn); !ok {
1418			return fmt.Errorf("got %T want *fakeConn", dc)
1419		}
1420		return nil
1421	})
1422	if err != nil {
1423		t.Fatal(err)
1424	}
1425	if !sawFunc {
1426		t.Fatal("Raw func not called")
1427	}
1428
1429	func() {
1430		defer func() {
1431			x := recover()
1432			if x == nil {
1433				t.Fatal("expected panic")
1434			}
1435			conn.closemu.Lock()
1436			closed := conn.dc == nil
1437			conn.closemu.Unlock()
1438			if !closed {
1439				t.Fatal("expected connection to be closed after panic")
1440			}
1441		}()
1442		err = conn.Raw(func(dc any) error {
1443			panic("Conn.Raw panic should return an error")
1444		})
1445		t.Fatal("expected panic from Raw func")
1446	}()
1447}
1448
1449func TestCursorFake(t *testing.T) {
1450	db := newTestDB(t, "people")
1451	defer closeDB(t, db)
1452
1453	ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
1454	defer cancel()
1455
1456	exec(t, db, "CREATE|peoplecursor|list=table")
1457	exec(t, db, "INSERT|peoplecursor|list=people!name!age")
1458
1459	rows, err := db.QueryContext(ctx, `SELECT|peoplecursor|list|`)
1460	if err != nil {
1461		t.Fatal(err)
1462	}
1463	defer rows.Close()
1464
1465	if !rows.Next() {
1466		t.Fatal("no rows")
1467	}
1468	var cursor = &Rows{}
1469	err = rows.Scan(cursor)
1470	if err != nil {
1471		t.Fatal(err)
1472	}
1473	defer cursor.Close()
1474
1475	const expectedRows = 3
1476	var currentRow int64
1477
1478	var n int64
1479	var s string
1480	for cursor.Next() {
1481		currentRow++
1482		err = cursor.Scan(&s, &n)
1483		if err != nil {
1484			t.Fatal(err)
1485		}
1486		if n != currentRow {
1487			t.Errorf("expected number(Age)=%d, got %d", currentRow, n)
1488		}
1489	}
1490	if currentRow != expectedRows {
1491		t.Errorf("expected %d rows, got %d rows", expectedRows, currentRow)
1492	}
1493}
1494
1495func TestInvalidNilValues(t *testing.T) {
1496	var date1 time.Time
1497	var date2 int
1498
1499	tests := []struct {
1500		name          string
1501		input         any
1502		expectedError string
1503	}{
1504		{
1505			name:          "time.Time",
1506			input:         &date1,
1507			expectedError: `sql: Scan error on column index 0, name "bdate": unsupported Scan, storing driver.Value type <nil> into type *time.Time`,
1508		},
1509		{
1510			name:          "int",
1511			input:         &date2,
1512			expectedError: `sql: Scan error on column index 0, name "bdate": converting NULL to int is unsupported`,
1513		},
1514	}
1515
1516	for _, tt := range tests {
1517		t.Run(tt.name, func(t *testing.T) {
1518			db := newTestDB(t, "people")
1519			defer closeDB(t, db)
1520
1521			ctx, cancel := context.WithCancel(context.Background())
1522			defer cancel()
1523			conn, err := db.Conn(ctx)
1524			if err != nil {
1525				t.Fatal(err)
1526			}
1527			conn.dc.ci.(*fakeConn).skipDirtySession = true
1528			defer conn.Close()
1529
1530			err = conn.QueryRowContext(ctx, "SELECT|people|bdate|age=?", 1).Scan(tt.input)
1531			if err == nil {
1532				t.Fatal("expected error when querying nil column, but succeeded")
1533			}
1534			if err.Error() != tt.expectedError {
1535				t.Fatalf("Expected error: %s\nReceived: %s", tt.expectedError, err.Error())
1536			}
1537
1538			err = conn.PingContext(ctx)
1539			if err != nil {
1540				t.Fatal(err)
1541			}
1542		})
1543	}
1544}
1545
1546func TestConnTx(t *testing.T) {
1547	db := newTestDB(t, "people")
1548	defer closeDB(t, db)
1549
1550	ctx, cancel := context.WithCancel(context.Background())
1551	defer cancel()
1552	conn, err := db.Conn(ctx)
1553	if err != nil {
1554		t.Fatal(err)
1555	}
1556	conn.dc.ci.(*fakeConn).skipDirtySession = true
1557	defer conn.Close()
1558
1559	tx, err := conn.BeginTx(ctx, nil)
1560	if err != nil {
1561		t.Fatal(err)
1562	}
1563	insertName, insertAge := "Nancy", 33
1564	_, err = tx.ExecContext(ctx, "INSERT|people|name=?,age=?,photo=APHOTO", insertName, insertAge)
1565	if err != nil {
1566		t.Fatal(err)
1567	}
1568	err = tx.Commit()
1569	if err != nil {
1570		t.Fatal(err)
1571	}
1572
1573	var selectName string
1574	err = conn.QueryRowContext(ctx, "SELECT|people|name|age=?", insertAge).Scan(&selectName)
1575	if err != nil {
1576		t.Fatal(err)
1577	}
1578	if selectName != insertName {
1579		t.Fatalf("got %q want %q", selectName, insertName)
1580	}
1581}
1582
1583// TestConnIsValid verifies that a database connection that should be discarded,
1584// is actually discarded and does not re-enter the connection pool.
1585// If the IsValid method from *fakeConn is removed, this test will fail.
1586func TestConnIsValid(t *testing.T) {
1587	db := newTestDB(t, "people")
1588	defer closeDB(t, db)
1589
1590	db.SetMaxOpenConns(1)
1591
1592	ctx := context.Background()
1593
1594	c, err := db.Conn(ctx)
1595	if err != nil {
1596		t.Fatal(err)
1597	}
1598
1599	err = c.Raw(func(raw any) error {
1600		dc := raw.(*fakeConn)
1601		dc.stickyBad = true
1602		return nil
1603	})
1604	if err != nil {
1605		t.Fatal(err)
1606	}
1607	c.Close()
1608
1609	if len(db.freeConn) > 0 && db.freeConn[0].ci.(*fakeConn).stickyBad {
1610		t.Fatal("bad connection returned to pool; expected bad connection to be discarded")
1611	}
1612}
1613
1614// Tests fix for issue 2542, that we release a lock when querying on
1615// a closed connection.
1616func TestIssue2542Deadlock(t *testing.T) {
1617	db := newTestDB(t, "people")
1618	closeDB(t, db)
1619	for i := 0; i < 2; i++ {
1620		_, err := db.Query("SELECT|people|age,name|")
1621		if err == nil {
1622			t.Fatalf("expected error")
1623		}
1624	}
1625}
1626
1627// From golang.org/issue/3865
1628func TestCloseStmtBeforeRows(t *testing.T) {
1629	db := newTestDB(t, "people")
1630	defer closeDB(t, db)
1631
1632	s, err := db.Prepare("SELECT|people|name|")
1633	if err != nil {
1634		t.Fatal(err)
1635	}
1636
1637	r, err := s.Query()
1638	if err != nil {
1639		s.Close()
1640		t.Fatal(err)
1641	}
1642
1643	err = s.Close()
1644	if err != nil {
1645		t.Fatal(err)
1646	}
1647
1648	r.Close()
1649}
1650
1651// Tests fix for issue 2788, that we bind nil to a []byte if the
1652// value in the column is sql null
1653func TestNullByteSlice(t *testing.T) {
1654	db := newTestDB(t, "")
1655	defer closeDB(t, db)
1656	exec(t, db, "CREATE|t|id=int32,name=nullstring")
1657	exec(t, db, "INSERT|t|id=10,name=?", nil)
1658
1659	var name []byte
1660
1661	err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name)
1662	if err != nil {
1663		t.Fatal(err)
1664	}
1665	if name != nil {
1666		t.Fatalf("name []byte should be nil for null column value, got: %#v", name)
1667	}
1668
1669	exec(t, db, "INSERT|t|id=11,name=?", "bob")
1670	err = db.QueryRow("SELECT|t|name|id=?", 11).Scan(&name)
1671	if err != nil {
1672		t.Fatal(err)
1673	}
1674	if string(name) != "bob" {
1675		t.Fatalf("name []byte should be bob, got: %q", string(name))
1676	}
1677}
1678
1679func TestPointerParamsAndScans(t *testing.T) {
1680	db := newTestDB(t, "")
1681	defer closeDB(t, db)
1682	exec(t, db, "CREATE|t|id=int32,name=nullstring")
1683
1684	bob := "bob"
1685	var name *string
1686
1687	name = &bob
1688	exec(t, db, "INSERT|t|id=10,name=?", name)
1689	name = nil
1690	exec(t, db, "INSERT|t|id=20,name=?", name)
1691
1692	err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name)
1693	if err != nil {
1694		t.Fatalf("querying id 10: %v", err)
1695	}
1696	if name == nil {
1697		t.Errorf("id 10's name = nil; want bob")
1698	} else if *name != "bob" {
1699		t.Errorf("id 10's name = %q; want bob", *name)
1700	}
1701
1702	err = db.QueryRow("SELECT|t|name|id=?", 20).Scan(&name)
1703	if err != nil {
1704		t.Fatalf("querying id 20: %v", err)
1705	}
1706	if name != nil {
1707		t.Errorf("id 20 = %q; want nil", *name)
1708	}
1709}
1710
1711func TestQueryRowClosingStmt(t *testing.T) {
1712	db := newTestDB(t, "people")
1713	defer closeDB(t, db)
1714	var name string
1715	var age int
1716	err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age, &name)
1717	if err != nil {
1718		t.Fatal(err)
1719	}
1720	if len(db.freeConn) != 1 {
1721		t.Fatalf("expected 1 free conn")
1722	}
1723	fakeConn := db.freeConn[0].ci.(*fakeConn)
1724	if made, closed := fakeConn.stmtsMade, fakeConn.stmtsClosed; made != closed {
1725		t.Errorf("statement close mismatch: made %d, closed %d", made, closed)
1726	}
1727}
1728
1729var atomicRowsCloseHook atomic.Value // of func(*Rows, *error)
1730
1731func init() {
1732	rowsCloseHook = func() func(*Rows, *error) {
1733		fn, _ := atomicRowsCloseHook.Load().(func(*Rows, *error))
1734		return fn
1735	}
1736}
1737
1738func setRowsCloseHook(fn func(*Rows, *error)) {
1739	if fn == nil {
1740		// Can't change an atomic.Value back to nil, so set it to this
1741		// no-op func instead.
1742		fn = func(*Rows, *error) {}
1743	}
1744	atomicRowsCloseHook.Store(fn)
1745}
1746
1747// Test issue 6651
1748func TestIssue6651(t *testing.T) {
1749	db := newTestDB(t, "people")
1750	defer closeDB(t, db)
1751
1752	var v string
1753
1754	want := "error in rows.Next"
1755	rowsCursorNextHook = func(dest []driver.Value) error {
1756		return errors.New(want)
1757	}
1758	defer func() { rowsCursorNextHook = nil }()
1759
1760	err := db.QueryRow("SELECT|people|name|").Scan(&v)
1761	if err == nil || err.Error() != want {
1762		t.Errorf("error = %q; want %q", err, want)
1763	}
1764	rowsCursorNextHook = nil
1765
1766	want = "error in rows.Close"
1767	setRowsCloseHook(func(rows *Rows, err *error) {
1768		*err = errors.New(want)
1769	})
1770	defer setRowsCloseHook(nil)
1771	err = db.QueryRow("SELECT|people|name|").Scan(&v)
1772	if err == nil || err.Error() != want {
1773		t.Errorf("error = %q; want %q", err, want)
1774	}
1775}
1776
1777type nullTestRow struct {
1778	nullParam    any
1779	notNullParam any
1780	scanNullVal  any
1781}
1782
1783type nullTestSpec struct {
1784	nullType    string
1785	notNullType string
1786	rows        [6]nullTestRow
1787}
1788
1789func TestNullStringParam(t *testing.T) {
1790	spec := nullTestSpec{"nullstring", "string", [6]nullTestRow{
1791		{NullString{"aqua", true}, "", NullString{"aqua", true}},
1792		{NullString{"brown", false}, "", NullString{"", false}},
1793		{"chartreuse", "", NullString{"chartreuse", true}},
1794		{NullString{"darkred", true}, "", NullString{"darkred", true}},
1795		{NullString{"eel", false}, "", NullString{"", false}},
1796		{"foo", NullString{"black", false}, nil},
1797	}}
1798	nullTestRun(t, spec)
1799}
1800
1801func TestGenericNullStringParam(t *testing.T) {
1802	spec := nullTestSpec{"nullstring", "string", [6]nullTestRow{
1803		{Null[string]{"aqua", true}, "", Null[string]{"aqua", true}},
1804		{Null[string]{"brown", false}, "", Null[string]{"", false}},
1805		{"chartreuse", "", Null[string]{"chartreuse", true}},
1806		{Null[string]{"darkred", true}, "", Null[string]{"darkred", true}},
1807		{Null[string]{"eel", false}, "", Null[string]{"", false}},
1808		{"foo", Null[string]{"black", false}, nil},
1809	}}
1810	nullTestRun(t, spec)
1811}
1812
1813func TestNullInt64Param(t *testing.T) {
1814	spec := nullTestSpec{"nullint64", "int64", [6]nullTestRow{
1815		{NullInt64{31, true}, 1, NullInt64{31, true}},
1816		{NullInt64{-22, false}, 1, NullInt64{0, false}},
1817		{22, 1, NullInt64{22, true}},
1818		{NullInt64{33, true}, 1, NullInt64{33, true}},
1819		{NullInt64{222, false}, 1, NullInt64{0, false}},
1820		{0, NullInt64{31, false}, nil},
1821	}}
1822	nullTestRun(t, spec)
1823}
1824
1825func TestNullInt32Param(t *testing.T) {
1826	spec := nullTestSpec{"nullint32", "int32", [6]nullTestRow{
1827		{NullInt32{31, true}, 1, NullInt32{31, true}},
1828		{NullInt32{-22, false}, 1, NullInt32{0, false}},
1829		{22, 1, NullInt32{22, true}},
1830		{NullInt32{33, true}, 1, NullInt32{33, true}},
1831		{NullInt32{222, false}, 1, NullInt32{0, false}},
1832		{0, NullInt32{31, false}, nil},
1833	}}
1834	nullTestRun(t, spec)
1835}
1836
1837func TestNullInt16Param(t *testing.T) {
1838	spec := nullTestSpec{"nullint16", "int16", [6]nullTestRow{
1839		{NullInt16{31, true}, 1, NullInt16{31, true}},
1840		{NullInt16{-22, false}, 1, NullInt16{0, false}},
1841		{22, 1, NullInt16{22, true}},
1842		{NullInt16{33, true}, 1, NullInt16{33, true}},
1843		{NullInt16{222, false}, 1, NullInt16{0, false}},
1844		{0, NullInt16{31, false}, nil},
1845	}}
1846	nullTestRun(t, spec)
1847}
1848
1849func TestNullByteParam(t *testing.T) {
1850	spec := nullTestSpec{"nullbyte", "byte", [6]nullTestRow{
1851		{NullByte{31, true}, 1, NullByte{31, true}},
1852		{NullByte{0, false}, 1, NullByte{0, false}},
1853		{22, 1, NullByte{22, true}},
1854		{NullByte{33, true}, 1, NullByte{33, true}},
1855		{NullByte{222, false}, 1, NullByte{0, false}},
1856		{0, NullByte{31, false}, nil},
1857	}}
1858	nullTestRun(t, spec)
1859}
1860
1861func TestNullFloat64Param(t *testing.T) {
1862	spec := nullTestSpec{"nullfloat64", "float64", [6]nullTestRow{
1863		{NullFloat64{31.2, true}, 1, NullFloat64{31.2, true}},
1864		{NullFloat64{13.1, false}, 1, NullFloat64{0, false}},
1865		{-22.9, 1, NullFloat64{-22.9, true}},
1866		{NullFloat64{33.81, true}, 1, NullFloat64{33.81, true}},
1867		{NullFloat64{222, false}, 1, NullFloat64{0, false}},
1868		{10, NullFloat64{31.2, false}, nil},
1869	}}
1870	nullTestRun(t, spec)
1871}
1872
1873func TestNullBoolParam(t *testing.T) {
1874	spec := nullTestSpec{"nullbool", "bool", [6]nullTestRow{
1875		{NullBool{false, true}, true, NullBool{false, true}},
1876		{NullBool{true, false}, false, NullBool{false, false}},
1877		{true, true, NullBool{true, true}},
1878		{NullBool{true, true}, false, NullBool{true, true}},
1879		{NullBool{true, false}, true, NullBool{false, false}},
1880		{true, NullBool{true, false}, nil},
1881	}}
1882	nullTestRun(t, spec)
1883}
1884
1885func TestNullTimeParam(t *testing.T) {
1886	t0 := time.Time{}
1887	t1 := time.Date(2000, 1, 1, 8, 9, 10, 11, time.UTC)
1888	t2 := time.Date(2010, 1, 1, 8, 9, 10, 11, time.UTC)
1889	spec := nullTestSpec{"nulldatetime", "datetime", [6]nullTestRow{
1890		{NullTime{t1, true}, t2, NullTime{t1, true}},
1891		{NullTime{t1, false}, t2, NullTime{t0, false}},
1892		{t1, t2, NullTime{t1, true}},
1893		{NullTime{t1, true}, t2, NullTime{t1, true}},
1894		{NullTime{t1, false}, t2, NullTime{t0, false}},
1895		{t2, NullTime{t1, false}, nil},
1896	}}
1897	nullTestRun(t, spec)
1898}
1899
1900func nullTestRun(t *testing.T, spec nullTestSpec) {
1901	db := newTestDB(t, "")
1902	defer closeDB(t, db)
1903	exec(t, db, fmt.Sprintf("CREATE|t|id=int32,name=string,nullf=%s,notnullf=%s", spec.nullType, spec.notNullType))
1904
1905	// Inserts with db.Exec:
1906	exec(t, db, "INSERT|t|id=?,name=?,nullf=?,notnullf=?", 1, "alice", spec.rows[0].nullParam, spec.rows[0].notNullParam)
1907	exec(t, db, "INSERT|t|id=?,name=?,nullf=?,notnullf=?", 2, "bob", spec.rows[1].nullParam, spec.rows[1].notNullParam)
1908
1909	// Inserts with a prepared statement:
1910	stmt, err := db.Prepare("INSERT|t|id=?,name=?,nullf=?,notnullf=?")
1911	if err != nil {
1912		t.Fatalf("prepare: %v", err)
1913	}
1914	defer stmt.Close()
1915	if _, err := stmt.Exec(3, "chris", spec.rows[2].nullParam, spec.rows[2].notNullParam); err != nil {
1916		t.Errorf("exec insert chris: %v", err)
1917	}
1918	if _, err := stmt.Exec(4, "dave", spec.rows[3].nullParam, spec.rows[3].notNullParam); err != nil {
1919		t.Errorf("exec insert dave: %v", err)
1920	}
1921	if _, err := stmt.Exec(5, "eleanor", spec.rows[4].nullParam, spec.rows[4].notNullParam); err != nil {
1922		t.Errorf("exec insert eleanor: %v", err)
1923	}
1924
1925	// Can't put null val into non-null col
1926	row5 := spec.rows[5]
1927	if _, err := stmt.Exec(6, "bob", row5.nullParam, row5.notNullParam); err == nil {
1928		t.Errorf("expected error inserting nil val with prepared statement Exec: NULL=%#v, NOT-NULL=%#v", row5.nullParam, row5.notNullParam)
1929	}
1930
1931	_, err = db.Exec("INSERT|t|id=?,name=?,nullf=?", 999, nil, nil)
1932	if err == nil {
1933		// TODO: this test fails, but it's just because
1934		// fakeConn implements the optional Execer interface,
1935		// so arguably this is the correct behavior. But
1936		// maybe I should flesh out the fakeConn.Exec
1937		// implementation so this properly fails.
1938		// t.Errorf("expected error inserting nil name with Exec")
1939	}
1940
1941	paramtype := reflect.TypeOf(spec.rows[0].nullParam)
1942	bindVal := reflect.New(paramtype).Interface()
1943
1944	for i := 0; i < 5; i++ {
1945		id := i + 1
1946		if err := db.QueryRow("SELECT|t|nullf|id=?", id).Scan(bindVal); err != nil {
1947			t.Errorf("id=%d Scan: %v", id, err)
1948		}
1949		bindValDeref := reflect.ValueOf(bindVal).Elem().Interface()
1950		if !reflect.DeepEqual(bindValDeref, spec.rows[i].scanNullVal) {
1951			t.Errorf("id=%d got %#v, want %#v", id, bindValDeref, spec.rows[i].scanNullVal)
1952		}
1953	}
1954}
1955
1956// golang.org/issue/4859
1957func TestQueryRowNilScanDest(t *testing.T) {
1958	db := newTestDB(t, "people")
1959	defer closeDB(t, db)
1960	var name *string // nil pointer
1961	err := db.QueryRow("SELECT|people|name|").Scan(name)
1962	want := `sql: Scan error on column index 0, name "name": destination pointer is nil`
1963	if err == nil || err.Error() != want {
1964		t.Errorf("error = %q; want %q", err.Error(), want)
1965	}
1966}
1967
1968func TestIssue4902(t *testing.T) {
1969	db := newTestDB(t, "people")
1970	defer closeDB(t, db)
1971
1972	driver := db.Driver().(*fakeDriver)
1973	opens0 := driver.openCount
1974
1975	var stmt *Stmt
1976	var err error
1977	for i := 0; i < 10; i++ {
1978		stmt, err = db.Prepare("SELECT|people|name|")
1979		if err != nil {
1980			t.Fatal(err)
1981		}
1982		err = stmt.Close()
1983		if err != nil {
1984			t.Fatal(err)
1985		}
1986	}
1987
1988	opens := driver.openCount - opens0
1989	if opens > 1 {
1990		t.Errorf("opens = %d; want <= 1", opens)
1991		t.Logf("db = %#v", db)
1992		t.Logf("driver = %#v", driver)
1993		t.Logf("stmt = %#v", stmt)
1994	}
1995}
1996
1997// Issue 3857
1998// This used to deadlock.
1999func TestSimultaneousQueries(t *testing.T) {
2000	db := newTestDB(t, "people")
2001	defer closeDB(t, db)
2002
2003	tx, err := db.Begin()
2004	if err != nil {
2005		t.Fatal(err)
2006	}
2007	defer tx.Rollback()
2008
2009	r1, err := tx.Query("SELECT|people|name|")
2010	if err != nil {
2011		t.Fatal(err)
2012	}
2013	defer r1.Close()
2014
2015	r2, err := tx.Query("SELECT|people|name|")
2016	if err != nil {
2017		t.Fatal(err)
2018	}
2019	defer r2.Close()
2020}
2021
2022func TestMaxIdleConns(t *testing.T) {
2023	db := newTestDB(t, "people")
2024	defer closeDB(t, db)
2025
2026	tx, err := db.Begin()
2027	if err != nil {
2028		t.Fatal(err)
2029	}
2030	tx.Commit()
2031	if got := len(db.freeConn); got != 1 {
2032		t.Errorf("freeConns = %d; want 1", got)
2033	}
2034
2035	db.SetMaxIdleConns(0)
2036
2037	if got := len(db.freeConn); got != 0 {
2038		t.Errorf("freeConns after set to zero = %d; want 0", got)
2039	}
2040
2041	tx, err = db.Begin()
2042	if err != nil {
2043		t.Fatal(err)
2044	}
2045	tx.Commit()
2046	if got := len(db.freeConn); got != 0 {
2047		t.Errorf("freeConns = %d; want 0", got)
2048	}
2049}
2050
2051func TestMaxOpenConns(t *testing.T) {
2052	if testing.Short() {
2053		t.Skip("skipping in short mode")
2054	}
2055	defer setHookpostCloseConn(nil)
2056	setHookpostCloseConn(func(_ *fakeConn, err error) {
2057		if err != nil {
2058			t.Errorf("Error closing fakeConn: %v", err)
2059		}
2060	})
2061
2062	db := newTestDB(t, "magicquery")
2063	defer closeDB(t, db)
2064
2065	driver := db.Driver().(*fakeDriver)
2066
2067	// Force the number of open connections to 0 so we can get an accurate
2068	// count for the test
2069	db.clearAllConns(t)
2070
2071	driver.mu.Lock()
2072	opens0 := driver.openCount
2073	closes0 := driver.closeCount
2074	driver.mu.Unlock()
2075
2076	db.SetMaxIdleConns(10)
2077	db.SetMaxOpenConns(10)
2078
2079	stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?")
2080	if err != nil {
2081		t.Fatal(err)
2082	}
2083
2084	// Start 50 parallel slow queries.
2085	const (
2086		nquery      = 50
2087		sleepMillis = 25
2088		nbatch      = 2
2089	)
2090	var wg sync.WaitGroup
2091	for batch := 0; batch < nbatch; batch++ {
2092		for i := 0; i < nquery; i++ {
2093			wg.Add(1)
2094			go func() {
2095				defer wg.Done()
2096				var op string
2097				if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows {
2098					t.Error(err)
2099				}
2100			}()
2101		}
2102		// Wait for the batch of queries above to finish before starting the next round.
2103		wg.Wait()
2104	}
2105
2106	if g, w := db.numFreeConns(), 10; g != w {
2107		t.Errorf("free conns = %d; want %d", g, w)
2108	}
2109
2110	if n := db.numDepsPoll(t, 20); n > 20 {
2111		t.Errorf("number of dependencies = %d; expected <= 20", n)
2112		db.dumpDeps(t)
2113	}
2114
2115	driver.mu.Lock()
2116	opens := driver.openCount - opens0
2117	closes := driver.closeCount - closes0
2118	driver.mu.Unlock()
2119
2120	if opens > 10 {
2121		t.Logf("open calls = %d", opens)
2122		t.Logf("close calls = %d", closes)
2123		t.Errorf("db connections opened = %d; want <= 10", opens)
2124		db.dumpDeps(t)
2125	}
2126
2127	if err := stmt.Close(); err != nil {
2128		t.Fatal(err)
2129	}
2130
2131	if g, w := db.numFreeConns(), 10; g != w {
2132		t.Errorf("free conns = %d; want %d", g, w)
2133	}
2134
2135	if n := db.numDepsPoll(t, 10); n > 10 {
2136		t.Errorf("number of dependencies = %d; expected <= 10", n)
2137		db.dumpDeps(t)
2138	}
2139
2140	db.SetMaxOpenConns(5)
2141
2142	if g, w := db.numFreeConns(), 5; g != w {
2143		t.Errorf("free conns = %d; want %d", g, w)
2144	}
2145
2146	if n := db.numDepsPoll(t, 5); n > 5 {
2147		t.Errorf("number of dependencies = %d; expected 0", n)
2148		db.dumpDeps(t)
2149	}
2150
2151	db.SetMaxOpenConns(0)
2152
2153	if g, w := db.numFreeConns(), 5; g != w {
2154		t.Errorf("free conns = %d; want %d", g, w)
2155	}
2156
2157	if n := db.numDepsPoll(t, 5); n > 5 {
2158		t.Errorf("number of dependencies = %d; expected 0", n)
2159		db.dumpDeps(t)
2160	}
2161
2162	db.clearAllConns(t)
2163}
2164
2165// Issue 9453: tests that SetMaxOpenConns can be lowered at runtime
2166// and affects the subsequent release of connections.
2167func TestMaxOpenConnsOnBusy(t *testing.T) {
2168	defer setHookpostCloseConn(nil)
2169	setHookpostCloseConn(func(_ *fakeConn, err error) {
2170		if err != nil {
2171			t.Errorf("Error closing fakeConn: %v", err)
2172		}
2173	})
2174
2175	db := newTestDB(t, "magicquery")
2176	defer closeDB(t, db)
2177
2178	db.SetMaxOpenConns(3)
2179
2180	ctx := context.Background()
2181
2182	conn0, err := db.conn(ctx, cachedOrNewConn)
2183	if err != nil {
2184		t.Fatalf("db open conn fail: %v", err)
2185	}
2186
2187	conn1, err := db.conn(ctx, cachedOrNewConn)
2188	if err != nil {
2189		t.Fatalf("db open conn fail: %v", err)
2190	}
2191
2192	conn2, err := db.conn(ctx, cachedOrNewConn)
2193	if err != nil {
2194		t.Fatalf("db open conn fail: %v", err)
2195	}
2196
2197	if g, w := db.numOpen, 3; g != w {
2198		t.Errorf("free conns = %d; want %d", g, w)
2199	}
2200
2201	db.SetMaxOpenConns(2)
2202	if g, w := db.numOpen, 3; g != w {
2203		t.Errorf("free conns = %d; want %d", g, w)
2204	}
2205
2206	conn0.releaseConn(nil)
2207	conn1.releaseConn(nil)
2208	if g, w := db.numOpen, 2; g != w {
2209		t.Errorf("free conns = %d; want %d", g, w)
2210	}
2211
2212	conn2.releaseConn(nil)
2213	if g, w := db.numOpen, 2; g != w {
2214		t.Errorf("free conns = %d; want %d", g, w)
2215	}
2216}
2217
2218// Issue 10886: tests that all connection attempts return when more than
2219// DB.maxOpen connections are in flight and the first DB.maxOpen fail.
2220func TestPendingConnsAfterErr(t *testing.T) {
2221	const (
2222		maxOpen = 2
2223		tryOpen = maxOpen*2 + 2
2224	)
2225
2226	// No queries will be run.
2227	db, err := Open("test", fakeDBName)
2228	if err != nil {
2229		t.Fatalf("Open: %v", err)
2230	}
2231	defer closeDB(t, db)
2232	defer func() {
2233		for k, v := range db.lastPut {
2234			t.Logf("%p: %v", k, v)
2235		}
2236	}()
2237
2238	db.SetMaxOpenConns(maxOpen)
2239	db.SetMaxIdleConns(0)
2240
2241	errOffline := errors.New("db offline")
2242
2243	defer func() { setHookOpenErr(nil) }()
2244
2245	errs := make(chan error, tryOpen)
2246
2247	var opening sync.WaitGroup
2248	opening.Add(tryOpen)
2249
2250	setHookOpenErr(func() error {
2251		// Wait for all connections to enqueue.
2252		opening.Wait()
2253		return errOffline
2254	})
2255
2256	for i := 0; i < tryOpen; i++ {
2257		go func() {
2258			opening.Done() // signal one connection is in flight
2259			_, err := db.Exec("will never run")
2260			errs <- err
2261		}()
2262	}
2263
2264	opening.Wait() // wait for all workers to begin running
2265
2266	const timeout = 5 * time.Second
2267	to := time.NewTimer(timeout)
2268	defer to.Stop()
2269
2270	// check that all connections fail without deadlock
2271	for i := 0; i < tryOpen; i++ {
2272		select {
2273		case err := <-errs:
2274			if got, want := err, errOffline; got != want {
2275				t.Errorf("unexpected err: got %v, want %v", got, want)
2276			}
2277		case <-to.C:
2278			t.Fatalf("orphaned connection request(s), still waiting after %v", timeout)
2279		}
2280	}
2281
2282	// Wait a reasonable time for the database to close all connections.
2283	tick := time.NewTicker(3 * time.Millisecond)
2284	defer tick.Stop()
2285	for {
2286		select {
2287		case <-tick.C:
2288			db.mu.Lock()
2289			if db.numOpen == 0 {
2290				db.mu.Unlock()
2291				return
2292			}
2293			db.mu.Unlock()
2294		case <-to.C:
2295			// Closing the database will check for numOpen and fail the test.
2296			return
2297		}
2298	}
2299}
2300
2301func TestSingleOpenConn(t *testing.T) {
2302	db := newTestDB(t, "people")
2303	defer closeDB(t, db)
2304
2305	db.SetMaxOpenConns(1)
2306
2307	rows, err := db.Query("SELECT|people|name|")
2308	if err != nil {
2309		t.Fatal(err)
2310	}
2311	if err = rows.Close(); err != nil {
2312		t.Fatal(err)
2313	}
2314	// shouldn't deadlock
2315	rows, err = db.Query("SELECT|people|name|")
2316	if err != nil {
2317		t.Fatal(err)
2318	}
2319	if err = rows.Close(); err != nil {
2320		t.Fatal(err)
2321	}
2322}
2323
2324func TestStats(t *testing.T) {
2325	db := newTestDB(t, "people")
2326	stats := db.Stats()
2327	if got := stats.OpenConnections; got != 1 {
2328		t.Errorf("stats.OpenConnections = %d; want 1", got)
2329	}
2330
2331	tx, err := db.Begin()
2332	if err != nil {
2333		t.Fatal(err)
2334	}
2335	tx.Commit()
2336
2337	closeDB(t, db)
2338	stats = db.Stats()
2339	if got := stats.OpenConnections; got != 0 {
2340		t.Errorf("stats.OpenConnections = %d; want 0", got)
2341	}
2342}
2343
2344func TestConnMaxLifetime(t *testing.T) {
2345	t0 := time.Unix(1000000, 0)
2346	offset := time.Duration(0)
2347
2348	nowFunc = func() time.Time { return t0.Add(offset) }
2349	defer func() { nowFunc = time.Now }()
2350
2351	db := newTestDB(t, "magicquery")
2352	defer closeDB(t, db)
2353
2354	driver := db.Driver().(*fakeDriver)
2355
2356	// Force the number of open connections to 0 so we can get an accurate
2357	// count for the test
2358	db.clearAllConns(t)
2359
2360	driver.mu.Lock()
2361	opens0 := driver.openCount
2362	closes0 := driver.closeCount
2363	driver.mu.Unlock()
2364
2365	db.SetMaxIdleConns(10)
2366	db.SetMaxOpenConns(10)
2367
2368	tx, err := db.Begin()
2369	if err != nil {
2370		t.Fatal(err)
2371	}
2372
2373	offset = time.Second
2374	tx2, err := db.Begin()
2375	if err != nil {
2376		t.Fatal(err)
2377	}
2378
2379	tx.Commit()
2380	tx2.Commit()
2381
2382	driver.mu.Lock()
2383	opens := driver.openCount - opens0
2384	closes := driver.closeCount - closes0
2385	driver.mu.Unlock()
2386
2387	if opens != 2 {
2388		t.Errorf("opens = %d; want 2", opens)
2389	}
2390	if closes != 0 {
2391		t.Errorf("closes = %d; want 0", closes)
2392	}
2393	if g, w := db.numFreeConns(), 2; g != w {
2394		t.Errorf("free conns = %d; want %d", g, w)
2395	}
2396
2397	// Expire first conn
2398	offset = 11 * time.Second
2399	db.SetConnMaxLifetime(10 * time.Second)
2400
2401	tx, err = db.Begin()
2402	if err != nil {
2403		t.Fatal(err)
2404	}
2405	tx2, err = db.Begin()
2406	if err != nil {
2407		t.Fatal(err)
2408	}
2409	tx.Commit()
2410	tx2.Commit()
2411
2412	// Give connectionCleaner chance to run.
2413	waitCondition(t, func() bool {
2414		driver.mu.Lock()
2415		opens = driver.openCount - opens0
2416		closes = driver.closeCount - closes0
2417		driver.mu.Unlock()
2418
2419		return closes == 1
2420	})
2421
2422	if opens != 3 {
2423		t.Errorf("opens = %d; want 3", opens)
2424	}
2425	if closes != 1 {
2426		t.Errorf("closes = %d; want 1", closes)
2427	}
2428
2429	if s := db.Stats(); s.MaxLifetimeClosed != 1 {
2430		t.Errorf("MaxLifetimeClosed = %d; want 1 %#v", s.MaxLifetimeClosed, s)
2431	}
2432}
2433
2434// golang.org/issue/5323
2435func TestStmtCloseDeps(t *testing.T) {
2436	if testing.Short() {
2437		t.Skip("skipping in short mode")
2438	}
2439	defer setHookpostCloseConn(nil)
2440	setHookpostCloseConn(func(_ *fakeConn, err error) {
2441		if err != nil {
2442			t.Errorf("Error closing fakeConn: %v", err)
2443		}
2444	})
2445
2446	db := newTestDB(t, "magicquery")
2447	defer closeDB(t, db)
2448
2449	driver := db.Driver().(*fakeDriver)
2450
2451	driver.mu.Lock()
2452	opens0 := driver.openCount
2453	closes0 := driver.closeCount
2454	driver.mu.Unlock()
2455	openDelta0 := opens0 - closes0
2456
2457	stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?")
2458	if err != nil {
2459		t.Fatal(err)
2460	}
2461
2462	// Start 50 parallel slow queries.
2463	const (
2464		nquery      = 50
2465		sleepMillis = 25
2466		nbatch      = 2
2467	)
2468	var wg sync.WaitGroup
2469	for batch := 0; batch < nbatch; batch++ {
2470		for i := 0; i < nquery; i++ {
2471			wg.Add(1)
2472			go func() {
2473				defer wg.Done()
2474				var op string
2475				if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows {
2476					t.Error(err)
2477				}
2478			}()
2479		}
2480		// Wait for the batch of queries above to finish before starting the next round.
2481		wg.Wait()
2482	}
2483
2484	if g, w := db.numFreeConns(), 2; g != w {
2485		t.Errorf("free conns = %d; want %d", g, w)
2486	}
2487
2488	if n := db.numDepsPoll(t, 4); n > 4 {
2489		t.Errorf("number of dependencies = %d; expected <= 4", n)
2490		db.dumpDeps(t)
2491	}
2492
2493	driver.mu.Lock()
2494	opens := driver.openCount - opens0
2495	closes := driver.closeCount - closes0
2496	openDelta := (driver.openCount - driver.closeCount) - openDelta0
2497	driver.mu.Unlock()
2498
2499	if openDelta > 2 {
2500		t.Logf("open calls = %d", opens)
2501		t.Logf("close calls = %d", closes)
2502		t.Logf("open delta = %d", openDelta)
2503		t.Errorf("db connections opened = %d; want <= 2", openDelta)
2504		db.dumpDeps(t)
2505	}
2506
2507	if !waitCondition(t, func() bool {
2508		return len(stmt.css) <= nquery
2509	}) {
2510		t.Errorf("len(stmt.css) = %d; want <= %d", len(stmt.css), nquery)
2511	}
2512
2513	if err := stmt.Close(); err != nil {
2514		t.Fatal(err)
2515	}
2516
2517	if g, w := db.numFreeConns(), 2; g != w {
2518		t.Errorf("free conns = %d; want %d", g, w)
2519	}
2520
2521	if n := db.numDepsPoll(t, 2); n > 2 {
2522		t.Errorf("number of dependencies = %d; expected <= 2", n)
2523		db.dumpDeps(t)
2524	}
2525
2526	db.clearAllConns(t)
2527}
2528
2529// golang.org/issue/5046
2530func TestCloseConnBeforeStmts(t *testing.T) {
2531	db := newTestDB(t, "people")
2532	defer closeDB(t, db)
2533
2534	defer setHookpostCloseConn(nil)
2535	setHookpostCloseConn(func(_ *fakeConn, err error) {
2536		if err != nil {
2537			t.Errorf("Error closing fakeConn: %v; from %s", err, stack())
2538			db.dumpDeps(t)
2539			t.Errorf("DB = %#v", db)
2540		}
2541	})
2542
2543	stmt, err := db.Prepare("SELECT|people|name|")
2544	if err != nil {
2545		t.Fatal(err)
2546	}
2547
2548	if len(db.freeConn) != 1 {
2549		t.Fatalf("expected 1 freeConn; got %d", len(db.freeConn))
2550	}
2551	dc := db.freeConn[0]
2552	if dc.closed {
2553		t.Errorf("conn shouldn't be closed")
2554	}
2555
2556	if n := len(dc.openStmt); n != 1 {
2557		t.Errorf("driverConn num openStmt = %d; want 1", n)
2558	}
2559	err = db.Close()
2560	if err != nil {
2561		t.Errorf("db Close = %v", err)
2562	}
2563	if !dc.closed {
2564		t.Errorf("after db.Close, driverConn should be closed")
2565	}
2566	if n := len(dc.openStmt); n != 0 {
2567		t.Errorf("driverConn num openStmt = %d; want 0", n)
2568	}
2569
2570	err = stmt.Close()
2571	if err != nil {
2572		t.Errorf("Stmt close = %v", err)
2573	}
2574
2575	if !dc.closed {
2576		t.Errorf("conn should be closed")
2577	}
2578	if dc.ci != nil {
2579		t.Errorf("after Stmt Close, driverConn's Conn interface should be nil")
2580	}
2581}
2582
2583// golang.org/issue/5283: don't release the Rows' connection in Close
2584// before calling Stmt.Close.
2585func TestRowsCloseOrder(t *testing.T) {
2586	db := newTestDB(t, "people")
2587	defer closeDB(t, db)
2588
2589	db.SetMaxIdleConns(0)
2590	setStrictFakeConnClose(t)
2591	defer setStrictFakeConnClose(nil)
2592
2593	rows, err := db.Query("SELECT|people|age,name|")
2594	if err != nil {
2595		t.Fatal(err)
2596	}
2597	err = rows.Close()
2598	if err != nil {
2599		t.Fatal(err)
2600	}
2601}
2602
2603func TestRowsImplicitClose(t *testing.T) {
2604	db := newTestDB(t, "people")
2605	defer closeDB(t, db)
2606
2607	rows, err := db.Query("SELECT|people|age,name|")
2608	if err != nil {
2609		t.Fatal(err)
2610	}
2611
2612	want, fail := 2, errors.New("fail")
2613	r := rows.rowsi.(*rowsCursor)
2614	r.errPos, r.err = want, fail
2615
2616	got := 0
2617	for rows.Next() {
2618		got++
2619	}
2620	if got != want {
2621		t.Errorf("got %d rows, want %d", got, want)
2622	}
2623	if err := rows.Err(); err != fail {
2624		t.Errorf("got error %v, want %v", err, fail)
2625	}
2626	if !r.closed {
2627		t.Errorf("r.closed is false, want true")
2628	}
2629}
2630
2631func TestRowsCloseError(t *testing.T) {
2632	db := newTestDB(t, "people")
2633	defer db.Close()
2634	rows, err := db.Query("SELECT|people|age,name|")
2635	if err != nil {
2636		t.Fatalf("Query: %v", err)
2637	}
2638	type row struct {
2639		age  int
2640		name string
2641	}
2642	got := []row{}
2643
2644	rc, ok := rows.rowsi.(*rowsCursor)
2645	if !ok {
2646		t.Fatal("not using *rowsCursor")
2647	}
2648	rc.closeErr = errors.New("rowsCursor: failed to close")
2649
2650	for rows.Next() {
2651		var r row
2652		err = rows.Scan(&r.age, &r.name)
2653		if err != nil {
2654			t.Fatalf("Scan: %v", err)
2655		}
2656		got = append(got, r)
2657	}
2658	err = rows.Err()
2659	if err != rc.closeErr {
2660		t.Fatalf("unexpected err: got %v, want %v", err, rc.closeErr)
2661	}
2662}
2663
2664func TestStmtCloseOrder(t *testing.T) {
2665	db := newTestDB(t, "people")
2666	defer closeDB(t, db)
2667
2668	db.SetMaxIdleConns(0)
2669	setStrictFakeConnClose(t)
2670	defer setStrictFakeConnClose(nil)
2671
2672	_, err := db.Query("SELECT|non_existent|name|")
2673	if err == nil {
2674		t.Fatal("Querying non-existent table should fail")
2675	}
2676}
2677
2678// Test cases where there's more than maxBadConnRetries bad connections in the
2679// pool (issue 8834)
2680func TestManyErrBadConn(t *testing.T) {
2681	manyErrBadConnSetup := func(first ...func(db *DB)) *DB {
2682		db := newTestDB(t, "people")
2683
2684		for _, f := range first {
2685			f(db)
2686		}
2687
2688		nconn := maxBadConnRetries + 1
2689		db.SetMaxIdleConns(nconn)
2690		db.SetMaxOpenConns(nconn)
2691		// open enough connections
2692		func() {
2693			for i := 0; i < nconn; i++ {
2694				rows, err := db.Query("SELECT|people|age,name|")
2695				if err != nil {
2696					t.Fatal(err)
2697				}
2698				defer rows.Close()
2699			}
2700		}()
2701
2702		db.mu.Lock()
2703		defer db.mu.Unlock()
2704		if db.numOpen != nconn {
2705			t.Fatalf("unexpected numOpen %d (was expecting %d)", db.numOpen, nconn)
2706		} else if len(db.freeConn) != nconn {
2707			t.Fatalf("unexpected len(db.freeConn) %d (was expecting %d)", len(db.freeConn), nconn)
2708		}
2709		for _, conn := range db.freeConn {
2710			conn.Lock()
2711			conn.ci.(*fakeConn).stickyBad = true
2712			conn.Unlock()
2713		}
2714		return db
2715	}
2716
2717	// Query
2718	db := manyErrBadConnSetup()
2719	defer closeDB(t, db)
2720	rows, err := db.Query("SELECT|people|age,name|")
2721	if err != nil {
2722		t.Fatal(err)
2723	}
2724	if err = rows.Close(); err != nil {
2725		t.Fatal(err)
2726	}
2727
2728	// Exec
2729	db = manyErrBadConnSetup()
2730	defer closeDB(t, db)
2731	_, err = db.Exec("INSERT|people|name=Julia,age=19")
2732	if err != nil {
2733		t.Fatal(err)
2734	}
2735
2736	// Begin
2737	db = manyErrBadConnSetup()
2738	defer closeDB(t, db)
2739	tx, err := db.Begin()
2740	if err != nil {
2741		t.Fatal(err)
2742	}
2743	if err = tx.Rollback(); err != nil {
2744		t.Fatal(err)
2745	}
2746
2747	// Prepare
2748	db = manyErrBadConnSetup()
2749	defer closeDB(t, db)
2750	stmt, err := db.Prepare("SELECT|people|age,name|")
2751	if err != nil {
2752		t.Fatal(err)
2753	}
2754	if err = stmt.Close(); err != nil {
2755		t.Fatal(err)
2756	}
2757
2758	// Stmt.Exec
2759	db = manyErrBadConnSetup(func(db *DB) {
2760		stmt, err = db.Prepare("INSERT|people|name=Julia,age=19")
2761		if err != nil {
2762			t.Fatal(err)
2763		}
2764	})
2765	defer closeDB(t, db)
2766	_, err = stmt.Exec()
2767	if err != nil {
2768		t.Fatal(err)
2769	}
2770	if err = stmt.Close(); err != nil {
2771		t.Fatal(err)
2772	}
2773
2774	// Stmt.Query
2775	db = manyErrBadConnSetup(func(db *DB) {
2776		stmt, err = db.Prepare("SELECT|people|age,name|")
2777		if err != nil {
2778			t.Fatal(err)
2779		}
2780	})
2781	defer closeDB(t, db)
2782	rows, err = stmt.Query()
2783	if err != nil {
2784		t.Fatal(err)
2785	}
2786	if err = rows.Close(); err != nil {
2787		t.Fatal(err)
2788	}
2789	if err = stmt.Close(); err != nil {
2790		t.Fatal(err)
2791	}
2792
2793	// Conn
2794	db = manyErrBadConnSetup()
2795	defer closeDB(t, db)
2796	ctx, cancel := context.WithCancel(context.Background())
2797	defer cancel()
2798	conn, err := db.Conn(ctx)
2799	if err != nil {
2800		t.Fatal(err)
2801	}
2802	conn.dc.ci.(*fakeConn).skipDirtySession = true
2803	err = conn.Close()
2804	if err != nil {
2805		t.Fatal(err)
2806	}
2807
2808	// Ping
2809	db = manyErrBadConnSetup()
2810	defer closeDB(t, db)
2811	err = db.PingContext(ctx)
2812	if err != nil {
2813		t.Fatal(err)
2814	}
2815}
2816
2817// Issue 34775: Ensure that a Tx cannot commit after a rollback.
2818func TestTxCannotCommitAfterRollback(t *testing.T) {
2819	db := newTestDB(t, "tx_status")
2820	defer closeDB(t, db)
2821
2822	// First check query reporting is correct.
2823	var txStatus string
2824	err := db.QueryRow("SELECT|tx_status|tx_status|").Scan(&txStatus)
2825	if err != nil {
2826		t.Fatal(err)
2827	}
2828	if g, w := txStatus, "autocommit"; g != w {
2829		t.Fatalf("tx_status=%q, wanted %q", g, w)
2830	}
2831
2832	ctx, cancel := context.WithCancel(context.Background())
2833	defer cancel()
2834
2835	tx, err := db.BeginTx(ctx, nil)
2836	if err != nil {
2837		t.Fatal(err)
2838	}
2839
2840	// Ignore dirty session for this test.
2841	// A failing test should trigger the dirty session flag as well,
2842	// but that isn't exactly what this should test for.
2843	tx.txi.(*fakeTx).c.skipDirtySession = true
2844
2845	defer tx.Rollback()
2846
2847	err = tx.QueryRow("SELECT|tx_status|tx_status|").Scan(&txStatus)
2848	if err != nil {
2849		t.Fatal(err)
2850	}
2851	if g, w := txStatus, "transaction"; g != w {
2852		t.Fatalf("tx_status=%q, wanted %q", g, w)
2853	}
2854
2855	// 1. Begin a transaction.
2856	// 2. (A) Start a query, (B) begin Tx rollback through a ctx cancel.
2857	// 3. Check if 2.A has committed in Tx (pass) or outside of Tx (fail).
2858	sendQuery := make(chan struct{})
2859	// The Tx status is returned through the row results, ensure
2860	// that the rows results are not canceled.
2861	bypassRowsAwaitDone = true
2862	hookTxGrabConn = func() {
2863		cancel()
2864		<-sendQuery
2865	}
2866	rollbackHook = func() {
2867		close(sendQuery)
2868	}
2869	defer func() {
2870		hookTxGrabConn = nil
2871		rollbackHook = nil
2872		bypassRowsAwaitDone = false
2873	}()
2874
2875	err = tx.QueryRow("SELECT|tx_status|tx_status|").Scan(&txStatus)
2876	if err != nil {
2877		// A failure here would be expected if skipDirtySession was not set to true above.
2878		t.Fatal(err)
2879	}
2880	if g, w := txStatus, "transaction"; g != w {
2881		t.Fatalf("tx_status=%q, wanted %q", g, w)
2882	}
2883}
2884
2885// Issue 40985 transaction statement deadlock while context cancel.
2886func TestTxStmtDeadlock(t *testing.T) {
2887	db := newTestDB(t, "people")
2888	defer closeDB(t, db)
2889
2890	ctx, cancel := context.WithCancel(context.Background())
2891	defer cancel()
2892	tx, err := db.BeginTx(ctx, nil)
2893	if err != nil {
2894		t.Fatal(err)
2895	}
2896
2897	stmt, err := tx.Prepare("SELECT|people|name,age|age=?")
2898	if err != nil {
2899		t.Fatal(err)
2900	}
2901	cancel()
2902	// Run number of stmt queries to reproduce deadlock from context cancel
2903	for i := 0; i < 1e3; i++ {
2904		// Encounter any close related errors (e.g. ErrTxDone, stmt is closed)
2905		// is expected due to context cancel.
2906		_, err = stmt.Query(1)
2907		if err != nil {
2908			break
2909		}
2910	}
2911	_ = tx.Rollback()
2912}
2913
2914// Issue32530 encounters an issue where a connection may
2915// expire right after it comes out of a used connection pool
2916// even when a new connection is requested.
2917func TestConnExpiresFreshOutOfPool(t *testing.T) {
2918	execCases := []struct {
2919		expired  bool
2920		badReset bool
2921	}{
2922		{false, false},
2923		{true, false},
2924		{false, true},
2925	}
2926
2927	t0 := time.Unix(1000000, 0)
2928	offset := time.Duration(0)
2929	offsetMu := sync.RWMutex{}
2930
2931	nowFunc = func() time.Time {
2932		offsetMu.RLock()
2933		defer offsetMu.RUnlock()
2934		return t0.Add(offset)
2935	}
2936	defer func() { nowFunc = time.Now }()
2937
2938	ctx, cancel := context.WithCancel(context.Background())
2939	defer cancel()
2940
2941	db := newTestDB(t, "magicquery")
2942	defer closeDB(t, db)
2943
2944	db.SetMaxOpenConns(1)
2945
2946	for _, ec := range execCases {
2947		ec := ec
2948		name := fmt.Sprintf("expired=%t,badReset=%t", ec.expired, ec.badReset)
2949		t.Run(name, func(t *testing.T) {
2950			db.clearAllConns(t)
2951
2952			db.SetMaxIdleConns(1)
2953			db.SetConnMaxLifetime(10 * time.Second)
2954
2955			conn, err := db.conn(ctx, alwaysNewConn)
2956			if err != nil {
2957				t.Fatal(err)
2958			}
2959
2960			afterPutConn := make(chan struct{})
2961			waitingForConn := make(chan struct{})
2962
2963			go func() {
2964				defer close(afterPutConn)
2965
2966				conn, err := db.conn(ctx, alwaysNewConn)
2967				if err == nil {
2968					db.putConn(conn, err, false)
2969				} else {
2970					t.Errorf("db.conn: %v", err)
2971				}
2972			}()
2973			go func() {
2974				defer close(waitingForConn)
2975
2976				for {
2977					if t.Failed() {
2978						return
2979					}
2980					db.mu.Lock()
2981					ct := db.connRequests.Len()
2982					db.mu.Unlock()
2983					if ct > 0 {
2984						return
2985					}
2986					time.Sleep(pollDuration)
2987				}
2988			}()
2989
2990			<-waitingForConn
2991
2992			if t.Failed() {
2993				return
2994			}
2995
2996			offsetMu.Lock()
2997			if ec.expired {
2998				offset = 11 * time.Second
2999			} else {
3000				offset = time.Duration(0)
3001			}
3002			offsetMu.Unlock()
3003
3004			conn.ci.(*fakeConn).stickyBad = ec.badReset
3005
3006			db.putConn(conn, err, true)
3007
3008			<-afterPutConn
3009		})
3010	}
3011}
3012
3013// TestIssue20575 ensures the Rows from query does not block
3014// closing a transaction. Ensure Rows is closed while closing a transaction.
3015func TestIssue20575(t *testing.T) {
3016	db := newTestDB(t, "people")
3017	defer closeDB(t, db)
3018
3019	tx, err := db.Begin()
3020	if err != nil {
3021		t.Fatal(err)
3022	}
3023	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
3024	defer cancel()
3025	_, err = tx.QueryContext(ctx, "SELECT|people|age,name|")
3026	if err != nil {
3027		t.Fatal(err)
3028	}
3029	// Do not close Rows from QueryContext.
3030	err = tx.Rollback()
3031	if err != nil {
3032		t.Fatal(err)
3033	}
3034	select {
3035	default:
3036	case <-ctx.Done():
3037		t.Fatal("timeout: failed to rollback query without closing rows:", ctx.Err())
3038	}
3039}
3040
3041// TestIssue20622 tests closing the transaction before rows is closed, requires
3042// the race detector to fail.
3043func TestIssue20622(t *testing.T) {
3044	db := newTestDB(t, "people")
3045	defer closeDB(t, db)
3046
3047	ctx, cancel := context.WithCancel(context.Background())
3048	defer cancel()
3049
3050	tx, err := db.BeginTx(ctx, nil)
3051	if err != nil {
3052		t.Fatal(err)
3053	}
3054
3055	rows, err := tx.Query("SELECT|people|age,name|")
3056	if err != nil {
3057		t.Fatal(err)
3058	}
3059
3060	count := 0
3061	for rows.Next() {
3062		count++
3063		var age int
3064		var name string
3065		if err := rows.Scan(&age, &name); err != nil {
3066			t.Fatal("scan failed", err)
3067		}
3068
3069		if count == 1 {
3070			cancel()
3071		}
3072		time.Sleep(100 * time.Millisecond)
3073	}
3074	rows.Close()
3075	tx.Commit()
3076}
3077
3078// golang.org/issue/5718
3079func TestErrBadConnReconnect(t *testing.T) {
3080	db := newTestDB(t, "foo")
3081	defer closeDB(t, db)
3082	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
3083
3084	simulateBadConn := func(name string, hook *func() bool, op func() error) {
3085		broken, retried := false, false
3086		numOpen := db.numOpen
3087
3088		// simulate a broken connection on the first try
3089		*hook = func() bool {
3090			if !broken {
3091				broken = true
3092				return true
3093			}
3094			retried = true
3095			return false
3096		}
3097
3098		if err := op(); err != nil {
3099			t.Errorf(name+": %v", err)
3100			return
3101		}
3102
3103		if !broken || !retried {
3104			t.Error(name + ": Failed to simulate broken connection")
3105		}
3106		*hook = nil
3107
3108		if numOpen != db.numOpen {
3109			t.Errorf(name+": leaked %d connection(s)!", db.numOpen-numOpen)
3110			numOpen = db.numOpen
3111		}
3112	}
3113
3114	// db.Exec
3115	dbExec := func() error {
3116		_, err := db.Exec("INSERT|t1|name=?,age=?,dead=?", "Gordon", 3, true)
3117		return err
3118	}
3119	simulateBadConn("db.Exec prepare", &hookPrepareBadConn, dbExec)
3120	simulateBadConn("db.Exec exec", &hookExecBadConn, dbExec)
3121
3122	// db.Query
3123	dbQuery := func() error {
3124		rows, err := db.Query("SELECT|t1|age,name|")
3125		if err == nil {
3126			err = rows.Close()
3127		}
3128		return err
3129	}
3130	simulateBadConn("db.Query prepare", &hookPrepareBadConn, dbQuery)
3131	simulateBadConn("db.Query query", &hookQueryBadConn, dbQuery)
3132
3133	// db.Prepare
3134	simulateBadConn("db.Prepare", &hookPrepareBadConn, func() error {
3135		stmt, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?")
3136		if err != nil {
3137			return err
3138		}
3139		stmt.Close()
3140		return nil
3141	})
3142
3143	// Provide a way to force a re-prepare of a statement on next execution
3144	forcePrepare := func(stmt *Stmt) {
3145		stmt.css = nil
3146	}
3147
3148	// stmt.Exec
3149	stmt1, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?")
3150	if err != nil {
3151		t.Fatalf("prepare: %v", err)
3152	}
3153	defer stmt1.Close()
3154	// make sure we must prepare the stmt first
3155	forcePrepare(stmt1)
3156
3157	stmtExec := func() error {
3158		_, err := stmt1.Exec("Gopher", 3, false)
3159		return err
3160	}
3161	simulateBadConn("stmt.Exec prepare", &hookPrepareBadConn, stmtExec)
3162	simulateBadConn("stmt.Exec exec", &hookExecBadConn, stmtExec)
3163
3164	// stmt.Query
3165	stmt2, err := db.Prepare("SELECT|t1|age,name|")
3166	if err != nil {
3167		t.Fatalf("prepare: %v", err)
3168	}
3169	defer stmt2.Close()
3170	// make sure we must prepare the stmt first
3171	forcePrepare(stmt2)
3172
3173	stmtQuery := func() error {
3174		rows, err := stmt2.Query()
3175		if err == nil {
3176			err = rows.Close()
3177		}
3178		return err
3179	}
3180	simulateBadConn("stmt.Query prepare", &hookPrepareBadConn, stmtQuery)
3181	simulateBadConn("stmt.Query exec", &hookQueryBadConn, stmtQuery)
3182}
3183
3184// golang.org/issue/11264
3185func TestTxEndBadConn(t *testing.T) {
3186	db := newTestDB(t, "foo")
3187	defer closeDB(t, db)
3188	db.SetMaxIdleConns(0)
3189	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
3190	db.SetMaxIdleConns(1)
3191
3192	simulateBadConn := func(name string, hook *func() bool, op func() error) {
3193		broken := false
3194		numOpen := db.numOpen
3195
3196		*hook = func() bool {
3197			if !broken {
3198				broken = true
3199			}
3200			return broken
3201		}
3202
3203		if err := op(); !errors.Is(err, driver.ErrBadConn) {
3204			t.Errorf(name+": %v", err)
3205			return
3206		}
3207
3208		if !broken {
3209			t.Error(name + ": Failed to simulate broken connection")
3210		}
3211		*hook = nil
3212
3213		if numOpen != db.numOpen {
3214			t.Errorf(name+": leaked %d connection(s)!", db.numOpen-numOpen)
3215		}
3216	}
3217
3218	// db.Exec
3219	dbExec := func(endTx func(tx *Tx) error) func() error {
3220		return func() error {
3221			tx, err := db.Begin()
3222			if err != nil {
3223				return err
3224			}
3225			_, err = tx.Exec("INSERT|t1|name=?,age=?,dead=?", "Gordon", 3, true)
3226			if err != nil {
3227				return err
3228			}
3229			return endTx(tx)
3230		}
3231	}
3232	simulateBadConn("db.Tx.Exec commit", &hookCommitBadConn, dbExec((*Tx).Commit))
3233	simulateBadConn("db.Tx.Exec rollback", &hookRollbackBadConn, dbExec((*Tx).Rollback))
3234
3235	// db.Query
3236	dbQuery := func(endTx func(tx *Tx) error) func() error {
3237		return func() error {
3238			tx, err := db.Begin()
3239			if err != nil {
3240				return err
3241			}
3242			rows, err := tx.Query("SELECT|t1|age,name|")
3243			if err == nil {
3244				err = rows.Close()
3245			} else {
3246				return err
3247			}
3248			return endTx(tx)
3249		}
3250	}
3251	simulateBadConn("db.Tx.Query commit", &hookCommitBadConn, dbQuery((*Tx).Commit))
3252	simulateBadConn("db.Tx.Query rollback", &hookRollbackBadConn, dbQuery((*Tx).Rollback))
3253}
3254
3255type concurrentTest interface {
3256	init(t testing.TB, db *DB)
3257	finish(t testing.TB)
3258	test(t testing.TB) error
3259}
3260
3261type concurrentDBQueryTest struct {
3262	db *DB
3263}
3264
3265func (c *concurrentDBQueryTest) init(t testing.TB, db *DB) {
3266	c.db = db
3267}
3268
3269func (c *concurrentDBQueryTest) finish(t testing.TB) {
3270	c.db = nil
3271}
3272
3273func (c *concurrentDBQueryTest) test(t testing.TB) error {
3274	rows, err := c.db.Query("SELECT|people|name|")
3275	if err != nil {
3276		t.Error(err)
3277		return err
3278	}
3279	var name string
3280	for rows.Next() {
3281		rows.Scan(&name)
3282	}
3283	rows.Close()
3284	return nil
3285}
3286
3287type concurrentDBExecTest struct {
3288	db *DB
3289}
3290
3291func (c *concurrentDBExecTest) init(t testing.TB, db *DB) {
3292	c.db = db
3293}
3294
3295func (c *concurrentDBExecTest) finish(t testing.TB) {
3296	c.db = nil
3297}
3298
3299func (c *concurrentDBExecTest) test(t testing.TB) error {
3300	_, err := c.db.Exec("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
3301	if err != nil {
3302		t.Error(err)
3303		return err
3304	}
3305	return nil
3306}
3307
3308type concurrentStmtQueryTest struct {
3309	db   *DB
3310	stmt *Stmt
3311}
3312
3313func (c *concurrentStmtQueryTest) init(t testing.TB, db *DB) {
3314	c.db = db
3315	var err error
3316	c.stmt, err = db.Prepare("SELECT|people|name|")
3317	if err != nil {
3318		t.Fatal(err)
3319	}
3320}
3321
3322func (c *concurrentStmtQueryTest) finish(t testing.TB) {
3323	if c.stmt != nil {
3324		c.stmt.Close()
3325		c.stmt = nil
3326	}
3327	c.db = nil
3328}
3329
3330func (c *concurrentStmtQueryTest) test(t testing.TB) error {
3331	rows, err := c.stmt.Query()
3332	if err != nil {
3333		t.Errorf("error on query:  %v", err)
3334		return err
3335	}
3336
3337	var name string
3338	for rows.Next() {
3339		rows.Scan(&name)
3340	}
3341	rows.Close()
3342	return nil
3343}
3344
3345type concurrentStmtExecTest struct {
3346	db   *DB
3347	stmt *Stmt
3348}
3349
3350func (c *concurrentStmtExecTest) init(t testing.TB, db *DB) {
3351	c.db = db
3352	var err error
3353	c.stmt, err = db.Prepare("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?")
3354	if err != nil {
3355		t.Fatal(err)
3356	}
3357}
3358
3359func (c *concurrentStmtExecTest) finish(t testing.TB) {
3360	if c.stmt != nil {
3361		c.stmt.Close()
3362		c.stmt = nil
3363	}
3364	c.db = nil
3365}
3366
3367func (c *concurrentStmtExecTest) test(t testing.TB) error {
3368	_, err := c.stmt.Exec(3, chrisBirthday)
3369	if err != nil {
3370		t.Errorf("error on exec:  %v", err)
3371		return err
3372	}
3373	return nil
3374}
3375
3376type concurrentTxQueryTest struct {
3377	db *DB
3378	tx *Tx
3379}
3380
3381func (c *concurrentTxQueryTest) init(t testing.TB, db *DB) {
3382	c.db = db
3383	var err error
3384	c.tx, err = c.db.Begin()
3385	if err != nil {
3386		t.Fatal(err)
3387	}
3388}
3389
3390func (c *concurrentTxQueryTest) finish(t testing.TB) {
3391	if c.tx != nil {
3392		c.tx.Rollback()
3393		c.tx = nil
3394	}
3395	c.db = nil
3396}
3397
3398func (c *concurrentTxQueryTest) test(t testing.TB) error {
3399	rows, err := c.db.Query("SELECT|people|name|")
3400	if err != nil {
3401		t.Error(err)
3402		return err
3403	}
3404	var name string
3405	for rows.Next() {
3406		rows.Scan(&name)
3407	}
3408	rows.Close()
3409	return nil
3410}
3411
3412type concurrentTxExecTest struct {
3413	db *DB
3414	tx *Tx
3415}
3416
3417func (c *concurrentTxExecTest) init(t testing.TB, db *DB) {
3418	c.db = db
3419	var err error
3420	c.tx, err = c.db.Begin()
3421	if err != nil {
3422		t.Fatal(err)
3423	}
3424}
3425
3426func (c *concurrentTxExecTest) finish(t testing.TB) {
3427	if c.tx != nil {
3428		c.tx.Rollback()
3429		c.tx = nil
3430	}
3431	c.db = nil
3432}
3433
3434func (c *concurrentTxExecTest) test(t testing.TB) error {
3435	_, err := c.tx.Exec("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
3436	if err != nil {
3437		t.Error(err)
3438		return err
3439	}
3440	return nil
3441}
3442
3443type concurrentTxStmtQueryTest struct {
3444	db   *DB
3445	tx   *Tx
3446	stmt *Stmt
3447}
3448
3449func (c *concurrentTxStmtQueryTest) init(t testing.TB, db *DB) {
3450	c.db = db
3451	var err error
3452	c.tx, err = c.db.Begin()
3453	if err != nil {
3454		t.Fatal(err)
3455	}
3456	c.stmt, err = c.tx.Prepare("SELECT|people|name|")
3457	if err != nil {
3458		t.Fatal(err)
3459	}
3460}
3461
3462func (c *concurrentTxStmtQueryTest) finish(t testing.TB) {
3463	if c.stmt != nil {
3464		c.stmt.Close()
3465		c.stmt = nil
3466	}
3467	if c.tx != nil {
3468		c.tx.Rollback()
3469		c.tx = nil
3470	}
3471	c.db = nil
3472}
3473
3474func (c *concurrentTxStmtQueryTest) test(t testing.TB) error {
3475	rows, err := c.stmt.Query()
3476	if err != nil {
3477		t.Errorf("error on query:  %v", err)
3478		return err
3479	}
3480
3481	var name string
3482	for rows.Next() {
3483		rows.Scan(&name)
3484	}
3485	rows.Close()
3486	return nil
3487}
3488
3489type concurrentTxStmtExecTest struct {
3490	db   *DB
3491	tx   *Tx
3492	stmt *Stmt
3493}
3494
3495func (c *concurrentTxStmtExecTest) init(t testing.TB, db *DB) {
3496	c.db = db
3497	var err error
3498	c.tx, err = c.db.Begin()
3499	if err != nil {
3500		t.Fatal(err)
3501	}
3502	c.stmt, err = c.tx.Prepare("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?")
3503	if err != nil {
3504		t.Fatal(err)
3505	}
3506}
3507
3508func (c *concurrentTxStmtExecTest) finish(t testing.TB) {
3509	if c.stmt != nil {
3510		c.stmt.Close()
3511		c.stmt = nil
3512	}
3513	if c.tx != nil {
3514		c.tx.Rollback()
3515		c.tx = nil
3516	}
3517	c.db = nil
3518}
3519
3520func (c *concurrentTxStmtExecTest) test(t testing.TB) error {
3521	_, err := c.stmt.Exec(3, chrisBirthday)
3522	if err != nil {
3523		t.Errorf("error on exec:  %v", err)
3524		return err
3525	}
3526	return nil
3527}
3528
3529type concurrentRandomTest struct {
3530	tests []concurrentTest
3531}
3532
3533func (c *concurrentRandomTest) init(t testing.TB, db *DB) {
3534	c.tests = []concurrentTest{
3535		new(concurrentDBQueryTest),
3536		new(concurrentDBExecTest),
3537		new(concurrentStmtQueryTest),
3538		new(concurrentStmtExecTest),
3539		new(concurrentTxQueryTest),
3540		new(concurrentTxExecTest),
3541		new(concurrentTxStmtQueryTest),
3542		new(concurrentTxStmtExecTest),
3543	}
3544	for _, ct := range c.tests {
3545		ct.init(t, db)
3546	}
3547}
3548
3549func (c *concurrentRandomTest) finish(t testing.TB) {
3550	for _, ct := range c.tests {
3551		ct.finish(t)
3552	}
3553}
3554
3555func (c *concurrentRandomTest) test(t testing.TB) error {
3556	ct := c.tests[rand.Intn(len(c.tests))]
3557	return ct.test(t)
3558}
3559
3560func doConcurrentTest(t testing.TB, ct concurrentTest) {
3561	maxProcs, numReqs := 1, 500
3562	if testing.Short() {
3563		maxProcs, numReqs = 4, 50
3564	}
3565	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
3566
3567	db := newTestDB(t, "people")
3568	defer closeDB(t, db)
3569
3570	ct.init(t, db)
3571	defer ct.finish(t)
3572
3573	var wg sync.WaitGroup
3574	wg.Add(numReqs)
3575
3576	reqs := make(chan bool)
3577	defer close(reqs)
3578
3579	for i := 0; i < maxProcs*2; i++ {
3580		go func() {
3581			for range reqs {
3582				err := ct.test(t)
3583				if err != nil {
3584					wg.Done()
3585					continue
3586				}
3587				wg.Done()
3588			}
3589		}()
3590	}
3591
3592	for i := 0; i < numReqs; i++ {
3593		reqs <- true
3594	}
3595
3596	wg.Wait()
3597}
3598
3599func TestIssue6081(t *testing.T) {
3600	db := newTestDB(t, "people")
3601	defer closeDB(t, db)
3602
3603	drv := db.Driver().(*fakeDriver)
3604	drv.mu.Lock()
3605	opens0 := drv.openCount
3606	closes0 := drv.closeCount
3607	drv.mu.Unlock()
3608
3609	stmt, err := db.Prepare("SELECT|people|name|")
3610	if err != nil {
3611		t.Fatal(err)
3612	}
3613	setRowsCloseHook(func(rows *Rows, err *error) {
3614		*err = driver.ErrBadConn
3615	})
3616	defer setRowsCloseHook(nil)
3617	for i := 0; i < 10; i++ {
3618		rows, err := stmt.Query()
3619		if err != nil {
3620			t.Fatal(err)
3621		}
3622		rows.Close()
3623	}
3624	if n := len(stmt.css); n > 1 {
3625		t.Errorf("len(css slice) = %d; want <= 1", n)
3626	}
3627	stmt.Close()
3628	if n := len(stmt.css); n != 0 {
3629		t.Errorf("len(css slice) after Close = %d; want 0", n)
3630	}
3631
3632	drv.mu.Lock()
3633	opens := drv.openCount - opens0
3634	closes := drv.closeCount - closes0
3635	drv.mu.Unlock()
3636	if opens < 9 {
3637		t.Errorf("opens = %d; want >= 9", opens)
3638	}
3639	if closes < 9 {
3640		t.Errorf("closes = %d; want >= 9", closes)
3641	}
3642}
3643
3644// TestIssue18429 attempts to stress rolling back the transaction from a
3645// context cancel while simultaneously calling Tx.Rollback. Rolling back from a
3646// context happens concurrently so tx.rollback and tx.Commit must guard against
3647// double entry.
3648//
3649// In the test, a context is canceled while the query is in process so
3650// the internal rollback will run concurrently with the explicitly called
3651// Tx.Rollback.
3652//
3653// The addition of calling rows.Next also tests
3654// Issue 21117.
3655func TestIssue18429(t *testing.T) {
3656	db := newTestDB(t, "people")
3657	defer closeDB(t, db)
3658
3659	ctx := context.Background()
3660	sem := make(chan bool, 20)
3661	var wg sync.WaitGroup
3662
3663	const milliWait = 30
3664
3665	for i := 0; i < 100; i++ {
3666		sem <- true
3667		wg.Add(1)
3668		go func() {
3669			defer func() {
3670				<-sem
3671				wg.Done()
3672			}()
3673			qwait := (time.Duration(rand.Intn(milliWait)) * time.Millisecond).String()
3674
3675			ctx, cancel := context.WithTimeout(ctx, time.Duration(rand.Intn(milliWait))*time.Millisecond)
3676			defer cancel()
3677
3678			tx, err := db.BeginTx(ctx, nil)
3679			if err != nil {
3680				return
3681			}
3682			// This is expected to give a cancel error most, but not all the time.
3683			// Test failure will happen with a panic or other race condition being
3684			// reported.
3685			rows, _ := tx.QueryContext(ctx, "WAIT|"+qwait+"|SELECT|people|name|")
3686			if rows != nil {
3687				var name string
3688				// Call Next to test Issue 21117 and check for races.
3689				for rows.Next() {
3690					// Scan the buffer so it is read and checked for races.
3691					rows.Scan(&name)
3692				}
3693				rows.Close()
3694			}
3695			// This call will race with the context cancel rollback to complete
3696			// if the rollback itself isn't guarded.
3697			tx.Rollback()
3698		}()
3699	}
3700	wg.Wait()
3701}
3702
3703// TestIssue20160 attempts to test a short context life on a stmt Query.
3704func TestIssue20160(t *testing.T) {
3705	db := newTestDB(t, "people")
3706	defer closeDB(t, db)
3707
3708	ctx := context.Background()
3709	sem := make(chan bool, 20)
3710	var wg sync.WaitGroup
3711
3712	const milliWait = 30
3713
3714	stmt, err := db.PrepareContext(ctx, "SELECT|people|name|")
3715	if err != nil {
3716		t.Fatal(err)
3717	}
3718	defer stmt.Close()
3719
3720	for i := 0; i < 100; i++ {
3721		sem <- true
3722		wg.Add(1)
3723		go func() {
3724			defer func() {
3725				<-sem
3726				wg.Done()
3727			}()
3728			ctx, cancel := context.WithTimeout(ctx, time.Duration(rand.Intn(milliWait))*time.Millisecond)
3729			defer cancel()
3730
3731			// This is expected to give a cancel error most, but not all the time.
3732			// Test failure will happen with a panic or other race condition being
3733			// reported.
3734			rows, _ := stmt.QueryContext(ctx)
3735			if rows != nil {
3736				rows.Close()
3737			}
3738		}()
3739	}
3740	wg.Wait()
3741}
3742
3743// TestIssue18719 closes the context right before use. The sql.driverConn
3744// will nil out the ci on close in a lock, but if another process uses it right after
3745// it will panic with on the nil ref.
3746//
3747// See https://golang.org/cl/35550 .
3748func TestIssue18719(t *testing.T) {
3749	db := newTestDB(t, "people")
3750	defer closeDB(t, db)
3751
3752	ctx, cancel := context.WithCancel(context.Background())
3753	defer cancel()
3754
3755	tx, err := db.BeginTx(ctx, nil)
3756	if err != nil {
3757		t.Fatal(err)
3758	}
3759
3760	hookTxGrabConn = func() {
3761		cancel()
3762
3763		// Wait for the context to cancel and tx to rollback.
3764		for !tx.isDone() {
3765			time.Sleep(pollDuration)
3766		}
3767	}
3768	defer func() { hookTxGrabConn = nil }()
3769
3770	// This call will grab the connection and cancel the context
3771	// after it has done so. Code after must deal with the canceled state.
3772	_, err = tx.QueryContext(ctx, "SELECT|people|name|")
3773	if err != nil {
3774		t.Fatalf("expected error %v but got %v", nil, err)
3775	}
3776
3777	// Rows may be ignored because it will be closed when the context is canceled.
3778
3779	// Do not explicitly rollback. The rollback will happen from the
3780	// canceled context.
3781
3782	cancel()
3783}
3784
3785func TestIssue20647(t *testing.T) {
3786	db := newTestDB(t, "people")
3787	defer closeDB(t, db)
3788
3789	ctx, cancel := context.WithCancel(context.Background())
3790	defer cancel()
3791
3792	conn, err := db.Conn(ctx)
3793	if err != nil {
3794		t.Fatal(err)
3795	}
3796	conn.dc.ci.(*fakeConn).skipDirtySession = true
3797	defer conn.Close()
3798
3799	stmt, err := conn.PrepareContext(ctx, "SELECT|people|name|")
3800	if err != nil {
3801		t.Fatal(err)
3802	}
3803	defer stmt.Close()
3804
3805	rows1, err := stmt.QueryContext(ctx)
3806	if err != nil {
3807		t.Fatal("rows1", err)
3808	}
3809	defer rows1.Close()
3810
3811	rows2, err := stmt.QueryContext(ctx)
3812	if err != nil {
3813		t.Fatal("rows2", err)
3814	}
3815	defer rows2.Close()
3816
3817	if rows1.dc != rows2.dc {
3818		t.Fatal("stmt prepared on Conn does not use same connection")
3819	}
3820}
3821
3822func TestConcurrency(t *testing.T) {
3823	list := []struct {
3824		name string
3825		ct   concurrentTest
3826	}{
3827		{"Query", new(concurrentDBQueryTest)},
3828		{"Exec", new(concurrentDBExecTest)},
3829		{"StmtQuery", new(concurrentStmtQueryTest)},
3830		{"StmtExec", new(concurrentStmtExecTest)},
3831		{"TxQuery", new(concurrentTxQueryTest)},
3832		{"TxExec", new(concurrentTxExecTest)},
3833		{"TxStmtQuery", new(concurrentTxStmtQueryTest)},
3834		{"TxStmtExec", new(concurrentTxStmtExecTest)},
3835		{"Random", new(concurrentRandomTest)},
3836	}
3837	for _, item := range list {
3838		t.Run(item.name, func(t *testing.T) {
3839			doConcurrentTest(t, item.ct)
3840		})
3841	}
3842}
3843
3844func TestConnectionLeak(t *testing.T) {
3845	db := newTestDB(t, "people")
3846	defer closeDB(t, db)
3847	// Start by opening defaultMaxIdleConns
3848	rows := make([]*Rows, defaultMaxIdleConns)
3849	// We need to SetMaxOpenConns > MaxIdleConns, so the DB can open
3850	// a new connection and we can fill the idle queue with the released
3851	// connections.
3852	db.SetMaxOpenConns(len(rows) + 1)
3853	for ii := range rows {
3854		r, err := db.Query("SELECT|people|name|")
3855		if err != nil {
3856			t.Fatal(err)
3857		}
3858		r.Next()
3859		if err := r.Err(); err != nil {
3860			t.Fatal(err)
3861		}
3862		rows[ii] = r
3863	}
3864	// Now we have defaultMaxIdleConns busy connections. Open
3865	// a new one, but wait until the busy connections are released
3866	// before returning control to DB.
3867	drv := db.Driver().(*fakeDriver)
3868	drv.waitCh = make(chan struct{}, 1)
3869	drv.waitingCh = make(chan struct{}, 1)
3870	var wg sync.WaitGroup
3871	wg.Add(1)
3872	go func() {
3873		r, err := db.Query("SELECT|people|name|")
3874		if err != nil {
3875			t.Error(err)
3876			return
3877		}
3878		r.Close()
3879		wg.Done()
3880	}()
3881	// Wait until the goroutine we've just created has started waiting.
3882	<-drv.waitingCh
3883	// Now close the busy connections. This provides a connection for
3884	// the blocked goroutine and then fills up the idle queue.
3885	for _, v := range rows {
3886		v.Close()
3887	}
3888	// At this point we give the new connection to DB. This connection is
3889	// now useless, since the idle queue is full and there are no pending
3890	// requests. DB should deal with this situation without leaking the
3891	// connection.
3892	drv.waitCh <- struct{}{}
3893	wg.Wait()
3894}
3895
3896func TestStatsMaxIdleClosedZero(t *testing.T) {
3897	db := newTestDB(t, "people")
3898	defer closeDB(t, db)
3899
3900	db.SetMaxOpenConns(1)
3901	db.SetMaxIdleConns(1)
3902	db.SetConnMaxLifetime(0)
3903
3904	preMaxIdleClosed := db.Stats().MaxIdleClosed
3905
3906	for i := 0; i < 10; i++ {
3907		rows, err := db.Query("SELECT|people|name|")
3908		if err != nil {
3909			t.Fatal(err)
3910		}
3911		rows.Close()
3912	}
3913
3914	st := db.Stats()
3915	maxIdleClosed := st.MaxIdleClosed - preMaxIdleClosed
3916	t.Logf("MaxIdleClosed: %d", maxIdleClosed)
3917	if maxIdleClosed != 0 {
3918		t.Fatal("expected 0 max idle closed conns, got: ", maxIdleClosed)
3919	}
3920}
3921
3922func TestStatsMaxIdleClosedTen(t *testing.T) {
3923	db := newTestDB(t, "people")
3924	defer closeDB(t, db)
3925
3926	db.SetMaxOpenConns(1)
3927	db.SetMaxIdleConns(0)
3928	db.SetConnMaxLifetime(0)
3929
3930	preMaxIdleClosed := db.Stats().MaxIdleClosed
3931
3932	for i := 0; i < 10; i++ {
3933		rows, err := db.Query("SELECT|people|name|")
3934		if err != nil {
3935			t.Fatal(err)
3936		}
3937		rows.Close()
3938	}
3939
3940	st := db.Stats()
3941	maxIdleClosed := st.MaxIdleClosed - preMaxIdleClosed
3942	t.Logf("MaxIdleClosed: %d", maxIdleClosed)
3943	if maxIdleClosed != 10 {
3944		t.Fatal("expected 0 max idle closed conns, got: ", maxIdleClosed)
3945	}
3946}
3947
3948// testUseConns uses count concurrent connections with 1 nanosecond apart.
3949// Returns the returnedAt time of the final connection.
3950func testUseConns(t *testing.T, count int, tm time.Time, db *DB) time.Time {
3951	conns := make([]*Conn, count)
3952	ctx := context.Background()
3953	for i := range conns {
3954		tm = tm.Add(time.Nanosecond)
3955		nowFunc = func() time.Time {
3956			return tm
3957		}
3958		c, err := db.Conn(ctx)
3959		if err != nil {
3960			t.Error(err)
3961		}
3962		conns[i] = c
3963	}
3964
3965	for i := len(conns) - 1; i >= 0; i-- {
3966		tm = tm.Add(time.Nanosecond)
3967		nowFunc = func() time.Time {
3968			return tm
3969		}
3970		if err := conns[i].Close(); err != nil {
3971			t.Error(err)
3972		}
3973	}
3974
3975	return tm
3976}
3977
3978func TestMaxIdleTime(t *testing.T) {
3979	usedConns := 5
3980	reusedConns := 2
3981	list := []struct {
3982		wantMaxIdleTime   time.Duration
3983		wantMaxLifetime   time.Duration
3984		wantNextCheck     time.Duration
3985		wantIdleClosed    int64
3986		wantMaxIdleClosed int64
3987		timeOffset        time.Duration
3988		secondTimeOffset  time.Duration
3989	}{
3990		{
3991			time.Millisecond,
3992			0,
3993			time.Millisecond - time.Nanosecond,
3994			int64(usedConns - reusedConns),
3995			int64(usedConns - reusedConns),
3996			10 * time.Millisecond,
3997			0,
3998		},
3999		{
4000			// Want to close some connections via max idle time and one by max lifetime.
4001			time.Millisecond,
4002			// nowFunc() - MaxLifetime should be 1 * time.Nanosecond in connectionCleanerRunLocked.
4003			// This guarantees that first opened connection is to be closed.
4004			// Thus it is timeOffset + secondTimeOffset + 3 (+2 for Close while reusing conns and +1 for Conn).
4005			10*time.Millisecond + 100*time.Nanosecond + 3*time.Nanosecond,
4006			time.Nanosecond,
4007			// Closed all not reused connections and extra one by max lifetime.
4008			int64(usedConns - reusedConns + 1),
4009			int64(usedConns - reusedConns),
4010			10 * time.Millisecond,
4011			// Add second offset because otherwise connections are expired via max lifetime in Close.
4012			100 * time.Nanosecond,
4013		},
4014		{
4015			time.Hour,
4016			0,
4017			time.Second,
4018			0,
4019			0,
4020			10 * time.Millisecond,
4021			0},
4022	}
4023	baseTime := time.Unix(0, 0)
4024	defer func() {
4025		nowFunc = time.Now
4026	}()
4027	for _, item := range list {
4028		nowFunc = func() time.Time {
4029			return baseTime
4030		}
4031		t.Run(fmt.Sprintf("%v", item.wantMaxIdleTime), func(t *testing.T) {
4032			db := newTestDB(t, "people")
4033			defer closeDB(t, db)
4034
4035			db.SetMaxOpenConns(usedConns)
4036			db.SetMaxIdleConns(usedConns)
4037			db.SetConnMaxIdleTime(item.wantMaxIdleTime)
4038			db.SetConnMaxLifetime(item.wantMaxLifetime)
4039
4040			preMaxIdleClosed := db.Stats().MaxIdleTimeClosed
4041
4042			// Busy usedConns.
4043			testUseConns(t, usedConns, baseTime, db)
4044
4045			tm := baseTime.Add(item.timeOffset)
4046
4047			// Reuse connections which should never be considered idle
4048			// and exercises the sorting for issue 39471.
4049			tm = testUseConns(t, reusedConns, tm, db)
4050
4051			tm = tm.Add(item.secondTimeOffset)
4052			nowFunc = func() time.Time {
4053				return tm
4054			}
4055
4056			db.mu.Lock()
4057			nc, closing := db.connectionCleanerRunLocked(time.Second)
4058			if nc != item.wantNextCheck {
4059				t.Errorf("got %v; want %v next check duration", nc, item.wantNextCheck)
4060			}
4061
4062			// Validate freeConn order.
4063			var last time.Time
4064			for _, c := range db.freeConn {
4065				if last.After(c.returnedAt) {
4066					t.Error("freeConn is not ordered by returnedAt")
4067					break
4068				}
4069				last = c.returnedAt
4070			}
4071
4072			db.mu.Unlock()
4073			for _, c := range closing {
4074				c.Close()
4075			}
4076			if g, w := int64(len(closing)), item.wantIdleClosed; g != w {
4077				t.Errorf("got: %d; want %d closed conns", g, w)
4078			}
4079
4080			st := db.Stats()
4081			maxIdleClosed := st.MaxIdleTimeClosed - preMaxIdleClosed
4082			if g, w := maxIdleClosed, item.wantMaxIdleClosed; g != w {
4083				t.Errorf("got: %d; want %d max idle closed conns", g, w)
4084			}
4085		})
4086	}
4087}
4088
4089type nvcDriver struct {
4090	fakeDriver
4091	skipNamedValueCheck bool
4092}
4093
4094func (d *nvcDriver) Open(dsn string) (driver.Conn, error) {
4095	c, err := d.fakeDriver.Open(dsn)
4096	fc := c.(*fakeConn)
4097	fc.db.allowAny = true
4098	return &nvcConn{fc, d.skipNamedValueCheck}, err
4099}
4100
4101type nvcConn struct {
4102	*fakeConn
4103	skipNamedValueCheck bool
4104}
4105
4106type decimalInt struct {
4107	value int
4108}
4109
4110type doNotInclude struct{}
4111
4112var _ driver.NamedValueChecker = &nvcConn{}
4113
4114func (c *nvcConn) CheckNamedValue(nv *driver.NamedValue) error {
4115	if c.skipNamedValueCheck {
4116		return driver.ErrSkip
4117	}
4118	switch v := nv.Value.(type) {
4119	default:
4120		return driver.ErrSkip
4121	case Out:
4122		switch ov := v.Dest.(type) {
4123		default:
4124			return errors.New("unknown NameValueCheck OUTPUT type")
4125		case *string:
4126			*ov = "from-server"
4127			nv.Value = "OUT:*string"
4128		}
4129		return nil
4130	case decimalInt, []int64:
4131		return nil
4132	case doNotInclude:
4133		return driver.ErrRemoveArgument
4134	}
4135}
4136
4137func TestNamedValueChecker(t *testing.T) {
4138	Register("NamedValueCheck", &nvcDriver{})
4139	db, err := Open("NamedValueCheck", "")
4140	if err != nil {
4141		t.Fatal(err)
4142	}
4143	defer db.Close()
4144
4145	ctx, cancel := context.WithCancel(context.Background())
4146	defer cancel()
4147
4148	_, err = db.ExecContext(ctx, "WIPE")
4149	if err != nil {
4150		t.Fatal("exec wipe", err)
4151	}
4152
4153	_, err = db.ExecContext(ctx, "CREATE|keys|dec1=any,str1=string,out1=string,array1=any")
4154	if err != nil {
4155		t.Fatal("exec create", err)
4156	}
4157
4158	o1 := ""
4159	_, 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{})
4160	if err != nil {
4161		t.Fatal("exec insert", err)
4162	}
4163	var (
4164		str1 string
4165		dec1 decimalInt
4166		arr1 []int64
4167	)
4168	err = db.QueryRowContext(ctx, "SELECT|keys|dec1,str1,array1|").Scan(&dec1, &str1, &arr1)
4169	if err != nil {
4170		t.Fatal("select", err)
4171	}
4172
4173	list := []struct{ got, want any }{
4174		{o1, "from-server"},
4175		{dec1, decimalInt{123}},
4176		{str1, "hello"},
4177		{arr1, []int64{42, 128, 707}},
4178	}
4179
4180	for index, item := range list {
4181		if !reflect.DeepEqual(item.got, item.want) {
4182			t.Errorf("got %#v wanted %#v for index %d", item.got, item.want, index)
4183		}
4184	}
4185}
4186
4187func TestNamedValueCheckerSkip(t *testing.T) {
4188	Register("NamedValueCheckSkip", &nvcDriver{skipNamedValueCheck: true})
4189	db, err := Open("NamedValueCheckSkip", "")
4190	if err != nil {
4191		t.Fatal(err)
4192	}
4193	defer db.Close()
4194
4195	ctx, cancel := context.WithCancel(context.Background())
4196	defer cancel()
4197
4198	_, err = db.ExecContext(ctx, "WIPE")
4199	if err != nil {
4200		t.Fatal("exec wipe", err)
4201	}
4202
4203	_, err = db.ExecContext(ctx, "CREATE|keys|dec1=any")
4204	if err != nil {
4205		t.Fatal("exec create", err)
4206	}
4207
4208	_, err = db.ExecContext(ctx, "INSERT|keys|dec1=?A", Named("A", decimalInt{123}))
4209	if err == nil {
4210		t.Fatalf("expected error with bad argument, got %v", err)
4211	}
4212}
4213
4214func TestOpenConnector(t *testing.T) {
4215	Register("testctx", &fakeDriverCtx{})
4216	db, err := Open("testctx", "people")
4217	if err != nil {
4218		t.Fatal(err)
4219	}
4220	defer db.Close()
4221
4222	c, ok := db.connector.(*fakeConnector)
4223	if !ok {
4224		t.Fatal("not using *fakeConnector")
4225	}
4226
4227	if err := db.Close(); err != nil {
4228		t.Fatal(err)
4229	}
4230
4231	if !c.closed {
4232		t.Fatal("connector is not closed")
4233	}
4234}
4235
4236type ctxOnlyDriver struct {
4237	fakeDriver
4238}
4239
4240func (d *ctxOnlyDriver) Open(dsn string) (driver.Conn, error) {
4241	conn, err := d.fakeDriver.Open(dsn)
4242	if err != nil {
4243		return nil, err
4244	}
4245	return &ctxOnlyConn{fc: conn.(*fakeConn)}, nil
4246}
4247
4248var (
4249	_ driver.Conn           = &ctxOnlyConn{}
4250	_ driver.QueryerContext = &ctxOnlyConn{}
4251	_ driver.ExecerContext  = &ctxOnlyConn{}
4252)
4253
4254type ctxOnlyConn struct {
4255	fc *fakeConn
4256
4257	queryCtxCalled bool
4258	execCtxCalled  bool
4259}
4260
4261func (c *ctxOnlyConn) Begin() (driver.Tx, error) {
4262	return c.fc.Begin()
4263}
4264
4265func (c *ctxOnlyConn) Close() error {
4266	return c.fc.Close()
4267}
4268
4269// Prepare is still part of the Conn interface, so while it isn't used
4270// must be defined for compatibility.
4271func (c *ctxOnlyConn) Prepare(q string) (driver.Stmt, error) {
4272	panic("not used")
4273}
4274
4275func (c *ctxOnlyConn) PrepareContext(ctx context.Context, q string) (driver.Stmt, error) {
4276	return c.fc.PrepareContext(ctx, q)
4277}
4278
4279func (c *ctxOnlyConn) QueryContext(ctx context.Context, q string, args []driver.NamedValue) (driver.Rows, error) {
4280	c.queryCtxCalled = true
4281	return c.fc.QueryContext(ctx, q, args)
4282}
4283
4284func (c *ctxOnlyConn) ExecContext(ctx context.Context, q string, args []driver.NamedValue) (driver.Result, error) {
4285	c.execCtxCalled = true
4286	return c.fc.ExecContext(ctx, q, args)
4287}
4288
4289// TestQueryExecContextOnly ensures drivers only need to implement QueryContext
4290// and ExecContext methods.
4291func TestQueryExecContextOnly(t *testing.T) {
4292	// Ensure connection does not implement non-context interfaces.
4293	var connType driver.Conn = &ctxOnlyConn{}
4294	if _, ok := connType.(driver.Execer); ok {
4295		t.Fatalf("%T must not implement driver.Execer", connType)
4296	}
4297	if _, ok := connType.(driver.Queryer); ok {
4298		t.Fatalf("%T must not implement driver.Queryer", connType)
4299	}
4300
4301	Register("ContextOnly", &ctxOnlyDriver{})
4302	db, err := Open("ContextOnly", "")
4303	if err != nil {
4304		t.Fatal(err)
4305	}
4306	defer db.Close()
4307
4308	ctx, cancel := context.WithCancel(context.Background())
4309	defer cancel()
4310
4311	conn, err := db.Conn(ctx)
4312	if err != nil {
4313		t.Fatal("db.Conn", err)
4314	}
4315	defer conn.Close()
4316	coc := conn.dc.ci.(*ctxOnlyConn)
4317	coc.fc.skipDirtySession = true
4318
4319	_, err = conn.ExecContext(ctx, "WIPE")
4320	if err != nil {
4321		t.Fatal("exec wipe", err)
4322	}
4323
4324	_, err = conn.ExecContext(ctx, "CREATE|keys|v1=string")
4325	if err != nil {
4326		t.Fatal("exec create", err)
4327	}
4328	expectedValue := "value1"
4329	_, err = conn.ExecContext(ctx, "INSERT|keys|v1=?", expectedValue)
4330	if err != nil {
4331		t.Fatal("exec insert", err)
4332	}
4333	rows, err := conn.QueryContext(ctx, "SELECT|keys|v1|")
4334	if err != nil {
4335		t.Fatal("query select", err)
4336	}
4337	v1 := ""
4338	for rows.Next() {
4339		err = rows.Scan(&v1)
4340		if err != nil {
4341			t.Fatal("rows scan", err)
4342		}
4343	}
4344	rows.Close()
4345
4346	if v1 != expectedValue {
4347		t.Fatalf("expected %q, got %q", expectedValue, v1)
4348	}
4349
4350	if !coc.execCtxCalled {
4351		t.Error("ExecContext not called")
4352	}
4353	if !coc.queryCtxCalled {
4354		t.Error("QueryContext not called")
4355	}
4356}
4357
4358type alwaysErrScanner struct{}
4359
4360var errTestScanWrap = errors.New("errTestScanWrap")
4361
4362func (alwaysErrScanner) Scan(any) error {
4363	return errTestScanWrap
4364}
4365
4366// Issue 38099: Ensure that Rows.Scan properly wraps underlying errors.
4367func TestRowsScanProperlyWrapsErrors(t *testing.T) {
4368	db := newTestDB(t, "people")
4369	defer closeDB(t, db)
4370
4371	rows, err := db.Query("SELECT|people|age|")
4372	if err != nil {
4373		t.Fatalf("Query: %v", err)
4374	}
4375
4376	var res alwaysErrScanner
4377
4378	for rows.Next() {
4379		err = rows.Scan(&res)
4380		if err == nil {
4381			t.Fatal("expecting back an error")
4382		}
4383		if !errors.Is(err, errTestScanWrap) {
4384			t.Fatalf("errors.Is mismatch\n%v\nWant: %v", err, errTestScanWrap)
4385		}
4386		// Ensure that error substring matching still correctly works.
4387		if !strings.Contains(err.Error(), errTestScanWrap.Error()) {
4388			t.Fatalf("Error %v does not contain %v", err, errTestScanWrap)
4389		}
4390	}
4391}
4392
4393type alwaysErrValuer struct{}
4394
4395// errEmpty is returned when an empty value is found
4396var errEmpty = errors.New("empty value")
4397
4398func (v alwaysErrValuer) Value() (driver.Value, error) {
4399	return nil, errEmpty
4400}
4401
4402// Issue 64707: Ensure that Stmt.Exec and Stmt.Query properly wraps underlying errors.
4403func TestDriverArgsWrapsErrors(t *testing.T) {
4404	db := newTestDB(t, "people")
4405	defer closeDB(t, db)
4406
4407	t.Run("exec", func(t *testing.T) {
4408		_, err := db.Exec("INSERT|keys|dec1=?", alwaysErrValuer{})
4409		if err == nil {
4410			t.Fatal("expecting back an error")
4411		}
4412		if !errors.Is(err, errEmpty) {
4413			t.Fatalf("errors.Is mismatch\n%v\nWant: %v", err, errEmpty)
4414		}
4415		// Ensure that error substring matching still correctly works.
4416		if !strings.Contains(err.Error(), errEmpty.Error()) {
4417			t.Fatalf("Error %v does not contain %v", err, errEmpty)
4418		}
4419	})
4420
4421	t.Run("query", func(t *testing.T) {
4422		_, err := db.Query("INSERT|keys|dec1=?", alwaysErrValuer{})
4423		if err == nil {
4424			t.Fatal("expecting back an error")
4425		}
4426		if !errors.Is(err, errEmpty) {
4427			t.Fatalf("errors.Is mismatch\n%v\nWant: %v", err, errEmpty)
4428		}
4429		// Ensure that error substring matching still correctly works.
4430		if !strings.Contains(err.Error(), errEmpty.Error()) {
4431			t.Fatalf("Error %v does not contain %v", err, errEmpty)
4432		}
4433	})
4434}
4435
4436func TestContextCancelDuringRawBytesScan(t *testing.T) {
4437	for _, mode := range []string{"nocancel", "top", "bottom", "go"} {
4438		t.Run(mode, func(t *testing.T) {
4439			testContextCancelDuringRawBytesScan(t, mode)
4440		})
4441	}
4442}
4443
4444// From go.dev/issue/60304
4445func testContextCancelDuringRawBytesScan(t *testing.T, mode string) {
4446	db := newTestDB(t, "people")
4447	defer closeDB(t, db)
4448
4449	if _, err := db.Exec("USE_RAWBYTES"); err != nil {
4450		t.Fatal(err)
4451	}
4452
4453	// cancel used to call close asynchronously.
4454	// This test checks that it waits so as not to interfere with RawBytes.
4455	ctx, cancel := context.WithCancel(context.Background())
4456	defer cancel()
4457
4458	r, err := db.QueryContext(ctx, "SELECT|people|name|")
4459	if err != nil {
4460		t.Fatal(err)
4461	}
4462	numRows := 0
4463	var sink byte
4464	for r.Next() {
4465		if mode == "top" && numRows == 2 {
4466			// cancel between Next and Scan is observed by Scan as err = context.Canceled.
4467			// The sleep here is only to make it more likely that the cancel will be observed.
4468			// If not, the test should still pass, like in "go" mode.
4469			cancel()
4470			time.Sleep(100 * time.Millisecond)
4471		}
4472		numRows++
4473		var s RawBytes
4474		err = r.Scan(&s)
4475		if numRows == 3 && err == context.Canceled {
4476			if r.closemuScanHold {
4477				t.Errorf("expected closemu NOT to be held")
4478			}
4479			break
4480		}
4481		if !r.closemuScanHold {
4482			t.Errorf("expected closemu to be held")
4483		}
4484		if err != nil {
4485			t.Fatal(err)
4486		}
4487		t.Logf("read %q", s)
4488		if mode == "bottom" && numRows == 2 {
4489			// cancel before Next should be observed by Next, exiting the loop.
4490			// The sleep here is only to make it more likely that the cancel will be observed.
4491			// If not, the test should still pass, like in "go" mode.
4492			cancel()
4493			time.Sleep(100 * time.Millisecond)
4494		}
4495		if mode == "go" && numRows == 2 {
4496			// cancel at any future time, to catch other cases
4497			go cancel()
4498		}
4499		for _, b := range s { // some operation reading from the raw memory
4500			sink += b
4501		}
4502	}
4503	if r.closemuScanHold {
4504		t.Errorf("closemu held; should not be")
4505	}
4506
4507	// There are 3 rows. We canceled after reading 2 so we expect either
4508	// 2 or 3 depending on how the awaitDone goroutine schedules.
4509	switch numRows {
4510	case 0, 1:
4511		t.Errorf("got %d rows; want 2+", numRows)
4512	case 2:
4513		if err := r.Err(); err != context.Canceled {
4514			t.Errorf("unexpected error: %v (%T)", err, err)
4515		}
4516	default:
4517		// Made it to the end. This is rare, but fine. Permit it.
4518	}
4519
4520	if err := r.Close(); err != nil {
4521		t.Fatal(err)
4522	}
4523}
4524
4525func TestContextCancelBetweenNextAndErr(t *testing.T) {
4526	db := newTestDB(t, "people")
4527	defer closeDB(t, db)
4528	ctx, cancel := context.WithCancel(context.Background())
4529	defer cancel()
4530
4531	r, err := db.QueryContext(ctx, "SELECT|people|name|")
4532	if err != nil {
4533		t.Fatal(err)
4534	}
4535	for r.Next() {
4536	}
4537	cancel()                          // wake up the awaitDone goroutine
4538	time.Sleep(10 * time.Millisecond) // increase odds of seeing failure
4539	if err := r.Err(); err != nil {
4540		t.Fatal(err)
4541	}
4542}
4543
4544func TestNilErrorAfterClose(t *testing.T) {
4545	db := newTestDB(t, "people")
4546	defer closeDB(t, db)
4547
4548	// This WithCancel is important; Rows contains an optimization to avoid
4549	// spawning a goroutine when the query/transaction context cannot be
4550	// canceled, but this test tests a bug which is caused by said goroutine.
4551	ctx, cancel := context.WithCancel(context.Background())
4552	defer cancel()
4553
4554	r, err := db.QueryContext(ctx, "SELECT|people|name|")
4555	if err != nil {
4556		t.Fatal(err)
4557	}
4558
4559	if err := r.Close(); err != nil {
4560		t.Fatal(err)
4561	}
4562
4563	time.Sleep(10 * time.Millisecond) // increase odds of seeing failure
4564	if err := r.Err(); err != nil {
4565		t.Fatal(err)
4566	}
4567}
4568
4569// Issue #65201.
4570//
4571// If a RawBytes is reused across multiple queries,
4572// subsequent queries shouldn't overwrite driver-owned memory from previous queries.
4573func TestRawBytesReuse(t *testing.T) {
4574	db := newTestDB(t, "people")
4575	defer closeDB(t, db)
4576
4577	if _, err := db.Exec("USE_RAWBYTES"); err != nil {
4578		t.Fatal(err)
4579	}
4580
4581	var raw RawBytes
4582
4583	// The RawBytes in this query aliases driver-owned memory.
4584	rows, err := db.Query("SELECT|people|name|")
4585	if err != nil {
4586		t.Fatal(err)
4587	}
4588	rows.Next()
4589	rows.Scan(&raw) // now raw is pointing to driver-owned memory
4590	name1 := string(raw)
4591	rows.Close()
4592
4593	// The RawBytes in this query does not alias driver-owned memory.
4594	rows, err = db.Query("SELECT|people|age|")
4595	if err != nil {
4596		t.Fatal(err)
4597	}
4598	rows.Next()
4599	rows.Scan(&raw) // this must not write to the driver-owned memory in raw
4600	rows.Close()
4601
4602	// Repeat the first query. Nothing should have changed.
4603	rows, err = db.Query("SELECT|people|name|")
4604	if err != nil {
4605		t.Fatal(err)
4606	}
4607	rows.Next()
4608	rows.Scan(&raw) // raw points to driver-owned memory again
4609	name2 := string(raw)
4610	rows.Close()
4611	if name1 != name2 {
4612		t.Fatalf("Scan read name %q, want %q", name2, name1)
4613	}
4614}
4615
4616// badConn implements a bad driver.Conn, for TestBadDriver.
4617// The Exec method panics.
4618type badConn struct{}
4619
4620func (bc badConn) Prepare(query string) (driver.Stmt, error) {
4621	return nil, errors.New("badConn Prepare")
4622}
4623
4624func (bc badConn) Close() error {
4625	return nil
4626}
4627
4628func (bc badConn) Begin() (driver.Tx, error) {
4629	return nil, errors.New("badConn Begin")
4630}
4631
4632func (bc badConn) Exec(query string, args []driver.Value) (driver.Result, error) {
4633	panic("badConn.Exec")
4634}
4635
4636// badDriver is a driver.Driver that uses badConn.
4637type badDriver struct{}
4638
4639func (bd badDriver) Open(name string) (driver.Conn, error) {
4640	return badConn{}, nil
4641}
4642
4643// Issue 15901.
4644func TestBadDriver(t *testing.T) {
4645	Register("bad", badDriver{})
4646	db, err := Open("bad", "ignored")
4647	if err != nil {
4648		t.Fatal(err)
4649	}
4650	defer func() {
4651		if r := recover(); r == nil {
4652			t.Error("expected panic")
4653		} else {
4654			if want := "badConn.Exec"; r.(string) != want {
4655				t.Errorf("panic was %v, expected %v", r, want)
4656			}
4657		}
4658	}()
4659	defer db.Close()
4660	db.Exec("ignored")
4661}
4662
4663type pingDriver struct {
4664	fails bool
4665}
4666
4667type pingConn struct {
4668	badConn
4669	driver *pingDriver
4670}
4671
4672var pingError = errors.New("Ping failed")
4673
4674func (pc pingConn) Ping(ctx context.Context) error {
4675	if pc.driver.fails {
4676		return pingError
4677	}
4678	return nil
4679}
4680
4681var _ driver.Pinger = pingConn{}
4682
4683func (pd *pingDriver) Open(name string) (driver.Conn, error) {
4684	return pingConn{driver: pd}, nil
4685}
4686
4687func TestPing(t *testing.T) {
4688	driver := &pingDriver{}
4689	Register("ping", driver)
4690
4691	db, err := Open("ping", "ignored")
4692	if err != nil {
4693		t.Fatal(err)
4694	}
4695
4696	if err := db.Ping(); err != nil {
4697		t.Errorf("err was %#v, expected nil", err)
4698		return
4699	}
4700
4701	driver.fails = true
4702	if err := db.Ping(); err != pingError {
4703		t.Errorf("err was %#v, expected pingError", err)
4704	}
4705}
4706
4707// Issue 18101.
4708func TestTypedString(t *testing.T) {
4709	db := newTestDB(t, "people")
4710	defer closeDB(t, db)
4711
4712	type Str string
4713	var scanned Str
4714
4715	err := db.QueryRow("SELECT|people|name|name=?", "Alice").Scan(&scanned)
4716	if err != nil {
4717		t.Fatal(err)
4718	}
4719	expected := Str("Alice")
4720	if scanned != expected {
4721		t.Errorf("expected %+v, got %+v", expected, scanned)
4722	}
4723}
4724
4725func BenchmarkConcurrentDBExec(b *testing.B) {
4726	b.ReportAllocs()
4727	ct := new(concurrentDBExecTest)
4728	for i := 0; i < b.N; i++ {
4729		doConcurrentTest(b, ct)
4730	}
4731}
4732
4733func BenchmarkConcurrentStmtQuery(b *testing.B) {
4734	b.ReportAllocs()
4735	ct := new(concurrentStmtQueryTest)
4736	for i := 0; i < b.N; i++ {
4737		doConcurrentTest(b, ct)
4738	}
4739}
4740
4741func BenchmarkConcurrentStmtExec(b *testing.B) {
4742	b.ReportAllocs()
4743	ct := new(concurrentStmtExecTest)
4744	for i := 0; i < b.N; i++ {
4745		doConcurrentTest(b, ct)
4746	}
4747}
4748
4749func BenchmarkConcurrentTxQuery(b *testing.B) {
4750	b.ReportAllocs()
4751	ct := new(concurrentTxQueryTest)
4752	for i := 0; i < b.N; i++ {
4753		doConcurrentTest(b, ct)
4754	}
4755}
4756
4757func BenchmarkConcurrentTxExec(b *testing.B) {
4758	b.ReportAllocs()
4759	ct := new(concurrentTxExecTest)
4760	for i := 0; i < b.N; i++ {
4761		doConcurrentTest(b, ct)
4762	}
4763}
4764
4765func BenchmarkConcurrentTxStmtQuery(b *testing.B) {
4766	b.ReportAllocs()
4767	ct := new(concurrentTxStmtQueryTest)
4768	for i := 0; i < b.N; i++ {
4769		doConcurrentTest(b, ct)
4770	}
4771}
4772
4773func BenchmarkConcurrentTxStmtExec(b *testing.B) {
4774	b.ReportAllocs()
4775	ct := new(concurrentTxStmtExecTest)
4776	for i := 0; i < b.N; i++ {
4777		doConcurrentTest(b, ct)
4778	}
4779}
4780
4781func BenchmarkConcurrentRandom(b *testing.B) {
4782	b.ReportAllocs()
4783	ct := new(concurrentRandomTest)
4784	for i := 0; i < b.N; i++ {
4785		doConcurrentTest(b, ct)
4786	}
4787}
4788
4789func BenchmarkManyConcurrentQueries(b *testing.B) {
4790	b.ReportAllocs()
4791	// To see lock contention in Go 1.4, 16~ cores and 128~ goroutines are required.
4792	const parallelism = 16
4793
4794	db := newTestDB(b, "magicquery")
4795	defer closeDB(b, db)
4796	db.SetMaxIdleConns(runtime.GOMAXPROCS(0) * parallelism)
4797
4798	stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?")
4799	if err != nil {
4800		b.Fatal(err)
4801	}
4802	defer stmt.Close()
4803
4804	b.SetParallelism(parallelism)
4805	b.RunParallel(func(pb *testing.PB) {
4806		for pb.Next() {
4807			rows, err := stmt.Query("sleep", 1)
4808			if err != nil {
4809				b.Error(err)
4810				return
4811			}
4812			rows.Close()
4813		}
4814	})
4815}
4816
4817func TestGrabConnAllocs(t *testing.T) {
4818	testenv.SkipIfOptimizationOff(t)
4819	if race.Enabled {
4820		t.Skip("skipping allocation test when using race detector")
4821	}
4822	c := new(Conn)
4823	ctx := context.Background()
4824	n := int(testing.AllocsPerRun(1000, func() {
4825		_, release, err := c.grabConn(ctx)
4826		if err != nil {
4827			t.Fatal(err)
4828		}
4829		release(nil)
4830	}))
4831	if n > 0 {
4832		t.Fatalf("Conn.grabConn allocated %v objects; want 0", n)
4833	}
4834}
4835
4836func BenchmarkGrabConn(b *testing.B) {
4837	b.ReportAllocs()
4838	c := new(Conn)
4839	ctx := context.Background()
4840	for i := 0; i < b.N; i++ {
4841		_, release, err := c.grabConn(ctx)
4842		if err != nil {
4843			b.Fatal(err)
4844		}
4845		release(nil)
4846	}
4847}
4848
4849func TestConnRequestSet(t *testing.T) {
4850	var s connRequestSet
4851	wantLen := func(want int) {
4852		t.Helper()
4853		if got := s.Len(); got != want {
4854			t.Errorf("Len = %d; want %d", got, want)
4855		}
4856		if want == 0 && !t.Failed() {
4857			if _, ok := s.TakeRandom(); ok {
4858				t.Fatalf("TakeRandom returned result when empty")
4859			}
4860		}
4861	}
4862	reset := func() { s = connRequestSet{} }
4863
4864	t.Run("add-delete", func(t *testing.T) {
4865		reset()
4866		wantLen(0)
4867		dh := s.Add(nil)
4868		wantLen(1)
4869		if !s.Delete(dh) {
4870			t.Fatal("failed to delete")
4871		}
4872		wantLen(0)
4873		if s.Delete(dh) {
4874			t.Error("delete worked twice")
4875		}
4876		wantLen(0)
4877	})
4878	t.Run("take-before-delete", func(t *testing.T) {
4879		reset()
4880		ch1 := make(chan connRequest)
4881		dh := s.Add(ch1)
4882		wantLen(1)
4883		if got, ok := s.TakeRandom(); !ok || got != ch1 {
4884			t.Fatalf("wrong take; ok=%v", ok)
4885		}
4886		wantLen(0)
4887		if s.Delete(dh) {
4888			t.Error("unexpected delete after take")
4889		}
4890	})
4891	t.Run("get-take-many", func(t *testing.T) {
4892		reset()
4893		m := map[chan connRequest]bool{}
4894		const N = 100
4895		var inOrder, backOut []chan connRequest
4896		for range N {
4897			c := make(chan connRequest)
4898			m[c] = true
4899			s.Add(c)
4900			inOrder = append(inOrder, c)
4901		}
4902		if s.Len() != N {
4903			t.Fatalf("Len = %v; want %v", s.Len(), N)
4904		}
4905		for s.Len() > 0 {
4906			c, ok := s.TakeRandom()
4907			if !ok {
4908				t.Fatal("failed to take when non-empty")
4909			}
4910			if !m[c] {
4911				t.Fatal("returned item not in remaining set")
4912			}
4913			delete(m, c)
4914			backOut = append(backOut, c)
4915		}
4916		if len(m) > 0 {
4917			t.Error("items remain in expected map")
4918		}
4919		if slices.Equal(inOrder, backOut) { // N! chance of flaking; N=100 is fine
4920			t.Error("wasn't random")
4921		}
4922	})
4923	t.Run("close-delete", func(t *testing.T) {
4924		reset()
4925		ch := make(chan connRequest)
4926		dh := s.Add(ch)
4927		wantLen(1)
4928		s.CloseAndRemoveAll()
4929		wantLen(0)
4930		if s.Delete(dh) {
4931			t.Error("unexpected delete after CloseAndRemoveAll")
4932		}
4933	})
4934}
4935
4936func BenchmarkConnRequestSet(b *testing.B) {
4937	var s connRequestSet
4938	for range b.N {
4939		for range 16 {
4940			s.Add(nil)
4941		}
4942		for range 8 {
4943			if _, ok := s.TakeRandom(); !ok {
4944				b.Fatal("want ok")
4945			}
4946		}
4947		for range 8 {
4948			s.Add(nil)
4949		}
4950		for range 16 {
4951			if _, ok := s.TakeRandom(); !ok {
4952				b.Fatal("want ok")
4953			}
4954		}
4955		if _, ok := s.TakeRandom(); ok {
4956			b.Fatal("unexpected ok")
4957		}
4958	}
4959}
4960