Skip to content
Merged
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
3 changes: 3 additions & 0 deletions changelogs/drizzle-kit/0.31.8.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Bug fixes

- Fixed `algorythm` => `algorithm` typo
5 changes: 5 additions & 0 deletions changelogs/drizzle-orm/0.45.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
- Fixed pg-native Pool detection in node-postgres transactions
- Allowed subqueries in select fields
- Updated typo algorythm => algorithm
- Fixed `$onUpdate` not handling `SQL` values (fixes [#2388](https://github.com/drizzle-team/drizzle-orm/issues/2388), tests implemented by [L-Mario564](https://github.com/L-Mario564) in [#2911](https://github.com/drizzle-team/drizzle-orm/pull/2911))
- Fixed `pg` mappers not handling `Date` instances in `bun-sql:postgresql` driver responses for `date`, `timestamp` types (fixes [#4493](https://github.com/drizzle-team/drizzle-orm/issues/4493))
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.31.7",
"version": "0.31.8",
"homepage": "https://orm.drizzle.team",
"keywords": [
"drizzle",
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 @@ -365,7 +365,7 @@ export const generateMySqlSnapshot = (
columns: indexColumns,
isUnique: value.config.unique ?? false,
using: value.config.using,
algorithm: value.config.algorythm,
algorithm: value.config.algorithm,
lock: value.config.lock,
};
});
Expand Down
2 changes: 1 addition & 1 deletion drizzle-kit/src/serializer/singlestoreSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ export const generateSingleStoreSnapshot = (
columns: indexColumns,
isUnique: value.config.unique ?? false,
using: value.config.using,
algorithm: value.config.algorythm,
algorithm: value.config.algorithm,
lock: value.config.lock,
};
});
Expand Down
2 changes: 1 addition & 1 deletion drizzle-orm/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "drizzle-orm",
"version": "0.44.7",
"version": "0.45.0",
"description": "Drizzle ORM package for SQL databases",
"type": "module",
"scripts": {
Expand Down
20 changes: 19 additions & 1 deletion drizzle-orm/src/gel-core/dialect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ export class GelDialect {
return sql.join(columnNames.flatMap((colName, i) => {
const col = tableColumns[colName]!;

const value = set[colName] ?? sql.param(col.onUpdateFn!(), col);
const onUpdateFnResult = col.onUpdateFn?.();
const value = set[colName] ?? (is(onUpdateFnResult, SQL) ? onUpdateFnResult : sql.param(onUpdateFnResult, col));
const res = sql`${sql.identifier(this.casing.getColumnCasing(col))} = ${value}`;

if (i < setSize - 1) {
Expand Down Expand Up @@ -241,6 +242,23 @@ export class GelDialect {
// } else {
chunk.push(field);
// }
} else if (is(field, Subquery)) {
const entries = Object.entries(field._.selectedFields) as [string, SQL.Aliased | Column | SQL][];

if (entries.length === 1) {
const entry = entries[0]![1];

const fieldDecoder = is(entry, SQL)
? entry.decoder
: is(entry, Column)
? { mapFromDriverValue: (v: any) => entry.mapFromDriverValue(v) }
: entry.sql.decoder;

if (fieldDecoder) {
field._.sql.decoder = fieldDecoder;
}
}
chunk.push(field);
}

if (i < columnsLen - 1) {
Expand Down
20 changes: 19 additions & 1 deletion drizzle-orm/src/mysql-core/dialect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ export class MySqlDialect {
return sql.join(columnNames.flatMap((colName, i) => {
const col = tableColumns[colName]!;

const value = set[colName] ?? sql.param(col.onUpdateFn!(), col);
const onUpdateFnResult = col.onUpdateFn?.();
const value = set[colName] ?? (is(onUpdateFnResult, SQL) ? onUpdateFnResult : sql.param(onUpdateFnResult, col));
const res = sql`${sql.identifier(this.casing.getColumnCasing(col))} = ${value}`;

if (i < setSize - 1) {
Expand Down Expand Up @@ -222,6 +223,23 @@ export class MySqlDialect {
} else {
chunk.push(field);
}
} else if (is(field, Subquery)) {
const entries = Object.entries(field._.selectedFields) as [string, SQL.Aliased | Column | SQL][];

if (entries.length === 1) {
const entry = entries[0]![1];

const fieldDecoder = is(entry, SQL)
? entry.decoder
: is(entry, Column)
? { mapFromDriverValue: (v: any) => entry.mapFromDriverValue(v) }
: entry.sql.decoder;

if (fieldDecoder) {
field._.sql.decoder = fieldDecoder;
}
}
chunk.push(field);
}

if (i < columnsLen - 1) {
Expand Down
8 changes: 4 additions & 4 deletions drizzle-orm/src/mysql-core/indexes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ interface IndexConfig {
using?: 'btree' | 'hash';

/**
* If set, the index will be created as `create index ... algorythm { 'default' | 'inplace' | 'copy' }`.
* If set, the index will be created as `create index ... algorithm { 'default' | 'inplace' | 'copy' }`.
*/
algorythm?: 'default' | 'inplace' | 'copy';
algorithm?: 'default' | 'inplace' | 'copy';

/**
* If set, adds locks to the index creation.
Expand Down Expand Up @@ -67,8 +67,8 @@ export class IndexBuilder implements AnyIndexBuilder {
return this;
}

algorythm(algorythm: IndexConfig['algorythm']): this {
this.config.algorythm = algorythm;
algorithm(algorithm: IndexConfig['algorithm']): this {
this.config.algorithm = algorithm;
return this;
}

Expand Down
5 changes: 3 additions & 2 deletions drizzle-orm/src/node-postgres/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { tracer } from '~/tracing.ts';
import { type Assume, mapResultRow } from '~/utils.ts';

const { Pool, types } = pg;
const NativePool = (<any> pg).native ? (<{ Pool: typeof Pool }> (<any> pg).native).Pool : undefined;

export type NodePgClient = pg.Pool | PoolClient | Client;

Expand Down Expand Up @@ -249,7 +250,7 @@ export class NodePgSession<
transaction: (tx: NodePgTransaction<TFullSchema, TSchema>) => Promise<T>,
config?: PgTransactionConfig | undefined,
): Promise<T> {
const session = this.client instanceof Pool // eslint-disable-line no-instanceof/no-instanceof
const session = (this.client instanceof Pool || (NativePool && this.client instanceof NativePool)) // eslint-disable-line no-instanceof/no-instanceof
? new NodePgSession(await this.client.connect(), this.dialect, this.schema, this.options)
: this;
const tx = new NodePgTransaction<TFullSchema, TSchema>(this.dialect, session, this.schema);
Expand All @@ -262,7 +263,7 @@ export class NodePgSession<
await tx.execute(sql`rollback`);
throw error;
} finally {
if (this.client instanceof Pool) { // eslint-disable-line no-instanceof/no-instanceof
if (this.client instanceof Pool || (NativePool && this.client instanceof NativePool)) { // eslint-disable-line no-instanceof/no-instanceof
(session.client as PoolClient).release();
}
}
Expand Down
5 changes: 3 additions & 2 deletions drizzle-orm/src/operations.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { AnyColumn, Column } from './column.ts';
import type { SQL } from './sql/sql.ts';
import type { Subquery } from './subquery.ts';
import type { Table } from './table.ts';

export type RequiredKeyOnly<TKey extends string, T extends Column> = T extends AnyColumn<{
Expand All @@ -25,7 +26,7 @@ export type OptionalKeyOnly<TKey extends string, T extends Column, OverrideT ext
// TODO: SQL -> SQLWrapper
export type SelectedFieldsFlat<TColumn extends Column> = Record<
string,
TColumn | SQL | SQL.Aliased
TColumn | SQL | SQL.Aliased | Subquery
>;

export type SelectedFieldsFlatFull<TColumn extends Column> = Record<
Expand All @@ -40,5 +41,5 @@ export type SelectedFields<TColumn extends Column, TTable extends Table> = Recor

export type SelectedFieldsOrdered<TColumn extends Column> = {
path: string[];
field: TColumn | SQL | SQL.Aliased;
field: TColumn | SQL | SQL.Aliased | Subquery;
}[];
12 changes: 10 additions & 2 deletions drizzle-orm/src/pg-core/columns/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ export class PgDate<T extends ColumnBaseConfig<'date', 'PgDate'>> extends PgColu
return 'date';
}

override mapFromDriverValue(value: string): Date {
return new Date(value);
override mapFromDriverValue(value: string | Date): Date {
if (typeof value === 'string') return new Date(value);

return value;
}

override mapToDriverValue(value: Date): string {
Expand Down Expand Up @@ -81,6 +83,12 @@ export class PgDateString<T extends ColumnBaseConfig<'string', 'PgDateString'>>
getSQLType(): string {
return 'date';
}

override mapFromDriverValue(value: Date | string): string {
if (typeof value === 'string') return value;

return value.toISOString().slice(0, -14);
}
}

export interface PgDateConfig<T extends 'date' | 'string' = 'date' | 'string'> {
Expand Down
21 changes: 18 additions & 3 deletions drizzle-orm/src/pg-core/columns/timestamp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ export class PgTimestamp<T extends ColumnBaseConfig<'date', 'PgTimestamp'>> exte
return `timestamp${precision}${this.withTimezone ? ' with time zone' : ''}`;
}

override mapFromDriverValue = (value: string): Date | null => {
return new Date(this.withTimezone ? value : value + '+0000');
};
override mapFromDriverValue(value: Date | string): Date {
if (typeof value === 'string') return new Date(this.withTimezone ? value : value + '+0000');

return value;
}

override mapToDriverValue = (value: Date): string => {
return value.toISOString();
Expand Down Expand Up @@ -121,6 +123,19 @@ export class PgTimestampString<T extends ColumnBaseConfig<'string', 'PgTimestamp
const precision = this.precision === undefined ? '' : `(${this.precision})`;
return `timestamp${precision}${this.withTimezone ? ' with time zone' : ''}`;
}

override mapFromDriverValue(value: Date | string): string {
if (typeof value === 'string') return value;

const shortened = value.toISOString().slice(0, -1).replace('T', ' ');
if (this.withTimezone) {
const offset = value.getTimezoneOffset();
const sign = offset <= 0 ? '+' : '-';
return `${shortened}${sign}${Math.floor(Math.abs(offset) / 60).toString().padStart(2, '0')}`;
}

return shortened;
}
}

export type Precision = 0 | 1 | 2 | 3 | 4 | 5 | 6;
Expand Down
20 changes: 19 additions & 1 deletion drizzle-orm/src/pg-core/dialect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ export class PgDialect {
return sql.join(columnNames.flatMap((colName, i) => {
const col = tableColumns[colName]!;

const value = set[colName] ?? sql.param(col.onUpdateFn!(), col);
const onUpdateFnResult = col.onUpdateFn?.();
const value = set[colName] ?? (is(onUpdateFnResult, SQL) ? onUpdateFnResult : sql.param(onUpdateFnResult, col));
const res = sql`${sql.identifier(this.casing.getColumnCasing(col))} = ${value}`;

if (i < setSize - 1) {
Expand Down Expand Up @@ -246,6 +247,23 @@ export class PgDialect {
} else {
chunk.push(field);
}
} else if (is(field, Subquery)) {
const entries = Object.entries(field._.selectedFields) as [string, SQL.Aliased | Column | SQL][];

if (entries.length === 1) {
const entry = entries[0]![1];

const fieldDecoder = is(entry, SQL)
? entry.decoder
: is(entry, Column)
? { mapFromDriverValue: (v: any) => entry.mapFromDriverValue(v) }
: entry.sql.decoder;

if (fieldDecoder) {
field._.sql.decoder = fieldDecoder;
}
}
chunk.push(field);
}

if (i < columnsLen - 1) {
Expand Down
11 changes: 6 additions & 5 deletions drizzle-orm/src/query-builders/select.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { SelectedFields } from '~/operations.ts';
import type { ColumnsSelection, SQL, View } from '~/sql/sql.ts';
import type { Subquery } from '~/subquery.ts';
import type { Table } from '~/table.ts';
import type { Assume, DrizzleTypeError, Equal, IsAny, Simplify } from '~/utils.ts';
import type { Assume, DrizzleTypeError, Equal, FromSingleKeyObject, IsAny, IsUnion, Not, Simplify } from '~/utils.ts';

export type JoinType = 'inner' | 'left' | 'right' | 'full' | 'cross';

Expand Down Expand Up @@ -44,10 +44,6 @@ export type SelectResult<
: TSelectMode extends 'single' ? SelectResultFields<TResult>
: ApplyNotNullMapToJoins<SelectResultFields<TResult>, TNullabilityMap>;

type IsUnion<T, U extends T = T> = (T extends any ? (U extends T ? false : true) : never) extends false ? false : true;

type Not<T extends boolean> = T extends true ? false : true;

type SelectPartialResult<TFields, TNullability extends Record<string, JoinNullability>> = TNullability extends
TNullability ? {
[Key in keyof TFields]: TFields[Key] extends infer TField
Expand All @@ -61,6 +57,11 @@ type SelectPartialResult<TFields, TNullability extends Record<string, JoinNullab
? ApplyNullability<SelectResultField<TField>, TNullability[TField['_']['tableName']]>
: never
: TField extends SQL | SQL.Aliased ? SelectResultField<TField>
: TField extends Subquery ? FromSingleKeyObject<
TField['_']['selectedFields'],
TField['_']['selectedFields'] extends { [key: string]: infer TValue } ? SelectResultField<TValue> : never,
'You can only select one column in the subquery'
>
: TField extends Record<string, any>
? TField[keyof TField] extends AnyColumn<{ tableName: infer TTableName extends string }> | SQL | SQL.Aliased
? Not<IsUnion<TTableName>> extends true
Expand Down
20 changes: 19 additions & 1 deletion drizzle-orm/src/singlestore-core/dialect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ export class SingleStoreDialect {
return sql.join(columnNames.flatMap((colName, i) => {
const col = tableColumns[colName]!;

const value = set[colName] ?? sql.param(col.onUpdateFn!(), col);
const onUpdateFnResult = col.onUpdateFn?.();
const value = set[colName] ?? (is(onUpdateFnResult, SQL) ? onUpdateFnResult : sql.param(onUpdateFnResult, col));
const res = sql`${sql.identifier(this.casing.getColumnCasing(col))} = ${value}`;

if (i < setSize - 1) {
Expand Down Expand Up @@ -221,6 +222,23 @@ export class SingleStoreDialect {
} else {
chunk.push(field);
}
} else if (is(field, Subquery)) {
const entries = Object.entries(field._.selectedFields) as [string, SQL.Aliased | Column | SQL][];

if (entries.length === 1) {
const entry = entries[0]![1];

const fieldDecoder = is(entry, SQL)
? entry.decoder
: is(entry, Column)
? { mapFromDriverValue: (v: any) => entry.mapFromDriverValue(v) }
: entry.sql.decoder;

if (fieldDecoder) {
field._.sql.decoder = fieldDecoder;
}
}
chunk.push(field);
}

if (i < columnsLen - 1) {
Expand Down
8 changes: 4 additions & 4 deletions drizzle-orm/src/singlestore-core/indexes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ interface IndexConfig {
using?: 'btree' | 'hash';

/**
* If set, the index will be created as `create index ... algorythm { 'default' | 'inplace' | 'copy' }`.
* If set, the index will be created as `create index ... algorithm { 'default' | 'inplace' | 'copy' }`.
*/
algorythm?: 'default' | 'inplace' | 'copy';
algorithm?: 'default' | 'inplace' | 'copy';

/**
* If set, adds locks to the index creation.
Expand Down Expand Up @@ -67,8 +67,8 @@ export class IndexBuilder implements AnyIndexBuilder {
return this;
}

algorythm(algorythm: IndexConfig['algorythm']): this {
this.config.algorythm = algorythm;
algorithm(algorithm: IndexConfig['algorithm']): this {
this.config.algorithm = algorithm;
return this;
}

Expand Down
Loading
Loading