remove unused files
[platform/upstream/gcc48.git] / libgo / go / database / sql / sql_test.go
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 }