Go言語からSQLを使うときは
Go言語からSQL(or SQL-like)データベースを使うときは、Go言語標準のsql - The Go Programming Languageが定めるinterfaceを実装したdriverを実際は使っています.
たとえばdriverはここに列挙されてたりします.
driverの違いによる挙動の違い
なるべく無いように作ってるとは思うんですが、今回PostgreSQLを使っていて、そのdriverであるlib/pq · GitHub、とメジャーなMySQL driverであるgo-sql-driver/mysql · GitHubの間に、CHAR
型、VARCHAR
型、TEXT
型の挙動の違いがあって、軽く「ガッデム!!」となったので備忘録.
MySQL driverの使うコード
package main import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" ) /* CREATE TABLE foo ( hoge CHAR(16), fuga VARCHAR(16), piyo TEXT ); */ func main() { db, _ := sql.Open("mysql", "/test") db.Exec( "INSERT INTO foo (hoge, fuga, piyo) VALUES (?, ?, ?)", "ほげ", "ふが", "ぴよ", ) var hoge, fuga, piyo string db.QueryRow( "SELECT hoge, fuga, piyo FROM foo LIMIT 1", ).Scan(&hoge, &fuga, &piyo) fmt.Printf("hoge: ^%s$\nfuga: ^%s$\npiyo: ^%s$\n", hoge, fuga, piyo) }
Postgres driverの使うコード
package main import ( "database/sql" "fmt" _ "github.com/lib/pq" ) /* CREATE TABLE foo ( hoge CHAR(16), fuga VARCHAR(16), piyo TEXT ); */ func main() { db, _ := sql.Open("postgres", "host=localhost dbname=test sslmode=disable") db.Exec( "INSERT INTO foo (hoge, fuga, piyo) VALUES ($1, $2, $3)", "ほげ", "ふが", "ぴよ", ) var hoge, fuga, piyo string db.QueryRow( "SELECT hoge, fuga, piyo FROM foo LIMIT 1", ).Scan(&hoge, &fuga, &piyo) fmt.Printf("hoge: ^%s$\nfuga: ^%s$\npiyo: ^%s$\n", hoge, fuga, piyo) }
その結果の違い
hoge: ^ほげ$ fuga: ^ふが$ piyo: ^ぴよ$
postgres
hoge: ^ほげ $ fuga: ^ふが$ piyo: ^ぴよ$
go-sql-driver/mysqlを使った方は、CHAR型であってもTrimして返しており、一方lib/pqはCHAR型は空白含めて返していることが分かります.
どちらがあるべき姿なんすかね.
雑感
- pq/hstore.go at 960f4898d8d3ee5e1f47a8422e9b23ac7bab129b · lib/pq · GitHub
- (ここに strings.Trim入れたらいいんかな...)