driver_test.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047
  1. package mysql
  2. import (
  3. "database/sql"
  4. "fmt"
  5. "io"
  6. "io/ioutil"
  7. "net"
  8. "os"
  9. "strings"
  10. "testing"
  11. "time"
  12. )
  13. var (
  14. charset string
  15. dsn string
  16. netAddr string
  17. available bool
  18. )
  19. // See https://github.com/go-sql-driver/mysql/wiki/Testing
  20. func init() {
  21. env := func(key, defaultValue string) string {
  22. if value := os.Getenv(key); value != "" {
  23. return value
  24. }
  25. return defaultValue
  26. }
  27. user := env("MYSQL_TEST_USER", "root")
  28. pass := env("MYSQL_TEST_PASS", "")
  29. prot := env("MYSQL_TEST_PROT", "tcp")
  30. addr := env("MYSQL_TEST_ADDR", "localhost:3306")
  31. dbname := env("MYSQL_TEST_DBNAME", "gotest")
  32. charset = "charset=utf8"
  33. netAddr = fmt.Sprintf("%s(%s)", prot, addr)
  34. dsn = fmt.Sprintf("%s:%s@%s/%s?timeout=30s&"+charset, user, pass, netAddr, dbname)
  35. c, err := net.Dial(prot, addr)
  36. if err == nil {
  37. available = true
  38. c.Close()
  39. }
  40. }
  41. func TestCharset(t *testing.T) {
  42. mustSetCharset := func(charsetParam, expected string) {
  43. db, err := sql.Open("mysql", strings.Replace(dsn, charset, charsetParam, 1))
  44. if err != nil {
  45. t.Fatalf("Error on Open: %v", err)
  46. }
  47. defer db.Close()
  48. dbt := &DBTest{t, db}
  49. rows := dbt.mustQuery("SELECT @@character_set_connection")
  50. defer rows.Close()
  51. if !rows.Next() {
  52. dbt.Fatalf("Error getting connection charset: %v", err)
  53. }
  54. var got string
  55. rows.Scan(&got)
  56. if got != expected {
  57. dbt.Fatalf("Expected connection charset %s but got %s", expected, got)
  58. }
  59. }
  60. if !available {
  61. t.Logf("MySQL-Server not running on %s. Skipping TestCharset", netAddr)
  62. return
  63. }
  64. // non utf8 test
  65. mustSetCharset("charset=ascii", "ascii")
  66. // when the first charset is invalid, use the second
  67. mustSetCharset("charset=none,utf8", "utf8")
  68. // when the first charset is valid, use it
  69. mustSetCharset("charset=ascii,utf8", "ascii")
  70. mustSetCharset("charset=utf8,ascii", "utf8")
  71. }
  72. func TestFailingCharset(t *testing.T) {
  73. if !available {
  74. t.Logf("MySQL-Server not running on %s. Skipping TestFailingCharset", netAddr)
  75. return
  76. }
  77. db, err := sql.Open("mysql", strings.Replace(dsn, charset, "charset=none", 1))
  78. if err != nil {
  79. t.Fatalf("Error on Open: %v", err)
  80. }
  81. defer db.Close()
  82. // run query to really establish connection...
  83. _, err = db.Exec("SELECT 1")
  84. if err == nil {
  85. db.Close()
  86. t.Fatalf("Connection must not succeed without a valid charset")
  87. }
  88. }
  89. type DBTest struct {
  90. *testing.T
  91. *sql.DB
  92. }
  93. func runTests(t *testing.T, name string, tests ...func(db *DBTest)) {
  94. if !available {
  95. t.Logf("MySQL-Server not running on %s. Skipping %s", netAddr, name)
  96. return
  97. }
  98. db, err := sql.Open("mysql", dsn)
  99. if err != nil {
  100. t.Fatalf("Error connecting: %v", err)
  101. }
  102. defer db.Close()
  103. environment := &DBTest{t, db}
  104. environment.mustExec("DROP TABLE IF EXISTS test")
  105. for _, test := range tests {
  106. test(environment)
  107. }
  108. environment.mustExec("DROP TABLE IF EXISTS test")
  109. }
  110. func args(args ...interface{}) []interface{} {
  111. return args
  112. }
  113. func (dbt *DBTest) fail(method, query string, err error) {
  114. if len(query) > 300 {
  115. query = "[query too large to print]"
  116. }
  117. dbt.Fatalf("Error on %s %s: %v", method, query, err)
  118. }
  119. func (dbt *DBTest) execWithArgs(query string, args []interface{}, test func(res sql.Result)) {
  120. res, err := dbt.Exec(query, args...)
  121. if err != nil {
  122. dbt.fail("Exec", query, err)
  123. }
  124. test(res)
  125. }
  126. func (dbt *DBTest) exec(query string, test func(result sql.Result)) {
  127. dbt.execWithArgs(query, args(), test)
  128. }
  129. func (dbt *DBTest) queryWithArgs(query string, args []interface{}, test func(rows *sql.Rows)) {
  130. rows, err := dbt.Query(query, args...)
  131. if err != nil {
  132. dbt.fail("Query", query, err)
  133. }
  134. defer rows.Close()
  135. test(rows)
  136. }
  137. func (dbt *DBTest) query(query string, test func(result *sql.Rows)) {
  138. dbt.queryWithArgs(query, args(), test)
  139. }
  140. func (dbt *DBTest) mustExec(query string, args ...interface{}) (res sql.Result) {
  141. res, err := dbt.Exec(query, args...)
  142. if err != nil {
  143. if len(query) > 300 {
  144. query = "[query too large to print]"
  145. }
  146. dbt.Fatalf("Error on Exec %s: %v", query, err)
  147. }
  148. return res
  149. }
  150. func (dbt *DBTest) mustQuery(query string, args ...interface{}) (rows *sql.Rows) {
  151. rows, err := dbt.Query(query, args...)
  152. if err != nil {
  153. if len(query) > 300 {
  154. query = "[query too large to print]"
  155. }
  156. dbt.Fatalf("Error on Query %s: %v", query, err)
  157. }
  158. return rows
  159. }
  160. func TestRawBytesResultExceedsBuffer(t *testing.T) {
  161. runTests(t, "TestRawBytesResultExceedsBuffer", _rawBytesResultExceedsBuffer)
  162. }
  163. func TestCRUD(t *testing.T) {
  164. runTests(t, "TestCRUD", _crud)
  165. }
  166. func _rawBytesResultExceedsBuffer(db *DBTest) {
  167. // defaultBufSize from buffer.go
  168. expected := strings.Repeat("abc", defaultBufSize)
  169. db.query("SELECT '"+expected+"'", func(rows *sql.Rows) {
  170. if !rows.Next() {
  171. db.Error("expected result, got none")
  172. }
  173. var result sql.RawBytes
  174. rows.Scan(&result)
  175. if expected != string(result) {
  176. db.Error("result did not match expected value")
  177. }
  178. })
  179. }
  180. func _crud(db *DBTest) {
  181. // Create Table
  182. db.mustExec("CREATE TABLE test (value BOOL)")
  183. // Test for unexpected data
  184. var out bool
  185. rows := db.mustQuery("SELECT * FROM test")
  186. if rows.Next() {
  187. db.Error("unexpected data in empty table")
  188. }
  189. // Create Data
  190. res := db.mustExec("INSERT INTO test VALUES (1)")
  191. count, err := res.RowsAffected()
  192. if err != nil {
  193. db.Fatalf("res.RowsAffected() returned error: %v", err)
  194. }
  195. if count != 1 {
  196. db.Fatalf("Expected 1 affected row, got %d", count)
  197. }
  198. id, err := res.LastInsertId()
  199. if err != nil {
  200. db.Fatalf("res.LastInsertId() returned error: %v", err)
  201. }
  202. if id != 0 {
  203. db.Fatalf("Expected InsertID 0, got %d", id)
  204. }
  205. // Read
  206. rows = db.mustQuery("SELECT value FROM test")
  207. if rows.Next() {
  208. rows.Scan(&out)
  209. if true != out {
  210. db.Errorf("true != %t", out)
  211. }
  212. if rows.Next() {
  213. db.Error("unexpected data")
  214. }
  215. } else {
  216. db.Error("no data")
  217. }
  218. // Update
  219. res = db.mustExec("UPDATE test SET value = ? WHERE value = ?", false, true)
  220. count, err = res.RowsAffected()
  221. if err != nil {
  222. db.Fatalf("res.RowsAffected() returned error: %v", err)
  223. }
  224. if count != 1 {
  225. db.Fatalf("Expected 1 affected row, got %d", count)
  226. }
  227. // Check Update
  228. rows = db.mustQuery("SELECT value FROM test")
  229. if rows.Next() {
  230. rows.Scan(&out)
  231. if false != out {
  232. db.Errorf("false != %t", out)
  233. }
  234. if rows.Next() {
  235. db.Error("unexpected data")
  236. }
  237. } else {
  238. db.Error("no data")
  239. }
  240. // Delete
  241. res = db.mustExec("DELETE FROM test WHERE value = ?", false)
  242. count, err = res.RowsAffected()
  243. if err != nil {
  244. db.Fatalf("res.RowsAffected() returned error: %v", err)
  245. }
  246. if count != 1 {
  247. db.Fatalf("Expected 1 affected row, got %d", count)
  248. }
  249. // Check for unexpected rows
  250. res = db.mustExec("DELETE FROM test")
  251. count, err = res.RowsAffected()
  252. if err != nil {
  253. db.Fatalf("res.RowsAffected() returned error: %v", err)
  254. }
  255. if count != 0 {
  256. db.Fatalf("Expected 0 affected row, got %d", count)
  257. }
  258. }
  259. func TestInt(t *testing.T) {
  260. runTests(t, "TestInt", _int)
  261. }
  262. func _int(db *DBTest) {
  263. types := [5]string{"TINYINT", "SMALLINT", "MEDIUMINT", "INT", "BIGINT"}
  264. in := int64(42)
  265. var out int64
  266. var rows *sql.Rows
  267. // SIGNED
  268. for _, v := range types {
  269. db.mustExec("CREATE TABLE test (value " + v + ")")
  270. db.mustExec("INSERT INTO test VALUES (?)", in)
  271. rows = db.mustQuery("SELECT value FROM test")
  272. if rows.Next() {
  273. rows.Scan(&out)
  274. if in != out {
  275. db.Errorf("%s: %d != %d", v, in, out)
  276. }
  277. } else {
  278. db.Errorf("%s: no data", v)
  279. }
  280. db.mustExec("DROP TABLE IF EXISTS test")
  281. }
  282. // UNSIGNED ZEROFILL
  283. for _, v := range types {
  284. db.mustExec("CREATE TABLE test (value " + v + " ZEROFILL)")
  285. db.mustExec("INSERT INTO test VALUES (?)", in)
  286. rows = db.mustQuery("SELECT value FROM test")
  287. if rows.Next() {
  288. rows.Scan(&out)
  289. if in != out {
  290. db.Errorf("%s ZEROFILL: %d != %d", v, in, out)
  291. }
  292. } else {
  293. db.Errorf("%s ZEROFILL: no data", v)
  294. }
  295. db.mustExec("DROP TABLE IF EXISTS test")
  296. }
  297. }
  298. func TestFloat(t *testing.T) {
  299. runTests(t, "TestFloat", _float)
  300. }
  301. func _float(db *DBTest) {
  302. types := [2]string{"FLOAT", "DOUBLE"}
  303. in := float32(42.23)
  304. var out float32
  305. var rows *sql.Rows
  306. for _, v := range types {
  307. db.mustExec("CREATE TABLE test (value " + v + ")")
  308. db.mustExec("INSERT INTO test VALUES (?)", in)
  309. rows = db.mustQuery("SELECT value FROM test")
  310. if rows.Next() {
  311. rows.Scan(&out)
  312. if in != out {
  313. db.Errorf("%s: %g != %g", v, in, out)
  314. }
  315. } else {
  316. db.Errorf("%s: no data", v)
  317. }
  318. db.mustExec("DROP TABLE IF EXISTS test")
  319. }
  320. }
  321. func TestString(t *testing.T) {
  322. runTests(t, "TestString", _string)
  323. }
  324. func _string(db *DBTest) {
  325. types := [6]string{"CHAR(255)", "VARCHAR(255)", "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT"}
  326. in := "κόσμε üöäßñóùéàâÿœ'îë Árvíztűrő いろはにほへとちりぬるを イロハニホヘト דג סקרן чащах น่าฟังเอย"
  327. var out string
  328. var rows *sql.Rows
  329. for _, v := range types {
  330. db.mustExec("CREATE TABLE test (value " + v + ") CHARACTER SET utf8 COLLATE utf8_unicode_ci")
  331. db.mustExec("INSERT INTO test VALUES (?)", in)
  332. rows = db.mustQuery("SELECT value FROM test")
  333. if rows.Next() {
  334. rows.Scan(&out)
  335. if in != out {
  336. db.Errorf("%s: %s != %s", v, in, out)
  337. }
  338. } else {
  339. db.Errorf("%s: no data", v)
  340. }
  341. db.mustExec("DROP TABLE IF EXISTS test")
  342. }
  343. // BLOB
  344. db.mustExec("CREATE TABLE test (id int, value BLOB) CHARACTER SET utf8 COLLATE utf8_unicode_ci")
  345. id := 2
  346. in = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, " +
  347. "sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, " +
  348. "sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. " +
  349. "Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. " +
  350. "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, " +
  351. "sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, " +
  352. "sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. " +
  353. "Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
  354. db.mustExec("INSERT INTO test VALUES (?, ?)", id, in)
  355. err := db.QueryRow("SELECT value FROM test WHERE id = ?", id).Scan(&out)
  356. if err != nil {
  357. db.Fatalf("Error on BLOB-Query: %v", err)
  358. } else if out != in {
  359. db.Errorf("BLOB: %s != %s", in, out)
  360. }
  361. }
  362. func TestDateTime(t *testing.T) {
  363. type testmode struct {
  364. selectSuffix string
  365. args []interface{}
  366. }
  367. type timetest struct {
  368. in interface{}
  369. sOut string
  370. tOut time.Time
  371. tIsZero bool
  372. }
  373. type tester func(db *DBTest, rows *sql.Rows,
  374. test *timetest, sqltype, resulttype, mode string)
  375. type setup struct {
  376. vartype string
  377. dsnSuffix string
  378. test tester
  379. }
  380. var (
  381. date = time.Date(2012, 6, 14, 0, 0, 0, 0, time.UTC)
  382. dstring = "2012-06-14"
  383. datetime = time.Date(2011, 11, 20, 21, 27, 37, 0, time.UTC)
  384. dtstring = "2011-11-20 21:27:37"
  385. date0 = time.Time{}
  386. d0string = "0000-00-00"
  387. dt0string = "0000-00-00 00:00:00"
  388. modes = map[string]*testmode{
  389. "text": &testmode{"", args()},
  390. "binary": &testmode{" WHERE 1 = ?", args(1)},
  391. }
  392. timetests = map[string][]*timetest{
  393. "DATE": {
  394. {dstring, dstring, date, false},
  395. {d0string, d0string, date0, true},
  396. {date, dstring, date, false},
  397. {date0, d0string, date0, true},
  398. },
  399. "DATETIME": {
  400. {dtstring, dtstring, datetime, false},
  401. {dt0string, dt0string, date0, true},
  402. {datetime, dtstring, datetime, false},
  403. {date0, dt0string, date0, true},
  404. },
  405. }
  406. setups = []*setup{
  407. {"string", "&parseTime=false", func(
  408. db *DBTest, rows *sql.Rows, test *timetest, sqltype, resulttype, mode string) {
  409. var sOut string
  410. if err := rows.Scan(&sOut); err != nil {
  411. db.Errorf("%s (%s %s): %v",
  412. sqltype, resulttype, mode, err)
  413. } else if test.sOut != sOut {
  414. db.Errorf("%s (%s %s): %s != %s",
  415. sqltype, resulttype, mode,
  416. test.sOut, sOut)
  417. }
  418. }},
  419. {"time.Time", "&parseTime=true", func(
  420. db *DBTest, rows *sql.Rows, test *timetest, sqltype, resulttype, mode string) {
  421. var tOut time.Time
  422. if err := rows.Scan(&tOut); err != nil {
  423. db.Errorf("%s (%s %s): %v",
  424. sqltype, resulttype, mode, err)
  425. } else if test.tOut != tOut || test.tIsZero != tOut.IsZero() {
  426. db.Errorf("%s (%s %s): %s [%t] != %s [%t]",
  427. sqltype, resulttype, mode,
  428. test.tOut, test.tIsZero,
  429. tOut, tOut.IsZero())
  430. }
  431. }},
  432. }
  433. )
  434. var s *setup
  435. testTime := func(db *DBTest) {
  436. var rows *sql.Rows
  437. for sqltype, tests := range timetests {
  438. db.mustExec("DROP TABLE IF EXISTS test")
  439. db.mustExec("CREATE TABLE test (value " + sqltype + ") CHARACTER SET utf8 COLLATE utf8_unicode_ci")
  440. for _, test := range tests {
  441. for mode, q := range modes {
  442. db.mustExec("TRUNCATE test")
  443. db.mustExec("INSERT INTO test VALUES (?)", test.in)
  444. rows = db.mustQuery("SELECT value FROM test"+q.selectSuffix, q.args...)
  445. if rows.Next() {
  446. s.test(db, rows, test, sqltype, s.vartype, mode)
  447. } else {
  448. if err := rows.Err(); err != nil {
  449. db.Errorf("%s (%s %s): %v",
  450. sqltype, s.vartype, mode, err)
  451. } else {
  452. db.Errorf("%s (%s %s): no data",
  453. sqltype, s.vartype, mode)
  454. }
  455. }
  456. }
  457. }
  458. }
  459. }
  460. oldDsn := dsn
  461. usedDsn := oldDsn + "&sql_mode=ALLOW_INVALID_DATES"
  462. for _, v := range setups {
  463. s = v
  464. dsn = usedDsn + s.dsnSuffix
  465. runTests(t, "TestDateTime", testTime)
  466. }
  467. dsn = oldDsn
  468. }
  469. func TestNULL(t *testing.T) {
  470. runTests(t, "TestNULL", _null)
  471. }
  472. func _null(db *DBTest) {
  473. nullStmt, err := db.Prepare("SELECT NULL")
  474. if err != nil {
  475. db.Fatal(err)
  476. }
  477. defer nullStmt.Close()
  478. nonNullStmt, err := db.Prepare("SELECT 1")
  479. if err != nil {
  480. db.Fatal(err)
  481. }
  482. defer nonNullStmt.Close()
  483. // NullBool
  484. var nb sql.NullBool
  485. // Invalid
  486. err = nullStmt.QueryRow().Scan(&nb)
  487. if err != nil {
  488. db.Fatal(err)
  489. }
  490. if nb.Valid {
  491. db.Error("Valid NullBool which should be invalid")
  492. }
  493. // Valid
  494. err = nonNullStmt.QueryRow().Scan(&nb)
  495. if err != nil {
  496. db.Fatal(err)
  497. }
  498. if !nb.Valid {
  499. db.Error("Invalid NullBool which should be valid")
  500. } else if nb.Bool != true {
  501. db.Errorf("Unexpected NullBool value: %t (should be true)", nb.Bool)
  502. }
  503. // NullFloat64
  504. var nf sql.NullFloat64
  505. // Invalid
  506. err = nullStmt.QueryRow().Scan(&nf)
  507. if err != nil {
  508. db.Fatal(err)
  509. }
  510. if nf.Valid {
  511. db.Error("Valid NullFloat64 which should be invalid")
  512. }
  513. // Valid
  514. err = nonNullStmt.QueryRow().Scan(&nf)
  515. if err != nil {
  516. db.Fatal(err)
  517. }
  518. if !nf.Valid {
  519. db.Error("Invalid NullFloat64 which should be valid")
  520. } else if nf.Float64 != float64(1) {
  521. db.Errorf("Unexpected NullFloat64 value: %f (should be 1.0)", nf.Float64)
  522. }
  523. // NullInt64
  524. var ni sql.NullInt64
  525. // Invalid
  526. err = nullStmt.QueryRow().Scan(&ni)
  527. if err != nil {
  528. db.Fatal(err)
  529. }
  530. if ni.Valid {
  531. db.Error("Valid NullInt64 which should be invalid")
  532. }
  533. // Valid
  534. err = nonNullStmt.QueryRow().Scan(&ni)
  535. if err != nil {
  536. db.Fatal(err)
  537. }
  538. if !ni.Valid {
  539. db.Error("Invalid NullInt64 which should be valid")
  540. } else if ni.Int64 != int64(1) {
  541. db.Errorf("Unexpected NullInt64 value: %d (should be 1)", ni.Int64)
  542. }
  543. // NullString
  544. var ns sql.NullString
  545. // Invalid
  546. err = nullStmt.QueryRow().Scan(&ns)
  547. if err != nil {
  548. db.Fatal(err)
  549. }
  550. if ns.Valid {
  551. db.Error("Valid NullString which should be invalid")
  552. }
  553. // Valid
  554. err = nonNullStmt.QueryRow().Scan(&ns)
  555. if err != nil {
  556. db.Fatal(err)
  557. }
  558. if !ns.Valid {
  559. db.Error("Invalid NullString which should be valid")
  560. } else if ns.String != `1` {
  561. db.Error("Unexpected NullString value:" + ns.String + " (should be `1`)")
  562. }
  563. // Insert NULL
  564. db.mustExec("CREATE TABLE test (dummmy1 int, value int, dummy2 int)")
  565. db.mustExec("INSERT INTO test VALUES (?, ?, ?)", 1, nil, 2)
  566. var out interface{}
  567. rows := db.mustQuery("SELECT * FROM test")
  568. if rows.Next() {
  569. rows.Scan(&out)
  570. if out != nil {
  571. db.Errorf("%v != nil", out)
  572. }
  573. } else {
  574. db.Error("no data")
  575. }
  576. }
  577. func TestLongData(t *testing.T) {
  578. runTests(t, "TestLongData", _longData)
  579. }
  580. func _longData(db *DBTest) {
  581. var maxAllowedPacketSize int
  582. err := db.QueryRow("select @@max_allowed_packet").Scan(&maxAllowedPacketSize)
  583. if err != nil {
  584. db.Fatal(err)
  585. }
  586. maxAllowedPacketSize--
  587. // don't get too ambitious
  588. if maxAllowedPacketSize > 1<<25 {
  589. maxAllowedPacketSize = 1 << 25
  590. }
  591. db.mustExec("CREATE TABLE test (value LONGBLOB) CHARACTER SET utf8 COLLATE utf8_unicode_ci")
  592. in := strings.Repeat(`0`, maxAllowedPacketSize+1)
  593. var out string
  594. var rows *sql.Rows
  595. // Long text data
  596. const nonDataQueryLen = 28 // length query w/o value
  597. inS := in[:maxAllowedPacketSize-nonDataQueryLen]
  598. db.mustExec("INSERT INTO test VALUES('" + inS + "')")
  599. rows = db.mustQuery("SELECT value FROM test")
  600. if rows.Next() {
  601. rows.Scan(&out)
  602. if inS != out {
  603. db.Fatalf("LONGBLOB: length in: %d, length out: %d", len(inS), len(out))
  604. }
  605. if rows.Next() {
  606. db.Error("LONGBLOB: unexpexted row")
  607. }
  608. } else {
  609. db.Fatalf("LONGBLOB: no data")
  610. }
  611. // Empty table
  612. db.mustExec("TRUNCATE TABLE test")
  613. // Long binary data
  614. db.mustExec("INSERT INTO test VALUES(?)", in)
  615. rows = db.mustQuery("SELECT value FROM test WHERE 1=?", 1)
  616. if rows.Next() {
  617. rows.Scan(&out)
  618. if in != out {
  619. db.Fatalf("LONGBLOB: length in: %d, length out: %d", len(in), len(out))
  620. }
  621. if rows.Next() {
  622. db.Error("LONGBLOB: unexpexted row")
  623. }
  624. } else {
  625. db.Fatalf("LONGBLOB: no data")
  626. }
  627. }
  628. func TestLoadData(t *testing.T) {
  629. runTests(t, "TestLoadData", _loadData)
  630. }
  631. func _loadData(db *DBTest) {
  632. verifyLoadDataResult := func() {
  633. rows, err := db.Query("SELECT * FROM test")
  634. if err != nil {
  635. db.Fatal(err.Error())
  636. }
  637. i := 0
  638. values := [4]string{
  639. "a string",
  640. "a string containing a \t",
  641. "a string containing a \n",
  642. "a string containing both \t\n",
  643. }
  644. var id int
  645. var value string
  646. for rows.Next() {
  647. i++
  648. err = rows.Scan(&id, &value)
  649. if err != nil {
  650. db.Fatal(err.Error())
  651. }
  652. if i != id {
  653. db.Fatalf("%d != %d", i, id)
  654. }
  655. if values[i-1] != value {
  656. db.Fatalf("%s != %s", values[i-1], value)
  657. }
  658. }
  659. err = rows.Err()
  660. if err != nil {
  661. db.Fatal(err.Error())
  662. }
  663. if i != 4 {
  664. db.Fatalf("Rows count mismatch. Got %d, want 4", i)
  665. }
  666. }
  667. file, err := ioutil.TempFile("", "gotest")
  668. defer os.Remove(file.Name())
  669. if err != nil {
  670. db.Fatal(err)
  671. }
  672. file.WriteString("1\ta string\n2\ta string containing a \\t\n3\ta string containing a \\n\n4\ta string containing both \\t\\n\n")
  673. file.Close()
  674. db.mustExec("DROP TABLE IF EXISTS test")
  675. db.mustExec("CREATE TABLE test (id INT NOT NULL PRIMARY KEY, value TEXT NOT NULL) CHARACTER SET utf8 COLLATE utf8_unicode_ci")
  676. // Local File
  677. RegisterLocalFile(file.Name())
  678. db.mustExec(fmt.Sprintf("LOAD DATA LOCAL INFILE '%q' INTO TABLE test", file.Name()))
  679. verifyLoadDataResult()
  680. // negative test
  681. _, err = db.Exec("LOAD DATA LOCAL INFILE 'doesnotexist' INTO TABLE test")
  682. if err == nil {
  683. db.Fatal("Load non-existent file didn't fail")
  684. } else if err.Error() != "Local File 'doesnotexist' is not registered. Use the DSN parameter 'allowAllFiles=true' to allow all files" {
  685. db.Fatal(err.Error())
  686. }
  687. // Empty table
  688. db.mustExec("TRUNCATE TABLE test")
  689. // Reader
  690. RegisterReaderHandler("test", func() io.Reader {
  691. file, err = os.Open(file.Name())
  692. if err != nil {
  693. db.Fatal(err)
  694. }
  695. return file
  696. })
  697. db.mustExec("LOAD DATA LOCAL INFILE 'Reader::test' INTO TABLE test")
  698. verifyLoadDataResult()
  699. // negative test
  700. _, err = db.Exec("LOAD DATA LOCAL INFILE 'Reader::doesnotexist' INTO TABLE test")
  701. if err == nil {
  702. db.Fatal("Load non-existent Reader didn't fail")
  703. } else if err.Error() != "Reader 'doesnotexist' is not registered" {
  704. db.Fatal(err.Error())
  705. }
  706. }
  707. // Special cases
  708. func TestRowsClose(t *testing.T) {
  709. runTests(t, "TestRowsClose", _rowsClose)
  710. }
  711. func _rowsClose(db *DBTest) {
  712. rows, err := db.Query("SELECT 1")
  713. if err != nil {
  714. db.Fatal(err)
  715. }
  716. err = rows.Close()
  717. if err != nil {
  718. db.Fatal(err)
  719. }
  720. if rows.Next() {
  721. db.Fatal("Unexpected row after rows.Close()")
  722. }
  723. err = rows.Err()
  724. if err != nil {
  725. db.Fatal(err)
  726. }
  727. }
  728. // dangling statements
  729. // http://code.google.com/p/go/issues/detail?id=3865
  730. func TestCloseStmtBeforeRows(t *testing.T) {
  731. runTests(t, "TestCloseStmtBeforeRows", _closeStmtBeforeRows)
  732. }
  733. func _closeStmtBeforeRows(db *DBTest) {
  734. stmt, err := db.Prepare("SELECT 1")
  735. if err != nil {
  736. db.Fatal(err)
  737. }
  738. rows, err := stmt.Query()
  739. if err != nil {
  740. stmt.Close()
  741. db.Fatal(err)
  742. }
  743. defer rows.Close()
  744. err = stmt.Close()
  745. if err != nil {
  746. db.Fatal(err)
  747. }
  748. if !rows.Next() {
  749. db.Fatal("Getting row failed")
  750. } else {
  751. err = rows.Err()
  752. if err != nil {
  753. db.Fatal(err)
  754. }
  755. var out bool
  756. err = rows.Scan(&out)
  757. if err != nil {
  758. db.Fatalf("Error on rows.Scan(): %v", err)
  759. }
  760. if out != true {
  761. db.Errorf("true != %t", out)
  762. }
  763. }
  764. }
  765. // It is valid to have multiple Rows for the same Stmt
  766. // http://code.google.com/p/go/issues/detail?id=3734
  767. func TestStmtMultiRows(t *testing.T) {
  768. runTests(t, "TestStmtMultiRows", _stmtMultiRows)
  769. }
  770. func _stmtMultiRows(db *DBTest) {
  771. stmt, err := db.Prepare("SELECT 1 UNION SELECT 0")
  772. if err != nil {
  773. db.Fatal(err)
  774. }
  775. rows1, err := stmt.Query()
  776. if err != nil {
  777. stmt.Close()
  778. db.Fatal(err)
  779. }
  780. defer rows1.Close()
  781. rows2, err := stmt.Query()
  782. if err != nil {
  783. stmt.Close()
  784. db.Fatal(err)
  785. }
  786. defer rows2.Close()
  787. var out bool
  788. // 1
  789. if !rows1.Next() {
  790. db.Fatal("1st rows1.Next failed")
  791. } else {
  792. err = rows1.Err()
  793. if err != nil {
  794. db.Fatal(err)
  795. }
  796. err = rows1.Scan(&out)
  797. if err != nil {
  798. db.Fatalf("Error on rows.Scan(): %v", err)
  799. }
  800. if out != true {
  801. db.Errorf("true != %t", out)
  802. }
  803. }
  804. if !rows2.Next() {
  805. db.Fatal("1st rows2.Next failed")
  806. } else {
  807. err = rows2.Err()
  808. if err != nil {
  809. db.Fatal(err)
  810. }
  811. err = rows2.Scan(&out)
  812. if err != nil {
  813. db.Fatalf("Error on rows.Scan(): %v", err)
  814. }
  815. if out != true {
  816. db.Errorf("true != %t", out)
  817. }
  818. }
  819. // 2
  820. if !rows1.Next() {
  821. db.Fatal("2nd rows1.Next failed")
  822. } else {
  823. err = rows1.Err()
  824. if err != nil {
  825. db.Fatal(err)
  826. }
  827. err = rows1.Scan(&out)
  828. if err != nil {
  829. db.Fatalf("Error on rows.Scan(): %v", err)
  830. }
  831. if out != false {
  832. db.Errorf("false != %t", out)
  833. }
  834. if rows1.Next() {
  835. db.Fatal("Unexpected row on rows1")
  836. }
  837. err = rows1.Close()
  838. if err != nil {
  839. db.Fatal(err)
  840. }
  841. }
  842. if !rows2.Next() {
  843. db.Fatal("2nd rows2.Next failed")
  844. } else {
  845. err = rows2.Err()
  846. if err != nil {
  847. db.Fatal(err)
  848. }
  849. err = rows2.Scan(&out)
  850. if err != nil {
  851. db.Fatalf("Error on rows.Scan(): %v", err)
  852. }
  853. if out != false {
  854. db.Errorf("false != %t", out)
  855. }
  856. if rows2.Next() {
  857. db.Fatal("Unexpected row on rows2")
  858. }
  859. err = rows2.Close()
  860. if err != nil {
  861. db.Fatal(err)
  862. }
  863. }
  864. }
  865. func TestConcurrent(t *testing.T) {
  866. if os.Getenv("MYSQL_TEST_CONCURRENT") != "1" {
  867. t.Log("CONCURRENT env var not set. Skipping TestConcurrent")
  868. return
  869. }
  870. runTests(t, "TestConcurrent", _concurrent)
  871. }
  872. func _concurrent(db *DBTest) {
  873. var max int
  874. err := db.QueryRow("SELECT @@max_connections").Scan(&max)
  875. if err != nil {
  876. db.Fatalf("%v", err)
  877. }
  878. db.Logf("Testing up to %d concurrent connections \r\n", max)
  879. canStop := false
  880. c := make(chan struct{}, max)
  881. for i := 0; i < max; i++ {
  882. go func(id int) {
  883. tx, err := db.Begin()
  884. if err != nil {
  885. canStop = true
  886. if err.Error() == "Error 1040: Too many connections" {
  887. max--
  888. return
  889. } else {
  890. db.Fatalf("Error on Con %d: %s", id, err.Error())
  891. }
  892. }
  893. c <- struct{}{}
  894. for !canStop {
  895. _, err = tx.Exec("SELECT 1")
  896. if err != nil {
  897. canStop = true
  898. db.Fatalf("Error on Con %d: %s", id, err.Error())
  899. }
  900. }
  901. err = tx.Commit()
  902. if err != nil {
  903. canStop = true
  904. db.Fatalf("Error on Con %d: %s", id, err.Error())
  905. }
  906. }(i)
  907. }
  908. for i := 0; i < max; i++ {
  909. <-c
  910. }
  911. canStop = true
  912. db.Logf("Reached %d concurrent connections \r\n", max)
  913. }