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)