mysql2 3.18.2 → 3.18.3-canary.099beeae

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -660,14 +660,27 @@ class Packet {
660
660
  if (len === null) {
661
661
  return null;
662
662
  }
663
+ if (len === 0) {
664
+ return 0; // TODO: assert? exception?
665
+ }
666
+
667
+ // For numbers with many digits (>17), use built-in parseFloat to avoid
668
+ // precision loss from accumulated rounding errors in repeated *10 operations.
669
+ // This fixes issues #2928 (MAX_VALUE doubles) and #3690 (DECIMAL(36,18))
670
+ // where very large numbers or numbers with many fractional digits lose precision.
671
+ // The threshold of 17 is based on IEEE 754 double precision (~15-17 significant digits).
672
+ // Testing shows minimal performance impact as most real-world numbers are shorter.
673
+ if (len > 17) {
674
+ const str = this.buffer.toString('utf8', this.offset, this.offset + len);
675
+ this.offset += len;
676
+ return Number.parseFloat(str);
677
+ }
678
+
663
679
  let result = 0;
664
680
  const end = this.offset + len;
665
681
  let factor = 1;
666
682
  let pastDot = false;
667
683
  let charCode = 0;
668
- if (len === 0) {
669
- return 0; // TODO: assert? exception?
670
- }
671
684
  if (this.buffer[this.offset] === minus) {
672
685
  this.offset++;
673
686
  factor = -1;
@@ -681,9 +694,13 @@ class Packet {
681
694
  pastDot = true;
682
695
  this.offset++;
683
696
  } else if (charCode === exponent || charCode === exponentCapital) {
684
- this.offset++;
685
- const exponentValue = this.parseInt(end - this.offset);
686
- return (result / factor) * Math.pow(10, exponentValue);
697
+ // Scientific notation detected - bail out to parseFloat for exact match.
698
+ // Manual calculation with Math.pow(10, exp) cannot match parseFloat()
699
+ // exactly for most non-zero exponents due to accumulated rounding errors.
700
+ const start = end - len;
701
+ const str = this.buffer.toString('utf8', start, end);
702
+ this.offset = end;
703
+ return Number.parseFloat(str);
687
704
  } else {
688
705
  result *= 10;
689
706
  result += this.buffer[this.offset] - 48;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mysql2",
3
- "version": "3.18.2",
3
+ "version": "3.18.3-canary.099beeae",
4
4
  "description": "fast mysql driver. Implements core protocol, prepared statements, ssl and compression in native JS",
5
5
  "main": "index.js",
6
6
  "typings": "typings/mysql/index",