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 }