From 605c993bb70d5171e2a7d0c322e470656863ea89 Mon Sep 17 00:00:00 2001 From: Said Akhrarov <36972061+akhrarovsaid@users.noreply.github.com> Date: Thu, 26 Jun 2025 15:52:29 -0400 Subject: [PATCH] fix(drizzle): skip column if undefined in findMany (#12902) ### What? This PR fixes an issue where sorting on a traditional virtual field with `virtual: true` while using a drizzle-based db adapter would cause a runtime error. ### Why? To skip attempting to sort virtual fields which are not linked to a relationship/upload and prevent a runtime error from surfacing. ### How? Skipping the deletion of the property from the `selectFields` object if the column is false-y. Fixes #12886 Before: [sort-virtualfield-drizzle-error.mp4](https://private-user-images.githubusercontent.com/78685728/457602747-b8661e47-a1a8-4453-b2ec-b7e7199b9846.mp4?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NTA2OTU0NzksIm5iZiI6MTc1MDY5NTE3OSwicGF0aCI6Ii83ODY4NTcyOC80NTc2MDI3NDctYjg2NjFlNDctYTFhOC00NDUzLWIyZWMtYjdlNzE5OWI5ODQ2Lm1wND9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTA2MjMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwNjIzVDE2MTI1OVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTE3NmMzOWI5YjNiNzEwYzk3ZWUyNDllYTBjMzZkNzkzMjhjNzc5YzJhNDlkOTBiNDk5MDFhMTdmNDA4NjJhZWQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.N1GJsiI_gZ8M54VHCAmiPEhcJGqRw3Ucy-VeM5R7UFE) After: [virtualfields-sort-Posts---Payload.webm](https://github.com/user-attachments/assets/f5a15d98-4a40-4817-bc6a-415f3ec27484)
Collection config used above ```ts export const PostsCollection: CollectionConfig = { slug: postsSlug, admin: { useAsTitle: 'title', defaultColumns: ['title', 'exampleField'], }, fields: [ { name: 'title', type: 'text', }, { name: 'exampleField', type: 'text', virtual: true, admin: { readOnly: true, }, hooks: { afterRead: [({ data }) => data?.title], }, }, { type: 'relationship', name: 'category', relationTo: 'categories', }, { name: 'categoryTitle', type: 'text', virtual: 'category.title', }, ], } ```
--------- Co-authored-by: Sasha <64744993+r1tsuu@users.noreply.github.com> --- packages/drizzle/src/find/findMany.ts | 2 +- test/database/int.spec.ts | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/drizzle/src/find/findMany.ts b/packages/drizzle/src/find/findMany.ts index 76102df30e..e991b55197 100644 --- a/packages/drizzle/src/find/findMany.ts +++ b/packages/drizzle/src/find/findMany.ts @@ -80,7 +80,7 @@ export const findMany = async function find({ if (orderBy) { for (const key in selectFields) { const column = selectFields[key] - if (column.primary) { + if (!column || column.primary) { continue } diff --git a/test/database/int.spec.ts b/test/database/int.spec.ts index e2b04bde95..0a6adc771c 100644 --- a/test/database/int.spec.ts +++ b/test/database/int.spec.ts @@ -32,7 +32,7 @@ import { initPayloadInt } from '../helpers/initPayloadInt.js' import { isMongoose } from '../helpers/isMongoose.js' import removeFiles from '../helpers/removeFiles.js' import { seed } from './seed.js' -import { errorOnUnnamedFieldsSlug, postsSlug } from './shared.js' +import { errorOnUnnamedFieldsSlug, fieldsPersistanceSlug, postsSlug } from './shared.js' const filename = fileURLToPath(import.meta.url) const dirname = path.dirname(filename) @@ -2325,6 +2325,19 @@ describe('database', () => { expect(localAsc[1].id).toBe(doc_2.id) expect(localAsc[0].id).toBe(doc_1.id) }) + + it('should allow to sort by a virtual field without error', async () => { + await payload.delete({ collection: fieldsPersistanceSlug, where: {} }) + await payload.create({ + collection: fieldsPersistanceSlug, + data: {}, + }) + const { docs } = await payload.find({ + collection: fieldsPersistanceSlug, + sort: '-textHooked', + }) + expect(docs).toHaveLength(1) + }) }) it('should convert numbers to text', async () => {