Skip to content

Commit 1cd928c

Browse files
committed
MDEV-33281 Implement optimizer hints
Forbid adding optimizer hints to view definitions. In the case when optimizer hints are added to the view definition at a `CREATE (OR REPLACE) VIEW`/`ALTER VIEW` statement, a warning is generated and the hints are ignored. This commit also disables ps-protocol for test cases where `Unresolved table/index name` warnings are generated. The reason for this is such warnings are generated during both PREPARE and EXECUTE stages. Since opt_hints.test has `--enable_prepare_warnings`, running it with `--ps-protocol` causes duplication of warning messages
1 parent 4bb2669 commit 1cd928c

File tree

5 files changed

+149
-3
lines changed

5 files changed

+149
-3
lines changed

mysql-test/main/lowercase_table.test

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ SET NAMES utf8mb4;
219219
CREATE TABLE t1 (a INT);
220220
INSERT INTO t1 VALUES (1), (2);
221221

222+
--enable_prepare_warnings
222223
# Test that aliases are accent sensitive with lowercase-table-names=1
223224
# Test that table names in hints are also accent sensitive
224225
SELECT /*+BKA(a) BKA(å)*/ a.a FROM t1 a, t1 å;
@@ -228,6 +229,7 @@ SELECT /*+BKA(a) BKA(å)*/ a.a FROM t1 a, t1 å;
228229
SELECT a.a, A.a FROM t1 a, t1 A;
229230
# Test that table names in hints are also case insensitive
230231
SELECT /*+BKA(a) BKA(A)*/ a.a FROM t1 a;
232+
--disable_prepare_warnings
231233

232234
DROP TABLE t1;
233235

mysql-test/main/opt_hints.result

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1070,7 +1070,69 @@ i
10701070
Warnings:
10711071
Warning 4202 Hint NO_ICP(`t1`@`q1` `PRIMARY`) is ignored as conflicting/duplicated
10721072
DROP TABLE t1;
1073-
# WL#8016 Parser for optimizer hints
1073+
#
1074+
# Hints inside views are not supported
1075+
#
1076+
CREATE TABLE t1 (a INT, INDEX idx_a(a));
1077+
INSERT INTO t1 VALUES (1),(2);
1078+
CREATE VIEW v1 AS SELECT /*+ NO_MRR(t1 idx_a) */ a FROM t1;
1079+
Warnings:
1080+
Warning 4206 Optimizer hints are not supported inside view definitions
1081+
SELECT * FROM v1;
1082+
a
1083+
1
1084+
2
1085+
# Make sure hints are not present inside the view definition:
1086+
SHOW CREATE VIEW v1;
1087+
View Create View character_set_client collation_connection
1088+
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` utf8mb4 utf8mb4_uca1400_ai_ci
1089+
EXPLAIN EXTENDED SELECT * FROM v1;
1090+
id select_type table type possible_keys key key_len ref rows filtered Extra
1091+
1 SIMPLE t1 index NULL idx_a 5 NULL 2 100.00 Using index
1092+
Warnings:
1093+
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1`
1094+
CREATE OR REPLACE VIEW v1 AS SELECT /*+ NO_MRR(t1 idx_a) BKA(t1)*/ a FROM t1;
1095+
Warnings:
1096+
Warning 4206 Optimizer hints are not supported inside view definitions
1097+
SHOW CREATE VIEW v1;
1098+
View Create View character_set_client collation_connection
1099+
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` utf8mb4 utf8mb4_uca1400_ai_ci
1100+
ALTER VIEW v1 AS SELECT /*+ QB_NAME(q1)*/ a FROM t1;
1101+
Warnings:
1102+
Warning 4206 Optimizer hints are not supported inside view definitions
1103+
SHOW CREATE VIEW v1;
1104+
View Create View character_set_client collation_connection
1105+
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` utf8mb4 utf8mb4_uca1400_ai_ci
1106+
SELECT * FROM v1;
1107+
a
1108+
1
1109+
2
1110+
# Wrong place for the hint, must be simply ignored:
1111+
CREATE OR REPLACE VIEW v1 AS SELECT a /*+ NO_ICP(t1 idx_a)*/ FROM t1;
1112+
SHOW CREATE VIEW v1;
1113+
View Create View character_set_client collation_connection
1114+
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` utf8mb4 utf8mb4_uca1400_ai_ci
1115+
# Incorrect hint does not prevent view creation, only a warning generated:
1116+
CREATE VIEW v2 AS SELECT /*+ BAD HINT*/ a+10 FROM t1;
1117+
Warnings:
1118+
Warning 1064 Optimizer hint syntax error near 'BAD HINT*/ a+10 FROM t1' at line 1
1119+
SELECT * FROM v2;
1120+
a+10
1121+
11
1122+
12
1123+
EXPLAIN EXTENDED SELECT * FROM v2;
1124+
id select_type table type possible_keys key key_len ref rows filtered Extra
1125+
1 SIMPLE t1 index NULL idx_a 5 NULL 2 100.00 Using index
1126+
Warnings:
1127+
Note 1003 select `test`.`t1`.`a` + 10 AS `a+10` from `test`.`t1`
1128+
SHOW CREATE VIEW v2;
1129+
View Create View character_set_client collation_connection
1130+
v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t1`.`a` + 10 AS `a+10` from `t1` utf8mb4 utf8mb4_uca1400_ai_ci
1131+
DROP VIEW v1, v2;
1132+
DROP TABLE t1;
1133+
#
1134+
# Tests of parser for optimizer hints
1135+
#
10741136
CREATE TABLE t1 (i INT, j INT);
10751137
CREATE INDEX i1 ON t1(i);
10761138
CREATE INDEX i2 ON t1(j);
@@ -1450,6 +1512,10 @@ SELECT 1 FROM /*+ #1 */ t1 WHERE /*+ #2 */ 1 /*+ #3 */;
14501512
1
14511513
1
14521514
1
1515+
SELECT 1 FROM /*+ QB_NAME(q1) */ t1 /*+ NO_ICP() */WHERE /*+ NO_MRR(t1) */ 1 /*+ #3 */;
1516+
1
1517+
1
1518+
1
14531519
# Warnings expected:
14541520
SELECT /*+ NO_ICP() */ 1
14551521
FROM /*+ regular commentary, not a hint! */ t1;

