Modified Set Parser

v3.0_4799_4827
Rahim Kanji 1 year ago
parent 9e62cf65af
commit b4e9060f71

@ -192,7 +192,7 @@ class __attribute__((aligned(64))) MySQL_Thread : public Base_Thread
pthread_mutex_t thread_mutex;
// if set_parser_algorithm == 2 , a single thr_SetParser is used
SetParser *thr_SetParser;
SetParser<MySQL_Session> *thr_SetParser;
MySQL_Thread();
~MySQL_Thread();

@ -244,7 +244,7 @@ public:
pthread_mutex_t thread_mutex;
// if set_parser_algorithm == 2 , a single thr_SetParser is used
SetParser* thr_SetParser;
SetParser<PgSQL_Session>* thr_SetParser;
/**
* @brief Default constructor for the PgSQL_Thread class.

@ -9,6 +9,7 @@
//#define PARSERDEBUG
template<typename S>
class SetParser {
private:
// parse1v2 variables used for compile the RE only once

@ -5714,7 +5714,7 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
if (session_type == PROXYSQL_SESSION_MYSQL) {
__sync_fetch_and_add(&MyHGM->status.frontend_use_db, 1);
string nq=string((char *)pkt->ptr+sizeof(mysql_hdr)+1,pkt->size-sizeof(mysql_hdr)-1);
SetParser parser(nq);
SetParser<MySQL_Session> parser(nq);
string errmsg = "";
string schemaname = parser.parse_USE_query(errmsg);
if (schemaname != "") {
@ -5992,7 +5992,7 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
) {
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Parsing SET command %s\n", nq.c_str());
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "Parsing SET command = %s\n", nq.c_str());
SetParser parser(nq);
SetParser<MySQL_Session> parser(nq);
std::map<std::string, std::vector<std::string>> set = {};
if (mysql_thread___set_parser_algorithm == 1) { // legacy behavior
set = parser.parse1();
@ -6545,7 +6545,7 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
}
}
} else if (match_regexes && match_regexes[2]->match(dig)) {
SetParser parser(nq);
SetParser<MySQL_Session> parser(nq);
std::map<std::string, std::vector<std::string>> set = parser.parse2();
for(auto it = std::begin(set); it != std::end(set); ++it) {
@ -6610,7 +6610,7 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
}
}
} else if (match_regexes && match_regexes[3]->match(dig)) {
SetParser parser(nq);
SetParser<MySQL_Session> parser(nq);
std::string charset = parser.parse_character_set();
const MARIADB_CHARSET_INFO * c;
if (!charset.empty()) {

@ -2951,7 +2951,7 @@ bool MySQL_Thread::init() {
mypolls.add(POLLIN, pipefd[0], NULL, 0);
assert(i==0);
thr_SetParser = new SetParser("");
thr_SetParser = new SetParser<MySQL_Session>("");
match_regexes=(Session_Regex **)malloc(sizeof(Session_Regex *)*4);
// match_regexes[0]=new Session_Regex((char *)"^SET (|SESSION |@@|@@session.)SQL_LOG_BIN( *)(:|)=( *)");
match_regexes[0] = NULL; // NOTE: historically we used match_regexes[0] for SET SQL_LOG_BIN . Not anymore

@ -5013,7 +5013,7 @@ bool PgSQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
) {
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Parsing SET command %s\n", nq.c_str());
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "Parsing SET command = %s\n", nq.c_str());
SetParser parser(nq);
SetParser<PgSQL_Session> parser(nq);
std::map<std::string, std::vector<std::string>> set = {};
if (pgsql_thread___set_parser_algorithm == 1) { // legacy behavior
set = parser.parse1();

@ -2844,7 +2844,7 @@ bool PgSQL_Thread::init() {
mypolls.add(POLLIN, pipefd[0], NULL, 0);
assert(i == 0);
thr_SetParser = new SetParser("");
thr_SetParser = new SetParser<PgSQL_Session>("");
match_regexes = (Session_Regex**)malloc(sizeof(Session_Regex*) * 4);
// match_regexes[0]=new Session_Regex((char *)"^SET (|SESSION |@@|@@session.)SQL_LOG_BIN( *)(:|)=( *)");
match_regexes[0] = NULL; // NOTE: historically we used match_regexes[0] for SET SQL_LOG_BIN . Not anymore

@ -39,20 +39,23 @@ static void remove_quotes(string& v) {
SetParser::SetParser(std::string nq, int verb) {
verbosity = verb;
#else
SetParser::SetParser(std::string nq) {
template<typename S>
SetParser<S>::SetParser(std::string nq) {
#endif
parse1v2_init = false;
set_query(nq);
}
SetParser::~SetParser() {
template<typename S>
SetParser<S>::~SetParser() {
if (parse1v2_init == true) {
delete parse1v2_opt2;
delete parse1v2_re;
}
}
void SetParser::set_query(const std::string& nq) {
template<typename S>
void SetParser<S>::set_query(const std::string& nq) {
int query_no_space_length = nq.length();
char *query_no_space=(char *)malloc(query_no_space_length+1);
memcpy(query_no_space,nq.c_str(),query_no_space_length);
@ -80,7 +83,8 @@ void SetParser::set_query(const std::string& nq) {
#define VAR_VALUE_P1_6 "|(?: )+"
#define VAR_VALUE_P1 "(" VAR_VALUE_P1_1 VAR_VALUE_P1_2 VAR_VALUE_P1_3 VAR_VALUE_P1_4 VAR_VALUE_P1_5 VAR_VALUE_P1_6 ")"
std::map<std::string,std::vector<std::string>> SetParser::parse1() {
template<typename S>
std::map<std::string,std::vector<std::string>> SetParser<S>::parse1() {
#ifdef DEBUG
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 4, "Parsing query %s\n", query.c_str());
#endif // DEBUG
@ -148,7 +152,8 @@ VALGRIND_ENABLE_ERROR_REPORTING;
return result;
}
void SetParser::generateRE_parse1v2() {
template<typename S>
void SetParser<S>::generateRE_parse1v2() {
vector<string> quote_symbol = {"\"", "'", "`"};
vector<string> var_patterns = {};
{
@ -306,7 +311,15 @@ void SetParser::generateRE_parse1v2() {
}
#endif
const std::string pattern="(?:" NAMES SPACES + name_value + "(?: +COLLATE +" + name_value + "|)" "|" + var_1 + SPACES "(?:|:)=" SPACES + var_value + ") *,? *";
std::string pattern;
if constexpr (std::is_same_v<S, MySQL_Session>) {
pattern = "(?:" NAMES SPACES + name_value + "(?: +COLLATE +" + name_value + "|)" "|" + var_1 + SPACES "(?:|:)=" SPACES + var_value + ") *,? *";
} else if constexpr (std::is_same_v<S, PgSQL_Session>) {
pattern = "(?:" NAMES SPACES + name_value + "(?: +COLLATE +" + name_value + "|)" "|" + var_1 + SPACES "(?:|:)(?:TO|=)" SPACES + var_value + ") *,? *";
} else {
assert(0);
}
#ifdef DEBUG
VALGRIND_DISABLE_ERROR_REPORTING;
#endif // DEBUG
@ -320,7 +333,8 @@ VALGRIND_DISABLE_ERROR_REPORTING;
parse1v2_init = true;
}
std::map<std::string,std::vector<std::string>> SetParser::parse1v2() {
template<typename S>
std::map<std::string,std::vector<std::string>> SetParser<S>::parse1v2() {
std::map<std::string,std::vector<std::string>> result = {};
@ -391,8 +405,8 @@ VALGRIND_ENABLE_ERROR_REPORTING;
return result;
}
std::map<std::string,std::vector<std::string>> SetParser::parse2() {
template<typename S>
std::map<std::string,std::vector<std::string>> SetParser<S>::parse2() {
#ifdef DEBUG
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 4, "Parsing query %s\n", query.c_str());
@ -438,7 +452,8 @@ std::map<std::string,std::vector<std::string>> SetParser::parse2() {
return result;
}
std::string SetParser::parse_character_set() {
template<>
std::string SetParser<MySQL_Session>::parse_character_set() {
#ifdef DEBUG
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 4, "Parsing query %s\n", query.c_str());
#endif // DEBUG
@ -462,7 +477,32 @@ std::string SetParser::parse_character_set() {
return value4;
}
std::string SetParser::parse_USE_query(std::string& errmsg) {
template<>
std::string SetParser<PgSQL_Session>::parse_character_set() {
#ifdef DEBUG
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 4, "Parsing query %s\n", query.c_str());
#endif // DEBUG
re2::RE2::Options *opt2=new re2::RE2::Options(RE2::Quiet);
opt2->set_case_sensitive(false);
opt2->set_longest_match(false);
re2::RE2 re0("^\\s*SET\\s+", *opt2);
re2::RE2::Replace(&query, re0, "");
std::map<std::string,std::vector<std::string>> result;
const std::string pattern = "(client_encoding|names)\\s*(|=|TO)\\s*['\"]?([A-Z_0-9]+)['\"]?";
re2::RE2 re(pattern, *opt2);
std::string var;
std::string value1, value2, value3;
re2::StringPiece input(query);
re2::RE2::Consume(&input, re, &value1, &value2, &value3);
delete opt2;
return value3;
}
template<typename S>
std::string SetParser<S>::parse_USE_query(std::string& errmsg) {
#ifdef DEBUG
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 4, "Parsing query %s\n", query.c_str());
#endif // DEBUG
@ -513,8 +553,8 @@ std::string SetParser::parse_USE_query(std::string& errmsg) {
return dbname;
}
std::string SetParser::remove_comments(const std::string& q) {
template<typename S>
std::string SetParser<S>::remove_comments(const std::string& q) {
std::string result = "";
bool in_multiline_comment = false;
@ -558,7 +598,8 @@ std::string SetParser::remove_comments(const std::string& q) {
#ifdef DEBUG
void SetParser::test_parse_USE_query() {
template<typename S>
void SetParser<S>::test_parse_USE_query() {
// Define vector of pairs (query, expected dbname)
std::vector<std::pair<std::string, std::string>> testCases = {
@ -621,3 +662,6 @@ void SetParser::test_parse_USE_query() {
}
}
#endif // DEBUG
template class SetParser<PgSQL_Session>;
template class SetParser<MySQL_Session>;

@ -2325,7 +2325,7 @@ int main(int argc, const char * argv[]) {
#ifdef DEBUG
{
// Automated testing
SetParser parser("");
SetParser<MySQL_Session> parser("");
parser.test_parse_USE_query();
}
#endif // DEBUG

Loading…
Cancel
Save