Skip to content

RenameDutchCatalogColumns is live on development and unguarded — it renames Dutch columns the register still declares #492

Description

@rubenvdlinde

Status: the step is on development, registered, and unguarded

RenameDutchCatalogColumns merged in #488 (088e14ce, 2026-08-12 07:15:02Z). A blocking review landed on the PR three minutes later and is therefore easy to miss — #488 (comment). This issue restates it against the merged state.

Measured on origin/development after the merge:

repair step registered in appinfo/info.xml yes
appinfo/info.xml version 0.2.22 — unchanged, not bumped
register still declares naam / beschrijvingKort / publicatiedatum yes, 19 property keys

The only thing preventing the step from firing is the un-bumped version. Repair steps run on app update and on occ maintenance:repair. The next release bump arms it.

What it will do when it fires

run() renames precisely when the English column is absent (RenameDutchCatalogColumns.php:201) — which is the state of every in-scope schema today, because the rename slice has not landed.

  1. sector.naamsector.name, sector.beschrijvingsector.description, and the same across eleven shard tables (suite, dienst, kwetsbaarheid, organisatie, gebruik, koppeling, beoordeeling, module, bioMaatregel, moduleVersie).
  2. The register still declares naam / beschrijving, so on the next schema sync MagicMapper finds naam missing and adds it back, empty.
  3. Every read returns null. No error, nothing logged as a failure, invisible to suites that assert against fixtures.

Destinations short_description, publication_date, depublication_date, contact_person are declared nowhere in the register. name/description exist only on element, view, model, relation, property-definition, organization, sbomComponent — none of which is in scope. Extraction positive-controlled at 220 distinct property keys.

This is the step's own header docblock with the two halves swapped, and it targets the ~9,500 imported VNG records the PR names as the population that was never validated.

Nothing enforces the ordering the code requires

appinfo/info.xml states it in prose — "Must run AFTER the register sync that adds the English columns" — with no mechanism behind it. grep -c properties lib/Repair/RenameDutchCatalogColumns.php returns 0: the step never reads a schema's declared properties, so it cannot distinguish "renamed, mapper behind" from "not renamed at all". Those two states are byte-identical in the column list it inspects. The safe back-fill branch fires after the rename; the rename branch fires before, and only the second is currently reachable.

Two ways to close it — either works, "do nothing" does not

  1. Guard the step. Gate each rename on the destination being a declared property of that schema. It already resolves the register id and the schema ids from oc_openregister_schemas; reading the declared properties there turns the ordering assumption into a checked precondition and makes the step safe in either merge order. Preferred, because it also survives a future reordering.
  2. Land the rename slice before any version bump, and treat the two as one release unit.

The sibling did it a third way that also works: decidesk #467 shipped the property rename and RenameDutchVocabularyColumns in one commit (7a551682), so register and columns move together and the question never arises.

Until one of those lands

Do not bump appinfo/info.xml. That is currently the only thing standing between this step and the outcome above, and a version bump is the most routine change in the repo.

Secondary, worth folding into the same fix

  • information_schema is not scoped to the current database. inScopeShardTables() (:298) and columnsOf() (:395) filter only on table_name. On MySQL that view spans every database on the server, so columnsOf() can return another database's column list for a same-named table. Postgres scopes to the current database, which is why the dev rig never showed it. Add AND table_schema = DATABASE() / current_schema().
  • $columns is read once per table (:184) and never refreshed after a rename. Safe today only because the collision guard already refuses the one many-to-one family (description). That is load-bearing and undocumented.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions