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:
@ -7,10 +7,10 @@ export interface ObjectRecord {
|
||||
deletedAt: string | null;
|
||||
}
|
||||
|
||||
export type ObjectRecordFilter = {
|
||||
export type ObjectRecordFilter = Partial<{
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
[Property in keyof ObjectRecord]: any;
|
||||
};
|
||||
}>;
|
||||
|
||||
export enum OrderByDirection {
|
||||
AscNullsFirst = 'AscNullsFirst',
|
||||
@ -19,11 +19,29 @@ export enum OrderByDirection {
|
||||
DescNullsLast = 'DescNullsLast',
|
||||
}
|
||||
|
||||
export type ObjectRecordOrderBy = Array<{
|
||||
export type ObjectRecordOrderBy = Array<
|
||||
ObjectRecordOrderByForScalarField | ObjectRecordOrderByForCompositeField
|
||||
>;
|
||||
|
||||
export type ObjectRecordOrderByForScalarField = {
|
||||
[Property in keyof ObjectRecord]?: OrderByDirection;
|
||||
};
|
||||
|
||||
export type ObjectRecordOrderByForCompositeField = {
|
||||
[Property in keyof ObjectRecord]?: Record<string, OrderByDirection>;
|
||||
};
|
||||
|
||||
export type ObjectRecordCursorLeafScalarValue = string | number | boolean;
|
||||
export type ObjectRecordCursorLeafCompositeValue = Record<
|
||||
string,
|
||||
ObjectRecordCursorLeafScalarValue
|
||||
>;
|
||||
|
||||
export type ObjectRecordCursor = {
|
||||
[Property in keyof ObjectRecord]?:
|
||||
| OrderByDirection
|
||||
| Record<string, OrderByDirection>;
|
||||
}>;
|
||||
| ObjectRecordCursorLeafScalarValue
|
||||
| ObjectRecordCursorLeafCompositeValue;
|
||||
};
|
||||
|
||||
export interface ObjectRecordDuplicateCriteria {
|
||||
objectName: string;
|
||||
|
||||
Reference in New Issue
Block a user