github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/function/strcmp_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 20 "github.com/stretchr/testify/require" 21 "gopkg.in/src-d/go-errors.v1" 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 TestStrCmp(t *testing.T) { 29 testCases := []struct { 30 name string 31 e1Type sql.Type 32 e2Type sql.Type 33 row sql.Row 34 expected interface{} 35 err *errors.Kind 36 }{ 37 {"equal strings", types.Text, types.Text, sql.NewRow("a", "a"), int(0), nil}, 38 {"first string is smaller", types.Text, types.Text, sql.NewRow("a", "b"), int(-1), nil}, 39 {"second string is smaller", types.Text, types.Text, sql.NewRow("b", "a"), int(1), nil}, 40 {"first argument is null", types.Text, types.Text, sql.NewRow(nil, "a"), nil, nil}, 41 {"second argument is null", types.Text, types.Text, sql.NewRow("a", nil), nil, nil}, 42 {"both arguments are null", types.Text, types.Text, sql.NewRow(nil, nil), nil, nil}, 43 {"first argument is text, second argument is not text", types.Text, types.Date, sql.NewRow("a", 2022), int(1), nil}, 44 {"first argument is not text, second argument is text", types.Int8, types.Text, sql.NewRow(1, "1"), int(0), nil}, 45 {"both arguments are non-text, different types", types.Int8, types.Date, sql.NewRow(3, 2007), int(1), nil}, 46 {"type coercion, equal arguments", types.Int8, types.Int8, sql.NewRow(1, 1), int(0), nil}, 47 {"type coercion, first argument is smaller", types.Int8, types.Int8, sql.NewRow(0, 1), int(-1), nil}, 48 {"type coercion, second argument is smaller", types.Int8, types.Int8, sql.NewRow(1, 0), int(1), nil}, 49 // TODO: returning different results from MySQL 50 // {"same character set, both case sensitive", sql.CreateTinyText(sql.Collation_utf8mb4_0900_as_cs), sql.CreateTinyText(sql.Collation_utf8mb4_cs_0900_as_cs), sql.NewRow("a", "a"), nil, sql.ErrCollationIllegalMix}, 51 // {"same character set, both case insensitive", sql.CreateTinyText(sql.Collation_latin1_general_ci), sql.CreateTinyText(sql.Collation_latin1_german1_ci), sql.NewRow("a", "a"), nil, sql.ErrCollationIllegalMix}, 52 {"different character sets, both case sensitive", types.CreateTinyText(sql.Collation_utf8mb4_0900_as_cs), types.CreateTinyText(sql.Collation_latin1_general_cs), sql.NewRow("a", "a"), int(0), nil}, 53 {"different character sets, both case insensitive", types.CreateTinyText(sql.Collation_utf8mb4_0900_ai_ci), types.CreateTinyText(sql.Collation_latin1_general_ci), sql.NewRow("a", "a"), int(0), nil}, 54 {"different character sets, one case sensitive, one case insensitive", types.CreateTinyText(sql.Collation_utf8mb4_0900_ai_ci), types.CreateTinyText(sql.Collation_latin1_general_cs), sql.NewRow("a", "a"), int(0), nil}, 55 } 56 57 for _, tt := range testCases { 58 args0 := expression.NewGetField(0, tt.e1Type, "", false) 59 args1 := expression.NewGetField(1, tt.e2Type, "", false) 60 f := NewStrCmp(args0, args1) 61 62 t.Run(tt.name, func(t *testing.T) { 63 require := require.New(t) 64 65 result, err := f.Eval(sql.NewEmptyContext(), tt.row) 66 if tt.err != nil { 67 require.Error(err) 68 require.True(tt.err.Is(err)) 69 } else { 70 require.NoError(err) 71 require.Equal(tt.expected, result) 72 } 73 }) 74 } 75 76 t.Run("too many arguments", func(t *testing.T) { 77 require := require.New(t) 78 79 f := NewStrCmp(expression.NewLiteral('a', types.Text), expression.NewLiteral('b', types.Text)) 80 _, err := f.WithChildren(expression.NewLiteral('a', types.Text), expression.NewLiteral('b', types.Text), expression.NewLiteral('c', types.Text)) 81 require.Error(err) 82 }) 83 84 t.Run("too few arguments", func(t *testing.T) { 85 require := require.New(t) 86 87 f := NewStrCmp(expression.NewLiteral('a', types.Text), expression.NewLiteral('b', types.Text)) 88 _, err := f.WithChildren(expression.NewLiteral('a', types.Text)) 89 require.Error(err) 90 }) 91 }