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 }