mysql-test/main/opt_hints.test

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
--enable_prepare_warnings
2-
2+
--disable_view_protocol # Since optimizer hints are not supported inside views
33
SET NAMES utf8mb4;
44

55
--echo # Testing that index names in hints are accent sensitive case insensitive
66
CREATE TABLE t1 (a INT, ä INT, INDEX idx_a(a), INDEX idx_ä(ä));
77
INSERT INTO t1 VALUES (1,1),(2,2);
88
SELECT /*+ NO_MRR(t1 idx_a) */ a FROM t1;
99
SELECT /*+ NO_MRR(t1 idx_A) */ a FROM t1;
10+
11+
# Warnings "Unresolved table/index name..." are generated during both prepare
12+
# and execution stages. So disable PS protocol to avoid duplication
13+
--disable_ps_protocol
1014
SELECT /*+ NO_MRR(t1 idx_å) */ a FROM t1;
1115
SELECT /*+ NO_MRR(t1 idx_a, idx_å, idx_A) */ a FROM t1;
16+
--enable_ps_protocol
1217
DROP TABLE t1;
1318

1419
--echo # Testing that query block names are accent sensitive case insensitive
@@ -129,9 +134,13 @@ EXPLAIN EXTENDED SELECT /*+ NO_ICP(t5@блок1 x_idx) */ * FROM
129134

130135

131136
--echo # Expected warning for z_idx key, unresolved name.
137+
# Warnings "Unresolved table/index name..." are generated during both prepare
138+
# and execution stages. So disable PS protocol to avoid duplication
139+
--disable_ps_protocol
132140
EXPLAIN EXTENDED SELECT * FROM
133141
(SELECT /*+ NO_ICP(t5 y_idx, x_idx, z_idx) */ t4.x, t5.y FROM t4, t4 t5
134142
WHERE t4.y = 8 AND t5.x BETWEEN 7 AND t4.y+0) AS TD;
143+
--enable_ps_protocol
135144

136145
--echo # ICP should still be used
137146
EXPLAIN EXTENDED SELECT * FROM
@@ -300,10 +309,14 @@ EXPLAIN EXTENDED SELECT /*+ BKA(tbl12, tbl13) */ * FROM t12 tbl12, t13 tbl13
300309
WHERE tbl12.a=tbl13.a AND (tbl13.b+1 <= tbl13.b+1);
301310

