Problem/Motivation
Editing a node's URL alias back and forth between two values inside a workspace can crash with a raw database error:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '...' for key 'redirect.hash'Steps to reproduce
- Create a workspace and switch to it.
- Create a page with alias
/alpha. - Change the alias to
/beta— Redirect auto-creates a redirect from/alpha. - Change the alias back to
/alpha— the/alpharedirect gets trashed, and a new redirect from/betais auto-created. - Change the alias to
/betaagain — trashing the/betaredirect and recreating the/alphaone throws the error above.
Root cause: once the Redirect entity is revisionable and workspace-supported (see #3313540: Convert the Redirect entity type to revisionable), a new redirect's first revision is always inserted as the live default revision, even inside a workspace. But trashing an existing redirect inside a workspace only creates a pending, non-default revision — the live/default revision, which is what the hash unique key actually constrains, is never touched. So the redirect's original hash stays "live" in the database even after it's trashed. When the alias flips back and a new redirect needs to reuse that same source path, the insert collides with that untouched original hash.
Proposed resolution
Before creating a new redirect for a given source, check whether a redirect with that exact source was already trashed, and if so, restore it instead of creating a new entity. Restoring reuses the same database row rather than competing with it for the same hash, so the collision never happens, regardless of whether the trashed redirect was created inside the current workspace or predates it.
Issue fork trash-3609101
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
amateescu commentedComment #6
amateescu commentedMerged!
Comment #10
amateescu commentedPushed a followup commit to fix a review by @plach.