go-mysql-server
This is a short tutorial about how to make and test changes in Dolt and its Go MySQL engine. We're going to work through fixing and testing a recent bug that was filed against Dolt. In the bug report, a user is using RMariaDB, a database connector library for R, and is seeing some values of certain timestamps fail to insert. The server is returning an error:
Setup
Follow these setup instructions.
Reproduce the Bug
Let's see if we can make progress on reproducing the bug. Here, we just attempt to insert the same string that appears in the error message into a timestamp
column:
Brilliant, we've managed to reproduce the bug. Let's track down where that error is coming from.
Tracking Down the Error
Hopefully this isn't too hard:
so we can open go-mysql-server/sql/datetimetype.go
in an editor and look for uses of ErrConvertingToTime
. We quickly find the only place it is returned:
and going to the definition of TimestampDatetimeLayouts
, we find:
Notably present is a "2006-1-2 15:4:5.999999"
, which looks like it might handle single-digit months and days in a date that comes with a timestamp. But there is no corresponding "2006-1-2"
in that list, which would possibly handle the case we're trying to fix. Let's start by looking for a unit test we could write that would demonstrate the bug in this ConvertWithoutRangeCheck
function. We open up datetimetype_test.go
, and look through the top level functions:
for our purposes, TestDatetimeConvert
looks the most promising, and digging into the implementation, it's a table driven test with a pretty straight forward structure of giving an input to Convert
and asserting a matching output and error value. We can just add tests for each of the three handled time types:
and then try running the tests:
Perfect. Let's go ahead and see if we can fix it by adding the new pattern in TimestampDatetimeLayouts
.
and test again:
Seems to work. So now we have a unit test demonstrating the problem and we've made that test pass. There's one other type of test we can add if we want to. The original bug was reported in the context of an insert, and it would be great to codify the fact that INSERT INTO table_with_datetime (timestamp) VALUES ("2006-6-3")
should always work. For that kind of test, go-mysql-server
has a directory of integration tests that lives at //enginetest
. If we look around a little, we will find a file called insert_queries.go
and we can look through that file for places where we're doing integration tests of inserts into datetime columns. Eventually, we might come with something like:
which hopefully captures the spirit of the behavior we want to verify. We can also verify that this fixes the behavior all the way at the dolt layer:
Committing and Opening a Pull Request
At this point, the bug is fixed in Dolt's SQL engine. Commit and push your changes through git.
Finally, we just need to submit a pull request.
Last updated