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.
## Release `3.1.2` Version bump and changelog update for release `3.1.2`. **Changelog draft:** * Allow configuring the SQLite busy timeout with `SQLITE_BUSY_TIMEOUT` ([#558](#558)) * Keep the user transaction active after a failed statement ([#536](#536)) * Support odd-length `0x` hexadecimal literals ([#573](#573)) * Fix rebuilds of legacy text and binary columns ([#565](#565)) * Use `'0'` column defaults in non-strict `INSERT` statements ([#569](#569)) * Roll back failed `OPTIMIZE TABLE` and `REPAIR TABLE` rebuilds ([#567](#567)) * Remove the Rust parser extension ([#566](#566)) * Preserve `AUTO_INCREMENT` counters when rebuilding tables ([#561](#561)) * Fix `ALTER TABLE ... ADD (...)` for columns, indexes, and constraints ([#557](#557)) * Fix `ON UPDATE CURRENT_TIMESTAMP` for explicit values and unchanged rows ([#560](#560)) * Normalize zero defaults in date and time columns ([#542](#542)) * Add support for `ALTER COLUMN` with `SET DEFAULT` and `DROP DEFAULT` ([#555](#555)) **Full changelog:** v3.1.1...release/v3.1.2 ## Next steps 1. **Review** the changes in this pull request. 2. **Push** any additional edits to this branch (`release/v3.1.2`). 3. **Merge** this pull request to complete the release. Merging will automatically build the plugin ZIP, create a [GitHub release](https://github.com/WordPress/sqlite-database-integration/releases), and deploy to [WordPress.org](https://wordpress.org/plugins/sqlite-database-integration/). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> <!-- coderabbit-ai-generated:v1 --> ## Summary by CodeRabbit * **Release** * Updated the SQLite database integration to version 3.1.2. * **New Features** * Added support for more `ALTER TABLE` operations and configurable SQLite busy timeouts. * **Bug Fixes** * Improved transaction handling after failed statements and addressed SQL compatibility, table rebuild, and default-value handling issues. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
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.