Skip to content

Commit

Permalink
Fixed self-referencing relations, switched dbConfig callbacks table t…
Browse files Browse the repository at this point in the history
…ypes to tables instead of column records, relational tests v2 for postgresql, updated relations .where field names, added error on nothing selected from table in relational queries v2
  • Loading branch information
Sukairo-02 committed Dec 27, 2024
1 parent 661b6f2 commit 66f461a
Show file tree
Hide file tree
Showing 15 changed files with 20,680 additions and 1,030 deletions.
49 changes: 32 additions & 17 deletions drizzle-orm/src/mysql-core/dialect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ import {
AggregatedField,
One,
relationExtrasToSQL,
relationFilterToSQL,
relationsFilterToSQL,
relationsOrderToSQL,
relationToSQL,
} from '~/relations.ts';
import { Param, SQL, sql, View } from '~/sql/sql.ts';
import type { Name, Placeholder, QueryWithTypings, SQLChunk } from '~/sql/sql.ts';
import { Subquery } from '~/subquery.ts';
import { Columns, getTableName, getTableUniqueName, Table } from '~/table.ts';
import { Columns, getTableName, getTableUniqueName, IsAlias, OriginalName, Schema, Table } from '~/table.ts';
import { type Casing, orderSelectedFields, type UpdateSet } from '~/utils.ts';
import { ViewBaseConfig } from '~/view-common.ts';
import { MySqlColumn } from './columns/common.ts';
Expand Down Expand Up @@ -1207,13 +1207,9 @@ export class MySqlDialect {

return columnIdentifiers.length
? sql.join(columnIdentifiers, sql`, `)
: this.unwrapAllColumns(table, selection);
: undefined;
})()
: (() => {
const columnIdentifiers = [this.unwrapAllColumns(table, selection)];

return sql.join(columnIdentifiers, sql`, `);
})();
: this.unwrapAllColumns(table, selection);

buildRelationalQuery(
{
Expand All @@ -1225,6 +1221,8 @@ export class MySqlDialect {
queryConfig: config,
relationWhere,
mode,
errorPath,
depth,
}: {
tables: Record<string, MySqlTable>;
schema: TablesRelationalConfig;
Expand All @@ -1234,27 +1232,31 @@ export class MySqlDialect {
queryConfig?: DBQueryConfig<'many'> | true;
relationWhere?: SQL;
mode: 'first' | 'many';
errorPath?: string;
depth?: number;
},
): BuildRelationalQueryResult {
const selection: BuildRelationalQueryResult['selection'] = [];
const isSingle = mode === 'first';
const params = config === true ? undefined : config;
const currentPath = errorPath ?? '';
const currentDepth = depth ?? 0;

const limit = isSingle ? 1 : params?.limit;
const offset = params?.offset;

const columns = this.buildColumns(table, selection, params);

const where: SQL | undefined = (params?.where && relationWhere)
? and(relationFilterToSQL(table, params.where), relationWhere)
? and(relationsFilterToSQL(table, params.where), relationWhere)
: params?.where
? relationFilterToSQL(table, params.where)
? relationsFilterToSQL(table, params.where)
: relationWhere;
const order = params?.orderBy ? relationsOrderToSQL(table, params.orderBy as OrderBy) : undefined;
const extras = params?.extras ? relationExtrasToSQL(table, params.extras as Extras) : undefined;
if (extras) selection.push(...extras.selection);

const selectionArr: SQL[] = [columns];
const selectionArr: SQL[] = columns ? [columns] : [];

const joins = params
? (() => {
Expand Down Expand Up @@ -1283,18 +1285,20 @@ export class MySqlDialect {

const relation = tableConfig.relations[k]! as Relation;
const isSingle = is(relation, One);
const targetTable = relation.targetTable;
const relationFilter = relationToSQL(relation);
const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
const relationFilter = relationToSQL(relation, table, targetTable);

const innerQuery = this.buildRelationalQuery({
table: targetTable as MySqlTable,
mode: isSingle ? 'first' : 'many',
schema,
queryConfig: join as DBQueryConfig,
tableConfig: schema[tableNamesMap[getTableUniqueName(targetTable)]!]!,
tableConfig: schema[tableNamesMap[getTableUniqueName(relation.targetTable)]!]!,
tableNamesMap,
tables,
relationWhere: relationFilter,
errorPath: `${currentPath.length ? `${currentPath}.` : ''}${k}`,
depth: currentDepth + 1,
});

selection.push({
Expand All @@ -1320,11 +1324,22 @@ export class MySqlDialect {
: undefined;

if (extras?.sql) selectionArr.push(extras.sql);
if (!selectionArr.length) {
throw new DrizzleError({
message: `No fields selected for table "${tableConfig.tsName}"${currentPath ? ` ("${currentPath}")` : ''}`,
});
}
const selectionSet = sql.join(selectionArr, sql`, `);

const query = sql`select ${selectionSet} from ${table}${sql`${joins}`.if(joins)}${sql` where ${where}`.if(where)}${
sql` order by ${order}`.if(order)
}${sql` limit ${limit}`.if(limit !== undefined)}${sql` offset ${offset}`.if(offset !== undefined)}`;
const query = sql`select ${selectionSet} from ${
table[IsAlias]
? sql`${sql`${sql.identifier(table[Schema] ?? '')}.`.if(table[Schema])}${
sql.identifier(table[OriginalName])
} as ${table}`
: table
}${sql`${joins}`.if(joins)}${sql` where ${where}`.if(where)}${sql` order by ${order}`.if(order)}${
sql` limit ${limit}`.if(limit !== undefined)
}${sql` offset ${offset}`.if(offset !== undefined)}`;

return {
sql: query,
Expand Down
49 changes: 32 additions & 17 deletions drizzle-orm/src/pg-core/dialect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {
type OrderBy,
type Relation,
relationExtrasToSQL,
relationFilterToSQL,
relationsFilterToSQL,
relationsOrderToSQL,
relationToSQL,
type TableRelationalConfig,
Expand All @@ -54,7 +54,7 @@ import {
type SQLChunk,
} from '~/sql/sql.ts';
import { Subquery } from '~/subquery.ts';
import { Columns, getTableName, getTableUniqueName, Table } from '~/table.ts';
import { Columns, getTableName, getTableUniqueName, IsAlias, OriginalName, Schema, Table } from '~/table.ts';
import { type Casing, orderSelectedFields, type UpdateSet } from '~/utils.ts';
import { ViewBaseConfig } from '~/view-common.ts';
import type { PgSession } from './session.ts';
Expand Down Expand Up @@ -958,13 +958,9 @@ export class PgDialect {

return columnIdentifiers.length
? sql.join(columnIdentifiers, sql`, `)
: this.unwrapAllColumns(table, selection);
: undefined;
})()
: (() => {
const columnIdentifiers = [this.unwrapAllColumns(table, selection)];

return sql.join(columnIdentifiers, sql`, `);
})();
: this.unwrapAllColumns(table, selection);

buildRelationalQuery({
tables,
Expand All @@ -975,6 +971,8 @@ export class PgDialect {
queryConfig: config,
relationWhere,
mode,
errorPath,
depth,
}: {
tables: Record<string, PgTable>;
schema: TablesRelationalConfig;
Expand All @@ -984,26 +982,30 @@ export class PgDialect {
queryConfig?: DBQueryConfig<'many'> | true;
relationWhere?: SQL;
mode: 'first' | 'many';
errorPath?: string;
depth?: number;
}): BuildRelationalQueryResult {
const selection: BuildRelationalQueryResult['selection'] = [];
const isSingle = mode === 'first';
const params = config === true ? undefined : config;
const currentPath = errorPath ?? '';
const currentDepth = depth ?? 0;

const limit = isSingle ? 1 : params?.limit;
const offset = params?.offset;

const where: SQL | undefined = (params?.where && relationWhere)
? and(relationFilterToSQL(table, params.where), relationWhere)
? and(relationsFilterToSQL(table, params.where), relationWhere)
: params?.where
? relationFilterToSQL(table, params.where)
? relationsFilterToSQL(table, params.where)
: relationWhere;

const order = params?.orderBy ? relationsOrderToSQL(table, params.orderBy as OrderBy) : undefined;
const columns = this.buildColumns(table, tableConfig, selection, params);
const extras = params?.extras ? relationExtrasToSQL(table, params.extras as Extras) : undefined;
if (extras) selection.push(...extras.selection);

const selectionArr: SQL[] = [columns];
const selectionArr: SQL[] = columns ? [columns] : [];

const joins = params
? (() => {
Expand Down Expand Up @@ -1033,8 +1035,8 @@ export class PgDialect {

const relation = tableConfig.relations[k]! as Relation;
const isSingle = is(relation, One);
const targetTable = relation.targetTable;
const relationFilter = relationToSQL(relation);
const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
const relationFilter = relationToSQL(relation, table, targetTable);

selectionArr.push(
isSingle
Expand All @@ -1047,10 +1049,12 @@ export class PgDialect {
mode: isSingle ? 'first' : 'many',
schema,
queryConfig: join as DBQueryConfig,
tableConfig: schema[tableNamesMap[getTableUniqueName(targetTable)]!]!,
tableConfig: schema[tableNamesMap[getTableUniqueName(relation.targetTable)]!]!,
tableNamesMap,
tables,
relationWhere: relationFilter,
errorPath: `${currentPath.length ? `${currentPath}.` : ''}${k}`,
depth: currentDepth + 1,
});

selection.push({
Expand All @@ -1072,11 +1076,22 @@ export class PgDialect {
: undefined;

if (extras?.sql) selectionArr.push(extras.sql);
if (!selectionArr.length) {
throw new DrizzleError({
message: `No fields selected for table "${tableConfig.tsName}"${currentPath ? ` ("${currentPath}")` : ''}`,
});
}
const selectionSet = sql.join(selectionArr.filter((e) => e !== undefined), sql`, `);

const query = sql`select ${selectionSet} from ${table}${sql` ${joins}`.if(joins)}${sql` where ${where}`.if(where)}${
sql` order by ${order}`.if(order)
}${sql` limit ${limit}`.if(limit !== undefined)}${sql` offset ${offset}`.if(offset !== undefined)}`;
const query = sql`select ${selectionSet} from ${
table[IsAlias]
? sql`${sql`${sql.identifier(table[Schema] ?? '')}.`.if(table[Schema])}${
sql.identifier(table[OriginalName])
} as ${table}`
: table
}${sql` ${joins}`.if(joins)}${sql` where ${where}`.if(where)}${sql` order by ${order}`.if(order)}${
sql` limit ${limit}`.if(limit !== undefined)
}${sql` offset ${offset}`.if(offset !== undefined)}`;

return {
sql: query,
Expand Down
Loading

0 comments on commit 66f461a

Please sign in to comment.