302311
--echo # Print warnings for nonexistent names
312+
# Warnings "Unresolved table/index name..." are generated during both prepare
313+
# and execution stages. So disable PS protocol to avoid duplication
314+
--disable_ps_protocol
303315
EXPLAIN EXTENDED
304316
SELECT /*+ BKA(t2) NO_BNL(t1) BKA(t3) NO_RANGE_OPTIMIZATION(t3 idx1) NO_RANGE_OPTIMIZATION(t3) */
305317
t2.f1, t2.f2, t2.f3 FROM t1,t2 WHERE t1.f1=t2.f1 AND
306318
t2.f2 BETWEEN t1.f1 AND t1.f2 AND t2.f2 + 1 >= t1.f1 + 1;
319+
--enable_ps_protocol
307320

308321
--echo # Check illegal syntax
309322
EXPLAIN EXTENDED SELECT /*+ BKA(qb1 t3@qb1) */ f2 FROM
@@ -319,8 +332,12 @@ EXPLAIN EXTENDED SELECT /*+ BKA(@qb1 t13) */ * FROM (SELECT /*+ QB_NAME(QB1) */
319332
WHERE t12.a=t13.a AND (t13.b+1 <= t13.b+1)) AS s1;
320333

321334
--echo # Check that original table name is not recognized if alias is used.
335+
# Warnings "Unresolved table/index name..." are generated during both prepare
336+
# and execution stages. So disable PS protocol to avoid duplication
337+
--disable_ps_protocol
322338
EXPLAIN EXTENDED SELECT /*+ BKA(tbl2) */ * FROM t12 tbl12, t13 tbl13
323339
WHERE tbl12.a=tbl13.a AND (tbl13.b+1 <= tbl13.b+1);
340+
--enable_ps_protocol
324341

325342
--disable_ps2_protocol
326343
--echo # Check that PS and conventional statements give the same result.
@@ -500,8 +517,41 @@ SELECT /*+ QB_NAME(q1) NO_ICP(@q1 t1 PRIMARY) NO_ICP(@q1 t1 PRIMARY) */ * FROM t
500517

501518
DROP TABLE t1;
502519

503-
--echo # WL#8016 Parser for optimizer hints
520+
--echo #
521+
--echo # Hints inside views are not supported
522+
--echo #
523+
CREATE TABLE t1 (a INT, INDEX idx_a(a));
524+
INSERT INTO t1 VALUES (1),(2);
525+
526+
CREATE VIEW v1 AS SELECT /*+ NO_MRR(t1 idx_a) */ a FROM t1;
527+
SELECT * FROM v1;
528+
--echo # Make sure hints are not present inside the view definition:
529+
SHOW CREATE VIEW v1;
530+
EXPLAIN EXTENDED SELECT * FROM v1;
531+
532+
CREATE OR REPLACE VIEW v1 AS SELECT /*+ NO_MRR(t1 idx_a) BKA(t1)*/ a FROM t1;
533+
SHOW CREATE VIEW v1;
534+
535+
ALTER VIEW v1 AS SELECT /*+ QB_NAME(q1)*/ a FROM t1;
536+
SHOW CREATE VIEW v1;
537+
SELECT * FROM v1;
538+
539+
--echo # Wrong place for the hint, must be simply ignored:
540+
CREATE OR REPLACE VIEW v1 AS SELECT a /*+ NO_ICP(t1 idx_a)*/ FROM t1;
541+
SHOW CREATE VIEW v1;
504542

543+
--echo # Incorrect hint does not prevent view creation, only a warning generated:
544+
CREATE VIEW v2 AS SELECT /*+ BAD HINT*/ a+10 FROM t1;
545+
SELECT * FROM v2;
546+
EXPLAIN EXTENDED SELECT * FROM v2;
547+
SHOW CREATE VIEW v2;
548+
549+
DROP VIEW v1, v2;
550+
DROP TABLE t1;
551+
552+
--echo #
553+
--echo # Tests of parser for optimizer hints
554+
--echo #
505555

506556
CREATE TABLE t1 (i INT, j INT);
507557
CREATE INDEX i1 ON t1(i);
@@ -552,8 +602,12 @@ DELETE /*+ NO_ICP() */ FROM t1 WHERE 1;
552602

553603
SELECT /*+ BKA(a b) */ 1 FROM t1 a, t1 b;
554604

605+
# Warnings "Unresolved table/index name..." are generated during both prepare
606+
# and execution stages. So disable PS protocol to avoid duplication
607+
--disable_ps_protocol
555608
SELECT /*+ NO_ICP(i1) */ 1 FROM t1;
556609
SELECT /*+ NO_ICP(i1 i2) */ 1 FROM t1;
610+
--enable_ps_protocol
557611
SELECT /*+ NO_ICP(@qb ident) */ 1 FROM t1;
558612

