Skip to content

Commit

Permalink
database/sql: Add Null[T]
Browse files Browse the repository at this point in the history
Generic version of NullString, NullInt64, etc.

Fix #60370
  • Loading branch information
methane committed Jun 8, 2023
1 parent b9baf44 commit 2c642df
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/database/sql/sql.go
Expand Up @@ -391,6 +391,44 @@ func (n NullTime) Value() (driver.Value, error) {
return n.Time, nil
}

// Null represents a value that may be null.
// Null implements the Scanner interface so
// it can be used as a scan destination:
//
// var s Null[string]
// err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s)
// ...
// if s.Valid {
// // use s.String
// } else {
// // NULL value
// }

type Null[T any] struct {
X T
Valid bool
}

func (n *Null[T]) Scan(value any) error {
n.Valid = false
if value == nil {
n.X = *new(T)
return nil
}
err := convertAssign(&n.X, value)
if err == nil {
n.Valid = true
}
return err
}

func (n Null[T]) Value() (driver.Value, error) {
if !n.Valid {
return nil, nil
}
return n.X, nil
}

// Scanner is an interface used by Scan.
type Scanner interface {
// Scan assigns a value from a database driver.
Expand Down
10 changes: 10 additions & 0 deletions src/database/sql/sql_test.go
Expand Up @@ -1801,6 +1801,16 @@ func TestNullStringParam(t *testing.T) {
{"foo", NullString{"black", false}, nil},
}}
nullTestRun(t, spec)

genericSpec := nullTestSpec{"nullstring", "string", [6]nullTestRow{
{Null[string]{"aqua", true}, "", Null[string]{"aqua", true}},
{Null[string]{"brown", false}, "", Null[string]{"", false}},
{"chartreuse", "", Null[string]{"chartreuse", true}},
{Null[string]{"darkred", true}, "", Null[string]{"darkred", true}},
{Null[string]{"eel", false}, "", Null[string]{"", false}},
{"foo", Null[string]{"black", false}, nil},
}}
nullTestRun(t, genericSpec)
}

func TestNullInt64Param(t *testing.T) {
Expand Down

0 comments on commit 2c642df

Please sign in to comment.