mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
MDEV-33281 Optimizer hints Cleanup: fix formatting, rename objects
This commit is contained in:
@@ -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
|
||||||
|
#
|
||||||
|
@@ -204,3 +204,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;
|
|||||||
#
|
#
|
||||||
# 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;
|
|||||||
--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 #
|
||||||
|
@@ -1,4 +1,40 @@
|
|||||||
# 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:
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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);
|
|||||||
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);
|
|||||||
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
|
|||||||
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:
|
||||||
|
@@ -1,6 +1,22 @@
|
|||||||
--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;
|
|||||||
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%';
|
|||||||
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
|
|||||||
(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
|
|||||||
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)
|
|||||||
(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;
|
|||||||
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 (
|
|||||||
|
|
||||||
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');
|
|||||||
|
|
||||||
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)
|
|||||||
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;
|
|||||||
|
|
||||||
# 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),
|
|||||||
--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;
|
|||||||
# 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
|
|||||||
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,
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
#
|
#
|
||||||
# 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
|
|||||||
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
|
|||||||
# 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
|
|||||||
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),
|
|||||||
(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
|
|||||||
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
|
|||||||
# 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
|
|||||||
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,
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
# 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
|
|||||||
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
|
|||||||
#
|
#
|
||||||
# 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
|
|||||||
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),
|
|||||||
(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
|
|||||||
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
|
|||||||
# 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
|
|||||||
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);
|
|||||||
|
|
||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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]');
|
|||||||
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.*
|
|||||||
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,
|
||||||
|
162
sql/opt_hints.cc
162
sql/opt_hints.cc
@@ -1,4 +1,5 @@
|
|||||||
/* 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 @@
|
|||||||
|
|
||||||
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,14 @@ 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 +87,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 +105,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 +127,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 +146,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 +162,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 +210,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,12 +219,10 @@ 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))
|
||||||
return hints_map.switch_on(type_arg);
|
return hints_map.is_switched_on(type_arg);
|
||||||
|
|
||||||
if (opt_hint_info[type_arg].check_upper_lvl)
|
if (opt_hint_info[type_arg].check_upper_lvl)
|
||||||
return parent->get_switch(type_arg);
|
return parent->get_switch(type_arg);
|
||||||
@@ -255,8 +235,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 +253,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 +264,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.is_switched_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 +304,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)
|
||||||
@@ -360,7 +330,11 @@ Opt_hints_table *Opt_hints_qb::adjust_table_hints(TABLE *table,
|
|||||||
return tab;
|
return tab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@brief
|
||||||
|
For each index IDX, put its hints into keyinfo_array[IDX]
|
||||||
|
|
||||||
|
*/
|
||||||
void Opt_hints_table::adjust_key_hints(TABLE *table)
|
void Opt_hints_table::adjust_key_hints(TABLE *table)
|
||||||
{
|
{
|
||||||
set_resolved();
|
set_resolved();
|
||||||
@@ -370,7 +344,7 @@ void Opt_hints_table::adjust_key_hints(TABLE *table)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure that adjustement is called only once. */
|
/* Make sure that adjustment is called only once. */
|
||||||
DBUG_ASSERT(keyinfo_array.size() == 0);
|
DBUG_ASSERT(keyinfo_array.size() == 0);
|
||||||
keyinfo_array.resize(table->s->keys, NULL);
|
keyinfo_array.resize(table->s->keys, NULL);
|
||||||
|
|
||||||
@@ -380,7 +354,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);
|
||||||
@@ -445,6 +419,14 @@ static bool get_hint_state(Opt_hints *hint,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@brief
|
||||||
|
Check whether a given optimization is enabled for table.keyno.
|
||||||
|
|
||||||
|
@detail
|
||||||
|
First check if a hint is present, then check optimizer_switch
|
||||||
|
*/
|
||||||
|
|
||||||
bool hint_key_state(const THD *thd, const TABLE *table,
|
bool hint_key_state(const THD *thd, const TABLE *table,
|
||||||
uint keyno, opt_hints_enum type_arg,
|
uint keyno, opt_hints_enum type_arg,
|
||||||
uint optimizer_switch)
|
uint optimizer_switch)
|
||||||
@@ -543,7 +525,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 +537,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 +557,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 +566,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 +580,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 +634,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 +650,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 +672,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -712,23 +693,20 @@ bool Optimizer_hint_parser::Hint_list::resolve(Parse_context *pc)
|
|||||||
List_iterator_fast<Optimizer_hint_parser::Hint> li(*this);
|
List_iterator_fast<Optimizer_hint_parser::Hint> li(*this);
|
||||||
while(Optimizer_hint_parser::Hint *hint= li++)
|
while(Optimizer_hint_parser::Hint *hint= li++)
|
||||||
{
|
{
|
||||||
if (const Table_level_hint &table_hint=
|
if (const Table_level_hint &table_hint= *hint)
|
||||||
static_cast<const Table_level_hint &>(*hint))
|
|
||||||
{
|
{
|
||||||
if (table_hint.resolve(pc))
|
if (table_hint.resolve(pc))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (const Index_level_hint &index_hint=
|
else if (const Index_level_hint &index_hint= *hint)
|
||||||
static_cast<const Index_level_hint &>(*hint))
|
|
||||||
{
|
{
|
||||||
if (index_hint.resolve(pc))
|
if (index_hint.resolve(pc))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (const Qb_name_hint &qb_hint=
|
else if (const Qb_name_hint &qb_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;
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
/* 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
|
|||||||
|
|
||||||
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 @@ public:
|
|||||||
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
|
||||||
*/
|
*/
|
||||||
@@ -111,15 +112,13 @@ public:
|
|||||||
|
|
||||||
@return switch value.
|
@return switch value.
|
||||||
*/
|
*/
|
||||||
bool switch_on(opt_hints_enum type_arg) const
|
bool is_switched_on(opt_hints_enum type_arg) const
|
||||||
{
|
{
|
||||||
return hints.is_set(type_arg);
|
return hints.is_set(type_arg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class PT_hint;
|
|
||||||
class PT_hint_max_execution_time;
|
|
||||||
class Opt_hints_key;
|
class Opt_hints_key;
|
||||||
|
|
||||||
|
|
||||||
@@ -129,15 +128,16 @@ class Opt_hints_key;
|
|||||||
|
|
||||||
Opt_hints_global class is hierarchical structure.
|
Opt_hints_global class is hierarchical structure.
|
||||||
It contains information about global hints and also
|
It contains information about global hints and also
|
||||||
conains array of QUERY BLOCK level objects (Opt_hints_qb class).
|
contains array of QUERY BLOCK level objects (Opt_hints_qb class).
|
||||||
Each QUERY BLOCK level object contains array of TABLE level hints
|
Each QUERY BLOCK level object contains array of TABLE level hints
|
||||||
(class Opt_hints_table). Each TABLE level hint contains array of
|
(class Opt_hints_table). Each TABLE level hint contains array of
|
||||||
KEY lelev hints (Opt_hints_key class).
|
KEY level hints (Opt_hints_key class).
|
||||||
Hint information(specified, on|off state) is stored in hints_map object.
|
Hint information(specified, on|off state) is stored in hints_map object.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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
|
|||||||
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 @@ public:
|
|||||||
*/
|
*/
|
||||||
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 name.str ? &name : nullptr;
|
return Lex_ident_column::charset_info();
|
||||||
|
}
|
||||||
|
|
||||||
|
const LEX_CSTRING get_name() const
|
||||||
|
{
|
||||||
|
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 @@ public:
|
|||||||
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
|
|||||||
{
|
{
|
||||||
|
|
||||||
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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
*/
|
*/
|
||||||
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 @@ public:
|
|||||||
@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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
@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,
|
|||||||
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 @@
|
|||||||
#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 @@
|
|||||||
#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 @@ private:
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using OR3::OR3;
|
using OR3::OR3;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -579,8 +579,6 @@ private:
|
|||||||
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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -196,7 +196,7 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A rule consisting of three other rules in a row:
|
A rule consisting of four other rules in a row:
|
||||||
rule ::= rule1 rule2 rule3 rule4
|
rule ::= rule1 rule2 rule3 rule4
|
||||||
*/
|
*/
|
||||||
template<class PARSER, class A, class B, class C, class D>
|
template<class PARSER, class A, class B, class C, class D>
|
||||||
|
@@ -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"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -3112,7 +3112,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()
|
||||||
@@ -3167,7 +3167,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -11107,6 +11107,7 @@ bool LEX::parsed_insert_select(SELECT_LEX *first_select)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// fix "main" select
|
// fix "main" select
|
||||||
|
resolve_optimizer_hints_in_last_select();
|
||||||
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);
|
||||||
@@ -12900,7 +12901,7 @@ LEX::parse_optimizer_hints(const Lex_comment_st &hints_str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LEX::resolve_optimizer_hints()
|
void LEX::resolve_optimizer_hints_in_last_select()
|
||||||
{
|
{
|
||||||
SELECT_LEX *select_lex;
|
SELECT_LEX *select_lex;
|
||||||
if (likely(select_stack_top))
|
if (likely(select_stack_top))
|
||||||
|
@@ -1390,6 +1390,7 @@ public:
|
|||||||
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_lock_type(String *str);
|
void print_lock_type(String *str);
|
||||||
|
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,
|
||||||
@@ -3747,7 +3748,7 @@ public:
|
|||||||
DBUG_RETURN(select_lex);
|
DBUG_RETURN(select_lex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void resolve_optimizer_hints();
|
void resolve_optimizer_hints_in_last_select();
|
||||||
|
|
||||||
SELECT_LEX *current_select_or_default()
|
SELECT_LEX *current_select_or_default()
|
||||||
{
|
{
|
||||||
|
@@ -32105,35 +32105,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)
|
||||||
@@ -32190,8 +32165,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)
|
||||||
{
|
{
|
||||||
@@ -32318,6 +32292,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.
|
||||||
|
|
||||||
|
@@ -1015,10 +1015,6 @@ public:
|
|||||||
{
|
{
|
||||||
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);
|
||||||
|
@@ -9005,6 +9005,7 @@ query_specification:
|
|||||||
opt_having_clause
|
opt_having_clause
|
||||||
opt_window_clause
|
opt_window_clause
|
||||||
{
|
{
|
||||||
|
Lex->resolve_optimizer_hints_in_last_select();
|
||||||
$$= Lex->pop_select();
|
$$= Lex->pop_select();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@@ -9018,6 +9019,7 @@ select_into_query_specification:
|
|||||||
opt_having_clause
|
opt_having_clause
|
||||||
opt_window_clause
|
opt_window_clause
|
||||||
{
|
{
|
||||||
|
Lex->resolve_optimizer_hints_in_last_select();
|
||||||
$$= Lex->pop_select();
|
$$= Lex->pop_select();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@@ -9157,7 +9159,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;
|
||||||
}
|
}
|
||||||
@@ -13604,7 +13605,7 @@ insert:
|
|||||||
insert_field_spec opt_insert_update opt_returning
|
insert_field_spec opt_insert_update opt_returning
|
||||||
insert_stmt_end
|
insert_stmt_end
|
||||||
{
|
{
|
||||||
Lex->resolve_optimizer_hints();
|
Lex->resolve_optimizer_hints_in_last_select();
|
||||||
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);
|
||||||
}
|
}
|
||||||
@@ -13624,8 +13625,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_in_last_select();
|
||||||
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);
|
||||||
}
|
}
|
||||||
@@ -13641,7 +13643,7 @@ insert_start: {
|
|||||||
;
|
;
|
||||||
|
|
||||||
stmt_end: {
|
stmt_end: {
|
||||||
Lex->resolve_optimizer_hints();
|
Lex->resolve_optimizer_hints_in_last_select();
|
||||||
Lex->pop_select(); //main select
|
Lex->pop_select(); //main select
|
||||||
if (Lex->check_main_unit_semantics())
|
if (Lex->check_main_unit_semantics())
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
@@ -14008,7 +14010,7 @@ delete:
|
|||||||
{
|
{
|
||||||
if (Lex->check_cte_dependencies_and_resolve_references())
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
Lex->resolve_optimizer_hints();
|
Lex->resolve_optimizer_hints_in_last_select();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user