[3.0] Sync PostgreSQL sequences with the rows the installer inserts - #9348
Open
albertlast wants to merge 1 commit into
Open
[3.0] Sync PostgreSQL sequences with the rows the installer inserts#9348albertlast wants to merge 1 commit into
albertlast wants to merge 1 commit into
Conversation
A table's initial data carries its own IDs - the default board is board 1, and other rows in it refer to each other by number - so those values are supplied to the INSERT rather than generated. MySQL sees a value larger than its AUTO_INCREMENT counter and moves the counter along by itself. PostgreSQL does not: a sequence only advances when something calls nextval() on it, nothing has, so it still sits at 1 and hands 1 to the next insert. That collides with the row already there and the insert fails on the primary key. On a new PostgreSQL forum, 28 sequences are in that state. Starting the first topic is the usual way to meet it, and the symptom is not obviously a database problem: Post2 runs on to its normal redirect, the browser lands on the board, and no topic is there. It then works on the second try, because the attempt that failed still consumed the 1 and the retry gets 2 - which makes it look like a fluke rather than something to report. The 2.1 upgrade path has carried this fix for years, as the PostgreSqlSequences migration. This is the same setval() for a fresh install, next to the insert that causes it, and it is a no-op on MySQL. Not covered by the unit suite: it needs a database, and it only shows up on a forum that has just been installed. Verified by installing on PostgreSQL and posting - the first topic now works where it previously vanished - and by checking that the sequences report a position instead of never having been called. MySQL was reinstalled and exercised too, since populate() is shared. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
Contributor
|
My recommendation is to cut over to Identity Columns in 3.0. https://www.simplemachines.org/community/index.php?topic=592387.0 |
Collaborator
Author
|
i know, but this is here a bug fix pr, not feature pr ^^ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
On a freshly installed PostgreSQL forum, the first topic anybody starts is silently not created.
The table schemas carry initial data with explicit IDs — the default board is board 1, and other seeded rows refer to each other by number — so those values are supplied to the
INSERTrather than generated. MySQL notices a value above itsAUTO_INCREMENTcounter and moves the counter along by itself. PostgreSQL does not: a sequence only advances when something callsnextval()on it, nothing has, so it still sits at 1 and hands 1 to the next insert. That collides with the row already there:28 sequences are in that state on a new install —
boards,categories,membergroups,smileys,attachments,polls,personal_messages,scheduled_tasksand more.What makes it easy to miss rather than easy to report:
Post2runs on to its normal redirect, the browser lands on the board, and the topic simply is not there. Nothing is shown to the user and nothing reacheslog_errors.1, so the retry gets2and succeeds. Anyone who tries again concludes it was a fluke, and the forum behaves correctly from then on.Because of that second point it only reproduces on a forum that has just been installed, which is why it has survived this long.
The fix
Table::populate()already works out which column auto-increments, in order to decide its insert mode. After the insert it now points the generator past what it just wrote. On MySQL this returns immediately.This is not a new idea in the codebase: the 2.1 upgrade path has carried the same
setval()for years, asSources/Maintenance/Migration/v2_1/PostgreSqlSequences.php. Installs never got the equivalent.Testing
The unit suite cannot reach this — it needs a database, and the state only exists on a forum that has just been installed.
Verified by hand on both engines, installing from scratch each time:
pg_sequences.last_valueisNULLfor 28 sequences.populate()is shared. Unchanged, as expected.Issues References (Fixes|Related|Closes)
Found while running HTTP tests against a freshly installed forum in #9347. Not otherwise reported that I can find.