Files
2026-07-13 12:10:05 +08:00

2506 lines
60 KiB
TypeScript

import { integer, pgEnum, pgSchema, pgTable, serial, text, varchar } from 'drizzle-orm/pg-core';
import { expect, test } from 'vitest';
import { diffTestSchemas } from './schemaDiffer';
test('enums #1', async () => {
const to = {
enum: pgEnum('enum', ['value']),
};
const { statements, sqlStatements } = await diffTestSchemas({}, to, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(`CREATE TYPE "public"."enum" AS ENUM('value');`);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
name: 'enum',
schema: 'public',
type: 'create_type_enum',
values: ['value'],
});
});
test('enums #2', async () => {
const folder = pgSchema('folder');
const to = {
enum: folder.enum('enum', ['value']),
};
const { statements, sqlStatements } = await diffTestSchemas({}, to, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(`CREATE TYPE "folder"."enum" AS ENUM('value');`);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
name: 'enum',
schema: 'folder',
type: 'create_type_enum',
values: ['value'],
});
});
test('enums #3', async () => {
const from = {
enum: pgEnum('enum', ['value']),
};
const { statements, sqlStatements } = await diffTestSchemas(from, {}, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(`DROP TYPE "public"."enum";`);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
type: 'drop_type_enum',
name: 'enum',
schema: 'public',
});
});
test('enums #4', async () => {
const folder = pgSchema('folder');
const from = {
enum: folder.enum('enum', ['value']),
};
const { statements, sqlStatements } = await diffTestSchemas(from, {}, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(`DROP TYPE "folder"."enum";`);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
type: 'drop_type_enum',
name: 'enum',
schema: 'folder',
});
});
test('enums #5', async () => {
const folder1 = pgSchema('folder1');
const folder2 = pgSchema('folder2');
const from = {
folder1,
enum: folder1.enum('enum', ['value']),
};
const to = {
folder2,
enum: folder2.enum('enum', ['value']),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, ['folder1->folder2']);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(`ALTER SCHEMA "folder1" RENAME TO "folder2";\n`);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
type: 'rename_schema',
from: 'folder1',
to: 'folder2',
});
});
test('enums #6', async () => {
const folder1 = pgSchema('folder1');
const folder2 = pgSchema('folder2');
const from = {
folder1,
folder2,
enum: folder1.enum('enum', ['value']),
};
const to = {
folder1,
folder2,
enum: folder2.enum('enum', ['value']),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, [
'folder1.enum->folder2.enum',
]);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(`ALTER TYPE "folder1"."enum" SET SCHEMA "folder2";`);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
type: 'move_type_enum',
name: 'enum',
schemaFrom: 'folder1',
schemaTo: 'folder2',
});
});
test('enums #7', async () => {
const from = {
enum: pgEnum('enum', ['value1']),
};
const to = {
enum: pgEnum('enum', ['value1', 'value2']),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(`ALTER TYPE "public"."enum" ADD VALUE 'value2';`);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
type: 'alter_type_add_value',
name: 'enum',
schema: 'public',
value: 'value2',
before: '',
});
});
test('enums #8', async () => {
const from = {
enum: pgEnum('enum', ['value1']),
};
const to = {
enum: pgEnum('enum', ['value1', 'value2', 'value3']),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(2);
expect(sqlStatements[0]).toBe(`ALTER TYPE "public"."enum" ADD VALUE 'value2';`);
expect(sqlStatements[1]).toBe(`ALTER TYPE "public"."enum" ADD VALUE 'value3';`);
expect(statements.length).toBe(2);
expect(statements[0]).toStrictEqual({
type: 'alter_type_add_value',
name: 'enum',
schema: 'public',
value: 'value2',
before: '',
});
expect(statements[1]).toStrictEqual({
type: 'alter_type_add_value',
name: 'enum',
schema: 'public',
value: 'value3',
before: '',
});
});
test('enums #9', async () => {
const from = {
enum: pgEnum('enum', ['value1', 'value3']),
};
const to = {
enum: pgEnum('enum', ['value1', 'value2', 'value3']),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(`ALTER TYPE "public"."enum" ADD VALUE 'value2' BEFORE 'value3';`);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
type: 'alter_type_add_value',
name: 'enum',
schema: 'public',
value: 'value2',
before: 'value3',
});
});
test('enums #10', async () => {
const schema = pgSchema('folder');
const from = {
enum: schema.enum('enum', ['value1']),
};
const to = {
enum: schema.enum('enum', ['value1', 'value2']),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(`ALTER TYPE "folder"."enum" ADD VALUE 'value2';`);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
type: 'alter_type_add_value',
name: 'enum',
schema: 'folder',
value: 'value2',
before: '',
});
});
test('enums #11', async () => {
const schema1 = pgSchema('folder1');
const from = {
enum: schema1.enum('enum', ['value1']),
};
const to = {
enum: pgEnum('enum', ['value1']),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, [
'folder1.enum->public.enum',
]);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(`ALTER TYPE "folder1"."enum" SET SCHEMA "public";`);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
type: 'move_type_enum',
name: 'enum',
schemaFrom: 'folder1',
schemaTo: 'public',
});
});
test('enums #12', async () => {
const schema1 = pgSchema('folder1');
const from = {
enum: pgEnum('enum', ['value1']),
};
const to = {
enum: schema1.enum('enum', ['value1']),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, [
'public.enum->folder1.enum',
]);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(`ALTER TYPE "public"."enum" SET SCHEMA "folder1";`);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
type: 'move_type_enum',
name: 'enum',
schemaFrom: 'public',
schemaTo: 'folder1',
});
});
test('enums #13', async () => {
const from = {
enum: pgEnum('enum1', ['value1']),
};
const to = {
enum: pgEnum('enum2', ['value1']),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, [
'public.enum1->public.enum2',
]);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(`ALTER TYPE "public"."enum1" RENAME TO "enum2";`);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
type: 'rename_type_enum',
nameFrom: 'enum1',
nameTo: 'enum2',
schema: 'public',
});
});
test('enums #14', async () => {
const folder1 = pgSchema('folder1');
const folder2 = pgSchema('folder2');
const from = {
enum: folder1.enum('enum1', ['value1']),
};
const to = {
enum: folder2.enum('enum2', ['value1']),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, [
'folder1.enum1->folder2.enum2',
]);
expect(sqlStatements.length).toBe(2);
expect(sqlStatements[0]).toBe(`ALTER TYPE "folder1"."enum1" SET SCHEMA "folder2";`);
expect(sqlStatements[1]).toBe(`ALTER TYPE "folder2"."enum1" RENAME TO "enum2";`);
expect(statements.length).toBe(2);
expect(statements[0]).toStrictEqual({
type: 'move_type_enum',
name: 'enum1',
schemaFrom: 'folder1',
schemaTo: 'folder2',
});
expect(statements[1]).toStrictEqual({
type: 'rename_type_enum',
nameFrom: 'enum1',
nameTo: 'enum2',
schema: 'folder2',
});
});
test('enums #15', async () => {
const folder1 = pgSchema('folder1');
const folder2 = pgSchema('folder2');
const from = {
enum: folder1.enum('enum1', ['value1', 'value4']),
};
const to = {
enum: folder2.enum('enum2', ['value1', 'value2', 'value3', 'value4']),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, [
'folder1.enum1->folder2.enum2',
]);
expect(sqlStatements.length).toBe(4);
expect(sqlStatements[0]).toBe(`ALTER TYPE "folder1"."enum1" SET SCHEMA "folder2";`);
expect(sqlStatements[1]).toBe(`ALTER TYPE "folder2"."enum1" RENAME TO "enum2";`);
expect(sqlStatements[2]).toBe(`ALTER TYPE "folder2"."enum2" ADD VALUE 'value2' BEFORE 'value4';`);
expect(sqlStatements[3]).toBe(`ALTER TYPE "folder2"."enum2" ADD VALUE 'value3' BEFORE 'value4';`);
expect(statements.length).toBe(4);
expect(statements[0]).toStrictEqual({
type: 'move_type_enum',
name: 'enum1',
schemaFrom: 'folder1',
schemaTo: 'folder2',
});
expect(statements[1]).toStrictEqual({
type: 'rename_type_enum',
nameFrom: 'enum1',
nameTo: 'enum2',
schema: 'folder2',
});
expect(statements[2]).toStrictEqual({
type: 'alter_type_add_value',
name: 'enum2',
schema: 'folder2',
value: 'value2',
before: 'value4',
});
expect(statements[3]).toStrictEqual({
type: 'alter_type_add_value',
name: 'enum2',
schema: 'folder2',
value: 'value3',
before: 'value4',
});
});
test('enums #16', async () => {
const enum1 = pgEnum('enum1', ['value1']);
const enum2 = pgEnum('enum2', ['value1']);
const from = {
enum1,
table: pgTable('table', {
column: enum1('column'),
}),
};
const to = {
enum2,
table: pgTable('table', {
column: enum2('column'),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, [
'public.enum1->public.enum2',
]);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(`ALTER TYPE "public"."enum1" RENAME TO "enum2";`);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
type: 'rename_type_enum',
nameFrom: 'enum1',
nameTo: 'enum2',
schema: 'public',
});
});
test('enums #17', async () => {
const schema = pgSchema('schema');
const enum1 = pgEnum('enum1', ['value1']);
const enum2 = schema.enum('enum1', ['value1']);
const from = {
enum1,
table: pgTable('table', {
column: enum1('column'),
}),
};
const to = {
enum2,
table: pgTable('table', {
column: enum2('column'),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, [
'public.enum1->schema.enum1',
]);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(`ALTER TYPE "public"."enum1" SET SCHEMA "schema";`);
expect(sqlStatements.length).toBe(1);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
type: 'move_type_enum',
name: 'enum1',
schemaFrom: 'public',
schemaTo: 'schema',
});
});
test('enums #18', async () => {
const schema1 = pgSchema('schema1');
const schema2 = pgSchema('schema2');
const enum1 = schema1.enum('enum1', ['value1']);
const enum2 = schema2.enum('enum2', ['value1']);
const from = {
enum1,
table: pgTable('table', {
column: enum1('column'),
}),
};
const to = {
enum2,
table: pgTable('table', {
column: enum2('column'),
}),
};
// change name and schema of the enum, no table changes
const { statements, sqlStatements } = await diffTestSchemas(from, to, [
'schema1.enum1->schema2.enum2',
]);
expect(sqlStatements.length).toBe(2);
expect(sqlStatements[0]).toBe(`ALTER TYPE "schema1"."enum1" SET SCHEMA "schema2";`);
expect(sqlStatements[1]).toBe(`ALTER TYPE "schema2"."enum1" RENAME TO "enum2";`);
expect(statements.length).toBe(2);
expect(statements[0]).toStrictEqual({
type: 'move_type_enum',
name: 'enum1',
schemaFrom: 'schema1',
schemaTo: 'schema2',
});
expect(statements[1]).toStrictEqual({
type: 'rename_type_enum',
nameFrom: 'enum1',
nameTo: 'enum2',
schema: 'schema2',
});
});
test('enums #19', async () => {
const myEnum = pgEnum('my_enum', ["escape's quotes"]);
const from = {};
const to = { myEnum };
const { sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toStrictEqual(
'CREATE TYPE "public"."my_enum" AS ENUM(\'escape\'\'s quotes\');',
);
});
test('enums #20', async () => {
const myEnum = pgEnum('my_enum', ['one', 'two', 'three']);
const from = {
myEnum,
table: pgTable('table', {
id: serial('id').primaryKey(),
}),
};
const to = {
myEnum,
table: pgTable('table', {
id: serial('id').primaryKey(),
col1: myEnum('col1'),
col2: integer('col2'),
}),
};
const { sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(2);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE "table" ADD COLUMN "col1" "my_enum";',
'ALTER TABLE "table" ADD COLUMN "col2" integer;',
]);
});
test('enums #21', async () => {
const myEnum = pgEnum('my_enum', ['one', 'two', 'three']);
const from = {
myEnum,
table: pgTable('table', {
id: serial('id').primaryKey(),
}),
};
const to = {
myEnum,
table: pgTable('table', {
id: serial('id').primaryKey(),
col1: myEnum('col1').array(),
col2: integer('col2').array(),
}),
};
const { sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(2);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE "table" ADD COLUMN "col1" "my_enum"[];',
'ALTER TABLE "table" ADD COLUMN "col2" integer[];',
]);
});
test('drop enum value', async () => {
const enum1 = pgEnum('enum', ['value1', 'value2', 'value3']);
const from = {
enum1,
};
const enum2 = pgEnum('enum', ['value1', 'value3']);
const to = {
enum2,
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(2);
expect(sqlStatements[0]).toBe(`DROP TYPE "public"."enum";`);
expect(sqlStatements[1]).toBe(`CREATE TYPE "public"."enum" AS ENUM('value1', 'value3');`);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnsWithEnum: [],
deletedValues: [
'value2',
],
name: 'enum',
newValues: [
'value1',
'value3',
],
enumSchema: 'public',
type: 'alter_type_drop_value',
});
});
test('drop enum value. enum is columns data type', async () => {
const enum1 = pgEnum('enum', ['value1', 'value2', 'value3']);
const schema = pgSchema('new_schema');
const from = {
schema,
enum1,
table: pgTable('table', {
column: enum1('column'),
}),
table2: schema.table('table', {
column: enum1('column'),
}),
};
const enum2 = pgEnum('enum', ['value1', 'value3']);
const to = {
schema,
enum2,
table: pgTable('table', {
column: enum1('column'),
}),
table2: schema.table('table', {
column: enum1('column'),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(6);
expect(sqlStatements[0]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE text;`);
expect(sqlStatements[1]).toBe(`ALTER TABLE "new_schema"."table" ALTER COLUMN "column" SET DATA TYPE text;`);
expect(sqlStatements[2]).toBe(`DROP TYPE "public"."enum";`);
expect(sqlStatements[3]).toBe(`CREATE TYPE "public"."enum" AS ENUM('value1', 'value3');`);
expect(sqlStatements[4]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "public"."enum" USING "column"::"public"."enum";`,
);
expect(sqlStatements[5]).toBe(
`ALTER TABLE "new_schema"."table" ALTER COLUMN "column" SET DATA TYPE "public"."enum" USING "column"::"public"."enum";`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnsWithEnum: [
{
column: 'column',
tableSchema: '',
table: 'table',
default: undefined,
columnType: 'enum',
},
{
column: 'column',
tableSchema: 'new_schema',
table: 'table',
default: undefined,
columnType: 'enum',
},
],
deletedValues: [
'value2',
],
name: 'enum',
newValues: [
'value1',
'value3',
],
enumSchema: 'public',
type: 'alter_type_drop_value',
});
});
test('shuffle enum values', async () => {
const enum1 = pgEnum('enum', ['value1', 'value2', 'value3']);
const schema = pgSchema('new_schema');
const from = {
schema,
enum1,
table: pgTable('table', {
column: enum1('column'),
}),
table2: schema.table('table', {
column: enum1('column'),
}),
};
const enum2 = pgEnum('enum', ['value1', 'value3', 'value2']);
const to = {
schema,
enum2,
table: pgTable('table', {
column: enum2('column'),
}),
table2: schema.table('table', {
column: enum2('column'),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(6);
expect(sqlStatements[0]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE text;`);
expect(sqlStatements[1]).toBe(`ALTER TABLE "new_schema"."table" ALTER COLUMN "column" SET DATA TYPE text;`);
expect(sqlStatements[2]).toBe(`DROP TYPE "public"."enum";`);
expect(sqlStatements[3]).toBe(`CREATE TYPE "public"."enum" AS ENUM('value1', 'value3', 'value2');`);
expect(sqlStatements[4]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "public"."enum" USING "column"::"public"."enum";`,
);
expect(sqlStatements[5]).toBe(
`ALTER TABLE "new_schema"."table" ALTER COLUMN "column" SET DATA TYPE "public"."enum" USING "column"::"public"."enum";`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnsWithEnum: [
{
column: 'column',
tableSchema: '',
table: 'table',
default: undefined,
columnType: 'enum',
},
{
column: 'column',
tableSchema: 'new_schema',
table: 'table',
columnType: 'enum',
default: undefined,
},
],
deletedValues: [
'value3',
],
name: 'enum',
newValues: [
'value1',
'value3',
'value2',
],
enumSchema: 'public',
type: 'alter_type_drop_value',
});
});
test('enums as ts enum', async () => {
enum Test {
value = 'value',
}
const to = {
enum: pgEnum('enum', Test),
};
const { statements, sqlStatements } = await diffTestSchemas({}, to, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(`CREATE TYPE "public"."enum" AS ENUM('value');`);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
name: 'enum',
schema: 'public',
type: 'create_type_enum',
values: ['value'],
});
});
// +
test('column is enum type with default value. shuffle enum', async () => {
const enum1 = pgEnum('enum', ['value1', 'value2', 'value3']);
const from = {
enum1,
table: pgTable('table', {
column: enum1('column').default('value2'),
}),
};
const enum2 = pgEnum('enum', ['value1', 'value3', 'value2']);
const to = {
enum2,
table: pgTable('table', {
column: enum2('column').default('value2'),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(6);
expect(sqlStatements[0]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE text;`);
expect(sqlStatements[1]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT 'value2'::text;`);
expect(sqlStatements[2]).toBe(`DROP TYPE "public"."enum";`);
expect(sqlStatements[3]).toBe(`CREATE TYPE "public"."enum" AS ENUM('value1', 'value3', 'value2');`);
expect(sqlStatements[4]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT 'value2'::"public"."enum";`,
);
expect(sqlStatements[5]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "public"."enum" USING "column"::"public"."enum";`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnsWithEnum: [
{
column: 'column',
tableSchema: '',
table: 'table',
default: "'value2'",
columnType: 'enum',
},
],
deletedValues: [
'value3',
],
name: 'enum',
newValues: [
'value1',
'value3',
'value2',
],
enumSchema: 'public',
type: 'alter_type_drop_value',
});
});
// +
test('column is array enum type with default value. shuffle enum', async () => {
const enum1 = pgEnum('enum', ['value1', 'value2', 'value3']);
const from = {
enum1,
table: pgTable('table', {
column: enum1('column').array().default(['value2']),
}),
};
const enum2 = pgEnum('enum', ['value1', 'value3', 'value2']);
const to = {
enum2,
table: pgTable('table', {
column: enum2('column').array().default(['value3']),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(6);
expect(sqlStatements[0]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE text;`);
expect(sqlStatements[1]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT '{"value3"}'::text;`);
expect(sqlStatements[2]).toBe(`DROP TYPE "public"."enum";`);
expect(sqlStatements[3]).toBe(`CREATE TYPE "public"."enum" AS ENUM('value1', 'value3', 'value2');`);
expect(sqlStatements[4]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT '{"value3"}'::"public"."enum"[];`,
);
expect(sqlStatements[5]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "public"."enum"[] USING "column"::"public"."enum"[];`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnsWithEnum: [
{
column: 'column',
tableSchema: '',
table: 'table',
default: `'{"value3"}'`,
columnType: 'enum[]',
},
],
deletedValues: [
'value3',
],
name: 'enum',
newValues: [
'value1',
'value3',
'value2',
],
enumSchema: 'public',
type: 'alter_type_drop_value',
});
});
// +
test('column is array enum with custom size type with default value. shuffle enum', async () => {
const enum1 = pgEnum('enum', ['value1', 'value2', 'value3']);
const from = {
enum1,
table: pgTable('table', {
column: enum1('column').array(3).default(['value2']),
}),
};
const enum2 = pgEnum('enum', ['value1', 'value3', 'value2']);
const to = {
enum2,
table: pgTable('table', {
column: enum2('column').array(3).default(['value2']),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(6);
expect(sqlStatements[0]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE text;`);
expect(sqlStatements[1]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT '{"value2"}'::text;`);
expect(sqlStatements[2]).toBe(`DROP TYPE "public"."enum";`);
expect(sqlStatements[3]).toBe(`CREATE TYPE "public"."enum" AS ENUM('value1', 'value3', 'value2');`);
expect(sqlStatements[4]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT '{"value2"}'::"public"."enum"[3];`,
);
expect(sqlStatements[5]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "public"."enum"[3] USING "column"::"public"."enum"[3];`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnsWithEnum: [
{
column: 'column',
tableSchema: '',
table: 'table',
default: `'{"value2"}'`,
columnType: 'enum[3]',
},
],
deletedValues: [
'value3',
],
name: 'enum',
newValues: [
'value1',
'value3',
'value2',
],
enumSchema: 'public',
type: 'alter_type_drop_value',
});
});
// +
test('column is array enum with custom size type. shuffle enum', async () => {
const enum1 = pgEnum('enum', ['value1', 'value2', 'value3']);
const from = {
enum1,
table: pgTable('table', {
column: enum1('column').array(3),
}),
};
const enum2 = pgEnum('enum', ['value1', 'value3', 'value2']);
const to = {
enum2,
table: pgTable('table', {
column: enum2('column').array(3),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(4);
expect(sqlStatements[0]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE text;`);
expect(sqlStatements[1]).toBe(`DROP TYPE "public"."enum";`);
expect(sqlStatements[2]).toBe(`CREATE TYPE "public"."enum" AS ENUM('value1', 'value3', 'value2');`);
expect(sqlStatements[3]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "public"."enum"[3] USING "column"::"public"."enum"[3];`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnsWithEnum: [
{
column: 'column',
tableSchema: '',
table: 'table',
default: undefined,
columnType: 'enum[3]',
},
],
deletedValues: [
'value3',
],
name: 'enum',
newValues: [
'value1',
'value3',
'value2',
],
enumSchema: 'public',
type: 'alter_type_drop_value',
});
});
// +
test('column is array of enum with multiple dimenions with custom sizes type. shuffle enum', async () => {
const enum1 = pgEnum('enum', ['value1', 'value2', 'value3']);
const from = {
enum1,
table: pgTable('table', {
column: enum1('column').array(3).array(2),
}),
};
const enum2 = pgEnum('enum', ['value1', 'value3', 'value2']);
const to = {
enum2,
table: pgTable('table', {
column: enum2('column').array(3).array(2),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(4);
expect(sqlStatements[0]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE text;`);
expect(sqlStatements[1]).toBe(`DROP TYPE "public"."enum";`);
expect(sqlStatements[2]).toBe(`CREATE TYPE "public"."enum" AS ENUM('value1', 'value3', 'value2');`);
expect(sqlStatements[3]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "public"."enum"[3][2] USING "column"::"public"."enum"[3][2];`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnsWithEnum: [
{
column: 'column',
tableSchema: '',
table: 'table',
default: undefined,
columnType: 'enum[3][2]',
},
],
deletedValues: [
'value3',
],
name: 'enum',
newValues: [
'value1',
'value3',
'value2',
],
enumSchema: 'public',
type: 'alter_type_drop_value',
});
});
// +
test('column is array of enum with multiple dimenions type with custom size with default value. shuffle enum', async () => {
const enum1 = pgEnum('enum', ['value1', 'value2', 'value3']);
const from = {
enum1,
table: pgTable('table', {
column: enum1('column').array(3).array(2).default([['value2']]),
}),
};
const enum2 = pgEnum('enum', ['value1', 'value3', 'value2']);
const to = {
enum2,
table: pgTable('table', {
column: enum2('column').array(3).array(2).default([['value2']]),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(6);
expect(sqlStatements[0]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE text;`);
expect(sqlStatements[1]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT '{{"value2"}}'::text;`);
expect(sqlStatements[2]).toBe(`DROP TYPE "public"."enum";`);
expect(sqlStatements[3]).toBe(`CREATE TYPE "public"."enum" AS ENUM('value1', 'value3', 'value2');`);
expect(sqlStatements[4]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT '{{"value2"}}'::"public"."enum"[3][2];`,
);
expect(sqlStatements[5]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "public"."enum"[3][2] USING "column"::"public"."enum"[3][2];`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnsWithEnum: [
{
column: 'column',
tableSchema: '',
table: 'table',
default: `'{{\"value2\"}}'`,
columnType: 'enum[3][2]',
},
],
deletedValues: [
'value3',
],
name: 'enum',
newValues: [
'value1',
'value3',
'value2',
],
enumSchema: 'public',
type: 'alter_type_drop_value',
});
});
// +
test('column is enum type with default value. custom schema. shuffle enum', async () => {
const schema = pgSchema('new_schema');
const enum1 = schema.enum('enum', ['value1', 'value2', 'value3']);
const from = {
schema,
enum1,
table: pgTable('table', {
column: enum1('column').default('value2'),
}),
};
const enum2 = schema.enum('enum', ['value1', 'value3', 'value2']);
const to = {
schema,
enum2,
table: pgTable('table', {
column: enum2('column').default('value2'),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(6);
expect(sqlStatements[0]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE text;`);
expect(sqlStatements[1]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT 'value2'::text;`);
expect(sqlStatements[2]).toBe(`DROP TYPE "new_schema"."enum";`);
expect(sqlStatements[3]).toBe(`CREATE TYPE "new_schema"."enum" AS ENUM('value1', 'value3', 'value2');`);
expect(sqlStatements[4]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT 'value2'::"new_schema"."enum";`,
);
expect(sqlStatements[5]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "new_schema"."enum" USING "column"::"new_schema"."enum";`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnsWithEnum: [
{
column: 'column',
tableSchema: '',
table: 'table',
default: "'value2'",
columnType: 'enum',
},
],
deletedValues: [
'value3',
],
name: 'enum',
newValues: [
'value1',
'value3',
'value2',
],
enumSchema: 'new_schema',
type: 'alter_type_drop_value',
});
});
// +
test('column is array enum type with default value. custom schema. shuffle enum', async () => {
const schema = pgSchema('new_schema');
const enum1 = schema.enum('enum', ['value1', 'value2', 'value3']);
const from = {
enum1,
table: schema.table('table', {
column: enum1('column').array().default(['value2']),
}),
};
const enum2 = schema.enum('enum', ['value1', 'value3', 'value2']);
const to = {
enum2,
table: schema.table('table', {
column: enum2('column').array().default(['value2']),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(6);
expect(sqlStatements[0]).toBe(`ALTER TABLE "new_schema"."table" ALTER COLUMN "column" SET DATA TYPE text;`);
expect(sqlStatements[1]).toBe(
`ALTER TABLE "new_schema"."table" ALTER COLUMN "column" SET DEFAULT '{"value2"}'::text;`,
);
expect(sqlStatements[2]).toBe(`DROP TYPE "new_schema"."enum";`);
expect(sqlStatements[3]).toBe(`CREATE TYPE "new_schema"."enum" AS ENUM('value1', 'value3', 'value2');`);
expect(sqlStatements[4]).toBe(
`ALTER TABLE "new_schema"."table" ALTER COLUMN "column" SET DEFAULT '{"value2"}'::"new_schema"."enum"[];`,
);
expect(sqlStatements[5]).toBe(
`ALTER TABLE "new_schema"."table" ALTER COLUMN "column" SET DATA TYPE "new_schema"."enum"[] USING "column"::"new_schema"."enum"[];`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnsWithEnum: [
{
column: 'column',
tableSchema: 'new_schema',
table: 'table',
default: `'{"value2"}'`,
columnType: 'enum[]',
},
],
deletedValues: [
'value3',
],
name: 'enum',
newValues: [
'value1',
'value3',
'value2',
],
enumSchema: 'new_schema',
type: 'alter_type_drop_value',
});
});
// +
test('column is array enum type with custom size with default value. custom schema. shuffle enum', async () => {
const schema = pgSchema('new_schema');
const enum1 = schema.enum('enum', ['value1', 'value2', 'value3']);
const from = {
enum1,
table: schema.table('table', {
column: enum1('column').array(3).default(['value2']),
}),
};
const enum2 = schema.enum('enum', ['value1', 'value3', 'value2']);
const to = {
enum2,
table: schema.table('table', {
column: enum2('column').array(3).default(['value2']),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(6);
expect(sqlStatements[0]).toBe(`ALTER TABLE "new_schema"."table" ALTER COLUMN "column" SET DATA TYPE text;`);
expect(sqlStatements[1]).toBe(
`ALTER TABLE "new_schema"."table" ALTER COLUMN "column" SET DEFAULT '{"value2"}'::text;`,
);
expect(sqlStatements[2]).toBe(`DROP TYPE "new_schema"."enum";`);
expect(sqlStatements[3]).toBe(`CREATE TYPE "new_schema"."enum" AS ENUM('value1', 'value3', 'value2');`);
expect(sqlStatements[4]).toBe(
`ALTER TABLE "new_schema"."table" ALTER COLUMN "column" SET DEFAULT '{"value2"}'::"new_schema"."enum"[3];`,
);
expect(sqlStatements[5]).toBe(
`ALTER TABLE "new_schema"."table" ALTER COLUMN "column" SET DATA TYPE "new_schema"."enum"[3] USING "column"::"new_schema"."enum"[3];`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnsWithEnum: [
{
column: 'column',
tableSchema: 'new_schema',
table: 'table',
default: `'{"value2"}'`,
columnType: 'enum[3]',
},
],
deletedValues: [
'value3',
],
name: 'enum',
newValues: [
'value1',
'value3',
'value2',
],
enumSchema: 'new_schema',
type: 'alter_type_drop_value',
});
});
// +
test('column is array enum type with custom size. custom schema. shuffle enum', async () => {
const schema = pgSchema('new_schema');
const enum1 = schema.enum('enum', ['value1', 'value2', 'value3']);
const from = {
enum1,
table: schema.table('table', {
column: enum1('column').array(3),
}),
};
const enum2 = schema.enum('enum', ['value1', 'value3', 'value2']);
const to = {
enum2,
table: schema.table('table', {
column: enum2('column').array(3),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(4);
expect(sqlStatements[0]).toBe(`ALTER TABLE "new_schema"."table" ALTER COLUMN "column" SET DATA TYPE text;`);
expect(sqlStatements[1]).toBe(`DROP TYPE "new_schema"."enum";`);
expect(sqlStatements[2]).toBe(`CREATE TYPE "new_schema"."enum" AS ENUM('value1', 'value3', 'value2');`);
expect(sqlStatements[3]).toBe(
`ALTER TABLE "new_schema"."table" ALTER COLUMN "column" SET DATA TYPE "new_schema"."enum"[3] USING "column"::"new_schema"."enum"[3];`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnsWithEnum: [
{
column: 'column',
tableSchema: 'new_schema',
table: 'table',
default: undefined,
columnType: 'enum[3]',
},
],
deletedValues: [
'value3',
],
name: 'enum',
newValues: [
'value1',
'value3',
'value2',
],
enumSchema: 'new_schema',
type: 'alter_type_drop_value',
});
});
// +
test('column is enum type without default value. add default to column', async () => {
const enum1 = pgEnum('enum', ['value1', 'value3']);
const from = {
enum1,
table: pgTable('table', {
column: enum1('column'),
}),
};
const enum2 = pgEnum('enum', ['value1', 'value3']);
const to = {
enum2,
table: pgTable('table', {
column: enum2('column').default('value3'),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT 'value3';`);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: 'enum',
newDefaultValue: "'value3'",
schema: '',
tableName: 'table',
type: 'alter_table_alter_column_set_default',
});
});
// +
test('change data type from standart type to enum', async () => {
const enum1 = pgEnum('enum', ['value1', 'value3']);
const from = {
enum1,
table: pgTable('table', {
column: varchar('column'),
}),
};
const to = {
enum1,
table: pgTable('table', {
column: enum1('column'),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "public"."enum" USING "column"::"public"."enum";`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: undefined,
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: true,
name: 'enum',
},
oldDataType: {
isEnum: false,
name: 'varchar',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: 'public',
});
});
// +
test('change data type from standart type to enum. column has default', async () => {
const enum1 = pgEnum('enum', ['value1', 'value3']);
const from = {
enum1,
table: pgTable('table', {
column: varchar('column').default('value2'),
}),
};
const to = {
enum1,
table: pgTable('table', {
column: enum1('column').default('value3'),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(2);
expect(sqlStatements[0]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT 'value3'::"public"."enum";`);
expect(sqlStatements[1]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "public"."enum" USING "column"::"public"."enum";`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: "'value3'",
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: true,
name: 'enum',
},
oldDataType: {
isEnum: false,
name: 'varchar',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: 'public',
});
});
// +
test('change data type from array standart type to array enum. column has default', async () => {
const enum1 = pgEnum('enum', ['value1', 'value3']);
const from = {
enum1,
table: pgTable('table', {
column: varchar('column').array().default(['value2']),
}),
};
const to = {
enum1,
table: pgTable('table', {
column: enum1('column').array().default(['value3']),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(2);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT '{"value3"}'::"public"."enum"[];`,
);
expect(sqlStatements[1]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "public"."enum"[] USING "column"::"public"."enum"[];`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: `'{"value3"}'`,
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: true,
name: 'enum[]',
},
oldDataType: {
isEnum: false,
name: 'varchar[]',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: 'public',
});
});
// +
test('change data type from array standart type to array enum. column without default', async () => {
const enum1 = pgEnum('enum', ['value1', 'value3']);
const from = {
enum1,
table: pgTable('table', {
column: varchar('column').array(),
}),
};
const to = {
enum1,
table: pgTable('table', {
column: enum1('column').array(),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "public"."enum"[] USING "column"::"public"."enum"[];`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: undefined,
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: true,
name: 'enum[]',
},
oldDataType: {
isEnum: false,
name: 'varchar[]',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: 'public',
});
});
// +
test('change data type from array standart type with custom size to array enum with custom size. column has default', async () => {
const enum1 = pgEnum('enum', ['value1', 'value3']);
const from = {
enum1,
table: pgTable('table', {
column: varchar('column').array(3).default(['value2']),
}),
};
const to = {
enum1,
table: pgTable('table', {
column: enum1('column').array(3).default(['value3']),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(2);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT '{"value3"}'::"public"."enum"[3];`,
);
expect(sqlStatements[1]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "public"."enum"[3] USING "column"::"public"."enum"[3];`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: `'{"value3"}'`,
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: true,
name: 'enum[3]',
},
oldDataType: {
isEnum: false,
name: 'varchar[3]',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: 'public',
});
});
// +
test('change data type from array standart type with custom size to array enum with custom size. column without default', async () => {
const enum1 = pgEnum('enum', ['value1', 'value3']);
const from = {
enum1,
table: pgTable('table', {
column: varchar('column').array(2),
}),
};
const to = {
enum1,
table: pgTable('table', {
column: enum1('column').array(2),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "public"."enum"[2] USING "column"::"public"."enum"[2];`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: undefined,
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: true,
name: 'enum[2]',
},
oldDataType: {
isEnum: false,
name: 'varchar[2]',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: 'public',
});
});
// +
test('change data type from enum type to standart type', async () => {
const enum1 = pgEnum('enum', ['value1', 'value3']);
const from = {
enum1,
table: pgTable('table', {
column: enum1('column'),
}),
};
const to = {
enum1,
table: pgTable('table', {
column: varchar('column'),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE varchar;`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: undefined,
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: false,
name: 'varchar',
},
oldDataType: {
isEnum: true,
name: 'enum',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: undefined,
});
});
// +
test('change data type from enum type to standart type. column has default', async () => {
const enum1 = pgEnum('enum', ['value1', 'value3']);
const from = {
enum1,
table: pgTable('table', {
column: enum1('column').default('value3'),
}),
};
const to = {
enum1,
table: pgTable('table', {
column: varchar('column').default('value2'),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(2);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE varchar;`,
);
expect(sqlStatements[1]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT 'value2';`);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: "'value2'",
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: false,
name: 'varchar',
},
oldDataType: {
isEnum: true,
name: 'enum',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: undefined,
});
});
// +
test('change data type from array enum type to array standart type', async () => {
const enum1 = pgEnum('enum', ['value1', 'value3']);
const from = {
enum1,
table: pgTable('table', {
column: enum1('column').array(),
}),
};
const to = {
enum1,
table: pgTable('table', {
column: varchar('column').array(),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE varchar[];`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: undefined,
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: false,
name: 'varchar[]',
},
oldDataType: {
isEnum: true,
name: 'enum[]',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: undefined,
});
});
// +
test('change data type from array enum with custom size type to array standart type with custom size', async () => {
const enum1 = pgEnum('enum', ['value1', 'value3']);
const from = {
enum1,
table: pgTable('table', {
column: enum1('column').array(2),
}),
};
const to = {
enum1,
table: pgTable('table', {
column: varchar('column').array(2),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE varchar[2];`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: undefined,
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: false,
name: 'varchar[2]',
},
oldDataType: {
isEnum: true,
name: 'enum[2]',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: undefined,
});
});
//
test('change data type from array enum type to array standart type. column has default', async () => {
const enum1 = pgEnum('enum', ['value1', 'value2']);
const from = {
enum1,
table: pgTable('table', {
column: enum1('column').array().default(['value2']),
}),
};
const to = {
enum1,
table: pgTable('table', {
column: varchar('column').array().default(['value2']),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(2);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE varchar[];`,
);
expect(sqlStatements[1]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT '{"value2"}';`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: `'{"value2"}'`,
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: false,
name: 'varchar[]',
},
oldDataType: {
isEnum: true,
name: 'enum[]',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: undefined,
});
});
// +
test('change data type from array enum type with custom size to array standart type with custom size. column has default', async () => {
const enum1 = pgEnum('enum', ['value1', 'value2']);
const from = {
enum1,
table: pgTable('table', {
column: enum1('column').array(3).default(['value2']),
}),
};
const to = {
enum1,
table: pgTable('table', {
column: varchar('column').array(3).default(['value2']),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(2);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE varchar[3];`,
);
expect(sqlStatements[1]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT '{"value2"}';`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: `'{"value2"}'`,
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: false,
name: 'varchar[3]',
},
oldDataType: {
isEnum: true,
name: 'enum[3]',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: undefined,
});
});
// +
test('change data type from standart type to standart type', async () => {
const from = {
table: pgTable('table', {
column: varchar('column'),
}),
};
const to = {
table: pgTable('table', {
column: text('column'),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE text;`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: undefined,
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: false,
name: 'text',
},
oldDataType: {
isEnum: false,
name: 'varchar',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: undefined,
});
});
// +
test('change data type from standart type to standart type. column has default', async () => {
const from = {
table: pgTable('table', {
column: varchar('column').default('value3'),
}),
};
const to = {
table: pgTable('table', {
column: text('column').default('value2'),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(2);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE text;`,
);
expect(sqlStatements[1]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT 'value2';`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: "'value2'",
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: false,
name: 'text',
},
oldDataType: {
isEnum: false,
name: 'varchar',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: undefined,
});
});
// +
test('change data type from standart type to standart type. columns are arrays', async () => {
const from = {
table: pgTable('table', {
column: varchar('column').array(),
}),
};
const to = {
table: pgTable('table', {
column: text('column').array(),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE text[];`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: undefined,
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: false,
name: 'text[]',
},
oldDataType: {
isEnum: false,
name: 'varchar[]',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: undefined,
});
});
// +
test('change data type from standart type to standart type. columns are arrays with custom sizes', async () => {
const from = {
table: pgTable('table', {
column: varchar('column').array(2),
}),
};
const to = {
table: pgTable('table', {
column: text('column').array(2),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE text[2];`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: undefined,
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: false,
name: 'text[2]',
},
oldDataType: {
isEnum: false,
name: 'varchar[2]',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: undefined,
});
});
// +
test('change data type from standart type to standart type. columns are arrays. column has default', async () => {
const from = {
table: pgTable('table', {
column: varchar('column').array().default(['hello']),
}),
};
const to = {
table: pgTable('table', {
column: text('column').array().default(['hello']),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(2);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE text[];`,
);
expect(sqlStatements[1]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT '{"hello"}';`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: `'{"hello"}'`,
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: false,
name: 'text[]',
},
oldDataType: {
isEnum: false,
name: 'varchar[]',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: undefined,
});
});
// +
test('change data type from standart type to standart type. columns are arrays with custom sizes.column has default', async () => {
const from = {
table: pgTable('table', {
column: varchar('column').array(2).default(['hello']),
}),
};
const to = {
table: pgTable('table', {
column: text('column').array(2).default(['hello']),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(2);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE text[2];`,
);
expect(sqlStatements[1]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT '{"hello"}';`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: `'{"hello"}'`,
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: false,
name: 'text[2]',
},
oldDataType: {
isEnum: false,
name: 'varchar[2]',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: undefined,
});
});
// +
test('change data type from one enum to other', async () => {
const enum1 = pgEnum('enum1', ['value1', 'value3']);
const enum2 = pgEnum('enum2', ['value1', 'value3']);
const from = {
enum1,
enum2,
table: pgTable('table', {
column: enum1('column'),
}),
};
const to = {
enum1,
enum2,
table: pgTable('table', {
column: enum2('column'),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(1);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "public"."enum2" USING "column"::text::"public"."enum2";`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: undefined,
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: true,
name: 'enum2',
},
oldDataType: {
isEnum: true,
name: 'enum1',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: 'public',
});
});
// +
test('change data type from one enum to other. column has default', async () => {
const enum1 = pgEnum('enum1', ['value1', 'value3']);
const enum2 = pgEnum('enum2', ['value1', 'value3']);
const from = {
enum1,
enum2,
table: pgTable('table', {
column: enum1('column').default('value3'),
}),
};
const to = {
enum1,
enum2,
table: pgTable('table', {
column: enum2('column').default('value3'),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(3);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" DROP DEFAULT;`,
);
expect(sqlStatements[1]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "public"."enum2" USING "column"::text::"public"."enum2";`,
);
expect(sqlStatements[2]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT 'value3';`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: "'value3'",
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: true,
name: 'enum2',
},
oldDataType: {
isEnum: true,
name: 'enum1',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: 'public',
});
});
// +
test('change data type from one enum to other. changed defaults', async () => {
const enum1 = pgEnum('enum1', ['value1', 'value3']);
const enum2 = pgEnum('enum2', ['value1', 'value3']);
const from = {
enum1,
enum2,
table: pgTable('table', {
column: enum1('column').default('value3'),
}),
};
const to = {
enum1,
enum2,
table: pgTable('table', {
column: enum2('column').default('value1'),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(3);
expect(sqlStatements[0]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" DROP DEFAULT;`,
);
expect(sqlStatements[1]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "public"."enum2" USING "column"::text::"public"."enum2";`,
);
expect(sqlStatements[2]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT 'value1';`,
);
expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: "'value1'",
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: true,
name: 'enum2',
},
oldDataType: {
isEnum: true,
name: 'enum1',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: 'public',
});
});
test('check filtering json statements. here we have recreate enum + set new type + alter default', async () => {
const enum1 = pgEnum('enum1', ['value1', 'value3']);
const from = {
enum1,
table: pgTable('table', {
column: varchar('column').default('value3'),
}),
};
const enum2 = pgEnum('enum1', ['value3', 'value1', 'value2']);
const to = {
enum2,
table: pgTable('table', {
column: enum2('column').default('value2'),
}),
};
const { statements, sqlStatements } = await diffTestSchemas(from, to, []);
expect(sqlStatements.length).toBe(6);
expect(sqlStatements[0]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE text;`);
expect(sqlStatements[1]).toBe(`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT 'value2'::text;`);
expect(sqlStatements[2]).toBe(`DROP TYPE "public"."enum1";`);
expect(sqlStatements[3]).toBe(`CREATE TYPE "public"."enum1" AS ENUM('value3', 'value1', 'value2');`);
expect(sqlStatements[4]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DEFAULT 'value2'::"public"."enum1";`,
);
expect(sqlStatements[5]).toBe(
`ALTER TABLE "table" ALTER COLUMN "column" SET DATA TYPE "public"."enum1" USING "column"::"public"."enum1";`,
);
expect(statements.length).toBe(2);
expect(statements[0]).toStrictEqual({
columnsWithEnum: [
{
column: 'column',
columnType: 'enum1',
default: "'value2'",
table: 'table',
tableSchema: '',
},
],
deletedValues: [
'value3',
],
enumSchema: 'public',
name: 'enum1',
newValues: [
'value3',
'value1',
'value2',
],
type: 'alter_type_drop_value',
});
expect(statements[1]).toStrictEqual({
columnAutoIncrement: undefined,
columnDefault: "'value2'",
columnName: 'column',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: {
isEnum: true,
name: 'enum1',
},
oldDataType: {
isEnum: false,
name: 'varchar',
},
schema: '',
tableName: 'table',
type: 'pg_alter_table_alter_column_set_type',
typeSchema: 'public',
});
});