-
Notifications
You must be signed in to change notification settings - Fork 297
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
[persistent-mysql] Use an "INSERT IGNORE" query if the updates are empty. #702
[persistent-mysql] Use an "INSERT IGNORE" query if the updates are empty. #702
Conversation
This PR is a subset of #701 and can be closed without merging if that PR is merged. PR #701 needed to incorporate these changes in order to unentangle the If you choose not to merge #701, then merging this PR and Esqueleto merging the BackendCompatible class will work to get |
I'm getting a weird test failure on the MySQL tests in an unrelated module.
The test handles MySQL specially: roundTime :: TimeOfDay -> TimeOfDay
#ifdef WITH_MYSQL
roundTime (TimeOfDay h m s) = TimeOfDay h m (fromIntegral (truncate s :: Integer))
#else
roundTime = id
#endif Seems like updating the Travis image might have changed an expectation on how MySQL does times. When inserting values into the database, we use |
The mysql test seems to have been broken by Travis recently upgrading their default Ubuntu images to "trusty". As a result, MySQL will have been upgraded from 5.5.X to 5.7.X, assuming travis uses the standard versions for the distro. Before MySQL 5.6.4, fractional seconds were not supported, and, if I understand correctly, any fractional part in a literal was simply ignored, thereby truncating to the whole second below - documented here. Since 5.6.4 the default is to use whole-second precision, but, crucially, excess precision in literals is now rounded, as described in the 5.7 documentation here. So, MySQL itself has made a totally incompatible change. The I'll see if I can come up with a way of fixing the test... |
MySQL, you bring me so much joy 😡 Thanks for posting the rationale there. I figured it was a Travis change. I replaced |
I realise #701 includes this change, but I feel more competent to comment on the MySQL part of it for now.
It is a little worrying that a behind-the-scenes use of Is it possible to use BTW I don't understand the statement in the docs about InnoDB tables and auto-increment columns - I have just tried it and I don't see that behaviour! |
That's a fantastic point that I hadn't considered. Thanks! I'll modify the PR to use |
Hooray for spurious CI failures 😂 This is passing all tests now, using the dummy update. |
Thanks for including the changelog note as well! I suggest I merge this now, and then if you could rebase #701 on this, we can look at the new type class separately, and ask one of the others for comments (I can't see any objections myself). |
Thanks! Will do :) |
The current behavior of
insertManyOnDuplicateKeyUpdate
will perform aninsertMany_
if there are no updates to perform.insertMany_
will then throw an error if the key already exists in the database.This is surprising -- typically, when you're doing a bulk upsert like this, the desired behavior is "Try to insert these rows into the database. If there's a key collision, then perform the set of updates." Given an empty set of updates, I would expect nothing to be done to the preexisting record, not throwing an exception and rolling back the entire insert.
MySQL's
INSERT IGNORE
is a little unfortunate: docsI believe the unfortunate bits of this API are hidden behind the guarantees that Persistent can make about the query we're generating.