github.com/dolthub/go-mysql-server@v0.18.0/sql/expression/between_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 expression
    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/types"
    24  )
    25  
    26  func TestBetween(t *testing.T) {
    27  	b := NewBetween(
    28  		NewGetField(0, types.Int64, "val", true),
    29  		NewGetField(1, types.Int64, "lower", true),
    30  		NewGetField(2, types.Int64, "upper", true),
    31  	)
    32  
    33  	testCases := []struct {
    34  		name     string
    35  		row      sql.Row
    36  		expected interface{}
    37  		err      bool
    38  	}{
    39  		{"val is null", sql.NewRow(nil, 1, 2), nil, false},
    40  		{"lower is null, out of range", sql.NewRow(1, nil, 2), nil, false},
    41  		{"lower is null, in range", sql.NewRow(2, nil, 2), nil, false},
    42  		{"upper is null, out of range", sql.NewRow(1, 2, nil), false, false},
    43  		{"upper is null, in range", sql.NewRow(2, 2, nil), nil, false},
    44  		{"val is lower", sql.NewRow(1, 1, 3), true, false},
    45  		{"val is upper", sql.NewRow(3, 1, 3), true, false},
    46  		{"val is between lower and upper", sql.NewRow(2, 1, 3), true, false},
    47  		{"val is less than lower", sql.NewRow(0, 1, 3), false, false},
    48  		{"val is more than upper", sql.NewRow(4, 1, 3), false, false},
    49  		{"val type is different than lower", sql.NewRow(4, "lower", 3), false, false},
    50  		{"val type is different than upper", sql.NewRow(4, 1, "upper"), false, false},
    51  		{"val type is different than lower", sql.NewRow(2, "lower", 3), true, false},
    52  		{"val type is different than upper", sql.NewRow(0, 0, "upper"), true, false},
    53  	}
    54  
    55  	for _, tt := range testCases {
    56  		t.Run(tt.name, func(t *testing.T) {
    57  			require := require.New(t)
    58  			result, err := b.Eval(sql.NewEmptyContext(), tt.row)
    59  			if tt.err {
    60  				require.Error(err)
    61  			} else {
    62  				require.NoError(err)
    63  				require.Equal(tt.expected, result)
    64  			}
    65  		})
    66  	}
    67  }
    68  
    69  func TestBetweenIsNullable(t *testing.T) {
    70  	testCases := []struct {
    71  		name     string
    72  		b        *Between
    73  		nullable bool
    74  	}{
    75  		{
    76  			"val is nullable",
    77  			NewBetween(
    78  				NewGetField(0, types.Int64, "foo", true),
    79  				NewLiteral(1, types.Int64),
    80  				NewLiteral(2, types.Int64),
    81  			),
    82  			true,
    83  		},
    84  		{
    85  			"lower is nullable",
    86  			NewBetween(
    87  				NewLiteral(1, types.Int64),
    88  				NewGetField(0, types.Int64, "foo", true),
    89  				NewLiteral(2, types.Int64),
    90  			),
    91  			true,
    92  		},
    93  		{
    94  			"upper is nullable",
    95  			NewBetween(
    96  				NewLiteral(1, types.Int64),
    97  				NewLiteral(2, types.Int64),
    98  				NewGetField(0, types.Int64, "foo", true),
    99  			),
   100  			true,
   101  		},
   102  		{
   103  			"all are not nullable",
   104  			NewBetween(
   105  				NewLiteral(1, types.Int64),
   106  				NewLiteral(2, types.Int64),
   107  				NewLiteral(3, types.Int64),
   108  			),
   109  			false,
   110  		},
   111  	}
   112  
   113  	for _, tt := range testCases {
   114  		t.Run(tt.name, func(t *testing.T) {
   115  			require.Equal(t, tt.nullable, tt.b.IsNullable())
   116  		})
   117  	}
   118  }
   119  
   120  func TestBetweenResolved(t *testing.T) {
   121  	testCases := []struct {
   122  		name     string
   123  		b        *Between
   124  		resolved bool
   125  	}{
   126  		{
   127  			"val is unresolved",
   128  			NewBetween(
   129  				NewUnresolvedColumn("foo"),
   130  				NewLiteral(1, types.Int64),
   131  				NewLiteral(2, types.Int64),
   132  			),
   133  			false,
   134  		},
   135  		{
   136  			"lower is unresolved",
   137  			NewBetween(
   138  				NewLiteral(1, types.Int64),
   139  				NewUnresolvedColumn("foo"),
   140  				NewLiteral(2, types.Int64),
   141  			),
   142  			false,
   143  		},
   144  		{
   145  			"upper is unresolved",
   146  			NewBetween(
   147  				NewLiteral(1, types.Int64),
   148  				NewLiteral(2, types.Int64),
   149  				NewUnresolvedColumn("foo"),
   150  			),
   151  			false,
   152  		},
   153  		{
   154  			"all are resolved",
   155  			NewBetween(
   156  				NewLiteral(1, types.Int64),
   157  				NewLiteral(2, types.Int64),
   158  				NewLiteral(3, types.Int64),
   159  			),
   160  			true,
   161  		},
   162  	}
   163  
   164  	for _, tt := range testCases {
   165  		t.Run(tt.name, func(t *testing.T) {
   166  			require.Equal(t, tt.resolved, tt.b.Resolved())
   167  		})
   168  	}
   169  }
   170  
   171  func TestNotBetween(t *testing.T) {
   172  	n := NewNot(NewBetween(
   173  		NewGetField(0, types.Int64, "val", true),
   174  		NewGetField(1, types.Int64, "lower", true),
   175  		NewGetField(2, types.Int64, "upper", true),
   176  	))
   177  
   178  	testCases := []struct {
   179  		name     string
   180  		row      sql.Row
   181  		expected interface{}
   182  		err      bool
   183  	}{
   184  		{"val is null", sql.NewRow(nil, 1, 2), nil, false},
   185  		{"lower is null, out of range", sql.NewRow(1, nil, 2), nil, false},
   186  		{"lower is null, in range", sql.NewRow(2, nil, 2), nil, false},
   187  		{"upper is null, out of range", sql.NewRow(1, 2, nil), true, false},
   188  		{"upper is null, in range", sql.NewRow(2, 2, nil), nil, false},
   189  		{"val is lower", sql.NewRow(1, 1, 3), false, false},
   190  		{"val is upper", sql.NewRow(3, 1, 3), false, false},
   191  		{"val is between lower and upper", sql.NewRow(2, 1, 3), false, false},
   192  		{"val is less than lower", sql.NewRow(0, 1, 3), true, false},
   193  		{"val is more than upper", sql.NewRow(4, 1, 3), true, false},
   194  		{"val type is different than lower", sql.NewRow(4, "lower", 3), true, false},
   195  		{"val type is different than upper", sql.NewRow(4, 1, "upper"), true, false},
   196  		{"val type is different than lower", sql.NewRow(2, "lower", 3), false, false},
   197  		{"val type is different than upper", sql.NewRow(0, 0, "upper"), false, false},
   198  	}
   199  
   200  	for _, tt := range testCases {
   201  		t.Run(tt.name, func(t *testing.T) {
   202  			require := require.New(t)
   203  			result, err := n.Eval(sql.NewEmptyContext(), tt.row)
   204  			if tt.err {
   205  				require.Error(err)
   206  			} else {
   207  				require.NoError(err)
   208  				require.Equal(tt.expected, result)
   209  			}
   210  		})
   211  	}
   212  }