Precision or encoding error storing JS numbers in MySQL DOUBLE
See original GitHub issueThis bug is unique to the mysql2 npm package - it does not happen with the mysql npm package.
I have a db schema which declares a column as a DOUBLE; mysql docs say this is an eight byte floating point number, presumably a 64-bit IEEE 754 quantity. JS uses, by definition, IEEE 754-2019 numbers.
When I store certain values in my database and select them back out, I sometimes get different numbers. Once such example is 0.45494253843119004
, which gets stored correctly, but selected back out as 0.4549425384311901
.
My platform is mysql2@2.3.3, node v12.22.9 on Linux wes-linux-kds 5.4.0-94-generic #106~18.04.1-Ubuntu SMP Fri Jan 7 07:23:53 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux.
We have an ORM in the way, so I haven’t written a minimal test case yet. If the team wants to follow up on this bug, I can produce one. If you want help fixing the issue, point me in the right direction…I am a C and JS programmer with some experience with the mysql and v8 APIs.
This is a complete record of statements executed in our internal test case:
SET NAMES utf8mb4;
SET autocommit=1;
select @@wait_timeout;
START TRANSACTION;
INSERT INTO jobs (status,lastUpdate,maxSlicesPerTask,duplicationLevel) VALUES (?,?,?,?); [ 'map-test-1646070071709', 1646070071710, 1, 0.45494253843119004 ]
SELECT LAST_INSERT_ID() as id, FOUND_ROWS() as found, ROW_COUNT() as count
SELECT SQL_CALC_FOUND_ROWS id, address, uuid, status, startTime, endTime, lastUpdate, owner, paymentAccount, lastSliceNumber, nextSliceNumber, maxSlicesPerTask, absoluteSlicePayment, mvMultSlicePayment, duplicationLevel, duplicationType, flags, dataStorageType, dataStorageDetails, resultStorageType, resultStorageDetails, resultStorageParams, requirements, description, link, name FROM jobs WHERE status LIKE 'map-test-%' AND id>=14659 FOR UPDATE
The callback invoked from mysql2/lib/commands/query.js:86:15
received the following arguments – the fields object has the wrong value in it:
console.log(results)
[
{
id: '14660',
address: null,
uuid: null,
status: 'map-test-1646071286462',
startTime: null,
endTime: null,
lastUpdate: '1646071286463',
owner: null,
paymentAccount: null,
lastSliceNumber: null,
nextSliceNumber: null,
maxSlicesPerTask: 1,
absoluteSlicePayment: null,
mvMultSlicePayment: null,
duplicationLevel: 0.4549425384311901,
duplicationType: null,
flags: null,
dataStorageType: null,
dataStorageDetails: null,
resultStorageType: null,
resultStorageDetails: null,
resultStorageParams: null,
requirements: null,
description: null,
link: null,
name: null
}
]
undefined
console.log(fields)
[
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 10,
_schemaLength: 24,
_schemaStart: 14,
_tableLength: 4,
_tableStart: 39,
_orgTableLength: 4,
_orgTableStart: 44,
_orgNameLength: 2,
_orgNameStart: 52,
characterSet: 63,
encoding: 'binary',
name: 'id',
columnLength: 20,
columnType: 8,
flags: 16899,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 72,
_schemaLength: 24,
_schemaStart: 76,
_tableLength: 4,
_tableStart: 101,
_orgTableLength: 4,
_orgTableStart: 106,
_orgNameLength: 7,
_orgNameStart: 119,
characterSet: 45,
encoding: 'utf8',
name: 'address',
columnLength: 160,
columnType: 254,
flags: 16516,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 144,
_schemaLength: 24,
_schemaStart: 148,
_tableLength: 4,
_tableStart: 173,
_orgTableLength: 4,
_orgTableStart: 178,
_orgNameLength: 4,
_orgNameStart: 188,
characterSet: 45,
encoding: 'utf8',
name: 'uuid',
columnLength: 1020,
columnType: 253,
flags: 128,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 210,
_schemaLength: 24,
_schemaStart: 214,
_tableLength: 4,
_tableStart: 239,
_orgTableLength: 4,
_orgTableStart: 244,
_orgNameLength: 6,
_orgNameStart: 256,
characterSet: 45,
encoding: 'utf8',
name: 'status',
columnLength: 1020,
columnType: 253,
flags: 128,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 280,
_schemaLength: 24,
_schemaStart: 284,
_tableLength: 4,
_tableStart: 309,
_orgTableLength: 4,
_orgTableStart: 314,
_orgNameLength: 9,
_orgNameStart: 329,
characterSet: 63,
encoding: 'binary',
name: 'startTime',
columnLength: 20,
columnType: 8,
flags: 0,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 356,
_schemaLength: 24,
_schemaStart: 360,
_tableLength: 4,
_tableStart: 385,
_orgTableLength: 4,
_orgTableStart: 390,
_orgNameLength: 7,
_orgNameStart: 403,
characterSet: 63,
encoding: 'binary',
name: 'endTime',
columnLength: 20,
columnType: 8,
flags: 0,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 428,
_schemaLength: 24,
_schemaStart: 432,
_tableLength: 4,
_tableStart: 457,
_orgTableLength: 4,
_orgTableStart: 462,
_orgNameLength: 10,
_orgNameStart: 478,
characterSet: 63,
encoding: 'binary',
name: 'lastUpdate',
columnLength: 20,
columnType: 8,
flags: 4097,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 506,
_schemaLength: 24,
_schemaStart: 510,
_tableLength: 4,
_tableStart: 535,
_orgTableLength: 4,
_orgTableStart: 540,
_orgNameLength: 5,
_orgNameStart: 551,
characterSet: 45,
encoding: 'utf8',
name: 'owner',
columnLength: 160,
columnType: 254,
flags: 128,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 574,
_schemaLength: 24,
_schemaStart: 578,
_tableLength: 4,
_tableStart: 603,
_orgTableLength: 4,
_orgTableStart: 608,
_orgNameLength: 14,
_orgNameStart: 628,
characterSet: 45,
encoding: 'utf8',
name: 'paymentAccount',
columnLength: 160,
columnType: 254,
flags: 128,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 660,
_schemaLength: 24,
_schemaStart: 664,
_tableLength: 4,
_tableStart: 689,
_orgTableLength: 4,
_orgTableStart: 694,
_orgNameLength: 15,
_orgNameStart: 715,
characterSet: 63,
encoding: 'binary',
name: 'lastSliceNumber',
columnLength: 20,
columnType: 8,
flags: 0,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 748,
_schemaLength: 24,
_schemaStart: 752,
_tableLength: 4,
_tableStart: 777,
_orgTableLength: 4,
_orgTableStart: 782,
_orgNameLength: 15,
_orgNameStart: 803,
characterSet: 63,
encoding: 'binary',
name: 'nextSliceNumber',
columnLength: 20,
columnType: 8,
flags: 0,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 836,
_schemaLength: 24,
_schemaStart: 840,
_tableLength: 4,
_tableStart: 865,
_orgTableLength: 4,
_orgTableStart: 870,
_orgNameLength: 16,
_orgNameStart: 892,
characterSet: 63,
encoding: 'binary',
name: 'maxSlicesPerTask',
columnLength: 11,
columnType: 3,
flags: 0,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 926,
_schemaLength: 24,
_schemaStart: 930,
_tableLength: 4,
_tableStart: 955,
_orgTableLength: 4,
_orgTableStart: 960,
_orgNameLength: 20,
_orgNameStart: 986,
characterSet: 63,
encoding: 'binary',
name: 'absoluteSlicePayment',
columnLength: 33,
columnType: 246,
flags: 0,
decimals: 18
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 1024,
_schemaLength: 24,
_schemaStart: 1028,
_tableLength: 4,
_tableStart: 1053,
_orgTableLength: 4,
_orgTableStart: 1058,
_orgNameLength: 18,
_orgNameStart: 1082,
characterSet: 63,
encoding: 'binary',
name: 'mvMultSlicePayment',
columnLength: 33,
columnType: 246,
flags: 0,
decimals: 18
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 1118,
_schemaLength: 24,
_schemaStart: 1122,
_tableLength: 4,
_tableStart: 1147,
_orgTableLength: 4,
_orgTableStart: 1152,
_orgNameLength: 16,
_orgNameStart: 1174,
characterSet: 63,
encoding: 'binary',
name: 'duplicationLevel',
columnLength: 22,
columnType: 5,
flags: 0,
decimals: 31
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 1208,
_schemaLength: 24,
_schemaStart: 1212,
_tableLength: 4,
_tableStart: 1237,
_orgTableLength: 4,
_orgTableStart: 1242,
_orgNameLength: 15,
_orgNameStart: 1263,
characterSet: 45,
encoding: 'utf8',
name: 'duplicationType',
columnLength: 1020,
columnType: 253,
flags: 128,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 1296,
_schemaLength: 24,
_schemaStart: 1300,
_tableLength: 4,
_tableStart: 1325,
_orgTableLength: 4,
_orgTableStart: 1330,
_orgNameLength: 5,
_orgNameStart: 1341,
characterSet: 63,
encoding: 'binary',
name: 'flags',
columnLength: 10,
columnType: 3,
flags: 32,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 1364,
_schemaLength: 24,
_schemaStart: 1368,
_tableLength: 4,
_tableStart: 1393,
_orgTableLength: 4,
_orgTableStart: 1398,
_orgNameLength: 15,
_orgNameStart: 1419,
characterSet: 45,
encoding: 'utf8',
name: 'dataStorageType',
columnLength: 1020,
columnType: 253,
flags: 128,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 1452,
_schemaLength: 24,
_schemaStart: 1456,
_tableLength: 4,
_tableStart: 1481,
_orgTableLength: 4,
_orgTableStart: 1486,
_orgNameLength: 18,
_orgNameStart: 1510,
characterSet: 45,
encoding: 'utf8',
name: 'dataStorageDetails',
columnLength: 262140,
columnType: 252,
flags: 144,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 1546,
_schemaLength: 24,
_schemaStart: 1550,
_tableLength: 4,
_tableStart: 1575,
_orgTableLength: 4,
_orgTableStart: 1580,
_orgNameLength: 17,
_orgNameStart: 1603,
characterSet: 45,
encoding: 'utf8',
name: 'resultStorageType',
columnLength: 1020,
columnType: 253,
flags: 128,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 1638,
_schemaLength: 24,
_schemaStart: 1642,
_tableLength: 4,
_tableStart: 1667,
_orgTableLength: 4,
_orgTableStart: 1672,
_orgNameLength: 20,
_orgNameStart: 1698,
characterSet: 45,
encoding: 'utf8',
name: 'resultStorageDetails',
columnLength: 262140,
columnType: 252,
flags: 144,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 1736,
_schemaLength: 24,
_schemaStart: 1740,
_tableLength: 4,
_tableStart: 1765,
_orgTableLength: 4,
_orgTableStart: 1770,
_orgNameLength: 19,
_orgNameStart: 1795,
characterSet: 45,
encoding: 'utf8',
name: 'resultStorageParams',
columnLength: 4294967295,
columnType: 252,
flags: 144,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 1832,
_schemaLength: 24,
_schemaStart: 1836,
_tableLength: 4,
_tableStart: 1861,
_orgTableLength: 4,
_orgTableStart: 1866,
_orgNameLength: 12,
_orgNameStart: 1884,
characterSet: 45,
encoding: 'utf8',
name: 'requirements',
columnLength: 4294967295,
columnType: 252,
flags: 144,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 1914,
_schemaLength: 24,
_schemaStart: 1918,
_tableLength: 4,
_tableStart: 1943,
_orgTableLength: 4,
_orgTableStart: 1948,
_orgNameLength: 11,
_orgNameStart: 1965,
characterSet: 45,
encoding: 'utf8',
name: 'description',
columnLength: 1020,
columnType: 253,
flags: 128,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 1994,
_schemaLength: 24,
_schemaStart: 1998,
_tableLength: 4,
_tableStart: 2023,
_orgTableLength: 4,
_orgTableStart: 2028,
_orgNameLength: 4,
_orgNameStart: 2038,
characterSet: 45,
encoding: 'utf8',
name: 'link',
columnLength: 1020,
columnType: 253,
flags: 128,
decimals: 0
},
ColumnDefinition {
_buf: <Buffer 01 00 00 01 1a 3a 00 00 02 03 64 65 66 18 64 63 70 5f 73 63 68 65 64 5f 64 62 5f 31 30 39 30 30 5f 32 37 38 39 32 04 6a 6f 62 73 04 6a 6f 62 73 02 69 ... 2179 more bytes>,
_clientEncoding: 'utf8',
_catalogLength: 3,
_catalogStart: 2060,
_schemaLength: 24,
_schemaStart: 2064,
_tableLength: 4,
_tableStart: 2089,
_orgTableLength: 4,
_orgTableStart: 2094,
_orgNameLength: 4,
_orgNameStart: 2104,
characterSet: 45,
encoding: 'utf8',
name: 'name',
columnLength: 1020,
columnType: 253,
flags: 128,
decimals: 0
}
]
Schema –
+----------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+------------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| address | char(40) | YES | UNI | NULL | |
| uuid | varchar(255) | YES | | NULL | |
| status | varchar(255) | YES | | NULL | |
| startTime | bigint(20) | YES | | NULL | |
| endTime | bigint(20) | YES | | NULL | |
| lastUpdate | bigint(20) | NO | | NULL | |
| owner | char(40) | YES | | NULL | |
| paymentAccount | char(40) | YES | | NULL | |
| lastSliceNumber | bigint(20) | YES | | NULL | |
| nextSliceNumber | bigint(20) | YES | | NULL | |
| maxSlicesPerTask | int(11) | YES | | NULL | |
| absoluteSlicePayment | decimal(31,18) | YES | | NULL | |
| mvMultSlicePayment | decimal(31,18) | YES | | NULL | |
| duplicationLevel | double | YES | | NULL | |
| duplicationType | varchar(255) | YES | | NULL | |
| flags | int(10) unsigned | YES | | NULL | |
| dataStorageType | varchar(255) | YES | | NULL | |
| dataStorageDetails | text | YES | | NULL | |
| resultStorageType | varchar(255) | YES | | NULL | |
| resultStorageDetails | text | YES | | NULL | |
| resultStorageParams | longtext | YES | | NULL | |
| requirements | longtext | YES | | NULL | |
| description | varchar(255) | YES | | NULL | |
| link | varchar(255) | YES | | NULL | |
| name | varchar(255) | YES | | NULL | |
+----------------------+------------------+------+-----+---------+----------------+
26 rows in set (0.00 sec)
Issue Analytics
- State:
- Created 2 years ago
- Comments:24 (9 by maintainers)
My personal recommendation: if you don’t do math with numbers ( ids etc ) - always store them as strings. Many other potential difficult to debug rounding problems, for example built in JSON.stringify / JSON.parse would corrupt data if
375418676418970374
number is serializedStill, what @wesgarland described here is a legitimate bug and I’d really like to fix it ideally without big performance hit
@sidorares re “
built in JSON.stringify / JSON.parse would corrupt data if 375418676418970374 number is serialized
” – this is not corruption. What’s happening is that there is no number named 375418676418970374 in JavaScript. It simply does not exist. It is not part of the IEEE-754 number line. Just like there is no 1.7 in the set of Integers.So, when you ask JS to parse the string 375418676418970374 into a number, it selects the nearest* number and stores that as a number. That nearest* number is 375418676418970400.
The same thing happens in every other programming language, and in mysql itself, when using floating point numbers. However, when you ask it to store a number which DOES exist in the number IEEE-754 line – for example, 375418676418970400 – that exact number is stored, and when you ask mysql to retrieve it, it retrieves exactly that number.
The bug that is described in this issue is that when retrieving exact IEEE-754 numbers which do exist and are stored correctly, the mysql2
parseFloat
functionality does not correctly parse the wireline representation (which is, inexplicably, a decimal string) into a JS double, due errors in the parsing algorithm.*nearest
- it’s a little more complex than just the nearest number, there are statistical rules in place so that rounding errors over multiple computations have minimal aggregate effects