Skip to content

Commit fc0c438

Browse files
committed
fix(dynamodb): treat a number as exact only when its string form round-trips
A decimal like 1.0000000000000000001 parses to a safe integer, so the safe-integer shortcut dropped its digits. Return a JS number only when String(parsed) equals the DynamoDB value (and it is not an unsafe integer); item output is unchanged.
1 parent 7e17913 commit fc0c438

2 files changed

Lines changed: 5 additions & 4 deletions

File tree

‎apps/sim/lib/internal/dynamodb/client.test.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ describe('DynamoDB item unmarshalling', () => {
8181
bin: { B: new Uint8Array([104, 105]) },
8282
age: { N: '42' },
8383
ratio: { N: '0.12345678901234567890123' },
84+
nearOne: { N: '1.0000000000000000001' },
8485
},
8586
})
8687
const firstPage = await queryItems(pageClient, 'Users', 'pk = :pk', {
@@ -93,6 +94,7 @@ describe('DynamoDB item unmarshalling', () => {
9394
bin: { B: 'aGk=' },
9495
age: 42,
9596
ratio: { N: '0.12345678901234567890123' },
97+
nearOne: { N: '1.0000000000000000001' },
9698
})
9799

98100
let sentStartKey: unknown
@@ -110,6 +112,7 @@ describe('DynamoDB item unmarshalling', () => {
110112
bin: { B: new Uint8Array([104, 105]) },
111113
age: { N: '42' },
112114
ratio: { N: '0.12345678901234567890123' },
115+
nearOne: { N: '1.0000000000000000001' },
113116
})
114117
pageClient.destroy()
115118
client.destroy()

‎apps/sim/lib/internal/dynamodb/client.ts‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,8 @@ type DynamoDBReturnValues = 'NONE' | 'ALL_OLD' | 'UPDATED_OLD' | 'ALL_NEW' | 'UP
2323
*/
2424
function unwrapNumber(value: string): number | NumberValue {
2525
const parsed = Number(value)
26-
if (Number.isSafeInteger(parsed)) return parsed
27-
if (Number.isFinite(parsed) && !Number.isInteger(parsed) && String(parsed) === value) {
28-
return parsed
29-
}
26+
const exact = Number.isFinite(parsed) && String(parsed) === value
27+
if (exact && (!Number.isInteger(parsed) || Number.isSafeInteger(parsed))) return parsed
3028
return NumberValue.from(value)
3129
}
3230

0 commit comments

Comments
 (0)