Skip to content

entc/sql/decode: fix decoding of NullTime in optional and nillable time fields#60

Closed
htdvisser wants to merge 1 commit into
ent:masterfrom
htdvisser:fix/null_time
Closed

entc/sql/decode: fix decoding of NullTime in optional and nillable time fields#60
htdvisser wants to merge 1 commit into
ent:masterfrom
htdvisser:fix/null_time

Conversation

@htdvisser
Copy link
Copy Markdown
Contributor

While trying out this project I think I found a bug in the generated code when using an optional and nillable time field.

vet: ent/user.go:46:16: cannot use &vu.DeletedAt (value of type *sql.NullTime) as *time.Time value in assignment

7438104 made a change to the {{ $scan }} struct, which now always uses {{ $f.NullType }} as type, so the $f.IsTime check can now be removed. This pull request does that.

This is my fist contribution here. I hope I didn't miss anything.

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 4, 2019
@a8m
Copy link
Copy Markdown
Member

a8m commented Oct 4, 2019

Thanks for your contribution @htdvisser.

In general, Optional means that the value is optional on entity creation and can be NULL in the database. If the value is NULL in the database, the struct field will hold a zero value of its type.

However, sometimes you want to distinguish between zero values and NULL (database column contains "", false or 0). Therefore, this is what Nillable option is used to. The struct field won't be nil only if the database column doesn't contain NULL.

Now, going back to the bug you found - I think we should address it. However, I'm not sure this is the way to go, since godoc for the time.Time package mentions that:

Programs using times should typically store and pass them as values, not pointers. That is, time variables and struct fields should be of type time.Time, not *time.Time.

The zero value of type Time is January 1, year 1, 00:00:00.000000000 UTC. As this time is unlikely to come up in practice, the IsZero method gives a simple way of detecting a time that has not been initialized explicitly.

My suggestion is to follow the Go standard and remove the Nillable option from the field.Time builder. But maybe I miss something. I would love to hear your thoughts, wdyt?

BTW, really impressive ramp-up. This reminds me that I need to write a better contribution doc.

@htdvisser
Copy link
Copy Markdown
Contributor Author

For my DeletedAt I indeed decided to use only Optional and not use Nillable, which works fine so far.

However, I don't think that Nillable should be removed completely from field.Time. The way I read it, the "should typically" in the godoc implies that there may still be situations where it's acceptable to use *time.Time, and I think it would be good to let developers choose to do so.

@a8m
Copy link
Copy Markdown
Member

a8m commented Oct 4, 2019

and I think it would be good to let developers choose to do so.

Agree.

@alexsn any thoughts?

Copy link
Copy Markdown
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@a8m has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@alexsn
Copy link
Copy Markdown
Collaborator

alexsn commented Oct 4, 2019

and I think it would be good to let developers choose to do so.

Agree.

@alexsn any thoughts?

I'm not sure I see a use case where you'd want to distinguish between not setting time and explicitly setting zero time. If there are such cases then Nillable should stay.

facebook-github-bot pushed a commit that referenced this pull request Oct 4, 2019
…me fields (#60)

Summary:
While trying out this project I think I found a bug in the generated code when using an optional and nillable time field.

```
vet: ent/user.go:46:16: cannot use &vu.DeletedAt (value of type *sql.NullTime) as *time.Time value in assignment
```

7438104 made a change to the `{{ $scan }}` struct, which now always uses `{{ $f.NullType }}` as type, so the `$f.IsTime` check can now be removed. This pull request does that.

This is my fist contribution here. I hope I didn't miss anything.
Pull Request resolved: #60

Differential Revision: D17760925

Pulled By: a8m

fbshipit-source-id: 675005be62487b1b9eb77302b8185bd3b6ef0195
@htdvisser
Copy link
Copy Markdown
Contributor Author

Thanks for accepting my pull request!

I think removing Nillable from field.Time would definitely have been out-of-scope for this particular pull request, but maybe it would be good to open an issue for discussion and make a decision on it before you release a v1.

@a8m
Copy link
Copy Markdown
Member

a8m commented Oct 4, 2019

Thanks for your contribution.

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

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants