1#include "duckdb/function/scalar/regexp.hpp"
2#include "duckdb/execution/expression_executor.hpp"
3
4namespace duckdb {
5
6namespace regexp_util {
7
8bool TryParseConstantPattern(ClientContext &context, Expression &expr, string &constant_string) {
9 if (!expr.IsFoldable()) {
10 return false;
11 }
12 Value pattern_str = ExpressionExecutor::EvaluateScalar(context, expr);
13 if (!pattern_str.IsNull() && pattern_str.type().id() == LogicalTypeId::VARCHAR) {
14 constant_string = StringValue::Get(value: pattern_str);
15 return true;
16 }
17 return false;
18}
19
20void ParseRegexOptions(const string &options, duckdb_re2::RE2::Options &result, bool *global_replace) {
21 for (idx_t i = 0; i < options.size(); i++) {
22 switch (options[i]) {
23 case 'c':
24 // case-sensitive matching
25 result.set_case_sensitive(true);
26 break;
27 case 'i':
28 // case-insensitive matching
29 result.set_case_sensitive(false);
30 break;
31 case 'l':
32 // literal matching
33 result.set_literal(true);
34 break;
35 case 'm':
36 case 'n':
37 case 'p':
38 // newline-sensitive matching
39 result.set_dot_nl(false);
40 break;
41 case 's':
42 // non-newline-sensitive matching
43 result.set_dot_nl(true);
44 break;
45 case 'g':
46 // global replace, only available for regexp_replace
47 if (global_replace) {
48 *global_replace = true;
49 } else {
50 throw InvalidInputException("Option 'g' (global replace) is only valid for regexp_replace");
51 }
52 break;
53 case ' ':
54 case '\t':
55 case '\n':
56 // ignore whitespace
57 break;
58 default:
59 throw InvalidInputException("Unrecognized Regex option %c", options[i]);
60 }
61 }
62}
63
64void ParseRegexOptions(ClientContext &context, Expression &expr, RE2::Options &target, bool *global_replace) {
65 if (expr.HasParameter()) {
66 throw ParameterNotResolvedException();
67 }
68 if (!expr.IsFoldable()) {
69 throw InvalidInputException("Regex options field must be a constant");
70 }
71 Value options_str = ExpressionExecutor::EvaluateScalar(context, expr);
72 if (options_str.IsNull()) {
73 throw InvalidInputException("Regex options field must not be NULL");
74 }
75 if (options_str.type().id() != LogicalTypeId::VARCHAR) {
76 throw InvalidInputException("Regex options field must be a string");
77 }
78 ParseRegexOptions(options: StringValue::Get(value: options_str), result&: target, global_replace);
79}
80
81} // namespace regexp_util
82
83} // namespace duckdb
84