Skip to content

feat(QueryRunner): add ifExists parameter to all drop methods#12121

Merged
pkuczynski merged 10 commits intomasterfrom
feat/add-if-exists-to-all-drop-methods
Mar 9, 2026
Merged

feat(QueryRunner): add ifExists parameter to all drop methods#12121
pkuczynski merged 10 commits intomasterfrom
feat/add-if-exists-to-all-drop-methods

Conversation

@pkuczynski
Copy link
Member

  • Add optional ifExists parameter to all drop methods that previously lacked it: dropColumn, dropColumns, dropIndex, dropIndices, dropPrimaryKey, dropForeignKey, dropForeignKeys, dropUniqueConstraint, dropUniqueConstraints, dropCheckConstraint, dropCheckConstraints, dropExclusionConstraint, dropExclusionConstraints
  • Each driver uses the best available strategy: SQL IF EXISTS where the database supports it, client-side existence checks as fallback
  • Update Query Runner API docs with all new signatures and parameters
  • Add test coverage for all new ifExists parameters

Closes #11450

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

Review Summary by Qodo

Add ifExists parameter to all drop methods across all database drivers

✨ Enhancement 🧪 Tests 📝 Documentation

Grey Divider

Walkthroughs

Description
• Add optional ifExists parameter to all drop methods across all database drivers that previously
  lacked it: dropColumn, dropColumns, dropIndex, dropIndices, dropPrimaryKey,
  dropForeignKey, dropForeignKeys, dropUniqueConstraint, dropUniqueConstraints,
  dropCheckConstraint, dropCheckConstraints, dropExclusionConstraint,
  dropExclusionConstraints, and dropView
• Standardize parameter naming from ifNotExist/ifExist to ifNotExists/ifExists across all
  QueryRunner implementations for consistency
• Implement database-specific strategies: SQL IF EXISTS clause where supported (PostgreSQL,
  CockroachDB, SQLite, MySQL, Aurora MySQL), client-side existence checks as fallback for databases
  without native support (Oracle, SAP HANA, Spanner, SQL Server)
• Update QueryRunner interface signatures with new ifExists parameters and improved JSDoc comments
• Add comprehensive test coverage for all new ifExists parameters across drop methods
• Update API documentation with all new method signatures and parameter descriptions
• Fix JSDoc comments in several drivers (Oracle, SQLite, Spanner) for accuracy
Diagram
flowchart LR
  QR["QueryRunner Interface"]
  QR -- "standardize parameters" --> Drivers["Database Drivers"]
  Drivers --> PG["PostgreSQL"]
  Drivers --> CDB["CockroachDB"]
  Drivers --> MySQL["MySQL/Aurora"]
  Drivers --> SQLite["SQLite"]
  Drivers --> Oracle["Oracle"]
  Drivers --> SAP["SAP HANA"]
  Drivers --> Spanner["Spanner"]
  Drivers --> MSSQL["SQL Server"]
  Drivers --> Mongo["MongoDB"]
  PG -- "add ifExists" --> DropMethods["Drop Methods"]
  CDB -- "add ifExists" --> DropMethods
  MySQL -- "add ifExists" --> DropMethods
  SQLite -- "add ifExists" --> DropMethods
  Oracle -- "add ifExists" --> DropMethods
  SAP -- "add ifExists" --> DropMethods
  Spanner -- "add ifExists" --> DropMethods
  MSSQL -- "add ifExists" --> DropMethods
  Mongo -- "add ifExists" --> DropMethods
  DropMethods --> Tests["Test Coverage"]
  DropMethods --> Docs["API Documentation"]
Loading

Grey Divider

File Changes

1. src/driver/postgres/PostgresQueryRunner.ts ✨ Enhancement +106/-43

Add ifExists parameter to PostgreSQL drop methods

• Renamed parameter ifNotExist to ifNotExists and ifExist to ifExists across all methods for
 consistency
• Added ifExists parameter to drop methods: dropColumn, dropColumns, dropIndex,
 dropIndices, dropPrimaryKey, dropForeignKey, dropForeignKeys, dropUniqueConstraint,
 dropUniqueConstraints, dropCheckConstraint, dropCheckConstraints, dropExclusionConstraint,
 dropExclusionConstraints, and dropView
• Updated SQL generation methods to include IF EXISTS clause when ifExists parameter is true
• Modified drop methods to pass ifExists parameter to their corresponding SQL generation methods

src/driver/postgres/PostgresQueryRunner.ts


2. src/driver/cockroachdb/CockroachQueryRunner.ts ✨ Enhancement +80/-38

Add ifExists parameter to CockroachDB drop methods

• Renamed parameter ifNotExist to ifNotExists and ifExist to ifExists for consistency
• Added ifExists parameter to drop methods: dropColumn, dropColumns, dropIndex,
 dropIndices, dropPrimaryKey, dropForeignKey, dropForeignKeys, dropUniqueConstraint,
 dropUniqueConstraints, dropCheckConstraint, dropCheckConstraints, dropExclusionConstraint,
 dropExclusionConstraints, and dropView
• Updated dropView to conditionally use DROP VIEW IF EXISTS syntax when ifExists is true
• Modified SQL generation methods to include IF EXISTS clause in generated queries

src/driver/cockroachdb/CockroachQueryRunner.ts


3. src/driver/sqlserver/SqlServerQueryRunner.ts ✨ Enhancement +87/-38

Add ifExists parameter to SQL Server drop methods

• Renamed parameter ifNotExist to ifNotExists and ifExist to ifExists across all methods
• Added ifExists parameter to drop methods: dropColumn, dropColumns, dropIndex,
 dropIndices, dropPrimaryKey, dropForeignKey, dropForeignKeys, dropUniqueConstraint,
 dropUniqueConstraints, dropCheckConstraint, dropCheckConstraints, dropExclusionConstraint,
 dropExclusionConstraints, and dropView
• Enhanced dropView to gracefully handle non-existent views when ifExists is true using
 .catch() fallback
• Added early return logic for non-existent constraints and columns when ifExists is true
• Updated dropViewSql to generate DROP VIEW IF EXISTS syntax

src/driver/sqlserver/SqlServerQueryRunner.ts


View more (20)
4. src/driver/oracle/OracleQueryRunner.ts ✨ Enhancement +73/-31

Add ifExists parameter to Oracle drop methods

• Renamed parameter ifNotExist to ifNotExists and ifExist to ifExists for consistency
• Added ifExists parameter to drop methods: dropColumn, dropColumns, dropIndex,
 dropIndices, dropPrimaryKey, dropForeignKey, dropForeignKeys, dropUniqueConstraint,
 dropUniqueConstraints, dropCheckConstraint, dropCheckConstraints, dropExclusionConstraint,
 dropExclusionConstraints, and dropView
• Enhanced dropView to gracefully handle non-existent views when ifExists is true
• Added early return logic for non-existent constraints and columns when ifExists is true
• Fixed JSDoc comment from "Creates a unique constraints" to "Drops unique constraints"

