From 348e49632fc04fcd4e13de3ca99ba5443058bc1b Mon Sep 17 00:00:00 2001 From: Sukairo-02 Date: Tue, 28 Jan 2025 15:32:45 +0200 Subject: [PATCH 1/4] Fixed SQLite onConflict clauses being overwritten instead of stacked, added related tests, removed unused import --- drizzle-orm/src/sqlite-core/db.ts | 2 +- drizzle-orm/src/sqlite-core/dialect.ts | 4 +- .../src/sqlite-core/query-builders/insert.ts | 15 +- .../tests/sqlite/better-sqlite.test.ts | 2 +- .../tests/sqlite/sqlite-common.ts | 176 ++++++++++++++++++ 5 files changed, 192 insertions(+), 7 deletions(-) diff --git a/drizzle-orm/src/sqlite-core/db.ts b/drizzle-orm/src/sqlite-core/db.ts index f8593c783..f5735155f 100644 --- a/drizzle-orm/src/sqlite-core/db.ts +++ b/drizzle-orm/src/sqlite-core/db.ts @@ -25,7 +25,7 @@ import { SQLiteCountBuilder } from './query-builders/count.ts'; import { RelationalQueryBuilder } from './query-builders/query.ts'; import { SQLiteRaw } from './query-builders/raw.ts'; import type { SelectedFields } from './query-builders/select.types.ts'; -import type { WithBuilder, WithSubqueryWithSelection } from './subquery.ts'; +import type { WithBuilder } from './subquery.ts'; import type { SQLiteViewBase } from './view-base.ts'; export class BaseSQLiteDatabase< diff --git a/drizzle-orm/src/sqlite-core/dialect.ts b/drizzle-orm/src/sqlite-core/dialect.ts index 8db4ee56b..6eae0dd93 100644 --- a/drizzle-orm/src/sqlite-core/dialect.ts +++ b/drizzle-orm/src/sqlite-core/dialect.ts @@ -487,7 +487,9 @@ export abstract class SQLiteDialect { ? sql` returning ${this.buildSelection(returning, { isSingleTable: true })}` : undefined; - const onConflictSql = onConflict ? sql` on conflict ${onConflict}` : undefined; + const onConflictSql = onConflict?.length + ? sql.join(onConflict) + : undefined; // if (isSingleValue && valuesSqlList.length === 0){ // return sql`insert into ${table} default values ${onConflictSql}${returningSql}`; diff --git a/drizzle-orm/src/sqlite-core/query-builders/insert.ts b/drizzle-orm/src/sqlite-core/query-builders/insert.ts index 2c26df8df..7609162c3 100644 --- a/drizzle-orm/src/sqlite-core/query-builders/insert.ts +++ b/drizzle-orm/src/sqlite-core/query-builders/insert.ts @@ -21,7 +21,7 @@ export interface SQLiteInsertConfig { table: TTable; values: Record[] | SQLiteInsertSelectQueryBuilder | SQL; withList?: Subquery[]; - onConflict?: SQL; + onConflict?: SQL[]; returning?: SelectedFieldsOrdered; select?: boolean; } @@ -303,12 +303,14 @@ export class SQLiteInsertBase< * ``` */ onConflictDoNothing(config: { target?: IndexColumn | IndexColumn[]; where?: SQL } = {}): this { + if (!this.config.onConflict) this.config.onConflict = []; + if (config.target === undefined) { - this.config.onConflict = sql`do nothing`; + this.config.onConflict.push(sql` on conflict do nothing`); } else { const targetSql = Array.isArray(config.target) ? sql`${config.target}` : sql`${[config.target]}`; const whereSql = config.where ? sql` where ${config.where}` : sql``; - this.config.onConflict = sql`${targetSql} do nothing${whereSql}`; + this.config.onConflict.push(sql` on conflict ${targetSql} do nothing${whereSql}`); } return this; } @@ -348,12 +350,17 @@ export class SQLiteInsertBase< 'You cannot use both "where" and "targetWhere"/"setWhere" at the same time - "where" is deprecated, use "targetWhere" or "setWhere" instead.', ); } + + if (!this.config.onConflict) this.config.onConflict = []; + const whereSql = config.where ? sql` where ${config.where}` : undefined; const targetWhereSql = config.targetWhere ? sql` where ${config.targetWhere}` : undefined; const setWhereSql = config.setWhere ? sql` where ${config.setWhere}` : undefined; const targetSql = Array.isArray(config.target) ? sql`${config.target}` : sql`${[config.target]}`; const setSql = this.dialect.buildUpdateSet(this.config.table, mapUpdateSet(this.config.table, config.set)); - this.config.onConflict = sql`${targetSql}${targetWhereSql} do update set ${setSql}${whereSql}${setWhereSql}`; + this.config.onConflict.push( + sql` on conflict ${targetSql}${targetWhereSql} do update set ${setSql}${whereSql}${setWhereSql}`, + ); return this; } diff --git a/integration-tests/tests/sqlite/better-sqlite.test.ts b/integration-tests/tests/sqlite/better-sqlite.test.ts index 53feee15f..ed9a2f861 100644 --- a/integration-tests/tests/sqlite/better-sqlite.test.ts +++ b/integration-tests/tests/sqlite/better-sqlite.test.ts @@ -6,7 +6,7 @@ import { afterAll, beforeAll, beforeEach, expect, test } from 'vitest'; import { skipTests } from '~/common'; import { anotherUsersMigratorTable, tests, usersMigratorTable } from './sqlite-common'; -const ENABLE_LOGGING = false; +const ENABLE_LOGGING = true; let db: BetterSQLite3Database; let client: Database.Database; diff --git a/integration-tests/tests/sqlite/sqlite-common.ts b/integration-tests/tests/sqlite/sqlite-common.ts index 2419b1cc2..1263e46ed 100644 --- a/integration-tests/tests/sqlite/sqlite-common.ts +++ b/integration-tests/tests/sqlite/sqlite-common.ts @@ -125,6 +125,14 @@ const pkExampleTable = sqliteTable('pk_example', { compositePk: primaryKey({ columns: [table.id, table.name] }), })); +const conflictChainExampleTable = sqliteTable('conflict_chain_example', { + id: integer('id').notNull().unique(), + name: text('name').notNull(), + email: text('email').notNull(), +}, (table) => ({ + compositePk: primaryKey({ columns: [table.id, table.name] }), +})); + const bigIntExample = sqliteTable('big_int_example', { id: integer('id').primaryKey(), name: text('name').notNull(), @@ -154,6 +162,7 @@ export function tests() { await db.run(sql`drop table if exists ${orders}`); await db.run(sql`drop table if exists ${bigIntExample}`); await db.run(sql`drop table if exists ${pkExampleTable}`); + await db.run(sql`drop table if exists ${conflictChainExampleTable}`); await db.run(sql`drop table if exists user_notifications_insert_into`); await db.run(sql`drop table if exists users_insert_into`); await db.run(sql`drop table if exists notifications_insert_into`); @@ -212,6 +221,14 @@ export function tests() { primary key (id, name) ) `); + await db.run(sql` + create table ${conflictChainExampleTable} ( + id integer not null unique, + name text not null, + email text not null, + primary key (id, name) + ) + `); await db.run(sql` create table ${bigIntExample} ( id integer primary key, @@ -2037,6 +2054,165 @@ export function tests() { expect(res).toEqual([{ id: 1, name: 'John', email: 'john1@example.com' }]); }); + test('insert with onConflict chained (.update -> .nothing)', async (ctx) => { + const { db } = ctx.sqlite; + + await db.insert(conflictChainExampleTable).values([{ id: 1, name: 'John', email: 'john@example.com' }, { + id: 2, + name: 'John Second', + email: '2john@example.com', + }]).run(); + + await db + .insert(conflictChainExampleTable) + .values([{ id: 1, name: 'John', email: 'john@example.com' }, { + id: 2, + name: 'Anthony', + email: 'idthief@example.com', + }]) + .onConflictDoUpdate({ + target: [conflictChainExampleTable.id, conflictChainExampleTable.name], + set: { email: 'john1@example.com' }, + }) + .onConflictDoNothing({ target: conflictChainExampleTable.id }) + .run(); + + const res = await db + .select({ + id: conflictChainExampleTable.id, + name: conflictChainExampleTable.name, + email: conflictChainExampleTable.email, + }) + .from(conflictChainExampleTable) + .orderBy(conflictChainExampleTable.id) + .all(); + + expect(res).toEqual([{ id: 1, name: 'John', email: 'john1@example.com' }, { + id: 2, + name: 'John Second', + email: '2john@example.com', + }]); + }); + + test('insert with onConflict chained (.nothing -> .update)', async (ctx) => { + const { db } = ctx.sqlite; + + await db.insert(conflictChainExampleTable).values([{ id: 1, name: 'John', email: 'john@example.com' }, { + id: 2, + name: 'John Second', + email: '2john@example.com', + }]).run(); + + await db + .insert(conflictChainExampleTable) + .values([{ id: 1, name: 'John', email: 'john@example.com' }, { + id: 2, + name: 'Anthony', + email: 'idthief@example.com', + }]) + .onConflictDoUpdate({ + target: [conflictChainExampleTable.id, conflictChainExampleTable.name], + set: { email: 'john1@example.com' }, + }) + .onConflictDoNothing({ target: conflictChainExampleTable.id }) + .run(); + + const res = await db + .select({ + id: conflictChainExampleTable.id, + name: conflictChainExampleTable.name, + email: conflictChainExampleTable.email, + }) + .from(conflictChainExampleTable) + .orderBy(conflictChainExampleTable.id) + .all(); + + expect(res).toEqual([{ id: 1, name: 'John', email: 'john1@example.com' }, { + id: 2, + name: 'John Second', + email: '2john@example.com', + }]); + }); + + test('insert with onConflict chained (.update -> .update)', async (ctx) => { + const { db } = ctx.sqlite; + + await db.insert(conflictChainExampleTable).values([{ id: 1, name: 'John', email: 'john@example.com' }, { + id: 2, + name: 'John Second', + email: '2john@example.com', + }]).run(); + + await db + .insert(conflictChainExampleTable) + .values([{ id: 1, name: 'John', email: 'john@example.com' }, { + id: 2, + name: 'Anthony', + email: 'idthief@example.com', + }]) + .onConflictDoUpdate({ + target: [conflictChainExampleTable.id, conflictChainExampleTable.name], + set: { email: 'john1@example.com' }, + }) + .onConflictDoUpdate({ target: conflictChainExampleTable.id, set: { email: 'john2@example.com' } }) + .run(); + + const res = await db + .select({ + id: conflictChainExampleTable.id, + name: conflictChainExampleTable.name, + email: conflictChainExampleTable.email, + }) + .from(conflictChainExampleTable) + .orderBy(conflictChainExampleTable.id) + .all(); + + expect(res).toEqual([{ id: 1, name: 'John', email: 'john1@example.com' }, { + id: 2, + name: 'John Second', + email: 'john2@example.com', + }]); + }); + + test('insert with onConflict chained (.nothing -> .nothing)', async (ctx) => { + const { db } = ctx.sqlite; + + await db.insert(conflictChainExampleTable).values([{ id: 1, name: 'John', email: 'john@example.com' }, { + id: 2, + name: 'John Second', + email: '2john@example.com', + }]).run(); + + await db + .insert(conflictChainExampleTable) + .values([{ id: 1, name: 'John', email: 'john@example.com' }, { + id: 2, + name: 'Anthony', + email: 'idthief@example.com', + }]) + .onConflictDoNothing({ + target: [conflictChainExampleTable.id, conflictChainExampleTable.name], + }) + .onConflictDoNothing({ target: conflictChainExampleTable.id }) + .run(); + + const res = await db + .select({ + id: conflictChainExampleTable.id, + name: conflictChainExampleTable.name, + email: conflictChainExampleTable.email, + }) + .from(conflictChainExampleTable) + .orderBy(conflictChainExampleTable.id) + .all(); + + expect(res).toEqual([{ id: 1, name: 'John', email: 'john@example.com' }, { + id: 2, + name: 'John Second', + email: '2john@example.com', + }]); + }); + test('insert undefined', async (ctx) => { const { db } = ctx.sqlite; From 2c677837c4c5efa556100fee4c0f8b422f5f74fb Mon Sep 17 00:00:00 2001 From: Sukairo-02 Date: Tue, 28 Jan 2025 15:35:02 +0200 Subject: [PATCH 2/4] Reverted flag change --- integration-tests/tests/sqlite/better-sqlite.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/tests/sqlite/better-sqlite.test.ts b/integration-tests/tests/sqlite/better-sqlite.test.ts index ed9a2f861..53feee15f 100644 --- a/integration-tests/tests/sqlite/better-sqlite.test.ts +++ b/integration-tests/tests/sqlite/better-sqlite.test.ts @@ -6,7 +6,7 @@ import { afterAll, beforeAll, beforeEach, expect, test } from 'vitest'; import { skipTests } from '~/common'; import { anotherUsersMigratorTable, tests, usersMigratorTable } from './sqlite-common'; -const ENABLE_LOGGING = true; +const ENABLE_LOGGING = false; let db: BetterSQLite3Database; let client: Database.Database; From 6b6aca742968291d50ac915a903656ff577917e6 Mon Sep 17 00:00:00 2001 From: Sukairo-02 Date: Tue, 28 Jan 2025 20:19:47 +0200 Subject: [PATCH 3/4] Fixed types of joined views, fixed `aliasedTable()` not aliasing tables on type level, added `View` support to `aliasedTable()`, fixed sql builder prefixing aliased views and tables with their schema names --- drizzle-orm/src/alias.ts | 16 +- .../mysql-core/query-builders/select.types.ts | 2 +- .../pg-core/query-builders/select.types.ts | 2 +- drizzle-orm/src/sql/sql.ts | 4 +- .../type-tests/common/aliased-table.ts | 229 ++++++++++++++++++ 5 files changed, 247 insertions(+), 6 deletions(-) create mode 100644 drizzle-orm/type-tests/common/aliased-table.ts diff --git a/drizzle-orm/src/alias.ts b/drizzle-orm/src/alias.ts index 0711dc53d..eb2270f8e 100644 --- a/drizzle-orm/src/alias.ts +++ b/drizzle-orm/src/alias.ts @@ -1,9 +1,14 @@ import type { AnyColumn } from './column.ts'; import { Column } from './column.ts'; import { entityKind, is } from './entity.ts'; +import type { AnyMySqlTable, BuildAliasTable as BuildAliasMySqlTable, MySqlView } from './mysql-core/index.ts'; +import type { AnyPgTable, BuildAliasTable as BuildAliasPgTable, PgView } from './pg-core/index.ts'; import type { Relation } from './relations.ts'; import type { View } from './sql/sql.ts'; import { SQL, sql } from './sql/sql.ts'; +import type { BuildAliasTable as BuildAliasSQLiteTable } from './sqlite-core/index.ts'; +import type { AnySQLiteTable } from './sqlite-core/table.ts'; +import type { SQLiteView } from './sqlite-core/view.ts'; import { Table } from './table.ts'; import { ViewBaseConfig } from './view-common.ts'; @@ -88,8 +93,15 @@ export class RelationTableAliasProxyHandler implements Proxy } } -export function aliasedTable(table: T, tableAlias: string): T { - return new Proxy(table, new TableAliasProxyHandler(tableAlias, false)); +export function aliasedTable( + table: T, + tableAlias: TAlias, +): T extends AnyPgTable | PgView ? BuildAliasPgTable + : T extends AnySQLiteTable | SQLiteView ? BuildAliasSQLiteTable + : T extends AnyMySqlTable | MySqlView ? BuildAliasMySqlTable + : never +{ + return new Proxy(table, new TableAliasProxyHandler(tableAlias, false)) as any; } export function aliasedRelation(relation: T, tableAlias: string): T { diff --git a/drizzle-orm/src/mysql-core/query-builders/select.types.ts b/drizzle-orm/src/mysql-core/query-builders/select.types.ts index 78b6f91a6..4b0f97d3a 100644 --- a/drizzle-orm/src/mysql-core/query-builders/select.types.ts +++ b/drizzle-orm/src/mysql-core/query-builders/select.types.ts @@ -97,7 +97,7 @@ export type MySqlJoin< T['_']['selection'], TJoinedName, TJoinedTable extends MySqlTable ? TJoinedTable['_']['columns'] - : TJoinedTable extends Subquery ? Assume + : TJoinedTable extends Subquery | View ? Assume : never, T['_']['selectMode'] >, diff --git a/drizzle-orm/src/pg-core/query-builders/select.types.ts b/drizzle-orm/src/pg-core/query-builders/select.types.ts index 87f21e526..b887c1ebd 100644 --- a/drizzle-orm/src/pg-core/query-builders/select.types.ts +++ b/drizzle-orm/src/pg-core/query-builders/select.types.ts @@ -98,7 +98,7 @@ export type PgSelectJoin< T['_']['selection'], TJoinedName, TJoinedTable extends Table ? TJoinedTable['_']['columns'] - : TJoinedTable extends Subquery ? Assume + : TJoinedTable extends Subquery | View ? Assume : never, T['_']['selectMode'] >, diff --git a/drizzle-orm/src/sql/sql.ts b/drizzle-orm/src/sql/sql.ts index 50d4c1557..ec4feb20c 100644 --- a/drizzle-orm/src/sql/sql.ts +++ b/drizzle-orm/src/sql/sql.ts @@ -181,7 +181,7 @@ export class SQL implements SQLWrapper { const schemaName = chunk[Table.Symbol.Schema]; const tableName = chunk[Table.Symbol.Name]; return { - sql: schemaName === undefined + sql: schemaName === undefined || chunk[IsAlias] ? escapeName(tableName) : escapeName(schemaName) + '.' + escapeName(tableName), params: [], @@ -208,7 +208,7 @@ export class SQL implements SQLWrapper { const schemaName = chunk[ViewBaseConfig].schema; const viewName = chunk[ViewBaseConfig].name; return { - sql: schemaName === undefined + sql: schemaName === undefined || chunk[ViewBaseConfig].isAlias ? escapeName(viewName) : escapeName(schemaName) + '.' + escapeName(viewName), params: [], diff --git a/drizzle-orm/type-tests/common/aliased-table.ts b/drizzle-orm/type-tests/common/aliased-table.ts new file mode 100644 index 000000000..59fc7516f --- /dev/null +++ b/drizzle-orm/type-tests/common/aliased-table.ts @@ -0,0 +1,229 @@ +import { type Equal, Expect } from 'type-tests/utils.ts'; +import { aliasedTable, eq } from '~/index.ts'; +import { drizzle as sqlited } from '~/libsql/index.ts'; +import { mysqlView } from '~/mysql-core/view.ts'; +import { drizzle as mysqld } from '~/mysql2/index.ts'; +import { pgView } from '~/pg-core/view.ts'; +import { drizzle as pgd } from '~/postgres-js/index.ts'; +import { sqliteView } from '~/sqlite-core/view.ts'; +import { users as mysqlUsers } from '../mysql/tables.ts'; +import { users as pgUsers } from '../pg/tables.ts'; +import { users as sqliteUsers } from '../sqlite/tables.ts'; + +const pg = pgd.mock(); +const sqlite = sqlited.mock(); +const mysql = mysqld.mock(); + +const pgvUsers = pgView('users_view').as((qb) => qb.select().from(pgUsers)); +const sqlitevUsers = sqliteView('users_view').as((qb) => qb.select().from(sqliteUsers)); +const mysqlvUsers = mysqlView('users_view').as((qb) => qb.select().from(mysqlUsers)); + +const pgAlias = aliasedTable(pgUsers, 'usersAlias'); +const sqliteAlias = aliasedTable(sqliteUsers, 'usersAlias'); +const mysqlAlias = aliasedTable(mysqlUsers, 'usersAlias'); + +const pgvAlias = aliasedTable(pgvUsers, 'usersvAlias'); +const sqlitevAlias = aliasedTable(sqlitevUsers, 'usersvAlias'); +const mysqlvAlias = aliasedTable(mysqlvUsers, 'usersvAlias'); + +const pgRes = await pg.select().from(pgUsers).leftJoin(pgAlias, eq(pgAlias.id, pgUsers.id)); +const sqliteRes = await sqlite.select().from(sqliteUsers).leftJoin(sqliteAlias, eq(sqliteAlias.id, sqliteUsers.id)); +const mysqlRes = await mysql.select().from(mysqlUsers).leftJoin(mysqlAlias, eq(mysqlAlias.id, mysqlUsers.id)); + +const pgvRes = await pg.select().from(pgUsers).leftJoin(pgvAlias, eq(pgvAlias.id, pgUsers.id)); +const sqlitevRes = await sqlite.select().from(sqliteUsers).leftJoin(sqlitevAlias, eq(sqlitevAlias.id, sqliteUsers.id)); +const mysqlvRes = await mysql.select().from(mysqlUsers).leftJoin(mysqlvAlias, eq(mysqlvAlias.id, mysqlUsers.id)); + +Expect< + Equal +>; + +Expect< + Equal +>; + +Expect< + Equal +>; + +Expect< + Equal +>; + +Expect< + Equal +>; + +Expect< + Equal +>; From a42bb0391586875cb7e62d8e49bed70164a262d0 Mon Sep 17 00:00:00 2001 From: Sukairo-02 Date: Wed, 29 Jan 2025 11:42:22 +0200 Subject: [PATCH 4/4] Reverted `aliasedTable` type improvements in favor of dialect-specific `alias` functions --- drizzle-orm/src/alias.ts | 15 +++------------ drizzle-orm/type-tests/common/aliased-table.ts | 17 ++++++++++------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/drizzle-orm/src/alias.ts b/drizzle-orm/src/alias.ts index eb2270f8e..21e802a1c 100644 --- a/drizzle-orm/src/alias.ts +++ b/drizzle-orm/src/alias.ts @@ -1,14 +1,9 @@ import type { AnyColumn } from './column.ts'; import { Column } from './column.ts'; import { entityKind, is } from './entity.ts'; -import type { AnyMySqlTable, BuildAliasTable as BuildAliasMySqlTable, MySqlView } from './mysql-core/index.ts'; -import type { AnyPgTable, BuildAliasTable as BuildAliasPgTable, PgView } from './pg-core/index.ts'; import type { Relation } from './relations.ts'; import type { View } from './sql/sql.ts'; import { SQL, sql } from './sql/sql.ts'; -import type { BuildAliasTable as BuildAliasSQLiteTable } from './sqlite-core/index.ts'; -import type { AnySQLiteTable } from './sqlite-core/table.ts'; -import type { SQLiteView } from './sqlite-core/view.ts'; import { Table } from './table.ts'; import { ViewBaseConfig } from './view-common.ts'; @@ -93,14 +88,10 @@ export class RelationTableAliasProxyHandler implements Proxy } } -export function aliasedTable( +export function aliasedTable( table: T, - tableAlias: TAlias, -): T extends AnyPgTable | PgView ? BuildAliasPgTable - : T extends AnySQLiteTable | SQLiteView ? BuildAliasSQLiteTable - : T extends AnyMySqlTable | MySqlView ? BuildAliasMySqlTable - : never -{ + tableAlias: string, +): T { return new Proxy(table, new TableAliasProxyHandler(tableAlias, false)) as any; } diff --git a/drizzle-orm/type-tests/common/aliased-table.ts b/drizzle-orm/type-tests/common/aliased-table.ts index 59fc7516f..9c2be8c5f 100644 --- a/drizzle-orm/type-tests/common/aliased-table.ts +++ b/drizzle-orm/type-tests/common/aliased-table.ts @@ -1,10 +1,13 @@ import { type Equal, Expect } from 'type-tests/utils.ts'; -import { aliasedTable, eq } from '~/index.ts'; +import { eq } from '~/index.ts'; import { drizzle as sqlited } from '~/libsql/index.ts'; +import { alias as mysqlAliasFn } from '~/mysql-core/alias.ts'; import { mysqlView } from '~/mysql-core/view.ts'; import { drizzle as mysqld } from '~/mysql2/index.ts'; +import { alias as pgAliasFn } from '~/pg-core/alias.ts'; import { pgView } from '~/pg-core/view.ts'; import { drizzle as pgd } from '~/postgres-js/index.ts'; +import { alias as sqliteAliasFn } from '~/sqlite-core/alias.ts'; import { sqliteView } from '~/sqlite-core/view.ts'; import { users as mysqlUsers } from '../mysql/tables.ts'; import { users as pgUsers } from '../pg/tables.ts'; @@ -18,13 +21,13 @@ const pgvUsers = pgView('users_view').as((qb) => qb.select().from(pgUsers)); const sqlitevUsers = sqliteView('users_view').as((qb) => qb.select().from(sqliteUsers)); const mysqlvUsers = mysqlView('users_view').as((qb) => qb.select().from(mysqlUsers)); -const pgAlias = aliasedTable(pgUsers, 'usersAlias'); -const sqliteAlias = aliasedTable(sqliteUsers, 'usersAlias'); -const mysqlAlias = aliasedTable(mysqlUsers, 'usersAlias'); +const pgAlias = pgAliasFn(pgUsers, 'usersAlias'); +const sqliteAlias = sqliteAliasFn(sqliteUsers, 'usersAlias'); +const mysqlAlias = mysqlAliasFn(mysqlUsers, 'usersAlias'); -const pgvAlias = aliasedTable(pgvUsers, 'usersvAlias'); -const sqlitevAlias = aliasedTable(sqlitevUsers, 'usersvAlias'); -const mysqlvAlias = aliasedTable(mysqlvUsers, 'usersvAlias'); +const pgvAlias = pgAliasFn(pgvUsers, 'usersvAlias'); +const sqlitevAlias = sqliteAliasFn(sqlitevUsers, 'usersvAlias'); +const mysqlvAlias = mysqlAliasFn(mysqlvUsers, 'usersvAlias'); const pgRes = await pg.select().from(pgUsers).leftJoin(pgAlias, eq(pgAlias.id, pgUsers.id)); const sqliteRes = await sqlite.select().from(sqliteUsers).leftJoin(sqliteAlias, eq(sqliteAlias.id, sqliteUsers.id));