github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/spatial/x_y_latitude_longitude_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 spatial 16 17 import ( 18 "testing" 19 20 "github.com/stretchr/testify/require" 21 22 "github.com/dolthub/go-mysql-server/sql" 23 "github.com/dolthub/go-mysql-server/sql/expression" 24 "github.com/dolthub/go-mysql-server/sql/types" 25 ) 26 27 func TestSTX(t *testing.T) { 28 t.Run("select int x value", func(t *testing.T) { 29 require := require.New(t) 30 f, err := NewSTX(expression.NewLiteral(types.Point{X: 1, Y: 2}, types.PointType{})) 31 require.NoError(err) 32 33 v, err := f.Eval(sql.NewEmptyContext(), nil) 34 require.NoError(err) 35 require.Equal(1.0, v) 36 }) 37 38 t.Run("select float x value", func(t *testing.T) { 39 require := require.New(t) 40 f, err := NewSTX(expression.NewLiteral(types.Point{X: 123.456, Y: 78.9}, types.PointType{})) 41 require.NoError(err) 42 43 v, err := f.Eval(sql.NewEmptyContext(), nil) 44 require.NoError(err) 45 require.Equal(123.456, v) 46 }) 47 48 t.Run("replace x value", func(t *testing.T) { 49 require := require.New(t) 50 f, err := NewSTX(expression.NewLiteral(types.Point{X: 0, Y: 0}, types.PointType{}), 51 expression.NewLiteral(123.456, types.Float64)) 52 require.NoError(err) 53 54 v, err := f.Eval(sql.NewEmptyContext(), nil) 55 require.NoError(err) 56 require.Equal(types.Point{X: 123.456, Y: 0}, v) 57 }) 58 59 t.Run("replace x value with valid string", func(t *testing.T) { 60 require := require.New(t) 61 f, err := NewSTX(expression.NewLiteral(types.Point{X: 0, Y: 0}, types.PointType{}), 62 expression.NewLiteral("-123.456", types.Blob)) 63 require.NoError(err) 64 65 v, err := f.Eval(sql.NewEmptyContext(), nil) 66 require.NoError(err) 67 require.Equal(types.Point{X: -123.456, Y: 0}, v) 68 }) 69 70 t.Run("replace x value with negative float", func(t *testing.T) { 71 require := require.New(t) 72 f, err := NewSTX(expression.NewLiteral(types.Point{X: 0, Y: 0}, types.PointType{}), 73 expression.NewLiteral("-123.456", types.Blob)) 74 require.NoError(err) 75 76 v, err := f.Eval(sql.NewEmptyContext(), nil) 77 require.NoError(err) 78 require.Equal(types.Point{X: -123.456, Y: 0}, v) 79 }) 80 81 t.Run("non-point provided", func(t *testing.T) { 82 require := require.New(t) 83 f, err := NewSTX(expression.NewLiteral("notapoint", types.Blob)) 84 require.NoError(err) 85 86 _, err = f.Eval(sql.NewEmptyContext(), nil) 87 require.Error(err) 88 }) 89 90 t.Run("check return type with one argument", func(t *testing.T) { 91 require := require.New(t) 92 f, err := NewSTX(expression.NewLiteral(types.Point{X: 1, Y: 2}, types.PointType{})) 93 require.NoError(err) 94 95 v, err := f.Eval(sql.NewEmptyContext(), nil) 96 require.NoError(err) 97 98 typ := f.Type() 99 _, _, err = typ.Convert(v) 100 require.NoError(err) 101 }) 102 103 t.Run("check return type with two arguments", func(t *testing.T) { 104 require := require.New(t) 105 f, err := NewSTX(expression.NewLiteral(types.Point{X: 0, Y: 0}, types.PointType{}), 106 expression.NewLiteral(123.456, types.Float64)) 107 require.NoError(err) 108 109 v, err := f.Eval(sql.NewEmptyContext(), nil) 110 require.NoError(err) 111 112 typ := f.Type() 113 _, _, err = typ.Convert(v) 114 require.NoError(err) 115 }) 116 } 117 118 func TestSTY(t *testing.T) { 119 t.Run("select int y value", func(t *testing.T) { 120 require := require.New(t) 121 f, err := NewSTY(expression.NewLiteral(types.Point{X: 1, Y: 2}, types.PointType{})) 122 require.NoError(err) 123 124 v, err := f.Eval(sql.NewEmptyContext(), nil) 125 require.NoError(err) 126 require.Equal(2.0, v) 127 }) 128 129 t.Run("select float y value", func(t *testing.T) { 130 require := require.New(t) 131 f, err := NewSTY(expression.NewLiteral(types.Point{X: 123.456, Y: 78.9}, types.PointType{})) 132 require.NoError(err) 133 134 v, err := f.Eval(sql.NewEmptyContext(), nil) 135 require.NoError(err) 136 require.Equal(78.9, v) 137 }) 138 139 t.Run("replace y value", func(t *testing.T) { 140 require := require.New(t) 141 f, err := NewSTY(expression.NewLiteral(types.Point{X: 0, Y: 0}, types.PointType{}), 142 expression.NewLiteral(123.456, types.Float64)) 143 require.NoError(err) 144 145 v, err := f.Eval(sql.NewEmptyContext(), nil) 146 require.NoError(err) 147 require.Equal(types.Point{X: 0, Y: 123.456}, v) 148 }) 149 150 t.Run("replace y value with valid string", func(t *testing.T) { 151 require := require.New(t) 152 f, err := NewSTY(expression.NewLiteral(types.Point{X: 0, Y: 0}, types.PointType{}), 153 expression.NewLiteral("-123.456", types.Blob)) 154 require.NoError(err) 155 156 v, err := f.Eval(sql.NewEmptyContext(), nil) 157 require.NoError(err) 158 require.Equal(types.Point{X: 0, Y: -123.456}, v) 159 }) 160 161 t.Run("replace y value with negative float", func(t *testing.T) { 162 require := require.New(t) 163 f, err := NewSTY(expression.NewLiteral(types.Point{X: 0, Y: 0}, types.PointType{}), 164 expression.NewLiteral("-123.456", types.Blob)) 165 require.NoError(err) 166 167 v, err := f.Eval(sql.NewEmptyContext(), nil) 168 require.NoError(err) 169 require.Equal(types.Point{X: 0, Y: -123.456}, v) 170 }) 171 172 t.Run("non-point provided", func(t *testing.T) { 173 require := require.New(t) 174 f, err := NewSTY(expression.NewLiteral("notapoint", types.Blob)) 175 require.NoError(err) 176 177 _, err = f.Eval(sql.NewEmptyContext(), nil) 178 require.Error(err) 179 }) 180 181 t.Run("check return type with one argument", func(t *testing.T) { 182 require := require.New(t) 183 f, err := NewSTY(expression.NewLiteral(types.Point{X: 1, Y: 2}, types.PointType{})) 184 require.NoError(err) 185 186 v, err := f.Eval(sql.NewEmptyContext(), nil) 187 require.NoError(err) 188 189 typ := f.Type() 190 _, _, err = typ.Convert(v) 191 require.NoError(err) 192 }) 193 194 t.Run("check return type with two arguments", func(t *testing.T) { 195 require := require.New(t) 196 f, err := NewSTY(expression.NewLiteral(types.Point{X: 0, Y: 0}, types.PointType{}), 197 expression.NewLiteral(123.456, types.Float64)) 198 require.NoError(err) 199 200 typ := f.Type() 201 _, ok := typ.(types.PointType) 202 require.True(ok) 203 }) 204 } 205 206 func TestLongitude(t *testing.T) { 207 t.Run("select longitude value", func(t *testing.T) { 208 require := require.New(t) 209 f, err := NewLongitude(expression.NewLiteral(types.Point{SRID: 4326, X: 1, Y: 2}, types.PointType{})) 210 require.NoError(err) 211 212 v, err := f.Eval(sql.NewEmptyContext(), nil) 213 require.NoError(err) 214 require.Equal(1.0, v) 215 }) 216 217 t.Run("replace longitude value", func(t *testing.T) { 218 require := require.New(t) 219 f, err := NewLongitude(expression.NewLiteral(types.Point{SRID: 4326, X: 0, Y: 0}, types.PointType{}), 220 expression.NewLiteral(123.456, types.Float64)) 221 require.NoError(err) 222 223 v, err := f.Eval(sql.NewEmptyContext(), nil) 224 require.NoError(err) 225 require.Equal(types.Point{SRID: 4326, X: 123.456, Y: 0}, v) 226 }) 227 228 t.Run("replace x value with valid string", func(t *testing.T) { 229 require := require.New(t) 230 f, err := NewLongitude(expression.NewLiteral(types.Point{SRID: 4326, X: 0, Y: 0}, types.PointType{}), 231 expression.NewLiteral("-123.456", types.Blob)) 232 require.NoError(err) 233 234 v, err := f.Eval(sql.NewEmptyContext(), nil) 235 require.NoError(err) 236 require.Equal(types.Point{SRID: 4326, X: -123.456, Y: 0}, v) 237 }) 238 239 t.Run("replace x value with negative float", func(t *testing.T) { 240 require := require.New(t) 241 f, err := NewLongitude(expression.NewLiteral(types.Point{SRID: 4326, X: 0, Y: 0}, types.PointType{}), 242 expression.NewLiteral("-123.456", types.Blob)) 243 require.NoError(err) 244 245 v, err := f.Eval(sql.NewEmptyContext(), nil) 246 require.NoError(err) 247 require.Equal(types.Point{SRID: 4326, X: -123.456, Y: 0}, v) 248 }) 249 250 t.Run("null point", func(t *testing.T) { 251 require := require.New(t) 252 f, err := NewLongitude(expression.NewLiteral(nil, types.Null)) 253 require.NoError(err) 254 255 v, err := f.Eval(sql.NewEmptyContext(), nil) 256 require.NoError(err) 257 require.Equal(nil, v) 258 }) 259 260 t.Run("replace with null value", func(t *testing.T) { 261 require := require.New(t) 262 f, err := NewLongitude(expression.NewLiteral(types.Point{SRID: 4326, X: 0, Y: 0}, types.PointType{}), 263 expression.NewLiteral(nil, types.Null)) 264 require.NoError(err) 265 266 v, err := f.Eval(sql.NewEmptyContext(), nil) 267 require.NoError(err) 268 require.Equal(nil, v) 269 }) 270 271 t.Run("replace x value with out of range coordinate", func(t *testing.T) { 272 require := require.New(t) 273 f, err := NewLongitude(expression.NewLiteral(types.Point{SRID: 4326, X: 0, Y: 0}, types.PointType{}), 274 expression.NewLiteral(999, types.Blob)) 275 require.NoError(err) 276 277 _, err = f.Eval(sql.NewEmptyContext(), nil) 278 require.Error(err) 279 }) 280 281 t.Run("non-point provided", func(t *testing.T) { 282 require := require.New(t) 283 f, err := NewLongitude(expression.NewLiteral("notapoint", types.Blob)) 284 require.NoError(err) 285 286 _, err = f.Eval(sql.NewEmptyContext(), nil) 287 require.Error(err) 288 }) 289 290 t.Run("check return type with one argument", func(t *testing.T) { 291 require := require.New(t) 292 f, err := NewLongitude(expression.NewLiteral(types.Point{SRID: 4326, X: 1, Y: 2}, types.PointType{})) 293 require.NoError(err) 294 295 v, err := f.Eval(sql.NewEmptyContext(), nil) 296 require.NoError(err) 297 298 typ := f.Type() 299 _, _, err = typ.Convert(v) 300 require.NoError(err) 301 }) 302 303 t.Run("check return type with two arguments", func(t *testing.T) { 304 require := require.New(t) 305 f, err := NewLongitude(expression.NewLiteral(types.Point{SRID: 4326, X: 0, Y: 0}, types.PointType{}), 306 expression.NewLiteral(123.456, types.Float64)) 307 require.NoError(err) 308 309 v, err := f.Eval(sql.NewEmptyContext(), nil) 310 require.NoError(err) 311 312 typ := f.Type() 313 _, _, err = typ.Convert(v) 314 require.NoError(err) 315 }) 316 } 317 318 func TestLatitude(t *testing.T) { 319 t.Run("select latitude value", func(t *testing.T) { 320 require := require.New(t) 321 f, err := NewLatitude(expression.NewLiteral(types.Point{SRID: 4326, X: 1, Y: 2}, types.PointType{})) 322 require.NoError(err) 323 324 v, err := f.Eval(sql.NewEmptyContext(), nil) 325 require.NoError(err) 326 require.Equal(2.0, v) 327 }) 328 329 t.Run("replace latitude value", func(t *testing.T) { 330 require := require.New(t) 331 f, err := NewLatitude(expression.NewLiteral(types.Point{SRID: 4326, X: 0, Y: 0}, types.PointType{}), 332 expression.NewLiteral(12.3456, types.Float64)) 333 require.NoError(err) 334 335 v, err := f.Eval(sql.NewEmptyContext(), nil) 336 require.NoError(err) 337 require.Equal(types.Point{SRID: 4326, X: 0, Y: 12.3456}, v) 338 }) 339 340 t.Run("replace y value with valid string", func(t *testing.T) { 341 require := require.New(t) 342 f, err := NewLatitude(expression.NewLiteral(types.Point{SRID: 4326, X: 0, Y: 0}, types.PointType{}), 343 expression.NewLiteral("-12.3456", types.Blob)) 344 require.NoError(err) 345 346 v, err := f.Eval(sql.NewEmptyContext(), nil) 347 require.NoError(err) 348 require.Equal(types.Point{SRID: 4326, X: 0, Y: -12.3456}, v) 349 }) 350 351 t.Run("replace y value with negative float", func(t *testing.T) { 352 require := require.New(t) 353 f, err := NewLatitude(expression.NewLiteral(types.Point{SRID: 4326, X: 0, Y: 0}, types.PointType{}), 354 expression.NewLiteral("-12.3456", types.Blob)) 355 require.NoError(err) 356 357 v, err := f.Eval(sql.NewEmptyContext(), nil) 358 require.NoError(err) 359 require.Equal(types.Point{SRID: 4326, X: 0, Y: -12.3456}, v) 360 }) 361 362 t.Run("null point", func(t *testing.T) { 363 require := require.New(t) 364 f, err := NewLatitude(expression.NewLiteral(nil, types.Null)) 365 require.NoError(err) 366 367 v, err := f.Eval(sql.NewEmptyContext(), nil) 368 require.NoError(err) 369 require.Equal(nil, v) 370 }) 371 372 t.Run("replace with null value", func(t *testing.T) { 373 require := require.New(t) 374 f, err := NewLatitude(expression.NewLiteral(types.Point{SRID: 4326, X: 0, Y: 0}, types.PointType{}), 375 expression.NewLiteral(nil, types.Null)) 376 require.NoError(err) 377 378 v, err := f.Eval(sql.NewEmptyContext(), nil) 379 require.NoError(err) 380 require.Equal(nil, v) 381 }) 382 383 t.Run("replace y value with out of range coordinate", func(t *testing.T) { 384 require := require.New(t) 385 f, err := NewLatitude(expression.NewLiteral(types.Point{SRID: 4326, X: 0, Y: 0}, types.PointType{}), 386 expression.NewLiteral(999, types.Blob)) 387 require.NoError(err) 388 389 _, err = f.Eval(sql.NewEmptyContext(), nil) 390 require.Error(err) 391 }) 392 393 t.Run("non-point provided", func(t *testing.T) { 394 require := require.New(t) 395 f, err := NewLatitude(expression.NewLiteral("notapoint", types.Blob)) 396 require.NoError(err) 397 398 _, err = f.Eval(sql.NewEmptyContext(), nil) 399 require.Error(err) 400 }) 401 402 t.Run("check return type with one argument", func(t *testing.T) { 403 require := require.New(t) 404 f, err := NewLatitude(expression.NewLiteral(types.Point{SRID: 4326, X: 1, Y: 2}, types.PointType{})) 405 require.NoError(err) 406 407 v, err := f.Eval(sql.NewEmptyContext(), nil) 408 require.NoError(err) 409 410 typ := f.Type() 411 _, _, err = typ.Convert(v) 412 require.NoError(err) 413 }) 414 415 t.Run("check return type with two arguments", func(t *testing.T) { 416 require := require.New(t) 417 f, err := NewLatitude(expression.NewLiteral(types.Point{SRID: 4326, X: 0, Y: 0}, types.PointType{}), 418 expression.NewLiteral(12.3456, types.Float64)) 419 require.NoError(err) 420 421 v, err := f.Eval(sql.NewEmptyContext(), nil) 422 require.NoError(err) 423 424 typ := f.Type() 425 _, _, err = typ.Convert(v) 426 require.NoError(err) 427 }) 428 }