Fix cursor-based pagination with lexicographic ordering for composite fields (#12467)
# Fix cursor-based pagination with lexicographic ordering for composite
fields
## Bug
The existing cursor-based pagination implementation had a bug when
handling composite fields.
When paginating through results sorted by composite fields (like
`fullName` with sub-properties `firstName` and`lastName`), the WHERE
conditions generated for cursor positioning were incorrect, leading to
records being skipped.
The previous implementation was generating wrong WHERE conditions:
For example, when paginating with a cursor like `{ firstName: 'John',
lastName: 'Doe' }`, it would generate:
```sql
WHERE firstName > 'John' AND lastName > 'Doe'
```
This is incorrect because it would miss records like `{ firstName:
'John', lastName: 'Smith' }` which should be included in forward
pagination.
## Fix
Create a new util to use proper lexicographic order when sorting a
composite field.
---------
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -6,6 +6,12 @@ type FindManyOperationFactoryParams = {
|
||||
objectMetadataPluralName: string;
|
||||
gqlFields: string;
|
||||
filter?: object;
|
||||
orderBy?: object;
|
||||
limit?: number;
|
||||
after?: string;
|
||||
before?: string;
|
||||
first?: number;
|
||||
last?: number;
|
||||
};
|
||||
|
||||
export const findManyOperationFactory = ({
|
||||
@ -13,19 +19,38 @@ export const findManyOperationFactory = ({
|
||||
objectMetadataPluralName,
|
||||
gqlFields,
|
||||
filter = {},
|
||||
orderBy = {},
|
||||
limit,
|
||||
after,
|
||||
before,
|
||||
first,
|
||||
last,
|
||||
}: FindManyOperationFactoryParams) => ({
|
||||
query: gql`
|
||||
query ${capitalize(objectMetadataPluralName)}($filter: ${capitalize(objectMetadataSingularName)}FilterInput) {
|
||||
${objectMetadataPluralName}(filter: $filter) {
|
||||
query ${capitalize(objectMetadataPluralName)}($filter: ${capitalize(objectMetadataSingularName)}FilterInput, $orderBy: [${capitalize(objectMetadataSingularName)}OrderByInput], $limit: Int, $after: String, $before: String, $first: Int, $last: Int) {
|
||||
${objectMetadataPluralName}(filter: $filter, orderBy: $orderBy, limit: $limit, after: $after, before: $before, first: $first, last: $last) {
|
||||
edges {
|
||||
node {
|
||||
${gqlFields}
|
||||
}
|
||||
cursor
|
||||
}
|
||||
pageInfo {
|
||||
hasNextPage
|
||||
hasPreviousPage
|
||||
startCursor
|
||||
endCursor
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
filter,
|
||||
orderBy,
|
||||
limit,
|
||||
after,
|
||||
before,
|
||||
first,
|
||||
last,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user