github.com/matrixorigin/matrixone@v0.7.0/pkg/vectorize/regular/regular_like.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 regular 16 17 import ( 18 "fmt" 19 "regexp" 20 21 "github.com/matrixorigin/matrixone/pkg/common/moerr" 22 "github.com/matrixorigin/matrixone/pkg/container/nulls" 23 ) 24 25 // Support four arguments: 26 // i: case insensitive. 27 // c: case sensitive. 28 // m: multiple line mode. 29 // n: '.' can match line terminator. 30 func getPureMatchType(input string) (string, error) { 31 retstring := "" 32 caseType := "" 33 foundn := false 34 foundm := false 35 36 for _, c := range input { 37 switch string(c) { 38 case "i": 39 caseType = "i" 40 case "c": 41 caseType = "" 42 case "m": 43 if !foundm { 44 retstring += "m" 45 foundm = true 46 } 47 case "n": 48 if !foundn { 49 retstring += "s" 50 foundn = true 51 } 52 default: 53 return "", moerr.NewInvalidInputNoCtx("regexp_like got invalid match_type input!") 54 } 55 } 56 57 retstring += caseType 58 59 return retstring, nil 60 } 61 62 func compileWithMatchType(pat, match_type string) (*regexp.Regexp, error) { 63 if len(pat) == 0 { 64 return nil, moerr.NewInvalidInputNoCtx("regexp_like got invalid input!") 65 } 66 match_type, err := getPureMatchType(match_type) 67 if err != nil { 68 return nil, err 69 } 70 re, err := regexp.Compile(fmt.Sprintf("(?%s)%s", match_type, pat)) 71 if err != nil { 72 return nil, err 73 } 74 return re, nil 75 } 76 77 func RegularLike(expr, pat, match_type string) (bool, error) { 78 re, err := compileWithMatchType(pat, match_type) 79 if err != nil { 80 return false, err 81 } 82 matchRes := re.MatchString(expr) 83 return matchRes, nil 84 } 85 86 func RegularLikeWithArrays(expr, pat []string, match_type []string, exprN, patN, matchN, rns *nulls.Nulls, rs []bool, maxLen int) error { 87 matchIndex := 0 88 if len(expr) == 1 && len(pat) == 1 { 89 for i := 0; i < maxLen; i++ { 90 if nulls.Contains(exprN, uint64(0)) || nulls.Contains(patN, uint64(0)) || nulls.Contains(matchN, uint64(0)) { 91 nulls.Add(rns, uint64(i)) 92 continue 93 } 94 res, err := RegularLike(expr[0], pat[0], match_type[i]) 95 if err != nil { 96 return err 97 } 98 rs[i] = res 99 } 100 } else if len(expr) == 1 { 101 for i := 0; i < maxLen; i++ { 102 if nulls.Contains(exprN, uint64(0)) || nulls.Contains(patN, uint64(i)) || nulls.Contains(matchN, uint64(0)) { 103 nulls.Add(rns, uint64(i)) 104 continue 105 } 106 if len(match_type) != 1 { 107 matchIndex = i 108 } 109 res, err := RegularLike(expr[0], pat[i], match_type[matchIndex]) 110 if err != nil { 111 return err 112 } 113 rs[i] = res 114 } 115 } else if len(pat) == 1 { 116 for i := 0; i < maxLen; i++ { 117 if nulls.Contains(exprN, uint64(i)) || nulls.Contains(patN, uint64(0)) || nulls.Contains(matchN, uint64(0)) { 118 nulls.Add(rns, uint64(i)) 119 continue 120 } 121 if len(match_type) != 1 { 122 matchIndex = i 123 } 124 res, err := RegularLike(expr[i], pat[0], match_type[matchIndex]) 125 if err != nil { 126 return err 127 } 128 rs[i] = res 129 } 130 } else { 131 for i := 0; i < maxLen; i++ { 132 if nulls.Contains(exprN, uint64(i)) || nulls.Contains(patN, uint64(i)) || nulls.Contains(matchN, uint64(0)) { 133 nulls.Add(rns, uint64(i)) 134 continue 135 } 136 if len(match_type) != 1 { 137 matchIndex = i 138 } 139 res, err := RegularLike(expr[i], pat[i], match_type[matchIndex]) 140 if err != nil { 141 return err 142 } 143 rs[i] = res 144 } 145 } 146 return nil 147 }