github.com/XiaoMi/Gaea@v1.2.5/parser/tidb-types/datum.go (about)

     1  // Copyright 2016 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package types
    15  
    16  import (
    17  	"fmt"
    18  	"math"
    19  	"sort"
    20  	"strconv"
    21  	"strings"
    22  	"time"
    23  	"unicode/utf8"
    24  
    25  	"github.com/pingcap/errors"
    26  
    27  	"github.com/XiaoMi/Gaea/log"
    28  	"github.com/XiaoMi/Gaea/mysql"
    29  	"github.com/XiaoMi/Gaea/parser/stmtctx"
    30  	"github.com/XiaoMi/Gaea/parser/terror"
    31  	"github.com/XiaoMi/Gaea/parser/tidb-types/json"
    32  	"github.com/XiaoMi/Gaea/util/hack"
    33  )
    34  
    35  // Kind constants.
    36  const (
    37  	KindNull          byte = 0
    38  	KindInt64         byte = 1
    39  	KindUint64        byte = 2
    40  	KindFloat32       byte = 3
    41  	KindFloat64       byte = 4
    42  	KindString        byte = 5
    43  	KindBytes         byte = 6
    44  	KindBinaryLiteral byte = 7 // Used for BIT / HEX literals.
    45  	KindMysqlDecimal  byte = 8
    46  	KindMysqlDuration byte = 9
    47  	KindMysqlEnum     byte = 10
    48  	KindMysqlBit      byte = 11 // Used for BIT table column values.
    49  	KindMysqlSet      byte = 12
    50  	KindMysqlTime     byte = 13
    51  	KindInterface     byte = 14
    52  	KindMinNotNull    byte = 15
    53  	KindMaxValue      byte = 16
    54  	KindRaw           byte = 17
    55  	KindMysqlJSON     byte = 18
    56  )
    57  
    58  // Datum is a data box holds different kind of data.
    59  // It has better performance and is easier to use than `interface{}`.
    60  type Datum struct {
    61  	k         byte        // datum kind.
    62  	collation uint8       // collation can hold uint8 values.
    63  	decimal   uint16      // decimal can hold uint16 values.
    64  	length    uint32      // length can hold uint32 values.
    65  	i         int64       // i can hold int64 uint64 float64 values.
    66  	b         []byte      // b can hold string or []byte values.
    67  	x         interface{} // x hold all other types.
    68  }
    69  
    70  // Copy deep copies a Datum.
    71  func (d *Datum) Copy() *Datum {
    72  	ret := *d
    73  	if d.b != nil {
    74  		ret.b = make([]byte, len(d.b))
    75  		copy(ret.b, d.b)
    76  	}
    77  	switch ret.Kind() {
    78  	case KindMysqlDecimal:
    79  		d := *d.GetMysqlDecimal()
    80  		ret.SetMysqlDecimal(&d)
    81  	case KindMysqlTime:
    82  		ret.SetMysqlTime(d.GetMysqlTime())
    83  	}
    84  	return &ret
    85  }
    86  
    87  // Kind gets the kind of the datum.
    88  func (d *Datum) Kind() byte {
    89  	return d.k
    90  }
    91  
    92  // Collation gets the collation of the datum.
    93  func (d *Datum) Collation() byte {
    94  	return d.collation
    95  }
    96  
    97  // SetCollation sets the collation of the datum.
    98  func (d *Datum) SetCollation(collation byte) {
    99  	d.collation = collation
   100  }
   101  
   102  // Frac gets the frac of the datum.
   103  func (d *Datum) Frac() int {
   104  	return int(d.decimal)
   105  }
   106  
   107  // SetFrac sets the frac of the datum.
   108  func (d *Datum) SetFrac(frac int) {
   109  	d.decimal = uint16(frac)
   110  }
   111  
   112  // Length gets the length of the datum.
   113  func (d *Datum) Length() int {
   114  	return int(d.length)
   115  }
   116  
   117  // SetLength sets the length of the datum.
   118  func (d *Datum) SetLength(l int) {
   119  	d.length = uint32(l)
   120  }
   121  
   122  // IsNull checks if datum is null.
   123  func (d *Datum) IsNull() bool {
   124  	return d.k == KindNull
   125  }
   126  
   127  // GetInt64 gets int64 value.
   128  func (d *Datum) GetInt64() int64 {
   129  	return d.i
   130  }
   131  
   132  // SetInt64 sets int64 value.
   133  func (d *Datum) SetInt64(i int64) {
   134  	d.k = KindInt64
   135  	d.i = i
   136  }
   137  
   138  // GetUint64 gets uint64 value.
   139  func (d *Datum) GetUint64() uint64 {
   140  	return uint64(d.i)
   141  }
   142  
   143  // SetUint64 sets uint64 value.
   144  func (d *Datum) SetUint64(i uint64) {
   145  	d.k = KindUint64
   146  	d.i = int64(i)
   147  }
   148  
   149  // GetFloat64 gets float64 value.
   150  func (d *Datum) GetFloat64() float64 {
   151  	return math.Float64frombits(uint64(d.i))
   152  }
   153  
   154  // SetFloat64 sets float64 value.
   155  func (d *Datum) SetFloat64(f float64) {
   156  	d.k = KindFloat64
   157  	d.i = int64(math.Float64bits(f))
   158  }
   159  
   160  // GetFloat32 gets float32 value.
   161  func (d *Datum) GetFloat32() float32 {
   162  	return float32(math.Float64frombits(uint64(d.i)))
   163  }
   164  
   165  // SetFloat32 sets float32 value.
   166  func (d *Datum) SetFloat32(f float32) {
   167  	d.k = KindFloat32
   168  	d.i = int64(math.Float64bits(float64(f)))
   169  }
   170  
   171  // GetString gets string value.
   172  func (d *Datum) GetString() string {
   173  	return string(hack.String(d.b))
   174  }
   175  
   176  // SetString sets string value.
   177  func (d *Datum) SetString(s string) {
   178  	d.k = KindString
   179  	sink(s)
   180  	d.b = hack.Slice(s)
   181  }
   182  
   183  // sink prevents s from being allocated on the stack.
   184  var sink = func(s string) {
   185  }
   186  
   187  // GetBytes gets bytes value.
   188  func (d *Datum) GetBytes() []byte {
   189  	return d.b
   190  }
   191  
   192  // SetBytes sets bytes value to datum.
   193  func (d *Datum) SetBytes(b []byte) {
   194  	d.k = KindBytes
   195  	d.b = b
   196  }
   197  
   198  // SetBytesAsString sets bytes value to datum as string type.
   199  func (d *Datum) SetBytesAsString(b []byte) {
   200  	d.k = KindString
   201  	d.b = b
   202  }
   203  
   204  // GetInterface gets interface value.
   205  func (d *Datum) GetInterface() interface{} {
   206  	return d.x
   207  }
   208  
   209  // SetInterface sets interface to datum.
   210  func (d *Datum) SetInterface(x interface{}) {
   211  	d.k = KindInterface
   212  	d.x = x
   213  }
   214  
   215  // SetNull sets datum to nil.
   216  func (d *Datum) SetNull() {
   217  	d.k = KindNull
   218  	d.x = nil
   219  }
   220  
   221  // SetMinNotNull sets datum to minNotNull value.
   222  func (d *Datum) SetMinNotNull() {
   223  	d.k = KindMinNotNull
   224  	d.x = nil
   225  }
   226  
   227  // GetBinaryLiteral gets Bit value
   228  func (d *Datum) GetBinaryLiteral() BinaryLiteral {
   229  	return d.b
   230  }
   231  
   232  // GetMysqlBit gets MysqlBit value
   233  func (d *Datum) GetMysqlBit() BinaryLiteral {
   234  	return d.GetBinaryLiteral()
   235  }
   236  
   237  // SetBinaryLiteral sets Bit value
   238  func (d *Datum) SetBinaryLiteral(b BinaryLiteral) {
   239  	d.k = KindBinaryLiteral
   240  	d.b = b
   241  }
   242  
   243  // SetMysqlBit sets MysqlBit value
   244  func (d *Datum) SetMysqlBit(b BinaryLiteral) {
   245  	d.k = KindMysqlBit
   246  	d.b = b
   247  }
   248  
   249  // GetMysqlDecimal gets Decimal value
   250  func (d *Datum) GetMysqlDecimal() *MyDecimal {
   251  	return d.x.(*MyDecimal)
   252  }
   253  
   254  // SetMysqlDecimal sets Decimal value
   255  func (d *Datum) SetMysqlDecimal(b *MyDecimal) {
   256  	d.k = KindMysqlDecimal
   257  	d.x = b
   258  }
   259  
   260  // GetMysqlDuration gets Duration value
   261  func (d *Datum) GetMysqlDuration() Duration {
   262  	return Duration{Duration: time.Duration(d.i), Fsp: int(d.decimal)}
   263  }
   264  
   265  // SetMysqlDuration sets Duration value
   266  func (d *Datum) SetMysqlDuration(b Duration) {
   267  	d.k = KindMysqlDuration
   268  	d.i = int64(b.Duration)
   269  	d.decimal = uint16(b.Fsp)
   270  }
   271  
   272  // GetMysqlEnum gets Enum value
   273  func (d *Datum) GetMysqlEnum() Enum {
   274  	str := string(hack.String(d.b))
   275  	return Enum{Value: uint64(d.i), Name: str}
   276  }
   277  
   278  // SetMysqlEnum sets Enum value
   279  func (d *Datum) SetMysqlEnum(b Enum) {
   280  	d.k = KindMysqlEnum
   281  	d.i = int64(b.Value)
   282  	sink(b.Name)
   283  	d.b = hack.Slice(b.Name)
   284  }
   285  
   286  // GetMysqlSet gets Set value
   287  func (d *Datum) GetMysqlSet() Set {
   288  	str := string(hack.String(d.b))
   289  	return Set{Value: uint64(d.i), Name: str}
   290  }
   291  
   292  // SetMysqlSet sets Set value
   293  func (d *Datum) SetMysqlSet(b Set) {
   294  	d.k = KindMysqlSet
   295  	d.i = int64(b.Value)
   296  	sink(b.Name)
   297  	d.b = hack.Slice(b.Name)
   298  }
   299  
   300  // GetMysqlJSON gets json.BinaryJSON value
   301  func (d *Datum) GetMysqlJSON() json.BinaryJSON {
   302  	return json.BinaryJSON{TypeCode: byte(d.i), Value: d.b}
   303  }
   304  
   305  // SetMysqlJSON sets json.BinaryJSON value
   306  func (d *Datum) SetMysqlJSON(b json.BinaryJSON) {
   307  	d.k = KindMysqlJSON
   308  	d.i = int64(b.TypeCode)
   309  	d.b = b.Value
   310  }
   311  
   312  // GetMysqlTime gets types.Time value
   313  func (d *Datum) GetMysqlTime() Time {
   314  	return d.x.(Time)
   315  }
   316  
   317  // SetMysqlTime sets types.Time value
   318  func (d *Datum) SetMysqlTime(b Time) {
   319  	d.k = KindMysqlTime
   320  	d.x = b
   321  }
   322  
   323  // SetRaw sets raw value.
   324  func (d *Datum) SetRaw(b []byte) {
   325  	d.k = KindRaw
   326  	d.b = b
   327  }
   328  
   329  // GetRaw gets raw value.
   330  func (d *Datum) GetRaw() []byte {
   331  	return d.b
   332  }
   333  
   334  // SetAutoID set the auto increment ID according to its int flag.
   335  func (d *Datum) SetAutoID(id int64, flag uint) {
   336  	if mysql.HasUnsignedFlag(flag) {
   337  		d.SetUint64(uint64(id))
   338  	} else {
   339  		d.SetInt64(id)
   340  	}
   341  }
   342  
   343  // GetValue gets the value of the datum of any kind.
   344  func (d *Datum) GetValue() interface{} {
   345  	switch d.k {
   346  	case KindInt64:
   347  		return d.GetInt64()
   348  	case KindUint64:
   349  		return d.GetUint64()
   350  	case KindFloat32:
   351  		return d.GetFloat32()
   352  	case KindFloat64:
   353  		return d.GetFloat64()
   354  	case KindString:
   355  		return d.GetString()
   356  	case KindBytes:
   357  		return d.GetBytes()
   358  	case KindMysqlDecimal:
   359  		return d.GetMysqlDecimal()
   360  	case KindMysqlDuration:
   361  		return d.GetMysqlDuration()
   362  	case KindMysqlEnum:
   363  		return d.GetMysqlEnum()
   364  	case KindBinaryLiteral, KindMysqlBit:
   365  		return d.GetBinaryLiteral()
   366  	case KindMysqlSet:
   367  		return d.GetMysqlSet()
   368  	case KindMysqlJSON:
   369  		return d.GetMysqlJSON()
   370  	case KindMysqlTime:
   371  		return d.GetMysqlTime()
   372  	default:
   373  		return d.GetInterface()
   374  	}
   375  }
   376  
   377  // SetValue sets any kind of value.
   378  func (d *Datum) SetValue(val interface{}) {
   379  	switch x := val.(type) {
   380  	case nil:
   381  		d.SetNull()
   382  	case bool:
   383  		if x {
   384  			d.SetInt64(1)
   385  		} else {
   386  			d.SetInt64(0)
   387  		}
   388  	case int:
   389  		d.SetInt64(int64(x))
   390  	case int64:
   391  		d.SetInt64(x)
   392  	case uint64:
   393  		d.SetUint64(x)
   394  	case float32:
   395  		d.SetFloat32(x)
   396  	case float64:
   397  		d.SetFloat64(x)
   398  	case string:
   399  		d.SetString(x)
   400  	case []byte:
   401  		d.SetBytes(x)
   402  	case *MyDecimal:
   403  		d.SetMysqlDecimal(x)
   404  	case Duration:
   405  		d.SetMysqlDuration(x)
   406  	case Enum:
   407  		d.SetMysqlEnum(x)
   408  	case BinaryLiteral:
   409  		d.SetBinaryLiteral(x)
   410  	case BitLiteral: // Store as BinaryLiteral for Bit and Hex literals
   411  		d.SetBinaryLiteral(BinaryLiteral(x))
   412  	case HexLiteral:
   413  		d.SetBinaryLiteral(BinaryLiteral(x))
   414  	case Set:
   415  		d.SetMysqlSet(x)
   416  	case json.BinaryJSON:
   417  		d.SetMysqlJSON(x)
   418  	case Time:
   419  		d.SetMysqlTime(x)
   420  	default:
   421  		d.SetInterface(x)
   422  	}
   423  }
   424  
   425  // CompareDatum compares datum to another datum.
   426  // TODO: return error properly.
   427  func (d *Datum) CompareDatum(sc *stmtctx.StatementContext, ad *Datum) (int, error) {
   428  	if d.k == KindMysqlJSON && ad.k != KindMysqlJSON {
   429  		cmp, err := ad.CompareDatum(sc, d)
   430  		return cmp * -1, errors.Trace(err)
   431  	}
   432  	switch ad.k {
   433  	case KindNull:
   434  		if d.k == KindNull {
   435  			return 0, nil
   436  		}
   437  		return 1, nil
   438  	case KindMinNotNull:
   439  		if d.k == KindNull {
   440  			return -1, nil
   441  		} else if d.k == KindMinNotNull {
   442  			return 0, nil
   443  		}
   444  		return 1, nil
   445  	case KindMaxValue:
   446  		if d.k == KindMaxValue {
   447  			return 0, nil
   448  		}
   449  		return -1, nil
   450  	case KindInt64:
   451  		return d.compareInt64(sc, ad.GetInt64())
   452  	case KindUint64:
   453  		return d.compareUint64(sc, ad.GetUint64())
   454  	case KindFloat32, KindFloat64:
   455  		return d.compareFloat64(sc, ad.GetFloat64())
   456  	case KindString:
   457  		return d.compareString(sc, ad.GetString())
   458  	case KindBytes:
   459  		return d.compareBytes(sc, ad.GetBytes())
   460  	case KindMysqlDecimal:
   461  		return d.compareMysqlDecimal(sc, ad.GetMysqlDecimal())
   462  	case KindMysqlDuration:
   463  		return d.compareMysqlDuration(sc, ad.GetMysqlDuration())
   464  	case KindMysqlEnum:
   465  		return d.compareMysqlEnum(sc, ad.GetMysqlEnum())
   466  	case KindBinaryLiteral, KindMysqlBit:
   467  		return d.compareBinaryLiteral(sc, ad.GetBinaryLiteral())
   468  	case KindMysqlSet:
   469  		return d.compareMysqlSet(sc, ad.GetMysqlSet())
   470  	case KindMysqlJSON:
   471  		return d.compareMysqlJSON(sc, ad.GetMysqlJSON())
   472  	case KindMysqlTime:
   473  		return d.compareMysqlTime(sc, ad.GetMysqlTime())
   474  	default:
   475  		return 0, nil
   476  	}
   477  }
   478  
   479  func (d *Datum) compareInt64(sc *stmtctx.StatementContext, i int64) (int, error) {
   480  	switch d.k {
   481  	case KindMaxValue:
   482  		return 1, nil
   483  	case KindInt64:
   484  		return CompareInt64(d.i, i), nil
   485  	case KindUint64:
   486  		if i < 0 || d.GetUint64() > math.MaxInt64 {
   487  			return 1, nil
   488  		}
   489  		return CompareInt64(d.i, i), nil
   490  	default:
   491  		return d.compareFloat64(sc, float64(i))
   492  	}
   493  }
   494  
   495  func (d *Datum) compareUint64(sc *stmtctx.StatementContext, u uint64) (int, error) {
   496  	switch d.k {
   497  	case KindMaxValue:
   498  		return 1, nil
   499  	case KindInt64:
   500  		if d.i < 0 || u > math.MaxInt64 {
   501  			return -1, nil
   502  		}
   503  		return CompareInt64(d.i, int64(u)), nil
   504  	case KindUint64:
   505  		return CompareUint64(d.GetUint64(), u), nil
   506  	default:
   507  		return d.compareFloat64(sc, float64(u))
   508  	}
   509  }
   510  
   511  func (d *Datum) compareFloat64(sc *stmtctx.StatementContext, f float64) (int, error) {
   512  	switch d.k {
   513  	case KindNull, KindMinNotNull:
   514  		return -1, nil
   515  	case KindMaxValue:
   516  		return 1, nil
   517  	case KindInt64:
   518  		return CompareFloat64(float64(d.i), f), nil
   519  	case KindUint64:
   520  		return CompareFloat64(float64(d.GetUint64()), f), nil
   521  	case KindFloat32, KindFloat64:
   522  		return CompareFloat64(d.GetFloat64(), f), nil
   523  	case KindString, KindBytes:
   524  		fVal, err := StrToFloat(sc, d.GetString())
   525  		return CompareFloat64(fVal, f), errors.Trace(err)
   526  	case KindMysqlDecimal:
   527  		fVal, err := d.GetMysqlDecimal().ToFloat64()
   528  		return CompareFloat64(fVal, f), errors.Trace(err)
   529  	case KindMysqlDuration:
   530  		fVal := d.GetMysqlDuration().Seconds()
   531  		return CompareFloat64(fVal, f), nil
   532  	case KindMysqlEnum:
   533  		fVal := d.GetMysqlEnum().ToNumber()
   534  		return CompareFloat64(fVal, f), nil
   535  	case KindBinaryLiteral, KindMysqlBit:
   536  		val, err := d.GetBinaryLiteral().ToInt(sc)
   537  		fVal := float64(val)
   538  		return CompareFloat64(fVal, f), errors.Trace(err)
   539  	case KindMysqlSet:
   540  		fVal := d.GetMysqlSet().ToNumber()
   541  		return CompareFloat64(fVal, f), nil
   542  	case KindMysqlTime:
   543  		fVal, err := d.GetMysqlTime().ToNumber().ToFloat64()
   544  		return CompareFloat64(fVal, f), errors.Trace(err)
   545  	default:
   546  		return -1, nil
   547  	}
   548  }
   549  
   550  func (d *Datum) compareString(sc *stmtctx.StatementContext, s string) (int, error) {
   551  	switch d.k {
   552  	case KindNull, KindMinNotNull:
   553  		return -1, nil
   554  	case KindMaxValue:
   555  		return 1, nil
   556  	case KindString, KindBytes:
   557  		return CompareString(d.GetString(), s), nil
   558  	case KindMysqlDecimal:
   559  		dec := new(MyDecimal)
   560  		err := sc.HandleTruncate(dec.FromString(hack.Slice(s)))
   561  		return d.GetMysqlDecimal().Compare(dec), errors.Trace(err)
   562  	case KindMysqlTime:
   563  		dt, err := ParseDatetime(sc, s)
   564  		return d.GetMysqlTime().Compare(dt), errors.Trace(err)
   565  	case KindMysqlDuration:
   566  		dur, err := ParseDuration(sc, s, MaxFsp)
   567  		return d.GetMysqlDuration().Compare(dur), errors.Trace(err)
   568  	case KindMysqlSet:
   569  		return CompareString(d.GetMysqlSet().String(), s), nil
   570  	case KindMysqlEnum:
   571  		return CompareString(d.GetMysqlEnum().String(), s), nil
   572  	case KindBinaryLiteral, KindMysqlBit:
   573  		return CompareString(d.GetBinaryLiteral().ToString(), s), nil
   574  	default:
   575  		fVal, err := StrToFloat(sc, s)
   576  		if err != nil {
   577  			return 0, errors.Trace(err)
   578  		}
   579  		return d.compareFloat64(sc, fVal)
   580  	}
   581  }
   582  
   583  func (d *Datum) compareBytes(sc *stmtctx.StatementContext, b []byte) (int, error) {
   584  	str := string(hack.String(b))
   585  	return d.compareString(sc, str)
   586  }
   587  
   588  func (d *Datum) compareMysqlDecimal(sc *stmtctx.StatementContext, dec *MyDecimal) (int, error) {
   589  	switch d.k {
   590  	case KindNull, KindMinNotNull:
   591  		return -1, nil
   592  	case KindMaxValue:
   593  		return 1, nil
   594  	case KindMysqlDecimal:
   595  		return d.GetMysqlDecimal().Compare(dec), nil
   596  	case KindString, KindBytes:
   597  		dDec := new(MyDecimal)
   598  		err := sc.HandleTruncate(dDec.FromString(d.GetBytes()))
   599  		return dDec.Compare(dec), errors.Trace(err)
   600  	default:
   601  		dVal, err := d.ConvertTo(sc, NewFieldType(mysql.TypeNewDecimal))
   602  		if err != nil {
   603  			return 0, errors.Trace(err)
   604  		}
   605  		return dVal.GetMysqlDecimal().Compare(dec), nil
   606  	}
   607  }
   608  
   609  func (d *Datum) compareMysqlDuration(sc *stmtctx.StatementContext, dur Duration) (int, error) {
   610  	switch d.k {
   611  	case KindMysqlDuration:
   612  		return d.GetMysqlDuration().Compare(dur), nil
   613  	case KindString, KindBytes:
   614  		dDur, err := ParseDuration(sc, d.GetString(), MaxFsp)
   615  		return dDur.Compare(dur), errors.Trace(err)
   616  	default:
   617  		return d.compareFloat64(sc, dur.Seconds())
   618  	}
   619  }
   620  
   621  func (d *Datum) compareMysqlEnum(sc *stmtctx.StatementContext, enum Enum) (int, error) {
   622  	switch d.k {
   623  	case KindString, KindBytes:
   624  		return CompareString(d.GetString(), enum.String()), nil
   625  	default:
   626  		return d.compareFloat64(sc, enum.ToNumber())
   627  	}
   628  }
   629  
   630  func (d *Datum) compareBinaryLiteral(sc *stmtctx.StatementContext, b BinaryLiteral) (int, error) {
   631  	switch d.k {
   632  	case KindString, KindBytes:
   633  		return CompareString(d.GetString(), b.ToString()), nil
   634  	case KindBinaryLiteral, KindMysqlBit:
   635  		return CompareString(d.GetBinaryLiteral().ToString(), b.ToString()), nil
   636  	default:
   637  		val, err := b.ToInt(sc)
   638  		if err != nil {
   639  			return 0, errors.Trace(err)
   640  		}
   641  		result, err := d.compareFloat64(sc, float64(val))
   642  		return result, errors.Trace(err)
   643  	}
   644  }
   645  
   646  func (d *Datum) compareMysqlSet(sc *stmtctx.StatementContext, set Set) (int, error) {
   647  	switch d.k {
   648  	case KindString, KindBytes:
   649  		return CompareString(d.GetString(), set.String()), nil
   650  	default:
   651  		return d.compareFloat64(sc, set.ToNumber())
   652  	}
   653  }
   654  
   655  func (d *Datum) compareMysqlJSON(sc *stmtctx.StatementContext, target json.BinaryJSON) (int, error) {
   656  	origin, err := d.ToMysqlJSON()
   657  	if err != nil {
   658  		return 0, errors.Trace(err)
   659  	}
   660  	return json.CompareBinary(origin, target), nil
   661  }
   662  
   663  func (d *Datum) compareMysqlTime(sc *stmtctx.StatementContext, time Time) (int, error) {
   664  	switch d.k {
   665  	case KindString, KindBytes:
   666  		dt, err := ParseDatetime(sc, d.GetString())
   667  		return dt.Compare(time), errors.Trace(err)
   668  	case KindMysqlTime:
   669  		return d.GetMysqlTime().Compare(time), nil
   670  	default:
   671  		fVal, err := time.ToNumber().ToFloat64()
   672  		if err != nil {
   673  			return 0, errors.Trace(err)
   674  		}
   675  		return d.compareFloat64(sc, fVal)
   676  	}
   677  }
   678  
   679  // ConvertTo converts a datum to the target field type.
   680  func (d *Datum) ConvertTo(sc *stmtctx.StatementContext, target *FieldType) (Datum, error) {
   681  	if d.k == KindNull {
   682  		return Datum{}, nil
   683  	}
   684  	switch target.Tp { // TODO: implement mysql types convert when "CAST() AS" syntax are supported.
   685  	case mysql.TypeTiny, mysql.TypeShort, mysql.TypeInt24, mysql.TypeLong, mysql.TypeLonglong:
   686  		unsigned := mysql.HasUnsignedFlag(target.Flag)
   687  		if unsigned {
   688  			return d.convertToUint(sc, target)
   689  		}
   690  		return d.convertToInt(sc, target)
   691  	case mysql.TypeFloat, mysql.TypeDouble:
   692  		return d.convertToFloat(sc, target)
   693  	case mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob,
   694  		mysql.TypeString, mysql.TypeVarchar, mysql.TypeVarString:
   695  		return d.convertToString(sc, target)
   696  	case mysql.TypeTimestamp:
   697  		return d.convertToMysqlTimestamp(sc, target)
   698  	case mysql.TypeDatetime, mysql.TypeDate:
   699  		return d.convertToMysqlTime(sc, target)
   700  	case mysql.TypeDuration:
   701  		return d.convertToMysqlDuration(sc, target)
   702  	case mysql.TypeNewDecimal:
   703  		return d.convertToMysqlDecimal(sc, target)
   704  	case mysql.TypeYear:
   705  		return d.convertToMysqlYear(sc, target)
   706  	case mysql.TypeEnum:
   707  		return d.convertToMysqlEnum(sc, target)
   708  	case mysql.TypeBit:
   709  		return d.convertToMysqlBit(sc, target)
   710  	case mysql.TypeSet:
   711  		return d.convertToMysqlSet(sc, target)
   712  	case mysql.TypeJSON:
   713  		return d.convertToMysqlJSON(sc, target)
   714  	case mysql.TypeNull:
   715  		return Datum{}, nil
   716  	default:
   717  		panic("should never happen")
   718  	}
   719  }
   720  
   721  func (d *Datum) convertToFloat(sc *stmtctx.StatementContext, target *FieldType) (Datum, error) {
   722  	var (
   723  		f   float64
   724  		ret Datum
   725  		err error
   726  	)
   727  	switch d.k {
   728  	case KindNull:
   729  		return ret, nil
   730  	case KindInt64:
   731  		f = float64(d.GetInt64())
   732  	case KindUint64:
   733  		f = float64(d.GetUint64())
   734  	case KindFloat32, KindFloat64:
   735  		f = d.GetFloat64()
   736  	case KindString, KindBytes:
   737  		f, err = StrToFloat(sc, d.GetString())
   738  	case KindMysqlTime:
   739  		f, err = d.GetMysqlTime().ToNumber().ToFloat64()
   740  	case KindMysqlDuration:
   741  		f, err = d.GetMysqlDuration().ToNumber().ToFloat64()
   742  	case KindMysqlDecimal:
   743  		f, err = d.GetMysqlDecimal().ToFloat64()
   744  	case KindMysqlSet:
   745  		f = d.GetMysqlSet().ToNumber()
   746  	case KindMysqlEnum:
   747  		f = d.GetMysqlEnum().ToNumber()
   748  	case KindBinaryLiteral, KindMysqlBit:
   749  		val, err1 := d.GetBinaryLiteral().ToInt(sc)
   750  		f, err = float64(val), err1
   751  	case KindMysqlJSON:
   752  		f, err = ConvertJSONToFloat(sc, d.GetMysqlJSON())
   753  	default:
   754  		return invalidConv(d, target.Tp)
   755  	}
   756  	var err1 error
   757  	f, err1 = ProduceFloatWithSpecifiedTp(f, target, sc)
   758  	if err == nil && err1 != nil {
   759  		err = err1
   760  	}
   761  	if target.Tp == mysql.TypeFloat {
   762  		ret.SetFloat32(float32(f))
   763  	} else {
   764  		ret.SetFloat64(f)
   765  	}
   766  	return ret, errors.Trace(err)
   767  }
   768  
   769  // ProduceFloatWithSpecifiedTp produces a new float64 according to `flen` and `decimal`.
   770  func ProduceFloatWithSpecifiedTp(f float64, target *FieldType, sc *stmtctx.StatementContext) (_ float64, err error) {
   771  	// For float and following double type, we will only truncate it for float(M, D) format.
   772  	// If no D is set, we will handle it like origin float whether M is set or not.
   773  	if target.Flen != UnspecifiedLength && target.Decimal != UnspecifiedLength {
   774  		f, err = TruncateFloat(f, target.Flen, target.Decimal)
   775  		if err = sc.HandleOverflow(err, err); err != nil {
   776  			return f, errors.Trace(err)
   777  		}
   778  	}
   779  	if mysql.HasUnsignedFlag(target.Flag) && f < 0 {
   780  		return 0, overflow(f, target.Tp)
   781  	}
   782  	return f, nil
   783  }
   784  
   785  func (d *Datum) convertToString(sc *stmtctx.StatementContext, target *FieldType) (Datum, error) {
   786  	var ret Datum
   787  	var s string
   788  	switch d.k {
   789  	case KindInt64:
   790  		s = strconv.FormatInt(d.GetInt64(), 10)
   791  	case KindUint64:
   792  		s = strconv.FormatUint(d.GetUint64(), 10)
   793  	case KindFloat32:
   794  		s = strconv.FormatFloat(d.GetFloat64(), 'f', -1, 32)
   795  	case KindFloat64:
   796  		s = strconv.FormatFloat(d.GetFloat64(), 'f', -1, 64)
   797  	case KindString, KindBytes:
   798  		s = d.GetString()
   799  	case KindMysqlTime:
   800  		s = d.GetMysqlTime().String()
   801  	case KindMysqlDuration:
   802  		s = d.GetMysqlDuration().String()
   803  	case KindMysqlDecimal:
   804  		s = d.GetMysqlDecimal().String()
   805  	case KindMysqlEnum:
   806  		s = d.GetMysqlEnum().String()
   807  	case KindMysqlSet:
   808  		s = d.GetMysqlSet().String()
   809  	case KindBinaryLiteral, KindMysqlBit:
   810  		s = d.GetBinaryLiteral().ToString()
   811  	case KindMysqlJSON:
   812  		s = d.GetMysqlJSON().String()
   813  	default:
   814  		return invalidConv(d, target.Tp)
   815  	}
   816  	s, err := ProduceStrWithSpecifiedTp(s, target, sc, true)
   817  	ret.SetString(s)
   818  	if target.Charset == mysql.CharsetBin {
   819  		ret.k = KindBytes
   820  	}
   821  	return ret, errors.Trace(err)
   822  }
   823  
   824  // ProduceStrWithSpecifiedTp produces a new string according to `flen` and `chs`. Param `padZero` indicates
   825  // whether we should pad `\0` for `binary(flen)` type.
   826  func ProduceStrWithSpecifiedTp(s string, tp *FieldType, sc *stmtctx.StatementContext, padZero bool) (_ string, err error) {
   827  	flen, chs := tp.Flen, tp.Charset
   828  	if flen >= 0 {
   829  		// Flen is the rune length, not binary length, for UTF8 charset, we need to calculate the
   830  		// rune count and truncate to Flen runes if it is too long.
   831  		if chs == mysql.CharsetUTF8 || chs == mysql.CharsetUTF8MB4 {
   832  			characterLen := utf8.RuneCountInString(s)
   833  			if characterLen > flen {
   834  				// 1. If len(s) is 0 and flen is 0, truncateLen will be 0, don't truncate s.
   835  				//    CREATE TABLE t (a char(0));
   836  				//    INSERT INTO t VALUES (``);
   837  				// 2. If len(s) is 10 and flen is 0, truncateLen will be 0 too, but we still need to truncate s.
   838  				//    SELECT 1, CAST(1234 AS CHAR(0));
   839  				// So truncateLen is not a suitable variable to determine to do truncate or not.
   840  				var runeCount int
   841  				var truncateLen int
   842  				for i := range s {
   843  					if runeCount == flen {
   844  						truncateLen = i
   845  						break
   846  					}
   847  					runeCount++
   848  				}
   849  				err = ErrDataTooLong.GenWithStack("Data Too Long, field len %d, data len %d", flen, characterLen)
   850  				s = truncateStr(s, truncateLen)
   851  			}
   852  		} else if len(s) > flen {
   853  			err = ErrDataTooLong.GenWithStack("Data Too Long, field len %d, data len %d", flen, len(s))
   854  			s = truncateStr(s, flen)
   855  		} else if tp.Tp == mysql.TypeString && IsBinaryStr(tp) && len(s) < flen && padZero {
   856  			padding := make([]byte, flen-len(s))
   857  			s = string(append([]byte(s), padding...))
   858  		}
   859  	}
   860  	return s, errors.Trace(sc.HandleTruncate(err))
   861  }
   862  
   863  func (d *Datum) convertToInt(sc *stmtctx.StatementContext, target *FieldType) (Datum, error) {
   864  	i64, err := d.toSignedInteger(sc, target.Tp)
   865  	return NewIntDatum(i64), errors.Trace(err)
   866  }
   867  
   868  func (d *Datum) convertToUint(sc *stmtctx.StatementContext, target *FieldType) (Datum, error) {
   869  	tp := target.Tp
   870  	upperBound := UnsignedUpperBound[tp]
   871  	var (
   872  		val uint64
   873  		err error
   874  		ret Datum
   875  	)
   876  	switch d.k {
   877  	case KindInt64:
   878  		val, err = ConvertIntToUint(sc, d.GetInt64(), upperBound, tp)
   879  	case KindUint64:
   880  		val, err = ConvertUintToUint(d.GetUint64(), upperBound, tp)
   881  	case KindFloat32, KindFloat64:
   882  		val, err = ConvertFloatToUint(sc, d.GetFloat64(), upperBound, tp)
   883  	case KindString, KindBytes:
   884  		uval, err1 := StrToUint(sc, d.GetString())
   885  		if err1 != nil && ErrOverflow.Equal(err1) && !sc.ShouldIgnoreOverflowError() {
   886  			return ret, errors.Trace(err1)
   887  		}
   888  		val, err = ConvertUintToUint(uval, upperBound, tp)
   889  		if err != nil {
   890  			return ret, errors.Trace(err)
   891  		}
   892  		err = err1
   893  	case KindMysqlTime:
   894  		dec := d.GetMysqlTime().ToNumber()
   895  		err = dec.Round(dec, 0, ModeHalfEven)
   896  		ival, err1 := dec.ToInt()
   897  		if err == nil {
   898  			err = err1
   899  		}
   900  		val, err1 = ConvertIntToUint(sc, ival, upperBound, tp)
   901  		if err == nil {
   902  			err = err1
   903  		}
   904  	case KindMysqlDuration:
   905  		dec := d.GetMysqlDuration().ToNumber()
   906  		err = dec.Round(dec, 0, ModeHalfEven)
   907  		ival, err1 := dec.ToInt()
   908  		if err1 == nil {
   909  			val, err = ConvertIntToUint(sc, ival, upperBound, tp)
   910  		}
   911  	case KindMysqlDecimal:
   912  		fval, err1 := d.GetMysqlDecimal().ToFloat64()
   913  		val, err = ConvertFloatToUint(sc, fval, upperBound, tp)
   914  		if err == nil {
   915  			err = err1
   916  		}
   917  	case KindMysqlEnum:
   918  		val, err = ConvertFloatToUint(sc, d.GetMysqlEnum().ToNumber(), upperBound, tp)
   919  	case KindMysqlSet:
   920  		val, err = ConvertFloatToUint(sc, d.GetMysqlSet().ToNumber(), upperBound, tp)
   921  	case KindBinaryLiteral, KindMysqlBit:
   922  		val, err = d.GetBinaryLiteral().ToInt(sc)
   923  	case KindMysqlJSON:
   924  		var i64 int64
   925  		i64, err = ConvertJSONToInt(sc, d.GetMysqlJSON(), true)
   926  		val = uint64(i64)
   927  	default:
   928  		return invalidConv(d, target.Tp)
   929  	}
   930  	ret.SetUint64(val)
   931  	if err != nil {
   932  		return ret, errors.Trace(err)
   933  	}
   934  	return ret, nil
   935  }
   936  
   937  func (d *Datum) convertToMysqlTimestamp(sc *stmtctx.StatementContext, target *FieldType) (Datum, error) {
   938  	var (
   939  		ret Datum
   940  		t   Time
   941  		err error
   942  	)
   943  	fsp := DefaultFsp
   944  	if target.Decimal != UnspecifiedLength {
   945  		fsp = target.Decimal
   946  	}
   947  	switch d.k {
   948  	case KindMysqlTime:
   949  		t = d.GetMysqlTime()
   950  		t, err = t.RoundFrac(sc, fsp)
   951  	case KindMysqlDuration:
   952  		t, err = d.GetMysqlDuration().ConvertToTime(sc, mysql.TypeTimestamp)
   953  		if err != nil {
   954  			ret.SetValue(t)
   955  			return ret, errors.Trace(err)
   956  		}
   957  		t, err = t.RoundFrac(sc, fsp)
   958  	case KindString, KindBytes:
   959  		t, err = ParseTime(sc, d.GetString(), mysql.TypeTimestamp, fsp)
   960  	case KindInt64:
   961  		t, err = ParseTimeFromNum(sc, d.GetInt64(), mysql.TypeTimestamp, fsp)
   962  	default:
   963  		return invalidConv(d, mysql.TypeTimestamp)
   964  	}
   965  	t.Type = mysql.TypeTimestamp
   966  	ret.SetMysqlTime(t)
   967  	if err != nil {
   968  		return ret, errors.Trace(err)
   969  	}
   970  	return ret, nil
   971  }
   972  
   973  func (d *Datum) convertToMysqlTime(sc *stmtctx.StatementContext, target *FieldType) (Datum, error) {
   974  	tp := target.Tp
   975  	fsp := DefaultFsp
   976  	if target.Decimal != UnspecifiedLength {
   977  		fsp = target.Decimal
   978  	}
   979  	var (
   980  		ret Datum
   981  		t   Time
   982  		err error
   983  	)
   984  	switch d.k {
   985  	case KindMysqlTime:
   986  		t, err = d.GetMysqlTime().Convert(sc, tp)
   987  		if err != nil {
   988  			ret.SetValue(t)
   989  			return ret, errors.Trace(err)
   990  		}
   991  		t, err = t.RoundFrac(sc, fsp)
   992  	case KindMysqlDuration:
   993  		t, err = d.GetMysqlDuration().ConvertToTime(sc, tp)
   994  		if err != nil {
   995  			ret.SetValue(t)
   996  			return ret, errors.Trace(err)
   997  		}
   998  		t, err = t.RoundFrac(sc, fsp)
   999  	case KindString, KindBytes:
  1000  		t, err = ParseTime(sc, d.GetString(), tp, fsp)
  1001  	case KindInt64:
  1002  		t, err = ParseTimeFromNum(sc, d.GetInt64(), tp, fsp)
  1003  	default:
  1004  		return invalidConv(d, tp)
  1005  	}
  1006  	if tp == mysql.TypeDate {
  1007  		// Truncate hh:mm:ss part if the type is Date.
  1008  		t.Time = FromDate(t.Time.Year(), t.Time.Month(), t.Time.Day(), 0, 0, 0, 0)
  1009  	}
  1010  	ret.SetValue(t)
  1011  	if err != nil {
  1012  		return ret, errors.Trace(err)
  1013  	}
  1014  	return ret, nil
  1015  }
  1016  
  1017  func (d *Datum) convertToMysqlDuration(sc *stmtctx.StatementContext, target *FieldType) (Datum, error) {
  1018  	tp := target.Tp
  1019  	fsp := DefaultFsp
  1020  	if target.Decimal != UnspecifiedLength {
  1021  		fsp = target.Decimal
  1022  	}
  1023  	var ret Datum
  1024  	switch d.k {
  1025  	case KindMysqlTime:
  1026  		dur, err := d.GetMysqlTime().ConvertToDuration()
  1027  		if err != nil {
  1028  			ret.SetValue(dur)
  1029  			return ret, errors.Trace(err)
  1030  		}
  1031  		dur, err = dur.RoundFrac(fsp)
  1032  		ret.SetValue(dur)
  1033  		if err != nil {
  1034  			return ret, errors.Trace(err)
  1035  		}
  1036  	case KindMysqlDuration:
  1037  		dur, err := d.GetMysqlDuration().RoundFrac(fsp)
  1038  		ret.SetValue(dur)
  1039  		if err != nil {
  1040  			return ret, errors.Trace(err)
  1041  		}
  1042  	case KindInt64, KindFloat32, KindFloat64, KindMysqlDecimal:
  1043  		// TODO: We need a ParseDurationFromNum to avoid the cost of converting a num to string.
  1044  		timeStr, err := d.ToString()
  1045  		if err != nil {
  1046  			return ret, errors.Trace(err)
  1047  		}
  1048  		timeNum, err := d.ToInt64(sc)
  1049  		if err != nil {
  1050  			return ret, errors.Trace(err)
  1051  		}
  1052  		// For huge numbers(>'0001-00-00 00-00-00') try full DATETIME in ParseDuration.
  1053  		if timeNum > MaxDuration && timeNum < 10000000000 {
  1054  			// mysql return max in no strict sql mode.
  1055  			ret.SetValue(Duration{Duration: MaxTime, Fsp: 0})
  1056  			return ret, ErrInvalidTimeFormat.GenWithStack("Incorrect time value: '%s'", timeStr)
  1057  		}
  1058  		if timeNum < -MaxDuration {
  1059  			return ret, ErrInvalidTimeFormat.GenWithStack("Incorrect time value: '%s'", timeStr)
  1060  		}
  1061  		t, err := ParseDuration(sc, timeStr, fsp)
  1062  		ret.SetValue(t)
  1063  		if err != nil {
  1064  			return ret, errors.Trace(err)
  1065  		}
  1066  	case KindString, KindBytes:
  1067  		t, err := ParseDuration(sc, d.GetString(), fsp)
  1068  		ret.SetValue(t)
  1069  		if err != nil {
  1070  			return ret, errors.Trace(err)
  1071  		}
  1072  	default:
  1073  		return invalidConv(d, tp)
  1074  	}
  1075  	return ret, nil
  1076  }
  1077  
  1078  func (d *Datum) convertToMysqlDecimal(sc *stmtctx.StatementContext, target *FieldType) (Datum, error) {
  1079  	var ret Datum
  1080  	ret.SetLength(target.Flen)
  1081  	ret.SetFrac(target.Decimal)
  1082  	var dec = &MyDecimal{}
  1083  	var err error
  1084  	switch d.k {
  1085  	case KindInt64:
  1086  		dec.FromInt(d.GetInt64())
  1087  	case KindUint64:
  1088  		dec.FromUint(d.GetUint64())
  1089  	case KindFloat32, KindFloat64:
  1090  		err = dec.FromFloat64(d.GetFloat64())
  1091  	case KindString, KindBytes:
  1092  		err = dec.FromString(d.GetBytes())
  1093  	case KindMysqlDecimal:
  1094  		*dec = *d.GetMysqlDecimal()
  1095  	case KindMysqlTime:
  1096  		dec = d.GetMysqlTime().ToNumber()
  1097  	case KindMysqlDuration:
  1098  		dec = d.GetMysqlDuration().ToNumber()
  1099  	case KindMysqlEnum:
  1100  		err = dec.FromFloat64(d.GetMysqlEnum().ToNumber())
  1101  	case KindMysqlSet:
  1102  		err = dec.FromFloat64(d.GetMysqlSet().ToNumber())
  1103  	case KindBinaryLiteral, KindMysqlBit:
  1104  		val, err1 := d.GetBinaryLiteral().ToInt(sc)
  1105  		err = err1
  1106  		dec.FromUint(val)
  1107  	case KindMysqlJSON:
  1108  		f, err1 := ConvertJSONToFloat(sc, d.GetMysqlJSON())
  1109  		if err1 != nil {
  1110  			return ret, errors.Trace(err1)
  1111  		}
  1112  		err = dec.FromFloat64(f)
  1113  	default:
  1114  		return invalidConv(d, target.Tp)
  1115  	}
  1116  	var err1 error
  1117  	dec, err1 = ProduceDecWithSpecifiedTp(dec, target, sc)
  1118  	if err == nil && err1 != nil {
  1119  		err = err1
  1120  	}
  1121  	if dec.negative && mysql.HasUnsignedFlag(target.Flag) {
  1122  		*dec = zeroMyDecimal
  1123  		if err == nil {
  1124  			err = ErrOverflow.GenWithStackByArgs("DECIMAL", fmt.Sprintf("(%d, %d)", target.Flen, target.Decimal))
  1125  		}
  1126  	}
  1127  	ret.SetValue(dec)
  1128  	return ret, errors.Trace(err)
  1129  }
  1130  
  1131  // ProduceDecWithSpecifiedTp produces a new decimal according to `flen` and `decimal`.
  1132  func ProduceDecWithSpecifiedTp(dec *MyDecimal, tp *FieldType, sc *stmtctx.StatementContext) (_ *MyDecimal, err error) {
  1133  	flen, decimal := tp.Flen, tp.Decimal
  1134  	if flen != UnspecifiedLength && decimal != UnspecifiedLength {
  1135  		if flen < decimal {
  1136  			return nil, ErrMBiggerThanD.GenWithStackByArgs("")
  1137  		}
  1138  		prec, frac := dec.PrecisionAndFrac()
  1139  		if !dec.IsZero() && prec-frac > flen-decimal {
  1140  			dec = NewMaxOrMinDec(dec.IsNegative(), flen, decimal)
  1141  			// select (cast 111 as decimal(1)) causes a warning in MySQL.
  1142  			err = ErrOverflow.GenWithStackByArgs("DECIMAL", fmt.Sprintf("(%d, %d)", flen, decimal))
  1143  		} else if frac != decimal {
  1144  			old := *dec
  1145  			err = dec.Round(dec, decimal, ModeHalfEven)
  1146  			if err != nil {
  1147  				return nil, errors.Trace(err)
  1148  			}
  1149  			if !dec.IsZero() && frac > decimal && dec.Compare(&old) != 0 {
  1150  				if sc.InInsertStmt || sc.InUpdateStmt || sc.InDeleteStmt {
  1151  					// fix https://github.com/pingcap/tidb/issues/3895
  1152  					// fix https://github.com/pingcap/tidb/issues/5532
  1153  					sc.AppendWarning(ErrTruncated)
  1154  					err = nil
  1155  				} else {
  1156  					err = sc.HandleTruncate(ErrTruncated)
  1157  				}
  1158  			}
  1159  		}
  1160  	}
  1161  
  1162  	if ErrOverflow.Equal(err) {
  1163  		// TODO: warnErr need to be ErrWarnDataOutOfRange
  1164  		err = sc.HandleOverflow(err, err)
  1165  	}
  1166  	unsigned := mysql.HasUnsignedFlag(tp.Flag)
  1167  	if unsigned && dec.IsNegative() {
  1168  		dec = dec.FromUint(0)
  1169  	}
  1170  	return dec, errors.Trace(err)
  1171  }
  1172  
  1173  func (d *Datum) convertToMysqlYear(sc *stmtctx.StatementContext, target *FieldType) (Datum, error) {
  1174  	var (
  1175  		ret    Datum
  1176  		y      int64
  1177  		err    error
  1178  		adjust bool
  1179  	)
  1180  	switch d.k {
  1181  	case KindString, KindBytes:
  1182  		s := d.GetString()
  1183  		y, err = StrToInt(sc, s)
  1184  		if err != nil {
  1185  			return ret, errors.Trace(err)
  1186  		}
  1187  		adjust = len(s) < 4
  1188  	case KindMysqlTime:
  1189  		y = int64(d.GetMysqlTime().Time.Year())
  1190  	case KindMysqlDuration:
  1191  		y = int64(time.Now().Year())
  1192  	default:
  1193  		ret, err = d.convertToInt(sc, NewFieldType(mysql.TypeLonglong))
  1194  		if err != nil {
  1195  			return invalidConv(d, target.Tp)
  1196  		}
  1197  		y = ret.GetInt64()
  1198  	}
  1199  	y, err = AdjustYear(y, adjust)
  1200  	if err != nil {
  1201  		return invalidConv(d, target.Tp)
  1202  	}
  1203  	ret.SetInt64(y)
  1204  	return ret, nil
  1205  }
  1206  
  1207  func (d *Datum) convertToMysqlBit(sc *stmtctx.StatementContext, target *FieldType) (Datum, error) {
  1208  	var ret Datum
  1209  	var uintValue uint64
  1210  	var err error
  1211  	switch d.k {
  1212  	case KindString, KindBytes:
  1213  		uintValue, err = BinaryLiteral(d.b).ToInt(sc)
  1214  	default:
  1215  		uintDatum, err1 := d.convertToUint(sc, target)
  1216  		uintValue, err = uintDatum.GetUint64(), err1
  1217  	}
  1218  	if target.Flen < 64 && uintValue >= 1<<(uint64(target.Flen)) {
  1219  		return Datum{}, errors.Trace(ErrOverflow.GenWithStackByArgs("BIT", fmt.Sprintf("(%d)", target.Flen)))
  1220  	}
  1221  	byteSize := (target.Flen + 7) >> 3
  1222  	ret.SetMysqlBit(NewBinaryLiteralFromUint(uintValue, byteSize))
  1223  	return ret, errors.Trace(err)
  1224  }
  1225  
  1226  func (d *Datum) convertToMysqlEnum(sc *stmtctx.StatementContext, target *FieldType) (Datum, error) {
  1227  	var (
  1228  		ret Datum
  1229  		e   Enum
  1230  		err error
  1231  	)
  1232  	switch d.k {
  1233  	case KindString, KindBytes:
  1234  		e, err = ParseEnumName(target.Elems, d.GetString())
  1235  	default:
  1236  		var uintDatum Datum
  1237  		uintDatum, err = d.convertToUint(sc, target)
  1238  		if err != nil {
  1239  			return ret, errors.Trace(err)
  1240  		}
  1241  		e, err = ParseEnumValue(target.Elems, uintDatum.GetUint64())
  1242  	}
  1243  	if err != nil {
  1244  		log.Warn(err.Error())
  1245  		err = errors.Trace(ErrTruncated)
  1246  	}
  1247  	ret.SetValue(e)
  1248  	return ret, err
  1249  }
  1250  
  1251  func (d *Datum) convertToMysqlSet(sc *stmtctx.StatementContext, target *FieldType) (Datum, error) {
  1252  	var (
  1253  		ret Datum
  1254  		s   Set
  1255  		err error
  1256  	)
  1257  	switch d.k {
  1258  	case KindString, KindBytes:
  1259  		s, err = ParseSetName(target.Elems, d.GetString())
  1260  	default:
  1261  		var uintDatum Datum
  1262  		uintDatum, err = d.convertToUint(sc, target)
  1263  		if err != nil {
  1264  			return ret, errors.Trace(err)
  1265  		}
  1266  		s, err = ParseSetValue(target.Elems, uintDatum.GetUint64())
  1267  	}
  1268  
  1269  	if err != nil {
  1270  		return invalidConv(d, target.Tp)
  1271  	}
  1272  	ret.SetValue(s)
  1273  	return ret, nil
  1274  }
  1275  
  1276  func (d *Datum) convertToMysqlJSON(sc *stmtctx.StatementContext, target *FieldType) (ret Datum, err error) {
  1277  	switch d.k {
  1278  	case KindString, KindBytes:
  1279  		var j json.BinaryJSON
  1280  		if j, err = json.ParseBinaryFromString(d.GetString()); err == nil {
  1281  			ret.SetMysqlJSON(j)
  1282  		}
  1283  	case KindInt64:
  1284  		i64 := d.GetInt64()
  1285  		ret.SetMysqlJSON(json.CreateBinary(i64))
  1286  	case KindUint64:
  1287  		u64 := d.GetUint64()
  1288  		ret.SetMysqlJSON(json.CreateBinary(u64))
  1289  	case KindFloat32, KindFloat64:
  1290  		f64 := d.GetFloat64()
  1291  		ret.SetMysqlJSON(json.CreateBinary(f64))
  1292  	case KindMysqlDecimal:
  1293  		var f64 float64
  1294  		if f64, err = d.GetMysqlDecimal().ToFloat64(); err == nil {
  1295  			ret.SetMysqlJSON(json.CreateBinary(f64))
  1296  		}
  1297  	case KindMysqlJSON:
  1298  		ret = *d
  1299  	default:
  1300  		var s string
  1301  		if s, err = d.ToString(); err == nil {
  1302  			// TODO: fix precision of MysqlTime. For example,
  1303  			// On MySQL 5.7 CAST(NOW() AS JSON) -> "2011-11-11 11:11:11.111111",
  1304  			// But now we can only return "2011-11-11 11:11:11".
  1305  			ret.SetMysqlJSON(json.CreateBinary(s))
  1306  		}
  1307  	}
  1308  	return ret, errors.Trace(err)
  1309  }
  1310  
  1311  // ToBool converts to a bool.
  1312  // We will use 1 for true, and 0 for false.
  1313  func (d *Datum) ToBool(sc *stmtctx.StatementContext) (int64, error) {
  1314  	var err error
  1315  	isZero := false
  1316  	switch d.Kind() {
  1317  	case KindInt64:
  1318  		isZero = d.GetInt64() == 0
  1319  	case KindUint64:
  1320  		isZero = d.GetUint64() == 0
  1321  	case KindFloat32:
  1322  		isZero = RoundFloat(d.GetFloat64()) == 0
  1323  	case KindFloat64:
  1324  		isZero = RoundFloat(d.GetFloat64()) == 0
  1325  	case KindString, KindBytes:
  1326  		iVal, err1 := StrToInt(sc, d.GetString())
  1327  		isZero, err = iVal == 0, err1
  1328  	case KindMysqlTime:
  1329  		isZero = d.GetMysqlTime().IsZero()
  1330  	case KindMysqlDuration:
  1331  		isZero = d.GetMysqlDuration().Duration == 0
  1332  	case KindMysqlDecimal:
  1333  		v, err1 := d.GetMysqlDecimal().ToFloat64()
  1334  		isZero, err = RoundFloat(v) == 0, err1
  1335  	case KindMysqlEnum:
  1336  		isZero = d.GetMysqlEnum().ToNumber() == 0
  1337  	case KindMysqlSet:
  1338  		isZero = d.GetMysqlSet().ToNumber() == 0
  1339  	case KindBinaryLiteral, KindMysqlBit:
  1340  		val, err1 := d.GetBinaryLiteral().ToInt(sc)
  1341  		isZero, err = val == 0, err1
  1342  	default:
  1343  		return 0, errors.Errorf("cannot convert %v(type %T) to bool", d.GetValue(), d.GetValue())
  1344  	}
  1345  	var ret int64
  1346  	if isZero {
  1347  		ret = 0
  1348  	} else {
  1349  		ret = 1
  1350  	}
  1351  	if err != nil {
  1352  		return ret, errors.Trace(err)
  1353  	}
  1354  	return ret, nil
  1355  }
  1356  
  1357  // ConvertDatumToDecimal converts datum to decimal.
  1358  func ConvertDatumToDecimal(sc *stmtctx.StatementContext, d Datum) (*MyDecimal, error) {
  1359  	dec := new(MyDecimal)
  1360  	var err error
  1361  	switch d.Kind() {
  1362  	case KindInt64:
  1363  		dec.FromInt(d.GetInt64())
  1364  	case KindUint64:
  1365  		dec.FromUint(d.GetUint64())
  1366  	case KindFloat32:
  1367  		err = dec.FromFloat64(float64(d.GetFloat32()))
  1368  	case KindFloat64:
  1369  		err = dec.FromFloat64(d.GetFloat64())
  1370  	case KindString:
  1371  		err = sc.HandleTruncate(dec.FromString(d.GetBytes()))
  1372  	case KindMysqlDecimal:
  1373  		*dec = *d.GetMysqlDecimal()
  1374  	case KindMysqlEnum:
  1375  		dec.FromUint(d.GetMysqlEnum().Value)
  1376  	case KindMysqlSet:
  1377  		dec.FromUint(d.GetMysqlSet().Value)
  1378  	case KindBinaryLiteral, KindMysqlBit:
  1379  		val, err1 := d.GetBinaryLiteral().ToInt(sc)
  1380  		dec.FromUint(val)
  1381  		err = err1
  1382  	case KindMysqlJSON:
  1383  		f, err1 := ConvertJSONToFloat(sc, d.GetMysqlJSON())
  1384  		if err1 != nil {
  1385  			return nil, errors.Trace(err1)
  1386  		}
  1387  		err = dec.FromFloat64(f)
  1388  	default:
  1389  		err = fmt.Errorf("can't convert %v to decimal", d.GetValue())
  1390  	}
  1391  	return dec, errors.Trace(err)
  1392  }
  1393  
  1394  // ToDecimal converts to a decimal.
  1395  func (d *Datum) ToDecimal(sc *stmtctx.StatementContext) (*MyDecimal, error) {
  1396  	switch d.Kind() {
  1397  	case KindMysqlTime:
  1398  		return d.GetMysqlTime().ToNumber(), nil
  1399  	case KindMysqlDuration:
  1400  		return d.GetMysqlDuration().ToNumber(), nil
  1401  	default:
  1402  		return ConvertDatumToDecimal(sc, *d)
  1403  	}
  1404  }
  1405  
  1406  // ToInt64 converts to a int64.
  1407  func (d *Datum) ToInt64(sc *stmtctx.StatementContext) (int64, error) {
  1408  	return d.toSignedInteger(sc, mysql.TypeLonglong)
  1409  }
  1410  
  1411  func (d *Datum) toSignedInteger(sc *stmtctx.StatementContext, tp byte) (int64, error) {
  1412  	lowerBound := SignedLowerBound[tp]
  1413  	upperBound := SignedUpperBound[tp]
  1414  	switch d.Kind() {
  1415  	case KindInt64:
  1416  		return ConvertIntToInt(d.GetInt64(), lowerBound, upperBound, tp)
  1417  	case KindUint64:
  1418  		return ConvertUintToInt(d.GetUint64(), upperBound, tp)
  1419  	case KindFloat32:
  1420  		return ConvertFloatToInt(float64(d.GetFloat32()), lowerBound, upperBound, tp)
  1421  	case KindFloat64:
  1422  		return ConvertFloatToInt(d.GetFloat64(), lowerBound, upperBound, tp)
  1423  	case KindString, KindBytes:
  1424  		iVal, err := StrToInt(sc, d.GetString())
  1425  		iVal, err2 := ConvertIntToInt(iVal, lowerBound, upperBound, tp)
  1426  		if err == nil {
  1427  			err = err2
  1428  		}
  1429  		return iVal, errors.Trace(err)
  1430  	case KindMysqlTime:
  1431  		// 2011-11-10 11:11:11.999999 -> 20111110111112
  1432  		// 2011-11-10 11:59:59.999999 -> 20111110120000
  1433  		t, err := d.GetMysqlTime().RoundFrac(sc, DefaultFsp)
  1434  		if err != nil {
  1435  			return 0, errors.Trace(err)
  1436  		}
  1437  		ival, err := t.ToNumber().ToInt()
  1438  		ival, err2 := ConvertIntToInt(ival, lowerBound, upperBound, tp)
  1439  		if err == nil {
  1440  			err = err2
  1441  		}
  1442  		return ival, errors.Trace(err)
  1443  	case KindMysqlDuration:
  1444  		// 11:11:11.999999 -> 111112
  1445  		// 11:59:59.999999 -> 120000
  1446  		dur, err := d.GetMysqlDuration().RoundFrac(DefaultFsp)
  1447  		if err != nil {
  1448  			return 0, errors.Trace(err)
  1449  		}
  1450  		ival, err := dur.ToNumber().ToInt()
  1451  		ival, err2 := ConvertIntToInt(ival, lowerBound, upperBound, tp)
  1452  		if err == nil {
  1453  			err = err2
  1454  		}
  1455  		return ival, errors.Trace(err)
  1456  	case KindMysqlDecimal:
  1457  		var to MyDecimal
  1458  		err := d.GetMysqlDecimal().Round(&to, 0, ModeHalfEven)
  1459  		ival, err1 := to.ToInt()
  1460  		if err == nil {
  1461  			err = err1
  1462  		}
  1463  		ival, err2 := ConvertIntToInt(ival, lowerBound, upperBound, tp)
  1464  		if err == nil {
  1465  			err = err2
  1466  		}
  1467  		return ival, errors.Trace(err)
  1468  	case KindMysqlEnum:
  1469  		fval := d.GetMysqlEnum().ToNumber()
  1470  		return ConvertFloatToInt(fval, lowerBound, upperBound, tp)
  1471  	case KindMysqlSet:
  1472  		fval := d.GetMysqlSet().ToNumber()
  1473  		return ConvertFloatToInt(fval, lowerBound, upperBound, tp)
  1474  	case KindMysqlJSON:
  1475  		return ConvertJSONToInt(sc, d.GetMysqlJSON(), false)
  1476  	case KindBinaryLiteral, KindMysqlBit:
  1477  		val, err := d.GetBinaryLiteral().ToInt(sc)
  1478  		return int64(val), errors.Trace(err)
  1479  	default:
  1480  		return 0, errors.Errorf("cannot convert %v(type %T) to int64", d.GetValue(), d.GetValue())
  1481  	}
  1482  }
  1483  
  1484  // ToFloat64 converts to a float64
  1485  func (d *Datum) ToFloat64(sc *stmtctx.StatementContext) (float64, error) {
  1486  	switch d.Kind() {
  1487  	case KindInt64:
  1488  		return float64(d.GetInt64()), nil
  1489  	case KindUint64:
  1490  		return float64(d.GetUint64()), nil
  1491  	case KindFloat32:
  1492  		return float64(d.GetFloat32()), nil
  1493  	case KindFloat64:
  1494  		return d.GetFloat64(), nil
  1495  	case KindString:
  1496  		return StrToFloat(sc, d.GetString())
  1497  	case KindBytes:
  1498  		return StrToFloat(sc, string(d.GetBytes()))
  1499  	case KindMysqlTime:
  1500  		f, err := d.GetMysqlTime().ToNumber().ToFloat64()
  1501  		return f, errors.Trace(err)
  1502  	case KindMysqlDuration:
  1503  		f, err := d.GetMysqlDuration().ToNumber().ToFloat64()
  1504  		return f, errors.Trace(err)
  1505  	case KindMysqlDecimal:
  1506  		f, err := d.GetMysqlDecimal().ToFloat64()
  1507  		return f, errors.Trace(err)
  1508  	case KindMysqlEnum:
  1509  		return d.GetMysqlEnum().ToNumber(), nil
  1510  	case KindMysqlSet:
  1511  		return d.GetMysqlSet().ToNumber(), nil
  1512  	case KindBinaryLiteral, KindMysqlBit:
  1513  		val, err := d.GetBinaryLiteral().ToInt(sc)
  1514  		return float64(val), errors.Trace(err)
  1515  	case KindMysqlJSON:
  1516  		f, err := ConvertJSONToFloat(sc, d.GetMysqlJSON())
  1517  		return f, errors.Trace(err)
  1518  	default:
  1519  		return 0, errors.Errorf("cannot convert %v(type %T) to float64", d.GetValue(), d.GetValue())
  1520  	}
  1521  }
  1522  
  1523  // ToString gets the string representation of the datum.
  1524  func (d *Datum) ToString() (string, error) {
  1525  	switch d.Kind() {
  1526  	case KindInt64:
  1527  		return strconv.FormatInt(d.GetInt64(), 10), nil
  1528  	case KindUint64:
  1529  		return strconv.FormatUint(d.GetUint64(), 10), nil
  1530  	case KindFloat32:
  1531  		return strconv.FormatFloat(float64(d.GetFloat32()), 'f', -1, 32), nil
  1532  	case KindFloat64:
  1533  		return strconv.FormatFloat(d.GetFloat64(), 'f', -1, 64), nil
  1534  	case KindString:
  1535  		return d.GetString(), nil
  1536  	case KindBytes:
  1537  		return d.GetString(), nil
  1538  	case KindMysqlTime:
  1539  		return d.GetMysqlTime().String(), nil
  1540  	case KindMysqlDuration:
  1541  		return d.GetMysqlDuration().String(), nil
  1542  	case KindMysqlDecimal:
  1543  		return d.GetMysqlDecimal().String(), nil
  1544  	case KindMysqlEnum:
  1545  		return d.GetMysqlEnum().String(), nil
  1546  	case KindMysqlSet:
  1547  		return d.GetMysqlSet().String(), nil
  1548  	case KindMysqlJSON:
  1549  		return d.GetMysqlJSON().String(), nil
  1550  	case KindBinaryLiteral, KindMysqlBit:
  1551  		return d.GetBinaryLiteral().ToString(), nil
  1552  	default:
  1553  		return "", errors.Errorf("cannot convert %v(type %T) to string", d.GetValue(), d.GetValue())
  1554  	}
  1555  }
  1556  
  1557  // ToBytes gets the bytes representation of the datum.
  1558  func (d *Datum) ToBytes() ([]byte, error) {
  1559  	switch d.k {
  1560  	case KindString, KindBytes:
  1561  		return d.GetBytes(), nil
  1562  	default:
  1563  		str, err := d.ToString()
  1564  		if err != nil {
  1565  			return nil, errors.Trace(err)
  1566  		}
  1567  		return []byte(str), nil
  1568  	}
  1569  }
  1570  
  1571  // ToMysqlJSON is similar to convertToMysqlJSON, except the
  1572  // latter parses from string, but the former uses it as primitive.
  1573  func (d *Datum) ToMysqlJSON() (j json.BinaryJSON, err error) {
  1574  	var in interface{}
  1575  	switch d.Kind() {
  1576  	case KindMysqlJSON:
  1577  		j = d.GetMysqlJSON()
  1578  		return
  1579  	case KindInt64:
  1580  		in = d.GetInt64()
  1581  	case KindUint64:
  1582  		in = d.GetUint64()
  1583  	case KindFloat32, KindFloat64:
  1584  		in = d.GetFloat64()
  1585  	case KindMysqlDecimal:
  1586  		in, err = d.GetMysqlDecimal().ToFloat64()
  1587  	case KindString, KindBytes:
  1588  		in = d.GetString()
  1589  	case KindBinaryLiteral, KindMysqlBit:
  1590  		in = d.GetBinaryLiteral().ToString()
  1591  	case KindNull:
  1592  		in = nil
  1593  	default:
  1594  		in, err = d.ToString()
  1595  	}
  1596  	if err != nil {
  1597  		err = errors.Trace(err)
  1598  		return
  1599  	}
  1600  	j = json.CreateBinary(in)
  1601  	return
  1602  }
  1603  
  1604  func invalidConv(d *Datum, tp byte) (Datum, error) {
  1605  	return Datum{}, errors.Errorf("cannot convert datum from %s to type %s.", KindStr(d.Kind()), TypeStr(tp))
  1606  }
  1607  
  1608  func (d *Datum) convergeType(hasUint, hasDecimal, hasFloat *bool) (x Datum) {
  1609  	x = *d
  1610  	switch d.Kind() {
  1611  	case KindUint64:
  1612  		*hasUint = true
  1613  	case KindFloat32:
  1614  		f := d.GetFloat32()
  1615  		x.SetFloat64(float64(f))
  1616  		*hasFloat = true
  1617  	case KindFloat64:
  1618  		*hasFloat = true
  1619  	case KindMysqlDecimal:
  1620  		*hasDecimal = true
  1621  	}
  1622  	return x
  1623  }
  1624  
  1625  // NewDatum creates a new Datum from an interface{}.
  1626  func NewDatum(in interface{}) (d Datum) {
  1627  	switch x := in.(type) {
  1628  	case []interface{}:
  1629  		d.SetValue(MakeDatums(x...))
  1630  	default:
  1631  		d.SetValue(in)
  1632  	}
  1633  	return d
  1634  }
  1635  
  1636  // NewIntDatum creates a new Datum from an int64 value.
  1637  func NewIntDatum(i int64) (d Datum) {
  1638  	d.SetInt64(i)
  1639  	return d
  1640  }
  1641  
  1642  // NewUintDatum creates a new Datum from an uint64 value.
  1643  func NewUintDatum(i uint64) (d Datum) {
  1644  	d.SetUint64(i)
  1645  	return d
  1646  }
  1647  
  1648  // NewBytesDatum creates a new Datum from a byte slice.
  1649  func NewBytesDatum(b []byte) (d Datum) {
  1650  	d.SetBytes(b)
  1651  	return d
  1652  }
  1653  
  1654  // NewStringDatum creates a new Datum from a string.
  1655  func NewStringDatum(s string) (d Datum) {
  1656  	d.SetString(s)
  1657  	return d
  1658  }
  1659  
  1660  // NewFloat64Datum creates a new Datum from a float64 value.
  1661  func NewFloat64Datum(f float64) (d Datum) {
  1662  	d.SetFloat64(f)
  1663  	return d
  1664  }
  1665  
  1666  // NewFloat32Datum creates a new Datum from a float32 value.
  1667  func NewFloat32Datum(f float32) (d Datum) {
  1668  	d.SetFloat32(f)
  1669  	return d
  1670  }
  1671  
  1672  // NewDurationDatum creates a new Datum from a Duration value.
  1673  func NewDurationDatum(dur Duration) (d Datum) {
  1674  	d.SetMysqlDuration(dur)
  1675  	return d
  1676  }
  1677  
  1678  // NewTimeDatum creates a new Time from a Time value.
  1679  func NewTimeDatum(t Time) (d Datum) {
  1680  	d.SetMysqlTime(t)
  1681  	return d
  1682  }
  1683  
  1684  // NewDecimalDatum creates a new Datum form a MyDecimal value.
  1685  func NewDecimalDatum(dec *MyDecimal) (d Datum) {
  1686  	d.SetMysqlDecimal(dec)
  1687  	return d
  1688  }
  1689  
  1690  // NewBinaryLiteralDatum creates a new BinaryLiteral Datum for a BinaryLiteral value.
  1691  func NewBinaryLiteralDatum(b BinaryLiteral) (d Datum) {
  1692  	d.SetBinaryLiteral(b)
  1693  	return d
  1694  }
  1695  
  1696  // NewMysqlBitDatum creates a new MysqlBit Datum for a BinaryLiteral value.
  1697  func NewMysqlBitDatum(b BinaryLiteral) (d Datum) {
  1698  	d.SetMysqlBit(b)
  1699  	return d
  1700  }
  1701  
  1702  // NewMysqlEnumDatum creates a new MysqlEnum Datum for a Enum value.
  1703  func NewMysqlEnumDatum(e Enum) (d Datum) {
  1704  	d.SetMysqlEnum(e)
  1705  	return d
  1706  }
  1707  
  1708  // MakeDatums creates datum slice from interfaces.
  1709  func MakeDatums(args ...interface{}) []Datum {
  1710  	datums := make([]Datum, len(args))
  1711  	for i, v := range args {
  1712  		datums[i] = NewDatum(v)
  1713  	}
  1714  	return datums
  1715  }
  1716  
  1717  // MinNotNullDatum returns a datum represents minimum not null value.
  1718  func MinNotNullDatum() Datum {
  1719  	return Datum{k: KindMinNotNull}
  1720  }
  1721  
  1722  // MaxValueDatum returns a datum represents max value.
  1723  func MaxValueDatum() Datum {
  1724  	return Datum{k: KindMaxValue}
  1725  }
  1726  
  1727  // EqualDatums compare if a and b contains the same datum values.
  1728  func EqualDatums(sc *stmtctx.StatementContext, a []Datum, b []Datum) (bool, error) {
  1729  	if len(a) != len(b) {
  1730  		return false, nil
  1731  	}
  1732  	if a == nil && b == nil {
  1733  		return true, nil
  1734  	}
  1735  	if a == nil || b == nil {
  1736  		return false, nil
  1737  	}
  1738  	for i, ai := range a {
  1739  		v, err := ai.CompareDatum(sc, &b[i])
  1740  		if err != nil {
  1741  			return false, errors.Trace(err)
  1742  		}
  1743  		if v != 0 {
  1744  			return false, nil
  1745  		}
  1746  	}
  1747  	return true, nil
  1748  }
  1749  
  1750  // SortDatums sorts a slice of datum.
  1751  func SortDatums(sc *stmtctx.StatementContext, datums []Datum) error {
  1752  	sorter := datumsSorter{datums: datums, sc: sc}
  1753  	sort.Sort(&sorter)
  1754  	return sorter.err
  1755  }
  1756  
  1757  type datumsSorter struct {
  1758  	datums []Datum
  1759  	sc     *stmtctx.StatementContext
  1760  	err    error
  1761  }
  1762  
  1763  func (ds *datumsSorter) Len() int {
  1764  	return len(ds.datums)
  1765  }
  1766  
  1767  func (ds *datumsSorter) Less(i, j int) bool {
  1768  	cmp, err := ds.datums[i].CompareDatum(ds.sc, &ds.datums[j])
  1769  	if err != nil {
  1770  		ds.err = errors.Trace(err)
  1771  		return true
  1772  	}
  1773  	return cmp < 0
  1774  }
  1775  
  1776  func (ds *datumsSorter) Swap(i, j int) {
  1777  	ds.datums[i], ds.datums[j] = ds.datums[j], ds.datums[i]
  1778  }
  1779  
  1780  func handleTruncateError(sc *stmtctx.StatementContext) error {
  1781  	if sc.IgnoreTruncate {
  1782  		return nil
  1783  	}
  1784  	if !sc.TruncateAsWarning {
  1785  		return ErrTruncated
  1786  	}
  1787  	sc.AppendWarning(ErrTruncated)
  1788  	return nil
  1789  }
  1790  
  1791  // DatumsToString converts several datums to formatted string.
  1792  func DatumsToString(datums []Datum, handleSpecialValue bool) (string, error) {
  1793  	var strs []string
  1794  	for _, datum := range datums {
  1795  		if handleSpecialValue {
  1796  			switch datum.Kind() {
  1797  			case KindNull:
  1798  				strs = append(strs, "NULL")
  1799  				continue
  1800  			case KindMinNotNull:
  1801  				strs = append(strs, "-inf")
  1802  				continue
  1803  			case KindMaxValue:
  1804  				strs = append(strs, "+inf")
  1805  				continue
  1806  			}
  1807  		}
  1808  		str, err := datum.ToString()
  1809  		if err != nil {
  1810  			return "", errors.Trace(err)
  1811  		}
  1812  		strs = append(strs, str)
  1813  	}
  1814  	size := len(datums)
  1815  	if size > 1 {
  1816  		strs[0] = "(" + strs[0]
  1817  		strs[size-1] = strs[size-1] + ")"
  1818  	}
  1819  	return strings.Join(strs, ", "), nil
  1820  }
  1821  
  1822  // DatumsToStrNoErr converts some datums to a formatted string.
  1823  // If an error occurs, it will print a log instead of returning an error.
  1824  func DatumsToStrNoErr(datums []Datum) string {
  1825  	str, err := DatumsToString(datums, true)
  1826  	terror.Log(errors.Trace(err))
  1827  	return str
  1828  }
  1829  
  1830  // CopyDatum returns a new copy of the datum.
  1831  // TODO: Abandon this function.
  1832  func CopyDatum(datum Datum) Datum {
  1833  	return *datum.Copy()
  1834  }
  1835  
  1836  // CopyRow deep copies a Datum slice.
  1837  func CopyRow(dr []Datum) []Datum {
  1838  	c := make([]Datum, len(dr))
  1839  	for i, d := range dr {
  1840  		c[i] = *d.Copy()
  1841  	}
  1842  	return c
  1843  }