fix(db-postgres): joins count with hasMany relationships (#14008)

Fixes https://github.com/payloadcms/payload/issues/13950
This commit is contained in:
Sasha
2025-10-01 18:38:54 +03:00
committed by GitHub
parent 267ea9ea36
commit 1510e125ab
2 changed files with 26 additions and 8 deletions

View File

@@ -1,4 +1,3 @@
import type { SQL } from 'drizzle-orm'
import type { LibSQLDatabase } from 'drizzle-orm/libsql' import type { LibSQLDatabase } from 'drizzle-orm/libsql'
import type { SQLiteSelect, SQLiteSelectBase } from 'drizzle-orm/sqlite-core' import type { SQLiteSelect, SQLiteSelectBase } from 'drizzle-orm/sqlite-core'
@@ -730,17 +729,24 @@ export const traverseFields = ({
const subQuery = query.as(subQueryAlias) const subQuery = query.as(subQueryAlias)
if (shouldCount) { if (shouldCount) {
let countSubquery: SQLiteSelect = db
.select(selectFields as any)
.from(newAliasTable)
.where(subQueryWhere)
.$dynamic()
joins.forEach(({ type, condition, table }) => {
countSubquery = countSubquery[type ?? 'leftJoin'](table, condition)
})
currentArgs.extras[`${columnName}_count`] = sql`${db currentArgs.extras[`${columnName}_count`] = sql`${db
.select({ .select({
count: count(), count: count(),
}) })
.from( .from(sql`${countSubquery.as(`${subQueryAlias}_count_subquery`)}`)}`.as(
sql`${db `${subQueryAlias}_count`,
.select(selectFields as any) )
.from(newAliasTable)
.where(subQueryWhere)
.as(`${subQueryAlias}_count_subquery`)}`,
)}`.as(`${subQueryAlias}_count`)
} }
currentArgs.extras[columnName] = sql`${db currentArgs.extras[columnName] = sql`${db

View File

@@ -215,6 +215,18 @@ describe('Joins Field', () => {
expect(categoryWithPosts.group.relatedPosts?.totalDocs).toBe(15) expect(categoryWithPosts.group.relatedPosts?.totalDocs).toBe(15)
}) })
it('should count hasMany relationship joins', async () => {
const res = await payload.findByID({
id: category.id,
collection: categoriesSlug,
joins: {
hasManyPosts: { limit: 1, count: true },
},
})
expect(res.hasManyPosts?.totalDocs).toBe(15)
})
it('should populate relationships in joins', async () => { it('should populate relationships in joins', async () => {
const { docs } = await payload.find({ const { docs } = await payload.find({
limit: 1, limit: 1,