mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
Fix BigInt primary key routing (#20744)
Co-authored-by: Pascal Jufer <pascal-jufer@bluewin.ch>
This commit is contained in:
5
.changeset/chatty-eagles-fix.md
Normal file
5
.changeset/chatty-eagles-fix.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@directus/api': patch
|
||||
---
|
||||
|
||||
Ensured filter values higher than JavaScript max safe integer work with big integer fields
|
||||
@@ -76,6 +76,8 @@ const FAKE_SCHEMA: SchemaOverview = {
|
||||
relations: [],
|
||||
};
|
||||
|
||||
class Client_SQLite3 extends MockClient {}
|
||||
|
||||
describe('applySearch', () => {
|
||||
function mockDatabase() {
|
||||
const self: Record<string, any> = {
|
||||
@@ -158,10 +160,7 @@ describe('applyFilter', () => {
|
||||
for (const { filterOperator, sqlWhereClause } of withReverseOperators) {
|
||||
for (const filterValue of [true, '', false]) {
|
||||
test(`${filterOperator} with value ${filterValue}`, async () => {
|
||||
class Client_SQLite3 extends MockClient {}
|
||||
|
||||
const db = vi.mocked(knex.default({ client: Client_SQLite3 }));
|
||||
|
||||
const queryBuilder = db.queryBuilder();
|
||||
|
||||
const collection = 'test';
|
||||
@@ -190,4 +189,64 @@ describe('applyFilter', () => {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test(`filter values on bigint fields are correctly passed as such to db query`, async () => {
|
||||
const collection = 'test';
|
||||
const field = 'bigInteger';
|
||||
|
||||
const BIGINT_FAKE_SCHEMA: SchemaOverview = {
|
||||
collections: {
|
||||
[collection]: {
|
||||
collection: 'test',
|
||||
primary: 'id',
|
||||
singleton: false,
|
||||
sortField: null,
|
||||
note: null,
|
||||
accountability: null,
|
||||
fields: {
|
||||
[field]: {
|
||||
field: field,
|
||||
defaultValue: null,
|
||||
nullable: false,
|
||||
generated: false,
|
||||
type: 'bigInteger',
|
||||
dbType: null,
|
||||
precision: null,
|
||||
scale: null,
|
||||
special: [],
|
||||
note: null,
|
||||
validation: null,
|
||||
alias: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
relations: [],
|
||||
};
|
||||
|
||||
const db = vi.mocked(knex.default({ client: Client_SQLite3 }));
|
||||
const queryBuilder = db.queryBuilder();
|
||||
|
||||
// testing with value greater than Number.MAX_SAFE_INTEGER
|
||||
const bigintId = 9007199254740991477n;
|
||||
|
||||
const rootFilter = {
|
||||
[field]: {
|
||||
_eq: bigintId.toString(),
|
||||
},
|
||||
};
|
||||
|
||||
const { query } = applyFilter(db, BIGINT_FAKE_SCHEMA, queryBuilder, rootFilter, collection, {});
|
||||
|
||||
const tracker = createTracker(db);
|
||||
tracker.on.select('*').response([]);
|
||||
|
||||
await query;
|
||||
|
||||
const resultingSelectQuery = tracker.history.select[0];
|
||||
const expectedSql = `select * where "${collection}"."${field}" = ?`;
|
||||
|
||||
expect(resultingSelectQuery?.sql).toEqual(expectedSql);
|
||||
expect(resultingSelectQuery?.bindings[0]).toEqual(bigintId);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -644,8 +644,10 @@ export function applyFilter(
|
||||
const functionName = column!.split('(')[0] as FieldFunction;
|
||||
const type = getOutputTypeForFunction(functionName);
|
||||
|
||||
if (['bigInteger', 'integer', 'float', 'decimal'].includes(type)) {
|
||||
if (['integer', 'float', 'decimal'].includes(type)) {
|
||||
compareValue = Number(compareValue);
|
||||
} else if (type === 'bigInteger') {
|
||||
compareValue = BigInt(compareValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -664,13 +666,21 @@ export function applyFilter(
|
||||
}
|
||||
}
|
||||
|
||||
if (['bigInteger', 'integer', 'float', 'decimal'].includes(type)) {
|
||||
if (['integer', 'float', 'decimal'].includes(type)) {
|
||||
if (Array.isArray(compareValue)) {
|
||||
compareValue = compareValue.map((val) => Number(val));
|
||||
} else {
|
||||
compareValue = Number(compareValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (type === 'bigInteger') {
|
||||
if (Array.isArray(compareValue)) {
|
||||
compareValue = compareValue.map((val) => BigInt(val));
|
||||
} else {
|
||||
compareValue = BigInt(compareValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (operator === '_eq') {
|
||||
|
||||
Reference in New Issue
Block a user