[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
#endifSeems 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
insertManyOnDuplicateKeyUpdatewill 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 IGNOREis 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.