Skip to content

Commit a100dc3

Browse files
committed
feat: enable eq comparison for date and add a tests.
1 parent 50c4dd9 commit a100dc3

File tree

2 files changed

+47
-8
lines changed

2 files changed

+47
-8
lines changed

packages/db/src/indexes/btree-index.ts

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@ import { BaseIndex } from "./base-index.js"
44
import type { BasicExpression } from "../query/ir.js"
55
import type { IndexOperation } from "./base-index.js"
66

7+
/**
8+
* Normalizes values for use as Map keys to ensure proper equality comparison
9+
* For Date objects, uses timestamp. For other objects, uses JSON serialization.
10+
*/
11+
function normalizeMapKey(value: any): any {
12+
if (value instanceof Date) {
13+
return value.getTime()
14+
}
15+
if (typeof value === `object` && value !== null) {
16+
// For other objects, use JSON serialization as a fallback
17+
// This ensures objects with same content are treated as equal
18+
return JSON.stringify(value)
19+
}
20+
return value
21+
}
722
/**
823
* Options for Ordered index
924
*/
@@ -71,14 +86,17 @@ export class BTreeIndex<
7186
)
7287
}
7388

89+
// Normalize the value for Map key usage
90+
const normalizedValue = normalizeMapKey(indexedValue)
91+
7492
// Check if this value already exists
75-
if (this.valueMap.has(indexedValue)) {
93+
if (this.valueMap.has(normalizedValue)) {
7694
// Add to existing set
77-
this.valueMap.get(indexedValue)!.add(key)
95+
this.valueMap.get(normalizedValue)!.add(key)
7896
} else {
7997
// Create new set for this value
8098
const keySet = new Set<TKey>([key])
81-
this.valueMap.set(indexedValue, keySet)
99+
this.valueMap.set(normalizedValue, keySet)
82100
this.orderedEntries.set(indexedValue, undefined)
83101
}
84102

@@ -101,13 +119,16 @@ export class BTreeIndex<
101119
return
102120
}
103121

104-
if (this.valueMap.has(indexedValue)) {
105-
const keySet = this.valueMap.get(indexedValue)!
122+
// Normalize the value for Map key usage
123+
const normalizedValue = normalizeMapKey(indexedValue)
124+
125+
if (this.valueMap.has(normalizedValue)) {
126+
const keySet = this.valueMap.get(normalizedValue)!
106127
keySet.delete(key)
107128

108129
// If set is now empty, remove the entry entirely
109130
if (keySet.size === 0) {
110-
this.valueMap.delete(indexedValue)
131+
this.valueMap.delete(normalizedValue)
111132

112133
// Remove from ordered entries
113134
this.orderedEntries.delete(indexedValue)
@@ -195,7 +216,8 @@ export class BTreeIndex<
195216
* Performs an equality lookup
196217
*/
197218
equalityLookup(value: any): Set<TKey> {
198-
return new Set(this.valueMap.get(value) ?? [])
219+
const normalizedValue = normalizeMapKey(value)
220+
return new Set(this.valueMap.get(normalizedValue) ?? [])
199221
}
200222

201223
/**
@@ -266,7 +288,8 @@ export class BTreeIndex<
266288
const result = new Set<TKey>()
267289

268290
for (const value of values) {
269-
const keys = this.valueMap.get(value)
291+
const normalizedValue = normalizeMapKey(value)
292+
const keys = this.valueMap.get(normalizedValue)
270293
if (keys) {
271294
keys.forEach((key) => result.add(key))
272295
}

packages/db/tests/query/where.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,22 @@ function createWhereTests(autoIndex: `off` | `eager`): void {
139139
})
140140

141141
test(`eq operator - equality comparison`, () => {
142+
const hireDateEmployee = createLiveQueryCollection({
143+
startSync: true,
144+
query: (q) =>
145+
q
146+
.from({ emp: employeesCollection })
147+
.where(({ emp }) =>
148+
eq(emp.hire_date_instance, new Date(`2020-01-15`))
149+
)
150+
.select(({ emp }) => ({
151+
id: emp.id,
152+
name: emp.name,
153+
active: emp.active,
154+
})),
155+
})
156+
expect(hireDateEmployee.size).toBe(2)
157+
142158
const activeEmployees = createLiveQueryCollection({
143159
startSync: true,
144160
query: (q) =>

0 commit comments

Comments
 (0)