docs: the upgrade path is reachable for the installations it targets - #873
Merged
blaipr merged 1 commit intoAug 23, 2026
Merged
Conversation
#867 recorded the two shipped migrations as declaring versions the application can never reach, and left resolving that as a deployment decision. The first half is true and the second was the wrong conclusion, so this corrects the record before somebody acts on it. `AppInfoInterface::APP_BUILD` has not moved since the rewrite was imported, so the code reports `400.21031301` while the migrations declare `400.24210101` and `400.24240101`. But `checkUpgradeNeeded()` compares the *stored* version against that, and `getTargetUpgradeHandlers()` then selects every handler above the stored one. An installation arriving from 3.2 stores something like `320.19012701`, which is behind both — so it triggers the upgrade and runs both migrations. Measured against the real Version class rather than reasoned about. What cannot reach them is an installation this rewrite performed, which is stamped with the version the code reports. Neither migration applies to one: `dbstructure.sql` already ships CustomFieldData with the composite primary key and no `id` column, and text written after the escaping change is stored as typed. Bumping APP_BUILD would make it worse. `40024210101.sql` would run against schemas that already have it applied, dropping a column that is not there; and `40024240101.sql` decodes stored text, saying in its own header that it is not idempotent and that no decode of stored text could be — so on an installation whose text is already correct it turns a name typed as `Q&A` into something else. The population that would benefit is the narrow one installed by this rewrite before the escaping change; the population that would be damaged is every installation since. The two stay on the list, and the list keeps doing the job it was added for: a third migration cannot join them unnoticed. No behaviour changes here — only the reasoning recorded on the constant, which is what the next person will read before touching APP_BUILD.
blaipr
deleted the
docs/the-upgrade-path-is-reachable-for-the-installs-it-targets
branch
August 23, 2026 23:58
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.
#867 recorded the two shipped migrations as declaring versions the application can never
reach, and left resolving that as a deployment decision. The first half is true and the
second was the wrong conclusion, so this corrects the record before somebody acts on it.
AppInfoInterface::APP_BUILDhas not moved since the rewrite was imported, so the codereports
400.21031301while the migrations declare400.24210101and400.24240101.But
checkUpgradeNeeded()compares the stored version against that, andgetTargetUpgradeHandlers()then selects every handler above the stored one. Aninstallation arriving from 3.2 stores something like
320.19012701, which is behindboth — so it triggers the upgrade and runs both migrations. Measured against the real
Version class rather than reasoned about.
What cannot reach them is an installation this rewrite performed, which is stamped with
the version the code reports. Neither migration applies to one:
dbstructure.sqlalreadyships CustomFieldData with the composite primary key and no
idcolumn, and text writtenafter the escaping change is stored as typed.
Bumping APP_BUILD would make it worse.
40024210101.sqlwould run against schemas thatalready have it applied, dropping a column that is not there; and
40024240101.sqldecodes stored text, saying in its own header that it is not idempotent and that no decode
of stored text could be — so on an installation whose text is already correct it turns a
name typed as
Q&Ainto something else. The population that would benefit is the narrowone installed by this rewrite before the escaping change; the population that would be
damaged is every installation since.
The two stay on the list, and the list keeps doing the job it was added for: a third
migration cannot join them unnoticed. No behaviour changes here — only the reasoning
recorded on the constant, which is what the next person will read before touching
APP_BUILD.