Commit 5a9fff80 authored by Oleg Smirnov's avatar Oleg Smirnov

MDEV-33281 Fix code review comments

parent 189c8eb9
...@@ -208,3 +208,30 @@ DROP PACKAGE test.pkg; ...@@ -208,3 +208,30 @@ DROP PACKAGE test.pkg;
# #
# End of 11.4 tests # End of 11.4 tests
# #
#
# Start of 11.7 tests
#
#
# MDEV-33281 Implement optimizer hints like in MySQL
#
SET NAMES utf8mb4;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1), (2);
SELECT /*+BKA(a) BKA(å)*/ a.a FROM t1 a, t1 å;
a
1
2
1
2
SELECT a.a, A.a FROM t1 a, t1 A;
ERROR 42000: Not unique table/alias: 'A'
SELECT /*+BKA(a) BKA(A)*/ a.a FROM t1 a;
a
1
2
Warnings:
Warning 4202 Hint BKA("A") is ignored as conflicting/duplicated
DROP TABLE t1;
#
# End of 11.7 tests
#
...@@ -205,3 +205,33 @@ DROP PACKAGE test.pkg; ...@@ -205,3 +205,33 @@ DROP PACKAGE test.pkg;
--echo # --echo #
--echo # End of 11.4 tests --echo # End of 11.4 tests
--echo # --echo #
--echo #
--echo # Start of 11.7 tests
--echo #
--echo #
--echo # MDEV-33281 Implement optimizer hints like in MySQL
--echo #
SET NAMES utf8mb4;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1), (2);
# Test that aliases are accent sensitive with lowercase-table-names=1
# Test that table names in hints are also accent sensitive
SELECT /*+BKA(a) BKA(å)*/ a.a FROM t1 a, t1 å;
# Test that aliases are case insensitive with lowercase-table-names=1
--error ER_NONUNIQ_TABLE
SELECT a.a, A.a FROM t1 a, t1 A;
# Test that table names in hints are also case insensitive
SELECT /*+BKA(a) BKA(A)*/ a.a FROM t1 a;
DROP TABLE t1;
--echo #
--echo # End of 11.7 tests
--echo #
...@@ -189,3 +189,28 @@ DROP DATABASE MYSQL; ...@@ -189,3 +189,28 @@ DROP DATABASE MYSQL;
# #
# End of 10.5 tests # End of 10.5 tests
# #
#
# Start of 11.7 tests
#
#
# MDEV-33281 Implement optimizer hints like in MySQL
#
SET NAMES utf8mb4;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1), (2);
SELECT /*+BKA(a) BKA(å)*/ a.a, å.a FROM t1 a, t1 å;
a a
1 1
2 1
1 2
2 2
SELECT /*+BKA(a) BKA(A)*/ a.a, A.a FROM t1 a, t1 A;
a a
1 1
2 1
1 2
2 2
DROP TABLE t1;
#
# End of 11.7 tests
#
...@@ -187,3 +187,30 @@ DROP DATABASE MYSQL; ...@@ -187,3 +187,30 @@ DROP DATABASE MYSQL;
--echo # --echo #
--echo # End of 10.5 tests --echo # End of 10.5 tests
--echo # --echo #
--echo #
--echo # Start of 11.7 tests
--echo #
--echo #
--echo # MDEV-33281 Implement optimizer hints like in MySQL
--echo #
SET NAMES utf8mb4;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1), (2);
# Test that table aliases are accent sensitive with lowercase-table-names=0
# Test that table names in hints are also accent sensitive
SELECT /*+BKA(a) BKA(å)*/ a.a, å.a FROM t1 a, t1 å;
# Test that table aliases are case sensitive with lowercase-table-names=0
# Test that table names in hints are also case sensitive
SELECT /*+BKA(a) BKA(A)*/ a.a, A.a FROM t1 a, t1 A;
DROP TABLE t1;
--echo #
--echo # End of 11.7 tests
--echo #
# WL#8017 Infrastructure for Optimizer Hints SET NAMES utf8mb4;
# Testing that index names in hints are accent sensitive case insensitive
CREATE TABLE t1 (a INT, ä INT, INDEX idx_a(a), INDEX idx_ä(ä));
INSERT INTO t1 VALUES (1,1),(2,2);
SELECT /*+ NO_MRR(t1 idx_a) */ a FROM t1;
a
1
2
SELECT /*+ NO_MRR(t1 idx_A) */ a FROM t1;
a
1
2
SELECT /*+ NO_MRR(t1 idx_å) */ a FROM t1;
a
1
2
Warnings:
Warning 4205 Unresolved index name `t1`@`select#1` `idx_å` for NO_MRR hint
SELECT /*+ NO_MRR(t1 idx_a, idx_å, idx_A) */ a FROM t1;
a
1
2
Warnings:
Warning 4202 Hint NO_MRR(`t1` `idx_A`) is ignored as conflicting/duplicated
Warning 4205 Unresolved index name `t1`@`select#1` `idx_å` for NO_MRR hint
DROP TABLE t1;
# Testing that query block names are accent sensitive case insensitive
CREATE TABLE t1 (a INT);
SELECT /*+ QB_NAME(a) BKA(t1@a) BKA(t1@A) */ * FROM t1;
a
Warnings:
Warning 4202 Hint BKA(`t1`@`A`) is ignored as conflicting/duplicated
SELECT /*+ QB_NAME(a) BKA(t1@a) BKA(t1@å) */ * FROM t1;
a
Warnings:
Warning 4203 Query block name `å` is not found for BKA hint
DROP TABLE t1;
CREATE TABLE t1(f1 INT, f2 INT); CREATE TABLE t1(f1 INT, f2 INT);
INSERT INTO t1 VALUES INSERT INTO t1 VALUES
(1,1),(2,2),(3,3); (1,1),(2,2),(3,3);
...@@ -77,32 +113,78 @@ Warnings: ...@@ -77,32 +113,78 @@ Warnings:
Note 1003 select `test`.`t3`.`f1` AS `f1` from `test`.`t3` where `test`.`t3`.`f1` > 30 and `test`.`t3`.`f1` < 33 Note 1003 select `test`.`t3`.`f1` AS `f1` from `test`.`t3` where `test`.`t3`.`f1` > 30 and `test`.`t3`.`f1` < 33
# Turn off range access for PRIMARY key # Turn off range access for PRIMARY key
# Should use range access by f2_idx key # Should use range access by f2_idx key
EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY) */ f1 FROM t3 WHERE f1 > 30 AND f1 < 33; EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY) */ f1
FROM t3 WHERE f1 > 30 AND f1 < 33;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t3 range PRIMARY,f2_idx f2_idx 4 NULL 2 100.00 Using where; Using index 1 SIMPLE t3 range PRIMARY,f2_idx f2_idx 4 NULL 2 100.00 Using where; Using index
Warnings: Warnings:
Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ `test`.`t3`.`f1` AS `f1` from `test`.`t3` where `test`.`t3`.`f1` > 30 and `test`.`t3`.`f1` < 33 Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ `test`.`t3`.`f1` AS `f1` from `test`.`t3` where `test`.`t3`.`f1` > 30 and `test`.`t3`.`f1` < 33
# Turn off range access for PRIMARY & f2_idx keys # Turn off range access for PRIMARY & f2_idx keys
# Should use index access # Should use index access
EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY, f2_idx) */ f1 FROM t3 WHERE f1 > 30 AND f1 < 33; EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY, f2_idx) */ f1
FROM t3 WHERE f1 > 30 AND f1 < 33;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t3 index PRIMARY,f2_idx PRIMARY 4 NULL 56 4.11 Using where; Using index 1 SIMPLE t3 index PRIMARY,f2_idx PRIMARY 4 NULL 56 4.11 Using where; Using index
Warnings: Warnings:
Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) NO_RANGE_OPTIMIZATION(`t3`@`select#1` `f2_idx`) */ `test`.`t3`.`f1` AS `f1` from `test`.`t3` where `test`.`t3`.`f1` > 30 and `test`.`t3`.`f1` < 33 Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) NO_RANGE_OPTIMIZATION(`t3`@`select#1` `f2_idx`) */ `test`.`t3`.`f1` AS `f1` from `test`.`t3` where `test`.`t3`.`f1` > 30 and `test`.`t3`.`f1` < 33
# Turn off range access for all keys # Turn off range access for all keys
# Should use index access # Should use index access
EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(t3) */ f1 FROM t3 WHERE f1 > 30 AND f1 < 33; EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(t3) */ f1
FROM t3 WHERE f1 > 30 AND f1 < 33;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t3 index PRIMARY,f2_idx PRIMARY 4 NULL 56 4.11 Using where; Using index 1 SIMPLE t3 index PRIMARY,f2_idx PRIMARY 4 NULL 56 4.11 Using where; Using index
Warnings: Warnings:
Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1`) */ `test`.`t3`.`f1` AS `f1` from `test`.`t3` where `test`.`t3`.`f1` > 30 and `test`.`t3`.`f1` < 33 Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1`) */ `test`.`t3`.`f1` AS `f1` from `test`.`t3` where `test`.`t3`.`f1` > 30 and `test`.`t3`.`f1` < 33
# Turn off range access for PRIMARY & f2_idx keys # Turn off range access for PRIMARY & f2_idx keys
# Should use index access # Should use index access
EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY) NO_RANGE_OPTIMIZATION(t3 f2_idx) */ f1 FROM t3 WHERE f1 > 30 AND f1 < 33; EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY) NO_RANGE_OPTIMIZATION(t3 f2_idx) */ f1
FROM t3 WHERE f1 > 30 AND f1 < 33;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t3 index PRIMARY,f2_idx PRIMARY 4 NULL 56 4.11 Using where; Using index 1 SIMPLE t3 index PRIMARY,f2_idx PRIMARY 4 NULL 56 4.11 Using where; Using index
Warnings: Warnings:
Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) NO_RANGE_OPTIMIZATION(`t3`@`select#1` `f2_idx`) */ `test`.`t3`.`f1` AS `f1` from `test`.`t3` where `test`.`t3`.`f1` > 30 and `test`.`t3`.`f1` < 33 Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) NO_RANGE_OPTIMIZATION(`t3`@`select#1` `f2_idx`) */ `test`.`t3`.`f1` AS `f1` from `test`.`t3` where `test`.`t3`.`f1` > 30 and `test`.`t3`.`f1` < 33
# Create a clone of t3 with cyrillic names
CREATE TABLE таблица (f1 INT NOT NULL, поле2 INT, поле3 VARCHAR(32),
PRIMARY KEY(f1), KEY f2_индекс(f1), KEY f3_индекс(поле3))
AS SELECT * FROM t3;
ANALYZE TABLE таблица;
Table Op Msg_type Msg_text
test.таблица analyze status Engine-independent statistics collected
test.таблица analyze status Table is already up to date
# Turn off range access for PRIMARY key
# Should use range access by f2_индекс key
EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(таблица PRIMARY) */ f1
FROM таблица WHERE f1 > 30 AND f1 < 33;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE таблица range PRIMARY,f2_индекс f2_индекс 4 NULL 2 100.00 Using where; Using index
Warnings:
Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`таблица`@`select#1` `PRIMARY`) */ `test`.`таблица`.`f1` AS `f1` from `test`.`таблица` where `test`.`таблица`.`f1` > 30 and `test`.`таблица`.`f1` < 33
# Turn off range access for PRIMARY & f2_индекс keys
# Should use index access
EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(таблица PRIMARY, f2_индекс) */ f1
FROM таблица WHERE f1 > 30 AND f1 < 33;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE таблица index PRIMARY,f2_индекс PRIMARY 4 NULL 56 4.11 Using where; Using index
Warnings:
Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`таблица`@`select#1` `PRIMARY`) NO_RANGE_OPTIMIZATION(`таблица`@`select#1` `f2_индекс`) */ `test`.`таблица`.`f1` AS `f1` from `test`.`таблица` where `test`.`таблица`.`f1` > 30 and `test`.`таблица`.`f1` < 33
# Turn off range access for all keys
# Should use index access
EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(таблица) */ f1
FROM таблица WHERE f1 > 30 AND f1 < 33;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE таблица index PRIMARY,f2_индекс PRIMARY 4 NULL 56 4.11 Using where; Using index
Warnings:
Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`таблица`@`select#1`) */ `test`.`таблица`.`f1` AS `f1` from `test`.`таблица` where `test`.`таблица`.`f1` > 30 and `test`.`таблица`.`f1` < 33
# Turn off range access for PRIMARY & f2_индекс keys
# Should use index access
EXPLAIN EXTENDED
SELECT /*+ NO_RANGE_OPTIMIZATION(таблица PRIMARY) NO_RANGE_OPTIMIZATION(таблица f2_индекс) */ f1
FROM таблица WHERE f1 > 30 AND f1 < 33;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE таблица index PRIMARY,f2_индекс PRIMARY 4 NULL 56 4.11 Using where; Using index
Warnings:
Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`таблица`@`select#1` `PRIMARY`) NO_RANGE_OPTIMIZATION(`таблица`@`select#1` `f2_индекс`) */ `test`.`таблица`.`f1` AS `f1` from `test`.`таблица` where `test`.`таблица`.`f1` > 30 and `test`.`таблица`.`f1` < 33
DROP TABLE таблица;
# NO_ICP hint testing # NO_ICP hint testing
set optimizer_switch='index_condition_pushdown=on'; set optimizer_switch='index_condition_pushdown=on';
CREATE TABLE t4 (x INT, y INT, KEY x_idx(x), KEY y_idx(y)); CREATE TABLE t4 (x INT, y INT, KEY x_idx(x), KEY y_idx(y));
...@@ -131,6 +213,15 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -131,6 +213,15 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t5 range x_idx x_idx 5 NULL 2 100.00 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t5 range x_idx x_idx 5 NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
Warnings: Warnings:
Note 1003 select /*+ NO_ICP(`t5`@`QB1` `x_idx`) */ `test`.`t4`.`x` AS `x`,`test`.`t5`.`y` AS `y` from `test`.`t4` join `test`.`t4` `t5` where `test`.`t4`.`y` = 8 and `test`.`t5`.`x` between 7 and <cache>(8 + 0) Note 1003 select /*+ NO_ICP(`t5`@`QB1` `x_idx`) */ `test`.`t4`.`x` AS `x`,`test`.`t5`.`y` AS `y` from `test`.`t4` join `test`.`t4` `t5` where `test`.`t4`.`y` = 8 and `test`.`t5`.`x` between 7 and <cache>(8 + 0)
# Cyrillic query block name
EXPLAIN EXTENDED SELECT /*+ NO_ICP(t5@блок1 x_idx) */ * FROM
(SELECT /*+ QB_NAME(блок1) */ t4.x, t5.y FROM t4, t4 t5
WHERE t4.y = 8 AND t5.x BETWEEN 7 AND t4.y+0) AS TD;
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
1 SIMPLE t5 range x_idx x_idx 5 NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1003 select /*+ NO_ICP(`t5`@`блок1` `x_idx`) */ `test`.`t4`.`x` AS `x`,`test`.`t5`.`y` AS `y` from `test`.`t4` join `test`.`t4` `t5` where `test`.`t4`.`y` = 8 and `test`.`t5`.`x` between 7 and <cache>(8 + 0)
# Expected warning for z_idx key, unresolved name. # Expected warning for z_idx key, unresolved name.
EXPLAIN EXTENDED SELECT * FROM EXPLAIN EXTENDED SELECT * FROM
(SELECT /*+ NO_ICP(t5 y_idx, x_idx, z_idx) */ t4.x, t5.y FROM t4, t4 t5 (SELECT /*+ NO_ICP(t5 y_idx, x_idx, z_idx) */ t4.x, t5.y FROM t4, t4 t5
...@@ -299,7 +390,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -299,7 +390,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t13 hash_ALL a #hash#a 5 test.t12.a 1000 0.10 Using where; Using join buffer (flat, BNLH join) 1 SIMPLE t13 hash_ALL a #hash#a 5 test.t12.a 1000 0.10 Using where; Using join buffer (flat, BNLH join)
Warnings: Warnings:
Note 1003 select /*+ QB_NAME(`QB1`) NO_BKA(`t13`@`QB1`) */ `test`.`t12`.`a` AS `a`,`test`.`t12`.`b` AS `b`,`test`.`t13`.`a` AS `a`,`test`.`t13`.`b` AS `b`,`test`.`t13`.`c` AS `c`,`test`.`t13`.`filler` AS `filler` from `test`.`t12` join `test`.`t13` where `test`.`t13`.`a` = `test`.`t12`.`a` and `test`.`t13`.`b` + 1 <= `test`.`t13`.`b` + 1 Note 1003 select /*+ QB_NAME(`QB1`) NO_BKA(`t13`@`QB1`) */ `test`.`t12`.`a` AS `a`,`test`.`t12`.`b` AS `b`,`test`.`t13`.`a` AS `a`,`test`.`t13`.`b` AS `b`,`test`.`t13`.`c` AS `c`,`test`.`t13`.`filler` AS `filler` from `test`.`t12` join `test`.`t13` where `test`.`t13`.`a` = `test`.`t12`.`a` and `test`.`t13`.`b` + 1 <= `test`.`t13`.`b` + 1
# UPDATE|DELETE|INSERT hint testing # UPDATE|DELETE|INSERT|REPLACE hint testing
EXPLAIN EXTENDED UPDATE t3 EXPLAIN EXTENDED UPDATE t3
SET f3 = 'mnbv' WHERE f1 > 30 AND f1 < 33 AND (t3.f1, t3.f2, t3.f3) IN 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 (SELECT t2.f1, t2.f2, t2.f3 FROM t1,t2 WHERE t1.f1=t2.f1 AND
...@@ -390,13 +481,48 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -390,13 +481,48 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t5 range x_idx x_idx 5 NULL 2 100.00 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t5 range x_idx x_idx 5 NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
Warnings: Warnings:
Note 1003 (insert into `test`.`t3`(f1,f2,f3) select /*+ QB_NAME(`qb1`) NO_ICP(`t5`@`qb1` `x_idx`) */ `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)) Note 1003 (insert into `test`.`t3`(f1,f2,f3) select /*+ QB_NAME(`qb1`) NO_ICP(`t5`@`qb1` `x_idx`) */ `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))
# Make sure ICP is expected to be used when there are no hints
EXPLAIN EXTENDED REPLACE INTO t3(f1, f2, f3)
(SELECT 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
1 SIMPLE t5 range x_idx x_idx 5 NULL 2 100.00 Using index condition; Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1003 (replace into `test`.`t3`(f1,f2,f3) select `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. ICP should not be used.
EXPLAIN EXTENDED REPLACE INTO t3(f1, f2, f3)
(SELECT /*+ NO_ICP(t5) */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
1 SIMPLE t5 range x_idx x_idx 5 NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1003 (replace into `test`.`t3`(f1,f2,f3) select /*+ NO_ICP(`t5`@`select#2`) */ `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
EXPLAIN EXTENDED REPLACE /*+ NO_ICP(t5@QB1) */ INTO t3(f1, f2, f3)
(SELECT /*+ 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
1 SIMPLE t5 range x_idx x_idx 5 NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1003 (replace into `test`.`t3`(f1,f2,f3) select /*+ QB_NAME(`qb1`) NO_ICP(`t5`@`qb1`) */ `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 REPLACE /*+ NO_ICP(t5@QB1 x_idx) */ INTO t3(f1, f2, f3)
(SELECT /*+ 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
1 SIMPLE t5 range x_idx x_idx 5 NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1003 (replace into `test`.`t3`(f1,f2,f3) select /*+ QB_NAME(`qb1`) NO_ICP(`t5`@`qb1` `x_idx`) */ `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))
# Misc tests # Misc tests
# Should issue warning # Should issue warning
EXPLAIN EXTENDED SELECT /*+ QB_NAME(qb1) QB_NAME(qb1 ) */ * FROM t2; EXPLAIN EXTENDED SELECT /*+ QB_NAME(qb1) QB_NAME(qb1 ) */ * FROM t2;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 28 100.00 1 SIMPLE t2 ALL NULL NULL NULL NULL 28 100.00
Warnings: Warnings:
Warning 4197 Hint QB_NAME(`qb1`) is ignored as conflicting/duplicated Warning 4202 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` 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 # Should issue warning
EXPLAIN EXTENDED SELECT /*+ BKA(@qb1) QB_NAME(qb1) */ t2.f1, t2.f2, t2.f3 FROM t1,t2 EXPLAIN EXTENDED SELECT /*+ BKA(@qb1) QB_NAME(qb1) */ t2.f1, t2.f2, t2.f3 FROM t1,t2
...@@ -462,7 +588,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -462,7 +588,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings: Warnings:
Warning 1064 Optimizer hint syntax error near 't3@qb1) */ f2 FROM Warning 1064 Optimizer hint syntax error near 't3@qb1) */ f2 FROM
(SELECT /*+ QB_NAME(qb1) */ f2, f3, f1 FROM t3 WHERE f1 > ...' at line 1 (SELECT /*+ QB_NAME(qb1) */ f2, f3, f1 FROM t3 WHERE f1 > ...' at line 1
Note 1003 select `test`.`t3`.`f2` AS `f2` from `test`.`t3` where `test`.`t3`.`f3` = 'poiu' and `test`.`t3`.`f1` > 2 and `test`.`t3`.`f1` > 2 Note 1003 select `test`.`t3`.`f2` AS `f2` from `test`.`t3` where `test`.`t3`.`f1` > 2 and `test`.`t3`.`f3` = 'poiu' and `test`.`t3`.`f1` > 2
# Check illegal syntax # Check illegal syntax
EXPLAIN EXTENDED SELECT * FROM EXPLAIN EXTENDED SELECT * FROM
(SELECT /*+ QB_NAME(qb1) BKA(@qb1 t1@qb1, t2@qb1, t3) */ t2.f1, t2.f2, t2.f3 FROM t1,t2,t3) tt; (SELECT /*+ QB_NAME(qb1) BKA(@qb1 t1@qb1, t2@qb1, t3) */ t2.f1, t2.f2, t2.f3 FROM t1,t2,t3) tt;
...@@ -471,7 +597,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -471,7 +597,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 28 100.00 Using join buffer (flat, BNL join) 1 SIMPLE t2 ALL NULL NULL NULL NULL 28 100.00 Using join buffer (flat, BNL join)
1 SIMPLE t3 index NULL PRIMARY 4 NULL 56 100.00 Using index; Using join buffer (incremental, BNL join) 1 SIMPLE t3 index NULL PRIMARY 4 NULL 56 100.00 Using index; Using join buffer (incremental, BNL join)
Warnings: Warnings:
Warning 1064 Optimizer hint syntax error near 'qb1, t2@qb1, t3) */ t2.f1, t2.f2, t2.f3 FROM t1,t2,t3) tt' at line 2 Warning 1064 Optimizer hint syntax error near '@qb1, t2@qb1, t3) */ t2.f1, t2.f2, t2.f3 FROM t1,t2,t3) tt' at line 2
Note 1003 select `test`.`t2`.`f1` AS `f1`,`test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f3` AS `f3` from `test`.`t1` join `test`.`t2` join `test`.`t3` Note 1003 select `test`.`t2`.`f1` AS `f1`,`test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f3` AS `f3` from `test`.`t1` join `test`.`t2` join `test`.`t3`
# Check '@qb_name table_name' syntax # Check '@qb_name table_name' syntax
EXPLAIN EXTENDED SELECT /*+ BKA(@qb1 t13) */ * FROM (SELECT /*+ QB_NAME(QB1) */ t12.a, t13.b FROM t12, t13 EXPLAIN EXTENDED SELECT /*+ BKA(@qb1 t13) */ * FROM (SELECT /*+ QB_NAME(QB1) */ t12.a, t13.b FROM t12, t13
...@@ -831,7 +957,7 @@ CREATE PROCEDURE p() SELECT /*+ NO_MRR(t1) */ * FROM t1 WHERE f2 <= 3 AND 3 <= f ...@@ -831,7 +957,7 @@ CREATE PROCEDURE p() SELECT /*+ NO_MRR(t1) */ * FROM t1 WHERE f2 <= 3 AND 3 <= f
SHOW CREATE PROCEDURE p; SHOW CREATE PROCEDURE p;
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
p STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p`() p STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p`()
SELECT /*+ NO_MRR(t1) */ * FROM t1 WHERE f2 <= 3 AND 3 <= f3 latin1 latin1_swedish_ci latin1_swedish_ci SELECT /*+ NO_MRR(t1) */ * FROM t1 WHERE f2 <= 3 AND 3 <= f3 utf8mb4 utf8mb4_uca1400_ai_ci utf8mb4_uca1400_ai_ci
FLUSH STATUS; FLUSH STATUS;
CALL p(); CALL p();
f1 f2 f3 f1 f2 f3
...@@ -1059,7 +1185,6 @@ Warning 1064 Optimizer hint syntax error near ') */ 1 UNION SELECT 1' at line 1 ...@@ -1059,7 +1185,6 @@ Warning 1064 Optimizer hint syntax error near ') */ 1 UNION SELECT 1' at line 1
1 1
Warnings: Warnings:
Warning 1064 Optimizer hint syntax error near ') */ 1) UNION (SELECT 1)' at line 1 Warning 1064 Optimizer hint syntax error near ') */ 1) UNION (SELECT 1)' at line 1
# OLEGS: this one does not issue a warning although should:
((SELECT /* + NO_ICP() */ 1)); ((SELECT /* + NO_ICP() */ 1));
1 1
1 1
...@@ -1099,7 +1224,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -1099,7 +1224,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used 2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 /* select#1 */ select /*+ QB_NAME(`qb1`) */ 1 AS `1` union /* select#2 */ select 1 AS `1` Note 1003 /* select#1 */ select /*+ QB_NAME(`qb1`) */ 1 AS `1` union /* select#2 */ select /*+ QB_NAME(`qb2`) */ 1 AS `1`
EXPLAIN EXTENDED (SELECT /*+ QB_NAME(qb1) */ 1) UNION (SELECT /*+ QB_NAME(qb2) */ 1); EXPLAIN EXTENDED (SELECT /*+ QB_NAME(qb1) */ 1) UNION (SELECT /*+ QB_NAME(qb2) */ 1);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
...@@ -1152,39 +1277,39 @@ CREATE TABLE ` quoted name test` (i INT); ...@@ -1152,39 +1277,39 @@ CREATE TABLE ` quoted name test` (i INT);
SELECT /*+ BKA(` quoted name test`) */ 1 FROM t1; SELECT /*+ BKA(` quoted name test`) */ 1 FROM t1;
1 1
Warnings: Warnings:
Warning 4199 Unresolved name ` quoted name test`@`select#1` for BKA hint Warning 4204 Unresolved table name ` quoted name test`@`select#1` for BKA hint
SELECT /*+ BKA(` quoted name test`@`select#1`) */ 1 FROM t1; SELECT /*+ BKA(` quoted name test`@`select#1`) */ 1 FROM t1;
1 1
Warnings: Warnings:
Warning 4198 Query block name `select#1` is not found for BKA hint Warning 4203 Query block name `select#1` is not found for BKA hint
DROP TABLE ` quoted name test`; DROP TABLE ` quoted name test`;
SET SQL_MODE = 'ANSI_QUOTES'; SET SQL_MODE = 'ANSI_QUOTES';
CREATE TABLE " quoted name test" (i INT); CREATE TABLE " quoted name test" (i INT);
SELECT /*+ BKA(" quoted name test") */ 1 FROM t1; SELECT /*+ BKA(" quoted name test") */ 1 FROM t1;
1 1
Warnings: Warnings:
Warning 4199 Unresolved name " quoted name test"@"select#1" for BKA hint Warning 4204 Unresolved table name " quoted name test"@"select#1" for BKA hint
SELECT /*+ BKA(" quoted name test"@"select#1") */ 1 FROM t1; SELECT /*+ BKA(" quoted name test"@"select#1") */ 1 FROM t1;
1 1
Warnings: Warnings:
Warning 4198 Query block name "select#1" is not found for BKA hint Warning 4203 Query block name "select#1" is not found for BKA hint
CREATE TABLE `test1``test2``` (i INT); CREATE TABLE `test1``test2``` (i INT);
SELECT /*+ BKA(`test1``test2```) */ 1; SELECT /*+ BKA(`test1``test2```) */ 1;
1 1
1 1
Warnings: Warnings:
Warning 4199 Unresolved name "test1`test2`"@"select#1" for BKA hint Warning 4204 Unresolved table name "test1`test2`"@"select#1" for BKA hint
SELECT /*+ BKA("test1""test2""") */ 1; SELECT /*+ BKA("test1""test2""") */ 1;
1 1
1 1
Warnings: Warnings:
Warning 4199 Unresolved name "test1""test2"""@"select#1" for BKA hint Warning 4204 Unresolved table name "test1""test2"""@"select#1" for BKA hint
SET SQL_MODE = ''; SET SQL_MODE = '';
# should warn: # should warn:
SELECT /*+ BKA(" quoted name test") */ 1 FROM t1; SELECT /*+ BKA(" quoted name test") */ 1 FROM t1;
1 1
Warnings: Warnings:
Warning 4204 Unresolved table name `" quoted name test"`@`select#1` for BKA hint Warning 4204 Unresolved table name ` quoted name test`@`select#1` for BKA hint
DROP TABLE ` quoted name test`; DROP TABLE ` quoted name test`;
DROP TABLE `test1``test2```; DROP TABLE `test1``test2```;
# Valid hints, no warning: # Valid hints, no warning:
...@@ -1238,7 +1363,7 @@ CREATE TABLE таблица (i INT); ...@@ -1238,7 +1363,7 @@ CREATE TABLE таблица (i INT);
SELECT /*+ BKA(`таблица`) */ 1 FROM t1; SELECT /*+ BKA(`таблица`) */ 1 FROM t1;
1 1
Warnings: Warnings:
Warning 4199 Unresolved name `таблица`@`select#1` for BKA hint Warning 4204 Unresolved table name `таблица`@`select#1` for BKA hint
SELECT /*+ BKA(таблица) */ 1 FROM t1; SELECT /*+ BKA(таблица) */ 1 FROM t1;
1 1
Warnings: Warnings:
...@@ -1250,7 +1375,7 @@ Warning 4203 Query block name `таблица` is not found for BKA hint ...@@ -1250,7 +1375,7 @@ Warning 4203 Query block name `таблица` is not found for BKA hint
SELECT /*+ NO_ICP(`\D1`) */ 1 FROM t1; SELECT /*+ NO_ICP(`\D1`) */ 1 FROM t1;
1 1
Warnings: Warnings:
Warning 4199 Unresolved name `\D1`@`select#1` for NO_ICP hint Warning 4204 Unresolved table name `\D1`@`select#1` for NO_ICP hint
DROP TABLE таблица; DROP TABLE таблица;
# derived tables and other subqueries: # derived tables and other subqueries:
......
--echo # WL#8017 Infrastructure for Optimizer Hints
--enable_prepare_warnings --enable_prepare_warnings
SET NAMES utf8mb4;
--echo # Testing that index names in hints are accent sensitive case insensitive
CREATE TABLE t1 (a INT, ä INT, INDEX idx_a(a), INDEX idx_ä(ä));
INSERT INTO t1 VALUES (1,1),(2,2);
SELECT /*+ NO_MRR(t1 idx_a) */ a FROM t1;
SELECT /*+ NO_MRR(t1 idx_A) */ a FROM t1;
SELECT /*+ NO_MRR(t1 idx_å) */ a FROM t1;
SELECT /*+ NO_MRR(t1 idx_a, idx_å, idx_A) */ a FROM t1;
DROP TABLE t1;
--echo # Testing that query block names are accent sensitive case insensitive
CREATE TABLE t1 (a INT);
SELECT /*+ QB_NAME(a) BKA(t1@a) BKA(t1@A) */ * FROM t1;
SELECT /*+ QB_NAME(a) BKA(t1@a) BKA(t1@å) */ * FROM t1;
DROP TABLE t1;
CREATE TABLE t1(f1 INT, f2 INT); CREATE TABLE t1(f1 INT, f2 INT);
INSERT INTO t1 VALUES INSERT INTO t1 VALUES
(1,1),(2,2),(3,3); (1,1),(2,2),(3,3);
...@@ -31,7 +47,6 @@ ANALYZE TABLE t1; ...@@ -31,7 +47,6 @@ ANALYZE TABLE t1;
ANALYZE TABLE t2; ANALYZE TABLE t2;
ANALYZE TABLE t3; ANALYZE TABLE t3;
--echo # NO_RANGE_OPTIMIZATION hint testing --echo # NO_RANGE_OPTIMIZATION hint testing
set optimizer_switch=default; set optimizer_switch=default;
...@@ -50,16 +65,44 @@ SHOW STATUS LIKE 'handler_read%'; ...@@ -50,16 +65,44 @@ SHOW STATUS LIKE 'handler_read%';
EXPLAIN EXTENDED SELECT f1 FROM t3 WHERE f1 > 30 AND f1 < 33; EXPLAIN EXTENDED SELECT f1 FROM t3 WHERE f1 > 30 AND f1 < 33;
--echo # Turn off range access for PRIMARY key --echo # Turn off range access for PRIMARY key
--echo # Should use range access by f2_idx key --echo # Should use range access by f2_idx key
EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY) */ f1 FROM t3 WHERE f1 > 30 AND f1 < 33; EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY) */ f1
FROM t3 WHERE f1 > 30 AND f1 < 33;
--echo # Turn off range access for PRIMARY & f2_idx keys --echo # Turn off range access for PRIMARY & f2_idx keys
--echo # Should use index access --echo # Should use index access
EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY, f2_idx) */ f1 FROM t3 WHERE f1 > 30 AND f1 < 33; EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY, f2_idx) */ f1
FROM t3 WHERE f1 > 30 AND f1 < 33;
--echo # Turn off range access for all keys --echo # Turn off range access for all keys
--echo # Should use index access --echo # Should use index access
EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(t3) */ f1 FROM t3 WHERE f1 > 30 AND f1 < 33; EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(t3) */ f1
FROM t3 WHERE f1 > 30 AND f1 < 33;
--echo # Turn off range access for PRIMARY & f2_idx keys --echo # Turn off range access for PRIMARY & f2_idx keys
--echo # Should use index access --echo # Should use index access
EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY) NO_RANGE_OPTIMIZATION(t3 f2_idx) */ f1 FROM t3 WHERE f1 > 30 AND f1 < 33; EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY) NO_RANGE_OPTIMIZATION(t3 f2_idx) */ f1
FROM t3 WHERE f1 > 30 AND f1 < 33;
--echo # Create a clone of t3 with cyrillic names
CREATE TABLE таблица (f1 INT NOT NULL, поле2 INT, поле3 VARCHAR(32),
PRIMARY KEY(f1), KEY f2_индекс(f1), KEY f3_индекс(поле3))
AS SELECT * FROM t3;
ANALYZE TABLE таблица;
--echo # Turn off range access for PRIMARY key
--echo # Should use range access by f2_индекс key
EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(таблица PRIMARY) */ f1
FROM таблица WHERE f1 > 30 AND f1 < 33;
--echo # Turn off range access for PRIMARY & f2_индекс keys
--echo # Should use index access
EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(таблица PRIMARY, f2_индекс) */ f1
FROM таблица WHERE f1 > 30 AND f1 < 33;
--echo # Turn off range access for all keys
--echo # Should use index access
EXPLAIN EXTENDED SELECT /*+ NO_RANGE_OPTIMIZATION(таблица) */ f1
FROM таблица WHERE f1 > 30 AND f1 < 33;
--echo # Turn off range access for PRIMARY & f2_индекс keys
--echo # Should use index access
EXPLAIN EXTENDED
SELECT /*+ NO_RANGE_OPTIMIZATION(таблица PRIMARY) NO_RANGE_OPTIMIZATION(таблица f2_индекс) */ f1
FROM таблица WHERE f1 > 30 AND f1 < 33;
DROP TABLE таблица;
--echo # NO_ICP hint testing --echo # NO_ICP hint testing
set optimizer_switch='index_condition_pushdown=on'; set optimizer_switch='index_condition_pushdown=on';
...@@ -79,6 +122,12 @@ EXPLAIN EXTENDED SELECT /*+ NO_ICP(t5@qb1 x_idx) */ * FROM ...@@ -79,6 +122,12 @@ EXPLAIN EXTENDED SELECT /*+ NO_ICP(t5@qb1 x_idx) */ * FROM
(SELECT /*+ QB_NAME(QB1) */ t4.x, t5.y FROM t4, t4 t5 (SELECT /*+ QB_NAME(QB1) */ t4.x, t5.y FROM t4, t4 t5
WHERE t4.y = 8 AND t5.x BETWEEN 7 AND t4.y+0) AS TD; WHERE t4.y = 8 AND t5.x BETWEEN 7 AND t4.y+0) AS TD;
--echo # Cyrillic query block name
EXPLAIN EXTENDED SELECT /*+ NO_ICP(t5@блок1 x_idx) */ * FROM
(SELECT /*+ QB_NAME(блок1) */ t4.x, t5.y FROM t4, t4 t5
WHERE t4.y = 8 AND t5.x BETWEEN 7 AND t4.y+0) AS TD;
--echo # Expected warning for z_idx key, unresolved name. --echo # Expected warning for z_idx key, unresolved name.
EXPLAIN EXTENDED SELECT * FROM EXPLAIN EXTENDED SELECT * FROM
(SELECT /*+ NO_ICP(t5 y_idx, x_idx, z_idx) */ t4.x, t5.y FROM t4, t4 t5 (SELECT /*+ NO_ICP(t5 y_idx, x_idx, z_idx) */ t4.x, t5.y FROM t4, t4 t5
...@@ -157,7 +206,7 @@ EXPLAIN EXTENDED SELECT /*+ NO_BKA(t12) */ * FROM t12, t13 ...@@ -157,7 +206,7 @@ EXPLAIN EXTENDED SELECT /*+ NO_BKA(t12) */ * FROM t12, t13
EXPLAIN EXTENDED SELECT /*+ QB_NAME(QB1) NO_BKA(t13@QB1) */ * FROM t12, t13 EXPLAIN EXTENDED SELECT /*+ QB_NAME(QB1) NO_BKA(t13@QB1) */ * FROM t12, t13
WHERE t12.a=t13.a AND (t13.b+1 <= t13.b+1); WHERE t12.a=t13.a AND (t13.b+1 <= t13.b+1);
--echo # UPDATE|DELETE|INSERT hint testing --echo # UPDATE|DELETE|INSERT|REPLACE hint testing
EXPLAIN EXTENDED UPDATE t3 EXPLAIN EXTENDED UPDATE t3
SET f3 = 'mnbv' WHERE f1 > 30 AND f1 < 33 AND (t3.f1, t3.f2, t3.f3) IN 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 (SELECT t2.f1, t2.f2, t2.f3 FROM t1,t2 WHERE t1.f1=t2.f1 AND
...@@ -207,6 +256,25 @@ EXPLAIN EXTENDED INSERT /*+ NO_ICP(t5@QB1 x_idx) */ INTO t3(f1, f2, f3) ...@@ -207,6 +256,25 @@ EXPLAIN EXTENDED INSERT /*+ NO_ICP(t5@QB1 x_idx) */ INTO t3(f1, f2, f3)
(SELECT /*+ QB_NAME(qb1) */ t4.x, t5.y, 'filler' FROM t4, t4 t5 (SELECT /*+ 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); 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
EXPLAIN EXTENDED REPLACE INTO t3(f1, f2, f3)
(SELECT t4.x, t5.y, 'filler' FROM t4, t4 t5 WHERE t4.y = 8 AND t5.x BETWEEN 7 AND t4.y+0);
--echo # Turn off ICP. ICP should not be used.
EXPLAIN EXTENDED REPLACE INTO t3(f1, f2, f3)
(SELECT /*+ NO_ICP(t5) */t4.x, t5.y, 'filler' FROM t4, t4 t5
WHERE t4.y = 8 AND t5.x BETWEEN 7 AND t4.y+0);
--echo # Turn off ICP for a particular table
EXPLAIN EXTENDED REPLACE /*+ NO_ICP(t5@QB1) */ INTO t3(f1, f2, f3)
(SELECT /*+ 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 # Turn off ICP for a particular table and a key
EXPLAIN EXTENDED REPLACE /*+ NO_ICP(t5@QB1 x_idx) */ INTO t3(f1, f2, f3)
(SELECT /*+ 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 # Misc tests --echo # Misc tests
--echo # Should issue warning --echo # Should issue warning
...@@ -475,7 +543,6 @@ SELECT /*+ NO_ICP ( ) */ 1; ...@@ -475,7 +543,6 @@ SELECT /*+ NO_ICP ( ) */ 1;
SELECT /*+ NO_ICP() */ 1 UNION SELECT 1; SELECT /*+ NO_ICP() */ 1 UNION SELECT 1;
(SELECT /*+ NO_ICP() */ 1) UNION (SELECT 1); (SELECT /*+ NO_ICP() */ 1) UNION (SELECT 1);
--echo # OLEGS: this one does not issue a warning although should:
((SELECT /* + NO_ICP() */ 1)); ((SELECT /* + NO_ICP() */ 1));
UPDATE /*+ NO_ICP() */ t1 SET i = 10; UPDATE /*+ NO_ICP() */ t1 SET i = 10;
......
...@@ -895,7 +895,7 @@ CREATE TABLE t ( ...@@ -895,7 +895,7 @@ CREATE TABLE t (
INSERT INTO t(a,b) VALUES(1,'cccc'); INSERT INTO t(a,b) VALUES(1,'cccc');
let $query= let $query=
SELECT /*+ bka() */ 1 AS c FROM t AS b RIGHT JOIN t AS c ON b.a > c.c SELECT 1 AS c FROM t AS b RIGHT JOIN t AS c ON b.a > c.c
WHERE b.b>c.a; WHERE b.b>c.a;
eval EXPLAIN $query; eval EXPLAIN $query;
eval $query; eval $query;
...@@ -1022,13 +1022,12 @@ VALUES (1, 'j'), (2, 'c'), (0, 'a'); ...@@ -1022,13 +1022,12 @@ VALUES (1, 'j'), (2, 'c'), (0, 'a');
ANALYZE TABLE t1, t2, t3, t4; ANALYZE TABLE t1, t2, t3, t4;
# Hint is added to avoid materialization of the subquery
let query= let query=
SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -1049,13 +1048,12 @@ if ($support_virtual_index) ...@@ -1049,13 +1048,12 @@ if ($support_virtual_index)
ALTER TABLE t3 ADD INDEX v_idx2 (i2_key, i1); ALTER TABLE t3 ADD INDEX v_idx2 (i2_key, i1);
} }
# Hint is added to avoid materialization of the subquery
let query= let query=
SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -1079,11 +1077,11 @@ ALTER TABLE t3 DROP INDEX v_idx; ...@@ -1079,11 +1077,11 @@ ALTER TABLE t3 DROP INDEX v_idx;
# Hint is added to avoid materialization of the subquery # Hint is added to avoid materialization of the subquery
let query= let query=
SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -1117,11 +1115,11 @@ VALUES (10,1), (11,1), (12,1), (13,1), (14,1),(15,1), (16,1),(17,1), (18,1), ...@@ -1117,11 +1115,11 @@ VALUES (10,1), (11,1), (12,1), (13,1), (14,1),(15,1), (16,1),(17,1), (18,1),
--echo # non-covering. --echo # non-covering.
# Hint is added to avoid materialization of the subquery # Hint is added to avoid materialization of the subquery
let query= let query=
SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1, t3.i1 SELECT t1.c1, t2.i1, t3.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -1154,11 +1152,11 @@ eval $query; ...@@ -1154,11 +1152,11 @@ eval $query;
# an extra query condition is added to the subquery. # an extra query condition is added to the subquery.
# Hint is added to avoid materialization of the subquery # Hint is added to avoid materialization of the subquery
let query= let query=
SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' and t4.i1 < (t2.i1 + 1) WHERE t4.c1 < 'o' and t4.i1 < (t2.i1 + 1)
) )
......
...@@ -444,7 +444,7 @@ Note 1265 Data truncated for column 'c13' at row 1 ...@@ -444,7 +444,7 @@ Note 1265 Data truncated for column 'c13' at row 1
Note 1265 Data truncated for column 'c11' at row 2 Note 1265 Data truncated for column 'c11' at row 2
Note 1265 Data truncated for column 'c13' at row 2 Note 1265 Data truncated for column 'c13' at row 2
CREATE VIEW view_C AS SELECT * FROM C; CREATE VIEW view_C AS SELECT * FROM C;
SELECT /*+ NO_BNL(t1) */ t1.c13 FROM C AS t2 STRAIGHT_JOIN C AS t1 FORCE INDEX(c13); SELECT t1.c13 FROM C AS t2 STRAIGHT_JOIN C AS t1 FORCE INDEX(c13);
c13 c13
00:00:00 00:00:00
00:00:00 00:00:00
......
...@@ -555,12 +555,12 @@ c BLOB GENERATED ALWAYS AS (a+b) VIRTUAL, ...@@ -555,12 +555,12 @@ c BLOB GENERATED ALWAYS AS (a+b) VIRTUAL,
UNIQUE KEY i0008 (a) UNIQUE KEY i0008 (a)
); );
INSERT INTO t(a,b) VALUES(1,'cccc'); INSERT INTO t(a,b) VALUES(1,'cccc');
EXPLAIN SELECT /*+ bka() */ 1 AS c FROM t AS b RIGHT JOIN t AS c ON b.a > c.c EXPLAIN SELECT 1 AS c FROM t AS b RIGHT JOIN t AS c ON b.a > c.c
WHERE b.b>c.a; WHERE b.b>c.a;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE b ALL i0008 NULL NULL NULL 1 1 SIMPLE b ALL i0008 NULL NULL NULL 1
1 SIMPLE c ALL i0008 NULL NULL NULL 1 Range checked for each record (index map: 0x1) 1 SIMPLE c ALL i0008 NULL NULL NULL 1 Range checked for each record (index map: 0x1)
SELECT /*+ bka() */ 1 AS c FROM t AS b RIGHT JOIN t AS c ON b.a > c.c SELECT 1 AS c FROM t AS b RIGHT JOIN t AS c ON b.a > c.c
WHERE b.b>c.a; WHERE b.b>c.a;
c c
Warnings: Warnings:
...@@ -689,11 +689,11 @@ test.t3 analyze status Engine-independent statistics collected ...@@ -689,11 +689,11 @@ test.t3 analyze status Engine-independent statistics collected
test.t3 analyze status OK test.t3 analyze status OK
test.t4 analyze status Engine-independent statistics collected test.t4 analyze status Engine-independent statistics collected
test.t4 analyze status OK test.t4 analyze status OK
EXPLAIN SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 EXPLAIN SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -704,11 +704,11 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -704,11 +704,11 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where; End temporary 1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where; End temporary
1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join)
SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -743,11 +743,11 @@ t 9 ...@@ -743,11 +743,11 @@ t 9
# #
# Test 2: Two alternative covering indexes for the range scan # Test 2: Two alternative covering indexes for the range scan
# #
EXPLAIN SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 EXPLAIN SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -758,11 +758,11 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -758,11 +758,11 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where; End temporary 1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where; End temporary
1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join)
SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -798,11 +798,11 @@ t 9 ...@@ -798,11 +798,11 @@ t 9
# Test 3: One covering index including the base column for the virtual # Test 3: One covering index including the base column for the virtual
# column # column
# #
EXPLAIN SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 EXPLAIN SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -813,11 +813,11 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -813,11 +813,11 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where; End temporary 1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where; End temporary
1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join)
SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -861,11 +861,11 @@ VALUES (10,1), (11,1), (12,1), (13,1), (14,1),(15,1), (16,1),(17,1), (18,1), ...@@ -861,11 +861,11 @@ VALUES (10,1), (11,1), (12,1), (13,1), (14,1),(15,1), (16,1),(17,1), (18,1),
(28,1), (29,1); (28,1), (29,1);
# Change the query to read an extra column (t3.i1) making the index # Change the query to read an extra column (t3.i1) making the index
# non-covering. # non-covering.
EXPLAIN SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1, t3.i1 EXPLAIN SELECT t1.c1, t2.i1, t3.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -876,11 +876,11 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -876,11 +876,11 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where; End temporary 1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where; End temporary
1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join)
SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1, t3.i1 SELECT t1.c1, t2.i1, t3.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -916,11 +916,11 @@ t 9 48 ...@@ -916,11 +916,11 @@ t 9 48
# Test 5: Test where the added primary key to secondary indexes is # Test 5: Test where the added primary key to secondary indexes is
# used after it has been included in the join buffer # used after it has been included in the join buffer
# #
EXPLAIN SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 EXPLAIN SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' and t4.i1 < (t2.i1 + 1) WHERE t4.c1 < 'o' and t4.i1 < (t2.i1 + 1)
) )
...@@ -931,11 +931,11 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -931,11 +931,11 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where 1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where
1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where; End temporary; Using join buffer (flat, BNL join) 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where; End temporary; Using join buffer (flat, BNL join)
SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' and t4.i1 < (t2.i1 + 1) WHERE t4.c1 < 'o' and t4.i1 < (t2.i1 + 1)
) )
......
...@@ -1174,14 +1174,14 @@ c BLOB GENERATED ALWAYS AS (a+b) VIRTUAL, ...@@ -1174,14 +1174,14 @@ c BLOB GENERATED ALWAYS AS (a+b) VIRTUAL,
UNIQUE KEY i0008 (a) UNIQUE KEY i0008 (a)
); );
INSERT INTO t(a,b) VALUES(1,'cccc'); INSERT INTO t(a,b) VALUES(1,'cccc');
EXPLAIN SELECT /*+ bka() */ 1 AS c FROM t AS b RIGHT JOIN t AS c ON b.a > c.c EXPLAIN SELECT 1 AS c FROM t AS b RIGHT JOIN t AS c ON b.a > c.c
WHERE b.b>c.a; WHERE b.b>c.a;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings: Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'cccc' Warning 1292 Truncated incorrect DOUBLE value: 'cccc'
Warning 1292 Truncated incorrect DECIMAL value: 'cccc' Warning 1292 Truncated incorrect DECIMAL value: 'cccc'
SELECT /*+ bka() */ 1 AS c FROM t AS b RIGHT JOIN t AS c ON b.a > c.c SELECT 1 AS c FROM t AS b RIGHT JOIN t AS c ON b.a > c.c
WHERE b.b>c.a; WHERE b.b>c.a;
c c
Warnings: Warnings:
...@@ -1315,11 +1315,11 @@ test.t3 analyze status Engine-independent statistics collected ...@@ -1315,11 +1315,11 @@ test.t3 analyze status Engine-independent statistics collected
test.t3 analyze status OK test.t3 analyze status OK
test.t4 analyze status Engine-independent statistics collected test.t4 analyze status Engine-independent statistics collected
test.t4 analyze status OK test.t4 analyze status OK
EXPLAIN SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 EXPLAIN SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -1330,11 +1330,11 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -1330,11 +1330,11 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
1 PRIMARY t3 eq_ref PRIMARY,v_idx PRIMARY 4 test.t4.i1 1 Using where; End temporary 1 PRIMARY t3 eq_ref PRIMARY,v_idx PRIMARY 4 test.t4.i1 1 Using where; End temporary
1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join)
SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -1370,11 +1370,11 @@ t 9 ...@@ -1370,11 +1370,11 @@ t 9
# Test 2: Two alternative covering indexes for the range scan # Test 2: Two alternative covering indexes for the range scan
# #
ALTER TABLE t3 ADD INDEX v_idx2 (i2_key, i1); ALTER TABLE t3 ADD INDEX v_idx2 (i2_key, i1);
EXPLAIN SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 EXPLAIN SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -1385,11 +1385,11 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -1385,11 +1385,11 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
1 PRIMARY t3 eq_ref PRIMARY,v_idx,v_idx2 PRIMARY 4 test.t4.i1 1 Using where; End temporary 1 PRIMARY t3 eq_ref PRIMARY,v_idx,v_idx2 PRIMARY 4 test.t4.i1 1 Using where; End temporary
1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join)
SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -1427,11 +1427,11 @@ t 9 ...@@ -1427,11 +1427,11 @@ t 9
# #
# Drop the index with only the virtual column # Drop the index with only the virtual column
ALTER TABLE t3 DROP INDEX v_idx; ALTER TABLE t3 DROP INDEX v_idx;
EXPLAIN SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 EXPLAIN SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -1442,11 +1442,11 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -1442,11 +1442,11 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
1 PRIMARY t3 eq_ref PRIMARY,v_idx2 PRIMARY 4 test.t4.i1 1 Using where; End temporary 1 PRIMARY t3 eq_ref PRIMARY,v_idx2 PRIMARY 4 test.t4.i1 1 Using where; End temporary
1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join)
SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -1493,11 +1493,11 @@ VALUES (10,1), (11,1), (12,1), (13,1), (14,1),(15,1), (16,1),(17,1), (18,1), ...@@ -1493,11 +1493,11 @@ VALUES (10,1), (11,1), (12,1), (13,1), (14,1),(15,1), (16,1),(17,1), (18,1),
(28,1), (29,1); (28,1), (29,1);
# Change the query to read an extra column (t3.i1) making the index # Change the query to read an extra column (t3.i1) making the index
# non-covering. # non-covering.
EXPLAIN SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1, t3.i1 EXPLAIN SELECT t1.c1, t2.i1, t3.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -1508,11 +1508,11 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -1508,11 +1508,11 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
1 PRIMARY t3 eq_ref PRIMARY,v_idx PRIMARY 4 test.t4.i1 1 Using where; End temporary 1 PRIMARY t3 eq_ref PRIMARY,v_idx PRIMARY 4 test.t4.i1 1 Using where; End temporary
1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join)
SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1, t3.i1 SELECT t1.c1, t2.i1, t3.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' WHERE t4.c1 < 'o'
) )
...@@ -1548,11 +1548,11 @@ t 9 48 ...@@ -1548,11 +1548,11 @@ t 9 48
# Test 5: Test where the added primary key to secondary indexes is # Test 5: Test where the added primary key to secondary indexes is
# used after it has been included in the join buffer # used after it has been included in the join buffer
# #
EXPLAIN SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 EXPLAIN SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' and t4.i1 < (t2.i1 + 1) WHERE t4.c1 < 'o' and t4.i1 < (t2.i1 + 1)
) )
...@@ -1563,11 +1563,11 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -1563,11 +1563,11 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
1 PRIMARY t3 eq_ref PRIMARY,v_idx PRIMARY 4 test.t4.i1 1 Using where 1 PRIMARY t3 eq_ref PRIMARY,v_idx PRIMARY 4 test.t4.i1 1 Using where
1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where; End temporary; Using join buffer (flat, BNL join) 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where; End temporary; Using join buffer (flat, BNL join)
SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN WHERE ( t3.pk IN
( (
SELECT /*+ QB_NAME(subq1) */ t4.i1 SELECT t4.i1
FROM t4 FROM t4
WHERE t4.c1 < 'o' and t4.i1 < (t2.i1 + 1) WHERE t4.c1 < 'o' and t4.i1 < (t2.i1 + 1)
) )
......
...@@ -429,7 +429,7 @@ INSERT INTO C (c8,c9) VALUES('1970-01-01',0),('1970-01-01',1); ...@@ -429,7 +429,7 @@ INSERT INTO C (c8,c9) VALUES('1970-01-01',0),('1970-01-01',1);
CREATE VIEW view_C AS SELECT * FROM C; CREATE VIEW view_C AS SELECT * FROM C;
SELECT /*+ NO_BNL(t1) */ t1.c13 FROM C AS t2 STRAIGHT_JOIN C AS t1 FORCE INDEX(c13); SELECT t1.c13 FROM C AS t2 STRAIGHT_JOIN C AS t1 FORCE INDEX(c13);
SELECT DISTINCT t1.c13 FROM C AS t1, view_C AS t2; SELECT DISTINCT t1.c13 FROM C AS t1, view_C AS t2;
DROP TABLE C; DROP TABLE C;
......
...@@ -469,7 +469,7 @@ id jid val ...@@ -469,7 +469,7 @@ id jid val
2 1 2 2 1 2
2 2 4 2 2 4
2 3 6 2 3 6
SELECT /*+ JOIN_ORDER(jt, t1) */ id, jt.* SELECT id, jt.*
FROM t1, FROM t1,
JSON_TABLE(jd, '$[*]' COLUMNS (jid FOR ORDINALITY, JSON_TABLE(jd, '$[*]' COLUMNS (jid FOR ORDINALITY,
val INT PATH '$')) AS jt; val INT PATH '$')) AS jt;
...@@ -480,14 +480,14 @@ id jid val ...@@ -480,14 +480,14 @@ id jid val
2 1 2 2 1 2
2 2 4 2 2 4
2 3 6 2 3 6
EXPLAIN SELECT /*+ JOIN_ORDER(jt, t1) */ id, jt.* EXPLAIN SELECT id, jt.*
FROM t1, FROM t1,
JSON_TABLE(jd, '$[*]' COLUMNS (jid FOR ORDINALITY, JSON_TABLE(jd, '$[*]' COLUMNS (jid FOR ORDINALITY,
val INT PATH '$')) AS jt; val INT PATH '$')) AS jt;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 1 SIMPLE t1 ALL NULL NULL NULL NULL 2
1 SIMPLE jt ALL NULL NULL NULL NULL 40 Table function: json_table 1 SIMPLE jt ALL NULL NULL NULL NULL 40 Table function: json_table
SELECT /*+ JOIN_ORDER(t2,jt) */ t1.id, t2.id, jt.* SELECT t1.id, t2.id, jt.*
FROM t1, FROM t1,
JSON_TABLE(t1.jd, '$[*]' COLUMNS (jid FOR ORDINALITY, JSON_TABLE(t1.jd, '$[*]' COLUMNS (jid FOR ORDINALITY,
val INT PATH '$')) AS jt, val INT PATH '$')) AS jt,
...@@ -514,7 +514,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -514,7 +514,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 1 SIMPLE t1 ALL NULL NULL NULL NULL 2
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join) 1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
1 SIMPLE jt ALL NULL NULL NULL NULL 40 Table function: json_table 1 SIMPLE jt ALL NULL NULL NULL NULL 40 Table function: json_table
EXPLAIN SELECT /*+ JOIN_ORDER(t2,jt) */ t1.id, t2.id, jt.* EXPLAIN SELECT t1.id, t2.id, jt.*
FROM t1, FROM t1,
JSON_TABLE(t1.jd, '$[*]' COLUMNS (jid FOR ORDINALITY, JSON_TABLE(t1.jd, '$[*]' COLUMNS (jid FOR ORDINALITY,
val INT PATH '$')) AS jt, val INT PATH '$')) AS jt,
......
...@@ -379,18 +379,18 @@ INSERT INTO t1 values (1, '[1,3,5]'),(2,'[2,4,6]'); ...@@ -379,18 +379,18 @@ INSERT INTO t1 values (1, '[1,3,5]'),(2,'[2,4,6]');
SELECT id, jt.* FROM t1, SELECT id, jt.* FROM t1,
JSON_TABLE(jd, '$[*]' COLUMNS (jid FOR ORDINALITY, JSON_TABLE(jd, '$[*]' COLUMNS (jid FOR ORDINALITY,
val INT PATH '$')) AS jt; val INT PATH '$')) AS jt;
SELECT /*+ JOIN_ORDER(jt, t1) */ id, jt.* SELECT id, jt.*
FROM t1, FROM t1,
JSON_TABLE(jd, '$[*]' COLUMNS (jid FOR ORDINALITY, JSON_TABLE(jd, '$[*]' COLUMNS (jid FOR ORDINALITY,
val INT PATH '$')) AS jt; val INT PATH '$')) AS jt;
EXPLAIN SELECT /*+ JOIN_ORDER(jt, t1) */ id, jt.* EXPLAIN SELECT id, jt.*
FROM t1, FROM t1,
JSON_TABLE(jd, '$[*]' COLUMNS (jid FOR ORDINALITY, JSON_TABLE(jd, '$[*]' COLUMNS (jid FOR ORDINALITY,
val INT PATH '$')) AS jt; val INT PATH '$')) AS jt;
--sorted_result --sorted_result
SELECT /*+ JOIN_ORDER(t2,jt) */ t1.id, t2.id, jt.* SELECT t1.id, t2.id, jt.*
FROM t1, FROM t1,
JSON_TABLE(t1.jd, '$[*]' COLUMNS (jid FOR ORDINALITY, JSON_TABLE(t1.jd, '$[*]' COLUMNS (jid FOR ORDINALITY,
val INT PATH '$')) AS jt, val INT PATH '$')) AS jt,
...@@ -402,7 +402,7 @@ EXPLAIN SELECT t1.id, t2.id, jt.* ...@@ -402,7 +402,7 @@ EXPLAIN SELECT t1.id, t2.id, jt.*
val INT PATH '$')) AS jt, val INT PATH '$')) AS jt,
t1 AS t2; t1 AS t2;
EXPLAIN SELECT /*+ JOIN_ORDER(t2,jt) */ t1.id, t2.id, jt.* EXPLAIN SELECT t1.id, t2.id, jt.*
FROM t1, FROM t1,
JSON_TABLE(t1.jd, '$[*]' COLUMNS (jid FOR ORDINALITY, JSON_TABLE(t1.jd, '$[*]' COLUMNS (jid FOR ORDINALITY,
val INT PATH '$')) AS jt, val INT PATH '$')) AS jt,
......
/* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. /* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2024, MariaDB.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -33,13 +34,13 @@ ...@@ -33,13 +34,13 @@
struct st_opt_hint_info opt_hint_info[]= struct st_opt_hint_info opt_hint_info[]=
{ {
{"BKA", true, true}, {{STRING_WITH_LEN("BKA")}, true, true},
{"BNL", true, true}, {{STRING_WITH_LEN("BNL")}, true, true},
{"ICP", true, true}, {{STRING_WITH_LEN("ICP")}, true, true},
{"MRR", true, true}, {{STRING_WITH_LEN("MRR")}, true, true},
{"NO_RANGE_OPTIMIZATION", true, true}, {{STRING_WITH_LEN("NO_RANGE_OPTIMIZATION")}, true, true},
{"QB_NAME", false, false}, {{STRING_WITH_LEN("QB_NAME")}, false, false},
{0, 0, 0} {null_clex_str, 0, 0}
}; };
/** /**
...@@ -49,35 +50,13 @@ struct st_opt_hint_info opt_hint_info[]= ...@@ -49,35 +50,13 @@ struct st_opt_hint_info opt_hint_info[]=
const LEX_CSTRING sys_qb_prefix= {"select#", 7}; const LEX_CSTRING sys_qb_prefix= {"select#", 7};
/*
Compare LEX_CSTRING objects.
@param s Pointer to LEX_CSTRING
@param t Pointer to LEX_CSTRING
@return 0 if strings are equal
1 if s is greater
-1 if t is greater
*/
static int cmp_lex_string(const LEX_CSTRING *s,
const LEX_CSTRING *t)
{
return system_charset_info->
coll->strnncollsp(system_charset_info,
(uchar *) s->str, s->length,
(uchar *) t->str, t->length);
}
static const Lex_ident_sys null_ident_sys; static const Lex_ident_sys null_ident_sys;
static void print_warn(THD *thd, uint err_code, opt_hints_enum hint_type, static void print_warn(THD *thd, uint err_code, opt_hints_enum hint_type,
bool hint_state, bool hint_state,
const Lex_ident_sys *qb_name_arg, const Lex_ident_sys *qb_name_arg,
const Lex_ident_sys *table_name_arg, const Lex_ident_sys *table_name_arg,
const Lex_ident_sys *key_name_arg/*, PT_hint *hint*/) const Lex_ident_sys *key_name_arg)
{ {
String str; String str;
...@@ -107,7 +86,14 @@ static void print_warn(THD *thd, uint err_code, opt_hints_enum hint_type, ...@@ -107,7 +86,14 @@ static void print_warn(THD *thd, uint err_code, opt_hints_enum hint_type,
/* Append QB name */ /* Append QB name */
if (qb_name_arg && qb_name_arg->length > 0) if (qb_name_arg && qb_name_arg->length > 0)
{ {
str.append(STRING_WITH_LEN("@")); if (hint_type != QB_NAME_HINT_ENUM)
{
/*
Add the delimiter for warnings like "Hint NO_ICP(`t1`@`q1` is ignored".
No need for the delimiter for warnings "Hint QB_NAME(qb1) is ignored"
*/
str.append(STRING_WITH_LEN("@"));
}
append_identifier(thd, &str, qb_name_arg->str, qb_name_arg->length); append_identifier(thd, &str, qb_name_arg->str, qb_name_arg->length);
} }
...@@ -118,16 +104,6 @@ static void print_warn(THD *thd, uint err_code, opt_hints_enum hint_type, ...@@ -118,16 +104,6 @@ static void print_warn(THD *thd, uint err_code, opt_hints_enum hint_type,
append_identifier(thd, &str, key_name_arg->str, key_name_arg->length); append_identifier(thd, &str, key_name_arg->str, key_name_arg->length);
} }
/* Append additional hint arguments if they exist */
// OLEGS: todo
// if (hint)
// {
// if (qb_name_arg || table_name_arg || key_name_arg)
// str.append(' ');
// hint->append_args(thd, &str);
// }
str.append(')'); str.append(')');
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
...@@ -150,7 +126,10 @@ static Opt_hints_global *get_global_hints(Parse_context *pc) ...@@ -150,7 +126,10 @@ static Opt_hints_global *get_global_hints(Parse_context *pc)
LEX *lex= pc->thd->lex; LEX *lex= pc->thd->lex;
if (!lex->opt_hints_global) if (!lex->opt_hints_global)
lex->opt_hints_global= new Opt_hints_global(pc->thd->mem_root); {
lex->opt_hints_global= new (pc->thd->mem_root)
Opt_hints_global(pc->thd->mem_root);
}
if (lex->opt_hints_global) if (lex->opt_hints_global)
lex->opt_hints_global->set_resolved(); lex->opt_hints_global->set_resolved();
return lex->opt_hints_global; return lex->opt_hints_global;
...@@ -166,8 +145,8 @@ static Opt_hints_qb *get_qb_hints(Parse_context *pc) ...@@ -166,8 +145,8 @@ static Opt_hints_qb *get_qb_hints(Parse_context *pc)
if (global_hints == NULL) if (global_hints == NULL)
return NULL; return NULL;
Opt_hints_qb *qb= new Opt_hints_qb(global_hints, pc->thd->mem_root, Opt_hints_qb *qb= new (pc->thd->mem_root)
pc->select->select_number); Opt_hints_qb(global_hints, pc->thd->mem_root, pc->select->select_number);
if (qb) if (qb)
{ {
global_hints->register_child(qb); global_hints->register_child(qb);
...@@ -182,8 +161,9 @@ static Opt_hints_qb *get_qb_hints(Parse_context *pc) ...@@ -182,8 +161,9 @@ static Opt_hints_qb *get_qb_hints(Parse_context *pc)
if the query block is not found. if the query block is not found.
@param pc pointer to Parse_context object @param pc pointer to Parse_context object
@param table_name query block name @param qb_name query block name
@param hint processed hint // OLEGS: amend this @param hint_type the type of the hint from opt_hints_enum
@param hint_state true: hint enables a feature; false: disables it
@return pointer to Opt_hints_table object if found, @return pointer to Opt_hints_table object if found,
NULL otherwise NULL otherwise
...@@ -229,7 +209,8 @@ static Opt_hints_table *get_table_hints(Parse_context *pc, ...@@ -229,7 +209,8 @@ static Opt_hints_table *get_table_hints(Parse_context *pc,
static_cast<Opt_hints_table *> (qb->find_by_name(table_name)); static_cast<Opt_hints_table *> (qb->find_by_name(table_name));
if (!tab) if (!tab)
{ {
tab= new Opt_hints_table(table_name, qb, pc->thd->mem_root); tab= new (pc->thd->mem_root)
Opt_hints_table(table_name, qb, pc->thd->mem_root);
qb->register_child(tab); qb->register_child(tab);
} }
...@@ -237,8 +218,6 @@ static Opt_hints_table *get_table_hints(Parse_context *pc, ...@@ -237,8 +218,6 @@ static Opt_hints_table *get_table_hints(Parse_context *pc,
} }
bool Opt_hints::get_switch(opt_hints_enum type_arg) const bool Opt_hints::get_switch(opt_hints_enum type_arg) const
{ {
if (is_specified(type_arg)) if (is_specified(type_arg))
...@@ -255,8 +234,9 @@ Opt_hints* Opt_hints::find_by_name(const LEX_CSTRING &name_arg) const ...@@ -255,8 +234,9 @@ Opt_hints* Opt_hints::find_by_name(const LEX_CSTRING &name_arg) const
{ {
for (uint i= 0; i < child_array.size(); i++) for (uint i= 0; i < child_array.size(); i++)
{ {
const LEX_CSTRING *name= child_array[i]->get_name(); const LEX_CSTRING name= child_array[i]->get_name();
if (name && !cmp_lex_string(name, &name_arg)) CHARSET_INFO *cs= child_array[i]->charset_info();
if (name.str && !cs->strnncollsp(name, name_arg))
return child_array[i]; return child_array[i];
} }
return NULL; return NULL;
...@@ -272,9 +252,6 @@ void Opt_hints::print(THD *thd, String *str) ...@@ -272,9 +252,6 @@ void Opt_hints::print(THD *thd, String *str)
append_hint_type(str, static_cast<opt_hints_enum>(i)); append_hint_type(str, static_cast<opt_hints_enum>(i));
str->append(STRING_WITH_LEN("(")); str->append(STRING_WITH_LEN("("));
append_name(thd, str); append_name(thd, str);
// OLEGS:
//if (!opt_hint_info[i].switch_hint)
// get_complex_hints(i)->append_args(thd, str);
str->append(STRING_WITH_LEN(") ")); str->append(STRING_WITH_LEN(") "));
} }
} }
...@@ -286,10 +263,9 @@ void Opt_hints::print(THD *thd, String *str) ...@@ -286,10 +263,9 @@ void Opt_hints::print(THD *thd, String *str)
void Opt_hints::append_hint_type(String *str, opt_hints_enum type) void Opt_hints::append_hint_type(String *str, opt_hints_enum type)
{ {
const char* hint_name= opt_hint_info[type].hint_name;
if(!hints_map.switch_on(type)) if(!hints_map.switch_on(type))
str->append(STRING_WITH_LEN("NO_")); str->append(STRING_WITH_LEN("NO_"));
str->append(hint_name); str->append(opt_hint_info[type].hint_name);
} }
...@@ -327,13 +303,6 @@ void Opt_hints::check_unresolved(THD *thd) ...@@ -327,13 +303,6 @@ void Opt_hints::check_unresolved(THD *thd)
} }
PT_hint *Opt_hints_global::get_complex_hints(uint type)
{
DBUG_ASSERT(0);
return NULL;
}
Opt_hints_qb::Opt_hints_qb(Opt_hints *opt_hints_arg, Opt_hints_qb::Opt_hints_qb(Opt_hints *opt_hints_arg,
MEM_ROOT *mem_root_arg, MEM_ROOT *mem_root_arg,
uint select_number_arg) uint select_number_arg)
...@@ -380,7 +349,7 @@ void Opt_hints_table::adjust_key_hints(TABLE *table) ...@@ -380,7 +349,7 @@ void Opt_hints_table::adjust_key_hints(TABLE *table)
KEY *key_info= table->key_info; KEY *key_info= table->key_info;
for (uint j= 0 ; j < table->s->keys ; j++, key_info++) for (uint j= 0 ; j < table->s->keys ; j++, key_info++)
{ {
if (!cmp_lex_string((*hint)->get_name(), &key_info->name)) if (key_info->name.streq((*hint)->get_name()))
{ {
(*hint)->set_resolved(); (*hint)->set_resolved();
keyinfo_array[j]= static_cast<Opt_hints_key *>(*hint); keyinfo_array[j]= static_cast<Opt_hints_key *>(*hint);
...@@ -543,7 +512,7 @@ bool Optimizer_hint_parser::Table_level_hint::resolve(Parse_context *pc) const ...@@ -543,7 +512,7 @@ bool Optimizer_hint_parser::Table_level_hint::resolve(Parse_context *pc) const
// e.g. BKA(@qb1) // e.g. BKA(@qb1)
if (qb->set_switch(hint_state, hint_type, false)) if (qb->set_switch(hint_state, hint_type, false))
print_warn(pc->thd, ER_WARN_CONFLICTING_HINT, hint_type, hint_state, print_warn(pc->thd, ER_WARN_CONFLICTING_HINT, hint_type, hint_state,
&qb_name_sys, NULL, NULL/*, this*/); &qb_name_sys, NULL, NULL);
return false; return false;
} }
else else
...@@ -555,10 +524,10 @@ bool Optimizer_hint_parser::Table_level_hint::resolve(Parse_context *pc) const ...@@ -555,10 +524,10 @@ bool Optimizer_hint_parser::Table_level_hint::resolve(Parse_context *pc) const
const Lex_ident_sys table_name_sys= table.to_ident_sys(pc->thd); const Lex_ident_sys table_name_sys= table.to_ident_sys(pc->thd);
Opt_hints_table *tab= get_table_hints(pc, table_name_sys, qb); Opt_hints_table *tab= get_table_hints(pc, table_name_sys, qb);
if (!tab) if (!tab)
return true; // OLEGS: why no warning? return true;
if (tab->set_switch(hint_state, hint_type, true)) if (tab->set_switch(hint_state, hint_type, true))
print_warn(pc->thd, ER_WARN_CONFLICTING_HINT, hint_type, hint_state, print_warn(pc->thd, ER_WARN_CONFLICTING_HINT, hint_type, hint_state,
&qb_name_sys, &table_name_sys, NULL/*, this*/); &qb_name_sys, &table_name_sys, NULL);
} }
} }
} }
...@@ -575,7 +544,7 @@ bool Optimizer_hint_parser::Table_level_hint::resolve(Parse_context *pc) const ...@@ -575,7 +544,7 @@ bool Optimizer_hint_parser::Table_level_hint::resolve(Parse_context *pc) const
// e.g. BKA() // e.g. BKA()
if (qb->set_switch(hint_state, hint_type, false)) if (qb->set_switch(hint_state, hint_type, false))
print_warn(pc->thd, ER_WARN_CONFLICTING_HINT, hint_type, hint_state, print_warn(pc->thd, ER_WARN_CONFLICTING_HINT, hint_type, hint_state,
&null_ident_sys, NULL, NULL/*, this*/); &null_ident_sys, NULL, NULL);
return false; return false;
} }
for (const Table_name &table : table_name_list) for (const Table_name &table : table_name_list)
...@@ -584,10 +553,10 @@ bool Optimizer_hint_parser::Table_level_hint::resolve(Parse_context *pc) const ...@@ -584,10 +553,10 @@ bool Optimizer_hint_parser::Table_level_hint::resolve(Parse_context *pc) const
const Lex_ident_sys table_name_sys= table.to_ident_sys(pc->thd); const Lex_ident_sys table_name_sys= table.to_ident_sys(pc->thd);
Opt_hints_table *tab= get_table_hints(pc, table_name_sys, qb); Opt_hints_table *tab= get_table_hints(pc, table_name_sys, qb);
if (!tab) if (!tab)
return true; // OLEGS: no warning? return true;
if (tab->set_switch(hint_state, hint_type, true)) if (tab->set_switch(hint_state, hint_type, true))
print_warn(pc->thd, ER_WARN_CONFLICTING_HINT, hint_type, hint_state, print_warn(pc->thd, ER_WARN_CONFLICTING_HINT, hint_type, hint_state,
&null_ident_sys, &table_name_sys, NULL/*, this*/); &null_ident_sys, &table_name_sys, NULL);
} }
for (const Hint_param_table &table : opt_hint_param_table_list) for (const Hint_param_table &table : opt_hint_param_table_list)
...@@ -598,16 +567,14 @@ bool Optimizer_hint_parser::Table_level_hint::resolve(Parse_context *pc) const ...@@ -598,16 +567,14 @@ bool Optimizer_hint_parser::Table_level_hint::resolve(Parse_context *pc) const
Opt_hints_qb *qb= find_qb_hints(pc, qb_name_sys, hint_type, hint_state); Opt_hints_qb *qb= find_qb_hints(pc, qb_name_sys, hint_type, hint_state);
if (qb == NULL) if (qb == NULL)
return false; return false;
// OLEGS: todo
const Lex_ident_sys table_name_sys= table.Table_name:: const Lex_ident_sys table_name_sys= table.Table_name::
to_ident_sys(pc->thd); to_ident_sys(pc->thd);
Opt_hints_table *tab= get_table_hints(pc, table_name_sys, qb); Opt_hints_table *tab= get_table_hints(pc, table_name_sys, qb);
if (!tab) if (!tab)
return true; // OLEGS: why no warning? return true;
if (tab->set_switch(hint_state, hint_type, true)) if (tab->set_switch(hint_state, hint_type, true))
print_warn(pc->thd, ER_WARN_CONFLICTING_HINT, hint_type, hint_state, print_warn(pc->thd, ER_WARN_CONFLICTING_HINT, hint_type, hint_state,
&qb_name_sys, &table_name_sys, NULL/*, this*/); &qb_name_sys, &table_name_sys, NULL);
} }
} }
return false; return false;
...@@ -654,13 +621,13 @@ bool Optimizer_hint_parser::Index_level_hint::resolve(Parse_context *pc) const ...@@ -654,13 +621,13 @@ bool Optimizer_hint_parser::Index_level_hint::resolve(Parse_context *pc) const
Opt_hints_table *tab= get_table_hints(pc, table_name_sys, qb); Opt_hints_table *tab= get_table_hints(pc, table_name_sys, qb);
if (!tab) if (!tab)
return true; // OLEGS: why no warning? return true;
if (is_empty()) // Table level hint if (is_empty()) // Table level hint
{ {
if (tab->set_switch(hint_state, hint_type, false)) if (tab->set_switch(hint_state, hint_type, false))
print_warn(pc->thd, ER_WARN_CONFLICTING_HINT, hint_type, hint_state, print_warn(pc->thd, ER_WARN_CONFLICTING_HINT, hint_type, hint_state,
&qb_name_sys, &table_name_sys, NULL/*, this*/); &qb_name_sys, &table_name_sys, NULL);
return false; return false;
} }
...@@ -670,13 +637,14 @@ bool Optimizer_hint_parser::Index_level_hint::resolve(Parse_context *pc) const ...@@ -670,13 +637,14 @@ bool Optimizer_hint_parser::Index_level_hint::resolve(Parse_context *pc) const
Opt_hints_key *idx= (Opt_hints_key *)tab->find_by_name(index_name_sys); Opt_hints_key *idx= (Opt_hints_key *)tab->find_by_name(index_name_sys);
if (!idx) if (!idx)
{ {
idx= new Opt_hints_key(index_name_sys, tab, pc->thd->mem_root); idx= new (pc->thd->mem_root)
Opt_hints_key(index_name_sys, tab, pc->thd->mem_root);
tab->register_child(idx); tab->register_child(idx);
} }
if (idx->set_switch(hint_state, hint_type, true)) if (idx->set_switch(hint_state, hint_type, true))
print_warn(pc->thd, ER_WARN_CONFLICTING_HINT, hint_type, hint_state, print_warn(pc->thd, ER_WARN_CONFLICTING_HINT, hint_type, hint_state,
&qb_name_sys, &table_name_sys, &index_name_sys/*, this*/); &qb_name_sys, &table_name_sys, &index_name_sys);
} }
return false; return false;
...@@ -691,11 +659,11 @@ bool Optimizer_hint_parser::Qb_name_hint::resolve(Parse_context *pc) const ...@@ -691,11 +659,11 @@ bool Optimizer_hint_parser::Qb_name_hint::resolve(Parse_context *pc) const
const Lex_ident_sys qb_name_sys= Query_block_name::to_ident_sys(pc->thd); const Lex_ident_sys qb_name_sys= Query_block_name::to_ident_sys(pc->thd);
if (qb->get_name() || // QB name is already set if (qb->get_name().str || // QB name is already set
qb->get_parent()->find_by_name(qb_name_sys)) // Name is already used qb->get_parent()->find_by_name(qb_name_sys)) // Name is already used
{ {
print_warn(pc->thd, ER_WARN_CONFLICTING_HINT, QB_NAME_HINT_ENUM, false, print_warn(pc->thd, ER_WARN_CONFLICTING_HINT, QB_NAME_HINT_ENUM, true,
NULL, NULL, NULL/*, this*/); &qb_name_sys, NULL, NULL);
return false; return false;
} }
...@@ -728,7 +696,7 @@ bool Optimizer_hint_parser::Hint_list::resolve(Parse_context *pc) ...@@ -728,7 +696,7 @@ bool Optimizer_hint_parser::Hint_list::resolve(Parse_context *pc)
static_cast<const Qb_name_hint &>(*hint)) static_cast<const Qb_name_hint &>(*hint))
{ {
if (qb_hint.resolve(pc)) if (qb_hint.resolve(pc))
return true; // OLEGS: check this result return true;
} }
} }
return false; return false;
......
/* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. /* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2024, MariaDB plc.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -53,7 +54,7 @@ enum opt_hints_enum ...@@ -53,7 +54,7 @@ enum opt_hints_enum
struct st_opt_hint_info struct st_opt_hint_info
{ {
const char* hint_name; // Hint name. LEX_CSTRING hint_name; // Hint name.
bool check_upper_lvl; // true if upper level hint check is needed (for hints bool check_upper_lvl; // true if upper level hint check is needed (for hints
// which can be specified on more than one level). // which can be specified on more than one level).
bool switch_hint; // true if hint is not complex. bool switch_hint; // true if hint is not complex.
...@@ -81,7 +82,7 @@ class Opt_hints_map : public Sql_alloc ...@@ -81,7 +82,7 @@ class Opt_hints_map : public Sql_alloc
Check if hint is specified. Check if hint is specified.
@param type_arg hint type @param type_arg hint type
@return true if hint is specified, @return true if hint is specified,
false otherwise false otherwise
*/ */
...@@ -118,8 +119,6 @@ class Opt_hints_map : public Sql_alloc ...@@ -118,8 +119,6 @@ class Opt_hints_map : public Sql_alloc
}; };
class PT_hint;
class PT_hint_max_execution_time;
class Opt_hints_key; class Opt_hints_key;
...@@ -138,6 +137,7 @@ class Opt_hints_key; ...@@ -138,6 +137,7 @@ class Opt_hints_key;
class Opt_hints : public Sql_alloc class Opt_hints : public Sql_alloc
{ {
protected:
/* /*
Name of object referred by the hint. Name of object referred by the hint.
This name is empty for global level, This name is empty for global level,
...@@ -146,6 +146,7 @@ class Opt_hints : public Sql_alloc ...@@ -146,6 +146,7 @@ class Opt_hints : public Sql_alloc
for key level. for key level.
*/ */
Lex_ident_sys name; Lex_ident_sys name;
private:
/* /*
Parent object. There is no parent for global level, Parent object. There is no parent for global level,
for query block level parent is Opt_hints_global object, for query block level parent is Opt_hints_global object,
...@@ -209,9 +210,14 @@ class Opt_hints : public Sql_alloc ...@@ -209,9 +210,14 @@ class Opt_hints : public Sql_alloc
*/ */
bool get_switch(opt_hints_enum type_arg) const; bool get_switch(opt_hints_enum type_arg) const;
virtual const LEX_CSTRING *get_name() const virtual CHARSET_INFO *charset_info() const
{
return Lex_ident_column::charset_info();
}
const LEX_CSTRING get_name() const
{ {
return name.str ? &name : nullptr; return name;
} }
void set_name(const Lex_ident_sys &name_arg) { name= name_arg; } void set_name(const Lex_ident_sys &name_arg) { name= name_arg; }
Opt_hints *get_parent() const { return parent; } Opt_hints *get_parent() const { return parent; }
...@@ -230,25 +236,11 @@ class Opt_hints : public Sql_alloc ...@@ -230,25 +236,11 @@ class Opt_hints : public Sql_alloc
child_array.push_back(hint_arg); child_array.push_back(hint_arg);
} }
// OLEGS: remove it if not used
/**
Returns pointer to complex hint for a given type
@param type hint type
@return pointer to complex hint for a given type.
*/
// virtual PT_hint *get_complex_hints(uint type)
// {
// DBUG_ASSERT(0);
// return NULL; /* error C4716: must return a value*/
// };
/** /**
Find hint among lower-level hint objects. Find hint among lower-level hint objects.
@param name_arg hint name @param name_arg hint name
@return hint if found, @return hint if found,
NULL otherwise NULL otherwise
*/ */
...@@ -303,16 +295,11 @@ class Opt_hints_global : public Opt_hints ...@@ -303,16 +295,11 @@ class Opt_hints_global : public Opt_hints
{ {
public: public:
PT_hint_max_execution_time *max_exec_time;
Opt_hints_global(MEM_ROOT *mem_root_arg) Opt_hints_global(MEM_ROOT *mem_root_arg)
: Opt_hints(Lex_ident_sys(), NULL, mem_root_arg) : Opt_hints(Lex_ident_sys(), NULL, mem_root_arg)
{ {}
max_exec_time= NULL;
}
virtual void append_name(THD *thd, String *str) {} virtual void append_name(THD *thd, String *str) override {}
virtual PT_hint *get_complex_hints(uint type);
}; };
...@@ -334,10 +321,9 @@ class Opt_hints_qb : public Opt_hints ...@@ -334,10 +321,9 @@ class Opt_hints_qb : public Opt_hints
MEM_ROOT *mem_root_arg, MEM_ROOT *mem_root_arg,
uint select_number_arg); uint select_number_arg);
const LEX_CSTRING *get_print_name() const LEX_CSTRING get_print_name()
{ {
const LEX_CSTRING *str= Opt_hints::get_name(); return name.str ? name : sys_name;
return str ? str : &sys_name;
} }
/** /**
...@@ -348,10 +334,10 @@ class Opt_hints_qb : public Opt_hints ...@@ -348,10 +334,10 @@ class Opt_hints_qb : public Opt_hints
*/ */
void append_qb_hint(THD *thd, String *str) void append_qb_hint(THD *thd, String *str)
{ {
if (get_name()) if (name.str)
{ {
str->append(STRING_WITH_LEN("QB_NAME(")); str->append(STRING_WITH_LEN("QB_NAME("));
append_identifier(thd, str, get_name()->str, get_name()->length); append_identifier(thd, str, &name);
str->append(STRING_WITH_LEN(") ")); str->append(STRING_WITH_LEN(") "));
} }
} }
...@@ -361,10 +347,11 @@ class Opt_hints_qb : public Opt_hints ...@@ -361,10 +347,11 @@ class Opt_hints_qb : public Opt_hints
@param thd pointer to THD object @param thd pointer to THD object
@param str pointer to String object @param str pointer to String object
*/ */
virtual void append_name(THD *thd, String *str) virtual void append_name(THD *thd, String *str) override
{ {
str->append(STRING_WITH_LEN("@")); str->append(STRING_WITH_LEN("@"));
append_identifier(thd, str, get_print_name()->str, get_print_name()->length); const LEX_CSTRING print_name= get_print_name();
append_identifier(thd, str, &print_name);
} }
/** /**
...@@ -399,15 +386,21 @@ class Opt_hints_table : public Opt_hints ...@@ -399,15 +386,21 @@ class Opt_hints_table : public Opt_hints
keyinfo_array(mem_root_arg) keyinfo_array(mem_root_arg)
{ } { }
CHARSET_INFO *charset_info() const override
{
return Lex_ident_table::charset_info();
}
/** /**
Append table name. Append table name.
@param thd pointer to THD object @param thd pointer to THD object
@param str pointer to String object @param str pointer to String object
*/ */
virtual void append_name(THD *thd, String *str) virtual void append_name(THD *thd, String *str) override
{ {
append_identifier(thd, str, get_name()->str, get_name()->length); append_identifier(thd, str, &name);
get_parent()->append_name(thd, str); get_parent()->append_name(thd, str);
} }
/** /**
...@@ -445,11 +438,11 @@ class Opt_hints_key : public Opt_hints ...@@ -445,11 +438,11 @@ class Opt_hints_key : public Opt_hints
@param thd pointer to THD object @param thd pointer to THD object
@param str pointer to String object @param str pointer to String object
*/ */
virtual void append_name(THD *thd, String *str) virtual void append_name(THD *thd, String *str) override
{ {
get_parent()->append_name(thd, str); get_parent()->append_name(thd, str);
str->append(' '); str->append(' ');
append_identifier(thd, str, get_name()->str, get_name()->length); append_identifier(thd, str, &name);
} }
virtual uint get_warn_unresolved_code() const override virtual uint get_warn_unresolved_code() const override
...@@ -507,5 +500,4 @@ bool hint_table_state(const THD *thd, const TABLE *table, ...@@ -507,5 +500,4 @@ bool hint_table_state(const THD *thd, const TABLE *table,
bool hint_table_state_or_fallback(const THD *thd, const TABLE *table, bool hint_table_state_or_fallback(const THD *thd, const TABLE *table,
opt_hints_enum type_arg, opt_hints_enum type_arg,
bool fallback_value); bool fallback_value);
#endif /* OPT_HINTS_INCLUDED */ #endif /* OPT_HINTS_INCLUDED */
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "sql_error.h" #include "sql_error.h"
#include "mysqld_error.h" #include "mysqld_error.h"
#include "sql_class.h" #include "sql_class.h"
#include "sql_show.h"
extern struct st_opt_hint_info opt_hint_info[]; extern struct st_opt_hint_info opt_hint_info[];
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "lex_ident_sys.h" #include "lex_ident_sys.h"
#include "simple_tokenizer.h" #include "simple_tokenizer.h"
#include "sql_list.h" #include "sql_list.h"
#include "sql_string.h"
#include "simple_parser.h" #include "simple_parser.h"
class st_select_lex; class st_select_lex;
...@@ -565,7 +566,6 @@ class Optimizer_hint_parser: public Optimizer_hint_tokenizer, ...@@ -565,7 +566,6 @@ class Optimizer_hint_parser: public Optimizer_hint_tokenizer,
{ {
public: public:
using OR3::OR3; using OR3::OR3;
}; };
...@@ -579,8 +579,6 @@ class Optimizer_hint_parser: public Optimizer_hint_tokenizer, ...@@ -579,8 +579,6 @@ class Optimizer_hint_parser: public Optimizer_hint_tokenizer,
size_t count() const { return elements; } size_t count() const { return elements; }
}; };
public:
class Hint_list: public LIST<PARSER, Hint_list_container, class Hint_list: public LIST<PARSER, Hint_list_container,
Hint, TokenID::tNULL/*not separated list*/, 1> Hint, TokenID::tNULL/*not separated list*/, 1>
{ {
...@@ -590,6 +588,7 @@ class Optimizer_hint_parser: public Optimizer_hint_tokenizer, ...@@ -590,6 +588,7 @@ class Optimizer_hint_parser: public Optimizer_hint_tokenizer,
bool resolve(Parse_context *pc); bool resolve(Parse_context *pc);
}; };
public:
/* /*
The main rule: The main rule:
hints ::= hint_list EOF hints ::= hint_list EOF
...@@ -608,10 +607,10 @@ class Optimizer_hint_parser: public Optimizer_hint_tokenizer, ...@@ -608,10 +607,10 @@ class Optimizer_hint_parser: public Optimizer_hint_tokenizer,
instead of including the entire opt_hints_parser.h. instead of including the entire opt_hints_parser.h.
(forward declarations of qualified nested classes are not possible in C++) (forward declarations of qualified nested classes are not possible in C++)
*/ */
class Optimizer_hint_parser_output: public Optimizer_hint_parser::Hint_list class Optimizer_hint_parser_output: public Optimizer_hint_parser::Hints
{ {
public: public:
using Hint_list::Hint_list; using Hints::Hints;
}; };
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#define SIMPLE_TOKENIZER_INCLUDED #define SIMPLE_TOKENIZER_INCLUDED
#include "lex_ident.h" #include "lex_string.h"
#include "scan_char.h" #include "scan_char.h"
/** /**
......
...@@ -3111,7 +3111,7 @@ void st_select_lex::init_query() ...@@ -3111,7 +3111,7 @@ void st_select_lex::init_query()
pushdown_select= 0; pushdown_select= 0;
orig_names_of_item_list_elems= 0; orig_names_of_item_list_elems= 0;
opt_hints_qb= 0; opt_hints_qb= 0;
parsed_optimizer_hints= 0; // OLEGS: remove if not used parsed_optimizer_hints= 0;
} }
void st_select_lex::init_select() void st_select_lex::init_select()
...@@ -3166,7 +3166,7 @@ void st_select_lex::init_select() ...@@ -3166,7 +3166,7 @@ void st_select_lex::init_select()
orig_names_of_item_list_elems= 0; orig_names_of_item_list_elems= 0;
item_list_usage= MARK_COLUMNS_READ; item_list_usage= MARK_COLUMNS_READ;
opt_hints_qb= 0; opt_hints_qb= 0;
parsed_optimizer_hints= 0; // OLEGS: remove if not used parsed_optimizer_hints= 0;
} }
/* /*
...@@ -10684,6 +10684,7 @@ bool LEX::parsed_insert_select(SELECT_LEX *first_select) ...@@ -10684,6 +10684,7 @@ bool LEX::parsed_insert_select(SELECT_LEX *first_select)
return true; return true;
// fix "main" select // fix "main" select
resolve_optimizer_hints();
SELECT_LEX *blt __attribute__((unused))= pop_select(); SELECT_LEX *blt __attribute__((unused))= pop_select();
DBUG_ASSERT(blt == &builtin_select); DBUG_ASSERT(blt == &builtin_select);
push_select(first_select); push_select(first_select);
......
...@@ -1380,6 +1380,7 @@ class st_select_lex: public st_select_lex_node ...@@ -1380,6 +1380,7 @@ class st_select_lex: public st_select_lex_node
bool setup_ref_array(THD *thd, uint order_group_num); bool setup_ref_array(THD *thd, uint order_group_num);
uint get_cardinality_of_ref_ptrs_slice(uint order_group_num_arg); uint get_cardinality_of_ref_ptrs_slice(uint order_group_num_arg);
void print(THD *thd, String *str, enum_query_type query_type); void print(THD *thd, String *str, enum_query_type query_type);
void print_hints(THD *thd, String *hint_str);
void print_item_list(THD *thd, String *str, enum_query_type query_type); void print_item_list(THD *thd, String *str, enum_query_type query_type);
void print_set_clause(THD *thd, String *str, enum_query_type query_type); void print_set_clause(THD *thd, String *str, enum_query_type query_type);
void print_on_duplicate_key_clause(THD *thd, String *str, void print_on_duplicate_key_clause(THD *thd, String *str,
......
...@@ -31452,35 +31452,10 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type) ...@@ -31452,35 +31452,10 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
return; return;
} }
char buff[NAME_LEN]; if (sel_type == SELECT_CMD ||
String hint_str(buff, sizeof(buff), system_charset_info); sel_type == INSERT_CMD ||
hint_str.length(0); sel_type == REPLACE_CMD)
if (thd->lex->opt_hints_global) print_hints(thd, str);
{
char tmp_buff[NAME_LEN];
String hints_tmp(tmp_buff, sizeof(tmp_buff), system_charset_info);
hints_tmp.length(0);
if (select_number == 1)
{
if (opt_hints_qb)
opt_hints_qb->append_qb_hint(thd, &hints_tmp);
thd->lex->opt_hints_global->print(thd, &hints_tmp);
}
else if (opt_hints_qb)
opt_hints_qb->append_qb_hint(thd, &hints_tmp);
if (hints_tmp.length() > 0)
{
hint_str.append(STRING_WITH_LEN("/*+ "));
hint_str.append(hints_tmp);
hint_str.append(STRING_WITH_LEN("*/ "));
}
}
if (hint_str.length() > 0 && (sel_type == SELECT_CMD ||
sel_type == INSERT_CMD ||
sel_type == REPLACE_CMD))
str->append(hint_str);
/* First add options */ /* First add options */
if (options & SELECT_STRAIGHT_JOIN) if (options & SELECT_STRAIGHT_JOIN)
...@@ -31537,8 +31512,7 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type) ...@@ -31537,8 +31512,7 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
if (sel_type == UPDATE_CMD || sel_type == DELETE_CMD) if (sel_type == UPDATE_CMD || sel_type == DELETE_CMD)
{ {
str->append(get_explainable_cmd_name(sel_type)); str->append(get_explainable_cmd_name(sel_type));
if (hint_str.length() > 0) print_hints(thd, str);
str->append(hint_str);
} }
if (sel_type == DELETE_CMD) if (sel_type == DELETE_CMD)
{ {
...@@ -31668,6 +31642,36 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type) ...@@ -31668,6 +31642,36 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
} }
void st_select_lex::print_hints(THD *thd,
String *str)
{
if (!thd->lex->opt_hints_global)
return;
constexpr LEX_CSTRING header={STRING_WITH_LEN("/*+ ")};
str->append(header);
uint32 len_before_hints= str->length();
if (select_number == 1)
{
if (opt_hints_qb)
opt_hints_qb->append_qb_hint(thd, str);
thd->lex->opt_hints_global->print(thd, str);
}
else if (opt_hints_qb)
opt_hints_qb->append_qb_hint(thd, str);
if (str->length() > len_before_hints)
{
// Some hints were printed, close the hint string
str->append(STRING_WITH_LEN("*/ "));
}
else
{
// No hints were added, rollback the previouly added header
str->length(len_before_hints - header.length);
}
}
/** /**
Change the select_result object of the JOIN. Change the select_result object of the JOIN.
...@@ -1011,10 +1011,6 @@ class String: public Charset, public Binary_string ...@@ -1011,10 +1011,6 @@ class String: public Charset, public Binary_string
{ {
return Binary_string::append(s); return Binary_string::append(s);
} }
bool append(const char *s)
{
return append(s, (uint) strlen(s));
}
inline bool append(char chr) inline bool append(char chr)
{ {
return Binary_string::append_char(chr); return Binary_string::append_char(chr);
......
...@@ -8765,6 +8765,7 @@ query_specification: ...@@ -8765,6 +8765,7 @@ query_specification:
opt_having_clause opt_having_clause
opt_window_clause opt_window_clause
{ {
Lex->resolve_optimizer_hints();
$$= Lex->pop_select(); $$= Lex->pop_select();
} }
; ;
...@@ -8778,6 +8779,7 @@ select_into_query_specification: ...@@ -8778,6 +8779,7 @@ select_into_query_specification:
opt_having_clause opt_having_clause
opt_window_clause opt_window_clause
{ {
Lex->resolve_optimizer_hints();
$$= Lex->pop_select(); $$= Lex->pop_select();
} }
; ;
...@@ -8917,7 +8919,6 @@ query_expression_body: ...@@ -8917,7 +8919,6 @@ query_expression_body:
query_simple query_simple
{ {
Lex->push_select($1); Lex->push_select($1);
Lex->resolve_optimizer_hints();
if (!($$= Lex->create_unit($1))) if (!($$= Lex->create_unit($1)))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
...@@ -13358,8 +13359,9 @@ replace: ...@@ -13358,8 +13359,9 @@ replace:
Select->set_lock_for_tables($5, true, false); Select->set_lock_for_tables($5, true, false);
} }
insert_field_spec opt_returning insert_field_spec opt_returning
stmt_end insert_stmt_end
{ {
Lex->resolve_optimizer_hints();
Lex->mark_first_table_as_inserting(); Lex->mark_first_table_as_inserting();
thd->get_stmt_da()->reset_current_row_for_warning(0); thd->get_stmt_da()->reset_current_row_for_warning(0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment