Files
drizzle-team--drizzle-orm/drizzle-kit/tests/sqlite-generated.test.ts
T
2026-07-13 12:10:05 +08:00

1727 lines
38 KiB
TypeScript

// 1. add stored column to existing table - not supported +
// 2. add virtual column to existing table - supported +
// 3. create table with stored/virtual columns(pg, mysql, sqlite)
// 4. add stored generated to column -> not supported +
// 5. add virtual generated to column -> supported with drop+add column +
// 6. drop stored/virtual expression -> supported with drop+add column
// 7. alter generated expession -> stored not supported, virtual supported
import { SQL, sql } from 'drizzle-orm';
import { int, sqliteTable, text } from 'drizzle-orm/sqlite-core';
import { expect, test } from 'vitest';
import { diffTestSchemasSqlite } from './schemaDiffer';
// should generate 0 statements + warning/error in console
test('generated as callback: add column with stored generated constraint', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
(): SQL => sql`${to.users.name} || 'hello'`,
{ mode: 'stored' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([]);
expect(sqlStatements).toStrictEqual([]);
});
test('generated as callback: add column with virtual generated constraint', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
(): SQL => sql`${to.users.name} || 'hello'`,
{ mode: 'virtual' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
column: {
generated: {
as: '("name" || \'hello\')',
type: 'virtual',
},
autoincrement: false,
name: 'gen_name',
notNull: false,
primaryKey: false,
type: 'text',
},
referenceData: undefined,
tableName: 'users',
type: 'sqlite_alter_table_add_column',
},
]);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS ("name" || \'hello\') VIRTUAL;',
]);
});
test('generated as callback: add generated constraint to an exisiting column as stored', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').notNull(),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name')
.notNull()
.generatedAlwaysAs((): SQL => sql`${from.users.name} || 'to add'`, {
mode: 'stored',
}),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([]);
expect(sqlStatements).toStrictEqual([]);
});
test('generated as callback: add generated constraint to an exisiting column as virtual', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').notNull(),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name')
.notNull()
.generatedAlwaysAs((): SQL => sql`${from.users.name} || 'to add'`, {
mode: 'virtual',
}),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columnAutoIncrement: false,
columnDefault: undefined,
columnGenerated: {
as: '("name" || \'to add\')',
type: 'virtual',
},
columnName: 'gen_name',
columnNotNull: true,
columnOnUpdate: undefined,
columnPk: false,
newDataType: 'text',
schema: '',
tableName: 'users',
type: 'alter_table_alter_column_set_generated',
},
]);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE `users` DROP COLUMN `gen_name`;',
'ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS ("name" || \'to add\') VIRTUAL NOT NULL;',
]);
});
test('generated as callback: drop generated constraint as stored', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
(): SQL => sql`${from.users.name} || 'to delete'`,
{ mode: 'stored' },
),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName1: text('gen_name'),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columnAutoIncrement: false,
columnDefault: undefined,
columnGenerated: undefined,
columnName: 'gen_name',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: 'text',
schema: '',
tableName: 'users',
type: 'alter_table_alter_column_drop_generated',
},
]);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE `users` DROP COLUMN `gen_name`;',
'ALTER TABLE `users` ADD `gen_name` text;',
]);
});
test('generated as callback: drop generated constraint as virtual', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
(): SQL => sql`${from.users.name} || 'to delete'`,
{ mode: 'virtual' },
),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName1: text('gen_name'),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columnAutoIncrement: false,
columnDefault: undefined,
columnGenerated: undefined,
columnName: 'gen_name',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: 'text',
schema: '',
tableName: 'users',
type: 'alter_table_alter_column_drop_generated',
},
]);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE `users` DROP COLUMN `gen_name`;',
'ALTER TABLE `users` ADD `gen_name` text;',
]);
});
// no way to do it
test('generated as callback: change generated constraint type from virtual to stored', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
(): SQL => sql`${from.users.name}`,
{ mode: 'virtual' },
),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
(): SQL => sql`${to.users.name} || 'hello'`,
{ mode: 'stored' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([]);
expect(sqlStatements).toStrictEqual([]);
});
test('generated as callback: change generated constraint type from stored to virtual', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
(): SQL => sql`${from.users.name}`,
{ mode: 'stored' },
),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
(): SQL => sql`${to.users.name} || 'hello'`,
{ mode: 'virtual' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columnAutoIncrement: false,
columnDefault: undefined,
columnGenerated: {
as: '("name" || \'hello\')',
type: 'virtual',
},
columnName: 'gen_name',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: 'text',
schema: '',
tableName: 'users',
type: 'alter_table_alter_column_alter_generated',
},
]);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE `users` DROP COLUMN `gen_name`;',
'ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS ("name" || \'hello\') VIRTUAL;',
]);
});
// not supported
test('generated as callback: change stored generated constraint', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
(): SQL => sql`${from.users.name}`,
{ mode: 'stored' },
),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
(): SQL => sql`${to.users.name} || 'hello'`,
{ mode: 'stored' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([]);
expect(sqlStatements).toStrictEqual([]);
});
test('generated as callback: change virtual generated constraint', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
(): SQL => sql`${from.users.name}`,
),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
(): SQL => sql`${to.users.name} || 'hello'`,
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columnAutoIncrement: false,
columnDefault: undefined,
columnGenerated: {
as: '("name" || \'hello\')',
type: 'virtual',
},
columnName: 'gen_name',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: 'text',
schema: '',
tableName: 'users',
type: 'alter_table_alter_column_alter_generated',
},
]);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE `users` DROP COLUMN `gen_name`;',
'ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS ("name" || \'hello\') VIRTUAL;',
]);
});
test('generated as callback: add table with column with stored generated constraint', async () => {
const from = {};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
(): SQL => sql`${to.users.name} || 'hello'`,
{ mode: 'stored' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columns: [
{
autoincrement: false,
name: 'id',
notNull: false,
primaryKey: false,
type: 'integer',
},
{
autoincrement: false,
name: 'id2',
notNull: false,
primaryKey: false,
type: 'integer',
},
{
autoincrement: false,
name: 'name',
notNull: false,
primaryKey: false,
type: 'text',
},
{
autoincrement: false,
generated: {
as: '("name" || \'hello\')',
type: 'stored',
},
name: 'gen_name',
notNull: false,
primaryKey: false,
type: 'text',
},
],
compositePKs: [],
referenceData: [],
tableName: 'users',
type: 'sqlite_create_table',
uniqueConstraints: [],
checkConstraints: [],
},
]);
expect(sqlStatements).toStrictEqual([
'CREATE TABLE `users` (\n\t`id` integer,\n\t`id2` integer,\n\t`name` text,\n\t`gen_name` text GENERATED ALWAYS AS ("name" || \'hello\') STORED\n);\n',
]);
});
test('generated as callback: add table with column with virtual generated constraint', async () => {
const from = {};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
(): SQL => sql`${to.users.name} || 'hello'`,
{ mode: 'virtual' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columns: [
{
autoincrement: false,
name: 'id',
notNull: false,
primaryKey: false,
type: 'integer',
},
{
autoincrement: false,
name: 'id2',
notNull: false,
primaryKey: false,
type: 'integer',
},
{
autoincrement: false,
name: 'name',
notNull: false,
primaryKey: false,
type: 'text',
},
{
autoincrement: false,
generated: {
as: '("name" || \'hello\')',
type: 'virtual',
},
name: 'gen_name',
notNull: false,
primaryKey: false,
type: 'text',
},
],
compositePKs: [],
referenceData: [],
tableName: 'users',
type: 'sqlite_create_table',
uniqueConstraints: [],
checkConstraints: [],
},
]);
expect(sqlStatements).toStrictEqual([
'CREATE TABLE `users` (\n\t`id` integer,\n\t`id2` integer,\n\t`name` text,\n\t`gen_name` text GENERATED ALWAYS AS ("name" || \'hello\') VIRTUAL\n);\n',
]);
});
// ---
test('generated as sql: add column with stored generated constraint', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
sql`"users"."name" || \'hello\' || 'hello'`,
{ mode: 'stored' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([]);
expect(sqlStatements).toStrictEqual([]);
});
test('generated as sql: add column with virtual generated constraint', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
sql`"users"."name" || \'hello\'`,
{ mode: 'virtual' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
column: {
generated: {
as: '("users"."name" || \'hello\')',
type: 'virtual',
},
autoincrement: false,
name: 'gen_name',
notNull: false,
primaryKey: false,
type: 'text',
},
referenceData: undefined,
tableName: 'users',
type: 'sqlite_alter_table_add_column',
},
]);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS ("users"."name" || \'hello\') VIRTUAL;',
]);
});
test('generated as sql: add generated constraint to an exisiting column as stored', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').notNull(),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name')
.notNull()
.generatedAlwaysAs(sql`"users"."name" || 'to add'`, {
mode: 'stored',
}),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([]);
expect(sqlStatements).toStrictEqual([]);
});
test('generated as sql: add generated constraint to an exisiting column as virtual', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').notNull(),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name')
.notNull()
.generatedAlwaysAs(sql`"users"."name" || 'to add'`, {
mode: 'virtual',
}),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columnAutoIncrement: false,
columnDefault: undefined,
columnGenerated: {
as: '("users"."name" || \'to add\')',
type: 'virtual',
},
columnName: 'gen_name',
columnNotNull: true,
columnOnUpdate: undefined,
columnPk: false,
newDataType: 'text',
schema: '',
tableName: 'users',
type: 'alter_table_alter_column_set_generated',
},
]);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE `users` DROP COLUMN `gen_name`;',
'ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS ("users"."name" || \'to add\') VIRTUAL NOT NULL;',
]);
});
test('generated as sql: drop generated constraint as stored', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
sql`"users"."name" || 'to delete'`,
{ mode: 'stored' },
),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName1: text('gen_name'),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columnAutoIncrement: false,
columnDefault: undefined,
columnGenerated: undefined,
columnName: 'gen_name',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: 'text',
schema: '',
tableName: 'users',
type: 'alter_table_alter_column_drop_generated',
},
]);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE `users` DROP COLUMN `gen_name`;',
'ALTER TABLE `users` ADD `gen_name` text;',
]);
});
test('generated as sql: drop generated constraint as virtual', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
sql`"users"."name" || 'to delete'`,
{ mode: 'virtual' },
),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName1: text('gen_name'),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columnAutoIncrement: false,
columnDefault: undefined,
columnGenerated: undefined,
columnName: 'gen_name',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: 'text',
schema: '',
tableName: 'users',
type: 'alter_table_alter_column_drop_generated',
},
]);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE `users` DROP COLUMN `gen_name`;',
'ALTER TABLE `users` ADD `gen_name` text;',
]);
});
// no way to do it
test('generated as sql: change generated constraint type from virtual to stored', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(sql`"users"."name"`, {
mode: 'virtual',
}),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
sql`"users"."name" || 'hello'`,
{ mode: 'stored' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([]);
expect(sqlStatements).toStrictEqual([]);
});
test('generated as sql: change generated constraint type from stored to virtual', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(sql`"users"."name"`, {
mode: 'stored',
}),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
sql`"users"."name" || 'hello'`,
{ mode: 'virtual' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columnAutoIncrement: false,
columnDefault: undefined,
columnGenerated: {
as: '("users"."name" || \'hello\')',
type: 'virtual',
},
columnName: 'gen_name',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: 'text',
schema: '',
tableName: 'users',
type: 'alter_table_alter_column_alter_generated',
},
]);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE `users` DROP COLUMN `gen_name`;',
'ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS ("users"."name" || \'hello\') VIRTUAL;',
]);
});
// not supported
test('generated as sql: change stored generated constraint', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(sql`"users"."name"`, {
mode: 'stored',
}),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
sql`"users"."name" || 'hello'`,
{ mode: 'stored' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([]);
expect(sqlStatements).toStrictEqual([]);
});
test('generated as sql: change virtual generated constraint', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(sql`"users"."name"`),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
sql`"users"."name" || 'hello'`,
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columnAutoIncrement: false,
columnDefault: undefined,
columnGenerated: {
as: '("users"."name" || \'hello\')',
type: 'virtual',
},
columnName: 'gen_name',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: 'text',
schema: '',
tableName: 'users',
type: 'alter_table_alter_column_alter_generated',
},
]);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE `users` DROP COLUMN `gen_name`;',
'ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS ("users"."name" || \'hello\') VIRTUAL;',
]);
});
test('generated as sql: add table with column with stored generated constraint', async () => {
const from = {};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
sql`"users"."name" || 'hello'`,
{ mode: 'stored' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columns: [
{
autoincrement: false,
name: 'id',
notNull: false,
primaryKey: false,
type: 'integer',
},
{
autoincrement: false,
name: 'id2',
notNull: false,
primaryKey: false,
type: 'integer',
},
{
autoincrement: false,
name: 'name',
notNull: false,
primaryKey: false,
type: 'text',
},
{
autoincrement: false,
generated: {
as: '("users"."name" || \'hello\')',
type: 'stored',
},
name: 'gen_name',
notNull: false,
primaryKey: false,
type: 'text',
},
],
compositePKs: [],
referenceData: [],
tableName: 'users',
type: 'sqlite_create_table',
uniqueConstraints: [],
checkConstraints: [],
},
]);
expect(sqlStatements).toStrictEqual([
'CREATE TABLE `users` (\n\t`id` integer,\n\t`id2` integer,\n\t`name` text,\n\t`gen_name` text GENERATED ALWAYS AS ("users"."name" || \'hello\') STORED\n);\n',
]);
});
test('generated as sql: add table with column with virtual generated constraint', async () => {
const from = {};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
sql`"users"."name" || 'hello'`,
{ mode: 'virtual' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columns: [
{
autoincrement: false,
name: 'id',
notNull: false,
primaryKey: false,
type: 'integer',
},
{
autoincrement: false,
name: 'id2',
notNull: false,
primaryKey: false,
type: 'integer',
},
{
autoincrement: false,
name: 'name',
notNull: false,
primaryKey: false,
type: 'text',
},
{
autoincrement: false,
generated: {
as: '("users"."name" || \'hello\')',
type: 'virtual',
},
name: 'gen_name',
notNull: false,
primaryKey: false,
type: 'text',
},
],
compositePKs: [],
referenceData: [],
tableName: 'users',
type: 'sqlite_create_table',
uniqueConstraints: [],
checkConstraints: [],
},
]);
expect(sqlStatements).toStrictEqual([
'CREATE TABLE `users` (\n\t`id` integer,\n\t`id2` integer,\n\t`name` text,\n\t`gen_name` text GENERATED ALWAYS AS ("users"."name" || \'hello\') VIRTUAL\n);\n',
]);
});
// ---
test('generated as string: add column with stored generated constraint', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
`"users"."name" || \'hello\'`,
{ mode: 'stored' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([]);
expect(sqlStatements).toStrictEqual([]);
});
test('generated as string: add column with virtual generated constraint', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
`"users"."name" || \'hello\'`,
{ mode: 'virtual' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
column: {
generated: {
as: '("users"."name" || \'hello\')',
type: 'virtual',
},
autoincrement: false,
name: 'gen_name',
notNull: false,
primaryKey: false,
type: 'text',
},
referenceData: undefined,
tableName: 'users',
type: 'sqlite_alter_table_add_column',
},
]);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS ("users"."name" || \'hello\') VIRTUAL;',
]);
});
test('generated as string: add generated constraint to an exisiting column as stored', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').notNull(),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name')
.notNull()
.generatedAlwaysAs(`"users"."name" || 'to add'`, {
mode: 'stored',
}),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([]);
expect(sqlStatements).toStrictEqual([]);
});
test('generated as string: add generated constraint to an exisiting column as virtual', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').notNull(),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name')
.notNull()
.generatedAlwaysAs(`"users"."name" || 'to add'`, {
mode: 'virtual',
}),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columnAutoIncrement: false,
columnDefault: undefined,
columnGenerated: {
as: '("users"."name" || \'to add\')',
type: 'virtual',
},
columnName: 'gen_name',
columnNotNull: true,
columnOnUpdate: undefined,
columnPk: false,
newDataType: 'text',
schema: '',
tableName: 'users',
type: 'alter_table_alter_column_set_generated',
},
]);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE `users` DROP COLUMN `gen_name`;',
'ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS ("users"."name" || \'to add\') VIRTUAL NOT NULL;',
]);
});
test('generated as string: drop generated constraint as stored', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
`"users"."name" || 'to delete'`,
{ mode: 'stored' },
),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName1: text('gen_name'),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columnAutoIncrement: false,
columnDefault: undefined,
columnGenerated: undefined,
columnName: 'gen_name',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: 'text',
schema: '',
tableName: 'users',
type: 'alter_table_alter_column_drop_generated',
},
]);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE `users` DROP COLUMN `gen_name`;',
'ALTER TABLE `users` ADD `gen_name` text;',
]);
});
test('generated as string: drop generated constraint as virtual', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
`"users"."name" || 'to delete'`,
{ mode: 'virtual' },
),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName1: text('gen_name'),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columnAutoIncrement: false,
columnDefault: undefined,
columnGenerated: undefined,
columnName: 'gen_name',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: 'text',
schema: '',
tableName: 'users',
type: 'alter_table_alter_column_drop_generated',
},
]);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE `users` DROP COLUMN `gen_name`;',
'ALTER TABLE `users` ADD `gen_name` text;',
]);
});
// no way to do it
test('generated as string: change generated constraint type from virtual to stored', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(`"users"."name"`, {
mode: 'virtual',
}),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
`"users"."name" || 'hello'`,
{ mode: 'stored' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([]);
expect(sqlStatements).toStrictEqual([]);
});
test('generated as string: change generated constraint type from stored to virtual', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(`"users"."name"`, {
mode: 'stored',
}),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
`"users"."name" || 'hello'`,
{ mode: 'virtual' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columnAutoIncrement: false,
columnDefault: undefined,
columnGenerated: {
as: '("users"."name" || \'hello\')',
type: 'virtual',
},
columnName: 'gen_name',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: 'text',
schema: '',
tableName: 'users',
type: 'alter_table_alter_column_alter_generated',
},
]);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE `users` DROP COLUMN `gen_name`;',
'ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS ("users"."name" || \'hello\') VIRTUAL;',
]);
});
// not supported
test('generated as string: change stored generated constraint', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(`"users"."name"`, {
mode: 'stored',
}),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
`"users"."name" || 'hello'`,
{ mode: 'stored' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([]);
expect(sqlStatements).toStrictEqual([]);
});
test('generated as string: change virtual generated constraint', async () => {
const from = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(`"users"."name"`),
}),
};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
`"users"."name" || 'hello'`,
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columnAutoIncrement: false,
columnDefault: undefined,
columnGenerated: {
as: '("users"."name" || \'hello\')',
type: 'virtual',
},
columnName: 'gen_name',
columnNotNull: false,
columnOnUpdate: undefined,
columnPk: false,
newDataType: 'text',
schema: '',
tableName: 'users',
type: 'alter_table_alter_column_alter_generated',
},
]);
expect(sqlStatements).toStrictEqual([
'ALTER TABLE `users` DROP COLUMN `gen_name`;',
'ALTER TABLE `users` ADD `gen_name` text GENERATED ALWAYS AS ("users"."name" || \'hello\') VIRTUAL;',
]);
});
test('generated as string: add table with column with stored generated constraint', async () => {
const from = {};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
`"users"."name" || 'hello'`,
{ mode: 'stored' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columns: [
{
autoincrement: false,
name: 'id',
notNull: false,
primaryKey: false,
type: 'integer',
},
{
autoincrement: false,
name: 'id2',
notNull: false,
primaryKey: false,
type: 'integer',
},
{
autoincrement: false,
name: 'name',
notNull: false,
primaryKey: false,
type: 'text',
},
{
autoincrement: false,
generated: {
as: '("users"."name" || \'hello\')',
type: 'stored',
},
name: 'gen_name',
notNull: false,
primaryKey: false,
type: 'text',
},
],
compositePKs: [],
referenceData: [],
tableName: 'users',
type: 'sqlite_create_table',
uniqueConstraints: [],
checkConstraints: [],
},
]);
expect(sqlStatements).toStrictEqual([
'CREATE TABLE `users` (\n\t`id` integer,\n\t`id2` integer,\n\t`name` text,\n\t`gen_name` text GENERATED ALWAYS AS ("users"."name" || \'hello\') STORED\n);\n',
]);
});
test('generated as string: add table with column with virtual generated constraint', async () => {
const from = {};
const to = {
users: sqliteTable('users', {
id: int('id'),
id2: int('id2'),
name: text('name'),
generatedName: text('gen_name').generatedAlwaysAs(
`"users"."name" || 'hello'`,
{ mode: 'virtual' },
),
}),
};
const { statements, sqlStatements } = await diffTestSchemasSqlite(
from,
to,
[],
);
expect(statements).toStrictEqual([
{
columns: [
{
autoincrement: false,
name: 'id',
notNull: false,
primaryKey: false,
type: 'integer',
},
{
autoincrement: false,
name: 'id2',
notNull: false,
primaryKey: false,
type: 'integer',
},
{
autoincrement: false,
name: 'name',
notNull: false,
primaryKey: false,
type: 'text',
},
{
autoincrement: false,
generated: {
as: '("users"."name" || \'hello\')',
type: 'virtual',
},
name: 'gen_name',
notNull: false,
primaryKey: false,
type: 'text',
},
],
compositePKs: [],
referenceData: [],
tableName: 'users',
type: 'sqlite_create_table',
uniqueConstraints: [],
checkConstraints: [],
},
]);
expect(sqlStatements).toStrictEqual([
'CREATE TABLE `users` (\n\t`id` integer,\n\t`id2` integer,\n\t`name` text,\n\t`gen_name` text GENERATED ALWAYS AS ("users"."name" || \'hello\') VIRTUAL\n);\n',
]);
});