Skip to content

fix: emit DROP+ADD COLUMN for incompatible type changes#4

Open
andyc-valstro wants to merge 1 commit into
mainfrom
fix/incompatible-column-type-change-drop-add
Open

fix: emit DROP+ADD COLUMN for incompatible type changes#4
andyc-valstro wants to merge 1 commit into
mainfrom
fix/incompatible-column-type-change-drop-add

Conversation

@andyc-valstro
Copy link
Copy Markdown

Problem

When a column's type changes from a built-in numeric type (like double precision) to a custom enum type, pgschema generates:

ALTER TABLE orders_summary ALTER COLUMN settlement_fx_rate_calc TYPE orders_summary_settlement_fx_rate_calc USING settlement_fx_rate_calc::orders_summary_settlement_fx_rate_calc;

This fails at execution time because PostgreSQL has no cast from double precision to an enum. The same issue occurs for other incompatible transitions like boolean → enum or enum → integer.

Solution

Added a requiresDropAdd(oldType, newType) check in generateColumnSQL() that detects type transitions where no PostgreSQL cast path exists. When detected, the migration emits:

ALTER TABLE ... ALTER COLUMN ... DROP DEFAULT;  -- if column had a default
ALTER TABLE ... DROP COLUMN ...;
ALTER TABLE ... ADD COLUMN ... <new_type>;       -- with NOT NULL / DEFAULT as needed

The detection logic: if one side is a non-text-like built-in type and the other is a custom type (enum/composite/domain), there is no valid cast. Text-like types (text, varchar, char) can still be cast to enums via USING col::enum_type and continue using the existing ALTER TYPE ... USING approach.

Note: This is a data-destructive operation by nature — the column data is lost. However, this is the only correct approach when types are truly incompatible, and mirrors what a DBA would do manually.

Test plan

  • New test case alter_column_incompatible_type covering double precision → enum and enum → integer
  • Existing alter_column_types test still passes (text → enum uses ALTER TYPE USING)
  • Full diff test suite passes (140+ tests)
  • Full integration test suite (TestPlanAndApply) passes

Made with Cursor

When a column's type changes between incompatible types (e.g. double
precision → enum, or enum → integer), ALTER COLUMN ... TYPE ... USING
fails because PostgreSQL has no cast path. Detect these transitions
and emit DROP COLUMN + ADD COLUMN instead.

Text-like types can still be cast to custom types via USING and remain
on the existing ALTER TYPE path.

Co-authored-by: Cursor <cursoragent@cursor.com>
@wellcode-ai wellcode-ai Bot added database-migration Requires special attention: database migration review-effort-4 Deep review (1-2 hours) labels Jun 4, 2026
@wellcode-ai
Copy link
Copy Markdown

wellcode-ai Bot commented Jun 4, 2026

🔍 General Code Quality Feedback

🔍 Comprehensive Code Review

Consolidated Feedback

  • 🔍 Code Review Analysis

Overall Assessment: The pull request introduces a significant change to handle incompatible type transitions in PostgreSQL migrations. While the solution is well thought out, there are areas for improvement in maintainability, documentation, and testing coverage.

Critical Issues:

  • Issue 1: Lack of comprehensive documentation for the requiresDropAdd function → Actionable solution: Add detailed comments explaining the logic and reasoning behind the function, including examples of incompatible type transitions.
  • Issue 2: The generateColumnSQL function is becoming complex and difficult to read due to the added logic → Actionable solution: Refactor the function by breaking it into smaller, more manageable helper functions that handle specific tasks (e.g., handling default values, generating drop/add statements).

Improvements:

  • Suggestion 1: Improve naming conventions for clarity → For example, consider renaming requiresDropAdd to isDropAddRequiredForTypeChange to better convey its purpose.
  • Suggestion 2: Enhance test coverage for edge cases → Add tests for scenarios where the old type is a text-like type that can be cast to an enum, ensuring that the existing logic is validated.

Positive Notes:

  • The implementation of the requiresDropAdd check is a good approach to handle incompatible type changes, reflecting a solid understanding of PostgreSQL's type casting limitations.
  • The inclusion of a new test case specifically targeting the incompatible type transitions demonstrates a commitment to maintaining code quality and reliability.

Next Steps:

  1. Refactor the generateColumnSQL function to improve readability and maintainability by breaking it into smaller functions.
  2. Add comprehensive documentation for the requiresDropAdd function and any other complex logic.
  3. Enhance test coverage by adding edge cases and ensuring that all possible type transitions are tested.
  4. Review naming conventions throughout the code for clarity and consistency.

By addressing these issues and suggestions, the code will be more maintainable, easier to understand, and less prone to future bugs.

🤖 Generated by Wellcode.ai

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

Labels

database-migration Requires special attention: database migration review-effort-4 Deep review (1-2 hours)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant