Skip to content

Commit

Permalink
Removing trailing semicolon from USE #4628
Browse files Browse the repository at this point in the history
Trailing semicolon are now removed.

This commit also ensure that an error is returned if `USE` is part
of a multi-statement.
  • Loading branch information
renecannao committed Aug 29, 2024
1 parent 6f671ee commit 645963a
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 11 deletions.
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
6 changes: 5 additions & 1 deletion 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
30 changes: 21 additions & 9 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 @@ -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
Expand All @@ -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) {
Expand All @@ -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;
}


Expand Down Expand Up @@ -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

0 comments on commit 645963a

Please sign in to comment.