github.com/hlts2/go@v0.0.0-20170904000733-812b34efaed8/src/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 "context" 9 "database/sql/driver" 10 "errors" 11 "fmt" 12 "math/rand" 13 "reflect" 14 "runtime" 15 "strings" 16 "sync" 17 "sync/atomic" 18 "testing" 19 "time" 20 ) 21 22 func init() { 23 type dbConn struct { 24 db *DB 25 c *driverConn 26 } 27 freedFrom := make(map[dbConn]string) 28 var mu sync.Mutex 29 getFreedFrom := func(c dbConn) string { 30 mu.Lock() 31 defer mu.Unlock() 32 return freedFrom[c] 33 } 34 setFreedFrom := func(c dbConn, s string) { 35 mu.Lock() 36 defer mu.Unlock() 37 freedFrom[c] = s 38 } 39 putConnHook = func(db *DB, c *driverConn) { 40 idx := -1 41 for i, v := range db.freeConn { 42 if v == c { 43 idx = i 44 break 45 } 46 } 47 if idx >= 0 { 48 // print before panic, as panic may get lost due to conflicting panic 49 // (all goroutines asleep) elsewhere, since we might not unlock 50 // the mutex in freeConn here. 51 println("double free of conn. conflicts are:\nA) " + getFreedFrom(dbConn{db, c}) + "\n\nand\nB) " + stack()) 52 panic("double free of conn.") 53 } 54 setFreedFrom(dbConn{db, c}, stack()) 55 } 56 } 57 58 const fakeDBName = "foo" 59 60 var chrisBirthday = time.Unix(123456789, 0) 61 62 func newTestDB(t testing.TB, name string) *DB { 63 db, err := Open("test", fakeDBName) 64 if err != nil { 65 t.Fatalf("Open: %v", err) 66 } 67 if _, err := db.Exec("WIPE"); err != nil { 68 t.Fatalf("exec wipe: %v", err) 69 } 70 if name == "people" { 71 exec(t, db, "CREATE|people|name=string,age=int32,photo=blob,dead=bool,bdate=datetime") 72 exec(t, db, "INSERT|people|name=Alice,age=?,photo=APHOTO", 1) 73 exec(t, db, "INSERT|people|name=Bob,age=?,photo=BPHOTO", 2) 74 exec(t, db, "INSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday) 75 } 76 if name == "magicquery" { 77 // Magic table name and column, known by fakedb_test.go. 78 exec(t, db, "CREATE|magicquery|op=string,millis=int32") 79 exec(t, db, "INSERT|magicquery|op=sleep,millis=10") 80 } 81 return db 82 } 83 84 func TestDriverPanic(t *testing.T) { 85 // Test that if driver panics, database/sql does not deadlock. 86 db, err := Open("test", fakeDBName) 87 if err != nil { 88 t.Fatalf("Open: %v", err) 89 } 90 expectPanic := func(name string, f func()) { 91 defer func() { 92 err := recover() 93 if err == nil { 94 t.Fatalf("%s did not panic", name) 95 } 96 }() 97 f() 98 } 99 100 expectPanic("Exec Exec", func() { db.Exec("PANIC|Exec|WIPE") }) 101 exec(t, db, "WIPE") // check not deadlocked 102 expectPanic("Exec NumInput", func() { db.Exec("PANIC|NumInput|WIPE") }) 103 exec(t, db, "WIPE") // check not deadlocked 104 expectPanic("Exec Close", func() { db.Exec("PANIC|Close|WIPE") }) 105 exec(t, db, "WIPE") // check not deadlocked 106 exec(t, db, "PANIC|Query|WIPE") // should run successfully: Exec does not call Query 107 exec(t, db, "WIPE") // check not deadlocked 108 109 exec(t, db, "CREATE|people|name=string,age=int32,photo=blob,dead=bool,bdate=datetime") 110 111 expectPanic("Query Query", func() { db.Query("PANIC|Query|SELECT|people|age,name|") }) 112 expectPanic("Query NumInput", func() { db.Query("PANIC|NumInput|SELECT|people|age,name|") }) 113 expectPanic("Query Close", func() { 114 rows, err := db.Query("PANIC|Close|SELECT|people|age,name|") 115 if err != nil { 116 t.Fatal(err) 117 } 118 rows.Close() 119 }) 120 db.Query("PANIC|Exec|SELECT|people|age,name|") // should run successfully: Query does not call Exec 121 exec(t, db, "WIPE") // check not deadlocked 122 } 123 124 func exec(t testing.TB, db *DB, query string, args ...interface{}) { 125 _, err := db.Exec(query, args...) 126 if err != nil { 127 t.Fatalf("Exec of %q: %v", query, err) 128 } 129 } 130 131 func closeDB(t testing.TB, db *DB) { 132 if e := recover(); e != nil { 133 fmt.Printf("Panic: %v\n", e) 134 panic(e) 135 } 136 defer setHookpostCloseConn(nil) 137 setHookpostCloseConn(func(_ *fakeConn, err error) { 138 if err != nil { 139 t.Errorf("Error closing fakeConn: %v", err) 140 } 141 }) 142 db.mu.Lock() 143 for i, dc := range db.freeConn { 144 if n := len(dc.openStmt); n > 0 { 145 // Just a sanity check. This is legal in 146 // general, but if we make the tests clean up 147 // their statements first, then we can safely 148 // verify this is always zero here, and any 149 // other value is a leak. 150 t.Errorf("while closing db, freeConn %d/%d had %d open stmts; want 0", i, len(db.freeConn), n) 151 } 152 } 153 db.mu.Unlock() 154 155 err := db.Close() 156 if err != nil { 157 t.Fatalf("error closing DB: %v", err) 158 } 159 160 var numOpen int 161 if !waitCondition(5*time.Second, 5*time.Millisecond, func() bool { 162 numOpen = db.numOpenConns() 163 return numOpen == 0 164 }) { 165 t.Fatalf("%d connections still open after closing DB", numOpen) 166 } 167 } 168 169 // numPrepares assumes that db has exactly 1 idle conn and returns 170 // its count of calls to Prepare 171 func numPrepares(t *testing.T, db *DB) int { 172 if n := len(db.freeConn); n != 1 { 173 t.Fatalf("free conns = %d; want 1", n) 174 } 175 return db.freeConn[0].ci.(*fakeConn).numPrepare 176 } 177 178 func (db *DB) numDeps() int { 179 db.mu.Lock() 180 defer db.mu.Unlock() 181 return len(db.dep) 182 } 183 184 // Dependencies are closed via a goroutine, so this polls waiting for 185 // numDeps to fall to want, waiting up to d. 186 func (db *DB) numDepsPollUntil(want int, d time.Duration) int { 187 deadline := time.Now().Add(d) 188 for { 189 n := db.numDeps() 190 if n <= want || time.Now().After(deadline) { 191 return n 192 } 193 time.Sleep(50 * time.Millisecond) 194 } 195 } 196 197 func (db *DB) numFreeConns() int { 198 db.mu.Lock() 199 defer db.mu.Unlock() 200 return len(db.freeConn) 201 } 202 203 func (db *DB) numOpenConns() int { 204 db.mu.Lock() 205 defer db.mu.Unlock() 206 return db.numOpen 207 } 208 209 // clearAllConns closes all connections in db. 210 func (db *DB) clearAllConns(t *testing.T) { 211 db.SetMaxIdleConns(0) 212 213 if g, w := db.numFreeConns(), 0; g != w { 214 t.Errorf("free conns = %d; want %d", g, w) 215 } 216 217 if n := db.numDepsPollUntil(0, time.Second); n > 0 { 218 t.Errorf("number of dependencies = %d; expected 0", n) 219 db.dumpDeps(t) 220 } 221 } 222 223 func (db *DB) dumpDeps(t *testing.T) { 224 for fc := range db.dep { 225 db.dumpDep(t, 0, fc, map[finalCloser]bool{}) 226 } 227 } 228 229 func (db *DB) dumpDep(t *testing.T, depth int, dep finalCloser, seen map[finalCloser]bool) { 230 seen[dep] = true 231 indent := strings.Repeat(" ", depth) 232 ds := db.dep[dep] 233 for k := range ds { 234 t.Logf("%s%T (%p) waiting for -> %T (%p)", indent, dep, dep, k, k) 235 if fc, ok := k.(finalCloser); ok { 236 if !seen[fc] { 237 db.dumpDep(t, depth+1, fc, seen) 238 } 239 } 240 } 241 } 242 243 func TestQuery(t *testing.T) { 244 db := newTestDB(t, "people") 245 defer closeDB(t, db) 246 prepares0 := numPrepares(t, db) 247 rows, err := db.Query("SELECT|people|age,name|") 248 if err != nil { 249 t.Fatalf("Query: %v", err) 250 } 251 type row struct { 252 age int 253 name string 254 } 255 got := []row{} 256 for rows.Next() { 257 var r row 258 err = rows.Scan(&r.age, &r.name) 259 if err != nil { 260 t.Fatalf("Scan: %v", err) 261 } 262 got = append(got, r) 263 } 264 err = rows.Err() 265 if err != nil { 266 t.Fatalf("Err: %v", err) 267 } 268 want := []row{ 269 {age: 1, name: "Alice"}, 270 {age: 2, name: "Bob"}, 271 {age: 3, name: "Chris"}, 272 } 273 if !reflect.DeepEqual(got, want) { 274 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want) 275 } 276 277 // And verify that the final rows.Next() call, which hit EOF, 278 // also closed the rows connection. 279 if n := db.numFreeConns(); n != 1 { 280 t.Fatalf("free conns after query hitting EOF = %d; want 1", n) 281 } 282 if prepares := numPrepares(t, db) - prepares0; prepares != 1 { 283 t.Errorf("executed %d Prepare statements; want 1", prepares) 284 } 285 } 286 287 // TestQueryContext tests canceling the context while scanning the rows. 288 func TestQueryContext(t *testing.T) { 289 db := newTestDB(t, "people") 290 defer closeDB(t, db) 291 prepares0 := numPrepares(t, db) 292 293 ctx, cancel := context.WithCancel(context.Background()) 294 defer cancel() 295 296 rows, err := db.QueryContext(ctx, "SELECT|people|age,name|") 297 if err != nil { 298 t.Fatalf("Query: %v", err) 299 } 300 type row struct { 301 age int 302 name string 303 } 304 got := []row{} 305 index := 0 306 for rows.Next() { 307 if index == 2 { 308 cancel() 309 waitForRowsClose(t, rows, 5*time.Second) 310 } 311 var r row 312 err = rows.Scan(&r.age, &r.name) 313 if err != nil { 314 if index == 2 { 315 break 316 } 317 t.Fatalf("Scan: %v", err) 318 } 319 if index == 2 && err == nil { 320 t.Fatal("expected an error on last scan") 321 } 322 got = append(got, r) 323 index++ 324 } 325 select { 326 case <-ctx.Done(): 327 if err := ctx.Err(); err != context.Canceled { 328 t.Fatalf("context err = %v; want context.Canceled", err) 329 } 330 default: 331 t.Fatalf("context err = nil; want context.Canceled") 332 } 333 want := []row{ 334 {age: 1, name: "Alice"}, 335 {age: 2, name: "Bob"}, 336 } 337 if !reflect.DeepEqual(got, want) { 338 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want) 339 } 340 341 // And verify that the final rows.Next() call, which hit EOF, 342 // also closed the rows connection. 343 waitForRowsClose(t, rows, 5*time.Second) 344 waitForFree(t, db, 5*time.Second, 1) 345 if prepares := numPrepares(t, db) - prepares0; prepares != 1 { 346 t.Errorf("executed %d Prepare statements; want 1", prepares) 347 } 348 } 349 350 func waitCondition(waitFor, checkEvery time.Duration, fn func() bool) bool { 351 deadline := time.Now().Add(waitFor) 352 for time.Now().Before(deadline) { 353 if fn() { 354 return true 355 } 356 time.Sleep(checkEvery) 357 } 358 return false 359 } 360 361 // waitForFree checks db.numFreeConns until either it equals want or 362 // the maxWait time elapses. 363 func waitForFree(t *testing.T, db *DB, maxWait time.Duration, want int) { 364 var numFree int 365 if !waitCondition(maxWait, 5*time.Millisecond, func() bool { 366 numFree = db.numFreeConns() 367 return numFree == want 368 }) { 369 t.Fatalf("free conns after hitting EOF = %d; want %d", numFree, want) 370 } 371 } 372 373 func waitForRowsClose(t *testing.T, rows *Rows, maxWait time.Duration) { 374 if !waitCondition(maxWait, 5*time.Millisecond, func() bool { 375 rows.closemu.RLock() 376 defer rows.closemu.RUnlock() 377 return rows.closed 378 }) { 379 t.Fatal("failed to close rows") 380 } 381 } 382 383 // TestQueryContextWait ensures that rows and all internal statements are closed when 384 // a query context is closed during execution. 385 func TestQueryContextWait(t *testing.T) { 386 db := newTestDB(t, "people") 387 defer closeDB(t, db) 388 prepares0 := numPrepares(t, db) 389 390 // TODO(kardianos): convert this from using a timeout to using an explicit 391 // cancel when the query signals that is is "executing" the query. 392 ctx, cancel := context.WithTimeout(context.Background(), 300*time.Millisecond) 393 defer cancel() 394 395 // This will trigger the *fakeConn.Prepare method which will take time 396 // performing the query. The ctxDriverPrepare func will check the context 397 // after this and close the rows and return an error. 398 _, err := db.QueryContext(ctx, "WAIT|1s|SELECT|people|age,name|") 399 if err != context.DeadlineExceeded { 400 t.Fatalf("expected QueryContext to error with context deadline exceeded but returned %v", err) 401 } 402 403 // Verify closed rows connection after error condition. 404 waitForFree(t, db, 5*time.Second, 1) 405 if prepares := numPrepares(t, db) - prepares0; prepares != 1 { 406 // TODO(kardianos): if the context timeouts before the db.QueryContext 407 // executes this check may fail. After adjusting how the context 408 // is canceled above revert this back to a Fatal error. 409 t.Logf("executed %d Prepare statements; want 1", prepares) 410 } 411 } 412 413 // TestTxContextWait tests the transaction behavior when the tx context is canceled 414 // during execution of the query. 415 func TestTxContextWait(t *testing.T) { 416 db := newTestDB(t, "people") 417 defer closeDB(t, db) 418 419 ctx, cancel := context.WithTimeout(context.Background(), 15*time.Millisecond) 420 defer cancel() 421 422 tx, err := db.BeginTx(ctx, nil) 423 if err != nil { 424 // Guard against the context being canceled before BeginTx completes. 425 if err == context.DeadlineExceeded { 426 t.Skip("tx context canceled prior to first use") 427 } 428 t.Fatal(err) 429 } 430 431 // This will trigger the *fakeConn.Prepare method which will take time 432 // performing the query. The ctxDriverPrepare func will check the context 433 // after this and close the rows and return an error. 434 _, err = tx.QueryContext(ctx, "WAIT|1s|SELECT|people|age,name|") 435 if err != context.DeadlineExceeded { 436 t.Fatalf("expected QueryContext to error with context deadline exceeded but returned %v", err) 437 } 438 439 waitForFree(t, db, 5*time.Second, 0) 440 } 441 442 // TestUnsupportedOptions checks that the database fails when a driver that 443 // doesn't implement ConnBeginTx is used with non-default options and an 444 // un-cancellable context. 445 func TestUnsupportedOptions(t *testing.T) { 446 db := newTestDB(t, "people") 447 defer closeDB(t, db) 448 _, err := db.BeginTx(context.Background(), &TxOptions{ 449 Isolation: LevelSerializable, ReadOnly: true, 450 }) 451 if err == nil { 452 t.Fatal("expected error when using unsupported options, got nil") 453 } 454 } 455 456 func TestMultiResultSetQuery(t *testing.T) { 457 db := newTestDB(t, "people") 458 defer closeDB(t, db) 459 prepares0 := numPrepares(t, db) 460 rows, err := db.Query("SELECT|people|age,name|;SELECT|people|name|") 461 if err != nil { 462 t.Fatalf("Query: %v", err) 463 } 464 type row1 struct { 465 age int 466 name string 467 } 468 type row2 struct { 469 name string 470 } 471 got1 := []row1{} 472 for rows.Next() { 473 var r row1 474 err = rows.Scan(&r.age, &r.name) 475 if err != nil { 476 t.Fatalf("Scan: %v", err) 477 } 478 got1 = append(got1, r) 479 } 480 err = rows.Err() 481 if err != nil { 482 t.Fatalf("Err: %v", err) 483 } 484 want1 := []row1{ 485 {age: 1, name: "Alice"}, 486 {age: 2, name: "Bob"}, 487 {age: 3, name: "Chris"}, 488 } 489 if !reflect.DeepEqual(got1, want1) { 490 t.Errorf("mismatch.\n got1: %#v\nwant: %#v", got1, want1) 491 } 492 493 if !rows.NextResultSet() { 494 t.Errorf("expected another result set") 495 } 496 497 got2 := []row2{} 498 for rows.Next() { 499 var r row2 500 err = rows.Scan(&r.name) 501 if err != nil { 502 t.Fatalf("Scan: %v", err) 503 } 504 got2 = append(got2, r) 505 } 506 err = rows.Err() 507 if err != nil { 508 t.Fatalf("Err: %v", err) 509 } 510 want2 := []row2{ 511 {name: "Alice"}, 512 {name: "Bob"}, 513 {name: "Chris"}, 514 } 515 if !reflect.DeepEqual(got2, want2) { 516 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got2, want2) 517 } 518 if rows.NextResultSet() { 519 t.Errorf("expected no more result sets") 520 } 521 522 // And verify that the final rows.Next() call, which hit EOF, 523 // also closed the rows connection. 524 waitForFree(t, db, 5*time.Second, 1) 525 if prepares := numPrepares(t, db) - prepares0; prepares != 1 { 526 t.Errorf("executed %d Prepare statements; want 1", prepares) 527 } 528 } 529 530 func TestQueryNamedArg(t *testing.T) { 531 db := newTestDB(t, "people") 532 defer closeDB(t, db) 533 prepares0 := numPrepares(t, db) 534 rows, err := db.Query( 535 // Ensure the name and age parameters only match on placeholder name, not position. 536 "SELECT|people|age,name|name=?name,age=?age", 537 Named("age", 2), 538 Named("name", "Bob"), 539 ) 540 if err != nil { 541 t.Fatalf("Query: %v", err) 542 } 543 type row struct { 544 age int 545 name string 546 } 547 got := []row{} 548 for rows.Next() { 549 var r row 550 err = rows.Scan(&r.age, &r.name) 551 if err != nil { 552 t.Fatalf("Scan: %v", err) 553 } 554 got = append(got, r) 555 } 556 err = rows.Err() 557 if err != nil { 558 t.Fatalf("Err: %v", err) 559 } 560 want := []row{ 561 {age: 2, name: "Bob"}, 562 } 563 if !reflect.DeepEqual(got, want) { 564 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want) 565 } 566 567 // And verify that the final rows.Next() call, which hit EOF, 568 // also closed the rows connection. 569 if n := db.numFreeConns(); n != 1 { 570 t.Fatalf("free conns after query hitting EOF = %d; want 1", n) 571 } 572 if prepares := numPrepares(t, db) - prepares0; prepares != 1 { 573 t.Errorf("executed %d Prepare statements; want 1", prepares) 574 } 575 } 576 577 func TestPoolExhaustOnCancel(t *testing.T) { 578 if testing.Short() { 579 t.Skip("long test") 580 } 581 db := newTestDB(t, "people") 582 defer closeDB(t, db) 583 584 max := 3 585 586 db.SetMaxOpenConns(max) 587 588 // First saturate the connection pool. 589 // Then start new requests for a connection that is cancelled after it is requested. 590 591 var saturate, saturateDone sync.WaitGroup 592 saturate.Add(max) 593 saturateDone.Add(max) 594 595 for i := 0; i < max; i++ { 596 go func() { 597 saturate.Done() 598 rows, err := db.Query("WAIT|500ms|SELECT|people|name,photo|") 599 if err != nil { 600 t.Fatalf("Query: %v", err) 601 } 602 rows.Close() 603 saturateDone.Done() 604 }() 605 } 606 607 saturate.Wait() 608 609 // Now cancel the request while it is waiting. 610 ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) 611 defer cancel() 612 613 for i := 0; i < max; i++ { 614 ctxReq, cancelReq := context.WithCancel(ctx) 615 go func() { 616 time.Sleep(100 * time.Millisecond) 617 cancelReq() 618 }() 619 err := db.PingContext(ctxReq) 620 if err != context.Canceled { 621 t.Fatalf("PingContext (Exhaust): %v", err) 622 } 623 } 624 625 saturateDone.Wait() 626 627 // Now try to open a normal connection. 628 err := db.PingContext(ctx) 629 if err != nil { 630 t.Fatalf("PingContext (Normal): %v", err) 631 } 632 } 633 634 func TestByteOwnership(t *testing.T) { 635 db := newTestDB(t, "people") 636 defer closeDB(t, db) 637 rows, err := db.Query("SELECT|people|name,photo|") 638 if err != nil { 639 t.Fatalf("Query: %v", err) 640 } 641 type row struct { 642 name []byte 643 photo RawBytes 644 } 645 got := []row{} 646 for rows.Next() { 647 var r row 648 err = rows.Scan(&r.name, &r.photo) 649 if err != nil { 650 t.Fatalf("Scan: %v", err) 651 } 652 got = append(got, r) 653 } 654 corruptMemory := []byte("\xffPHOTO") 655 want := []row{ 656 {name: []byte("Alice"), photo: corruptMemory}, 657 {name: []byte("Bob"), photo: corruptMemory}, 658 {name: []byte("Chris"), photo: corruptMemory}, 659 } 660 if !reflect.DeepEqual(got, want) { 661 t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want) 662 } 663 664 var photo RawBytes 665 err = db.QueryRow("SELECT|people|photo|name=?", "Alice").Scan(&photo) 666 if err == nil { 667 t.Error("want error scanning into RawBytes from QueryRow") 668 } 669 } 670 671 func TestRowsColumns(t *testing.T) { 672 db := newTestDB(t, "people") 673 defer closeDB(t, db) 674 rows, err := db.Query("SELECT|people|age,name|") 675 if err != nil { 676 t.Fatalf("Query: %v", err) 677 } 678 cols, err := rows.Columns() 679 if err != nil { 680 t.Fatalf("Columns: %v", err) 681 } 682 want := []string{"age", "name"} 683 if !reflect.DeepEqual(cols, want) { 684 t.Errorf("got %#v; want %#v", cols, want) 685 } 686 if err := rows.Close(); err != nil { 687 t.Errorf("error closing rows: %s", err) 688 } 689 } 690 691 func TestRowsColumnTypes(t *testing.T) { 692 db := newTestDB(t, "people") 693 defer closeDB(t, db) 694 rows, err := db.Query("SELECT|people|age,name|") 695 if err != nil { 696 t.Fatalf("Query: %v", err) 697 } 698 tt, err := rows.ColumnTypes() 699 if err != nil { 700 t.Fatalf("ColumnTypes: %v", err) 701 } 702 703 types := make([]reflect.Type, len(tt)) 704 for i, tp := range tt { 705 st := tp.ScanType() 706 if st == nil { 707 t.Errorf("scantype is null for column %q", tp.Name()) 708 continue 709 } 710 types[i] = st 711 } 712 values := make([]interface{}, len(tt)) 713 for i := range values { 714 values[i] = reflect.New(types[i]).Interface() 715 } 716 ct := 0 717 for rows.Next() { 718 err = rows.Scan(values...) 719 if err != nil { 720 t.Fatalf("failed to scan values in %v", err) 721 } 722 ct++ 723 if ct == 0 { 724 if values[0].(string) != "Bob" { 725 t.Errorf("Expected Bob, got %v", values[0]) 726 } 727 if values[1].(int) != 2 { 728 t.Errorf("Expected 2, got %v", values[1]) 729 } 730 } 731 } 732 if ct != 3 { 733 t.Errorf("expected 3 rows, got %d", ct) 734 } 735 736 if err := rows.Close(); err != nil { 737 t.Errorf("error closing rows: %s", err) 738 } 739 } 740 741 func TestQueryRow(t *testing.T) { 742 db := newTestDB(t, "people") 743 defer closeDB(t, db) 744 var name string 745 var age int 746 var birthday time.Time 747 748 err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age) 749 if err == nil || !strings.Contains(err.Error(), "expected 2 destination arguments") { 750 t.Errorf("expected error from wrong number of arguments; actually got: %v", err) 751 } 752 753 err = db.QueryRow("SELECT|people|bdate|age=?", 3).Scan(&birthday) 754 if err != nil || !birthday.Equal(chrisBirthday) { 755 t.Errorf("chris birthday = %v, err = %v; want %v", birthday, err, chrisBirthday) 756 } 757 758 err = db.QueryRow("SELECT|people|age,name|age=?", 2).Scan(&age, &name) 759 if err != nil { 760 t.Fatalf("age QueryRow+Scan: %v", err) 761 } 762 if name != "Bob" { 763 t.Errorf("expected name Bob, got %q", name) 764 } 765 if age != 2 { 766 t.Errorf("expected age 2, got %d", age) 767 } 768 769 err = db.QueryRow("SELECT|people|age,name|name=?", "Alice").Scan(&age, &name) 770 if err != nil { 771 t.Fatalf("name QueryRow+Scan: %v", err) 772 } 773 if name != "Alice" { 774 t.Errorf("expected name Alice, got %q", name) 775 } 776 if age != 1 { 777 t.Errorf("expected age 1, got %d", age) 778 } 779 780 var photo []byte 781 err = db.QueryRow("SELECT|people|photo|name=?", "Alice").Scan(&photo) 782 if err != nil { 783 t.Fatalf("photo QueryRow+Scan: %v", err) 784 } 785 want := []byte("APHOTO") 786 if !reflect.DeepEqual(photo, want) { 787 t.Errorf("photo = %q; want %q", photo, want) 788 } 789 } 790 791 func TestTxRollbackCommitErr(t *testing.T) { 792 db := newTestDB(t, "people") 793 defer closeDB(t, db) 794 795 tx, err := db.Begin() 796 if err != nil { 797 t.Fatal(err) 798 } 799 err = tx.Rollback() 800 if err != nil { 801 t.Errorf("expected nil error from Rollback; got %v", err) 802 } 803 err = tx.Commit() 804 if err != ErrTxDone { 805 t.Errorf("expected %q from Commit; got %q", ErrTxDone, err) 806 } 807 808 tx, err = db.Begin() 809 if err != nil { 810 t.Fatal(err) 811 } 812 err = tx.Commit() 813 if err != nil { 814 t.Errorf("expected nil error from Commit; got %v", err) 815 } 816 err = tx.Rollback() 817 if err != ErrTxDone { 818 t.Errorf("expected %q from Rollback; got %q", ErrTxDone, err) 819 } 820 } 821 822 func TestStatementErrorAfterClose(t *testing.T) { 823 db := newTestDB(t, "people") 824 defer closeDB(t, db) 825 stmt, err := db.Prepare("SELECT|people|age|name=?") 826 if err != nil { 827 t.Fatalf("Prepare: %v", err) 828 } 829 err = stmt.Close() 830 if err != nil { 831 t.Fatalf("Close: %v", err) 832 } 833 var name string 834 err = stmt.QueryRow("foo").Scan(&name) 835 if err == nil { 836 t.Errorf("expected error from QueryRow.Scan after Stmt.Close") 837 } 838 } 839 840 func TestStatementQueryRow(t *testing.T) { 841 db := newTestDB(t, "people") 842 defer closeDB(t, db) 843 stmt, err := db.Prepare("SELECT|people|age|name=?") 844 if err != nil { 845 t.Fatalf("Prepare: %v", err) 846 } 847 defer stmt.Close() 848 var age int 849 for n, tt := range []struct { 850 name string 851 want int 852 }{ 853 {"Alice", 1}, 854 {"Bob", 2}, 855 {"Chris", 3}, 856 } { 857 if err := stmt.QueryRow(tt.name).Scan(&age); err != nil { 858 t.Errorf("%d: on %q, QueryRow/Scan: %v", n, tt.name, err) 859 } else if age != tt.want { 860 t.Errorf("%d: age=%d, want %d", n, age, tt.want) 861 } 862 } 863 } 864 865 type stubDriverStmt struct { 866 err error 867 } 868 869 func (s stubDriverStmt) Close() error { 870 return s.err 871 } 872 873 func (s stubDriverStmt) NumInput() int { 874 return -1 875 } 876 877 func (s stubDriverStmt) Exec(args []driver.Value) (driver.Result, error) { 878 return nil, nil 879 } 880 881 func (s stubDriverStmt) Query(args []driver.Value) (driver.Rows, error) { 882 return nil, nil 883 } 884 885 // golang.org/issue/12798 886 func TestStatementClose(t *testing.T) { 887 want := errors.New("STMT ERROR") 888 889 tests := []struct { 890 stmt *Stmt 891 msg string 892 }{ 893 {&Stmt{stickyErr: want}, "stickyErr not propagated"}, 894 {&Stmt{cg: &Tx{}, cgds: &driverStmt{Locker: &sync.Mutex{}, si: stubDriverStmt{want}}}, "driverStmt.Close() error not propagated"}, 895 } 896 for _, test := range tests { 897 if err := test.stmt.Close(); err != want { 898 t.Errorf("%s. Got stmt.Close() = %v, want = %v", test.msg, err, want) 899 } 900 } 901 } 902 903 // golang.org/issue/3734 904 func TestStatementQueryRowConcurrent(t *testing.T) { 905 db := newTestDB(t, "people") 906 defer closeDB(t, db) 907 stmt, err := db.Prepare("SELECT|people|age|name=?") 908 if err != nil { 909 t.Fatalf("Prepare: %v", err) 910 } 911 defer stmt.Close() 912 913 const n = 10 914 ch := make(chan error, n) 915 for i := 0; i < n; i++ { 916 go func() { 917 var age int 918 err := stmt.QueryRow("Alice").Scan(&age) 919 if err == nil && age != 1 { 920 err = fmt.Errorf("unexpected age %d", age) 921 } 922 ch <- err 923 }() 924 } 925 for i := 0; i < n; i++ { 926 if err := <-ch; err != nil { 927 t.Error(err) 928 } 929 } 930 } 931 932 // just a test of fakedb itself 933 func TestBogusPreboundParameters(t *testing.T) { 934 db := newTestDB(t, "foo") 935 defer closeDB(t, db) 936 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool") 937 _, err := db.Prepare("INSERT|t1|name=?,age=bogusconversion") 938 if err == nil { 939 t.Fatalf("expected error") 940 } 941 if err.Error() != `fakedb: invalid conversion to int32 from "bogusconversion"` { 942 t.Errorf("unexpected error: %v", err) 943 } 944 } 945 946 func TestExec(t *testing.T) { 947 db := newTestDB(t, "foo") 948 defer closeDB(t, db) 949 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool") 950 stmt, err := db.Prepare("INSERT|t1|name=?,age=?") 951 if err != nil { 952 t.Errorf("Stmt, err = %v, %v", stmt, err) 953 } 954 defer stmt.Close() 955 956 type execTest struct { 957 args []interface{} 958 wantErr string 959 } 960 execTests := []execTest{ 961 // Okay: 962 {[]interface{}{"Brad", 31}, ""}, 963 {[]interface{}{"Brad", int64(31)}, ""}, 964 {[]interface{}{"Bob", "32"}, ""}, 965 {[]interface{}{7, 9}, ""}, 966 967 // Invalid conversions: 968 {[]interface{}{"Brad", int64(0xFFFFFFFF)}, "sql: converting argument $2 type: sql/driver: value 4294967295 overflows int32"}, 969 {[]interface{}{"Brad", "strconv fail"}, `sql: converting argument $2 type: sql/driver: value "strconv fail" can't be converted to int32`}, 970 971 // Wrong number of args: 972 {[]interface{}{}, "sql: expected 2 arguments, got 0"}, 973 {[]interface{}{1, 2, 3}, "sql: expected 2 arguments, got 3"}, 974 } 975 for n, et := range execTests { 976 _, err := stmt.Exec(et.args...) 977 errStr := "" 978 if err != nil { 979 errStr = err.Error() 980 } 981 if errStr != et.wantErr { 982 t.Errorf("stmt.Execute #%d: for %v, got error %q, want error %q", 983 n, et.args, errStr, et.wantErr) 984 } 985 } 986 } 987 988 func TestTxPrepare(t *testing.T) { 989 db := newTestDB(t, "") 990 defer closeDB(t, db) 991 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool") 992 tx, err := db.Begin() 993 if err != nil { 994 t.Fatalf("Begin = %v", err) 995 } 996 stmt, err := tx.Prepare("INSERT|t1|name=?,age=?") 997 if err != nil { 998 t.Fatalf("Stmt, err = %v, %v", stmt, err) 999 } 1000 defer stmt.Close() 1001 _, err = stmt.Exec("Bobby", 7) 1002 if err != nil { 1003 t.Fatalf("Exec = %v", err) 1004 } 1005 err = tx.Commit() 1006 if err != nil { 1007 t.Fatalf("Commit = %v", err) 1008 } 1009 // Commit() should have closed the statement 1010 if !stmt.closed { 1011 t.Fatal("Stmt not closed after Commit") 1012 } 1013 } 1014 1015 func TestTxStmt(t *testing.T) { 1016 db := newTestDB(t, "") 1017 defer closeDB(t, db) 1018 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool") 1019 stmt, err := db.Prepare("INSERT|t1|name=?,age=?") 1020 if err != nil { 1021 t.Fatalf("Stmt, err = %v, %v", stmt, err) 1022 } 1023 defer stmt.Close() 1024 tx, err := db.Begin() 1025 if err != nil { 1026 t.Fatalf("Begin = %v", err) 1027 } 1028 txs := tx.Stmt(stmt) 1029 defer txs.Close() 1030 _, err = txs.Exec("Bobby", 7) 1031 if err != nil { 1032 t.Fatalf("Exec = %v", err) 1033 } 1034 err = tx.Commit() 1035 if err != nil { 1036 t.Fatalf("Commit = %v", err) 1037 } 1038 // Commit() should have closed the statement 1039 if !txs.closed { 1040 t.Fatal("Stmt not closed after Commit") 1041 } 1042 } 1043 1044 func TestTxStmtPreparedOnce(t *testing.T) { 1045 db := newTestDB(t, "") 1046 defer closeDB(t, db) 1047 exec(t, db, "CREATE|t1|name=string,age=int32") 1048 1049 prepares0 := numPrepares(t, db) 1050 1051 // db.Prepare increments numPrepares. 1052 stmt, err := db.Prepare("INSERT|t1|name=?,age=?") 1053 if err != nil { 1054 t.Fatalf("Stmt, err = %v, %v", stmt, err) 1055 } 1056 defer stmt.Close() 1057 1058 tx, err := db.Begin() 1059 if err != nil { 1060 t.Fatalf("Begin = %v", err) 1061 } 1062 1063 txs1 := tx.Stmt(stmt) 1064 txs2 := tx.Stmt(stmt) 1065 1066 _, err = txs1.Exec("Go", 7) 1067 if err != nil { 1068 t.Fatalf("Exec = %v", err) 1069 } 1070 txs1.Close() 1071 1072 _, err = txs2.Exec("Gopher", 8) 1073 if err != nil { 1074 t.Fatalf("Exec = %v", err) 1075 } 1076 txs2.Close() 1077 1078 err = tx.Commit() 1079 if err != nil { 1080 t.Fatalf("Commit = %v", err) 1081 } 1082 1083 if prepares := numPrepares(t, db) - prepares0; prepares != 1 { 1084 t.Errorf("executed %d Prepare statements; want 1", prepares) 1085 } 1086 } 1087 1088 func TestTxStmtClosedRePrepares(t *testing.T) { 1089 db := newTestDB(t, "") 1090 defer closeDB(t, db) 1091 exec(t, db, "CREATE|t1|name=string,age=int32") 1092 1093 prepares0 := numPrepares(t, db) 1094 1095 // db.Prepare increments numPrepares. 1096 stmt, err := db.Prepare("INSERT|t1|name=?,age=?") 1097 if err != nil { 1098 t.Fatalf("Stmt, err = %v, %v", stmt, err) 1099 } 1100 tx, err := db.Begin() 1101 if err != nil { 1102 t.Fatalf("Begin = %v", err) 1103 } 1104 err = stmt.Close() 1105 if err != nil { 1106 t.Fatalf("stmt.Close() = %v", err) 1107 } 1108 // tx.Stmt increments numPrepares because stmt is closed. 1109 txs := tx.Stmt(stmt) 1110 if txs.stickyErr != nil { 1111 t.Fatal(txs.stickyErr) 1112 } 1113 if txs.parentStmt != nil { 1114 t.Fatal("expected nil parentStmt") 1115 } 1116 _, err = txs.Exec(`Eric`, 82) 1117 if err != nil { 1118 t.Fatalf("txs.Exec = %v", err) 1119 } 1120 1121 err = txs.Close() 1122 if err != nil { 1123 t.Fatalf("txs.Close = %v", err) 1124 } 1125 1126 tx.Rollback() 1127 1128 if prepares := numPrepares(t, db) - prepares0; prepares != 2 { 1129 t.Errorf("executed %d Prepare statements; want 2", prepares) 1130 } 1131 } 1132 1133 func TestParentStmtOutlivesTxStmt(t *testing.T) { 1134 db := newTestDB(t, "") 1135 defer closeDB(t, db) 1136 exec(t, db, "CREATE|t1|name=string,age=int32") 1137 1138 // Make sure everything happens on the same connection. 1139 db.SetMaxOpenConns(1) 1140 1141 prepares0 := numPrepares(t, db) 1142 1143 // db.Prepare increments numPrepares. 1144 stmt, err := db.Prepare("INSERT|t1|name=?,age=?") 1145 if err != nil { 1146 t.Fatalf("Stmt, err = %v, %v", stmt, err) 1147 } 1148 defer stmt.Close() 1149 tx, err := db.Begin() 1150 if err != nil { 1151 t.Fatalf("Begin = %v", err) 1152 } 1153 txs := tx.Stmt(stmt) 1154 if len(stmt.css) != 1 { 1155 t.Fatalf("len(stmt.css) = %v; want 1", len(stmt.css)) 1156 } 1157 err = txs.Close() 1158 if err != nil { 1159 t.Fatalf("txs.Close() = %v", err) 1160 } 1161 err = tx.Rollback() 1162 if err != nil { 1163 t.Fatalf("tx.Rollback() = %v", err) 1164 } 1165 // txs must not be valid. 1166 _, err = txs.Exec("Suzan", 30) 1167 if err == nil { 1168 t.Fatalf("txs.Exec(), expected err") 1169 } 1170 // Stmt must still be valid. 1171 _, err = stmt.Exec("Janina", 25) 1172 if err != nil { 1173 t.Fatalf("stmt.Exec() = %v", err) 1174 } 1175 1176 if prepares := numPrepares(t, db) - prepares0; prepares != 1 { 1177 t.Errorf("executed %d Prepare statements; want 1", prepares) 1178 } 1179 } 1180 1181 // Test that tx.Stmt called with a statement already 1182 // associated with tx as argument re-prepares the same 1183 // statement again. 1184 func TestTxStmtFromTxStmtRePrepares(t *testing.T) { 1185 db := newTestDB(t, "") 1186 defer closeDB(t, db) 1187 exec(t, db, "CREATE|t1|name=string,age=int32") 1188 prepares0 := numPrepares(t, db) 1189 // db.Prepare increments numPrepares. 1190 stmt, err := db.Prepare("INSERT|t1|name=?,age=?") 1191 if err != nil { 1192 t.Fatalf("Stmt, err = %v, %v", stmt, err) 1193 } 1194 defer stmt.Close() 1195 1196 tx, err := db.Begin() 1197 if err != nil { 1198 t.Fatalf("Begin = %v", err) 1199 } 1200 txs1 := tx.Stmt(stmt) 1201 1202 // tx.Stmt(txs1) increments numPrepares because txs1 already 1203 // belongs to a transaction (albeit the same transaction). 1204 txs2 := tx.Stmt(txs1) 1205 if txs2.stickyErr != nil { 1206 t.Fatal(txs2.stickyErr) 1207 } 1208 if txs2.parentStmt != nil { 1209 t.Fatal("expected nil parentStmt") 1210 } 1211 _, err = txs2.Exec(`Eric`, 82) 1212 if err != nil { 1213 t.Fatal(err) 1214 } 1215 1216 err = txs1.Close() 1217 if err != nil { 1218 t.Fatalf("txs1.Close = %v", err) 1219 } 1220 err = txs2.Close() 1221 if err != nil { 1222 t.Fatalf("txs1.Close = %v", err) 1223 } 1224 err = tx.Rollback() 1225 if err != nil { 1226 t.Fatalf("tx.Rollback = %v", err) 1227 } 1228 1229 if prepares := numPrepares(t, db) - prepares0; prepares != 2 { 1230 t.Errorf("executed %d Prepare statements; want 2", prepares) 1231 } 1232 } 1233 1234 // Issue: https://golang.org/issue/2784 1235 // This test didn't fail before because we got lucky with the fakedb driver. 1236 // It was failing, and now not, in github.com/bradfitz/go-sql-test 1237 func TestTxQuery(t *testing.T) { 1238 db := newTestDB(t, "") 1239 defer closeDB(t, db) 1240 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool") 1241 exec(t, db, "INSERT|t1|name=Alice") 1242 1243 tx, err := db.Begin() 1244 if err != nil { 1245 t.Fatal(err) 1246 } 1247 defer tx.Rollback() 1248 1249 r, err := tx.Query("SELECT|t1|name|") 1250 if err != nil { 1251 t.Fatal(err) 1252 } 1253 defer r.Close() 1254 1255 if !r.Next() { 1256 if r.Err() != nil { 1257 t.Fatal(r.Err()) 1258 } 1259 t.Fatal("expected one row") 1260 } 1261 1262 var x string 1263 err = r.Scan(&x) 1264 if err != nil { 1265 t.Fatal(err) 1266 } 1267 } 1268 1269 func TestTxQueryInvalid(t *testing.T) { 1270 db := newTestDB(t, "") 1271 defer closeDB(t, db) 1272 1273 tx, err := db.Begin() 1274 if err != nil { 1275 t.Fatal(err) 1276 } 1277 defer tx.Rollback() 1278 1279 _, err = tx.Query("SELECT|t1|name|") 1280 if err == nil { 1281 t.Fatal("Error expected") 1282 } 1283 } 1284 1285 // Tests fix for issue 4433, that retries in Begin happen when 1286 // conn.Begin() returns ErrBadConn 1287 func TestTxErrBadConn(t *testing.T) { 1288 db, err := Open("test", fakeDBName+";badConn") 1289 if err != nil { 1290 t.Fatalf("Open: %v", err) 1291 } 1292 if _, err := db.Exec("WIPE"); err != nil { 1293 t.Fatalf("exec wipe: %v", err) 1294 } 1295 defer closeDB(t, db) 1296 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool") 1297 stmt, err := db.Prepare("INSERT|t1|name=?,age=?") 1298 if err != nil { 1299 t.Fatalf("Stmt, err = %v, %v", stmt, err) 1300 } 1301 defer stmt.Close() 1302 tx, err := db.Begin() 1303 if err != nil { 1304 t.Fatalf("Begin = %v", err) 1305 } 1306 txs := tx.Stmt(stmt) 1307 defer txs.Close() 1308 _, err = txs.Exec("Bobby", 7) 1309 if err != nil { 1310 t.Fatalf("Exec = %v", err) 1311 } 1312 err = tx.Commit() 1313 if err != nil { 1314 t.Fatalf("Commit = %v", err) 1315 } 1316 } 1317 1318 func TestConnQuery(t *testing.T) { 1319 db := newTestDB(t, "people") 1320 defer closeDB(t, db) 1321 1322 ctx, cancel := context.WithCancel(context.Background()) 1323 defer cancel() 1324 conn, err := db.Conn(ctx) 1325 if err != nil { 1326 t.Fatal(err) 1327 } 1328 defer conn.Close() 1329 1330 var name string 1331 err = conn.QueryRowContext(ctx, "SELECT|people|name|age=?", 3).Scan(&name) 1332 if err != nil { 1333 t.Fatal(err) 1334 } 1335 if name != "Chris" { 1336 t.Fatalf("unexpected result, got %q want Chris", name) 1337 } 1338 1339 err = conn.PingContext(ctx) 1340 if err != nil { 1341 t.Fatal(err) 1342 } 1343 } 1344 1345 func TestConnTx(t *testing.T) { 1346 db := newTestDB(t, "people") 1347 defer closeDB(t, db) 1348 1349 ctx, cancel := context.WithCancel(context.Background()) 1350 defer cancel() 1351 conn, err := db.Conn(ctx) 1352 if err != nil { 1353 t.Fatal(err) 1354 } 1355 defer conn.Close() 1356 1357 tx, err := conn.BeginTx(ctx, nil) 1358 if err != nil { 1359 t.Fatal(err) 1360 } 1361 insertName, insertAge := "Nancy", 33 1362 _, err = tx.ExecContext(ctx, "INSERT|people|name=?,age=?,photo=APHOTO", insertName, insertAge) 1363 if err != nil { 1364 t.Fatal(err) 1365 } 1366 err = tx.Commit() 1367 if err != nil { 1368 t.Fatal(err) 1369 } 1370 1371 var selectName string 1372 err = conn.QueryRowContext(ctx, "SELECT|people|name|age=?", insertAge).Scan(&selectName) 1373 if err != nil { 1374 t.Fatal(err) 1375 } 1376 if selectName != insertName { 1377 t.Fatalf("got %q want %q", selectName, insertName) 1378 } 1379 } 1380 1381 // Tests fix for issue 2542, that we release a lock when querying on 1382 // a closed connection. 1383 func TestIssue2542Deadlock(t *testing.T) { 1384 db := newTestDB(t, "people") 1385 closeDB(t, db) 1386 for i := 0; i < 2; i++ { 1387 _, err := db.Query("SELECT|people|age,name|") 1388 if err == nil { 1389 t.Fatalf("expected error") 1390 } 1391 } 1392 } 1393 1394 // From golang.org/issue/3865 1395 func TestCloseStmtBeforeRows(t *testing.T) { 1396 db := newTestDB(t, "people") 1397 defer closeDB(t, db) 1398 1399 s, err := db.Prepare("SELECT|people|name|") 1400 if err != nil { 1401 t.Fatal(err) 1402 } 1403 1404 r, err := s.Query() 1405 if err != nil { 1406 s.Close() 1407 t.Fatal(err) 1408 } 1409 1410 err = s.Close() 1411 if err != nil { 1412 t.Fatal(err) 1413 } 1414 1415 r.Close() 1416 } 1417 1418 // Tests fix for issue 2788, that we bind nil to a []byte if the 1419 // value in the column is sql null 1420 func TestNullByteSlice(t *testing.T) { 1421 db := newTestDB(t, "") 1422 defer closeDB(t, db) 1423 exec(t, db, "CREATE|t|id=int32,name=nullstring") 1424 exec(t, db, "INSERT|t|id=10,name=?", nil) 1425 1426 var name []byte 1427 1428 err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name) 1429 if err != nil { 1430 t.Fatal(err) 1431 } 1432 if name != nil { 1433 t.Fatalf("name []byte should be nil for null column value, got: %#v", name) 1434 } 1435 1436 exec(t, db, "INSERT|t|id=11,name=?", "bob") 1437 err = db.QueryRow("SELECT|t|name|id=?", 11).Scan(&name) 1438 if err != nil { 1439 t.Fatal(err) 1440 } 1441 if string(name) != "bob" { 1442 t.Fatalf("name []byte should be bob, got: %q", string(name)) 1443 } 1444 } 1445 1446 func TestPointerParamsAndScans(t *testing.T) { 1447 db := newTestDB(t, "") 1448 defer closeDB(t, db) 1449 exec(t, db, "CREATE|t|id=int32,name=nullstring") 1450 1451 bob := "bob" 1452 var name *string 1453 1454 name = &bob 1455 exec(t, db, "INSERT|t|id=10,name=?", name) 1456 name = nil 1457 exec(t, db, "INSERT|t|id=20,name=?", name) 1458 1459 err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name) 1460 if err != nil { 1461 t.Fatalf("querying id 10: %v", err) 1462 } 1463 if name == nil { 1464 t.Errorf("id 10's name = nil; want bob") 1465 } else if *name != "bob" { 1466 t.Errorf("id 10's name = %q; want bob", *name) 1467 } 1468 1469 err = db.QueryRow("SELECT|t|name|id=?", 20).Scan(&name) 1470 if err != nil { 1471 t.Fatalf("querying id 20: %v", err) 1472 } 1473 if name != nil { 1474 t.Errorf("id 20 = %q; want nil", *name) 1475 } 1476 } 1477 1478 func TestQueryRowClosingStmt(t *testing.T) { 1479 db := newTestDB(t, "people") 1480 defer closeDB(t, db) 1481 var name string 1482 var age int 1483 err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age, &name) 1484 if err != nil { 1485 t.Fatal(err) 1486 } 1487 if len(db.freeConn) != 1 { 1488 t.Fatalf("expected 1 free conn") 1489 } 1490 fakeConn := db.freeConn[0].ci.(*fakeConn) 1491 if made, closed := fakeConn.stmtsMade, fakeConn.stmtsClosed; made != closed { 1492 t.Errorf("statement close mismatch: made %d, closed %d", made, closed) 1493 } 1494 } 1495 1496 var atomicRowsCloseHook atomic.Value // of func(*Rows, *error) 1497 1498 func init() { 1499 rowsCloseHook = func() func(*Rows, *error) { 1500 fn, _ := atomicRowsCloseHook.Load().(func(*Rows, *error)) 1501 return fn 1502 } 1503 } 1504 1505 func setRowsCloseHook(fn func(*Rows, *error)) { 1506 if fn == nil { 1507 // Can't change an atomic.Value back to nil, so set it to this 1508 // no-op func instead. 1509 fn = func(*Rows, *error) {} 1510 } 1511 atomicRowsCloseHook.Store(fn) 1512 } 1513 1514 // Test issue 6651 1515 func TestIssue6651(t *testing.T) { 1516 db := newTestDB(t, "people") 1517 defer closeDB(t, db) 1518 1519 var v string 1520 1521 want := "error in rows.Next" 1522 rowsCursorNextHook = func(dest []driver.Value) error { 1523 return fmt.Errorf(want) 1524 } 1525 defer func() { rowsCursorNextHook = nil }() 1526 1527 err := db.QueryRow("SELECT|people|name|").Scan(&v) 1528 if err == nil || err.Error() != want { 1529 t.Errorf("error = %q; want %q", err, want) 1530 } 1531 rowsCursorNextHook = nil 1532 1533 want = "error in rows.Close" 1534 setRowsCloseHook(func(rows *Rows, err *error) { 1535 *err = fmt.Errorf(want) 1536 }) 1537 defer setRowsCloseHook(nil) 1538 err = db.QueryRow("SELECT|people|name|").Scan(&v) 1539 if err == nil || err.Error() != want { 1540 t.Errorf("error = %q; want %q", err, want) 1541 } 1542 } 1543 1544 type nullTestRow struct { 1545 nullParam interface{} 1546 notNullParam interface{} 1547 scanNullVal interface{} 1548 } 1549 1550 type nullTestSpec struct { 1551 nullType string 1552 notNullType string 1553 rows [6]nullTestRow 1554 } 1555 1556 func TestNullStringParam(t *testing.T) { 1557 spec := nullTestSpec{"nullstring", "string", [6]nullTestRow{ 1558 {NullString{"aqua", true}, "", NullString{"aqua", true}}, 1559 {NullString{"brown", false}, "", NullString{"", false}}, 1560 {"chartreuse", "", NullString{"chartreuse", true}}, 1561 {NullString{"darkred", true}, "", NullString{"darkred", true}}, 1562 {NullString{"eel", false}, "", NullString{"", false}}, 1563 {"foo", NullString{"black", false}, nil}, 1564 }} 1565 nullTestRun(t, spec) 1566 } 1567 1568 func TestNullInt64Param(t *testing.T) { 1569 spec := nullTestSpec{"nullint64", "int64", [6]nullTestRow{ 1570 {NullInt64{31, true}, 1, NullInt64{31, true}}, 1571 {NullInt64{-22, false}, 1, NullInt64{0, false}}, 1572 {22, 1, NullInt64{22, true}}, 1573 {NullInt64{33, true}, 1, NullInt64{33, true}}, 1574 {NullInt64{222, false}, 1, NullInt64{0, false}}, 1575 {0, NullInt64{31, false}, nil}, 1576 }} 1577 nullTestRun(t, spec) 1578 } 1579 1580 func TestNullFloat64Param(t *testing.T) { 1581 spec := nullTestSpec{"nullfloat64", "float64", [6]nullTestRow{ 1582 {NullFloat64{31.2, true}, 1, NullFloat64{31.2, true}}, 1583 {NullFloat64{13.1, false}, 1, NullFloat64{0, false}}, 1584 {-22.9, 1, NullFloat64{-22.9, true}}, 1585 {NullFloat64{33.81, true}, 1, NullFloat64{33.81, true}}, 1586 {NullFloat64{222, false}, 1, NullFloat64{0, false}}, 1587 {10, NullFloat64{31.2, false}, nil}, 1588 }} 1589 nullTestRun(t, spec) 1590 } 1591 1592 func TestNullBoolParam(t *testing.T) { 1593 spec := nullTestSpec{"nullbool", "bool", [6]nullTestRow{ 1594 {NullBool{false, true}, true, NullBool{false, true}}, 1595 {NullBool{true, false}, false, NullBool{false, false}}, 1596 {true, true, NullBool{true, true}}, 1597 {NullBool{true, true}, false, NullBool{true, true}}, 1598 {NullBool{true, false}, true, NullBool{false, false}}, 1599 {true, NullBool{true, false}, nil}, 1600 }} 1601 nullTestRun(t, spec) 1602 } 1603 1604 func nullTestRun(t *testing.T, spec nullTestSpec) { 1605 db := newTestDB(t, "") 1606 defer closeDB(t, db) 1607 exec(t, db, fmt.Sprintf("CREATE|t|id=int32,name=string,nullf=%s,notnullf=%s", spec.nullType, spec.notNullType)) 1608 1609 // Inserts with db.Exec: 1610 exec(t, db, "INSERT|t|id=?,name=?,nullf=?,notnullf=?", 1, "alice", spec.rows[0].nullParam, spec.rows[0].notNullParam) 1611 exec(t, db, "INSERT|t|id=?,name=?,nullf=?,notnullf=?", 2, "bob", spec.rows[1].nullParam, spec.rows[1].notNullParam) 1612 1613 // Inserts with a prepared statement: 1614 stmt, err := db.Prepare("INSERT|t|id=?,name=?,nullf=?,notnullf=?") 1615 if err != nil { 1616 t.Fatalf("prepare: %v", err) 1617 } 1618 defer stmt.Close() 1619 if _, err := stmt.Exec(3, "chris", spec.rows[2].nullParam, spec.rows[2].notNullParam); err != nil { 1620 t.Errorf("exec insert chris: %v", err) 1621 } 1622 if _, err := stmt.Exec(4, "dave", spec.rows[3].nullParam, spec.rows[3].notNullParam); err != nil { 1623 t.Errorf("exec insert dave: %v", err) 1624 } 1625 if _, err := stmt.Exec(5, "eleanor", spec.rows[4].nullParam, spec.rows[4].notNullParam); err != nil { 1626 t.Errorf("exec insert eleanor: %v", err) 1627 } 1628 1629 // Can't put null val into non-null col 1630 if _, err := stmt.Exec(6, "bob", spec.rows[5].nullParam, spec.rows[5].notNullParam); err == nil { 1631 t.Errorf("expected error inserting nil val with prepared statement Exec") 1632 } 1633 1634 _, err = db.Exec("INSERT|t|id=?,name=?,nullf=?", 999, nil, nil) 1635 if err == nil { 1636 // TODO: this test fails, but it's just because 1637 // fakeConn implements the optional Execer interface, 1638 // so arguably this is the correct behavior. But 1639 // maybe I should flesh out the fakeConn.Exec 1640 // implementation so this properly fails. 1641 // t.Errorf("expected error inserting nil name with Exec") 1642 } 1643 1644 paramtype := reflect.TypeOf(spec.rows[0].nullParam) 1645 bindVal := reflect.New(paramtype).Interface() 1646 1647 for i := 0; i < 5; i++ { 1648 id := i + 1 1649 if err := db.QueryRow("SELECT|t|nullf|id=?", id).Scan(bindVal); err != nil { 1650 t.Errorf("id=%d Scan: %v", id, err) 1651 } 1652 bindValDeref := reflect.ValueOf(bindVal).Elem().Interface() 1653 if !reflect.DeepEqual(bindValDeref, spec.rows[i].scanNullVal) { 1654 t.Errorf("id=%d got %#v, want %#v", id, bindValDeref, spec.rows[i].scanNullVal) 1655 } 1656 } 1657 } 1658 1659 // golang.org/issue/4859 1660 func TestQueryRowNilScanDest(t *testing.T) { 1661 db := newTestDB(t, "people") 1662 defer closeDB(t, db) 1663 var name *string // nil pointer 1664 err := db.QueryRow("SELECT|people|name|").Scan(name) 1665 want := "sql: Scan error on column index 0: destination pointer is nil" 1666 if err == nil || err.Error() != want { 1667 t.Errorf("error = %q; want %q", err.Error(), want) 1668 } 1669 } 1670 1671 func TestIssue4902(t *testing.T) { 1672 db := newTestDB(t, "people") 1673 defer closeDB(t, db) 1674 1675 driver := db.driver.(*fakeDriver) 1676 opens0 := driver.openCount 1677 1678 var stmt *Stmt 1679 var err error 1680 for i := 0; i < 10; i++ { 1681 stmt, err = db.Prepare("SELECT|people|name|") 1682 if err != nil { 1683 t.Fatal(err) 1684 } 1685 err = stmt.Close() 1686 if err != nil { 1687 t.Fatal(err) 1688 } 1689 } 1690 1691 opens := driver.openCount - opens0 1692 if opens > 1 { 1693 t.Errorf("opens = %d; want <= 1", opens) 1694 t.Logf("db = %#v", db) 1695 t.Logf("driver = %#v", driver) 1696 t.Logf("stmt = %#v", stmt) 1697 } 1698 } 1699 1700 // Issue 3857 1701 // This used to deadlock. 1702 func TestSimultaneousQueries(t *testing.T) { 1703 db := newTestDB(t, "people") 1704 defer closeDB(t, db) 1705 1706 tx, err := db.Begin() 1707 if err != nil { 1708 t.Fatal(err) 1709 } 1710 defer tx.Rollback() 1711 1712 r1, err := tx.Query("SELECT|people|name|") 1713 if err != nil { 1714 t.Fatal(err) 1715 } 1716 defer r1.Close() 1717 1718 r2, err := tx.Query("SELECT|people|name|") 1719 if err != nil { 1720 t.Fatal(err) 1721 } 1722 defer r2.Close() 1723 } 1724 1725 func TestMaxIdleConns(t *testing.T) { 1726 db := newTestDB(t, "people") 1727 defer closeDB(t, db) 1728 1729 tx, err := db.Begin() 1730 if err != nil { 1731 t.Fatal(err) 1732 } 1733 tx.Commit() 1734 if got := len(db.freeConn); got != 1 { 1735 t.Errorf("freeConns = %d; want 1", got) 1736 } 1737 1738 db.SetMaxIdleConns(0) 1739 1740 if got := len(db.freeConn); got != 0 { 1741 t.Errorf("freeConns after set to zero = %d; want 0", got) 1742 } 1743 1744 tx, err = db.Begin() 1745 if err != nil { 1746 t.Fatal(err) 1747 } 1748 tx.Commit() 1749 if got := len(db.freeConn); got != 0 { 1750 t.Errorf("freeConns = %d; want 0", got) 1751 } 1752 } 1753 1754 func TestMaxOpenConns(t *testing.T) { 1755 if testing.Short() { 1756 t.Skip("skipping in short mode") 1757 } 1758 defer setHookpostCloseConn(nil) 1759 setHookpostCloseConn(func(_ *fakeConn, err error) { 1760 if err != nil { 1761 t.Errorf("Error closing fakeConn: %v", err) 1762 } 1763 }) 1764 1765 db := newTestDB(t, "magicquery") 1766 defer closeDB(t, db) 1767 1768 driver := db.driver.(*fakeDriver) 1769 1770 // Force the number of open connections to 0 so we can get an accurate 1771 // count for the test 1772 db.clearAllConns(t) 1773 1774 driver.mu.Lock() 1775 opens0 := driver.openCount 1776 closes0 := driver.closeCount 1777 driver.mu.Unlock() 1778 1779 db.SetMaxIdleConns(10) 1780 db.SetMaxOpenConns(10) 1781 1782 stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?") 1783 if err != nil { 1784 t.Fatal(err) 1785 } 1786 1787 // Start 50 parallel slow queries. 1788 const ( 1789 nquery = 50 1790 sleepMillis = 25 1791 nbatch = 2 1792 ) 1793 var wg sync.WaitGroup 1794 for batch := 0; batch < nbatch; batch++ { 1795 for i := 0; i < nquery; i++ { 1796 wg.Add(1) 1797 go func() { 1798 defer wg.Done() 1799 var op string 1800 if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows { 1801 t.Error(err) 1802 } 1803 }() 1804 } 1805 // Sleep for twice the expected length of time for the 1806 // batch of 50 queries above to finish before starting 1807 // the next round. 1808 time.Sleep(2 * sleepMillis * time.Millisecond) 1809 } 1810 wg.Wait() 1811 1812 if g, w := db.numFreeConns(), 10; g != w { 1813 t.Errorf("free conns = %d; want %d", g, w) 1814 } 1815 1816 if n := db.numDepsPollUntil(20, time.Second); n > 20 { 1817 t.Errorf("number of dependencies = %d; expected <= 20", n) 1818 db.dumpDeps(t) 1819 } 1820 1821 driver.mu.Lock() 1822 opens := driver.openCount - opens0 1823 closes := driver.closeCount - closes0 1824 driver.mu.Unlock() 1825 1826 if opens > 10 { 1827 t.Logf("open calls = %d", opens) 1828 t.Logf("close calls = %d", closes) 1829 t.Errorf("db connections opened = %d; want <= 10", opens) 1830 db.dumpDeps(t) 1831 } 1832 1833 if err := stmt.Close(); err != nil { 1834 t.Fatal(err) 1835 } 1836 1837 if g, w := db.numFreeConns(), 10; g != w { 1838 t.Errorf("free conns = %d; want %d", g, w) 1839 } 1840 1841 if n := db.numDepsPollUntil(10, time.Second); n > 10 { 1842 t.Errorf("number of dependencies = %d; expected <= 10", n) 1843 db.dumpDeps(t) 1844 } 1845 1846 db.SetMaxOpenConns(5) 1847 1848 if g, w := db.numFreeConns(), 5; g != w { 1849 t.Errorf("free conns = %d; want %d", g, w) 1850 } 1851 1852 if n := db.numDepsPollUntil(5, time.Second); n > 5 { 1853 t.Errorf("number of dependencies = %d; expected 0", n) 1854 db.dumpDeps(t) 1855 } 1856 1857 db.SetMaxOpenConns(0) 1858 1859 if g, w := db.numFreeConns(), 5; g != w { 1860 t.Errorf("free conns = %d; want %d", g, w) 1861 } 1862 1863 if n := db.numDepsPollUntil(5, time.Second); n > 5 { 1864 t.Errorf("number of dependencies = %d; expected 0", n) 1865 db.dumpDeps(t) 1866 } 1867 1868 db.clearAllConns(t) 1869 } 1870 1871 // Issue 9453: tests that SetMaxOpenConns can be lowered at runtime 1872 // and affects the subsequent release of connections. 1873 func TestMaxOpenConnsOnBusy(t *testing.T) { 1874 defer setHookpostCloseConn(nil) 1875 setHookpostCloseConn(func(_ *fakeConn, err error) { 1876 if err != nil { 1877 t.Errorf("Error closing fakeConn: %v", err) 1878 } 1879 }) 1880 1881 db := newTestDB(t, "magicquery") 1882 defer closeDB(t, db) 1883 1884 db.SetMaxOpenConns(3) 1885 1886 ctx := context.Background() 1887 1888 conn0, err := db.conn(ctx, cachedOrNewConn) 1889 if err != nil { 1890 t.Fatalf("db open conn fail: %v", err) 1891 } 1892 1893 conn1, err := db.conn(ctx, cachedOrNewConn) 1894 if err != nil { 1895 t.Fatalf("db open conn fail: %v", err) 1896 } 1897 1898 conn2, err := db.conn(ctx, cachedOrNewConn) 1899 if err != nil { 1900 t.Fatalf("db open conn fail: %v", err) 1901 } 1902 1903 if g, w := db.numOpen, 3; g != w { 1904 t.Errorf("free conns = %d; want %d", g, w) 1905 } 1906 1907 db.SetMaxOpenConns(2) 1908 if g, w := db.numOpen, 3; g != w { 1909 t.Errorf("free conns = %d; want %d", g, w) 1910 } 1911 1912 conn0.releaseConn(nil) 1913 conn1.releaseConn(nil) 1914 if g, w := db.numOpen, 2; g != w { 1915 t.Errorf("free conns = %d; want %d", g, w) 1916 } 1917 1918 conn2.releaseConn(nil) 1919 if g, w := db.numOpen, 2; g != w { 1920 t.Errorf("free conns = %d; want %d", g, w) 1921 } 1922 } 1923 1924 // Issue 10886: tests that all connection attempts return when more than 1925 // DB.maxOpen connections are in flight and the first DB.maxOpen fail. 1926 func TestPendingConnsAfterErr(t *testing.T) { 1927 const ( 1928 maxOpen = 2 1929 tryOpen = maxOpen*2 + 2 1930 ) 1931 1932 // No queries will be run. 1933 db, err := Open("test", fakeDBName) 1934 if err != nil { 1935 t.Fatalf("Open: %v", err) 1936 } 1937 defer closeDB(t, db) 1938 defer func() { 1939 for k, v := range db.lastPut { 1940 t.Logf("%p: %v", k, v) 1941 } 1942 }() 1943 1944 db.SetMaxOpenConns(maxOpen) 1945 db.SetMaxIdleConns(0) 1946 1947 errOffline := errors.New("db offline") 1948 1949 defer func() { setHookOpenErr(nil) }() 1950 1951 errs := make(chan error, tryOpen) 1952 1953 var opening sync.WaitGroup 1954 opening.Add(tryOpen) 1955 1956 setHookOpenErr(func() error { 1957 // Wait for all connections to enqueue. 1958 opening.Wait() 1959 return errOffline 1960 }) 1961 1962 for i := 0; i < tryOpen; i++ { 1963 go func() { 1964 opening.Done() // signal one connection is in flight 1965 _, err := db.Exec("will never run") 1966 errs <- err 1967 }() 1968 } 1969 1970 opening.Wait() // wait for all workers to begin running 1971 1972 const timeout = 5 * time.Second 1973 to := time.NewTimer(timeout) 1974 defer to.Stop() 1975 1976 // check that all connections fail without deadlock 1977 for i := 0; i < tryOpen; i++ { 1978 select { 1979 case err := <-errs: 1980 if got, want := err, errOffline; got != want { 1981 t.Errorf("unexpected err: got %v, want %v", got, want) 1982 } 1983 case <-to.C: 1984 t.Fatalf("orphaned connection request(s), still waiting after %v", timeout) 1985 } 1986 } 1987 1988 // Wait a reasonable time for the database to close all connections. 1989 tick := time.NewTicker(3 * time.Millisecond) 1990 defer tick.Stop() 1991 for { 1992 select { 1993 case <-tick.C: 1994 db.mu.Lock() 1995 if db.numOpen == 0 { 1996 db.mu.Unlock() 1997 return 1998 } 1999 db.mu.Unlock() 2000 case <-to.C: 2001 // Closing the database will check for numOpen and fail the test. 2002 return 2003 } 2004 } 2005 } 2006 2007 func TestSingleOpenConn(t *testing.T) { 2008 db := newTestDB(t, "people") 2009 defer closeDB(t, db) 2010 2011 db.SetMaxOpenConns(1) 2012 2013 rows, err := db.Query("SELECT|people|name|") 2014 if err != nil { 2015 t.Fatal(err) 2016 } 2017 if err = rows.Close(); err != nil { 2018 t.Fatal(err) 2019 } 2020 // shouldn't deadlock 2021 rows, err = db.Query("SELECT|people|name|") 2022 if err != nil { 2023 t.Fatal(err) 2024 } 2025 if err = rows.Close(); err != nil { 2026 t.Fatal(err) 2027 } 2028 } 2029 2030 func TestStats(t *testing.T) { 2031 db := newTestDB(t, "people") 2032 stats := db.Stats() 2033 if got := stats.OpenConnections; got != 1 { 2034 t.Errorf("stats.OpenConnections = %d; want 1", got) 2035 } 2036 2037 tx, err := db.Begin() 2038 if err != nil { 2039 t.Fatal(err) 2040 } 2041 tx.Commit() 2042 2043 closeDB(t, db) 2044 stats = db.Stats() 2045 if got := stats.OpenConnections; got != 0 { 2046 t.Errorf("stats.OpenConnections = %d; want 0", got) 2047 } 2048 } 2049 2050 func TestConnMaxLifetime(t *testing.T) { 2051 t0 := time.Unix(1000000, 0) 2052 offset := time.Duration(0) 2053 2054 nowFunc = func() time.Time { return t0.Add(offset) } 2055 defer func() { nowFunc = time.Now }() 2056 2057 db := newTestDB(t, "magicquery") 2058 defer closeDB(t, db) 2059 2060 driver := db.driver.(*fakeDriver) 2061 2062 // Force the number of open connections to 0 so we can get an accurate 2063 // count for the test 2064 db.clearAllConns(t) 2065 2066 driver.mu.Lock() 2067 opens0 := driver.openCount 2068 closes0 := driver.closeCount 2069 driver.mu.Unlock() 2070 2071 db.SetMaxIdleConns(10) 2072 db.SetMaxOpenConns(10) 2073 2074 tx, err := db.Begin() 2075 if err != nil { 2076 t.Fatal(err) 2077 } 2078 2079 offset = time.Second 2080 tx2, err := db.Begin() 2081 if err != nil { 2082 t.Fatal(err) 2083 } 2084 2085 tx.Commit() 2086 tx2.Commit() 2087 2088 driver.mu.Lock() 2089 opens := driver.openCount - opens0 2090 closes := driver.closeCount - closes0 2091 driver.mu.Unlock() 2092 2093 if opens != 2 { 2094 t.Errorf("opens = %d; want 2", opens) 2095 } 2096 if closes != 0 { 2097 t.Errorf("closes = %d; want 0", closes) 2098 } 2099 if g, w := db.numFreeConns(), 2; g != w { 2100 t.Errorf("free conns = %d; want %d", g, w) 2101 } 2102 2103 // Expire first conn 2104 offset = 11 * time.Second 2105 db.SetConnMaxLifetime(10 * time.Second) 2106 if err != nil { 2107 t.Fatal(err) 2108 } 2109 2110 tx, err = db.Begin() 2111 if err != nil { 2112 t.Fatal(err) 2113 } 2114 tx2, err = db.Begin() 2115 if err != nil { 2116 t.Fatal(err) 2117 } 2118 tx.Commit() 2119 tx2.Commit() 2120 2121 driver.mu.Lock() 2122 opens = driver.openCount - opens0 2123 closes = driver.closeCount - closes0 2124 driver.mu.Unlock() 2125 2126 if opens != 3 { 2127 t.Errorf("opens = %d; want 3", opens) 2128 } 2129 if closes != 1 { 2130 t.Errorf("closes = %d; want 1", closes) 2131 } 2132 } 2133 2134 // golang.org/issue/5323 2135 func TestStmtCloseDeps(t *testing.T) { 2136 if testing.Short() { 2137 t.Skip("skipping in short mode") 2138 } 2139 defer setHookpostCloseConn(nil) 2140 setHookpostCloseConn(func(_ *fakeConn, err error) { 2141 if err != nil { 2142 t.Errorf("Error closing fakeConn: %v", err) 2143 } 2144 }) 2145 2146 db := newTestDB(t, "magicquery") 2147 defer closeDB(t, db) 2148 2149 driver := db.driver.(*fakeDriver) 2150 2151 driver.mu.Lock() 2152 opens0 := driver.openCount 2153 closes0 := driver.closeCount 2154 driver.mu.Unlock() 2155 openDelta0 := opens0 - closes0 2156 2157 stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?") 2158 if err != nil { 2159 t.Fatal(err) 2160 } 2161 2162 // Start 50 parallel slow queries. 2163 const ( 2164 nquery = 50 2165 sleepMillis = 25 2166 nbatch = 2 2167 ) 2168 var wg sync.WaitGroup 2169 for batch := 0; batch < nbatch; batch++ { 2170 for i := 0; i < nquery; i++ { 2171 wg.Add(1) 2172 go func() { 2173 defer wg.Done() 2174 var op string 2175 if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows { 2176 t.Error(err) 2177 } 2178 }() 2179 } 2180 // Sleep for twice the expected length of time for the 2181 // batch of 50 queries above to finish before starting 2182 // the next round. 2183 time.Sleep(2 * sleepMillis * time.Millisecond) 2184 } 2185 wg.Wait() 2186 2187 if g, w := db.numFreeConns(), 2; g != w { 2188 t.Errorf("free conns = %d; want %d", g, w) 2189 } 2190 2191 if n := db.numDepsPollUntil(4, time.Second); n > 4 { 2192 t.Errorf("number of dependencies = %d; expected <= 4", n) 2193 db.dumpDeps(t) 2194 } 2195 2196 driver.mu.Lock() 2197 opens := driver.openCount - opens0 2198 closes := driver.closeCount - closes0 2199 openDelta := (driver.openCount - driver.closeCount) - openDelta0 2200 driver.mu.Unlock() 2201 2202 if openDelta > 2 { 2203 t.Logf("open calls = %d", opens) 2204 t.Logf("close calls = %d", closes) 2205 t.Logf("open delta = %d", openDelta) 2206 t.Errorf("db connections opened = %d; want <= 2", openDelta) 2207 db.dumpDeps(t) 2208 } 2209 2210 if !waitCondition(5*time.Second, 5*time.Millisecond, func() bool { 2211 return len(stmt.css) <= nquery 2212 }) { 2213 t.Errorf("len(stmt.css) = %d; want <= %d", len(stmt.css), nquery) 2214 } 2215 2216 if err := stmt.Close(); err != nil { 2217 t.Fatal(err) 2218 } 2219 2220 if g, w := db.numFreeConns(), 2; g != w { 2221 t.Errorf("free conns = %d; want %d", g, w) 2222 } 2223 2224 if n := db.numDepsPollUntil(2, time.Second); n > 2 { 2225 t.Errorf("number of dependencies = %d; expected <= 2", n) 2226 db.dumpDeps(t) 2227 } 2228 2229 db.clearAllConns(t) 2230 } 2231 2232 // golang.org/issue/5046 2233 func TestCloseConnBeforeStmts(t *testing.T) { 2234 db := newTestDB(t, "people") 2235 defer closeDB(t, db) 2236 2237 defer setHookpostCloseConn(nil) 2238 setHookpostCloseConn(func(_ *fakeConn, err error) { 2239 if err != nil { 2240 t.Errorf("Error closing fakeConn: %v; from %s", err, stack()) 2241 db.dumpDeps(t) 2242 t.Errorf("DB = %#v", db) 2243 } 2244 }) 2245 2246 stmt, err := db.Prepare("SELECT|people|name|") 2247 if err != nil { 2248 t.Fatal(err) 2249 } 2250 2251 if len(db.freeConn) != 1 { 2252 t.Fatalf("expected 1 freeConn; got %d", len(db.freeConn)) 2253 } 2254 dc := db.freeConn[0] 2255 if dc.closed { 2256 t.Errorf("conn shouldn't be closed") 2257 } 2258 2259 if n := len(dc.openStmt); n != 1 { 2260 t.Errorf("driverConn num openStmt = %d; want 1", n) 2261 } 2262 err = db.Close() 2263 if err != nil { 2264 t.Errorf("db Close = %v", err) 2265 } 2266 if !dc.closed { 2267 t.Errorf("after db.Close, driverConn should be closed") 2268 } 2269 if n := len(dc.openStmt); n != 0 { 2270 t.Errorf("driverConn num openStmt = %d; want 0", n) 2271 } 2272 2273 err = stmt.Close() 2274 if err != nil { 2275 t.Errorf("Stmt close = %v", err) 2276 } 2277 2278 if !dc.closed { 2279 t.Errorf("conn should be closed") 2280 } 2281 if dc.ci != nil { 2282 t.Errorf("after Stmt Close, driverConn's Conn interface should be nil") 2283 } 2284 } 2285 2286 // golang.org/issue/5283: don't release the Rows' connection in Close 2287 // before calling Stmt.Close. 2288 func TestRowsCloseOrder(t *testing.T) { 2289 db := newTestDB(t, "people") 2290 defer closeDB(t, db) 2291 2292 db.SetMaxIdleConns(0) 2293 setStrictFakeConnClose(t) 2294 defer setStrictFakeConnClose(nil) 2295 2296 rows, err := db.Query("SELECT|people|age,name|") 2297 if err != nil { 2298 t.Fatal(err) 2299 } 2300 err = rows.Close() 2301 if err != nil { 2302 t.Fatal(err) 2303 } 2304 } 2305 2306 func TestRowsImplicitClose(t *testing.T) { 2307 db := newTestDB(t, "people") 2308 defer closeDB(t, db) 2309 2310 rows, err := db.Query("SELECT|people|age,name|") 2311 if err != nil { 2312 t.Fatal(err) 2313 } 2314 2315 want, fail := 2, errors.New("fail") 2316 r := rows.rowsi.(*rowsCursor) 2317 r.errPos, r.err = want, fail 2318 2319 got := 0 2320 for rows.Next() { 2321 got++ 2322 } 2323 if got != want { 2324 t.Errorf("got %d rows, want %d", got, want) 2325 } 2326 if err := rows.Err(); err != fail { 2327 t.Errorf("got error %v, want %v", err, fail) 2328 } 2329 if !r.closed { 2330 t.Errorf("r.closed is false, want true") 2331 } 2332 } 2333 2334 func TestStmtCloseOrder(t *testing.T) { 2335 db := newTestDB(t, "people") 2336 defer closeDB(t, db) 2337 2338 db.SetMaxIdleConns(0) 2339 setStrictFakeConnClose(t) 2340 defer setStrictFakeConnClose(nil) 2341 2342 _, err := db.Query("SELECT|non_existent|name|") 2343 if err == nil { 2344 t.Fatal("Querying non-existent table should fail") 2345 } 2346 } 2347 2348 // Test cases where there's more than maxBadConnRetries bad connections in the 2349 // pool (issue 8834) 2350 func TestManyErrBadConn(t *testing.T) { 2351 manyErrBadConnSetup := func(first ...func(db *DB)) *DB { 2352 db := newTestDB(t, "people") 2353 2354 for _, f := range first { 2355 f(db) 2356 } 2357 2358 nconn := maxBadConnRetries + 1 2359 db.SetMaxIdleConns(nconn) 2360 db.SetMaxOpenConns(nconn) 2361 // open enough connections 2362 func() { 2363 for i := 0; i < nconn; i++ { 2364 rows, err := db.Query("SELECT|people|age,name|") 2365 if err != nil { 2366 t.Fatal(err) 2367 } 2368 defer rows.Close() 2369 } 2370 }() 2371 2372 db.mu.Lock() 2373 defer db.mu.Unlock() 2374 if db.numOpen != nconn { 2375 t.Fatalf("unexpected numOpen %d (was expecting %d)", db.numOpen, nconn) 2376 } else if len(db.freeConn) != nconn { 2377 t.Fatalf("unexpected len(db.freeConn) %d (was expecting %d)", len(db.freeConn), nconn) 2378 } 2379 for _, conn := range db.freeConn { 2380 conn.ci.(*fakeConn).stickyBad = true 2381 } 2382 return db 2383 } 2384 2385 // Query 2386 db := manyErrBadConnSetup() 2387 defer closeDB(t, db) 2388 rows, err := db.Query("SELECT|people|age,name|") 2389 if err != nil { 2390 t.Fatal(err) 2391 } 2392 if err = rows.Close(); err != nil { 2393 t.Fatal(err) 2394 } 2395 2396 // Exec 2397 db = manyErrBadConnSetup() 2398 defer closeDB(t, db) 2399 _, err = db.Exec("INSERT|people|name=Julia,age=19") 2400 if err != nil { 2401 t.Fatal(err) 2402 } 2403 2404 // Begin 2405 db = manyErrBadConnSetup() 2406 defer closeDB(t, db) 2407 tx, err := db.Begin() 2408 if err != nil { 2409 t.Fatal(err) 2410 } 2411 if err = tx.Rollback(); err != nil { 2412 t.Fatal(err) 2413 } 2414 2415 // Prepare 2416 db = manyErrBadConnSetup() 2417 defer closeDB(t, db) 2418 stmt, err := db.Prepare("SELECT|people|age,name|") 2419 if err != nil { 2420 t.Fatal(err) 2421 } 2422 if err = stmt.Close(); err != nil { 2423 t.Fatal(err) 2424 } 2425 2426 // Stmt.Exec 2427 db = manyErrBadConnSetup(func(db *DB) { 2428 stmt, err = db.Prepare("INSERT|people|name=Julia,age=19") 2429 if err != nil { 2430 t.Fatal(err) 2431 } 2432 }) 2433 defer closeDB(t, db) 2434 _, err = stmt.Exec() 2435 if err != nil { 2436 t.Fatal(err) 2437 } 2438 if err = stmt.Close(); err != nil { 2439 t.Fatal(err) 2440 } 2441 2442 // Stmt.Query 2443 db = manyErrBadConnSetup(func(db *DB) { 2444 stmt, err = db.Prepare("SELECT|people|age,name|") 2445 if err != nil { 2446 t.Fatal(err) 2447 } 2448 }) 2449 defer closeDB(t, db) 2450 rows, err = stmt.Query() 2451 if err != nil { 2452 t.Fatal(err) 2453 } 2454 if err = rows.Close(); err != nil { 2455 t.Fatal(err) 2456 } 2457 if err = stmt.Close(); err != nil { 2458 t.Fatal(err) 2459 } 2460 2461 // Conn 2462 db = manyErrBadConnSetup() 2463 defer closeDB(t, db) 2464 ctx, cancel := context.WithCancel(context.Background()) 2465 defer cancel() 2466 conn, err := db.Conn(ctx) 2467 if err != nil { 2468 t.Fatal(err) 2469 } 2470 err = conn.Close() 2471 if err != nil { 2472 t.Fatal(err) 2473 } 2474 2475 // Ping 2476 db = manyErrBadConnSetup() 2477 defer closeDB(t, db) 2478 err = db.PingContext(ctx) 2479 if err != nil { 2480 t.Fatal(err) 2481 } 2482 } 2483 2484 // TestIssue20575 ensures the Rows from query does not block 2485 // closing a transaction. Ensure Rows is closed while closing a trasaction. 2486 func TestIssue20575(t *testing.T) { 2487 db := newTestDB(t, "people") 2488 defer closeDB(t, db) 2489 2490 tx, err := db.Begin() 2491 if err != nil { 2492 t.Fatal(err) 2493 } 2494 ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) 2495 defer cancel() 2496 _, err = tx.QueryContext(ctx, "SELECT|people|age,name|") 2497 if err != nil { 2498 t.Fatal(err) 2499 } 2500 // Do not close Rows from QueryContext. 2501 err = tx.Rollback() 2502 if err != nil { 2503 t.Fatal(err) 2504 } 2505 select { 2506 default: 2507 case <-ctx.Done(): 2508 t.Fatal("timeout: failed to rollback query without closing rows:", ctx.Err()) 2509 } 2510 } 2511 2512 // TestIssue20622 tests closing the transaction before rows is closed, requires 2513 // the race detector to fail. 2514 func TestIssue20622(t *testing.T) { 2515 db := newTestDB(t, "people") 2516 defer closeDB(t, db) 2517 2518 ctx, cancel := context.WithCancel(context.Background()) 2519 defer cancel() 2520 2521 tx, err := db.BeginTx(ctx, nil) 2522 if err != nil { 2523 t.Fatal(err) 2524 } 2525 2526 rows, err := tx.Query("SELECT|people|age,name|") 2527 if err != nil { 2528 t.Fatal(err) 2529 } 2530 2531 count := 0 2532 for rows.Next() { 2533 count++ 2534 var age int 2535 var name string 2536 if err := rows.Scan(&age, &name); err != nil { 2537 t.Fatal("scan failed", err) 2538 } 2539 2540 if count == 1 { 2541 cancel() 2542 } 2543 time.Sleep(100 * time.Millisecond) 2544 } 2545 rows.Close() 2546 tx.Commit() 2547 } 2548 2549 // golang.org/issue/5718 2550 func TestErrBadConnReconnect(t *testing.T) { 2551 db := newTestDB(t, "foo") 2552 defer closeDB(t, db) 2553 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool") 2554 2555 simulateBadConn := func(name string, hook *func() bool, op func() error) { 2556 broken, retried := false, false 2557 numOpen := db.numOpen 2558 2559 // simulate a broken connection on the first try 2560 *hook = func() bool { 2561 if !broken { 2562 broken = true 2563 return true 2564 } 2565 retried = true 2566 return false 2567 } 2568 2569 if err := op(); err != nil { 2570 t.Errorf(name+": %v", err) 2571 return 2572 } 2573 2574 if !broken || !retried { 2575 t.Error(name + ": Failed to simulate broken connection") 2576 } 2577 *hook = nil 2578 2579 if numOpen != db.numOpen { 2580 t.Errorf(name+": leaked %d connection(s)!", db.numOpen-numOpen) 2581 numOpen = db.numOpen 2582 } 2583 } 2584 2585 // db.Exec 2586 dbExec := func() error { 2587 _, err := db.Exec("INSERT|t1|name=?,age=?,dead=?", "Gordon", 3, true) 2588 return err 2589 } 2590 simulateBadConn("db.Exec prepare", &hookPrepareBadConn, dbExec) 2591 simulateBadConn("db.Exec exec", &hookExecBadConn, dbExec) 2592 2593 // db.Query 2594 dbQuery := func() error { 2595 rows, err := db.Query("SELECT|t1|age,name|") 2596 if err == nil { 2597 err = rows.Close() 2598 } 2599 return err 2600 } 2601 simulateBadConn("db.Query prepare", &hookPrepareBadConn, dbQuery) 2602 simulateBadConn("db.Query query", &hookQueryBadConn, dbQuery) 2603 2604 // db.Prepare 2605 simulateBadConn("db.Prepare", &hookPrepareBadConn, func() error { 2606 stmt, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?") 2607 if err != nil { 2608 return err 2609 } 2610 stmt.Close() 2611 return nil 2612 }) 2613 2614 // Provide a way to force a re-prepare of a statement on next execution 2615 forcePrepare := func(stmt *Stmt) { 2616 stmt.css = nil 2617 } 2618 2619 // stmt.Exec 2620 stmt1, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?") 2621 if err != nil { 2622 t.Fatalf("prepare: %v", err) 2623 } 2624 defer stmt1.Close() 2625 // make sure we must prepare the stmt first 2626 forcePrepare(stmt1) 2627 2628 stmtExec := func() error { 2629 _, err := stmt1.Exec("Gopher", 3, false) 2630 return err 2631 } 2632 simulateBadConn("stmt.Exec prepare", &hookPrepareBadConn, stmtExec) 2633 simulateBadConn("stmt.Exec exec", &hookExecBadConn, stmtExec) 2634 2635 // stmt.Query 2636 stmt2, err := db.Prepare("SELECT|t1|age,name|") 2637 if err != nil { 2638 t.Fatalf("prepare: %v", err) 2639 } 2640 defer stmt2.Close() 2641 // make sure we must prepare the stmt first 2642 forcePrepare(stmt2) 2643 2644 stmtQuery := func() error { 2645 rows, err := stmt2.Query() 2646 if err == nil { 2647 err = rows.Close() 2648 } 2649 return err 2650 } 2651 simulateBadConn("stmt.Query prepare", &hookPrepareBadConn, stmtQuery) 2652 simulateBadConn("stmt.Query exec", &hookQueryBadConn, stmtQuery) 2653 } 2654 2655 // golang.org/issue/11264 2656 func TestTxEndBadConn(t *testing.T) { 2657 db := newTestDB(t, "foo") 2658 defer closeDB(t, db) 2659 db.SetMaxIdleConns(0) 2660 exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool") 2661 db.SetMaxIdleConns(1) 2662 2663 simulateBadConn := func(name string, hook *func() bool, op func() error) { 2664 broken := false 2665 numOpen := db.numOpen 2666 2667 *hook = func() bool { 2668 if !broken { 2669 broken = true 2670 } 2671 return broken 2672 } 2673 2674 if err := op(); err != driver.ErrBadConn { 2675 t.Errorf(name+": %v", err) 2676 return 2677 } 2678 2679 if !broken { 2680 t.Error(name + ": Failed to simulate broken connection") 2681 } 2682 *hook = nil 2683 2684 if numOpen != db.numOpen { 2685 t.Errorf(name+": leaked %d connection(s)!", db.numOpen-numOpen) 2686 } 2687 } 2688 2689 // db.Exec 2690 dbExec := func(endTx func(tx *Tx) error) func() error { 2691 return func() error { 2692 tx, err := db.Begin() 2693 if err != nil { 2694 return err 2695 } 2696 _, err = tx.Exec("INSERT|t1|name=?,age=?,dead=?", "Gordon", 3, true) 2697 if err != nil { 2698 return err 2699 } 2700 return endTx(tx) 2701 } 2702 } 2703 simulateBadConn("db.Tx.Exec commit", &hookCommitBadConn, dbExec((*Tx).Commit)) 2704 simulateBadConn("db.Tx.Exec rollback", &hookRollbackBadConn, dbExec((*Tx).Rollback)) 2705 2706 // db.Query 2707 dbQuery := func(endTx func(tx *Tx) error) func() error { 2708 return func() error { 2709 tx, err := db.Begin() 2710 if err != nil { 2711 return err 2712 } 2713 rows, err := tx.Query("SELECT|t1|age,name|") 2714 if err == nil { 2715 err = rows.Close() 2716 } else { 2717 return err 2718 } 2719 return endTx(tx) 2720 } 2721 } 2722 simulateBadConn("db.Tx.Query commit", &hookCommitBadConn, dbQuery((*Tx).Commit)) 2723 simulateBadConn("db.Tx.Query rollback", &hookRollbackBadConn, dbQuery((*Tx).Rollback)) 2724 } 2725 2726 type concurrentTest interface { 2727 init(t testing.TB, db *DB) 2728 finish(t testing.TB) 2729 test(t testing.TB) error 2730 } 2731 2732 type concurrentDBQueryTest struct { 2733 db *DB 2734 } 2735 2736 func (c *concurrentDBQueryTest) init(t testing.TB, db *DB) { 2737 c.db = db 2738 } 2739 2740 func (c *concurrentDBQueryTest) finish(t testing.TB) { 2741 c.db = nil 2742 } 2743 2744 func (c *concurrentDBQueryTest) test(t testing.TB) error { 2745 rows, err := c.db.Query("SELECT|people|name|") 2746 if err != nil { 2747 t.Error(err) 2748 return err 2749 } 2750 var name string 2751 for rows.Next() { 2752 rows.Scan(&name) 2753 } 2754 rows.Close() 2755 return nil 2756 } 2757 2758 type concurrentDBExecTest struct { 2759 db *DB 2760 } 2761 2762 func (c *concurrentDBExecTest) init(t testing.TB, db *DB) { 2763 c.db = db 2764 } 2765 2766 func (c *concurrentDBExecTest) finish(t testing.TB) { 2767 c.db = nil 2768 } 2769 2770 func (c *concurrentDBExecTest) test(t testing.TB) error { 2771 _, err := c.db.Exec("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday) 2772 if err != nil { 2773 t.Error(err) 2774 return err 2775 } 2776 return nil 2777 } 2778 2779 type concurrentStmtQueryTest struct { 2780 db *DB 2781 stmt *Stmt 2782 } 2783 2784 func (c *concurrentStmtQueryTest) init(t testing.TB, db *DB) { 2785 c.db = db 2786 var err error 2787 c.stmt, err = db.Prepare("SELECT|people|name|") 2788 if err != nil { 2789 t.Fatal(err) 2790 } 2791 } 2792 2793 func (c *concurrentStmtQueryTest) finish(t testing.TB) { 2794 if c.stmt != nil { 2795 c.stmt.Close() 2796 c.stmt = nil 2797 } 2798 c.db = nil 2799 } 2800 2801 func (c *concurrentStmtQueryTest) test(t testing.TB) error { 2802 rows, err := c.stmt.Query() 2803 if err != nil { 2804 t.Errorf("error on query: %v", err) 2805 return err 2806 } 2807 2808 var name string 2809 for rows.Next() { 2810 rows.Scan(&name) 2811 } 2812 rows.Close() 2813 return nil 2814 } 2815 2816 type concurrentStmtExecTest struct { 2817 db *DB 2818 stmt *Stmt 2819 } 2820 2821 func (c *concurrentStmtExecTest) init(t testing.TB, db *DB) { 2822 c.db = db 2823 var err error 2824 c.stmt, err = db.Prepare("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?") 2825 if err != nil { 2826 t.Fatal(err) 2827 } 2828 } 2829 2830 func (c *concurrentStmtExecTest) finish(t testing.TB) { 2831 if c.stmt != nil { 2832 c.stmt.Close() 2833 c.stmt = nil 2834 } 2835 c.db = nil 2836 } 2837 2838 func (c *concurrentStmtExecTest) test(t testing.TB) error { 2839 _, err := c.stmt.Exec(3, chrisBirthday) 2840 if err != nil { 2841 t.Errorf("error on exec: %v", err) 2842 return err 2843 } 2844 return nil 2845 } 2846 2847 type concurrentTxQueryTest struct { 2848 db *DB 2849 tx *Tx 2850 } 2851 2852 func (c *concurrentTxQueryTest) init(t testing.TB, db *DB) { 2853 c.db = db 2854 var err error 2855 c.tx, err = c.db.Begin() 2856 if err != nil { 2857 t.Fatal(err) 2858 } 2859 } 2860 2861 func (c *concurrentTxQueryTest) finish(t testing.TB) { 2862 if c.tx != nil { 2863 c.tx.Rollback() 2864 c.tx = nil 2865 } 2866 c.db = nil 2867 } 2868 2869 func (c *concurrentTxQueryTest) test(t testing.TB) error { 2870 rows, err := c.db.Query("SELECT|people|name|") 2871 if err != nil { 2872 t.Error(err) 2873 return err 2874 } 2875 var name string 2876 for rows.Next() { 2877 rows.Scan(&name) 2878 } 2879 rows.Close() 2880 return nil 2881 } 2882 2883 type concurrentTxExecTest struct { 2884 db *DB 2885 tx *Tx 2886 } 2887 2888 func (c *concurrentTxExecTest) init(t testing.TB, db *DB) { 2889 c.db = db 2890 var err error 2891 c.tx, err = c.db.Begin() 2892 if err != nil { 2893 t.Fatal(err) 2894 } 2895 } 2896 2897 func (c *concurrentTxExecTest) finish(t testing.TB) { 2898 if c.tx != nil { 2899 c.tx.Rollback() 2900 c.tx = nil 2901 } 2902 c.db = nil 2903 } 2904 2905 func (c *concurrentTxExecTest) test(t testing.TB) error { 2906 _, err := c.tx.Exec("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday) 2907 if err != nil { 2908 t.Error(err) 2909 return err 2910 } 2911 return nil 2912 } 2913 2914 type concurrentTxStmtQueryTest struct { 2915 db *DB 2916 tx *Tx 2917 stmt *Stmt 2918 } 2919 2920 func (c *concurrentTxStmtQueryTest) init(t testing.TB, db *DB) { 2921 c.db = db 2922 var err error 2923 c.tx, err = c.db.Begin() 2924 if err != nil { 2925 t.Fatal(err) 2926 } 2927 c.stmt, err = c.tx.Prepare("SELECT|people|name|") 2928 if err != nil { 2929 t.Fatal(err) 2930 } 2931 } 2932 2933 func (c *concurrentTxStmtQueryTest) finish(t testing.TB) { 2934 if c.stmt != nil { 2935 c.stmt.Close() 2936 c.stmt = nil 2937 } 2938 if c.tx != nil { 2939 c.tx.Rollback() 2940 c.tx = nil 2941 } 2942 c.db = nil 2943 } 2944 2945 func (c *concurrentTxStmtQueryTest) test(t testing.TB) error { 2946 rows, err := c.stmt.Query() 2947 if err != nil { 2948 t.Errorf("error on query: %v", err) 2949 return err 2950 } 2951 2952 var name string 2953 for rows.Next() { 2954 rows.Scan(&name) 2955 } 2956 rows.Close() 2957 return nil 2958 } 2959 2960 type concurrentTxStmtExecTest struct { 2961 db *DB 2962 tx *Tx 2963 stmt *Stmt 2964 } 2965 2966 func (c *concurrentTxStmtExecTest) init(t testing.TB, db *DB) { 2967 c.db = db 2968 var err error 2969 c.tx, err = c.db.Begin() 2970 if err != nil { 2971 t.Fatal(err) 2972 } 2973 c.stmt, err = c.tx.Prepare("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?") 2974 if err != nil { 2975 t.Fatal(err) 2976 } 2977 } 2978 2979 func (c *concurrentTxStmtExecTest) finish(t testing.TB) { 2980 if c.stmt != nil { 2981 c.stmt.Close() 2982 c.stmt = nil 2983 } 2984 if c.tx != nil { 2985 c.tx.Rollback() 2986 c.tx = nil 2987 } 2988 c.db = nil 2989 } 2990 2991 func (c *concurrentTxStmtExecTest) test(t testing.TB) error { 2992 _, err := c.stmt.Exec(3, chrisBirthday) 2993 if err != nil { 2994 t.Errorf("error on exec: %v", err) 2995 return err 2996 } 2997 return nil 2998 } 2999 3000 type concurrentRandomTest struct { 3001 tests []concurrentTest 3002 } 3003 3004 func (c *concurrentRandomTest) init(t testing.TB, db *DB) { 3005 c.tests = []concurrentTest{ 3006 new(concurrentDBQueryTest), 3007 new(concurrentDBExecTest), 3008 new(concurrentStmtQueryTest), 3009 new(concurrentStmtExecTest), 3010 new(concurrentTxQueryTest), 3011 new(concurrentTxExecTest), 3012 new(concurrentTxStmtQueryTest), 3013 new(concurrentTxStmtExecTest), 3014 } 3015 for _, ct := range c.tests { 3016 ct.init(t, db) 3017 } 3018 } 3019 3020 func (c *concurrentRandomTest) finish(t testing.TB) { 3021 for _, ct := range c.tests { 3022 ct.finish(t) 3023 } 3024 } 3025 3026 func (c *concurrentRandomTest) test(t testing.TB) error { 3027 ct := c.tests[rand.Intn(len(c.tests))] 3028 return ct.test(t) 3029 } 3030 3031 func doConcurrentTest(t testing.TB, ct concurrentTest) { 3032 maxProcs, numReqs := 1, 500 3033 if testing.Short() { 3034 maxProcs, numReqs = 4, 50 3035 } 3036 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs)) 3037 3038 db := newTestDB(t, "people") 3039 defer closeDB(t, db) 3040 3041 ct.init(t, db) 3042 defer ct.finish(t) 3043 3044 var wg sync.WaitGroup 3045 wg.Add(numReqs) 3046 3047 reqs := make(chan bool) 3048 defer close(reqs) 3049 3050 for i := 0; i < maxProcs*2; i++ { 3051 go func() { 3052 for range reqs { 3053 err := ct.test(t) 3054 if err != nil { 3055 wg.Done() 3056 continue 3057 } 3058 wg.Done() 3059 } 3060 }() 3061 } 3062 3063 for i := 0; i < numReqs; i++ { 3064 reqs <- true 3065 } 3066 3067 wg.Wait() 3068 } 3069 3070 func TestIssue6081(t *testing.T) { 3071 db := newTestDB(t, "people") 3072 defer closeDB(t, db) 3073 3074 drv := db.driver.(*fakeDriver) 3075 drv.mu.Lock() 3076 opens0 := drv.openCount 3077 closes0 := drv.closeCount 3078 drv.mu.Unlock() 3079 3080 stmt, err := db.Prepare("SELECT|people|name|") 3081 if err != nil { 3082 t.Fatal(err) 3083 } 3084 setRowsCloseHook(func(rows *Rows, err *error) { 3085 *err = driver.ErrBadConn 3086 }) 3087 defer setRowsCloseHook(nil) 3088 for i := 0; i < 10; i++ { 3089 rows, err := stmt.Query() 3090 if err != nil { 3091 t.Fatal(err) 3092 } 3093 rows.Close() 3094 } 3095 if n := len(stmt.css); n > 1 { 3096 t.Errorf("len(css slice) = %d; want <= 1", n) 3097 } 3098 stmt.Close() 3099 if n := len(stmt.css); n != 0 { 3100 t.Errorf("len(css slice) after Close = %d; want 0", n) 3101 } 3102 3103 drv.mu.Lock() 3104 opens := drv.openCount - opens0 3105 closes := drv.closeCount - closes0 3106 drv.mu.Unlock() 3107 if opens < 9 { 3108 t.Errorf("opens = %d; want >= 9", opens) 3109 } 3110 if closes < 9 { 3111 t.Errorf("closes = %d; want >= 9", closes) 3112 } 3113 } 3114 3115 // TestIssue18429 attempts to stress rolling back the transaction from a 3116 // context cancel while simultaneously calling Tx.Rollback. Rolling back from a 3117 // context happens concurrently so tx.rollback and tx.Commit must guard against 3118 // double entry. 3119 // 3120 // In the test, a context is canceled while the query is in process so 3121 // the internal rollback will run concurrently with the explicitly called 3122 // Tx.Rollback. 3123 func TestIssue18429(t *testing.T) { 3124 db := newTestDB(t, "people") 3125 defer closeDB(t, db) 3126 3127 ctx := context.Background() 3128 sem := make(chan bool, 20) 3129 var wg sync.WaitGroup 3130 3131 const milliWait = 30 3132 3133 for i := 0; i < 100; i++ { 3134 sem <- true 3135 wg.Add(1) 3136 go func() { 3137 defer func() { 3138 <-sem 3139 wg.Done() 3140 }() 3141 qwait := (time.Duration(rand.Intn(milliWait)) * time.Millisecond).String() 3142 3143 ctx, cancel := context.WithTimeout(ctx, time.Duration(rand.Intn(milliWait))*time.Millisecond) 3144 defer cancel() 3145 3146 tx, err := db.BeginTx(ctx, nil) 3147 if err != nil { 3148 return 3149 } 3150 // This is expected to give a cancel error most, but not all the time. 3151 // Test failure will happen with a panic or other race condition being 3152 // reported. 3153 rows, _ := tx.QueryContext(ctx, "WAIT|"+qwait+"|SELECT|people|name|") 3154 if rows != nil { 3155 rows.Close() 3156 } 3157 // This call will race with the context cancel rollback to complete 3158 // if the rollback itself isn't guarded. 3159 tx.Rollback() 3160 }() 3161 } 3162 wg.Wait() 3163 } 3164 3165 // TestIssue20160 attempts to test a short context life on a stmt Query. 3166 func TestIssue20160(t *testing.T) { 3167 db := newTestDB(t, "people") 3168 defer closeDB(t, db) 3169 3170 ctx := context.Background() 3171 sem := make(chan bool, 20) 3172 var wg sync.WaitGroup 3173 3174 const milliWait = 30 3175 3176 stmt, err := db.PrepareContext(ctx, "SELECT|people|name|") 3177 if err != nil { 3178 t.Fatal(err) 3179 } 3180 defer stmt.Close() 3181 3182 for i := 0; i < 100; i++ { 3183 sem <- true 3184 wg.Add(1) 3185 go func() { 3186 defer func() { 3187 <-sem 3188 wg.Done() 3189 }() 3190 ctx, cancel := context.WithTimeout(ctx, time.Duration(rand.Intn(milliWait))*time.Millisecond) 3191 defer cancel() 3192 3193 // This is expected to give a cancel error most, but not all the time. 3194 // Test failure will happen with a panic or other race condition being 3195 // reported. 3196 rows, _ := stmt.QueryContext(ctx) 3197 if rows != nil { 3198 rows.Close() 3199 } 3200 }() 3201 } 3202 wg.Wait() 3203 } 3204 3205 // TestIssue18719 closes the context right before use. The sql.driverConn 3206 // will nil out the ci on close in a lock, but if another process uses it right after 3207 // it will panic with on the nil ref. 3208 // 3209 // See https://golang.org/cl/35550 . 3210 func TestIssue18719(t *testing.T) { 3211 db := newTestDB(t, "people") 3212 defer closeDB(t, db) 3213 3214 ctx, cancel := context.WithCancel(context.Background()) 3215 defer cancel() 3216 3217 tx, err := db.BeginTx(ctx, nil) 3218 if err != nil { 3219 t.Fatal(err) 3220 } 3221 3222 hookTxGrabConn = func() { 3223 cancel() 3224 3225 // Wait for the context to cancel and tx to rollback. 3226 for tx.isDone() == false { 3227 time.Sleep(3 * time.Millisecond) 3228 } 3229 } 3230 defer func() { hookTxGrabConn = nil }() 3231 3232 // This call will grab the connection and cancel the context 3233 // after it has done so. Code after must deal with the canceled state. 3234 rows, err := tx.QueryContext(ctx, "SELECT|people|name|") 3235 if err != nil { 3236 rows.Close() 3237 t.Fatalf("expected error %v but got %v", nil, err) 3238 } 3239 3240 // Rows may be ignored because it will be closed when the context is canceled. 3241 3242 // Do not explicitly rollback. The rollback will happen from the 3243 // canceled context. 3244 3245 cancel() 3246 } 3247 3248 func TestIssue20647(t *testing.T) { 3249 db := newTestDB(t, "people") 3250 defer closeDB(t, db) 3251 3252 ctx, cancel := context.WithCancel(context.Background()) 3253 defer cancel() 3254 3255 conn, err := db.Conn(ctx) 3256 if err != nil { 3257 t.Fatal(err) 3258 } 3259 defer conn.Close() 3260 3261 stmt, err := conn.PrepareContext(ctx, "SELECT|people|name|") 3262 if err != nil { 3263 t.Fatal(err) 3264 } 3265 defer stmt.Close() 3266 3267 rows1, err := stmt.QueryContext(ctx) 3268 if err != nil { 3269 t.Fatal("rows1", err) 3270 } 3271 defer rows1.Close() 3272 3273 rows2, err := stmt.QueryContext(ctx) 3274 if err != nil { 3275 t.Fatal("rows2", err) 3276 } 3277 defer rows2.Close() 3278 3279 if rows1.dc != rows2.dc { 3280 t.Fatal("stmt prepared on Conn does not use same connection") 3281 } 3282 } 3283 3284 func TestConcurrency(t *testing.T) { 3285 list := []struct { 3286 name string 3287 ct concurrentTest 3288 }{ 3289 {"Query", new(concurrentDBQueryTest)}, 3290 {"Exec", new(concurrentDBExecTest)}, 3291 {"StmtQuery", new(concurrentStmtQueryTest)}, 3292 {"StmtExec", new(concurrentStmtExecTest)}, 3293 {"TxQuery", new(concurrentTxQueryTest)}, 3294 {"TxExec", new(concurrentTxExecTest)}, 3295 {"TxStmtQuery", new(concurrentTxStmtQueryTest)}, 3296 {"TxStmtExec", new(concurrentTxStmtExecTest)}, 3297 {"Random", new(concurrentRandomTest)}, 3298 } 3299 for _, item := range list { 3300 t.Run(item.name, func(t *testing.T) { 3301 doConcurrentTest(t, item.ct) 3302 }) 3303 } 3304 } 3305 3306 func TestConnectionLeak(t *testing.T) { 3307 db := newTestDB(t, "people") 3308 defer closeDB(t, db) 3309 // Start by opening defaultMaxIdleConns 3310 rows := make([]*Rows, defaultMaxIdleConns) 3311 // We need to SetMaxOpenConns > MaxIdleConns, so the DB can open 3312 // a new connection and we can fill the idle queue with the released 3313 // connections. 3314 db.SetMaxOpenConns(len(rows) + 1) 3315 for ii := range rows { 3316 r, err := db.Query("SELECT|people|name|") 3317 if err != nil { 3318 t.Fatal(err) 3319 } 3320 r.Next() 3321 if err := r.Err(); err != nil { 3322 t.Fatal(err) 3323 } 3324 rows[ii] = r 3325 } 3326 // Now we have defaultMaxIdleConns busy connections. Open 3327 // a new one, but wait until the busy connections are released 3328 // before returning control to DB. 3329 drv := db.driver.(*fakeDriver) 3330 drv.waitCh = make(chan struct{}, 1) 3331 drv.waitingCh = make(chan struct{}, 1) 3332 var wg sync.WaitGroup 3333 wg.Add(1) 3334 go func() { 3335 r, err := db.Query("SELECT|people|name|") 3336 if err != nil { 3337 t.Error(err) 3338 return 3339 } 3340 r.Close() 3341 wg.Done() 3342 }() 3343 // Wait until the goroutine we've just created has started waiting. 3344 <-drv.waitingCh 3345 // Now close the busy connections. This provides a connection for 3346 // the blocked goroutine and then fills up the idle queue. 3347 for _, v := range rows { 3348 v.Close() 3349 } 3350 // At this point we give the new connection to DB. This connection is 3351 // now useless, since the idle queue is full and there are no pending 3352 // requests. DB should deal with this situation without leaking the 3353 // connection. 3354 drv.waitCh <- struct{}{} 3355 wg.Wait() 3356 } 3357 3358 type nvcDriver struct { 3359 fakeDriver 3360 skipNamedValueCheck bool 3361 } 3362 3363 func (d *nvcDriver) Open(dsn string) (driver.Conn, error) { 3364 c, err := d.fakeDriver.Open(dsn) 3365 fc := c.(*fakeConn) 3366 fc.db.allowAny = true 3367 return &nvcConn{fc, d.skipNamedValueCheck}, err 3368 } 3369 3370 type nvcConn struct { 3371 *fakeConn 3372 skipNamedValueCheck bool 3373 } 3374 3375 type decimal struct { 3376 value int 3377 } 3378 3379 type doNotInclude struct{} 3380 3381 var _ driver.NamedValueChecker = &nvcConn{} 3382 3383 func (c *nvcConn) CheckNamedValue(nv *driver.NamedValue) error { 3384 if c.skipNamedValueCheck { 3385 return driver.ErrSkip 3386 } 3387 switch v := nv.Value.(type) { 3388 default: 3389 return driver.ErrSkip 3390 case Out: 3391 switch ov := v.Dest.(type) { 3392 default: 3393 return errors.New("unknown NameValueCheck OUTPUT type") 3394 case *string: 3395 *ov = "from-server" 3396 nv.Value = "OUT:*string" 3397 } 3398 return nil 3399 case decimal, []int64: 3400 return nil 3401 case doNotInclude: 3402 return driver.ErrRemoveArgument 3403 } 3404 } 3405 3406 func TestNamedValueChecker(t *testing.T) { 3407 Register("NamedValueCheck", &nvcDriver{}) 3408 db, err := Open("NamedValueCheck", "") 3409 if err != nil { 3410 t.Fatal(err) 3411 } 3412 defer db.Close() 3413 3414 ctx, cancel := context.WithCancel(context.Background()) 3415 defer cancel() 3416 3417 _, err = db.ExecContext(ctx, "WIPE") 3418 if err != nil { 3419 t.Fatal("exec wipe", err) 3420 } 3421 3422 _, err = db.ExecContext(ctx, "CREATE|keys|dec1=any,str1=string,out1=string,array1=any") 3423 if err != nil { 3424 t.Fatal("exec create", err) 3425 } 3426 3427 o1 := "" 3428 _, err = db.ExecContext(ctx, "INSERT|keys|dec1=?A,str1=?,out1=?O1,array1=?", Named("A", decimal{123}), "hello", Named("O1", Out{Dest: &o1}), []int64{42, 128, 707}, doNotInclude{}) 3429 if err != nil { 3430 t.Fatal("exec insert", err) 3431 } 3432 var ( 3433 str1 string 3434 dec1 decimal 3435 arr1 []int64 3436 ) 3437 err = db.QueryRowContext(ctx, "SELECT|keys|dec1,str1,array1|").Scan(&dec1, &str1, &arr1) 3438 if err != nil { 3439 t.Fatal("select", err) 3440 } 3441 3442 list := []struct{ got, want interface{} }{ 3443 {o1, "from-server"}, 3444 {dec1, decimal{123}}, 3445 {str1, "hello"}, 3446 {arr1, []int64{42, 128, 707}}, 3447 } 3448 3449 for index, item := range list { 3450 if !reflect.DeepEqual(item.got, item.want) { 3451 t.Errorf("got %#v wanted %#v for index %d", item.got, item.want, index) 3452 } 3453 } 3454 } 3455 3456 func TestNamedValueCheckerSkip(t *testing.T) { 3457 Register("NamedValueCheckSkip", &nvcDriver{skipNamedValueCheck: true}) 3458 db, err := Open("NamedValueCheckSkip", "") 3459 if err != nil { 3460 t.Fatal(err) 3461 } 3462 defer db.Close() 3463 3464 ctx, cancel := context.WithCancel(context.Background()) 3465 defer cancel() 3466 3467 _, err = db.ExecContext(ctx, "WIPE") 3468 if err != nil { 3469 t.Fatal("exec wipe", err) 3470 } 3471 3472 _, err = db.ExecContext(ctx, "CREATE|keys|dec1=any") 3473 if err != nil { 3474 t.Fatal("exec create", err) 3475 } 3476 3477 _, err = db.ExecContext(ctx, "INSERT|keys|dec1=?A", Named("A", decimal{123})) 3478 if err == nil { 3479 t.Fatalf("expected error with bad argument, got %v", err) 3480 } 3481 } 3482 3483 // badConn implements a bad driver.Conn, for TestBadDriver. 3484 // The Exec method panics. 3485 type badConn struct{} 3486 3487 func (bc badConn) Prepare(query string) (driver.Stmt, error) { 3488 return nil, errors.New("badConn Prepare") 3489 } 3490 3491 func (bc badConn) Close() error { 3492 return nil 3493 } 3494 3495 func (bc badConn) Begin() (driver.Tx, error) { 3496 return nil, errors.New("badConn Begin") 3497 } 3498 3499 func (bc badConn) Exec(query string, args []driver.Value) (driver.Result, error) { 3500 panic("badConn.Exec") 3501 } 3502 3503 // badDriver is a driver.Driver that uses badConn. 3504 type badDriver struct{} 3505 3506 func (bd badDriver) Open(name string) (driver.Conn, error) { 3507 return badConn{}, nil 3508 } 3509 3510 // Issue 15901. 3511 func TestBadDriver(t *testing.T) { 3512 Register("bad", badDriver{}) 3513 db, err := Open("bad", "ignored") 3514 if err != nil { 3515 t.Fatal(err) 3516 } 3517 defer func() { 3518 if r := recover(); r == nil { 3519 t.Error("expected panic") 3520 } else { 3521 if want := "badConn.Exec"; r.(string) != want { 3522 t.Errorf("panic was %v, expected %v", r, want) 3523 } 3524 } 3525 }() 3526 defer db.Close() 3527 db.Exec("ignored") 3528 } 3529 3530 type pingDriver struct { 3531 fails bool 3532 } 3533 3534 type pingConn struct { 3535 badConn 3536 driver *pingDriver 3537 } 3538 3539 var pingError = errors.New("Ping failed") 3540 3541 func (pc pingConn) Ping(ctx context.Context) error { 3542 if pc.driver.fails { 3543 return pingError 3544 } 3545 return nil 3546 } 3547 3548 var _ driver.Pinger = pingConn{} 3549 3550 func (pd *pingDriver) Open(name string) (driver.Conn, error) { 3551 return pingConn{driver: pd}, nil 3552 } 3553 3554 func TestPing(t *testing.T) { 3555 driver := &pingDriver{} 3556 Register("ping", driver) 3557 3558 db, err := Open("ping", "ignored") 3559 if err != nil { 3560 t.Fatal(err) 3561 } 3562 3563 if err := db.Ping(); err != nil { 3564 t.Errorf("err was %#v, expected nil", err) 3565 return 3566 } 3567 3568 driver.fails = true 3569 if err := db.Ping(); err != pingError { 3570 t.Errorf("err was %#v, expected pingError", err) 3571 } 3572 } 3573 3574 // Issue 18101. 3575 func TestTypedString(t *testing.T) { 3576 db := newTestDB(t, "people") 3577 defer closeDB(t, db) 3578 3579 type Str string 3580 var scanned Str 3581 3582 err := db.QueryRow("SELECT|people|name|name=?", "Alice").Scan(&scanned) 3583 if err != nil { 3584 t.Fatal(err) 3585 } 3586 expected := Str("Alice") 3587 if scanned != expected { 3588 t.Errorf("expected %+v, got %+v", expected, scanned) 3589 } 3590 } 3591 3592 func BenchmarkConcurrentDBExec(b *testing.B) { 3593 b.ReportAllocs() 3594 ct := new(concurrentDBExecTest) 3595 for i := 0; i < b.N; i++ { 3596 doConcurrentTest(b, ct) 3597 } 3598 } 3599 3600 func BenchmarkConcurrentStmtQuery(b *testing.B) { 3601 b.ReportAllocs() 3602 ct := new(concurrentStmtQueryTest) 3603 for i := 0; i < b.N; i++ { 3604 doConcurrentTest(b, ct) 3605 } 3606 } 3607 3608 func BenchmarkConcurrentStmtExec(b *testing.B) { 3609 b.ReportAllocs() 3610 ct := new(concurrentStmtExecTest) 3611 for i := 0; i < b.N; i++ { 3612 doConcurrentTest(b, ct) 3613 } 3614 } 3615 3616 func BenchmarkConcurrentTxQuery(b *testing.B) { 3617 b.ReportAllocs() 3618 ct := new(concurrentTxQueryTest) 3619 for i := 0; i < b.N; i++ { 3620 doConcurrentTest(b, ct) 3621 } 3622 } 3623 3624 func BenchmarkConcurrentTxExec(b *testing.B) { 3625 b.ReportAllocs() 3626 ct := new(concurrentTxExecTest) 3627 for i := 0; i < b.N; i++ { 3628 doConcurrentTest(b, ct) 3629 } 3630 } 3631 3632 func BenchmarkConcurrentTxStmtQuery(b *testing.B) { 3633 b.ReportAllocs() 3634 ct := new(concurrentTxStmtQueryTest) 3635 for i := 0; i < b.N; i++ { 3636 doConcurrentTest(b, ct) 3637 } 3638 } 3639 3640 func BenchmarkConcurrentTxStmtExec(b *testing.B) { 3641 b.ReportAllocs() 3642 ct := new(concurrentTxStmtExecTest) 3643 for i := 0; i < b.N; i++ { 3644 doConcurrentTest(b, ct) 3645 } 3646 } 3647 3648 func BenchmarkConcurrentRandom(b *testing.B) { 3649 b.ReportAllocs() 3650 ct := new(concurrentRandomTest) 3651 for i := 0; i < b.N; i++ { 3652 doConcurrentTest(b, ct) 3653 } 3654 } 3655 3656 func BenchmarkManyConcurrentQueries(b *testing.B) { 3657 b.ReportAllocs() 3658 // To see lock contention in Go 1.4, 16~ cores and 128~ goroutines are required. 3659 const parallelism = 16 3660 3661 db := newTestDB(b, "magicquery") 3662 defer closeDB(b, db) 3663 db.SetMaxIdleConns(runtime.GOMAXPROCS(0) * parallelism) 3664 3665 stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?") 3666 if err != nil { 3667 b.Fatal(err) 3668 } 3669 defer stmt.Close() 3670 3671 b.SetParallelism(parallelism) 3672 b.RunParallel(func(pb *testing.PB) { 3673 for pb.Next() { 3674 rows, err := stmt.Query("sleep", 1) 3675 if err != nil { 3676 b.Error(err) 3677 return 3678 } 3679 rows.Close() 3680 } 3681 }) 3682 }