github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_like_vec.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 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 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package memex 15 16 import ( 17 "regexp" 18 19 "github.com/whtcorpsinc/errors" 20 "github.com/whtcorpsinc/milevadb/types" 21 "github.com/whtcorpsinc/milevadb/soliton/chunk" 22 ) 23 24 func (b *builtinLikeSig) vectorized() bool { 25 return true 26 } 27 28 func (b *builtinLikeSig) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error { 29 n := input.NumEvents() 30 bufVal, err := b.bufSlabPredictor.get(types.ETString, n) 31 if err != nil { 32 return err 33 } 34 defer b.bufSlabPredictor.put(bufVal) 35 if err = b.args[0].VecEvalString(b.ctx, input, bufVal); err != nil { 36 return err 37 } 38 bufPattern, err := b.bufSlabPredictor.get(types.ETString, n) 39 if err != nil { 40 return err 41 } 42 defer b.bufSlabPredictor.put(bufPattern) 43 if err = b.args[1].VecEvalString(b.ctx, input, bufPattern); err != nil { 44 return err 45 } 46 47 bufEscape, err := b.bufSlabPredictor.get(types.ETInt, n) 48 if err != nil { 49 return err 50 } 51 defer b.bufSlabPredictor.put(bufEscape) 52 if err = b.args[2].VecEvalInt(b.ctx, input, bufEscape); err != nil { 53 return err 54 } 55 escapes := bufEscape.Int64s() 56 57 // Must not use b.pattern to avoid data race 58 pattern := b.defCauslator().Pattern() 59 60 result.ResizeInt64(n, false) 61 result.MergeNulls(bufVal, bufPattern, bufEscape) 62 i64s := result.Int64s() 63 for i := 0; i < n; i++ { 64 if result.IsNull(i) { 65 continue 66 } 67 pattern.Compile(bufPattern.GetString(i), byte(escapes[i])) 68 match := pattern.DoMatch(bufVal.GetString(i)) 69 i64s[i] = boolToInt64(match) 70 } 71 72 return nil 73 } 74 75 func (b *builtinRegexpSig) vectorized() bool { 76 return true 77 } 78 79 func (b *builtinRegexpUTF8Sig) vectorized() bool { 80 return true 81 } 82 83 func (b *builtinRegexpSharedSig) isMemorizedRegexpInitialized() bool { 84 return !(b.memorizedRegexp == nil && b.memorizedErr == nil) 85 } 86 87 func (b *builtinRegexpSharedSig) initMemoizedRegexp(patterns *chunk.DeferredCauset, n int) { 88 // Precondition: patterns is generated from a constant memex 89 if n == 0 { 90 // If the input rownum is zero, the Regexp error shouldn't be generated. 91 return 92 } 93 for i := 0; i < n; i++ { 94 if patterns.IsNull(i) { 95 continue 96 } 97 re, err := b.compile(patterns.GetString(i)) 98 b.memorizedRegexp = re 99 b.memorizedErr = err 100 break 101 } 102 if !b.isMemorizedRegexpInitialized() { 103 b.memorizedErr = errors.New("No valid regexp pattern found") 104 } 105 if b.memorizedErr != nil { 106 b.memorizedRegexp = nil 107 } 108 } 109 110 func (b *builtinRegexpSharedSig) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error { 111 n := input.NumEvents() 112 bufExpr, err := b.bufSlabPredictor.get(types.ETString, n) 113 if err != nil { 114 return err 115 } 116 defer b.bufSlabPredictor.put(bufExpr) 117 if err := b.args[0].VecEvalString(b.ctx, input, bufExpr); err != nil { 118 return err 119 } 120 121 bufPat, err := b.bufSlabPredictor.get(types.ETString, n) 122 if err != nil { 123 return err 124 } 125 defer b.bufSlabPredictor.put(bufPat) 126 if err := b.args[1].VecEvalString(b.ctx, input, bufPat); err != nil { 127 return err 128 } 129 130 if b.args[1].ConstItem(b.ctx.GetStochastikVars().StmtCtx) && !b.isMemorizedRegexpInitialized() { 131 b.initMemoizedRegexp(bufPat, n) 132 } 133 getRegexp := func(pat string) (*regexp.Regexp, error) { 134 if b.isMemorizedRegexpInitialized() { 135 return b.memorizedRegexp, b.memorizedErr 136 } 137 return b.compile(pat) 138 } 139 140 result.ResizeInt64(n, false) 141 result.MergeNulls(bufExpr, bufPat) 142 i64s := result.Int64s() 143 for i := 0; i < n; i++ { 144 if result.IsNull(i) { 145 continue 146 } 147 re, err := getRegexp(bufPat.GetString(i)) 148 if err != nil { 149 return err 150 } 151 i64s[i] = boolToInt64(re.MatchString(bufExpr.GetString(i))) 152 } 153 return nil 154 }