-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MySQL datetime guardrail #428
Conversation
lib/mysql/schema/convert.go
Outdated
// MySQL supports '0000-00-00 00:00:00' for datetime columns. | ||
// We are returning `nil` here because this will fail most Time parsers. | ||
stringValue := string(bytesValue) | ||
if strings.HasSuffix(stringValue, "-00-00 00:00:00") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reading the MySQL docs it seems like it's also possible for the date to be non-zero and the month zero, or vice versa, so maybe what we want to do is lop off just the date, split by hyphens, and then check if any of the three segments is only zeros, something like:
func hasNonStrictModeDate(d string) bool {
if len(d) < 10 {
return false
}
parts := strings.Split(d[:10], "-")
if len(parts) != 3 {
return false
}
for _, part := range parts {
value, err := strconv.Atoi(part)
if err != nil {
return false
}
if value == 0 {
return true
}
}
return false
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
date to be non-zero and the month zero
Oh god.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah makes sense
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not to mention whether it's possible to have a zero day/month but a non-zero h/m/s. 😬
lib/mysql/schema/convert_test.go
Outdated
@@ -318,3 +318,13 @@ func TestConvertValues(t *testing.T) { | |||
assert.Equal(t, []any{int64(1234), "hello world", true}, values) | |||
} | |||
} | |||
|
|||
func TestHasNonStrictModeDate(t *testing.T) { | |||
assert.False(t, hasNonStrictModeDate("2021-01-02")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd add a test for an empty string, a junk string, and a string with just two hyphens, all of which should return false.
lib/mysql/schema/convert.go
Outdated
@@ -184,3 +185,27 @@ func ConvertValues(values []any, cols []Column) error { | |||
} | |||
return nil | |||
} | |||
|
|||
// hasNonStrictModeDate - if strict mode is not enabled, we can end up having invalid datetimes | |||
func hasNonStrictModeDate(d string) bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lol, I know I suggested this name, but maybe we could call this hasNonStrictModeInvalidDate
to be a little clearer.
If strict mode isn't enabled, MySQL may allow invalid datetime / timestamps.