@@ -1134,6 +1134,9 @@ func convertToUint64(t NumberTypeImpl_, v interface{}) (uint64, sql.ConvertInRan
11341134 return uint64 (v ), sql .InRange , nil
11351135 case int64 :
11361136 if v < 0 {
1137+ // For negative integers, use two's complement wrapping:
1138+ // -1 -> MaxUint64, -2 -> MaxUint64-1, -3 -> MaxUint64-2, etc.
1139+ // Formula: MaxUint64 - uint(-v-1)
11371140 return uint64 (math .MaxUint64 - uint (- v - 1 )), sql .OutOfRange , nil
11381141 }
11391142 return uint64 (v ), sql .InRange , nil
@@ -1151,16 +1154,24 @@ func convertToUint64(t NumberTypeImpl_, v interface{}) (uint64, sql.ConvertInRan
11511154 if v > float32 (math .MaxInt64 ) {
11521155 return math .MaxUint64 , sql .OutOfRange , nil
11531156 } else if v < 0 {
1154- return uint64 (math .MaxUint64 - v ), sql .OutOfRange , nil
1157+ // For negative floats, use the same two's complement wrapping as integers:
1158+ // -1 -> MaxUint64, -2 -> MaxUint64-1, -3 -> MaxUint64-2, etc.
1159+ // Formula: MaxUint64 - uint(-v-1)
1160+ return uint64 (math .MaxUint64 - uint (- v - 1 )), sql .OutOfRange , nil
11551161 }
11561162 return uint64 (math .Round (float64 (v ))), sql .InRange , nil
11571163 case float64 :
11581164 if v >= float64 (math .MaxUint64 ) {
11591165 return math .MaxUint64 , sql .OutOfRange , nil
11601166 } else if v <= 0 {
1161- return uint64 (math .MaxUint64 - v ), sql .OutOfRange , nil
1162- }
1163- return uint64 (math .Round (v )), sql .InRange , nil
1167+ // For negative floats, use the same two's complement wrapping as integers:
1168+ // -1 -> MaxUint64, -2 -> MaxUint64-1, -3 -> MaxUint64-2, etc.
1169+ // Formula: MaxUint64 - uint(-v-1)
1170+ result := uint64 (math .MaxUint64 - uint (- v - 1 ))
1171+ return result , sql .OutOfRange , nil
1172+ }
1173+ result := uint64 (math .Round (v ))
1174+ return result , sql .InRange , nil
11641175 case decimal.Decimal :
11651176 if v .GreaterThan (dec_uint64_max ) {
11661177 return math .MaxUint64 , sql .OutOfRange , nil
@@ -1186,7 +1197,9 @@ func convertToUint64(t NumberTypeImpl_, v interface{}) (uint64, sql.ConvertInRan
11861197 return math .MaxUint64 , sql .OutOfRange , nil
11871198 }
11881199 if f , err := strconv .ParseFloat (v , 64 ); err == nil {
1189- if val , inRange , err := convertToUint64 (t , f ); err == nil && inRange {
1200+ // Note: We only check err == nil, not inRangqe, because negative numbers
1201+ // correctly return OutOfRange but should still be processed
1202+ if val , inRange , err := convertToUint64 (t , f ); err == nil {
11901203 return val , inRange , err
11911204 }
11921205 }
0 commit comments