question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Precision or encoding error storing JS numbers in MySQL DOUBLE

See original GitHub issue

This 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:open
  • Created 2 years ago
  • Comments:24 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
sidorarescommented, Apr 19, 2022

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 serialized

Still, what @wesgarland described here is a legitimate bug and I’d really like to fix it ideally without big performance hit

0reactions
wesgarlandcommented, Jun 22, 2022

@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

Read more comments on GitHub >

github_iconTop Results From Across the Web

2 Server Error Message Reference - MySQL :: Developer Zone
Occurs for failure to create or copy a file needed for some operation. Possible causes: Permissions problem for source file; destination file already...
Read more >
B.3.4.8 Problems with Floating-Point Values
Floating-point numbers sometimes cause confusion because they are approximate and not stored as exact values. A floating-point value as written in an SQL ......
Read more >
MySQL 8.0 Reference Manual :: 11.5 The JSON Data Type
In MySQL, JSON values are written as strings. MySQL parses any string used in a context that requires a JSON value, and produces...
Read more >
12.11 Cast Functions and Operators - MySQL :: Developer Zone
Produces a DECIMAL value. If the optional M and D values are given, they specify the maximum number of digits (the precision) and...
Read more >
12.14 Encryption and Compression Functions
The size penalty for storing the hex string in a CHAR column is at least two times, up to eight times if the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found