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  }