Skip to content

Commit 4c396c7

Browse files
authored
fix(db-postgres): alias already in use in this query (#8823)
Fixes #8517 Reuses existing joins instead of adding new, duplicate ones which causes: ``` Error: Alias "" is already used in this query. ```
1 parent 6912550 commit 4c396c7

File tree

7 files changed

+101
-22
lines changed

7 files changed

+101
-22
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import type { SQL } from 'drizzle-orm'
2+
import type { PgTableWithColumns } from 'drizzle-orm/pg-core'
3+
4+
import type { GenericTable } from '../types.js'
5+
import type { BuildQueryJoinAliases } from './buildQuery.js'
6+
7+
import { getNameFromDrizzleTable } from '../utilities/getNameFromDrizzleTable.js'
8+
9+
export const addJoinTable = ({
10+
type,
11+
condition,
12+
joins,
13+
table,
14+
}: {
15+
condition: SQL
16+
joins: BuildQueryJoinAliases
17+
table: GenericTable | PgTableWithColumns<any>
18+
type?: 'innerJoin' | 'leftJoin' | 'rightJoin'
19+
}) => {
20+
const name = getNameFromDrizzleTable(table)
21+
22+
if (!joins.some((eachJoin) => getNameFromDrizzleTable(eachJoin.table) === name)) {
23+
joins.push({ type, condition, table })
24+
}
25+
}

packages/drizzle/src/queries/buildOrderBy.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ export const buildOrderBy = ({
5555
pathSegments: sortPath.replace(/__/g, '.').split('.'),
5656
selectFields,
5757
tableName,
58-
useAlias: true,
5958
value: sortPath,
6059
})
6160
orderBy.column = sortTable?.[sortTableColumnName]

packages/drizzle/src/queries/getTableColumnFromPath.ts

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type { DrizzleAdapter, GenericColumn } from '../types.js'
1313
import type { BuildQueryJoinAliases } from './buildQuery.js'
1414

1515
import { isPolymorphicRelationship } from '../utilities/isPolymorphicRelationship.js'
16+
import { addJoinTable } from './addJoinTable.js'
1617
import { getTableAlias } from './getTableAlias.js'
1718

1819
type Constraint = {
@@ -53,7 +54,6 @@ type Args = {
5354
* If creating a new table name for arrays and blocks, this suffix should be appended to the table name
5455
*/
5556
tableNameSuffix?: string
56-
useAlias?: boolean
5757
/**
5858
* The raw value of the query before sanitization
5959
*/
@@ -79,7 +79,6 @@ export const getTableColumnFromPath = ({
7979
selectFields,
8080
tableName,
8181
tableNameSuffix = '',
82-
useAlias,
8382
value,
8483
}: Args): TableColumn => {
8584
const fieldPath = incomingSegments[0]
@@ -141,7 +140,6 @@ export const getTableColumnFromPath = ({
141140
selectFields,
142141
tableName: newTableName,
143142
tableNameSuffix,
144-
useAlias,
145143
value,
146144
})
147145
}
@@ -162,7 +160,6 @@ export const getTableColumnFromPath = ({
162160
selectFields,
163161
tableName: newTableName,
164162
tableNameSuffix: `${tableNameSuffix}${toSnakeCase(field.name)}_`,
165-
useAlias,
166163
value,
167164
})
168165
}
@@ -181,7 +178,6 @@ export const getTableColumnFromPath = ({
181178
selectFields,
182179
tableName: newTableName,
183180
tableNameSuffix,
184-
useAlias,
185181
value,
186182
})
187183
}
@@ -190,8 +186,9 @@ export const getTableColumnFromPath = ({
190186
if (locale && field.localized && adapter.payload.config.localization) {
191187
newTableName = `${tableName}${adapter.localesSuffix}`
192188

193-
joins.push({
189+
addJoinTable({
194190
condition: eq(adapter.tables[tableName].id, adapter.tables[newTableName]._parentID),
191+
joins,
195192
table: adapter.tables[newTableName],
196193
})
197194
if (locale !== 'all') {
@@ -217,7 +214,6 @@ export const getTableColumnFromPath = ({
217214
selectFields,
218215
tableName: newTableName,
219216
tableNameSuffix: `${tableNameSuffix}${toSnakeCase(field.name)}_`,
220-
useAlias,
221217
value,
222218
})
223219
}
@@ -229,11 +225,12 @@ export const getTableColumnFromPath = ({
229225
)
230226

231227
if (locale && field.localized && adapter.payload.config.localization) {
232-
joins.push({
228+
addJoinTable({
233229
condition: and(
234230
eq(adapter.tables[tableName].id, adapter.tables[newTableName].parent),
235231
eq(adapter.tables[newTableName]._locale, locale),
236232
),
233+
joins,
237234
table: adapter.tables[newTableName],
238235
})
239236
if (locale !== 'all') {
@@ -244,8 +241,9 @@ export const getTableColumnFromPath = ({
244241
})
245242
}
246243
} else {
247-
joins.push({
244+
addJoinTable({
248245
condition: eq(adapter.tables[tableName].id, adapter.tables[newTableName].parent),
246+
joins,
249247
table: adapter.tables[newTableName],
250248
})
251249
}
@@ -276,8 +274,9 @@ export const getTableColumnFromPath = ({
276274
]
277275

278276
if (locale && field.localized && adapter.payload.config.localization) {
279-
joins.push({
277+
addJoinTable({
280278
condition: and(...joinConstraints, eq(adapter.tables[newTableName]._locale, locale)),
279+
joins,
281280
table: adapter.tables[newTableName],
282281
})
283282
if (locale !== 'all') {
@@ -288,8 +287,9 @@ export const getTableColumnFromPath = ({
288287
})
289288
}
290289
} else {
291-
joins.push({
290+
addJoinTable({
292291
condition: and(...joinConstraints),
292+
joins,
293293
table: adapter.tables[newTableName],
294294
})
295295
}
@@ -313,11 +313,12 @@ export const getTableColumnFromPath = ({
313313

314314
constraintPath = `${constraintPath}${field.name}.%.`
315315
if (locale && field.localized && adapter.payload.config.localization) {
316-
joins.push({
316+
addJoinTable({
317317
condition: and(
318318
eq(arrayParentTable.id, adapter.tables[newTableName]._parentID),
319319
eq(adapter.tables[newTableName]._locale, locale),
320320
),
321+
joins,
321322
table: adapter.tables[newTableName],
322323
})
323324
if (locale !== 'all') {
@@ -328,8 +329,9 @@ export const getTableColumnFromPath = ({
328329
})
329330
}
330331
} else {
331-
joins.push({
332+
addJoinTable({
332333
condition: eq(arrayParentTable.id, adapter.tables[newTableName]._parentID),
334+
joins,
333335
table: adapter.tables[newTableName],
334336
})
335337
}
@@ -345,7 +347,6 @@ export const getTableColumnFromPath = ({
345347
rootTableName,
346348
selectFields,
347349
tableName: newTableName,
348-
useAlias,
349350
value,
350351
})
351352
}
@@ -404,7 +405,6 @@ export const getTableColumnFromPath = ({
404405
rootTableName,
405406
selectFields: blockSelectFields,
406407
tableName: newTableName,
407-
useAlias,
408408
value,
409409
})
410410
} catch (error) {
@@ -641,7 +641,6 @@ export const getTableColumnFromPath = ({
641641
rootTableName: newTableName,
642642
selectFields,
643643
tableName: newTableName,
644-
useAlias,
645644
value,
646645
})
647646
} else if (
@@ -694,7 +693,6 @@ export const getTableColumnFromPath = ({
694693
pathSegments: pathSegments.slice(1),
695694
selectFields,
696695
tableName: newTableName,
697-
useAlias,
698696
value,
699697
})
700698
}
@@ -716,12 +714,11 @@ export const getTableColumnFromPath = ({
716714
const parentTable = aliasTable || adapter.tables[tableName]
717715
newTableName = `${tableName}${adapter.localesSuffix}`
718716

719-
newTable = useAlias
720-
? getTableAlias({ adapter, tableName: newTableName }).newAliasTable
721-
: adapter.tables[newTableName]
717+
newTable = adapter.tables[newTableName]
722718

723-
joins.push({
719+
addJoinTable({
724720
condition: eq(parentTable.id, newTable._parentID),
721+
joins,
725722
table: newTable,
726723
})
727724

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import type { Table } from 'drizzle-orm'
2+
3+
export const getNameFromDrizzleTable = (table: Table): string => {
4+
const symbol = Object.getOwnPropertySymbols(table).find((symb) =>
5+
symb.description.includes('Name'),
6+
)
7+
8+
return table[symbol]
9+
}

test/fields/collections/Array/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ const ArrayFields: CollectionConfig = {
2323
type: 'text',
2424
required: true,
2525
},
26+
{
27+
name: 'anotherText',
28+
type: 'text',
29+
},
2630
{
2731
name: 'localizedText',
2832
type: 'text',

test/fields/int.spec.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,6 +1546,50 @@ describe('Fields', () => {
15461546
expect(allLocales.localized.en[0].text).toStrictEqual(enText)
15471547
expect(allLocales.localized.es[0].text).toStrictEqual(esText)
15481548
})
1549+
1550+
it('should query by the same array', async () => {
1551+
const doc = await payload.create({
1552+
collection,
1553+
data: {
1554+
items: [
1555+
{
1556+
localizedText: 'test',
1557+
text: 'required',
1558+
anotherText: 'another',
1559+
},
1560+
],
1561+
localized: [{ text: 'a' }],
1562+
},
1563+
})
1564+
1565+
// left join collection_items + left join collection_items_locales
1566+
const {
1567+
docs: [res],
1568+
} = await payload.find({
1569+
collection,
1570+
where: {
1571+
and: [
1572+
{
1573+
'items.localizedText': {
1574+
equals: 'test',
1575+
},
1576+
},
1577+
{
1578+
'items.anotherText': {
1579+
equals: 'another',
1580+
},
1581+
},
1582+
{
1583+
'items.text': {
1584+
equals: 'required',
1585+
},
1586+
},
1587+
],
1588+
},
1589+
})
1590+
1591+
expect(res.id).toBe(doc.id)
1592+
})
15491593
})
15501594

15511595
describe('group', () => {

test/fields/payload-types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ export interface ArrayField {
353353
title?: string | null;
354354
items: {
355355
text: string;
356+
anotherText?: string | null;
356357
localizedText?: string | null;
357358
subArray?:
358359
| {

0 commit comments

Comments
 (0)