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
48 changes: 42 additions & 6 deletions mysql-test/main/opt_hints.result
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,18 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ref f1 f1 8 test.t3.f1,test.t3.f2 2 50.00 Using where; FirstMatch(t3)
Warnings:
Note 1003 update /*+ BKA(`t2`@`select#2`) NO_BNL(`t1`@`select#2`) NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ `test`.`t3` semi join (`test`.`t1` join `test`.`t2`) set `test`.`t3`.`f3` = 'mnbv' where `test`.`t1`.`f1` = `test`.`t3`.`f1` and `test`.`t2`.`f1` = `test`.`t3`.`f1` and `test`.`t2`.`f2` = `test`.`t3`.`f2` and `test`.`t3`.`f1` > 30 and `test`.`t3`.`f1` < 33 and `test`.`t3`.`f2` between `test`.`t3`.`f1` and `test`.`t1`.`f2` and `test`.`t3`.`f2` + 1 >= `test`.`t3`.`f1` + 1 and `test`.`t3`.`f3` = `test`.`t2`.`f3`
# Same as above but addressing tables with QB name
EXPLAIN EXTENDED
UPDATE /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY) BKA(t2@QB1) NO_BNL(t1@QB1)*/ t3
SET f3 = 'mnbv' WHERE f1 > 30 AND f1 < 33 AND (t3.f1, t3.f2, t3.f3) IN
(SELECT /*+ QB_NAME(QB1) */ t2.f1, t2.f2, t2.f3 FROM t1,t2 WHERE t1.f1=t2.f1 AND
t2.f2 BETWEEN t1.f1 AND t1.f2 AND t2.f2 + 1 >= t1.f1 + 1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 range PRIMARY,f2_idx,f3_idx f2_idx 4 NULL 2 100.00 Using index condition; Using where
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 3.33 Using where
1 PRIMARY t2 ref f1 f1 8 test.t3.f1,test.t3.f2 2 50.00 Using where; FirstMatch(t3)
Warnings:
Note 1003 update /*+ BKA(`t2`@`QB1`) NO_BNL(`t1`@`QB1`) NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ `test`.`t3` semi join (`test`.`t1` join `test`.`t2`) set `test`.`t3`.`f3` = 'mnbv' where `test`.`t1`.`f1` = `test`.`t3`.`f1` and `test`.`t2`.`f1` = `test`.`t3`.`f1` and `test`.`t2`.`f2` = `test`.`t3`.`f2` and `test`.`t3`.`f1` > 30 and `test`.`t3`.`f1` < 33 and `test`.`t3`.`f2` between `test`.`t3`.`f1` and `test`.`t1`.`f2` and `test`.`t3`.`f2` + 1 >= `test`.`t3`.`f1` + 1 and `test`.`t3`.`f3` = `test`.`t2`.`f3`
# Turn off range access for all keys.
EXPLAIN EXTENDED UPDATE /*+ NO_RANGE_OPTIMIZATION(t3) */ t3
SET f3 = 'mnbv' WHERE f1 > 30 AND f1 < 33 AND (t3.f1, t3.f2, t3.f3) IN
Expand All @@ -450,6 +462,31 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 eq_ref PRIMARY,f2_idx,f3_idx PRIMARY 4 test.t2.f1 1 100.00 Using where; End temporary
Warnings:
Note 1003 update /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1`) */ `test`.`t3` semi join (`test`.`t1` join `test`.`t2`) set `test`.`t3`.`f3` = 'mnbv' where `test`.`t1`.`f1` = `test`.`t2`.`f1` and `test`.`t3`.`f1` = `test`.`t2`.`f1` and `test`.`t3`.`f2` = `test`.`t2`.`f2` and `test`.`t2`.`f1` > 30 and `test`.`t2`.`f1` < 33 and `test`.`t2`.`f2` between `test`.`t2`.`f1` and `test`.`t1`.`f2` and `test`.`t2`.`f2` + 1 >= `test`.`t2`.`f1` + 1 and `test`.`t3`.`f3` = `test`.`t2`.`f3`
# Multi-table UPDATE with a derived table
EXPLAIN EXTENDED
UPDATE /*+ NO_RANGE_OPTIMIZATION(t2@dt)*/ t3,
(SELECT /*+ qb_name(dt)*/ t1.* FROM t1, t2 WHERE t1.f1 > t2.f1) AS dt
SET t3.f3 = 'mnbv' WHERE t3.f1 = dt.f1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL PRIMARY,f2_idx NULL NULL NULL 56 100.00
1 PRIMARY <derived2> ref key0 key0 5 test.t3.f1 8 100.00
2 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00
2 DERIVED t2 index f1 f1 8 NULL 28 100.00 Using where; Using index; Using join buffer (flat, BNL join)
Warnings:
Note 1003 /* select#1 */ update /*+ NO_RANGE_OPTIMIZATION(`t2`@`dt`) */ `test`.`t3` join (/* select#2 */ select /*+ QB_NAME(`dt`) */ `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`f1` > `test`.`t2`.`f1`) `dt` set `test`.`t3`.`f3` = 'mnbv' where `dt`.`f1` = `test`.`t3`.`f1`
# Multi-table UPDATE with a derived table and both table-level and
# query block-level hints
EXPLAIN EXTENDED
UPDATE /*+ NO_RANGE_OPTIMIZATION(t2@dt) NO_BNL(@dt)*/ t3,
(SELECT /*+ qb_name(dt)*/ t1.* FROM t1, t2 WHERE t1.f1 > t2.f1) AS dt
SET t3.f3 = 'mnbv' WHERE t3.f1 = dt.f1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL PRIMARY,f2_idx NULL NULL NULL 56 100.00
1 PRIMARY <derived2> ref key0 key0 5 test.t3.f1 8 100.00
2 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00
2 DERIVED t2 index f1 f1 8 NULL 28 100.00 Using where; Using index
Warnings:
Note 1003 /* select#1 */ update /*+ NO_BNL(@`dt`) NO_RANGE_OPTIMIZATION(`t2`@`dt`) */ `test`.`t3` join (/* select#2 */ select /*+ QB_NAME(`dt`) */ `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`f1` > `test`.`t2`.`f1`) `dt` set `test`.`t3`.`f3` = 'mnbv' where `dt`.`f1` = `test`.`t3`.`f1`
EXPLAIN EXTENDED DELETE FROM t3
WHERE f1 > 30 AND f1 < 33 AND (t3.f1, t3.f2, t3.f3) IN
(SELECT /*+ QB_NAME(qb1) */ t2.f1, t2.f2, t2.f3 FROM t1,t2 WHERE t1.f1=t2.f1 AND
Expand Down Expand Up @@ -500,7 +537,7 @@ Warnings:
Note 1003 (insert into `test`.`t3`(f1,f2,f3) select /*+ NO_ICP(`t5`@`select#1`) */ `test`.`t4`.`x` AS `x`,`test`.`t5`.`y` AS `y`,'filler' AS `filler` from `test`.`t4` join `test`.`t4` `t5` where `test`.`t4`.`y` = 8 and `test`.`t5`.`x` between 7 and <cache>(8 + 0))
# Turn off ICP for a particular table and a key
EXPLAIN EXTENDED INSERT INTO t3(f1, f2, f3)
(SELECT /*+ QB_NAME(qb1) NO_ICP(t5@QB1 x_idx)*/ t4.x, t5.y, 'filler' FROM t4, t4 t5
(SELECT /*+ NO_ICP(t5@QB1 x_idx) QB_NAME(qb1) */ t4.x, t5.y, 'filler' FROM t4, t4 t5
WHERE t4.y = 8 AND t5.x BETWEEN 7 AND t4.y+0);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t4 ref y_idx y_idx 5 const 1 100.00
Expand Down Expand Up @@ -550,15 +587,14 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Warning 4219 Hint QB_NAME(`qb1`) is ignored as conflicting/duplicated
Note 1003 select /*+ QB_NAME(`qb1`) */ `test`.`t2`.`f1` AS `f1`,`test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f3` AS `f3` from `test`.`t2`
# Should issue warning
EXPLAIN EXTENDED SELECT /*+ BKA(@qb1) QB_NAME(qb1) */ t2.f1, t2.f2, t2.f3 FROM t1,t2
# QB_NAME may appear after the hint, but the hint is still resolved
EXPLAIN EXTENDED SELECT /*+ NO_BNL(@qb1) QB_NAME(qb1) */ t2.f1, t2.f2, t2.f3 FROM t1,t2
WHERE t1.f1=t2.f1 AND t2.f2 BETWEEN t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1;
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
1 SIMPLE t2 ALL f1 NULL NULL NULL 28 25.00 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t2 ALL f1 NULL NULL NULL 28 25.00 Using where
Warnings:
Warning 4220 Query block name `qb1` is not found for BKA hint
Note 1003 select /*+ QB_NAME(`qb1`) */ `test`.`t2`.`f1` AS `f1`,`test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f3` AS `f3` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`f1` = `test`.`t1`.`f1` and `test`.`t2`.`f2` between `test`.`t1`.`f1` and `test`.`t1`.`f2` and `test`.`t2`.`f2` + 1 >= `test`.`t1`.`f1` + 1
Note 1003 select /*+ QB_NAME(`qb1`) NO_BNL(@`qb1`) */ `test`.`t2`.`f1` AS `f1`,`test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f3` AS `f3` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`f1` = `test`.`t1`.`f1` and `test`.`t2`.`f2` between `test`.`t1`.`f1` and `test`.`t1`.`f2` and `test`.`t2`.`f2` + 1 >= `test`.`t1`.`f1` + 1
# Should not crash
PREPARE stmt1 FROM "SELECT /*+ BKA(t2) */ t2.f1, t2.f2, t2.f3 FROM t1,t2
WHERE t1.f1=t2.f1 AND t2.f2 BETWEEN t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1";
Expand Down
26 changes: 23 additions & 3 deletions mysql-test/main/opt_hints.test
Original file line number Diff line number Diff line change
Expand Up @@ -248,12 +248,32 @@ SET f3 = 'mnbv' WHERE f1 > 30 AND f1 < 33 AND (t3.f1, t3.f2, t3.f3) IN
(SELECT /*+ BKA(t2) NO_BNL(t1) */ t2.f1, t2.f2, t2.f3 FROM t1,t2 WHERE t1.f1=t2.f1 AND
t2.f2 BETWEEN t1.f1 AND t1.f2 AND t2.f2 + 1 >= t1.f1 + 1);

--echo # Same as above but addressing tables with QB name
EXPLAIN EXTENDED
UPDATE /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY) BKA(t2@QB1) NO_BNL(t1@QB1)*/ t3
SET f3 = 'mnbv' WHERE f1 > 30 AND f1 < 33 AND (t3.f1, t3.f2, t3.f3) IN
(SELECT /*+ QB_NAME(QB1) */ t2.f1, t2.f2, t2.f3 FROM t1,t2 WHERE t1.f1=t2.f1 AND
t2.f2 BETWEEN t1.f1 AND t1.f2 AND t2.f2 + 1 >= t1.f1 + 1);

--echo # Turn off range access for all keys.
EXPLAIN EXTENDED UPDATE /*+ NO_RANGE_OPTIMIZATION(t3) */ t3
SET f3 = 'mnbv' WHERE f1 > 30 AND f1 < 33 AND (t3.f1, t3.f2, t3.f3) IN
(SELECT t2.f1, t2.f2, t2.f3 FROM t1,t2 WHERE t1.f1=t2.f1 AND
t2.f2 BETWEEN t1.f1 AND t1.f2 AND t2.f2 + 1 >= t1.f1 + 1);

--echo # Multi-table UPDATE with a derived table
EXPLAIN EXTENDED
UPDATE /*+ NO_RANGE_OPTIMIZATION(t2@dt)*/ t3,
(SELECT /*+ qb_name(dt)*/ t1.* FROM t1, t2 WHERE t1.f1 > t2.f1) AS dt
SET t3.f3 = 'mnbv' WHERE t3.f1 = dt.f1;

--echo # Multi-table UPDATE with a derived table and both table-level and
--echo # query block-level hints
EXPLAIN EXTENDED
UPDATE /*+ NO_RANGE_OPTIMIZATION(t2@dt) NO_BNL(@dt)*/ t3,
(SELECT /*+ qb_name(dt)*/ t1.* FROM t1, t2 WHERE t1.f1 > t2.f1) AS dt
SET t3.f3 = 'mnbv' WHERE t3.f1 = dt.f1;

EXPLAIN EXTENDED DELETE FROM t3
WHERE f1 > 30 AND f1 < 33 AND (t3.f1, t3.f2, t3.f3) IN
(SELECT /*+ QB_NAME(qb1) */ t2.f1, t2.f2, t2.f3 FROM t1,t2 WHERE t1.f1=t2.f1 AND
Expand Down Expand Up @@ -282,7 +302,7 @@ EXPLAIN EXTENDED INSERT INTO t3(f1, f2, f3)

--echo # Turn off ICP for a particular table and a key
EXPLAIN EXTENDED INSERT INTO t3(f1, f2, f3)
(SELECT /*+ QB_NAME(qb1) NO_ICP(t5@QB1 x_idx)*/ t4.x, t5.y, 'filler' FROM t4, t4 t5
(SELECT /*+ NO_ICP(t5@QB1 x_idx) QB_NAME(qb1) */ t4.x, t5.y, 'filler' FROM t4, t4 t5
WHERE t4.y = 8 AND t5.x BETWEEN 7 AND t4.y+0);

--echo # Make sure ICP is expected to be used when there are no hints
Expand All @@ -308,8 +328,8 @@ EXPLAIN EXTENDED REPLACE INTO t3(f1, f2, f3)

--echo # Should issue warning
EXPLAIN EXTENDED SELECT /*+ QB_NAME(qb1) QB_NAME(qb1 ) */ * FROM t2;
--echo # Should issue warning
EXPLAIN EXTENDED SELECT /*+ BKA(@qb1) QB_NAME(qb1) */ t2.f1, t2.f2, t2.f3 FROM t1,t2
--echo # QB_NAME may appear after the hint, but the hint is still resolved
EXPLAIN EXTENDED SELECT /*+ NO_BNL(@qb1) QB_NAME(qb1) */ t2.f1, t2.f2, t2.f3 FROM t1,t2
WHERE t1.f1=t2.f1 AND t2.f2 BETWEEN t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1;

--echo # Should not crash
Expand Down
177 changes: 177 additions & 0 deletions mysql-test/main/opt_hints_impl_qb_name.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
--echo # Table-level hint
explain extended select /*+ no_bnl(t2@dt)*/ * from
(select t1.* from t1, t2 where t1.a > t2.a) as dt;

--echo # QB-level hint
explain extended select /*+ no_bnl(@dt)*/ * from
(select t1.* from t1, t2 where t1.a > t2.a) as dt;

--echo # Index-level hints
--echo # Without the hint 'range' index access would be chosen
explain extended select /*+ no_index(t1@`T`)*/ * from
(select * from t1 where a < 3) t;

--echo # Without the hint 'range' index access would be chosen
explain extended select /*+ no_range_optimization(t1@t1)*/ * from
(select * from t1 where a > 100 and a < 120) as t1;

--echo # Regular and derived tables share same name but the hint is applied correctly
explain extended select /*+ index(t1@t1 idx_ab)*/ * from
(select * from t1 where a < 3) as t1;

explain extended select /*+ no_index(t1@t2 idx_a) index(t1@t1 idx_ab)*/ * from
(select * from t1 where a < 3) as t1, (select * from t1 where a < 5) as t2;

explain extended select /*+ no_index(t1@t1 idx_a, idx_ab)*/ * from
(select * from t1 where a < 3) as t1, (select * from t1 where a < 5) as t2;

--echo # Nested derived tables
explain extended select /*+ no_bnl(t1@dt2)*/ * from
(select count(*) from t1, (select * from t1 where a < 5) dt1) as dt2;

explain extended select /*+ no_index(t1@DT2)*/ * from
(select count(*) from t1, (select * from t1 where a < 5) dt1) as dt2;

--echo # Explicit QB name overrides the implicit one
explain extended select /*+ no_index(t1@dt2)*/ * from
(select count(*) from t1, (select /*+ qb_name(dt2)*/ * from t1 where a < 5) dt1) as dt2;

--echo # Both hints are applied
explain extended select /*+ no_index(t1@dt1) no_bnl(t1@dt2)*/ * from
(select count(*) from t1, (select * from t1 where a < 5) dt1) as dt2;

--echo # Nested derived tables with ambiguous names
explain extended select * from
(select count(*) from t1, (select * from t1 where a < 5) t1) as t1;

--echo # Warning on ambiguous query block name, hint is ignored

--disable_ps_protocol
# PS protocol is disabled because the warning is genererated only during
# PREPARE step of a statement. When the QB name cannot be resolved the hint
# is discarded, so it is not present during EXECUTE step. The same applies
# not only to implicit but also to explicit QB names.

explain extended select /*+ no_index(t1@t1)*/* from
(select count(*) from t1, (select * from t1 where a < 5) t1) as t1;

--echo # The hint cannot be applied to a derived table with UNION
explain extended select /*+ no_index(t2@t1)*/* from
(select * from t1 where a < 3 union select * from t2 where a < 9) as t1;

explain extended select /*+ no_index(t1@t1)*/* from
(select * from t1 where a < 3 union select * from t2 where a < 9) as t1;

--echo # Test INSERT..SELECT
explain extended insert into t2 select /*+ no_bnl(t2@dt)*/ * from
(select t1.* from t1, t2 where t1.a > t2.a) as dt;

--echo # MERGE/NO_MERGE hints are resolved early and so do not support
--echo # implicit QB names. Warning is expected
explain extended select /*+ no_merge(@dt)*/ * from
(select * from (select t1.* from t1, t2 where t1.a > t2.a) as dt1) as dt;

--enable_ps_protocol

--echo # ======================================
--echo # Test CTEs
--echo # By default BNL and index access to t1 is used.
explain extended
with cte as (select count(*) from t1, (select * from t1 where a < 5) dt1)
select * from cte;

explain extended
with cte as (select count(*) from t1, (select * from t1 where a < 5) dt1)
select /*+ no_bnl(t1@cte)*/ * from cte;

explain extended
with cte as (select count(*) from t1, (select * from t1 where a < 5) dt1)
select /*+ no_bnl(@cte)*/ * from cte;

explain extended
with cte as (select count(*) from t1, (select * from t1 where a < 5) dt1)
select /*+ no_index(t1@cte)*/ * from cte;

explain extended
with cte as (select count(*) from t1, (select * from t1 where a < 5) dt1)
select /*+ no_index(t1@cte) no_index(t1@dt1)*/ * from cte;

explain extended
with cte as (select count(*) from t1, (select * from t1 where a < 5) dt1)
select /*+ no_index(t1@dt1 idx_a) no_bnl(@cte)*/ * from cte;

--echo # Ambiguity: multiple occurencies of `cte`, the hint is ignored

--disable_ps_protocol
# See the comment above for why PS protocol is disabled

explain extended
with cte as (select count(*) as cnt from t1, (select * from t1 where a < 5) dt1)
select /*+ no_bnl(@cte)*/ * from cte where cnt > 10
union
select * from cte where cnt < 100;

--echo # However, if CTE occurencies have different aliases, the hint can be applied
explain extended
with cte as (select count(*) as cnt from t1, (select * from t1 where a < 5) dt1)
select /*+ no_index(t1@cte1)*/ * from cte as cte1 where cnt > 10
union
select * from cte where cnt < 100;

--enable_ps_protocol

--echo # ======================================
--echo # Test views
create view v1 as select * from t1 where a < 100;

--echo # Default execution plan
explain extended select *
from v1, v1 as v2 where v1.a = v2.a and v1.a < 3;

explain extended
select /*+ index(t1@`v1` idx_ab) no_index(t1@`v2`)*/ *
from v1, v1 as v2 where v1.a = v2.a and v1.a < 3;

--echo # Nested views
create view v2 as select * from v1 where a < 300;

--echo # Default execution plan
explain extended select * from v2;

--echo # Addressing an object inside a nested view
explain extended select /*+ index(t1@`v1` idx_ab)*/ * from v2;

create view v3 as select * from t1 union select * from t2;

--echo # Unable to apply the hint to a table with UNION

--disable_ps_protocol
# See the comment above for why PS protocol is disabled

explain extended select /*+ no_index(t1@v3) */ * from v3;

--echo # Ambiguity: view `v1` appears two times - should warn and ignore hint
explain extended select /*+ index(t2@v1) */ * from v1,
(select a from v1 where b > 5) dt;

--enable_ps_protocol

--echo # Implicit QB names are not supported inside views
create view v4 as select /*+ no_bnl(t2@dt)*/ * from
(select t1.* from t1, t2 where t1.a > t2.a) as dt;

show create view v4;

--echo # However, a derived table inside a view can be addressed from outer query
create view v5 as select dt.a from
t1, (select t1.* from t1, t2 where t1.a > t2.a) as dt where t1.a=dt.a;

--echo # Addressing a single table
explain extended select /*+ no_bnl(t2@dt) */* from v5;
--echo # Addressing the whole derived table
explain extended select /*+ no_bnl(@dt) */* from v5;

--echo # Derived tables inside views can be addressed by their aliases
explain extended select /*+ no_bnl(t2@dt) */ * from v4;

drop view v1, v2, v3, v4, v5;
Loading