Commit fba2438
authored
fix(drizzle): error when using contains operator on hasMany select fields (#15865)
Fixes `contains` operator on hasMany `select` fields in PostgreSQL. This
was a regression introduced in #15671.
## The problem
Given a collection with a hasMany `select` field:
```typescript
{
slug: 'users',
fields: [
{
name: 'roles',
type: 'select',
hasMany: true,
options: ['user', 'admin', 'editor'],
},
],
}
```
Payload stores this across two PostgreSQL tables. For a user created
with `roles: ['admin', 'editor']`:
**`users`**
| id | created_at | updated_at |
|----|------------|------------|
| 1 | 2026-03-05 | 2026-03-05 |
**`users_roles`**
| id | parent_id | value | order |
|----|-----------|----------|-------|
| 1 | 1 | `admin` | 1 |
| 2 | 1 | `editor` | 2 |
The `value` column is a PostgreSQL **enum type**, not a `varchar`.
When querying `{ roles: { contains: 'admin' } }`, Payload generated:
```sql
SELECT DISTINCT "users"."id"
FROM "users"
LEFT JOIN "users_roles"
ON "users"."id" = "users_roles"."parent_id"
WHERE "users_roles"."value" ILIKE '%admin%'
-- ❌ PostgreSQL error: operator does not exist: enum_users_roles ~~* unknown
```
`ILIKE` does not work on PostgreSQL enum types.
## The fix
The LEFT JOIN already flattens the array into individual rows:
| users.id | users_roles.value |
|----------|-------------------|
| 1 | `admin` |
| 1 | `editor` |
So "contains admin" just means "has a row where value equals admin". The
fix converts `contains` to `equals` for hasMany `select` fields, the
same way it already works for hasMany `relationship` and `upload`
fields:
```sql
SELECT DISTINCT "users"."id"
FROM "users"
LEFT JOIN "users_roles"
ON "users"."id" = "users_roles"."parent_id"
WHERE "users_roles"."value" = 'admin'
-- ✅ Matches row 1, returns user id=1
```
## Why hasMany `text` fields are different
HasMany `text` fields store values as `varchar`, not as an enum. `ILIKE`
works fine on `varchar` columns, so substring matching (`contains:
'adm'` matching `'admin'`) is valid there. Whether it's _desirable_ is a
problem separate from this PR, being discussed internally
[here](https://payloadcms.slack.com/archives/C049BR3QBHC/p1772680331359859)1 parent 17a0d19 commit fba2438
File tree
5 files changed
+124
-9
lines changed- packages
- db-mongodb/src/queries
- drizzle/src/queries
- test/database
5 files changed
+124
-9
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
450 | 450 | | |
451 | 451 | | |
452 | 452 | | |
453 | | - | |
454 | | - | |
455 | | - | |
456 | | - | |
457 | | - | |
458 | | - | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
459 | 472 | | |
460 | 473 | | |
461 | 474 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
238 | 238 | | |
239 | 239 | | |
240 | 240 | | |
241 | | - | |
| 241 | + | |
| 242 | + | |
242 | 243 | | |
243 | 244 | | |
244 | 245 | | |
245 | 246 | | |
246 | | - | |
| 247 | + | |
247 | 248 | | |
248 | 249 | | |
249 | 250 | | |
| |||
260 | 261 | | |
261 | 262 | | |
262 | 263 | | |
263 | | - | |
| 264 | + | |
264 | 265 | | |
265 | 266 | | |
266 | 267 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1016 | 1016 | | |
1017 | 1017 | | |
1018 | 1018 | | |
| 1019 | + | |
| 1020 | + | |
| 1021 | + | |
| 1022 | + | |
| 1023 | + | |
| 1024 | + | |
| 1025 | + | |
| 1026 | + | |
| 1027 | + | |
| 1028 | + | |
| 1029 | + | |
| 1030 | + | |
| 1031 | + | |
| 1032 | + | |
| 1033 | + | |
| 1034 | + | |
| 1035 | + | |
1019 | 1036 | | |
1020 | 1037 | | |
1021 | 1038 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
692 | 692 | | |
693 | 693 | | |
694 | 694 | | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
| 717 | + | |
| 718 | + | |
| 719 | + | |
| 720 | + | |
| 721 | + | |
| 722 | + | |
| 723 | + | |
| 724 | + | |
| 725 | + | |
| 726 | + | |
| 727 | + | |
| 728 | + | |
| 729 | + | |
| 730 | + | |
| 731 | + | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
695 | 739 | | |
696 | 740 | | |
697 | 741 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
| 92 | + | |
92 | 93 | | |
93 | 94 | | |
94 | 95 | | |
| |||
119 | 120 | | |
120 | 121 | | |
121 | 122 | | |
| 123 | + | |
122 | 124 | | |
123 | 125 | | |
124 | 126 | | |
| |||
144 | 146 | | |
145 | 147 | | |
146 | 148 | | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
147 | 152 | | |
148 | 153 | | |
149 | 154 | | |
| |||
693 | 698 | | |
694 | 699 | | |
695 | 700 | | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
696 | 712 | | |
697 | 713 | | |
698 | 714 | | |
| |||
830 | 846 | | |
831 | 847 | | |
832 | 848 | | |
| 849 | + | |
| 850 | + | |
| 851 | + | |
| 852 | + | |
833 | 853 | | |
834 | 854 | | |
835 | 855 | | |
| |||
1330 | 1350 | | |
1331 | 1351 | | |
1332 | 1352 | | |
| 1353 | + | |
| 1354 | + | |
| 1355 | + | |
| 1356 | + | |
| 1357 | + | |
| 1358 | + | |
| 1359 | + | |
| 1360 | + | |
| 1361 | + | |
| 1362 | + | |
1333 | 1363 | | |
1334 | 1364 | | |
1335 | 1365 | | |
| |||
1540 | 1570 | | |
1541 | 1571 | | |
1542 | 1572 | | |
| 1573 | + | |
| 1574 | + | |
| 1575 | + | |
| 1576 | + | |
| 1577 | + | |
| 1578 | + | |
| 1579 | + | |
| 1580 | + | |
| 1581 | + | |
| 1582 | + | |
1543 | 1583 | | |
1544 | 1584 | | |
1545 | 1585 | | |
| |||
0 commit comments