From fa9006221d81cea21887863be186433d0154e84d Mon Sep 17 00:00:00 2001 From: Kenny Daniel Date: Sat, 19 Apr 2025 00:32:08 -0700 Subject: [PATCH] Fix statistics writing for dates and decimals --- package.json | 2 +- src/unconvert.js | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 180938f..b574025 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "@babel/eslint-parser": "7.27.0", "@types/node": "22.14.1", "@vitest/coverage-v8": "3.1.1", - "eslint": "9.24.0", + "eslint": "9.25.0", "eslint-plugin-jsdoc": "50.6.9", "typescript": "5.8.3", "vitest": "3.1.1" diff --git a/src/unconvert.js b/src/unconvert.js index 16844e5..509cd64 100644 --- a/src/unconvert.js +++ b/src/unconvert.js @@ -11,8 +11,7 @@ const dayMillis = 86400000 // 1 day in milliseconds export function unconvert(element, values) { const ctype = element.converted_type if (ctype === 'DECIMAL') { - const scale = element.scale || 0 - const factor = 10 ** scale + const factor = 10 ** (element.scale || 0) return values.map(v => { if (v === null || v === undefined) return v if (typeof v !== 'number') throw new Error('DECIMAL must be a number') @@ -52,6 +51,22 @@ export function unconvertMinMax(value, element) { if (value === undefined || value === null) return undefined const { type, converted_type } = element if (type === 'BOOLEAN') return new Uint8Array([value ? 1 : 0]) + if (converted_type === 'DECIMAL') { + if (typeof value !== 'number') throw new Error('DECIMAL must be a number') + const factor = 10 ** (element.scale || 0) + const out = unconvertDecimal(element, BigInt(Math.round(value * factor))) + if (out instanceof Uint8Array) return out + if (typeof out === 'number') { + const buffer = new ArrayBuffer(4) + new DataView(buffer).setFloat32(0, out, true) + return new Uint8Array(buffer) + } + if (typeof out === 'bigint') { + const buffer = new ArrayBuffer(8) + new DataView(buffer).setBigInt64(0, out, true) + return new Uint8Array(buffer) + } + } if (type === 'BYTE_ARRAY' || type === 'FIXED_LEN_BYTE_ARRAY') { // truncate byte arrays to 16 bytes for statistics if (value instanceof Uint8Array) return value.slice(0, 16) @@ -78,7 +93,7 @@ export function unconvertMinMax(value, element) { return new Uint8Array(buffer) } if (type === 'INT32' && converted_type === 'DATE' && value instanceof Date) { - const buffer = new ArrayBuffer(8) + const buffer = new ArrayBuffer(4) new DataView(buffer).setInt32(0, Math.floor(value.getTime() / dayMillis), true) return new Uint8Array(buffer) }