MCPcopy Create free account
hub / github.com/apache/arrow / TryOptimize

Method TryOptimize

cpp/src/gandiva/regex_functions_holder.cc:37–88  ·  view source on GitHub ↗

Short-circuit pattern matches for the following common sub cases : - starts_with, ends_with and is_substr

Source from the content-addressed store, hash-verified

35// Short-circuit pattern matches for the following common sub cases :
36// - starts_with, ends_with and is_substr
37const FunctionNode LikeHolder::TryOptimize(const FunctionNode& node) {
38 // NOTE: avoid making those constants global to avoid compiling regexes at startup
39 // pre-compiled pattern for matching starts_with
40 static const RE2 starts_with_regex(R"(([^\.\*])*\.\*)");
41 // pre-compiled pattern for matching ends_with
42 static const RE2 ends_with_regex(R"(\.\*([^\.\*])*)");
43 // pre-compiled pattern for matching is_substr
44 static const RE2 is_substr_regex(R"(\.\*([^\.\*])*\.\*)");
45
46 static bool global_checked = false;
47 if (ARROW_PREDICT_FALSE(!global_checked)) {
48 if (ARROW_PREDICT_FALSE(
49 !(starts_with_regex.ok() && ends_with_regex.ok() && is_substr_regex.ok()))) {
50 return node;
51 }
52 global_checked = true;
53 }
54
55 auto maybe_holder = Make(node);
56 if (maybe_holder.ok()) {
57 auto holder = *maybe_holder;
58 std::string& pattern = holder->pattern_;
59 auto literal_type = node.children().at(1)->return_type();
60
61 if (RE2::FullMatch(pattern, starts_with_regex)) {
62 auto prefix = pattern.substr(0, pattern.length() - 2); // trim .*
63 auto parsed_prefix = RemovePatternEscapeChars(node, prefix);
64 auto prefix_node = std::make_shared<LiteralNode>(
65 literal_type, LiteralHolder(parsed_prefix), false);
66 return FunctionNode("starts_with", {node.children().at(0), prefix_node},
67 node.return_type());
68 } else if (RE2::FullMatch(pattern, ends_with_regex)) {
69 auto suffix = pattern.substr(2); // skip .*
70 auto parsed_suffix = RemovePatternEscapeChars(node, suffix);
71 auto suffix_node = std::make_shared<LiteralNode>(
72 literal_type, LiteralHolder(parsed_suffix), false);
73 return FunctionNode("ends_with", {node.children().at(0), suffix_node},
74 node.return_type());
75 } else if (RE2::FullMatch(pattern, is_substr_regex)) {
76 auto substr =
77 pattern.substr(2, pattern.length() - 4); // trim starting and ending .*
78 auto parsed_substr = RemovePatternEscapeChars(node, substr);
79 auto substr_node = std::make_shared<LiteralNode>(
80 literal_type, LiteralHolder(parsed_substr), false);
81 return FunctionNode("is_substr", {node.children().at(0), substr_node},
82 node.return_type());
83 }
84 }
85
86 // Could not optimize, return original node.
87 return node;
88}
89
90Result<std::shared_ptr<LikeHolder>> LikeHolder::Make(const FunctionNode& node) {
91 ARROW_RETURN_IF(node.children().size() != 2 && node.children().size() != 3,

Callers

nothing calls this directly

Calls 7

FunctionNodeClass · 0.85
substrMethod · 0.80
MakeFunction · 0.70
okMethod · 0.45
return_typeMethod · 0.45
childrenMethod · 0.45
lengthMethod · 0.45

Tested by

no test coverage detected