Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions null.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,22 @@ func (nu *NullUUID) Scan(value interface{}) error {
return nil
}

// UUID.Scan treats empty string and empty []byte as a null UUID (returning
// no error). Mirror that behavior here so NullUUID.Valid reflects the same
// null semantics instead of incorrectly reporting Valid=true for empty input.
switch v := value.(type) {
case string:
if v == "" {
nu.UUID, nu.Valid = Nil, false
return nil
}
case []byte:
if len(v) == 0 {
nu.UUID, nu.Valid = Nil, false
return nil
}
}

err := nu.UUID.Scan(value)
if err != nil {
nu.Valid = false
Expand Down
26 changes: 26 additions & 0 deletions null_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,32 @@ func TestNullUUIDScan(t *testing.T) {
}
}

func TestNullUUIDScanEmptyIsNull(t *testing.T) {
// An empty string or empty []byte should be treated as NULL (Valid=false),
// consistent with how UUID.Scan handles empty input. See issue #109.
var nu NullUUID

if err := nu.Scan(""); err != nil {
t.Fatalf("unexpected error scanning empty string: %v", err)
}
if nu.Valid {
t.Error("expected Valid=false after scanning empty string, got true")
}
if nu.UUID != Nil {
t.Errorf("expected Nil UUID after scanning empty string, got %v", nu.UUID)
}

if err := nu.Scan([]byte{}); err != nil {
t.Fatalf("unexpected error scanning empty []byte: %v", err)
}
if nu.Valid {
t.Error("expected Valid=false after scanning empty []byte, got true")
}
if nu.UUID != Nil {
t.Errorf("expected Nil UUID after scanning empty []byte, got %v", nu.UUID)
}
}

func TestNullUUIDValue(t *testing.T) {
var u UUID
var nu NullUUID
Expand Down