Skip to content

Commit f34186c

Browse files
committed
Various fixes, features bundled for v0.41.0
1 parent a270acb commit f34186c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+2301
-148
lines changed

changelogs/drizzle-orm/0.41.0.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
- `bigint`, `number` modes for `SQLite`, `MySQL`, `PostgreSQL`, `SingleStore` `decimal` & `numeric` column types
2+
- Changed behavior of `sql-js` query preparation to query prebuild instead of db-side prepare due to need to manually free prepared queries, removed `.free()` method
3+
- Fixed `MySQL`, `SingleStore` `varchar` allowing not specifying `length` in config
4+
- Fixed `MySQL`, `SingleStore` `binary`, `varbinary` data\\type mismatches
5+
- Fixed `numeric`\\`decimal` data\\type mismatches: [#1290](https://github.com/drizzle-team/drizzle-orm/issues/1290), [#1453](https://github.com/drizzle-team/drizzle-orm/issues/1453)
6+
- Fixed `drizzle-studio` + `AWS Data Api` connection issue: [#3224](https://github.com/drizzle-team/drizzle-orm/issues/3224)
7+
- Fixed `isConfig` utility function checking types of wrong fields
8+
- Enabled `supportBigNumbers` in auto-created `mysql2` driver instances
9+
- Fixed custom schema tables querying in RQBv1: [#4060](https://github.com/drizzle-team/drizzle-orm/issues/4060)
10+
- Removed in-driver mapping for postgres types `1231` (`numeric[]`), `1115` (`timestamp[]`), `1185` (`timestamp_with_timezone[]`), `1187` (`interval[]`), `1182` (`date[]`), preventing precision loss and data\\type mismatches

drizzle-orm/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "drizzle-orm",
3-
"version": "0.40.1",
3+
"version": "0.41.0",
44
"description": "Drizzle ORM package for SQL databases",
55
"type": "module",
66
"scripts": {

drizzle-orm/src/aws-data-api/pg/driver.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ export function drizzle<
152152
$client: TClient;
153153
} {
154154
// eslint-disable-next-line no-instanceof/no-instanceof
155-
if (params[0] instanceof RDSDataClient) {
155+
if (params[0] instanceof RDSDataClient || params[0].constructor.name !== 'Object') {
156156
return construct(params[0] as TClient, params[1] as DrizzleAwsDataApiPgConfig<TSchema>) as any;
157157
}
158158

drizzle-orm/src/mysql-core/columns/binary.ts

+12
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,18 @@ export class MySqlBinary<T extends ColumnBaseConfig<'string', 'MySqlBinary'>> ex
4141

4242
length: number | undefined = this.config.length;
4343

44+
override mapFromDriverValue(value: string | Buffer | Uint8Array): string {
45+
if (typeof value === 'string') return value;
46+
if (Buffer.isBuffer(value)) return value.toString();
47+
48+
const str: string[] = [];
49+
for (const v of value) {
50+
str.push(v === 49 ? '1' : '0');
51+
}
52+
53+
return str.join('');
54+
}
55+
4456
getSQLType(): string {
4557
return this.length === undefined ? `binary` : `binary(${this.length})`;
4658
}

drizzle-orm/src/mysql-core/columns/decimal.ts

+147-9
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnCon
22
import type { ColumnBaseConfig } from '~/column.ts';
33
import { entityKind } from '~/entity.ts';
44
import type { AnyMySqlTable } from '~/mysql-core/table.ts';
5-
import { getColumnNameAndConfig } from '~/utils.ts';
5+
import { type Equal, getColumnNameAndConfig } from '~/utils.ts';
66
import { MySqlColumnBuilderWithAutoIncrement, MySqlColumnWithAutoIncrement } from './common.ts';
77

88
export type MySqlDecimalBuilderInitial<TName extends string> = MySqlDecimalBuilder<{
@@ -46,6 +46,134 @@ export class MySqlDecimal<T extends ColumnBaseConfig<'string', 'MySqlDecimal'>>
4646
readonly scale: number | undefined = this.config.scale;
4747
readonly unsigned: boolean | undefined = this.config.unsigned;
4848

49+
override mapFromDriverValue(value: unknown): string {
50+
if (typeof value === 'string') return value;
51+
52+
return String(value);
53+
}
54+
55+
getSQLType(): string {
56+
let type = '';
57+
if (this.precision !== undefined && this.scale !== undefined) {
58+
type += `decimal(${this.precision},${this.scale})`;
59+
} else if (this.precision === undefined) {
60+
type += 'decimal';
61+
} else {
62+
type += `decimal(${this.precision})`;
63+
}
64+
type = type === 'decimal(10,0)' || type === 'decimal(10)' ? 'decimal' : type;
65+
return this.unsigned ? `${type} unsigned` : type;
66+
}
67+
}
68+
69+
export type MySqlDecimalNumberBuilderInitial<TName extends string> = MySqlDecimalNumberBuilder<{
70+
name: TName;
71+
dataType: 'number';
72+
columnType: 'MySqlDecimalNumber';
73+
data: number;
74+
driverParam: string;
75+
enumValues: undefined;
76+
}>;
77+
78+
export class MySqlDecimalNumberBuilder<
79+
T extends ColumnBuilderBaseConfig<'number', 'MySqlDecimalNumber'>,
80+
> extends MySqlColumnBuilderWithAutoIncrement<T, MySqlDecimalConfig> {
81+
static override readonly [entityKind]: string = 'MySqlDecimalNumberBuilder';
82+
83+
constructor(name: T['name'], config: MySqlDecimalConfig | undefined) {
84+
super(name, 'number', 'MySqlDecimalNumber');
85+
this.config.precision = config?.precision;
86+
this.config.scale = config?.scale;
87+
this.config.unsigned = config?.unsigned;
88+
}
89+
90+
/** @internal */
91+
override build<TTableName extends string>(
92+
table: AnyMySqlTable<{ name: TTableName }>,
93+
): MySqlDecimalNumber<MakeColumnConfig<T, TTableName>> {
94+
return new MySqlDecimalNumber<MakeColumnConfig<T, TTableName>>(
95+
table,
96+
this.config as ColumnBuilderRuntimeConfig<any, any>,
97+
);
98+
}
99+
}
100+
101+
export class MySqlDecimalNumber<T extends ColumnBaseConfig<'number', 'MySqlDecimalNumber'>>
102+
extends MySqlColumnWithAutoIncrement<T, MySqlDecimalConfig>
103+
{
104+
static override readonly [entityKind]: string = 'MySqlDecimalNumber';
105+
106+
readonly precision: number | undefined = this.config.precision;
107+
readonly scale: number | undefined = this.config.scale;
108+
readonly unsigned: boolean | undefined = this.config.unsigned;
109+
110+
override mapFromDriverValue(value: unknown): number {
111+
if (typeof value === 'number') return value;
112+
113+
return Number(value);
114+
}
115+
116+
override mapToDriverValue = String;
117+
118+
getSQLType(): string {
119+
let type = '';
120+
if (this.precision !== undefined && this.scale !== undefined) {
121+
type += `decimal(${this.precision},${this.scale})`;
122+
} else if (this.precision === undefined) {
123+
type += 'decimal';
124+
} else {
125+
type += `decimal(${this.precision})`;
126+
}
127+
type = type === 'decimal(10,0)' || type === 'decimal(10)' ? 'decimal' : type;
128+
return this.unsigned ? `${type} unsigned` : type;
129+
}
130+
}
131+
132+
export type MySqlDecimalBigIntBuilderInitial<TName extends string> = MySqlDecimalBigIntBuilder<{
133+
name: TName;
134+
dataType: 'bigint';
135+
columnType: 'MySqlDecimalBigInt';
136+
data: bigint;
137+
driverParam: string;
138+
enumValues: undefined;
139+
}>;
140+
141+
export class MySqlDecimalBigIntBuilder<
142+
T extends ColumnBuilderBaseConfig<'bigint', 'MySqlDecimalBigInt'>,
143+
> extends MySqlColumnBuilderWithAutoIncrement<T, MySqlDecimalConfig> {
144+
static override readonly [entityKind]: string = 'MySqlDecimalBigIntBuilder';
145+
146+
constructor(name: T['name'], config: MySqlDecimalConfig | undefined) {
147+
super(name, 'bigint', 'MySqlDecimalBigInt');
148+
this.config.precision = config?.precision;
149+
this.config.scale = config?.scale;
150+
this.config.unsigned = config?.unsigned;
151+
}
152+
153+
/** @internal */
154+
override build<TTableName extends string>(
155+
table: AnyMySqlTable<{ name: TTableName }>,
156+
): MySqlDecimalBigInt<MakeColumnConfig<T, TTableName>> {
157+
return new MySqlDecimalBigInt<MakeColumnConfig<T, TTableName>>(
158+
table,
159+
this.config as ColumnBuilderRuntimeConfig<any, any>,
160+
);
161+
}
162+
}
163+
164+
export class MySqlDecimalBigInt<T extends ColumnBaseConfig<'bigint', 'MySqlDecimalBigInt'>>
165+
extends MySqlColumnWithAutoIncrement<T, MySqlDecimalConfig>
166+
{
167+
static override readonly [entityKind]: string = 'MySqlDecimalBigInt';
168+
169+
readonly precision: number | undefined = this.config.precision;
170+
readonly scale: number | undefined = this.config.scale;
171+
readonly unsigned: boolean | undefined = this.config.unsigned;
172+
173+
override mapFromDriverValue = BigInt;
174+
175+
override mapToDriverValue = String;
176+
49177
getSQLType(): string {
50178
let type = '';
51179
if (this.precision !== undefined && this.scale !== undefined) {
@@ -60,21 +188,31 @@ export class MySqlDecimal<T extends ColumnBaseConfig<'string', 'MySqlDecimal'>>
60188
}
61189
}
62190

63-
export interface MySqlDecimalConfig {
191+
export interface MySqlDecimalConfig<T extends 'string' | 'number' | 'bigint' = 'string' | 'number' | 'bigint'> {
64192
precision?: number;
65193
scale?: number;
66194
unsigned?: boolean;
195+
mode?: T;
67196
}
68197

69198
export function decimal(): MySqlDecimalBuilderInitial<''>;
70-
export function decimal(
71-
config: MySqlDecimalConfig,
72-
): MySqlDecimalBuilderInitial<''>;
73-
export function decimal<TName extends string>(
199+
export function decimal<TMode extends 'string' | 'number' | 'bigint'>(
200+
config: MySqlDecimalConfig<TMode>,
201+
): Equal<TMode, 'number'> extends true ? MySqlDecimalNumberBuilderInitial<''>
202+
: Equal<TMode, 'bigint'> extends true ? MySqlDecimalBigIntBuilderInitial<''>
203+
: MySqlDecimalBuilderInitial<''>;
204+
export function decimal<TName extends string, TMode extends 'string' | 'number' | 'bigint'>(
74205
name: TName,
75-
config?: MySqlDecimalConfig,
76-
): MySqlDecimalBuilderInitial<TName>;
206+
config?: MySqlDecimalConfig<TMode>,
207+
): Equal<TMode, 'number'> extends true ? MySqlDecimalNumberBuilderInitial<TName>
208+
: Equal<TMode, 'bigint'> extends true ? MySqlDecimalBigIntBuilderInitial<TName>
209+
: MySqlDecimalBuilderInitial<TName>;
77210
export function decimal(a?: string | MySqlDecimalConfig, b: MySqlDecimalConfig = {}) {
78211
const { name, config } = getColumnNameAndConfig<MySqlDecimalConfig>(a, b);
79-
return new MySqlDecimalBuilder(name, config);
212+
const mode = config?.mode;
213+
return mode === 'number'
214+
? new MySqlDecimalNumberBuilder(name, config)
215+
: mode === 'bigint'
216+
? new MySqlDecimalBigIntBuilder(name, config)
217+
: new MySqlDecimalBuilder(name, config);
80218
}

drizzle-orm/src/mysql-core/columns/varbinary.ts

+12
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ export class MySqlVarBinary<
4343

4444
length: number | undefined = this.config.length;
4545

46+
override mapFromDriverValue(value: string | Buffer | Uint8Array): string {
47+
if (typeof value === 'string') return value;
48+
if (Buffer.isBuffer(value)) return value.toString();
49+
50+
const str: string[] = [];
51+
for (const v of value) {
52+
str.push(v === 49 ? '1' : '0');
53+
}
54+
55+
return str.join('');
56+
}
57+
4658
getSQLType(): string {
4759
return this.length === undefined ? `varbinary` : `varbinary(${this.length})`;
4860
}

drizzle-orm/src/mysql-core/columns/varchar.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export interface MySqlVarCharConfig<
6363
TLength extends number | undefined = number | undefined,
6464
> {
6565
enum?: TEnum;
66-
length?: TLength;
66+
length: TLength;
6767
}
6868

6969
export function varchar<U extends string, T extends Readonly<[U, ...U[]]>, L extends number | undefined>(

drizzle-orm/src/mysql-core/dialect.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,10 @@ export class MySqlDialect {
312312
const selection = this.buildSelection(fieldsList, { isSingleTable });
313313

314314
const tableSql = (() => {
315-
if (is(table, Table) && table[Table.Symbol.OriginalName] !== table[Table.Symbol.Name]) {
316-
return sql`${sql.identifier(table[Table.Symbol.OriginalName])} ${sql.identifier(table[Table.Symbol.Name])}`;
315+
if (is(table, Table) && table[Table.Symbol.IsAlias]) {
316+
return sql`${sql`${sql.identifier(table[Table.Symbol.Schema] ?? '')}.`.if(table[Table.Symbol.Schema])}${
317+
sql.identifier(table[Table.Symbol.OriginalName])
318+
} ${sql.identifier(table[Table.Symbol.Name])}`;
317319
}
318320

319321
return table;

drizzle-orm/src/mysql2/driver.ts

+1
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ export function drizzle<
151151
const instance = typeof connection === 'string'
152152
? createPool({
153153
uri: connection,
154+
supportBigNumbers: true,
154155
})
155156
: createPool(connection!);
156157
const db = construct(instance, drizzleConfig);

drizzle-orm/src/neon-serverless/session.ts

+40
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,26 @@ export class NeonPreparedQuery<T extends PreparedQueryConfig> extends PgPrepared
5757
if (typeId === types.builtins.INTERVAL) {
5858
return (val: any) => val;
5959
}
60+
// numeric[]
61+
if (typeId === 1231) {
62+
return (val: any) => val;
63+
}
64+
// timestamp[]
65+
if (typeId === 1115) {
66+
return (val) => val;
67+
}
68+
// timestamp with timezone[]
69+
if (typeId === 1185) {
70+
return (val) => val;
71+
}
72+
// interval[]
73+
if (typeId === 1187) {
74+
return (val) => val;
75+
}
76+
// date[]
77+
if (typeId === 1182) {
78+
return (val) => val;
79+
}
6080
// @ts-ignore
6181
return types.getTypeParser(typeId, format);
6282
},
@@ -81,6 +101,26 @@ export class NeonPreparedQuery<T extends PreparedQueryConfig> extends PgPrepared
81101
if (typeId === types.builtins.INTERVAL) {
82102
return (val: any) => val;
83103
}
104+
// numeric[]
105+
if (typeId === 1231) {
106+
return (val: any) => val;
107+
}
108+
// timestamp[]
109+
if (typeId === 1115) {
110+
return (val) => val;
111+
}
112+
// timestamp with timezone[]
113+
if (typeId === 1185) {
114+
return (val) => val;
115+
}
116+
// interval[]
117+
if (typeId === 1187) {
118+
return (val) => val;
119+
}
120+
// date[]
121+
if (typeId === 1182) {
122+
return (val) => val;
123+
}
84124
// @ts-ignore
85125
return types.getTypeParser(typeId, format);
86126
},

drizzle-orm/src/node-postgres/session.ts

+40
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,26 @@ export class NodePgPreparedQuery<T extends PreparedQueryConfig> extends PgPrepar
5151
if (typeId === types.builtins.INTERVAL) {
5252
return (val) => val;
5353
}
54+
// numeric[]
55+
if (typeId === 1231) {
56+
return (val) => val;
57+
}
58+
// timestamp[]
59+
if (typeId === 1115) {
60+
return (val) => val;
61+
}
62+
// timestamp with timezone[]
63+
if (typeId === 1185) {
64+
return (val) => val;
65+
}
66+
// interval[]
67+
if (typeId === 1187) {
68+
return (val) => val;
69+
}
70+
// date[]
71+
if (typeId === 1182) {
72+
return (val) => val;
73+
}
5474
// @ts-ignore
5575
return types.getTypeParser(typeId, format);
5676
},
@@ -75,6 +95,26 @@ export class NodePgPreparedQuery<T extends PreparedQueryConfig> extends PgPrepar
7595
if (typeId === types.builtins.INTERVAL) {
7696
return (val) => val;
7797
}
98+
// numeric[]
99+
if (typeId === 1231) {
100+
return (val) => val;
101+
}
102+
// timestamp[]
103+
if (typeId === 1115) {
104+
return (val) => val;
105+
}
106+
// timestamp with timezone[]
107+
if (typeId === 1185) {
108+
return (val) => val;
109+
}
110+
// interval[]
111+
if (typeId === 1187) {
112+
return (val) => val;
113+
}
114+
// date[]
115+
if (typeId === 1182) {
116+
return (val) => val;
117+
}
78118
// @ts-ignore
79119
return types.getTypeParser(typeId, format);
80120
},

0 commit comments

Comments
 (0)