Skip to content

fix(migration): create text_steps index ascending on oracle - #9440

Draft
moodyjmz wants to merge 7 commits into
mainfrom
fix/oracle-text-steps-asc-index
Draft

moodyjmz wants to merge 7 commits into
mainfrom
fix/oracle-text-steps-asc-index

Conversation

@moodyjmz

@moodyjmz moodyjmz commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

📝 Summary

On Oracle, a DESC key is stored as a hidden virtual column, which makes the schema comparison of every later migration fail. This creates text_steps_doc_id_id_index ascending on Oracle through the schema API, as on MySQL. Oracle scans it backwards for ORDER BY id DESC, at the same plan cost (numbers in #9439). A repair step replaces an existing descending index, and the index is registered for occ db:add-missing-indices.

Details
  • Version080000Date20260331132113: Oracle takes the addIndex() path instead of the raw CREATE INDEX ... DESC. Fresh Oracle installs now get the index too.
  • Version080000Date20261020120000: Oracle only. If the index references a column the table doesn't list, it drops the index with raw SQL in preSchemaChange (the schema API can't, because the comparison is what fails), then re-adds it ascending in changeSchema. It throws if the hidden column is still there. It is numbered 080000 so the same class sorts directly after the step it repairs on every branch.
  • Repair coverage: the step runs in the app phase, after core's migrations. On a point release that's usually enough. On a major upgrade, core's first schema-changing step fails before the repair runs, so those instances need the manual workaround in Oracle: descending text_steps_doc_id_id_index blocks every later schema migration #9439.
  • AddMissingIndicesListener: registers text_steps_doc_id_id_index. Fresh PostgreSQL and SQLite installs, and Oracle installs set up before this change, never got the index, because fresh installs skip postSchemaChange. occ db:add-missing-indices can now add it, and the schema check treats it as optional.
  • TextStepsIndexOracleTest: fresh installs only run changeSchema, so CI never ran the old statement. The tests check the index after install, drive both steps through executeStep(), and assert an ascending index and a working dry-run schema comparison. The repair test first asserts that the comparison fails while the descending index exists.
  • App version bump so the new step runs.

Backports: stable32–35, the same as #9393. They need merging before the next maintenance releases, which would otherwise ship the descending index from #9393's backports. Each branch needs its own version bump.

🖼️ Screenshots

No UI change.

🏁 Checklist

  • Code is properly formatted (npm run lint / npm run stylelint / composer run cs:check)
  • Sign-off message is added to all commits
  • Tests (unit, integration and/or end-to-end) passing and the changes are covered with tests
  • Documentation (README or documentation) has been updated or is not required

🤖 AI (if applicable)

  • The content of this PR was partly or fully generated using AI tools
  • The AI-generated content was reviewed, comprehended and tested by a human

Oracle stores a DESC key as a hidden virtual column (SYS_NC...$). The
index then references a column the table does not list, so the schema
comparison of every later migration fails with "There is no column with
name ...". Oracle scans an ascending index backwards for ORDER BY id DESC,
so use the schema API as on MySQL.

Fresh installs only run changeSchema, so the test drives the migration
through the upgrade path on Oracle.

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: James Manuel <moodyjmz@users.noreply.github.com>
@moodyjmz moodyjmz added the bug Something isn't working label Oct 20, 2026
Assert the index exists after install instead of skipping the drop when
it is missing, and keep the class constant untyped so the test backports
to PHP 8.1 and 8.2.

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: James Manuel <moodyjmz@users.noreply.github.com>
An Oracle instance with text_steps_doc_id_id_index created as "id" DESC
cannot run any later migration that changes the schema. Drop that index
and recreate it ascending.

This only helps when no schema-changing step runs before it. Core
migrations run before app migrations, so on a major upgrade an instance
with the descending index still needs it replaced by hand.

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: James Manuel <moodyjmz@users.noreply.github.com>
Fresh installs on PostgreSQL and SQLite, and Oracle installs that ran the
migration before it created the index, have no text_steps_doc_id_id_index.
Let occ db:add-missing-indices add it, and let the schema check treat it
as optional.

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: James Manuel <moodyjmz@users.noreply.github.com>
Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: James Manuel <moodyjmz@users.noreply.github.com>
Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: James Manuel <moodyjmz@users.noreply.github.com>
Rector requires typed class constants on main, which stable32 to 34
cannot parse, so use the literal as the migrations do.

Assisted-by: ClaudeCode:claude-opus-5-5
Signed-off-by: James Manuel <moodyjmz@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Oracle: descending text_steps_doc_id_id_index blocks every later schema migration

1 participant