Skip to content

Commit

Permalink
Switched MySQL RQBv2 builders to lateral left joins, fixed nested agg…
Browse files Browse the repository at this point in the history
…regated relations
  • Loading branch information
Sukairo-02 committed Jan 8, 2025
1 parent b4f992e commit 348fb92
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 14 deletions.
17 changes: 10 additions & 7 deletions drizzle-orm/src/mysql-core/dialect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,8 @@ export class MySqlDialect {

return sql.join(
withEntries.map(([k, join]) => {
selectionArr.push(sql`${sql.identifier(k)}.${sql.identifier('r')} as ${sql.identifier(k)}`);

if (is(tableConfig.relations[k]!, AggregatedField)) {
const relation = tableConfig.relations[k]!;
relation.onTable(table);
Expand All @@ -1309,12 +1311,9 @@ export class MySqlDialect {
field: relation,
});

selectionArr.push(sql`(${query}) as ${sql.identifier(k)}`);
return;
return sql` left join lateral (${query}) as ${sql.identifier(k)} on true`;
}

selectionArr.push(sql`${sql.identifier(k)}.${sql.identifier('r')} as ${sql.identifier(k)}`);

const relation = tableConfig.relations[k]! as Relation;
const isSingle = is(relation, One);
const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
Expand Down Expand Up @@ -1348,9 +1347,13 @@ export class MySqlDialect {
sql`, `,
);

return sql`, lateral(select ${sql`coalesce(json_arrayagg(json_object(${jsonColumns})), json_array()) as ${
sql.identifier('r')
}`} from (${innerQuery.sql}) as ${sql.identifier('t')}) as ${sql.identifier(k)}`;
return sql` left join lateral(select ${sql`${
isSingle
? sql`json_object(${jsonColumns})`
: sql`coalesce(json_arrayagg(json_object(${jsonColumns})), json_array())`
} as ${sql.identifier('r')}`} from (${innerQuery.sql}) as ${sql.identifier('t')}) as ${
sql.identifier(k)
} on true`;
}),
);
})()
Expand Down
25 changes: 18 additions & 7 deletions drizzle-orm/src/relations.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { type AnyTable, getTableUniqueName, type InferModelFromColumns, IsAlias, Schema, Table } from '~/table.ts';
import {
type AnyTable,
getTableUniqueName,
type InferModelFromColumns,
IsAlias,
OriginalName,
Schema,
Table,
} from '~/table.ts';
import { Columns, getTableName } from '~/table.ts';
import { type AnyColumn, Column } from './column.ts';
import { entityKind, is } from './entity.ts';
Expand Down Expand Up @@ -307,7 +315,15 @@ export class Count extends AggregatedField<number> {
if (!this.query) {
if (!this.table) throw new Error('Table must be set before building aggregate field');

this.query = sql`select count(*) as ${sql.identifier('r')} from ${this.table}`.mapWith(Number);
const table = this.table;

this.query = sql`select count(*) as ${sql.identifier('r')} from ${
table[IsAlias]
? sql`${sql`${sql.identifier(table[Schema] ?? '')}.`.if(table[Schema])}${
sql.identifier(table[OriginalName])
} as ${table}`
: table
}`.mapWith(Number);
}

return this.query;
Expand Down Expand Up @@ -606,11 +622,6 @@ export function mapRelationalRow(
const field = selectionItem.field!;

if (is(field, Table)) {
// MySQL's lateral joins act only as inner joins, thus must have null responses on single relations be casted as arrays to preserve rows
if (!selectionItem.isArray && Array.isArray(row[selectionItem.key])) {
row[selectionItem.key] = (row[selectionItem.key] as Array<any>)[0] ?? null;
}

const currentPath = `${path ? `${path}.` : ''}${selectionItem.key}`;

if (row[selectionItem.key] === null) {
Expand Down

0 comments on commit 348fb92

Please sign in to comment.