Commit 282c3037 authored by Michael Widenius's avatar Michael Widenius

Added MariaDB executable comment syntax: /*M!##### */

client/mysql.cc:
  Don't remove MariaDB executable comments.
mysql-test/r/comments.result:
  Test MariaDB executable comments.
mysql-test/r/mysql.result:
  Test MariaDB executable comments.
mysql-test/t/comments.test:
  Test MariaDB executable comments.
mysql-test/t/mysql.test:
  Test MariaDB executable comments.
sql/sql_cache.cc:
  Don't delete MariaDB executable comments.
sql/sql_lex.cc:
  Handle MariaDB executable comments
parent 2df19147
...@@ -49,7 +49,7 @@ and you are welcome to modify and redistribute it under the GPL v2 license\n" ...@@ -49,7 +49,7 @@ and you are welcome to modify and redistribute it under the GPL v2 license\n"
#include <locale.h> #include <locale.h>
#endif #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 */ /* Don't try to make a nice table if the data is too big */
#define MAX_COLUMN_LENGTH 1024 #define MAX_COLUMN_LENGTH 1024
...@@ -2302,7 +2302,7 @@ static bool add_line(String &buffer,char *line,char *in_string, ...@@ -2302,7 +2302,7 @@ static bool add_line(String &buffer,char *line,char *in_string,
break; break;
} }
else if (!*in_string && inchar == '/' && *(pos+1) == '*' && else if (!*in_string && inchar == '/' && *(pos+1) == '*' &&
*(pos+2) != '!') !(*(pos+2) == '!' || (*(pos+2) == 'M' && *(pos+3) == '!')))
{ {
if (preserve_comments) if (preserve_comments)
{ {
......
...@@ -26,6 +26,20 @@ select 1 # The rest of the row will be ignored ...@@ -26,6 +26,20 @@ select 1 # The rest of the row will be ignored
1 1
1 1
/* line with only comment */; /* 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*/; 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 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*/; select 1/*!000002*/;
......
...@@ -137,6 +137,14 @@ drop table t1; ...@@ -137,6 +137,14 @@ drop table t1;
1 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 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 ERROR at line 1: USE must be followed by a database name
1 +1
2
1 +1
2
1 +1
2
1 +1
2
\ \
\\ \\
'; ';
......
...@@ -20,6 +20,17 @@ select 1 # The rest of the row will be ignored ...@@ -20,6 +20,17 @@ select 1 # The rest of the row will be ignored
# End of 4.1 tests # 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) # Bug#25411 (trigger code truncated)
# #
......
...@@ -124,6 +124,13 @@ drop table t1; ...@@ -124,6 +124,13 @@ drop table t1;
--exec echo "use" > $file --exec echo "use" > $file
--exec $MYSQL < $file 2>&1 --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 --remove_file $file
# #
......
...@@ -491,11 +491,12 @@ static void make_base_query(String *new_query, ...@@ -491,11 +491,12 @@ static void make_base_query(String *new_query,
continue; // Continue with next symbol continue; // Continue with next symbol
case '/': // Start of comment ? 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 These may include '"' and other comments, but it should
be safe to parse the content as a normal string. 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; break;
query++; // skip "/" query++; // skip "/"
......
...@@ -1272,39 +1272,39 @@ int MYSQLlex(void *arg, void *yythd) ...@@ -1272,39 +1272,39 @@ int MYSQLlex(void *arg, void *yythd)
lip->save_in_comment_state(); 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) == '!') if (lip->yyPeekn(2) == '!')
{ {
lip->in_comment= DISCARD_COMMENT; lip->in_comment= DISCARD_COMMENT;
/* Accept '/' '*' '!', but do not keep this marker. */ /* Accept '/' '*' '!', but do not keep this marker. */
lip->set_echo(FALSE); lip->set_echo(FALSE);
lip->yySkip(); lip->yySkipn(3);
lip->yySkip();
lip->yySkip();
/* /*
The special comment format is very strict: 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). 1 digit (major), 2 digits (minor), then 2 digits (dot).
32302 -> 3.23.02 32302 -> 3.23.02
50032 -> 5.0.32 50032 -> 5.0.32
50114 -> 5.1.14 50114 -> 5.1.14
*/ */
char version_str[6]; if ( my_isdigit(cs, lip->yyPeekn(0))
version_str[0]= lip->yyPeekn(0); && my_isdigit(cs, lip->yyPeekn(1))
version_str[1]= lip->yyPeekn(1); && my_isdigit(cs, lip->yyPeekn(2))
version_str[2]= lip->yyPeekn(2); && my_isdigit(cs, lip->yyPeekn(3))
version_str[3]= lip->yyPeekn(3); && my_isdigit(cs, lip->yyPeekn(4))
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])
) )
{ {
ulong version; 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) if (version <= MYSQL_VERSION_ID)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment