github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/colexec/expr_eval.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 colexec 16 17 import ( 18 "context" 19 "fmt" 20 21 "github.com/matrixorigin/matrixone/pkg/common/moerr" 22 "github.com/matrixorigin/matrixone/pkg/container/batch" 23 "github.com/matrixorigin/matrixone/pkg/container/types" 24 "github.com/matrixorigin/matrixone/pkg/container/vector" 25 "github.com/matrixorigin/matrixone/pkg/pb/plan" 26 "github.com/matrixorigin/matrixone/pkg/sql/plan/function" 27 "github.com/matrixorigin/matrixone/pkg/vm/process" 28 ) 29 30 var ( 31 constBType = types.Type{Oid: types.T_bool} 32 constI8Type = types.Type{Oid: types.T_int8} 33 constI16Type = types.Type{Oid: types.T_int16} 34 constI32Type = types.Type{Oid: types.T_int32} 35 constI64Type = types.Type{Oid: types.T_int64} 36 constU8Type = types.Type{Oid: types.T_uint8} 37 constU16Type = types.Type{Oid: types.T_uint16} 38 constU32Type = types.Type{Oid: types.T_uint32} 39 constU64Type = types.Type{Oid: types.T_uint64} 40 constFType = types.Type{Oid: types.T_float32} 41 constDType = types.Type{Oid: types.T_float64} 42 constSType = types.Type{Oid: types.T_varchar, Width: types.MaxVarcharLen} 43 constDateType = types.Type{Oid: types.T_date} 44 constTimeType = types.Type{Oid: types.T_time} 45 constDatetimeType = types.Type{Oid: types.T_datetime} 46 constDecimal64Type = types.Type{Oid: types.T_decimal64} 47 constDecimal128Type = types.Type{Oid: types.T_decimal128} 48 constTimestampTypes = []types.Type{ 49 {Oid: types.T_timestamp}, 50 {Oid: types.T_timestamp, Precision: 1}, 51 {Oid: types.T_timestamp, Precision: 2}, 52 {Oid: types.T_timestamp, Precision: 3}, 53 {Oid: types.T_timestamp, Precision: 4}, 54 {Oid: types.T_timestamp, Precision: 5}, 55 {Oid: types.T_timestamp, Precision: 6}, 56 } 57 ) 58 59 func getConstVecInList(ctx context.Context, proc *process.Process, exprs []*plan.Expr) (*vector.Vector, error) { 60 lenList := len(exprs) 61 vec, err := proc.AllocVectorOfRows(types.T(exprs[0].Typ.Id).ToType(), int64(lenList), nil) 62 if err != nil { 63 panic(moerr.NewOOM(proc.Ctx)) 64 } 65 for i := 0; i < lenList; i++ { 66 expr := exprs[i] 67 t, ok := expr.Expr.(*plan.Expr_C) 68 if !ok { 69 return nil, moerr.NewInternalError(proc.Ctx, "args in list must be constant") 70 } 71 if t.C.GetIsnull() { 72 vec.Nsp.Set(uint64(i)) 73 } else { 74 switch t.C.GetValue().(type) { 75 case *plan.Const_Bval: 76 veccol := vec.Col.([]bool) 77 veccol[i] = t.C.GetBval() 78 case *plan.Const_I8Val: 79 veccol := vec.Col.([]int8) 80 veccol[i] = int8(t.C.GetI8Val()) 81 case *plan.Const_I16Val: 82 veccol := vec.Col.([]int16) 83 veccol[i] = int16(t.C.GetI16Val()) 84 case *plan.Const_I32Val: 85 veccol := vec.Col.([]int32) 86 veccol[i] = t.C.GetI32Val() 87 case *plan.Const_I64Val: 88 veccol := vec.Col.([]int64) 89 veccol[i] = t.C.GetI64Val() 90 case *plan.Const_U8Val: 91 veccol := vec.Col.([]uint8) 92 veccol[i] = uint8(t.C.GetU8Val()) 93 case *plan.Const_U16Val: 94 veccol := vec.Col.([]uint16) 95 veccol[i] = uint16(t.C.GetU16Val()) 96 case *plan.Const_U32Val: 97 veccol := vec.Col.([]uint32) 98 veccol[i] = t.C.GetU32Val() 99 case *plan.Const_U64Val: 100 veccol := vec.Col.([]uint64) 101 veccol[i] = t.C.GetU64Val() 102 case *plan.Const_Fval: 103 veccol := vec.Col.([]float32) 104 veccol[i] = t.C.GetFval() 105 case *plan.Const_Dval: 106 veccol := vec.Col.([]float64) 107 veccol[i] = t.C.GetDval() 108 case *plan.Const_Dateval: 109 veccol := vec.Col.([]types.Date) 110 veccol[i] = types.Date(t.C.GetDateval()) 111 case *plan.Const_Timeval: 112 veccol := vec.Col.([]types.Time) 113 veccol[i] = types.Time(t.C.GetTimeval()) 114 case *plan.Const_Datetimeval: 115 veccol := vec.Col.([]types.Datetime) 116 veccol[i] = types.Datetime(t.C.GetDatetimeval()) 117 case *plan.Const_Decimal64Val: 118 cd64 := t.C.GetDecimal64Val() 119 d64 := types.Decimal64FromInt64Raw(cd64.A) 120 veccol := vec.Col.([]types.Decimal64) 121 veccol[i] = d64 122 case *plan.Const_Decimal128Val: 123 cd128 := t.C.GetDecimal128Val() 124 d128 := types.Decimal128FromInt64Raw(cd128.A, cd128.B) 125 veccol := vec.Col.([]types.Decimal128) 126 veccol[i] = d128 127 case *plan.Const_Timestampval: 128 pre := expr.Typ.Precision 129 if pre < 0 || pre > 6 { 130 return nil, moerr.NewInternalError(proc.Ctx, "invalid timestamp precision") 131 } 132 veccol := vec.Col.([]types.Timestamp) 133 veccol[i] = types.Timestamp(t.C.GetTimestampval()) 134 case *plan.Const_Sval: 135 sval := t.C.GetSval() 136 vector.SetStringAt(vec, i, sval, proc.Mp()) 137 case *plan.Const_Defaultval: 138 defaultVal := t.C.GetDefaultval() 139 veccol := vec.Col.([]bool) 140 veccol[i] = defaultVal 141 default: 142 return nil, moerr.NewNYI(ctx, fmt.Sprintf("const expression %v", t.C.GetValue())) 143 } 144 vec.SetIsBin(t.C.IsBin) 145 } 146 } 147 return vec, nil 148 } 149 150 func getConstVec(ctx context.Context, proc *process.Process, expr *plan.Expr, length int) (*vector.Vector, error) { 151 var vec *vector.Vector 152 t := expr.Expr.(*plan.Expr_C) 153 if t.C.GetIsnull() { 154 if types.T(expr.Typ.GetId()) == types.T_any { 155 vec = vector.NewConstNull(types.Type{Oid: types.T(expr.Typ.GetId())}, length) 156 } else { 157 vec = vector.NewConstNullWithData(types.Type{Oid: types.T(expr.Typ.GetId())}, length, proc.Mp()) 158 } 159 } else { 160 switch t.C.GetValue().(type) { 161 case *plan.Const_Bval: 162 vec = vector.NewConstFixed(constBType, length, t.C.GetBval(), proc.Mp()) 163 case *plan.Const_I8Val: 164 vec = vector.NewConstFixed(constI8Type, length, int8(t.C.GetI8Val()), proc.Mp()) 165 case *plan.Const_I16Val: 166 vec = vector.NewConstFixed(constI16Type, length, int16(t.C.GetI16Val()), proc.Mp()) 167 case *plan.Const_I32Val: 168 vec = vector.NewConstFixed(constI32Type, length, t.C.GetI32Val(), proc.Mp()) 169 case *plan.Const_I64Val: 170 vec = vector.NewConstFixed(constI64Type, length, t.C.GetI64Val(), proc.Mp()) 171 case *plan.Const_U8Val: 172 vec = vector.NewConstFixed(constU8Type, length, uint8(t.C.GetU8Val()), proc.Mp()) 173 case *plan.Const_U16Val: 174 vec = vector.NewConstFixed(constU16Type, length, uint16(t.C.GetU16Val()), proc.Mp()) 175 case *plan.Const_U32Val: 176 vec = vector.NewConstFixed(constU32Type, length, t.C.GetU32Val(), proc.Mp()) 177 case *plan.Const_U64Val: 178 vec = vector.NewConstFixed(constU64Type, length, t.C.GetU64Val(), proc.Mp()) 179 case *plan.Const_Fval: 180 vec = vector.NewConstFixed(constFType, length, t.C.GetFval(), proc.Mp()) 181 case *plan.Const_Dval: 182 vec = vector.NewConstFixed(constDType, length, t.C.GetDval(), proc.Mp()) 183 case *plan.Const_Dateval: 184 vec = vector.NewConstFixed(constDateType, length, types.Date(t.C.GetDateval()), proc.Mp()) 185 case *plan.Const_Timeval: 186 vec = vector.NewConstFixed(constTimeType, length, types.Time(t.C.GetTimeval()), proc.Mp()) 187 case *plan.Const_Datetimeval: 188 vec = vector.NewConstFixed(constDatetimeType, length, types.Datetime(t.C.GetDatetimeval()), proc.Mp()) 189 case *plan.Const_Decimal64Val: 190 cd64 := t.C.GetDecimal64Val() 191 d64 := types.Decimal64FromInt64Raw(cd64.A) 192 vec = vector.NewConstFixed(constDecimal64Type, length, d64, proc.Mp()) 193 case *plan.Const_Decimal128Val: 194 cd128 := t.C.GetDecimal128Val() 195 d128 := types.Decimal128FromInt64Raw(cd128.A, cd128.B) 196 vec = vector.NewConstFixed(constDecimal128Type, length, d128, proc.Mp()) 197 case *plan.Const_Timestampval: 198 pre := expr.Typ.Precision 199 if pre < 0 || pre > 6 { 200 return nil, moerr.NewInternalError(proc.Ctx, "invalid timestamp precision") 201 } 202 vec = vector.NewConstFixed(constTimestampTypes[pre], length, types.Timestamp(t.C.GetTimestampval()), proc.Mp()) 203 case *plan.Const_Sval: 204 sval := t.C.GetSval() 205 vec = vector.NewConstString(constSType, length, sval, proc.Mp()) 206 case *plan.Const_Defaultval: 207 defaultVal := t.C.GetDefaultval() 208 vec = vector.NewConstFixed(constBType, length, defaultVal, proc.Mp()) 209 default: 210 return nil, moerr.NewNYI(ctx, fmt.Sprintf("const expression %v", t.C.GetValue())) 211 } 212 } 213 vec.SetIsBin(t.C.IsBin) 214 return vec, nil 215 } 216 217 func EvalExpr(bat *batch.Batch, proc *process.Process, expr *plan.Expr) (*vector.Vector, error) { 218 if len(bat.Zs) == 0 { 219 return vector.NewConstNull(types.Type{Oid: types.T(expr.Typ.GetId())}, 1), nil 220 } 221 222 var length = len(bat.Zs) 223 e := expr.Expr 224 switch t := e.(type) { 225 case *plan.Expr_C: 226 return getConstVec(proc.Ctx, proc, expr, length) 227 case *plan.Expr_T: 228 // return a vector recorded type information but without real data 229 return vector.NewConst(types.Type{ 230 Oid: types.T(t.T.Typ.GetId()), 231 Width: t.T.Typ.GetWidth(), 232 Scale: t.T.Typ.GetScale(), 233 Precision: t.T.Typ.GetPrecision(), 234 }, len(bat.Zs)), nil 235 case *plan.Expr_Col: 236 vec := bat.Vecs[t.Col.ColPos] 237 if vec.IsScalarNull() { 238 vec.Typ = types.T(expr.Typ.GetId()).ToType() 239 } 240 return vec, nil 241 case *plan.Expr_List: 242 return getConstVecInList(proc.Ctx, proc, t.List.List) 243 case *plan.Expr_F: 244 var result *vector.Vector 245 246 fid := t.F.GetFunc().GetObj() 247 f, err := function.GetFunctionByID(proc.Ctx, fid) 248 if err != nil { 249 return nil, err 250 } 251 252 functionParameters := make([]*vector.Vector, len(t.F.Args)) 253 for i := range functionParameters { 254 functionParameters[i], err = EvalExpr(bat, proc, t.F.Args[i]) 255 if err != nil { 256 break 257 } 258 } 259 if err != nil { 260 cleanVectorsExceptList(proc, functionParameters, bat.Vecs) 261 return nil, err 262 } 263 264 result, err = evalFunction(proc, f, functionParameters, len(bat.Zs)) 265 cleanVectorsExceptList(proc, functionParameters, append(bat.Vecs, result)) 266 if err != nil { 267 return nil, err 268 } 269 return result, nil 270 default: 271 // *plan.Expr_Corr, *plan.Expr_P, *plan.Expr_V, *plan.Expr_Sub 272 return nil, moerr.NewNYI(proc.Ctx, fmt.Sprintf("unsupported eval expr '%v'", t)) 273 } 274 } 275 276 func JoinFilterEvalExpr(r, s *batch.Batch, rRow int, proc *process.Process, expr *plan.Expr) (*vector.Vector, error) { 277 e := expr.Expr 278 switch t := e.(type) { 279 case *plan.Expr_C: 280 return getConstVec(proc.Ctx, proc, expr, 1) 281 case *plan.Expr_T: 282 // return a vector recorded type information but without real data 283 return vector.NewConst(types.Type{ 284 Oid: types.T(t.T.Typ.GetId()), 285 Width: t.T.Typ.GetWidth(), 286 Scale: t.T.Typ.GetScale(), 287 Precision: t.T.Typ.GetPrecision(), 288 }, len(s.Zs)), nil 289 case *plan.Expr_Col: 290 if t.Col.RelPos == 0 { 291 return r.Vecs[t.Col.ColPos].ToConst(rRow, proc.Mp()), nil 292 } 293 return s.Vecs[t.Col.ColPos], nil 294 case *plan.Expr_List: 295 return getConstVecInList(proc.Ctx, proc, t.List.List) 296 case *plan.Expr_F: 297 var result *vector.Vector 298 299 fid := t.F.GetFunc().GetObj() 300 f, err := function.GetFunctionByID(proc.Ctx, fid) 301 if err != nil { 302 return nil, err 303 } 304 305 functionParameters := make([]*vector.Vector, len(t.F.Args)) 306 for i := range functionParameters { 307 functionParameters[i], err = JoinFilterEvalExpr(r, s, rRow, proc, t.F.Args[i]) 308 if err != nil { 309 break 310 } 311 } 312 if err != nil { 313 cleanVectorsExceptList(proc, functionParameters, append(r.Vecs, s.Vecs...)) 314 return nil, err 315 } 316 317 result, err = evalFunction(proc, f, functionParameters, len(s.Zs)) 318 cleanVectorsExceptList(proc, functionParameters, append(append(r.Vecs, s.Vecs...), result)) 319 if err != nil { 320 return nil, err 321 } 322 return result, nil 323 default: 324 // *plan.Expr_Corr, *plan.Expr_List, *plan.Expr_P, *plan.Expr_V, *plan.Expr_Sub 325 return nil, moerr.NewNYI(proc.Ctx, fmt.Sprintf("eval expr '%v'", t)) 326 } 327 } 328 329 func EvalExprByZonemapBat(ctx context.Context, bat *batch.Batch, proc *process.Process, expr *plan.Expr) (*vector.Vector, error) { 330 if len(bat.Zs) == 0 { 331 return vector.NewConstNull(types.Type{Oid: types.T(expr.Typ.GetId())}, 1), nil 332 } 333 334 var length = len(bat.Zs) 335 e := expr.Expr 336 switch t := e.(type) { 337 case *plan.Expr_C: 338 return getConstVec(ctx, proc, expr, length) 339 case *plan.Expr_T: 340 // return a vector recorded type information but without real data 341 return vector.NewConst(types.Type{ 342 Oid: types.T(t.T.Typ.GetId()), 343 Width: t.T.Typ.GetWidth(), 344 Scale: t.T.Typ.GetScale(), 345 Precision: t.T.Typ.GetPrecision(), 346 }, len(bat.Zs)), nil 347 case *plan.Expr_Col: 348 vec := bat.Vecs[t.Col.ColPos] 349 if vec.IsScalarNull() { 350 vec.Typ = types.T(expr.Typ.GetId()).ToType() 351 } 352 return vec, nil 353 case *plan.Expr_F: 354 var result *vector.Vector 355 356 fid := t.F.GetFunc().GetObj() 357 f, err := function.GetFunctionByID(proc.Ctx, fid) 358 if err != nil { 359 return nil, err 360 } 361 362 functionParameters := make([]*vector.Vector, len(t.F.Args)) 363 for i := range functionParameters { 364 functionParameters[i], err = EvalExprByZonemapBat(ctx, bat, proc, t.F.Args[i]) 365 if err != nil { 366 break 367 } 368 } 369 if err != nil { 370 cleanVectorsExceptList(proc, functionParameters, bat.Vecs) 371 return nil, err 372 } 373 374 compareAndReturn := func(isTrue bool, err error) (*vector.Vector, error) { 375 if err != nil { 376 // if it can't compare, just return true. 377 // that means we don't know this filter expr's return, so you must readBlock 378 return vector.NewConstFixed(types.T_bool.ToType(), 1, true, proc.Mp()), nil 379 } 380 return vector.NewConstFixed(types.T_bool.ToType(), 1, isTrue, proc.Mp()), nil 381 } 382 383 switch t.F.Func.ObjName { 384 case ">": 385 // if someone in left > someone in right, that will be true 386 return compareAndReturn(functionParameters[0].CompareAndCheckAnyResultIsTrue(ctx, functionParameters[1], ">")) 387 case "<": 388 // if someone in left < someone in right, that will be true 389 return compareAndReturn(functionParameters[0].CompareAndCheckAnyResultIsTrue(ctx, functionParameters[1], "<")) 390 case "=": 391 // if left intersect right, that will be true 392 return compareAndReturn(functionParameters[0].CompareAndCheckIntersect(ctx, functionParameters[1])) 393 case ">=": 394 // if someone in left >= someone in right, that will be true 395 return compareAndReturn(functionParameters[0].CompareAndCheckAnyResultIsTrue(ctx, functionParameters[1], ">=")) 396 case "<=": 397 // if someone in left <= someone in right, that will be true 398 return compareAndReturn(functionParameters[0].CompareAndCheckAnyResultIsTrue(ctx, functionParameters[1], "<=")) 399 case "and": 400 // if left has one true and right has one true, that will be true 401 cols1 := vector.MustTCols[bool](functionParameters[0]) 402 cols2 := vector.MustTCols[bool](functionParameters[1]) 403 404 for _, leftHasTrue := range cols1 { 405 if leftHasTrue { 406 for _, rightHasTrue := range cols2 { 407 if rightHasTrue { 408 return vector.NewConstFixed(types.T_bool.ToType(), 1, true, proc.Mp()), nil 409 } 410 } 411 break 412 } 413 } 414 return vector.NewConstFixed(types.T_bool.ToType(), 1, false, proc.Mp()), nil 415 case "or": 416 // if someone is true in left/right, that will be true 417 cols1 := vector.MustTCols[bool](functionParameters[0]) 418 cols2 := vector.MustTCols[bool](functionParameters[1]) 419 for _, flag := range cols1 { 420 if flag { 421 return vector.NewConstFixed(types.T_bool.ToType(), 1, true, proc.Mp()), nil 422 } 423 } 424 for _, flag := range cols2 { 425 if flag { 426 return vector.NewConstFixed(types.T_bool.ToType(), 1, true, proc.Mp()), nil 427 } 428 } 429 return vector.NewConstFixed(types.T_bool.ToType(), 1, false, proc.Mp()), nil 430 } 431 432 result, err = evalFunction(proc, f, functionParameters, len(bat.Zs)) 433 cleanVectorsExceptList(proc, functionParameters, append(bat.Vecs, result)) 434 if err != nil { 435 return nil, err 436 } 437 return result, nil 438 default: 439 // *plan.Expr_Corr, *plan.Expr_P, *plan.Expr_V, *plan.Expr_Sub 440 return nil, moerr.NewNYI(ctx, fmt.Sprintf("unsupported eval expr '%v'", t)) 441 } 442 } 443 444 func JoinFilterEvalExprInBucket(r, s *batch.Batch, rRow, sRow int, proc *process.Process, expr *plan.Expr) (*vector.Vector, error) { 445 e := expr.Expr 446 switch t := e.(type) { 447 case *plan.Expr_C: 448 return getConstVec(proc.Ctx, proc, expr, 1) 449 case *plan.Expr_T: 450 // return a vector recorded type information but without real data 451 return vector.NewConst(types.Type{ 452 Oid: types.T(t.T.Typ.GetId()), 453 Width: t.T.Typ.GetWidth(), 454 Scale: t.T.Typ.GetScale(), 455 Precision: t.T.Typ.GetPrecision(), 456 }, 1), nil 457 case *plan.Expr_Col: 458 if t.Col.RelPos == 0 { 459 return r.Vecs[t.Col.ColPos].ToConst(rRow, proc.Mp()), nil 460 } 461 return s.Vecs[t.Col.ColPos].ToConst(sRow, proc.Mp()), nil 462 case *plan.Expr_F: 463 var result *vector.Vector 464 465 fid := t.F.GetFunc().GetObj() 466 f, err := function.GetFunctionByID(proc.Ctx, fid) 467 if err != nil { 468 return nil, err 469 } 470 471 functionParameters := make([]*vector.Vector, len(t.F.Args)) 472 for i := range functionParameters { 473 functionParameters[i], err = JoinFilterEvalExprInBucket(r, s, rRow, sRow, proc, t.F.Args[i]) 474 if err != nil { 475 break 476 } 477 } 478 if err != nil { 479 cleanVectorsExceptList(proc, functionParameters, append(r.Vecs, s.Vecs...)) 480 return nil, err 481 } 482 483 result, err = evalFunction(proc, f, functionParameters, 1) 484 cleanVectorsExceptList(proc, functionParameters, append(append(r.Vecs, s.Vecs...), result)) 485 if err != nil { 486 return nil, err 487 } 488 return result, nil 489 default: 490 // *plan.Expr_Corr, *plan.Expr_List, *plan.Expr_P, *plan.Expr_V, *plan.Expr_Sub 491 return nil, moerr.NewNYI(proc.Ctx, fmt.Sprintf("eval expr '%v'", t)) 492 } 493 } 494 495 func evalFunction(proc *process.Process, f *function.Function, args []*vector.Vector, length int) (*vector.Vector, error) { 496 if !f.UseNewFramework { 497 v, err := f.VecFn(args, proc) 498 if err != nil { 499 return nil, err 500 } 501 vector.SetLength(v, length) 502 v.FillDefaultValue() 503 return v, nil 504 } 505 var resultWrapper vector.FunctionResultWrapper 506 var err error 507 508 var parameterTypes []types.Type 509 if f.FlexibleReturnType != nil { 510 parameterTypes = make([]types.Type, len(args)) 511 for i := range args { 512 parameterTypes[i] = args[i].GetType() 513 } 514 } 515 rTyp, _ := f.ReturnType(parameterTypes) 516 numScalar := 0 517 // If any argument is `NULL`, return NULL. 518 // If all arguments are scalar, return scalar. 519 for i := range args { 520 if args[i].IsScalar() { 521 numScalar++ 522 } else { 523 if len(f.ParameterMustScalar) > i && f.ParameterMustScalar[i] { 524 return nil, moerr.NewInternalError(proc.Ctx, 525 fmt.Sprintf("the %dth parameter of function can only be constant", i+1)) 526 } 527 } 528 } 529 530 if !f.Volatile && numScalar == len(args) { 531 resultWrapper = vector.NewFunctionResultWrapper(rTyp, proc.Mp(), true, length) 532 // XXX only evaluate the first row. 533 err = f.NewFn(args, resultWrapper, proc, 1) 534 } else { 535 resultWrapper = vector.NewFunctionResultWrapper(rTyp, proc.Mp(), false, length) 536 err = f.NewFn(args, resultWrapper, proc, length) 537 } 538 if err != nil { 539 resultWrapper.Free() 540 } 541 return resultWrapper.GetResultVector(), err 542 } 543 544 func cleanVectorsExceptList(proc *process.Process, vs []*vector.Vector, excepts []*vector.Vector) { 545 mp := proc.Mp() 546 for i := range vs { 547 if vs[i] == nil { 548 continue 549 } 550 needClean := true 551 for j := range excepts { 552 if excepts[j] == vs[i] { 553 needClean = false 554 break 555 } 556 } 557 if needClean { 558 vs[i].Free(mp) 559 } 560 } 561 } 562 563 // RewriteFilterExprList will convert an expression list to be an AndExpr 564 func RewriteFilterExprList(list []*plan.Expr) *plan.Expr { 565 l := len(list) 566 if l == 0 { 567 return nil 568 } else if l == 1 { 569 return list[0] 570 } else { 571 left := list[0] 572 right := RewriteFilterExprList(list[1:]) 573 return &plan.Expr{ 574 Typ: left.Typ, 575 Expr: makeAndExpr(left, right), 576 } 577 } 578 } 579 580 func SplitAndExprs(list []*plan.Expr) []*plan.Expr { 581 exprs := make([]*plan.Expr, 0, len(list)) 582 for i := range list { 583 exprs = append(exprs, splitAndExpr(list[i])...) 584 } 585 return exprs 586 } 587 588 func splitAndExpr(expr *plan.Expr) []*plan.Expr { 589 exprs := make([]*plan.Expr, 0, 1) 590 if e, ok := expr.Expr.(*plan.Expr_F); ok { 591 fid, _ := function.DecodeOverloadID(e.F.Func.GetObj()) 592 if fid == function.AND { 593 exprs = append(exprs, splitAndExpr(e.F.Args[0])...) 594 exprs = append(exprs, splitAndExpr(e.F.Args[1])...) 595 return exprs 596 } 597 } 598 exprs = append(exprs, expr) 599 return exprs 600 } 601 602 func makeAndExpr(left, right *plan.Expr) *plan.Expr_F { 603 return &plan.Expr_F{ 604 F: &plan.Function{ 605 Func: &plan.ObjectRef{Obj: function.AndFunctionEncodedID, ObjName: function.AndFunctionName}, 606 Args: []*plan.Expr{left, right}, 607 }, 608 } 609 }