github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/builtin/multi/field.go (about) 1 // Copyright 2022 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 multi 16 17 import ( 18 "github.com/matrixorigin/matrixone/pkg/container/nulls" 19 "github.com/matrixorigin/matrixone/pkg/container/types" 20 "github.com/matrixorigin/matrixone/pkg/container/vector" 21 "github.com/matrixorigin/matrixone/pkg/vm/process" 22 "golang.org/x/exp/constraints" 23 ) 24 25 type number interface { 26 constraints.Unsigned | constraints.Signed | constraints.Float 27 } 28 29 func FieldString(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 30 firstVector := vs[0] 31 firstValues := vector.MustStrCols(firstVector) 32 33 vecLen := vector.Length(firstVector) 34 35 //return vector 36 returnType := types.T_uint64.ToType() 37 resultVector, err := proc.AllocVector(returnType, int64(vecLen*returnType.Oid.TypeLen())) 38 if err != nil { 39 return nil, err 40 } 41 rs := vector.MustTCols[uint64](resultVector) 42 43 //if first vector is scalar 44 if firstVector.IsScalar() { 45 46 //if first vector is null, the return value is 0 47 if firstVector.IsScalarNull() { 48 return vector.NewConstFixed(returnType, vecLen, uint64(0), proc.Mp()), err 49 } 50 51 //detect index 52 startIdx := 1 53 54 //detect in pre scalar vector 55 for i := 1; i < len(vs); i++ { 56 input := vs[i] 57 if input.IsScalar() { 58 if !input.IsScalarNull() { 59 cols := vector.MustStrCols(input) 60 if firstValues[0] == cols[0] { 61 return vector.NewConstFixed(returnType, input.Length(), uint64(i), proc.Mp()), err 62 } 63 } 64 } else { 65 startIdx = i 66 break 67 } 68 } 69 70 //shouldReturn represents the non-null counts 71 shouldReturn := vecLen 72 73 for i := startIdx; i < len(vs); i++ { 74 input := vs[i] 75 cols := vector.MustStrCols(input) 76 77 if input.IsScalar() { 78 if !input.IsScalarNull() { 79 if firstValues[0] == cols[0] { 80 for j := 0; j < vecLen; j++ { 81 if rs[j] == 0 { 82 rs[j] = uint64(i) 83 } 84 } 85 break 86 } 87 } 88 } else { 89 for j := 0; j < vecLen; j++ { 90 if !nulls.Contains(input.Nsp, uint64(j)) && rs[j] == 0 && firstValues[0] == cols[j] { 91 rs[j] = uint64(i) 92 shouldReturn-- 93 } 94 } 95 if shouldReturn == 0 { 96 break 97 } 98 } 99 } 100 return resultVector, nil 101 } else { 102 103 //if the first vector is null 104 nullsLength := nulls.Length(firstVector.Nsp) 105 if nullsLength == vecLen { 106 return resultVector, nil 107 } 108 109 //shouldReturn represents the non-null counts 110 shouldReturn := vecLen - nullsLength 111 112 for i := 1; i < len(vs); i++ { 113 input := vs[i] 114 cols := vector.MustStrCols(input) 115 116 if input.IsScalar() { 117 if !input.IsScalarNull() { 118 for j := 0; j < vecLen; j++ { 119 if rs[j] == 0 && firstValues[j] == cols[0] { 120 rs[j] = uint64(i) 121 shouldReturn-- 122 } 123 } 124 } 125 } else { 126 for j := 0; j < vecLen; j++ { 127 if !nulls.Contains(input.Nsp, uint64(j)) && rs[j] == 0 && firstValues[j] == cols[j] { 128 rs[j] = uint64(i) 129 shouldReturn-- 130 } 131 } 132 } 133 134 if shouldReturn == 0 { 135 break 136 } 137 138 } 139 140 return resultVector, nil 141 } 142 } 143 144 func FieldNumber[T number](vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 145 firstVector := vs[0] 146 firstValues := vector.MustTCols[T](firstVector) 147 148 vecLen := vector.Length(firstVector) 149 150 //return vector 151 returnType := types.T_uint64.ToType() 152 resultVector, err := proc.AllocVector(returnType, int64(vecLen*returnType.Oid.TypeLen())) 153 if err != nil { 154 return nil, err 155 } 156 rs := vector.MustTCols[uint64](resultVector) 157 158 //if first vector is scalar 159 if firstVector.IsScalar() { 160 161 //if first vector is null, the return value is 0 162 if firstVector.IsScalarNull() { 163 return vector.NewConstFixed(returnType, vecLen, uint64(0), proc.Mp()), err 164 } 165 166 //detect index 167 startIdx := 1 168 169 //detect in pre scalar vector 170 for i := 1; i < len(vs); i++ { 171 input := vs[i] 172 if input.IsScalar() { 173 if !input.IsScalarNull() { 174 cols := vector.MustTCols[T](input) 175 if firstValues[0] == cols[0] { 176 return vector.NewConstFixed(returnType, input.Length(), uint64(i), proc.Mp()), err 177 } 178 } 179 } else { 180 startIdx = i 181 break 182 } 183 } 184 185 //shouldReturn represents the non-null counts 186 shouldReturn := vecLen 187 188 for i := startIdx; i < len(vs); i++ { 189 input := vs[i] 190 cols := vector.MustTCols[T](input) 191 192 if input.IsScalar() { 193 if !input.IsScalarNull() { 194 if firstValues[0] == cols[0] { 195 for j := 0; j < vecLen; j++ { 196 if rs[j] == 0 { 197 rs[j] = uint64(i) 198 } 199 } 200 break 201 } 202 } 203 } else { 204 for j := 0; j < vecLen; j++ { 205 if !nulls.Contains(input.Nsp, uint64(j)) && rs[j] == 0 && firstValues[0] == cols[j] { 206 rs[j] = uint64(i) 207 shouldReturn-- 208 } 209 } 210 if shouldReturn == 0 { 211 break 212 } 213 } 214 } 215 return resultVector, nil 216 } else { 217 218 //if the first vector is null 219 nullsLength := nulls.Length(firstVector.Nsp) 220 if nullsLength == vecLen { 221 return resultVector, nil 222 } 223 224 //shouldReturn represents the non-null counts 225 shouldReturn := vecLen - nullsLength 226 227 for i := 1; i < len(vs); i++ { 228 input := vs[i] 229 cols := vector.MustTCols[T](input) 230 231 if input.IsScalar() { 232 if !input.IsScalarNull() { 233 for j := 0; j < vecLen; j++ { 234 if rs[j] == 0 && firstValues[j] == cols[0] { 235 rs[j] = uint64(i) 236 shouldReturn-- 237 } 238 } 239 } 240 } else { 241 for j := 0; j < vecLen; j++ { 242 if !nulls.Contains(input.Nsp, uint64(j)) && rs[j] == 0 && firstValues[j] == cols[j] { 243 rs[j] = uint64(i) 244 shouldReturn-- 245 } 246 } 247 } 248 249 if shouldReturn == 0 { 250 break 251 } 252 253 } 254 return resultVector, nil 255 } 256 }