@@ -16,9 +16,9 @@ package expression
1616
1717import (
1818 "fmt"
19- "strconv"
2019
2120 "github.com/dolthub/go-mysql-server/sql"
21+ "github.com/dolthub/go-mysql-server/sql/hash"
2222 "github.com/dolthub/go-mysql-server/sql/types"
2323)
2424
@@ -106,11 +106,11 @@ func (in *InTuple) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
106106 elType := el .Type ()
107107 if types .IsDecimal (elType ) || types .IsFloat (elType ) {
108108 rtyp := el .Type ().Promote ()
109- left , err := convertOrTruncate (ctx , left , rtyp )
109+ left , err := types . ConvertOrTruncate (ctx , left , rtyp )
110110 if err != nil {
111111 return nil , err
112112 }
113- right , err := convertOrTruncate (ctx , originalRight , rtyp )
113+ right , err := types . ConvertOrTruncate (ctx , originalRight , rtyp )
114114 if err != nil {
115115 return nil , err
116116 }
@@ -119,7 +119,7 @@ func (in *InTuple) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
119119 return nil , err
120120 }
121121 } else {
122- right , err := convertOrTruncate (ctx , originalRight , typ )
122+ right , err := types . ConvertOrTruncate (ctx , originalRight , typ )
123123 if err != nil {
124124 return nil , err
125125 }
@@ -233,9 +233,9 @@ func newInMap(ctx *sql.Context, right Tuple, lType sql.Type) (map[uint64]sql.Exp
233233
234234 var key uint64
235235 if types .IsDecimal (rType ) || types .IsFloat (rType ) {
236- key , err = hashOfSimple (ctx , i , rType )
236+ key , err = hash . HashOfSimple (ctx , i , rType )
237237 } else {
238- key , err = hashOfSimple (ctx , i , lType )
238+ key , err = hash . HashOfSimple (ctx , i , lType )
239239 }
240240 if err != nil {
241241 return nil , false , err
@@ -246,66 +246,6 @@ func newInMap(ctx *sql.Context, right Tuple, lType sql.Type) (map[uint64]sql.Exp
246246 return elements , hasNull , nil
247247}
248248
249- func hashOfSimple (ctx * sql.Context , i interface {}, t sql.Type ) (uint64 , error ) {
250- if i == nil {
251- return 0 , nil
252- }
253-
254- var str string
255- coll := sql .Collation_Default
256- if types .IsTuple (t ) {
257- tup := i .([]interface {})
258- tupType := t .(types.TupleType )
259- hashes := make ([]uint64 , len (tup ))
260- for idx , v := range tup {
261- h , err := hashOfSimple (ctx , v , tupType [idx ])
262- if err != nil {
263- return 0 , err
264- }
265- hashes [idx ] = h
266- }
267- str = fmt .Sprintf ("%v" , hashes )
268- } else if types .IsTextOnly (t ) {
269- coll = t .(sql.StringType ).Collation ()
270- if s , ok := i .(string ); ok {
271- str = s
272- } else {
273- converted , err := convertOrTruncate (ctx , i , t )
274- if err != nil {
275- return 0 , err
276- }
277- str , _ , err = sql .Unwrap [string ](ctx , converted )
278- if err != nil {
279- return 0 , err
280- }
281- }
282- } else {
283- x , err := convertOrTruncate (ctx , i , t .Promote ())
284- if err != nil {
285- return 0 , err
286- }
287-
288- // Remove trailing 0s from floats
289- switch v := x .(type ) {
290- case float32 :
291- str = strconv .FormatFloat (float64 (v ), 'f' , - 1 , 32 )
292- if str == "-0" {
293- str = "0"
294- }
295- case float64 :
296- str = strconv .FormatFloat (v , 'f' , - 1 , 64 )
297- if str == "-0" {
298- str = "0"
299- }
300- default :
301- str = fmt .Sprintf ("%v" , v )
302- }
303- }
304-
305- // Collated strings that are equivalent may have different runes, so we must make them hash to the same value
306- return coll .HashToUint (str )
307- }
308-
309249// Eval implements the Expression interface.
310250func (hit * HashInTuple ) Eval (ctx * sql.Context , row sql.Row ) (interface {}, error ) {
311251 leftElems := types .NumColumns (hit .in .Left ().Type ().Promote ())
@@ -319,7 +259,7 @@ func (hit *HashInTuple) Eval(ctx *sql.Context, row sql.Row) (interface{}, error)
319259 return nil , nil
320260 }
321261
322- key , err := hashOfSimple (ctx , leftVal , hit .in .Left ().Type ())
262+ key , err := hash . HashOfSimple (ctx , leftVal , hit .in .Left ().Type ())
323263 if err != nil {
324264 return nil , err
325265 }
@@ -339,43 +279,6 @@ func (hit *HashInTuple) Eval(ctx *sql.Context, row sql.Row) (interface{}, error)
339279 return true , nil
340280}
341281
342- // convertOrTruncate converts the value |i| to type |t| and returns the converted value; if the value does not convert
343- // cleanly and the type is automatically coerced (i.e. string and numeric types), then a warning is logged and the
344- // value is truncated to the Zero value for type |t|. If the value does not convert and the type is not automatically
345- // coerced, then an error is returned.
346- func convertOrTruncate (ctx * sql.Context , i interface {}, t sql.Type ) (interface {}, error ) {
347- converted , _ , err := t .Convert (ctx , i )
348- if err == nil {
349- return converted , nil
350- }
351-
352- // If a value can't be converted to an enum or set type, truncate it to a value that is guaranteed
353- // to not match any enum value.
354- if types .IsEnum (t ) || types .IsSet (t ) {
355- return nil , nil
356- }
357-
358- // Values for numeric and string types are automatically coerced. For all other types, if they
359- // don't convert cleanly, it's an error.
360- if err != nil && ! (types .IsNumber (t ) || types .IsTextOnly (t )) {
361- return nil , err
362- }
363-
364- // For numeric and string types, if the value can't be cleanly converted, truncate to the zero value for
365- // the type and log a warning in the session.
366- warning := sql.Warning {
367- Level : "Warning" ,
368- Message : fmt .Sprintf ("Truncated incorrect %s value: %v" , t .String (), i ),
369- Code : 1292 ,
370- }
371-
372- if ctx != nil && ctx .Session != nil {
373- ctx .Session .Warn (& warning )
374- }
375-
376- return t .Zero (), nil
377- }
378-
379282func (hit * HashInTuple ) CollationCoercibility (ctx * sql.Context ) (collation sql.CollationID , coercibility byte ) {
380283 return hit .in .CollationCoercibility (ctx )
381284}
0 commit comments