Skip to content

Commit be1ec1c

Browse files
committed
Try alternate fix for these casts using strconv
1 parent 83950fa commit be1ec1c

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

sql/system_settype.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package sql
1717
import (
1818
"math"
1919
"reflect"
20+
"strconv"
2021

2122
"github.com/dolthub/vitess/go/sqltypes"
2223
"github.com/dolthub/vitess/go/vt/proto/query"
@@ -86,7 +87,13 @@ func (t systemSetType) Convert(v interface{}) (interface{}, error) {
8687
case uint64:
8788
return t.SetType.Convert(value)
8889
case float32:
89-
return t.Convert(float64(value))
90+
// First convert to string, then pass to float64 handler for consistent processing
91+
strValue := strconv.FormatFloat(float64(value), 'f', -1, 32)
92+
floatValue, err := strconv.ParseFloat(strValue, 64)
93+
if err != nil {
94+
return nil, ErrInvalidSystemVariableValue.New(t.varName, v)
95+
}
96+
return t.Convert(floatValue)
9097
case float64:
9198
// Float values aren't truly accepted, but the engine will give them when it should give ints.
9299
// Therefore, if the float doesn't have a fractional portion, we treat it as an int.
@@ -95,7 +102,12 @@ func (t systemSetType) Convert(v interface{}) (interface{}, error) {
95102
if value < float64(math.MinInt64) || value > float64(math.MaxInt64) {
96103
return nil, ErrInvalidSystemVariableValue.New(t.varName, v) // Reject out-of-range values
97104
}
98-
intValue := int64(value)
105+
// Convert float64 to string and then to int64 to avoid unsafe type casting
106+
strValue := strconv.FormatFloat(value, 'f', 0, 64)
107+
intValue, err := strconv.ParseInt(strValue, 10, 64)
108+
if err != nil {
109+
return nil, ErrInvalidSystemVariableValue.New(t.varName, v)
110+
}
99111
return t.SetType.Convert(intValue)
100112
}
101113
return nil, ErrInvalidSystemVariableValue.New(t.varName, v) // Reject out-of-range values

sql/timetype.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,23 @@ func (t timespanType) ConvertToTimespan(v interface{}) (Timespan, error) {
178178
if value < float64(math.MinInt64) || value > float64(math.MaxInt64) {
179179
return Timespan(0), fmt.Errorf("float64 value %f exceeds int64 bounds", value)
180180
}
181-
intValue := int64(value)
182-
microseconds := int64Abs(int64(math.Round((value - float64(intValue)) * float64(microsecondsPerSecond))))
181+
// Convert float64 to string and then to int64 to avoid direct casting
182+
strValue := strconv.FormatFloat(value, 'f', 0, 64)
183+
intValue, err := strconv.ParseInt(strValue, 10, 64)
184+
if err != nil {
185+
return Timespan(0), fmt.Errorf("error converting float64 to int64: %v", err)
186+
}
187+
188+
// Calculate fractional part (microseconds) safely
189+
fractionalPart := value - float64(intValue)
190+
// Format with 6 decimal places to get microseconds
191+
microStr := strconv.FormatFloat(math.Abs(fractionalPart)*float64(microsecondsPerSecond), 'f', 0, 64)
192+
microValue, err := strconv.ParseInt(microStr, 10, 64)
193+
if err != nil {
194+
return Timespan(0), fmt.Errorf("error converting microseconds: %v", err)
195+
}
196+
microseconds := int64Abs(microValue)
197+
183198
absValue := int64Abs(intValue)
184199
if absValue >= -59 && absValue <= 59 {
185200
totalMicroseconds := (absValue * microsecondsPerSecond) + microseconds

0 commit comments

Comments
 (0)