MCPcopy Create free account
hub / github.com/apache/impala / RegexpMatchCount4Args

Method RegexpMatchCount4Args

be/src/exprs/string-functions-ir.cc:1183–1237  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1181}
1182
1183IntVal StringFunctions::RegexpMatchCount4Args(FunctionContext* context,
1184 const StringVal& str, const StringVal& pattern, const IntVal& start_pos,
1185 const StringVal& match_parameter) {
1186 if (str.is_null || pattern.is_null) return IntVal::null();
1187
1188 int offset = 0;
1189 DCHECK_GE(str.len, 0);
1190 // The parameter "start_pos" starts counting at 1 instead of 0. If "start_pos" is
1191 // beyond the end of the string, "str" will be considered an empty string.
1192 if (!start_pos.is_null) offset = min(start_pos.val - 1, str.len);
1193 if (offset < 0) {
1194 stringstream error;
1195 error << "Illegal starting position " << start_pos.val << endl;
1196 context->SetError(error.str().c_str());
1197 return IntVal::null();
1198 }
1199
1200 re2::RE2* re = reinterpret_cast<re2::RE2*>(
1201 context->GetFunctionState(FunctionContext::THREAD_LOCAL));
1202 // Destroys re if we have to locally compile it.
1203 scoped_ptr<re2::RE2> scoped_re;
1204 if (re == NULL) {
1205 DCHECK(!context->IsArgConstant(1) || (context->GetNumArgs() == 4 &&
1206 !context->IsArgConstant(3)));
1207 string error_str;
1208 re = CompileRegex(pattern, &error_str, match_parameter);
1209 if (re == NULL) {
1210 context->SetError(error_str.c_str());
1211 return IntVal::null();
1212 }
1213 scoped_re.reset(re);
1214 }
1215
1216 DCHECK_GE(str.len, offset);
1217 re2::StringPiece str_sp(reinterpret_cast<char*>(str.ptr), str.len);
1218 int count = 0;
1219 re2::StringPiece match;
1220 while (offset <= str.len &&
1221 re->Match(str_sp, offset, str.len, re2::RE2::UNANCHORED, &match, 1)) {
1222 // Empty string is a valid match for pattern with '*'. Start matching at the next
1223 // character until we reach the end of the string.
1224 count++;
1225 if (match.size() == 0) {
1226 if (offset == str.len) {
1227 break;
1228 }
1229 offset++;
1230 } else {
1231 // Make sure forward progress is being made or we will be in an infinite loop.
1232 DCHECK_GT(match.data() - str_sp.data() + match.size(), offset);
1233 offset = match.data() - str_sp.data() + match.size();
1234 }
1235 }
1236 return IntVal(count);
1237}
1238
1239// NULL handling of function Concat and ConcatWs are different.
1240// Function concat was reimplemented to keep the original

Callers

nothing calls this directly

Calls 12

minFunction · 0.85
CompileRegexFunction · 0.85
IntValClass · 0.85
GetFunctionStateMethod · 0.80
IsArgConstantMethod · 0.80
GetNumArgsMethod · 0.80
MatchMethod · 0.80
resetMethod · 0.65
SetErrorMethod · 0.45
strMethod · 0.45
sizeMethod · 0.45
dataMethod · 0.45

Tested by

no test coverage detected