src/driver/oracle/OracleQueryRunner.ts


5. src/driver/sqlite-abstract/AbstractSqliteQueryRunner.ts ✨ Enhancement +94/-34

Add ifExists parameter to SQLite drop methods

• Renamed parameter ifNotExist to ifNotExists and ifExist to ifExists across all methods
• Added ifExists parameter to drop methods: dropColumn, dropColumns, dropIndex,
 dropIndices, dropPrimaryKey, dropForeignKey, dropForeignKeys, dropUniqueConstraint,
 dropUniqueConstraints, dropCheckConstraint, dropCheckConstraints, dropExclusionConstraint,
 dropExclusionConstraints, and dropView
• Updated SQL generation methods dropTableSql, dropViewSql, and dropIndexSql to include `IF
 EXISTS` clause
• Added early return logic for non-existent constraints and columns when ifExists is true
• Fixed JSDoc comment from "Creates a unique constraints" to "Drops unique constraints"

src/driver/sqlite-abstract/AbstractSqliteQueryRunner.ts


6. src/driver/sap/SapQueryRunner.ts ✨ Enhancement +78/-31

Add ifExists parameter to SAP HANA drop methods

• Renamed parameter ifNotExist to ifNotExists and ifExist to ifExists for consistency
• Added ifExists parameter to drop methods: dropColumn, dropColumns, dropIndex,
 dropIndices, dropPrimaryKey, dropForeignKey, dropForeignKeys, dropUniqueConstraint,
 dropUniqueConstraints, dropCheckConstraint, dropCheckConstraints, dropExclusionConstraint,
 dropExclusionConstraints, and dropView
• Enhanced dropView to check view existence when ifExists is true using loadViews method
• Added early return logic for non-existent constraints and columns when ifExists is true
• Updated dropTableSql to generate DROP TABLE IF EXISTS syntax

src/driver/sap/SapQueryRunner.ts


7. src/driver/spanner/SpannerQueryRunner.ts ✨ Enhancement +82/-29

Add ifExists parameter to Spanner drop methods

• Renamed parameter ifNotExist to ifNotExists and ifExist to ifExists across all methods
• Added ifExists parameter to drop methods: dropColumn, dropColumns, dropIndex,
 dropIndices, dropPrimaryKey, dropForeignKey, dropForeignKeys, dropUniqueConstraint,
 dropUniqueConstraints, dropCheckConstraint, dropCheckConstraints, dropExclusionConstraint,
 dropExclusionConstraints, and dropView
• Enhanced dropDatabase to check database existence when ifExists is true instead of using SQL
 syntax
• Enhanced dropView to check view existence when ifExists is true using loadViews method
• Added early return logic for unsupported operations when ifExists is true
• Fixed JSDoc comment from "Creates a new primary key" to "Drops a primary key"

src/driver/spanner/SpannerQueryRunner.ts


8. src/driver/mongodb/MongoQueryRunner.ts ✨ Enhancement +43/-9

Add ifExists parameter to MongoDB drop methods

• Renamed parameter ifNotExist to ifNotExists and ifExist to ifExists for consistency
• Added ifExists parameter to all drop methods: dropColumn, dropColumns, dropIndex,
 dropIndices, dropPrimaryKey, dropForeignKey, dropForeignKeys, dropUniqueConstraint,
 dropUniqueConstraints, dropCheckConstraint, dropCheckConstraints, dropExclusionConstraint,
 dropExclusionConstraints, and dropView
• All methods continue to throw TypeORMError as MongoDB does not support schema updates

src/driver/mongodb/MongoQueryRunner.ts


9. test/functional/query-runner/drop-primary-key.test.ts 🧪 Tests +20/-0

Add test for ifExists parameter in drop primary key

• Added new test case to verify that dropping a non-existent primary key with ifExists parameter
 does not throw an error
• Test skips CockroachDB and Spanner drivers which do not support primary key dropping

test/functional/query-runner/drop-primary-key.test.ts


10. test/functional/query-runner/drop-check-constraint.test.ts 🧪 Tests +16/-0

Add test for ifExists parameter in drop check constraint

• Added new test case to verify that dropping a non-existent check constraint with ifExists
 parameter does not throw an error
• Test skips MySQL family drivers which do not support check constraints

test/functional/query-runner/drop-check-constraint.test.ts


11. test/functional/query-runner/drop-exclusion-constraint.test.ts 🧪 Tests +13/-0

Add test for ifExists parameter in drop exclusion constraint

• Added new test case to verify that dropping a non-existent exclusion constraint with ifExists
 parameter does not throw an error

test/functional/query-runner/drop-exclusion-constraint.test.ts


12. test/functional/query-runner/drop-foreign-key.test.ts 🧪 Tests +13/-0

Add test for ifExists parameter in drop foreign key

• Added new test case to verify that dropping a non-existent foreign key with ifExists parameter
 does not throw an error

test/functional/query-runner/drop-foreign-key.test.ts


13. test/functional/query-runner/drop-column.test.ts 🧪 Tests +13/-0

Add test for ifExists parameter in drop column

• Added new test case to verify that dropping a non-existent column with ifExists parameter does
 not throw an error

test/functional/query-runner/drop-column.test.ts


14. test/functional/query-runner/drop-unique-constraint.test.ts 🧪 Tests +13/-0

Add test for ifExists parameter in drop unique constraint

• Added new test case to verify that dropping a non-existent unique constraint with ifExists
 parameter does not throw an error

test/functional/query-runner/drop-unique-constraint.test.ts


15. src/driver/aurora-mysql/AuroraMysqlQueryRunner.ts ✨ Enhancement +75/-27

Add ifExists parameter to all drop methods in Aurora MySQL

• Standardized parameter naming from ifNotExist/ifExist to ifNotExists/ifExists across all
 methods
• Added ifExists parameter to dropView, dropColumn, dropColumns, dropPrimaryKey,
 dropUniqueConstraint, dropUniqueConstraints, dropCheckConstraint, dropCheckConstraints,
 dropExclusionConstraint, dropExclusionConstraints, dropForeignKey, dropForeignKeys,
 dropIndex, and dropIndices methods
• Implemented client-side existence checks that return early when ifExists is true and the target
 doesn't exist
• Updated dropViewSql helper method to accept ifExists parameter and generate IF EXISTS clause

src/driver/aurora-mysql/AuroraMysqlQueryRunner.ts


16. src/driver/mysql/MysqlQueryRunner.ts ✨ Enhancement +77/-25

Add ifExists parameter to all drop methods in MySQL

• Standardized parameter naming from ifNotExist/ifExist to ifNotExists/ifExists across all
 methods
• Added ifExists parameter to dropView, dropColumn, dropColumns, dropPrimaryKey,
 dropUniqueConstraint, dropUniqueConstraints, dropCheckConstraint, dropCheckConstraints,
 dropExclusionConstraint, dropExclusionConstraints, dropForeignKey, dropForeignKeys,
 dropIndex, and dropIndices methods
