Removing trailing semicolon from `USE` #4628

Trailing semicolon are now removed.

This commit also ensure that an error is returned if `USE` is part
of a multi-statement.
pull/4629/head
René Cannaò 2 years ago
parent 6f671eed80
commit 645963af8e

@ -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

@ -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) {
@ -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);
}

@ -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) {
@ -508,7 +509,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
@ -518,6 +519,7 @@ std::string SetParser::parse_USE_query() {
opt2.set_longest_match(false);
std::string dbname = remove_comments(query);
dbname.erase(dbname.find_last_not_of(" ;") + 1); // remove trailing spaces and semicolumns
re2::RE2 re0("^\\s*", opt2);
re2::RE2::Replace(&dbname, re0, "");
if (dbname.size() >= 4) {
@ -537,18 +539,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 = "";
}
if (dbname.find_first_of(';') != std::string::npos) {
errmsg = MULTI_STATEMENTS_USE;
dbname = "";
}
return "";
return dbname;
}
@ -638,18 +644,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…
Cancel
Save