Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions mysql-test/main/opt_hints_comments.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# MDEV-41606 Comments in new-style optimizer hints
CREATE TABLE t1 (a INT, KEY(a));
CREATE TABLE t2 (a INT, b INT);
INSERT INTO t1 VALUES (1),(2),(3);
INSERT INTO t2 VALUES (1,10),(2,20),(3,30);
# Comments before, between and after hints; commented hints are ignored
EXPLAIN EXTENDED
SELECT /*+
-- NO_INDEX(t1)
QB_NAME(qb)-- name the query block
-- INDEX(t1 a)
NO_INDEX(t1) -- do not use the index
*/ a FROM t1 WHERE a= 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select /*+ QB_NAME(`qb`) NO_INDEX(`t1`@`qb`) */ `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 2
# Comments inside hint arguments
EXPLAIN EXTENDED
SELECT /*+ QB_NAME(-- query block name
qb) NO_INDEX(-- table name
t1@qb -- index name
a) */ a FROM t1 WHERE a= 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select /*+ QB_NAME(`qb`) NO_INDEX(`t1`@`qb` `a`) */ `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 2
# Query block paths and join order from the report
EXPLAIN EXTENDED
SELECT /*+
QB_NAME(child_select, derived1.derived2) -- name the nested block
-- JOIN_ORDER(@child_select t1, t2)
JOIN_ORDER(@child_select t2, t1) -- reverse the join order
*/ * FROM
(SELECT * FROM
(SELECT t1.a, t2.b FROM t1, t2 WHERE t1.a= t2.a LIMIT 10)
AS derived2)
AS derived1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 3 100.00
3 DERIVED t2 ALL NULL NULL NULL NULL 3 100.00 Using where
3 DERIVED t1 ref a a 5 test.t2.a 1 100.00 Using index
Warnings:
Note 1003 /* select#1 */ select /*+ JOIN_ORDER(@`child_select` `t2`,`t1`) */ `derived2`.`a` AS `a`,`derived2`.`b` AS `b` from (/* select#3 */ select /*+ QB_NAME(`child_select`) */ `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`a` = `test`.`t2`.`a` limit 10) `derived2`
# A quoted identifier can contain a comment marker
EXPLAIN EXTENDED
SELECT /*+ QB_NAME(`-- qb`) NO_INDEX(t1@`-- qb`) */ a
FROM t1 WHERE a= 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select /*+ QB_NAME(`-- qb`) NO_INDEX(`t1`@`-- qb`) */ `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 2
EXPLAIN EXTENDED
SELECT /*+ QB_NAME("-- qb") NO_INDEX(t1@"-- qb") */ a
FROM t1 WHERE a= 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select /*+ QB_NAME(`-- qb`) NO_INDEX(`t1`@`-- qb`) */ `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 2
# A line comment can run up to the end of the hint
EXPLAIN EXTENDED
SELECT /*+ NO_INDEX(t1) -- INDEX(t1 a) */ a FROM t1 WHERE a= 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select /*+ NO_INDEX(`t1`@`select#1`) */ `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 2
# Comment-only hints retain the existing empty-hint warning
SELECT /*+ */ 1;
1
1
Warnings:
Warning 1064 Optimizer hint syntax error near '*/ 1' at line 1
SELECT /*+ -- QB_NAME(ignored) */ 1;
1
1
Warnings:
Warning 1064 Optimizer hint syntax error near '*/ 1' at line 1
SELECT /*+ --*/ 1;
1
1
Warnings:
Warning 1064 Optimizer hint syntax error near '*/ 1' at line 1
# Tabs after the marker and CRLF line endings
SET @stmt= CONCAT('EXPLAIN EXTENDED SELECT /*+ --', CHAR(9), 'ignored',
CHAR(13), CHAR(10),
'NO_INDEX(t1) */ a FROM t1 WHERE a= 2');
PREPARE stmt FROM @stmt;
EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select /*+ NO_INDEX(`t1`@`select#1`) */ `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 2
DEALLOCATE PREPARE stmt;
# Whitespace is required after the two dashes
SELECT /*+ --not_a_comment */ 1;
1
1
Warnings:
Warning 1064 Optimizer hint syntax error near '--not_a_comment */ 1' at line 1
SELECT /*+ - */ 1;
1
1
Warnings:
Warning 1064 Optimizer hint syntax error near '- */ 1' at line 1
# Syntax errors after a comment retain their line number
SELECT /*+
-- ignored text
NOT_A_HINT()
*/ 1;
1
1
Warnings:
Warning 1064 Optimizer hint syntax error near 'NOT_A_HINT()
*/ 1' at line 3
DROP TABLE t1, t2;
76 changes: 76 additions & 0 deletions mysql-test/main/opt_hints_comments.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
--echo # MDEV-41606 Comments in new-style optimizer hints
--enable_prepare_warnings

CREATE TABLE t1 (a INT, KEY(a));
CREATE TABLE t2 (a INT, b INT);
INSERT INTO t1 VALUES (1),(2),(3);
INSERT INTO t2 VALUES (1,10),(2,20),(3,30);

--echo # Comments before, between and after hints; commented hints are ignored
EXPLAIN EXTENDED
SELECT /*+
-- NO_INDEX(t1)
QB_NAME(qb)-- name the query block
-- INDEX(t1 a)
NO_INDEX(t1) -- do not use the index
*/ a FROM t1 WHERE a= 2;

--echo # Comments inside hint arguments
EXPLAIN EXTENDED
SELECT /*+ QB_NAME(-- query block name
qb) NO_INDEX(-- table name
t1@qb -- index name
a) */ a FROM t1 WHERE a= 2;

--echo # Query block paths and join order from the report
EXPLAIN EXTENDED
SELECT /*+
QB_NAME(child_select, derived1.derived2) -- name the nested block
-- JOIN_ORDER(@child_select t1, t2)
JOIN_ORDER(@child_select t2, t1) -- reverse the join order
*/ * FROM
(SELECT * FROM
(SELECT t1.a, t2.b FROM t1, t2 WHERE t1.a= t2.a LIMIT 10)
AS derived2)
AS derived1;

--echo # A quoted identifier can contain a comment marker
EXPLAIN EXTENDED
SELECT /*+ QB_NAME(`-- qb`) NO_INDEX(t1@`-- qb`) */ a
FROM t1 WHERE a= 2;
EXPLAIN EXTENDED
SELECT /*+ QB_NAME("-- qb") NO_INDEX(t1@"-- qb") */ a
FROM t1 WHERE a= 2;

--echo # A line comment can run up to the end of the hint
EXPLAIN EXTENDED
SELECT /*+ NO_INDEX(t1) -- INDEX(t1 a) */ a FROM t1 WHERE a= 2;

--echo # Comment-only hints retain the existing empty-hint warning
SELECT /*+ */ 1;
SELECT /*+ -- QB_NAME(ignored) */ 1;
SELECT /*+ --*/ 1;

--echo # Tabs after the marker and CRLF line endings
SET @stmt= CONCAT('EXPLAIN EXTENDED SELECT /*+ --', CHAR(9), 'ignored',
CHAR(13), CHAR(10),
'NO_INDEX(t1) */ a FROM t1 WHERE a= 2');
PREPARE stmt FROM @stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

--echo # Whitespace is required after the two dashes
--disable_ps_protocol
--disable_view_protocol
SELECT /*+ --not_a_comment */ 1;
SELECT /*+ - */ 1;

--echo # Syntax errors after a comment retain their line number
SELECT /*+
-- ignored text
NOT_A_HINT()
*/ 1;
--enable_ps_protocol
--enable_view_protocol

DROP TABLE t1, t2;
13 changes: 12 additions & 1 deletion sql/opt_hints_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,18 @@ Optimizer_hint_tokenizer::find_keyword(const LEX_CSTRING &str)
Optimizer_hint_tokenizer::Token
Optimizer_hint_tokenizer::get_token(CHARSET_INFO *cs)
{
get_spaces();
for ( ; ; )
{
get_spaces();
if (m_end - m_ptr < 2 || m_ptr[0] != '-' || m_ptr[1] != '-')
break;
// Match the SQL lexer's whitespace requirement after --.
if (m_end - m_ptr > 2 &&
!my_isspace(cs, m_ptr[2]) && !my_iscntrl(cs, m_ptr[2]))
break;
for (m_ptr+= 2; !eof() && *m_ptr != '\n'; m_ptr++)
{ }
}
if (eof())
return Token(Lex_cstring(m_ptr, m_ptr), TokenID::tEOF);
const char head= m_ptr[0];
Expand Down