1#include <my_global.h>
2
3
4/* MySQL includes */
5#include "./debug_sync.h"
6#include "./my_bit.h"
7#include "./my_stacktrace.h"
8#include "./sql_table.h"
9#include "./log.h"
10#include <mysys_err.h>
11#include <mysql/psi/mysql_table.h>
12#ifdef MARIAROCKS_NOT_YET
13#include <mysql/thread_pool_priv.h>
14#endif
15
16#include <string>
17
18/* MyRocks includes */
19#include "./rdb_threads.h"
20
21#include "rdb_mariadb_server_port.h"
22
23void warn_about_bad_patterns(const Regex_list_handler* regex_list_handler,
24 const char *name)
25{
26 // There was some invalid regular expression data in the patterns supplied
27
28 // NO_LINT_DEBUG
29 sql_print_warning("Invalid pattern in %s: %s", name,
30 regex_list_handler->bad_pattern().c_str());
31}
32
33
34/*
35 Set the patterns string. If there are invalid regex patterns they will
36 be stored in m_bad_patterns and the result will be false, otherwise the
37 result will be true.
38*/
39bool Regex_list_handler::set_patterns(const std::string& pattern_str)
40{
41 bool pattern_valid= true;
42
43 // Create a normalized version of the pattern string with all delimiters
44 // replaced by the '|' character
45 std::string norm_pattern= pattern_str;
46 std::replace(norm_pattern.begin(), norm_pattern.end(), m_delimiter, '|');
47
48 // Make sure no one else is accessing the list while we are changing it.
49 mysql_rwlock_wrlock(&m_rwlock);
50
51 // Clear out any old error information
52 m_bad_pattern_str.clear();
53
54 try
55 {
56 // Replace all delimiters with the '|' operator and create the regex
57 // Note that this means the delimiter can not be part of a regular
58 // expression. This is currently not a problem as we are using the comma
59 // character as a delimiter and commas are not valid in table names.
60 const std::regex* pattern= new std::regex(norm_pattern);
61
62 // Free any existing regex information and setup the new one
63 delete m_pattern;
64 m_pattern= pattern;
65 }
66 catch (const std::regex_error&)
67 {
68 // This pattern is invalid.
69 pattern_valid= false;
70
71 // Put the bad pattern into a member variable so it can be retrieved later.
72 m_bad_pattern_str= pattern_str;
73 }
74
75 // Release the lock
76 mysql_rwlock_unlock(&m_rwlock);
77
78 return pattern_valid;
79}
80
81bool Regex_list_handler::matches(const std::string& str) const
82{
83 DBUG_ASSERT(m_pattern != nullptr);
84
85 // Make sure no one else changes the list while we are accessing it.
86 mysql_rwlock_rdlock(&m_rwlock);
87
88 // See if the table name matches the regex we have created
89 bool found= std::regex_match(str, *m_pattern);
90
91 // Release the lock
92 mysql_rwlock_unlock(&m_rwlock);
93
94 return found;
95}
96
97// Split a string based on a delimiter. Two delimiters in a row will not add
98// an empty string in the set.
99std::vector<std::string> split_into_vector(const std::string& input,
100 char delimiter)
101{
102 size_t pos;
103 size_t start = 0;
104 std::vector<std::string> elems;
105
106 // Find next delimiter
107 while ((pos = input.find(delimiter, start)) != std::string::npos)
108 {
109 // If there is any data since the last delimiter add it to the list
110 if (pos > start)
111 elems.push_back(input.substr(start, pos - start));
112
113 // Set our start position to the character after the delimiter
114 start = pos + 1;
115 }
116
117 // Add a possible string since the last delimiter
118 if (input.length() > start)
119 elems.push_back(input.substr(start));
120
121 // Return the resulting list back to the caller
122 return elems;
123}
124
125