Skip to content

Commit

Permalink
fix(db-postgres): query with like on id columns (#6414)
Browse files Browse the repository at this point in the history
When typing into the search input on the list view of a collection, the
`like` operator is used for id which causes an error for postgres. To
fix this we are sanitizing the `like` for number or uuid fields to
instead be an `equals` operator. An alternate solution would have been
to cast the ids to text `id::text` but this would have performence
implications on larger data sets.

---------

Co-authored-by: James <james@trbl.design>
  • Loading branch information
DanRibbens and jmikrut committed May 17, 2024
1 parent bf106db commit 12c812d
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 37 deletions.
9 changes: 8 additions & 1 deletion packages/db-postgres/src/queries/parseParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export async function parseParams({
// So we need to loop on keys again here to handle each operator independently
const pathOperators = where[relationOrPath]
if (typeof pathOperators === 'object') {
for (const operator of Object.keys(pathOperators)) {
for (let operator of Object.keys(pathOperators)) {
if (validOperators.includes(operator as Operator)) {
const val = where[relationOrPath][operator]
const {
Expand Down Expand Up @@ -157,6 +157,13 @@ export async function parseParams({
break
}

if (
operator === 'like' &&
(field.type === 'number' || table[columnName].columnType === 'PgUUID')
) {
operator = 'equals'
}

if (operator === 'like') {
constraints.push(
and(...val.split(' ').map((word) => ilike(table[columnName], `%${word}%`))),
Expand Down
44 changes: 21 additions & 23 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 36 additions & 13 deletions test/collections-rest/int.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,10 @@ describe('collections-rest', () => {

const description = 'updated'
const response = await restClient.PATCH(`/${slug}`, {
query: { where: { title: { equals: 'title' } } },
body: JSON.stringify({
description,
}),
query: { where: { title: { equals: 'title' } } },
})
const { docs, errors } = await response.json()

Expand All @@ -155,10 +155,10 @@ describe('collections-rest', () => {
const description = 'updated'

const response = await restClient.PATCH(`/${slug}`, {
query: { where: { missing: { equals: 'title' } } },
body: JSON.stringify({
description,
}),
query: { where: { missing: { equals: 'title' } } },
})
const { docs: noDocs, errors } = await response.json()

Expand All @@ -181,18 +181,18 @@ describe('collections-rest', () => {

const description = 'updated'
const relationFieldResponse = await restClient.PATCH(`/${slug}`, {
query: { where: { 'relationField.missing': { equals: 'title' } } },
body: JSON.stringify({
description,
}),
query: { where: { 'relationField.missing': { equals: 'title' } } },
})
expect(relationFieldResponse.status).toEqual(400)

const relationMultiRelationToResponse = await restClient.PATCH(`/${slug}`, {
query: { where: { 'relationMultiRelationTo.missing': { equals: 'title' } } },
body: JSON.stringify({
description,
}),
query: { where: { 'relationMultiRelationTo.missing': { equals: 'title' } } },
})
expect(relationMultiRelationToResponse.status).toEqual(400)

Expand All @@ -214,10 +214,10 @@ describe('collections-rest', () => {

const description = 'description'
const response = await restClient.PATCH(`/${slug}`, {
query: { where: { restrictedField: { equals: 'restricted' } } },
body: JSON.stringify({
description,
}),
query: { where: { restrictedField: { equals: 'restricted' } } },
})
const result = await response.json()

Expand Down Expand Up @@ -253,10 +253,10 @@ describe('collections-rest', () => {

const update = 'update'
const response = await restClient.PATCH(`/${errorOnHookSlug}`, {
query: { where: { text: { equals: text } } },
body: JSON.stringify({
text: update,
}),
query: { where: { text: { equals: text } } },
})
const result = await response.json()

Expand Down Expand Up @@ -544,6 +544,29 @@ describe('collections-rest', () => {
expect(result.docs).toEqual([post])
expect(result.totalDocs).toEqual(1)
})

it('should query LIKE by ID', async () => {
const post = await payload.create({
collection: slug,
data: {
title: 'find me buddy',
},
})

const response = await restClient.GET(`/${slug}`, {
query: {
where: {
id: {
like: post.id,
},
},
},
})

const result = await response.json()
expect(response.status).toStrictEqual(200)
expect(result.totalDocs).toStrictEqual(1)
})
})

it('should query nested relationship - hasMany', async () => {
Expand Down Expand Up @@ -1058,13 +1081,13 @@ describe('collections-rest', () => {
const { docs } = await restClient
.GET(`/${pointSlug}`, {
query: {
limit: 5,
where: {
point: {
// querying large enough range to include all docs
near: '0, 0, 100000, 0',
},
},
limit: 5,
},
})
.then((res) => res.json())
Expand Down Expand Up @@ -1094,8 +1117,8 @@ describe('collections-rest', () => {
where: {
point: {
within: {
coordinates: [polygon],
type: 'Polygon',
coordinates: [polygon],
},
},
},
Expand All @@ -1113,8 +1136,8 @@ describe('collections-rest', () => {
where: {
point: {
within: {
coordinates: [polygon.map((vertex) => vertex.map((coord) => coord * 0.1))], // Reduce polygon to 10% of its size
type: 'Polygon',
coordinates: [polygon.map((vertex) => vertex.map((coord) => coord * 0.1))], // Reduce polygon to 10% of its size
},
},
},
Expand Down Expand Up @@ -1144,8 +1167,8 @@ describe('collections-rest', () => {
where: {
point: {
intersects: {
coordinates: [polygon],
type: 'Polygon',
coordinates: [polygon],
},
},
},
Expand All @@ -1163,8 +1186,8 @@ describe('collections-rest', () => {
where: {
point: {
intersects: {
coordinates: [polygon.map((vertex) => vertex.map((coord) => coord * 0.1))], // Reduce polygon to 10% of its size
type: 'Polygon',
coordinates: [polygon.map((vertex) => vertex.map((coord) => coord * 0.1))], // Reduce polygon to 10% of its size
},
},
},
Expand Down Expand Up @@ -1397,12 +1420,12 @@ describe('collections-rest', () => {
it('should query a limited set of docs', async () => {
const response = await restClient.GET(`/${slug}`, {
query: {
limit: 15,
where: {
title: {
equals: 'limit-test',
},
},
limit: 15,
},
})
const result = await response.json()
Expand All @@ -1414,12 +1437,12 @@ describe('collections-rest', () => {
it('should query all docs when limit=0', async () => {
const response = await restClient.GET(`/${slug}`, {
query: {
limit: 0,
where: {
title: {
equals: 'limit-test',
},
},
limit: 0,
},
})
const result = await response.json()
Expand Down

0 comments on commit 12c812d

Please sign in to comment.