sqlc icon indicating copy to clipboard operation
sqlc copied to clipboard

Optionally replace sql.Null* types with pointers

Open xeoncross opened this issue 3 years ago • 1 comments
trafficstars

What do you want to change?

Structs generated by sqlc which contain null fields use the sql.Null* types. However, it would be nice if there was an option to use a pointer instead. So instead of sql.NullString we could use *string. The reason has to do with serialization since sql.NullString is an object you must manually define your serialization format for.

Consider the following object

type User struct {
	Name  sql.NullString
	Email string
}

which JSON encoded looks like

{
    "Name": {
        "String": "john",
        "Valid": true
    },
    "Email": "[email protected]"
}

And JSON decoded looks like: Unmarshal type error: expected=sql.NullString, got=string, field=Name and json: cannot unmarshal string into Go struct field User.Name of type sql.NullString. We must manually wrap sql.NullString to add proper marshaling support for each transport like JSON:

// Nullable String that wraps sql.NullString
type NullString struct {
	sql.NullString
}

func (ns NullString) MarshalJSON() ([]byte, error) {
	if ns.Valid {
		return json.Marshal(ns.String)
	}
	return json.Marshal(nil)
}

func (ns *NullString) UnmarshalJSON(data []byte) error {
	var s *string
	if err := json.Unmarshal(data, &s); err != nil {
		return err
	}
	if s != nil {
		ns.Valid = true
		ns.String = *s
	} else {
		ns.Valid = false
	}
	return nil
}

Of course, we could also manually update the configuration for every single null type in our database using overriding but that seems like a lot of work when we could just use pointers instead.

If I submit a PR to add an option like emit_struct_field_pointers would you potentially accept it?

What database engines need to be changed?

No response

What programming language backends need to be changed?

Go

xeoncross avatar Aug 22 '22 13:08 xeoncross

We have a pull request that adds this in https://github.com/kyleconroy/sqlc/pull/1571. That PR is a bit stale at this point, but could be cleaned up.

kyleconroy avatar Aug 28 '22 16:08 kyleconroy

Fixed by #1571 and https://github.com/kyleconroy/sqlc/pull/1950

kyleconroy avatar Nov 10 '22 08:11 kyleconroy