Skip to content

Commit b6de09b

Browse files
author
James Cor
committed
consolidate logic for truncation
1 parent a46dbec commit b6de09b

File tree

5 files changed

+25
-26
lines changed

5 files changed

+25
-26
lines changed

sql/expression/in.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,11 @@ func (in *InTuple) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
107107
if types.IsDecimal(elType) || types.IsFloat(elType) {
108108
rtyp := el.Type().Promote()
109109
left, _, err := rtyp.Convert(ctx, left)
110-
if err != nil {
110+
if err != nil && !sql.ErrTruncatedIncorrect.Is(err) {
111111
return nil, err
112112
}
113113
right, _, err := rtyp.Convert(ctx, originalRight)
114-
if err != nil {
114+
if err != nil && !sql.ErrTruncatedIncorrect.Is(err) {
115115
return nil, err
116116
}
117117
cmp, err = rtyp.Compare(ctx, left, right)
@@ -120,7 +120,7 @@ func (in *InTuple) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
120120
}
121121
} else {
122122
right, _, err := typ.Convert(ctx, originalRight)
123-
if err != nil {
123+
if err != nil && !sql.ErrTruncatedIncorrect.Is(err) {
124124
return nil, err
125125
}
126126
cmp, err = typ.Compare(ctx, left, right)

sql/hash/hash.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ func HashOfSimple(ctx *sql.Context, i interface{}, t sql.Type) (uint64, error) {
142142
}
143143
} else {
144144
x, _, err := t.Promote().Convert(ctx, i)
145-
if err != nil {
145+
// TODO: throw warning?
146+
if err != nil && !sql.ErrTruncatedIncorrect.Is(err) {
146147
return 0, err
147148
}
148149

sql/types/conversion.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -823,14 +823,9 @@ func ConvertHexBlobToUint(val interface{}, originType sql.Type) (interface{}, er
823823
return val, nil
824824
}
825825

826-
// TruncateStringToNumber truncates a string to the appropriate number prefix
826+
// TruncateStringToNumber truncates a string to the appropriate number prefix.
827+
// This function expects whitespace to already be properly trimmed.
827828
func TruncateStringToNumber(s string, isInt bool) string {
828-
if isInt {
829-
s = strings.TrimLeft(s, IntCutSet)
830-
} else {
831-
s = strings.TrimLeft(s, NumericCutSet)
832-
}
833-
834829
seenDigit := false
835830
seenDot := false
836831
seenExp := false

sql/types/decimal.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"gopkg.in/src-d/go-errors.v1"
2424
"math/big"
2525
"reflect"
26+
"strings"
2627

2728
"github.com/dolthub/go-mysql-server/sql"
2829
)
@@ -199,7 +200,7 @@ func (t DecimalType_) ConvertToNullDecimal(v interface{}) (decimal.NullDecimal,
199200
case float64:
200201
return t.ConvertToNullDecimal(decimal.NewFromFloat(value))
201202
case string:
202-
// TODO: implement truncation here
203+
value = strings.Trim(value, NumericCutSet)
203204
if len(value) == 0 {
204205
return t.ConvertToNullDecimal(decimal.NewFromInt(0))
205206
}
@@ -213,7 +214,7 @@ func (t DecimalType_) ConvertToNullDecimal(v interface{}) (decimal.NullDecimal,
213214
}
214215
}
215216

216-
// TODO: how do we know that it is a hex number and not string?
217+
// TODO: hex strings should not make it this far as numbers
217218
value = TruncateStringToNumber(value, false)
218219
if len(value) == 0 {
219220
return t.ConvertToNullDecimal(decimal.NewFromInt(0))

sql/types/number.go

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"reflect"
2323
"regexp"
2424
"strconv"
25+
"strings"
2526
"time"
2627

2728
"github.com/dolthub/vitess/go/sqltypes"
@@ -990,7 +991,7 @@ func convertToInt64(t NumberTypeImpl_, v interface{}) (int64, sql.ConvertInRange
990991
}
991992
return i, sql.InRange, nil
992993
case string:
993-
994+
v = strings.Trim(v, IntCutSet)
994995
if len(v) == 0 {
995996
// StringType{}.Zero() returns empty string, but should represent "0" for number value
996997
return 0, sql.InRange, nil
@@ -1001,18 +1002,18 @@ func convertToInt64(t NumberTypeImpl_, v interface{}) (int64, sql.ConvertInRange
10011002
}
10021003
// If that fails, try as a float and round to integral
10031004
if f, err := strconv.ParseFloat(v, 64); err == nil {
1004-
f = math.Round(f)
1005+
f = math.Round(f) // TODO: inserting rounds up, while casting truncates
10051006
return int64(f), sql.InRange, nil
10061007
}
10071008
// If that fails, truncate the string and parse as int
1008-
// TODO: throw error / warning?
10091009
v = TruncateStringToNumber(v, true)
10101010
if len(v) == 0 {
1011-
return 0, sql.InRange, nil
1011+
return 0, sql.InRange, sql.ErrTruncatedIncorrect.New(t.String(), v)
10121012
}
10131013
if i, err := strconv.ParseInt(v, 10, 64); err == nil {
1014-
return i, sql.InRange, nil
1014+
return i, sql.InRange, sql.ErrTruncatedIncorrect.New(t.String(), v)
10151015
}
1016+
// TODO: what should this error be?
10161017
return 0, sql.OutOfRange, sql.ErrInvalidValue.New(v, t.String())
10171018
case bool:
10181019
if v {
@@ -1547,14 +1548,15 @@ func convertToFloat64(t NumberTypeImpl_, v interface{}) (float64, error) {
15471548
}
15481549
return float64(i), nil
15491550
case string:
1550-
i, err := strconv.ParseFloat(v, 64)
1551-
if err != nil {
1552-
// parse the first longest valid numbers
1553-
s := numre.FindString(v)
1554-
i, _ = strconv.ParseFloat(s, 64)
1555-
return i, sql.ErrTruncatedIncorrect.New(t.String(), v)
1556-
}
1557-
return i, nil
1551+
v = strings.Trim(v, NumericCutSet)
1552+
if i, err := strconv.ParseFloat(v, 64); err == nil {
1553+
return i, nil
1554+
}
1555+
// TODO: what's the difference between this and TruncateStringToNumber?
1556+
// parse the first longest valid numbers
1557+
s := numre.FindString(v)
1558+
i, _ := strconv.ParseFloat(s, 64)
1559+
return i, sql.ErrTruncatedIncorrect.New(t.String(), v)
15581560
case bool:
15591561
if v {
15601562
return 1, nil

0 commit comments

Comments
 (0)