Skip to content

Commit

Permalink
database/sql: add NullInt32
Browse files Browse the repository at this point in the history
It is common for database integers to be represented as int32
internally. Although NullInt64 is already defined,
this should remove some type casts and make working with those eaiser.

For #31231

Change-Id: Ia0c37ecef035fee0734c1d1fb6f58aef6905cf5e
Reviewed-on: https://go-review.googlesource.com/c/go/+/174178
Run-TryBot: Daniel Theophanes <kardianos@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
  • Loading branch information
kardianos committed Apr 26, 2019
1 parent 8ef45cf commit 2177bfb
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/database/sql/fakedb_test.go
Expand Up @@ -1141,6 +1141,8 @@ func converterForType(typ string) driver.ValueConverter {
return driver.Null{Converter: driver.Bool}
case "int32":
return driver.Int32
case "nullint32":
return driver.Null{Converter: driver.DefaultParameterConverter}
case "string":
return driver.NotNull{Converter: fakeDriverString{}}
case "nullstring":
Expand Down Expand Up @@ -1175,6 +1177,8 @@ func colTypeToReflectType(typ string) reflect.Type {
return reflect.TypeOf(NullBool{})
case "int32":
return reflect.TypeOf(int32(0))
case "nullint32":
return reflect.TypeOf(NullInt32{})
case "string":
return reflect.TypeOf("")
case "nullstring":
Expand Down
26 changes: 26 additions & 0 deletions src/database/sql/sql.go
Expand Up @@ -234,6 +234,32 @@ func (n NullInt64) Value() (driver.Value, error) {
return n.Int64, nil
}

// NullInt32 represents an int32 that may be null.
// NullInt32 implements the Scanner interface so
// it can be used as a scan destination, similar to NullString.
type NullInt32 struct {
Int32 int32
Valid bool // Valid is true if Int32 is not NULL
}

// Scan implements the Scanner interface.
func (n *NullInt32) Scan(value interface{}) error {
if value == nil {
n.Int32, n.Valid = 0, false
return nil
}
n.Valid = true
return convertAssign(&n.Int32, value)
}

// Value implements the driver Valuer interface.
func (n NullInt32) Value() (driver.Value, error) {
if !n.Valid {
return nil, nil
}
return int64(n.Int32), nil
}

// NullFloat64 represents a float64 that may be null.
// NullFloat64 implements the Scanner interface so
// it can be used as a scan destination, similar to NullString.
Expand Down
13 changes: 13 additions & 0 deletions src/database/sql/sql_test.go
Expand Up @@ -131,6 +131,7 @@ func TestDriverPanic(t *testing.T) {
}

func exec(t testing.TB, db *DB, query string, args ...interface{}) {
t.Helper()
_, err := db.Exec(query, args...)
if err != nil {
t.Fatalf("Exec of %q: %v", query, err)
Expand Down Expand Up @@ -1671,6 +1672,18 @@ func TestNullInt64Param(t *testing.T) {
nullTestRun(t, spec)
}

func TestNullInt32Param(t *testing.T) {
spec := nullTestSpec{"nullint32", "int32", [6]nullTestRow{
{NullInt32{31, true}, 1, NullInt32{31, true}},
{NullInt32{-22, false}, 1, NullInt32{0, false}},
{22, 1, NullInt32{22, true}},
{NullInt32{33, true}, 1, NullInt32{33, true}},
{NullInt32{222, false}, 1, NullInt32{0, false}},
{0, NullInt32{31, false}, nil},
}}
nullTestRun(t, spec)
}

func TestNullFloat64Param(t *testing.T) {
spec := nullTestSpec{"nullfloat64", "float64", [6]nullTestRow{
{NullFloat64{31.2, true}, 1, NullFloat64{31.2, true}},
Expand Down

0 comments on commit 2177bfb

Please sign in to comment.