From 203a75ee4a2fd508edd6c2df97a956e676edcb07 Mon Sep 17 00:00:00 2001 From: sonnemusk Date: Wed, 22 Jul 2026 15:31:16 +0800 Subject: [PATCH] fix: treat empty string/bytes as NULL in NullUUID.Scan UUID.Scan("") succeeds with a Nil UUID, so NullUUID.Scan previously set Valid=true for empty DB values. Treat empty string and empty []byte as SQL NULL (Valid=false), matching NullUUID.Scan(nil). Fixes #109. --- null.go | 15 +++++++++++++++ null_test.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/null.go b/null.go index d7fcbf2..e04f408 100644 --- a/null.go +++ b/null.go @@ -38,6 +38,21 @@ func (nu *NullUUID) Scan(value interface{}) error { return nil } + // Treat empty database values as NULL. UUID.Scan("") leaves a Nil UUID + // and returns nil, which would otherwise mark Valid=true (issue #109). + 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 diff --git a/null_test.go b/null_test.go index fe0fe8d..a8317bb 100644 --- a/null_test.go +++ b/null_test.go @@ -212,3 +212,37 @@ func TestNullUUIDUnmarshalJSON(t *testing.T) { t.Errorf("expected nil when unmarshalling null, got %s", err) } } + +func TestNullUUIDScanEmpty(t *testing.T) { + var nu NullUUID + // Start from a valid value to ensure empty clears Valid. + if err := nu.Scan("12345678-abcd-1234-abcd-0123456789ab"); err != nil { + t.Fatalf("setup scan: %v", err) + } + if !nu.Valid { + t.Fatal("expected Valid after setup") + } + + if err := nu.Scan(""); err != nil { + t.Fatalf("empty string scan: %v", err) + } + if nu.Valid { + t.Error("expected Valid=false after scanning empty string") + } + if nu.UUID != Nil { + t.Errorf("expected Nil UUID after empty string, got %v", nu.UUID) + } + + if err := nu.Scan("12345678-abcd-1234-abcd-0123456789ab"); err != nil { + t.Fatalf("re-setup scan: %v", err) + } + if err := nu.Scan([]byte{}); err != nil { + t.Fatalf("empty []byte scan: %v", err) + } + if nu.Valid { + t.Error("expected Valid=false after scanning empty []byte") + } + if nu.UUID != Nil { + t.Errorf("expected Nil UUID after empty []byte, got %v", nu.UUID) + } +}