• Implemented early returns when ifExists is true and the target doesn't exist, preventing errors
• Updated dropView to use DROP VIEW IF EXISTS SQL syntax when ifExists is true

src/driver/mysql/MysqlQueryRunner.ts


17. src/query-runner/QueryRunner.ts ✨ Enhancement +31/-12

Update QueryRunner interface with ifExists parameters

• Standardized parameter naming from ifNotExist/ifExist to ifNotExists/ifExists in interface
 signatures
• Added ifExists parameter to all drop method signatures: dropView, dropColumn, dropColumns,
 dropPrimaryKey, dropUniqueConstraint, dropUniqueConstraints, dropCheckConstraint,
 dropCheckConstraints, dropExclusionConstraint, dropExclusionConstraints, dropForeignKey,
 dropForeignKeys, dropIndex, and dropIndices
• Improved JSDoc comments for consistency and clarity

src/query-runner/QueryRunner.ts


18. test/functional/query-runner/create-and-drop-database.test.ts 🧪 Tests +9/-0

Add test for dropDatabase with ifExists parameter

• Added test case to verify that dropping a non-existent database with ifExists set to true does
 not throw an error

test/functional/query-runner/create-and-drop-database.test.ts


19. test/functional/query-runner/create-and-drop-schema.test.ts 🧪 Tests +9/-0

Add test for dropSchema with ifExists parameter

• Added test case to verify that dropping a non-existent schema with ifExists set to true does not
 throw an error

test/functional/query-runner/create-and-drop-schema.test.ts


20. test/functional/query-runner/drop-table.test.ts 🧪 Tests +9/-0

Add test for dropTable with ifExists parameter

• Added test case to verify that dropping a non-existent table with ifExists set to true does not
 throw an error

test/functional/query-runner/drop-table.test.ts


21. test/functional/query-runner/drop-view.test.ts 🧪 Tests +9/-0

Add test for dropView with ifExists parameter

• Added test case to verify that dropping a non-existent view with ifExists set to true does not
 throw an error

test/functional/query-runner/drop-view.test.ts


22. test/functional/query-runner/drop-index.test.ts 🧪 Tests +9/-0

Add test for dropIndex with ifExists parameter

• Added test case to verify that dropping a non-existent index with ifExists set to true does not
 throw an error

test/functional/query-runner/drop-index.test.ts


23. docs/docs/migrations/09-api.md 📝 Documentation +116/-27

Update API documentation with ifExists parameters

• Updated all method signatures to use standardized ifNotExists/ifExists parameter names
• Enhanced parameter descriptions to clarify behavior when ifExists is true (silently ignores
 non-existent targets)
• Added documentation for dropView method with ifExists parameter
• Added documentation for dropExclusionConstraint and dropExclusionConstraints methods with
 ifExists parameter
• Improved grammar and consistency in method descriptions and notes

docs/docs/migrations/09-api.md


Grey Divider

Qodo Logo

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 7, 2026

commit: adc30ed

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

qodo-free-for-open-source-projects bot commented Mar 7, 2026

Code Review by Qodo

🐞 Bugs (15) 📘 Rule violations (5) 📎 Requirement gaps (0)

Grey Divider


Action required

1. dropView() catch-all hides errors📘 Rule violation ⛯ Reliability
Description
dropView() catches all errors from getCachedView() and converts them into a "does not exist"
path (or silently returns with ifExists), which can mask real failures like permission/connection
issues. This introduces an abnormal defensive try/catch block instead of handling only the
expected "missing view" case.
Code

src/driver/postgres/PostgresQueryRunner.ts[R750-756]

+        let view: View
+        try {
+            view = await this.getCachedView(viewName)
+        } catch {
+            if (ifExists) return
+            throw new TypeORMError(`View "${viewName}" does not exist.`)
+        }
Evidence
Compliance rule 4 disallows adding abnormal defensive try/catch blocks; the new code adds a bare
catch that treats any thrown error as "view missing" (or ignores it entirely when ifExists is
true).

Rule 4: Remove AI-generated noise
src/driver/postgres/PostgresQueryRunner.ts[750-756]

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

## Issue description
`dropView()` currently uses a catch-all `catch { ... }` around `getCachedView()`. This can incorrectly treat unexpected errors (permissions, connectivity, query errors) as "view does not exist" or silently ignore them when `ifExists` is true.
## Issue Context
The new `ifExists` behavior should only suppress the specific "view is missing" scenario, not all failures.
## Fix Focus Areas
- src/driver/postgres/PostgresQueryRunner.ts[750-756]

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


2. Oracle .catch(()=>undefined) swallows errors 📘 Rule violation ⛯ Reliability
Description
When ifExists is true, dropView() uses .catch(() => undefined) which suppresses any error from
getCachedView() and returns early if view is falsy. This is an abnormal defensive
error-swallowing pattern that can hide legitimate failures.
Code

src/driver/oracle/OracleQueryRunner.ts[R677-680]

+        const view = ifExists
+            ? await this.getCachedView(viewName).catch(() => undefined)
+            : await this.getCachedView(viewName)
+        if (!view) return
Evidence
Compliance rule 4 disallows abnormal defensive error handling; the new .catch(() => undefined)
suppresses all errors, not just the expected "missing view" case when ifExists is enabled.

Rule 4: Remove AI-generated noise
src/driver/oracle/OracleQueryRunner.ts[677-680]

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

## Issue description
Oracle `dropView()` suppresses all errors from `getCachedView()` when `ifExists` is true by using `.catch(() => undefined)`, which can mask legitimate failures.
## Issue Context
`ifExists` should only change behavior for non-existent objects; it should not hide unexpected runtime errors.
## Fix Focus Areas
- src/driver/oracle/OracleQueryRunner.ts[677-680]

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


3. dropView ifExists still throws 🐞 Bug ✓ Correctness
Description
In multiple drivers, dropView(name, true) still calls getCachedView() unconditionally, which
throws when the view does not exist, so ifExists does not provide the promised idempotent
behavior.
Code

src/driver/mysql/MysqlQueryRunner.ts[R619-622]

