Go's zero value for a bool type is false
. Postgres supports an undefined BOOL type, represented as NULL. This leads to problems when trying to fetch a BOOL value from Postgres in Go:
rows,err := db.Query("SELECT UNNEST('{TRUE,FALSE,NULL}'::BOOL[])");
if err != nil {
log.Fatal(err)
}
for rows.Next() {
var value bool
if err := rows.Scan(&value); err != nil {
log.Fatal(err)
}
fmt.Printf("Value: %t
",value);
}
Output:
Value: true
Value: false
2014/11/17 09:34:26 sql: Scan error on column index 0: sql/driver: couldn't convert <nil> (<nil>) into type bool
What's the most idiomatic way around this problem? The two solutions I have imagined are neither very attractive:
bool
type. Instead I would probably use a string, and do my own conversion which accounts for nil
COALESCE()
or some other means.My preference is using a pointer:
for rows.Next() {
var value *bool
if err := rows.Scan(&value); err != nil {
log.Fatal(err)
}
if value == nil {
// Handle nil
}
fmt.Printf("Value: %t
", *value);
}
See http://golang.org/pkg/database/sql/#NullBool in the standard library.
NullBool represents a bool that may be null. NullBool implements the Scanner interface so it can be used as a scan destination, similar to NullString.