Repository navigation
Fix ON UPDATE CURRENT_TIMESTAMP for explicit values and unchanged rows - #560
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
b35d7b6 to
02814c0
Compare
The driver emulated ON UPDATE CURRENT_TIMESTAMP with an unconditional AFTER UPDATE trigger. Explicit values, self-assignments, and unchanged rows all got the current time. Columns with DEFAULT_GENERATED in EXTRA never got a trigger. Now, the SET list translation appends a CASE for each ON UPDATE column that the statement doesn't assign. The column gets the current time only when an assigned value differs from the stored one. This covers UPDATE and ON DUPLICATE KEY UPDATE, and tables no longer get triggers. See: #554
Remove the legacy and AST driver triggers before they can overwrite values set by the UPDATE translation. Recover missing ON UPDATE column metadata before other migrations rebuild tables and discard the legacy triggers. Match exact trigger names and their tables to preserve unrelated triggers. Cover legacy upgrades, table rebuilds, version gating, and rollback. See: #554 Fixes: #547
02814c0 to
0a5f1db
Compare
| $assigned_columns = array(); | ||
| $value_expressions = array(); | ||
| $changes = array(); | ||
| foreach ( $assigned_values as $column_name => $value ) { |
There was a problem hiding this comment.
any chance $assigned_values is empty or contains something that isn't a literal column name?
There was a problem hiding this comment.
Hm, it doesn't seem so. I'll go ahead and merge. Let's rollback and keep the discussion going if I'm wrong here.
The driver emulated
ON UPDATE CURRENT_TIMESTAMPwith a trigger that ran after everyUPDATE. It overwrote explicit timestamps and changed timestamps on unchanged rows:Automatic updates were also missing in these cases:
DEFAULT CURRENT_TIMESTAMPnever got anON UPDATEtrigger.ALTER COLUMN ... SET DEFAULT (expr)could remove the trigger.ON UPDATEbehavior.Changes
This PR handles automatic timestamps in the translated
UPDATEandINSERT ... ON DUPLICATE KEY UPDATEstatements:RAND()results consistent and avoiding repeated subqueries.ts = ts), orDEFAULTprevents the automatic update, as MySQL documents.DEFAULT CURRENT_TIMESTAMP, expression defaults, and defaults changed byALTER COLUMN.ON UPDATEmetadata before other migrations can rebuild tables, then remove the legacy and AST driver triggers. Match exact trigger names and their tables to preserve unrelated user triggers.As in MySQL, changing
'a'to'A'counts as a change. Assigning'1'to anINTcolumn already containing1does not. Expected results were checked against MySQL 8.4 and 8.0.Fixes #554.
Fixes #547.
Summary by CodeRabbit
ON UPDATE CURRENT_TIMESTAMPnow updates automatically when another value in the row changes, while preserving the timestamp when assigned values remain unchanged. Explicit timestamp assignments continue to be respected.