Description:
A query with trailing semicolon would get a different digest when it
is processed by the parser service, mysql_parser_parse(), comparing
to that by other functions taking user input such as
dispatch_command(). It would fail the match when the same query is
used both to define a rule for, say, Rewriter plugin and to run
as user input.
It is similar to Bug #115943 STATEMENT_DIGEST() adds trailing
semicolon to digest.
How to repeat:
Here the rewriter plugin is used to show the problem:
INSERT INTO query_rewrite.rewrite_rules ( pattern, replacement )
VALUES ( 'SELECT ?;', 'SELECT "literal"' );
SELECT * FROM query_rewrite.rewrite_rules;
CALL query_rewrite.flush_rewrite_rules();
SELECT * FROM query_rewrite.rewrite_rules;
SELECT 1;
Expected Result:
mysql> SELECT * FROM query_rewrite.rewrite_rules;
+----+-----------+------------------+------------------+---------+---------+
| id | pattern | pattern_database | replacement | enabled | message |
+----+-----------+------------------+------------------+---------+---------+
| 5 | SELECT ?; | NULL | SELECT "literal" | YES | NULL |
+----+-----------+------------------+------------------+---------+---------+
1 row in set (0.00 sec)
mysql> select 1;
+---------+
| literal |
+---------+
| literal |
+---------+
1 row in set, 1 warning (0.00 sec)
mysql> show warnings;
+-------+------+----------------------------------------------------------------------------+
| Level | Code | Message |
+-------+------+----------------------------------------------------------------------------+
| Note | 1105 | Query 'select 1' rewritten to 'SELECT "literal"' by a query rewrite plugin |
+-------+------+----------------------------------------------------------------------------+
1 row in set (0.00 sec)
Actual Result:
mysql> SELECT * FROM query_rewrite.rewrite_rules;
+----+-----------+------------------+------------------+---------+---------+
| id | pattern | pattern_database | replacement | enabled | message |
+----+-----------+------------------+------------------+---------+---------+
| 4 | SELECT ?; | NULL | SELECT "literal" | YES | NULL |
+----+-----------+------------------+------------------+---------+---------+
1 row in set (0.00 sec)
mysql> select 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)
Suggested fix:
Invoke parser_state.init() with the trimmed query from alloc_query(),
just as processing user input.