559613
--echo
@@ -578,6 +632,10 @@ EXPLAIN EXTENDED DELETE /*+ test */ FROM t1 WHERE i = 10;
578632
--echo
579633

580634
CREATE INDEX 3rd_index ON t1(i, j);
635+
636+
# Warnings "Unresolved table/index name..." are generated during both prepare
637+
# and execution stages. So disable PS protocol to avoid duplication
638+
--disable_ps_protocol
581639
SELECT /*+ NO_ICP(3rd_index) */ 1 FROM t1;
582640

583641
CREATE INDEX $index ON t1(j, i);
@@ -605,6 +663,7 @@ SELECT /*+ BKA(" quoted name test") */ 1 FROM t1;
605663

606664
DROP TABLE ` quoted name test`;
607665
DROP TABLE `test1``test2```;
666+
--enable_ps_protocol
608667

609668
--echo # Valid hints, no warning:
610669
EXPLAIN EXTENDED SELECT /*+ QB_NAME(`*`) */ 1;
@@ -622,6 +681,10 @@ EXPLAIN EXTENDED SELECT /*+ QB_NAME(`\BF``\BF`) */ 1;
622681
CREATE TABLE tableТ (i INT);
623682

624683
--echo # invalid hints, should warn:
684+
685+
# Warnings "Unresolved table/index name..." are generated during both prepare
686+
# and execution stages. So disable PS protocol to avoid duplication
687+
--disable_ps_protocol
625688
SELECT /*+ BKA(tableТ) */ 1 FROM t1;
626689
SELECT /*+ BKA(test@tableТ) */ 1 FROM t1;
627690
DROP TABLE tableТ;
@@ -635,6 +698,7 @@ SELECT /*+ BKA(test@таблица) */ 1 FROM t1;
635698
SELECT /*+ NO_ICP(`\D1`) */ 1 FROM t1;
636699

637700
DROP TABLE таблица;
701+
--enable_ps_protocol
638702

639703
--echo
640704
--echo # derived tables and other subqueries:
@@ -649,7 +713,9 @@ SELECT 1 FROM DUAL WHERE 1 IN (SELECT /*+ DEBUG_HINT3 */ 1);
649713
--echo
650714
SELECT /*+ 10 */ 1;
651715
SELECT /*+ NO_ICP() */ 1;
716+
--disable_ps_protocol # to avoid warnings duplication, see details above
652717
SELECT /*+ NO_ICP(10) */ 1;
718+
--enable_ps_protocol
653719
SELECT /*+ NO_ICP( */ 1;
654720
SELECT /*+ NO_ICP) */ 1;
655721
SELECT /*+ NO_ICP(t1 */ 1;
@@ -664,6 +730,7 @@ INSERT INTO t1 VALUES (1, 1), (2, 2);
664730

665731
SELECT 1 FROM /*+ regular commentary, not a hint! */ t1;
666732
SELECT 1 FROM /*+ #1 */ t1 WHERE /*+ #2 */ 1 /*+ #3 */;
733+
SELECT 1 FROM /*+ QB_NAME(q1) */ t1 /*+ NO_ICP() */WHERE /*+ NO_MRR(t1) */ 1 /*+ #3 */;
667734

668735
--echo # Warnings expected:
669736
SELECT /*+ NO_ICP() */ 1

sql/opt_hints.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,15 @@ bool Optimizer_hint_parser::Qb_name_hint::resolve(Parse_context *pc) const
687687

688688
bool Optimizer_hint_parser::Hint_list::resolve(Parse_context *pc)
689689
{
690+
if (pc->thd->lex->create_view)
691+
{
692+
// we're creating or modifying a view, hints are not allowed here
693+
push_warning_printf(pc->thd, Sql_condition::WARN_LEVEL_WARN,
694+
ER_HINTS_INSIDE_VIEWS_NOT_SUPPORTED,
695+
ER_THD(pc->thd, ER_HINTS_INSIDE_VIEWS_NOT_SUPPORTED));
696+
return false;
697+
}
698+
690699
if (!get_qb_hints(pc))
691700
return true;
692701

sql/share/errmsg-utf8.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12322,3 +12322,5 @@ ER_UNRESOLVED_TABLE_HINT_NAME
1232212322
eng "Unresolved table name %s for %s hint"
1232312323
ER_UNRESOLVED_INDEX_HINT_NAME
1232412324
eng "Unresolved index name %s for %s hint"
12325+
ER_HINTS_INSIDE_VIEWS_NOT_SUPPORTED
12326+
eng "Optimizer hints are not supported inside view definitions"

0 commit comments

Comments
 (0)