Bug fix: don't round JSON numeric values when outside of float64 range#2692
Conversation
|
|
Ito Test Report ✅
16 test cases ran. 2 additional findings, 14 passed. Across 16 executed JSONB tests, 14 passed and 2 failed, confirming strong behavior for precision and safety checks including exact int64 boundary round-trips, rejection of malformed/trailing or extreme numeric inputs without crashes, responsive sessions after failures, and correct transaction atomicity/rollback handling. Both failures point to the same real defect (not introduced by this PR): jsonb_build_object can serialize equivalent numeric inputs as JSON strings while ::jsonb cast normalizes them as numbers, causing parity breaks that split GROUP BY/equality keys and can yield incorrect aggregations in mixed-write datasets. ✅ Passed (14)ℹ️ Additional Findings (2)
🟠 Builder path serializes numeric inputs as JSON strings
Relevant code:
// jsonb_in represents the PostgreSQL function of jsonb type IO input.
var jsonb_in = framework.Function1{
Name: "jsonb_in",
Return: pgtypes.JsonB,
Parameters: [1]*pgtypes.DoltgresType{pgtypes.Cstring},
Strict: true,
Callable: func(ctx *sql.Context, _ [2]*pgtypes.DoltgresType, val any) (any, error) {
input := val.(string)
inputBytes := unsafe.Slice(unsafe.StringData(input), len(input))
if json.Valid(inputBytes) {
doc, err := pgtypes.UnmarshalToJsonDocument(inputBytes)
return doc, err
}
decoder := json.NewDecoder(bytes.NewReader(val))
decoder.UseNumber()
if err := decoder.Decode(&decoded); err != nil {
return JsonDocument{}, err
}
...
case json.Number:
d, err := decimal.NewFromString(string(val))
if err != nil {
return nil, err
}
d, err = decimal.NewFromString(d.String())
if err != nil {
return nil, err
}
return JsonValueNumber(d), nil
func buildJsonObject(fnName string, _ [2]*pgtypes.DoltgresType, val1 any) ([]byte, error) {
inputArray := val1.([]any)
...
jsonObject := make(map[string]any)
...
} else {
jsonObject[key] = e
key = ""
}
}
return json.Marshal(jsonObject)
}
|













Fixes: #2686