Skip to content

[3.0] Compares the generation expression a column actually has - #9625

Merged
Sesquipedalian merged 1 commit into
SimpleMachines:release-3.0from
albertlast:3.0/normalize-generation-expression
Sep 5, 2026
Merged

Sesquipedalian merged 1 commit into
SimpleMachines:release-3.0from
albertlast:3.0/normalize-generation-expression

Conversation

@albertlast

@albertlast albertlast commented Sep 5, 2026 •

Copy link
Copy Markdown
Collaborator

Description

normalize() decides whether a column needs changing by walking a list of properties and comparing what the schema asks for against what the database reports:

foreach (['name', 'size', 'unsigned', 'generated_expression', 'stored', 'not_null', 'default', 'auto'] as $prop) {
    if (($structure['columns'][$col->name][$prop] ?? null) != ($col->{$prop} ?? null)) {

One of those names is not what either side calls it. The property on GeneratedColumn is generation_expression, and so is the key every database API puts in the structure it returns. Sources/Db/Schema/Table.php:240 is the only place in the tree spelling it the other way:

$ grep -rn "generated_expression" Sources/
Sources/Db/Schema/Table.php:240:  foreach (['name', 'size', 'unsigned', 'generated_expression', 'stored', ...

Both sides of that comparison therefore resolve to null through the null coalescing operators around them, null is never unequal to null, and the check cannot fire. A column whose generation expression no longer matches its definition is reported as already correct.

Nothing depends on it today, because the generated columns on messages also differ in not_null and that catches them instead. It would matter the first time a 3.0.x changed the expression behind a generated column: fresh installs would build the new one, every existing forum would keep the old one, and the upgrade would report that it had nothing to do.

How this was verified

This is latent rather than observable, so there is no before-and-after to show for the bug itself. What was checked is that correcting the name does not disturb what normalize() already does: the modified_time, modified_name and modified_reason generated columns on messages come out the same on both engines, and a 2.1 → 3.0 upgrade followed by a second upgrade of the result changes nothing, on MySQL and on PostgreSQL, using .docker/rerun-upgrade.sh (#9622) against the 2.1.7 baseline from the 2.1 development environment.

Not reachable from the unit suite

Schema\Column::__construct() calls Db::$db->calculate_type(), so the schema classes cannot be instantiated without a connection, and normalize() does nothing but read and alter a live database.

Issues References (Fixes|Related|Closes)

  1. Related: [3.0][Testing] Check that an upgrade survives being run twice and being interrupted #9622 -- the check used to confirm nothing else moved

normalize() decides whether a column needs changing by walking a list of
properties and comparing what the schema asks for against what the database
reports. One of the names in that list is generated_expression, which is not
what either side calls it: the property on GeneratedColumn is
generation_expression, and so is the key every database API puts in the
structure it returns. It is the only place in the tree spelling it the other
way.

Both sides of the comparison therefore resolved to null through the null
coalescing operators around them, null is never unequal to null, and the check
could not fire. A column whose generation expression no longer matches the
definition was reported as already correct.

Nothing depends on it today, because these columns also differ in not_null and
that catches them instead. It would matter the first time a 3.0.x changed the
expression behind a generated column: fresh installs would build the new one,
every existing forum would keep the old one, and the upgrade would report that
it had nothing to do.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
@Sesquipedalian
Sesquipedalian merged commit 2bf90ab into SimpleMachines:release-3.0 Sep 5, 2026
9 checks passed
@jdarwood007 jdarwood007 added this to the 3.0 Alpha 5 milestone Sep 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants