Skip to content

Down migration for enums with defaults are wrong #6115

@nulvinge

Description

@nulvinge

Issue type:

[X] bug report

Database system/driver:

[X] postgres

TypeORM version:

[X] 0.2.24 (or put your version here)

Steps to reproduce or a small repository showing the problem:
I have the following entity:

export enum Operator {
  LT = "lt",
  LE = "le",
  EQ = "eq",
  NE = "ne",
  GE = "ge",
  GT = "gt"
}

@Entity()
export class Metric {
  @PrimaryGeneratedColumn()
  id!: number;

  @Column({ type: "enum", enum: Operator, default: Operator.EQ })
  defaultOperator!: string;
}

I then change the enum to the following:

export enum Operator {
  LT = "lessthan",
  LE = "lessequal",
  EQ = "equal",
  NE = "notequal",
  GE = "greaterequal",
  GT = "greaterthan"
}

The generated migration looks like this:

import {MigrationInterface, QueryRunner} from "typeorm";

export class CorrectedOperator1589908094570 implements MigrationInterface {
    name = 'CorrectedOperator1589908094570'

    public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`ALTER TYPE "public"."metric_defaultoperator_enum" RENAME TO "metric_defaultoperator_enum_old"`, undefined);
        await queryRunner.query(`CREATE TYPE "metric_defaultoperator_enum" AS ENUM('lessthan', 'lessequal', 'equal', 'notequal', 'greaterequal', 'greaterthan')`, undefined);
        await queryRunner.query(`ALTER TABLE "metric" ALTER COLUMN "defaultOperator" DROP DEFAULT`, undefined);
        await queryRunner.query(`ALTER TABLE "metric" ALTER COLUMN "defaultOperator" TYPE "metric_defaultoperator_enum" USING "defaultOperator"::"text"::"metric_defaultoperator_enum"`, undefined);
        await queryRunner.query(`ALTER TABLE "metric" ALTER COLUMN "defaultOperator" SET DEFAULT 'equal'`, undefined);
        await queryRunner.query(`DROP TYPE "metric_defaultoperator_enum_old"`, undefined);
        await queryRunner.query(`ALTER TABLE "metric" ALTER COLUMN "defaultOperator" SET DEFAULT 'equal'`, undefined);
    }

    public async down(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`ALTER TABLE "metric" ALTER COLUMN "defaultOperator" SET DEFAULT 'eq'`, undefined);
        await queryRunner.query(`CREATE TYPE "metric_defaultoperator_enum_old" AS ENUM('lt', 'le', 'eq', 'ne', 'ge', 'gt')`, undefined);
        await queryRunner.query(`ALTER TABLE "metric" ALTER COLUMN "defaultOperator" DROP DEFAULT`, undefined);
        await queryRunner.query(`ALTER TABLE "metric" ALTER COLUMN "defaultOperator" TYPE "metric_defaultoperator_enum_old" USING "defaultOperator"::"text"::"metric_defaultoperator_enum_old"`, undefined);
        await queryRunner.query(`ALTER TABLE "metric" ALTER COLUMN "defaultOperator" SET DEFAULT 'equal'`, undefined);
        await queryRunner.query(`DROP TYPE "metric_defaultoperator_enum"`, undefined);
        await queryRunner.query(`ALTER TYPE "metric_defaultoperator_enum_old" RENAME TO  "metric_defaultoperator_enum"`, undefined);
    }
}

When reverting this, it fails. It tries to set default to 'eq', when it should set it to 'equal', and later it does the opposite.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions