Skip to content

Commit

Permalink
Merge pull request #2760 from drizzle-team/beta
Browse files Browse the repository at this point in the history
Beta
  • Loading branch information
AndriiSherman authored Aug 8, 2024
2 parents 7d2ae84 + f2a2b5f commit 6adbd78
Show file tree
Hide file tree
Showing 20 changed files with 890 additions and 35 deletions.
24 changes: 24 additions & 0 deletions changelogs/drizzle-kit/0.24.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
## Breaking changes (for SQLite users)

#### Fixed [Composite primary key order is not consistent](https://github.com/drizzle-team/drizzle-kit-mirror/issues/342) by removing `sort` in SQLite and to be consistant with the same logic in PostgreSQL and MySQL

The issue that may arise for SQLite users with any driver using composite primary keys is that the order in the database may differ from the Drizzle schema.

- If you are using `push`, you **MAY** be prompted to update your table with a new order of columns in the composite primary key. You will need to either change it manually in the database or push the changes, but this may lead to data loss, etc.

- If you are using `generate`, you **MAY** also be prompted to update your table with a new order of columns in the composite primary key. You can either keep that migration or skip it by emptying the SQL migration file.

If nothing works for you and you are blocked, please reach out to me @AndriiSherman. I will try to help you!


## Bug fixes

- [[BUG] When using double type columns, import is not inserted](https://github.com/drizzle-team/drizzle-kit-mirror/issues/403) - thanks @Karibash
- [[BUG] A number value is specified as the default for a column of type char](https://github.com/drizzle-team/drizzle-kit-mirror/issues/404) - thanks @Karibash
- [[BUG]: Array default in migrations are wrong](https://github.com/drizzle-team/drizzle-orm/issues/2621) - thanks @L-Mario564
- [[FEATURE]: Simpler default array fields](https://github.com/drizzle-team/drizzle-orm/issues/2709) - thanks @L-Mario564
- [[BUG]: drizzle-kit generate succeeds but generates invalid SQL for default([]) - Postgres](https://github.com/drizzle-team/drizzle-orm/issues/2432) - thanks @L-Mario564
- [[BUG]: Incorrect type for array column default value](https://github.com/drizzle-team/drizzle-orm/issues/2334) - thanks @L-Mario564
- [[BUG]: error: column is of type integer[] but default expression is of type integer](https://github.com/drizzle-team/drizzle-orm/issues/2224) - thanks @L-Mario564
- [[BUG]: Default value in array generating wrong migration file](https://github.com/drizzle-team/drizzle-orm/issues/1003) - thanks @L-Mario564
- [[BUG]: enum as array, not possible?](https://github.com/drizzle-team/drizzle-orm/issues/1564) - thanks @L-Mario564
64 changes: 64 additions & 0 deletions changelogs/drizzle-orm/0.33.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
## Breaking changes (for some of postgres.js users)

#### Bugs fixed for this breaking change

- [Open
[BUG]: jsonb always inserted as a json string when using postgres-js](https://github.com/drizzle-team/drizzle-orm/issues/724)
- [[BUG]: jsonb type on postgres implement incorrectly](https://github.com/drizzle-team/drizzle-orm/issues/1511)

> As we are doing with other drivers, we've changed the behavior of PostgreSQL-JS to pass raw JSON values, the same as you see them in the database. So if you are using the PostgreSQL-JS driver and passing data to Drizzle elsewhere, please check the new behavior of the client after it is passed to Drizzle.
> We will update it to ensure it does not override driver behaviors, but this will be done as a complex task for everything in Drizzle in other releases
If you were using `postgres-js` with `jsonb` fields, you might have seen stringified objects in your database, while drizzle insert and select operations were working as expected.

You need to convert those fields from strings to actual JSON objects. To do this, you can use the following query to update your database:

**if you are using jsonb:**
```sql
update table_name
set jsonb_column = (jsonb_column #>> '{}')::jsonb;
```

**if you are using json:**
```sql
update table_name
set json_column = (json_column #>> '{}')::json;
```

We've tested it in several cases, and it worked well, but only if all stringified objects are arrays or objects. If you have primitives like strings, numbers, booleans, etc., you can use this query to update all the fields

**if you are using jsonb:**
```sql
UPDATE table_name
SET jsonb_column = CASE
-- Convert to JSONB if it is a valid JSON object or array
WHEN jsonb_column #>> '{}' LIKE '{%' OR jsonb_column #>> '{}' LIKE '[%' THEN
(jsonb_column #>> '{}')::jsonb
ELSE
jsonb_column
END
WHERE
jsonb_column IS NOT NULL;
```

**if you are using json:**
```sql
UPDATE table_name
SET json_column = CASE
-- Convert to JSON if it is a valid JSON object or array
WHEN json_column #>> '{}' LIKE '{%' OR json_column #>> '{}' LIKE '[%' THEN
(json_column #>> '{}')::json
ELSE
json_column
END
WHERE json_column IS NOT NULL;
```

If nothing works for you and you are blocked, please reach out to me @AndriiSherman. I will try to help you!

## Bug Fixes

- [[BUG]: boolean mode not working with prepared statements (bettersqlite)](https://github.com/drizzle-team/drizzle-orm/issues/2568) - thanks @veloii
- [[BUG]: isTable helper function is not working](https://github.com/drizzle-team/drizzle-orm/issues/2672) - thanks @hajek-raven
- [[BUG]: Documentation is outdated on inArray and notInArray Methods](https://github.com/drizzle-team/drizzle-orm/issues/2690) - thanks @RemiPeruto
2 changes: 1 addition & 1 deletion drizzle-kit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "drizzle-kit",
"version": "0.23.2",
"version": "0.24.0",
"homepage": "https://orm.drizzle.team",
"keywords": [
"drizzle",
Expand Down
10 changes: 8 additions & 2 deletions drizzle-kit/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from './cli/commands/migrate';
import { pgPushIntrospect } from './cli/commands/pgIntrospect';
import { pgSuggestions } from './cli/commands/pgPushUtils';
import { updateUpToV6 as upPgV6 } from './cli/commands/pgUp';
import { updateUpToV6 as upPgV6, updateUpToV7 as upPgV7 } from './cli/commands/pgUp';
import { sqlitePushIntrospect } from './cli/commands/sqliteIntrospect';
import { logSuggestionsAndReturn } from './cli/commands/sqlitePushUtils';
import { originUUID } from './global';
Expand Down Expand Up @@ -341,5 +341,11 @@ export const pushMySQLSchema = async (
};

export const upPgSnapshot = (snapshot: Record<string, unknown>) => {
return upPgV6(snapshot);
if (snapshot.version === '5') {
return upPgV7(upPgV6(snapshot));
}
if (snapshot.version === '6') {
return upPgV7(snapshot);
}
return snapshot;
};
1 change: 1 addition & 0 deletions drizzle-kit/src/introspect-mysql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ export const schemaToTypeScript = (
patched = patched.startsWith('datetime(') ? 'datetime' : patched;
patched = patched.startsWith('varbinary(') ? 'varbinary' : patched;
patched = patched.startsWith('int(') ? 'int' : patched;
patched = patched.startsWith('double(') ? 'double' : patched;
return patched;
})
.filter((type) => {
Expand Down
2 changes: 1 addition & 1 deletion drizzle-kit/src/serializer/mysqlSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ export const fromDatabase = async (
default: columnDefault === null
? undefined
: /^-?[\d.]+(?:e-?\d+)?$/.test(columnDefault)
&& !columnType.startsWith('decimal')
&& !['decimal', 'char', 'varchar'].some((type) => columnType.startsWith(type))
? Number(columnDefault)
: isDefaultAnExpression
? clearDefaults(columnDefault, collation)
Expand Down
46 changes: 45 additions & 1 deletion drizzle-kit/src/serializer/pgSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import type {
Table,
UniqueConstraint,
} from '../serializer/pgSchema';
import type { DB } from '../utils';
import { type DB, isPgArrayType } from '../utils';
import { sqlToStr } from '.';

const dialect = new PgDialect();
Expand Down Expand Up @@ -75,6 +75,43 @@ function stringFromDatabaseIdentityProperty(field: any): string | undefined {
: String(field);
}

function buildArrayString(array: any[], sqlType: string): string {
sqlType = sqlType.split('[')[0];
const values = array
.map((value) => {
if (typeof value === 'number' || typeof value === 'bigint') {
return value.toString();
} else if (typeof value === 'boolean') {
return value ? 'true' : 'false';
} else if (Array.isArray(value)) {
return buildArrayString(value, sqlType);
} else if (value instanceof Date) {
if (sqlType === 'date') {
return `"${value.toISOString().split('T')[0]}"`;
} else if (sqlType === 'timestamp') {
return `"${
value.toISOString()
.replace('T', ' ')
.slice(0, 23)
}"`;
} else {
return `"${value.toISOString()}"`;
}
} else if (typeof value === 'object') {
return `"${
JSON
.stringify(value)
.replaceAll('"', '\\"')
}"`;
}

return `"${value}"`;
})
.join(',');

return `{${values}}`;
}

export const generatePgSnapshot = (
tables: AnyPgTable[],
enums: PgEnum<any>[],
Expand Down Expand Up @@ -226,6 +263,13 @@ export const generatePgSnapshot = (
} else {
columnToSet.default = `'${column.default.toISOString()}'`;
}
} else if (isPgArrayType(sqlTypeLowered) && Array.isArray(column.default)) {
columnToSet.default = `'${
buildArrayString(
column.default,
sqlTypeLowered,
)
}'::${sqlTypeLowered}`;
} else {
// Should do for all types
// columnToSet.default = `'${column.default}'::${sqlTypeLowered}`;
Expand Down
3 changes: 1 addition & 2 deletions drizzle-kit/src/serializer/sqliteSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ export const generateSqliteSnapshot = (
primaryKeys.forEach((it) => {
if (it.columns.length > 1) {
primaryKeysObject[it.getName()] = {
columns: it.columns.map((it) => it.name).sort(),
columns: it.columns.map((it) => it.name),
name: it.getName(),
};
} else {
Expand Down Expand Up @@ -509,7 +509,6 @@ export const fromDatabase = async (

for (const [key, value] of Object.entries(tableToPk)) {
if (value.length > 1) {
value.sort();
result[key].compositePrimaryKeys = {
[`${key}_${value.join('_')}_pk`]: {
columns: value,
Expand Down
4 changes: 4 additions & 0 deletions drizzle-kit/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,3 +327,7 @@ export const normaliseSQLiteUrl = (

assertUnreachable(type);
};

export function isPgArrayType(sqlType: string) {
return sqlType.match(/.*\[\d*\].*|.*\[\].*/g) !== null;
}
44 changes: 43 additions & 1 deletion drizzle-kit/tests/introspect/mysql.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Docker from 'dockerode';
import { SQL, sql } from 'drizzle-orm';
import { int, mysqlTable, text } from 'drizzle-orm/mysql-core';
import { char, int, mysqlTable, text, varchar } from 'drizzle-orm/mysql-core';
import * as fs from 'fs';
import getPort from 'get-port';
import { Connection, createConnection } from 'mysql2/promise';
Expand Down Expand Up @@ -123,3 +123,45 @@ test('generated always column virtual: link to another column', async () => {

await client.query(`drop table users;`);
});

test('Default value of character type column: char', async () => {
const schema = {
users: mysqlTable('users', {
id: int('id'),
sortKey: char('sortKey', { length: 255 }).default('0'),
}),
};

const { statements, sqlStatements } = await introspectMySQLToFile(
client,
schema,
'default-value-char-column',
'drizzle',
);

expect(statements.length).toBe(0);
expect(sqlStatements.length).toBe(0);

await client.query(`drop table users;`);
});

test('Default value of character type column: varchar', async () => {
const schema = {
users: mysqlTable('users', {
id: int('id'),
sortKey: varchar('sortKey', { length: 255 }).default('0'),
}),
};

const { statements, sqlStatements } = await introspectMySQLToFile(
client,
schema,
'default-value-varchar-column',
'drizzle',
);

expect(statements.length).toBe(0);
expect(sqlStatements.length).toBe(0);

await client.query(`drop table users;`);
});
Loading

0 comments on commit 6adbd78

Please sign in to comment.