user2094540
user2094540

Reputation:

Difference between *string and sql.NullString

I've been strugguling with SQL NULL values in Golang recently. After trying to unsuccessfully unmarshal JSON objects using Decode() and sql.NullString, I came to this answer on StackOverflow :

Assigning null to JSON fields instead of empty strings in Golang

The solution using a string pointer seems to work perfectly with Decode() and nil values. So what is the difference between sql.NullString and *string ? Is it just about nil checking ?

Upvotes: 36

Views: 44967

Answers (2)

Ben
Ben

Reputation: 6348

Making @sepehr's comment in the previous answer an answer of it's own, and adding some conversion functions I find helpful.

From Russ Cox

There's no effective difference. We thought people might want to use NullString because it is so common and perhaps expresses the intent more clearly than *string. But either will work

In fact, a few generic functions make it easy to convert from *string and sql.NullString with a minimum of fuss:

func DerefOrEmpty[T any](val *T) T {
    if val == nil {
        var empty T
        return empty
    }
    return *val
}

func IsNotNil[T any](val *T) bool {
    return val != nil
}

Usage:

func main() {
    var comment string = "hello"
    commentPtr := &comment

    sqlStrComment := sql.NullString{
        String: DerefOrEmpty(commentPtr),
        Valid:  IsNotNil(commentPtr),
    }
    fmt.Printf("%#v\n", sqlStrComment)

    commentPtr = nil
    sqlStrComment = sql.NullString{
        String: DerefOrEmpty(commentPtr),
        Valid:  IsNotNil(commentPtr),
    }
    fmt.Printf("%#v\n", sqlStrComment)
}

Playground link at https://go.dev/play/p/KFNHe2iJmGU

Upvotes: 2

T. Claverie
T. Claverie

Reputation: 12256

SQL has different null values than Golang.

If you look at the definition of sql.NullString then this is what you get:

type NullString struct {
    String string
    Valid  bool // Valid is true if String is not NULL
}

As you can see, sql.NullString is a way to represent null string coming from SQL (which correspond to "NULL"). On the other hand, a nil *string is a pointer to a string which is nil, so the two are different.

Upvotes: 33

Related Questions