github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/colexec/overloads_test.go (about)

     1  // Copyright 2019 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package colexec
    12  
    13  import (
    14  	"math"
    15  	"testing"
    16  
    17  	"github.com/cockroachdb/apd"
    18  	"github.com/cockroachdb/cockroach/pkg/sql/colexecbase/colexecerror"
    19  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    20  	"github.com/cockroachdb/cockroach/pkg/util/leaktest"
    21  	"github.com/cockroachdb/errors"
    22  	"github.com/stretchr/testify/require"
    23  )
    24  
    25  func TestIntegerAddition(t *testing.T) {
    26  	defer leaktest.AfterTest(t)()
    27  	// The addition overload is the same for all integer widths, so we only test
    28  	// one of them.
    29  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performPlusInt16Int16(1, math.MaxInt16) }), tree.ErrIntOutOfRange))
    30  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performPlusInt16Int16(-1, math.MinInt16) }), tree.ErrIntOutOfRange))
    31  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performPlusInt16Int16(math.MaxInt16, 1) }), tree.ErrIntOutOfRange))
    32  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performPlusInt16Int16(math.MinInt16, -1) }), tree.ErrIntOutOfRange))
    33  
    34  	require.Equal(t, int16(math.MaxInt16), performPlusInt16Int16(1, math.MaxInt16-1))
    35  	require.Equal(t, int16(math.MinInt16), performPlusInt16Int16(-1, math.MinInt16+1))
    36  	require.Equal(t, int16(math.MaxInt16-1), performPlusInt16Int16(-1, math.MaxInt16))
    37  	require.Equal(t, int16(math.MinInt16+1), performPlusInt16Int16(1, math.MinInt16))
    38  
    39  	require.Equal(t, int16(22), performPlusInt16Int16(10, 12))
    40  	require.Equal(t, int16(-22), performPlusInt16Int16(-10, -12))
    41  	require.Equal(t, int16(2), performPlusInt16Int16(-10, 12))
    42  	require.Equal(t, int16(-2), performPlusInt16Int16(10, -12))
    43  }
    44  
    45  func TestIntegerSubtraction(t *testing.T) {
    46  	defer leaktest.AfterTest(t)()
    47  	// The subtraction overload is the same for all integer widths, so we only
    48  	// test one of them.
    49  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMinusInt16Int16(1, -math.MaxInt16) }), tree.ErrIntOutOfRange))
    50  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMinusInt16Int16(-2, math.MaxInt16) }), tree.ErrIntOutOfRange))
    51  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMinusInt16Int16(math.MaxInt16, -1) }), tree.ErrIntOutOfRange))
    52  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMinusInt16Int16(math.MinInt16, 1) }), tree.ErrIntOutOfRange))
    53  
    54  	require.Equal(t, int16(math.MaxInt16), performMinusInt16Int16(1, -math.MaxInt16+1))
    55  	require.Equal(t, int16(math.MinInt16), performMinusInt16Int16(-1, math.MaxInt16))
    56  	require.Equal(t, int16(math.MaxInt16-1), performMinusInt16Int16(-1, -math.MaxInt16))
    57  	require.Equal(t, int16(math.MinInt16+1), performMinusInt16Int16(0, math.MaxInt16))
    58  
    59  	require.Equal(t, int16(-2), performMinusInt16Int16(10, 12))
    60  	require.Equal(t, int16(2), performMinusInt16Int16(-10, -12))
    61  	require.Equal(t, int16(-22), performMinusInt16Int16(-10, 12))
    62  	require.Equal(t, int16(22), performMinusInt16Int16(10, -12))
    63  }
    64  
    65  func TestIntegerDivision(t *testing.T) {
    66  	defer leaktest.AfterTest(t)()
    67  	d := &apd.Decimal{}
    68  	var res apd.Decimal
    69  
    70  	res = performDivInt16Int16(math.MinInt16, -1)
    71  	require.Equal(t, 0, res.Cmp(d.SetFinite(-math.MinInt16, 0)))
    72  	res = performDivInt32Int32(math.MinInt32, -1)
    73  	require.Equal(t, 0, res.Cmp(d.SetFinite(-math.MinInt32, 0)))
    74  	res = performDivInt64Int64(math.MinInt64, -1)
    75  	d.SetFinite(math.MinInt64, 0)
    76  	if _, err := tree.DecimalCtx.Neg(d, d); err != nil {
    77  		t.Error(err)
    78  	}
    79  	require.Equal(t, 0, res.Cmp(d))
    80  
    81  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performDivInt16Int16(10, 0) }), tree.ErrDivByZero))
    82  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performDivInt32Int32(10, 0) }), tree.ErrDivByZero))
    83  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performDivInt64Int64(10, 0) }), tree.ErrDivByZero))
    84  
    85  	res = performDivInt16Int16(math.MaxInt16, -1)
    86  	require.Equal(t, 0, res.Cmp(d.SetFinite(-math.MaxInt16, 0)))
    87  	res = performDivInt32Int32(math.MaxInt32, -1)
    88  	require.Equal(t, 0, res.Cmp(d.SetFinite(-math.MaxInt32, 0)))
    89  	res = performDivInt64Int64(math.MaxInt64, -1)
    90  	require.Equal(t, 0, res.Cmp(d.SetFinite(-math.MaxInt64, 0)))
    91  }
    92  
    93  func TestIntegerMultiplication(t *testing.T) {
    94  	defer leaktest.AfterTest(t)()
    95  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMultInt16Int16(math.MaxInt16-1, 100) }), tree.ErrIntOutOfRange))
    96  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMultInt16Int16(math.MaxInt16-1, 3) }), tree.ErrIntOutOfRange))
    97  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMultInt16Int16(math.MinInt16+1, 3) }), tree.ErrIntOutOfRange))
    98  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMultInt16Int16(math.MinInt16+1, 100) }), tree.ErrIntOutOfRange))
    99  
   100  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMultInt32Int32(math.MaxInt32-1, 100) }), tree.ErrIntOutOfRange))
   101  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMultInt32Int32(math.MaxInt32-1, 3) }), tree.ErrIntOutOfRange))
   102  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMultInt32Int32(math.MinInt32+1, 3) }), tree.ErrIntOutOfRange))
   103  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMultInt32Int32(math.MinInt32+1, 100) }), tree.ErrIntOutOfRange))
   104  
   105  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMultInt64Int64(math.MaxInt64-1, 100) }), tree.ErrIntOutOfRange))
   106  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMultInt64Int64(math.MaxInt64-1, 3) }), tree.ErrIntOutOfRange))
   107  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMultInt64Int64(math.MinInt64+1, 3) }), tree.ErrIntOutOfRange))
   108  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMultInt64Int64(math.MinInt64+1, 100) }), tree.ErrIntOutOfRange))
   109  
   110  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMultInt16Int16(math.MinInt16, -1) }), tree.ErrIntOutOfRange))
   111  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMultInt32Int32(math.MinInt32, -1) }), tree.ErrIntOutOfRange))
   112  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performMultInt64Int64(math.MinInt64, -1) }), tree.ErrIntOutOfRange))
   113  
   114  	require.Equal(t, int16(-math.MaxInt16), performMultInt16Int16(math.MaxInt16, -1))
   115  	require.Equal(t, int32(-math.MaxInt32), performMultInt32Int32(math.MaxInt32, -1))
   116  	require.Equal(t, int64(-math.MaxInt64), performMultInt64Int64(math.MaxInt64, -1))
   117  
   118  	require.Equal(t, int16(0), performMultInt16Int16(math.MinInt16, 0))
   119  	require.Equal(t, int32(0), performMultInt32Int32(math.MinInt32, 0))
   120  	require.Equal(t, int64(0), performMultInt64Int64(math.MinInt64, 0))
   121  
   122  	require.Equal(t, int16(120), performMultInt16Int16(-10, -12))
   123  	require.Equal(t, int32(-120), performMultInt32Int32(-12, 10))
   124  	require.Equal(t, int64(-120), performMultInt64Int64(12, -10))
   125  }
   126  
   127  func TestMixedTypeInteger(t *testing.T) {
   128  	defer leaktest.AfterTest(t)()
   129  	require.Equal(t, int64(22), performPlusInt16Int32(10, 12))
   130  	require.Equal(t, int64(-22), performPlusInt16Int64(-10, -12))
   131  	require.Equal(t, int64(2), performPlusInt64Int32(-10, 12))
   132  	require.Equal(t, int64(-2), performPlusInt64Int16(10, -12))
   133  
   134  	require.Equal(t, int64(-2), performMinusInt16Int32(10, 12))
   135  	require.Equal(t, int64(2), performMinusInt16Int64(-10, -12))
   136  	require.Equal(t, int64(-22), performMinusInt64Int32(-10, 12))
   137  	require.Equal(t, int64(22), performMinusInt64Int16(10, -12))
   138  
   139  	require.Equal(t, int64(120), performMultInt16Int32(10, 12))
   140  	require.Equal(t, int64(120), performMultInt16Int64(-10, -12))
   141  	require.Equal(t, int64(-120), performMultInt64Int32(-12, 10))
   142  	require.Equal(t, int64(-120), performMultInt64Int16(12, -10))
   143  
   144  	d := &apd.Decimal{}
   145  	var res apd.Decimal
   146  
   147  	res = performDivInt16Int32(4, 2)
   148  	require.Equal(t, 0, res.Cmp(d.SetFinite(2, 0)))
   149  	res = performDivInt16Int64(6, 2)
   150  	require.Equal(t, 0, res.Cmp(d.SetFinite(3, 0)))
   151  	res = performDivInt64Int32(12, 3)
   152  	require.Equal(t, 0, res.Cmp(d.SetFinite(4, 0)))
   153  	res = performDivInt64Int16(20, 4)
   154  	require.Equal(t, 0, res.Cmp(d.SetFinite(5, 0)))
   155  }
   156  
   157  func TestDecimalDivByZero(t *testing.T) {
   158  	defer leaktest.AfterTest(t)()
   159  	nonZeroDec, zeroDec := apd.Decimal{}, apd.Decimal{}
   160  	nonZeroDec.SetFinite(4, 0)
   161  	zeroDec.SetFinite(0, 0)
   162  
   163  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performDivDecimalInt16(nonZeroDec, 0) }), tree.ErrDivByZero))
   164  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performDivDecimalInt32(nonZeroDec, 0) }), tree.ErrDivByZero))
   165  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performDivDecimalInt64(nonZeroDec, 0) }), tree.ErrDivByZero))
   166  
   167  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performDivInt64Decimal(2, zeroDec) }), tree.ErrDivByZero))
   168  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performDivInt32Decimal(2, zeroDec) }), tree.ErrDivByZero))
   169  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performDivInt16Decimal(2, zeroDec) }), tree.ErrDivByZero))
   170  
   171  	require.True(t, errors.Is(colexecerror.CatchVectorizedRuntimeError(func() { performDivDecimalDecimal(nonZeroDec, zeroDec) }), tree.ErrDivByZero))
   172  }
   173  
   174  func TestDecimalComparison(t *testing.T) {
   175  	defer leaktest.AfterTest(t)()
   176  	d := apd.Decimal{}
   177  	if _, err := d.SetFloat64(1.234); err != nil {
   178  		t.Error(err)
   179  	}
   180  	require.Equal(t, true, performEQDecimalDecimal(d, d))
   181  	require.Equal(t, true, performEQDecimalFloat64(d, 1.234))
   182  	require.Equal(t, false, performEQDecimalInt16(d, 1))
   183  	require.Equal(t, false, performEQDecimalInt32(d, 2))
   184  	require.Equal(t, false, performEQDecimalInt64(d, 3))
   185  
   186  	require.Equal(t, false, performLTDecimalDecimal(d, d))
   187  	require.Equal(t, true, performLTDecimalFloat64(d, 4.234))
   188  	require.Equal(t, false, performLTDecimalInt16(d, 1))
   189  	require.Equal(t, true, performLTDecimalInt32(d, 2))
   190  	require.Equal(t, true, performLTDecimalInt64(d, 3))
   191  
   192  	require.Equal(t, true, performGEDecimalDecimal(d, d))
   193  	require.Equal(t, false, performGEDecimalFloat64(d, 4.234))
   194  	require.Equal(t, true, performGEDecimalInt16(d, 1))
   195  	require.Equal(t, false, performGEDecimalInt32(d, 2))
   196  	require.Equal(t, false, performGEDecimalInt64(d, 3))
   197  }
   198  
   199  func TestFloatComparison(t *testing.T) {
   200  	defer leaktest.AfterTest(t)()
   201  	f := 1.234
   202  	d := apd.Decimal{}
   203  	if _, err := d.SetFloat64(f); err != nil {
   204  		t.Error(err)
   205  	}
   206  	require.Equal(t, true, performEQFloat64Decimal(f, d))
   207  	require.Equal(t, true, performEQFloat64Float64(f, 1.234))
   208  	require.Equal(t, false, performEQFloat64Int16(f, 1))
   209  	require.Equal(t, false, performEQFloat64Int32(f, 2))
   210  	require.Equal(t, false, performEQFloat64Int64(f, 3))
   211  
   212  	require.Equal(t, false, performLTFloat64Decimal(f, d))
   213  	require.Equal(t, true, performLTFloat64Float64(f, 4.234))
   214  	require.Equal(t, false, performLTFloat64Int16(f, 1))
   215  	require.Equal(t, true, performLTFloat64Int32(f, 2))
   216  	require.Equal(t, true, performLTFloat64Int64(f, 3))
   217  
   218  	require.Equal(t, true, performGEFloat64Decimal(f, d))
   219  	require.Equal(t, false, performGEFloat64Float64(f, 4.234))
   220  	require.Equal(t, true, performGEFloat64Int16(f, 1))
   221  	require.Equal(t, false, performGEFloat64Int32(f, 2))
   222  	require.Equal(t, false, performGEFloat64Int64(f, 3))
   223  }
   224  
   225  func TestIntComparison(t *testing.T) {
   226  	defer leaktest.AfterTest(t)()
   227  	i := int64(2)
   228  	d := apd.Decimal{}
   229  	if _, err := d.SetFloat64(1.234); err != nil {
   230  		t.Error(err)
   231  	}
   232  	require.Equal(t, false, performEQInt64Decimal(i, d))
   233  	require.Equal(t, false, performEQInt64Float64(i, 1.234))
   234  	require.Equal(t, false, performEQInt64Int16(i, 1))
   235  	require.Equal(t, true, performEQInt64Int32(i, 2))
   236  	require.Equal(t, false, performEQInt64Int64(i, 3))
   237  
   238  	require.Equal(t, false, performLTInt64Decimal(i, d))
   239  	require.Equal(t, true, performLTInt64Float64(i, 4.234))
   240  	require.Equal(t, false, performLTInt64Int16(i, 1))
   241  	require.Equal(t, false, performLTInt64Int32(i, 2))
   242  	require.Equal(t, true, performLTInt64Int64(i, 3))
   243  
   244  	require.Equal(t, true, performGEInt64Decimal(i, d))
   245  	require.Equal(t, false, performGEInt64Float64(i, 4.234))
   246  	require.Equal(t, true, performGEInt64Int16(i, 1))
   247  	require.Equal(t, true, performGEInt64Int32(i, 2))
   248  	require.Equal(t, false, performGEInt64Int64(i, 3))
   249  }