{"record":{"id":"5873f2ac591a68b4","repo":"vitessio/vitess","slug":"overflow","errorCode":null,"errorMessage":"overflow","messagePattern":"overflow","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/mysql/decimal/scan.go","lineNumber":31,"sourceCode":"See the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage decimal\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"math/big\"\n\t\"math/bits\"\n\t\"strings\"\n\n\t\"vitess.io/vitess/go/mysql/fastparse\"\n)\n\nvar errOverflow = errors.New(\"overflow\")\n\nfunc parseDecimal64(s []byte) (Decimal, error) {\n\tconst cutoff = math.MaxUint64/10 + 1\n\tvar n uint64\n\tdot := -1\n\n\tfor i, c := range s {\n\t\tvar d byte\n\t\tswitch {\n\t\tcase c == '.':\n\t\t\tif dot > -1 {\n\t\t\t\treturn Decimal{}, errors.New(\"too many .s\")\n\t\t\t}\n\t\t\tdot = i\n\t\t\tcontinue\n\t\tcase '0' <= c && c <= '9':\n\t\t\td = c - '0'\n\t\tdefault:","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/mysql/decimal/scan.go#L13-L49","documentation":"errOverflow is a sentinel error in go/mysql/decimal returned by parseDecimal64 when the digits being accumulated into a uint64 would exceed math.MaxUint64 — either n already reached the cutoff (n*10 would overflow) or adding the next digit wrapped (n1 < n). NewFromMySQL propagates it when decoding a MySQL wire-format decimal whose significant digits don't fit in 64 bits.","triggerScenarios":"parseDecimal64 receiving a digit string whose integer part exceeds MaxUint64 (~1.8e19); NewFromMySQL decoding a DECIMAL column value with more significant digits than uint64 can hold (more than 20 digits, or 19-20 large values).","commonSituations":"DECIMAL(30,6) or BIGINT UNSIGNED columns holding very large values; aggregations (SUM) that overflow; importing data from systems with wider decimals than the 64-bit fast path supports.","solutions":["Reduce the value's magnitude/scale (e.g. divide, or store as exponent/scientific form) so it fits in uint64","Use a smaller column scale/precision or a different type (e.g. store as string or big.Decimal) if values legitimately exceed 64 bits","Handle the error in the caller by falling back to the slower big-number decimal path instead of the 64-bit fast path"],"exampleFix":"// before\ndec, err := decimal.NewFromMySQL(raw) // errors for huge values\n// after\ndec, err := decimal.NewFromMySQL(raw)\nif errors.Is(err, decimal.ErrOverflow /* errOverflow */) {\n    return handleBigValueWithBigFloat(raw)\n}","handlingStrategy":"type-guard","validationCode":"// strip sign and split on '.', then check integer digits before calling NewFromMySQL:\nif len(intPart) > 20 { return errors.New(\"value exceeds 64-bit decimal fast path\") }\nif len(intPart) == 20 && intPart > \"18446744073709551615\" { return errors.New(\"overflow\") }","typeGuard":"func fitsDecimal64(s string) bool {\n    digits := strings.SplitN(strings.Trim(s, \"-+\"), \".\", 2)[0]\n    return len(digits) <= 19\n}","tryCatchPattern":"dec, err := decimal.NewFromMySQL(raw)\nif err != nil && errors.Is(err, errOverflow) {\n    return parseWithBigFloat(raw) // fallback path\n}","preventionTips":["Pre-check magnitude of DECIMAL/BIGINT UNSIGNED values exceeding uint64","Avoid SUM/aggregations that overflow 64 bits before parsing","Maintain a big-number fallback path for wide decimals"],"tags":["decimal","overflow","parsing","mysql"],"backgroundTag":"numeric-overflow","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}