Skip to content

fix(schema-builder): drop dependent indices and constraints for removed columns. - #12762

Open
Delorne007 wants to merge 1 commit into
typeorm:masterfrom
Delorne007:fix/column-migration-drop
Open

fix(schema-builder): drop dependent indices and constraints for removed columns.#12762
Delorne007 wants to merge 1 commit into
typeorm:masterfrom
Delorne007:fix/column-migration-drop

Conversation

@Delorne007

Copy link
Copy Markdown

Description of change

  • What the change is intended to do: Automatically drops dependent indices, unique constraints, and check constraints linked to database columns right before those columns are removed during schema synchronization.
  • Why this change is needed: Prevents database query execution errors or failures that happen when a schema synchronization tries to drop a column that still has active constraints or indices pointing to it.
  • How you've verified it: Inspected the code structure inside RdbmsSchemaBuilder.ts, verified the sequential execution order of schema operations, and reviewed a clean diff showing 58 target additions.

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (2) 📜 Skill insights (0)

Grey Divider


Action required

1. Misindented new schema method 📘 Rule violation ⚙ Maintainability
Description
The newly added dropIndicesAndConstraintsForRemovedColumns() block is not indented like other
class methods, creating inconsistent style and likely failing formatting/lint expectations for this
file.
Code

src/schema-builder/RdbmsSchemaBuilder.ts[R250-253]

+/**
+ * Drops indices, checks, and unique constraints that involve columns about to be dropped.
+ */
+protected async dropIndicesAndConstraintsForRemovedColumns(): Promise<void> {
Evidence
PR Compliance ID 4 requires avoiding inconsistent style. The new method and its comment begin at
column 0 while surrounding class methods are indented, demonstrating inconsistent formatting in the
changed code.

Rule 4: Remove AI-generated noise
src/schema-builder/RdbmsSchemaBuilder.ts[250-258]
src/schema-builder/RdbmsSchemaBuilder.ts[308-310]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`dropIndicesAndConstraintsForRemovedColumns()` (and its JSDoc) is not indented consistently with the rest of `RdbmsSchemaBuilder` methods, making the style inconsistent and potentially breaking formatting/lint checks.

## Issue Context
In `src/schema-builder/RdbmsSchemaBuilder.ts`, other methods inside `export class RdbmsSchemaBuilder` are indented (e.g., `private getTablePath`). The new method starts at column 0.

## Fix Focus Areas
- src/schema-builder/RdbmsSchemaBuilder.ts[250-308]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Unsafe check constraint detection 🐞 Bug ☼ Reliability
Description
dropIndicesAndConstraintsForRemovedColumns() calls check.expression.includes(colName) even though
TableCheck.expression is optional, which can throw at runtime during schema sync. Substring matching
can also misidentify constraints (e.g., dropped column "id" matching "order_id"), causing unrelated
CHECK constraints to be dropped or required ones to be missed so dropRemovedColumns() still fails.
Code

src/schema-builder/RdbmsSchemaBuilder.ts[R296-299]

+            const checksToDrop = table.checks.filter((check) =>
+                droppedColumnNames.some((colName) => check.expression.includes(colName))
+            )
+            if (checksToDrop.length > 0) {
Evidence
The PR introduces CHECK selection using check.expression.includes(...) without null-guarding;
TableCheck.expression is defined as optional, so this can throw. Additionally, at least Postgres
populates TableCheck.columnNames, which provides a safer way to detect referenced columns than
substring matching.

src/schema-builder/RdbmsSchemaBuilder.ts[250-307]
src/schema-builder/table/TableCheck.ts[14-37]
src/driver/postgres/PostgresQueryRunner.ts[4218-4231]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`dropIndicesAndConstraintsForRemovedColumns()` determines which CHECK constraints reference soon-to-be-dropped columns by using `check.expression.includes(colName)`. This is unsafe because `TableCheck.expression` is optional (can be `undefined`, causing a crash), and it is logically incorrect because substring matching is not SQL-identifier aware (false positives/negatives).

### Issue Context
Several drivers (e.g., Postgres) already populate `TableCheck.columnNames`, which is a structured way to know which columns a CHECK constraint references.

### Fix Focus Areas
- src/schema-builder/RdbmsSchemaBuilder.ts[292-305]
- src/schema-builder/table/TableCheck.ts[14-37]
- src/driver/postgres/PostgresQueryRunner.ts[4218-4231]

### Suggested fix
1) Prefer structured matching:
- If `check.columnNames?.length`, drop when `check.columnNames` intersects `droppedColumnNames`.
2) Only if `columnNames` is unavailable, fall back to expression-based detection, but:
- Guard `check.expression` (skip or treat as non-match when missing)
- Use a safer identifier match (e.g., word-boundary/quoted-identifier aware regex) rather than plain substring.

This prevents crashes and avoids dropping unrelated CHECK constraints while still reliably removing those that block column drops.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. No tests for unique/check drops 📘 Rule violation ☼ Reliability
Description
The PR adds logic to drop unique and check constraints for soon-to-be-removed columns, but there is
no corresponding functional test coverage for these new cases, increasing regression risk.
Code

src/schema-builder/RdbmsSchemaBuilder.ts[R282-289]

+        const uniquesToDrop = table.uniques.filter((unique) =>
+            unique.columnNames.some((colName) => droppedColumnNames.includes(colName))
+        )
+        if (uniquesToDrop.length > 0) {
+            this.dataSource.logger.logSchemaBuild(
+                `dropping unique constraints from table "${table.name}" because they reference dropped columns`,
+            )
+            await this.queryRunner.dropUniqueConstraints(table, uniquesToDrop)
Evidence
PR Compliance ID 3 expects issue fixes to live in the functional test suite. The diff adds new
behavior for dropping unique/check constraints, while the existing related functional test asserts
only index removal when dropping a column and does not cover unique/check constraints.

Rule 3: Prefer functional tests over per-issue tests
src/schema-builder/RdbmsSchemaBuilder.ts[282-305]
test/functional/schema-builder/column/drop/drop-column-with-index/drop-column-with-index.test.ts[23-47]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
New schema sync behavior drops unique and check constraints referencing removed columns, but existing functional tests only cover dropping an index when dropping a column.

## Issue Context
`dropIndicesAndConstraintsForRemovedColumns()` now includes dropping `table.uniques` and `table.checks` when they reference columns being removed. There is an existing functional test for dropping a column with an index, but it does not assert unique/check constraint behavior.

## Fix Focus Areas
- src/schema-builder/RdbmsSchemaBuilder.ts[272-305]
- test/functional/schema-builder/column/drop/drop-column-with-index/drop-column-with-index.test.ts[23-47]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


  • Author self-review: I have reviewed the code review findings, and addressed the relevant ones.

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

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

Labels

Compliance violation needs-triage PR needs issue link triage

Development

Successfully merging this pull request may close these issues.

2 participants