github.com/matrixorigin/matrixone@v0.7.0/pkg/container/vector/tools.go (about) 1 // Copyright 2021 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 vector 16 17 import ( 18 "context" 19 "strings" 20 21 "github.com/matrixorigin/matrixone/pkg/common/mpool" 22 23 "github.com/matrixorigin/matrixone/pkg/common/moerr" 24 "github.com/matrixorigin/matrixone/pkg/container/nulls" 25 "github.com/matrixorigin/matrixone/pkg/container/types" 26 "github.com/matrixorigin/matrixone/pkg/pb/api" 27 "github.com/matrixorigin/matrixone/pkg/pb/plan" 28 "golang.org/x/exp/constraints" 29 ) 30 31 // CheckInsertVector vector.data will not be nil when insert rows 32 func CheckInsertVector(v *Vector, m *mpool.MPool) *Vector { 33 if v.data == nil && v.Typ.Oid != types.T_any && v.Length() > 0 { 34 newVec := New(v.Typ) 35 newVec.isConst = v.isConst 36 val := GetInitConstVal(v.Typ) 37 for i := 0; i < v.Length(); i++ { 38 newVec.Append(val, true, m) 39 } 40 newVec.length = v.length 41 return newVec 42 } 43 return v 44 } 45 46 func MustTCols[T types.FixedSizeT](v *Vector) []T { 47 // XXX hack. Sometimes we generate an t_any, for untyped const null. 48 // This should be handled more carefully and gracefully. 49 if v.GetType().Oid == types.T_any { 50 return nil 51 } 52 53 if t, ok := v.Col.([]T); ok { 54 return t 55 } 56 panic("unexpected parameter types were received") 57 } 58 59 func MustBytesCols(v *Vector) [][]byte { 60 varcol := MustTCols[types.Varlena](v) 61 ret := make([][]byte, len(varcol)) 62 for i := range varcol { 63 ret[i] = (&varcol[i]).GetByteSlice(v.area) 64 } 65 return ret 66 } 67 68 func MustStrCols(v *Vector) []string { 69 varcol := MustTCols[types.Varlena](v) 70 ret := make([]string, len(varcol)) 71 for i := range varcol { 72 ret[i] = (&varcol[i]).GetString(v.area) 73 } 74 return ret 75 } 76 77 func MustVarlenaRawData(v *Vector) (data []types.Varlena, area []byte) { 78 data = MustTCols[types.Varlena](v) 79 area = v.area 80 return 81 } 82 83 func BuildVarlenaVector(typ types.Type, data []types.Varlena, area []byte) (vec *Vector, err error) { 84 vec = NewOriginal(typ) 85 vec.data = types.EncodeSlice(data) 86 vec.area = area 87 vec.colFromData() 88 return 89 } 90 91 func VectorToProtoVector(vec *Vector) (*api.Vector, error) { 92 nsp, err := vec.Nsp.Show() 93 if err != nil { 94 return nil, err 95 } 96 return &api.Vector{ 97 Nsp: nsp, 98 Nullable: true, 99 Area: vec.area, 100 IsConst: vec.isConst, 101 Len: uint32(vec.length), 102 Type: TypeToProtoType(vec.Typ), 103 Data: vec.encodeColToByteSlice(), 104 }, nil 105 } 106 107 func ProtoVectorToVector(vec *api.Vector) (*Vector, error) { 108 rvec := &Vector{ 109 original: true, 110 data: vec.Data, 111 area: vec.Area, 112 isConst: vec.IsConst, 113 length: int(vec.Len), 114 Typ: ProtoTypeToType(vec.Type), 115 } 116 rvec.Nsp = &nulls.Nulls{} 117 if err := rvec.Nsp.Read(vec.Nsp); err != nil { 118 return nil, err 119 } 120 rvec.colFromData() 121 return rvec, nil 122 } 123 124 func TypeToProtoType(typ types.Type) *plan.Type { 125 return &plan.Type{ 126 Id: int32(typ.Oid), 127 Width: typ.Width, 128 Precision: typ.Precision, 129 Size: typ.Size, 130 Scale: typ.Scale, 131 } 132 } 133 134 func ProtoTypeToType(typ *plan.Type) types.Type { 135 return types.Type{ 136 Oid: types.T(typ.Id), 137 Size: typ.Size, 138 Width: typ.Width, 139 Scale: typ.Scale, 140 Precision: typ.Precision, 141 } 142 } 143 144 func (v *Vector) colFromData() { 145 if v.data == nil { 146 v.Col = nil 147 } 148 149 if v.Typ.Oid == types.T_tuple || v.Typ.Oid == types.T_any { 150 // No op 151 } else if v.GetType().IsVarlen() { 152 v.Col = DecodeFixedCol[types.Varlena](v, types.VarlenaSize) 153 } else { 154 // The followng switch attach the correct type to v.Col 155 // even though v.Col is only an interface. 156 tlen := v.GetType().TypeSize() 157 switch v.Typ.Oid { 158 case types.T_bool: 159 v.Col = DecodeFixedCol[bool](v, tlen) 160 case types.T_int8: 161 v.Col = DecodeFixedCol[int8](v, tlen) 162 case types.T_int16: 163 v.Col = DecodeFixedCol[int16](v, tlen) 164 case types.T_int32: 165 v.Col = DecodeFixedCol[int32](v, tlen) 166 case types.T_int64: 167 v.Col = DecodeFixedCol[int64](v, tlen) 168 case types.T_uint8: 169 v.Col = DecodeFixedCol[uint8](v, tlen) 170 case types.T_uint16: 171 v.Col = DecodeFixedCol[uint16](v, tlen) 172 case types.T_uint32: 173 v.Col = DecodeFixedCol[uint32](v, tlen) 174 case types.T_uint64: 175 v.Col = DecodeFixedCol[uint64](v, tlen) 176 case types.T_float32: 177 v.Col = DecodeFixedCol[float32](v, tlen) 178 case types.T_float64: 179 v.Col = DecodeFixedCol[float64](v, tlen) 180 case types.T_decimal64: 181 v.Col = DecodeFixedCol[types.Decimal64](v, tlen) 182 case types.T_decimal128: 183 v.Col = DecodeFixedCol[types.Decimal128](v, tlen) 184 case types.T_uuid: 185 v.Col = DecodeFixedCol[types.Uuid](v, tlen) 186 case types.T_date: 187 v.Col = DecodeFixedCol[types.Date](v, tlen) 188 case types.T_time: 189 v.Col = DecodeFixedCol[types.Time](v, tlen) 190 case types.T_datetime: 191 v.Col = DecodeFixedCol[types.Datetime](v, tlen) 192 case types.T_timestamp: 193 v.Col = DecodeFixedCol[types.Timestamp](v, tlen) 194 case types.T_TS: 195 v.Col = DecodeFixedCol[types.TS](v, tlen) 196 case types.T_Rowid: 197 v.Col = DecodeFixedCol[types.Rowid](v, tlen) 198 default: 199 panic("unknown type") 200 } 201 } 202 } 203 204 func (v *Vector) setupColFromData(start, end int) { 205 if v.Typ.Oid == types.T_tuple { 206 vec := v.Col.([][]interface{}) 207 v.Col = vec[start:end] 208 } else if v.GetType().IsVarlen() { 209 v.Col = DecodeFixedCol[types.Varlena](v, types.VarlenaSize)[start:end] 210 } else { 211 // The followng switch attach the correct type to v.Col 212 // even though v.Col is only an interface. 213 tlen := v.GetType().TypeSize() 214 switch v.Typ.Oid { 215 case types.T_bool: 216 v.Col = DecodeFixedCol[bool](v, tlen)[start:end] 217 case types.T_int8: 218 v.Col = DecodeFixedCol[int8](v, tlen)[start:end] 219 case types.T_int16: 220 v.Col = DecodeFixedCol[int16](v, tlen)[start:end] 221 case types.T_int32: 222 v.Col = DecodeFixedCol[int32](v, tlen)[start:end] 223 case types.T_int64: 224 v.Col = DecodeFixedCol[int64](v, tlen)[start:end] 225 case types.T_uint8: 226 v.Col = DecodeFixedCol[uint8](v, tlen)[start:end] 227 case types.T_uint16: 228 v.Col = DecodeFixedCol[uint16](v, tlen)[start:end] 229 case types.T_uint32: 230 v.Col = DecodeFixedCol[uint32](v, tlen)[start:end] 231 case types.T_uint64: 232 v.Col = DecodeFixedCol[uint64](v, tlen)[start:end] 233 case types.T_float32: 234 v.Col = DecodeFixedCol[float32](v, tlen)[start:end] 235 case types.T_float64: 236 v.Col = DecodeFixedCol[float64](v, tlen)[start:end] 237 case types.T_decimal64: 238 v.Col = DecodeFixedCol[types.Decimal64](v, tlen)[start:end] 239 case types.T_decimal128: 240 v.Col = DecodeFixedCol[types.Decimal128](v, tlen)[start:end] 241 case types.T_uuid: 242 v.Col = DecodeFixedCol[types.Uuid](v, tlen)[start:end] 243 case types.T_date: 244 v.Col = DecodeFixedCol[types.Date](v, tlen)[start:end] 245 case types.T_time: 246 v.Col = DecodeFixedCol[types.Time](v, tlen)[start:end] 247 case types.T_datetime: 248 v.Col = DecodeFixedCol[types.Datetime](v, tlen)[start:end] 249 case types.T_timestamp: 250 v.Col = DecodeFixedCol[types.Timestamp](v, tlen)[start:end] 251 case types.T_TS: 252 v.Col = DecodeFixedCol[types.TS](v, tlen)[start:end] 253 case types.T_Rowid: 254 v.Col = DecodeFixedCol[types.Rowid](v, tlen)[start:end] 255 default: 256 panic("unknown type") 257 } 258 } 259 } 260 261 func (v *Vector) encodeColToByteSlice() []byte { 262 if v.Col == nil { 263 return nil 264 } 265 switch v.GetType().Oid { 266 case types.T_bool: 267 return types.EncodeSlice(v.Col.([]bool)) 268 case types.T_int8: 269 return types.EncodeSlice(v.Col.([]int8)) 270 case types.T_int16: 271 return types.EncodeSlice(v.Col.([]int16)) 272 case types.T_int32: 273 return types.EncodeSlice(v.Col.([]int32)) 274 case types.T_int64: 275 return types.EncodeSlice(v.Col.([]int64)) 276 case types.T_uint8: 277 return types.EncodeSlice(v.Col.([]uint8)) 278 case types.T_uint16: 279 return types.EncodeSlice(v.Col.([]uint16)) 280 case types.T_uint32: 281 return types.EncodeSlice(v.Col.([]uint32)) 282 case types.T_uint64: 283 return types.EncodeSlice(v.Col.([]uint64)) 284 case types.T_float32: 285 return types.EncodeSlice(v.Col.([]float32)) 286 case types.T_float64: 287 return types.EncodeSlice(v.Col.([]float64)) 288 case types.T_decimal64: 289 return types.EncodeSlice(v.Col.([]types.Decimal64)) 290 case types.T_decimal128: 291 return types.EncodeSlice(v.Col.([]types.Decimal128)) 292 case types.T_uuid: 293 return types.EncodeSlice(v.Col.([]types.Uuid)) 294 case types.T_date: 295 return types.EncodeSlice(v.Col.([]types.Date)) 296 case types.T_time: 297 return types.EncodeSlice(v.Col.([]types.Time)) 298 case types.T_datetime: 299 return types.EncodeSlice(v.Col.([]types.Datetime)) 300 case types.T_timestamp: 301 return types.EncodeSlice(v.Col.([]types.Timestamp)) 302 case types.T_TS: 303 return types.EncodeSlice(v.Col.([]types.TS)) 304 case types.T_Rowid: 305 return types.EncodeSlice(v.Col.([]types.Rowid)) 306 case types.T_char, types.T_varchar, types.T_blob, types.T_json, types.T_text: 307 return types.EncodeSlice(v.Col.([]types.Varlena)) 308 case types.T_tuple: 309 bs, _ := types.Encode(v.Col.([][]interface{})) 310 return bs 311 default: 312 panic("unknow type when encode vector column") 313 } 314 } 315 316 // XXX extend will extend the vector's Data to accommodate rows more entry. 317 func (v *Vector) extend(rows int, m *mpool.MPool) error { 318 origSz := len(v.data) 319 growSz := rows * v.GetType().TypeSize() 320 tgtSz := origSz + growSz 321 if tgtSz <= cap(v.data) { 322 // XXX v.data can hold data, just grow. 323 // XXX do not use Grow, because this case it will still malloc and copy 324 v.data = v.data[:tgtSz] 325 } else if v.data == nil { 326 // XXX mheap Relloc is broken, cannot handle nil, so we Alloc here. 327 // XXX The interface on size, int/int64 u, FUBAR. 328 data, err := m.Alloc(tgtSz) 329 if err != nil { 330 return err 331 } 332 v.data = data[:tgtSz] 333 } else { 334 data, err := m.Grow(v.data, tgtSz) 335 if err != nil { 336 return err 337 } 338 v.data = data[:tgtSz] 339 } 340 341 newRows := int(tgtSz / v.GetType().TypeSize()) 342 // Setup v.Col 343 v.setupColFromData(0, newRows) 344 return nil 345 } 346 347 // CompareAndCheckIntersect we use this method for eval expr by zonemap 348 func (v *Vector) CompareAndCheckIntersect(ctx context.Context, vec *Vector) (bool, error) { 349 switch v.Typ.Oid { 350 case types.T_int8: 351 return checkNumberIntersect[int8](v, vec) 352 case types.T_int16: 353 return checkNumberIntersect[int16](v, vec) 354 case types.T_int32: 355 return checkNumberIntersect[int32](v, vec) 356 case types.T_int64: 357 return checkNumberIntersect[int64](v, vec) 358 case types.T_uint8: 359 return checkNumberIntersect[uint8](v, vec) 360 case types.T_uint16: 361 return checkNumberIntersect[uint16](v, vec) 362 case types.T_uint32: 363 return checkNumberIntersect[uint32](v, vec) 364 case types.T_uint64: 365 return checkNumberIntersect[uint64](v, vec) 366 case types.T_float32: 367 return checkNumberIntersect[float32](v, vec) 368 case types.T_float64: 369 return checkNumberIntersect[float64](v, vec) 370 case types.T_date: 371 return checkNumberIntersect[types.Date](v, vec) 372 case types.T_time: 373 return checkNumberIntersect[types.Time](v, vec) 374 case types.T_datetime: 375 return checkNumberIntersect[types.Datetime](v, vec) 376 case types.T_timestamp: 377 return checkNumberIntersect[types.Timestamp](v, vec) 378 case types.T_decimal64: 379 return checkGeneralIntersect(v, vec, func(t1, t2 types.Decimal64) bool { 380 return t1.Ge(t2) 381 }, func(t1, t2 types.Decimal64) bool { 382 return t1.Le(t2) 383 }) 384 case types.T_decimal128: 385 return checkGeneralIntersect(v, vec, func(t1, t2 types.Decimal128) bool { 386 return t1.Ge(t2) 387 }, func(t1, t2 types.Decimal128) bool { 388 return t1.Le(t2) 389 }) 390 case types.T_uuid: 391 return checkGeneralIntersect(v, vec, func(t1, t2 types.Uuid) bool { 392 return t1.Ge(t2) 393 }, func(t1, t2 types.Uuid) bool { 394 return t1.Le(t2) 395 }) 396 case types.T_varchar, types.T_char, types.T_text: 397 return checkStrIntersect(v, vec, func(t1, t2 string) bool { 398 return strings.Compare(t1, t2) >= 0 399 }, func(t1, t2 string) bool { 400 return strings.Compare(t1, t2) <= 0 401 }) 402 } 403 return false, moerr.NewInternalError(ctx, "unsupport type to check intersect") 404 } 405 406 func checkNumberIntersect[T constraints.Integer | constraints.Float | types.Date | types.Datetime | types.Timestamp](v1, v2 *Vector) (bool, error) { 407 cols1 := MustTCols[T](v1) 408 cols2 := MustTCols[T](v2) 409 return checkIntersect(cols1, cols2, func(i1, i2 T) bool { 410 return i1 >= i2 411 }, func(i1, i2 T) bool { 412 return i1 <= i2 413 }) 414 } 415 416 func checkStrIntersect(v1, v2 *Vector, gtFun compFn[string], ltFun compFn[string]) (bool, error) { 417 cols1 := MustStrCols(v1) 418 cols2 := MustStrCols(v2) 419 return checkIntersect(cols1, cols2, gtFun, ltFun) 420 } 421 422 func checkGeneralIntersect[T compT](v1, v2 *Vector, gtFun compFn[T], ltFun compFn[T]) (bool, error) { 423 cols1 := MustTCols[T](v1) 424 cols2 := MustTCols[T](v2) 425 return checkIntersect(cols1, cols2, gtFun, ltFun) 426 } 427 428 func checkIntersect[T compT](cols1, cols2 []T, gtFun compFn[T], ltFun compFn[T]) (bool, error) { 429 // get v1's min/max 430 colLength := len(cols1) 431 min := cols1[0] 432 max := cols1[0] 433 for i := 1; i < colLength; i++ { 434 // cols1[i] <= min 435 if ltFun(cols1[i], min) { 436 min = cols1[i] 437 } else if gtFun(cols1[i], max) { 438 // cols1[i] >= max 439 max = cols1[i] 440 } 441 } 442 443 // check v2 if some item >= min && <= max 444 for i := 0; i < len(cols2); i++ { 445 // cols2[i] >= min && cols2[i] <= max 446 if gtFun(cols2[i], min) && ltFun(cols2[i], max) { 447 return true, nil 448 } 449 } 450 return false, nil 451 } 452 453 // CompareAndCheckAnyResultIsTrue we use this method for eval expr by zonemap 454 // funName must be ">,<,>=,<=" 455 func (v *Vector) CompareAndCheckAnyResultIsTrue(ctx context.Context, vec *Vector, funName string) (bool, error) { 456 if v.Typ.Oid != vec.Typ.Oid { 457 return false, moerr.NewInternalError(ctx, "can not compare two vector because their type is not match") 458 } 459 if v.Length() != vec.Length() { 460 return false, moerr.NewInternalError(ctx, "can not compare two vector because their length is not match") 461 } 462 if v.Length() == 0 { 463 return false, moerr.NewInternalError(ctx, "can not compare two vector because their length is zero") 464 } 465 466 switch funName { 467 case ">", "<", ">=", "<=": 468 default: 469 return false, moerr.NewInternalError(ctx, "unsupport compare function") 470 } 471 472 switch v.Typ.Oid { 473 case types.T_int8: 474 return compareNumber[int8](ctx, v, vec, funName) 475 case types.T_int16: 476 return compareNumber[int16](ctx, v, vec, funName) 477 case types.T_int32: 478 return compareNumber[int32](ctx, v, vec, funName) 479 case types.T_int64: 480 return compareNumber[int64](ctx, v, vec, funName) 481 case types.T_uint8: 482 return compareNumber[uint8](ctx, v, vec, funName) 483 case types.T_uint16: 484 return compareNumber[uint16](ctx, v, vec, funName) 485 case types.T_uint32: 486 return compareNumber[uint32](ctx, v, vec, funName) 487 case types.T_uint64: 488 return compareNumber[uint64](ctx, v, vec, funName) 489 case types.T_float32: 490 return compareNumber[float32](ctx, v, vec, funName) 491 case types.T_float64: 492 return compareNumber[float64](ctx, v, vec, funName) 493 case types.T_date: 494 return compareNumber[types.Date](ctx, v, vec, funName) 495 case types.T_time: 496 return compareNumber[types.Time](ctx, v, vec, funName) 497 case types.T_datetime: 498 return compareNumber[types.Datetime](ctx, v, vec, funName) 499 case types.T_timestamp: 500 return compareNumber[types.Timestamp](ctx, v, vec, funName) 501 case types.T_decimal64: 502 switch funName { 503 case ">": 504 return runCompareCheckAnyResultIsTrue(v, vec, func(t1, t2 types.Decimal64) bool { 505 return t1.Gt(t2) 506 }), nil 507 case "<": 508 return runCompareCheckAnyResultIsTrue(v, vec, func(t1, t2 types.Decimal64) bool { 509 return t1.Lt(t2) 510 }), nil 511 case ">=": 512 return runCompareCheckAnyResultIsTrue(v, vec, func(t1, t2 types.Decimal64) bool { 513 return t1.Ge(t2) 514 }), nil 515 case "<=": 516 return runCompareCheckAnyResultIsTrue(v, vec, func(t1, t2 types.Decimal64) bool { 517 return t1.Le(t2) 518 }), nil 519 } 520 case types.T_decimal128: 521 switch funName { 522 case ">": 523 return runCompareCheckAnyResultIsTrue(v, vec, func(t1, t2 types.Decimal128) bool { 524 return t1.Gt(t2) 525 }), nil 526 case "<": 527 return runCompareCheckAnyResultIsTrue(v, vec, func(t1, t2 types.Decimal128) bool { 528 return t1.Lt(t2) 529 }), nil 530 case ">=": 531 return runCompareCheckAnyResultIsTrue(v, vec, func(t1, t2 types.Decimal128) bool { 532 return t1.Ge(t2) 533 }), nil 534 case "<=": 535 return runCompareCheckAnyResultIsTrue(v, vec, func(t1, t2 types.Decimal128) bool { 536 return t1.Le(t2) 537 }), nil 538 } 539 case types.T_uuid: 540 switch funName { 541 case ">": 542 return runCompareCheckAnyResultIsTrue(v, vec, func(t1, t2 types.Uuid) bool { 543 return t1.Gt(t2) 544 }), nil 545 case "<": 546 return runCompareCheckAnyResultIsTrue(v, vec, func(t1, t2 types.Uuid) bool { 547 return t1.Lt(t2) 548 }), nil 549 case ">=": 550 return runCompareCheckAnyResultIsTrue(v, vec, func(t1, t2 types.Uuid) bool { 551 return t1.Ge(t2) 552 }), nil 553 case "<=": 554 return runCompareCheckAnyResultIsTrue(v, vec, func(t1, t2 types.Uuid) bool { 555 return t1.Le(t2) 556 }), nil 557 } 558 case types.T_varchar, types.T_char: 559 switch funName { 560 case ">": 561 return runStrCompareCheckAnyResultIsTrue(v, vec, func(t1, t2 string) bool { 562 return strings.Compare(t1, t2) == 1 563 }), nil 564 case "<": 565 return runStrCompareCheckAnyResultIsTrue(v, vec, func(t1, t2 string) bool { 566 return strings.Compare(t1, t2) == -1 567 }), nil 568 case ">=": 569 return runStrCompareCheckAnyResultIsTrue(v, vec, func(t1, t2 string) bool { 570 return strings.Compare(t1, t2) >= 0 571 }), nil 572 case "<=": 573 return runStrCompareCheckAnyResultIsTrue(v, vec, func(t1, t2 string) bool { 574 return strings.Compare(t1, t2) <= 0 575 }), nil 576 } 577 default: 578 return false, moerr.NewInternalError(ctx, "unsupport compare type") 579 } 580 581 return false, moerr.NewInternalError(ctx, "unsupport compare function") 582 } 583 584 type compT interface { 585 constraints.Integer | constraints.Float | types.Decimal64 | types.Decimal128 | 586 types.Date | types.Time | types.Datetime | types.Timestamp | types.Uuid | string 587 } 588 589 type compFn[T compT] func(T, T) bool 590 type numberType interface { 591 constraints.Integer | constraints.Float | types.Date | types.Time | types.Datetime | types.Timestamp 592 } 593 594 func compareNumber[T numberType](ctx context.Context, v1, v2 *Vector, fnName string) (bool, error) { 595 switch fnName { 596 case ">": 597 return runCompareCheckAnyResultIsTrue(v1, v2, func(t1, t2 T) bool { 598 return t1 > t2 599 }), nil 600 case "<": 601 return runCompareCheckAnyResultIsTrue(v1, v2, func(t1, t2 T) bool { 602 return t1 < t2 603 }), nil 604 case ">=": 605 return runCompareCheckAnyResultIsTrue(v1, v2, func(t1, t2 T) bool { 606 return t1 >= t2 607 }), nil 608 case "<=": 609 return runCompareCheckAnyResultIsTrue(v1, v2, func(t1, t2 T) bool { 610 return t1 <= t2 611 }), nil 612 default: 613 return false, moerr.NewInternalError(ctx, "unsupport compare function") 614 } 615 } 616 617 func runCompareCheckAnyResultIsTrue[T compT](vec1, vec2 *Vector, fn compFn[T]) bool { 618 // column_a operator column_b -> return true 619 // that means we don't known the return, just readBlock 620 if vec1.IsScalarNull() || vec2.IsScalarNull() { 621 return true 622 } 623 if nulls.Any(vec1.Nsp) || nulls.Any(vec2.Nsp) { 624 return true 625 } 626 cols1 := MustTCols[T](vec1) 627 cols2 := MustTCols[T](vec2) 628 return compareCheckAnyResultIsTrue(cols1, cols2, fn) 629 } 630 631 func runStrCompareCheckAnyResultIsTrue(vec1, vec2 *Vector, fn compFn[string]) bool { 632 // column_a operator column_b -> return true 633 // that means we don't known the return, just readBlock 634 if vec1.IsScalarNull() || vec2.IsScalarNull() { 635 return true 636 } 637 if nulls.Any(vec1.Nsp) || nulls.Any(vec2.Nsp) { 638 return true 639 } 640 641 cols1 := MustStrCols(vec1) 642 cols2 := MustStrCols(vec2) 643 return compareCheckAnyResultIsTrue(cols1, cols2, fn) 644 } 645 646 func compareCheckAnyResultIsTrue[T compT](cols1, cols2 []T, fn compFn[T]) bool { 647 for i := 0; i < len(cols1); i++ { 648 for j := 0; j < len(cols2); j++ { 649 if fn(cols1[i], cols2[j]) { 650 return true 651 } 652 } 653 } 654 return false 655 }