github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/database/sql/sql_test.go (about)

     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  
     5  package sql
     6  
     7  import (
     8  	"fmt"
     9  	"reflect"
    10  	"runtime"
    11  	"strings"
    12  	"sync"
    13  	"testing"
    14  	"time"
    15  )
    16  
    17  func init() {
    18  	type dbConn struct {
    19  		db *DB
    20  		c  *driverConn
    21  	}
    22  	freedFrom := make(map[dbConn]string)
    23  	putConnHook = func(db *DB, c *driverConn) {
    24  		for _, oc := range db.freeConn {
    25  			if oc == c {
    26  				// print before panic, as panic may get lost due to conflicting panic
    27  				// (all goroutines asleep) elsewhere, since we might not unlock
    28  				// the mutex in freeConn here.
    29  				println("double free of conn. conflicts are:\nA) " + freedFrom[dbConn{db, c}] + "\n\nand\nB) " + stack())
    30  				panic("double free of conn.")
    31  			}
    32  		}
    33  		freedFrom[dbConn{db, c}] = stack()
    34  	}
    35  }
    36  
    37  const fakeDBName = "foo"
    38  
    39  var chrisBirthday = time.Unix(123456789, 0)
    40  
    41  type testOrBench interface {
    42  	Fatalf(string, ...interface{})
    43  	Errorf(string, ...interface{})
    44  	Fatal(...interface{})
    45  	Error(...interface{})
    46  	Logf(string, ...interface{})
    47  }
    48  
    49  func newTestDB(t testOrBench, name string) *DB {
    50  	db, err := Open("test", fakeDBName)
    51  	if err != nil {
    52  		t.Fatalf("Open: %v", err)
    53  	}
    54  	if _, err := db.Exec("WIPE"); err != nil {
    55  		t.Fatalf("exec wipe: %v", err)
    56  	}
    57  	if name == "people" {
    58  		exec(t, db, "CREATE|people|name=string,age=int32,photo=blob,dead=bool,bdate=datetime")
    59  		exec(t, db, "INSERT|people|name=Alice,age=?,photo=APHOTO", 1)
    60  		exec(t, db, "INSERT|people|name=Bob,age=?,photo=BPHOTO", 2)
    61  		exec(t, db, "INSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
    62  	}
    63  	if name == "magicquery" {
    64  		// Magic table name and column, known by fakedb_test.go.
    65  		exec(t, db, "CREATE|magicquery|op=string,millis=int32")
    66  		exec(t, db, "INSERT|magicquery|op=sleep,millis=10")
    67  	}
    68  	return db
    69  }
    70  
    71  func exec(t testOrBench, db *DB, query string, args ...interface{}) {
    72  	_, err := db.Exec(query, args...)
    73  	if err != nil {
    74  		t.Fatalf("Exec of %q: %v", query, err)
    75  	}
    76  }
    77  
    78  func closeDB(t testOrBench, db *DB) {
    79  	if e := recover(); e != nil {
    80  		fmt.Printf("Panic: %v\n", e)
    81  		panic(e)
    82  	}
    83  	defer setHookpostCloseConn(nil)
    84  	setHookpostCloseConn(func(_ *fakeConn, err error) {
    85  		if err != nil {
    86  			t.Errorf("Error closing fakeConn: %v", err)
    87  		}
    88  	})
    89  	for i, dc := range db.freeConn {
    90  		if n := len(dc.openStmt); n > 0 {
    91  			// Just a sanity check. This is legal in
    92  			// general, but if we make the tests clean up
    93  			// their statements first, then we can safely
    94  			// verify this is always zero here, and any
    95  			// other value is a leak.
    96  			t.Errorf("while closing db, freeConn %d/%d had %d open stmts; want 0", i, len(db.freeConn), n)
    97  		}
    98  	}
    99  	err := db.Close()
   100  	if err != nil {
   101  		t.Fatalf("error closing DB: %v", err)
   102  	}
   103  }
   104  
   105  // numPrepares assumes that db has exactly 1 idle conn and returns
   106  // its count of calls to Prepare
   107  func numPrepares(t *testing.T, db *DB) int {
   108  	if n := len(db.freeConn); n != 1 {
   109  		t.Fatalf("free conns = %d; want 1", n)
   110  	}
   111  	return db.freeConn[0].ci.(*fakeConn).numPrepare
   112  }
   113  
   114  func (db *DB) numDeps() int {
   115  	db.mu.Lock()
   116  	defer db.mu.Unlock()
   117  	return len(db.dep)
   118  }
   119  
   120  // Dependencies are closed via a goroutine, so this polls waiting for
   121  // numDeps to fall to want, waiting up to d.
   122  func (db *DB) numDepsPollUntil(want int, d time.Duration) int {
   123  	deadline := time.Now().Add(d)
   124  	for {
   125  		n := db.numDeps()
   126  		if n <= want || time.Now().After(deadline) {
   127  			return n
   128  		}
   129  		time.Sleep(50 * time.Millisecond)
   130  	}
   131  }
   132  
   133  func (db *DB) numFreeConns() int {
   134  	db.mu.Lock()
   135  	defer db.mu.Unlock()
   136  	return len(db.freeConn)
   137  }
   138  
   139  func (db *DB) dumpDeps(t *testing.T) {
   140  	for fc := range db.dep {
   141  		db.dumpDep(t, 0, fc, map[finalCloser]bool{})
   142  	}
   143  }
   144  
   145  func (db *DB) dumpDep(t *testing.T, depth int, dep finalCloser, seen map[finalCloser]bool) {
   146  	seen[dep] = true
   147  	indent := strings.Repeat("  ", depth)
   148  	ds := db.dep[dep]
   149  	for k := range ds {
   150  		t.Logf("%s%T (%p) waiting for -> %T (%p)", indent, dep, dep, k, k)
   151  		if fc, ok := k.(finalCloser); ok {
   152  			if !seen[fc] {
   153  				db.dumpDep(t, depth+1, fc, seen)
   154  			}
   155  		}
   156  	}
   157  }
   158  
   159  func TestQuery(t *testing.T) {
   160  	db := newTestDB(t, "people")
   161  	defer closeDB(t, db)
   162  	prepares0 := numPrepares(t, db)
   163  	rows, err := db.Query("SELECT|people|age,name|")
   164  	if err != nil {
   165  		t.Fatalf("Query: %v", err)
   166  	}
   167  	type row struct {
   168  		age  int
   169  		name string
   170  	}
   171  	got := []row{}
   172  	for rows.Next() {
   173  		var r row
   174  		err = rows.Scan(&r.age, &r.name)
   175  		if err != nil {
   176  			t.Fatalf("Scan: %v", err)
   177  		}
   178  		got = append(got, r)
   179  	}
   180  	err = rows.Err()
   181  	if err != nil {
   182  		t.Fatalf("Err: %v", err)
   183  	}
   184  	want := []row{
   185  		{age: 1, name: "Alice"},
   186  		{age: 2, name: "Bob"},
   187  		{age: 3, name: "Chris"},
   188  	}
   189  	if !reflect.DeepEqual(got, want) {
   190  		t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
   191  	}
   192  
   193  	// And verify that the final rows.Next() call, which hit EOF,
   194  	// also closed the rows connection.
   195  	if n := db.numFreeConns(); n != 1 {
   196  		t.Fatalf("free conns after query hitting EOF = %d; want 1", n)
   197  	}
   198  	if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
   199  		t.Errorf("executed %d Prepare statements; want 1", prepares)
   200  	}
   201  }
   202  
   203  func TestByteOwnership(t *testing.T) {
   204  	db := newTestDB(t, "people")
   205  	defer closeDB(t, db)
   206  	rows, err := db.Query("SELECT|people|name,photo|")
   207  	if err != nil {
   208  		t.Fatalf("Query: %v", err)
   209  	}
   210  	type row struct {
   211  		name  []byte
   212  		photo RawBytes
   213  	}
   214  	got := []row{}
   215  	for rows.Next() {
   216  		var r row
   217  		err = rows.Scan(&r.name, &r.photo)
   218  		if err != nil {
   219  			t.Fatalf("Scan: %v", err)
   220  		}
   221  		got = append(got, r)
   222  	}
   223  	corruptMemory := []byte("\xffPHOTO")
   224  	want := []row{
   225  		{name: []byte("Alice"), photo: corruptMemory},
   226  		{name: []byte("Bob"), photo: corruptMemory},
   227  		{name: []byte("Chris"), photo: corruptMemory},
   228  	}
   229  	if !reflect.DeepEqual(got, want) {
   230  		t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
   231  	}
   232  
   233  	var photo RawBytes
   234  	err = db.QueryRow("SELECT|people|photo|name=?", "Alice").Scan(&photo)
   235  	if err == nil {
   236  		t.Error("want error scanning into RawBytes from QueryRow")
   237  	}
   238  }
   239  
   240  func TestRowsColumns(t *testing.T) {
   241  	db := newTestDB(t, "people")
   242  	defer closeDB(t, db)
   243  	rows, err := db.Query("SELECT|people|age,name|")
   244  	if err != nil {
   245  		t.Fatalf("Query: %v", err)
   246  	}
   247  	cols, err := rows.Columns()
   248  	if err != nil {
   249  		t.Fatalf("Columns: %v", err)
   250  	}
   251  	want := []string{"age", "name"}
   252  	if !reflect.DeepEqual(cols, want) {
   253  		t.Errorf("got %#v; want %#v", cols, want)
   254  	}
   255  }
   256  
   257  func TestQueryRow(t *testing.T) {
   258  	db := newTestDB(t, "people")
   259  	defer closeDB(t, db)
   260  	var name string
   261  	var age int
   262  	var birthday time.Time
   263  
   264  	err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age)
   265  	if err == nil || !strings.Contains(err.Error(), "expected 2 destination arguments") {
   266  		t.Errorf("expected error from wrong number of arguments; actually got: %v", err)
   267  	}
   268  
   269  	err = db.QueryRow("SELECT|people|bdate|age=?", 3).Scan(&birthday)
   270  	if err != nil || !birthday.Equal(chrisBirthday) {
   271  		t.Errorf("chris birthday = %v, err = %v; want %v", birthday, err, chrisBirthday)
   272  	}
   273  
   274  	err = db.QueryRow("SELECT|people|age,name|age=?", 2).Scan(&age, &name)
   275  	if err != nil {
   276  		t.Fatalf("age QueryRow+Scan: %v", err)
   277  	}
   278  	if name != "Bob" {
   279  		t.Errorf("expected name Bob, got %q", name)
   280  	}
   281  	if age != 2 {
   282  		t.Errorf("expected age 2, got %d", age)
   283  	}
   284  
   285  	err = db.QueryRow("SELECT|people|age,name|name=?", "Alice").Scan(&age, &name)
   286  	if err != nil {
   287  		t.Fatalf("name QueryRow+Scan: %v", err)
   288  	}
   289  	if name != "Alice" {
   290  		t.Errorf("expected name Alice, got %q", name)
   291  	}
   292  	if age != 1 {
   293  		t.Errorf("expected age 1, got %d", age)
   294  	}
   295  
   296  	var photo []byte
   297  	err = db.QueryRow("SELECT|people|photo|name=?", "Alice").Scan(&photo)
   298  	if err != nil {
   299  		t.Fatalf("photo QueryRow+Scan: %v", err)
   300  	}
   301  	want := []byte("APHOTO")
   302  	if !reflect.DeepEqual(photo, want) {
   303  		t.Errorf("photo = %q; want %q", photo, want)
   304  	}
   305  }
   306  
   307  func TestStatementErrorAfterClose(t *testing.T) {
   308  	db := newTestDB(t, "people")
   309  	defer closeDB(t, db)
   310  	stmt, err := db.Prepare("SELECT|people|age|name=?")
   311  	if err != nil {
   312  		t.Fatalf("Prepare: %v", err)
   313  	}
   314  	err = stmt.Close()
   315  	if err != nil {
   316  		t.Fatalf("Close: %v", err)
   317  	}
   318  	var name string
   319  	err = stmt.QueryRow("foo").Scan(&name)
   320  	if err == nil {
   321  		t.Errorf("expected error from QueryRow.Scan after Stmt.Close")
   322  	}
   323  }
   324  
   325  func TestStatementQueryRow(t *testing.T) {
   326  	db := newTestDB(t, "people")
   327  	defer closeDB(t, db)
   328  	stmt, err := db.Prepare("SELECT|people|age|name=?")
   329  	if err != nil {
   330  		t.Fatalf("Prepare: %v", err)
   331  	}
   332  	defer stmt.Close()
   333  	var age int
   334  	for n, tt := range []struct {
   335  		name string
   336  		want int
   337  	}{
   338  		{"Alice", 1},
   339  		{"Bob", 2},
   340  		{"Chris", 3},
   341  	} {
   342  		if err := stmt.QueryRow(tt.name).Scan(&age); err != nil {
   343  			t.Errorf("%d: on %q, QueryRow/Scan: %v", n, tt.name, err)
   344  		} else if age != tt.want {
   345  			t.Errorf("%d: age=%d, want %d", n, age, tt.want)
   346  		}
   347  	}
   348  
   349  }
   350  
   351  // golang.org/issue/3734
   352  func TestStatementQueryRowConcurrent(t *testing.T) {
   353  	db := newTestDB(t, "people")
   354  	defer closeDB(t, db)
   355  	stmt, err := db.Prepare("SELECT|people|age|name=?")
   356  	if err != nil {
   357  		t.Fatalf("Prepare: %v", err)
   358  	}
   359  	defer stmt.Close()
   360  
   361  	const n = 10
   362  	ch := make(chan error, n)
   363  	for i := 0; i < n; i++ {
   364  		go func() {
   365  			var age int
   366  			err := stmt.QueryRow("Alice").Scan(&age)
   367  			if err == nil && age != 1 {
   368  				err = fmt.Errorf("unexpected age %d", age)
   369  			}
   370  			ch <- err
   371  		}()
   372  	}
   373  	for i := 0; i < n; i++ {
   374  		if err := <-ch; err != nil {
   375  			t.Error(err)
   376  		}
   377  	}
   378  }
   379  
   380  // just a test of fakedb itself
   381  func TestBogusPreboundParameters(t *testing.T) {
   382  	db := newTestDB(t, "foo")
   383  	defer closeDB(t, db)
   384  	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
   385  	_, err := db.Prepare("INSERT|t1|name=?,age=bogusconversion")
   386  	if err == nil {
   387  		t.Fatalf("expected error")
   388  	}
   389  	if err.Error() != `fakedb: invalid conversion to int32 from "bogusconversion"` {
   390  		t.Errorf("unexpected error: %v", err)
   391  	}
   392  }
   393  
   394  func TestExec(t *testing.T) {
   395  	db := newTestDB(t, "foo")
   396  	defer closeDB(t, db)
   397  	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
   398  	stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
   399  	if err != nil {
   400  		t.Errorf("Stmt, err = %v, %v", stmt, err)
   401  	}
   402  	defer stmt.Close()
   403  
   404  	type execTest struct {
   405  		args    []interface{}
   406  		wantErr string
   407  	}
   408  	execTests := []execTest{
   409  		// Okay:
   410  		{[]interface{}{"Brad", 31}, ""},
   411  		{[]interface{}{"Brad", int64(31)}, ""},
   412  		{[]interface{}{"Bob", "32"}, ""},
   413  		{[]interface{}{7, 9}, ""},
   414  
   415  		// Invalid conversions:
   416  		{[]interface{}{"Brad", int64(0xFFFFFFFF)}, "sql: converting argument #1's type: sql/driver: value 4294967295 overflows int32"},
   417  		{[]interface{}{"Brad", "strconv fail"}, "sql: converting argument #1's type: sql/driver: value \"strconv fail\" can't be converted to int32"},
   418  
   419  		// Wrong number of args:
   420  		{[]interface{}{}, "sql: expected 2 arguments, got 0"},
   421  		{[]interface{}{1, 2, 3}, "sql: expected 2 arguments, got 3"},
   422  	}
   423  	for n, et := range execTests {
   424  		_, err := stmt.Exec(et.args...)
   425  		errStr := ""
   426  		if err != nil {
   427  			errStr = err.Error()
   428  		}
   429  		if errStr != et.wantErr {
   430  			t.Errorf("stmt.Execute #%d: for %v, got error %q, want error %q",
   431  				n, et.args, errStr, et.wantErr)
   432  		}
   433  	}
   434  }
   435  
   436  func TestTxStmt(t *testing.T) {
   437  	db := newTestDB(t, "")
   438  	defer closeDB(t, db)
   439  	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
   440  	stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
   441  	if err != nil {
   442  		t.Fatalf("Stmt, err = %v, %v", stmt, err)
   443  	}
   444  	defer stmt.Close()
   445  	tx, err := db.Begin()
   446  	if err != nil {
   447  		t.Fatalf("Begin = %v", err)
   448  	}
   449  	txs := tx.Stmt(stmt)
   450  	defer txs.Close()
   451  	_, err = txs.Exec("Bobby", 7)
   452  	if err != nil {
   453  		t.Fatalf("Exec = %v", err)
   454  	}
   455  	err = tx.Commit()
   456  	if err != nil {
   457  		t.Fatalf("Commit = %v", err)
   458  	}
   459  }
   460  
   461  // Issue: http://golang.org/issue/2784
   462  // This test didn't fail before because we got luckly with the fakedb driver.
   463  // It was failing, and now not, in github.com/bradfitz/go-sql-test
   464  func TestTxQuery(t *testing.T) {
   465  	db := newTestDB(t, "")
   466  	defer closeDB(t, db)
   467  	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
   468  	exec(t, db, "INSERT|t1|name=Alice")
   469  
   470  	tx, err := db.Begin()
   471  	if err != nil {
   472  		t.Fatal(err)
   473  	}
   474  	defer tx.Rollback()
   475  
   476  	r, err := tx.Query("SELECT|t1|name|")
   477  	if err != nil {
   478  		t.Fatal(err)
   479  	}
   480  	defer r.Close()
   481  
   482  	if !r.Next() {
   483  		if r.Err() != nil {
   484  			t.Fatal(r.Err())
   485  		}
   486  		t.Fatal("expected one row")
   487  	}
   488  
   489  	var x string
   490  	err = r.Scan(&x)
   491  	if err != nil {
   492  		t.Fatal(err)
   493  	}
   494  }
   495  
   496  func TestTxQueryInvalid(t *testing.T) {
   497  	db := newTestDB(t, "")
   498  	defer closeDB(t, db)
   499  
   500  	tx, err := db.Begin()
   501  	if err != nil {
   502  		t.Fatal(err)
   503  	}
   504  	defer tx.Rollback()
   505  
   506  	_, err = tx.Query("SELECT|t1|name|")
   507  	if err == nil {
   508  		t.Fatal("Error expected")
   509  	}
   510  }
   511  
   512  // Tests fix for issue 4433, that retries in Begin happen when
   513  // conn.Begin() returns ErrBadConn
   514  func TestTxErrBadConn(t *testing.T) {
   515  	db, err := Open("test", fakeDBName+";badConn")
   516  	if err != nil {
   517  		t.Fatalf("Open: %v", err)
   518  	}
   519  	if _, err := db.Exec("WIPE"); err != nil {
   520  		t.Fatalf("exec wipe: %v", err)
   521  	}
   522  	defer closeDB(t, db)
   523  	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
   524  	stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
   525  	if err != nil {
   526  		t.Fatalf("Stmt, err = %v, %v", stmt, err)
   527  	}
   528  	defer stmt.Close()
   529  	tx, err := db.Begin()
   530  	if err != nil {
   531  		t.Fatalf("Begin = %v", err)
   532  	}
   533  	txs := tx.Stmt(stmt)
   534  	defer txs.Close()
   535  	_, err = txs.Exec("Bobby", 7)
   536  	if err != nil {
   537  		t.Fatalf("Exec = %v", err)
   538  	}
   539  	err = tx.Commit()
   540  	if err != nil {
   541  		t.Fatalf("Commit = %v", err)
   542  	}
   543  }
   544  
   545  // Tests fix for issue 2542, that we release a lock when querying on
   546  // a closed connection.
   547  func TestIssue2542Deadlock(t *testing.T) {
   548  	db := newTestDB(t, "people")
   549  	closeDB(t, db)
   550  	for i := 0; i < 2; i++ {
   551  		_, err := db.Query("SELECT|people|age,name|")
   552  		if err == nil {
   553  			t.Fatalf("expected error")
   554  		}
   555  	}
   556  }
   557  
   558  // From golang.org/issue/3865
   559  func TestCloseStmtBeforeRows(t *testing.T) {
   560  	db := newTestDB(t, "people")
   561  	defer closeDB(t, db)
   562  
   563  	s, err := db.Prepare("SELECT|people|name|")
   564  	if err != nil {
   565  		t.Fatal(err)
   566  	}
   567  
   568  	r, err := s.Query()
   569  	if err != nil {
   570  		s.Close()
   571  		t.Fatal(err)
   572  	}
   573  
   574  	err = s.Close()
   575  	if err != nil {
   576  		t.Fatal(err)
   577  	}
   578  
   579  	r.Close()
   580  }
   581  
   582  // Tests fix for issue 2788, that we bind nil to a []byte if the
   583  // value in the column is sql null
   584  func TestNullByteSlice(t *testing.T) {
   585  	db := newTestDB(t, "")
   586  	defer closeDB(t, db)
   587  	exec(t, db, "CREATE|t|id=int32,name=nullstring")
   588  	exec(t, db, "INSERT|t|id=10,name=?", nil)
   589  
   590  	var name []byte
   591  
   592  	err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name)
   593  	if err != nil {
   594  		t.Fatal(err)
   595  	}
   596  	if name != nil {
   597  		t.Fatalf("name []byte should be nil for null column value, got: %#v", name)
   598  	}
   599  
   600  	exec(t, db, "INSERT|t|id=11,name=?", "bob")
   601  	err = db.QueryRow("SELECT|t|name|id=?", 11).Scan(&name)
   602  	if err != nil {
   603  		t.Fatal(err)
   604  	}
   605  	if string(name) != "bob" {
   606  		t.Fatalf("name []byte should be bob, got: %q", string(name))
   607  	}
   608  }
   609  
   610  func TestPointerParamsAndScans(t *testing.T) {
   611  	db := newTestDB(t, "")
   612  	defer closeDB(t, db)
   613  	exec(t, db, "CREATE|t|id=int32,name=nullstring")
   614  
   615  	bob := "bob"
   616  	var name *string
   617  
   618  	name = &bob
   619  	exec(t, db, "INSERT|t|id=10,name=?", name)
   620  	name = nil
   621  	exec(t, db, "INSERT|t|id=20,name=?", name)
   622  
   623  	err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name)
   624  	if err != nil {
   625  		t.Fatalf("querying id 10: %v", err)
   626  	}
   627  	if name == nil {
   628  		t.Errorf("id 10's name = nil; want bob")
   629  	} else if *name != "bob" {
   630  		t.Errorf("id 10's name = %q; want bob", *name)
   631  	}
   632  
   633  	err = db.QueryRow("SELECT|t|name|id=?", 20).Scan(&name)
   634  	if err != nil {
   635  		t.Fatalf("querying id 20: %v", err)
   636  	}
   637  	if name != nil {
   638  		t.Errorf("id 20 = %q; want nil", *name)
   639  	}
   640  }
   641  
   642  func TestQueryRowClosingStmt(t *testing.T) {
   643  	db := newTestDB(t, "people")
   644  	defer closeDB(t, db)
   645  	var name string
   646  	var age int
   647  	err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age, &name)
   648  	if err != nil {
   649  		t.Fatal(err)
   650  	}
   651  	if len(db.freeConn) != 1 {
   652  		t.Fatalf("expected 1 free conn")
   653  	}
   654  	fakeConn := db.freeConn[0].ci.(*fakeConn)
   655  	if made, closed := fakeConn.stmtsMade, fakeConn.stmtsClosed; made != closed {
   656  		t.Errorf("statement close mismatch: made %d, closed %d", made, closed)
   657  	}
   658  }
   659  
   660  type nullTestRow struct {
   661  	nullParam    interface{}
   662  	notNullParam interface{}
   663  	scanNullVal  interface{}
   664  }
   665  
   666  type nullTestSpec struct {
   667  	nullType    string
   668  	notNullType string
   669  	rows        [6]nullTestRow
   670  }
   671  
   672  func TestNullStringParam(t *testing.T) {
   673  	spec := nullTestSpec{"nullstring", "string", [6]nullTestRow{
   674  		{NullString{"aqua", true}, "", NullString{"aqua", true}},
   675  		{NullString{"brown", false}, "", NullString{"", false}},
   676  		{"chartreuse", "", NullString{"chartreuse", true}},
   677  		{NullString{"darkred", true}, "", NullString{"darkred", true}},
   678  		{NullString{"eel", false}, "", NullString{"", false}},
   679  		{"foo", NullString{"black", false}, nil},
   680  	}}
   681  	nullTestRun(t, spec)
   682  }
   683  
   684  func TestNullInt64Param(t *testing.T) {
   685  	spec := nullTestSpec{"nullint64", "int64", [6]nullTestRow{
   686  		{NullInt64{31, true}, 1, NullInt64{31, true}},
   687  		{NullInt64{-22, false}, 1, NullInt64{0, false}},
   688  		{22, 1, NullInt64{22, true}},
   689  		{NullInt64{33, true}, 1, NullInt64{33, true}},
   690  		{NullInt64{222, false}, 1, NullInt64{0, false}},
   691  		{0, NullInt64{31, false}, nil},
   692  	}}
   693  	nullTestRun(t, spec)
   694  }
   695  
   696  func TestNullFloat64Param(t *testing.T) {
   697  	spec := nullTestSpec{"nullfloat64", "float64", [6]nullTestRow{
   698  		{NullFloat64{31.2, true}, 1, NullFloat64{31.2, true}},
   699  		{NullFloat64{13.1, false}, 1, NullFloat64{0, false}},
   700  		{-22.9, 1, NullFloat64{-22.9, true}},
   701  		{NullFloat64{33.81, true}, 1, NullFloat64{33.81, true}},
   702  		{NullFloat64{222, false}, 1, NullFloat64{0, false}},
   703  		{10, NullFloat64{31.2, false}, nil},
   704  	}}
   705  	nullTestRun(t, spec)
   706  }
   707  
   708  func TestNullBoolParam(t *testing.T) {
   709  	spec := nullTestSpec{"nullbool", "bool", [6]nullTestRow{
   710  		{NullBool{false, true}, true, NullBool{false, true}},
   711  		{NullBool{true, false}, false, NullBool{false, false}},
   712  		{true, true, NullBool{true, true}},
   713  		{NullBool{true, true}, false, NullBool{true, true}},
   714  		{NullBool{true, false}, true, NullBool{false, false}},
   715  		{true, NullBool{true, false}, nil},
   716  	}}
   717  	nullTestRun(t, spec)
   718  }
   719  
   720  func nullTestRun(t *testing.T, spec nullTestSpec) {
   721  	db := newTestDB(t, "")
   722  	defer closeDB(t, db)
   723  	exec(t, db, fmt.Sprintf("CREATE|t|id=int32,name=string,nullf=%s,notnullf=%s", spec.nullType, spec.notNullType))
   724  
   725  	// Inserts with db.Exec:
   726  	exec(t, db, "INSERT|t|id=?,name=?,nullf=?,notnullf=?", 1, "alice", spec.rows[0].nullParam, spec.rows[0].notNullParam)
   727  	exec(t, db, "INSERT|t|id=?,name=?,nullf=?,notnullf=?", 2, "bob", spec.rows[1].nullParam, spec.rows[1].notNullParam)
   728  
   729  	// Inserts with a prepared statement:
   730  	stmt, err := db.Prepare("INSERT|t|id=?,name=?,nullf=?,notnullf=?")
   731  	if err != nil {
   732  		t.Fatalf("prepare: %v", err)
   733  	}
   734  	defer stmt.Close()
   735  	if _, err := stmt.Exec(3, "chris", spec.rows[2].nullParam, spec.rows[2].notNullParam); err != nil {
   736  		t.Errorf("exec insert chris: %v", err)
   737  	}
   738  	if _, err := stmt.Exec(4, "dave", spec.rows[3].nullParam, spec.rows[3].notNullParam); err != nil {
   739  		t.Errorf("exec insert dave: %v", err)
   740  	}
   741  	if _, err := stmt.Exec(5, "eleanor", spec.rows[4].nullParam, spec.rows[4].notNullParam); err != nil {
   742  		t.Errorf("exec insert eleanor: %v", err)
   743  	}
   744  
   745  	// Can't put null val into non-null col
   746  	if _, err := stmt.Exec(6, "bob", spec.rows[5].nullParam, spec.rows[5].notNullParam); err == nil {
   747  		t.Errorf("expected error inserting nil val with prepared statement Exec")
   748  	}
   749  
   750  	_, err = db.Exec("INSERT|t|id=?,name=?,nullf=?", 999, nil, nil)
   751  	if err == nil {
   752  		// TODO: this test fails, but it's just because
   753  		// fakeConn implements the optional Execer interface,
   754  		// so arguably this is the correct behavior.  But
   755  		// maybe I should flesh out the fakeConn.Exec
   756  		// implementation so this properly fails.
   757  		// t.Errorf("expected error inserting nil name with Exec")
   758  	}
   759  
   760  	paramtype := reflect.TypeOf(spec.rows[0].nullParam)
   761  	bindVal := reflect.New(paramtype).Interface()
   762  
   763  	for i := 0; i < 5; i++ {
   764  		id := i + 1
   765  		if err := db.QueryRow("SELECT|t|nullf|id=?", id).Scan(bindVal); err != nil {
   766  			t.Errorf("id=%d Scan: %v", id, err)
   767  		}
   768  		bindValDeref := reflect.ValueOf(bindVal).Elem().Interface()
   769  		if !reflect.DeepEqual(bindValDeref, spec.rows[i].scanNullVal) {
   770  			t.Errorf("id=%d got %#v, want %#v", id, bindValDeref, spec.rows[i].scanNullVal)
   771  		}
   772  	}
   773  }
   774  
   775  // golang.org/issue/4859
   776  func TestQueryRowNilScanDest(t *testing.T) {
   777  	db := newTestDB(t, "people")
   778  	defer closeDB(t, db)
   779  	var name *string // nil pointer
   780  	err := db.QueryRow("SELECT|people|name|").Scan(name)
   781  	want := "sql: Scan error on column index 0: destination pointer is nil"
   782  	if err == nil || err.Error() != want {
   783  		t.Errorf("error = %q; want %q", err.Error(), want)
   784  	}
   785  }
   786  
   787  func TestIssue4902(t *testing.T) {
   788  	db := newTestDB(t, "people")
   789  	defer closeDB(t, db)
   790  
   791  	driver := db.driver.(*fakeDriver)
   792  	opens0 := driver.openCount
   793  
   794  	var stmt *Stmt
   795  	var err error
   796  	for i := 0; i < 10; i++ {
   797  		stmt, err = db.Prepare("SELECT|people|name|")
   798  		if err != nil {
   799  			t.Fatal(err)
   800  		}
   801  		err = stmt.Close()
   802  		if err != nil {
   803  			t.Fatal(err)
   804  		}
   805  	}
   806  
   807  	opens := driver.openCount - opens0
   808  	if opens > 1 {
   809  		t.Errorf("opens = %d; want <= 1", opens)
   810  		t.Logf("db = %#v", db)
   811  		t.Logf("driver = %#v", driver)
   812  		t.Logf("stmt = %#v", stmt)
   813  	}
   814  }
   815  
   816  // Issue 3857
   817  // This used to deadlock.
   818  func TestSimultaneousQueries(t *testing.T) {
   819  	db := newTestDB(t, "people")
   820  	defer closeDB(t, db)
   821  
   822  	tx, err := db.Begin()
   823  	if err != nil {
   824  		t.Fatal(err)
   825  	}
   826  	defer tx.Rollback()
   827  
   828  	r1, err := tx.Query("SELECT|people|name|")
   829  	if err != nil {
   830  		t.Fatal(err)
   831  	}
   832  	defer r1.Close()
   833  
   834  	r2, err := tx.Query("SELECT|people|name|")
   835  	if err != nil {
   836  		t.Fatal(err)
   837  	}
   838  	defer r2.Close()
   839  }
   840  
   841  func TestMaxIdleConns(t *testing.T) {
   842  	db := newTestDB(t, "people")
   843  	defer closeDB(t, db)
   844  
   845  	tx, err := db.Begin()
   846  	if err != nil {
   847  		t.Fatal(err)
   848  	}
   849  	tx.Commit()
   850  	if got := len(db.freeConn); got != 1 {
   851  		t.Errorf("freeConns = %d; want 1", got)
   852  	}
   853  
   854  	db.SetMaxIdleConns(0)
   855  
   856  	if got := len(db.freeConn); got != 0 {
   857  		t.Errorf("freeConns after set to zero = %d; want 0", got)
   858  	}
   859  
   860  	tx, err = db.Begin()
   861  	if err != nil {
   862  		t.Fatal(err)
   863  	}
   864  	tx.Commit()
   865  	if got := len(db.freeConn); got != 0 {
   866  		t.Errorf("freeConns = %d; want 0", got)
   867  	}
   868  }
   869  
   870  // golang.org/issue/5323
   871  func TestStmtCloseDeps(t *testing.T) {
   872  	if testing.Short() {
   873  		t.Skip("skipping in short mode")
   874  	}
   875  	defer setHookpostCloseConn(nil)
   876  	setHookpostCloseConn(func(_ *fakeConn, err error) {
   877  		if err != nil {
   878  			t.Errorf("Error closing fakeConn: %v", err)
   879  		}
   880  	})
   881  
   882  	db := newTestDB(t, "magicquery")
   883  	defer closeDB(t, db)
   884  
   885  	driver := db.driver.(*fakeDriver)
   886  
   887  	driver.mu.Lock()
   888  	opens0 := driver.openCount
   889  	closes0 := driver.closeCount
   890  	driver.mu.Unlock()
   891  	openDelta0 := opens0 - closes0
   892  
   893  	stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?")
   894  	if err != nil {
   895  		t.Fatal(err)
   896  	}
   897  
   898  	// Start 50 parallel slow queries.
   899  	const (
   900  		nquery      = 50
   901  		sleepMillis = 25
   902  		nbatch      = 2
   903  	)
   904  	var wg sync.WaitGroup
   905  	for batch := 0; batch < nbatch; batch++ {
   906  		for i := 0; i < nquery; i++ {
   907  			wg.Add(1)
   908  			go func() {
   909  				defer wg.Done()
   910  				var op string
   911  				if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows {
   912  					t.Error(err)
   913  				}
   914  			}()
   915  		}
   916  		// Sleep for twice the expected length of time for the
   917  		// batch of 50 queries above to finish before starting
   918  		// the next round.
   919  		time.Sleep(2 * sleepMillis * time.Millisecond)
   920  	}
   921  	wg.Wait()
   922  
   923  	if g, w := db.numFreeConns(), 2; g != w {
   924  		t.Errorf("free conns = %d; want %d", g, w)
   925  	}
   926  
   927  	if n := db.numDepsPollUntil(4, time.Second); n > 4 {
   928  		t.Errorf("number of dependencies = %d; expected <= 4", n)
   929  		db.dumpDeps(t)
   930  	}
   931  
   932  	driver.mu.Lock()
   933  	opens := driver.openCount - opens0
   934  	closes := driver.closeCount - closes0
   935  	driver.mu.Unlock()
   936  	openDelta := (driver.openCount - driver.closeCount) - openDelta0
   937  
   938  	if openDelta > 2 {
   939  		t.Logf("open calls = %d", opens)
   940  		t.Logf("close calls = %d", closes)
   941  		t.Logf("open delta = %d", openDelta)
   942  		t.Errorf("db connections opened = %d; want <= 2", openDelta)
   943  		db.dumpDeps(t)
   944  	}
   945  
   946  	if len(stmt.css) > nquery {
   947  		t.Errorf("len(stmt.css) = %d; want <= %d", len(stmt.css), nquery)
   948  	}
   949  
   950  	if err := stmt.Close(); err != nil {
   951  		t.Fatal(err)
   952  	}
   953  
   954  	if g, w := db.numFreeConns(), 2; g != w {
   955  		t.Errorf("free conns = %d; want %d", g, w)
   956  	}
   957  
   958  	if n := db.numDepsPollUntil(2, time.Second); n > 2 {
   959  		t.Errorf("number of dependencies = %d; expected <= 2", n)
   960  		db.dumpDeps(t)
   961  	}
   962  
   963  	db.SetMaxIdleConns(0)
   964  
   965  	if g, w := db.numFreeConns(), 0; g != w {
   966  		t.Errorf("free conns = %d; want %d", g, w)
   967  	}
   968  
   969  	if n := db.numDepsPollUntil(0, time.Second); n > 0 {
   970  		t.Errorf("number of dependencies = %d; expected 0", n)
   971  		db.dumpDeps(t)
   972  	}
   973  }
   974  
   975  // golang.org/issue/5046
   976  func TestCloseConnBeforeStmts(t *testing.T) {
   977  	db := newTestDB(t, "people")
   978  	defer closeDB(t, db)
   979  
   980  	defer setHookpostCloseConn(nil)
   981  	setHookpostCloseConn(func(_ *fakeConn, err error) {
   982  		if err != nil {
   983  			t.Errorf("Error closing fakeConn: %v; from %s", err, stack())
   984  			db.dumpDeps(t)
   985  			t.Errorf("DB = %#v", db)
   986  		}
   987  	})
   988  
   989  	stmt, err := db.Prepare("SELECT|people|name|")
   990  	if err != nil {
   991  		t.Fatal(err)
   992  	}
   993  
   994  	if len(db.freeConn) != 1 {
   995  		t.Fatalf("expected 1 freeConn; got %d", len(db.freeConn))
   996  	}
   997  	dc := db.freeConn[0]
   998  	if dc.closed {
   999  		t.Errorf("conn shouldn't be closed")
  1000  	}
  1001  
  1002  	if n := len(dc.openStmt); n != 1 {
  1003  		t.Errorf("driverConn num openStmt = %d; want 1", n)
  1004  	}
  1005  	err = db.Close()
  1006  	if err != nil {
  1007  		t.Errorf("db Close = %v", err)
  1008  	}
  1009  	if !dc.closed {
  1010  		t.Errorf("after db.Close, driverConn should be closed")
  1011  	}
  1012  	if n := len(dc.openStmt); n != 0 {
  1013  		t.Errorf("driverConn num openStmt = %d; want 0", n)
  1014  	}
  1015  
  1016  	err = stmt.Close()
  1017  	if err != nil {
  1018  		t.Errorf("Stmt close = %v", err)
  1019  	}
  1020  
  1021  	if !dc.closed {
  1022  		t.Errorf("conn should be closed")
  1023  	}
  1024  	if dc.ci != nil {
  1025  		t.Errorf("after Stmt Close, driverConn's Conn interface should be nil")
  1026  	}
  1027  }
  1028  
  1029  // golang.org/issue/5283: don't release the Rows' connection in Close
  1030  // before calling Stmt.Close.
  1031  func TestRowsCloseOrder(t *testing.T) {
  1032  	db := newTestDB(t, "people")
  1033  	defer closeDB(t, db)
  1034  
  1035  	db.SetMaxIdleConns(0)
  1036  	setStrictFakeConnClose(t)
  1037  	defer setStrictFakeConnClose(nil)
  1038  
  1039  	rows, err := db.Query("SELECT|people|age,name|")
  1040  	if err != nil {
  1041  		t.Fatal(err)
  1042  	}
  1043  	err = rows.Close()
  1044  	if err != nil {
  1045  		t.Fatal(err)
  1046  	}
  1047  }
  1048  
  1049  func manyConcurrentQueries(t testOrBench) {
  1050  	maxProcs, numReqs := 16, 500
  1051  	if testing.Short() {
  1052  		maxProcs, numReqs = 4, 50
  1053  	}
  1054  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
  1055  
  1056  	db := newTestDB(t, "people")
  1057  	defer closeDB(t, db)
  1058  
  1059  	stmt, err := db.Prepare("SELECT|people|name|")
  1060  	if err != nil {
  1061  		t.Fatal(err)
  1062  	}
  1063  	defer stmt.Close()
  1064  
  1065  	var wg sync.WaitGroup
  1066  	wg.Add(numReqs)
  1067  
  1068  	reqs := make(chan bool)
  1069  	defer close(reqs)
  1070  
  1071  	for i := 0; i < maxProcs*2; i++ {
  1072  		go func() {
  1073  			for _ = range reqs {
  1074  				rows, err := stmt.Query()
  1075  				if err != nil {
  1076  					t.Errorf("error on query:  %v", err)
  1077  					wg.Done()
  1078  					continue
  1079  				}
  1080  
  1081  				var name string
  1082  				for rows.Next() {
  1083  					rows.Scan(&name)
  1084  				}
  1085  				rows.Close()
  1086  
  1087  				wg.Done()
  1088  			}
  1089  		}()
  1090  	}
  1091  
  1092  	for i := 0; i < numReqs; i++ {
  1093  		reqs <- true
  1094  	}
  1095  
  1096  	wg.Wait()
  1097  }
  1098  
  1099  func TestConcurrency(t *testing.T) {
  1100  	manyConcurrentQueries(t)
  1101  }
  1102  
  1103  func BenchmarkConcurrency(b *testing.B) {
  1104  	b.ReportAllocs()
  1105  	for i := 0; i < b.N; i++ {
  1106  		manyConcurrentQueries(b)
  1107  	}
  1108  }