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

     1  // Copyright 2015 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  	"time"
    18  
    19  	. "github.com/pingcap/check"
    20  
    21  	"github.com/XiaoMi/Gaea/mysql"
    22  	"github.com/XiaoMi/Gaea/parser/stmtctx"
    23  	"github.com/XiaoMi/Gaea/util/testleak"
    24  )
    25  
    26  var _ = Suite(&testCompareSuite{})
    27  
    28  type testCompareSuite struct {
    29  }
    30  
    31  func (s *testCompareSuite) TestCompare(c *C) {
    32  	defer testleak.AfterTest(c)()
    33  	cmpTbl := []struct {
    34  		lhs interface{}
    35  		rhs interface{}
    36  		ret int // 0, 1, -1
    37  	}{
    38  		{float64(1), float64(1), 0},
    39  		{float64(1), "1", 0},
    40  		{int64(1), int64(1), 0},
    41  		{int64(-1), uint64(1), -1},
    42  		{int64(-1), "-1", 0},
    43  		{uint64(1), uint64(1), 0},
    44  		{uint64(1), int64(-1), 1},
    45  		{uint64(1), "1", 0},
    46  		{NewDecFromInt(1), NewDecFromInt(1), 0},
    47  		{NewDecFromInt(1), "1", 0},
    48  		{NewDecFromInt(1), []byte("1"), 0},
    49  		{"1", "1", 0},
    50  		{"1", int64(-1), 1},
    51  		{"1", float64(2), -1},
    52  		{"1", uint64(1), 0},
    53  		{"1", NewDecFromInt(1), 0},
    54  		{"2011-01-01 11:11:11", Time{Time: FromGoTime(time.Now()), Type: mysql.TypeDatetime, Fsp: 0}, -1},
    55  		{"12:00:00", ZeroDuration, 1},
    56  		{ZeroDuration, ZeroDuration, 0},
    57  		{Time{Time: FromGoTime(time.Now().Add(time.Second * 10)), Type: mysql.TypeDatetime, Fsp: 0},
    58  			Time{Time: FromGoTime(time.Now()), Type: mysql.TypeDatetime, Fsp: 0}, 1},
    59  
    60  		{nil, 2, -1},
    61  		{nil, nil, 0},
    62  
    63  		{false, nil, 1},
    64  		{false, true, -1},
    65  		{true, true, 0},
    66  		{false, false, 0},
    67  		{true, 2, -1},
    68  
    69  		{float64(1.23), nil, 1},
    70  		{float64(0.0), float64(3.45), -1},
    71  		{float64(354.23), float64(3.45), 1},
    72  		{float64(3.452), float64(3.452), 0},
    73  
    74  		{int(432), nil, 1},
    75  		{-4, int(32), -1},
    76  		{int(4), -32, 1},
    77  		{int(432), int64(12), 1},
    78  		{int(23), int64(128), -1},
    79  		{int(123), int64(123), 0},
    80  		{int(432), int(12), 1},
    81  		{int(23), int(123), -1},
    82  		{int64(133), int(183), -1},
    83  
    84  		{uint64(133), uint64(183), -1},
    85  		{uint64(2), int64(-2), 1},
    86  		{uint64(2), int64(1), 1},
    87  
    88  		{"", nil, 1},
    89  		{"", "24", -1},
    90  		{"aasf", "4", 1},
    91  		{"", "", 0},
    92  
    93  		{[]byte(""), nil, 1},
    94  		{[]byte(""), []byte("sff"), -1},
    95  
    96  		{Time{Time: ZeroTime}, nil, 1},
    97  		{Time{Time: ZeroTime}, Time{Time: FromGoTime(time.Now()), Type: mysql.TypeDatetime, Fsp: 3}, -1},
    98  		{Time{Time: FromGoTime(time.Now()), Type: mysql.TypeDatetime, Fsp: 3}, "0000-00-00 00:00:00", 1},
    99  
   100  		{Duration{Duration: time.Duration(34), Fsp: 2}, nil, 1},
   101  		{Duration{Duration: time.Duration(34), Fsp: 2}, Duration{Duration: time.Duration(29034), Fsp: 2}, -1},
   102  		{Duration{Duration: time.Duration(3340), Fsp: 2}, Duration{Duration: time.Duration(34), Fsp: 2}, 1},
   103  		{Duration{Duration: time.Duration(34), Fsp: 2}, Duration{Duration: time.Duration(34), Fsp: 2}, 0},
   104  
   105  		{[]byte{}, []byte{}, 0},
   106  		{[]byte("abc"), []byte("ab"), 1},
   107  		{[]byte("123"), 1234, -1},
   108  		{[]byte{}, nil, 1},
   109  
   110  		{NewBinaryLiteralFromUint(1, -1), 1, 0},
   111  		{NewBinaryLiteralFromUint(0x4D7953514C, -1), "MySQL", 0},
   112  		{NewBinaryLiteralFromUint(0, -1), uint64(10), -1},
   113  		{NewBinaryLiteralFromUint(1, -1), float64(0), 1},
   114  		{NewBinaryLiteralFromUint(1, -1), NewDecFromInt(1), 0},
   115  		{NewBinaryLiteralFromUint(1, -1), NewBinaryLiteralFromUint(0, -1), 1},
   116  		{NewBinaryLiteralFromUint(1, -1), NewBinaryLiteralFromUint(1, -1), 0},
   117  
   118  		{Enum{Name: "a", Value: 1}, 1, 0},
   119  		{Enum{Name: "a", Value: 1}, "a", 0},
   120  		{Enum{Name: "a", Value: 1}, uint64(10), -1},
   121  		{Enum{Name: "a", Value: 1}, float64(0), 1},
   122  		{Enum{Name: "a", Value: 1}, NewDecFromInt(1), 0},
   123  		{Enum{Name: "a", Value: 1}, NewBinaryLiteralFromUint(2, -1), -1},
   124  		{Enum{Name: "a", Value: 1}, NewBinaryLiteralFromUint(1, -1), 0},
   125  		{Enum{Name: "a", Value: 1}, Enum{Name: "a", Value: 1}, 0},
   126  
   127  		{Set{Name: "a", Value: 1}, 1, 0},
   128  		{Set{Name: "a", Value: 1}, "a", 0},
   129  		{Set{Name: "a", Value: 1}, uint64(10), -1},
   130  		{Set{Name: "a", Value: 1}, float64(0), 1},
   131  		{Set{Name: "a", Value: 1}, NewDecFromInt(1), 0},
   132  		{Set{Name: "a", Value: 1}, NewBinaryLiteralFromUint(2, -1), -1},
   133  		{Set{Name: "a", Value: 1}, NewBinaryLiteralFromUint(1, -1), 0},
   134  		{Set{Name: "a", Value: 1}, Enum{Name: "a", Value: 1}, 0},
   135  		{Set{Name: "a", Value: 1}, Set{Name: "a", Value: 1}, 0},
   136  
   137  		{"hello", NewDecFromInt(0), 0}, // compatible with MySQL.
   138  		{NewDecFromInt(0), "hello", 0},
   139  	}
   140  
   141  	for i, t := range cmpTbl {
   142  		comment := Commentf("%d %v %v", i, t.lhs, t.rhs)
   143  		ret, err := compareForTest(t.lhs, t.rhs)
   144  		c.Assert(err, IsNil)
   145  		c.Assert(ret, Equals, t.ret, comment)
   146  
   147  		ret, err = compareForTest(t.rhs, t.lhs)
   148  		c.Assert(err, IsNil)
   149  		c.Assert(ret, Equals, -t.ret, comment)
   150  	}
   151  }
   152  
   153  func compareForTest(a, b interface{}) (int, error) {
   154  	sc := new(stmtctx.StatementContext)
   155  	sc.IgnoreTruncate = true
   156  	aDatum := NewDatum(a)
   157  	bDatum := NewDatum(b)
   158  	return aDatum.CompareDatum(sc, &bDatum)
   159  }
   160  
   161  func (s *testCompareSuite) TestCompareDatum(c *C) {
   162  	defer testleak.AfterTest(c)()
   163  	cmpTbl := []struct {
   164  		lhs Datum
   165  		rhs Datum
   166  		ret int // 0, 1, -1
   167  	}{
   168  		{MaxValueDatum(), NewDatum("00:00:00"), 1},
   169  		{MinNotNullDatum(), NewDatum("00:00:00"), -1},
   170  		{Datum{}, NewDatum("00:00:00"), -1},
   171  		{Datum{}, Datum{}, 0},
   172  		{MinNotNullDatum(), MinNotNullDatum(), 0},
   173  		{MaxValueDatum(), MaxValueDatum(), 0},
   174  		{Datum{}, MinNotNullDatum(), -1},
   175  		{MinNotNullDatum(), MaxValueDatum(), -1},
   176  	}
   177  	sc := new(stmtctx.StatementContext)
   178  	sc.IgnoreTruncate = true
   179  	for i, t := range cmpTbl {
   180  		comment := Commentf("%d %v %v", i, t.lhs, t.rhs)
   181  		ret, err := t.lhs.CompareDatum(sc, &t.rhs)
   182  		c.Assert(err, IsNil)
   183  		c.Assert(ret, Equals, t.ret, comment)
   184  
   185  		ret, err = t.rhs.CompareDatum(sc, &t.lhs)
   186  		c.Assert(err, IsNil)
   187  		c.Assert(ret, Equals, -t.ret, comment)
   188  	}
   189  }