From 564d0697fc151091ca045a03f775eb129bbddcca Mon Sep 17 00:00:00 2001 From: Kevin De Porre Date: Mon, 5 Jan 2026 16:30:48 +0100 Subject: [PATCH 1/7] Reproduce problem with groupBy over BigInt --- packages/db/tests/query/group-by.test.ts | 332 +++++++++++++++++++++++ 1 file changed, 332 insertions(+) diff --git a/packages/db/tests/query/group-by.test.ts b/packages/db/tests/query/group-by.test.ts index e21f7be2c..e8f707de8 100644 --- a/packages/db/tests/query/group-by.test.ts +++ b/packages/db/tests/query/group-by.test.ts @@ -1108,6 +1108,338 @@ function createGroupByTests(autoIndex: `off` | `eager`): void { expect(customer1?.min_quantity).toBe(1) expect(customer1?.max_quantity).toBe(2) }) + + test(`group by BigInt column should not throw JSON.stringify error`, () => { + // Define a type with BigInt field (simulating a Postgres bigint column) + type District = { + id: number + district_id: bigint + name: string + status: string + } + + const sampleDistricts: Array = [ + { + id: 1, + district_id: BigInt('9007199254740991'), // Max safe integer + 1 + name: 'District A', + status: 'active', + }, + { + id: 2, + district_id: BigInt('9007199254740992'), + name: 'District B', + status: 'active', + }, + { + id: 3, + district_id: BigInt('9007199254740991'), // Same as first + name: 'District C', + status: 'inactive', + }, + { + id: 4, + district_id: BigInt('9007199254740993'), + name: 'District D', + status: 'active', + }, + ] + + const districtsCollection = createCollection( + mockSyncCollectionOptions({ + id: `test-districts`, + getKey: (district) => district.id, + initialData: sampleDistricts, + autoIndex, + }), + ) + + // This should not throw "Do not know how to serialize a BigInt" error + const districtSummary = createLiveQueryCollection({ + startSync: true, + query: (q) => + q + .from({ districts: districtsCollection }) + .groupBy(({ districts }) => districts.district_id) + .select(({ districts }) => ({ + district_id: districts.district_id, + count: count(districts.id), + statuses: districts.status, + })), + }) + + // Should have 3 groups (two districts share the same district_id) + expect(districtSummary.size).toBe(3) + + // Check the group with BigInt('9007199254740991') + const group1 = Array.from(districtSummary.values()).find( + (d) => d.district_id === BigInt('9007199254740991'), + ) + expect(group1).toBeDefined() + expect(group1?.count).toBe(2) // Districts 1 and 3 + + // Check the group with BigInt('9007199254740992') + const group2 = Array.from(districtSummary.values()).find( + (d) => d.district_id === BigInt('9007199254740992'), + ) + expect(group2).toBeDefined() + expect(group2?.count).toBe(1) // District 2 + + // Check the group with BigInt('9007199254740993') + const group3 = Array.from(districtSummary.values()).find( + (d) => d.district_id === BigInt('9007199254740993'), + ) + expect(group3).toBeDefined() + expect(group3?.count).toBe(1) // District 4 + }) + + test(`group by Date column should serialize correctly`, () => { + type Event = { + id: number + event_date: Date + name: string + category: string + } + + const date1 = new Date('2023-01-15T10:00:00Z') + const date2 = new Date('2023-01-20T14:30:00Z') + const date3 = new Date('2023-01-15T10:00:00Z') // Same as date1 + + const sampleEvents: Array = [ + { + id: 1, + event_date: date1, + name: 'Event A', + category: 'conference', + }, + { + id: 2, + event_date: date2, + name: 'Event B', + category: 'workshop', + }, + { + id: 3, + event_date: date3, // Same date as Event A + name: 'Event C', + category: 'conference', + }, + { + id: 4, + event_date: new Date('2023-02-01T09:00:00Z'), + name: 'Event D', + category: 'workshop', + }, + ] + + const eventsCollection = createCollection( + mockSyncCollectionOptions({ + id: `test-events`, + getKey: (event) => event.id, + initialData: sampleEvents, + autoIndex, + }), + ) + + // Group by Date - should serialize dates to ISO strings for keys + const eventSummary = createLiveQueryCollection({ + startSync: true, + query: (q) => + q + .from({ events: eventsCollection }) + .groupBy(({ events }) => events.event_date) + .select(({ events }) => ({ + event_date: events.event_date, + count: count(events.id), + names: events.name, + })), + }) + + // Should have 3 groups (two events share the same date) + expect(eventSummary.size).toBe(3) + + // Check the group with date1 (which equals date3) + const group1 = Array.from(eventSummary.values()).find( + (e) => e.event_date.getTime() === date1.getTime(), + ) + expect(group1).toBeDefined() + expect(group1?.count).toBe(2) // Events 1 and 3 + + // Check the group with date2 + const group2 = Array.from(eventSummary.values()).find( + (e) => e.event_date.getTime() === date2.getTime(), + ) + expect(group2).toBeDefined() + expect(group2?.count).toBe(1) // Event 2 + + // Check the group with the February date + const group3 = Array.from(eventSummary.values()).find( + (e) => e.event_date.getTime() === new Date('2023-02-01T09:00:00Z').getTime(), + ) + expect(group3).toBeDefined() + expect(group3?.count).toBe(1) // Event 4 + }) + + test(`group by multiple columns including Date should not throw error`, () => { + type LogEntry = { + id: number + timestamp: Date + level: string + service: string + } + + const timestamp1 = new Date('2023-01-15T10:00:00Z') + const timestamp2 = new Date('2023-01-15T10:00:00Z') // Same as timestamp1 + + const sampleLogs: Array = [ + { + id: 1, + timestamp: timestamp1, + level: 'error', + service: 'api', + }, + { + id: 2, + timestamp: timestamp1, + level: 'info', + service: 'api', + }, + { + id: 3, + timestamp: timestamp2, + level: 'error', + service: 'worker', + }, + { + id: 4, + timestamp: new Date('2023-01-20T14:30:00Z'), + level: 'warning', + service: 'api', + }, + ] + + const logsCollection = createCollection( + mockSyncCollectionOptions({ + id: `test-logs`, + getKey: (log) => log.id, + initialData: sampleLogs, + autoIndex, + }), + ) + + // Group by both Date and string - should not throw + const logSummary = createLiveQueryCollection({ + startSync: true, + query: (q) => + q + .from({ logs: logsCollection }) + .groupBy(({ logs }) => [logs.timestamp, logs.level]) + .select(({ logs }) => ({ + timestamp: logs.timestamp, + level: logs.level, + count: count(logs.id), + })), + }) + + expect(logSummary.size).toBe(3) // Three distinct combinations + + // Find the group with timestamp1 and 'error' + const group1 = Array.from(logSummary.values()).find( + (l) => + l.timestamp.getTime() === timestamp1.getTime() && l.level === 'error', + ) + expect(group1).toBeDefined() + expect(group1?.count).toBe(2) // Logs 1 and 3 (same timestamp, same level) + + // Find the group with timestamp1 and 'info' + const group2 = Array.from(logSummary.values()).find( + (l) => + l.timestamp.getTime() === timestamp1.getTime() && l.level === 'info', + ) + expect(group2).toBeDefined() + expect(group2?.count).toBe(1) // Log 2 + + // Find the group with the different timestamp and 'warning' + const group3 = Array.from(logSummary.values()).find( + (l) => + l.timestamp.getTime() === new Date('2023-01-20T14:30:00Z').getTime() && + l.level === 'warning', + ) + expect(group3).toBeDefined() + expect(group3?.count).toBe(1) // Log 4 + }) + + test(`group by multiple columns including BigInt should not throw error`, () => { + type School = { + id: number + district_id: bigint + name: string + status: string + } + + const sampleSchools: Array = [ + { + id: 1, + district_id: BigInt('9007199254740991'), + name: 'School A', + status: 'active', + }, + { + id: 2, + district_id: BigInt('9007199254740991'), + name: 'School B', + status: 'active', + }, + { + id: 3, + district_id: BigInt('9007199254740992'), + name: 'School C', + status: 'inactive', + }, + ] + + const schoolsCollection = createCollection( + mockSyncCollectionOptions({ + id: `test-schools`, + getKey: (school) => school.id, + initialData: sampleSchools, + autoIndex, + }), + ) + + // Group by both BigInt and string - should not throw + const schoolSummary = createLiveQueryCollection({ + startSync: true, + query: (q) => + q + .from({ schools: schoolsCollection }) + .groupBy(({ schools }) => [schools.district_id, schools.status]) + .select(({ schools }) => ({ + district_id: schools.district_id, + status: schools.status, + count: count(schools.id), + })), + }) + + expect(schoolSummary.size).toBe(2) // Two distinct combinations + + // Find the group with BigInt('9007199254740991') and 'active' + const group1 = Array.from(schoolSummary.values()).find( + (s) => + s.district_id === BigInt('9007199254740991') && s.status === 'active', + ) + expect(group1).toBeDefined() + expect(group1?.count).toBe(2) // Schools 1 and 2 + + // Find the group with BigInt('9007199254740992') and 'inactive' + const group2 = Array.from(schoolSummary.values()).find( + (s) => + s.district_id === BigInt('9007199254740992') && + s.status === 'inactive', + ) + expect(group2).toBeDefined() + expect(group2?.count).toBe(1) // School 3 + }) }) describe(`Nested Object GroupBy`, () => { From b590c9697d74600dcb1f396d655d889bae782586 Mon Sep 17 00:00:00 2001 From: Kevin De Porre Date: Mon, 5 Jan 2026 16:46:40 +0100 Subject: [PATCH 2/7] Fix queries in tests --- packages/db/tests/query/group-by.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/db/tests/query/group-by.test.ts b/packages/db/tests/query/group-by.test.ts index e8f707de8..cbff07943 100644 --- a/packages/db/tests/query/group-by.test.ts +++ b/packages/db/tests/query/group-by.test.ts @@ -1164,7 +1164,6 @@ function createGroupByTests(autoIndex: `off` | `eager`): void { .select(({ districts }) => ({ district_id: districts.district_id, count: count(districts.id), - statuses: districts.status, })), }) @@ -1251,7 +1250,6 @@ function createGroupByTests(autoIndex: `off` | `eager`): void { .select(({ events }) => ({ event_date: events.event_date, count: count(events.id), - names: events.name, })), }) From ae3236835b4effcbb368869d75cabfcfb1ecf5b3 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Mon, 5 Jan 2026 15:51:17 +0000 Subject: [PATCH 3/7] ci: apply automated fixes --- packages/db/tests/query/group-by.test.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/db/tests/query/group-by.test.ts b/packages/db/tests/query/group-by.test.ts index cbff07943..840ba0a6a 100644 --- a/packages/db/tests/query/group-by.test.ts +++ b/packages/db/tests/query/group-by.test.ts @@ -1272,7 +1272,9 @@ function createGroupByTests(autoIndex: `off` | `eager`): void { // Check the group with the February date const group3 = Array.from(eventSummary.values()).find( - (e) => e.event_date.getTime() === new Date('2023-02-01T09:00:00Z').getTime(), + (e) => + e.event_date.getTime() === + new Date('2023-02-01T09:00:00Z').getTime(), ) expect(group3).toBeDefined() expect(group3?.count).toBe(1) // Event 4 @@ -1344,7 +1346,8 @@ function createGroupByTests(autoIndex: `off` | `eager`): void { // Find the group with timestamp1 and 'error' const group1 = Array.from(logSummary.values()).find( (l) => - l.timestamp.getTime() === timestamp1.getTime() && l.level === 'error', + l.timestamp.getTime() === timestamp1.getTime() && + l.level === 'error', ) expect(group1).toBeDefined() expect(group1?.count).toBe(2) // Logs 1 and 3 (same timestamp, same level) @@ -1352,7 +1355,8 @@ function createGroupByTests(autoIndex: `off` | `eager`): void { // Find the group with timestamp1 and 'info' const group2 = Array.from(logSummary.values()).find( (l) => - l.timestamp.getTime() === timestamp1.getTime() && l.level === 'info', + l.timestamp.getTime() === timestamp1.getTime() && + l.level === 'info', ) expect(group2).toBeDefined() expect(group2?.count).toBe(1) // Log 2 @@ -1360,7 +1364,8 @@ function createGroupByTests(autoIndex: `off` | `eager`): void { // Find the group with the different timestamp and 'warning' const group3 = Array.from(logSummary.values()).find( (l) => - l.timestamp.getTime() === new Date('2023-01-20T14:30:00Z').getTime() && + l.timestamp.getTime() === + new Date('2023-01-20T14:30:00Z').getTime() && l.level === 'warning', ) expect(group3).toBeDefined() @@ -1424,7 +1429,8 @@ function createGroupByTests(autoIndex: `off` | `eager`): void { // Find the group with BigInt('9007199254740991') and 'active' const group1 = Array.from(schoolSummary.values()).find( (s) => - s.district_id === BigInt('9007199254740991') && s.status === 'active', + s.district_id === BigInt('9007199254740991') && + s.status === 'active', ) expect(group1).toBeDefined() expect(group1?.count).toBe(2) // Schools 1 and 2 From 00720dd8a7200c087d82458d176ed982fe2e70c8 Mon Sep 17 00:00:00 2001 From: Kevin De Porre Date: Mon, 5 Jan 2026 17:05:50 +0100 Subject: [PATCH 4/7] Properly serialize BigInt and Date in groupBy operator --- packages/db-ivm/src/index.ts | 2 +- packages/db-ivm/src/operators/groupBy.ts | 3 ++- packages/db-ivm/src/utils.ts | 17 +++++++++++++++++ packages/db/src/query/compiler/group-by.ts | 4 ++-- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/packages/db-ivm/src/index.ts b/packages/db-ivm/src/index.ts index 3ca1f26c6..cae148b46 100644 --- a/packages/db-ivm/src/index.ts +++ b/packages/db-ivm/src/index.ts @@ -2,4 +2,4 @@ export * from './d2.js' export * from './multiset.js' export * from './operators/index.js' export * from './types.js' -export { compareKeys } from './utils.js' +export { compareKeys, serializeValue } from './utils.js' diff --git a/packages/db-ivm/src/operators/groupBy.ts b/packages/db-ivm/src/operators/groupBy.ts index b752ae560..24b884715 100644 --- a/packages/db-ivm/src/operators/groupBy.ts +++ b/packages/db-ivm/src/operators/groupBy.ts @@ -1,3 +1,4 @@ +import { serializeValue } from '../utils.js' import { map } from './map.js' import { reduce } from './reduce.js' import type { IStreamBuilder, KeyValue } from '../types.js' @@ -67,7 +68,7 @@ export function groupBy< const withKeysAndValues = stream.pipe( map((data) => { const key = keyExtractor(data) - const keyString = JSON.stringify(key) + const keyString = serializeValue(key) // Create values object with pre-aggregated values const values: Record = {} diff --git a/packages/db-ivm/src/utils.ts b/packages/db-ivm/src/utils.ts index 8f931c362..70cfda48c 100644 --- a/packages/db-ivm/src/utils.ts +++ b/packages/db-ivm/src/utils.ts @@ -192,3 +192,20 @@ export function compareKeys(a: string | number, b: string | number): number { // Different types: strings come before numbers return typeof a === `string` ? -1 : 1 } + +/** + * Serializes a value for use as a key, handling BigInt and Date values that JSON.stringify cannot handle. + * Uses JSON.stringify with a replacer function to convert BigInt values to strings and Date values to ISO strings. + * This is used for creating string keys in groupBy operations. + */ +export function serializeValue(value: unknown): string { + return JSON.stringify(value, (_, val) => { + if (typeof val === 'bigint') { + return val.toString() + } + if (val instanceof Date) { + return val.toISOString() + } + return val + }) +} diff --git a/packages/db/src/query/compiler/group-by.ts b/packages/db/src/query/compiler/group-by.ts index e9c8fa436..891e9c419 100644 --- a/packages/db/src/query/compiler/group-by.ts +++ b/packages/db/src/query/compiler/group-by.ts @@ -1,4 +1,4 @@ -import { filter, groupBy, groupByOperators, map } from '@tanstack/db-ivm' +import { filter, groupBy, groupByOperators, map, serializeValue } from '@tanstack/db-ivm' import { Func, PropRef, getHavingExpression } from '../ir.js' import { AggregateFunctionNotInSelectError, @@ -248,7 +248,7 @@ export function processGroupBy( for (let i = 0; i < groupByClause.length; i++) { keyParts.push(aggregatedRow[`__key_${i}`]) } - finalKey = JSON.stringify(keyParts) + finalKey = serializeValue(keyParts) } return [ From b8c486df4e123a676b6f20918c4276aa5a9abd03 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Mon, 5 Jan 2026 16:06:54 +0000 Subject: [PATCH 5/7] ci: apply automated fixes --- packages/db/src/query/compiler/group-by.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/db/src/query/compiler/group-by.ts b/packages/db/src/query/compiler/group-by.ts index 891e9c419..9bfd327c0 100644 --- a/packages/db/src/query/compiler/group-by.ts +++ b/packages/db/src/query/compiler/group-by.ts @@ -1,4 +1,10 @@ -import { filter, groupBy, groupByOperators, map, serializeValue } from '@tanstack/db-ivm' +import { + filter, + groupBy, + groupByOperators, + map, + serializeValue, +} from '@tanstack/db-ivm' import { Func, PropRef, getHavingExpression } from '../ir.js' import { AggregateFunctionNotInSelectError, From 7aba950bec63e88c8e8f03a8ba841d775cb91e43 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 10:28:00 +0100 Subject: [PATCH 6/7] Replace hardcoded BigInt values with Number.MAX_SAFE_INTEGER expressions (#1093) * Initial plan * Replace hardcoded BigInt values with Number.MAX_SAFE_INTEGER + 1 Co-authored-by: kevin-dp <17384006+kevin-dp@users.noreply.github.com> * Extract MAX_SAFE_BIGINT constant to improve readability Co-authored-by: kevin-dp <17384006+kevin-dp@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: kevin-dp <17384006+kevin-dp@users.noreply.github.com> --- packages/db/tests/query/group-by.test.ts | 40 ++++++++++++++---------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/packages/db/tests/query/group-by.test.ts b/packages/db/tests/query/group-by.test.ts index 840ba0a6a..89055585f 100644 --- a/packages/db/tests/query/group-by.test.ts +++ b/packages/db/tests/query/group-by.test.ts @@ -1118,28 +1118,31 @@ function createGroupByTests(autoIndex: `off` | `eager`): void { status: string } + // Use BigInt values beyond MAX_SAFE_INTEGER to test BigInt serialization + const MAX_SAFE_BIGINT = BigInt(Number.MAX_SAFE_INTEGER + 1) + const sampleDistricts: Array = [ { id: 1, - district_id: BigInt('9007199254740991'), // Max safe integer + 1 + district_id: MAX_SAFE_BIGINT, name: 'District A', status: 'active', }, { id: 2, - district_id: BigInt('9007199254740992'), + district_id: MAX_SAFE_BIGINT + 1n, name: 'District B', status: 'active', }, { id: 3, - district_id: BigInt('9007199254740991'), // Same as first + district_id: MAX_SAFE_BIGINT, // Same as first name: 'District C', status: 'inactive', }, { id: 4, - district_id: BigInt('9007199254740993'), + district_id: MAX_SAFE_BIGINT + 2n, name: 'District D', status: 'active', }, @@ -1170,23 +1173,23 @@ function createGroupByTests(autoIndex: `off` | `eager`): void { // Should have 3 groups (two districts share the same district_id) expect(districtSummary.size).toBe(3) - // Check the group with BigInt('9007199254740991') + // Check the group with MAX_SAFE_BIGINT const group1 = Array.from(districtSummary.values()).find( - (d) => d.district_id === BigInt('9007199254740991'), + (d) => d.district_id === MAX_SAFE_BIGINT, ) expect(group1).toBeDefined() expect(group1?.count).toBe(2) // Districts 1 and 3 - // Check the group with BigInt('9007199254740992') + // Check the group with MAX_SAFE_BIGINT + 1n const group2 = Array.from(districtSummary.values()).find( - (d) => d.district_id === BigInt('9007199254740992'), + (d) => d.district_id === MAX_SAFE_BIGINT + 1n, ) expect(group2).toBeDefined() expect(group2?.count).toBe(1) // District 2 - // Check the group with BigInt('9007199254740993') + // Check the group with MAX_SAFE_BIGINT + 2n const group3 = Array.from(districtSummary.values()).find( - (d) => d.district_id === BigInt('9007199254740993'), + (d) => d.district_id === MAX_SAFE_BIGINT + 2n, ) expect(group3).toBeDefined() expect(group3?.count).toBe(1) // District 4 @@ -1380,22 +1383,25 @@ function createGroupByTests(autoIndex: `off` | `eager`): void { status: string } + // Use BigInt values beyond MAX_SAFE_INTEGER to test BigInt serialization + const MAX_SAFE_BIGINT = BigInt(Number.MAX_SAFE_INTEGER + 1) + const sampleSchools: Array = [ { id: 1, - district_id: BigInt('9007199254740991'), + district_id: MAX_SAFE_BIGINT, name: 'School A', status: 'active', }, { id: 2, - district_id: BigInt('9007199254740991'), + district_id: MAX_SAFE_BIGINT, name: 'School B', status: 'active', }, { id: 3, - district_id: BigInt('9007199254740992'), + district_id: MAX_SAFE_BIGINT + 1n, name: 'School C', status: 'inactive', }, @@ -1426,19 +1432,19 @@ function createGroupByTests(autoIndex: `off` | `eager`): void { expect(schoolSummary.size).toBe(2) // Two distinct combinations - // Find the group with BigInt('9007199254740991') and 'active' + // Find the group with MAX_SAFE_BIGINT and 'active' const group1 = Array.from(schoolSummary.values()).find( (s) => - s.district_id === BigInt('9007199254740991') && + s.district_id === MAX_SAFE_BIGINT && s.status === 'active', ) expect(group1).toBeDefined() expect(group1?.count).toBe(2) // Schools 1 and 2 - // Find the group with BigInt('9007199254740992') and 'inactive' + // Find the group with MAX_SAFE_BIGINT + 1n and 'inactive' const group2 = Array.from(schoolSummary.values()).find( (s) => - s.district_id === BigInt('9007199254740992') && + s.district_id === MAX_SAFE_BIGINT + 1n && s.status === 'inactive', ) expect(group2).toBeDefined() From d763ef3273e05088cb5aedc1720bdbacefdbfde8 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Tue, 6 Jan 2026 09:28:52 +0000 Subject: [PATCH 7/7] ci: apply automated fixes --- packages/db/tests/query/group-by.test.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/db/tests/query/group-by.test.ts b/packages/db/tests/query/group-by.test.ts index 89055585f..0785e8a8c 100644 --- a/packages/db/tests/query/group-by.test.ts +++ b/packages/db/tests/query/group-by.test.ts @@ -1434,9 +1434,7 @@ function createGroupByTests(autoIndex: `off` | `eager`): void { // Find the group with MAX_SAFE_BIGINT and 'active' const group1 = Array.from(schoolSummary.values()).find( - (s) => - s.district_id === MAX_SAFE_BIGINT && - s.status === 'active', + (s) => s.district_id === MAX_SAFE_BIGINT && s.status === 'active', ) expect(group1).toBeDefined() expect(group1?.count).toBe(2) // Schools 1 and 2 @@ -1444,8 +1442,7 @@ function createGroupByTests(autoIndex: `off` | `eager`): void { // Find the group with MAX_SAFE_BIGINT + 1n and 'inactive' const group2 = Array.from(schoolSummary.values()).find( (s) => - s.district_id === MAX_SAFE_BIGINT + 1n && - s.status === 'inactive', + s.district_id === MAX_SAFE_BIGINT + 1n && s.status === 'inactive', ) expect(group2).toBeDefined() expect(group2?.count).toBe(1) // School 3