Bug description
Core migration Version34000Date20260318095645 changes oc_jobs.argument from string(4000) to TEXT. On Oracle that is VARCHAR2(4000) → CLOB, which Doctrine emits as an in-place ALTER TABLE ... MODIFY. Oracle rejects that conversion unconditionally, including on an empty table:
ORA-22858: invalid alteration of datatype
occ upgrade aborts mid-migration and the instance is left in maintenance mode.
Neither OracleMigrator nor Doctrine intercepts the conversion. MySQL/MariaDB, PostgreSQL and SQLite support it natively.
occ db:convert-type to an Oracle target is affected by the same migration.
Steps to reproduce
- Install Nextcloud 31.x on Oracle.
- Upgrade to any affected release (below).
occ upgrade fails with ORA-22858.
Expected behaviour
The upgrade completes on Oracle as on every other supported database.
Affected versions
| Release |
Migration present |
| v32.0.6 |
no |
| v32.0.7 and later 32.x |
yes |
| v33.0.0 |
no |
| v33.0.1 and later 33.x |
yes |
| all 34.x |
yes |
v32.0.7 and v33.0.1 both shipped 2026-03-26. Introduced by #59029 (resolves #58913); backported keeping the class name, so the 34000 prefix records where the migration was authored, not which upgrade runs it.
Reproducer
#61912 reproduces the failure on Oracle 18 and 23 and passes on SQLite, MySQL, MariaDB and PostgreSQL.
Suggested fix
Perform the conversion out-of-place on Oracle: add a CLOB column, copy, verify, drop the original, rename. The 2018 precedent for the same bug class is #11975, fixed by #12275, still in tree at apps/dav/lib/Migration/Version1008Date20181105*.php.
Two constraints on the implementation:
The existing class must be modified, not supplemented. MigrationService::sortMigrations() orders by numeric prefix then natural-compares the date component, so any new class authored now sorts after 34000Date20260318095645 and the failing migration still runs first.
The column must end nullable. Restoring NOT NULL DEFAULT '' is not reachable through the framework:
- Doctrine always restates the column type in a
MODIFY (getColumnDeclarationSQL concatenates the type declaration unconditionally), producing MODIFY ("argument" CLOB DEFAULT '' NOT NULL). Oracle rejects that. Verified on Oracle Free 23.9: restating the type together with the default and NOT NULL gives ORA-22296, and a bare type restatement gives ORA-22859. The legal form omits the datatype entirely, which Doctrine cannot emit.
MigrationService::ensureOracleConstraints() throws for a newly added column with notnull && default === '', and for core migrations that check runs on every backend, not only Oracle.
Nothing depends on the constraint: JobList::add() always writes the column, and the 2018 precedent ended nullable.
Steps must be individually guarded, including the data copies — postSchemaChange runs even when changeSchema returns null, and some installations have already converted the column manually.
Test coverage
There is currently no test for column type changes. The Oracle CI job (.github/workflows/phpunit-oci.yml) does not exercise one. #61912 adds the negative case; a positive test running the corrected migration through MigrationService on Oracle should accompany the fix.
Related
Bug description
Core migration
Version34000Date20260318095645changesoc_jobs.argumentfromstring(4000)toTEXT. On Oracle that isVARCHAR2(4000)→CLOB, which Doctrine emits as an in-placeALTER TABLE ... MODIFY. Oracle rejects that conversion unconditionally, including on an empty table:occ upgradeaborts mid-migration and the instance is left in maintenance mode.Neither
OracleMigratornor Doctrine intercepts the conversion. MySQL/MariaDB, PostgreSQL and SQLite support it natively.occ db:convert-typeto an Oracle target is affected by the same migration.Steps to reproduce
occ upgradefails with ORA-22858.Expected behaviour
The upgrade completes on Oracle as on every other supported database.
Affected versions
v32.0.7 and v33.0.1 both shipped 2026-03-26. Introduced by #59029 (resolves #58913); backported keeping the class name, so the
34000prefix records where the migration was authored, not which upgrade runs it.Reproducer
#61912 reproduces the failure on Oracle 18 and 23 and passes on SQLite, MySQL, MariaDB and PostgreSQL.
Suggested fix
Perform the conversion out-of-place on Oracle: add a CLOB column, copy, verify, drop the original, rename. The 2018 precedent for the same bug class is #11975, fixed by #12275, still in tree at
apps/dav/lib/Migration/Version1008Date20181105*.php.Two constraints on the implementation:
The existing class must be modified, not supplemented.
MigrationService::sortMigrations()orders by numeric prefix then natural-compares the date component, so any new class authored now sorts after34000Date20260318095645and the failing migration still runs first.The column must end nullable. Restoring
NOT NULL DEFAULT ''is not reachable through the framework:MODIFY(getColumnDeclarationSQLconcatenates the type declaration unconditionally), producingMODIFY ("argument" CLOB DEFAULT '' NOT NULL). Oracle rejects that. Verified on Oracle Free 23.9: restating the type together with the default and NOT NULL gives ORA-22296, and a bare type restatement gives ORA-22859. The legal form omits the datatype entirely, which Doctrine cannot emit.MigrationService::ensureOracleConstraints()throws for a newly added column withnotnull && default === '', and for core migrations that check runs on every backend, not only Oracle.Nothing depends on the constraint:
JobList::add()always writes the column, and the 2018 precedent ended nullable.Steps must be individually guarded, including the data copies —
postSchemaChangeruns even whenchangeSchemareturnsnull, and some installations have already converted the column manually.Test coverage
There is currently no test for column type changes. The Oracle CI job (
.github/workflows/phpunit-oci.yml) does not exercise one. #61912 adds the negative case; a positive test running the corrected migration throughMigrationServiceon Oracle should accompany the fix.Related
EventReminderJobfails on Oracle, LOB inGROUP BYCleanupLoginTokens