diff --git a/client/mysql.cc b/client/mysql.cc index 04a7a15be56..824a416ec36 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -49,7 +49,7 @@ and you are welcome to modify and redistribute it under the GPL v2 license\n" #include #endif -const char *VER= "15.0"; +const char *VER= "15.1"; /* Don't try to make a nice table if the data is too big */ #define MAX_COLUMN_LENGTH 1024 @@ -2302,7 +2302,7 @@ static bool add_line(String &buffer,char *line,char *in_string, break; } else if (!*in_string && inchar == '/' && *(pos+1) == '*' && - *(pos+2) != '!') + !(*(pos+2) == '!' || (*(pos+2) == 'M' && *(pos+3) == '!'))) { if (preserve_comments) { diff --git a/mysql-test/r/comments.result b/mysql-test/r/comments.result index 99fab38d7a7..77c520b0c64 100644 --- a/mysql-test/r/comments.result +++ b/mysql-test/r/comments.result @@ -26,6 +26,20 @@ select 1 # The rest of the row will be ignored 1 1 /* line with only comment */; +select 1 /*M! +1 */; +1 +1 +2 +select 1 /*M!50000 +1 */; +1 +1 +2 +select 1 /*M!50300 +1 */; +1 +1 +2 +select 2 /*M!99999 +1 */; +2 +2 +select 2 /*M!0000 +1 */; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '0000 +1 */' at line 1 select 1/*!2*/; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '2*/' at line 1 select 1/*!000002*/; diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index f4298cc7a4c..32052ddfd02 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -137,6 +137,14 @@ drop table t1; 1 ERROR 1064 (42000) at line 3: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 ERROR at line 1: USE must be followed by a database name +1 +1 +2 +1 +1 +2 +1 +1 +2 +1 +1 +2 \ \\ '; diff --git a/mysql-test/t/comments.test b/mysql-test/t/comments.test index 3a18a8bd483..08c74c99d0c 100644 --- a/mysql-test/t/comments.test +++ b/mysql-test/t/comments.test @@ -20,6 +20,17 @@ select 1 # The rest of the row will be ignored # End of 4.1 tests +# +# Testing of MariaDB executable comments +# + +select 1 /*M! +1 */; +select 1 /*M!50000 +1 */; +select 1 /*M!50300 +1 */; +select 2 /*M!99999 +1 */; +--error ER_PARSE_ERROR +select 2 /*M!0000 +1 */; + # # Bug#25411 (trigger code truncated) # diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index d1ae90be864..4efd7c7636d 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -124,6 +124,13 @@ drop table t1; --exec echo "use" > $file --exec $MYSQL < $file 2>&1 +# Test exceutable comments +--exec echo "SELECT 1 /*! +1 */;" > $file +--exec echo "SELECT 1 /*M! +1 */;" >> $file +--exec echo "SELECT 1 /*!00000 +1 */;" >> $file +--exec echo "SELECT 1 /*M!00000 +1 */" >> $file +--exec $MYSQL < $file 2>&1 + --remove_file $file # diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index d7040a825fb..5378390ebb4 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -491,11 +491,12 @@ static void make_base_query(String *new_query, continue; // Continue with next symbol case '/': // Start of comment ? /* - Comment of format /#!number #/, must be skipped. + Comment of format /#!number #/ or /#M!number #/, must be skipped. These may include '"' and other comments, but it should be safe to parse the content as a normal string. */ - if (query[0] != '*' || query[1] == '!') + if (query[0] != '*' || query[1] == '!' || + (query[1] == 'M' && query[2] == '!')) break; query++; // skip "/" diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index fff1504b969..af3dad0945d 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1272,39 +1272,39 @@ int MYSQLlex(void *arg, void *yythd) lip->save_in_comment_state(); + if (lip->yyPeekn(2) == 'M' && lip->yyPeekn(3) == '!') + { + /* Skip MariaDB unique marker */ + lip->set_echo(FALSE); + lip->yySkip(); + /* The following if will be true */ + } if (lip->yyPeekn(2) == '!') { lip->in_comment= DISCARD_COMMENT; /* Accept '/' '*' '!', but do not keep this marker. */ lip->set_echo(FALSE); - lip->yySkip(); - lip->yySkip(); - lip->yySkip(); + lip->yySkipn(3); /* The special comment format is very strict: - '/' '*' '!', followed by exactly + '/' '*' '!', followed by an optional 'M' and exactly 1 digit (major), 2 digits (minor), then 2 digits (dot). 32302 -> 3.23.02 50032 -> 5.0.32 50114 -> 5.1.14 */ - char version_str[6]; - version_str[0]= lip->yyPeekn(0); - version_str[1]= lip->yyPeekn(1); - version_str[2]= lip->yyPeekn(2); - version_str[3]= lip->yyPeekn(3); - version_str[4]= lip->yyPeekn(4); - version_str[5]= 0; - if ( my_isdigit(cs, version_str[0]) - && my_isdigit(cs, version_str[1]) - && my_isdigit(cs, version_str[2]) - && my_isdigit(cs, version_str[3]) - && my_isdigit(cs, version_str[4]) + if ( my_isdigit(cs, lip->yyPeekn(0)) + && my_isdigit(cs, lip->yyPeekn(1)) + && my_isdigit(cs, lip->yyPeekn(2)) + && my_isdigit(cs, lip->yyPeekn(3)) + && my_isdigit(cs, lip->yyPeekn(4)) ) { ulong version; - version=strtol(version_str, NULL, 10); + char *end_ptr= (char*) lip->get_ptr()+5; + int error; + version= (ulong) my_strtoll10(lip->get_ptr(), &end_ptr, &error); if (version <= MYSQL_VERSION_ID) {