From 8f88f9db129a9c8750a7603511676fb1cb573bdc Mon Sep 17 00:00:00 2001 From: rusher Date: Mon, 18 Mar 2024 15:32:05 +0100 Subject: [PATCH] [CONJS-285] DECIMAL field wrong decoding with deprecated option 'supportBigNumbers' set --- lib/cmd/decoder/binary-decoder.js | 12 ++++++++---- lib/cmd/decoder/text-decoder.js | 12 ++++++++---- test/integration/datatype/test-integer.js | 24 ++++++++++++++++++++--- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/lib/cmd/decoder/binary-decoder.js b/lib/cmd/decoder/binary-decoder.js index 5b73d41d..ea1c1ec1 100644 --- a/lib/cmd/decoder/binary-decoder.js +++ b/lib/cmd/decoder/binary-decoder.js @@ -227,7 +227,7 @@ const readDecimalAsIntBinary = (packet, opts, throwUnexpectedError, nullBitmap, ); } if (opts.supportBigNumbers && (opts.bigNumberStrings || !Number.isSafeInteger(Number(valDec)))) { - return valDec.toString(); + return valDec; } return Number(valDec); } @@ -237,10 +237,14 @@ const readDecimalBinary = (packet, opts, throwUnexpectedError, nullBitmap, index if (isNullBitmap(index, nullBitmap)) return null; const valDec = packet.readDecimalLengthEncoded(); if (valDec != null && (opts.decimalAsNumber || opts.supportBigNumbers)) { - if (opts.supportBigNumbers && (opts.bigNumberStrings || !Number.isSafeInteger(Number(valDec)))) { - return valDec.toString(); + const numberValue = Number(valDec); + if ( + opts.supportBigNumbers && + (opts.bigNumberStrings || (Number.isInteger(numberValue) && !Number.isSafeInteger(numberValue))) + ) { + return valDec; } - return Number(valDec); + return numberValue; } return valDec; }; diff --git a/lib/cmd/decoder/text-decoder.js b/lib/cmd/decoder/text-decoder.js index 2b1c777c..dd3d77d5 100644 --- a/lib/cmd/decoder/text-decoder.js +++ b/lib/cmd/decoder/text-decoder.js @@ -143,7 +143,7 @@ const readDecimalAsIntLengthCoded = (packet, opts, throwUnexpectedError) => { ); } if (opts.supportBigNumbers && (opts.bigNumberStrings || !Number.isSafeInteger(Number(valDec)))) { - return valDec.toString(); + return valDec; } return Number(valDec); } @@ -152,10 +152,14 @@ const readDecimalAsIntLengthCoded = (packet, opts, throwUnexpectedError) => { const readDecimalLengthCoded = (packet, opts, throwUnexpectedError) => { const valDec = packet.readDecimalLengthEncoded(); if (valDec != null && (opts.decimalAsNumber || opts.supportBigNumbers)) { - if (opts.supportBigNumbers && (opts.bigNumberStrings || !Number.isSafeInteger(Number(valDec)))) { - return valDec.toString(); + const numberValue = Number(valDec); + if ( + opts.supportBigNumbers && + (opts.bigNumberStrings || (Number.isInteger(numberValue) && !Number.isSafeInteger(numberValue))) + ) { + return valDec; } - return Number(valDec); + return numberValue; } return valDec; }; diff --git a/test/integration/datatype/test-integer.js b/test/integration/datatype/test-integer.js index d174a310..652eaf2a 100644 --- a/test/integration/datatype/test-integer.js +++ b/test/integration/datatype/test-integer.js @@ -22,7 +22,7 @@ describe('integer with big value', () => { after(async () => { await shareConn.query('DROP TABLE IF EXISTS testBigint'); await shareConn.query('DROP TABLE IF EXISTS testInt'); - await shareConn.query('DROP TABLE IF EXISTS floatTest'); + // await shareConn.query('DROP TABLE IF EXISTS floatTest'); await shareConn.query('DROP TABLE IF EXISTS floatTestUnsigned'); }); @@ -77,6 +77,24 @@ describe('integer with big value', () => { rows = await shareConn.execute({ sql: 'SELECT * FROM floatTest', decimalAsNumber: true }); assert.deepEqual(rows, expectedNumber); + const expectedNumberConvert = [ + { + t: -0.1, + t2: 128.3, + t3: 129 + }, + { + t: -0.9999237060546875, + t2: '9999237060546875.9999237060546875', + t3: '9999237060546875' + } + ]; + rows = await shareConn.query({ sql: 'SELECT * FROM floatTest', decimalAsNumber: true, supportBigNumbers: true }); + assert.deepEqual(rows, expectedNumberConvert); + + rows = await shareConn.execute({ sql: 'SELECT * FROM floatTest', decimalAsNumber: true, supportBigNumbers: true }); + assert.deepEqual(rows, expectedNumberConvert); + try { await shareConn.query({ sql: 'SELECT * FROM floatTest', decimalAsNumber: true, checkNumberRange: true }); throw new Error('Expected to have failed'); @@ -94,7 +112,7 @@ describe('integer with big value', () => { const expectedBigNumber = [ { t: -0.1, - t2: '128.3000000000000000', + t2: 128.3, t3: 129 }, { t: -0.9999237060546875, t2: '9999237060546875.9999237060546875', t3: '9999237060546875' } @@ -181,7 +199,7 @@ describe('integer with big value', () => { const expectedBigNumber = [ { t: 0.1, - t2: '128.3000000000000000', + t2: 128.3, t3: 129 }, { t: 0.9999237060546875, t2: '9999237060546875.9999237060546875', t3: '9999237060546875' }