Skip to content

0.41 #4416

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Apr 15, 2025
Merged

0.41 #4416

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions changelogs/drizzle-kit/0.31.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## Features and improvements

### Enum DDL improvements

For situations where you drop an `enum` value or reorder values in an `enum`, there is no native way to do this in PostgreSQL. To handle these cases, `drizzle-kit` used to:

- Change the column data types from the enum to text
- Drop the old enum
- Add the new enum
- Change the column data types back to the new enum

However, there were a few scenarios that weren’t covered: `PostgreSQL` wasn’t updating default expressions for columns when their data types changed

Therefore, for cases where you either change a column’s data type from an `enum` to some other type, drop an `enum` value, or reorder `enum` values, we now do the following:

- Change the column data types from the enum to text
- Set the default using the ::text expression
- Drop the old enum
- Add the new enum
- Change the column data types back to the new enum
- Set the default using the ::<new_enum> expression

### `esbuild` version upgrade

For `drizzle-kit` we upgraded the version to latest (`0.25.2`), thanks @paulmarsicloud

## Bug fixes

- [[BUG]: Error on Malformed Array Literal](https://github.com/drizzle-team/drizzle-orm/issues/2715) - thanks @Kratious
- [[BUG]: Postgres drizzle-kit: Error while pulling indexes from a table with json/jsonb deep field index](https://github.com/drizzle-team/drizzle-orm/issues/2744) - thanks @Kratious
- [goog-vulnz flags CVE-2024-24790 in esbuild 0.19.7](https://github.com/drizzle-team/drizzle-orm/issues/4045)
52 changes: 52 additions & 0 deletions changelogs/drizzle-orm/0.42.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
## Features

### Duplicate imports removal

When importing from `drizzle-orm` using custom loaders, you may encounter issues such as: `SyntaxError: The requested module 'drizzle-orm' does not provide an export named 'eq'`

This issue arose because there were duplicated exports in `drizzle-orm`. To address this, we added a set of tests that checks every file in `drizzle-orm` to ensure all exports are valid. These tests will fail if any new duplicated exports appear.

In this release, we’ve removed all duplicated exports, so you should no longer encounter this issue.

### `pgEnum` and `mysqlEnum` now can accept both strings and TS enums

If you provide a TypeScript enum, all your types will be inferred as that enum - so you can insert and retrieve enum values directly. If you provide a string union, it will work as before.

```ts
enum Test {
a = 'a',
b = 'b',
c = 'c',
}

const tableWithTsEnums = mysqlTable('enums_test_case', {
id: serial().primaryKey(),
enum1: mysqlEnum(Test).notNull(),
enum2: mysqlEnum(Test).default(Test.a),
});

await db.insert(tableWithTsEnums).values([
{ id: 1, enum1: Test.a, enum2: Test.b, enum3: Test.c },
{ id: 2, enum1: Test.a, enum3: Test.c },
{ id: 3, enum1: Test.a },
]);

const res = await db.select().from(tableWithTsEnums);

expect(res).toEqual([
{ id: 1, enum1: 'a', enum2: 'b', enum3: 'c' },
{ id: 2, enum1: 'a', enum2: 'a', enum3: 'c' },
{ id: 3, enum1: 'a', enum2: 'a', enum3: 'b' },
]);
```

## Improvements
- Make `inArray` accept `ReadonlyArray` as a value - thanks @Zamiell
- Pass row type parameter to `@planetscale/database`'s execute - thanks @ayrton
- New `InferEnum` type - thanks @totigm

## Issues closed

- [Add first-class support for TS native enums](https://github.com/drizzle-team/drizzle-orm/issues/332)
- [[FEATURE]: support const enums](https://github.com/drizzle-team/drizzle-orm/issues/2798)
- [[BUG]: SyntaxError: The requested module 'drizzle-orm' does not provide an export named 'lte'](https://github.com/drizzle-team/drizzle-orm/issues/4079)
1 change: 1 addition & 0 deletions changelogs/drizzle-typebox/0.3.2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Functions `getColumns`, `handleColumns` and `handleEnum` were exported from `drizzle-typebox`
12 changes: 6 additions & 6 deletions drizzle-kit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "drizzle-kit",
"version": "0.30.6",
"version": "0.31.0",
"homepage": "https://orm.drizzle.team",
"keywords": [
"drizzle",
Expand Down Expand Up @@ -45,9 +45,8 @@
"dependencies": {
"@drizzle-team/brocli": "^0.10.2",
"@esbuild-kit/esm-loader": "^2.5.5",
"esbuild": "^0.19.7",
"esbuild-register": "^3.5.0",
"gel": "^2.0.0"
"esbuild": "^0.25.2",
"esbuild-register": "^3.5.0"
},
"devDependencies": {
"@arethetypeswrong/cli": "^0.15.3",
Expand All @@ -60,7 +59,7 @@
"@neondatabase/serverless": "^0.9.1",
"@originjs/vite-plugin-commonjs": "^1.0.3",
"@planetscale/database": "^1.16.0",
"@types/better-sqlite3": "^7.6.4",
"@types/better-sqlite3": "^7.6.13",
"@types/dockerode": "^3.3.28",
"@types/glob": "^8.1.0",
"@types/json-diff": "^1.0.3",
Expand All @@ -76,7 +75,7 @@
"@typescript-eslint/parser": "^7.2.0",
"@vercel/postgres": "^0.8.0",
"ava": "^5.1.0",
"better-sqlite3": "^9.4.3",
"better-sqlite3": "^11.9.1",
"bun-types": "^0.6.6",
"camelcase": "^7.0.1",
"chalk": "^5.2.0",
Expand All @@ -90,6 +89,7 @@
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"gel": "^2.0.0",
"get-port": "^6.1.2",
"glob": "^8.1.0",
"hanji": "^0.0.5",
Expand Down
65 changes: 55 additions & 10 deletions drizzle-kit/src/jsonStatements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
Index,
MatViewWithOption,
PgSchema,
PgSchemaSquashed,
PgSquasher,
Policy,
Role,
Expand Down Expand Up @@ -168,10 +169,10 @@ export interface JsonAlterRoleStatement {
export interface JsonDropValueFromEnumStatement {
type: 'alter_type_drop_value';
name: string;
schema: string;
enumSchema: string;
deletedValues: string[];
newValues: string[];
columnsWithEnum: { schema: string; table: string; column: string }[];
columnsWithEnum: { tableSchema: string; table: string; column: string; default?: string; columnType: string }[];
}

export interface JsonCreateSequenceStatement {
Expand Down Expand Up @@ -472,6 +473,22 @@ export interface JsonAlterColumnTypeStatement {
columnGenerated?: { as: string; type: 'stored' | 'virtual' };
}

export interface JsonAlterColumnPgTypeStatement {
type: 'pg_alter_table_alter_column_set_type';
tableName: string;
columnName: string;
typeSchema: string | undefined;
newDataType: { name: string; isEnum: boolean };
oldDataType: { name: string; isEnum: boolean };
schema: string;
columnDefault: string;
columnOnUpdate: boolean;
columnNotNull: boolean;
columnAutoIncrement: boolean;
columnPk: boolean;
columnGenerated?: { as: string; type: 'stored' | 'virtual' };
}

export interface JsonAlterColumnSetPrimaryKeyStatement {
type: 'alter_table_alter_column_set_pk';
tableName: string;
Expand Down Expand Up @@ -784,6 +801,7 @@ export type JsonAlterViewStatement =
export type JsonAlterColumnStatement =
| JsonRenameColumnStatement
| JsonAlterColumnTypeStatement
| JsonAlterColumnPgTypeStatement
| JsonAlterColumnSetDefaultStatement
| JsonAlterColumnDropDefaultStatement
| JsonAlterColumnSetNotNullStatement
Expand Down Expand Up @@ -1044,22 +1062,32 @@ export const prepareDropEnumValues = (
): JsonDropValueFromEnumStatement[] => {
if (!removedValues.length) return [];

const affectedColumns: { schema: string; table: string; column: string }[] = [];
const affectedColumns: JsonDropValueFromEnumStatement['columnsWithEnum'] = [];

for (const tableKey in json2.tables) {
const table = json2.tables[tableKey];
for (const columnKey in table.columns) {
const column = table.columns[columnKey];
if (column.type === name && column.typeSchema === schema) {
affectedColumns.push({ schema: table.schema || 'public', table: table.name, column: column.name });

const arrayDefinitionRegex = /\[\d*(?:\[\d*\])*\]/g;
const parsedColumnType = column.type.replace(arrayDefinitionRegex, '');

if (parsedColumnType === name && column.typeSchema === schema) {
affectedColumns.push({
tableSchema: table.schema,
table: table.name,
column: column.name,
columnType: column.type,
default: column.default,
});
}
}
}

return [{
type: 'alter_type_drop_value',
name: name,
schema: schema,
enumSchema: schema,
deletedValues: removedValues,
newValues: json2.enums[`${schema}.${name}`].values,
columnsWithEnum: affectedColumns,
Expand Down Expand Up @@ -2048,7 +2076,8 @@ export const preparePgAlterColumns = (
schema: string,
columns: AlteredColumn[],
// TODO: remove?
json2: CommonSquashedSchema,
json2: PgSchemaSquashed,
json1: PgSchemaSquashed,
action?: 'push' | undefined,
): JsonAlterColumnStatement[] => {
const tableKey = `${schema || 'public'}.${_tableName}`;
Expand All @@ -2074,6 +2103,8 @@ export const preparePgAlterColumns = (
).autoincrement;
const columnPk = (json2.tables[tableKey].columns[columnName] as any)
.primaryKey;
const typeSchema = json2.tables[tableKey].columns[columnName].typeSchema;
const json1ColumnTypeSchema = json1.tables[tableKey].columns[columnName].typeSchema;

const compositePk = json2.tables[tableKey].compositePrimaryKeys[`${tableName}_${columnName}`];

Expand All @@ -2088,12 +2119,26 @@ export const preparePgAlterColumns = (
}

if (column.type?.type === 'changed') {
const arrayDefinitionRegex = /\[\d*(?:\[\d*\])*\]/g;
const parsedNewColumnType = column.type.new.replace(arrayDefinitionRegex, '');
const parsedOldColumnType = column.type.old.replace(arrayDefinitionRegex, '');

const isNewTypeIsEnum = json2.enums[`${typeSchema}.${parsedNewColumnType}`];
const isOldTypeIsEnum = json1.enums[`${json1ColumnTypeSchema}.${parsedOldColumnType}`];

statements.push({
type: 'alter_table_alter_column_set_type',
type: 'pg_alter_table_alter_column_set_type',
tableName,
columnName,
newDataType: column.type.new,
oldDataType: column.type.old,
typeSchema: typeSchema,
newDataType: {
name: column.type.new,
isEnum: isNewTypeIsEnum ? true : false,
},
oldDataType: {
name: column.type.old,
isEnum: isOldTypeIsEnum ? true : false,
},
schema,
columnDefault,
columnOnUpdate,
Expand Down
19 changes: 10 additions & 9 deletions drizzle-kit/src/serializer/pgSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
getTableConfig,
getViewConfig,
IndexedColumn,
PgArray,
PgColumn,
PgDialect,
PgEnum,
Expand Down Expand Up @@ -158,7 +159,14 @@ export const generatePgSnapshot = (
const primaryKey: boolean = column.primary;
const sqlTypeLowered = column.getSQLType().toLowerCase();

const typeSchema = is(column, PgEnumColumn) ? column.enum.schema || 'public' : undefined;
const getEnumSchema = (column: PgColumn) => {
while (is(column, PgArray)) {
column = column.baseColumn;
}
return is(column, PgEnumColumn) ? column.enum.schema || 'public' : undefined;
};
const typeSchema: string | undefined = getEnumSchema(column);

const generated = column.generated;
const identity = column.generatedIdentity;

Expand Down Expand Up @@ -1536,14 +1544,7 @@ WHERE
i.indisunique as is_unique,
am.amname as method,
ic.reloptions as with,
coalesce(a.attname,
(('{' || pg_get_expr(
i.indexprs,
i.indrelid
)
|| '}')::text[]
)[k.i]
) AS column_name,
coalesce(a.attname, pg_get_indexdef(i.indexrelid, k.i, false)) AS column_name,
CASE
WHEN pg_get_expr(i.indexprs, i.indrelid) IS NOT NULL THEN 1
ELSE 0
Expand Down
Loading
Loading