Description
Proposal
Add an interface to database/sql
implemented by sql.Null*
types to unwrap the NULL or the value:
// NullUnwrap allows to unwrap sql.Null* types.
type NullUnwrap interface {
UnwrapNull() (value any, valid bool)
}
(names to be debatted)
Extend sql.Null*
types to implement it:
func (n Null[T]) UnwrapNull() (value any, valid bool) {
if !n.Valid {
return nil, false
}
return n.V, true
}
Why?
There is currently no builtin generic way to unwrap the value of types sql.Null
* (sql.NullBool
,sql.NullByte
, sql.NullInt16
, sql.NullInt32
sql.NullInt64
, sql.NullFloat64
, sql.NullString
, sql.NullTime
).
But at least the list of types was known, so it was possible to use a type switch.
With the addition of sql.Null[T]
(#60370) for Go 1.22 the type switch solution will not be enough.
The only ways to unwrap an sql.Null[T]
are just hacks using either the driver.Valuer
interface or reflect
:
(full example: https://go.dev/play/p/DnStyHLekX1?v=gotip)
func UnwrapNullable(val driver.Valuer) (value any, valid bool) {
v := reflect.ValueOf(val)
if v.Field(1).Bool() {
return v.Field(0).Interface(), true
}
return nil, false
}
func UnwrapNullable2(val driver.Valuer) (value any, valid bool) {
value, err := val.Value()
if err != nil {
panic(err)
}
if value != nil {
return value, true
}
return nil, false
}
A common method available on sql.Null*
types would allow to have an efficient unwrapping and be type safe as unwrapping could be done after an interface check.
That interface could also help to distinguish types that are able to represent a NULL
value (types that never return valid == false
should not implement it).
Metadata
Metadata
Assignees
Type
Projects
Status