Skip to content

Handle Postgres 'NULL' types #1097

Closed
Closed

Description

@fresonn

Hey!
For example, I have a schema

CREATE TYPE tag AS ENUM ('new', 'stock', 'top');

CREATE TABLE some_table (
    ...
    mainTag tag
    ...
)

You can see that the mainTag field in the table can be null.
And for the corresponding table, 'sqlc' generates me the following code

type TagType string

const (
	TagTypeNew   TagType = "new"
	TagTypeStock TagType = "stock"
	TagTypeTop     TagType = "top"
)

func (e *TagType) Scan(src interface{}) error {
	switch s := src.(type) {
	case []byte:
		*e = TagType(s)
	case string:
		*e = TagType(s)
	default:
		return fmt.Errorf("unsupported scan type for TagType: %T", src)
	}
	return nil
}

After I try to translate data from the database, I always get an error in the default case: "unsupported scan type for ...."

Question.
SQLC can track that this field can have a NULL value in the schema?

Activity

  1. added this to the v1.10.0 milestone on Aug 20, 2021
  2. kyleconroy commented on Aug 24, 2021

    @kyleconroy
    Collaborator

    I think the best option here to generate a second type that can handle NULL values. This will also be backwards compatible with the existing type.

    type NullTagType struct {
        TagType TagType
        Valid bool
    }
  3. fresonn commented on Aug 27, 2021

    @fresonn
    Author

    But it's internal error, how can I handle it? I only got an error from sqlc query method.

  4. modified the milestones: v1.10.0, v1.11.0 on Sep 5, 2021
  5. removed this from the v1.11.0 milestone on Jan 31, 2022
  6. sbres commented on Mar 14, 2022

    @sbres
    Contributor

    I'm looking at this problem and I think I can try at least scope out the work needed.

    In order to replicate the Nullable values form the SQL library, wee need the equivalent of convertAssignRows
    After looking at some PR golang/go#24258 for example it is clear the method will stay private.
    It is not possible to only copy-paste the method as I found it not that easy to extract it.
    This library has the equivalent function but is easy to copy paste:
    https://github.com/denisenkom/go-mssqldb/blob/master/convert.go

    1- We need an equivalent to convertAssign.
    Should we add a convert.go file on the generation with convertAssign from go-mssqldb ?
    Should we add convertAssign to sqlc as a public method ?
    Or we can just use the Scan method of the type that is already generated ?

    2- Once we have convertAssign we can create the NullXXX type needed with it's equivalent Scan and Value methods
    Should we generate this type even when the type is never used?
    If we can just generate it no matter what becomes very straightforward.

    3- Use the Nullable value instead of the raw type on the needed queries
    I actually have not vision on this part at all.

    @kyleconroy If you can tell me what you prefer for the point N-1 I can try to draft a PR with the changes, at least the points 1, 2

  7. added a commit that references this issue on May 2, 2022
  8. Jille commented on May 2, 2022

    @Jille
    Contributor

    @sbres I'm not sure why we need a copy of convertAssign at all? Shouldn't implementing driver.Valuer be enough?

    I've drafted up a PR, #1582. It seemed fairly simple, but I haven't even tried to execute the code yet.

  9. sbres commented on May 2, 2022

    @sbres
    Contributor

    I had forgotten about this comment. Yeah, we don't need the convertAssign.
    I've also made a PR for this issue
    #1485

  10. kyleconroy commented on Sep 22, 2023

    @kyleconroy
    Collaborator

    sqlc now generates the correct Null* types for enums.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions