fix(db-postgres): querying other collections via relationships inside blocks (#11255)
### What?
Previously, in postgres query like:
```ts
const result = await payload.find({
collection: 'blocks',
where: { 'blocks.director.name': { equals: 'Test Director' } },
})
```
where `blocks` is a blocks field, `director` is a relationship field and
`name` is a text field inside `directors`, failed with:

### Why?
The generated query before was a bit wrong.
Before:
```sql
select distinct
"blocks"."id",
"blocks"."created_at",
"blocks"."created_at"
from
"blocks"
left join "directors" "a5ad426a_eda4_4067_af7e_5b294d7f0968" on "a5ad426a_eda4_4067_af7e_5b294d7f0968"."id" = "blocks_blocks_some"."director_id"
left join "blocks_blocks_some" on "blocks"."id" = "blocks_blocks_some"."_parent_id"
where
"a5ad426a_eda4_4067_af7e_5b294d7f0968"."name" = 'Test Director'
order by
"blocks"."created_at" desc
limit
10
```
Notice `left join directors` _before_ join of `blocks_blocks_some`.
`blocks_blocks_some` doesn't exist yet, this PR changes so now we
generate
```sql
select distinct
"blocks"."id",
"blocks"."created_at",
"blocks"."created_at"
from
"blocks"
left join "blocks_blocks_some" on "blocks"."id" = "blocks_blocks_some"."_parent_id"
left join "directors" "a5ad426a_eda4_4067_af7e_5b294d7f0968" on "a5ad426a_eda4_4067_af7e_5b294d7f0968"."id" = "blocks_blocks_some"."director_id"
where
"a5ad426a_eda4_4067_af7e_5b294d7f0968"."name" = 'Test Director'
order by
"blocks"."created_at" desc
limit
10
```
This commit is contained in:
@@ -220,6 +220,37 @@ export const getTableColumnFromPath = ({
|
||||
let result: TableColumn
|
||||
const blockConstraints = []
|
||||
const blockSelectFields = {}
|
||||
|
||||
let blockJoin: BuildQueryJoinAliases[0]
|
||||
if (isFieldLocalized && adapter.payload.config.localization) {
|
||||
const conditions = [
|
||||
eq(
|
||||
(aliasTable || adapter.tables[tableName]).id,
|
||||
adapter.tables[newTableName]._parentID,
|
||||
),
|
||||
]
|
||||
|
||||
if (locale !== 'all') {
|
||||
conditions.push(eq(adapter.tables[newTableName]._locale, locale))
|
||||
}
|
||||
|
||||
blockJoin = {
|
||||
condition: and(...conditions),
|
||||
table: adapter.tables[newTableName],
|
||||
}
|
||||
} else {
|
||||
blockJoin = {
|
||||
condition: eq(
|
||||
(aliasTable || adapter.tables[tableName]).id,
|
||||
adapter.tables[newTableName]._parentID,
|
||||
),
|
||||
table: adapter.tables[newTableName],
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new reference for nested joins
|
||||
const newJoins = [...joins]
|
||||
|
||||
try {
|
||||
result = getTableColumnFromPath({
|
||||
adapter,
|
||||
@@ -227,7 +258,7 @@ export const getTableColumnFromPath = ({
|
||||
constraintPath,
|
||||
constraints: blockConstraints,
|
||||
fields: block.flattenedFields,
|
||||
joins,
|
||||
joins: newJoins,
|
||||
locale,
|
||||
parentIsLocalized: parentIsLocalized || field.localized,
|
||||
pathSegments: pathSegments.slice(1),
|
||||
@@ -246,30 +277,14 @@ export const getTableColumnFromPath = ({
|
||||
blockTableColumn = result
|
||||
constraints = constraints.concat(blockConstraints)
|
||||
selectFields = { ...selectFields, ...blockSelectFields }
|
||||
if (isFieldLocalized && adapter.payload.config.localization) {
|
||||
const conditions = [
|
||||
eq(
|
||||
(aliasTable || adapter.tables[tableName]).id,
|
||||
adapter.tables[newTableName]._parentID,
|
||||
),
|
||||
]
|
||||
|
||||
if (locale !== 'all') {
|
||||
conditions.push(eq(adapter.tables[newTableName]._locale, locale))
|
||||
const previousLength = joins.length
|
||||
joins.push(blockJoin)
|
||||
// Append new joins AFTER the block join to prevent errors with missing FROM clause.
|
||||
if (newJoins.length > previousLength) {
|
||||
for (let i = previousLength; i < newJoins.length; i++) {
|
||||
joins.push(newJoins[i])
|
||||
}
|
||||
|
||||
joins.push({
|
||||
condition: and(...conditions),
|
||||
table: adapter.tables[newTableName],
|
||||
})
|
||||
} else {
|
||||
joins.push({
|
||||
condition: eq(
|
||||
(aliasTable || adapter.tables[tableName]).id,
|
||||
adapter.tables[newTableName]._parentID,
|
||||
),
|
||||
table: adapter.tables[newTableName],
|
||||
})
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user