Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removing trailing semicolon from USE #4628 #4629

Merged
merged 2 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/set_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class SetParser {
// First implemenation of the parser for TRANSACTION ISOLATION LEVEL and TRANSACTION READ/WRITE
std::map<std::string, std::vector<std::string>> parse2();
std::string parse_character_set();
std::string parse_USE_query();
std::string parse_USE_query(std::string& errmsg);
std::string remove_comments(const std::string& q);
#ifdef DEBUG
// built-in testing
Expand Down
11 changes: 9 additions & 2 deletions lib/MySQL_Session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6139,7 +6139,8 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
__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);
string schemaname = parser.parse_USE_query();
string errmsg = "";
string schemaname = parser.parse_USE_query(errmsg);
if (schemaname != "") {
client_myds->myconn->userinfo->set_schemaname((char *)schemaname.c_str(),schemaname.length());
if (mirror==false) {
Expand All @@ -6156,6 +6157,9 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
l_free(pkt->size,pkt->ptr);
client_myds->setDSS_STATE_QUERY_SENT_NET();
std::string msg = "Unable to parse: " + nq;
if (errmsg != "") {
msg = errmsg + ": " + nq;
}
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,client_myds->pkt_sid+1,1148,(char *)"42000", msg.c_str());
RequestEnd(NULL);
}
Expand Down Expand Up @@ -6475,7 +6479,10 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
RE2::GlobalReplace(&nq,(char *)"^/\\*!\\d\\d\\d\\d\\d SET(.*)\\*/",(char *)"SET\\1");
RE2::GlobalReplace(&nq,(char *)"(?U)/\\*.*\\*/",(char *)"");
// remove trailing space and semicolon if present. See issue#4380
nq.erase(nq.find_last_not_of(" ;") + 1);
size_t pos = nq.find_last_not_of(" ;");
if (pos != nq.npos) {
nq.erase(pos + 1); // remove trailing spaces and semicolumns
}
/*
// we do not threat SET SQL_LOG_BIN as a special case
if (match_regexes && match_regexes[0]->match(dig)) {
Expand Down
43 changes: 32 additions & 11 deletions lib/set_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

using namespace std;

#define MULTI_STATEMENTS_USE "Unable to parse multi-statements command with USE statement"

static void remove_quotes(string& v) {
if (v.length() > 2) {
Expand Down Expand Up @@ -118,7 +119,10 @@ VALGRIND_ENABLE_ERROR_REPORTING;
} else if (strcasecmp("transaction_read_only", value4.c_str()) == 0) {
value4 = "tx_read_only";
}
value5.erase(value5.find_last_not_of(" \n\r\t,")+1);
size_t pos = value5.find_last_not_of(" \n\r\t,");
if (pos != value5.npos) {
value5.erase(pos+1);
}
key = value4;
if (value5 == "''" || value5 == "\"\"") {
op.push_back("");
Expand Down Expand Up @@ -404,7 +408,10 @@ VALGRIND_ENABLE_ERROR_REPORTING;
} else if (strcasecmp("transaction_read_only", value4.c_str()) == 0) {
value4 = "tx_read_only";
}
value5.erase(value5.find_last_not_of(" \n\r\t,")+1);
size_t pos = value5.find_last_not_of(" \n\r\t,");
if (pos != value5.npos) {
value5.erase(pos+1);
}
key = value4;
if (value5 == "''" || value5 == "\"\"") {
op.push_back("");
Expand Down Expand Up @@ -508,7 +515,7 @@ std::string SetParser::parse_character_set() {
return value4;
}

std::string SetParser::parse_USE_query() {
std::string SetParser::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
Expand All @@ -518,6 +525,10 @@ std::string SetParser::parse_USE_query() {
opt2.set_longest_match(false);

std::string dbname = remove_comments(query);
size_t pos = dbname.find_last_not_of(" ;");
if (pos != dbname.npos) {
dbname.erase(pos + 1); // remove trailing spaces and semicolumns
}
re2::RE2 re0("^\\s*", opt2);
re2::RE2::Replace(&dbname, re0, "");
if (dbname.size() >= 4) {
Expand All @@ -537,18 +548,22 @@ std::string SetParser::parse_USE_query() {
dbname.erase(0, 1);
// Remove the last character
dbname.erase(dbname.length() - 1);
return dbname;
}
}
} else {
return dbname;
}
} else {
dbname = "";
}
} else {
return "";
dbname = "";
}

return "";
if (dbname.find_first_of(';') != std::string::npos) {
errmsg = MULTI_STATEMENTS_USE;
dbname = "";
}

return dbname;
}


Expand Down Expand Up @@ -638,18 +653,24 @@ void SetParser::test_parse_USE_query() {
{"USE/*+ placeholder_comment */`test_use_comment-5`", "test_use_comment-5"},
{"/* comment */USE`test_use_comment-6`", "test_use_comment-6"},
{"USE`test_use_comment-7`", "test_use_comment-7"},
{"USE test_use_comment-7 ;", "test_use_comment-7"},
{"USE`test_use_comment-2` ; ", "test_use_comment-2"},
{"USE`test_use_comment-2` ; -- comment", "test_use_comment-2"},
{"USE test_use_comment-7 /* comment */ ; ", "test_use_comment-7"},
{"USE /* comment */ test_use_comment-7 ; ", "test_use_comment-7"},
{"USE dbame ; SELECT 1", ""},
};

// Run tests for each pair
for (const auto& p : testCases) {
set_query(p.first);
std::string dbname = parse_USE_query();
std::string errmsg = "";
std::string dbname = parse_USE_query(errmsg);
if (dbname != p.second) {
// we call parse_USE_query() again just to make it easier to create a breakpoint
std::string s = parse_USE_query();
std::string s = parse_USE_query(errmsg);
assert(s == p.second);
}
}

}
#endif // DEBUG
Loading