github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/plan/function/operator_between.go (about) 1 // Copyright 2023 Matrix Origin 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 "bytes" 19 20 "github.com/matrixorigin/matrixone/pkg/container/nulls" 21 "github.com/matrixorigin/matrixone/pkg/container/types" 22 "github.com/matrixorigin/matrixone/pkg/container/vector" 23 "github.com/matrixorigin/matrixone/pkg/vm/process" 24 "golang.org/x/exp/constraints" 25 ) 26 27 func betweenImpl(parameters []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) error { 28 paramType := parameters[0].GetType() 29 rs := vector.MustFunctionResult[bool](result) 30 switch paramType.Oid { 31 case types.T_bool: 32 return opBetweenBool(parameters, rs, proc, length) 33 case types.T_bit: 34 return opBetweenFixed[uint64](parameters, rs, proc, length) 35 case types.T_int8: 36 return opBetweenFixed[int8](parameters, rs, proc, length) 37 case types.T_int16: 38 return opBetweenFixed[int16](parameters, rs, proc, length) 39 case types.T_int32: 40 return opBetweenFixed[int32](parameters, rs, proc, length) 41 case types.T_int64: 42 return opBetweenFixed[int64](parameters, rs, proc, length) 43 case types.T_uint8: 44 return opBetweenFixed[uint8](parameters, rs, proc, length) 45 case types.T_uint16: 46 return opBetweenFixed[uint16](parameters, rs, proc, length) 47 case types.T_uint32: 48 return opBetweenFixed[uint32](parameters, rs, proc, length) 49 case types.T_uint64: 50 return opBetweenFixed[uint64](parameters, rs, proc, length) 51 case types.T_float32: 52 return opBetweenFixed[float32](parameters, rs, proc, length) 53 case types.T_float64: 54 return opBetweenFixed[float64](parameters, rs, proc, length) 55 case types.T_date: 56 return opBetweenFixed[types.Date](parameters, rs, proc, length) 57 case types.T_datetime: 58 return opBetweenFixed[types.Datetime](parameters, rs, proc, length) 59 case types.T_time: 60 return opBetweenFixed[types.Time](parameters, rs, proc, length) 61 case types.T_timestamp: 62 return opBetweenFixed[types.Timestamp](parameters, rs, proc, length) 63 64 case types.T_uuid: 65 return opBetweenFixedWithFn(parameters, rs, proc, length, func(lhs, rhs types.Uuid) bool { 66 return types.CompareUuid(lhs, rhs) <= 0 67 }) 68 case types.T_decimal64: 69 return opBetweenFixedWithFn(parameters, rs, proc, length, func(lhs, rhs types.Decimal64) bool { 70 return lhs.Compare(rhs) <= 0 71 }) 72 case types.T_decimal128: 73 return opBetweenFixedWithFn(parameters, rs, proc, length, func(lhs, rhs types.Decimal128) bool { 74 return lhs.Compare(rhs) <= 0 75 }) 76 case types.T_Rowid: 77 return opBetweenFixedWithFn(parameters, rs, proc, length, func(lhs, rhs types.Rowid) bool { 78 return lhs.Le(rhs) 79 }) 80 81 case types.T_char, types.T_varchar, types.T_blob, types.T_text, types.T_binary, types.T_varbinary: 82 return opBetweenBytes(parameters, rs, proc, length) 83 } 84 85 panic("unreached code") 86 } 87 88 func opBetweenBool( 89 parameters []*vector.Vector, 90 result vector.FunctionResultWrapper, 91 _ *process.Process, 92 length int, 93 ) error { 94 p0 := vector.GenerateFunctionFixedTypeParameter[bool](parameters[0]) 95 p1 := vector.GenerateFunctionFixedTypeParameter[bool](parameters[1]) 96 p2 := vector.GenerateFunctionFixedTypeParameter[bool](parameters[2]) 97 rs := vector.MustFunctionResult[bool](result) 98 rsVec := rs.GetResultVector() 99 rss := vector.MustFixedCol[bool](rsVec) 100 101 // The lower and upper bound of BETWEEN must be non-null constants, or it should be collapsed to "a >= b and a <= c" 102 lb, _ := p1.GetValue(0) 103 ub, _ := p2.GetValue(0) 104 alwaysTrue := lb != ub 105 106 if parameters[0].IsConst() { 107 v0, null0 := p0.GetValue(0) 108 if null0 { 109 nulls.AddRange(rsVec.GetNulls(), 0, uint64(length)) 110 } else { 111 if alwaysTrue { 112 for i := 0; i < length; i++ { 113 rss[i] = true 114 } 115 } 116 r := lb == v0 117 for i := 0; i < length; i++ { 118 rss[i] = r 119 } 120 } 121 return nil 122 } 123 124 // basic case. 125 if p0.WithAnyNullValue() { 126 nulls.Set(rsVec.GetNulls(), parameters[0].GetNulls()) 127 for i := 0; i < length; i++ { 128 v0, null0 := p0.GetValue(uint64(i)) 129 if null0 { 130 continue 131 } 132 rss[i] = alwaysTrue || lb == v0 133 } 134 return nil 135 } 136 137 if alwaysTrue { 138 for i := 0; i < length; i++ { 139 rss[i] = true 140 } 141 } else { 142 for i := 0; i < length; i++ { 143 v0, _ := p0.GetValue(uint64(i)) 144 rss[i] = lb == v0 145 } 146 } 147 return nil 148 } 149 150 func opBetweenFixed[T constraints.Integer | constraints.Float]( 151 parameters []*vector.Vector, 152 result vector.FunctionResultWrapper, 153 _ *process.Process, 154 length int, 155 ) error { 156 p0 := vector.GenerateFunctionFixedTypeParameter[T](parameters[0]) 157 p1 := vector.GenerateFunctionFixedTypeParameter[T](parameters[1]) 158 p2 := vector.GenerateFunctionFixedTypeParameter[T](parameters[2]) 159 rs := vector.MustFunctionResult[bool](result) 160 rsVec := rs.GetResultVector() 161 rss := vector.MustFixedCol[bool](rsVec) 162 163 // The lower and upper bound of BETWEEN must be non-null constants, or it should be collapsed to "a >= b and a <= c" 164 lb, _ := p1.GetValue(0) 165 ub, _ := p2.GetValue(0) 166 167 if parameters[0].IsConst() { 168 v0, null0 := p0.GetValue(0) 169 if null0 { 170 nulls.AddRange(rsVec.GetNulls(), 0, uint64(length)) 171 } else { 172 r := v0 >= lb && v0 <= ub 173 rowCount := uint64(length) 174 for i := uint64(0); i < rowCount; i++ { 175 rss[i] = r 176 } 177 } 178 return nil 179 } 180 181 // basic case. 182 if p0.WithAnyNullValue() { 183 nulls.Set(rsVec.GetNulls(), parameters[0].GetNulls()) 184 rowCount := uint64(length) 185 for i := uint64(0); i < rowCount; i++ { 186 v0, null0 := p0.GetValue(i) 187 if null0 { 188 continue 189 } 190 rss[i] = v0 >= lb && v0 <= ub 191 } 192 return nil 193 } 194 195 rowCount := uint64(length) 196 for i := uint64(0); i < rowCount; i++ { 197 v0, _ := p0.GetValue(i) 198 rss[i] = v0 >= lb && v0 <= ub 199 } 200 return nil 201 } 202 203 func opBetweenFixedWithFn[T types.FixedSizeTExceptStrType]( 204 parameters []*vector.Vector, 205 result vector.FunctionResultWrapper, 206 _ *process.Process, 207 length int, 208 lessEqualFn func(v1, v2 T) bool, 209 ) error { 210 p0 := vector.GenerateFunctionFixedTypeParameter[T](parameters[0]) 211 p1 := vector.GenerateFunctionFixedTypeParameter[T](parameters[1]) 212 p2 := vector.GenerateFunctionFixedTypeParameter[T](parameters[2]) 213 rs := vector.MustFunctionResult[bool](result) 214 rsVec := rs.GetResultVector() 215 rss := vector.MustFixedCol[bool](rsVec) 216 217 // The lower and upper bound of BETWEEN must be non-null constants, or it should be collapsed to "a >= b and a <= c" 218 lb, _ := p1.GetValue(0) 219 ub, _ := p2.GetValue(0) 220 221 if parameters[0].IsConst() { 222 v0, null0 := p0.GetValue(0) 223 if null0 { 224 nulls.AddRange(rsVec.GetNulls(), 0, uint64(length)) 225 } else { 226 r := lessEqualFn(lb, v0) && lessEqualFn(v0, ub) 227 rowCount := uint64(length) 228 for i := uint64(0); i < rowCount; i++ { 229 rss[i] = r 230 } 231 } 232 return nil 233 } 234 235 // basic case. 236 if p0.WithAnyNullValue() { 237 nulls.Set(rsVec.GetNulls(), parameters[0].GetNulls()) 238 rowCount := uint64(length) 239 for i := uint64(0); i < rowCount; i++ { 240 v0, null0 := p0.GetValue(i) 241 if null0 { 242 continue 243 } 244 rss[i] = lessEqualFn(lb, v0) && lessEqualFn(v0, ub) 245 } 246 return nil 247 } 248 249 rowCount := uint64(length) 250 for i := uint64(0); i < rowCount; i++ { 251 v0, _ := p0.GetValue(i) 252 rss[i] = lessEqualFn(lb, v0) && lessEqualFn(v0, ub) 253 } 254 return nil 255 } 256 257 func opBetweenBytes( 258 parameters []*vector.Vector, 259 result vector.FunctionResultWrapper, 260 _ *process.Process, 261 length int, 262 ) error { 263 p0 := vector.GenerateFunctionStrParameter(parameters[0]) 264 p1 := vector.GenerateFunctionStrParameter(parameters[1]) 265 p2 := vector.GenerateFunctionStrParameter(parameters[2]) 266 rs := vector.MustFunctionResult[bool](result) 267 rsVec := rs.GetResultVector() 268 rss := vector.MustFixedCol[bool](rsVec) 269 270 // The lower and upper bound of BETWEEN must be non-null constants, or it should be collapsed to "a >= b and a <= c" 271 lb, _ := p1.GetStrValue(0) 272 ub, _ := p2.GetStrValue(0) 273 274 if parameters[0].IsConst() { 275 v0, null0 := p0.GetStrValue(0) 276 if null0 { 277 nulls.AddRange(rsVec.GetNulls(), 0, uint64(length)) 278 } else { 279 r := bytes.Compare(v0, lb) >= 0 && bytes.Compare(v0, ub) <= 0 280 rowCount := uint64(length) 281 for i := uint64(0); i < rowCount; i++ { 282 rss[i] = r 283 } 284 } 285 return nil 286 } 287 288 // basic case. 289 if p0.WithAnyNullValue() { 290 nulls.Set(rsVec.GetNulls(), parameters[0].GetNulls()) 291 rowCount := uint64(length) 292 for i := uint64(0); i < rowCount; i++ { 293 v0, null0 := p0.GetStrValue(i) 294 if null0 { 295 continue 296 } 297 rss[i] = bytes.Compare(v0, lb) >= 0 && bytes.Compare(v0, ub) <= 0 298 } 299 return nil 300 } 301 302 rowCount := uint64(length) 303 for i := uint64(0); i < rowCount; i++ { 304 v0, _ := p0.GetStrValue(i) 305 rss[i] = bytes.Compare(v0, lb) >= 0 && bytes.Compare(v0, ub) <= 0 306 } 307 return nil 308 }