-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Closed
Description
I started with a structure like this:
DROP TABLE IF EXISTS `data_types`;
CREATE TABLE `data_types` (
`_time` time NOT NULL,
PRIMARY KEY (`id`)
);
Then I inserted a time value:
INSERT INTO `data_types` VALUES ('12:34:56');
In the client side (with Go), I used a string with a "?" condition to make a SELECT query, like this:
rows, err := db.Query(`SELECT _time FROM data_types WHERE id = ?`, 1)
Result was that every time I used a condition with "?", an extra 0x00 character was added to the beginning of the result column, making it 9 bytes long ("\x0012:23:56") instead of 8 bytes ("12:34:56") making the result different from the original time.
$ go run main.go
_time : [0 48 49 58 48 50 58 48 51]
-----------------------------------
I tracked the error down to packets.go
, the 0 at the beginning is just the value of the sign byte when data[pos] is not 1
.
1017 var sign byte
1018 if data[pos] == 1 {
1019 sign = byte('-')
1020 }
1021
1022 switch num {
1023 case 8:
1024 dest[i] = []byte(fmt.Sprintf(
1025 "%c%02d:%02d:%02d",
1026 sign,
Strangely enough, this bug does not appear if a don't use a condition with "?".
Full test code follows:
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, err := sql.Open("mysql", "test:test@unix(/var/run/mysqld/mysqld.sock)/tests")
if err != nil {
fmt.Println(err)
return
}
defer db.Close()
/*
Problem arises when we use conditions with '?' arguments.
*/
rows, err := db.Query(`SELECT _time FROM data_types WHERE id = ?`, 1)
/*
These conditions seem to work just fine.
*/
//rows, err := db.Query(`SELECT _time FROM data_types WHERE 1 = 1`)
//rows, err := db.Query(`SELECT _time FROM data_types`)
if err != nil {
fmt.Printf("%q: %s\n", err)
return
}
columns, err := rows.Columns()
if err != nil {
fmt.Printf("%q: %s\n", err)
return
}
values := make([]*sql.RawBytes, len(columns))
scanArgs := make([]interface{}, len(values))
for i := range values {
scanArgs[i] = &values[i]
}
/*
Expected output:
_time : [48 49 58 48 50 58 48 51]
-----------------------------------
*/
for rows.Next() {
err = rows.Scan(scanArgs...)
if err != nil {
panic(err.Error())
}
for i, col := range values {
if col != nil {
fmt.Println(columns[i], ": ", *col)
}
}
fmt.Println("-----------------------------------")
}
}
Metadata
Metadata
Assignees
Labels
No labels