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.
- package/lib/packets/packet.js +23 -6
- package/package.json +1 -1
package/lib/packets/packet.js
CHANGED
|
@@ -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
|
-
|
|
685
|
-
|
|
686
|
-
|
|
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