github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/operator/reg_match.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 operator 16 17 import ( 18 "regexp" 19 20 "github.com/matrixorigin/matrixone/pkg/common/moerr" 21 "github.com/matrixorigin/matrixone/pkg/container/nulls" 22 "github.com/matrixorigin/matrixone/pkg/container/types" 23 "github.com/matrixorigin/matrixone/pkg/container/vector" 24 "github.com/matrixorigin/matrixone/pkg/vm/process" 25 ) 26 27 func RegMatch(vectors []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 28 return generalRegMatch(vectors, proc, true) 29 } 30 31 func NotRegMatch(vectors []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 32 return generalRegMatch(vectors, proc, false) 33 } 34 35 func generalRegMatch(vectors []*vector.Vector, proc *process.Process, isReg bool) (*vector.Vector, error) { 36 left, right := vectors[0], vectors[1] 37 resultType := types.T_bool.ToType() 38 leftValues, rightValues := vector.MustStrCols(left), vector.MustStrCols(right) 39 switch { 40 case left.IsScalar() && right.IsScalar(): 41 if left.ConstVectorIsNull() || right.ConstVectorIsNull() { 42 return proc.AllocScalarNullVector(resultType), nil 43 } 44 resultVector := vector.NewConst(resultType, 1) 45 resultValues := vector.MustTCols[bool](resultVector) 46 err := RegMatchWithAllConst(leftValues, rightValues, resultValues, isReg) 47 if err != nil { 48 return nil, moerr.NewInvalidInput(proc.Ctx, "The Regular Expression have invalid parameter") 49 } 50 return resultVector, nil 51 case left.IsScalar() && !right.IsScalar(): 52 if left.ConstVectorIsNull() { 53 return proc.AllocScalarNullVector(resultType), nil 54 } 55 resultVector, err := proc.AllocVectorOfRows(resultType, int64(len(rightValues)), right.Nsp) 56 if err != nil { 57 return nil, err 58 } 59 resultValues := vector.MustTCols[bool](resultVector) 60 err = RegMatchWithLeftConst(leftValues, rightValues, resultValues, isReg) 61 if err != nil { 62 return nil, moerr.NewInvalidInput(proc.Ctx, "The Regular Expression have invalid parameter") 63 } 64 return resultVector, nil 65 case !left.IsScalar() && right.IsScalar(): 66 if right.ConstVectorIsNull() { 67 return proc.AllocScalarNullVector(resultType), nil 68 } 69 resultVector, err := proc.AllocVectorOfRows(resultType, int64(len(leftValues)), left.Nsp) 70 if err != nil { 71 return nil, err 72 } 73 resultValues := vector.MustTCols[bool](resultVector) 74 err = RegMatchWithRightConst(leftValues, rightValues, resultValues, isReg) 75 if err != nil { 76 return nil, moerr.NewInvalidInput(proc.Ctx, "The Regular Expression have invalid parameter") 77 } 78 return resultVector, nil 79 } 80 resultVector, err := proc.AllocVectorOfRows(resultType, int64(len(leftValues)), nil) 81 if err != nil { 82 return nil, err 83 } 84 resultValues := vector.MustTCols[bool](resultVector) 85 nulls.Or(left.Nsp, right.Nsp, resultVector.Nsp) 86 err = RegMatchWithALL(leftValues, rightValues, resultValues, isReg) 87 if err != nil { 88 return nil, moerr.NewInvalidInput(proc.Ctx, "The Regular Expression have invalid parameter") 89 } 90 return resultVector, nil 91 } 92 93 func RegMatchWithAllConst(lv, rv []string, rs []bool, isReg bool) error { 94 res, err := regexp.MatchString(rv[0], lv[0]) 95 if err != nil { 96 return err 97 } 98 99 rs[0] = BoolResult(res, isReg) 100 return nil 101 } 102 103 func RegMatchWithLeftConst(lv, rv []string, rs []bool, isReg bool) error { 104 for i := range rv { 105 res, err := regexp.MatchString(rv[i], lv[0]) 106 if err != nil { 107 return err 108 } 109 rs[i] = BoolResult(res, isReg) 110 } 111 return nil 112 } 113 114 func RegMatchWithRightConst(lv, rv []string, rs []bool, isReg bool) error { 115 for i := range lv { 116 res, err := regexp.MatchString(rv[0], lv[i]) 117 if err != nil { 118 return err 119 } 120 rs[i] = BoolResult(res, isReg) 121 } 122 return nil 123 } 124 125 func RegMatchWithALL(lv, rv []string, rs []bool, isReg bool) error { 126 for i := range lv { 127 res, err := regexp.MatchString(rv[i], lv[i]) 128 if err != nil { 129 return err 130 } 131 rs[i] = BoolResult(res, isReg) 132 } 133 return nil 134 } 135 136 func BoolResult(isMatch bool, isReg bool) bool { 137 return (isMatch && isReg) || !(isMatch || isReg) 138 }