Skip to content

Commit

Permalink
database/sql: add NullTime
Browse files Browse the repository at this point in the history
This matches NullBool, NullFloat64, and NullInt64.

Fixes #30305

Change-Id: I79bfcf04a3d43b965d2a3159b0ac22f3e8084a53
Reviewed-on: https://go-review.googlesource.com/c/go/+/170699
Run-TryBot: Daniel Theophanes <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Brad Fitzpatrick <[email protected]>
  • Loading branch information
kardianos committed Apr 5, 2019
1 parent c7a4099 commit d47da94
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/database/sql/fakedb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1158,7 +1158,9 @@ func converterForType(typ string) driver.ValueConverter {
// TODO(coopernurse): add type-specific converter
return driver.Null{Converter: driver.DefaultParameterConverter}
case "datetime":
return driver.DefaultParameterConverter
return driver.NotNull{Converter: driver.DefaultParameterConverter}
case "nulldatetime":
return driver.Null{Converter: driver.DefaultParameterConverter}
case "any":
return anyTypeConverter{}
}
Expand Down
26 changes: 26 additions & 0 deletions src/database/sql/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,32 @@ func (n NullBool) Value() (driver.Value, error) {
return n.Bool, nil
}

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

// Scan implements the Scanner interface.
func (n *NullTime) Scan(value interface{}) error {
if value == nil {
n.Time, n.Valid = time.Time{}, false
return nil
}
n.Valid = true

This comment has been minimized.

Copy link
@kolkov

kolkov Aug 30, 2019

NullTime is true if assertion is failed: for example Scan(int64(42))
error is "unsupported Scan, storing driver.Value type int64 into type *time.Time", but time is already true.
Is this good?

This comment has been minimized.

Copy link
@ianlancetaylor

ianlancetaylor Aug 30, 2019

Member

We don't use GitHub for code review, so very few people see these comments. If you want to comment on the change, please comment on https://golang.org/cl/170699 instead, or if you think this is a bug then open an issue at https://golang.org/issue. Thanks.

(I don't know the answer to your question.)

return convertAssign(&n.Time, value)
}

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

// Scanner is an interface used by Scan.
type Scanner interface {
// Scan assigns a value from a database driver.
Expand Down
15 changes: 15 additions & 0 deletions src/database/sql/sql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1695,6 +1695,21 @@ func TestNullBoolParam(t *testing.T) {
nullTestRun(t, spec)
}

func TestNullTimeParam(t *testing.T) {
t0 := time.Time{}
t1 := time.Date(2000, 1, 1, 8, 9, 10, 11, time.UTC)
t2 := time.Date(2010, 1, 1, 8, 9, 10, 11, time.UTC)
spec := nullTestSpec{"nulldatetime", "datetime", [6]nullTestRow{
{NullTime{t1, true}, t2, NullTime{t1, true}},
{NullTime{t1, false}, t2, NullTime{t0, false}},
{t1, t2, NullTime{t1, true}},
{NullTime{t1, true}, t2, NullTime{t1, true}},
{NullTime{t1, false}, t2, NullTime{t0, false}},
{t2, NullTime{t1, false}, nil},
}}
nullTestRun(t, spec)
}

func nullTestRun(t *testing.T, spec nullTestSpec) {
db := newTestDB(t, "")
defer closeDB(t, db)
Expand Down

0 comments on commit d47da94

Please sign in to comment.