-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
Use correct precision when touching updated_at
column in upsert
#42993
Use correct precision when touching updated_at
column in upsert
#42993
Conversation
0581979
to
393d244
Compare
231adfd
to
80a5da1
Compare
I'd prefer we use |
Ahh, interesting suggestion, @tenderlove. I hadn't considered offloading that per adapter. Couple questions:
|
CURRENT_TIMESTAMP provides differing precision on different databases. This method can be used in queries instead to provide a high precision current time regardless of the database being connected to. CURRENT_TIMESTAMP continues to be used as the default, unless overriden.
Some tests will require precision.
`CURRENT_TIMESTAMP` provides differing precision depending on the database, and not all databases support explicitly specifying additional precision. Instead, we delegate to the new `connection.high_precision_current_timestamp` for the SQL to produce a high precision timestamp on the current database.
0e41cbc
to
213c4c5
Compare
@tenderlove I've made the changes you requested 👍 |
@@ -441,6 +441,19 @@ def with_yaml_fallback(value) # :nodoc: | |||
end | |||
end | |||
|
|||
# This is a safe default, even if not high precision on all databases | |||
HIGH_PRECISION_CURRENT_TIMESTAMP = Arel.sql("CURRENT_TIMESTAMP").freeze # :nodoc: |
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 extracted these so we wouldn't create a new object each time. I saw this done in some other places, which also used :nodoc:
.
def high_precision_current_timestamp | ||
HIGH_PRECISION_CURRENT_TIMESTAMP | ||
end |
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 originally thought we'd be able to just have this be the only implementation of the method, and simply override the constant in each adapter, but that doesn't seem to work.
We could do self.class::HIGH_PRECISION_CURRENT_TIMESTAMP
but that seems wrong.
Another alternative would be to use differently named constants, but I'm not sure that's better.
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 originally thought we'd be able to just have this be the only implementation of the method, and simply override the constant in each adapter, but that doesn't seem to work.
We could do
self.class::HIGH_PRECISION_CURRENT_TIMESTAMP
but that seems wrong.
Meh. I think this is totally fine.
I don't know the answer to this. Probably using
If it's not too hard, yes. |
This test ensures we use the same high precision timestamp for bulk record creation as we do for bulk record updates. See rails#42993 for details.
In Rails7 the timestamps column is automatically updated when insert_all and upsert_all are executed, but before that it had to be updated manually. rails/rails#43003 There was a related pull request that presicion was not taken into account when auto-updating timestamps columns, but this does not affect `solid_queue` table schema as there is no presicion setting. rails/rails#42993
In Rails7 the timestamps column is automatically updated when insert_all and upsert_all are executed, but before that it had to be updated manually. rails/rails#43003 There was a related pull request that presicion was not taken into account when auto-updating timestamps columns, but this does not affect `solid_queue` table schema as there is no presicion setting. rails/rails#42993
In Rails7 the timestamps column is automatically updated when insert_all and upsert_all are executed, but before that it had to be updated manually. rails/rails#43003 There was a related pull request that presicion was not taken into account when auto-updating timestamps columns, but this does not affect `solid_queue` table schema as there is no presicion setting. rails/rails#42993
In Rails7 the timestamps column is automatically updated when insert_all and upsert_all are executed, but before that it had to be updated manually. rails/rails#43003 There was a related pull request that presicion was not taken into account when auto-updating timestamps columns, but this does not affect `solid_queue` table schema as there is no presicion setting. rails/rails#42993
In Rails7 the timestamps column is automatically updated when insert_all and upsert_all are executed, but before that it had to be updated manually. rails/rails#43003 There was a related pull request that presicion was not taken into account when auto-updating timestamps columns, but this does not affect `solid_queue` table schema as there is no presicion setting. rails/rails#42993
In Rails7 the timestamps column is automatically updated when insert_all and upsert_all are executed, but before that it had to be updated manually. rails/rails#43003 There was a related pull request that presicion was not taken into account when auto-updating timestamps columns, but this does not affect `solid_queue` table schema as there is no presicion setting. rails/rails#42993
Summary
Closes #42992
InsertAll
(the machinery which powers, among others methods,upsert
) usesCURRENT_TIMESTAMP
with an implicit precision of0
as the default when touchingupdated_at
/updated_on
.This PR updates it to pass in the current time, serialized according to the column's type.
Not all databases support increased precision for
CURRENT_TIMESTAMP
(e.g. MySQL supportsCURRENT_TIMESTAMP(6)
, but SQLite does not), so it is simpler to just serialize the current time.Other Information
CURRENT_TIMESTAMP
had been chosen instead of serializing the current time, and that this won't break anything.