github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/greatest_least_test.go (about) 1 // Copyright 2020-2021 Dolthub, 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 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package function 16 17 import ( 18 "testing" 19 "unsafe" 20 21 "github.com/stretchr/testify/require" 22 23 "github.com/dolthub/go-mysql-server/sql" 24 "github.com/dolthub/go-mysql-server/sql/expression" 25 "github.com/dolthub/go-mysql-server/sql/types" 26 ) 27 28 func TestGreatest(t *testing.T) { 29 testCases := []struct { 30 name string 31 args []sql.Expression 32 expected interface{} 33 }{ 34 { 35 "null", 36 []sql.Expression{ 37 expression.NewLiteral(nil, types.Null), 38 expression.NewLiteral(5, types.Int64), 39 expression.NewLiteral(1, types.Int64), 40 }, 41 nil, 42 }, 43 { 44 "negative and all ints", 45 []sql.Expression{ 46 expression.NewLiteral(int64(-1), types.Int64), 47 expression.NewLiteral(int64(5), types.Int64), 48 expression.NewLiteral(int64(1), types.Int64), 49 }, 50 int64(5), 51 }, 52 { 53 "string mixed", 54 []sql.Expression{ 55 expression.NewLiteral(string("9"), types.LongText), 56 expression.NewLiteral(int64(5), types.Int64), 57 expression.NewLiteral(int64(1), types.Int64), 58 }, 59 float64(9), 60 }, 61 { 62 "unconvertible string mixed ignored", 63 []sql.Expression{ 64 expression.NewLiteral(string("10.5"), types.LongText), 65 expression.NewLiteral(string("foobar"), types.Int64), 66 expression.NewLiteral(int64(5), types.Int64), 67 expression.NewLiteral(int64(1), types.Int64), 68 }, 69 float64(10.5), 70 }, 71 { 72 "float mixed", 73 []sql.Expression{ 74 expression.NewLiteral(float64(10.0), types.Float64), 75 expression.NewLiteral(int(5), types.Int64), 76 expression.NewLiteral(int(1), types.Int64), 77 }, 78 float64(10.0), 79 }, 80 { 81 "all strings", 82 []sql.Expression{ 83 expression.NewLiteral("aaa", types.LongText), 84 expression.NewLiteral("bbb", types.LongText), 85 expression.NewLiteral("9999", types.LongText), 86 expression.NewLiteral("", types.LongText), 87 }, 88 "bbb", 89 }, 90 { 91 "all strings and empty", 92 []sql.Expression{ 93 expression.NewLiteral("aaa", types.LongText), 94 expression.NewLiteral("bbb", types.LongText), 95 expression.NewLiteral("9999", types.LongText), 96 expression.NewLiteral("", types.LongText), 97 }, 98 "bbb", 99 }, 100 { 101 "nulls of a non-null type, char", 102 []sql.Expression{ 103 expression.NewConvert(expression.NewLiteral("aaa", types.LongText), expression.ConvertToChar), 104 expression.NewConvert(expression.NewLiteral(nil, types.Null), expression.ConvertToChar), 105 }, 106 nil, 107 }, 108 { 109 "nulls of a non-null type, signed", 110 []sql.Expression{ 111 expression.NewConvert(expression.NewLiteral(3.14159265359, types.Float64), expression.ConvertToSigned), 112 expression.NewConvert(expression.NewLiteral(nil, types.Null), expression.ConvertToSigned), 113 }, 114 nil, 115 }, 116 } 117 118 for _, tt := range testCases { 119 t.Run(tt.name, func(t *testing.T) { 120 require := require.New(t) 121 122 ctx := sql.NewEmptyContext() 123 f, err := NewGreatest(tt.args...) 124 require.NoError(err) 125 126 output, err := f.Eval(ctx, nil) 127 require.NoError(err) 128 require.Equal(tt.expected, output) 129 }) 130 } 131 } 132 133 func TestGreatestUnsignedOverflow(t *testing.T) { 134 require := require.New(t) 135 ctx := sql.NewEmptyContext() 136 137 var x int 138 var gr sql.Expression 139 var err error 140 141 switch unsafe.Sizeof(x) { 142 case 4: 143 gr, err = NewGreatest(expression.NewLiteral(int32(1), types.Int32), 144 expression.NewLiteral(uint32(4294967295), types.Uint32), 145 ) 146 require.NoError(err) 147 case 8: 148 gr, err = NewGreatest(expression.NewLiteral(int64(1), types.Int64), 149 expression.NewLiteral(uint64(18446744073709551615), types.Uint64), 150 ) 151 require.NoError(err) 152 default: 153 // non 32/64 bits?? 154 return 155 } 156 157 _, err = gr.Eval(ctx, nil) 158 require.EqualError(err, "Unsigned integer too big to fit on signed integer") 159 } 160 161 func TestLeast(t *testing.T) { 162 testCases := []struct { 163 name string 164 args []sql.Expression 165 expected interface{} 166 }{ 167 { 168 "null", 169 []sql.Expression{ 170 expression.NewLiteral(nil, types.Null), 171 expression.NewLiteral(5, types.Int64), 172 expression.NewLiteral(1, types.Int64), 173 }, 174 nil, 175 }, 176 { 177 "negative and all ints", 178 []sql.Expression{ 179 expression.NewLiteral(int64(-1), types.Int64), 180 expression.NewLiteral(int64(5), types.Int64), 181 expression.NewLiteral(int64(1), types.Int64), 182 }, 183 int64(-1), 184 }, 185 { 186 "string mixed", 187 []sql.Expression{ 188 expression.NewLiteral(string("10"), types.LongText), 189 expression.NewLiteral(int64(5), types.Int64), 190 expression.NewLiteral(int64(1), types.Int64), 191 }, 192 float64(1), 193 }, 194 { 195 "unconvertible string mixed ignored", 196 []sql.Expression{ 197 expression.NewLiteral(string("10.5"), types.LongText), 198 expression.NewLiteral(string("foobar"), types.Int64), 199 expression.NewLiteral(int64(5), types.Int64), 200 expression.NewLiteral(int64(1), types.Int64), 201 }, 202 float64(1), 203 }, 204 { 205 "float mixed", 206 []sql.Expression{ 207 expression.NewLiteral(float64(10.0), types.Float64), 208 expression.NewLiteral(int(5), types.Int64), 209 expression.NewLiteral(int(1), types.Int64), 210 }, 211 float64(1.0), 212 }, 213 { 214 "all strings", 215 []sql.Expression{ 216 expression.NewLiteral("aaa", types.LongText), 217 expression.NewLiteral("bbb", types.LongText), 218 expression.NewLiteral("9999", types.LongText), 219 }, 220 "9999", 221 }, 222 { 223 "all strings and empty", 224 []sql.Expression{ 225 expression.NewLiteral("aaa", types.LongText), 226 expression.NewLiteral("bbb", types.LongText), 227 expression.NewLiteral("9999", types.LongText), 228 expression.NewLiteral("", types.LongText), 229 }, 230 "", 231 }, 232 } 233 234 for _, tt := range testCases { 235 t.Run(tt.name, func(t *testing.T) { 236 ctx := sql.NewEmptyContext() 237 require := require.New(t) 238 239 f, err := NewLeast(tt.args...) 240 require.NoError(err) 241 242 output, err := f.Eval(ctx, nil) 243 require.NoError(err) 244 require.Equal(tt.expected, output) 245 }) 246 } 247 }