github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/plan/function/func_prefix.go (about) 1 // Copyright 2024 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 "sort" 20 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 ) 25 26 func PrefixEq(parameters []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) error { 27 lvec := parameters[0] 28 rval := parameters[1].GetBytesAt(0) 29 res := vector.MustFixedCol[bool](result.GetResultVector()) 30 31 lcol, larea := vector.MustVarlenaRawData(lvec) 32 33 if lvec.GetSorted() { 34 lowerBound := sort.Search(len(lcol), func(i int) bool { 35 return bytes.Compare(rval, lcol[i].GetByteSlice(larea)) <= 0 36 }) 37 38 upperBound := lowerBound 39 for upperBound < len(lcol) && bytes.HasPrefix(lcol[upperBound].GetByteSlice(larea), rval) { 40 upperBound++ 41 } 42 43 for i := 0; i < lowerBound; i++ { 44 res[i] = false 45 } 46 for i := lowerBound; i < upperBound; i++ { 47 res[i] = true 48 } 49 for i := upperBound; i < length; i++ { 50 res[i] = false 51 } 52 } else { 53 for i := 0; i < length; i++ { 54 res[i] = bytes.HasPrefix(lcol[i].GetByteSlice(larea), rval) 55 } 56 } 57 58 return nil 59 } 60 61 func PrefixBetween(parameters []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) error { 62 ivec := parameters[0] 63 lval := parameters[1].GetBytesAt(0) 64 rval := parameters[2].GetBytesAt(0) 65 res := vector.MustFixedCol[bool](result.GetResultVector()) 66 67 icol, iarea := vector.MustVarlenaRawData(ivec) 68 69 if ivec.GetSorted() { 70 lowerBound := sort.Search(len(icol), func(i int) bool { 71 return types.PrefixCompare(icol[i].GetByteSlice(iarea), lval) >= 0 72 }) 73 74 upperBound := sort.Search(len(icol), func(i int) bool { 75 return types.PrefixCompare(icol[i].GetByteSlice(iarea), rval) > 0 76 }) 77 78 for i := 0; i < lowerBound; i++ { 79 res[i] = false 80 } 81 for i := lowerBound; i < upperBound; i++ { 82 res[i] = true 83 } 84 for i := upperBound; i < length; i++ { 85 res[i] = false 86 } 87 } else { 88 for i := 0; i < length; i++ { 89 val := icol[i].GetByteSlice(iarea) 90 res[i] = types.PrefixCompare(val, lval) >= 0 && types.PrefixCompare(val, rval) <= 0 91 } 92 } 93 94 return nil 95 } 96 97 func PrefixIn(parameters []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) error { 98 lvec := parameters[0] 99 rvec := parameters[1] 100 res := vector.MustFixedCol[bool](result.GetResultVector()) 101 102 lcol, larea := vector.MustVarlenaRawData(lvec) 103 rcol, rarea := vector.MustVarlenaRawData(rvec) 104 105 if lvec.GetSorted() { 106 rval := rcol[0].GetByteSlice(rarea) 107 rpos := 0 108 rlen := rvec.Length() 109 110 for i := 0; i < length; i++ { 111 lval := lcol[i].GetByteSlice(larea) 112 for types.PrefixCompare(lval, rval) > 0 { 113 rpos++ 114 if rpos == rlen { 115 for j := i; j < length; j++ { 116 res[j] = false 117 } 118 return nil 119 } 120 121 rval = rcol[rpos].GetByteSlice(rarea) 122 } 123 124 res[i] = bytes.HasPrefix(lval, rval) 125 } 126 } else { 127 for i := 0; i < length; i++ { 128 lval := lcol[i].GetByteSlice(larea) 129 rpos, _ := sort.Find(len(rcol), func(j int) int { 130 return types.PrefixCompare(lval, rcol[j].GetByteSlice(rarea)) 131 }) 132 133 res[i] = rpos < len(rcol) && bytes.HasPrefix(lval, rcol[rpos].GetByteSlice(rarea)) 134 } 135 } 136 137 return nil 138 }