Skip to content

Commit c641501

Browse files
committed
handle scientific notation, trim strings for ints
1 parent 0e2aa0c commit c641501

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

sql/types/number.go

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -992,7 +992,7 @@ func convertToInt64(t NumberTypeImpl_, v interface{}) (int64, sql.ConvertInRange
992992
}
993993
return i, sql.InRange, nil
994994
case string:
995-
v = strings.Trim(v, intCutSet)
995+
v = trimStringToNumberPrefix(v, false)
996996
if v == "" {
997997
// StringType{}.Zero() returns empty string, but should represent "0" for number value
998998
return 0, sql.InRange, nil
@@ -1179,7 +1179,7 @@ func convertToUint64(t NumberTypeImpl_, v interface{}) (uint64, sql.ConvertInRan
11791179
}
11801180
return i, sql.InRange, nil
11811181
case string:
1182-
v = strings.Trim(v, intCutSet)
1182+
v = trimStringToNumberPrefix(v, false)
11831183
if i, err := strconv.ParseUint(v, 10, 64); err == nil {
11841184
return i, sql.InRange, nil
11851185
} else if err == strconv.ErrRange {
@@ -1538,7 +1538,7 @@ func convertToFloat64(t NumberTypeImpl_, v interface{}) (float64, error) {
15381538
}
15391539
return float64(i), nil
15401540
case string:
1541-
v = trimStringToNumber(v)
1541+
v = trimStringToNumberPrefix(v, true)
15421542
i, err := strconv.ParseFloat(v, 64)
15431543
if err != nil {
15441544
// parse the first longest valid numbers
@@ -1751,17 +1751,27 @@ func convertUintToUint32(v uint64) (uint32, sql.ConvertInRange, error) {
17511751
return uint32(v), sql.InRange, nil
17521752
}
17531753

1754-
func trimStringToNumber(s string) string {
1754+
func trimStringToNumberPrefix(s string, isFloat bool) string {
17551755
s = strings.TrimSpace(s)
1756-
seenDecimal := false
17571756

1758-
for i, char := range s {
1759-
if char == '.' && !seenDecimal {
1760-
seenDecimal = true
1761-
} else if !(unicode.IsDigit(char) || ((i == 0) && (char == '+' || char == '-'))) {
1757+
seenDigit := false
1758+
seenDot := false
1759+
seenExp := false
1760+
signIndex := 0
1761+
1762+
for i := 0; i < len(s); i++ {
1763+
char := rune(s[i])
1764+
1765+
if unicode.IsDigit(char) {
1766+
seenDigit = true
1767+
} else if char == '.' && !seenDot && isFloat {
1768+
seenDot = true
1769+
} else if (char == 'e' || char == 'E') && !seenExp && seenDigit && isFloat {
1770+
seenExp = true
1771+
signIndex = i + 1
1772+
} else if !((char == '-' || char == '+') && i == signIndex) {
17621773
return s[:i]
17631774
}
17641775
}
1765-
17661776
return s
17671777
}

0 commit comments

Comments
 (0)