From 1510e125ab922cfeef1353750b6f756485c2122b Mon Sep 17 00:00:00 2001 From: Sasha <64744993+r1tsuu@users.noreply.github.com> Date: Wed, 1 Oct 2025 18:38:54 +0300 Subject: [PATCH] fix(db-postgres): joins count with hasMany relationships (#14008) Fixes https://github.com/payloadcms/payload/issues/13950 --- packages/drizzle/src/find/traverseFields.ts | 22 +++++++++++++-------- test/joins/int.spec.ts | 12 +++++++++++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/packages/drizzle/src/find/traverseFields.ts b/packages/drizzle/src/find/traverseFields.ts index d71f0df3b..a1b1ddcc5 100644 --- a/packages/drizzle/src/find/traverseFields.ts +++ b/packages/drizzle/src/find/traverseFields.ts @@ -1,4 +1,3 @@ -import type { SQL } from 'drizzle-orm' import type { LibSQLDatabase } from 'drizzle-orm/libsql' import type { SQLiteSelect, SQLiteSelectBase } from 'drizzle-orm/sqlite-core' @@ -730,17 +729,24 @@ export const traverseFields = ({ const subQuery = query.as(subQueryAlias) 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 .select({ count: count(), }) - .from( - sql`${db - .select(selectFields as any) - .from(newAliasTable) - .where(subQueryWhere) - .as(`${subQueryAlias}_count_subquery`)}`, - )}`.as(`${subQueryAlias}_count`) + .from(sql`${countSubquery.as(`${subQueryAlias}_count_subquery`)}`)}`.as( + `${subQueryAlias}_count`, + ) } currentArgs.extras[columnName] = sql`${db diff --git a/test/joins/int.spec.ts b/test/joins/int.spec.ts index d8d1e506d..56149f2d8 100644 --- a/test/joins/int.spec.ts +++ b/test/joins/int.spec.ts @@ -215,6 +215,18 @@ describe('Joins Field', () => { 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 () => { const { docs } = await payload.find({ limit: 1,