Skip to content

Schema: repair lossless type drift, and gate a real 1.5 upgrade - #2007

Merged
mastacontrola merged 2 commits into
working-1.6from
fix/reconciler-lossless-widen
Oct 28, 2026
Merged

mastacontrola merged 2 commits into
working-1.6from
fix/reconciler-lossless-widen

Conversation

@mastacontrola

Copy link
Copy Markdown
Member

Problem

A 1.5 server's schema count lands on a different 1.6 step whenever 1.5 adds one, and the updater skips every 1.6 step below that count. SchemaReconciler::plan() puts back the tables and columns that the skipped steps created. A skipped step that changed an existing column's type was lost, and shapeDrift() only reported it. That is how users.uName kept 1.5's varchar(40) (#2000, fixed for that one column by #2005). No CI job could see any of this, because the rehearsal builds its start from 1.6's own steps.

Fix

Repair (this reopens GH-1542's "report, never repair", now for changes that cannot lose data). repairShape() applies only drift where every stored value fits unchanged:

  • a longer varchar/char/varbinary/binary;
  • a wider integer with the same signedness (a display width alone is not a change);
  • NOT NULL → NULL.

The MODIFY keeps the live column's charset, collation and AUTO_INCREMENT. A narrower type, a different type, NULL → NOT NULL, or an enum → tinyint stays report-only. A repair the server refuses is logged, and the update still completes. The repair runs before the foreign keys, because a widened child column is what lets its constraint land.

Gate. tests/upgrade-from-15-ci.test.sh:

  • installs the schema with 1.5's own updater, from origin/stable by default;
  • upgrades it with this tree's real SchemaUpdaterPage, both trees under Apache in a php:7.4 container (1.5 reads the request through filter_input(INPUT_SERVER), which php -S and php-cgi leave NULL);
  • fails on an update error, a schema version short of FOG_SCHEMA, any shape drift, or a lost AUTO_INCREMENT.

Each tree's config is rendered from its own installer template. FOGProject/fog-workflows#44 runs the gate twice, once from stable and once from dev-branch. Without a database, the script skips.

Tests

The gate fails on each defect found today:

Tree Result
before #2001 fails at step 290, error 1146 (#2000's first bug)
this repair without the AUTO_INCREMENT handling fails at step 419, error 1364: the repair widened modules.id and dropped AUTO_INCREMENT. The gate caught this in the first draft of this PR
this tree without the repair, before #2005 fails on users.uName and users.uCreateBy
this tree, from stable (c97e205) and from dev-branch (17973cd) passes: schema 446, no drift, every AUTO_INCREMENT intact
  • tests/schema-reconciler-lossless-repair.test.php: 20 checks on the repair planner, for each lossless case and each refused case.
  • schema-shape-drift, role-name-unique-restored and schema-manifest-consistent pass.
  • phpstan passes both ways (main and tests), with no errors.

Refs #2000, GH-1542

🤖 Generated with Claude Code

A 1.5 server's schema count lands on a different 1.6 step whenever 1.5
adds one, and the updater skips every 1.6 step below it. plan() puts back
the tables and columns those steps created, but a step that changed an
existing column's type was lost, and only shapeDrift() reported it. That
is how users.uName kept 1.5's varchar(40) (GH-2000).

repairShape() now applies the drift that cannot lose data: a longer
varchar/char/varbinary/binary, a wider integer of the same signedness,
and NOT NULL -> NULL. The MODIFY keeps the live column's charset,
collation and AUTO_INCREMENT. Everything else stays report-only. It runs
before the foreign keys, since a widened child is what lets one land.

tests/upgrade-from-15-ci.test.sh installs the schema with 1.5's own
updater (from origin/stable by default), upgrades with this tree's real
updater, both served by Apache in a php:7.4 container, and fails on an
update error, a short version, shape drift, or a lost AUTO_INCREMENT.
Without a database it skips. It fails on each of the three defects found
today: the pre-#2001 tree at step 290, this repair without AUTO_INCREMENT
at step 419, and the tree without this repair on the two users columns.

Refs #2000

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mastacontrola
mastacontrola added this pull request to the merge queue Oct 28, 2026
Merged via the queue into working-1.6 with commit bcf21bb Oct 28, 2026
12 checks passed
@mastacontrola
mastacontrola deleted the fix/reconciler-lossless-widen branch October 28, 2026 19:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant