xataio / pgroll

PostgreSQL zero-downtime migrations made easy
https://www.xata.io
Apache License 2.0
2.97k stars 54 forks source link

Altering a column type attempts to duplicate incompatible defaults and constraints #348

Closed andrew-farries closed 4 months ago

andrew-farries commented 4 months ago

Columns that are duplicated as part of an 'alter column' migration that changes the column type should not attempt to duplicate any DEFAULTs or CHECK constraints that are not compatible with the new column type.

Given this pair of migrations:

{
  "name": "01_create_table",
  "operations": [
    {
      "create_table": {
        "name": "products",
        "columns": [
          {
            "name": "id",
            "type": "serial",
            "pk": true
          },
          {
            "name": "age",
            "type": "text",
            "check": {
              "name": "length_check",
              "constraint": "LENGTH(\"age\") <= 3"
            }
          }
        ]
      }
    }
  ]
}
{
  "name": "02_alter_column",
  "operations": [
    {
      "alter_column": {
        "table": "products",
        "column": "age",
        "type": "bigint",
        "default": "0",
        "up": "CAST(age AS integer)",
        "down": "CAST(age AS text)"
      }
    }
  ]
}

will fail because the length_check constraint can't be applied to the new column type. A similar problem occurs if the column has a string default and the column type is changed to an integer.

As a first pass, it could be acceptable to simply drop defaults and constraints from columns that have their type changed; users can re-set them in the same 'alter column' operation that changes the type if they are intended to be preserved.

Ideally the default/constraints should be dropped if they are not compatible with the new column type and preserved otherwise.