github.com/XiaoMi/Gaea@v1.2.5/parser/tidb-types/overflow_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  	"math"
    18  
    19  	. "github.com/pingcap/check"
    20  
    21  	"github.com/XiaoMi/Gaea/util/testleak"
    22  )
    23  
    24  var _ = Suite(&testOverflowSuite{})
    25  
    26  type testOverflowSuite struct {
    27  }
    28  
    29  func (s *testOverflowSuite) TestAdd(c *C) {
    30  	defer testleak.AfterTest(c)()
    31  	tblUint64 := []struct {
    32  		lsh      uint64
    33  		rsh      uint64
    34  		ret      uint64
    35  		overflow bool
    36  	}{
    37  		{math.MaxUint64, 1, 0, true},
    38  		{math.MaxUint64, 0, math.MaxUint64, false},
    39  		{1, 1, 2, false},
    40  	}
    41  
    42  	for _, t := range tblUint64 {
    43  		ret, err := AddUint64(t.lsh, t.rsh)
    44  		if t.overflow {
    45  			c.Assert(err, NotNil)
    46  		} else {
    47  			c.Assert(ret, Equals, t.ret)
    48  		}
    49  	}
    50  
    51  	tblInt64 := []struct {
    52  		lsh      int64
    53  		rsh      int64
    54  		ret      int64
    55  		overflow bool
    56  	}{
    57  		{math.MaxInt64, 1, 0, true},
    58  		{math.MaxInt64, 0, math.MaxInt64, false},
    59  		{0, math.MinInt64, math.MinInt64, false},
    60  		{-1, math.MinInt64, 0, true},
    61  		{math.MaxInt64, math.MinInt64, -1, false},
    62  		{1, 1, 2, false},
    63  		{1, -1, 0, false},
    64  	}
    65  
    66  	for _, t := range tblInt64 {
    67  		ret, err := AddInt64(t.lsh, t.rsh)
    68  		if t.overflow {
    69  			c.Assert(err, NotNil)
    70  		} else {
    71  			c.Assert(ret, Equals, t.ret)
    72  		}
    73  	}
    74  
    75  	tblInt := []struct {
    76  		lsh      uint64
    77  		rsh      int64
    78  		ret      uint64
    79  		overflow bool
    80  	}{
    81  		{math.MaxUint64, math.MinInt64, math.MaxUint64 + math.MinInt64, false},
    82  		{math.MaxInt64, math.MinInt64, 0, true},
    83  		{0, -1, 0, true},
    84  		{1, -1, 0, false},
    85  		{0, 1, 1, false},
    86  		{1, 1, 2, false},
    87  	}
    88  
    89  	for _, t := range tblInt {
    90  		ret, err := AddInteger(t.lsh, t.rsh)
    91  		if t.overflow {
    92  			c.Assert(err, NotNil)
    93  		} else {
    94  			c.Assert(ret, Equals, t.ret)
    95  		}
    96  	}
    97  }
    98  
    99  func (s *testOverflowSuite) TestSub(c *C) {
   100  	defer testleak.AfterTest(c)()
   101  	tblUint64 := []struct {
   102  		lsh      uint64
   103  		rsh      uint64
   104  		ret      uint64
   105  		overflow bool
   106  	}{
   107  		{math.MaxUint64, 1, math.MaxUint64 - 1, false},
   108  		{math.MaxUint64, 0, math.MaxUint64, false},
   109  		{0, math.MaxUint64, 0, true},
   110  		{0, 1, 0, true},
   111  		{1, math.MaxUint64, 0, true},
   112  		{1, 1, 0, false},
   113  	}
   114  
   115  	for _, t := range tblUint64 {
   116  		ret, err := SubUint64(t.lsh, t.rsh)
   117  		if t.overflow {
   118  			c.Assert(err, NotNil)
   119  		} else {
   120  			c.Assert(ret, Equals, t.ret)
   121  		}
   122  	}
   123  
   124  	tblInt64 := []struct {
   125  		lsh      int64
   126  		rsh      int64
   127  		ret      int64
   128  		overflow bool
   129  	}{
   130  		{math.MinInt64, 0, math.MinInt64, false},
   131  		{math.MinInt64, 1, 0, true},
   132  		{math.MaxInt64, -1, 0, true},
   133  		{0, math.MinInt64, 0, true},
   134  		{-1, math.MinInt64, math.MaxInt64, false},
   135  		{math.MinInt64, math.MaxInt64, 0, true},
   136  		{math.MinInt64, math.MinInt64, 0, false},
   137  		{math.MinInt64, -math.MaxInt64, -1, false},
   138  		{1, 1, 0, false},
   139  	}
   140  
   141  	for _, t := range tblInt64 {
   142  		ret, err := SubInt64(t.lsh, t.rsh)
   143  		if t.overflow {
   144  			c.Assert(err, NotNil)
   145  		} else {
   146  			c.Assert(ret, Equals, t.ret)
   147  		}
   148  	}
   149  
   150  	tblInt := []struct {
   151  		lsh      uint64
   152  		rsh      int64
   153  		ret      uint64
   154  		overflow bool
   155  	}{
   156  		{0, math.MinInt64, -math.MinInt64, false},
   157  		{0, 1, 0, true},
   158  		{math.MaxUint64, math.MinInt64, 0, true},
   159  		{math.MaxInt64, math.MinInt64, 2*math.MaxInt64 + 1, false},
   160  		{math.MaxUint64, -1, 0, true},
   161  		{0, -1, 1, false},
   162  		{1, 1, 0, false},
   163  	}
   164  
   165  	for _, t := range tblInt {
   166  		ret, err := SubUintWithInt(t.lsh, t.rsh)
   167  		if t.overflow {
   168  			c.Assert(err, NotNil)
   169  		} else {
   170  			c.Assert(ret, Equals, t.ret)
   171  		}
   172  	}
   173  
   174  	tblInt2 := []struct {
   175  		lsh      int64
   176  		rsh      uint64
   177  		ret      uint64
   178  		overflow bool
   179  	}{
   180  		{math.MinInt64, 0, 0, true},
   181  		{math.MaxInt64, 0, math.MaxInt64, false},
   182  		{math.MaxInt64, math.MaxUint64, 0, true},
   183  		{math.MaxInt64, -math.MinInt64, 0, true},
   184  		{-1, 0, 0, true},
   185  		{1, 1, 0, false},
   186  	}
   187  
   188  	for _, t := range tblInt2 {
   189  		ret, err := SubIntWithUint(t.lsh, t.rsh)
   190  		if t.overflow {
   191  			c.Assert(err, NotNil)
   192  		} else {
   193  			c.Assert(ret, Equals, t.ret)
   194  		}
   195  	}
   196  }
   197  
   198  func (s *testOverflowSuite) TestMul(c *C) {
   199  	defer testleak.AfterTest(c)()
   200  	tblUint64 := []struct {
   201  		lsh      uint64
   202  		rsh      uint64
   203  		ret      uint64
   204  		overflow bool
   205  	}{
   206  		{math.MaxUint64, 1, math.MaxUint64, false},
   207  		{math.MaxUint64, 0, 0, false},
   208  		{math.MaxUint64, 2, 0, true},
   209  		{1, 1, 1, false},
   210  	}
   211  
   212  	for _, t := range tblUint64 {
   213  		ret, err := MulUint64(t.lsh, t.rsh)
   214  		if t.overflow {
   215  			c.Assert(err, NotNil)
   216  		} else {
   217  			c.Assert(ret, Equals, t.ret)
   218  		}
   219  	}
   220  
   221  	tblInt64 := []struct {
   222  		lsh      int64
   223  		rsh      int64
   224  		ret      int64
   225  		overflow bool
   226  	}{
   227  		{math.MaxInt64, 1, math.MaxInt64, false},
   228  		{math.MinInt64, 1, math.MinInt64, false},
   229  		{math.MaxInt64, -1, -math.MaxInt64, false},
   230  		{math.MinInt64, -1, 0, true},
   231  		{math.MinInt64, 0, 0, false},
   232  		{math.MaxInt64, 0, 0, false},
   233  		{math.MaxInt64, math.MaxInt64, 0, true},
   234  		{math.MaxInt64, math.MinInt64, 0, true},
   235  		{math.MinInt64 / 10, 11, 0, true},
   236  		{1, 1, 1, false},
   237  	}
   238  
   239  	for _, t := range tblInt64 {
   240  		ret, err := MulInt64(t.lsh, t.rsh)
   241  		if t.overflow {
   242  			c.Assert(err, NotNil)
   243  		} else {
   244  			c.Assert(ret, Equals, t.ret)
   245  		}
   246  	}
   247  
   248  	tblInt := []struct {
   249  		lsh      uint64
   250  		rsh      int64
   251  		ret      uint64
   252  		overflow bool
   253  	}{
   254  		{math.MaxUint64, 0, 0, false},
   255  		{0, -1, 0, false},
   256  		{1, -1, 0, true},
   257  		{math.MaxUint64, -1, 0, true},
   258  		{math.MaxUint64, 10, 0, true},
   259  		{1, 1, 1, false},
   260  	}
   261  
   262  	for _, t := range tblInt {
   263  		ret, err := MulInteger(t.lsh, t.rsh)
   264  		if t.overflow {
   265  			c.Assert(err, NotNil)
   266  		} else {
   267  			c.Assert(ret, Equals, t.ret)
   268  		}
   269  	}
   270  }
   271  
   272  func (s *testOverflowSuite) TestDiv(c *C) {
   273  	defer testleak.AfterTest(c)()
   274  	tblInt64 := []struct {
   275  		lsh      int64
   276  		rsh      int64
   277  		ret      int64
   278  		overflow bool
   279  	}{
   280  		{math.MaxInt64, 1, math.MaxInt64, false},
   281  		{math.MinInt64, 1, math.MinInt64, false},
   282  		{math.MinInt64, -1, 0, true},
   283  		{math.MaxInt64, -1, -math.MaxInt64, false},
   284  		{1, -1, -1, false},
   285  		{-1, 1, -1, false},
   286  		{-1, 2, 0, false},
   287  		{math.MinInt64, 2, math.MinInt64 / 2, false},
   288  	}
   289  
   290  	for _, t := range tblInt64 {
   291  		ret, err := DivInt64(t.lsh, t.rsh)
   292  		if t.overflow {
   293  			c.Assert(err, NotNil)
   294  		} else {
   295  			c.Assert(ret, Equals, t.ret)
   296  		}
   297  	}
   298  
   299  	tblInt := []struct {
   300  		lsh      uint64
   301  		rsh      int64
   302  		ret      uint64
   303  		overflow bool
   304  	}{
   305  		{0, -1, 0, false},
   306  		{1, -1, 0, true},
   307  		{math.MaxInt64, math.MinInt64, 0, false},
   308  		{math.MaxInt64, -1, 0, true},
   309  	}
   310  
   311  	for _, t := range tblInt {
   312  		ret, err := DivUintWithInt(t.lsh, t.rsh)
   313  		if t.overflow {
   314  			c.Assert(err, NotNil)
   315  		} else {
   316  			c.Assert(ret, Equals, t.ret)
   317  		}
   318  	}
   319  
   320  	tblInt2 := []struct {
   321  		lsh      int64
   322  		rsh      uint64
   323  		ret      uint64
   324  		overflow bool
   325  	}{
   326  		{math.MinInt64, math.MaxInt64, 0, true},
   327  		{0, 1, 0, false},
   328  		{-1, math.MaxInt64, 0, false},
   329  	}
   330  
   331  	for _, t := range tblInt2 {
   332  		ret, err := DivIntWithUint(t.lsh, t.rsh)
   333  		if t.overflow {
   334  			c.Assert(err, NotNil)
   335  		} else {
   336  			c.Assert(ret, Equals, t.ret)
   337  		}
   338  	}
   339  }