+    async dropView(target: View | string, ifExists?: boolean): Promise<void> {
 const viewName = InstanceChecker.isView(target) ? target.name : target
 const view = await this.getCachedView(viewName)
Evidence
getCachedView throws a TypeORMError when the view is missing. These drivers invoke
getCachedView before any ifExists logic, so the call fails early and never reaches the `DROP
VIEW IF EXISTS ...` query path.

src/driver/mysql/MysqlQueryRunner.ts[619-632]
src/driver/aurora-mysql/AuroraMysqlQueryRunner.ts[457-465]
src/driver/cockroachdb/CockroachQueryRunner.ts[852-863]
src/driver/sqlite-abstract/AbstractSqliteQueryRunner.ts[449-457]
src/query-runner/BaseQueryRunner.ts[296-306]

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

## Issue description
`dropView(viewName, true)` should be a no-op when the view does not exist. Several drivers still call `getCachedView(viewName)` unconditionally, which throws before the `ifExists` behavior can take effect.
### Issue Context
`BaseQueryRunner.getCachedView()` throws a `TypeORMError` when the view is not found, so drivers must not call it when `ifExists` is intended to suppress &amp;amp;amp;amp;amp;amp;amp;quot;not found&amp;amp;amp;amp;amp;amp;amp;quot;.
### Fix Focus Areas
- src/driver/mysql/MysqlQueryRunner.ts[619-636]
- src/driver/aurora-mysql/AuroraMysqlQueryRunner.ts[457-467]
- src/driver/cockroachdb/CockroachQueryRunner.ts[852-867]
- src/driver/sqlite-abstract/AbstractSqliteQueryRunner.ts[449-460]
- src/query-runner/BaseQueryRunner.ts[296-306]
### Implementation sketch
- If `ifExists` is true:
- `const foundViews = await this.loadViews([viewName])`; if none found, `return`.
- Otherwise proceed to `getCachedView(viewName)` and metadata cleanup + drop.
- Ensure any DB/query errors during `loadViews` still throw (do not swallow them).

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


View more (14)
4. dropPrimaryKey ifExists fails 🐞 Bug ✓ Correctness
Description
Postgres (and Cockroach) dropPrimaryKeySql throws when table.primaryColumns is empty, even if
ifExists=true, violating the documented behavior that ifExists should silently ignore missing
primary keys.
Code

src/driver/postgres/PostgresQueryRunner.ts[R4716-4719]

+    protected dropPrimaryKeySql(table: Table, ifExists?: boolean): Query {
if (!table.primaryColumns.length)
 throw new TypeORMError(`Table ${table} has no primary keys.`)
Evidence
dropPrimaryKey passes ifExists into dropPrimaryKeySql, but dropPrimaryKeySql still throws if
there are no primary columns. This directly contradicts the updated API docs stating ifExists=true
should ignore missing primary keys; Cockroach has the same unconditional throw pattern.

src/driver/postgres/PostgresQueryRunner.ts[2778-2787]
src/driver/postgres/PostgresQueryRunner.ts[4716-4719]
src/driver/cockroachdb/CockroachQueryRunner.ts[4131-4134]
docs/docs/migrations/09-api.md[394-400]

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

## Issue description
`dropPrimaryKey(..., ifExists=true)` should not throw when the table has no primary key, but Postgres/Cockroach still throw in `dropPrimaryKeySql` when `primaryColumns` is empty.
## Issue Context
The PR added an `ifExists` parameter and updated docs to claim missing primary keys are ignored when `ifExists=true`.
## Fix Focus Areas
- src/driver/postgres/PostgresQueryRunner.ts[2778-2792]
- src/driver/postgres/PostgresQueryRunner.ts[4716-4732]
- src/driver/cockroachdb/CockroachQueryRunner.ts[2509-2524]
- src/driver/cockroachdb/CockroachQueryRunner.ts[4131-4145]
- docs/docs/migrations/09-api.md[392-401]

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


5. dropPrimaryKey ifExists fails 🐞 Bug ✓ Correctness
Description
Postgres (and Cockroach) dropPrimaryKeySql throws when table.primaryColumns is empty, even if
ifExists=true, violating the documented behavior that ifExists should silently ignore missing
primary keys.
Code

src/driver/postgres/PostgresQueryRunner.ts[R4716-4719]

+    protected dropPrimaryKeySql(table: Table, ifExists?: boolean): Query {
if (!table.primaryColumns.length)
  throw new TypeORMError(`Table ${table} has no primary keys.`)
Evidence
dropPrimaryKey passes ifExists into dropPrimaryKeySql, but dropPrimaryKeySql still throws if
there are no primary columns. This directly contradicts the updated API docs stating ifExists=true
should ignore missing primary keys; Cockroach has the same unconditional throw pattern.

src/driver/postgres/PostgresQueryRunner.ts[2778-2787]
src/driver/postgres/PostgresQueryRunner.ts[4716-4719]
src/driver/cockroachdb/CockroachQueryRunner.ts[4131-4134]
docs/docs/migrations/09-api.md[394-400]

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

## Issue description
`dropPrimaryKey(..., ifExists=true)` should not throw when the table has no primary key, but Postgres/Cockroach still throw in `dropPrimaryKeySql` when `primaryColumns` is empty.
## Issue Context
The PR added an `ifExists` parameter and updated docs to claim missing primary keys are ignored when `ifExists=true`.
## Fix Focus Areas
- src/driver/postgres/PostgresQueryRunner.ts[2778-2792]
- src/driver/postgres/PostgresQueryRunner.ts[4716-4732]
- src/driver/cockroachdb/CockroachQueryRunner.ts[2509-2524]
- src/driver/cockroachdb/CockroachQueryRunner.ts[4131-4145]
- docs/docs/migrations/09-api.md[392-401]

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


6. Postgres ifExists still throws🐞 Bug ✓ Correctness
Description
PostgresQueryRunner adds ifExists parameters but still throws before executing SQL when the
target view/column/index/constraint is missing (and dropView always throws due to
getCachedView). This violates the new API contract and will fail the added tests that call drop*
with ifExists=true on non-existent objects.
Code

src/driver/postgres/PostgresQueryRunner.ts[R747-755]

+    async dropView(target: View | string, ifExists?: boolean): Promise<void> {
const viewName = InstanceChecker.isView(target) ? target.name : target
const view = await this.getCachedView(viewName)
const upQueries: Query[] = []
const downQueries: Query[] = []
upQueries.push(await this.deleteViewDefinitionSql(view))
-        upQueries.push(this.dropViewSql(view))
+        upQueries.push(this.dropViewSql(view, ifExists))
downQueries.push(await this.insertViewDefinitionSql(view))
Evidence
dropView(..., ifExists) still calls getCachedView() unconditionally, and getCachedView()
throws when a view does not exist—so ifExists cannot work. Other Postgres drop methods similarly
throw on missing objects regardless of ifExists, contradicting the newly-added tests expecting no
throw.

src/driver/postgres/PostgresQueryRunner.ts[742-758]
src/query-runner/BaseQueryRunner.ts[292-306]
src/driver/postgres/PostgresQueryRunner.ts[2450-2456]
src/driver/postgres/PostgresQueryRunner.ts[3260-3263]
test/functional/query-runner/drop-view.test.ts[69-75]

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

## Issue description
`PostgresQueryRunner` methods now accept `ifExists?: boolean`, but several still throw `TypeORMError` when the target object is missing (and `dropView` throws via `getCachedView`). This violates the new contract and breaks functional tests that call drop operations on non-existent objects with `ifExists=true`.
### Issue Context
- `BaseQueryRunner.getCachedView()` throws when a view is not found.
- New functional tests expect `dropView(&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;non_existent_view&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;, true)` (and other drop* with `ifExists=true`) to not throw.
### Fix Focus Areas
- src/driver/postgres/PostgresQueryRunner.ts[742-758]
- src/driver/postgres/PostgresQueryRunner.ts[2442-2457]
- src/driver/postgres/PostgresQueryRunner.ts[3249-3264]
- src/driver/postgres/PostgresQueryRunner.ts[2843-2858]
- src/driver/postgres/PostgresQueryRunner.ts[3024-3041]
- src/query-runner/BaseQueryRunner.ts[292-306]

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


7. Postgres ifExists still throws🐞 Bug ✓ Correctness
Description
PostgresQueryRunner adds ifExists parameters but still throws before executing SQL when the
target view/column/index/constraint is missing (and dropView always throws due to
getCachedView). This violates the new API contract and will fail the added tests that call drop*
with ifExists=true on non-existent objects.
Code

src/driver/postgres/PostgresQueryRunner.ts[R747-755]

+    async dropView(target: View | string, ifExists?: boolean): Promise<void> {
const viewName = InstanceChecker.isView(target) ? target.name : target
const view = await this.getCachedView(viewName)
const upQueries: Query[] = []
const downQueries: Query[] = []
upQueries.push(await this.deleteViewDefinitionSql(view))
-        upQueries.push(this.dropViewSql(view))
+        upQueries.push(this.dropViewSql(view, ifExists))
downQueries.push(await this.insertViewDefinitionSql(view))
Evidence
dropView(..., ifExists) still calls getCachedView() unconditionally, and getCachedView()
throws when a view does not exist—so ifExists cannot work. Other Postgres drop methods similarly
throw on missing objects regardless of ifExists, contradicting the newly-added tests expecting no
throw.

src/driver/postgres/PostgresQueryRunner.ts[742-758]
src/query-runner/BaseQueryRunner.ts[292-306]
src/driver/postgres/PostgresQueryRunner.ts[2450-2456]
src/driver/postgres/PostgresQueryRunner.ts[3260-3263]
test/functional/query-runner/drop-view.test.ts[69-75]

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

## Issue description
`PostgresQueryRunner` methods now accept `ifExists?: boolean`, but several still throw `TypeORMError` when the target object is missing (and `dropView` throws via `getCachedView`). This violates the new contract and breaks functional tests that call drop operations on non-existent objects with `ifExists=true`.
### Issue Context
- `BaseQueryRunner.getCachedView()` throws when a view is not found.
- New functional tests expect `dropView(&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;non_existent_view&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;, true)` (and other drop* with `ifExists=true`) to not throw.
### Fix Focus Areas
- src/driver/postgres/PostgresQueryRunner.ts[742-758]
- src/driver/postgres/PostgresQueryRunner.ts[2442-2457]
- src/driver/postgres/PostgresQueryRunner.ts[3249-3264]
- src/driver/postgres/PostgresQueryRunner.ts[2843-2858]
- src/driver/postgres/PostgresQueryRunner.ts[3024-3041]
- src/query-runner/BaseQueryRunner.ts[292-306]

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


8. Postgres ifExists still throws🐞 Bug ✓ Correctness
Description
PostgresQueryRunner adds ifExists parameters but still throws before executing SQL when the
target view/column/index/constraint is missing (and dropView always throws due to
getCachedView). This violates the new API contract and will fail the added tests that call drop*
with ifExists=true on non-existent objects.
Code

src/driver/postgres/PostgresQueryRunner.ts[R747-755]

+    async dropView(target: View | string, ifExists?: boolean): Promise<void> {
const viewName = InstanceChecker.isView(target) ? target.name : target
const view = await this.getCachedView(viewName)
const upQueries: Query[] = []
const downQueries: Query[] = []
upQueries.push(await this.deleteViewDefinitionSql(view))
-        upQueries.push(this.dropViewSql(view))
+        upQueries.push(this.dropViewSql(view, ifExists))
downQueries.push(await this.insertViewDefinitionSql(view))
Evidence
dropView(..., ifExists) still calls getCachedView() unconditionally, and getCachedView()
throws when a view does not exist—so ifExists cannot work. Other Postgres drop methods similarly
throw on missing objects regardless of ifExists, contradicting the newly-added tests expecting no
throw.

src/driver/postgres/PostgresQueryRunner.ts[742-758]
src/query-runner/BaseQueryRunner.ts[292-306]
src/driver/postgres/PostgresQueryRunner.ts[2450-2456]
src/driver/postgres/PostgresQueryRunner.ts[3260-3263]
test/functional/query-runner/drop-view.test.ts[69-75]

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

## Issue description
`PostgresQueryRunner` methods now accept `ifExists?: boolean`, but several still throw `TypeORMError` when the target object is missing (and `dropView` throws via `getCachedView`). This violates the new contract and breaks functional tests that call drop operations on non-existent objects with `ifExists=true`.
### Issue Context
- `BaseQueryRunner.getCachedView()` throws when a view is not found.
- New functional tests expect `dropView(&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;non_existent_view&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;, true)` (and other drop* with `ifExists=true`) to not throw.
### Fix Focus Areas
- src/driver/postgres/PostgresQueryRunner.ts[742-758]
- src/driver/postgres/PostgresQueryRunner.ts[2442-2457]
- src/driver/postgres/PostgresQueryRunner.ts[3249-3264]
- src/driver/postgres/PostgresQueryRunner.ts[2843-2858]
- src/driver/postgres/PostgresQueryRunner.ts[3024-3041]
- src/query-runner/BaseQueryRunner.ts[292-306]

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


9. Postgres ifExists still throws🐞 Bug ✓ Correctness
Description
PostgresQueryRunner adds ifExists parameters but still throws before executing SQL when the
target view/column/index/constraint is missing (and dropView always throws due to
getCachedView). This violates the new API contract and will fail the added tests that call drop*
with ifExists=true on non-existent objects.
Code

src/driver/postgres/PostgresQueryRunner.ts[R747-755]

+    async dropView(target: View | string, ifExists?: boolean): Promise<void> {
const viewName = InstanceChecker.isView(target) ? target.name : target
const view = await this.getCachedView(viewName)
const upQueries: Query[] = []
const downQueries: Query[] = []
upQueries.push(await this.deleteViewDefinitionSql(view))
-        upQueries.push(this.dropViewSql(view))
+        upQueries.push(this.dropViewSql(view, ifExists))
downQueries.push(await this.insertViewDefinitionSql(view))
Evidence
dropView(..., ifExists) still calls getCachedView() unconditionally, and getCachedView()
throws when a view does not exist—so ifExists cannot work. Other Postgres drop methods similarly
throw on missing objects regardless of ifExists, contradicting the newly-added tests expecting no
throw.

src/driver/postgres/PostgresQueryRunner.ts[742-758]
src/query-runner/BaseQueryRunner.ts[292-306]
src/driver/postgres/PostgresQueryRunner.ts[2450-2456]
src/driver/postgres/PostgresQueryRunner.ts[3260-3263]
test/functional/query-runner/drop-view.test.ts[69-75]

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

## Issue description
`PostgresQueryRunner` methods now accept `ifExists?: boolean`, but several still throw `TypeORMError` when the target object is missing (and `dropView` throws via `getCachedView`). This violates the new contract and breaks functional tests that call drop operations on non-existent objects with `ifExists=true`.
### Issue Context
- `BaseQueryRunner.getCachedView()` throws when a view is not found.
- New functional tests expect `dropView(&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;non_existent_view&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;, true)` (and other drop* with `ifExists=true`) to not throw.
### Fix Focus Areas
- src/driver/postgres/PostgresQueryRunner.ts[742-758]
- src/driver/postgres/PostgresQueryRunner.ts[2442-2457]
- src/driver/postgres/PostgresQueryRunner.ts[3249-3264]
- src/driver/postgres/PostgresQueryRunner.ts[2843-2858]
- src/driver/postgres/PostgresQueryRunner.ts[3024-3041]
- src/query-runner/BaseQueryRunner.ts[292-306]

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


10. Cockroach ifExists still throws🐞 Bug ✓ Correctness
Description
CockroachQueryRunner adds ifExists parameters but still throws when a column/index/unique
constraint is not found in table metadata, instead of returning when ifExists=true. This will fail
new tests like dropIndex(..., true) and dropUniqueConstraint(..., true) when the object is
missing.
Code

src/driver/cockroachdb/CockroachQueryRunner.ts[R2918-2924]

async dropIndex(
tableOrName: Table | string,
indexOrName: TableIndex | string,
+        ifExists?: boolean,
): Promise<void> {
const table = InstanceChecker.isTable(tableOrName)
 ? tableOrName
Evidence
Despite the new ifExists parameter, CockroachDB drop methods still throw on missing objects (same
control flow as pre-PR). Tests now explicitly call dropIndex(..., true) expecting no throw, so
this mismatch causes failures.

src/driver/cockroachdb/CockroachQueryRunner.ts[2918-2932]
src/driver/cockroachdb/CockroachQueryRunner.ts[2160-2174]
src/driver/cockroachdb/CockroachQueryRunner.ts[2576-2590]
test/functional/query-runner/drop-index.test.ts[183-189]

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

## Issue description
CockroachDB driver methods accept `ifExists?: boolean` but still throw when a target object is not found, making `ifExists` ineffective and breaking tests.
### Issue Context
New functional tests call methods like `dropIndex(&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;post&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;, &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;non_existent_index&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;, true)` expecting no error.
### Fix Focus Areas
- src/driver/cockroachdb/CockroachQueryRunner.ts[2160-2174]
- src/driver/cockroachdb/CockroachQueryRunner.ts[2918-2933]
- src/driver/cockroachdb/CockroachQueryRunner.ts[2576-2591]

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


11. Cockroach ifExists still throws🐞 Bug ✓ Correctness
Description
CockroachQueryRunner adds ifExists parameters but still throws when a column/index/unique
constraint is not found in table metadata, instead of returning when ifExists=true. This will fail
new tests like dropIndex(..., true) and dropUniqueConstraint(..., true) when the object is
missing.
Code

src/driver/cockroachdb/CockroachQueryRunner.ts[R2918-2924]

async dropIndex(
tableOrName: Table | string,
indexOrName: TableIndex | string,
+        ifExists?: boolean,
): Promise<void> {
const table = InstanceChecker.isTable(tableOrName)
  ? tableOrName
Evidence
Despite the new ifExists parameter, CockroachDB drop methods still throw on missing objects (same
control flow as pre-PR). Tests now explicitly call dropIndex(..., true) expecting no throw, so
this mismatch causes failures.

src/driver/cockroachdb/CockroachQueryRunner.ts[2918-2932]
src/driver/cockroachdb/CockroachQueryRunner.ts[2160-2174]
src/driver/cockroachdb/CockroachQueryRunner.ts[2576-2590]
test/functional/query-runner/drop-index.test.ts[183-189]

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

## Issue description
CockroachDB driver methods accept `ifExists?: boolean` but still throw when a target object is not found, making `ifExists` ineffective and breaking tests.
### Issue Context
New functional tests call methods like `dropIndex(&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;post&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;, &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;non_existent_index&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;, true)` expecting no error.
### Fix Focus Areas
- src/driver/cockroachdb/CockroachQueryRunner.ts[2160-2174]
- src/driver/cockroachdb/CockroachQueryRunner.ts[2918-2933]
- src/driver/cockroachdb/CockroachQueryRunner.ts[2576-2591]

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


12. Cockroach ifExists still throws🐞 Bug ✓ Correctness
Description
CockroachQueryRunner adds ifExists parameters but still throws when a column/index/unique
constraint is not found in table metadata, instead of returning when ifExists=true. This will fail
new tests like dropIndex(..., true) and dropUniqueConstraint(..., true) when the object is
missing.
Code

src/driver/cockroachdb/CockroachQueryRunner.ts[R2918-2924]

async dropIndex(
tableOrName: Table | string,
indexOrName: TableIndex | string,
+        ifExists?: boolean,
): Promise<void> {
const table = InstanceChecker.isTable(tableOrName)
? tableOrName
Evidence
Despite the new ifExists parameter, CockroachDB drop methods still throw on missing objects (same
control flow as pre-PR). Tests now explicitly call dropIndex(..., true) expecting no throw, so
this mismatch causes failures.

src/driver/cockroachdb/CockroachQueryRunner.ts[2918-2932]
src/driver/cockroachdb/CockroachQueryRunner.ts[2160-2174]
src/driver/cockroachdb/CockroachQueryRunner.ts[2576-2590]
test/functional/query-runner/drop-index.test.ts[183-189]

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

## Issue description
CockroachDB driver methods accept `ifExists?: boolean` but still throw when a target object is not found, making `ifExists` ineffective and breaking tests.
### Issue Context
New functional tests call methods like `dropIndex(&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;post&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;, &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;non_existent_index&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;, true)` expecting no error.
### Fix Focus Areas
- src/driver/cockroachdb/CockroachQueryRunner.ts[2160-2174]
- src/driver/cockroachdb/CockroachQueryRunner.ts[2918-2933]
- src/driver/cockroachdb/CockroachQueryRunner.ts[2576-2591]

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


13. Cockroach ifExists still throws🐞 Bug ✓ Correctness
Description
CockroachQueryRunner adds ifExists parameters but still throws when a column/index/unique
constraint is not found in table metadata, instead of returning when ifExists=true. This will fail
new tests like dropIndex(..., true) and dropUniqueConstraint(..., true) when the object is
missing.
Code

src/driver/cockroachdb/CockroachQueryRunner.ts[R2918-2924]

async dropIndex(
tableOrName: Table | string,
indexOrName: TableIndex | string,
+        ifExists?: boolean,
): Promise<void> {
const table = InstanceChecker.isTable(tableOrName)
 ? tableOrName
Evidence
Despite the new ifExists parameter, CockroachDB drop methods still throw on missing objects (same
control flow as pre-PR). Tests now explicitly call dropIndex(..., true) expecting no throw, so
this mismatch causes failures.

src/driver/cockroachdb/CockroachQueryRunner.ts[2918-2932]
src/driver/cockroachdb/CockroachQueryRunner.ts[2160-2174]
src/driver/cockroachdb/CockroachQueryRunner.ts[2576-2590]
test/functional/query-runner/drop-index.test.ts[183-189]

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

## Issue description
CockroachDB driver methods accept `ifExists?: boolean` but still throw when a target object is not found, making `ifExists` ineffective and breaking tests.
### Issue Context
New functional tests call methods like `dropIndex(&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;post&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;, &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;non_existent_index&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;, true)` expecting no error.
### Fix Focus Areas
- src/driver/cockroachdb/CockroachQueryRunner.ts[2160-2174]
- src/driver/cockroachdb/CockroachQueryRunner.ts[2918-2933]
- src/driver/cockroachdb/CockroachQueryRunner.ts[2576-2591]

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


14. SqlServer dropSchema inverted🐞 Bug ✓ Correctness
Description
In SqlServerQueryRunner.dropSchema, the ifExists branch uses `IF SCHEMA_ID(...) IS NULL ... DROP
SCHEMA`, which attempts to drop a schema only when it does not exist. This directly contradicts the
ifExists intent and will fail the new non-existent-schema test on SQL Server.
Code

src/driver/sqlserver/SqlServerQueryRunner.ts[R592-595]

+            const upQuery = ifExists
     ? `IF SCHEMA_ID('${schemaPath}') IS NULL BEGIN EXEC ('DROP SCHEMA "${schemaPath}"') END`
     : `DROP SCHEMA "${schemaPath}"`
 upQueries.push(new Query(upQuery))
Evidence
SCHEMA_ID(name) returns NULL when the schema is missing; the current IS NULL predicate therefore
executes the DROP for non-existent schemas, causing the exact error that ifExists is supposed to
prevent. The added test exercises this path.

src/driver/sqlserver/SqlServerQueryRunner.ts[587-607]
test/functional/query-runner/create-and-drop-schema.test.ts[43-49]

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

## Issue description
`SqlServerQueryRunner.dropSchema(schemaPath, ifExists)` uses an inverted `SCHEMA_ID()` check, causing it to try to drop schemas only when they do *not* exist.
### Issue Context
`SCHEMA_ID(name)` returns NULL for a non-existent schema.
### Fix Focus Areas
- src/driver/sqlserver/SqlServerQueryRunner.ts[587-612]

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


15. SqlServer dropSchema inverted🐞 Bug ✓ Correctness
Description
In SqlServerQueryRunner.dropSchema, the ifExists branch uses `IF SCHEMA_ID(...) IS NULL ... DROP
SCHEMA`, which attempts to drop a schema only when it does not exist. This directly contradicts the
ifExists intent and will fail the new non-existent-schema test on SQL Server.
Code

src/driver/sqlserver/SqlServerQueryRunner.ts[R592-595]

+            const upQuery = ifExists
      ? `IF SCHEMA_ID('${schemaPath}') IS NULL BEGIN EXEC ('DROP SCHEMA "${schemaPath}"') END`
      : `DROP SCHEMA "${schemaPath}"`
  upQueries.push(new Query(upQuery))
Evidence
SCHEMA_ID(name) returns NULL when the schema is missing; the current IS NULL predicate therefore
executes the DROP for non-existent schemas, causing the exact error that ifExists is supposed to
prevent. The added test exercises this path.

src/driver/sqlserver/SqlServerQueryRunner.ts[587-607]
test/functional/query-runner/create-and-drop-schema.test.ts[43-49]

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

## Issue description
`SqlServerQueryRunner.dropSchema(schemaPath, ifExists)` uses an inverted `SCHEMA_ID()` check, causing it to try to drop schemas only when they do *not* exist.
### Issue Context
`SCHEMA_ID(name)` returns NULL for a non-existent schema.
### Fix Focus Areas
- src/driver/sqlserver/SqlServerQueryRunner.ts[587-612]

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


16. SqlServer dropSchema inverted🐞 Bug ✓ Correctness
Description
In SqlServerQueryRunner.dropSchema, the ifExists branch uses `IF SCHEMA_ID(...) IS NULL ... DROP
SCHEMA`, which attempts to drop a schema only when it does not exist. This directly contradicts the
ifExists intent and will fail the new non-existent-schema test on SQL Server.
Code

src/driver/sqlserver/SqlServerQueryRunner.ts[R592-595]

+            const upQuery = ifExists
    ? `IF SCHEMA_ID('${schemaPath}') IS NULL BEGIN EXEC ('DROP SCHEMA "${schemaPath}"') END`
    : `DROP SCHEMA "${schemaPath}"`
upQueries.push(new Query(upQuery))
Evidence
SCHEMA_ID(name) returns NULL when the schema is missing; the current IS NULL predicate therefore
executes the DROP for non-existent schemas, causing the exact error that ifExists is supposed to
prevent. The added test exercises this path.

src/driver/sqlserver/SqlServerQueryRunner.ts[587-607]
test/functional/query-runner/create-and-drop-schema.test.ts[43-49]

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

## Issue description
`SqlServerQueryRunner.dropSchema(schemaPath, ifExists)` uses an inverted `SCHEMA_ID()` check, causing it to try to drop schemas only when they do *not* exist.
### Issue Context
`SCHEMA_ID(name)` returns NULL for a non-existent schema.
### Fix Focus Areas
- src/driver/sqlserver/SqlServerQueryRunner.ts[587-612]

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


17. SqlServer dropSchema inverted🐞 Bug ✓ Correctness
Description
In SqlServerQueryRunner.dropSchema, the ifExists branch uses `IF SCHEMA_ID(...) IS NULL ... DROP
SCHEMA`, which attempts to drop a schema only when it does not exist. This directly contradicts the
ifExists intent and will fail the new non-existent-schema test on SQL Server.
Code

src/driver/sqlserver/SqlServerQueryRunner.ts[R592-595]

+            const upQuery = ifExists
     ? `IF SCHEMA_ID('${schemaPath}') IS NULL BEGIN EXEC ('DROP SCHEMA "${schemaPath}"') END`
     : `DROP SCHEMA "${schemaPath}"`
 upQueries.push(new Query(upQuery))
Evidence
SCHEMA_ID(name) returns NULL when the schema is missing; the current IS NULL predicate therefore
executes the DROP for non-existent schemas, causing the exact error that ifExists is supposed to
prevent. The added test exercises this path.

src/driver/sqlserver/SqlServerQueryRunner.ts[587-607]
test/functional/query-runner/create-and-drop-schema.test.ts[43-49]

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

## Issue description
`SqlServerQueryRunner.dropSchema(schemaPath, ifExists)` uses an inverted `SCHEMA_ID()` check, causing it to try to drop schemas only when they do *not* exist.
### Issue Context
`SCHEMA_ID(name)` returns NULL for a non-existent schema.
### Fix Focus Areas
- src/driver/sqlserver/SqlServerQueryRunner.ts[587-612]

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



Remediation recommended

18. Missing #11450 test comment 📘 Rule violation ⛯ Reliability
Description
New functional tests added for the issue-related change do not include an issue reference comment
(e.g., #11450). This reduces traceability between the reported issue and the validating tests.
Code

test/functional/query-runner/drop-column.test.ts[R244-255]

+    it("should not throw when dropping non-existent column with ifExists", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                const queryRunner = dataSource.createQueryRunner()
+                await queryRunner.dropColumn(
+                    "post",
+                    "non_existent_column",
+                    true,
+                )
+                await queryRunner.release()
+            }),
+        ))
Evidence
The compliance checklist expects issue-related fixes to be covered in test/functional and include
an issue reference comment when applicable. The added test covers ifExists behavior but does not
reference #11450.

Rule 3: Prefer functional tests over per-issue tests
test/functional/query-runner/drop-column.test.ts[244-255]

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 functional tests validating the `ifExists` behavior do not include an issue reference comment for `#11450`, reducing traceability.
## Issue Context
This PR closes `#11450` and adds new functional test coverage. The compliance checklist requests an issue reference comment in functional tests when applicable.
## Fix Focus Areas
- test/functional/query-runner/drop-column.test.ts[244-255]

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


19. dropView hides view errors📘 Rule violation ⛯ Reliability
Description
When ifExists is true, dropView uses .catch(() => undefined) on getCachedView, which
suppresses all errors (not just "view does not exist"). This adds abnormal defensive error-handling
behavior that can mask real failures, conflicting with the requirement to avoid AI-like defensive
try/catch patterns.
Code

src/driver/sqlserver/SqlServerQueryRunner.ts[R806-809]

+        const view = ifExists
+            ? await this.getCachedView(viewName).catch(() => undefined)
+            : await this.getCachedView(viewName)
+        if (!view) return
Evidence
Compliance rule 4 forbids introducing abnormal defensive try/catch patterns; the new ifExists
implementation swallows any exception from getCachedView via a catch-all handler, potentially
hiding non-existence-unrelated errors.

Rule 4: Remove AI-generated noise
src/driver/sqlserver/SqlServerQueryRunner.ts[804-809]

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

## Issue description
`dropView(..., ifExists?: boolean)` currently suppresses all errors from `getCachedView()` by using `.catch(() =&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; undefined)` when `ifExists` is `true`. This can hide real failures (e.g., connectivity/issues in `loadViews`) and is an abnormal defensive pattern.
## Issue Context
`BaseQueryRunner.getCachedView()` throws `TypeORMError` when a view is missing. `ifExists` should only silence that specific missing-view case, not every possible error.
## Fix Focus Areas
- src/driver/sqlserver/SqlServerQueryRunner.ts[804-817]

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


20. dropView hides view errors📘 Rule violation ⛯ Reliability
Description
When ifExists is true, dropView uses .catch(() => undefined) on getCachedView, which
suppresses all errors (not just "view does not exist"). This adds abnormal defensive error-handling
behavior that can mask real failures, conflicting with the requirement to avoid AI-like defensive
try/catch patterns.
Code

src/driver/sqlserver/SqlServerQueryRunner.ts[R806-809]

+        const view = ifExists
+            ? await this.getCachedView(viewName).catch(() => undefined)
+            : await this.getCachedView(viewName)
+        if (!view) return
Evidence
Compliance rule 4 forbids introducing abnormal defensive try/catch patterns; the new ifExists
implementation swallows any exception from getCachedView via a catch-all handler, potentially
hiding non-existence-unrelated errors.

Rule 4: Remove AI-generated noise
src/driver/sqlserver/SqlServerQueryRunner.ts[804-809]

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

## Issue description
`dropView(..., ifExists?: boolean)` currently suppresses all errors from `getCachedView()` by using `.catch(() =&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; undefined)` when `ifExists` is `true`. This can hide real failures (e.g., connectivity/issues in `loadViews`) and is an abnormal defensive pattern.
## Issue Context
`BaseQueryRunner.getCachedView()` throws `TypeORMError` when a view is missing. `ifExists` should only silence that specific missing-view case, not every possible error.
## Fix Focus Areas
- src/driver/sqlserver/SqlServerQueryRunner.ts[804-817]

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


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

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

Persistent review updated to latest commit df77476

1 similar comment
@qodo-free-for-open-source-projects

Persistent review updated to latest commit df77476

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

Persistent review updated to latest commit 0f9ca04

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

Persistent review updated to latest commit 0f9ca04

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Mar 7, 2026

Deploying typeorm with  Cloudflare Pages  Cloudflare Pages

Latest commit: adc30ed
Status: ✅  Deploy successful!
Preview URL: https://b16ebcd8.typeorm.pages.dev
Branch Preview URL: https://feat-add-if-exists-to-all-dr.typeorm.pages.dev

View logs

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

Persistent review updated to latest commit 90875e6

1 similar comment
@qodo-free-for-open-source-projects

Persistent review updated to latest commit 90875e6

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

Persistent review updated to latest commit bd8e9e6

1 similar comment
@qodo-free-for-open-source-projects

Persistent review updated to latest commit bd8e9e6

@coveralls
Copy link

coveralls commented Mar 7, 2026

Coverage Status

coverage: 74.734% (+0.07%) from 74.664%
when pulling 1a6f8d6 on feat/add-if-exists-to-all-drop-methods
into cd72d2a on master.

@pkuczynski pkuczynski changed the title feat(QueryRunner)!: add ifExists parameter to all drop methods feat(QueryRunner): add ifExists parameter to all drop methods Mar 8, 2026
@pkuczynski pkuczynski enabled auto-merge (squash) March 8, 2026 19:09
@qodo-free-for-open-source-projects

Persistent review updated to latest commit 250bd09

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

Persistent review updated to latest commit 1a6f8d6

@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 9, 2026

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

Persistent review updated to latest commit adc30ed

@pkuczynski pkuczynski merged commit 3e47ee2 into master Mar 9, 2026
39 checks passed
@pkuczynski pkuczynski deleted the feat/add-if-exists-to-all-drop-methods branch March 9, 2026 00:27
@github-actions github-actions bot added this to the 1.0 milestone Mar 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

5 participants