Description:
1. Hint commentaries are designed to behave like regular /* ... */ commentaries:
SELECT /*+ " */ 1; -- a valid SQL query
However, the mysql client program waits for the closing doublequote character:
mysql> SELECT /*+ ' */ 1;
'>
'>
'> ';
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set, 1 warning (0,00 sec)
ERROR 1064 (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 ''' at line 1
Backquote "`" and singlequote "'" characters are affected the same way.
2. There is a similar issue with statement delimiters:
mysql> SELECT /*+ ; */ 1; -- also a valid SQL query
ERROR 1064 (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 '/*+' at line 1
ERROR 1064 (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 '*/ 1' at line 1
How to repeat:
In the mysql client program, with or without the --comments parameter:
SELECT /*+ ' */ 1;
SELECT /*+ ` */ 1;
SELECT /*+ " */ 1;
SELECT /*+ ; */ 1;
Suggested fix:
The patch:
================================================================================
diff --git a/client/mysql.cc b/client/mysql.cc
index 266725b..e41af00 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -2498,7 +2498,7 @@ static bool add_line(String &buffer, char *line, size_t line_length,
char buff[80], *pos, *out;
COMMANDS *com;
bool need_space= 0;
- bool ss_comment= 0;
+ enum { SSC_NONE= 0, SSC_CONDITIONAL, SSC_HINT } ss_comment= SSC_NONE;
DBUG_ENTER("add_line");
if (!line[0] && buffer.is_empty())
@@ -2595,7 +2595,8 @@ static bool add_line(String &buffer, char *line, size_t line_length,
continue;
}
}
- else if (!*ml_comment && !*in_string && is_prefix(pos, delimiter))
+ else if (!*ml_comment && !*in_string && ss_comment != SSC_HINT &&
+ is_prefix(pos, delimiter))
{
// Found a statement. Continue parsing after the delimiter
pos+= delimiter_length;
@@ -2717,12 +2718,12 @@ static bool add_line(String &buffer, char *line, size_t line_length,
{ // Add found char to buffer
if (!*in_string && inchar == '/' && pos[1] == '*' &&
(pos[2] == '!' || pos[2] == '+'))
- ss_comment= 1;
+ ss_comment= (pos[2] == '!') ? SSC_CONDITIONAL : SSC_HINT;
else if (!*in_string && ss_comment && inchar == '*' && *(pos + 1) == '/')
- ss_comment= 0;
+ ss_comment= SSC_NONE;
if (inchar == *in_string)
*in_string= 0;
- else if (!*ml_comment && !*in_string &&
+ else if (!*ml_comment && !*in_string && ss_comment != SSC_HINT &&
(inchar == '\'' || inchar == '"' || inchar == '`'))
*in_string= (char) inchar;
if (!*ml_comment || preserve_comments)
================================================================================
After the fix:
mysql> SELECT /* ' */ 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0,00 sec)
mysql> SELECT /*+ ' */ 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set, 1 warning (0,00 sec)
mysql> SHOW WARNINGS;
+---------+------+-----------------------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------------------+
| Warning | 1064 | Optimizer hint syntax error near '' */ 1' at line 1 |
+---------+------+-----------------------------------------------------+
1 row in set (0,00 sec)
mysql> SELECT /*+ " */ 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set, 1 warning (0,00 sec)
mysql> SHOW WARNINGS;
+---------+------+-----------------------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------------------+
| Warning | 1064 | Optimizer hint syntax error near '" */ 1' at line 1 |
+---------+------+-----------------------------------------------------+
1 row in set (0,00 sec)
mysql> SELECT /*+ ` */ 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set, 1 warning (0,00 sec)
mysql> SHOW WARNINGS;
+---------+------+----------------------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------------------+
| Warning | 1064 | Optimizer hint syntax error near ' */ 1' at line 1 |
+---------+------+----------------------------------------------------+
1 row in set (0,00 sec)
mysql> SELECT /*+ ; */ 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set, 1 warning (0,00 sec)
mysql> SHOW WARNINGS;
+---------+------+-----------------------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------------------+
| Warning | 1064 | Optimizer hint syntax error near '; */ 1' at line 1 |
+---------+------+-----------------------------------------------------+
1 row in set (0,00 sec)
Description: 1. Hint commentaries are designed to behave like regular /* ... */ commentaries: SELECT /*+ " */ 1; -- a valid SQL query However, the mysql client program waits for the closing doublequote character: mysql> SELECT /*+ ' */ 1; '> '> '> '; +---+ | 1 | +---+ | 1 | +---+ 1 row in set, 1 warning (0,00 sec) ERROR 1064 (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 ''' at line 1 Backquote "`" and singlequote "'" characters are affected the same way. 2. There is a similar issue with statement delimiters: mysql> SELECT /*+ ; */ 1; -- also a valid SQL query ERROR 1064 (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 '/*+' at line 1 ERROR 1064 (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 '*/ 1' at line 1 How to repeat: In the mysql client program, with or without the --comments parameter: SELECT /*+ ' */ 1; SELECT /*+ ` */ 1; SELECT /*+ " */ 1; SELECT /*+ ; */ 1; Suggested fix: The patch: ================================================================================ diff --git a/client/mysql.cc b/client/mysql.cc index 266725b..e41af00 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2498,7 +2498,7 @@ static bool add_line(String &buffer, char *line, size_t line_length, char buff[80], *pos, *out; COMMANDS *com; bool need_space= 0; - bool ss_comment= 0; + enum { SSC_NONE= 0, SSC_CONDITIONAL, SSC_HINT } ss_comment= SSC_NONE; DBUG_ENTER("add_line"); if (!line[0] && buffer.is_empty()) @@ -2595,7 +2595,8 @@ static bool add_line(String &buffer, char *line, size_t line_length, continue; } } - else if (!*ml_comment && !*in_string && is_prefix(pos, delimiter)) + else if (!*ml_comment && !*in_string && ss_comment != SSC_HINT && + is_prefix(pos, delimiter)) { // Found a statement. Continue parsing after the delimiter pos+= delimiter_length; @@ -2717,12 +2718,12 @@ static bool add_line(String &buffer, char *line, size_t line_length, { // Add found char to buffer if (!*in_string && inchar == '/' && pos[1] == '*' && (pos[2] == '!' || pos[2] == '+')) - ss_comment= 1; + ss_comment= (pos[2] == '!') ? SSC_CONDITIONAL : SSC_HINT; else if (!*in_string && ss_comment && inchar == '*' && *(pos + 1) == '/') - ss_comment= 0; + ss_comment= SSC_NONE; if (inchar == *in_string) *in_string= 0; - else if (!*ml_comment && !*in_string && + else if (!*ml_comment && !*in_string && ss_comment != SSC_HINT && (inchar == '\'' || inchar == '"' || inchar == '`')) *in_string= (char) inchar; if (!*ml_comment || preserve_comments) ================================================================================ After the fix: mysql> SELECT /* ' */ 1; +---+ | 1 | +---+ | 1 | +---+ 1 row in set (0,00 sec) mysql> SELECT /*+ ' */ 1; +---+ | 1 | +---+ | 1 | +---+ 1 row in set, 1 warning (0,00 sec) mysql> SHOW WARNINGS; +---------+------+-----------------------------------------------------+ | Level | Code | Message | +---------+------+-----------------------------------------------------+ | Warning | 1064 | Optimizer hint syntax error near '' */ 1' at line 1 | +---------+------+-----------------------------------------------------+ 1 row in set (0,00 sec) mysql> SELECT /*+ " */ 1; +---+ | 1 | +---+ | 1 | +---+ 1 row in set, 1 warning (0,00 sec) mysql> SHOW WARNINGS; +---------+------+-----------------------------------------------------+ | Level | Code | Message | +---------+------+-----------------------------------------------------+ | Warning | 1064 | Optimizer hint syntax error near '" */ 1' at line 1 | +---------+------+-----------------------------------------------------+ 1 row in set (0,00 sec) mysql> SELECT /*+ ` */ 1; +---+ | 1 | +---+ | 1 | +---+ 1 row in set, 1 warning (0,00 sec) mysql> SHOW WARNINGS; +---------+------+----------------------------------------------------+ | Level | Code | Message | +---------+------+----------------------------------------------------+ | Warning | 1064 | Optimizer hint syntax error near ' */ 1' at line 1 | +---------+------+----------------------------------------------------+ 1 row in set (0,00 sec) mysql> SELECT /*+ ; */ 1; +---+ | 1 | +---+ | 1 | +---+ 1 row in set, 1 warning (0,00 sec) mysql> SHOW WARNINGS; +---------+------+-----------------------------------------------------+ | Level | Code | Message | +---------+------+-----------------------------------------------------+ | Warning | 1064 | Optimizer hint syntax error near '; */ 1' at line 1 | +---------+------+-----------------------------------------------------+ 1 row in set (0,00 sec)