11
11
12
12
using namespace std ;
13
13
14
+ #define MULTI_STATEMENTS_USE " Unable to parse multi-statements command with USE statement"
14
15
15
16
static void remove_quotes (string& v) {
16
17
if (v.length () > 2 ) {
@@ -118,7 +119,10 @@ VALGRIND_ENABLE_ERROR_REPORTING;
118
119
} else if (strcasecmp (" transaction_read_only" , value4.c_str ()) == 0 ) {
119
120
value4 = " tx_read_only" ;
120
121
}
121
- value5.erase (value5.find_last_not_of (" \n\r\t ," )+1 );
122
+ size_t pos = value5.find_last_not_of (" \n\r\t ," );
123
+ if (pos != value5.npos ) {
124
+ value5.erase (pos+1 );
125
+ }
122
126
key = value4;
123
127
if (value5 == " ''" || value5 == " \"\" " ) {
124
128
op.push_back (" " );
@@ -404,7 +408,10 @@ VALGRIND_ENABLE_ERROR_REPORTING;
404
408
} else if (strcasecmp (" transaction_read_only" , value4.c_str ()) == 0 ) {
405
409
value4 = " tx_read_only" ;
406
410
}
407
- value5.erase (value5.find_last_not_of (" \n\r\t ," )+1 );
411
+ size_t pos = value5.find_last_not_of (" \n\r\t ," );
412
+ if (pos != value5.npos ) {
413
+ value5.erase (pos+1 );
414
+ }
408
415
key = value4;
409
416
if (value5 == " ''" || value5 == " \"\" " ) {
410
417
op.push_back (" " );
@@ -508,7 +515,7 @@ std::string SetParser::parse_character_set() {
508
515
return value4;
509
516
}
510
517
511
- std::string SetParser::parse_USE_query () {
518
+ std::string SetParser::parse_USE_query (std::string& errmsg ) {
512
519
#ifdef DEBUG
513
520
proxy_debug (PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 4 , " Parsing query %s\n " , query.c_str ());
514
521
#endif // DEBUG
@@ -518,6 +525,10 @@ std::string SetParser::parse_USE_query() {
518
525
opt2.set_longest_match (false );
519
526
520
527
std::string dbname = remove_comments (query);
528
+ size_t pos = dbname.find_last_not_of (" ;" );
529
+ if (pos != dbname.npos ) {
530
+ dbname.erase (pos + 1 ); // remove trailing spaces and semicolumns
531
+ }
521
532
re2::RE2 re0 (" ^\\ s*" , opt2);
522
533
re2::RE2::Replace (&dbname, re0, " " );
523
534
if (dbname.size () >= 4 ) {
@@ -537,18 +548,22 @@ std::string SetParser::parse_USE_query() {
537
548
dbname.erase (0 , 1 );
538
549
// Remove the last character
539
550
dbname.erase (dbname.length () - 1 );
540
- return dbname;
541
551
}
542
552
}
543
- } else {
544
- return dbname;
545
553
}
554
+ } else {
555
+ dbname = " " ;
546
556
}
547
557
} else {
548
- return " " ;
558
+ dbname = " " ;
549
559
}
550
560
551
- return " " ;
561
+ if (dbname.find_first_of (' ;' ) != std::string::npos) {
562
+ errmsg = MULTI_STATEMENTS_USE;
563
+ dbname = " " ;
564
+ }
565
+
566
+ return dbname;
552
567
}
553
568
554
569
@@ -638,18 +653,24 @@ void SetParser::test_parse_USE_query() {
638
653
{" USE/*+ placeholder_comment */`test_use_comment-5`" , " test_use_comment-5" },
639
654
{" /* comment */USE`test_use_comment-6`" , " test_use_comment-6" },
640
655
{" USE`test_use_comment-7`" , " test_use_comment-7" },
656
+ {" USE test_use_comment-7 ;" , " test_use_comment-7" },
657
+ {" USE`test_use_comment-2` ; " , " test_use_comment-2" },
658
+ {" USE`test_use_comment-2` ; -- comment" , " test_use_comment-2" },
659
+ {" USE test_use_comment-7 /* comment */ ; " , " test_use_comment-7" },
660
+ {" USE /* comment */ test_use_comment-7 ; " , " test_use_comment-7" },
661
+ {" USE dbame ; SELECT 1" , " " },
641
662
};
642
663
643
664
// Run tests for each pair
644
665
for (const auto & p : testCases) {
645
666
set_query (p.first );
646
- std::string dbname = parse_USE_query ();
667
+ std::string errmsg = " " ;
668
+ std::string dbname = parse_USE_query (errmsg);
647
669
if (dbname != p.second ) {
648
670
// we call parse_USE_query() again just to make it easier to create a breakpoint
649
- std::string s = parse_USE_query ();
671
+ std::string s = parse_USE_query (errmsg );
650
672
assert (s == p.second );
651
673
}
652
674
}
653
-
654
675
}
655
676
#endif // DEBUG
0 commit comments