diff options
| author | Ravi Sastry Kadali <ravisastryk@gmail.com> | 2026-01-25 18:29:30 -0800 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2026-02-06 12:10:59 -0800 |
| commit | 9263a71b92e84aa34d0e35887d5c23f5a0a21537 (patch) | |
| tree | 82d3b4c216b4d0b8ebaa8278e8fe916550d4e49e /src/database/sql/sql.go | |
| parent | 0430fa977573866f93e66aa61a66b37ff0738aba (diff) | |
| download | go-9263a71b92e84aa34d0e35887d5c23f5a0a21537.tar.xz | |
database/sql: ensure Null* types have Valid=false when Scan returns error
The Scan methods for NullString, NullInt64, NullInt32, NullFloat64,
NullBool, and NullTime set Valid=true before calling convertAssign.
If convertAssign returns an error, Valid remains true, which creates
an inconsistent state where Valid=true but err!=nil.
Fix by setting Valid only after successful conversion.
Fixes #45662
Change-Id: I855a20abbe517ed017f7c9b8f5603b17bd9d487d
Reviewed-on: https://go-review.googlesource.com/c/go/+/739160
Auto-Submit: Sean Liao <sean@liao.dev>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Sean Liao <sean@liao.dev>
Reviewed-by: Michael Pratt <mpratt@google.com>
Diffstat (limited to 'src/database/sql/sql.go')
| -rw-r--r-- | src/database/sql/sql.go | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go index 4be450ca87..c8ec91c1ec 100644 --- a/src/database/sql/sql.go +++ b/src/database/sql/sql.go @@ -202,8 +202,9 @@ func (ns *NullString) Scan(value any) error { ns.String, ns.Valid = "", false return nil } - ns.Valid = true - return convertAssign(&ns.String, value) + err := convertAssign(&ns.String, value) + ns.Valid = err == nil + return err } // Value implements the [driver.Valuer] interface. @@ -228,8 +229,9 @@ func (n *NullInt64) Scan(value any) error { n.Int64, n.Valid = 0, false return nil } - n.Valid = true - return convertAssign(&n.Int64, value) + err := convertAssign(&n.Int64, value) + n.Valid = err == nil + return err } // Value implements the [driver.Valuer] interface. @@ -254,8 +256,9 @@ func (n *NullInt32) Scan(value any) error { n.Int32, n.Valid = 0, false return nil } - n.Valid = true - return convertAssign(&n.Int32, value) + err := convertAssign(&n.Int32, value) + n.Valid = err == nil + return err } // Value implements the [driver.Valuer] interface. @@ -334,8 +337,9 @@ func (n *NullFloat64) Scan(value any) error { n.Float64, n.Valid = 0, false return nil } - n.Valid = true - return convertAssign(&n.Float64, value) + err := convertAssign(&n.Float64, value) + n.Valid = err == nil + return err } // Value implements the [driver.Valuer] interface. @@ -360,8 +364,9 @@ func (n *NullBool) Scan(value any) error { n.Bool, n.Valid = false, false return nil } - n.Valid = true - return convertAssign(&n.Bool, value) + err := convertAssign(&n.Bool, value) + n.Valid = err == nil + return err } // Value implements the [driver.Valuer] interface. @@ -386,8 +391,9 @@ func (n *NullTime) Scan(value any) error { n.Time, n.Valid = time.Time{}, false return nil } - n.Valid = true - return convertAssign(&n.Time, value) + err := convertAssign(&n.Time, value) + n.Valid = err == nil + return err } // Value implements the [driver.Valuer] interface. @@ -422,8 +428,9 @@ func (n *Null[T]) Scan(value any) error { n.V, n.Valid = *new(T), false return nil } - n.Valid = true - return convertAssign(&n.V, value) + err := convertAssign(&n.V, value) + n.Valid = err == nil + return err } func (n Null[T]) Value() (driver.Value, error) { |
