commit 03a925c7ff6f5664a34230af7db320f02f0781d4 Author: Maxime Conjard Date: Tue Oct 5 14:45:23 2021 +0800 OFFSET PUSHDOWN ** Combining Offset Pushdown with redundant SQL-layer checks removal for execution time optimization ** We consider the case of SELECT queries with LIMIT(n) /OFFSET(p). As it stood, the storage engine returned all the rows that satisfied the WHERE clause, and the SQL layer took care of discarding the p rows accounting for the OFFSET and selecting up to n rows. In cases where p>>n, this led to a large number of rows sent from the storage engine to the SQL-layer only to be discarded by the latter. **************** Feature 1: OFFSET PUSHDOWN ************************ We developed a feature called offset pushdown in which the OFFSET is handled in the storage engine, whenever possible. A certain number of conditions have to be met in order for this optimization to be possible, but it essentially revolves around whether the WHERE clause can be handled in its entirety by the storage engine as it is a necessary condition for the OFFSET to be handled there as well. If the WHERE clause requires a SQL-layer check to discard some rows, it will not be possible to push the OFFSET down to the storage engine as we might skip rows that would otherwise have been discarded by the SQL-layer, resulting in an incorrect output. The feature is implemented as follow, a function offset_pushdown implemented in sql_select.cc is called in sql_optimizer.cc and assesses whether the query is a candidate for offset pushdown, and communicates to the storage engine whether to pushdown down the OFFSET. The list of conditions for offset pushdown to take place is detailed in the function comments and is given here for information: * There must be an OFFSET * Only one table * It should not be a temporary internal table (this would require some * implementation in Temptable and InnoDB-intrinsic) * The table should be accessed by a simple access method (using only one * index - no index merge, or using a table scan) * The table in the query must be an InnoDB table * No HAVING (sits between table reading and OFFSET applying, and alters * the result, so OFFSET cannot be applied before HAVING) * No aggregation (same, needs all rows) * No GROUP BY (same) * No ROLLUP (same) * No windowing (same) * No filesort in SQL layer (same) * Condition must be empty - thereby making sure that there is nothing to * check up in the SQL layer * No post-processing temporary table (it may shuffle or filter rows) * No SQL_CALC_FOUND_ROWS (the logic for accurate counting of skipped * rows, necessary for this, is in the LimitOffsetIterator, not in the * engine). * LIMIT is not an extreme value (or the substraction we do to adjust the * offset and the limit in offset_pushdown would be wrong) * No partitioned table ( see ** for exception) The storage engine has been modified to be able to act on that information, it can now skips the first relevant p rows. In row0sel.cc, row_search_mvcc has been modified so that it can skip rows if necessary when offset pushdown is activated. The function skip_row_for_offset_pushdown assesses whether a given row must be skipped. When the OFFSET should be pushed down, offset_pushdown communicates pushed_offset = p (0 otherwise) and scanned_offset= 0. The first call to row_search_mvcc is going to skip rows and increment scanned_offset up to p. The second call to row_search_mvcc is going to then read the rows to be returned, if any. The modifications work also when MVCC confirmation is needed, and for locking reads (see ***) Optimizer switch: offset_pushdown Defaults to on Optimizer hint: OFFSET_PUSHDOWN() enables offset pushdown NO_OFFSET_PUSHDOWN() disables offset pushdown The hint takes precedence on the state of the optimizer_switch. A counter `innodb_rows_skipped_by_offset_pushdown` is added so that we can inspect in mtr tests how many rows were skipped using offset pushdown. (**) - Partitioned tables Deactivate offset pushdown when partitioned tables are used, except when rows are read from only one partition: The reason for that is that the function Partition_helper::handle_ordered_index_scan reads rows from the first partition first, then the second partition, etc, and does a merge sort to order all these rows. This function can be used when there is an ORDER BY clause in the query. Consider for instance a partitioned table such that PARTITION BY HASH (pk) PARTITIONS 4, the n rows are distributed in the partitions as follows: Part 1: row # 0 mod [4]: 4 8 12 16 ... Part 2: row # 1 mod [4]: 1 5 9 13 Part 3: row # 2 mod [4]: 2 6 10 14 ... Part 4 : row # 3 mod [4]: 3 7 11 15 ... Without an ORDER BY, the rows are read partition after partition, so first 4 8 12 16 … then 1 5 9 13 .. etc. If activated, offset pushdown is going to discard the p first rows that are read, where p is the value of the OFFSET, as would the same query without offset pushdown. With an ORDER BY pk, offset pushdown is going to discard the same rows as without the ORDER BY which is incorrect. The same query without offset pushdown is going to return different rows because it is going to skip rows 1 to p. The issue here is how the rows are re-arranged across partitions not within a given partition, so this issue does not arise when the query reads rows from only one partition. (***) - Locking reads For non-locking reads, the rows are skipped as soon as we know we could which is fine as long as no locks are to be placed. But if read rows are to be locked, we need to make sure that said lock is in place before we skip it. For non-locking reads, we skip the rows before PK access, if we did that for locking reads, locks on PK records could not be placed. So for locking reads, we wait until the lock is placed, before skipping the row. 1) Skipped rows are now locked. Unlocking is normally done by the handler layer (unlock_row()), for READ COMMITTED (RC) and READ UNCOMMITTED (RU). But the handler layer never sees rows skipped by OP. So we needed to add some unlocking for them. 2) * when scanning a range (read_range_next()), the range's end is checked at the handler level. * with offset pushdown (OP), rows are skipped in `row_search_mvcc()` without ever going back up to the handler as it would without OP. * Thus, if the range's size was actually smaller than the value of OFFSET, with OP we were scanning and locking more rows than necessary. * This would have an impact on next key locking and gap locks rendering some inserts and updates impossible when using OP. We solution that by implementing a systematic end-of-range check for locked records skipped using OP. We decided not to enable this systematic end-of-range check for non-locking reads as the skipping anyway stops at the end of the page if it exceeds the end of the range, which is good enough. OP does not modify the existing locking logic: In the case of a query with offset pushdown and ICP, the ICP locking logic is applied. In the case of a query with offset pushdown without ICP, the default locking logic is applied ************** Feature 2: Empty redundant SQL-layer checks ********** As the results suggested a reduction in execution time by an order of magnitude, we endeavored to extend the scope of the optimization. We realized that for many queries, the checks performed by the SQL-layer were in fact redundant. In particular, we focused on index range scans in which it was often the case that the whole WHERE clause was handled by the storage engine. We therefore developed a second feature that assesses whether, in the case of an index range scan, a condition in the WHERE clause is actually handled by the storage engine and which removes the SQL-layer check if that is the case. For queries in which all the conditions in the WHERE clause are assessed by the storage engine, removing the redundant checks therefore enables offset pushdown. The idea behind this second feature is to remove the “redundant” checks that are anyway guaranteed by InnoDB. To do that, in the optimizer, we modified the function reduce_cond_for_table. For every condition in the WHERE clause, we assess whether it can be removed. The idea is to match the information contained in the index range scan with the condition. If there’s a match, we can safely remove the condition. Condition for removal: *Index range scan: for a given condition in the WHERE clause, we make sure that they are equal to the lower ( < and <=) and upper ( > and >=) bounds (or both for = case) of the range scan on its field. It also work on IS NULL clauses. *Query collation and table collation must compatible Effect: * Remove redundant Filter checks * Remove redundant ICP * Broaden the scope of application of offset pushdown Not applicable to: * OR statements * Tmp tables * Skip scan **System variable: empty_redundant_check_in_range_scan If true, the feature is activated. Defaults to true. NOTE: The first feature is implemented in a similar way to the index condition pushdown (ICP), and for some queries, the ICP enables offset pushdown by pushing down the whole WHERE clause to the storage engine. By being evaluated prior to ICP, the second feature competes with it in the sense that it might remove a condition that would have otherwise been pushed down by the ICP. It also streamlines the use of ICP as it prevents its activation in cases where it would have been redundant. diff --git a/mysql-test/include/icp_tests.inc b/mysql-test/include/icp_tests.inc index b7282800f5e..3c094bd8932 100644 --- a/mysql-test/include/icp_tests.inc +++ b/mysql-test/include/icp_tests.inc @@ -1,7 +1,7 @@ --echo # Bug#36981 - "innodb crash when selecting for update" --echo # - +SET empty_redundant_check_in_range_scan=false; # # Test 1: Test based on the reproduction test case for this bug. # This query resulted in a crash in InnoDB due to diff --git a/mysql-test/r/all_persisted_variables.result b/mysql-test/r/all_persisted_variables.result index 46ecc241981..f62d911bee4 100644 --- a/mysql-test/r/all_persisted_variables.result +++ b/mysql-test/r/all_persisted_variables.result @@ -40,7 +40,7 @@ include/assert.inc [Expect 500+ variables in the table. Due to open Bugs, we are # Test SET PERSIST -include/assert.inc [Expect 448 persisted variables in the table.] +include/assert.inc [Expect 449 persisted variables in the table.] ************************************************************ * 3. Restart server, it must preserve the persisted variable @@ -48,9 +48,9 @@ include/assert.inc [Expect 448 persisted variables in the table.] ************************************************************ # restart -include/assert.inc [Expect 448 persisted variables in persisted_variables table.] -include/assert.inc [Expect 448 persisted variables shown as PERSISTED in variables_info table.] -include/assert.inc [Expect 448 persisted variables with matching peristed and global values.] +include/assert.inc [Expect 449 persisted variables in persisted_variables table.] +include/assert.inc [Expect 449 persisted variables shown as PERSISTED in variables_info table.] +include/assert.inc [Expect 449 persisted variables with matching peristed and global values.] ************************************************************ * 4. Test RESET PERSIST IF EXISTS. Verify persisted variable diff --git a/mysql-test/r/compress.result b/mysql-test/r/compress.result index b28ce3a5e1f..69bbde585c7 100644 --- a/mysql-test/r/compress.result +++ b/mysql-test/r/compress.result @@ -175,7 +175,7 @@ honeysuckle honoring explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range fld3 fld3 120 NULL # # Using where; Using index +1 SIMPLE t2 NULL range fld3 fld3 120 NULL # # Using index Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`fld3` AS `fld3` from `test`.`t2` where ((`test`.`t2`.`fld3` >= 'honeysuckle') and (`test`.`t2`.`fld3` <= 'honoring')) order by `test`.`t2`.`fld3` select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3; @@ -1456,19 +1456,19 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` join `test`.`t2` where ((`test`.`t4`.`companynr` = `test`.`t2`.`companynr`) and (`test`.`t2`.`companynr` > 0) and (`test`.`t2`.`companynr` > 0)) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL # # Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL # # Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL # # Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where ((`test`.`t4`.`companynr` > 0) and (`test`.`t4`.`companynr` > 0)) @@ -1492,7 +1492,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (ifnull(`test`.`t2`.`companynr`,1) > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL # # Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) @@ -2439,7 +2439,7 @@ honeysuckle honoring explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range fld3 fld3 120 NULL # # Using where; Using index +1 SIMPLE t2 NULL range fld3 fld3 120 NULL # # Using index Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`fld3` AS `fld3` from `test`.`t2` where ((`test`.`t2`.`fld3` >= 'honeysuckle') and (`test`.`t2`.`fld3` <= 'honoring')) order by `test`.`t2`.`fld3` select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3; @@ -3720,19 +3720,19 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` join `test`.`t2` where ((`test`.`t4`.`companynr` = `test`.`t2`.`companynr`) and (`test`.`t2`.`companynr` > 0) and (`test`.`t2`.`companynr` > 0)) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL # # Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL # # Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL # # Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where ((`test`.`t4`.`companynr` > 0) and (`test`.`t4`.`companynr` > 0)) @@ -3756,7 +3756,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (ifnull(`test`.`t2`.`companynr`,1) > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL # # Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) diff --git a/mysql-test/r/ctype_binary.result b/mysql-test/r/ctype_binary.result index 2940851b36b..7123ef56813 100644 --- a/mysql-test/r/ctype_binary.result +++ b/mysql-test/r/ctype_binary.result @@ -2647,7 +2647,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range date_column date_column 4 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range date_column date_column 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`date_column` AS `date_column` from `test`.`t1` where (`test`.`t1`.`date_column` between '2010-09-01' and '2010-10-01') ALTER TABLE t1 MODIFY date_column DATETIME DEFAULT NULL; @@ -2656,7 +2656,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range date_column date_column 6 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range date_column date_column 6 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`date_column` AS `date_column` from `test`.`t1` where (`test`.`t1`.`date_column` between '2010-09-01' and '2010-10-01') DROP TABLE t1; diff --git a/mysql-test/r/ctype_collate.result b/mysql-test/r/ctype_collate.result index f96bef300e3..14c324814ab 100644 --- a/mysql-test/r/ctype_collate.result +++ b/mysql-test/r/ctype_collate.result @@ -621,9 +621,9 @@ Warning 1739 Cannot use range access on index 's2' due to type or collation conv Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,`test`.`t1`.`s2` AS `s2` from `test`.`t1` where (`test`.`t1`.`s2` = (('a' collate latin1_german1_ci))) EXPLAIN SELECT * FROM t1 WHERE s1 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range s1 s1 11 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range s1 s1 11 NULL 2 100.00 NULL Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,`test`.`t1`.`s2` AS `s2` from `test`.`t1` where (`test`.`t1`.`s1` between 'a' and (('b' collate latin1_german1_ci))) +Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,`test`.`t1`.`s2` AS `s2` from `test`.`t1` where (`test`.`t1`.`s1` between 'a' and ('b' collate latin1_german1_ci)) EXPLAIN SELECT * FROM t1 WHERE s2 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL s2 NULL NULL NULL 10 10.10 Using where diff --git a/mysql-test/r/ctype_cp1251.result b/mysql-test/r/ctype_cp1251.result index e216eafe709..899898c8ed6 100644 --- a/mysql-test/r/ctype_cp1251.result +++ b/mysql-test/r/ctype_cp1251.result @@ -3041,7 +3041,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range date_column date_column 4 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range date_column date_column 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`date_column` AS `date_column` from `test`.`t1` where (`test`.`t1`.`date_column` between '2010-09-01' and '2010-10-01') ALTER TABLE t1 MODIFY date_column DATETIME DEFAULT NULL; @@ -3050,7 +3050,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range date_column date_column 6 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range date_column date_column 6 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`date_column` AS `date_column` from `test`.`t1` where (`test`.`t1`.`date_column` between '2010-09-01' and '2010-10-01') DROP TABLE t1; diff --git a/mysql-test/r/ctype_latin1_myisam.result b/mysql-test/r/ctype_latin1_myisam.result index bde6a431824..34c6fb67e38 100644 --- a/mysql-test/r/ctype_latin1_myisam.result +++ b/mysql-test/r/ctype_latin1_myisam.result @@ -2646,7 +2646,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range date_column date_column 4 NULL 1 100.00 Using index condition +1 SIMPLE t1 NULL range date_column date_column 4 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`date_column` AS `date_column` from `test`.`t1` where (`test`.`t1`.`date_column` between '2010-09-01' and '2010-10-01') ALTER TABLE t1 MODIFY date_column DATETIME DEFAULT NULL; @@ -2655,7 +2655,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range date_column date_column 6 NULL 1 100.00 Using index condition +1 SIMPLE t1 NULL range date_column date_column 6 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`date_column` AS `date_column` from `test`.`t1` where (`test`.`t1`.`date_column` between '2010-09-01' and '2010-10-01') DROP TABLE t1; diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 548feade4d9..f7a1406c2fb 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -4100,7 +4100,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range date_column date_column 4 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range date_column date_column 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`date_column` AS `date_column` from `test`.`t1` where (`test`.`t1`.`date_column` between '2010-09-01' and '2010-10-01') ALTER TABLE t1 MODIFY date_column DATETIME DEFAULT NULL; @@ -4109,7 +4109,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range date_column date_column 6 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range date_column date_column 6 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`date_column` AS `date_column` from `test`.`t1` where (`test`.`t1`.`date_column` between '2010-09-01' and '2010-10-01') DROP TABLE t1; diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 34c82e10f45..4a983c193ec 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -5475,7 +5475,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range date_column date_column 4 NULL 1 100.00 Using index condition +1 SIMPLE t1 NULL range date_column date_column 4 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`date_column` AS `date_column` from `test`.`t1` where (`test`.`t1`.`date_column` between '2010-09-01' and '2010-10-01') ALTER TABLE t1 MODIFY date_column DATETIME DEFAULT NULL; @@ -5484,7 +5484,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK EXPLAIN SELECT * FROM t1 WHERE date_column BETWEEN '2010-09-01' AND '2010-10-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range date_column date_column 6 NULL 1 100.00 Using index condition +1 SIMPLE t1 NULL range date_column date_column 6 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`date_column` AS `date_column` from `test`.`t1` where (`test`.`t1`.`date_column` between '2010-09-01' and '2010-10-01') DROP TABLE t1; diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index 9fd06d33073..c9a105a0725 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -3320,7 +3320,7 @@ GROUP BY t1.c1) a, t b WHERE b.id BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL system NULL NULL NULL NULL 1 100.00 NULL -1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using where +1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL 2 DERIVED t1 NULL ALL NULL NULL NULL NULL 4 25.00 Using where 2 DERIVED t2 NULL index NULL c2 5 NULL 4 100.00 Using index; Using join buffer (hash join) Warnings: @@ -3332,7 +3332,7 @@ GROUP BY t1.id, t2.c2) a, t b WHERE b.id BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL system NULL NULL NULL NULL 1 100.00 NULL -1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using where +1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL 2 DERIVED t1 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL 2 DERIVED t2 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL Warnings: @@ -3344,7 +3344,7 @@ GROUP BY t1.c1) a, t b WHERE b.id BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL system NULL NULL NULL NULL 1 100.00 NULL -1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using where +1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL 2 DERIVED t2 NULL ref c2 c2 5 const 1 100.00 Using index 2 DERIVED t1 NULL ALL NULL NULL NULL NULL 4 25.00 Using where; Using join buffer (hash join) Warnings: @@ -3356,7 +3356,7 @@ GROUP BY t1.c1, t2.c2) a, t b WHERE b.id BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL system NULL NULL NULL NULL 1 100.00 NULL -1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using where +1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL 2 DERIVED t2 NULL ref c2 c2 5 const 1 100.00 Using index 2 DERIVED t1 NULL ALL NULL NULL NULL NULL 4 25.00 Using where; Using join buffer (hash join) Warnings: @@ -3367,7 +3367,7 @@ FROM t t1 INNER JOIN t t2 ON t1.c1= 3 AND t2.c2= 3 GROUP BY t1.c1, t1.id) a, t b WHERE b.id BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using where +1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL 1 PRIMARY NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) 2 DERIVED t2 NULL ref c2 c2 5 const 1 100.00 Using index; Using temporary 2 DERIVED t1 NULL ALL NULL NULL NULL NULL 4 25.00 Using where; Using join buffer (hash join) @@ -3380,7 +3380,7 @@ GROUP BY t2.c1, t1.id) a, t b WHERE b.id BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL system NULL NULL NULL NULL 1 100.00 NULL -1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using where +1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL 2 DERIVED t1 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL 2 DERIVED t2 NULL ALL NULL NULL NULL NULL 4 25.00 Using where Warnings: @@ -3392,7 +3392,7 @@ GROUP BY t2.c1, t1.id) a, t b WHERE b.id BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL system NULL NULL NULL NULL 1 100.00 NULL -1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using where +1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL 2 DERIVED t1 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL 2 DERIVED t2 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL Warnings: @@ -3404,7 +3404,7 @@ GROUP BY t2.c2, t1.id) a, t b WHERE b.id BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL system NULL NULL NULL NULL 1 100.00 NULL -1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using where +1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL 2 DERIVED t1 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL 2 DERIVED t2 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL Warnings: @@ -3416,7 +3416,7 @@ GROUP BY t1.id, t2.c2) a, t b WHERE b.id BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL system NULL NULL NULL NULL 1 100.00 NULL -1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using where +1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL 2 DERIVED t1 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL 2 DERIVED t2 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL Warnings: @@ -3428,7 +3428,7 @@ GROUP BY t1.id, t2.c2, t3.c2) a, t b WHERE b.id BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL system NULL NULL NULL NULL 1 100.00 NULL -1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using where +1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL 2 DERIVED t1 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL 2 DERIVED t2 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL 2 DERIVED t3 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL @@ -3441,7 +3441,7 @@ WHERE t1.id= 1) a, t b WHERE b.id BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL system NULL NULL NULL NULL 1 100.00 NULL -1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using where +1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL 2 DERIVED t1 NULL const PRIMARY PRIMARY 4 const 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select '1' AS `id`,`test`.`b`.`id` AS `id`,`test`.`b`.`c1` AS `c1`,`test`.`b`.`c2` AS `c2` from `test`.`t` `b` where (`test`.`b`.`id` between 1 and 10) @@ -3452,7 +3452,7 @@ GROUP BY t1.id + 1) a, t b WHERE b.id BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL system NULL NULL NULL NULL 1 100.00 NULL -1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using where +1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL 2 DERIVED t1 NULL const PRIMARY PRIMARY 4 const 1 100.00 Using index 2 DERIVED t2 NULL index NULL c2 5 NULL 4 100.00 Using index Warnings: @@ -3464,7 +3464,7 @@ GROUP BY 1.5) a, t b WHERE b.id BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL system NULL NULL NULL NULL 1 100.00 NULL -1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using where +1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL 2 DERIVED t1 NULL ALL NULL NULL NULL NULL 4 25.00 Using where 2 DERIVED t2 NULL index NULL c2 5 NULL 4 100.00 Using index; Using join buffer (hash join) Warnings: @@ -3475,7 +3475,7 @@ FROM t t1 INNER JOIN t t2 ON mod(t1.id,1000)= 1 GROUP BY t1.id) a, t b WHERE b.id BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using where +1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL 1 PRIMARY NULL ALL NULL NULL NULL NULL 16 100.00 Using join buffer (hash join) 2 DERIVED t1 NULL index PRIMARY,c2 c2 5 NULL 4 100.00 Using where; Using index; Using temporary 2 DERIVED t2 NULL index NULL c2 5 NULL 4 100.00 Using index; Using join buffer (hash join) @@ -3488,7 +3488,7 @@ GROUP BY t1.id + 1) a, t b WHERE b.id BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL system NULL NULL NULL NULL 1 100.00 NULL -1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using where +1 PRIMARY b NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL 2 DERIVED t1 NULL index PRIMARY,c2 c2 5 NULL 4 100.00 Using where; Using index 2 DERIVED t2 NULL index NULL c2 5 NULL 4 100.00 Using index; Using join buffer (hash join) Warnings: @@ -3501,7 +3501,7 @@ GROUP BY v1.a) p, t q WHERE q.id BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL system NULL NULL NULL NULL 1 100.00 NULL -1 PRIMARY q NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using where +1 PRIMARY q NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL 2 DERIVED t NULL ALL NULL NULL NULL NULL 4 25.00 Using where 2 DERIVED t NULL ref c2 c2 5 const 2 100.00 Using where; Using index Warnings: @@ -3513,7 +3513,7 @@ FROM v1 LEFT OUTER JOIN v2 ON v1.a = v2.b AND v1.a = 10 GROUP BY v1.a) p, t q WHERE q.id BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 PRIMARY q NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using where +1 PRIMARY q NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL 1 PRIMARY NULL ALL NULL NULL NULL NULL 8 100.00 Using join buffer (hash join) 2 DERIVED t NULL ALL NULL NULL NULL NULL 4 100.00 Using temporary 2 DERIVED t NULL ref c2 c2 5 const 2 100.00 Using where; Using index @@ -3526,7 +3526,7 @@ GROUP BY v1.a) p, t q WHERE q.id BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL system NULL NULL NULL NULL 1 100.00 NULL -1 PRIMARY q NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using where +1 PRIMARY q NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL 2 DERIVED t NULL ALL NULL NULL NULL NULL 4 25.00 Using where 2 DERIVED t NULL ref c2 c2 5 const 2 100.00 Using where; Using index Warnings: diff --git a/mysql-test/r/derived_condition_pushdown.result b/mysql-test/r/derived_condition_pushdown.result index 109827d1dd9..274179e7f18 100644 --- a/mysql-test/r/derived_condition_pushdown.result +++ b/mysql-test/r/derived_condition_pushdown.result @@ -1,3 +1,5 @@ +# set to false to conserve original test design +set empty_redundant_check_in_range_scan=false; CREATE TABLE t0 ( i0 INTEGER ); @@ -2130,3 +2132,4 @@ SELECT * FROM (SELECT f1 FROM t1 UNION SELECT f1 FROM t1) AS dt WHERE f1 <> 0.5; f1 1 DROP TABLE t1; +set empty_redundant_check_in_range_scan=true; diff --git a/mysql-test/r/derived_limit.result b/mysql-test/r/derived_limit.result index 3038c737b91..220b7ee78d0 100644 --- a/mysql-test/r/derived_limit.result +++ b/mysql-test/r/derived_limit.result @@ -197,7 +197,7 @@ EXPLAIN FORMAT=TREE WITH cte AS (SELECT * FROM t1 LIMIT 5 OFFSET 1) SELECT * FRO EXPLAIN -> Table scan on cte (cost=2.26..4.31 rows=5) -> Materialize CTE cte (cost=1.75..1.75 rows=5) - -> Limit/Offset: 5/1 row(s) (cost=1.25 rows=5) + -> Limit/Offset: 5/1 row(s), with offset pushdown (cost=1.25 rows=5) -> Table scan on t1 (cost=1.25 rows=10) WITH cte AS (SELECT * FROM t1 LIMIT 5 OFFSET 1) SELECT * FROM cte; diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result index e82b77d7380..57a060b8fe4 100644 --- a/mysql-test/r/explain.result +++ b/mysql-test/r/explain.result @@ -632,7 +632,7 @@ Note 1003 /* select#1 */ select `test`.`t1`.`url` AS `url` from `test`.`t1` wher # Normally, range access on primary key is done EXPLAIN SELECT * FROM t1 WHERE url>'3'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY PRIMARY 1 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 NULL range PRIMARY PRIMARY 1 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`url` AS `url` from `test`.`t1` where (`test`.`t1`.`url` > '3') diff --git a/mysql-test/r/explain_dml.result b/mysql-test/r/explain_dml.result index 1798eb9a66f..dffc65b686a 100644 --- a/mysql-test/r/explain_dml.result +++ b/mysql-test/r/explain_dml.result @@ -52,7 +52,7 @@ UPDATE LOW_PRIORITY IGNORE t1 LEFT JOIN t2 ON t1.c1 = t2.c1 SET t1.c1 = 20 WHERE t1.c1 > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 UPDATE t1 p1_subp6,p1_subp7 range PRIMARY PRIMARY 4 NULL 3 100.00 Using where +1 UPDATE t1 p1_subp6,p1_subp7 range PRIMARY PRIMARY 4 NULL 3 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 3 100.00 Using where Warnings: Note 1003 update low_priority ignore `test`.`t1` left join `test`.`t2` on((`test`.`t2`.`c1` = `test`.`t1`.`c1`)) set `test`.`t1`.`c1` = 20 where (`test`.`t1`.`c1` > 0) @@ -132,7 +132,7 @@ EXPLAIN FORMAT=TRADITIONAL FOR QUERY 'UPDATE LOW_PRIORITY IGNORE t1 LEFT JOIN t2 SET t1.c1 = 20 WHERE t1.c1 > 0' id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 UPDATE t1 p1_subp6,p1_subp7 range PRIMARY PRIMARY 4 NULL 3 100.00 Using where +1 UPDATE t1 p1_subp6,p1_subp7 range PRIMARY PRIMARY 4 NULL 3 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 3 100.00 Using where EXPLAIN INSERT /*+ NO_BNL(t2@QB1) */ INTO t3 diff --git a/mysql-test/r/explain_tree.result b/mysql-test/r/explain_tree.result index 0c16d60d424..ab061276f22 100644 --- a/mysql-test/r/explain_tree.result +++ b/mysql-test/r/explain_tree.result @@ -490,11 +490,11 @@ CREATE TABLE t1 ( f1 INTEGER ); EXPLAIN FORMAT=TREE SELECT * FROM ( SELECT * FROM t1 LIMIT 2 OFFSET 1 ) AS alias1 WHERE f1 <= ANY ( SELECT f1 FROM t1 ) ORDER BY f1; EXPLAIN --> Sort: alias1.f1 (cost=2.95..2.95 rows=0) - -> Filter: ((alias1.f1 <= (select #3))) (cost=2.85..2.85 rows=0) - -> Table scan on alias1 (cost=2.85..2.85 rows=0) - -> Materialize (cost=0.35..0.35 rows=0) - -> Limit/Offset: 2/1 row(s) (cost=0.35 rows=0) +-> Sort: alias1.f1 (cost=3.16..3.16 rows=1) + -> Filter: ((alias1.f1 <= (select #3))) (cost=3.06..3.06 rows=1) + -> Table scan on alias1 (cost=2.96..2.96 rows=1) + -> Materialize (cost=0.45..0.45 rows=1) + -> Limit/Offset: 2/1 row(s), with offset pushdown (cost=0.35 rows=1) -> Table scan on t1 (cost=0.35 rows=1) -> Select #3 (subquery in condition; run only once) -> Aggregate: max(t1.f1) (cost=0.45 rows=1) @@ -942,14 +942,12 @@ Table Op Msg_type Msg_text test.t analyze status OK EXPLAIN FORMAT=tree SELECT * FROM t WHERE a > 'abc' AND a < 'ghi'; EXPLAIN --> Filter: ((t.a > 'abc') and (t.a < 'ghi')) (cost=0.46 rows=1) - -> Covering index range scan on t using a over ('abc' < a < 'ghi') (cost=0.46 rows=1) +-> Covering index range scan on t using a over ('abc' < a < 'ghi') (cost=0.46 rows=1) EXPLAIN FORMAT=tree SELECT * FROM t WHERE a > 'abc''def' AND a < CONCAT('z', UNHEX('090A1A5C0D')); EXPLAIN --> Filter: ((t.a > 'abc\'def') and (t.a < (concat('z',unhex('090A1A5C0D'))))) (cost=0.66 rows=2) - -> Covering index range scan on t using a over ('abc\'def' < a < 'z \n\Z\\\r') (cost=0.66 rows=2) +-> Covering index range scan on t using a over ('abc\'def' < a < 'z \n\Z\\\r') (cost=0.66 rows=2) DROP TABLE t; # diff --git a/mysql-test/r/filter_single_col_idx_big_myisam.result b/mysql-test/r/filter_single_col_idx_big_myisam.result index a97f11ef43a..9f8641ecb7d 100644 --- a/mysql-test/r/filter_single_col_idx_big_myisam.result +++ b/mysql-test/r/filter_single_col_idx_big_myisam.result @@ -1643,7 +1643,7 @@ Note 1003 /* select#1 */ select `test`.`t1`.`col1_idx` AS `col1_idx`,`test`.`t1` EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT col3 FROM t2 where col1_idx>2); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 1029 100.00 NULL -2 SUBQUERY t2 NULL range col1_idx col1_idx 5 NULL 1012 100.00 Using index condition +2 SUBQUERY t2 NULL range col1_idx col1_idx 5 NULL 1012 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`col1_idx` AS `col1_idx`,`test`.`t1`.`col2_idx` AS `col2_idx`,`test`.`t1`.`col3` AS `col3`,`test`.`t1`.`col4` AS `col4`,`test`.`t1`.`vc` AS `vc`,`test`.`t1`.`vc_ft` AS `vc_ft` from `test`.`t1` where true @@ -1659,7 +1659,7 @@ Note 1003 /* select#1 */ select `test`.`t1`.`col1_idx` AS `col1_idx`,`test`.`t1` EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT col3 FROM t2 where col1_idx>2 and col3=3); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 1029 100.00 NULL -2 SUBQUERY t2 NULL range col1_idx col1_idx 5 NULL 1012 10.00 Using index condition; Using where +2 SUBQUERY t2 NULL range col1_idx col1_idx 5 NULL 1012 10.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`col1_idx` AS `col1_idx`,`test`.`t1`.`col2_idx` AS `col2_idx`,`test`.`t1`.`col3` AS `col3`,`test`.`t1`.`col4` AS `col4`,`test`.`t1`.`vc` AS `vc`,`test`.`t1`.`vc_ft` AS `vc_ft` from `test`.`t1` where true @@ -1855,13 +1855,13 @@ Note 1003 /* select#1 */ select `test`.`t1`.`col1_idx` AS `col1_idx`,`test`.`t1` EXPLAIN SELECT * FROM t1 WHERE col1_idx > 500 AND col2_idx > 500; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range col1_idx,col2_idx col1_idx 5 NULL 5 1.00 Using index condition; Using where +1 SIMPLE t1 NULL range col1_idx,col2_idx col1_idx 5 NULL 5 1.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`col1_idx` AS `col1_idx`,`test`.`t1`.`col2_idx` AS `col2_idx`,`test`.`t1`.`col3` AS `col3`,`test`.`t1`.`col4` AS `col4`,`test`.`t1`.`vc` AS `vc`,`test`.`t1`.`vc_ft` AS `vc_ft` from `test`.`t1` where ((`test`.`t1`.`col1_idx` > 500) and (`test`.`t1`.`col2_idx` > 500)) EXPLAIN SELECT * FROM t1 WHERE col1_idx > 120 AND col2_idx > 120; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range col1_idx,col2_idx col1_idx 5 NULL 128 12.44 Using index condition; Using where +1 SIMPLE t1 NULL range col1_idx,col2_idx col1_idx 5 NULL 128 12.44 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`col1_idx` AS `col1_idx`,`test`.`t1`.`col2_idx` AS `col2_idx`,`test`.`t1`.`col3` AS `col3`,`test`.`t1`.`col4` AS `col4`,`test`.`t1`.`vc` AS `vc`,`test`.`t1`.`vc_ft` AS `vc_ft` from `test`.`t1` where ((`test`.`t1`.`col1_idx` > 120) and (`test`.`t1`.`col2_idx` > 120)) diff --git a/mysql-test/r/filter_single_col_idx_small_myisam.result b/mysql-test/r/filter_single_col_idx_small_myisam.result index e9e95ec90db..f40f2c28335 100644 --- a/mysql-test/r/filter_single_col_idx_small_myisam.result +++ b/mysql-test/r/filter_single_col_idx_small_myisam.result @@ -422,7 +422,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT col3 FROM t2 where col1_idx>2); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 128 100.00 NULL -2 SUBQUERY t2 NULL range col1_idx col1_idx 5 NULL 117 100.00 Using index condition +2 SUBQUERY t2 NULL range col1_idx col1_idx 5 NULL 117 100.00 NULL # table scan subquery, filter SEL(=) EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT col3 FROM t2 where col3=3); @@ -434,7 +434,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT col3 FROM t2 where col1_idx>2 and col3=3); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 128 100.00 NULL -2 SUBQUERY t2 NULL range col1_idx col1_idx 5 NULL 117 10.00 Using index condition; Using where +2 SUBQUERY t2 NULL range col1_idx col1_idx 5 NULL 117 10.00 Using where # EXISTS - outer reference # dynamic range subq, filter SEL(>) @@ -579,11 +579,11 @@ id select_type table partitions type possible_keys key key_len ref rows filtered EXPLAIN SELECT * FROM t1 WHERE col1_idx > 500 AND col2_idx > 500; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range col1_idx,col2_idx col1_idx 5 NULL 1 5.00 Using index condition; Using where +1 SIMPLE t1 NULL range col1_idx,col2_idx col1_idx 5 NULL 1 5.00 Using where EXPLAIN SELECT * FROM t1 WHERE col1_idx > 120 AND col2_idx > 120; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range col1_idx,col2_idx col1_idx 5 NULL 1 5.00 Using index condition; Using where +1 SIMPLE t1 NULL range col1_idx,col2_idx col1_idx 5 NULL 1 5.00 Using where EXPLAIN SELECT * FROM t1 WHERE col1_idx IN (120,121,122) AND col2_idx IN (120,121,122); @@ -616,7 +616,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.col3=t2.col1_idx WHERE t2.col1_idx>20; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range col1_idx col1_idx 5 NULL 2 100.00 Using index condition +1 SIMPLE t2 NULL range col1_idx col1_idx 5 NULL 2 100.00 NULL 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 128 10.00 Using where; Using join buffer (hash join) EXPLAIN diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index 25cf7cf0288..efaf6254bd1 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -711,8 +711,8 @@ Note 1003 /* select#1 */ select max(`test`.`t1`.`a3`) AS `max(a3)` from `test`.` explain select max(t1.a3), min(t2.a2) from t1, t2 where t1.a2 = 2 and t1.a3 < 'MIN' and t2.a3 > 'CA'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range k1 k1 16 NULL 1 100.00 Using where; Using index -1 SIMPLE t2 NULL range k1 k1 9 NULL 3 100.00 Using where; Using index; Using join buffer (hash join) +1 SIMPLE t1 NULL range k1 k1 16 NULL 1 100.00 Using index +1 SIMPLE t2 NULL range k1 k1 9 NULL 3 100.00 Using index; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select max(`test`.`t1`.`a3`) AS `max(t1.a3)`,min(`test`.`t2`.`a2`) AS `min(t2.a2)` from `test`.`t1` join `test`.`t2` where ((`test`.`t1`.`a2` = 2) and (`test`.`t1`.`a3` < 'MIN') and (`test`.`t2`.`a3` > 'CA')) explain diff --git a/mysql-test/r/functional_index.result b/mysql-test/r/functional_index.result index 1b54bb732aa..82e030ba1c8 100644 --- a/mysql-test/r/functional_index.result +++ b/mysql-test/r/functional_index.result @@ -187,7 +187,7 @@ DROP TABLE t1; CREATE TABLE t1 (col1 INT, INDEX ((ABS(col1)) DESC)); EXPLAIN SELECT col1 FROM t1 WHERE ABS(col1) < 1 ORDER BY ABS(col1) DESC; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range functional_index functional_index 5 NULL 1 100.00 Using where +1 SIMPLE t1 NULL range functional_index functional_index 5 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`col1` AS `col1` from `test`.`t1` where (abs(`col1`) < 1) order by abs(`test`.`t1`.`col1`) desc DROP TABLE t1; diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index 4851efba489..3f7699623db 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -333,17 +333,17 @@ select userid,count(*) from t1 group by userid having 3 IN (1,COUNT(*)) order b userid count(*) explain select spid,count(*) from t1 where spid between 1 and 2 group by spid order by spid desc; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range spID spID 5 NULL 3 100.00 Using where; Backward index scan; Using index +1 SIMPLE t1 NULL range spID spID 5 NULL 3 100.00 Backward index scan; Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`spID` AS `spid`,count(0) AS `count(*)` from `test`.`t1` where (`test`.`t1`.`spID` between 1 and 2) group by `test`.`t1`.`spID` desc order by `test`.`t1`.`spID` desc explain select spid,count(*) from t1 where spid between 1 and 2 group by spid; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range spID spID 5 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 NULL range spID spID 5 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`spID` AS `spid`,count(0) AS `count(*)` from `test`.`t1` where (`test`.`t1`.`spID` between 1 and 2) group by `test`.`t1`.`spID` explain select spid,count(*) from t1 where spid between 1 and 2 group by spid order by null; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range spID spID 5 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 NULL range spID spID 5 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`spID` AS `spid`,count(0) AS `count(*)` from `test`.`t1` where (`test`.`t1`.`spID` between 1 and 2) group by `test`.`t1`.`spID` order by NULL select spid,count(*) from t1 where spid between 1 and 2 group by spid; @@ -1552,17 +1552,17 @@ Table Op Msg_type Msg_text test.t1 analyze status OK EXPLAIN SELECT a FROM t1 WHERE a < 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,i2 PRIMARY 4 NULL 1 100.00 Using where; Using index +1 SIMPLE t1 NULL range PRIMARY,i2 PRIMARY 4 NULL 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < 2) EXPLAIN SELECT a FROM t1 WHERE a < 2 ORDER BY a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,i2 PRIMARY 4 NULL 1 100.00 Using where; Using index +1 SIMPLE t1 NULL range PRIMARY,i2 PRIMARY 4 NULL 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < 2) order by `test`.`t1`.`a` EXPLAIN SELECT a FROM t1 WHERE a < 2 GROUP BY a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,i2 PRIMARY 4 NULL 1 100.00 Using where; Using index +1 SIMPLE t1 NULL range PRIMARY,i2 PRIMARY 4 NULL 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < 2) group by `test`.`t1`.`a` EXPLAIN SELECT a FROM t1 IGNORE INDEX (PRIMARY,i2); diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index 44577df075d..9c276ed349f 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -2255,12 +2255,12 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,count(`test`.`t1`.`a2`) AS `count(a2)` from `test`.`t1` group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b` explain select a1,a2,count(a2) from t1 where (a1 > 'a') group by a1,a2,b; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 65 NULL 102 100.00 Using where; Using index +1 SIMPLE t1 NULL range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 65 NULL 102 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,count(`test`.`t1`.`a2`) AS `count(a2)` from `test`.`t1` where (`test`.`t1`.`a1` > 'a') group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b` explain select sum(ord(a1)) from t1 where (a1 > 'a') group by a1,a2,b; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 65 NULL 102 100.00 Using where; Using index +1 SIMPLE t1 NULL range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 65 NULL 102 100.00 Using index Warnings: Note 1003 /* select#1 */ select sum(ord(`test`.`t1`.`a1`)) AS `sum(ord(a1))` from `test`.`t1` where (`test`.`t1`.`a1` > 'a') group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b` explain select distinct(a1) from t1 where ord(a2) = 98; @@ -2492,7 +2492,7 @@ Table Op Msg_type Msg_text test.t2 analyze status OK explain SELECT MIN(c) FROM t2 WHERE b = 2 and a = 1 and c > 1 GROUP BY a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 12 NULL 1 100.00 Using where; Using index +1 SIMPLE t2 NULL range PRIMARY PRIMARY 12 NULL 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select min(`test`.`t2`.`c`) AS `MIN(c)` from `test`.`t2` where ((`test`.`t2`.`a` = 1) and (`test`.`t2`.`b` = 2) and (`test`.`t2`.`c` > 1)) group by `test`.`t2`.`a` SELECT MIN(c) FROM t2 WHERE b = 2 and a = 1 and c > 1 GROUP BY a; @@ -3002,7 +3002,7 @@ EXPLAIN SELECT MIN( a ) FROM t1 WHERE a = (SELECT a FROM t1 WHERE a < 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra x x x NULL x x x x x x NULL no matching row in const table -x x x NULL x x x x x x 100.00 Using where; Using index +x x x NULL x x x x x x 100.00 Using index Warnings: x x x SELECT MIN( a ) FROM t1 WHERE a = (SELECT a FROM t1 WHERE a < 0); @@ -3094,7 +3094,7 @@ EXPLAIN SELECT MIN( a ) FROM t1 WHERE a = (SELECT a FROM t1 WHERE a < 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra x x x NULL x x x x x x NULL no matching row in const table -x x x NULL x x x x x x 100.00 Using where; Using index +x x x NULL x x x x x x 100.00 Using index Warnings: x x x SELECT MIN( a ) FROM t1 WHERE a = (SELECT a FROM t1 WHERE a < 0); @@ -3188,7 +3188,7 @@ EXPLAIN SELECT MIN( a ) FROM t1 WHERE a = (SELECT a FROM t1 WHERE a < 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra x x x NULL x x x x x x NULL no matching row in const table -x x x NULL x x x x x x 100.00 Using where; Using index +x x x NULL x x x x x x 100.00 Using index Warnings: x x x SELECT MIN( a ) FROM t1 WHERE a = (SELECT a FROM t1 WHERE a < 0); diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result index a70fc9796fc..209b4d58275 100644 --- a/mysql-test/r/index_merge_innodb.result +++ b/mysql-test/r/index_merge_innodb.result @@ -393,7 +393,7 @@ Note 1003 /* select#1 */ select `test`.`t0`.`key1` AS `key1`,`test`.`t0`.`key2` explain select * from t0,t1 where t0.key1 < 3 and (t1.key1 = t0.key1 or t1.key8 = t0.key1); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t0 NULL range i1 i1 4 NULL # 100.00 Using index condition +1 SIMPLE t0 NULL range i1 i1 4 NULL # 100.00 NULL 1 SIMPLE t1 NULL ALL i1,i8 NULL NULL NULL # 0.20 Range checked for each record (index map: 0x81) Warnings: Note 1003 /* select#1 */ select `test`.`t0`.`key1` AS `key1`,`test`.`t0`.`key2` AS `key2`,`test`.`t0`.`key3` AS `key3`,`test`.`t0`.`key4` AS `key4`,`test`.`t0`.`key5` AS `key5`,`test`.`t0`.`key6` AS `key6`,`test`.`t0`.`key7` AS `key7`,`test`.`t0`.`key8` AS `key8`,`test`.`t1`.`key1` AS `key1`,`test`.`t1`.`key2` AS `key2`,`test`.`t1`.`key3` AS `key3`,`test`.`t1`.`key4` AS `key4`,`test`.`t1`.`key5` AS `key5`,`test`.`t1`.`key6` AS `key6`,`test`.`t1`.`key7` AS `key7`,`test`.`t1`.`key8` AS `key8` from `test`.`t0` join `test`.`t1` where ((`test`.`t0`.`key1` < 3) and ((`test`.`t1`.`key1` = `test`.`t0`.`key1`) or (`test`.`t1`.`key8` = `test`.`t0`.`key1`))) @@ -1001,7 +1001,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`st_a` AS `st_a`,`test`.`t1`.`swt1a` AS `swt1a`,`test`.`t1`.`swt2a` AS `swt2a`,`test`.`t1`.`st_b` AS `st_b`,`test`.`t1`.`swt1b` AS `swt1b`,`test`.`t1`.`swt2b` AS `swt2b`,`test`.`t1`.`key1` AS `key1`,`test`.`t1`.`key2` AS `key2`,`test`.`t1`.`key3` AS `key3`,`test`.`t1`.`key4` AS `key4`,`test`.`t1`.`filler1` AS `filler1`,`test`.`t1`.`filler2` AS `filler2`,`test`.`t1`.`filler3` AS `filler3`,`test`.`t1`.`filler4` AS `filler4`,`test`.`t1`.`filler5` AS `filler5`,`test`.`t1`.`filler6` AS `filler6` from `test`.`t1` where ((`test`.`t1`.`swt2a` = 1) and (`test`.`t1`.`swt1a` = 1) and (`test`.`t1`.`st_a` = 1)) explain select * from t1 where st_b=1 and swt1b=1 and swt2b=1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range stb_swt1a_2b,stb_swt1b,st_b stb_swt1b 8 NULL 4000 10.00 Using index condition; Using where; Using MRR +1 SIMPLE t1 NULL range stb_swt1a_2b,stb_swt1b,st_b stb_swt1b 8 NULL 4000 10.00 Using where; Using MRR Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`st_a` AS `st_a`,`test`.`t1`.`swt1a` AS `swt1a`,`test`.`t1`.`swt2a` AS `swt2a`,`test`.`t1`.`st_b` AS `st_b`,`test`.`t1`.`swt1b` AS `swt1b`,`test`.`t1`.`swt2b` AS `swt2b`,`test`.`t1`.`key1` AS `key1`,`test`.`t1`.`key2` AS `key2`,`test`.`t1`.`key3` AS `key3`,`test`.`t1`.`key4` AS `key4`,`test`.`t1`.`filler1` AS `filler1`,`test`.`t1`.`filler2` AS `filler2`,`test`.`t1`.`filler3` AS `filler3`,`test`.`t1`.`filler4` AS `filler4`,`test`.`t1`.`filler5` AS `filler5`,`test`.`t1`.`filler6` AS `filler6` from `test`.`t1` where ((`test`.`t1`.`swt2b` = 1) and (`test`.`t1`.`swt1b` = 1) and (`test`.`t1`.`st_b` = 1)) explain select * from t1 where st_a=1 and swt1a=1 and swt2a=1 and st_b=1 and swt1b=1 and swt2b=1; diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result index 94b6c8c934f..f34ad6a12ac 100644 --- a/mysql-test/r/index_merge_myisam.result +++ b/mysql-test/r/index_merge_myisam.result @@ -401,7 +401,7 @@ Note 1003 /* select#1 */ select `test`.`t0`.`key1` AS `key1`,`test`.`t0`.`key2` explain select * from t0,t1 where t0.key1 < 3 and (t1.key1 = t0.key1 or t1.key8 = t0.key1); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t0 NULL range i1 i1 4 NULL 3 100.00 Using index condition +1 SIMPLE t0 NULL range i1 i1 4 NULL 3 100.00 NULL 1 SIMPLE t1 NULL ALL i1,i8 NULL NULL NULL 1024 0.20 Range checked for each record (index map: 0x81) Warnings: Note 1003 /* select#1 */ select `test`.`t0`.`key1` AS `key1`,`test`.`t0`.`key2` AS `key2`,`test`.`t0`.`key3` AS `key3`,`test`.`t0`.`key4` AS `key4`,`test`.`t0`.`key5` AS `key5`,`test`.`t0`.`key6` AS `key6`,`test`.`t0`.`key7` AS `key7`,`test`.`t0`.`key8` AS `key8`,`test`.`t1`.`key1` AS `key1`,`test`.`t1`.`key2` AS `key2`,`test`.`t1`.`key3` AS `key3`,`test`.`t1`.`key4` AS `key4`,`test`.`t1`.`key5` AS `key5`,`test`.`t1`.`key6` AS `key6`,`test`.`t1`.`key7` AS `key7`,`test`.`t1`.`key8` AS `key8` from `test`.`t0` join `test`.`t1` where ((`test`.`t0`.`key1` < 3) and ((`test`.`t1`.`key1` = `test`.`t0`.`key1`) or (`test`.`t1`.`key8` = `test`.`t0`.`key1`))) @@ -1784,7 +1784,7 @@ primary key (pk1, pk2) # Column 9, rows, can change depending on innodb-page-size. explain select * from t1 where pk1 = 1 and pk2 < 80 and key1=0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,key1 PRIMARY 8 NULL ROWS # Using index condition; Using where +1 SIMPLE t1 NULL range PRIMARY,key1 PRIMARY 8 NULL ROWS # Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk1` AS `pk1`,`test`.`t1`.`pk2` AS `pk2`,`test`.`t1`.`key1` AS `key1`,`test`.`t1`.`key2` AS `key2`,`test`.`t1`.`pktail1ok` AS `pktail1ok`,`test`.`t1`.`pktail2ok` AS `pktail2ok`,`test`.`t1`.`pktail3bad` AS `pktail3bad`,`test`.`t1`.`pktail4bad` AS `pktail4bad`,`test`.`t1`.`pktail5bad` AS `pktail5bad`,`test`.`t1`.`pk2copy` AS `pk2copy`,`test`.`t1`.`badkey` AS `badkey`,`test`.`t1`.`filler1` AS `filler1`,`test`.`t1`.`filler2` AS `filler2` from `test`.`t1` where ((`test`.`t1`.`key1` = 0) and (`test`.`t1`.`pk1` = 1) and (`test`.`t1`.`pk2` < 80)) # CPK scan + 1 ROR range scan is a special case @@ -2108,19 +2108,19 @@ SET sql_mode = default; # select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on set optimizer_switch='index_merge=off,index_merge_union=off'; select @@optimizer_switch; @@optimizer_switch -index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on set optimizer_switch='index_merge_union=on'; select @@optimizer_switch; @@optimizer_switch -index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on set optimizer_switch='default,index_merge_sort_union=off'; select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on set optimizer_switch=4; set optimizer_switch=NULL; ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'NULL' @@ -2146,21 +2146,21 @@ set optimizer_switch=default; set optimizer_switch='index_merge=off,index_merge_union=off,default'; select @@optimizer_switch; @@optimizer_switch -index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on set optimizer_switch=default; select @@global.optimizer_switch; @@global.optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on set @@global.optimizer_switch=default; select @@global.optimizer_switch; @@global.optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on # # Check index_merge's @@optimizer_switch flags # select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on create table t0 (a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t1 (a int, b int, c int, filler char(100), @@ -2304,5 +2304,5 @@ Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`t set optimizer_switch=default; show variables like 'optimizer_switch'; Variable_name Value -optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on drop table t0, t1; diff --git a/mysql-test/r/innodb_explain_json_non_select_all.result b/mysql-test/r/innodb_explain_json_non_select_all.result index 420010371ae..54cb6c4ed5f 100644 --- a/mysql-test/r/innodb_explain_json_non_select_all.result +++ b/mysql-test/r/innodb_explain_json_non_select_all.result @@ -1767,7 +1767,6 @@ EXPLAIN "rows_examined_per_scan": 1, "rows_produced_per_join": 1, "filtered": "100.00", - "index_condition": "(`test`.`t1`.`a` < 3)", "using_MRR": true, "cost_info": { "read_cost": "0.60", @@ -3617,8 +3616,7 @@ EXPLAIN "used_columns": [ "a", "i" - ] /* used_columns */, - "attached_condition": "((`test`.`t1`.`i` > 10) and (`test`.`t1`.`i` <= 18))" + ] /* used_columns */ } /* table */ } /* ordering_operation */ } /* query_block */ @@ -4354,8 +4352,7 @@ EXPLAIN "used_columns": [ "a", "i" - ] /* used_columns */, - "attached_condition": "((`test`.`t2`.`i` > 10) and (`test`.`t2`.`i` <= 18))" + ] /* used_columns */ } /* table */ } /* ordering_operation */ } /* query_block */ @@ -4657,8 +4654,7 @@ EXPLAIN "used_columns": [ "a", "i" - ] /* used_columns */, - "attached_condition": "((`test`.`t2`.`i` > 10) and (`test`.`t2`.`i` <= 18))" + ] /* used_columns */ } /* table */ } /* ordering_operation */ } /* query_block */ @@ -5398,8 +5394,7 @@ EXPLAIN "used_columns": [ "a", "i" - ] /* used_columns */, - "attached_condition": "((`test`.`t2`.`i` > 10) and (`test`.`t2`.`i` <= 18))" + ] /* used_columns */ } /* table */ } /* ordering_operation */ } /* query_block */ @@ -5917,8 +5912,7 @@ EXPLAIN } /* cost_info */, "used_columns": [ "a" - ] /* used_columns */, - "attached_condition": "(`test`.`t1`.`a` > 34)" + ] /* used_columns */ } /* table */ } /* query_block */ } @@ -6815,8 +6809,7 @@ EXPLAIN } /* cost_info */, "used_columns": [ "a" - ] /* used_columns */, - "attached_condition": "(`test`.`t1`.`a` < 4)" + ] /* used_columns */ } /* table */ } /* query_block */ } @@ -8216,8 +8209,7 @@ EXPLAIN } /* cost_info */, "used_columns": [ "a" - ] /* used_columns */, - "attached_condition": "(`test`.`t1`.`a` > 10)" + ] /* used_columns */ } /* table */ } /* query_block */ } @@ -8315,8 +8307,7 @@ EXPLAIN } /* cost_info */, "used_columns": [ "a" - ] /* used_columns */, - "attached_condition": "(`test`.`t1`.`a` > 10)" + ] /* used_columns */ } /* table */ } /* ordering_operation */ } /* query_block */ diff --git a/mysql-test/r/innodb_explain_json_non_select_none.result b/mysql-test/r/innodb_explain_json_non_select_none.result index 775037aaf54..077b6be1a29 100644 --- a/mysql-test/r/innodb_explain_json_non_select_none.result +++ b/mysql-test/r/innodb_explain_json_non_select_none.result @@ -1782,8 +1782,7 @@ EXPLAIN "used_columns": [ "a", "b" - ] /* used_columns */, - "attached_condition": "(`test`.`t1`.`a` < 3)" + ] /* used_columns */ } /* table */ } /* query_block */ } @@ -3605,8 +3604,7 @@ EXPLAIN "used_columns": [ "a", "i" - ] /* used_columns */, - "attached_condition": "((`test`.`t1`.`i` > 10) and (`test`.`t1`.`i` <= 18))" + ] /* used_columns */ } /* table */ } /* ordering_operation */ } /* query_block */ @@ -4342,8 +4340,7 @@ EXPLAIN "used_columns": [ "a", "i" - ] /* used_columns */, - "attached_condition": "((`test`.`t2`.`i` > 10) and (`test`.`t2`.`i` <= 18))" + ] /* used_columns */ } /* table */ } /* ordering_operation */ } /* query_block */ @@ -4645,8 +4642,7 @@ EXPLAIN "used_columns": [ "a", "i" - ] /* used_columns */, - "attached_condition": "((`test`.`t2`.`i` > 10) and (`test`.`t2`.`i` <= 18))" + ] /* used_columns */ } /* table */ } /* ordering_operation */ } /* query_block */ @@ -5386,8 +5382,7 @@ EXPLAIN "used_columns": [ "a", "i" - ] /* used_columns */, - "attached_condition": "((`test`.`t2`.`i` > 10) and (`test`.`t2`.`i` <= 18))" + ] /* used_columns */ } /* table */ } /* ordering_operation */ } /* query_block */ @@ -5905,8 +5900,7 @@ EXPLAIN } /* cost_info */, "used_columns": [ "a" - ] /* used_columns */, - "attached_condition": "(`test`.`t1`.`a` > 34)" + ] /* used_columns */ } /* table */ } /* query_block */ } @@ -6803,8 +6797,7 @@ EXPLAIN } /* cost_info */, "used_columns": [ "a" - ] /* used_columns */, - "attached_condition": "(`test`.`t1`.`a` < 4)" + ] /* used_columns */ } /* table */ } /* query_block */ } @@ -8237,8 +8230,7 @@ EXPLAIN } /* cost_info */, "used_columns": [ "a" - ] /* used_columns */, - "attached_condition": "(`test`.`t1`.`a` > 10)" + ] /* used_columns */ } /* table */ } /* query_block */ } @@ -8336,8 +8328,7 @@ EXPLAIN } /* cost_info */, "used_columns": [ "a" - ] /* used_columns */, - "attached_condition": "(`test`.`t1`.`a` > 10)" + ] /* used_columns */ } /* table */ } /* ordering_operation */ } /* query_block */ diff --git a/mysql-test/r/innodb_icp.result b/mysql-test/r/innodb_icp.result index 47a04df4e22..5bd5b615e3b 100644 --- a/mysql-test/r/innodb_icp.result +++ b/mysql-test/r/innodb_icp.result @@ -3,6 +3,7 @@ set @save_storage_engine= @@default_storage_engine; set default_storage_engine=InnoDB; # Bug#36981 - "innodb crash when selecting for update" # +SET empty_redundant_check_in_range_scan=false; CREATE TABLE t1 ( c1 CHAR(1), c2 CHAR(10), diff --git a/mysql-test/r/innodb_icp_all.result b/mysql-test/r/innodb_icp_all.result index 2f6be6622f8..59ed5fcdf80 100644 --- a/mysql-test/r/innodb_icp_all.result +++ b/mysql-test/r/innodb_icp_all.result @@ -3,6 +3,7 @@ set @save_storage_engine= @@default_storage_engine; set default_storage_engine=InnoDB; # Bug#36981 - "innodb crash when selecting for update" # +SET empty_redundant_check_in_range_scan=false; CREATE TABLE t1 ( c1 CHAR(1), c2 CHAR(10), diff --git a/mysql-test/r/innodb_icp_none.result b/mysql-test/r/innodb_icp_none.result index 0d4368c3ea3..122404a8104 100644 --- a/mysql-test/r/innodb_icp_none.result +++ b/mysql-test/r/innodb_icp_none.result @@ -2,6 +2,7 @@ set @save_storage_engine= @@default_storage_engine; set default_storage_engine=InnoDB; # Bug#36981 - "innodb crash when selecting for update" # +SET empty_redundant_check_in_range_scan=false; CREATE TABLE t1 ( c1 CHAR(1), c2 CHAR(10), diff --git a/mysql-test/r/innodb_mrr.result b/mysql-test/r/innodb_mrr.result index b1b846a2bb0..02973214643 100644 --- a/mysql-test/r/innodb_mrr.result +++ b/mysql-test/r/innodb_mrr.result @@ -406,7 +406,7 @@ insert into t1 select A.a + 10 *(B.a + 10*C.a), A.a + 10 *(B.a + 10*C.a) from t0 This mustn't show "Using MRR": explain select * from t1 where a < 20 order by a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 Using where +1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` < 20) order by `test`.`t1`.`a` drop table t0, t1; @@ -425,7 +425,7 @@ EXPLAIN select count(length(a) + length(filler)) from t2 force index (k1) where a>='a-1000-a' and a <'a-1001-a'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range k1 k1 33 NULL 100 100.00 Using where; Using MRR +1 SIMPLE t2 NULL range k1 k1 33 NULL 100 100.00 Using MRR Warnings: Note 1003 /* select#1 */ select count((length(`test`.`t2`.`a`) + length(`test`.`t2`.`filler`))) AS `count(length(a) + length(filler))` from `test`.`t2` FORCE INDEX (`k1`) where ((`test`.`t2`.`a` >= 'a-1000-a') and (`test`.`t2`.`a` < 'a-1001-a')) select count(length(a) + length(filler)) @@ -439,7 +439,7 @@ filler char(10), key(d), primary key (a,b,c)) charset latin1; insert into t2 select A.a, B.a, B.a, A.a, 'filler' from t1 A, t1 B; explain select * from t2 force index (d) where d < 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range d d 5 NULL # 100.00 Using where +1 SIMPLE t2 NULL range d d 5 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2`.`filler` AS `filler` from `test`.`t2` FORCE INDEX (`d`) where (`test`.`t2`.`d` < 10) drop table t2; @@ -606,7 +606,7 @@ EXPLAIN SELECT i1 FROM t1 WHERE i2 > 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i2 i2 4 NULL 1 100.00 Using where +1 SIMPLE t1 NULL range i2 i2 4 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`i1` AS `i1` from `test`.`t1` where (`test`.`t1`.`i2` > 2) SELECT i1 @@ -755,7 +755,7 @@ REPEATABLE-READ START TRANSACTION; EXPLAIN SELECT * FROM t1 WHERE a > 2 FOR UPDATE; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`dummy` AS `dummy`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` > 2) SELECT * FROM t1 WHERE a > 2 FOR UPDATE; diff --git a/mysql-test/r/innodb_mrr_all.result b/mysql-test/r/innodb_mrr_all.result index 60b220103bd..294196db2e1 100644 --- a/mysql-test/r/innodb_mrr_all.result +++ b/mysql-test/r/innodb_mrr_all.result @@ -380,7 +380,7 @@ update t1 set b=repeat(char(65+a), 20) where a < 25; This must show range + using index condition: explain select * from t1 where a < 10 and b = repeat(char(65+a), 20); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL x x Using index condition; Using where +1 SIMPLE t1 NULL range a a 5 NULL x x Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`filler` AS `filler` from `test`.`t1` where ((`test`.`t1`.`a` < 10) and (`test`.`t1`.`b` = repeat(char((65 + `test`.`t1`.`a`)),20))) select * from t1 where a < 10 and b = repeat(char(65+a), 20); @@ -406,7 +406,7 @@ insert into t1 select A.a + 10 *(B.a + 10*C.a), A.a + 10 *(B.a + 10*C.a) from t0 This mustn't show "Using MRR": explain select * from t1 where a < 20 order by a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 Using index condition +1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` < 20) order by `test`.`t1`.`a` drop table t0, t1; @@ -425,7 +425,7 @@ EXPLAIN select count(length(a) + length(filler)) from t2 force index (k1) where a>='a-1000-a' and a <'a-1001-a'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range k1 k1 33 NULL 100 100.00 Using index condition; Using MRR +1 SIMPLE t2 NULL range k1 k1 33 NULL 100 100.00 Using MRR Warnings: Note 1003 /* select#1 */ select count((length(`test`.`t2`.`a`) + length(`test`.`t2`.`filler`))) AS `count(length(a) + length(filler))` from `test`.`t2` FORCE INDEX (`k1`) where ((`test`.`t2`.`a` >= 'a-1000-a') and (`test`.`t2`.`a` < 'a-1001-a')) select count(length(a) + length(filler)) @@ -439,7 +439,7 @@ filler char(10), key(d), primary key (a,b,c)) charset latin1; insert into t2 select A.a, B.a, B.a, A.a, 'filler' from t1 A, t1 B; explain select * from t2 force index (d) where d < 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range d d 5 NULL # 100.00 Using index condition +1 SIMPLE t2 NULL range d d 5 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2`.`filler` AS `filler` from `test`.`t2` FORCE INDEX (`d`) where (`test`.`t2`.`d` < 10) drop table t2; @@ -606,7 +606,7 @@ EXPLAIN SELECT i1 FROM t1 WHERE i2 > 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i2 i2 4 NULL 1 100.00 Using index condition +1 SIMPLE t1 NULL range i2 i2 4 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`i1` AS `i1` from `test`.`t1` where (`test`.`t1`.`i2` > 2) SELECT i1 @@ -755,7 +755,7 @@ REPEATABLE-READ START TRANSACTION; EXPLAIN SELECT * FROM t1 WHERE a > 2 FOR UPDATE; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`dummy` AS `dummy`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` > 2) SELECT * FROM t1 WHERE a > 2 FOR UPDATE; diff --git a/mysql-test/r/innodb_mrr_cost.result b/mysql-test/r/innodb_mrr_cost.result index d6f9986f0eb..cf55753a45a 100644 --- a/mysql-test/r/innodb_mrr_cost.result +++ b/mysql-test/r/innodb_mrr_cost.result @@ -406,7 +406,7 @@ insert into t1 select A.a + 10 *(B.a + 10*C.a), A.a + 10 *(B.a + 10*C.a) from t0 This mustn't show "Using MRR": explain select * from t1 where a < 20 order by a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 Using where +1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` < 20) order by `test`.`t1`.`a` drop table t0, t1; @@ -425,7 +425,7 @@ EXPLAIN select count(length(a) + length(filler)) from t2 force index (k1) where a>='a-1000-a' and a <'a-1001-a'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range k1 k1 33 NULL 100 100.00 Using where +1 SIMPLE t2 NULL range k1 k1 33 NULL 100 100.00 NULL Warnings: Note 1003 /* select#1 */ select count((length(`test`.`t2`.`a`) + length(`test`.`t2`.`filler`))) AS `count(length(a) + length(filler))` from `test`.`t2` FORCE INDEX (`k1`) where ((`test`.`t2`.`a` >= 'a-1000-a') and (`test`.`t2`.`a` < 'a-1001-a')) select count(length(a) + length(filler)) @@ -439,7 +439,7 @@ filler char(10), key(d), primary key (a,b,c)) charset latin1; insert into t2 select A.a, B.a, B.a, A.a, 'filler' from t1 A, t1 B; explain select * from t2 force index (d) where d < 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range d d 5 NULL # 100.00 Using where +1 SIMPLE t2 NULL range d d 5 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2`.`filler` AS `filler` from `test`.`t2` FORCE INDEX (`d`) where (`test`.`t2`.`d` < 10) drop table t2; @@ -606,7 +606,7 @@ EXPLAIN SELECT i1 FROM t1 WHERE i2 > 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i2 i2 4 NULL 1 100.00 Using where +1 SIMPLE t1 NULL range i2 i2 4 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`i1` AS `i1` from `test`.`t1` where (`test`.`t1`.`i2` > 2) SELECT i1 @@ -755,7 +755,7 @@ REPEATABLE-READ START TRANSACTION; EXPLAIN SELECT * FROM t1 WHERE a > 2 FOR UPDATE; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`dummy` AS `dummy`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` > 2) SELECT * FROM t1 WHERE a > 2 FOR UPDATE; diff --git a/mysql-test/r/innodb_mrr_cost_all.result b/mysql-test/r/innodb_mrr_cost_all.result index d6175210c5a..4e1acee826b 100644 --- a/mysql-test/r/innodb_mrr_cost_all.result +++ b/mysql-test/r/innodb_mrr_cost_all.result @@ -380,7 +380,7 @@ update t1 set b=repeat(char(65+a), 20) where a < 25; This must show range + using index condition: explain select * from t1 where a < 10 and b = repeat(char(65+a), 20); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL x x Using index condition; Using where +1 SIMPLE t1 NULL range a a 5 NULL x x Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`filler` AS `filler` from `test`.`t1` where ((`test`.`t1`.`a` < 10) and (`test`.`t1`.`b` = repeat(char((65 + `test`.`t1`.`a`)),20))) select * from t1 where a < 10 and b = repeat(char(65+a), 20); @@ -406,7 +406,7 @@ insert into t1 select A.a + 10 *(B.a + 10*C.a), A.a + 10 *(B.a + 10*C.a) from t0 This mustn't show "Using MRR": explain select * from t1 where a < 20 order by a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 Using index condition +1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` < 20) order by `test`.`t1`.`a` drop table t0, t1; @@ -425,7 +425,7 @@ EXPLAIN select count(length(a) + length(filler)) from t2 force index (k1) where a>='a-1000-a' and a <'a-1001-a'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range k1 k1 33 NULL 100 100.00 Using index condition +1 SIMPLE t2 NULL range k1 k1 33 NULL 100 100.00 NULL Warnings: Note 1003 /* select#1 */ select count((length(`test`.`t2`.`a`) + length(`test`.`t2`.`filler`))) AS `count(length(a) + length(filler))` from `test`.`t2` FORCE INDEX (`k1`) where ((`test`.`t2`.`a` >= 'a-1000-a') and (`test`.`t2`.`a` < 'a-1001-a')) select count(length(a) + length(filler)) @@ -439,7 +439,7 @@ filler char(10), key(d), primary key (a,b,c)) charset latin1; insert into t2 select A.a, B.a, B.a, A.a, 'filler' from t1 A, t1 B; explain select * from t2 force index (d) where d < 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range d d 5 NULL # 100.00 Using index condition +1 SIMPLE t2 NULL range d d 5 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2`.`filler` AS `filler` from `test`.`t2` FORCE INDEX (`d`) where (`test`.`t2`.`d` < 10) drop table t2; @@ -606,7 +606,7 @@ EXPLAIN SELECT i1 FROM t1 WHERE i2 > 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i2 i2 4 NULL 1 100.00 Using index condition +1 SIMPLE t1 NULL range i2 i2 4 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`i1` AS `i1` from `test`.`t1` where (`test`.`t1`.`i2` > 2) SELECT i1 @@ -755,7 +755,7 @@ REPEATABLE-READ START TRANSACTION; EXPLAIN SELECT * FROM t1 WHERE a > 2 FOR UPDATE; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`dummy` AS `dummy`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` > 2) SELECT * FROM t1 WHERE a > 2 FOR UPDATE; diff --git a/mysql-test/r/innodb_mrr_cost_icp.result b/mysql-test/r/innodb_mrr_cost_icp.result index 7f0cb638068..153e217fa6a 100644 --- a/mysql-test/r/innodb_mrr_cost_icp.result +++ b/mysql-test/r/innodb_mrr_cost_icp.result @@ -1,3 +1,4 @@ +set empty_redundant_check_in_range_scan=false; set optimizer_switch='index_condition_pushdown=on,mrr=on,mrr_cost_based=on'; set @save_storage_engine= @@default_storage_engine; set default_storage_engine=InnoDB; @@ -755,7 +756,7 @@ REPEATABLE-READ START TRANSACTION; EXPLAIN SELECT * FROM t1 WHERE a > 2 FOR UPDATE; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`dummy` AS `dummy`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` > 2) SELECT * FROM t1 WHERE a > 2 FOR UPDATE; @@ -789,3 +790,4 @@ DROP TABLE t1; COMMIT; set default_storage_engine= @save_storage_engine; set optimizer_switch=default; +set empty_redundant_check_in_range_scan=true; diff --git a/mysql-test/r/innodb_mrr_icp.result b/mysql-test/r/innodb_mrr_icp.result index 8077118389e..2ff63d070a1 100644 --- a/mysql-test/r/innodb_mrr_icp.result +++ b/mysql-test/r/innodb_mrr_icp.result @@ -1,6 +1,7 @@ set optimizer_switch='index_condition_pushdown=on,mrr=on,mrr_cost_based=off'; set @save_storage_engine= @@default_storage_engine; set default_storage_engine=InnoDB; +set empty_redundant_check_in_range_scan=false; create table t1(a int) charset utf8mb4; show create table t1; Table Create Table @@ -755,7 +756,7 @@ REPEATABLE-READ START TRANSACTION; EXPLAIN SELECT * FROM t1 WHERE a > 2 FOR UPDATE; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`dummy` AS `dummy`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` > 2) SELECT * FROM t1 WHERE a > 2 FOR UPDATE; @@ -787,5 +788,6 @@ ROLLBACK; ROLLBACK; DROP TABLE t1; COMMIT; +set empty_redundant_check_in_range_scan=true; set default_storage_engine= @save_storage_engine; set optimizer_switch=default; diff --git a/mysql-test/r/innodb_mrr_none.result b/mysql-test/r/innodb_mrr_none.result index 69e99d19609..e3ab420a2ba 100644 --- a/mysql-test/r/innodb_mrr_none.result +++ b/mysql-test/r/innodb_mrr_none.result @@ -405,7 +405,7 @@ insert into t1 select A.a + 10 *(B.a + 10*C.a), A.a + 10 *(B.a + 10*C.a) from t0 This mustn't show "Using MRR": explain select * from t1 where a < 20 order by a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 Using where +1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` < 20) order by `test`.`t1`.`a` drop table t0, t1; @@ -424,7 +424,7 @@ EXPLAIN select count(length(a) + length(filler)) from t2 force index (k1) where a>='a-1000-a' and a <'a-1001-a'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range k1 k1 33 NULL 100 100.00 Using where +1 SIMPLE t2 NULL range k1 k1 33 NULL 100 100.00 NULL Warnings: Note 1003 /* select#1 */ select count((length(`test`.`t2`.`a`) + length(`test`.`t2`.`filler`))) AS `count(length(a) + length(filler))` from `test`.`t2` FORCE INDEX (`k1`) where ((`test`.`t2`.`a` >= 'a-1000-a') and (`test`.`t2`.`a` < 'a-1001-a')) select count(length(a) + length(filler)) @@ -438,7 +438,7 @@ filler char(10), key(d), primary key (a,b,c)) charset latin1; insert into t2 select A.a, B.a, B.a, A.a, 'filler' from t1 A, t1 B; explain select * from t2 force index (d) where d < 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range d d 5 NULL # 100.00 Using where +1 SIMPLE t2 NULL range d d 5 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2`.`filler` AS `filler` from `test`.`t2` FORCE INDEX (`d`) where (`test`.`t2`.`d` < 10) drop table t2; @@ -605,7 +605,7 @@ EXPLAIN SELECT i1 FROM t1 WHERE i2 > 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i2 i2 4 NULL 1 100.00 Using where +1 SIMPLE t1 NULL range i2 i2 4 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`i1` AS `i1` from `test`.`t1` where (`test`.`t1`.`i2` > 2) SELECT i1 @@ -754,7 +754,7 @@ REPEATABLE-READ START TRANSACTION; EXPLAIN SELECT * FROM t1 WHERE a > 2 FOR UPDATE; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`dummy` AS `dummy`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` > 2) SELECT * FROM t1 WHERE a > 2 FOR UPDATE; diff --git a/mysql-test/r/innodb_pk_extension_off.result b/mysql-test/r/innodb_pk_extension_off.result index 86bf967cbf5..27ce1adf087 100644 --- a/mysql-test/r/innodb_pk_extension_off.result +++ b/mysql-test/r/innodb_pk_extension_off.result @@ -216,7 +216,7 @@ Handler_read_rnd_next 0 # EXPLAIN SELECT MIN(pk_1) FROM t1 WHERE f2 BETWEEN 13 AND 14 GROUP BY f2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range k2 k2 5 NULL # 100.00 Using where; Using index +1 SIMPLE t1 NULL range k2 k2 5 NULL # 100.00 Using index Warnings: Note 1003 /* select#1 */ select min(`test`.`t1`.`pk_1`) AS `MIN(pk_1)` from `test`.`t1` where (`test`.`t1`.`f2` between 13 and 14) group by `test`.`t1`.`f2` FLUSH STATUS; diff --git a/mysql-test/r/innodb_pk_extension_on.result b/mysql-test/r/innodb_pk_extension_on.result index 4bb99bc2b30..d0810208b1c 100644 --- a/mysql-test/r/innodb_pk_extension_on.result +++ b/mysql-test/r/innodb_pk_extension_on.result @@ -97,7 +97,7 @@ Handler_read_rnd_next 0 # EXPLAIN SELECT count(*) FROM t1 WHERE pk_1 BETWEEN 3 AND 5 AND f1 = '2000-01-03'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,k1 k1 10 NULL # 100.00 Using where; Using index +1 SIMPLE t1 NULL range PRIMARY,k1 k1 10 NULL # 100.00 Using index Warnings: Note 1003 /* select#1 */ select count(0) AS `count(*)` from `test`.`t1` where ((`test`.`t1`.`f1` = TIMESTAMP'2000-01-03 00:00:00') and (`test`.`t1`.`pk_1` between 3 and 5)) FLUSH STATUS; @@ -115,7 +115,7 @@ Handler_read_rnd 0 Handler_read_rnd_next 0 EXPLAIN SELECT pk_1, pk_2 FROM t1 WHERE pk_1 BETWEEN 3 AND 5 AND f1 = '2000-01-03'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,k1 k1 10 NULL # 100.00 Using where; Using index +1 SIMPLE t1 NULL range PRIMARY,k1 k1 10 NULL # 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk_1` AS `pk_1`,`test`.`t1`.`pk_2` AS `pk_2` from `test`.`t1` where ((`test`.`t1`.`f1` = TIMESTAMP'2000-01-03 00:00:00') and (`test`.`t1`.`pk_1` between 3 and 5)) FLUSH STATUS; @@ -310,7 +310,7 @@ Handler_read_rnd_next 0 EXPLAIN SELECT f1, pk_1, pk_2 FROM t1 WHERE pk_1 BETWEEN 3 AND 5 AND f1 = '2000-01-03' ORDER BY pk_2 DESC LIMIT 5; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,k1 k1 10 NULL # 100.00 Using where; Using index; Using filesort +1 SIMPLE t1 NULL range PRIMARY,k1 k1 10 NULL # 100.00 Using index; Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`pk_1` AS `pk_1`,`test`.`t1`.`pk_2` AS `pk_2` from `test`.`t1` where ((`test`.`t1`.`f1` = TIMESTAMP'2000-01-03 00:00:00') and (`test`.`t1`.`pk_1` between 3 and 5)) order by `test`.`t1`.`pk_2` desc limit 5 FLUSH STATUS; diff --git a/mysql-test/r/invisible_indexes.result b/mysql-test/r/invisible_indexes.result index 7cacc8f2f8c..1e844678790 100644 --- a/mysql-test/r/invisible_indexes.result +++ b/mysql-test/r/invisible_indexes.result @@ -526,7 +526,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` SELECT @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on EXPLAIN SELECT a FROM t1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL X 100.00 NULL @@ -540,7 +540,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` SELECT @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on EXPLAIN SELECT a FROM t1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL X 100.00 NULL @@ -548,7 +548,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` SELECT @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=on,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=on,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on SET @@optimizer_switch='use_invisible_indexes=off'; EXPLAIN SELECT a FROM t1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra diff --git a/mysql-test/r/join_cache_bka.result b/mysql-test/r/join_cache_bka.result index 9d508436771..048790f0aef 100644 --- a/mysql-test/r/join_cache_bka.result +++ b/mysql-test/r/join_cache_bka.result @@ -1064,7 +1064,7 @@ EXPLAIN SELECT city.Name, country.Name FROM city,country WHERE city.country=country.Code AND city.Population > 3000000; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE city NULL range Population,Country Population 4 NULL # 100.00 Using index condition; Using MRR +1 SIMPLE city NULL range Population,Country Population 4 NULL # 100.00 Using MRR 1 SIMPLE country NULL eq_ref PRIMARY PRIMARY 12 world.city.Country # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `world`.`city`.`Name` AS `Name`,`world`.`country`.`Name` AS `Name` from `world`.`city` join `world`.`country` where ((`world`.`country`.`Code` = `world`.`city`.`Country`) and (`world`.`city`.`Population` > 3000000)) @@ -1496,7 +1496,7 @@ test.t1 analyze status OK test.t2 analyze status OK EXPLAIN SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b >= 30; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx idx 5 NULL 3 100.00 Using index condition; Using where; Using MRR +1 SIMPLE t1 NULL range idx idx 5 NULL 3 100.00 Using where; Using MRR 1 SIMPLE t2 NULL ref idx idx 5 test.t1.a 2 100.00 Using join buffer (Batched Key Access) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t1`.`b` >= 30)) diff --git a/mysql-test/r/join_cache_bka_nobnl.result b/mysql-test/r/join_cache_bka_nobnl.result index 2d99d236b72..4b6f1360880 100644 --- a/mysql-test/r/join_cache_bka_nobnl.result +++ b/mysql-test/r/join_cache_bka_nobnl.result @@ -1064,7 +1064,7 @@ EXPLAIN SELECT city.Name, country.Name FROM city,country WHERE city.country=country.Code AND city.Population > 3000000; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE city NULL range Population,Country Population 4 NULL # 100.00 Using index condition; Using MRR +1 SIMPLE city NULL range Population,Country Population 4 NULL # 100.00 Using MRR 1 SIMPLE country NULL eq_ref PRIMARY PRIMARY 12 world.city.Country # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `world`.`city`.`Name` AS `Name`,`world`.`country`.`Name` AS `Name` from `world`.`city` join `world`.`country` where ((`world`.`country`.`Code` = `world`.`city`.`Country`) and (`world`.`city`.`Population` > 3000000)) @@ -1496,7 +1496,7 @@ test.t1 analyze status OK test.t2 analyze status OK EXPLAIN SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b >= 30; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx idx 5 NULL 3 100.00 Using index condition; Using where; Using MRR +1 SIMPLE t1 NULL range idx idx 5 NULL 3 100.00 Using where; Using MRR 1 SIMPLE t2 NULL ref idx idx 5 test.t1.a 2 100.00 Using join buffer (Batched Key Access) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t1`.`b` >= 30)) diff --git a/mysql-test/r/join_cache_bnl.result b/mysql-test/r/join_cache_bnl.result index 91c2b945540..b1e78aa342a 100644 --- a/mysql-test/r/join_cache_bnl.result +++ b/mysql-test/r/join_cache_bnl.result @@ -1065,7 +1065,7 @@ EXPLAIN SELECT city.Name, country.Name FROM city,country WHERE city.country=country.Code AND city.Population > 3000000; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE city NULL range Population,Country Population 4 NULL # 100.00 Using index condition; Using MRR +1 SIMPLE city NULL range Population,Country Population 4 NULL # 100.00 Using MRR 1 SIMPLE country NULL eq_ref PRIMARY PRIMARY 12 world.city.Country # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `world`.`city`.`Name` AS `Name`,`world`.`country`.`Name` AS `Name` from `world`.`city` join `world`.`country` where ((`world`.`country`.`Code` = `world`.`city`.`Country`) and (`world`.`city`.`Population` > 3000000)) @@ -1497,7 +1497,7 @@ test.t1 analyze status OK test.t2 analyze status OK EXPLAIN SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b >= 30; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx idx 5 NULL 3 100.00 Using index condition; Using where; Using MRR +1 SIMPLE t1 NULL range idx idx 5 NULL 3 100.00 Using where; Using MRR 1 SIMPLE t2 NULL ref idx idx 5 test.t1.a 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t1`.`b` >= 30)) diff --git a/mysql-test/r/join_cache_nojb.result b/mysql-test/r/join_cache_nojb.result index b49d7674beb..3a7e00ae541 100644 --- a/mysql-test/r/join_cache_nojb.result +++ b/mysql-test/r/join_cache_nojb.result @@ -1065,7 +1065,7 @@ EXPLAIN SELECT city.Name, country.Name FROM city,country WHERE city.country=country.Code AND city.Population > 3000000; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE city NULL range Population,Country Population 4 NULL # 100.00 Using index condition; Using MRR +1 SIMPLE city NULL range Population,Country Population 4 NULL # 100.00 Using MRR 1 SIMPLE country NULL eq_ref PRIMARY PRIMARY 12 world.city.Country # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `world`.`city`.`Name` AS `Name`,`world`.`country`.`Name` AS `Name` from `world`.`city` join `world`.`country` where ((`world`.`country`.`Code` = `world`.`city`.`Country`) and (`world`.`city`.`Population` > 3000000)) @@ -1497,7 +1497,7 @@ test.t1 analyze status OK test.t2 analyze status OK EXPLAIN SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b >= 30; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx idx 5 NULL 3 100.00 Using index condition; Using where; Using MRR +1 SIMPLE t1 NULL range idx idx 5 NULL 3 100.00 Using where; Using MRR 1 SIMPLE t2 NULL ref idx idx 5 test.t1.a 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t1`.`b` >= 30)) diff --git a/mysql-test/r/limit.result b/mysql-test/r/limit.result index ffb90e2aa0f..4a4b0bd9e0c 100644 --- a/mysql-test/r/limit.result +++ b/mysql-test/r/limit.result @@ -22,7 +22,7 @@ a 16 EXPLAIN FORMAT=TREE SELECT * FROM t1 LIMIT 5 OFFSET 1; EXPLAIN --> Limit/Offset: 5/1 row(s) (cost=1.15 rows=5) +-> Limit/Offset: 5/1 row(s), with offset pushdown (cost=1.15 rows=5) -> Table scan on t1 (cost=1.15 rows=9) (SELECT * FROM t1 LIMIT 7) ORDER BY a DESC LIMIT 4; diff --git a/mysql-test/r/merge_myisam.result b/mysql-test/r/merge_myisam.result index 68870b06f81..cb2f1f52eab 100644 --- a/mysql-test/r/merge_myisam.result +++ b/mysql-test/r/merge_myisam.result @@ -36,12 +36,12 @@ insert into t1 select NULL,message from t2; create table t3 (a int not null, b char(20), key(a)) engine=MERGE UNION=(test.t1,test.t2); explain select * from t3 where a < 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range a a 4 NULL 18 100.00 Using where +1 SIMPLE t3 NULL range a a 4 NULL 18 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where (`test`.`t3`.`a` < 10) explain select * from t3 where a > 10 and a < 20; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range a a 4 NULL 17 100.00 Using where +1 SIMPLE t3 NULL range a a 4 NULL 17 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where ((`test`.`t3`.`a` > 10) and (`test`.`t3`.`a` < 20)) select * from t3 where a = 10; @@ -688,19 +688,19 @@ Warning 1681 Integer display width is deprecated and will be removed in a future EXPLAIN SELECT * FROM t2 IGNORE INDEX (files) WHERE fileset_id = 2 AND file_code BETWEEN '0000000115' AND '0000000120' LIMIT 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 131 NULL 5 100.00 Using where +1 SIMPLE t2 NULL range PRIMARY PRIMARY 131 NULL 5 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`fileset_id` AS `fileset_id`,`test`.`t2`.`file_code` AS `file_code`,`test`.`t2`.`fileset_root_id` AS `fileset_root_id` from `test`.`t2` IGNORE INDEX (`files`) where ((`test`.`t2`.`fileset_id` = 2) and (`test`.`t2`.`file_code` between '0000000115' and '0000000120')) limit 1 EXPLAIN SELECT * FROM t2 WHERE fileset_id = 2 AND file_code BETWEEN '0000000115' AND '0000000120' LIMIT 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY,files PRIMARY 131 NULL 5 100.00 Using where +1 SIMPLE t2 NULL range PRIMARY,files PRIMARY 131 NULL 5 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`fileset_id` AS `fileset_id`,`test`.`t2`.`file_code` AS `file_code`,`test`.`t2`.`fileset_root_id` AS `fileset_root_id` from `test`.`t2` where ((`test`.`t2`.`fileset_id` = 2) and (`test`.`t2`.`file_code` between '0000000115' and '0000000120')) limit 1 EXPLAIN SELECT * FROM t1 WHERE fileset_id = 2 AND file_code BETWEEN '0000000115' AND '0000000120' LIMIT 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,files PRIMARY 131 NULL 5 100.00 Using index condition +1 SIMPLE t1 NULL range PRIMARY,files PRIMARY 131 NULL 5 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`fileset_id` AS `fileset_id`,`test`.`t1`.`file_code` AS `file_code`,`test`.`t1`.`fileset_root_id` AS `fileset_root_id` from `test`.`t1` where ((`test`.`t1`.`fileset_id` = 2) and (`test`.`t1`.`file_code` between '0000000115' and '0000000120')) limit 1 EXPLAIN SELECT * FROM t2 WHERE fileset_id = 2 diff --git a/mysql-test/r/mix2_myisam.result b/mysql-test/r/mix2_myisam.result index 106df3ffc79..ac03ab21488 100644 --- a/mysql-test/r/mix2_myisam.result +++ b/mysql-test/r/mix2_myisam.result @@ -1221,13 +1221,13 @@ count(*) 29267 explain select * from t1 where c between 1 and 2500; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range c c 5 NULL # 100.00 Using index condition +1 SIMPLE t1 NULL range c c 5 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (`test`.`t1`.`c` between 1 and 2500) update t1 set c=a; explain select * from t1 where c between 1 and 2500; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range c c 5 NULL # 100.00 Using index condition +1 SIMPLE t1 NULL range c c 5 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (`test`.`t1`.`c` between 1 and 2500) drop table t1,t2; diff --git a/mysql-test/r/myisam_explain_json_non_select_all.result b/mysql-test/r/myisam_explain_json_non_select_all.result index 80a34e8962b..f26697abbb7 100644 --- a/mysql-test/r/myisam_explain_json_non_select_all.result +++ b/mysql-test/r/myisam_explain_json_non_select_all.result @@ -1743,7 +1743,6 @@ EXPLAIN "rows_examined_per_scan": 1, "rows_produced_per_join": 1, "filtered": "100.00", - "index_condition": "(`test`.`t1`.`a` < 3)", "using_MRR": true, "cost_info": { "read_cost": "0.60", @@ -3531,7 +3530,6 @@ EXPLAIN "rows_examined_per_scan": 8, "rows_produced_per_join": 8, "filtered": "100.00", - "index_condition": "((`test`.`t1`.`i` > 10) and (`test`.`t1`.`i` <= 18))", "cost_info": { "read_cost": "1.46", "eval_cost": "0.80", @@ -4262,7 +4260,6 @@ EXPLAIN "rows_examined_per_scan": 8, "rows_produced_per_join": 8, "filtered": "100.00", - "index_condition": "((`test`.`t2`.`i` > 10) and (`test`.`t2`.`i` <= 18))", "backward_index_scan": true, "cost_info": { "read_cost": "1.46", @@ -4564,7 +4561,6 @@ EXPLAIN "rows_examined_per_scan": 8, "rows_produced_per_join": 8, "filtered": "100.00", - "index_condition": "((`test`.`t2`.`i` > 10) and (`test`.`t2`.`i` <= 18))", "cost_info": { "read_cost": "1.46", "eval_cost": "0.80", @@ -5299,7 +5295,6 @@ EXPLAIN "rows_examined_per_scan": 8, "rows_produced_per_join": 8, "filtered": "100.00", - "index_condition": "((`test`.`t2`.`i` > 10) and (`test`.`t2`.`i` <= 18))", "backward_index_scan": true, "cost_info": { "read_cost": "1.46", @@ -5830,8 +5825,7 @@ EXPLAIN } /* cost_info */, "used_columns": [ "a" - ] /* used_columns */, - "attached_condition": "(`test`.`t1`.`a` > 34)" + ] /* used_columns */ } /* table */ } /* query_block */ } @@ -6716,8 +6710,7 @@ EXPLAIN } /* cost_info */, "used_columns": [ "a" - ] /* used_columns */, - "attached_condition": "(`test`.`t1`.`a` < 4)" + ] /* used_columns */ } /* table */ } /* query_block */ } @@ -8059,8 +8052,7 @@ EXPLAIN } /* cost_info */, "used_columns": [ "a" - ] /* used_columns */, - "attached_condition": "(`test`.`t1`.`a` > 10)" + ] /* used_columns */ } /* table */ } /* query_block */ } @@ -8158,8 +8150,7 @@ EXPLAIN } /* cost_info */, "used_columns": [ "a" - ] /* used_columns */, - "attached_condition": "(`test`.`t1`.`a` > 10)" + ] /* used_columns */ } /* table */ } /* ordering_operation */ } /* query_block */ diff --git a/mysql-test/r/myisam_explain_json_non_select_none.result b/mysql-test/r/myisam_explain_json_non_select_none.result index aa661f8cb7f..18b6b4a8f37 100644 --- a/mysql-test/r/myisam_explain_json_non_select_none.result +++ b/mysql-test/r/myisam_explain_json_non_select_none.result @@ -1758,8 +1758,7 @@ EXPLAIN "used_columns": [ "a", "b" - ] /* used_columns */, - "attached_condition": "(`test`.`t1`.`a` < 3)" + ] /* used_columns */ } /* table */ } /* query_block */ } @@ -3528,8 +3527,7 @@ EXPLAIN "used_columns": [ "a", "i" - ] /* used_columns */, - "attached_condition": "((`test`.`t1`.`i` > 10) and (`test`.`t1`.`i` <= 18))" + ] /* used_columns */ } /* table */ } /* ordering_operation */ } /* query_block */ @@ -4260,8 +4258,7 @@ EXPLAIN "used_columns": [ "a", "i" - ] /* used_columns */, - "attached_condition": "((`test`.`t2`.`i` > 10) and (`test`.`t2`.`i` <= 18))" + ] /* used_columns */ } /* table */ } /* ordering_operation */ } /* query_block */ @@ -4561,8 +4558,7 @@ EXPLAIN "used_columns": [ "a", "i" - ] /* used_columns */, - "attached_condition": "((`test`.`t2`.`i` > 10) and (`test`.`t2`.`i` <= 18))" + ] /* used_columns */ } /* table */ } /* ordering_operation */ } /* query_block */ @@ -5297,8 +5293,7 @@ EXPLAIN "used_columns": [ "a", "i" - ] /* used_columns */, - "attached_condition": "((`test`.`t2`.`i` > 10) and (`test`.`t2`.`i` <= 18))" + ] /* used_columns */ } /* table */ } /* ordering_operation */ } /* query_block */ @@ -5818,8 +5813,7 @@ EXPLAIN } /* cost_info */, "used_columns": [ "a" - ] /* used_columns */, - "attached_condition": "(`test`.`t1`.`a` > 34)" + ] /* used_columns */ } /* table */ } /* query_block */ } @@ -6704,8 +6698,7 @@ EXPLAIN } /* cost_info */, "used_columns": [ "a" - ] /* used_columns */, - "attached_condition": "(`test`.`t1`.`a` < 4)" + ] /* used_columns */ } /* table */ } /* query_block */ } @@ -8080,8 +8073,7 @@ EXPLAIN } /* cost_info */, "used_columns": [ "a" - ] /* used_columns */, - "attached_condition": "(`test`.`t1`.`a` > 10)" + ] /* used_columns */ } /* table */ } /* query_block */ } @@ -8179,8 +8171,7 @@ EXPLAIN } /* cost_info */, "used_columns": [ "a" - ] /* used_columns */, - "attached_condition": "(`test`.`t1`.`a` > 10)" + ] /* used_columns */ } /* table */ } /* ordering_operation */ } /* query_block */ diff --git a/mysql-test/r/myisam_icp.result b/mysql-test/r/myisam_icp.result index 648b9d16824..30d16622641 100644 --- a/mysql-test/r/myisam_icp.result +++ b/mysql-test/r/myisam_icp.result @@ -1,6 +1,8 @@ +set empty_redundant_check_in_range_scan=false; set optimizer_switch='index_condition_pushdown=on'; # Bug#36981 - "innodb crash when selecting for update" # +SET empty_redundant_check_in_range_scan=false; CREATE TABLE t1 ( c1 CHAR(1), c2 CHAR(10), @@ -1115,3 +1117,4 @@ i1 i2 DROP FUNCTION f1; DROP TABLE t1, t2; set optimizer_switch=default; +set empty_redundant_check_in_range_scan=true; diff --git a/mysql-test/r/myisam_icp_all.result b/mysql-test/r/myisam_icp_all.result index e044f8bf7d1..77673d6f887 100644 --- a/mysql-test/r/myisam_icp_all.result +++ b/mysql-test/r/myisam_icp_all.result @@ -1,6 +1,8 @@ set optimizer_switch='semijoin=on,materialization=on,firstmatch=on,loosescan=on,index_condition_pushdown=on,mrr=on'; +set empty_redundant_check_in_range_scan=false; # Bug#36981 - "innodb crash when selecting for update" # +SET empty_redundant_check_in_range_scan=false; CREATE TABLE t1 ( c1 CHAR(1), c2 CHAR(10), @@ -1114,4 +1116,5 @@ i1 i2 5 5 DROP FUNCTION f1; DROP TABLE t1, t2; +set empty_redundant_check_in_range_scan=true; set optimizer_switch=default; diff --git a/mysql-test/r/myisam_icp_none.result b/mysql-test/r/myisam_icp_none.result index 8df90766e9e..8de986f6233 100644 --- a/mysql-test/r/myisam_icp_none.result +++ b/mysql-test/r/myisam_icp_none.result @@ -1,5 +1,6 @@ # Bug#36981 - "innodb crash when selecting for update" # +SET empty_redundant_check_in_range_scan=false; CREATE TABLE t1 ( c1 CHAR(1), c2 CHAR(10), diff --git a/mysql-test/r/myisam_mrr.result b/mysql-test/r/myisam_mrr.result index 1a5f4abd613..6d46f11d4ce 100644 --- a/mysql-test/r/myisam_mrr.result +++ b/mysql-test/r/myisam_mrr.result @@ -409,7 +409,7 @@ insert into t1 select A.a + 10 *(B.a + 10*C.a), A.a + 10 *(B.a + 10*C.a) from t0 This mustn't show "Using MRR": explain select * from t1 where a < 20 order by a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 Using where +1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` < 20) order by `test`.`t1`.`a` drop table t0, t1; @@ -428,7 +428,7 @@ EXPLAIN select count(length(a) + length(filler)) from t2 force index (k1) where a>='a-1000-a' and a <'a-1001-a'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range k1 k1 33 NULL 96 100.00 Using where; Using MRR +1 SIMPLE t2 NULL range k1 k1 33 NULL 96 100.00 Using MRR Warnings: Note 1003 /* select#1 */ select count((length(`test`.`t2`.`a`) + length(`test`.`t2`.`filler`))) AS `count(length(a) + length(filler))` from `test`.`t2` FORCE INDEX (`k1`) where ((`test`.`t2`.`a` >= 'a-1000-a') and (`test`.`t2`.`a` < 'a-1001-a')) select count(length(a) + length(filler)) @@ -442,7 +442,7 @@ filler char(10), key(d), primary key (a,b,c)) charset latin1; insert into t2 select A.a, B.a, B.a, A.a, 'filler' from t1 A, t1 B; explain select * from t2 force index (d) where d < 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range d d 5 NULL # 100.00 Using where; Using MRR +1 SIMPLE t2 NULL range d d 5 NULL # 100.00 Using MRR Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2`.`filler` AS `filler` from `test`.`t2` FORCE INDEX (`d`) where (`test`.`t2`.`d` < 10) drop table t2; @@ -609,7 +609,7 @@ EXPLAIN SELECT i1 FROM t1 WHERE i2 > 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i2 i2 4 NULL 2 100.00 Using where +1 SIMPLE t1 NULL range i2 i2 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`i1` AS `i1` from `test`.`t1` where (`test`.`t1`.`i2` > 2) SELECT i1 diff --git a/mysql-test/r/myisam_mrr_all.result b/mysql-test/r/myisam_mrr_all.result index 0b185c3bbbe..da14d7299a9 100644 --- a/mysql-test/r/myisam_mrr_all.result +++ b/mysql-test/r/myisam_mrr_all.result @@ -383,7 +383,7 @@ update t1 set b=repeat(char(65+a), 20) where a < 25; This must show range + using index condition: explain select * from t1 where a < 10 and b = repeat(char(65+a), 20); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL x x Using index condition; Using where +1 SIMPLE t1 NULL range a a 5 NULL x x Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`filler` AS `filler` from `test`.`t1` where ((`test`.`t1`.`a` < 10) and (`test`.`t1`.`b` = repeat(char((65 + `test`.`t1`.`a`)),20))) select * from t1 where a < 10 and b = repeat(char(65+a), 20); @@ -409,7 +409,7 @@ insert into t1 select A.a + 10 *(B.a + 10*C.a), A.a + 10 *(B.a + 10*C.a) from t0 This mustn't show "Using MRR": explain select * from t1 where a < 20 order by a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 Using index condition +1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` < 20) order by `test`.`t1`.`a` drop table t0, t1; @@ -428,7 +428,7 @@ EXPLAIN select count(length(a) + length(filler)) from t2 force index (k1) where a>='a-1000-a' and a <'a-1001-a'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range k1 k1 33 NULL 96 100.00 Using index condition; Using MRR +1 SIMPLE t2 NULL range k1 k1 33 NULL 96 100.00 Using MRR Warnings: Note 1003 /* select#1 */ select count((length(`test`.`t2`.`a`) + length(`test`.`t2`.`filler`))) AS `count(length(a) + length(filler))` from `test`.`t2` FORCE INDEX (`k1`) where ((`test`.`t2`.`a` >= 'a-1000-a') and (`test`.`t2`.`a` < 'a-1001-a')) select count(length(a) + length(filler)) @@ -442,7 +442,7 @@ filler char(10), key(d), primary key (a,b,c)) charset latin1; insert into t2 select A.a, B.a, B.a, A.a, 'filler' from t1 A, t1 B; explain select * from t2 force index (d) where d < 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range d d 5 NULL # 100.00 Using index condition; Using MRR +1 SIMPLE t2 NULL range d d 5 NULL # 100.00 Using MRR Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2`.`filler` AS `filler` from `test`.`t2` FORCE INDEX (`d`) where (`test`.`t2`.`d` < 10) drop table t2; @@ -581,7 +581,7 @@ FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.pk > 176; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 2 100.00 NULL -1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 1 100.00 Using index condition; Using where; Using MRR +1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 1 100.00 Using where; Using MRR Warnings: Note 1003 /* select#1 */ select straight_join `test`.`t1`.`c1` AS `c1` from `test`.`t2` join `test`.`t1` where ((`test`.`t1`.`c1` = `test`.`t2`.`c1`) and (`test`.`t1`.`pk` > 176)) SELECT STRAIGHT_JOIN t1.c1 @@ -609,7 +609,7 @@ EXPLAIN SELECT i1 FROM t1 WHERE i2 > 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i2 i2 4 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range i2 i2 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`i1` AS `i1` from `test`.`t1` where (`test`.`t1`.`i2` > 2) SELECT i1 diff --git a/mysql-test/r/myisam_mrr_cost.result b/mysql-test/r/myisam_mrr_cost.result index a5eff1de857..4a94ede3b6e 100644 --- a/mysql-test/r/myisam_mrr_cost.result +++ b/mysql-test/r/myisam_mrr_cost.result @@ -409,7 +409,7 @@ insert into t1 select A.a + 10 *(B.a + 10*C.a), A.a + 10 *(B.a + 10*C.a) from t0 This mustn't show "Using MRR": explain select * from t1 where a < 20 order by a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 Using where +1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` < 20) order by `test`.`t1`.`a` drop table t0, t1; @@ -428,7 +428,7 @@ EXPLAIN select count(length(a) + length(filler)) from t2 force index (k1) where a>='a-1000-a' and a <'a-1001-a'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range k1 k1 33 NULL 96 100.00 Using where +1 SIMPLE t2 NULL range k1 k1 33 NULL 96 100.00 NULL Warnings: Note 1003 /* select#1 */ select count((length(`test`.`t2`.`a`) + length(`test`.`t2`.`filler`))) AS `count(length(a) + length(filler))` from `test`.`t2` FORCE INDEX (`k1`) where ((`test`.`t2`.`a` >= 'a-1000-a') and (`test`.`t2`.`a` < 'a-1001-a')) select count(length(a) + length(filler)) @@ -442,7 +442,7 @@ filler char(10), key(d), primary key (a,b,c)) charset latin1; insert into t2 select A.a, B.a, B.a, A.a, 'filler' from t1 A, t1 B; explain select * from t2 force index (d) where d < 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range d d 5 NULL # 100.00 Using where +1 SIMPLE t2 NULL range d d 5 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2`.`filler` AS `filler` from `test`.`t2` FORCE INDEX (`d`) where (`test`.`t2`.`d` < 10) drop table t2; @@ -609,7 +609,7 @@ EXPLAIN SELECT i1 FROM t1 WHERE i2 > 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i2 i2 4 NULL 2 100.00 Using where +1 SIMPLE t1 NULL range i2 i2 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`i1` AS `i1` from `test`.`t1` where (`test`.`t1`.`i2` > 2) SELECT i1 diff --git a/mysql-test/r/myisam_mrr_cost_all.result b/mysql-test/r/myisam_mrr_cost_all.result index b58120754e7..b8d34bee481 100644 --- a/mysql-test/r/myisam_mrr_cost_all.result +++ b/mysql-test/r/myisam_mrr_cost_all.result @@ -383,7 +383,7 @@ update t1 set b=repeat(char(65+a), 20) where a < 25; This must show range + using index condition: explain select * from t1 where a < 10 and b = repeat(char(65+a), 20); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL x x Using index condition; Using where +1 SIMPLE t1 NULL range a a 5 NULL x x Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`filler` AS `filler` from `test`.`t1` where ((`test`.`t1`.`a` < 10) and (`test`.`t1`.`b` = repeat(char((65 + `test`.`t1`.`a`)),20))) select * from t1 where a < 10 and b = repeat(char(65+a), 20); @@ -409,7 +409,7 @@ insert into t1 select A.a + 10 *(B.a + 10*C.a), A.a + 10 *(B.a + 10*C.a) from t0 This mustn't show "Using MRR": explain select * from t1 where a < 20 order by a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 Using index condition +1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` < 20) order by `test`.`t1`.`a` drop table t0, t1; @@ -428,7 +428,7 @@ EXPLAIN select count(length(a) + length(filler)) from t2 force index (k1) where a>='a-1000-a' and a <'a-1001-a'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range k1 k1 33 NULL 96 100.00 Using index condition +1 SIMPLE t2 NULL range k1 k1 33 NULL 96 100.00 NULL Warnings: Note 1003 /* select#1 */ select count((length(`test`.`t2`.`a`) + length(`test`.`t2`.`filler`))) AS `count(length(a) + length(filler))` from `test`.`t2` FORCE INDEX (`k1`) where ((`test`.`t2`.`a` >= 'a-1000-a') and (`test`.`t2`.`a` < 'a-1001-a')) select count(length(a) + length(filler)) @@ -442,7 +442,7 @@ filler char(10), key(d), primary key (a,b,c)) charset latin1; insert into t2 select A.a, B.a, B.a, A.a, 'filler' from t1 A, t1 B; explain select * from t2 force index (d) where d < 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range d d 5 NULL # 100.00 Using index condition +1 SIMPLE t2 NULL range d d 5 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2`.`filler` AS `filler` from `test`.`t2` FORCE INDEX (`d`) where (`test`.`t2`.`d` < 10) drop table t2; @@ -581,7 +581,7 @@ FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1 WHERE t1.pk > 176; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 2 100.00 NULL -1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 1 100.00 Using index condition; Using where +1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 1 100.00 Using where Warnings: Note 1003 /* select#1 */ select straight_join `test`.`t1`.`c1` AS `c1` from `test`.`t2` join `test`.`t1` where ((`test`.`t1`.`c1` = `test`.`t2`.`c1`) and (`test`.`t1`.`pk` > 176)) SELECT STRAIGHT_JOIN t1.c1 @@ -609,7 +609,7 @@ EXPLAIN SELECT i1 FROM t1 WHERE i2 > 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i2 i2 4 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range i2 i2 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`i1` AS `i1` from `test`.`t1` where (`test`.`t1`.`i2` > 2) SELECT i1 diff --git a/mysql-test/r/myisam_mrr_cost_icp.result b/mysql-test/r/myisam_mrr_cost_icp.result index dd0b84a3478..43d94c168e4 100644 --- a/mysql-test/r/myisam_mrr_cost_icp.result +++ b/mysql-test/r/myisam_mrr_cost_icp.result @@ -4,6 +4,7 @@ set read_rnd_buffer_size=79; select @@read_rnd_buffer_size; @@read_rnd_buffer_size 79 +set empty_redundant_check_in_range_scan=false; create table t1(a int) charset utf8mb4; show create table t1; Table Create Table @@ -775,5 +776,6 @@ AND t2.pk IS NULL ORDER BY i1; i1 DROP TABLE t1, t2; +set empty_redundant_check_in_range_scan=true; set @@read_rnd_buffer_size= @read_rnd_buffer_size_save; set optimizer_switch=default; diff --git a/mysql-test/r/myisam_mrr_icp.result b/mysql-test/r/myisam_mrr_icp.result index 6eacd78fe10..6451a5cd163 100644 --- a/mysql-test/r/myisam_mrr_icp.result +++ b/mysql-test/r/myisam_mrr_icp.result @@ -1,4 +1,5 @@ set optimizer_switch='index_condition_pushdown=on,mrr=on,mrr_cost_based=off'; +set empty_redundant_check_in_range_scan=false; set @read_rnd_buffer_size_save= @@read_rnd_buffer_size; set read_rnd_buffer_size=79; select @@read_rnd_buffer_size; @@ -776,4 +777,5 @@ ORDER BY i1; i1 DROP TABLE t1, t2; set @@read_rnd_buffer_size= @read_rnd_buffer_size_save; +set empty_redundant_check_in_range_scan=true; set optimizer_switch=default; diff --git a/mysql-test/r/myisam_mrr_none.result b/mysql-test/r/myisam_mrr_none.result index 445e4773edf..1f99ef5ec79 100644 --- a/mysql-test/r/myisam_mrr_none.result +++ b/mysql-test/r/myisam_mrr_none.result @@ -408,7 +408,7 @@ insert into t1 select A.a + 10 *(B.a + 10*C.a), A.a + 10 *(B.a + 10*C.a) from t0 This mustn't show "Using MRR": explain select * from t1 where a < 20 order by a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 Using where +1 SIMPLE t1 NULL range a a 5 NULL 20 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` < 20) order by `test`.`t1`.`a` drop table t0, t1; @@ -427,7 +427,7 @@ EXPLAIN select count(length(a) + length(filler)) from t2 force index (k1) where a>='a-1000-a' and a <'a-1001-a'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range k1 k1 33 NULL 96 100.00 Using where +1 SIMPLE t2 NULL range k1 k1 33 NULL 96 100.00 NULL Warnings: Note 1003 /* select#1 */ select count((length(`test`.`t2`.`a`) + length(`test`.`t2`.`filler`))) AS `count(length(a) + length(filler))` from `test`.`t2` FORCE INDEX (`k1`) where ((`test`.`t2`.`a` >= 'a-1000-a') and (`test`.`t2`.`a` < 'a-1001-a')) select count(length(a) + length(filler)) @@ -441,7 +441,7 @@ filler char(10), key(d), primary key (a,b,c)) charset latin1; insert into t2 select A.a, B.a, B.a, A.a, 'filler' from t1 A, t1 B; explain select * from t2 force index (d) where d < 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range d d 5 NULL # 100.00 Using where +1 SIMPLE t2 NULL range d d 5 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2`.`filler` AS `filler` from `test`.`t2` FORCE INDEX (`d`) where (`test`.`t2`.`d` < 10) drop table t2; @@ -608,7 +608,7 @@ EXPLAIN SELECT i1 FROM t1 WHERE i2 > 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i2 i2 4 NULL 2 100.00 Using where +1 SIMPLE t1 NULL range i2 i2 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`i1` AS `i1` from `test`.`t1` where (`test`.`t1`.`i2` > 2) SELECT i1 diff --git a/mysql-test/r/mysqld--help-notwin.result b/mysql-test/r/mysqld--help-notwin.result index f9c0401ea1a..2fe69c27d35 100644 --- a/mysql-test/r/mysqld--help-notwin.result +++ b/mysql-test/r/mysqld--help-notwin.result @@ -350,6 +350,11 @@ The following options may be given as the first argument: before storage engine initialization, where each plugin is identified as name=library, where name is the plugin name and library is the plugin library in plugin_dir. + --empty-redundant-check-in-range-scan + From the condition evaluated at the SQL layer, remove any + comparison already evaluated by the range index scan + method in the storage engine + (Defaults to on; use --skip-empty-redundant-check-in-range-scan to disable.) --end-markers-in-json In JSON output ("EXPLAIN FORMAT=JSON" and optimizer trace), if variable is set to 1, repeats the structure's @@ -813,8 +818,8 @@ The following options may be given as the first argument: block_nested_loop, batched_key_access, use_index_extensions, condition_fanout_filter, derived_merge, hash_join, subquery_to_derived, - prefer_ordering_index, derived_condition_pushdown} and - val is one of {on, off, default} + prefer_ordering_index, derived_condition_pushdown, + offset_pushdown} and val is one of {on, off, default} --optimizer-trace=name Controls tracing of the Optimizer: optimizer_trace=option=val[,option=val...], where option @@ -1720,6 +1725,7 @@ disabled-storage-engines disconnect-on-expired-password TRUE disconnect-slave-event-count 0 div-precision-increment 4 +empty-redundant-check-in-range-scan TRUE end-markers-in-json FALSE enforce-gtid-consistency FALSE eq-range-index-dive-limit 200 @@ -1850,7 +1856,7 @@ old-style-user-limits FALSE optimizer-max-subgraph-pairs 100000 optimizer-prune-level 1 optimizer-search-depth 62 -optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on optimizer-trace optimizer-trace-features greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=on optimizer-trace-limit 1 diff --git a/mysql-test/r/negation_elimination.result b/mysql-test/r/negation_elimination.result index f42bfe1c6c6..b42e8cc7a5f 100644 --- a/mysql-test/r/negation_elimination.result +++ b/mysql-test/r/negation_elimination.result @@ -33,7 +33,7 @@ a 19 explain select * from t1 where not(not(not(a > 10))); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 11 100.00 Using where; Using index +1 SIMPLE t1 NULL range a a 5 NULL 11 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` <= 10) select * from t1 where not(not(not(a > 10))); @@ -51,7 +51,7 @@ a 10 explain select * from t1 where not(not(not(a < 5) and not(a > 10))); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 6 100.00 Using where; Using index +1 SIMPLE t1 NULL range a a 5 NULL 6 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` >= 5) and (`test`.`t1`.`a` <= 10)) select * from t1 where not(not(not(a < 5) and not(a > 10))); @@ -98,7 +98,7 @@ a 1 explain select * from t1 where not(a < 10); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 10 100.00 Using where; Using index +1 SIMPLE t1 NULL range a a 5 NULL 10 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` >= 10) select * from t1 where not(a < 10); @@ -115,7 +115,7 @@ a 19 explain select * from t1 where not(a >= 10); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 10 100.00 Using where; Using index +1 SIMPLE t1 NULL range a a 5 NULL 10 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < 10) select * from t1 where not(a >= 10); @@ -132,7 +132,7 @@ a 9 explain select * from t1 where not(a > 10); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 11 100.00 Using where; Using index +1 SIMPLE t1 NULL range a a 5 NULL 11 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` <= 10) select * from t1 where not(a > 10); @@ -150,7 +150,7 @@ a 10 explain select * from t1 where not(a <= 10); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 9 100.00 Using where; Using index +1 SIMPLE t1 NULL range a a 5 NULL 9 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > 10) select * from t1 where not(a <= 10); @@ -201,7 +201,7 @@ a NULL explain select * from t1 where not(a < 5 or a > 15); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 11 100.00 Using where; Using index +1 SIMPLE t1 NULL range a a 5 NULL 11 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` >= 5) and (`test`.`t1`.`a` <= 15)) select * from t1 where not(a < 5 or a > 15); @@ -255,7 +255,7 @@ a 19 explain select * from t1 where a > 5 and not(a > 10); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 5 100.00 Using where; Using index +1 SIMPLE t1 NULL range a a 5 NULL 5 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` > 5) and (`test`.`t1`.`a` <= 10)) select * from t1 where a > 5 and not(a > 10); @@ -346,7 +346,7 @@ a 19 explain select * from t1 where not(NULL and a > 5); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 6 100.00 Using where; Using index +1 SIMPLE t1 NULL range a a 5 NULL 6 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` <= 5) select * from t1 where not(NULL and a > 5); diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result index dca55791308..3f2b26f0691 100644 --- a/mysql-test/r/null.result +++ b/mysql-test/r/null.result @@ -167,12 +167,12 @@ Table Op Msg_type Msg_text test.t1 analyze status OK explain select * from t1 where a between 2 and 3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx idx 4 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range idx idx 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` between 2 and 3) explain select * from t1 where a between 2 and 3 or b is null; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx idx 4 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range idx idx 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` between 2 and 3) drop table t1; diff --git a/mysql-test/r/null_key_all_myisam.result b/mysql-test/r/null_key_all_myisam.result index 7d7ece29cd1..2aa1afe9268 100644 --- a/mysql-test/r/null_key_all_myisam.result +++ b/mysql-test/r/null_key_all_myisam.result @@ -61,12 +61,12 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (((`test`.`t1`.`b` = 9) and (`test`.`t1`.`a` is null)) or ((`test`.`t1`.`b` = 7) and (`test`.`t1`.`a` is null))) limit 3 explain select * from t1 where a > 1 and a < 3 limit 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 Using where; Using index +1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` > 1) and (`test`.`t1`.`a` < 3)) limit 1 explain select * from t1 where a > 8 and a < 9; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 Using where; Using index +1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` > 8) and (`test`.`t1`.`a` < 9)) select * from t1 where a is null; @@ -179,7 +179,7 @@ Warning 1739 Cannot use range access on index 'b' due to type or collation conve Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (((`test`.`t1`.`a` is null) and (`test`.`t1`.`b` = 9)) or ((`test`.`t1`.`a` is null) and (`test`.`t1`.`b` = 7))) limit 3 explain select * from t1 where a > 1 and a < 3 limit 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 Using where +1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`a` > 1) and (`test`.`t1`.`a` < 3)) limit 1 explain select * from t1 where a is null and b=7 or a > 1 and a < 3 limit 1; @@ -192,7 +192,7 @@ Warning 1739 Cannot use range access on index 'b' due to type or collation conve Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (((`test`.`t1`.`a` is null) and (`test`.`t1`.`b` = 7)) or ((`test`.`t1`.`a` > 1) and (`test`.`t1`.`a` < 3))) limit 1 explain select * from t1 where a > 8 and a < 9; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 Using where +1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`a` > 8) and (`test`.`t1`.`a` < 9)) explain select * from t1 where b like "6%"; diff --git a/mysql-test/r/null_key_icp_myisam.result b/mysql-test/r/null_key_icp_myisam.result index a7dc9812e64..b513096a340 100644 --- a/mysql-test/r/null_key_icp_myisam.result +++ b/mysql-test/r/null_key_icp_myisam.result @@ -61,12 +61,12 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (((`test`.`t1`.`b` = 9) and (`test`.`t1`.`a` is null)) or ((`test`.`t1`.`b` = 7) and (`test`.`t1`.`a` is null))) limit 3 explain select * from t1 where a > 1 and a < 3 limit 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 Using where; Using index +1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` > 1) and (`test`.`t1`.`a` < 3)) limit 1 explain select * from t1 where a > 8 and a < 9; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 Using where; Using index +1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` > 8) and (`test`.`t1`.`a` < 9)) select * from t1 where a is null; @@ -179,7 +179,7 @@ Warning 1739 Cannot use range access on index 'b' due to type or collation conve Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (((`test`.`t1`.`a` is null) and (`test`.`t1`.`b` = 9)) or ((`test`.`t1`.`a` is null) and (`test`.`t1`.`b` = 7))) limit 3 explain select * from t1 where a > 1 and a < 3 limit 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 Using where +1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`a` > 1) and (`test`.`t1`.`a` < 3)) limit 1 explain select * from t1 where a is null and b=7 or a > 1 and a < 3 limit 1; @@ -192,7 +192,7 @@ Warning 1739 Cannot use range access on index 'b' due to type or collation conve Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (((`test`.`t1`.`a` is null) and (`test`.`t1`.`b` = 7)) or ((`test`.`t1`.`a` > 1) and (`test`.`t1`.`a` < 3))) limit 1 explain select * from t1 where a > 8 and a < 9; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 Using where +1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`a` > 8) and (`test`.`t1`.`a` < 9)) explain select * from t1 where b like "6%"; diff --git a/mysql-test/r/null_key_none_myisam.result b/mysql-test/r/null_key_none_myisam.result index 5e8ddc5ab7a..0b16ec7d611 100644 --- a/mysql-test/r/null_key_none_myisam.result +++ b/mysql-test/r/null_key_none_myisam.result @@ -60,12 +60,12 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (((`test`.`t1`.`b` = 9) and (`test`.`t1`.`a` is null)) or ((`test`.`t1`.`b` = 7) and (`test`.`t1`.`a` is null))) limit 3 explain select * from t1 where a > 1 and a < 3 limit 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 Using where; Using index +1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` > 1) and (`test`.`t1`.`a` < 3)) limit 1 explain select * from t1 where a > 8 and a < 9; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 Using where; Using index +1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` > 8) and (`test`.`t1`.`a` < 9)) select * from t1 where a is null; @@ -178,7 +178,7 @@ Warning 1739 Cannot use range access on index 'b' due to type or collation conve Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (((`test`.`t1`.`a` is null) and (`test`.`t1`.`b` = 9)) or ((`test`.`t1`.`a` is null) and (`test`.`t1`.`b` = 7))) limit 3 explain select * from t1 where a > 1 and a < 3 limit 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 Using where +1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`a` > 1) and (`test`.`t1`.`a` < 3)) limit 1 explain select * from t1 where a is null and b=7 or a > 1 and a < 3 limit 1; @@ -191,7 +191,7 @@ Warning 1739 Cannot use range access on index 'b' due to type or collation conve Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (((`test`.`t1`.`a` is null) and (`test`.`t1`.`b` = 7)) or ((`test`.`t1`.`a` > 1) and (`test`.`t1`.`a` < 3))) limit 1 explain select * from t1 where a > 8 and a < 9; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 Using where +1 SIMPLE t1 NULL range a a 5 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`a` > 8) and (`test`.`t1`.`a` < 9)) explain select * from t1 where b like "6%"; diff --git a/mysql-test/r/offset_pushdown.result b/mysql-test/r/offset_pushdown.result new file mode 100644 index 00000000000..f148fc8afdc --- /dev/null +++ b/mysql-test/r/offset_pushdown.result @@ -0,0 +1,1298 @@ +# Initialise +# In EXPLAIN, "Using offset pushdown " indicates whether the feature is activated for a given query +# optimizer switch offset_pushdown flag defaults to true +# system variable empty_redundant_check_in_range_scan defaults to true +# table 1 +CREATE TABLE t1 (a INT , b INT , INDEX(b)); +INSERT INTO t1 VALUES (1, 2), (2, 3), (3, 3), (4, 3); +analyze TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +SET empty_redundant_check_in_range_scan=false; +# Shows that offset pushdown works with table scan, later in +# this file we will show it for index scan, range scan and lookup. +explain format=tree SELECT * FROM t1 LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Table scan on t1 (cost=*** rows=***) + +# non-covering index - icp is not disabled +# ICP is used and removes condition FROM server layer +# OFFSET pushdow is therefore active even opt empty_redundant_check_in_range_scan is false. +explain SELECT a,b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL range b b 5 NULL 3 100.00 Using offset pushdown; Using index condition +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`b` > 2) limit 1,100 +# Also visible in other EXPLAIN formats: +explain format=tree SELECT a,b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Index range scan on t1 using b over (2 < b), with index condition: (t1.b > 2) (cost=*** rows=***) + +explain format=json SELECT a,b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost_info": { + "query_cost": "1.61" + }, + "table": { + "table_name": "t1", + "access_type": "range", + "possible_keys": [ + "b" + ], + "key": "b", + "used_key_parts": [ + "b" + ], + "key_length": "5", + "rows_examined_per_scan": 3, + "rows_produced_per_join": 3, + "filtered": "100.00", + "offset pushdown": true, + "index_condition": "(`test`.`t1`.`b` > 2)", + "cost_info": { + "read_cost": "1.31", + "eval_cost": "0.30", + "prefix_cost": "1.61", + "data_read_per_join": "48" + }, + "used_columns": [ + "a", + "b" + ] + } + } +} +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`b` > 2) limit 1,100 +# The existing MySQL implementation of ICP is that it is off when the chosen index is covering. +# covering index => no icp => condition remains at SQL layer => no offset pushdown without opt empty_redundant_check_in_range_scan +explain SELECT b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL range b b 5 NULL 3 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`b` > 2) limit 1,100 +# covering index => no icp => but option empty_redundant_check_in_range_scan active, removes the condition => offset pushdown happens +SET empty_redundant_check_in_range_scan = true; +explain SELECT b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL range b b 5 NULL 3 100.00 Using offset pushdown; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`b` > 2) limit 1,100 +# ORDER BY (asc): condition removed, ORDER BY desc, condition removed; offset pushdown activated either way +explain format=tree SELECT b FROM t1 WHERE b > 2 ORDER BY b DESC LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Covering index range scan on t1 using b over (2 < b) (reverse) (cost=*** rows=***) + +explain format=tree SELECT b FROM t1 WHERE b > 2 ORDER BY b ASC LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Covering index range scan on t1 using b over (2 < b) (cost=*** rows=***) + +# works whether b OP cond or cond OP b +explain format=tree SELECT a,b FROM t1 WHERE 2 < b; +EXPLAIN +-> Index range scan on t1 using b over (2 < b) (cost=*** rows=***) + +CREATE TABLE t3 (a INT , b INT , INDEX(a,b)); +INSERT INTO t3 VALUES (1, 2),(2, 3),(3, 3),(4, 3); +analyze TABLE t3; +Table Op Msg_type Msg_text +test.t3 analyze status OK +explain format=tree SELECT a,b FROM t3 WHERE a = 2 AND b < 2; +EXPLAIN +-> Covering index range scan on t3 using a over (a = 2 AND NULL < b < 2) (cost=*** rows=***) + +explain format=tree SELECT a,b FROM t3 WHERE 2 = a AND b < 2; +EXPLAIN +-> Covering index range scan on t3 using a over (a = 2 AND NULL < b < 2) (cost=*** rows=***) + +explain format=tree SELECT a,b FROM t3 WHERE 2 = a AND 2 < b; +EXPLAIN +-> Covering index range scan on t3 using a over (a = 2 AND 2 < b) (cost=*** rows=***) + +# t3 is re-used to show that a BETWEEN clause can also be emptied by empty_redundant_check_in_range_scan +# thereby allowing offset pushdown +SET empty_redundant_check_in_range_scan = false; +explain format=tree SELECT * FROM t3 WHERE a BETWEEN 2 AND 3; +EXPLAIN +-> Filter: (t3.a between 2 and 3) (cost=*** rows=***) + -> Covering index range scan on t3 using a over (2 <= a <= 3) (cost=*** rows=***) + +explain format=tree SELECT * FROM t3 WHERE a BETWEEN 2 AND 3 LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s) (cost=*** rows=***) + -> Filter: (t3.a between 2 and 3) (cost=*** rows=***) + -> Covering index range scan on t3 using a over (2 <= a <= 3) (cost=*** rows=***) + +CREATE TABLE comp_1a AS SELECT * FROM t3 WHERE a BETWEEN 2 AND 3; +CREATE TABLE comp_1b AS SELECT * FROM t3 WHERE a BETWEEN 2 AND 3 LIMIT 100 OFFSET 1; +SET empty_redundant_check_in_range_scan = true; +explain format=tree SELECT * FROM t3 WHERE a BETWEEN 2 AND 3; +EXPLAIN +-> Covering index range scan on t3 using a over (2 <= a <= 3) (cost=*** rows=***) + +explain format=tree SELECT * FROM t3 WHERE a BETWEEN 2 AND 3 LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Covering index range scan on t3 using a over (2 <= a <= 3) (cost=*** rows=***) + +CREATE TABLE comp_2a AS SELECT * FROM t3 WHERE a BETWEEN 2 AND 3; +CREATE TABLE comp_2b AS SELECT * FROM t3 WHERE a BETWEEN 2 AND 3 LIMIT 100 OFFSET 1; +checksum TABLE comp_1a; +Table Checksum +test.comp_1a 3442709342 +checksum TABLE comp_2a; +Table Checksum +test.comp_2a 3442709342 +checksum TABLE comp_1b; +Table Checksum +test.comp_1b 1080478050 +checksum TABLE comp_2b; +Table Checksum +test.comp_2b 1080478050 +DROP TABLE comp_1a, comp_2a, comp_1b, comp_2b; +# BETWEEN and type conversion +explain format=tree SELECT * FROM t3 WHERE a BETWEEN "b" AND 5; +EXPLAIN +-> Filter: (t3.a between 'b' and 5) (cost=*** rows=***) + -> Index scan on t3 using a (cost=*** rows=***) + +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'b' +SELECT * FROM t3 WHERE a BETWEEN "b" AND 5; +a b +1 2 +2 3 +3 3 +4 3 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'b' +Warning 1292 Truncated incorrect DOUBLE value: 'b' +Warning 1292 Truncated incorrect DOUBLE value: 'b' +Warning 1292 Truncated incorrect DOUBLE value: 'b' +Warning 1292 Truncated incorrect DOUBLE value: 'b' +explain format=tree SELECT * FROM t3 WHERE a BETWEEN "2" AND "5"; +EXPLAIN +-> Covering index range scan on t3 using a over (2 <= a <= 5) (cost=*** rows=***) + +explain format=tree SELECT * FROM t3 WHERE a BETWEEN "2" AND 5; +EXPLAIN +-> Covering index range scan on t3 using a over (2 <= a <= 5) (cost=*** rows=***) + +explain format=tree SELECT * FROM t3 WHERE a BETWEEN 2 AND "5"; +EXPLAIN +-> Covering index range scan on t3 using a over (2 <= a <= 5) (cost=*** rows=***) + +explain format=tree SELECT * FROM t3 WHERE a BETWEEN "2.0" AND "5"; +EXPLAIN +-> Covering index range scan on t3 using a over (2 <= a <= 5) (cost=*** rows=***) + +explain format=tree SELECT * FROM t3 WHERE a BETWEEN "2" AND "5.0"; +EXPLAIN +-> Covering index range scan on t3 using a over (2 <= a <= 5) (cost=*** rows=***) + +# Empty IS NULL in WHERE clause +explain format=tree SELECT * FROM t3 WHERE a IS NULL AND b > 5; +EXPLAIN +-> Covering index range scan on t3 using a over (a = NULL AND 5 < b) (cost=*** rows=***) + +explain format=tree SELECT * FROM t3 WHERE a IS NULL AND b > 5 LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Covering index range scan on t3 using a over (a = NULL AND 5 < b) (cost=*** rows=***) + +# reset default +SET empty_redundant_check_in_range_scan = false; +# Offset pushdown is done for for "index lookup" too, and redundant +# conditions are removed even if empty_etc is false. +explain format=tree SELECT * FROM t3 WHERE a = 12 LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Covering index lookup on t3 using a (a=12) (cost=*** rows=***) + +explain format=tree SELECT * FROM t3 WHERE a = 12 AND b = 27 LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Covering index lookup on t3 using a (a=12, b=27) (cost=*** rows=***) + +DROP TABLE t3; +# show the results are the same with or without the optimization +SET optimizer_switch = 'offset_pushdown=on'; +explain SELECT a,b FROM t1 WHERE b>2 LIMIT 100 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL range b b 5 NULL 3 100.00 Using offset pushdown; Using index condition +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`b` > 2) limit 1,100 +CREATE TABLE comp_1 AS SELECT a,b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +SET optimizer_switch = 'offset_pushdown=off'; +explain SELECT a,b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL range b b 5 NULL 3 100.00 Using index condition +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`b` > 2) limit 1,100 +CREATE TABLE comp_2 AS SELECT a,b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +# checksum for comp_1 and comp_2 should give the same output: +checksum TABLE comp_1; +Table Checksum +test.comp_1 2332723677 +checksum TABLE comp_2; +Table Checksum +test.comp_2 2332723677 +DROP TABLE comp_1,comp_2; +#reset default +SET optimizer_switch = 'offset_pushdown=on'; +SET empty_redundant_check_in_range_scan = false; +# Use with stored procedure +CREATE PROCEDURE p1(p1 integer, p2 integer) +begin +SELECT * FROM t1 WHERE b>2 LIMIT p1 OFFSET p2; +end // +CREATE PROCEDURE p2(p1 integer, p2 integer) +begin +explain SELECT * FROM t1 WHERE b > 2 LIMIT p1 OFFSET p2; +end // +call p2(100,1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL range b b 5 NULL 3 100.00 Using offset pushdown; Using index condition +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`b` > 2) limit p2@1,p1@0 +call p1(100,1); +a b +3 3 +4 3 +DROP PROCEDURE if EXISTS p1; +DROP PROCEDURE if EXISTS p2; +# SQL_CALC_FOUND_ROWS disables optimization +explain SELECT a,b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL range b b 5 NULL 3 100.00 Using offset pushdown; Using index condition +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`b` > 2) limit 1,100 +explain SELECT sql_calc_found_rows a,b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL range b b 5 NULL 3 100.00 Using index condition +Warnings: +Warning 1287 SQL_CALC_FOUND_ROWS is deprecated and will be removed in a future release. Consider using two separate queries instead. +Note 1003 /* select#1 */ select sql_calc_found_rows `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`b` > 2) limit 1,100 +SELECT sql_calc_found_rows a,b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +a b +3 3 +4 3 +Warnings: +Warning 1287 SQL_CALC_FOUND_ROWS is deprecated and will be removed in a future release. Consider using two separate queries instead. +SELECT found_rows(); +found_rows() +3 +Warnings: +Warning 1287 FOUND_ROWS() is deprecated and will be removed in a future release. Consider using COUNT(*) instead. +# HAVING does, too +SELECT b FROM t1 HAVING b = 3; +b +3 +3 +3 +explain SELECT b FROM t1 HAVING b = 3 LIMIT 100 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL index NULL b 5 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`b` AS `b` from `test`.`t1` having (`test`.`t1`.`b` = 3) limit 1,100 +SELECT b FROM t1 HAVING b = 3 LIMIT 100 OFFSET 1; +b +3 +3 +# Offset pushdown supports merged derived tables +SET big_tables = 1; +# use InnoDB if we materialize +explain format=tree SELECT * FROM (SELECT * FROM t1) d LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Table scan on t1 (cost=*** rows=***) + +SELECT * FROM (SELECT * FROM t1) d LIMIT 100 OFFSET 1; +a b +2 3 +3 3 +4 3 +# Offset pushdown doesn't support materialized derived tables +explain format=tree SELECT /*+ no_merge() */ * FROM (SELECT * FROM t1) d LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s) (cost=***..1.55 rows=***) + -> Table scan on d (cost=***..1.55 rows=***) + -> Materialize (cost=***..1.05 rows=***) + -> Table scan on t1 (cost=*** rows=***) + +SELECT /*+ no_merge() */ * FROM (SELECT * FROM t1) d LIMIT 100 OFFSET 1; +a b +2 3 +3 3 +4 3 +# even if an index is used +SELECT /*+ no_merge() no_derived_condition_pushdown()*/ * FROM (SELECT * FROM t1) d WHERE b = 3; +a b +2 3 +3 3 +4 3 +explain format=tree SELECT /*+ no_merge() no_derived_condition_pushdown()*/ * FROM (SELECT * FROM t1) d WHERE b = 3 LIMIT 1 OFFSET 1; +EXPLAIN +-> Limit/Offset: 1/1 row(s) (cost=***..1.05 rows=***) + -> Index lookup on d using (b=3) + -> Materialize (cost=***..1.05 rows=***) + -> Table scan on t1 (cost=*** rows=***) + +SELECT /*+ no_merge() no_derived_condition_pushdown()*/ * FROM (SELECT * FROM t1) d WHERE b = 3 LIMIT 1 OFFSET 0; +a b +2 3 +SELECT /*+ no_merge() no_derived_condition_pushdown()*/ * FROM (SELECT * FROM t1) d WHERE b = 3 LIMIT 1 OFFSET 1; +a b +3 3 +SELECT /*+ no_merge() no_derived_condition_pushdown()*/ * FROM (SELECT * FROM t1) d WHERE b = 3 LIMIT 1 OFFSET 2; +a b +4 3 +SELECT /*+ no_merge() no_derived_condition_pushdown()*/ * FROM (SELECT * FROM t1) d WHERE b = 3 LIMIT 1 OFFSET 3; +a b +SET big_tables = default; +# Offset pushdown in a correlated subquery which is executed multiple times: +# check that each result is ok +explain format=tree SELECT (SELECT b+0*t0.b FROM t1 ORDER BY b LIMIT 1 OFFSET 2) FROM t1 AS t0; +EXPLAIN +-> Index scan on t0 using b (cost=*** rows=***) +-> Select #2 (subquery in projection; dependent) + -> Limit/Offset: 1/2 row(s), with offset pushdown (cost=*** rows=***) + -> Index scan on t1 using b (cost=*** rows=***) + +Warnings: +Note 1276 Field or reference 'test.t0.b' of SELECT #2 was resolved in SELECT #1 +SELECT (SELECT b+0*t0.b FROM t1 ORDER BY b LIMIT 1 OFFSET 2) FROM t1 AS t0; +(SELECT b+0*t0.b FROM t1 ORDER BY b LIMIT 1 OFFSET 2) +3 +3 +3 +3 +# prepared statements: +# check that nothing that is reused is changed +prepare stmt1 FROM 'SELECT * FROM t1 where b < 4 limit 100 OFFSET 1'; +execute stmt1; +a b +2 3 +3 3 +4 3 +execute stmt1; +a b +2 3 +3 3 +4 3 +execute stmt1; +a b +2 3 +3 3 +4 3 +deallocate prepare stmt1; +DROP TABLE t1; +# test +CREATE TABLE t2(a INT , b INT , INDEX(b)); +INSERT INTO t2 VALUES (1, 2), (2, 3), (3, 3), (4, 3),(5,6),(6,7); +analyze TABLE t2; +Table Op Msg_type Msg_text +test.t2 analyze status OK +# With UNION ALL +# without overlap +(SELECT * FROM t2 WHERE b > 4 LIMIT 100 OFFSET 0) UNION ALL (SELECT * FROM t2 WHERE b < 3 LIMIT 100 OFFSET 0) LIMIT 100 OFFSET 0; +a b +5 6 +6 7 +1 2 +(SELECT * FROM t2 WHERE b > 4 LIMIT 100 OFFSET 1) UNION ALL (SELECT * FROM t2 WHERE b < 3 LIMIT 100 OFFSET 0) LIMIT 100 OFFSET 0; +a b +6 7 +1 2 +(SELECT * FROM t2 WHERE b > 4 LIMIT 100 OFFSET 0) UNION ALL (SELECT * FROM t2 WHERE b < 3 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 0; +a b +5 6 +6 7 +(SELECT * FROM t2 WHERE b > 4 LIMIT 100 OFFSET 1) UNION ALL (SELECT * FROM t2 WHERE b < 3 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 0; +a b +6 7 +(SELECT * FROM t2 WHERE b > 4 LIMIT 100 OFFSET 0) UNION ALL (SELECT * FROM t2 WHERE b < 3 LIMIT 100 OFFSET 0) LIMIT 100 OFFSET 1; +a b +6 7 +1 2 +(SELECT * FROM t2 WHERE b > 4 LIMIT 100 OFFSET 1) UNION ALL (SELECT * FROM t2 WHERE b < 3 LIMIT 100 OFFSET 0) LIMIT 100 OFFSET 1; +a b +1 2 +(SELECT * FROM t2 WHERE b > 4 LIMIT 100 OFFSET 0) UNION ALL (SELECT * FROM t2 WHERE b < 3 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 1; +a b +6 7 +# outer OFFSET does not activate offset pushdown +# inner OFFSET activates offset pushdown +(SELECT * FROM t2 WHERE b > 4 LIMIT 100 OFFSET 1) UNION ALL (SELECT * FROM t2 WHERE b < 3 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 1; +a b +explain format=tree (SELECT * FROM t2 WHERE b > 4 LIMIT 100 OFFSET 1) UNION ALL (SELECT * FROM t2 WHERE b < 3 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s) + -> Append + -> Stream results (cost=*** rows=***) + -> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Index range scan on t2 using b over (4 < b), with index condition: (t2.b > 4) (cost=*** rows=***) + -> Stream results (cost=*** rows=***) + -> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Index range scan on t2 using b over (NULL < b < 3), with index condition: (t2.b < 3) (cost=*** rows=***) + +with overlap +(SELECT * FROM t2 WHERE b < 7 LIMIT 100 OFFSET 0) UNION ALL (SELECT * FROM t2 WHERE b < 4 LIMIT 100 OFFSET 0) LIMIT 100 OFFSET 0; +a b +1 2 +2 3 +3 3 +4 3 +5 6 +1 2 +2 3 +3 3 +4 3 +(SELECT * FROM t2 WHERE b < 7 LIMIT 100 OFFSET 1) UNION ALL (SELECT * FROM t2 WHERE b < 4 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 0; +a b +2 3 +3 3 +4 3 +5 6 +2 3 +3 3 +4 3 +(SELECT * FROM t2 WHERE b < 7 LIMIT 100 OFFSET 1) UNION ALL (SELECT * FROM t2 WHERE b < 4 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 1; +a b +3 3 +4 3 +5 6 +2 3 +3 3 +4 3 +explain format=tree (SELECT * FROM t2 WHERE b < 7 LIMIT 100 OFFSET 1) UNION ALL (SELECT * FROM t2 WHERE b < 4 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s) + -> Append + -> Stream results (cost=*** rows=***) + -> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Index range scan on t2 using b over (NULL < b < 7), with index condition: (t2.b < 7) (cost=*** rows=***) + -> Stream results (cost=*** rows=***) + -> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Index range scan on t2 using b over (NULL < b < 4), with index condition: (t2.b < 4) (cost=*** rows=***) + +# With UNION +# Only test with overlap +(SELECT * FROM t2 WHERE b < 7 LIMIT 100 OFFSET 0) UNION (SELECT * FROM t2 WHERE b < 4 LIMIT 100 OFFSET 0) LIMIT 100 OFFSET 0; +a b +1 2 +2 3 +3 3 +4 3 +5 6 +(SELECT * FROM t2 WHERE b < 7 LIMIT 100 OFFSET 1) UNION (SELECT * FROM t2 WHERE b < 4 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 0; +a b +2 3 +3 3 +4 3 +5 6 +(SELECT * FROM t2 WHERE b < 7 LIMIT 100 OFFSET 1) UNION (SELECT * FROM t2 WHERE b < 4 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 1; +a b +3 3 +4 3 +5 6 +# Same behavior as UNION ALL: +# outer OFFSET does not activate offset pushdown +# inner OFFSET activates offset pushdown +explain format=tree (SELECT * FROM t2 WHERE b < 7 LIMIT 100 OFFSET 1) UNION (SELECT * FROM t2 WHERE b < 4 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s) (cost=***..8.08 rows=***) + -> Table scan on (cost=***..8.08 rows=***) + -> Union materialize with deduplication (cost=***..5.47 rows=***) + -> Limit table size: 101 unique row(s) + -> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Index range scan on t2 using b over (NULL < b < 7), with index condition: (t2.b < 7) (cost=*** rows=***) + -> Limit table size: 101 unique row(s) + -> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Index range scan on t2 using b over (NULL < b < 4), with index condition: (t2.b < 4) (cost=*** rows=***) + +HA_POS_ERROR has to disable offset pushdown optimisation although the query otherwise satisfies the condition for said optimisation: +SET optimizer_switch = 'offset_pushdown=off'; +SELECT * FROM t2 WHERE b > 2 LIMIT 18446744073709551615 OFFSET 1; +a b +3 3 +4 3 +5 6 +6 7 +explain format=tree SELECT * FROM t2 WHERE b > 2 LIMIT 18446744073709551615 OFFSET 1; +EXPLAIN +-> Offset: 1 row(s) (cost=*** rows=***) + -> Index range scan on t2 using b over (2 < b), with index condition: (t2.b > 2) (cost=*** rows=***) + +SET optimizer_switch = 'offset_pushdown=on'; +SELECT * FROM t2 LIMIT 18446744073709551615 OFFSET 1; +a b +2 3 +3 3 +4 3 +5 6 +6 7 +explain format=tree SELECT * FROM t2 WHERE b > 2 LIMIT 18446744073709551615 OFFSET 1; +EXPLAIN +-> Offset: 1 row(s) (cost=*** rows=***) + -> Index range scan on t2 using b over (2 < b), with index condition: (t2.b > 2) (cost=*** rows=***) + +# Fewer calls from sql-layer to handler when the optimization is on: +SET optimizer_switch = 'offset_pushdown=off'; +flush status; +SELECT * FROM t2 WHERE b > 2 LIMIT 100 OFFSET 4; +a b +6 7 +show status LIKE 'handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 1 +Handler_read_last 0 +Handler_read_next 5 +Handler_read_prev 0 +Handler_read_rnd 0 +Handler_read_rnd_next 0 +SET optimizer_switch = 'offset_pushdown=on'; +flush status; +SELECT * FROM t2 WHERE b > 2 LIMIT 100 OFFSET 4; +a b +6 7 +show status LIKE 'handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 1 +Handler_read_last 0 +Handler_read_next 1 +Handler_read_prev 0 +Handler_read_rnd 0 +Handler_read_rnd_next 0 +DROP TABLE t2; +# offset pushdown with primary key - feature activated only with empty_redundant_check_in_range_scan +# which removes the unnecessary SQL layer check of the WHERE clause +CREATE TABLE test_pk +(a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a)); +INSERT INTO test_pk VALUES (1,0),(2,1),(3,2),(4,3); +analyze TABLE test_pk; +Table Op Msg_type Msg_text +test.test_pk analyze status OK +SET empty_redundant_check_in_range_scan = false; +explain SELECT * FROM test_pk WHERE a > 2 ORDER BY a LIMIT 100 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE test_pk NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +Warnings: +Note 1003 /* select#1 */ select `test`.`test_pk`.`a` AS `a`,`test`.`test_pk`.`b` AS `b` from `test`.`test_pk` where (`test`.`test_pk`.`a` > 2) order by `test`.`test_pk`.`a` limit 1,100 +SET empty_redundant_check_in_range_scan = true; +explain SELECT * FROM test_pk WHERE a > 2 ORDER BY a LIMIT 100 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE test_pk NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using offset pushdown +Warnings: +Note 1003 /* select#1 */ select `test`.`test_pk`.`a` AS `a`,`test`.`test_pk`.`b` AS `b` from `test`.`test_pk` where (`test`.`test_pk`.`a` > 2) order by `test`.`test_pk`.`a` limit 1,100 +# Query with only constant tables, makes sure changes to EXPLAIN code don't crash +# (no pushdown needed): +explain format=tree SELECT * FROM test_pk WHERE a = 2 LIMIT 100; +EXPLAIN +-> Limit: 100 row(s) (cost=***..0.00 rows=***) + -> Rows fetched before execution (cost=***..0.00 rows=***) + +DROP TABLE test_pk; +# Empty redundant condition in index range scan: check different data types +# redundant check removal extended to real numbers (DOUBLE) +CREATE TABLE t6(a DOUBLE, b DOUBLE, c DOUBLE , INDEX(a,b,c)); +INSERT INTO t6 VALUES (1,2,6), (2,3,7), (3,3,8), (4,3,12); +analyze TABLE t6; +Table Op Msg_type Msg_text +test.t6 analyze status OK +SET empty_redundant_check_in_range_scan = false; +explain format=tree SELECT * FROM t6 WHERE a > 2; +EXPLAIN +-> Filter: (t6.a > 2) (cost=*** rows=***) + -> Covering index range scan on t6 using a over (2 < a) (cost=*** rows=***) + +explain format=tree SELECT * FROM t6 WHERE a = 2 AND b < 5 AND b > 1; +EXPLAIN +-> Filter: ((t6.a = 2) and (t6.b < 5) and (t6.b > 1)) (cost=*** rows=***) + -> Covering index range scan on t6 using a over (a = 2 AND 1 < b < 5) (cost=*** rows=***) + +SET empty_redundant_check_in_range_scan = true; +explain format=tree SELECT * FROM t6 WHERE a > 2; +EXPLAIN +-> Covering index range scan on t6 using a over (2 < a) (cost=*** rows=***) + +explain format=tree SELECT * FROM t6 WHERE a = 2 AND b < 5 AND b > 1; +EXPLAIN +-> Covering index range scan on t6 using a over (a = 2 AND 1 < b < 5) (cost=*** rows=***) + +DROP TABLE t6; +# redundant check removal extended to DECIMAL +CREATE TABLE t6(a DECIMAL, b DECIMAL, c DECIMAL , INDEX(a,b,c)); +INSERT INTO t6 VALUES (1,2,6), (2,3,7), (3,3,8), (4,3,12); +analyze TABLE t6; +Table Op Msg_type Msg_text +test.t6 analyze status OK +SET empty_redundant_check_in_range_scan = false; +explain format=tree SELECT * FROM t6 WHERE a > 2; +EXPLAIN +-> Filter: (t6.a > 2) (cost=*** rows=***) + -> Covering index range scan on t6 using a over (2 < a) (cost=*** rows=***) + +explain format=tree SELECT * FROM t6 WHERE a = 2 AND b < 5 AND b > 1; +EXPLAIN +-> Filter: ((t6.a = 2) and (t6.b < 5) and (t6.b > 1)) (cost=*** rows=***) + -> Covering index range scan on t6 using a over (a = 2 AND 1 < b < 5) (cost=*** rows=***) + +SET empty_redundant_check_in_range_scan = true; +explain format=tree SELECT * FROM t6 WHERE a > 2; +EXPLAIN +-> Covering index range scan on t6 using a over (2 < a) (cost=*** rows=***) + +explain format=tree SELECT * FROM t6 WHERE a = 2 AND b < 5 AND b > 1; +EXPLAIN +-> Covering index range scan on t6 using a over (a = 2 AND 1 < b < 5) (cost=*** rows=***) + +DROP TABLE t6; +# redundant check removal extended to String +CREATE TABLE people(zipcode CHAR(10),lastname CHAR(10), firstname CHAR(10),address CHAR(10), INDEX (zipcode, lastname, firstname)); +analyze TABLE people; +Table Op Msg_type Msg_text +test.people analyze status OK +SET empty_redundant_check_in_range_scan = false; +explain format=tree SELECT * FROM people WHERE zipcode > '95054'; +EXPLAIN +-> Index range scan on people using zipcode over ('95054' < zipcode), with index condition: (people.zipcode > '95054') (cost=*** rows=***) + +SET empty_redundant_check_in_range_scan = true; +explain format=tree SELECT * FROM people WHERE zipcode > '95054'; +EXPLAIN +-> Index range scan on people using zipcode over ('95054' < zipcode) (cost=*** rows=***) + +DROP TABLE people; +# Test skip scan +CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL, PRIMARY KEY(f1, f2)); +INSERT INTO t1 VALUES +(1,1), (1,2), (1,3), (1,4), (1,5), +(2,1), (2,2), (2,3), (2,4), (2,5); +INSERT INTO t1 SELECT f1, f2 + 5 FROM t1; +INSERT INTO t1 SELECT f1, f2 + 10 FROM t1; +INSERT INTO t1 SELECT f1, f2 + 20 FROM t1; +INSERT INTO t1 SELECT f1, f2 + 40 FROM t1; +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +# first test without LIMIT OFFSET +SET empty_redundant_check_in_range_scan = false; +EXPLAIN SELECT f1, f2 FROM t1 WHERE f2 > 40; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL range PRIMARY PRIMARY 8 NULL 53 100.00 Using where; Using index for skip scan +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2` from `test`.`t1` where (`test`.`t1`.`f2` > 40) +SET empty_redundant_check_in_range_scan = true; +EXPLAIN SELECT f1, f2 FROM t1 WHERE f2 > 40; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL range PRIMARY PRIMARY 8 NULL 53 100.00 Using where; Using index for skip scan +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2` from `test`.`t1` where (`test`.`t1`.`f2` > 40) +#redundant conditions in skip scans can be removed +# test with LIMIT OFFSET +SET empty_redundant_check_in_range_scan = true; +EXPLAIN SELECT f1, f2 FROM t1 WHERE f2 > 40 LIMIT 100 OFFSET 2; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL range PRIMARY PRIMARY 8 NULL 53 100.00 Using where; Using index for skip scan +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2` from `test`.`t1` where (`test`.`t1`.`f2` > 40) limit 2,100 +# but skip scan cannot be used together with offset pushdown +DROP TABLE if EXISTS t1; +CREATE TABLE jemp ( +c JSON, +g INT GENERATED ALWAYS AS (c->"$.id"), +INDEX i (g) +); +INSERT INTO jemp (c) VALUES +('{"id": "1", "name": "Fred"}'), ('{"id": "2", "name": "Wilma"}'), +('{"id": "3", "name": "Barney"}'), ('{"id": "4", "name": "Betty"}'); +analyze TABLE jemp; +Table Op Msg_type Msg_text +test.jemp analyze status OK +# without optimization +SET empty_redundant_check_in_range_scan = false; +SELECT c->>"$.name" AS name +FROM jemp WHERE g > 2; +name +Barney +Betty +EXPLAIN SELECT c->>"$.name" AS name +FROM jemp WHERE g > 2; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE jemp NULL range i i 5 NULL 2 100.00 Using where +Warnings: +Note 1003 /* select#1 */ select json_unquote(json_extract(`test`.`jemp`.`c`,'$.name')) AS `name` from `test`.`jemp` where (`test`.`jemp`.`g` > 2) +# with optimization +SET empty_redundant_check_in_range_scan = true; +SELECT c->>"$.name" AS name +FROM jemp WHERE g > 2; +name +Barney +Betty +EXPLAIN SELECT c->>"$.name" AS name +FROM jemp WHERE g > 2; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE jemp NULL range i i 5 NULL 2 100.00 NULL +Warnings: +Note 1003 /* select#1 */ select json_unquote(json_extract(`test`.`jemp`.`c`,'$.name')) AS `name` from `test`.`jemp` where (`test`.`jemp`.`g` > 2) +# works with offset pushdown +SELECT c->>"$.name" AS name +FROM jemp WHERE g > 2 LIMIT 1 OFFSET 1; +name +Betty +EXPLAIN format=tree SELECT c->>"$.name" AS name +FROM jemp WHERE g > 2; +EXPLAIN +-> Index range scan on jemp using i over (2 < g) (cost=1.16 rows=2) + +DROP TABLE if EXISTS jemp; +# Inspired by the test for Bug #27578340: INCONSISTENT RESULTS FOR SELECTS FROM TABLE WITH CHAR(N) COLUMN +# AND NO_PAD COLLATION from ctype_uca.test, +# verify that an inequality condition is kept at SQL layer: +CREATE TABLE t1 ( +f1 CHAR(20) COLLATE utf8mb4_0900_ai_ci # A NO PAD collation. +); +INSERT INTO t1 VALUES ('ABC '); +INSERT INTO t1 VALUES ('XYZ'); +INSERT INTO t1 VALUES ('XYZ '); +INSERT INTO t1 VALUES ('ABC '); +CREATE INDEX f1_index ON t1 ( f1 ); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +set empty_redundant_check_in_range_scan = on; +explain format=tree SELECT CONCAT(f1, '|') FROM t1 WHERE f1 >= 'XYZ '; +EXPLAIN +-> Filter: (t1.f1 >= 'XYZ ') (cost=*** rows=***) + -> Covering index range scan on t1 using f1_index over ('XYZ' < f1) (cost=*** rows=***) + +# Now, a PAD SPACE collation, condition is not kept +ALTER TABLE t1 modify f1 CHAR(20) COLLATE utf8mb4_unicode_ci; +analyze TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +explain format=tree SELECT CONCAT(f1, '|') FROM t1 WHERE f1 >= 'XYZ '; +EXPLAIN +-> Covering index range scan on t1 using f1_index over ('XYZ' <= f1) (cost=*** rows=***) + +SET empty_redundant_check_in_range_scan=default; +DROP TABLE t1; +# Can remove DATE +SET empty_redundant_check_in_range_scan = true; +CREATE TABLE t9(a date); +ALTER TABLE t9 ADD INDEX (a); +INSERT INTO t9 VALUES ("20210907"); +INSERT INTO t9 VALUES ("20210907"); +INSERT INTO t9 VALUES ("20210907"); +INSERT INTO t9 VALUES ("20210907"); +INSERT INTO t9 VALUES ("20210907"); +INSERT INTO t9 VALUES ("20210907"); +INSERT INTO t9 VALUES ("20210907"); +INSERT INTO t9 VALUES ("20210907"); +INSERT INTO t9 VALUES ("20210907"); +INSERT INTO t9 VALUES ("20210907"); +INSERT INTO t9 VALUES ("20210907"); +INSERT INTO t9 VALUES ("20210907"); +INSERT INTO t9 VALUES ("20210907"); +INSERT INTO t9 VALUES ("20210907"); +INSERT INTO t9 VALUES ("20210907"); +INSERT INTO t9 VALUES ("20210907"); +analyze TABLE t9; +Table Op Msg_type Msg_text +test.t9 analyze status OK +explain format=tree SELECT * FROM t9 WHERE a >= "20211001"; +EXPLAIN +-> Covering index range scan on t9 using a over ('2021-10-01' <= a) (cost=*** rows=***) + +explain format=tree SELECT * FROM t9 WHERE a >= "2021-10-01"; +EXPLAIN +-> Covering index range scan on t9 using a over ('2021-10-01' <= a) (cost=*** rows=***) + +# can remove DATETIME +DROP TABLE if EXISTS t9; +CREATE TABLE t9(a datetime); +ALTER TABLE t9 ADD index(a); +INSERT INTO t9 VALUES ("2021-09-07 12:11"); +INSERT INTO t9 VALUES ("2021-09-07 12:11"); +INSERT INTO t9 VALUES ("2021-09-07 12:11"); +INSERT INTO t9 VALUES ("2021-09-07 12:11"); +INSERT INTO t9 VALUES ("2021-09-07 12:11"); +INSERT INTO t9 VALUES ("2021-09-07 12:11"); +analyze TABLE t9; +Table Op Msg_type Msg_text +test.t9 analyze status OK +explain format=tree SELECT * FROM t9 WHERE a >= "2022-09-07 12:25"; +EXPLAIN +-> Covering index range scan on t9 using a over ('2022-09-07 12:25:00' <= a) (cost=*** rows=***) + +# can remove TIMESTAMP +DROP TABLE if EXISTS t9; +CREATE TABLE t9 (a TIMESTAMP); +ALTER TABLE t9 ADD INDEX (a); +INSERT INTO t9 VALUES ("2021-09-07 12:11"); +INSERT INTO t9 VALUES ("2021-09-07 12:11"); +INSERT INTO t9 VALUES ("2021-09-07 12:11"); +INSERT INTO t9 VALUES ("2021-09-07 12:11"); +INSERT INTO t9 VALUES ("2021-09-07 12:11"); +INSERT INTO t9 VALUES ("2021-09-07 12:11"); +analyze TABLE t9; +Table Op Msg_type Msg_text +test.t9 analyze status OK +explain format=tree SELECT * FROM t9 WHERE a >= "2022-09-07 12:25"; +EXPLAIN +-> Covering index range scan on t9 using a over ('2022-09-07 12:25:00' <= a) (cost=*** rows=***) + +# can remove TIME +DROP TABLE if EXISTS t9; +CREATE TABLE t9 (a time); +ALTER TABLE t9 ADD INDEX (a); +INSERT INTO t9 VALUES ("1211"); +INSERT INTO t9 VALUES ("1211"); +INSERT INTO t9 VALUES ("1211"); +INSERT INTO t9 VALUES ("1211"); +INSERT INTO t9 VALUES ("1211"); +INSERT INTO t9 VALUES ("1211"); +INSERT INTO t9 VALUES ("1211"); +INSERT INTO t9 VALUES ("1211"); +analyze TABLE t9; +Table Op Msg_type Msg_text +test.t9 analyze status OK +explain format=tree SELECT * FROM t9 WHERE a >= "1218"; +EXPLAIN +-> Covering index range scan on t9 using a over ('00:12:18' <= a) (cost=*** rows=***) + +explain format=tree SELECT * FROM t9 WHERE a >= "12:18"; +EXPLAIN +-> Covering index range scan on t9 using a over ('12:18:00' <= a) (cost=*** rows=***) + +DROP TABLE IF EXISTS t9; +# ORDER BY ASC/DESC with INDEX ASC/DESC +# table t10 has descending index while t11 has normal index +CREATE TABLE t10 ( +c1 INT, c2 INT, +INDEX idx4 (c1 DESC, c2 DESC) +); +INSERT INTO t10 VALUES (1,2),(3,4),(5,6),(7,8),(9,10); +CREATE TABLE t11 ( +c1 INT, c2 INT, +INDEX idx4 (c1 , c2 ) +); +INSERT INTO t11 VALUES (1,2),(3,4),(5,6),(7,8),(9,10); +EXPLAIN format=tree SELECT * FROM t10 WHERE c1 > 2 ORDER BY c1 DESC LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Covering index range scan on t10 using idx4 over (c1 < 2) (cost=*** rows=***) + +EXPLAIN format=tree SELECT * FROM t11 WHERE c1 > 2 ORDER BY c1 DESC LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Covering index range scan on t11 using idx4 over (2 < c1) (reverse) (cost=*** rows=***) + +EXPLAIN format=tree SELECT * FROM t10 WHERE c1 > 2 ORDER BY c1 ASC LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Covering index range scan on t10 using idx4 over (c1 < 2) (reverse) (cost=*** rows=***) + +EXPLAIN format=tree SELECT * FROM t11 WHERE c1 > 2 ORDER BY c1 ASC LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Covering index range scan on t11 using idx4 over (2 < c1) (cost=*** rows=***) + +SELECT * FROM t10 WHERE c1 > 2 ORDER BY c1 DESC LIMIT 100 OFFSET 1; +c1 c2 +7 8 +5 6 +3 4 +SELECT * FROM t11 WHERE c1 > 2 ORDER BY c1 DESC LIMIT 100 OFFSET 1; +c1 c2 +7 8 +5 6 +3 4 +SELECT * FROM t10 WHERE c1 > 2 ORDER BY c1 ASC LIMIT 100 OFFSET 1; +c1 c2 +5 6 +7 8 +9 10 +SELECT * FROM t11 WHERE c1 > 2 ORDER BY c1 ASC LIMIT 100 OFFSET 1; +c1 c2 +5 6 +7 8 +9 10 +# Verify that the hint overrules the switch: +EXPLAIN format=tree SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t11 WHERE c1 > 2 ORDER BY c1 ASC LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s) (cost=*** rows=***) + -> Covering index range scan on t11 using idx4 over (2 < c1) (cost=*** rows=***) + +SET optimizer_switch = 'offset_pushdown=off'; +EXPLAIN format=tree SELECT * FROM t11 WHERE c1>2 ORDER BY c1 ASC LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s) (cost=*** rows=***) + -> Covering index range scan on t11 using idx4 over (2 < c1) (cost=*** rows=***) + +EXPLAIN format=tree SELECT /*+ OFFSET_PUSHDOWN() */ * FROM t11 WHERE c1 > 2 ORDER BY c1 ASC LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Covering index range scan on t11 using idx4 over (2 < c1) (cost=*** rows=***) + +SET optimizer_switch='offset_pushdown=on'; +# Verify that in a LEFT JOIN, the range condition is removed or not, correctly. +# Conditions on left table can be removed: +EXPLAIN format=tree SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t11.c1 > 3 WHERE t11.c1 > 2; +EXPLAIN +-> Left hash join (no condition), extra conditions: (t11.c1 > 3) (cost=*** rows=***) + -> Covering index range scan on t11 using idx4 over (2 < c1) (cost=*** rows=***) + -> Hash + -> Index scan on t12 using idx4 (cost=*** rows=***) + +# Condition on right table too, as it's in ON: if the range access has kept only +# rows of t12 with c1>3, this condition will not need to be checked again. +EXPLAIN format=tree SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t12.c1 > 3 WHERE t11.c1 > 2; +EXPLAIN +-> Left hash join (no condition) (cost=*** rows=***) + -> Covering index range scan on t11 using idx4 over (2 < c1) (cost=*** rows=***) + -> Hash + -> Covering index range scan on t12 using idx4 over (3 < c1) (cost=*** rows=***) + +# These two don't prove much, as the left join is changed to an inner join +# (as NULL-complemented rows cannot match the WHERE). +EXPLAIN format=tree SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t11.c1 > 3 WHERE t12.c1 > 2; +EXPLAIN +-> Inner hash join (no condition) (cost=*** rows=***) + -> Covering index range scan on t12 using idx4 over (2 < c1) (cost=*** rows=***) + -> Hash + -> Covering index range scan on t11 using idx4 over (3 < c1) (cost=*** rows=***) + +EXPLAIN format=tree SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t12.c1 > 3 WHERE t12.c1 > 2; +EXPLAIN +-> Inner hash join (no condition) (cost=*** rows=***) + -> Index scan on t11 using idx4 (cost=*** rows=***) + -> Hash + -> Filter: (t12.c1 > 2) (cost=*** rows=***) + -> Covering index range scan on t12 using idx4 over (3 < c1) (cost=*** rows=***) + +# Here the WHERE IS NULL cannot be removed: the range access has kept only +# rows of t12 with c1 NULL, but there can be other NULL-complemented rows, +# and then the WHERE must be checked on them too. This case is properly caught +# by the test: !(func->used_tables() & null_extended) in reduce_cond_for_table(). +EXPLAIN format=tree SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t12.c1 > 3 WHERE t12.c1 IS NULL; +EXPLAIN +-> Filter: (t12.c1 is null) (cost=*** rows=***) + -> Left hash join (no condition) (cost=*** rows=***) + -> Index scan on t11 using idx4 (cost=*** rows=***) + -> Hash + -> Covering index range scan on t12 using idx4 over (3 < c1) (cost=*** rows=***) + +DROP TABLE t10,t11; +CREATE TABLE t2 (b INT , key(b)); +INSERT INTO t2 VALUES (1),(1),(2),(2),(3),(3); +# Check that offset pushdown is deactivated when DISTINCT is done by doing some grouping +# inside ORDER BY ( "grouped" is true in if() condition in JOIN::offset_pushdown().) +explain format=tree SELECT /*+ NO_OFFSET_PUSHDOWN() */ DISTINCT b FROM t2 ORDER BY b LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s) (cost=*** rows=***) + -> Group (no aggregates) (cost=*** rows=***) + -> Index scan on t2 using b (cost=*** rows=***) + +SELECT /*+ NO_OFFSET_PUSHDOWN() */ DISTINCT b FROM t2 ORDER BY b LIMIT 100 OFFSET 1; +b +2 +3 +explain format=tree SELECT /*+ OFFSET_PUSHDOWN() */ DISTINCT b FROM t2 ORDER BY b LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s) (cost=*** rows=***) + -> Group (no aggregates) (cost=*** rows=***) + -> Index scan on t2 using b (cost=*** rows=***) + +SELECT /*+ OFFSET_PUSHDOWN() */ DISTINCT b FROM t2 ORDER BY b LIMIT 100 OFFSET 1; +b +2 +3 +# Check that offset pushdown is deactivated when using index for group-by is used +# (similarly to the previous test: DISTINCT is done by doing some grouping inside ORDER BY) +# in that case "grouped" is true. +analyze TABLE t2; +Table Op Msg_type Msg_text +test.t2 analyze status OK +explain SELECT /*+ NO_OFFSET_PUSHDOWN() */ DISTINCT b FROM t2 ORDER BY b LIMIT 100 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 NULL range b b 5 NULL 4 100.00 Using index for group-by +Warnings: +Note 1003 /* select#1 */ select /*+ NO_OFFSET_PUSHDOWN(@`select#1`) */ distinct `test`.`t2`.`b` AS `b` from `test`.`t2` order by `test`.`t2`.`b` limit 1,100 +SELECT /*+ NO_OFFSET_PUSHDOWN() */ DISTINCT b FROM t2 ORDER BY b LIMIT 100 OFFSET 1; +b +2 +3 +explain SELECT /*+ OFFSET_PUSHDOWN() */ DISTINCT b FROM t2 ORDER BY b LIMIT 100 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 NULL range b b 5 NULL 4 100.00 Using index for group-by +Warnings: +Note 1003 /* select#1 */ select /*+ OFFSET_PUSHDOWN(@`select#1`) */ distinct `test`.`t2`.`b` AS `b` from `test`.`t2` order by `test`.`t2`.`b` limit 1,100 +SELECT /*+ OFFSET_PUSHDOWN() */ DISTINCT b FROM t2 ORDER BY b LIMIT 100 OFFSET 1; +b +2 +3 +DROP TABLE t2; +CREATE TABLE t1 (a INT , b INT , c INT , INDEX(a,b,c)); +INSERT INTO t1 VALUES (1,100,1),(2,200,1),(3,300,1),(4,10,2),(5,20,2),(6,30,2),(7,110,3),(8,120,3),(9,130,3); +CREATE TABLE t2 (a INT , b INT , c INT , INDEX(a,b,c)); +INSERT INTO t2 VALUES (1,110,1),(2,210,1),(4,20,2),(5,30,2),(7,130,3),(8,140,3); +# Subqueries +# DOES NOT WORK on outer queries +# Offset pushdown is evaluated for each JOIN object and can therefore be applied to subqueries if a given JOIN object does qualify for OP. +# Both explain format=tree and actual query output are given since the feature is activated -- easier to maintain if outputs are produced +# Uncorrelated +# Inner query with LIMIT OFFSET +explain format=tree SELECT * FROM t1 WHERE a > (SELECT a FROM t1 LIMIT 1 OFFSET 1); +EXPLAIN +-> Filter: (t1.a > (select #2)) (cost=*** rows=***) + -> Covering index range scan on t1 using a over (2 < a) (cost=*** rows=***) + -> Select #2 (subquery in condition; run only once) + -> Limit/Offset: 1/1 row(s), with offset pushdown (cost=*** rows=***) + -> Covering index scan on t1 using a (cost=*** rows=***) + +SELECT * FROM t1 WHERE a > (SELECT a FROM t1 LIMIT 1 OFFSET 1); +a b c +3 300 1 +4 10 2 +5 20 2 +6 30 2 +7 110 3 +8 120 3 +9 130 3 +explain format=tree SELECT * FROM t1 WHERE a > (SELECT a FROM t1 WHERE a>2 LIMIT 1 OFFSET 1); +EXPLAIN +-> Filter: (t1.a > (select #2)) (cost=*** rows=***) + -> Covering index range scan on t1 using a over (4 < a) (cost=*** rows=***) + -> Select #2 (subquery in condition; run only once) + -> Limit/Offset: 1/1 row(s), with offset pushdown (cost=*** rows=***) + -> Covering index range scan on t1 using a over (2 < a) (cost=*** rows=***) + +SELECT * FROM t1 WHERE a > (SELECT a FROM t1 WHERE a>2 LIMIT 1 OFFSET 1); +a b c +5 20 2 +6 30 2 +7 110 3 +8 120 3 +9 130 3 +# Offset pushdown outer query - non constant item_subselect - no offset pushdown +# add row for non empty output of following SELECT statement +INSERT INTO t1 values (9,131,1); +explain format=tree SELECT * FROM t1 WHERE a = (SELECT max(a) FROM t1 WHERE a > 2) LIMIT 1 OFFSET 1; +EXPLAIN +-> Limit/Offset: 1/1 row(s) (cost=*** rows=***) + -> Filter: (t1.a = (select #2)) (cost=*** rows=***) + -> Covering index lookup on t1 using a (a=(select #2)) (cost=*** rows=***) + -> Select #2 (subquery in condition; run only once) + -> Rows fetched before execution (cost=***..0.00 rows=***) + +SELECT * FROM t1 WHERE a = (SELECT max(a) FROM t1 WHERE a > 2) LIMIT 1 OFFSET 1; +a b c +9 131 1 +DELETE FROM t1 WHERE a=9 AND b=131 AND c=3; +# both inner and outer queries with LIMIT OFFSET +# non constant item_subselect - no offset pushdown for the outer query +# add row for non empty output of following SELECT statement +INSERT INTO t1 values (4,10,3),(4,10,3),(4,10,3); +explain format=tree SELECT * FROM t1 WHERE a =(SELECT a FROM t1 WHERE a > 2 LIMIT 1 OFFSET 1) LIMIT 2 OFFSET 3; +EXPLAIN +-> Limit/Offset: 2/3 row(s) (cost=*** rows=***) + -> Filter: (t1.a = (select #2)) (cost=*** rows=***) + -> Covering index lookup on t1 using a (a=(select #2)) (cost=*** rows=***) + -> Select #2 (subquery in condition; run only once) + -> Limit/Offset: 1/1 row(s), with offset pushdown (cost=*** rows=***) + -> Covering index range scan on t1 using a over (2 < a) (cost=*** rows=***) + +SELECT * FROM t1 WHERE a = (SELECT a FROM t1 WHERE a > 2 LIMIT 1 OFFSET 1) LIMIT 2 OFFSET 3; +a b c +4 10 3 +DELETE FROM t1 WHERE a=4 AND b=10 AND c=3; +# Correlated was covered before +# SHOW that JOIN, SELF JOIN do not trigger offset pushdown +explain format=tree SELECT * FROM t1 JOIN t2 LIMIT 1 OFFSET 1; +EXPLAIN +-> Limit/Offset: 1/1 row(s) (cost=*** rows=***) + -> Inner hash join (no condition) (cost=*** rows=***) + -> Index scan on t1 using a (cost=*** rows=***) + -> Hash + -> Index scan on t2 using a (cost=*** rows=***) + +explain format=tree SELECT * FROM t1 T1, t1 T2 LIMIT 2 OFFSET 10; +EXPLAIN +-> Limit/Offset: 2/10 row(s) (cost=*** rows=***) + -> Inner hash join (no condition) (cost=*** rows=***) + -> Index scan on T2 using a (cost=*** rows=***) + -> Hash + -> Index scan on T1 using a (cost=*** rows=***) + +# Table function are not compatible with offset pushdown +explain format=tree SELECT * FROM JSON_TABLE('[{"x":2,"y":"8"},{"x":"3","y":"7"},{"x":"4","y":6}]',"$[1]" COLUMNS(xval VARCHAR(100) PATH "$.x", yval VARCHAR(100) PATH "$.y")) AS jt1 LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s) + -> Materialize table function + +DROP TABLE t1,t2; +# OFFSET exceeds number of rows: When the offset exceed the number of rows returned by the query without offset, offset pushdown still works +CREATE TABLE t1 (a INT, b INT , INDEX(a,b)); +INSERT INTO t1 VALUES (1,1),(2,2),(3,4),(8,9); +EXPLAIN format=tree SELECT * FROM t1 LIMIT 1 OFFSET 5; +EXPLAIN +-> Limit/Offset: 1/5 row(s), with offset pushdown (cost=*** rows=***) + -> Index scan on t1 using a (cost=*** rows=***) + +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t1 LIMIT 1 OFFSET 5; +a b +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +4 +DROP TABLE t1; +############################################## +############################################## +# +BUG2022101200261 +# +############################################## +############################################## +############################################## +# INT comparison +############################################## +CREATE TABLE t11 ( +c1 INT, c2 INT, +INDEX idx4 (c1 , c2 ) +); +INSERT INTO t11 VALUES (1,2),(3,4),(5,6),(7,8),(9,10); +# Two items containing t12.c1 > 3 and t12.c1 > 2 +# key_min only contains 3 +# Check that INT comparison works +EXPLAIN format=tree SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t12.c1 > 3 WHERE t12.c1 > 2; +EXPLAIN +-> Inner hash join (no condition) (cost=*** rows=***) + -> Index scan on t11 using idx4 (cost=*** rows=***) + -> Hash + -> Filter: (t12.c1 > 2) (cost=*** rows=***) + -> Covering index range scan on t12 using idx4 over (3 < c1) (cost=*** rows=***) + +drop table t11; +############################################## +# Descending index +############################################## +CREATE TABLE t10 ( +c1 INT, c2 INT, +INDEX idx4 (c1 DESC, c2 DESC) +); +INSERT INTO t10 VALUES (1,2),(3,4),(5,6),(7,8),(9,10); +# Make sure the min and the max are swapped when the index was descending +EXPLAIN format=tree SELECT * FROM t10 WHERE c1 > 2 ORDER BY c1 DESC LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=*** rows=***) + -> Covering index range scan on t10 using idx4 over (c1 < 2) (cost=*** rows=***) + +drop table t10; +############################################## +# BUG TEST 4: Navigating key_min and key_max; check that store_length fulfills its purpose +############################################## +CREATE TABLE t1 ( +pk INT PRIMARY KEY, +i1 INT, +i2 INT, +v varchar(1), +INDEX i1_idx (i1), +INDEX v_idx (v,i1) +) ENGINE=InnoDB, CHARSET utf8mb4; +INSERT INTO t1 VALUES (1, 1, 9,'a'), (2, 2, 8,'b'), (3, 3, 7,'c'), +(4, 4, 6,'d'), (5, 5, 5,'e'); +EXPLAIN format=tree SELECT v FROM t1 WHERE i1 = 1 AND v = 'a' AND pk < 3; +EXPLAIN +-> Covering index range scan on t1 using v_idx over (v = 'a' AND i1 = 1 AND pk < 3) (cost=*** rows=***) + +DROP TABLE t1; +############################################## +# NO_MAX/MIN_RANGE flag +############################################## +CREATE TABLE t1(pk INT , i4 INT ,INDEX(i4)); +INSERT INTO t1 VALUES (1,10), (2,20), (3,30); +# the comparison for the upper limit is not even performed because NO_MAX_RANGE flag is set +EXPLAIN format=tree SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999; +EXPLAIN +-> Index range scan on t1 using i4 over (10 <= i4), with index condition: (t1.i4 between 10 and 99999999999999999) (cost=*** rows=***) + +drop table t1; +############################################## +# comparison to NULL +############################################## +# column_A IS NULL is the only comparison we handle +# Following example: 2 items NULL and 18446744073709551614 +# : 1 key_min 18446744073709551614 +# We cannot justify removing NULL. +CREATE TABLE t11 ( +c1 BIGINT UNSIGNED, c2 BIGINT UNSIGNED, +INDEX idx4 (c1 , c2 ) +); +INSERT INTO t11 VALUES (1,2),(3,4),(5,6),(7,8),(9,10); +EXPLAIN format=tree SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t11.c1 > NULL WHERE t11.c1 > 18446744073709551614; +EXPLAIN +-> Left hash join (no condition), extra conditions: (t11.c1 > NULL) (cost=*** rows=***) + -> Covering index range scan on t11 using idx4 over (18446744073709551614 < c1) (cost=*** rows=***) + -> Hash + -> Index scan on t12 using idx4 (cost=*** rows=***) + +# If we try to remove c1>NULL, we get a wrong select output +# The following test verifies that the current implementation produce the same results +# regardless of the status of empty_redundant_check_in_range_scan +EXPLAIN format=tree SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t11.c1 > NULL WHERE t11.c1 > 3; +EXPLAIN +-> Left hash join (no condition), extra conditions: (t11.c1 > NULL) (cost=*** rows=***) + -> Covering index range scan on t11 using idx4 over (3 < c1) (cost=*** rows=***) + -> Hash + -> Index scan on t12 using idx4 (cost=*** rows=***) + +SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t11.c1 > NULL WHERE t11.c1 > 3; +c1 c2 c1 c2 +5 6 NULL NULL +7 8 NULL NULL +9 10 NULL NULL +SET empty_redundant_check_in_range_scan=false; +EXPLAIN format=tree SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t11.c1 > NULL WHERE t11.c1 > 3; +EXPLAIN +-> Left hash join (no condition), extra conditions: (t11.c1 > NULL) (cost=*** rows=***) + -> Filter: (t11.c1 > 3) (cost=*** rows=***) + -> Covering index range scan on t11 using idx4 over (3 < c1) (cost=*** rows=***) + -> Hash + -> Index scan on t12 using idx4 (cost=*** rows=***) + +SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t11.c1 > NULL WHERE t11.c1 > 3; +c1 c2 c1 c2 +5 6 NULL NULL +7 8 NULL NULL +9 10 NULL NULL +SET empty_redundant_check_in_range_scan=true; +drop table t11; +############################################## +# NOT BETWEEN +############################################## +# NOT BETWEEN should not be handled by redundant condition removal +# Disjoint intervals, similar to OR clauses, not handled by current design. +create table ta ( a float default NULL ,b decimal(25,5) DEFAULT NULL, key(a)); +insert into ta values (100,1),(2000,2),(30000,3),(400000,4),(900000,5); +analyze table ta; +Table Op Msg_type Msg_text +test.ta analyze status OK +explain format=tree select * from ta INNER JOIN ta tb ON ta.b=tb.a where ta.a NOT BETWEEN -1.17549e-38 AND -1.17549e-38; +EXPLAIN +-> Nested loop inner join (cost=*** rows=***) + -> Filter: (ta.b is not null) (cost=*** rows=***) + -> Index range scan on ta using a over (NULL < a), with index condition: (ta.a not between (-(1.17549e-38)) and (-(1.17549e-38))) (cost=*** rows=***) + -> Index lookup on tb using a (a=ta.b), with index condition: (ta.b = tb.a) (cost=*** rows=***) + +drop table ta; diff --git a/mysql-test/r/offset_pushdown_insert_delete_update.result b/mysql-test/r/offset_pushdown_insert_delete_update.result new file mode 100644 index 00000000000..f90363a8ddc --- /dev/null +++ b/mysql-test/r/offset_pushdown_insert_delete_update.result @@ -0,0 +1,516 @@ +SET @old_innodb_lock_wait_timeout= @@global.innodb_lock_wait_timeout; +SET @@global.innodb_lock_wait_timeout = 1; +# ---------------------- +# ---------------------- +# MVCC - INSERT/ UPDATE/ DELETE with OFFSET PUSHDOWN +# For each, we test +# 1/ INSERT/ UPDATE/ DELETE first in one session then SELECT with OP in another +# 2/ SELECT with OP first in one session then INSERT/ UPDATE/ DELETE in another +# ---------------------- +# ---------------------- +# To keep track of the number of rows skipped by OFFSET pushdown we use: +# SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +# SELECT query +# SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +CREATE TABLE t3 (a INT, b INT, INDEX(a,b)); +INSERT INTO t3 VALUES (1, 2), (2, 3), (3, 3), (4, 3); +# ---------------------- +# ---------------------- +# MVCC INSERT and OFFSET pushdown +# ---------------------- +# ---------------------- +# Insert in one session, not committed, SELECT query with OP in another session - check that results are consistent +# session 1: Trx that inserts a new rows +START TRANSACTION; +INSERT INTO t3 VALUES (6,6); +SELECT * FROM t3; +a b +1 2 +2 3 +3 3 +4 3 +6 6 +# session 2: Trx with SELECT query with OP - check that the inserted row is not accounted for +# neither for the SELECT with and without OFFSET pushdown. +START TRANSACTION; +explain format=tree SELECT * FROM t3 WHERE a>1 LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=#.# rows=##) + -> Covering index range scan on t3 using a over (1 < a) (cost=#.# rows=##) + +# Both SELECT return the same output! rows skipped differ +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t3 WHERE a > 1 LIMIT 100 OFFSET 1; +a b +3 3 +4 3 +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +1 +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t3 WHERE a > 1 LIMIT 100 OFFSET 1; +a b +3 3 +4 3 +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +0 +rollback; +rollback; +# MVCC Insert and Offset pushdown +# Select first with OP - insert then +# session 1: SELECT rows using OP +START TRANSACTION; +explain SELECT * FROM t3 WHERE a>1 LIMIT 100 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 NULL range a a 5 NULL 3 100.00 Using offset pushdown; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where (`test`.`t3`.`a` > 1) limit 1,100 +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t3 WHERE a > 1 LIMIT 100 OFFSET 1; +a b +3 3 +4 3 +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +1 +# session 2: Insert rows in the table queried by OP +START TRANSACTION; +INSERT INTO t3 VALUES (6,6); +# (6,6) is inserted here +SELECT * FROM t3; +a b +1 2 +2 3 +3 3 +4 3 +6 6 +# (6,6) is not visible. +SELECT * FROM t3 WHERE a > 1 LIMIT 100 OFFSET 1; +a b +3 3 +4 3 +rollback; +rollback; +# ---------------------- +# ---------------------- +# MVCC UPDATE with OFFSET pushdown +# ---------------------- +# ---------------------- +# session 1: Trx that updates a row +START TRANSACTION; +UPDATE t3 SET a = 8 WHERE a = 4; +SELECT * FROM t3; +a b +1 2 +2 3 +3 3 +8 3 +# session 2: Trx with SELECT query with OP - check that the updated row is not accounted for +# neither for the SELECT with and without OFFSET pushdown. +START TRANSACTION; +# Both output the same rows - rows skipped differ +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t3 WHERE a > 1 LIMIT 100 OFFSET 1; +a b +3 3 +4 3 +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +1 +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t3 WHERE a > 1 LIMIT 100 OFFSET 1; +a b +3 3 +4 3 +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +0 +rollback; +rollback; +# MVCC UPDATE and Offset pushdown +# Select first with OP - UPDATE then +# session 1: SELECT rows using OP +START TRANSACTION; +explain SELECT * FROM t3 WHERE a>1 LIMIT 100 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 NULL range a a 5 NULL 3 100.00 Using offset pushdown; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where (`test`.`t3`.`a` > 1) limit 1,100 +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t3 WHERE a > 1 LIMIT 100 OFFSET 1; +a b +3 3 +4 3 +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +1 +# session 2: Insert rows in the table queried by OP +UPDATE t3 SET a = 8 WHERE a =4; +# (8,3) is updated here +SELECT * FROM t3; +a b +1 2 +2 3 +3 3 +8 3 +# (8,3) is not updated. +SELECT * FROM t3 WHERE a > 1 LIMIT 100 OFFSET 1; +a b +3 3 +4 3 +rollback; +rollback; +# ---------------------- +# ---------------------- +# Additional testing for MVCC UPDATE : SELECT first - UPDATE then with VARCHAR +# ---------------------- +# ---------------------- +CREATE TABLE t4 ( a INT, b VARCHAR(50), INDEX(a)); +INSERT INTO t4 VALUES (1,'apples'),(2,'bananas'), (3,'oranges'),(4,'pears'); +start transaction; +EXPLAIN format=tree SELECT * FROM t4 WHERE a > 2 LIMIT 10 OFFSET 1; +EXPLAIN +-> Limit/Offset: 10/1 row(s), with offset pushdown (cost=1.16 rows=2) + -> Index range scan on t4 using a over (2 < a) (cost=1.16 rows=2) + +# Does not inspect clustered record. +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t4 WHERE a > 2 LIMIT 10 OFFSET 1; +a b +4 pears +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +1 +start transaction; +UPDATE t4 SET a = 2 WHERE a > 1; +UPDATE t4 SET b = ' I really do not like fruits' WHERE a = 2; +SELECT * FROM t4; +a b +1 apples +2 I really do not like fruits +2 I really do not like fruits +2 I really do not like fruits +# Inspect clustered record - table unchanged +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t4 WHERE a > 2 LIMIT 10 OFFSET 1; +a b +4 pears +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +1 +rollback; +rollback; +DROP TABLE t4; +# ---------------------- +# ---------------------- +# With PK access +# ---------------------- +# ---------------------- +CREATE TABLE t4 ( a INT, b VARCHAR(50), PRIMARY KEY (a)); +INSERT INTO t4 VALUES (1,'apples'),(2,'bananas'), (3,'oranges'),(4,'pears'); +start transaction; +EXPLAIN format=tree SELECT * FROM t4 WHERE a > 2 LIMIT 10 OFFSET 1; +EXPLAIN +-> Limit/Offset: 10/1 row(s), with offset pushdown (cost=0.91 rows=2) + -> Index range scan on t4 using PRIMARY over (2 < a) (cost=0.91 rows=2) + +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t4 WHERE a > 2 LIMIT 10 OFFSET 1; +a b +4 pears +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +1 +start transaction; +UPDATE t4 SET a = 5 WHERE a = 1; +UPDATE t4 SET b = ' I really do not like fruits' WHERE a = 5; +SELECT * FROM t4; +a b +2 bananas +3 oranges +4 pears +5 I really do not like fruits +# table unchanged +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t4 WHERE a > 2 LIMIT 10 OFFSET 1; +a b +4 pears +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +1 +rollback; +rollback; +DROP TABLE t4; +# ---------------------- +# ---------------------- +# MVCC DELETE and OFFSET pushdown +# ---------------------- +# ---------------------- +# Delete row in one session, not committed, SELECT query (including the row to be deleted) +# with OP in another session - check that results are consistent +insert into t3 values (3,10),(3,11),(3,12); +# session 1: Trx that delete a row +start transaction; +DELETE FROM t3 WHERE a > 2; +SELECT * FROM t3; +a b +1 2 +2 3 +# session 2 : Trx that SELECTs the "to be deleted" row with OP - check that the deleted rows is not accounted for +# neither for the SELECT with and without OFFSET pushdown. +explain SELECT * FROM t3 WHERE a = 3 LIMIT 100 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 NULL ref a a 5 const 4 100.00 Using offset pushdown; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where (`test`.`t3`.`a` = 3) limit 1,100 +# They both output the same - rows skipped differ +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN()*/ * FROM t3 WHERE a=3 LIMIT 100 OFFSET 1; +a b +3 10 +3 11 +3 12 +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +0 +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t3 WHERE a = 3 LIMIT 100 OFFSET 1; +a b +3 10 +3 11 +3 12 +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +1 +rollback; +# ---------------------- +# ---------------------- +# SELECT first- DELETE NEXT +# ---------------------- +# ---------------------- +# session 1: SELECT with OP +start transaction; +explain SELECT * FROM t3 WHERE a = 3 LIMIT 100 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 NULL ref a a 5 const 4 100.00 Using offset pushdown; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where (`test`.`t3`.`a` = 3) limit 1,100 +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t3 WHERE a = 3 LIMIT 100 OFFSET 1; +a b +3 10 +3 11 +3 12 +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +1 +# session 2 : DELETE after SELECT with OP +DELETE FROM t3 WHERE a > 2; +# rows are deleted here +SELECT * FROM t3; +a b +1 2 +2 3 +# rows are not deleted here +SELECT * FROM t3 WHERE a = 3 LIMIT 100 OFFSET 1; +a b +3 10 +3 11 +3 12 +rollback; +rollback; +DROP TABLE t3; +# ---------------------- +# ---------------------- +# SELECT for UPDATE - INSERT with LOCKING READ +# ---------------------- +# ---------------------- +CREATE TABLE t1 ( +dummy INT PRIMARY KEY, +a INT UNIQUE, +b INT, +KEY (a) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5); +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +START TRANSACTION; +EXPLAIN SELECT * FROM t1 WHERE a < 2 FOR UPDATE; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL range a,a_2 a 5 NULL 1 100.00 NULL +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`dummy` AS `dummy`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` < 2) +SELECT * FROM t1 WHERE a < 2 FOR UPDATE; +dummy a b +1 1 1 +START TRANSACTION; +explain format=tree SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t1 LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s) (cost=#.# rows=##) + -> Table scan on t1 (cost=#.# rows=##) + +explain format=tree SELECT * FROM t1 LIMIT 100 OFFSET 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=#.# rows=##) + -> Table scan on t1 (cost=#.# rows=##) + +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t1 LIMIT 100 OFFSET 1; +dummy a b +2 2 2 +3 3 3 +4 4 4 +5 5 5 +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +0 +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t1 LIMIT 100 OFFSET 1; +dummy a b +2 2 2 +3 3 3 +4 4 4 +5 5 5 +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +1 +ROLLBACK; +ROLLBACK; +DROP TABLE t1; +# SELECT for update +CREATE TABLE t1 ( +dummy INT PRIMARY KEY, +a INT UNIQUE, +b INT, +KEY (a) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5); +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +START TRANSACTION; +EXPLAIN SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t1 WHERE a < 2 LIMIT 100 OFFSET 2 FOR UPDATE; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL range a,a_2 a 5 NULL 1 100.00 NULL +Warnings: +Note 1003 /* select#1 */ select /*+ NO_OFFSET_PUSHDOWN(@`select#1`) */ `test`.`t1`.`dummy` AS `dummy`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` < 2) limit 2,100 +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t1 WHERE a < 2 LIMIT 100 OFFSET 2 FOR UPDATE; +dummy a b +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +0 +START TRANSACTION; +INSERT INTO t1 VALUES (2,2,2); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +ROLLBACK; +ROLLBACK; +DROP TABLE t1; +# SELECT for update with OP activated in for update +CREATE TABLE t1 ( +dummy INT PRIMARY KEY, +a INT UNIQUE, +b INT, +KEY (a) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5); +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +START TRANSACTION; +EXPLAIN SELECT * FROM t1 WHERE a < 2 LIMIT 100 OFFSET 2 FOR UPDATE; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL range a,a_2 a 5 NULL 1 100.00 Using offset pushdown +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`dummy` AS `dummy`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` < 2) limit 2,100 +# does not place a lock on the rows skipped by OFFSET pushdown +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t1 WHERE a < 2 LIMIT 100 OFFSET 2 FOR UPDATE; +dummy a b +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +1 +START TRANSACTION; +# OP is deactivated here +INSERT INTO t1 VALUES (2,2,2); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +ROLLBACK; +ROLLBACK; +DROP TABLE t1; +# ---------------- +# ---------------- +# Virtual COLUMN - UPDATE +# ---------------- +# ---------------- +CREATE TABLE tv ( +a INT DEFAULT NULL, +b INT DEFAULT NULL, +c INT GENERATED ALWAYS AS ((a + b)) VIRTUAL, +KEY c (c) +); +INSERT INTO tv(a,b) VALUES (1,2),(3,4),(5,6); +# NON-LOCKING read +start transaction; +EXPLAIN format=tree SELECT * FROM tv WHERE c > 5 LIMIT 1 OFFSET 1; +EXPLAIN +-> Limit/Offset: 1/1 row(s), with offset pushdown (cost=1.16 rows=1) + -> Index range scan on tv using c over (5 < c) (cost=1.16 rows=2) + +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM tv WHERE c > 5 LIMIT 1 OFFSET 1; +a b c +5 6 11 +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +1 +start transaction; +UPDATE tv SET a = 12 WHERE b > 1; +SELECT * FROM tv; +a b c +12 2 14 +12 4 16 +12 6 18 +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM tv WHERE c > 5 LIMIT 1 OFFSET 1; +a b c +5 6 11 +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +1 +rollback; +rollback; +# ---------------- +# ---------------- +# Virtual COLUMN: UPDATE with LOCKING READ +# ---------------- +# ---------------- +start transaction; +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM tv WHERE c > 5 LIMIT 1 OFFSET 1 FOR UPDATE; +a b c +5 6 11 +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +1 +start transaction; +UPDATE tv SET a = 15 WHERE b = 2; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE tv SET a = 12 WHERE b > 2; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM tv WHERE c > 5 LIMIT 1 OFFSET 1; +a b c +5 6 11 +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skippped_rows +1 +rollback; +rollback; +DROP TABLE tv; +# Restore orig wait timeout +SET @@global.innodb_lock_wait_timeout = @old_innodb_lock_wait_timeout; +DROP TABLE IF EXISTS t1; +Warnings: +Note 1051 Unknown table 'test.t1' diff --git a/mysql-test/r/offset_pushdown_limitations.result b/mysql-test/r/offset_pushdown_limitations.result new file mode 100644 index 00000000000..4f07cae6c02 --- /dev/null +++ b/mysql-test/r/offset_pushdown_limitations.result @@ -0,0 +1,136 @@ +# Cases where Offset pushdown cannot be used: +# To keep track of the number of rows skipped by offset pushdown we use: +# SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +# SELECT query +# SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +SET @old_innodb_lock_wait_timeout= @@global.innodb_lock_wait_timeout; +SET @@global.innodb_lock_wait_timeout = 1; +# 1/ Index scan scenarios +# Exotic scans not compatible with either offset pushing or redundant removal condition +#( no skip scan or group min max already addressed in main test file.) +# 1/a/ Using intersect() (grep shows it's always with Using where) - OR clause disable with offset pushdown +# Redundant range condition is not compatible with using intersect +# the where clause is going to stay - even if there is no where clause +# which seems unlikely offset pushdown is not compatible with it anyways +CREATE TABLE t1 +(a smallint, +b smallint, +c smallint, +KEY a (a), +KEY b (b) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1,1), (1,1,3),(1,2,7), (2,2,10),(1, 1, 13),(1, 2, 16),(2,1,19); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +EXPLAIN format=tree SELECT * FROM t1 WHERE b = 2 AND a = 2 LIMIT 1 OFFSET 1; +EXPLAIN +-> Limit/Offset: 1/1 row(s) (cost=#.# rows=##) + -> Filter: ((t1.a = 2) and (t1.b = 2)) (cost=#.# rows=##) + -> Intersect rows sorted by row ID (cost=#.# rows=##) + -> Index range scan on t1 using a over (a = 2) (cost=#.# rows=##) + -> Index range scan on t1 using b over (b = 2) (cost=#.# rows=##) + +DROP TABLE t1; +# 1/b/ Using union() - OR clause disabled with offset pushdown +# Redundant range condition is not compatible with using union +# the where clause is going to stay - even if there is no where clause +# which seems unlikely offset pushdown is not compatible with it anyways (grep shows) +CREATE TABLE t1 +( +key1 INT NOT NULL, +key2 INT NOT NULL, +key3 INT NOT NULL, +key4 INT NOT NULL, +key5 INT, +key6 INT, +key7 INT NOT NULL, +key8 INT NOT NULL, +INDEX i1(key1), +INDEX i2(key2), +INDEX i3(key3), +INDEX i4(key4), +INDEX i5(key5), +INDEX i6(key6) +); +INSERT INTO t1 VALUES ( 1,1,1,1,1,1,1,1),(2,2,2,2,2,2,2,2); +SET @d=2; +INSERT INTO t1 SELECT key1+@d, key2+@d, key3+@d, key4+@d, +key5+@d, key6+@d, key7+@d, key8+@d FROM t1; +SET @d=@d*2; +INSERT INTO t1 SELECT key1+@d, key2+@d, key3+@d, key4+@d, +key5+@d, key6+@d, key7+@d, key8+@d FROM t1; +SET @d=@d*2; +INSERT INTO t1 SELECT key1+@d, key2+@d, key3+@d, key4+@d, +key5+@d, key6+@d, key7+@d, key8+@d FROM t1; +SET @d=@d*2; +INSERT INTO t1 SELECT key1+@d, key2+@d, key3+@d, key4+@d, +key5+@d, key6+@d, key7+@d, key8+@d FROM t1; +SET @d=@d*2; +INSERT INTO t1 SELECT key1+@d, key2+@d, key3+@d, key4+@d, +key5+@d, key6+@d, key7+@d, key8+@d FROM t1; +SET @d=@d*2; +INSERT INTO t1 SELECT key1+@d, key2+@d, key3+@d, key4+@d, +key5+@d, key6+@d, key7+@d, key8+@d FROM t1; +SET @d=@d*2; +INSERT INTO t1 SELECT key1+@d, key2+@d, key3+@d, key4+@d, +key5+@d, key6+@d, key7+@d, key8+@d FROM t1; +SET @d=@d*2; +INSERT INTO t1 SELECT key1+@d, key2+@d, key3+@d, key4+@d, +key5+@d, key6+@d, key7+@d, key8+@d FROM t1; +SET @d=@d*2; +INSERT INTO t1 SELECT key1+@d, key2+@d, key3+@d, key4+@d, +key5+@d, key6+@d, key7+@d, key8+@d FROM t1; +SET @d=@d*2; +INSERT INTO t1 SELECT key1+@d, key2+@d, key3+@d, key4+@d, +key5+@d, key6+@d, key7+@d, key8+@d FROM t1; +SET @d=@d*2; +EXPLAIN SELECT * FROM t1 WHERE key1=48 OR key4=2 OR key6=3 LIMIT 1 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL index_merge i1,i4,i6 i1,i4,i6 4,4,5 NULL 3 100.00 Using union(i1,i4,i6); Using where +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`key1` AS `key1`,`test`.`t1`.`key2` AS `key2`,`test`.`t1`.`key3` AS `key3`,`test`.`t1`.`key4` AS `key4`,`test`.`t1`.`key5` AS `key5`,`test`.`t1`.`key6` AS `key6`,`test`.`t1`.`key7` AS `key7`,`test`.`t1`.`key8` AS `key8` from `test`.`t1` where ((`test`.`t1`.`key1` = 48) or (`test`.`t1`.`key4` = 2) or (`test`.`t1`.`key6` = 3)) limit 1,1 +DROP TABLE t1; +# ------------ +# Multi values index and offset pushdown +# The three ways that can trigger the use of the multivalue index (MEMBER OF() JSON_CONTAINS() JSON_OVERLAPS()) cannot +# be pushed down by ICP or by empty_redundant_check_in_range_scan +# Multi values index won't be used together with offset pushdown until that changes +# ------------ +CREATE TABLE customers ( +id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, +modified DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, +custinfo JSON +); +INSERT INTO customers VALUES +(NULL, '2022-04-19 10:15:45', '{"user":"Jack","user_id":37,"zipcode":[94582,94536]}'), +(NULL, '2022-04-19 10:15:45', '{"user":"Jill","user_id":22,"zipcode":[94568,94507,94582]}'), +(NULL, '2022-04-19 10:15:45', '{"user":"Bob","user_id":31,"zipcode":[94477,94507]}'), +(NULL, '2022-04-19 10:15:45', '{"user":"Mary","user_id":72,"zipcode":[94536]}'), +(NULL, '2022-04-19 10:15:45', '{"user":"Ted","user_id":56,"zipcode":[94507,94582]}'); +# add multi value index +ALTER TABLE customers ADD INDEX zips( (CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY)) ); +# Using where stays - no offset pushdown +EXPLAIN SELECT * FROM customers WHERE 94507 MEMBER OF(custinfo->'$.zipcode') LIMIT 1 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE customers NULL ref zips zips 9 const 3 100.00 Using where +Warnings: +Note 1003 /* select#1 */ select `test`.`customers`.`id` AS `id`,`test`.`customers`.`modified` AS `modified`,`test`.`customers`.`custinfo` AS `custinfo` from `test`.`customers` where json'94507' member of (cast(json_extract(`custinfo`,_utf8mb4'$.zipcode') as unsigned array)) limit 1,1 +EXPLAIN format=tree SELECT * FROM customers +WHERE JSON_CONTAINS(custinfo->'$.zipcode', CAST('[94507,94582]' AS JSON)) LIMIT 1 OFFSET 1; +EXPLAIN +-> Limit/Offset: 1/1 row(s) (cost=#.# rows=##) + -> Filter: json_contains(cast(json_extract(custinfo,_utf8mb4'$.zipcode') as unsigned array),json'[94507, 94582]') (cost=#.# rows=##) + -> Index range scan on customers using zips over (94582 MEMBER OF (json_extract(custinfo,_utf8mb4'$.zipcode'))) OR (94507 MEMBER OF (json_extract(custinfo,_utf8mb4'$.zipcode'))) (cost=#.# rows=##) + +EXPLAIN format=tree SELECT * FROM customers WHERE JSON_OVERLAPS(custinfo->'$.zipcode', CAST('[94507,94582]' AS JSON)) LIMIT 1 OFFSET 1; +EXPLAIN +-> Limit/Offset: 1/1 row(s) (cost=#.# rows=##) + -> Filter: json_overlaps(cast(json_extract(custinfo,_utf8mb4'$.zipcode') as unsigned array),json'[94507, 94582]') (cost=#.# rows=##) + -> Index range scan on customers using zips over (94582 MEMBER OF (json_extract(custinfo,_utf8mb4'$.zipcode'))) OR (94507 MEMBER OF (json_extract(custinfo,_utf8mb4'$.zipcode'))) (cost=#.# rows=##) + +drop table customers; +SET @@global.innodb_lock_wait_timeout= @old_innodb_lock_wait_timeout; +DROP TABLE IF EXISTS t1; +Warnings: +Note 1051 Unknown table 'test.t1' diff --git a/mysql-test/r/offset_pushdown_locking_test.result b/mysql-test/r/offset_pushdown_locking_test.result new file mode 100644 index 00000000000..c9c400c6bcd --- /dev/null +++ b/mysql-test/r/offset_pushdown_locking_test.result @@ -0,0 +1,1295 @@ +# ------------------------------- +# ------------------------------- +# Content of the test file: +# Offset pushdown and non-locking read +# SELECT LIMIT OFFSET FOR UPDATE w/ and w/o OP +# check locking - insert - # of rows skipped +# READ COMMITED +# LOCK IN SHARE MODE +# READ UNCOMMITTED +# SKIP LOCKED +# NO WAIT +# SERIALIZABLE +# FOR UPDATE with serializable - all read rows have an x-lock -> equivalent to FOR UPDATE with RR +# LOCK IN SHARE MODE with serializable - read rows have a s-lock - no different to LOCK IN SHARE MODE with RR +# To keep track of the number of rows skipped by offset pushdown we use: +# SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +# SELECT query +# SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +# ------------------------------- +# ------------------------------- +SET @old_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout; +SET @@global.innodb_lock_wait_timeout = 1; +# TOP +# ------------------------------- +# SELECT LIMIT OFFSET FOR UPDATE w/ and w/o OP +# check locking - insert - # of rows skipped +# ------------------------------ +# ------------------------------- +# Without OP +# ------------------------------- +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); +# Compare locks and count how many rows are skipped +# template query: SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap WHERE a BETWEEN 15 AND 25 LIMIT 100 OFFSET 2 FOR UPDATE; +# To check locking status use: SHOW ENGINE INNODB STATUS; with SET GLOBAL innodb_status_output_locks=ON; SET GLOBAL innodb_status_output=ON; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap WHERE a BETWEEN 15 AND 25 LIMIT 100 OFFSET 2 FOR UPDATE; +a +# Check that we don't skip any rows +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +START TRANSACTION; +# Should go through +INSERT INTO t_gap VALUES (9); +INSERT INTO t_gap VALUES (31); +# next key locking +INSERT INTO t_gap VALUES (11); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t_gap VALUES (29); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +# gap lock +INSERT INTO t_gap VALUES (18); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t_gap VALUES (23); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +rollback; +DROP TABLE t_gap; +# ------------------------------- +# With OP +# ------------------------------- +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); +# Compare locks and count how many rows are skipped +# Template query: SELECT * FROM t_gap WHERE a BETWEEN 15 AND 25 LIMIT 100 OFFSET 2 FOR UPDATE; +# To check locking status use: SHOW ENGINE INNODB STATUS; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap WHERE a BETWEEN 15 AND 25 LIMIT 100 OFFSET 2 FOR UPDATE; +a +# Check that we only skip one row +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +1 +START TRANSACTION; +# Should go through +INSERT INTO t_gap VALUES (9); +INSERT INTO t_gap VALUES (31); +# next key locking +INSERT INTO t_gap VALUES (11); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t_gap VALUES (29); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +# gap lock +INSERT INTO t_gap VALUES (18); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t_gap VALUES (23); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +rollback; +DROP TABLE t_gap; +# UPDATE statement locks and gaps locks +# -------------------- +# Without OP +# -------------------- +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30),(40),(50),(60),(70),(80),(90),(100); +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap WHERE a BETWEEN 45 AND 65 LIMIT 100 OFFSET 3 FOR UPDATE; +a +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +START TRANSACTION; +# Record LOCKs +UPDATE t_gap SET a = 200 WHERE a = 50; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t_gap SET a = 300 WHERE a = 60; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +# Next key locking +UPDATE t_gap SET a = 67 WHERE a = 10; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t_gap SET a = 42 WHERE a = 20; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t_gap SET a = 200 WHERE a = 40; +UPDATE t_gap SET a = 300 WHERE a = 70; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +# Gap Locks +UPDATE t_gap SET a = 47 WHERE a = 10; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t_gap SET a = 63 WHERE a = 90; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +# No locks outside next key locking +DELETE FROM t_gap WHERE a=20; +DELETE FROM t_gap WHERE a=90; +INSERT INTO t_gap values (75),(85); +UPDATE t_gap SET a = 85 WHERE a = 80; +rollback; +rollback; +DROP TABLE t_gap; +# -------------------- +# With Offset pushdown +# -------------------- +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30),(40),(50),(60),(70),(80),(90),(100); +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap WHERE a BETWEEN 45 AND 65 LIMIT 100 OFFSET 3 FOR UPDATE; +a +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +2 +START TRANSACTION; +# Record LOCKs +UPDATE t_gap SET a = 200 WHERE a = 50; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t_gap SET a = 300 WHERE a = 60; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +# Next key locking +UPDATE t_gap SET a = 67 WHERE a = 10; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t_gap SET a = 42 WHERE a = 20; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t_gap SET a = 200 WHERE a = 40; +UPDATE t_gap SET a = 300 WHERE a = 70; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +# Gap Locks +UPDATE t_gap SET a = 47 WHERE a = 10; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t_gap SET a = 63 WHERE a = 90; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +# No locks outside next key locking +DELETE FROM t_gap WHERE a=20; +DELETE FROM t_gap WHERE a=90; +INSERT INTO t_gap values (75),(85); +UPDATE t_gap SET a = 85 WHERE a = 80; +rollback; +rollback; +DROP TABLE t_gap; +# --------------------------------------------------- +# Skipping pk access +# --------------------------------------------------- +# --------------------------------------------------- +# WITHOUT OP +# --------------------------------------------------- +CREATE TABLE t1 (b INT, PRIMARY KEY (b)); +INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(7); +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ b FROM t1 WHERE b>2 AND b<5 LIMIT 100 OFFSET 100 FOR UPDATE; +b +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +start transaction; +UPDATE t1 SET b = 100 WHERE b = 2; +rollback; +start transaction; +UPDATE t1 SET b = 100 WHERE b = 3; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t1 SET b = 100 WHERE b = 4; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t1 SET b = 100 WHERE b = 5; +rollback; +rollback; +DROP TABLE t1; +# --------------------------------------------------- +# WITH OP +# --------------------------------------------------- +CREATE TABLE t1 (b INT, PRIMARY KEY (b)); +INSERT INTO t1 VALUES (1), (2), (3), (4),(5),(7); +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT b FROM t1 WHERE b>2 AND b<5 LIMIT 100 OFFSET 100 FOR UPDATE; +b +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +2 +start transaction; +UPDATE t1 SET b = 100 WHERE b = 2; +rollback; +start transaction; +UPDATE t1 SET b = 100 WHERE b = 3; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t1 SET b = 100 WHERE b = 4; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t1 SET b = 100 WHERE b = 5; +rollback; +rollback; +DROP TABLE t1; +# --------------------------------------------------- +# --------------------------------------------------- +# SERIALIZABLE +# --------------------------------------------------- +# --------------------------------------------------- +# ------------------------------- +# Without OP +# ------------------------------- +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); +# Compare locks and count how many rows are skipped +# To check locking status use: SHOW ENGINE INNODB STATUS; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap WHERE a BETWEEN 15 AND 25 LIMIT 100 OFFSET 2 FOR UPDATE; +a +# Check that we don't skip any rows +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +START TRANSACTION; +# Should go through +INSERT INTO t_gap VALUES (9); +INSERT INTO t_gap VALUES (31); +# next key locking +INSERT INTO t_gap VALUES (11); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t_gap VALUES (29); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +# gap lock +INSERT INTO t_gap VALUES (18); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t_gap VALUES (23); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +rollback; +DROP TABLE t_gap; +# ------------------------------- +# With OP +# ------------------------------- +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); +# Compare locks and count how many rows are skipped +# To check locking status use: SHOW ENGINE INNODB STATUS; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap WHERE a BETWEEN 15 AND 25 LIMIT 100 OFFSET 2 FOR UPDATE; +a +# Check that we only skip one row +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +1 +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +START TRANSACTION; +# Should go through +INSERT INTO t_gap VALUES (9); +INSERT INTO t_gap VALUES (31); +# next key locking +INSERT INTO t_gap VALUES (11); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t_gap VALUES (29); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +# gap lock +INSERT INTO t_gap VALUES (18); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t_gap VALUES (23); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +rollback; +DROP TABLE t_gap; +# --------------------------------------------------- +# --------------------------------------------------- +# READ COMMITED +# --------------------------------------------------- +# --------------------------------------------------- +# --------------------------------------------------- +# Without OP +# --------------------------------------------------- +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 50 FOR UPDATE; +a +# Check that no rows are skipped +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +# To check locking status use: SHOW ENGINE INNODB STATUS; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +UPDATE t_gap SET a = 30 WHERE a = 10; +UPDATE t_gap SET a = 30 WHERE a = 20; +UPDATE t_gap SET a = 30 WHERE a = 30; +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +rollback; +rollback; +DROP TABLE t_gap; +# --------------------------------------------------- +# With OP +# --------------------------------------------------- +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 50 FOR UPDATE; +a +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +3 +# To check locking status use: SHOW ENGINE INNODB STATUS; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +UPDATE t_gap SET a = 30 WHERE a = 10; +UPDATE t_gap SET a = 30 WHERE a = 20; +UPDATE t_gap SET a = 30 WHERE a = 30; +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +rollback; +rollback; +DROP TABLE t_gap; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +# --------------------------------------------------- +# READ COMMITED without OP (bis) +# --------------------------------------------------- +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); +# +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE; +a +20 +30 +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +# To check locking status use: SHOW ENGINE INNODB STATUS; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +UPDATE t_gap SET a = 30 WHERE a = 10; +UPDATE t_gap SET a = 30 WHERE a = 20; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t_gap SET a = 30 WHERE a = 30; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +rollback; +rollback; +DROP TABLE t_gap; +# --------------------------------------------------- +# READ COMMITED with OP (bis) +# --------------------------------------------------- +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE; +a +20 +30 +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +1 +# To check locking status use: SHOW ENGINE INNODB STATUS; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +UPDATE t_gap SET a = 30 WHERE a = 10; +UPDATE t_gap SET a = 30 WHERE a = 20; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t_gap SET a = 30 WHERE a = 30; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +rollback; +rollback; +DROP TABLE t_gap; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +# --------------------------------------------------- +#READ COMMITTED: Skipping pk access- check lock release +# --------------------------------------------------- +# --------------------------------------------------- +# WITHOUT OP +# --------------------------------------------------- +CREATE TABLE t1 (b INT, PRIMARY KEY (b)); +INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(7); +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ b FROM t1 LIMIT 100 OFFSET 100 FOR UPDATE; +b +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +UPDATE t1 SET b = 100 WHERE b = 3; +rollback; +rollback; +DROP TABLE t1; +# --------------------------------------------------- +# WITH OP +# --------------------------------------------------- +CREATE TABLE t1 (b INT, PRIMARY KEY (b)); +INSERT INTO t1 VALUES (1), (2), (3), (4),(5),(7); +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT b FROM t1 LIMIT 100 OFFSET 100 FOR UPDATE; +b +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +6 +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +UPDATE t1 SET b = 100 WHERE b = 3; +rollback; +rollback; +DROP TABLE t1; +# --------------------------------------------------- +# --------------------------------------------------- +# LOCK IN SHARE MODE +# For RR, check that we can read but not update rows +# For RC, can read, can't write - check what happens for released locks +# --------------------------------------------------- +# --------------------------------------------------- +# --------------------------------------------------- +# For RR, check that we can read but not update rows +# --------------------------------------------------- +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); +# --------------------------------------------------- +# Without OP +# --------------------------------------------------- +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 50 LOCK IN SHARE MODE; +a +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +start transaction; +SELECT * FROM t_gap WHERE a = 10 OR a = 20 OR a = 30; +a +10 +20 +30 +UPDATE t_gap SET a = 100 WHERE a = 10; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t_gap SET a = 100 WHERE a = 30; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t_gap VALUES (1); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t_gap VALUES (15); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t_gap VALUES (25); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t_gap VALUES (1000); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +rollback; +# ----------------------------------- +# With OP +# ----------------------------------- +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 50 LOCK IN SHARE MODE; +a +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +3 +start transaction; +SELECT * FROM t_gap WHERE a = 10 OR a = 20 OR a = 30; +a +10 +20 +30 +UPDATE t_gap SET a = 30 WHERE a = 10; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t_gap SET a = 30 WHERE a = 30; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t_gap VALUES (1); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t_gap VALUES (15); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t_gap VALUES (25); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t_gap VALUES (1000); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +rollback; +DROP TABLE t_gap; +# --------------------------------------------------- +# For RC, check that we can slide in the gaps +# --------------------------------------------------- +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); +# --------------------------------------------------- +# Without OP +# --------------------------------------------------- +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 50 LOCK IN SHARE MODE; +a +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT * FROM t_gap WHERE a = 10 OR a = 20 OR a = 30; +a +10 +20 +30 +UPDATE t_gap SET a = 50 WHERE a = 10; +UPDATE t_gap SET a = 60 WHERE a = 30; +INSERT INTO t_gap VALUES (1); +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +INSERT INTO t_gap VALUES (1000); +rollback; +rollback; +# --------------------------------------------------- +# With OP +# --------------------------------------------------- +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 50 LOCK IN SHARE MODE; +a +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +3 +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT * FROM t_gap WHERE a = 10 OR a = 20 OR a = 30; +a +10 +20 +30 +UPDATE t_gap SET a = 50 WHERE a = 10; +UPDATE t_gap SET a = 60 WHERE a = 30; +INSERT INTO t_gap VALUES (1); +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +INSERT INTO t_gap VALUES (1000); +rollback; +rollback; +# --------------------------------------------------- +# For RC, LOCK IN SHARED MODE places shared lock on all the read rows, so even if they are not displayed the locks stay in place +# but we can still insert in the gaps +# --------------------------------------------------- +# --------------------------------------------------- +# Without OP +# --------------------------------------------------- +# how do i check if there is a gap lock? - gap lock is respected +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 1 LOCK IN SHARE MODE; +a +20 +30 +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +# not released even though it's not output +UPDATE t_gap SET a = 50 WHERE a = 10; +INSERT INTO t_gap VALUES (1); +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +INSERT INTO t_gap VALUES (1000); +rollback; +rollback; +# --------------------------------------------------- +# With OP +# --------------------------------------------------- +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 1 LOCK IN SHARE MODE; +a +20 +30 +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +1 +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +# not release even though it's not output +UPDATE t_gap SET a = 50 WHERE a = 10; +INSERT INTO t_gap VALUES (1); +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +INSERT INTO t_gap VALUES (1000); +rollback; +rollback; +# --------------------------------------------------- +# READ UNCOMMITTED +# --------------------------------------------------- +# --------------------------------------------------- +# Without OP +# --------------------------------------------------- +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-UNCOMMITTED +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 50 FOR UPDATE; +a +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +# NO LOCKS placed ! +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-UNCOMMITTED +SELECT * FROM t_gap WHERE a = 10 OR a = 20 OR a = 30; +a +10 +20 +30 +UPDATE t_gap SET a = 50 WHERE a = 10; +UPDATE t_gap SET a = 60 WHERE a = 30; +INSERT INTO t_gap VALUES (1); +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +INSERT INTO t_gap VALUES (1000); +rollback; +rollback; +# --------------------------------------------------- +# With OP +# --------------------------------------------------- +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-UNCOMMITTED +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 50 FOR UPDATE; +a +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +3 +# NO LOCKS placed ! +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-UNCOMMITTED +SELECT * FROM t_gap WHERE a = 10 OR a = 20 OR a = 30; +a +10 +20 +30 +UPDATE t_gap SET a = 50 WHERE a = 10; +UPDATE t_gap SET a = 60 WHERE a = 30; +INSERT INTO t_gap VALUES (1); +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +INSERT INTO t_gap VALUES (1000); +rollback; +rollback; +# --------------------------------------------------- +# SKIP LOCKED +# --------------------------------------------------- +# --------------------------------------------------- +# Without OP +# --------------------------------------------------- +INSERT INTO t_gap VALUES (40),(50),(60); +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE; +a +20 +30 +40 +50 +60 +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +# No output all locked +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE SKIP LOCKED; +a +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +rollback; +rollback; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap WHERE a <15 LIMIT 100 OFFSET 1 FOR UPDATE; +a +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +# 10 20 locked, 30 skipped by OFFSET - rest : output +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE SKIP LOCKED; +a +40 +50 +60 +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +rollback; +rollback; +# --------------------------------------------------- +# With OP +# --------------------------------------------------- +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE; +a +20 +30 +40 +50 +60 +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +1 +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +# No output all locked +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE SKIP LOCKED; +a +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +rollback; +rollback; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap WHERE a < 15 LIMIT 100 OFFSET 1 FOR UPDATE; +a +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +1 +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +# 10 20 locked, 30 skipped by OFFSET - rest : output +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE SKIP LOCKED; +a +40 +50 +60 +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +1 +rollback; +rollback; +# --------------------------------------------------- +# NO WAIT +# --------------------------------------------------- +# --------------------------------------------------- +# Without OP +# --------------------------------------------------- +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE; +a +20 +30 +40 +50 +60 +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +# No output all locked +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE NOWAIT; +ERROR HY000: Statement aborted because lock(s) could not be acquired immediately and NOWAIT is set. +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +rollback; +rollback; +# --------------------------------------------------- +# With OP +# --------------------------------------------------- +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE; +a +20 +30 +40 +50 +60 +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +1 +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +# No output all locked +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE NOWAIT; +ERROR HY000: Statement aborted because lock(s) could not be acquired immediately and NOWAIT is set. +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +rollback; +rollback; +# ------------------------------------------------- +# ------------------------------------------------- +# End range check for OP at supremum (same for locking and non locking reads) +# ------------------------------------------------- +# ------------------------------------------------- +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +INSERT INTO t_gap SELECT * FROM t_gap; +INSERT INTO t_gap SELECT * FROM t_gap; +INSERT INTO t_gap SELECT * FROM t_gap; +INSERT INTO t_gap SELECT * FROM t_gap; +INSERT INTO t_gap SELECT * FROM t_gap; +INSERT INTO t_gap SELECT * FROM t_gap; +INSERT INTO t_gap SELECT * FROM t_gap; +INSERT INTO t_gap SELECT * FROM t_gap; +INSERT INTO t_gap VALUES (5); +# Show status shows we skipped less than 1000 OFFSET rows - stopped by end range check on page supremum. +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap WHERE a < 8 LIMIT 1 OFFSET 1000; +a +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +533 +# Show status shows we skipped less than 3000 OFFSET rows - stopped by end range check on page supremum +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap WHERE a < 11 LIMIT 1 OFFSET 3000; +a +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +533 +SET empty_redundant_check_in_range_scan=true; +DROP TABLE t_gap; +# ------------------------------------------------- +# ------------------------------------------------- +# End range check v ICP_OUT_OF_RANGE +# ------------------------------------------------- +# ------------------------------------------------- +CREATE TABLE t2 (a INT, b INT, c INT, INDEX(a,b)); +INSERT INTO t2 VALUES (1,10,4),(2,20,5),(3,30,6),(4,40,12),(5,50,13),(6,60,14),(7,70,15); +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +# End of range check does not apply with ICP - stopped by ICP out of range before OFFSET 5000 is reached +SET empty_redundant_check_in_range_scan = false; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t2 WHERE a = 1 AND b < 11 LIMIT 1 OFFSET 5000; +a b c +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +2048 +# ICP_OUT_OF_RANGE evaluated before systematic end of range check for locking scenario- no need to check end of range if idx_cond==true +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t2 WHERE a = 1 AND b < 11 LIMIT 1 OFFSET 5000 FOR UPDATE; +a b c +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +2048 +rollback; +DROP TABLE t2; +# ----------------- +# OP and ICP that hits ICP_NO_MATCH +# ----------------- +# -- +# RR +# -- +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +CREATE TABLE t0 (a VARCHAR(10), b INT, c INT, INDEX(a(10),b)); +insert into t0 values ('banama',1,1),('banana',1,1),('banana',2,3),('banana',3,3),('banaoa',3,6),('banapa',4,9),('banaqa',5,12); +explain format=tree SELECT a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=2.96 rows=6) + -> Index range scan on t0 using a over ('banama' < a), with index condition: ((t0.a > 'banama') and (t0.b > 2)) (cost=2.96 rows=6) + +explain format=tree SELECT /*+ NO_OFFSET_PUSHDOWN() */ a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s) (cost=2.96 rows=5) + -> Index range scan on t0 using a over ('banama' < a), with index condition: ((t0.a > 'banama') and (t0.b > 2)) (cost=2.96 rows=6) + +# row_search_mvcc hits ICP_NO_MATCH for ('banana',1,1),('banana',2,3) because 1 and 2 are smaller than 3 with and without OP +SELECT /*+ NO_OFFSET_PUSHDOWN() */ a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1; +a c +banaoa 6 +banapa 9 +banaqa 12 +# ('banana',3,3) is skipped by offset pushdown in innodb +SELECT a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1; +a c +banaoa 6 +banapa 9 +banaqa 12 +explain format=tree SELECT a,c FROM t0 WHERE a>'banama' AND a<'banaqa' AND b>2 LIMIT 100 offset 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=2.51 rows=5) + -> Index range scan on t0 using a over ('banama' < a < 'banaqa'), with index condition: ((t0.a > 'banama') and (t0.a < 'banaqa') and (t0.b > 2)) (cost=2.51 rows=5) + +# row_search_mvcc hits ICP_OUT_OF_RANGE for ('banaqa',5,12) +SELECT a,c FROM t0 WHERE a>'banama' AND a<'banaqa' AND b>2 LIMIT 100 offset 1; +a c +banaoa 6 +banapa 9 +# -- +# OP and ICP that hits ICP_NO_MATCH with LOCKING READ +# -- +# Without OP +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1 FOR UPDATE; +a c +banaoa 6 +banapa 9 +banaqa 12 +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +# Next key locking interval is (x,y], we can therefore update the 'banama',1,1 +UPDATE t0 SET a = ' pears' WHERE a = 'banama'; +rollback; +start transaction; +# Next key locking interval is (x,y], we cannot therefore insert right of the 'banama',1,1 row +INSERT INTO t0 values ('banama',2,2); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 1; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 2; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 3 AND c=3; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t0 SET a = 'apples' WHERE a= 'banaoa' AND b = 3 AND c=6; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +rollback; +# With OP +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1 FOR UPDATE; +a c +banaoa 6 +banapa 9 +banaqa 12 +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +1 +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +REPEATABLE-READ +# Next key locking interval is (x,y], we can therefore update the 'banama',1,1 +UPDATE t0 SET a = ' pears' WHERE a = 'banama'; +rollback; +start transaction; +# Next key locking interval is (x,y], we cannot therefore insert right of the 'banama',1,1 row +INSERT INTO t0 values ('banama',2,2); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 1; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 2; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 3 AND c=3; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t0 SET a = 'apples' WHERE a= 'banaoa' AND b = 3 AND c=6; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +rollback; +# -- +# RC +# -- +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +explain format=tree SELECT a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=2.96 rows=6) + -> Index range scan on t0 using a over ('banama' < a), with index condition: ((t0.a > 'banama') and (t0.b > 2)) (cost=2.96 rows=6) + +explain format=tree SELECT /*+ NO_OFFSET_PUSHDOWN() */ a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s) (cost=2.96 rows=5) + -> Index range scan on t0 using a over ('banama' < a), with index condition: ((t0.a > 'banama') and (t0.b > 2)) (cost=2.96 rows=6) + +# row_search_mvcc hits ICP_NO_MATCH for ('banana',1,1),('banana',2,3) because 1 and 2 are smaller than 3 with and without OP +SELECT /*+ NO_OFFSET_PUSHDOWN() */ a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1; +a c +banaoa 6 +banapa 9 +banaqa 12 +# ('banana',3,3) is skipped by offset pushdown in innodb +SELECT a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1; +a c +banaoa 6 +banapa 9 +banaqa 12 +explain format=tree SELECT a,c FROM t0 WHERE a>'banama' AND a<'banaqa' AND b>2 LIMIT 100 offset 1; +EXPLAIN +-> Limit/Offset: 100/1 row(s), with offset pushdown (cost=2.51 rows=5) + -> Index range scan on t0 using a over ('banama' < a < 'banaqa'), with index condition: ((t0.a > 'banama') and (t0.a < 'banaqa') and (t0.b > 2)) (cost=2.51 rows=5) + +# row_search_mvcc hits ICP_OUT_OF_RANGE for ('banaqa',5,12) +SELECT a,c FROM t0 WHERE a>'banama' AND a<'banaqa' AND b>2 LIMIT 100 offset 1; +a c +banaoa 6 +banapa 9 +# -- +# RC - OP and ICP that hits ICP_NO_MATCH with LOCKING READ +# -- +# Without OP - Without ICP +# This test is there to show that ICP does not release the locks in RC for rows that are read and not returned to the client. +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +SET optimizer_switch = 'index_condition_pushdown=off'; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1 FOR UPDATE; +a c +banaoa 6 +banapa 9 +banaqa 12 +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +# Next key locking interval is (x,y], we can therefore update the 'banama',1,1 +UPDATE t0 SET a = ' pears' WHERE a = 'banama'; +rollback; +start transaction; +INSERT INTO t0 values ('banama',2,2); +rollback; +start transaction; +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 1; +rollback; +start transaction; +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 2; +rollback; +start transaction; +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 3 AND c=3; +rollback; +start transaction; +UPDATE t0 SET a = 'apples' WHERE a= 'banaoa' AND b = 3 AND c=6; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +rollback; +SET optimizer_switch = 'index_condition_pushdown=on'; +# Without OP +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1 FOR UPDATE; +a c +banaoa 6 +banapa 9 +banaqa 12 +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +0 +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +# Next key locking interval is (x,y], we can therefore update the 'banama',1,1 +UPDATE t0 SET a = ' pears' WHERE a = 'banama'; +rollback; +start transaction; +# NO Next key locking +INSERT INTO t0 values ('banama',2,2); +rollback; +start transaction; +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 1; +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 2; +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 3 AND c=3; +rollback; +start transaction; +UPDATE t0 SET a = 'apples' WHERE a= 'banaoa' AND b = 3 AND c=6; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +rollback; +# With OP +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1 FOR UPDATE; +a c +banaoa 6 +banapa 9 +banaqa 12 +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +variable_value - @save_skipped_rows +1 +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +# Next key locking interval is (x,y], we can therefore update the 'banama',1,1 +UPDATE t0 SET a = ' pears' WHERE a = 'banama'; +rollback; +start transaction; +SELECT @@transaction_isolation; +@@transaction_isolation +READ-COMMITTED +# Next key locking interval is (x,y], we can therefore update the 'banama',1,1 +UPDATE t0 SET a = ' pears' WHERE a = 'banama'; +rollback; +start transaction; +# NO Next key locking +INSERT INTO t0 values ('banama',2,2); +rollback; +start transaction; +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 1; +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 2; +# Skipped - Not returned lock released +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 3 AND c=3; +rollback; +start transaction; +UPDATE t0 SET a = 'apples' WHERE a= 'banaoa' AND b = 3 AND c=6; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +rollback; +DROP TABLE t0; +# Restore orig wait timeout +# BOTTOM +show variables LIKE '%innodb_lock_wait_timeout%'; +Variable_name Value +innodb_lock_wait_timeout 50 +SET @@global.innodb_lock_wait_timeout = @old_innodb_lock_wait_timeout; +show variables LIKE '%innodb_lock_wait_timeout%'; +Variable_name Value +innodb_lock_wait_timeout 50 +DROP TABLE if EXISTS t2; +Warnings: +Note 1051 Unknown table 'test.t2' diff --git a/mysql-test/r/opt_costmodel_myisam.result b/mysql-test/r/opt_costmodel_myisam.result index 90d2772995c..8c91fe50799 100644 --- a/mysql-test/r/opt_costmodel_myisam.result +++ b/mysql-test/r/opt_costmodel_myisam.result @@ -58,8 +58,7 @@ EXPLAIN }, "used_columns": [ "i1" - ], - "attached_condition": "(`test`.`t1`.`i1` > 1)" + ] } } } diff --git a/mysql-test/r/opt_hints.result b/mysql-test/r/opt_hints.result index c8cb4257348..2e9bff5d698 100644 --- a/mysql-test/r/opt_hints.result +++ b/mysql-test/r/opt_hints.result @@ -65,14 +65,14 @@ Handler_read_rnd 0 Handler_read_rnd_next 0 EXPLAIN SELECT f1 FROM t3 WHERE f1 > 30 AND f1 < 33; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range PRIMARY,f2_idx,f3_idx f2_idx 4 NULL 2 100.00 Using where; Using index +1 SIMPLE t3 NULL range PRIMARY,f2_idx,f3_idx f2_idx 4 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ 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 # Should use range access by f2_idx key EXPLAIN SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY) */ f1 FROM t3 WHERE f1 > 30 AND f1 < 33; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range PRIMARY,f2_idx,f3_idx f2_idx 4 NULL 2 100.00 Using where; Using index +1 SIMPLE t3 NULL range PRIMARY,f2_idx,f3_idx f2_idx 4 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ 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 @@ -102,21 +102,21 @@ EXPLAIN SELECT f2 FROM (SELECT f2, f3, f1 FROM t3 WHERE f1 > 27 AND f3 = 'poiu') AS TD WHERE TD.f1 > 27 AND TD.f3 = 'poiu'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range PRIMARY,f2_idx,f3_idx f3_idx 135 NULL 10 100.00 Using index condition +1 SIMPLE t3 NULL range PRIMARY,f2_idx,f3_idx f3_idx 135 NULL 10 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`f2` AS `f2` from `test`.`t3` where ((`test`.`t3`.`f3` = 'poiu') and (`test`.`t3`.`f1` > 27) and (`test`.`t3`.`f1` > 27)) EXPLAIN SELECT /*+ NO_ICP(t3@qb1 f3_idx) */ f2 FROM (SELECT /*+ QB_NAME(QB1) */ f2, f3, f1 FROM t3 WHERE f1 > 27 AND f3 = 'poiu') AS TD WHERE TD.f1 > 27 AND TD.f3 = 'poiu'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range PRIMARY,f2_idx,f3_idx f3_idx 135 NULL 10 100.00 Using where +1 SIMPLE t3 NULL range PRIMARY,f2_idx,f3_idx f3_idx 135 NULL 10 100.00 NULL Warnings: Note 1003 /* select#1 */ select /*+ NO_ICP(`t3`@`QB1` `f3_idx`) */ `test`.`t3`.`f2` AS `f2` from `test`.`t3` where ((`test`.`t3`.`f3` = 'poiu') and (`test`.`t3`.`f1` > 27) and (`test`.`t3`.`f1` > 27)) EXPLAIN SELECT /*+ NO_ICP(t3@qb1) */ f2 FROM (SELECT /*+ QB_NAME(QB1) */ f2, f3, f1 FROM t3 WHERE f1 > 27 AND f3 = 'poiu') AS TD WHERE TD.f1 > 27 AND TD.f3 = 'poiu'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range PRIMARY,f2_idx,f3_idx f3_idx 135 NULL 10 100.00 Using where +1 SIMPLE t3 NULL range PRIMARY,f2_idx,f3_idx f3_idx 135 NULL 10 100.00 NULL Warnings: Note 1003 /* select#1 */ select /*+ NO_ICP(`t3`@`QB1`) */ `test`.`t3`.`f2` AS `f2` from `test`.`t3` where ((`test`.`t3`.`f3` = 'poiu') and (`test`.`t3`.`f1` > 27) and (`test`.`t3`.`f1` > 27)) # Expected warning for f1_idx key, unresolved name. @@ -124,7 +124,7 @@ EXPLAIN SELECT f2 FROM (SELECT /*+ NO_ICP(t3 f3_idx, f1_idx, f2_idx) */ f2, f3, f1 FROM t3 WHERE f1 > 27 AND f3 = 'poiu') AS TD WHERE TD.f1 > 27 AND TD.f3 = 'poiu'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range PRIMARY,f2_idx,f3_idx f3_idx 135 NULL 10 100.00 Using where +1 SIMPLE t3 NULL range PRIMARY,f2_idx,f3_idx f3_idx 135 NULL 10 100.00 NULL Warnings: Warning 3128 Unresolved name `t3`@`select#2` `f1_idx` for NO_ICP hint Note 1003 /* select#1 */ select /*+ NO_ICP(`t3`@`select#2` `f3_idx`) NO_ICP(`t3`@`select#2` `f2_idx`) */ `test`.`t3`.`f2` AS `f2` from `test`.`t3` where ((`test`.`t3`.`f3` = 'poiu') and (`test`.`t3`.`f1` > 27) and (`test`.`t3`.`f1` > 27)) @@ -133,7 +133,7 @@ EXPLAIN SELECT f2 FROM (SELECT /*+ NO_ICP(t3 f1_idx, f2_idx) */ f2, f3, f1 FROM t3 WHERE f1 > 27 AND f3 = 'poiu') AS TD WHERE TD.f1 > 27 AND TD.f3 = 'poiu'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range PRIMARY,f2_idx,f3_idx f3_idx 135 NULL 10 100.00 Using index condition +1 SIMPLE t3 NULL range PRIMARY,f2_idx,f3_idx f3_idx 135 NULL 10 100.00 NULL Warnings: Warning 3128 Unresolved name `t3`@`select#2` `f1_idx` for NO_ICP hint Note 1003 /* select#1 */ select /*+ NO_ICP(`t3`@`select#2` `f2_idx`) */ `test`.`t3`.`f2` AS `f2` from `test`.`t3` where ((`test`.`t3`.`f3` = 'poiu') and (`test`.`t3`.`f1` > 27) and (`test`.`t3`.`f1` > 27)) @@ -490,7 +490,7 @@ EXPLAIN SELECT /*+ BKA(qb1 t3@qb1) */ f2 FROM (SELECT /*+ QB_NAME(qb1) */ f2, f3, f1 FROM t3 WHERE f1 > 2 AND f3 = 'poiu') AS TD WHERE TD.f1 > 2 AND TD.f3 = 'poiu'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range PRIMARY,f2_idx,f3_idx f3_idx 135 NULL 16 100.00 Using index condition; Using MRR +1 SIMPLE t3 NULL range PRIMARY,f2_idx,f3_idx f3_idx 135 NULL 16 100.00 Using MRR Warnings: Warning 1064 Optimizer hint syntax error near 't3@qb1) */ f2 FROM (SELECT /*+ QB_NAME(qb1) */ f2, f3, f1 FROM t3 WHERE f1 > 2 A' at line 1 @@ -843,73 +843,73 @@ Handler_read_rnd 0 Handler_read_rnd_next 0 EXPLAIN SELECT * FROM t1 WHERE f2 <= 3 AND 3 <= f3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using index condition; Using where; Using MRR +1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using where; Using MRR Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t1`.`f3` AS `f3` from `test`.`t1` where ((`test`.`t1`.`f2` <= 3) and (3 <= `test`.`t1`.`f3`)) # Turn off MRR. MRR should not be used. EXPLAIN SELECT /*+ NO_MRR(t1) */ * FROM t1 WHERE f2 <= 3 AND 3 <= f3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using index condition; Using where +1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using where Warnings: Note 1003 /* select#1 */ select /*+ NO_MRR(`t1`@`select#1`) */ `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t1`.`f3` AS `f3` from `test`.`t1` where ((`test`.`t1`.`f2` <= 3) and (3 <= `test`.`t1`.`f3`)) # Turn off MRR. MRR should not be used. EXPLAIN SELECT /*+ NO_MRR(t1 idx2) */ * FROM t1 WHERE f2 <= 3 AND 3 <= f3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using index condition; Using where +1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using where Warnings: Note 1003 /* select#1 */ select /*+ NO_MRR(`t1`@`select#1` `idx2`) */ `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t1`.`f3` AS `f3` from `test`.`t1` where ((`test`.`t1`.`f2` <= 3) and (3 <= `test`.`t1`.`f3`)) # Turn off MRR for unused key. MRR should be used. EXPLAIN SELECT /*+ NO_MRR(t1 idx1) */ * FROM t1 WHERE f2 <= 3 AND 3 <= f3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using index condition; Using where; Using MRR +1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using where; Using MRR Warnings: Note 1003 /* select#1 */ select /*+ NO_MRR(`t1`@`select#1` `idx1`) */ `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t1`.`f3` AS `f3` from `test`.`t1` where ((`test`.`t1`.`f2` <= 3) and (3 <= `test`.`t1`.`f3`)) set optimizer_switch='mrr=off,mrr_cost_based=off'; EXPLAIN SELECT * FROM t1 WHERE f2 <= 3 AND 3 <= f3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using index condition; Using where +1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t1`.`f3` AS `f3` from `test`.`t1` where ((`test`.`t1`.`f2` <= 3) and (3 <= `test`.`t1`.`f3`)) # Turn on MRR. MRR should be used. EXPLAIN SELECT /*+ MRR(t1) */ * FROM t1 WHERE f2 <= 3 AND 3 <= f3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using index condition; Using where; Using MRR +1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using where; Using MRR Warnings: Note 1003 /* select#1 */ select /*+ MRR(`t1`@`select#1`) */ `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t1`.`f3` AS `f3` from `test`.`t1` where ((`test`.`t1`.`f2` <= 3) and (3 <= `test`.`t1`.`f3`)) # Turn on MRR. MRR should be used. EXPLAIN SELECT /*+ MRR(t1 IDX2) */ * FROM t1 WHERE f2 <= 3 AND 3 <= f3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using index condition; Using where; Using MRR +1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using where; Using MRR Warnings: Note 1003 /* select#1 */ select /*+ MRR(`t1`@`select#1` `IDX2`) */ `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t1`.`f3` AS `f3` from `test`.`t1` where ((`test`.`t1`.`f2` <= 3) and (3 <= `test`.`t1`.`f3`)) # Turn on MRR for unused key. MRR should not be used. EXPLAIN SELECT /*+ MRR(t1 idx1) */ * FROM t1 WHERE f2 <= 3 AND 3 <= f3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using index condition; Using where +1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using where Warnings: Note 1003 /* select#1 */ select /*+ MRR(`t1`@`select#1` `idx1`) */ `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t1`.`f3` AS `f3` from `test`.`t1` where ((`test`.`t1`.`f2` <= 3) and (3 <= `test`.`t1`.`f3`)) set optimizer_switch='mrr=off,mrr_cost_based=on'; EXPLAIN SELECT * FROM t1 WHERE f2 <= 3 AND 3 <= f3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using index condition; Using where +1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t1`.`f3` AS `f3` from `test`.`t1` where ((`test`.`t1`.`f2` <= 3) and (3 <= `test`.`t1`.`f3`)) # Turn on MRR. MRR should be used. EXPLAIN SELECT /*+ MRR(t1) */ * FROM t1 WHERE f2 <= 3 AND 3 <= f3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using index condition; Using where; Using MRR +1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using where; Using MRR Warnings: Note 1003 /* select#1 */ select /*+ MRR(`t1`@`select#1`) */ `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t1`.`f3` AS `f3` from `test`.`t1` where ((`test`.`t1`.`f2` <= 3) and (3 <= `test`.`t1`.`f3`)) # Turn on MRR. MRR should be used. EXPLAIN SELECT /*+ MRR(t1 idx2) */ * FROM t1 WHERE f2 <= 3 AND 3 <= f3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using index condition; Using where; Using MRR +1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using where; Using MRR Warnings: Note 1003 /* select#1 */ select /*+ MRR(`t1`@`select#1` `idx2`) */ `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t1`.`f3` AS `f3` from `test`.`t1` where ((`test`.`t1`.`f2` <= 3) and (3 <= `test`.`t1`.`f3`)) # Turn on MRR for unused key. MRR should not be used. EXPLAIN SELECT /*+ MRR(t1 IDX1) */ * FROM t1 WHERE f2 <= 3 AND 3 <= f3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using index condition; Using where +1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using where Warnings: Note 1003 /* select#1 */ select /*+ MRR(`t1`@`select#1` `IDX1`) */ `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t1`.`f3` AS `f3` from `test`.`t1` where ((`test`.`t1`.`f2` <= 3) and (3 <= `test`.`t1`.`f3`)) DROP TABLE t1; diff --git a/mysql-test/r/opt_hints_index.result b/mysql-test/r/opt_hints_index.result index 857bfcab060..db831b0c9a9 100644 --- a/mysql-test/r/opt_hints_index.result +++ b/mysql-test/r/opt_hints_index.result @@ -166,15 +166,15 @@ View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select /*+ NO_INDEX(`t1`@`select#1` `i_a`, `i_b`) NO_INDEX(`t1`@`select#2` `i_ab`, `i_b`) */ `t1`.`a` AS `a` from `t1` where `t1`.`b` in (select `t1`.`a` from `t1` where (`t1`.`a` > 3)) order by `t1`.`a` utf8mb4 utf8mb4_0900_ai_ci EXPLAIN SELECT a FROM v1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i_a i_a 5 NULL 160 5.00 Using where; Using index; Using temporary; Using filesort; LooseScan +1 SIMPLE t1 NULL range i_a i_a 5 NULL 160 5.00 Using index; Using temporary; Using filesort; LooseScan 1 SIMPLE t1 NULL index NULL i_ab 10 NULL 256 12.50 Using where; Using index; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` /*+ NO_INDEX(`t1`@`select#1` `i_a`, `i_b`) */ semi join (`test`.`t1` /*+ NO_INDEX(`t1`@`select#2` `i_ab`, `i_b`) */ ) where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 3)) order by `test`.`t1`.`a` EXPLAIN SELECT /*+ INDEX(ta i_a) */ ta.a FROM v1, t1 ta WHERE ta.a > 3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i_a i_a 5 NULL 160 5.00 Using where; Using index; LooseScan +1 SIMPLE t1 NULL range i_a i_a 5 NULL 160 5.00 Using index; LooseScan 1 SIMPLE t1 NULL index NULL i_ab 10 NULL 256 12.50 Using where; Using index; Using join buffer (hash join) -1 SIMPLE ta NULL range i_a i_a 5 NULL 160 100.00 Using where; Using index; Using join buffer (hash join) +1 SIMPLE ta NULL range i_a i_a 5 NULL 160 100.00 Using index; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select /*+ INDEX(`ta`@`select#1` `i_a`) */ `test`.`ta`.`a` AS `a` from `test`.`t1` /*+ NO_INDEX(`t1`@`select#1` `i_a`, `i_b`) */ semi join (`test`.`t1` /*+ NO_INDEX(`t1`@`select#2` `i_ab`, `i_b`) */ ) join `test`.`t1` `ta` where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`ta`.`a` > 3) and (`test`.`t1`.`a` > 3)) CREATE VIEW v2 AS SELECT /*+ INDEX(ta i_a) */ ta.a FROM v1, t1 ta WHERE ta.a > 3; @@ -183,17 +183,17 @@ View Create View character_set_client collation_connection v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select /*+ INDEX(`ta`@`select#1` `i_a`) */ `ta`.`a` AS `a` from (`v1` join `t1` `ta`) where (`ta`.`a` > 3) utf8mb4 utf8mb4_0900_ai_ci EXPLAIN SELECT a FROM v2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i_a i_a 5 NULL 160 5.00 Using where; Using index; LooseScan +1 SIMPLE t1 NULL range i_a i_a 5 NULL 160 5.00 Using index; LooseScan 1 SIMPLE t1 NULL index NULL i_ab 10 NULL 256 12.50 Using where; Using index; Using join buffer (hash join) -1 SIMPLE ta NULL range i_a i_a 5 NULL 160 100.00 Using where; Using index; Using join buffer (hash join) +1 SIMPLE ta NULL range i_a i_a 5 NULL 160 100.00 Using index; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`ta`.`a` AS `a` from `test`.`t1` /*+ NO_INDEX(`t1`@`select#1` `i_a`, `i_b`) */ semi join (`test`.`t1` /*+ NO_INDEX(`t1`@`select#2` `i_ab`, `i_b`) */ ) join `test`.`t1` `ta` /*+ INDEX(`ta`@`select#1` `i_a`) */ where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`ta`.`a` > 3) and (`test`.`t1`.`a` > 3)) EXPLAIN SELECT /*+ INDEX(tb i_a) */ tb.a FROM v2, t1 tb WHERE tb.a > 3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i_a i_a 5 NULL 160 5.00 Using where; Using index; LooseScan +1 SIMPLE t1 NULL range i_a i_a 5 NULL 160 5.00 Using index; LooseScan 1 SIMPLE t1 NULL index NULL i_ab 10 NULL 256 12.50 Using where; Using index; Using join buffer (hash join) -1 SIMPLE ta NULL range i_a i_a 5 NULL 160 100.00 Using where; Using index; Using join buffer (hash join) -1 SIMPLE tb NULL range i_a i_a 5 NULL 160 100.00 Using where; Using index; Using join buffer (hash join) +1 SIMPLE ta NULL range i_a i_a 5 NULL 160 100.00 Using index; Using join buffer (hash join) +1 SIMPLE tb NULL range i_a i_a 5 NULL 160 100.00 Using index; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select /*+ INDEX(`tb`@`select#1` `i_a`) */ `test`.`tb`.`a` AS `a` from `test`.`t1` /*+ NO_INDEX(`t1`@`select#1` `i_a`, `i_b`) */ semi join (`test`.`t1` /*+ NO_INDEX(`t1`@`select#2` `i_ab`, `i_b`) */ ) join `test`.`t1` `ta` /*+ INDEX(`ta`@`select#1` `i_a`) */ join `test`.`t1` `tb` where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`tb`.`a` > 3) and (`test`.`ta`.`a` > 3) and (`test`.`t1`.`a` > 3)) EXPLAIN SELECT /*+ INDEX(t1 i_a) */ * FROM t1 IGNORE INDEX(i_a) diff --git a/mysql-test/r/opt_hints_index_merge.result b/mysql-test/r/opt_hints_index_merge.result index f00c9568b0a..7710644305b 100644 --- a/mysql-test/r/opt_hints_index_merge.result +++ b/mysql-test/r/opt_hints_index_merge.result @@ -141,7 +141,7 @@ Warnings: Note 1003 /* select#1 */ select /*+ INDEX_MERGE(`t1`@`select#1` `PRIMARY`, `f4`, `f3`) */ count(0) AS `COUNT(*)` from `test`.`t1` where ((`test`.`t1`.`f5` = 'i') and (`test`.`t1`.`f3` = 'b') and (`test`.`t1`.`f4` = 'h')) EXPLAIN SELECT count(*) FROM t1 WHERE f2 = 3 AND f5 > '' AND f3 = 'c'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,f2,f3 f3 9 NULL 1 16.67 Using index condition; Using where +1 SIMPLE t1 NULL range PRIMARY,f2,f3 f3 9 NULL 1 16.67 Using where Warnings: Note 1003 /* select#1 */ select count(0) AS `count(*)` from `test`.`t1` where ((`test`.`t1`.`f3` = 'c') and (`test`.`t1`.`f2` = 3) and (`test`.`t1`.`f5` > '')) EXPLAIN SELECT /*+ INDEX_MERGE(t1 f3, PRIMARY) */ count(*) FROM t1 WHERE f2 = 3 AND f5 > '' AND f3 = 'c'; @@ -225,7 +225,7 @@ Warnings: Note 1003 /* select#1 */ select count(0) AS `count(*)` from `test`.`t1` where ((`test`.`t1`.`f3` = 'c') and (`test`.`t1`.`f2` = 3) and (`test`.`t1`.`f5` > '')) EXPLAIN SELECT /*+ NO_INDEX_MERGE(t1 PRIMARY) */ count(*) FROM t1 WHERE f2 = 3 AND f5 > '' AND f3 = 'c'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,f2,f3 f3 9 NULL 1 16.67 Using index condition; Using where +1 SIMPLE t1 NULL range PRIMARY,f2,f3 f3 9 NULL 1 16.67 Using where Warnings: Note 1003 /* select#1 */ select /*+ NO_INDEX_MERGE(`t1`@`select#1` `PRIMARY`) */ count(0) AS `count(*)` from `test`.`t1` where ((`test`.`t1`.`f3` = 'c') and (`test`.`t1`.`f2` = 3) and (`test`.`t1`.`f5` > '')) EXPLAIN SELECT /*+ NO_INDEX_MERGE(t1 f2) */ count(*) FROM t1 WHERE f2 = 3 AND f5 > '' AND f3 = 'c'; @@ -235,7 +235,7 @@ Warnings: Note 1003 /* select#1 */ select /*+ NO_INDEX_MERGE(`t1`@`select#1` `f2`) */ count(0) AS `count(*)` from `test`.`t1` where ((`test`.`t1`.`f3` = 'c') and (`test`.`t1`.`f2` = 3) and (`test`.`t1`.`f5` > '')) EXPLAIN SELECT /*+ NO_INDEX_MERGE(t1 f3) */ count(*) FROM t1 WHERE f2 = 3 AND f5 > '' AND f3 = 'c'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,f2,f3 f2 9 NULL 64 25.00 Using index condition; Using where +1 SIMPLE t1 NULL range PRIMARY,f2,f3 f2 9 NULL 64 25.00 Using where Warnings: Note 1003 /* select#1 */ select /*+ NO_INDEX_MERGE(`t1`@`select#1` `f3`) */ count(0) AS `count(*)` from `test`.`t1` where ((`test`.`t1`.`f3` = 'c') and (`test`.`t1`.`f2` = 3) and (`test`.`t1`.`f5` > '')) EXPLAIN SELECT COUNT(*) FROM t1 WHERE f4 = 'x' AND f2 = 5 AND f3 = 'n'; @@ -432,7 +432,7 @@ Warnings: Note 1003 /* select#1 */ select /*+ INDEX_MERGE(`t1`@`select#1`) */ `test`.`t1`.`f3` AS `f3` from `test`.`t1` where ((`test`.`t1`.`f5` = '') and (`test`.`t1`.`f4` = 'g') and (`test`.`t1`.`f2` = 3)) EXPLAIN SELECT f3 FROM t1 WHERE f2 = 3 AND f4 = '' AND f5 > ''; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,f2,f4 f2 9 NULL 64 25.00 Using index condition; Using where +1 SIMPLE t1 NULL range PRIMARY,f2,f4 f2 9 NULL 64 25.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`f3` AS `f3` from `test`.`t1` where ((`test`.`t1`.`f4` = '') and (`test`.`t1`.`f2` = 3) and (`test`.`t1`.`f5` > '')) EXPLAIN SELECT /*+ INDEX_MERGE(t1) */ f3 FROM t1 WHERE f2 = 3 AND f4 = '' AND f5 > ''; diff --git a/mysql-test/r/opt_hints_join_order.result b/mysql-test/r/opt_hints_join_order.result index 4e614d6e82b..80d408c55b5 100644 --- a/mysql-test/r/opt_hints_join_order.result +++ b/mysql-test/r/opt_hints_join_order.result @@ -708,7 +708,7 @@ EXPLAIN SELECT /*+ JOIN_ORDER(t2, t3) JOIN_ORDER(t1, t2) */ t3.f1 FROM ( t2 INNER JOIN t3 ON t3.f2 = t2.f2 LEFT JOIN t1 ON t1.f1 = t3.f1 ) WHERE NOT (t2.f1 >= 7); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range f2,f1 f1 5 NULL 1 100.00 Using index condition +1 SIMPLE t2 NULL range f2,f1 f1 5 NULL 1 100.00 NULL 1 SIMPLE t3 NULL ALL f2 NULL NULL NULL 1 100.00 Using where; Using join buffer (hash join) 1 SIMPLE t1 NULL ref f1 f1 5 test.t3.f1 1 100.00 Using index Warnings: diff --git a/mysql-test/r/opt_hints_set_var.result b/mysql-test/r/opt_hints_set_var.result index 4dcf6f1d8e6..cc835bbc1e8 100644 --- a/mysql-test/r/opt_hints_set_var.result +++ b/mysql-test/r/opt_hints_set_var.result @@ -509,11 +509,11 @@ set optimizer_switch=default; DROP TABLE t1; CALL test_hint("SET_VAR(optimizer_switch='mrr=off')", "optimizer_switch"); VARIABLE_VALUE -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on VARIABLE_VALUE -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=off,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=off,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on VARIABLE_VALUE -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on CALL test_hint("SET_VAR(range_alloc_block_size=8192)", "range_alloc_block_size"); VARIABLE_VALUE 4096 diff --git a/mysql-test/r/optimizer_switch.result b/mysql-test/r/optimizer_switch.result index 48fd6ab3f0c..9ab0f6d3f48 100644 --- a/mysql-test/r/optimizer_switch.result +++ b/mysql-test/r/optimizer_switch.result @@ -3,47 +3,47 @@ BUG#37120 optimizer_switch allowable values not according to specification select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on set optimizer_switch='default'; set optimizer_switch='materialization=off'; select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=off,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=off,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on set optimizer_switch='default'; set optimizer_switch='semijoin=off'; select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=off,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=off,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on set optimizer_switch='default'; set optimizer_switch='loosescan=off'; select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=off,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=off,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on set optimizer_switch='default'; set optimizer_switch='semijoin=off,materialization=off'; select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=off,semijoin=off,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=off,semijoin=off,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on set optimizer_switch='default'; set optimizer_switch='materialization=off,semijoin=off'; select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=off,semijoin=off,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=off,semijoin=off,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on set optimizer_switch='default'; set optimizer_switch='semijoin=off,materialization=off,loosescan=off'; select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on set optimizer_switch='default'; set optimizer_switch='semijoin=off,loosescan=off'; select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=off,loosescan=off,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=off,loosescan=off,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on set optimizer_switch='default'; set optimizer_switch='materialization=off,loosescan=off'; select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=off,semijoin=on,loosescan=off,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=off,semijoin=on,loosescan=off,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on set optimizer_switch='default'; create table t1 (a1 char(8), a2 char(8)); create table t2 (b1 char(8), b2 char(8)); diff --git a/mysql-test/r/order_by_all.result b/mysql-test/r/order_by_all.result index 0c58e86e91e..9b561e5b92d 100644 --- a/mysql-test/r/order_by_all.result +++ b/mysql-test/r/order_by_all.result @@ -404,7 +404,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`a` >= 1) and (`test`.`t1`.`a` < 3) and (`test`.`t1`.`b` > 0)) order by `test`.`t1`.`a` desc,`test`.`t1`.`b` desc explain select * from t1 where a = 2 and b >0 order by a desc,b desc; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 9 NULL 5 100.00 Using where; Backward index scan; Using index +1 SIMPLE t1 NULL range a a 9 NULL 5 100.00 Backward index scan; Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`a` = 2) and (`test`.`t1`.`b` > 0)) order by `test`.`t1`.`a` desc,`test`.`t1`.`b` desc explain select * from t1 where a = 2 and b is null order by a desc,b desc; @@ -420,12 +420,12 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`a` = 2) and ((`test`.`t1`.`b` is null) or (`test`.`t1`.`b` > 0))) order by `test`.`t1`.`a` desc,`test`.`t1`.`b` desc explain select * from t1 where a = 2 and b > 0 order by a desc,b desc; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 9 NULL 5 100.00 Using where; Backward index scan; Using index +1 SIMPLE t1 NULL range a a 9 NULL 5 100.00 Backward index scan; Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`a` = 2) and (`test`.`t1`.`b` > 0)) order by `test`.`t1`.`a` desc,`test`.`t1`.`b` desc explain select * from t1 where a = 2 and b < 2 order by a desc,b desc; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 9 NULL 2 100.00 Using where; Backward index scan; Using index +1 SIMPLE t1 NULL range a a 9 NULL 2 100.00 Backward index scan; Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`a` = 2) and (`test`.`t1`.`b` < 2)) order by `test`.`t1`.`a` desc,`test`.`t1`.`b` desc explain select * from t1 where a = 1 order by b desc; @@ -537,7 +537,7 @@ a b c 1 1 b explain select * from t1 where a between 0 and 1 order by a desc, b desc; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 4 NULL 6 100.00 Using where; Backward index scan; Using index +1 SIMPLE t1 NULL range a a 4 NULL 6 100.00 Backward index scan; Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (`test`.`t1`.`a` between 0 and 1) order by `test`.`t1`.`a` desc,`test`.`t1`.`b` desc select * from t1 where a between 0 and 1 order by a desc, b desc; @@ -753,7 +753,7 @@ FieldKey LongVal StringVal 1 2 1 EXPLAIN SELECT * FROM t1 ignore index (FieldKey, LongField) WHERE FieldKey > '2' ORDER BY LongVal; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range StringField StringField 146 NULL 3 100.00 Using index condition; Using filesort +1 SIMPLE t1 NULL range StringField StringField 146 NULL 3 100.00 Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`FieldKey` AS `FieldKey`,`test`.`t1`.`LongVal` AS `LongVal`,`test`.`t1`.`StringVal` AS `StringVal` from `test`.`t1` IGNORE INDEX (`LongField`) IGNORE INDEX (`FieldKey`) where (`test`.`t1`.`FieldKey` > '2') order by `test`.`t1`.`LongVal` SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal; @@ -763,7 +763,7 @@ FieldKey LongVal StringVal 3 3 3 EXPLAIN SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY FieldKey, LongVal; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range FieldKey,LongField,StringField LongField 146 NULL 3 100.00 Using index condition +1 SIMPLE t1 NULL range FieldKey,LongField,StringField LongField 146 NULL 3 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`FieldKey` AS `FieldKey`,`test`.`t1`.`LongVal` AS `LongVal`,`test`.`t1`.`StringVal` AS `StringVal` from `test`.`t1` where (`test`.`t1`.`FieldKey` > '2') order by `test`.`t1`.`FieldKey`,`test`.`t1`.`LongVal` SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY FieldKey, LongVal; @@ -1296,7 +1296,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`id` AS `id`,`test`.`t2`.`c3` AS `c3` from `test`.`t2` where (`test`.`t2`.`c2` between 10 and 12) order by `test`.`t2`.`c3` limit 20 EXPLAIN SELECT id,c3 FROM t2 WHERE c2 BETWEEN 20 AND 30 ORDER BY c3 LIMIT 4000; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range k2 k2 5 NULL 409 100.00 Using index condition; Using MRR; Using filesort +1 SIMPLE t2 NULL range k2 k2 5 NULL 409 100.00 Using MRR; Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`id` AS `id`,`test`.`t2`.`c3` AS `c3` from `test`.`t2` where (`test`.`t2`.`c2` between 20 and 30) order by `test`.`t2`.`c3` limit 4000 SELECT c3,id FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 20; @@ -3031,7 +3031,7 @@ INSERT INTO t2 SELECT a+4, b FROM t2; EXPLAIN SELECT * FROM t1 FORCE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 10 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` FORCE INDEX FOR ORDER BY (`a`) join `test`.`t2` where (`test`.`t1`.`a` < 2) order by `test`.`t1`.`a` @@ -3039,7 +3039,7 @@ Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`t EXPLAIN SELECT * FROM t1 USE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 Using index condition; Using MRR; Using temporary; Using filesort +1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 Using MRR; Using temporary; Using filesort 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 10 100.00 Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` USE INDEX FOR ORDER BY (`a`) join `test`.`t2` where (`test`.`t1`.`a` < 2) order by `test`.`t1`.`a` @@ -3047,7 +3047,7 @@ Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`t EXPLAIN SELECT * FROM t1 FORCE INDEX FOR JOIN (a), t2 WHERE t1.a < 2 ORDER BY t1.a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 Using index condition; Using MRR; Using temporary; Using filesort +1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 Using MRR; Using temporary; Using filesort 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 10 100.00 Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` FORCE INDEX FOR JOIN (`a`) join `test`.`t2` where (`test`.`t1`.`a` < 2) order by `test`.`t1`.`a` diff --git a/mysql-test/r/order_by_icp_mrr.result b/mysql-test/r/order_by_icp_mrr.result index 4cbb8658be0..926f8829c1a 100644 --- a/mysql-test/r/order_by_icp_mrr.result +++ b/mysql-test/r/order_by_icp_mrr.result @@ -1,4 +1,5 @@ set optimizer_switch='index_condition_pushdown=on,mrr=on,mrr_cost_based=off'; +set empty_redundant_check_in_range_scan=false; drop table if exists t1,t2,t3; SET sql_mode = 'NO_ENGINE_SUBSTITUTION'; CREATE TABLE t1 ( @@ -3378,4 +3379,5 @@ z y x DROP TABLE t1; +set empty_redundant_check_in_range_scan=true; set optimizer_switch=default; diff --git a/mysql-test/r/order_by_limit.result b/mysql-test/r/order_by_limit.result index a51c6ebfb8e..750ab08aa1d 100644 --- a/mysql-test/r/order_by_limit.result +++ b/mysql-test/r/order_by_limit.result @@ -32,7 +32,7 @@ EXPLAIN SELECT * FROM t1 WHERE i<100 AND j<10 ORDER BY i LIMIT 5; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i,j j 5 NULL 9 77.34 Using index condition; Using where; Using filesort +1 SIMPLE t1 NULL range i,j j 5 NULL 9 77.34 Using where; Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i` AS `i`,`test`.`t1`.`j` AS `j` from `test`.`t1` where ((`test`.`t1`.`i` < 100) and (`test`.`t1`.`j` < 10)) order by `test`.`t1`.`i` limit 5 SELECT * FROM t1 @@ -123,7 +123,7 @@ pk i1 i2 pk i1 EXPLAIN SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.i1=t2.i1 WHERE t1.pk > 7000 ORDER BY t1.i1 LIMIT 5; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,k1,k2 PRIMARY 4 NULL 30 100.00 Using where; Using filesort +1 SIMPLE t1 NULL range PRIMARY,k1,k2 PRIMARY 4 NULL 30 100.00 Using filesort 1 SIMPLE t2 NULL ref k1 k1 4 test.t1.i1 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t1`.`i2` AS `i2`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`i1` AS `i1` from `test`.`t1` straight_join `test`.`t2` where ((`test`.`t2`.`i1` = `test`.`t1`.`i1`) and (`test`.`t1`.`pk` > 7000)) order by `test`.`t1`.`i1` limit 5 @@ -172,7 +172,7 @@ i1 i2 EXPLAIN SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.i1=t2.i1 WHERE t1.pk > 7000 and t2.pk = 100 ORDER BY t1.i1 LIMIT 5; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,k1,k2 PRIMARY 4 NULL 30 100.00 Using where; Using filesort +1 SIMPLE t1 NULL range PRIMARY,k1,k2 PRIMARY 4 NULL 30 100.00 Using filesort 1 SIMPLE t2 NULL const PRIMARY,k1 PRIMARY 4 const 1 5.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t1`.`i2` AS `i2`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`i1` AS `i1` from `test`.`t1` straight_join `test`.`t2` where ((`test`.`t2`.`i1` = `test`.`t1`.`i1`) and (`test`.`t2`.`pk` = 100) and (`test`.`t1`.`pk` > 7000)) order by `test`.`t1`.`i1` limit 5 @@ -352,7 +352,7 @@ should_be_1 SET optimizer_switch = "prefer_ordering_index=off"; EXPLAIN SELECT non_covered_column FROM t WHERE other_id > 3 ORDER BY id ASC LIMIT 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t NULL range index_other_id_covered_column index_other_id_covered_column 8 NULL 7 100.00 Using index condition; Using filesort +1 SIMPLE t NULL range index_other_id_covered_column index_other_id_covered_column 8 NULL 7 100.00 Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`t`.`non_covered_column` AS `non_covered_column` from `test`.`t` where (`test`.`t`.`other_id` > 3) order by `test`.`t`.`id` limit 2 SELECT (trace LIKE '%"plan_changed": true%') AS should_be_0 FROM information_schema.optimizer_trace; @@ -420,7 +420,7 @@ should_be_1 SET optimizer_switch = "prefer_ordering_index=off"; EXPLAIN SELECT non_covered_column FROM t WHERE id > 8 GROUP BY other_id LIMIT 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t NULL range PRIMARY,index_other_id_covered_column PRIMARY 8 NULL 12 100.00 Using where; Using temporary +1 SIMPLE t NULL range PRIMARY,index_other_id_covered_column PRIMARY 8 NULL 12 100.00 Using temporary Warnings: Note 1003 /* select#1 */ select `test`.`t`.`non_covered_column` AS `non_covered_column` from `test`.`t` where (`test`.`t`.`id` > 8) group by `test`.`t`.`other_id` limit 1 SELECT (trace LIKE '%"plan_changed": true%') AS should_be_0 FROM information_schema.optimizer_trace; @@ -429,7 +429,7 @@ should_be_0 SET optimizer_switch = default; EXPLAIN SELECT non_covered_column FROM t WHERE id > 8 GROUP BY id LIMIT 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t NULL range PRIMARY,index_other_id_covered_column PRIMARY 8 NULL 12 100.00 Using where +1 SIMPLE t NULL range PRIMARY,index_other_id_covered_column PRIMARY 8 NULL 12 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t`.`non_covered_column` AS `non_covered_column` from `test`.`t` where (`test`.`t`.`id` > 8) group by `test`.`t`.`id` limit 1 SELECT (trace LIKE '%"plan_changed": true%') AS should_be_1 FROM information_schema.optimizer_trace; diff --git a/mysql-test/r/order_by_none.result b/mysql-test/r/order_by_none.result index 9bcd0a0bf5a..bf708e9a2c2 100644 --- a/mysql-test/r/order_by_none.result +++ b/mysql-test/r/order_by_none.result @@ -403,7 +403,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`a` >= 1) and (`test`.`t1`.`a` < 3) and (`test`.`t1`.`b` > 0)) order by `test`.`t1`.`a` desc,`test`.`t1`.`b` desc explain select * from t1 where a = 2 and b >0 order by a desc,b desc; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 9 NULL 5 100.00 Using where; Backward index scan; Using index +1 SIMPLE t1 NULL range a a 9 NULL 5 100.00 Backward index scan; Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`a` = 2) and (`test`.`t1`.`b` > 0)) order by `test`.`t1`.`a` desc,`test`.`t1`.`b` desc explain select * from t1 where a = 2 and b is null order by a desc,b desc; @@ -419,12 +419,12 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`a` = 2) and ((`test`.`t1`.`b` is null) or (`test`.`t1`.`b` > 0))) order by `test`.`t1`.`a` desc,`test`.`t1`.`b` desc explain select * from t1 where a = 2 and b > 0 order by a desc,b desc; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 9 NULL 5 100.00 Using where; Backward index scan; Using index +1 SIMPLE t1 NULL range a a 9 NULL 5 100.00 Backward index scan; Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`a` = 2) and (`test`.`t1`.`b` > 0)) order by `test`.`t1`.`a` desc,`test`.`t1`.`b` desc explain select * from t1 where a = 2 and b < 2 order by a desc,b desc; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 9 NULL 2 100.00 Using where; Backward index scan; Using index +1 SIMPLE t1 NULL range a a 9 NULL 2 100.00 Backward index scan; Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`a` = 2) and (`test`.`t1`.`b` < 2)) order by `test`.`t1`.`a` desc,`test`.`t1`.`b` desc explain select * from t1 where a = 1 order by b desc; @@ -536,7 +536,7 @@ a b c 1 1 b explain select * from t1 where a between 0 and 1 order by a desc, b desc; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 4 NULL 6 100.00 Using where; Backward index scan; Using index +1 SIMPLE t1 NULL range a a 4 NULL 6 100.00 Backward index scan; Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (`test`.`t1`.`a` between 0 and 1) order by `test`.`t1`.`a` desc,`test`.`t1`.`b` desc select * from t1 where a between 0 and 1 order by a desc, b desc; @@ -752,7 +752,7 @@ FieldKey LongVal StringVal 1 2 1 EXPLAIN SELECT * FROM t1 ignore index (FieldKey, LongField) WHERE FieldKey > '2' ORDER BY LongVal; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range StringField StringField 146 NULL 3 100.00 Using where; Using filesort +1 SIMPLE t1 NULL range StringField StringField 146 NULL 3 100.00 Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`FieldKey` AS `FieldKey`,`test`.`t1`.`LongVal` AS `LongVal`,`test`.`t1`.`StringVal` AS `StringVal` from `test`.`t1` IGNORE INDEX (`LongField`) IGNORE INDEX (`FieldKey`) where (`test`.`t1`.`FieldKey` > '2') order by `test`.`t1`.`LongVal` SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal; @@ -762,7 +762,7 @@ FieldKey LongVal StringVal 3 3 3 EXPLAIN SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY FieldKey, LongVal; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range FieldKey,LongField,StringField LongField 146 NULL 3 100.00 Using where +1 SIMPLE t1 NULL range FieldKey,LongField,StringField LongField 146 NULL 3 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`FieldKey` AS `FieldKey`,`test`.`t1`.`LongVal` AS `LongVal`,`test`.`t1`.`StringVal` AS `StringVal` from `test`.`t1` where (`test`.`t1`.`FieldKey` > '2') order by `test`.`t1`.`FieldKey`,`test`.`t1`.`LongVal` SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY FieldKey, LongVal; @@ -1296,7 +1296,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`id` AS `id`,`test`.`t2`.`c3` AS `c3` from `test`.`t2` where (`test`.`t2`.`c2` between 10 and 12) order by `test`.`t2`.`c3` limit 20 EXPLAIN SELECT id,c3 FROM t2 WHERE c2 BETWEEN 20 AND 30 ORDER BY c3 LIMIT 4000; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range k2 k2 5 NULL 409 100.00 Using where; Using filesort +1 SIMPLE t2 NULL range k2 k2 5 NULL 409 100.00 Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`id` AS `id`,`test`.`t2`.`c3` AS `c3` from `test`.`t2` where (`test`.`t2`.`c2` between 20 and 30) order by `test`.`t2`.`c3` limit 4000 SELECT c3,id FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 20; @@ -3031,7 +3031,7 @@ INSERT INTO t2 SELECT a+4, b FROM t2; EXPLAIN SELECT * FROM t1 FORCE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 Using where +1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 10 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` FORCE INDEX FOR ORDER BY (`a`) join `test`.`t2` where (`test`.`t1`.`a` < 2) order by `test`.`t1`.`a` @@ -3039,7 +3039,7 @@ Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`t EXPLAIN SELECT * FROM t1 USE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 Using where; Using temporary; Using filesort +1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 Using temporary; Using filesort 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 10 100.00 Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` USE INDEX FOR ORDER BY (`a`) join `test`.`t2` where (`test`.`t1`.`a` < 2) order by `test`.`t1`.`a` @@ -3047,7 +3047,7 @@ Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`t EXPLAIN SELECT * FROM t1 FORCE INDEX FOR JOIN (a), t2 WHERE t1.a < 2 ORDER BY t1.a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 Using where; Using temporary; Using filesort +1 SIMPLE t1 NULL range a a 5 NULL 2 100.00 Using temporary; Using filesort 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 10 100.00 Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` FORCE INDEX FOR JOIN (`a`) join `test`.`t2` where (`test`.`t1`.`a` < 2) order by `test`.`t1`.`a` diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index 328afc89920..cbc78ba6b96 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -250,7 +250,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK EXPLAIN SELECT * FROM t1 where a between '2007-01-01' and '2007-08-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p1 range PRIMARY PRIMARY 4 NULL 1 100.00 Using where +1 SIMPLE t1 p1 range PRIMARY PRIMARY 4 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` between '2007-01-01' and '2007-08-01') EXPLAIN SELECT * FROM t1 where a = '2007-07-30 17:35:48'; @@ -274,7 +274,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK EXPLAIN SELECT * FROM t1 where a between '2007-01-01' and '2007-08-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p1 range PRIMARY PRIMARY 4 NULL 1 100.00 Using where +1 SIMPLE t1 p1 range PRIMARY PRIMARY 4 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` between '2007-01-01' and '2007-08-01') EXPLAIN SELECT * FROM t1 where a = '2007-07-30 17:35:48'; @@ -482,6 +482,95 @@ SELECT a FROM t1 WHERE a BETWEEN 200 AND 220; a 200 210 +explain SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a DESC LIMIT 1000 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 p1,pmax range a a 4 NULL 6 100.00 Backward index scan; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between 60 and 220) order by `test`.`t1`.`a` desc limit 1,1000 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a DESC LIMIT 1000 OFFSET 1; +a +200 +199 +90 +70 +60 +explain SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a ASC LIMIT 1000 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 p1,pmax range a a 4 NULL 6 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between 60 and 220) order by `test`.`t1`.`a` limit 1,1000 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a ASC LIMIT 1000 OFFSET 1; +a +70 +90 +199 +200 +210 +explain SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a DESC LIMIT 1000 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 p1 range a a 4 NULL 3 100.00 Using offset pushdown; Backward index scan; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between 60 and 95) order by `test`.`t1`.`a` desc limit 1,1000 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a DESC LIMIT 1000 OFFSET 1; +a +70 +60 +explain SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a ASC LIMIT 1000 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 p1 range a a 4 NULL 3 100.00 Using offset pushdown; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between 60 and 95) order by `test`.`t1`.`a` limit 1,1000 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a ASC LIMIT 1000 OFFSET 1; +a +70 +90 +ALTER TABLE t1 DROP INDEX a; +ALTER TABLE t1 ADD INDEX (a DESC); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +explain SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a DESC LIMIT 1000 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 p1,pmax range a a 4 NULL 6 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between 60 and 220) order by `test`.`t1`.`a` desc limit 1,1000 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a DESC LIMIT 1000 OFFSET 1; +a +200 +199 +90 +70 +60 +explain SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a ASC LIMIT 1000 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 p1,pmax range a a 4 NULL 6 100.00 Backward index scan; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between 60 and 220) order by `test`.`t1`.`a` limit 1,1000 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a ASC LIMIT 1000 OFFSET 1; +a +70 +90 +199 +200 +210 +explain SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a DESC LIMIT 1000 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 p1 range a a 4 NULL 3 100.00 Using offset pushdown; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between 60 and 95) order by `test`.`t1`.`a` desc limit 1,1000 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a DESC LIMIT 1000 OFFSET 1; +a +70 +60 +explain SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a ASC LIMIT 1000 OFFSET 1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 p1 range a a 4 NULL 3 100.00 Using offset pushdown; Backward index scan; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between 60 and 95) order by `test`.`t1`.`a` limit 1,1000 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a ASC LIMIT 1000 OFFSET 1; +a +70 +90 DROP TABLE t1; CREATE TABLE t1 ( a INT NOT NULL, @@ -640,7 +729,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK EXPLAIN SELECT c1 FROM t1 WHERE (c1 > 2 AND c1 < 5); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range c1 c1 5 NULL 2 100.00 Using where; Using index +1 SIMPLE t1 NULL range c1 c1 5 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1` from `test`.`t1` where ((`test`.`t1`.`c1` > 2) and (`test`.`t1`.`c1` < 5)) FLUSH STATUS; @@ -659,7 +748,7 @@ Handler_read_rnd 0 Handler_read_rnd_next 0 EXPLAIN SELECT c1 FROM t2 WHERE (c1 > 2 AND c1 < 5); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 a range c1 c1 5 NULL 2 100.00 Using where; Using index +1 SIMPLE t2 a range c1 c1 5 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`c1` AS `c1` from `test`.`t2` where ((`test`.`t2`.`c1` > 2) and (`test`.`t2`.`c1` < 5)) FLUSH STATUS; @@ -678,7 +767,7 @@ Handler_read_rnd 0 Handler_read_rnd_next 0 EXPLAIN SELECT c1 FROM t1 WHERE (c1 > 12 AND c1 < 15); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range c1 c1 5 NULL 2 100.00 Using where; Using index +1 SIMPLE t1 NULL range c1 c1 5 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1` from `test`.`t1` where ((`test`.`t1`.`c1` > 12) and (`test`.`t1`.`c1` < 15)) FLUSH STATUS; @@ -697,7 +786,7 @@ Handler_read_rnd 0 Handler_read_rnd_next 0 EXPLAIN SELECT c1 FROM t2 WHERE (c1 > 12 AND c1 < 15); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 a range c1 c1 5 NULL 2 100.00 Using where; Using index +1 SIMPLE t2 a range c1 c1 5 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`c1` AS `c1` from `test`.`t2` where ((`test`.`t2`.`c1` > 12) and (`test`.`t2`.`c1` < 15)) FLUSH STATUS; @@ -2633,12 +2722,12 @@ Warning 1681 Integer display width is deprecated and will be removed in a future INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17),(18),(19),(20); EXPLAIN SELECT c1 FROM t1 WHERE (c1 > 2 AND c1 < 15); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 a,b range c1 c1 5 NULL 12 100.00 Using where; Using index +1 SIMPLE t1 a,b range c1 c1 5 NULL 12 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1` from `test`.`t1` where ((`test`.`t1`.`c1` > 2) and (`test`.`t1`.`c1` < 15)) EXPLAIN SELECT c1 FROM t1 WHERE (c1 > 2 AND c1 < 15); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 a,b range c1 c1 5 NULL 12 100.00 Using where; Using index +1 SIMPLE t1 a,b range c1 c1 5 NULL 12 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1` from `test`.`t1` where ((`test`.`t1`.`c1` > 2) and (`test`.`t1`.`c1` < 15)) EXPLAIN FORMAT=JSON SELECT c1 FROM t1 WHERE (c1 > 2 AND c1 < 15); @@ -2676,8 +2765,7 @@ EXPLAIN }, "used_columns": [ "c1" - ], - "attached_condition": "((`test`.`t1`.`c1` > 2) and (`test`.`t1`.`c1` < 15))" + ] } } } diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result index 22c129cd88e..4bdaac8c2de 100644 --- a/mysql-test/r/partition_pruning.result +++ b/mysql-test/r/partition_pruning.result @@ -128,7 +128,7 @@ a 6 EXPLAIN SELECT * FROM t1 WHERE a < 7; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL # 100.00 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL # 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < 7) SELECT * FROM t1 WHERE a <= 1; @@ -203,7 +203,7 @@ a 6 EXPLAIN SELECT * FROM t1 WHERE a <= 6; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL # 100.00 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL # 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` <= 6) SELECT * FROM t1 WHERE a <= 7; @@ -219,7 +219,7 @@ a 7 EXPLAIN SELECT * FROM t1 WHERE a <= 7; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL # 100.00 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL # 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` <= 7) SELECT * FROM t1 WHERE a = 1; @@ -436,7 +436,7 @@ a 8 EXPLAIN SELECT * FROM t1 WHERE a > 7; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 max range PRIMARY PRIMARY 4 NULL # 100.00 Using where; Using index +1 SIMPLE t1 max range PRIMARY PRIMARY 4 NULL # 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > 7) DROP TABLE t1; @@ -518,7 +518,7 @@ a 5 EXPLAIN SELECT * FROM t1 WHERE a < 6; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL # 100.00 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL # 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < 6) SELECT * FROM t1 WHERE a <= 1; @@ -578,7 +578,7 @@ a 5 EXPLAIN SELECT * FROM t1 WHERE a <= 5; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL # 100.00 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL # 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` <= 5) SELECT * FROM t1 WHERE a <= 6; @@ -593,7 +593,7 @@ a 6 EXPLAIN SELECT * FROM t1 WHERE a <= 6; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL # 100.00 Using where; Using index +1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL # 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` <= 6) SELECT * FROM t1 WHERE a = 1; @@ -773,7 +773,7 @@ a 7 EXPLAIN SELECT * FROM t1 WHERE a > 6; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 max range PRIMARY PRIMARY 4 NULL # 100.00 Using where; Using index +1 SIMPLE t1 max range PRIMARY PRIMARY 4 NULL # 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > 6) DROP TABLE t1; @@ -893,22 +893,22 @@ a 1001-01-01 EXPLAIN SELECT * FROM t1 WHERE a < '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 4 100.00 Using where; Using index +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 4 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < DATE'1001-01-01') EXPLAIN SELECT * FROM t1 WHERE a <= '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 5 100.00 Using where; Using index +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 5 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` <= DATE'1001-01-01') EXPLAIN SELECT * FROM t1 WHERE a >= '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` >= DATE'1001-01-01') EXPLAIN SELECT * FROM t1 WHERE a > '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 pNULL,p2001-01-01 range a a 4 NULL 2 100.00 Using where; Using index +1 SIMPLE t1 pNULL,p2001-01-01 range a a 4 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > DATE'1001-01-01') EXPLAIN SELECT * FROM t1 WHERE a = '1001-01-01'; @@ -918,22 +918,22 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = DATE'1001-01-01') EXPLAIN SELECT * FROM t1 WHERE a < '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < DATE'1001-00-00') EXPLAIN SELECT * FROM t1 WHERE a <= '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 4 100.00 Using where; Using index +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 4 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` <= DATE'1001-00-00') EXPLAIN SELECT * FROM t1 WHERE a >= '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 4 100.00 Using where; Using index +1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 4 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` >= DATE'1001-00-00') EXPLAIN SELECT * FROM t1 WHERE a > '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > DATE'1001-00-00') EXPLAIN SELECT * FROM t1 WHERE a = '1001-00-00'; @@ -943,22 +943,22 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = DATE'1001-00-00') EXPLAIN SELECT * FROM t1 WHERE a < '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 range a a 4 NULL 6 100.00 Using where; Using index +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 range a a 4 NULL 6 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < DATE'1999-02-31') EXPLAIN SELECT * FROM t1 WHERE a <= '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 range a a 4 NULL 6 100.00 Using where; Using index +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 range a a 4 NULL 6 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` <= DATE'1999-02-31') EXPLAIN SELECT * FROM t1 WHERE a >= '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 pNULL,p2001-01-01 range a a 4 NULL 1 100.00 Using where; Using index +1 SIMPLE t1 pNULL,p2001-01-01 range a a 4 NULL 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` >= DATE'1999-02-31') EXPLAIN SELECT * FROM t1 WHERE a > '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 pNULL,p2001-01-01 range a a 4 NULL 1 100.00 Using where; Using index +1 SIMPLE t1 pNULL,p2001-01-01 range a a 4 NULL 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > DATE'1999-02-31') EXPLAIN SELECT * FROM t1 WHERE a = '1999-02-31'; @@ -968,22 +968,22 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = DATE'1999-02-31') EXPLAIN SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 range a a 4 NULL 6 100.00 Using where; Using index +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01,p2001-01-01 range a a 4 NULL 6 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between '0000-00-00' and '1002-00-00') EXPLAIN SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 5 100.00 Using where; Using index +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 5 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between '0000-00-00' and '1001-01-01') EXPLAIN SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 pNULL,p1001-01-01,p2001-01-01 range a a 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between '0001-01-02' and '1002-00-00') EXPLAIN SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 pNULL,p0001-01-01,p1001-01-01 range a a 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between '0001-01-01' and '1001-01-01') SET sql_mode = @previous_sql_mode; @@ -1306,22 +1306,22 @@ a 1001-01-01 EXPLAIN SELECT * FROM t1 WHERE a < '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 4 100.00 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 4 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < DATE'1001-01-01') EXPLAIN SELECT * FROM t1 WHERE a <= '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 100.00 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` <= DATE'1001-01-01') EXPLAIN SELECT * FROM t1 WHERE a >= '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` >= DATE'1001-01-01') EXPLAIN SELECT * FROM t1 WHERE a > '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p2001-01-01,pNULL range a a 4 NULL 2 100.00 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL range a a 4 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > DATE'1001-01-01') EXPLAIN SELECT * FROM t1 WHERE a = '1001-01-01'; @@ -1331,22 +1331,22 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = DATE'1001-01-01') EXPLAIN SELECT * FROM t1 WHERE a < '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < DATE'1001-00-00') EXPLAIN SELECT * FROM t1 WHERE a <= '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 4 100.00 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 4 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` <= DATE'1001-00-00') EXPLAIN SELECT * FROM t1 WHERE a >= '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 4 100.00 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 4 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` >= DATE'1001-00-00') EXPLAIN SELECT * FROM t1 WHERE a > '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > DATE'1001-00-00') EXPLAIN SELECT * FROM t1 WHERE a = '1001-00-00'; @@ -1366,12 +1366,12 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` <= DATE'1999-02-31') EXPLAIN SELECT * FROM t1 WHERE a >= '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p2001-01-01,pNULL range a a 4 NULL 1 100.00 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL range a a 4 NULL 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` >= DATE'1999-02-31') EXPLAIN SELECT * FROM t1 WHERE a > '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p2001-01-01,pNULL range a a 4 NULL 1 100.00 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL range a a 4 NULL 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > DATE'1999-02-31') EXPLAIN SELECT * FROM t1 WHERE a = '1999-02-31'; @@ -1386,17 +1386,17 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between '0000-00-00' and '1002-00-00') EXPLAIN SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 100.00 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between '0000-00-00' and '1001-01-01') EXPLAIN SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 pNULL,p1001-01-01 range a a 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 pNULL,p1001-01-01 range a a 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between '0001-01-02' and '1002-00-00') EXPLAIN SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0001-01-01,pNULL,p1001-01-01 range a a 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p1001-01-01 range a a 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between '0001-01-01' and '1001-01-01') SET sql_mode = @previous_sql_mode; @@ -1719,22 +1719,22 @@ a 1001-01-01 EXPLAIN SELECT * FROM t1 WHERE a < '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 4 100.00 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 4 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < DATE'1001-01-01') EXPLAIN SELECT * FROM t1 WHERE a <= '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 100.00 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` <= DATE'1001-01-01') EXPLAIN SELECT * FROM t1 WHERE a >= '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` >= DATE'1001-01-01') EXPLAIN SELECT * FROM t1 WHERE a > '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p2001-01-01,pNULL range a a 4 NULL 2 100.00 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL range a a 4 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > DATE'1001-01-01') EXPLAIN SELECT * FROM t1 WHERE a = '1001-01-01'; @@ -1744,22 +1744,22 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = DATE'1001-01-01') EXPLAIN SELECT * FROM t1 WHERE a < '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` < DATE'1001-00-00') EXPLAIN SELECT * FROM t1 WHERE a <= '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 4 100.00 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 4 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` <= DATE'1001-00-00') EXPLAIN SELECT * FROM t1 WHERE a >= '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 4 100.00 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 4 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` >= DATE'1001-00-00') EXPLAIN SELECT * FROM t1 WHERE a > '1001-00-00'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > DATE'1001-00-00') EXPLAIN SELECT * FROM t1 WHERE a = '1001-00-00'; @@ -1779,12 +1779,12 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` <= DATE'1999-02-31') EXPLAIN SELECT * FROM t1 WHERE a >= '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p2001-01-01,pNULL range a a 4 NULL 1 100.00 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL range a a 4 NULL 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` >= DATE'1999-02-31') EXPLAIN SELECT * FROM t1 WHERE a > '1999-02-31'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p2001-01-01,pNULL range a a 4 NULL 1 100.00 Using where; Using index +1 SIMPLE t1 p2001-01-01,pNULL range a a 4 NULL 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > DATE'1999-02-31') EXPLAIN SELECT * FROM t1 WHERE a = '1999-02-31'; @@ -1799,17 +1799,17 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between '0000-00-00' and '1002-00-00') EXPLAIN SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 100.00 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between '0000-00-00' and '1001-01-01') EXPLAIN SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 pNULL,p1001-01-01 range a a 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 pNULL,p1001-01-01 range a a 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between '0001-01-02' and '1002-00-00') EXPLAIN SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0001-01-01,pNULL,p1001-01-01 range a a 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 p0001-01-01,pNULL,p1001-01-01 range a a 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between '0001-01-01' and '1001-01-01') SET sql_mode = @previous_sql_mode; @@ -4317,12 +4317,12 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where ((`test`.`t2`.`b` > 5) and (`test`.`t2`.`b` < 9)) explain select * from t2 where b > 5 and b < 7; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 p0,p1,p2,p3,p4 range b b 5 NULL # 100.00 Using index condition +1 SIMPLE t2 p0,p1,p2,p3,p4 range b b 5 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where ((`test`.`t2`.`b` > 5) and (`test`.`t2`.`b` < 7)) explain select * from t2 where b > 5 and b < 7; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 p0,p1,p2,p3,p4 range b b 5 NULL # 100.00 Using index condition +1 SIMPLE t2 p0,p1,p2,p3,p4 range b b 5 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where ((`test`.`t2`.`b` > 5) and (`test`.`t2`.`b` < 7)) explain select * from t2 where b > 0 and b < 5; @@ -4934,7 +4934,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1`,`test`.`t1`.`c2` AS `c2`,`test`.`t1`.`c3` AS `c3`,`test`.`t1`.`c4` AS `c4` from `test`.`t1` where ((`test`.`t1`.`c2` < 1) and multiple equal(1, `test`.`t1`.`c1`)) EXPLAIN SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p1 range PRIMARY PRIMARY 8 NULL # 100.00 Using where +1 SIMPLE t1 p1 range PRIMARY PRIMARY 8 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1`,`test`.`t1`.`c2` AS `c2`,`test`.`t1`.`c3` AS `c3`,`test`.`t1`.`c4` AS `c4` from `test`.`t1` where ((`test`.`t1`.`c1` = 1) and (`test`.`t1`.`c2` <= 1)) EXPLAIN SELECT * FROM t1 WHERE c1 = 1 AND c2 = 1; @@ -4944,27 +4944,27 @@ Warnings: Note 1003 /* select#1 */ select '1' AS `c1`,'1' AS `c2`,'1' AS `c3`,'1' AS `c4` from `test`.`t1` where true EXPLAIN SELECT * FROM t1 WHERE c1 = 1 AND c2 >= 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL # 100.00 Using where +1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1`,`test`.`t1`.`c2` AS `c2`,`test`.`t1`.`c3` AS `c3`,`test`.`t1`.`c4` AS `c4` from `test`.`t1` where ((`test`.`t1`.`c1` = 1) and (`test`.`t1`.`c2` >= 1)) EXPLAIN SELECT * FROM t1 WHERE c1 = 1 AND c2 > 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL # 100.00 Using where +1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1`,`test`.`t1`.`c2` AS `c2`,`test`.`t1`.`c3` AS `c3`,`test`.`t1`.`c4` AS `c4` from `test`.`t1` where ((`test`.`t1`.`c1` = 1) and (`test`.`t1`.`c2` > 1)) EXPLAIN SELECT * FROM t1 WHERE c1 = 1 AND c2 < 3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p1 range PRIMARY PRIMARY 8 NULL # 100.00 Using where +1 SIMPLE t1 p1 range PRIMARY PRIMARY 8 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1`,`test`.`t1`.`c2` AS `c2`,`test`.`t1`.`c3` AS `c3`,`test`.`t1`.`c4` AS `c4` from `test`.`t1` where ((`test`.`t1`.`c1` = 1) and (`test`.`t1`.`c2` < 3)) EXPLAIN SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL # 100.00 Using where +1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1`,`test`.`t1`.`c2` AS `c2`,`test`.`t1`.`c3` AS `c3`,`test`.`t1`.`c4` AS `c4` from `test`.`t1` where ((`test`.`t1`.`c1` = 1) and (`test`.`t1`.`c2` <= 3)) EXPLAIN SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL # 100.00 Using where +1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1`,`test`.`t1`.`c2` AS `c2`,`test`.`t1`.`c3` AS `c3`,`test`.`t1`.`c4` AS `c4` from `test`.`t1` where ((`test`.`t1`.`c1` = 2) and (`test`.`t1`.`c2` <= 3)) EXPLAIN SELECT * FROM t1 WHERE c1 = 2 AND c2 = 3; @@ -4974,22 +4974,22 @@ Warnings: Note 1003 /* select#1 */ select '2' AS `c1`,'3' AS `c2`,'1' AS `c3`,'1' AS `c4` from `test`.`t1` where true EXPLAIN SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p2 range PRIMARY PRIMARY 8 NULL # 100.00 Using where +1 SIMPLE t1 p2 range PRIMARY PRIMARY 8 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1`,`test`.`t1`.`c2` AS `c2`,`test`.`t1`.`c3` AS `c3`,`test`.`t1`.`c4` AS `c4` from `test`.`t1` where ((`test`.`t1`.`c1` = 2) and (`test`.`t1`.`c2` >= 3)) EXPLAIN SELECT * FROM t1 WHERE c1 = 2 AND c2 > 3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p2 range PRIMARY PRIMARY 8 NULL # 100.00 Using where +1 SIMPLE t1 p2 range PRIMARY PRIMARY 8 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1`,`test`.`t1`.`c2` AS `c2`,`test`.`t1`.`c3` AS `c3`,`test`.`t1`.`c4` AS `c4` from `test`.`t1` where ((`test`.`t1`.`c1` = 2) and (`test`.`t1`.`c2` > 3)) EXPLAIN SELECT * FROM t1 WHERE c1 = 2 AND c2 < 4; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL # 100.00 Using where +1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1`,`test`.`t1`.`c2` AS `c2`,`test`.`t1`.`c3` AS `c3`,`test`.`t1`.`c4` AS `c4` from `test`.`t1` where ((`test`.`t1`.`c1` = 2) and (`test`.`t1`.`c2` < 4)) EXPLAIN SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 4; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL # 100.00 Using where +1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1`,`test`.`t1`.`c2` AS `c2`,`test`.`t1`.`c3` AS `c3`,`test`.`t1`.`c4` AS `c4` from `test`.`t1` where ((`test`.`t1`.`c1` = 2) and (`test`.`t1`.`c2` <= 4)) EXPLAIN SELECT * FROM t1 WHERE c1 = 2 AND c2 = 4; @@ -4999,7 +4999,7 @@ Warnings: Note 1003 /* select#1 */ select '2' AS `c1`,'4' AS `c2`,'1' AS `c3`,'1' AS `c4` from `test`.`t1` where true EXPLAIN SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 4; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p2 range PRIMARY PRIMARY 8 NULL # 100.00 Using where +1 SIMPLE t1 p2 range PRIMARY PRIMARY 8 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`c1` AS `c1`,`test`.`t1`.`c2` AS `c2`,`test`.`t1`.`c3` AS `c3`,`test`.`t1`.`c4` AS `c4` from `test`.`t1` where ((`test`.`t1`.`c1` = 2) and (`test`.`t1`.`c2` >= 4)) EXPLAIN SELECT * FROM t1 WHERE c1 = 2 AND c2 > 4; @@ -5085,7 +5085,7 @@ test.t4 analyze status OK test.t5 analyze status OK EXPLAIN SELECT * FROM t1 JOIN t2 on t1.pk = t2.pk AND t1.pk > 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 8 100.00 Using where +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 8 100.00 NULL 1 SIMPLE t1 p3,p4 eq_ref PRIMARY PRIMARY 4 test.t2.pk 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c` AS `c`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where ((`test`.`t1`.`pk` = `test`.`t2`.`pk`) and (`test`.`t2`.`pk` > 2)) @@ -5147,7 +5147,7 @@ pk c pk c 10 30 10 10 EXPLAIN SELECT * FROM t2 JOIN t1 on t1.pk = t2.pk AND t1.pk > 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 8 100.00 Using where +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 8 100.00 NULL 1 SIMPLE t1 p3,p4 eq_ref PRIMARY PRIMARY 4 test.t2.pk 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c` AS `c`,`test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c` AS `c` from `test`.`t2` join `test`.`t1` where ((`test`.`t1`.`pk` = `test`.`t2`.`pk`) and (`test`.`t2`.`pk` > 2)) @@ -5163,7 +5163,7 @@ pk c pk c 10 30 10 10 EXPLAIN SELECT * FROM t1 JOIN (t2 LEFT JOIN t3 on t2.pk = t3.pk) on t1.pk = t2.pk AND t1.pk > 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 8 100.00 Using where +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 8 100.00 NULL 1 SIMPLE t1 p3,p4 eq_ref PRIMARY PRIMARY 4 test.t2.pk 1 100.00 NULL 1 SIMPLE t3 p0,p1,p2,p3,p4 eq_ref PRIMARY PRIMARY 4 test.t2.pk 1 100.00 NULL Warnings: @@ -5228,7 +5228,7 @@ pk c pk c pk c 10 30 10 40 10 10 EXPLAIN SELECT * FROM (t2 LEFT JOIN t3 on t2.pk = t3.pk) JOIN t1 on t1.pk = t2.pk AND t1.pk > 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 8 100.00 Using where +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 8 100.00 NULL 1 SIMPLE t1 p3,p4 eq_ref PRIMARY PRIMARY 4 test.t2.pk 1 100.00 NULL 1 SIMPLE t3 p0,p1,p2,p3,p4 eq_ref PRIMARY PRIMARY 4 test.t2.pk 1 100.00 NULL Warnings: @@ -5245,7 +5245,7 @@ pk c pk c pk c 10 30 10 40 10 10 EXPLAIN SELECT * FROM t1 JOIN ((t2 LEFT JOIN t3 on t2.pk = t3.pk) LEFT JOIN t4 on t2.c = t4.c + 15) on t1.pk = t2.pk AND t1.pk > 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 8 100.00 Using where +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 8 100.00 NULL 1 SIMPLE t1 p3,p4 eq_ref PRIMARY PRIMARY 4 test.t2.pk 1 100.00 NULL 1 SIMPLE t3 p0,p1,p2,p3,p4 eq_ref PRIMARY PRIMARY 4 test.t2.pk 1 100.00 NULL 1 SIMPLE t4 NULL ALL NULL NULL NULL NULL 10 100.00 Using where; Using join buffer (hash join) @@ -5313,7 +5313,7 @@ pk c pk c pk c pk c 10 30 10 40 NULL NULL 10 10 EXPLAIN SELECT * FROM ((t2 LEFT JOIN t3 on t2.pk = t3.pk) LEFT JOIN t4 on t2.c = t4.c + 15) JOIN t1 on t1.pk = t2.pk AND t1.pk > 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 8 100.00 Using where +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 8 100.00 NULL 1 SIMPLE t3 p0,p1,p2,p3,p4 eq_ref PRIMARY PRIMARY 4 test.t2.pk 1 100.00 NULL 1 SIMPLE t1 p3,p4 eq_ref PRIMARY PRIMARY 4 test.t2.pk 1 100.00 NULL 1 SIMPLE t4 NULL ALL NULL NULL NULL NULL 10 100.00 Using where; Using join buffer (hash join) @@ -5401,7 +5401,7 @@ SELECT * FROM (t4 LEFT JOIN (t2 LEFT JOIN t3 on t2.pk = t3.pk) on t2.c = t4.c + pk c pk c pk c pk c EXPLAIN SELECT * FROM (t1 LEFT JOIN t2 on t1.pk = t2.pk) JOIN (t3 LEFT JOIN t4 on t3.pk = t4.pk) on t1.pk = t3.pk AND t1.pk < 3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0,p1,p2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +1 SIMPLE t1 p0,p1,p2 range PRIMARY PRIMARY 4 NULL 2 100.00 NULL 1 SIMPLE t3 p0,p1,p2 eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 100.00 NULL 1 SIMPLE t2 NULL eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 100.00 NULL 1 SIMPLE t4 NULL eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 100.00 NULL @@ -5463,7 +5463,7 @@ pk c pk c pk c pk c 10 40 10 50 NULL NULL NULL NULL EXPLAIN SELECT * FROM (t3 LEFT JOIN t4 on t3.pk = t4.pk) JOIN (t1 LEFT JOIN t2 on t1.pk = t2.pk) on t1.pk = t3.pk AND t1.pk < 3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 p0,p1,p2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +1 SIMPLE t3 p0,p1,p2 range PRIMARY PRIMARY 4 NULL 2 100.00 NULL 1 SIMPLE t1 p0,p1,p2 eq_ref PRIMARY PRIMARY 4 test.t3.pk 1 100.00 NULL 1 SIMPLE t4 NULL eq_ref PRIMARY PRIMARY 4 test.t3.pk 1 100.00 NULL 1 SIMPLE t2 NULL eq_ref PRIMARY PRIMARY 4 test.t3.pk 1 100.00 NULL @@ -5475,7 +5475,7 @@ pk c pk c pk c pk c 2 32 2 42 2 2 2 22 EXPLAIN SELECT * FROM (t1 LEFT JOIN t2 on t1.pk = t2.pk and t1.pk < 2) JOIN ((t5 LEFT JOIN t3 on t5.pk = t3.pk) LEFT JOIN t4 on t5.c = t4.c + 15) on t1.pk = t3.pk AND t1.pk < 3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0,p1,p2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +1 SIMPLE t1 p0,p1,p2 range PRIMARY PRIMARY 4 NULL 2 100.00 NULL 1 SIMPLE t5 NULL eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 100.00 NULL 1 SIMPLE t3 p0,p1,p2 eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 100.00 NULL 1 SIMPLE t2 NULL eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 100.00 Using where @@ -5540,7 +5540,7 @@ pk c pk c pk c pk c pk c 10 60 10 40 5 45 NULL NULL NULL NULL EXPLAIN SELECT * FROM ((t5 LEFT JOIN t3 on t5.pk = t3.pk) LEFT JOIN t4 on t5.c = t4.c + 15) JOIN (t1 LEFT JOIN t2 on t1.pk = t2.pk and t1.pk < 2) on t1.pk = t3.pk AND t1.pk < 3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t5 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +1 SIMPLE t5 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL 1 SIMPLE t3 p0,p1,p2 eq_ref PRIMARY PRIMARY 4 test.t5.pk 1 100.00 NULL 1 SIMPLE t1 p0,p1,p2 eq_ref PRIMARY PRIMARY 4 test.t5.pk 1 100.00 NULL 1 SIMPLE t2 NULL eq_ref PRIMARY PRIMARY 4 test.t5.pk 1 100.00 Using where @@ -5556,7 +5556,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE t5 NULL range PRIMARY PRIMARY 4 NULL 7 100.00 Using where 1 SIMPLE t3 p4 eq_ref PRIMARY PRIMARY 4 test.t5.pk 1 100.00 NULL 1 SIMPLE t1 p4 eq_ref PRIMARY PRIMARY 4 test.t5.pk 1 100.00 NULL -1 SIMPLE t2 NULL eq_ref PRIMARY PRIMARY 4 test.t5.pk 1 100.00 Using where +1 SIMPLE t2 NULL eq_ref PRIMARY PRIMARY 4 test.t5.pk 1 100.00 NULL 1 SIMPLE t4 NULL ALL NULL NULL NULL NULL 10 100.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c` AS `c`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c` AS `c`,`test`.`t4`.`pk` AS `pk`,`test`.`t4`.`c` AS `c`,`test`.`t5`.`pk` AS `pk`,`test`.`t5`.`c` AS `c`,`test`.`t3`.`pk` AS `pk`,`test`.`t3`.`c` AS `c` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`pk` = `test`.`t5`.`pk`) and (`test`.`t5`.`pk` > 3))) join `test`.`t4` join `test`.`t5` join `test`.`t3` where ((`test`.`t3`.`pk` = `test`.`t5`.`pk`) and (`test`.`t1`.`pk` = `test`.`t5`.`pk`) and (`test`.`t5`.`pk` > 3) and (`test`.`t5`.`c` = (`test`.`t4`.`c` + 20))) @@ -5619,7 +5619,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE t5 NULL range PRIMARY PRIMARY 4 NULL 7 100.00 Using where 1 SIMPLE t3 p4 eq_ref PRIMARY PRIMARY 4 test.t5.pk 1 100.00 NULL 1 SIMPLE t1 p4 eq_ref PRIMARY PRIMARY 4 test.t5.pk 1 100.00 NULL -1 SIMPLE t2 NULL eq_ref PRIMARY PRIMARY 4 test.t5.pk 1 100.00 Using where +1 SIMPLE t2 NULL eq_ref PRIMARY PRIMARY 4 test.t5.pk 1 100.00 NULL 1 SIMPLE t4 NULL ALL NULL NULL NULL NULL 10 100.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`pk` AS `pk`,`test`.`t4`.`c` AS `c`,`test`.`t5`.`pk` AS `pk`,`test`.`t5`.`c` AS `c`,`test`.`t3`.`pk` AS `pk`,`test`.`t3`.`c` AS `c`,`test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c` AS `c`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c` AS `c` from `test`.`t4` join `test`.`t5` join `test`.`t3` join `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`pk` = `test`.`t5`.`pk`) and (`test`.`t5`.`pk` > 3))) where ((`test`.`t3`.`pk` = `test`.`t5`.`pk`) and (`test`.`t1`.`pk` = `test`.`t5`.`pk`) and (`test`.`t5`.`pk` > 3) and (`test`.`t5`.`c` = (`test`.`t4`.`c` + 20))) @@ -5989,7 +5989,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE t2 NULL ALL PRIMARY NULL NULL NULL 10 100.00 NULL 1 SIMPLE t1 p0,p1,p2,p3,p4 eq_ref PRIMARY PRIMARY 4 test.t2.pk 1 100.00 NULL 1 SIMPLE NULL eq_ref 5 test.t2.pk 1 100.00 NULL -2 MATERIALIZED t3 p3,p4 range PRIMARY PRIMARY 4 NULL 8 100.00 Using where +2 MATERIALIZED t3 p3,p4 range PRIMARY PRIMARY 4 NULL 8 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c` AS `c`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` semi join (`test`.`t3`) where ((`test`.`t1`.`pk` = `test`.`t2`.`pk`) and (``.`c` = `test`.`t2`.`pk`) and (`test`.`t3`.`pk` > 2)) SELECT * FROM t1 JOIN t2 on t1.pk = t2.pk WHERE t1.pk IN (SELECT c FROM t3 WHERE pk > 2); @@ -5999,7 +5999,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where 1 SIMPLE t1 p0,p1,p2,p3,p4 eq_ref PRIMARY PRIMARY 4 .c 1 100.00 NULL 1 SIMPLE t2 NULL ALL PRIMARY NULL NULL NULL 10 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t3 p3,p4 range PRIMARY PRIMARY 4 NULL 8 100.00 Using where +2 MATERIALIZED t3 p3,p4 range PRIMARY PRIMARY 4 NULL 8 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c` AS `c`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c` AS `c` from `test`.`t1` left join `test`.`t2` on((`test`.`t2`.`pk` = `test`.`t1`.`pk`)) semi join (`test`.`t3`) where ((`test`.`t1`.`pk` = ``.`c`) and (`test`.`t3`.`pk` > 2)) SELECT * FROM t1 LEFT JOIN t2 on t1.pk = t2.pk WHERE t1.pk IN (SELECT c FROM t3 WHERE pk > 2); @@ -6009,7 +6009,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE t2 NULL ALL PRIMARY NULL NULL NULL 10 100.00 NULL 1 SIMPLE t1 p0,p1,p2,p3,p4 eq_ref PRIMARY PRIMARY 4 test.t2.pk 1 100.00 NULL 1 SIMPLE NULL eq_ref 5 test.t2.pk 1 100.00 NULL -2 MATERIALIZED t3 p3,p4 range PRIMARY PRIMARY 4 NULL 8 100.00 Using where +2 MATERIALIZED t3 p3,p4 range PRIMARY PRIMARY 4 NULL 8 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c` AS `c`,`test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c` AS `c` from `test`.`t2` join `test`.`t1` semi join (`test`.`t3`) where ((`test`.`t1`.`pk` = `test`.`t2`.`pk`) and (``.`c` = `test`.`t2`.`pk`) and (`test`.`t3`.`pk` > 2)) SELECT * FROM t2 LEFT JOIN t1 on t1.pk = t2.pk WHERE t1.pk IN (SELECT c FROM t3 WHERE pk > 2); @@ -6019,7 +6019,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE t2 NULL ALL PRIMARY NULL NULL NULL 10 100.00 NULL 1 SIMPLE t1 p0,p1,p2,p3,p4 eq_ref PRIMARY PRIMARY 4 test.t2.pk 1 100.00 NULL 1 SIMPLE NULL eq_ref 5 test.t2.pk 1 100.00 NULL -2 MATERIALIZED t3 p3,p4 range PRIMARY PRIMARY 4 NULL 8 100.00 Using where +2 MATERIALIZED t3 p3,p4 range PRIMARY PRIMARY 4 NULL 8 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c` AS `c`,`test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c` AS `c` from `test`.`t2` join `test`.`t1` semi join (`test`.`t3`) where ((`test`.`t1`.`pk` = `test`.`t2`.`pk`) and (``.`c` = `test`.`t2`.`pk`) and (`test`.`t3`.`pk` > 2)) SELECT * FROM t2 JOIN t1 on t1.pk = t2.pk WHERE t1.pk IN (SELECT c FROM t3 WHERE pk > 2); @@ -6029,7 +6029,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE t2 NULL ALL PRIMARY NULL NULL NULL 10 100.00 NULL 1 SIMPLE t1 p4 eq_ref PRIMARY PRIMARY 4 test.t2.pk 1 100.00 Using where 1 SIMPLE NULL eq_ref 5 test.t2.pk 1 100.00 NULL -3 MATERIALIZED t3 p3,p4 range PRIMARY PRIMARY 4 NULL 8 100.00 Using where +3 MATERIALIZED t3 p3,p4 range PRIMARY PRIMARY 4 NULL 8 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c` AS `c`,`test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c` AS `c` from `test`.`t2` join `test`.`t1` semi join (`test`.`t3`) where ((`test`.`t1`.`pk` = `test`.`t2`.`pk`) and (``.`c` = `test`.`t2`.`pk`) and (`test`.`t1`.`pk` > 3) and (`test`.`t3`.`pk` > 2)) SELECT * FROM t2 JOIN (SELECT * FROM t1 WHERE t1.pk IN (SELECT c FROM t3 WHERE pk > 2)) t13 on t13.pk = t2.pk AND t13.pk > 3; @@ -6059,7 +6059,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where 1 SIMPLE t1 p0,p1,p2,p3,p4 eq_ref PRIMARY PRIMARY 4 .c 1 100.00 NULL 1 SIMPLE t2 NULL ALL PRIMARY NULL NULL NULL 10 100.00 Using where; Using join buffer (hash join) -3 MATERIALIZED t3 p3,p4 range PRIMARY PRIMARY 4 NULL 8 100.00 Using where +3 MATERIALIZED t3 p3,p4 range PRIMARY PRIMARY 4 NULL 8 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c` AS `c`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c` AS `c` from `test`.`t1` semi join (`test`.`t3`) left join `test`.`t2` on(((`test`.`t2`.`pk` = `test`.`t1`.`pk`) and (`test`.`t1`.`pk` > 3))) where ((`test`.`t1`.`pk` = ``.`c`) and (`test`.`t3`.`pk` > 2)) SELECT * FROM (SELECT * FROM t1 WHERE t1.pk IN (SELECT c FROM t3 WHERE pk > 2)) t13 LEFT JOIN t2 on t13.pk = t2.pk AND t13.pk > 3; @@ -6069,14 +6069,14 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE t2 NULL ALL PRIMARY NULL NULL NULL 10 100.00 NULL 1 SIMPLE t1 p4 eq_ref PRIMARY PRIMARY 4 test.t2.pk 1 100.00 Using where 1 SIMPLE NULL eq_ref 5 test.t2.pk 1 100.00 NULL -3 MATERIALIZED t3 p3,p4 range PRIMARY PRIMARY 4 NULL 8 100.00 Using where +3 MATERIALIZED t3 p3,p4 range PRIMARY PRIMARY 4 NULL 8 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c` AS `c`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c` AS `c` from `test`.`t1` semi join (`test`.`t3`) join `test`.`t2` where ((`test`.`t1`.`pk` = `test`.`t2`.`pk`) and (``.`c` = `test`.`t2`.`pk`) and (`test`.`t1`.`pk` > 3) and (`test`.`t3`.`pk` > 2)) SELECT * FROM (SELECT * FROM t1 WHERE t1.pk IN (SELECT c FROM t3 WHERE pk > 2)) t13 JOIN t2 on t13.pk = t2.pk AND t13.pk > 3; pk c pk c EXPLAIN SELECT * FROM (t1 LEFT JOIN t2 on t1.pk = t2.pk) JOIN (t3 LEFT JOIN (SELECT * FROM t1 as tx WHERE tx.pk IN (SELECT c FROM t3 WHERE pk > 2)) t13 on t3.pk = t13.pk) on t1.pk = t3.pk AND t1.pk < 3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 p0,p1,p2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +1 SIMPLE t1 p0,p1,p2 range PRIMARY PRIMARY 4 NULL 2 100.00 NULL 1 SIMPLE t3 p0,p1,p2 eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 100.00 NULL 1 SIMPLE t2 NULL eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 100.00 NULL 1 SIMPLE tx p0,p1,p2,p3,p4 eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 100.00 NULL @@ -6143,7 +6143,7 @@ pk c pk c pk c pk c 10 40 NULL NULL NULL NULL NULL NULL EXPLAIN SELECT * FROM (t3 LEFT JOIN (SELECT * FROM t1 as tx WHERE tx.pk IN (SELECT c FROM t3 WHERE pk > 2)) t13 on t3.pk = t13.pk) JOIN (t1 LEFT JOIN t2 on t1.pk = t2.pk) on t1.pk = t3.pk AND t1.pk < 3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 p0,p1,p2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +1 SIMPLE t3 p0,p1,p2 range PRIMARY PRIMARY 4 NULL 2 100.00 NULL 1 SIMPLE t1 p0,p1,p2 eq_ref PRIMARY PRIMARY 4 test.t3.pk 1 100.00 NULL 1 SIMPLE t2 NULL eq_ref PRIMARY PRIMARY 4 test.t3.pk 1 100.00 NULL 1 SIMPLE tx p0,p1,p2,p3,p4 eq_ref PRIMARY PRIMARY 4 test.t3.pk 1 100.00 NULL @@ -6239,10 +6239,10 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE t5 NULL range PRIMARY PRIMARY 4 NULL 7 100.00 Using where 1 SIMPLE t1 p4 eq_ref PRIMARY PRIMARY 4 test.t5.pk 1 100.00 NULL 1 SIMPLE tx p4 eq_ref PRIMARY PRIMARY 4 test.t5.pk 1 100.00 NULL -1 SIMPLE t2 NULL eq_ref PRIMARY PRIMARY 4 test.t5.pk 1 100.00 Using where +1 SIMPLE t2 NULL eq_ref PRIMARY PRIMARY 4 test.t5.pk 1 100.00 NULL 1 SIMPLE NULL eq_ref 5 test.t5.pk 1 100.00 NULL 1 SIMPLE t4 NULL ALL NULL NULL NULL NULL 10 100.00 Using where; Using join buffer (hash join) -3 MATERIALIZED t3 p3,p4 range PRIMARY PRIMARY 4 NULL 8 100.00 Using where +3 MATERIALIZED t3 p3,p4 range PRIMARY PRIMARY 4 NULL 8 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c` AS `c`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c` AS `c`,`test`.`t4`.`pk` AS `pk`,`test`.`t4`.`c` AS `c`,`test`.`t5`.`pk` AS `pk`,`test`.`t5`.`c` AS `c`,`test`.`tx`.`pk` AS `pk`,`test`.`tx`.`c` AS `c` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`pk` = `test`.`t5`.`pk`) and (`test`.`t5`.`pk` > 3))) join `test`.`t4` join `test`.`t5` join `test`.`t1` `tx` semi join (`test`.`t3`) where ((`test`.`t1`.`pk` = `test`.`t5`.`pk`) and (`test`.`tx`.`pk` = `test`.`t5`.`pk`) and (``.`c` = `test`.`t5`.`pk`) and (`test`.`t5`.`pk` > 3) and (`test`.`t3`.`pk` > 2) and (`test`.`t5`.`c` = (`test`.`t4`.`c` + 20))) SELECT * FROM (t1 LEFT JOIN t2 on t1.pk = t2.pk and t1.pk > 3) JOIN (t4 LEFT JOIN (t5 LEFT JOIN (SELECT * FROM t1 as tx WHERE tx.pk IN (SELECT c FROM t3 WHERE pk > 2)) t13 on t5.pk = t13.pk) on t5.c = t4.c + 20) on t1.pk = t13.pk AND t1.pk > 3; @@ -6311,7 +6311,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE t1 p4 eq_ref PRIMARY PRIMARY 4 .c 1 100.00 NULL 1 SIMPLE t2 NULL eq_ref PRIMARY PRIMARY 4 .c 1 100.00 Using where 1 SIMPLE t4 NULL ALL NULL NULL NULL NULL 10 100.00 Using where; Using join buffer (hash join) -3 MATERIALIZED t3 p3,p4 range PRIMARY PRIMARY 4 NULL 8 100.00 Using where +3 MATERIALIZED t3 p3,p4 range PRIMARY PRIMARY 4 NULL 8 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`pk` AS `pk`,`test`.`t4`.`c` AS `c`,`test`.`t5`.`pk` AS `pk`,`test`.`t5`.`c` AS `c`,`test`.`tx`.`pk` AS `pk`,`test`.`tx`.`c` AS `c`,`test`.`t1`.`pk` AS `pk`,`test`.`t1`.`c` AS `c`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c` AS `c` from `test`.`t4` join `test`.`t5` join `test`.`t1` `tx` semi join (`test`.`t3`) join `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`pk` = `test`.`t5`.`pk`) and (`test`.`t5`.`pk` > 3))) where ((`test`.`t5`.`pk` = ``.`c`) and (`test`.`tx`.`pk` = ``.`c`) and (`test`.`t1`.`pk` = ``.`c`) and (``.`c` > 3) and (`test`.`t3`.`pk` > 2) and (`test`.`t5`.`c` = (`test`.`t4`.`c` + 20))) SELECT * FROM (t4 LEFT JOIN (t5 LEFT JOIN (SELECT * FROM t1 as tx WHERE tx.pk IN (SELECT c FROM t3 WHERE pk > 2)) t13 on t5.pk = t13.pk) on t5.c = t4.c + 20) JOIN (t1 LEFT JOIN t2 on t1.pk = t2.pk and t1.pk > 3) on t1.pk = t13.pk AND t1.pk > 3; diff --git a/mysql-test/r/persisted_variables_bugs.result b/mysql-test/r/persisted_variables_bugs.result index 2e5259ca974..8b5aad6f731 100644 --- a/mysql-test/r/persisted_variables_bugs.result +++ b/mysql-test/r/persisted_variables_bugs.result @@ -167,7 +167,7 @@ SELECT @@global.optimizer_trace_offset; -1 SELECT @@global.optimizer_switch; @@global.optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on SELECT @@global.enforce_gtid_consistency; @@global.enforce_gtid_consistency OFF @@ -186,7 +186,7 @@ VARIABLE_NAME VARIABLE_VALUE binlog_cache_size 32768 collation_database utf8mb4_0900_ai_ci enforce_gtid_consistency 0 -optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on optimizer_trace_offset -1 sql_mode ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION # Restart server @@ -202,7 +202,7 @@ SELECT @@global.optimizer_trace_offset; -1 SELECT @@global.optimizer_switch; @@global.optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on SELECT @@global.enforce_gtid_consistency; @@global.enforce_gtid_consistency OFF @@ -214,7 +214,7 @@ VARIABLE_NAME VARIABLE_VALUE binlog_cache_size 32768 collation_database utf8mb4_0900_ai_ci enforce_gtid_consistency 0 -optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on optimizer_trace_offset -1 sql_mode ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION # Cleanup diff --git a/mysql-test/r/range_all.result b/mysql-test/r/range_all.result index 3ecf2f3a57c..2303c9a45d9 100644 --- a/mysql-test/r/range_all.result +++ b/mysql-test/r/range_all.result @@ -35,7 +35,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`event_date` AS `event_date`,`test`.`t1`.`type` AS `type`,`test`.`t1`.`event_id` AS `event_id` from `test`.`t1` where ((`test`.`t1`.`event_date` >= DATE'1999-07-01') and (`test`.`t1`.`event_date` < DATE'1999-07-15') and ((`test`.`t1`.`type` = 100600) or (`test`.`t1`.`type` = 100100))) order by `test`.`t1`.`event_date` explain format=tree select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date; EXPLAIN --> Filter: ((t1.event_date >= DATE'1999-07-01') and (t1.event_date < DATE'1999-07-15') and ((t1.`type` = 100600) or (t1.`type` = 100100))) (cost=1.46 rows=1) +-> Filter: ((t1.`type` = 100600) or (t1.`type` = 100100)) (cost=1.46 rows=1) -> Covering index range scan on t1 using PRIMARY over ('1999-07-01' <= event_date <= '1999-07-15' AND 100100 <= type) (cost=1.46 rows=6) select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date; @@ -252,37 +252,37 @@ test.t1 analyze status OK explain select * from t1, t1 t2 where t1.y = 8 and t2.x between 7 and t1.y+0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using index condition; Using MRR; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using MRR; Using join buffer (hash join) Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 8) and (`test`.`t2`.`x` between 7 and ((8 + 0)))) +Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 8) and (`test`.`t2`.`x` between 7 and (8 + 0))) explain select * from t1, t1 t2 where t1.y = 8 and t2.x >= 7 and t2.x <= t1.y+0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using index condition; Using MRR; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using MRR; Using join buffer (hash join) Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 8) and (`test`.`t2`.`x` >= 7) and (`test`.`t2`.`x` <= ((8 + 0)))) +Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 8) and (`test`.`t2`.`x` >= 7) and (`test`.`t2`.`x` <= (8 + 0))) explain select * from t1, t1 t2 where t1.y = 2 and t2.x between t1.y-1 and t1.y+1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 3 100.00 Using index condition; Using MRR; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 3 100.00 Using MRR; Using join buffer (hash join) Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` between ((2 - 1)) and ((2 + 1)))) +Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` between (2 - 1) and (2 + 1))) explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= t1.y-1 and t2.x <= t1.y+1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 3 100.00 Using index condition; Using MRR; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 3 100.00 Using MRR; Using join buffer (hash join) Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` >= ((2 - 1))) and (`test`.`t2`.`x` <= ((2 + 1)))) +Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` >= (2 - 1)) and (`test`.`t2`.`x` <= (2 + 1))) explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 0 and t1.y; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using index condition; Using MRR; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using MRR; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` between 0 and 2)) explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 0 and t2.x <= t1.y; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using index condition; Using MRR; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using MRR; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` >= 0) and (`test`.`t2`.`x` <= 2)) explain select count(*) from t1 where x in (1); @@ -492,11 +492,11 @@ test.t1 analyze status OK test.t2 analyze status OK explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE # NULL range uid_index uid_index 4 # 28 100.00 Using index condition; Using MRR +1 SIMPLE # NULL range uid_index uid_index 4 # 28 100.00 Using MRR 1 SIMPLE # NULL ref uid_index uid_index 4 # 28 100.00 NULL explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE # NULL range uid_index uid_index 4 # 28 100.00 Using index condition; Using MRR +1 SIMPLE # NULL range uid_index uid_index 4 # 28 100.00 Using MRR 1 SIMPLE # NULL ref uid_index uid_index 4 # 28 100.00 NULL explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra @@ -1068,7 +1068,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = 3) and (`test`.`t1`.`a` < 2)) EXPLAIN SELECT a,b FROM t1 WHERE a < 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` < 2) EXPLAIN SELECT a,b FROM v1 WHERE a < 2; @@ -1147,7 +1147,7 @@ create table t2 (a varchar(10), filler char(200), key(a)) charset utf8mb4; insert into t2 select * from t1; explain select * from t1 where a between 'a' and 'a '; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 13 NULL # 100.00 Using index condition; Using MRR +1 SIMPLE t1 NULL range a a 13 NULL # 100.00 Using MRR Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`filler` AS `filler` from `test`.`t1` where (`test`.`t1`.`a` between 'a' and 'a ') explain select * from t1 where a = 'a' or a='a '; @@ -1221,7 +1221,7 @@ id b c 0 3 4 EXPLAIN SELECT * FROM t1 WHERE b<=3 AND 3<=c; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using index condition; Using where; Using MRR +1 SIMPLE t1 NULL range idx1,idx2 idx2 4 NULL 2 100.00 Using where; Using MRR Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`b` <= 3) and (3 <= `test`.`t1`.`c`)) EXPLAIN SELECT * FROM t1 WHERE 3 BETWEEN b AND c; @@ -1302,7 +1302,7 @@ INSERT INTO t1 VALUES This must use range access: explain select * from t1 where dateval >= '2007-01-01 00:00:00' and dateval <= '2007-01-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range dateval dateval 4 NULL 2 100.00 Using where; Using index +1 SIMPLE t1 NULL range dateval dateval 4 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`dateval` AS `dateval` from `test`.`t1` where ((`test`.`t1`.`dateval` >= DATE'2007-01-01') and (`test`.`t1`.`dateval` <= DATE'2007-01-02')) drop table t1; @@ -1375,7 +1375,7 @@ Access method can be range/ALL with #rows >= 500. Or it can be ref with #rows = 2, only when there is memory limit. explain select * from t2 where a=1000 and b<11; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range a a 10 NULL 500 100.00 Using index condition; Using MRR +1 SIMPLE t2 NULL range a a 10 NULL 500 100.00 Using MRR Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`filler` AS `filler` from `test`.`t2` where ((`test`.`t2`.`a` = 1000) and (`test`.`t2`.`b` < 11)) drop table t1, t2; @@ -1979,7 +1979,7 @@ pk i4 EXPLAIN SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i4_uq i4_uq 5 NULL 2 100.00 Using where; Using index +1 SIMPLE t1 NULL range i4_uq i4_uq 5 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i4` AS `i4` from `test`.`t1` where (`test`.`t1`.`i4` between 10 and '20') SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20'; @@ -3864,7 +3864,7 @@ FROM transactions WHERE created > '2017-10-23 01:01:01' AND tbl = 1 AND trans_type in (3) GROUP BY '2017-10-23 01:01:01', HOUR(created), source_lvl1, source_lvl2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE transactions NULL range tbl_id_idx,created_idx,trans_type_created_idx created_idx 4 NULL # # Using index condition; Using where; Using MRR; Using filesort +1 SIMPLE transactions NULL range tbl_id_idx,created_idx,trans_type_created_idx created_idx 4 NULL # # Using where; Using MRR; Using filesort Warnings: Note 1003 /* select#1 */ select '2017-10-23 01:01:01' AS `2017-10-23 01:01:01`,hour(`test`.`transactions`.`created`) AS `HOUR(created)`,`test`.`transactions`.`source_lvl1` AS `source_lvl1`,`test`.`transactions`.`source_lvl2` AS `source_lvl2`,count(distinct `test`.`transactions`.`app_trans_id`) AS `COUNT(DISTINCT(app_trans_id))` from `test`.`transactions` where ((`test`.`transactions`.`trans_type` = 3) and (`test`.`transactions`.`tbl` = 1) and (`test`.`transactions`.`created` > TIMESTAMP'2017-10-23 01:01:01')) group by '2017-10-23 01:01:01',hour(`test`.`transactions`.`created`),`test`.`transactions`.`source_lvl1`,`test`.`transactions`.`source_lvl2` SET optimizer_trace="enabled=on"; diff --git a/mysql-test/r/range_icp.result b/mysql-test/r/range_icp.result index 6f0f8fb26a0..3a729b7ca41 100644 --- a/mysql-test/r/range_icp.result +++ b/mysql-test/r/range_icp.result @@ -1,4 +1,5 @@ set optimizer_switch='index_condition_pushdown=on'; +set empty_redundant_check_in_range_scan=false; drop table if exists t1, t2, t3; SET sql_mode = 'NO_ENGINE_SUBSTITUTION'; CREATE TABLE t1 ( @@ -4060,4 +4061,5 @@ a 2 1 DROP TABLE t1; +set empty_redundant_check_in_range_scan=true; set optimizer_switch=default; diff --git a/mysql-test/r/range_icp_mrr.result b/mysql-test/r/range_icp_mrr.result index 67983f48bb7..71c0e61036d 100644 --- a/mysql-test/r/range_icp_mrr.result +++ b/mysql-test/r/range_icp_mrr.result @@ -1,4 +1,5 @@ set optimizer_switch='index_condition_pushdown=on,mrr=on,mrr_cost_based=off'; +set empty_redundant_check_in_range_scan=false; drop table if exists t1, t2, t3; SET sql_mode = 'NO_ENGINE_SUBSTITUTION'; CREATE TABLE t1 ( @@ -4060,4 +4061,5 @@ a 2 1 DROP TABLE t1; +set empty_redundant_check_in_range_scan=true; set optimizer_switch=default; diff --git a/mysql-test/r/range_mrr.result b/mysql-test/r/range_mrr.result index 8841f957df3..504c820598d 100644 --- a/mysql-test/r/range_mrr.result +++ b/mysql-test/r/range_mrr.result @@ -35,7 +35,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`event_date` AS `event_date`,`test`.`t1`.`type` AS `type`,`test`.`t1`.`event_id` AS `event_id` from `test`.`t1` where ((`test`.`t1`.`event_date` >= DATE'1999-07-01') and (`test`.`t1`.`event_date` < DATE'1999-07-15') and ((`test`.`t1`.`type` = 100600) or (`test`.`t1`.`type` = 100100))) order by `test`.`t1`.`event_date` explain format=tree select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date; EXPLAIN --> Filter: ((t1.event_date >= DATE'1999-07-01') and (t1.event_date < DATE'1999-07-15') and ((t1.`type` = 100600) or (t1.`type` = 100100))) (cost=1.46 rows=1) +-> Filter: ((t1.`type` = 100600) or (t1.`type` = 100100)) (cost=1.46 rows=1) -> Covering index range scan on t1 using PRIMARY over ('1999-07-01' <= event_date <= '1999-07-15' AND 100100 <= type) (cost=1.46 rows=6) select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date; @@ -252,37 +252,37 @@ test.t1 analyze status OK explain select * from t1, t1 t2 where t1.y = 8 and t2.x between 7 and t1.y+0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using where; Using MRR; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using MRR; Using join buffer (hash join) Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 8) and (`test`.`t2`.`x` between 7 and ((8 + 0)))) +Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 8) and (`test`.`t2`.`x` between 7 and (8 + 0))) explain select * from t1, t1 t2 where t1.y = 8 and t2.x >= 7 and t2.x <= t1.y+0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using where; Using MRR; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using MRR; Using join buffer (hash join) Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 8) and (`test`.`t2`.`x` >= 7) and (`test`.`t2`.`x` <= ((8 + 0)))) +Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 8) and (`test`.`t2`.`x` >= 7) and (`test`.`t2`.`x` <= (8 + 0))) explain select * from t1, t1 t2 where t1.y = 2 and t2.x between t1.y-1 and t1.y+1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 3 100.00 Using where; Using MRR; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 3 100.00 Using MRR; Using join buffer (hash join) Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` between ((2 - 1)) and ((2 + 1)))) +Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` between (2 - 1) and (2 + 1))) explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= t1.y-1 and t2.x <= t1.y+1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 3 100.00 Using where; Using MRR; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 3 100.00 Using MRR; Using join buffer (hash join) Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` >= ((2 - 1))) and (`test`.`t2`.`x` <= ((2 + 1)))) +Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` >= (2 - 1)) and (`test`.`t2`.`x` <= (2 + 1))) explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 0 and t1.y; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using where; Using MRR; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using MRR; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` between 0 and 2)) explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 0 and t2.x <= t1.y; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using where; Using MRR; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using MRR; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` >= 0) and (`test`.`t2`.`x` <= 2)) explain select count(*) from t1 where x in (1); @@ -492,11 +492,11 @@ test.t1 analyze status OK test.t2 analyze status OK explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE # NULL range uid_index uid_index 4 # 28 100.00 Using where; Using MRR +1 SIMPLE # NULL range uid_index uid_index 4 # 28 100.00 Using MRR 1 SIMPLE # NULL ref uid_index uid_index 4 # 28 100.00 NULL explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE # NULL range uid_index uid_index 4 # 28 100.00 Using where; Using MRR +1 SIMPLE # NULL range uid_index uid_index 4 # 28 100.00 Using MRR 1 SIMPLE # NULL ref uid_index uid_index 4 # 28 100.00 NULL explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra @@ -1068,7 +1068,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = 3) and (`test`.`t1`.`a` < 2)) EXPLAIN SELECT a,b FROM t1 WHERE a < 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` < 2) EXPLAIN SELECT a,b FROM v1 WHERE a < 2; @@ -1147,7 +1147,7 @@ create table t2 (a varchar(10), filler char(200), key(a)) charset utf8mb4; insert into t2 select * from t1; explain select * from t1 where a between 'a' and 'a '; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 13 NULL # 100.00 Using where; Using MRR +1 SIMPLE t1 NULL range a a 13 NULL # 100.00 Using MRR Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`filler` AS `filler` from `test`.`t1` where (`test`.`t1`.`a` between 'a' and 'a ') explain select * from t1 where a = 'a' or a='a '; @@ -1302,7 +1302,7 @@ INSERT INTO t1 VALUES This must use range access: explain select * from t1 where dateval >= '2007-01-01 00:00:00' and dateval <= '2007-01-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range dateval dateval 4 NULL 2 100.00 Using where; Using index +1 SIMPLE t1 NULL range dateval dateval 4 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`dateval` AS `dateval` from `test`.`t1` where ((`test`.`t1`.`dateval` >= DATE'2007-01-01') and (`test`.`t1`.`dateval` <= DATE'2007-01-02')) drop table t1; @@ -1375,7 +1375,7 @@ Access method can be range/ALL with #rows >= 500. Or it can be ref with #rows = 2, only when there is memory limit. explain select * from t2 where a=1000 and b<11; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range a a 10 NULL 500 100.00 Using where; Using MRR +1 SIMPLE t2 NULL range a a 10 NULL 500 100.00 Using MRR Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`filler` AS `filler` from `test`.`t2` where ((`test`.`t2`.`a` = 1000) and (`test`.`t2`.`b` < 11)) drop table t1, t2; @@ -1979,7 +1979,7 @@ pk i4 EXPLAIN SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i4_uq i4_uq 5 NULL 2 100.00 Using where; Using index +1 SIMPLE t1 NULL range i4_uq i4_uq 5 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i4` AS `i4` from `test`.`t1` where (`test`.`t1`.`i4` between 10 and '20') SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20'; diff --git a/mysql-test/r/range_mrr_cost.result b/mysql-test/r/range_mrr_cost.result index 1ca21882377..f449d68c512 100644 --- a/mysql-test/r/range_mrr_cost.result +++ b/mysql-test/r/range_mrr_cost.result @@ -35,7 +35,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`event_date` AS `event_date`,`test`.`t1`.`type` AS `type`,`test`.`t1`.`event_id` AS `event_id` from `test`.`t1` where ((`test`.`t1`.`event_date` >= DATE'1999-07-01') and (`test`.`t1`.`event_date` < DATE'1999-07-15') and ((`test`.`t1`.`type` = 100600) or (`test`.`t1`.`type` = 100100))) order by `test`.`t1`.`event_date` explain format=tree select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date; EXPLAIN --> Filter: ((t1.event_date >= DATE'1999-07-01') and (t1.event_date < DATE'1999-07-15') and ((t1.`type` = 100600) or (t1.`type` = 100100))) (cost=1.46 rows=1) +-> Filter: ((t1.`type` = 100600) or (t1.`type` = 100100)) (cost=1.46 rows=1) -> Covering index range scan on t1 using PRIMARY over ('1999-07-01' <= event_date <= '1999-07-15' AND 100100 <= type) (cost=1.46 rows=6) select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date; @@ -252,37 +252,37 @@ test.t1 analyze status OK explain select * from t1, t1 t2 where t1.y = 8 and t2.x between 7 and t1.y+0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using where; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using join buffer (hash join) Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 8) and (`test`.`t2`.`x` between 7 and ((8 + 0)))) +Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 8) and (`test`.`t2`.`x` between 7 and (8 + 0))) explain select * from t1, t1 t2 where t1.y = 8 and t2.x >= 7 and t2.x <= t1.y+0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using where; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using join buffer (hash join) Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 8) and (`test`.`t2`.`x` >= 7) and (`test`.`t2`.`x` <= ((8 + 0)))) +Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 8) and (`test`.`t2`.`x` >= 7) and (`test`.`t2`.`x` <= (8 + 0))) explain select * from t1, t1 t2 where t1.y = 2 and t2.x between t1.y-1 and t1.y+1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 3 100.00 Using where; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 3 100.00 Using join buffer (hash join) Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` between ((2 - 1)) and ((2 + 1)))) +Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` between (2 - 1) and (2 + 1))) explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= t1.y-1 and t2.x <= t1.y+1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 3 100.00 Using where; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 3 100.00 Using join buffer (hash join) Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` >= ((2 - 1))) and (`test`.`t2`.`x` <= ((2 + 1)))) +Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` >= (2 - 1)) and (`test`.`t2`.`x` <= (2 + 1))) explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 0 and t1.y; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using where; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` between 0 and 2)) explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 0 and t2.x <= t1.y; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using where; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` >= 0) and (`test`.`t2`.`x` <= 2)) explain select count(*) from t1 where x in (1); @@ -492,11 +492,11 @@ test.t1 analyze status OK test.t2 analyze status OK explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE # NULL range uid_index uid_index 4 # 28 100.00 Using where +1 SIMPLE # NULL range uid_index uid_index 4 # 28 100.00 NULL 1 SIMPLE # NULL ref uid_index uid_index 4 # 28 100.00 NULL explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE # NULL range uid_index uid_index 4 # 28 100.00 Using where +1 SIMPLE # NULL range uid_index uid_index 4 # 28 100.00 NULL 1 SIMPLE # NULL ref uid_index uid_index 4 # 28 100.00 NULL explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra @@ -1068,7 +1068,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = 3) and (`test`.`t1`.`a` < 2)) EXPLAIN SELECT a,b FROM t1 WHERE a < 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` < 2) EXPLAIN SELECT a,b FROM v1 WHERE a < 2; @@ -1147,7 +1147,7 @@ create table t2 (a varchar(10), filler char(200), key(a)) charset utf8mb4; insert into t2 select * from t1; explain select * from t1 where a between 'a' and 'a '; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 13 NULL # 100.00 Using where +1 SIMPLE t1 NULL range a a 13 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`filler` AS `filler` from `test`.`t1` where (`test`.`t1`.`a` between 'a' and 'a ') explain select * from t1 where a = 'a' or a='a '; @@ -1302,7 +1302,7 @@ INSERT INTO t1 VALUES This must use range access: explain select * from t1 where dateval >= '2007-01-01 00:00:00' and dateval <= '2007-01-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range dateval dateval 4 NULL 2 100.00 Using where; Using index +1 SIMPLE t1 NULL range dateval dateval 4 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`dateval` AS `dateval` from `test`.`t1` where ((`test`.`t1`.`dateval` >= DATE'2007-01-01') and (`test`.`t1`.`dateval` <= DATE'2007-01-02')) drop table t1; @@ -1979,7 +1979,7 @@ pk i4 EXPLAIN SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i4_uq i4_uq 5 NULL 2 100.00 Using where; Using index +1 SIMPLE t1 NULL range i4_uq i4_uq 5 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i4` AS `i4` from `test`.`t1` where (`test`.`t1`.`i4` between 10 and '20') SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20'; diff --git a/mysql-test/r/range_none.result b/mysql-test/r/range_none.result index 8a7e227d4ba..b6da33a268f 100644 --- a/mysql-test/r/range_none.result +++ b/mysql-test/r/range_none.result @@ -34,7 +34,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`event_date` AS `event_date`,`test`.`t1`.`type` AS `type`,`test`.`t1`.`event_id` AS `event_id` from `test`.`t1` where ((`test`.`t1`.`event_date` >= DATE'1999-07-01') and (`test`.`t1`.`event_date` < DATE'1999-07-15') and ((`test`.`t1`.`type` = 100600) or (`test`.`t1`.`type` = 100100))) order by `test`.`t1`.`event_date` explain format=tree select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date; EXPLAIN --> Filter: ((t1.event_date >= DATE'1999-07-01') and (t1.event_date < DATE'1999-07-15') and ((t1.`type` = 100600) or (t1.`type` = 100100))) (cost=1.46 rows=1) +-> Filter: ((t1.`type` = 100600) or (t1.`type` = 100100)) (cost=1.46 rows=1) -> Covering index range scan on t1 using PRIMARY over ('1999-07-01' <= event_date <= '1999-07-15' AND 100100 <= type) (cost=1.46 rows=6) select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date; @@ -251,37 +251,37 @@ test.t1 analyze status OK explain select * from t1, t1 t2 where t1.y = 8 and t2.x between 7 and t1.y+0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using where; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using join buffer (hash join) Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 8) and (`test`.`t2`.`x` between 7 and ((8 + 0)))) +Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 8) and (`test`.`t2`.`x` between 7 and (8 + 0))) explain select * from t1, t1 t2 where t1.y = 8 and t2.x >= 7 and t2.x <= t1.y+0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using where; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using join buffer (hash join) Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 8) and (`test`.`t2`.`x` >= 7) and (`test`.`t2`.`x` <= ((8 + 0)))) +Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 8) and (`test`.`t2`.`x` >= 7) and (`test`.`t2`.`x` <= (8 + 0))) explain select * from t1, t1 t2 where t1.y = 2 and t2.x between t1.y-1 and t1.y+1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 3 100.00 Using where; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 3 100.00 Using join buffer (hash join) Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` between ((2 - 1)) and ((2 + 1)))) +Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` between (2 - 1) and (2 + 1))) explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= t1.y-1 and t2.x <= t1.y+1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 3 100.00 Using where; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 3 100.00 Using join buffer (hash join) Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` >= ((2 - 1))) and (`test`.`t2`.`x` <= ((2 + 1)))) +Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` >= (2 - 1)) and (`test`.`t2`.`x` <= (2 + 1))) explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 0 and t1.y; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using where; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` between 0 and 2)) explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 0 and t2.x <= t1.y; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ref y y 5 const 1 100.00 NULL -1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using where; Using join buffer (hash join) +1 SIMPLE t2 NULL range x x 5 NULL 2 100.00 Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t2`.`x` AS `x`,`test`.`t2`.`y` AS `y` from `test`.`t1` join `test`.`t1` `t2` where ((`test`.`t1`.`y` = 2) and (`test`.`t2`.`x` >= 0) and (`test`.`t2`.`x` <= 2)) explain select count(*) from t1 where x in (1); @@ -491,11 +491,11 @@ test.t1 analyze status OK test.t2 analyze status OK explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE # NULL range uid_index uid_index 4 # 28 100.00 Using where +1 SIMPLE # NULL range uid_index uid_index 4 # 28 100.00 NULL 1 SIMPLE # NULL ref uid_index uid_index 4 # 28 100.00 NULL explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE # NULL range uid_index uid_index 4 # 28 100.00 Using where +1 SIMPLE # NULL range uid_index uid_index 4 # 28 100.00 NULL 1 SIMPLE # NULL ref uid_index uid_index 4 # 28 100.00 NULL explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra @@ -1067,7 +1067,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = 3) and (`test`.`t1`.`a` < 2)) EXPLAIN SELECT a,b FROM t1 WHERE a < 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a` < 2) EXPLAIN SELECT a,b FROM v1 WHERE a < 2; @@ -1146,7 +1146,7 @@ create table t2 (a varchar(10), filler char(200), key(a)) charset utf8mb4; insert into t2 select * from t1; explain select * from t1 where a between 'a' and 'a '; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range a a 13 NULL # 100.00 Using where +1 SIMPLE t1 NULL range a a 13 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`filler` AS `filler` from `test`.`t1` where (`test`.`t1`.`a` between 'a' and 'a ') explain select * from t1 where a = 'a' or a='a '; @@ -1301,7 +1301,7 @@ INSERT INTO t1 VALUES This must use range access: explain select * from t1 where dateval >= '2007-01-01 00:00:00' and dateval <= '2007-01-02 23:59:59'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range dateval dateval 4 NULL 2 100.00 Using where; Using index +1 SIMPLE t1 NULL range dateval dateval 4 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`dateval` AS `dateval` from `test`.`t1` where ((`test`.`t1`.`dateval` >= DATE'2007-01-01') and (`test`.`t1`.`dateval` <= DATE'2007-01-02')) drop table t1; @@ -1978,7 +1978,7 @@ pk i4 EXPLAIN SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i4_uq i4_uq 5 NULL 2 100.00 Using where; Using index +1 SIMPLE t1 NULL range i4_uq i4_uq 5 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i4` AS `i4` from `test`.`t1` where (`test`.`t1`.`i4` between 10 and '20') SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20'; diff --git a/mysql-test/r/select_all.result b/mysql-test/r/select_all.result index bed9cf48503..a4db239d064 100644 --- a/mysql-test/r/select_all.result +++ b/mysql-test/r/select_all.result @@ -176,7 +176,7 @@ honeysuckle honoring explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range fld3 fld3 120 NULL 2 100.00 Using where; Using index +1 SIMPLE t2 NULL range fld3 fld3 120 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`fld3` AS `fld3` from `test`.`t2` where ((`test`.`t2`.`fld3` >= 'honeysuckle') and (`test`.`t2`.`fld3` <= 'honoring')) order by `test`.`t2`.`fld3` select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3; @@ -1467,19 +1467,19 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` join `test`.`t2` where ((`test`.`t4`.`companynr` = `test`.`t2`.`companynr`) and (`test`.`t2`.`companynr` > 0) and (`test`.`t2`.`companynr` > 0)) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where ((`test`.`t4`.`companynr` > 0) and (`test`.`t4`.`companynr` > 0)) @@ -1503,7 +1503,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (ifnull(`test`.`t2`.`companynr`,1) > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) @@ -3788,7 +3788,7 @@ test.t2 analyze status OK EXPLAIN SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,b b 5 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 NULL range PRIMARY,b b 5 NULL 3 100.00 Using index 1 SIMPLE t2 NULL ref c c 5 test.t1.a 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2`.`f` AS `f` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t1`.`b` between 4 and 6)) @@ -3961,7 +3961,7 @@ WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND t3.a=t2.a AND t3.c IN ('bb','ee'); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL -1 SIMPLE t2 NULL range si si 5 NULL 4 100.00 Using index condition; Using where; Using MRR +1 SIMPLE t2 NULL range si si 5 NULL 4 100.00 Using where; Using MRR 1 SIMPLE t3 NULL eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 30.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t1` join `test`.`t2` FORCE INDEX (`si`) join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and (`test`.`t2`.`i` between '81' and '89') and (`test`.`t3`.`c` in ('bb','ee'))) @@ -3971,7 +3971,7 @@ WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND t3.a=t2.a AND t3.c IN ('bb','ee') ; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL -1 SIMPLE t2 NULL range si,ai si 5 NULL 4 100.00 Using index condition; Using where; Using MRR +1 SIMPLE t2 NULL range si,ai si 5 NULL 4 100.00 Using where; Using MRR 1 SIMPLE t3 NULL eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 30.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t1` join `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and (`test`.`t2`.`i` between '81' and '89') and (`test`.`t3`.`c` in ('bb','ee'))) @@ -5460,7 +5460,7 @@ INSERT INTO `cc` VALUES EXPLAIN SELECT `varchar_nokey` g1 FROM cc WHERE `int_nokey` AND `int_key` <= 4 HAVING g1 ORDER BY `varchar_key` LIMIT 6 ; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE cc NULL range int_key int_key 4 NULL 9 90.00 Using index condition; Using where; Using MRR; Using filesort +1 SIMPLE cc NULL range int_key int_key 4 NULL 9 90.00 Using where; Using MRR; Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`cc`.`varchar_nokey` AS `g1` from `test`.`cc` where ((0 <> `test`.`cc`.`int_nokey`) and (`test`.`cc`.`int_key` <= 4)) having (0 <> `g1`) order by `test`.`cc`.`varchar_key` limit 6 SELECT `varchar_nokey` g1 FROM cc WHERE `int_nokey` AND `int_key` <= 4 diff --git a/mysql-test/r/select_all_bka.result b/mysql-test/r/select_all_bka.result index 1b6230e43dc..6c4e0b57ffd 100644 --- a/mysql-test/r/select_all_bka.result +++ b/mysql-test/r/select_all_bka.result @@ -177,7 +177,7 @@ honeysuckle honoring explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range fld3 fld3 120 NULL 2 100.00 Using where; Using index +1 SIMPLE t2 NULL range fld3 fld3 120 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`fld3` AS `fld3` from `test`.`t2` where ((`test`.`t2`.`fld3` >= 'honeysuckle') and (`test`.`t2`.`fld3` <= 'honoring')) order by `test`.`t2`.`fld3` select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3; @@ -1468,19 +1468,19 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` join `test`.`t2` where ((`test`.`t4`.`companynr` = `test`.`t2`.`companynr`) and (`test`.`t2`.`companynr` > 0) and (`test`.`t2`.`companynr` > 0)) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where ((`test`.`t4`.`companynr` > 0) and (`test`.`t4`.`companynr` > 0)) @@ -1504,7 +1504,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (ifnull(`test`.`t2`.`companynr`,1) > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) @@ -3789,7 +3789,7 @@ test.t2 analyze status OK EXPLAIN SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,b b 5 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 NULL range PRIMARY,b b 5 NULL 3 100.00 Using index 1 SIMPLE t2 NULL ref c c 5 test.t1.a 1 100.00 Using join buffer (Batched Key Access) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2`.`f` AS `f` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t1`.`b` between 4 and 6)) @@ -3962,7 +3962,7 @@ WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND t3.a=t2.a AND t3.c IN ('bb','ee'); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL -1 SIMPLE t2 NULL range si si 5 NULL 4 100.00 Using index condition; Using where; Using MRR +1 SIMPLE t2 NULL range si si 5 NULL 4 100.00 Using where; Using MRR 1 SIMPLE t3 NULL eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 30.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t1` join `test`.`t2` FORCE INDEX (`si`) join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and (`test`.`t2`.`i` between '81' and '89') and (`test`.`t3`.`c` in ('bb','ee'))) @@ -3972,7 +3972,7 @@ WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND t3.a=t2.a AND t3.c IN ('bb','ee') ; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL -1 SIMPLE t2 NULL range si,ai si 5 NULL 4 100.00 Using index condition; Using where; Using MRR +1 SIMPLE t2 NULL range si,ai si 5 NULL 4 100.00 Using where; Using MRR 1 SIMPLE t3 NULL eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 30.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t1` join `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and (`test`.`t2`.`i` between '81' and '89') and (`test`.`t3`.`c` in ('bb','ee'))) @@ -5461,7 +5461,7 @@ INSERT INTO `cc` VALUES EXPLAIN SELECT `varchar_nokey` g1 FROM cc WHERE `int_nokey` AND `int_key` <= 4 HAVING g1 ORDER BY `varchar_key` LIMIT 6 ; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE cc NULL range int_key int_key 4 NULL 9 90.00 Using index condition; Using where; Using MRR; Using filesort +1 SIMPLE cc NULL range int_key int_key 4 NULL 9 90.00 Using where; Using MRR; Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`cc`.`varchar_nokey` AS `g1` from `test`.`cc` where ((0 <> `test`.`cc`.`int_nokey`) and (`test`.`cc`.`int_key` <= 4)) having (0 <> `g1`) order by `test`.`cc`.`varchar_key` limit 6 SELECT `varchar_nokey` g1 FROM cc WHERE `int_nokey` AND `int_key` <= 4 diff --git a/mysql-test/r/select_all_bka_nobnl.result b/mysql-test/r/select_all_bka_nobnl.result index d163b24e229..12ca2278e55 100644 --- a/mysql-test/r/select_all_bka_nobnl.result +++ b/mysql-test/r/select_all_bka_nobnl.result @@ -177,7 +177,7 @@ honeysuckle honoring explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range fld3 fld3 120 NULL 2 100.00 Using where; Using index +1 SIMPLE t2 NULL range fld3 fld3 120 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`fld3` AS `fld3` from `test`.`t2` where ((`test`.`t2`.`fld3` >= 'honeysuckle') and (`test`.`t2`.`fld3` <= 'honoring')) order by `test`.`t2`.`fld3` select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3; @@ -1468,19 +1468,19 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` join `test`.`t2` where ((`test`.`t4`.`companynr` = `test`.`t2`.`companynr`) and (`test`.`t2`.`companynr` > 0) and (`test`.`t2`.`companynr` > 0)) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where ((`test`.`t4`.`companynr` > 0) and (`test`.`t4`.`companynr` > 0)) @@ -1504,7 +1504,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (ifnull(`test`.`t2`.`companynr`,1) > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) @@ -3789,7 +3789,7 @@ test.t2 analyze status OK EXPLAIN SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,b b 5 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 NULL range PRIMARY,b b 5 NULL 3 100.00 Using index 1 SIMPLE t2 NULL ref c c 5 test.t1.a 1 100.00 Using join buffer (Batched Key Access) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2`.`f` AS `f` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t1`.`b` between 4 and 6)) @@ -3962,7 +3962,7 @@ WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND t3.a=t2.a AND t3.c IN ('bb','ee'); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL -1 SIMPLE t2 NULL range si si 5 NULL 4 100.00 Using index condition; Using where; Using MRR +1 SIMPLE t2 NULL range si si 5 NULL 4 100.00 Using where; Using MRR 1 SIMPLE t3 NULL eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 30.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t1` join `test`.`t2` FORCE INDEX (`si`) join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and (`test`.`t2`.`i` between '81' and '89') and (`test`.`t3`.`c` in ('bb','ee'))) @@ -3972,7 +3972,7 @@ WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND t3.a=t2.a AND t3.c IN ('bb','ee') ; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL -1 SIMPLE t2 NULL range si,ai si 5 NULL 4 100.00 Using index condition; Using where; Using MRR +1 SIMPLE t2 NULL range si,ai si 5 NULL 4 100.00 Using where; Using MRR 1 SIMPLE t3 NULL eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 30.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t1` join `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and (`test`.`t2`.`i` between '81' and '89') and (`test`.`t3`.`c` in ('bb','ee'))) @@ -5461,7 +5461,7 @@ INSERT INTO `cc` VALUES EXPLAIN SELECT `varchar_nokey` g1 FROM cc WHERE `int_nokey` AND `int_key` <= 4 HAVING g1 ORDER BY `varchar_key` LIMIT 6 ; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE cc NULL range int_key int_key 4 NULL 9 90.00 Using index condition; Using where; Using MRR; Using filesort +1 SIMPLE cc NULL range int_key int_key 4 NULL 9 90.00 Using where; Using MRR; Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`cc`.`varchar_nokey` AS `g1` from `test`.`cc` where ((0 <> `test`.`cc`.`int_nokey`) and (`test`.`cc`.`int_key` <= 4)) having (0 <> `g1`) order by `test`.`cc`.`varchar_key` limit 6 SELECT `varchar_nokey` g1 FROM cc WHERE `int_nokey` AND `int_key` <= 4 diff --git a/mysql-test/r/select_icp_mrr.result b/mysql-test/r/select_icp_mrr.result index deed579c35e..a391d4a5640 100644 --- a/mysql-test/r/select_icp_mrr.result +++ b/mysql-test/r/select_icp_mrr.result @@ -1,4 +1,5 @@ set optimizer_switch='index_condition_pushdown=on,mrr=on,mrr_cost_based=off'; +set empty_redundant_check_in_range_scan=false; drop table if exists t1,t2,t3,t4,t11; drop table if exists t1_1,t1_2,t9_1,t9_2,t1aa,t2aa; drop view if exists v1; @@ -5595,4 +5596,5 @@ FROM t1 AS alias1 LEFT JOIN t1 AS alias2 ON alias1.f1 = alias2.f2 WHERE alias2.f1 NOT BETWEEN 4 AND 12; f1 f2 f1 f2 DROP TABLE t1; +set empty_redundant_check_in_range_scan=true; set optimizer_switch=default; diff --git a/mysql-test/r/select_icp_mrr_bka.result b/mysql-test/r/select_icp_mrr_bka.result index 208c0b0a960..f1fe137a8d2 100644 --- a/mysql-test/r/select_icp_mrr_bka.result +++ b/mysql-test/r/select_icp_mrr_bka.result @@ -1,5 +1,6 @@ set optimizer_switch='batched_key_access=on,mrr_cost_based=off'; set optimizer_switch='index_condition_pushdown=on,mrr=on,mrr_cost_based=off'; +set empty_redundant_check_in_range_scan=false; drop table if exists t1,t2,t3,t4,t11; drop table if exists t1_1,t1_2,t9_1,t9_2,t1aa,t2aa; drop view if exists v1; @@ -5597,5 +5598,6 @@ FROM t1 AS alias1 LEFT JOIN t1 AS alias2 ON alias1.f1 = alias2.f2 WHERE alias2.f1 NOT BETWEEN 4 AND 12; f1 f2 f1 f2 DROP TABLE t1; +set empty_redundant_check_in_range_scan=true; set optimizer_switch=default; set optimizer_switch=default; diff --git a/mysql-test/r/select_icp_mrr_bka_nobnl.result b/mysql-test/r/select_icp_mrr_bka_nobnl.result index 58640334e0a..41323ada6af 100644 --- a/mysql-test/r/select_icp_mrr_bka_nobnl.result +++ b/mysql-test/r/select_icp_mrr_bka_nobnl.result @@ -1,5 +1,6 @@ set optimizer_switch='batched_key_access=on,block_nested_loop=off,mrr_cost_based=off'; set optimizer_switch='index_condition_pushdown=on,mrr=on,mrr_cost_based=off'; +set empty_redundant_check_in_range_scan=false; drop table if exists t1,t2,t3,t4,t11; drop table if exists t1_1,t1_2,t9_1,t9_2,t1aa,t2aa; drop view if exists v1; @@ -5597,5 +5598,6 @@ FROM t1 AS alias1 LEFT JOIN t1 AS alias2 ON alias1.f1 = alias2.f2 WHERE alias2.f1 NOT BETWEEN 4 AND 12; f1 f2 f1 f2 DROP TABLE t1; +set empty_redundant_check_in_range_scan=true; set optimizer_switch=default; set optimizer_switch=default; diff --git a/mysql-test/r/select_none.result b/mysql-test/r/select_none.result index faa18d7d911..a9815d4f171 100644 --- a/mysql-test/r/select_none.result +++ b/mysql-test/r/select_none.result @@ -175,7 +175,7 @@ honeysuckle honoring explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range fld3 fld3 120 NULL 2 100.00 Using where; Using index +1 SIMPLE t2 NULL range fld3 fld3 120 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`fld3` AS `fld3` from `test`.`t2` where ((`test`.`t2`.`fld3` >= 'honeysuckle') and (`test`.`t2`.`fld3` <= 'honoring')) order by `test`.`t2`.`fld3` select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3; @@ -1466,19 +1466,19 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` join `test`.`t2` where ((`test`.`t4`.`companynr` = `test`.`t2`.`companynr`) and (`test`.`t2`.`companynr` > 0) and (`test`.`t2`.`companynr` > 0)) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where ((`test`.`t4`.`companynr` > 0) and (`test`.`t4`.`companynr` > 0)) @@ -1502,7 +1502,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (ifnull(`test`.`t2`.`companynr`,1) > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) @@ -3787,7 +3787,7 @@ test.t2 analyze status OK EXPLAIN SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,b b 5 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 NULL range PRIMARY,b b 5 NULL 3 100.00 Using index 1 SIMPLE t2 NULL ref c c 5 test.t1.a 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2`.`f` AS `f` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t1`.`b` between 4 and 6)) diff --git a/mysql-test/r/select_none_bka.result b/mysql-test/r/select_none_bka.result index 19f82745c1d..c6ae1bb38fc 100644 --- a/mysql-test/r/select_none_bka.result +++ b/mysql-test/r/select_none_bka.result @@ -176,7 +176,7 @@ honeysuckle honoring explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range fld3 fld3 120 NULL 2 100.00 Using where; Using index +1 SIMPLE t2 NULL range fld3 fld3 120 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`fld3` AS `fld3` from `test`.`t2` where ((`test`.`t2`.`fld3` >= 'honeysuckle') and (`test`.`t2`.`fld3` <= 'honoring')) order by `test`.`t2`.`fld3` select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3; @@ -1467,19 +1467,19 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` join `test`.`t2` where ((`test`.`t4`.`companynr` = `test`.`t2`.`companynr`) and (`test`.`t2`.`companynr` > 0) and (`test`.`t2`.`companynr` > 0)) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where ((`test`.`t4`.`companynr` > 0) and (`test`.`t4`.`companynr` > 0)) @@ -1503,7 +1503,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (ifnull(`test`.`t2`.`companynr`,1) > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) @@ -3788,7 +3788,7 @@ test.t2 analyze status OK EXPLAIN SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,b b 5 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 NULL range PRIMARY,b b 5 NULL 3 100.00 Using index 1 SIMPLE t2 NULL ref c c 5 test.t1.a 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2`.`f` AS `f` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t1`.`b` between 4 and 6)) diff --git a/mysql-test/r/select_none_bka_nobnl.result b/mysql-test/r/select_none_bka_nobnl.result index d27e1cc811d..019413bca2e 100644 --- a/mysql-test/r/select_none_bka_nobnl.result +++ b/mysql-test/r/select_none_bka_nobnl.result @@ -176,7 +176,7 @@ honeysuckle honoring explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range fld3 fld3 120 NULL 2 100.00 Using where; Using index +1 SIMPLE t2 NULL range fld3 fld3 120 NULL 2 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`fld3` AS `fld3` from `test`.`t2` where ((`test`.`t2`.`fld3` >= 'honeysuckle') and (`test`.`t2`.`fld3` <= 'honoring')) order by `test`.`t2`.`fld3` select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3; @@ -1467,19 +1467,19 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` join `test`.`t2` where ((`test`.`t4`.`companynr` = `test`.`t2`.`companynr`) and (`test`.`t2`.`companynr` > 0) and (`test`.`t2`.`companynr` > 0)) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where ((`test`.`t4`.`companynr` > 0) and (`test`.`t4`.`companynr` > 0)) @@ -1503,7 +1503,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (ifnull(`test`.`t2`.`companynr`,1) > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL 11 100.00 NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1199 100.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) @@ -3788,7 +3788,7 @@ test.t2 analyze status OK EXPLAIN SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,b b 5 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 NULL range PRIMARY,b b 5 NULL 3 100.00 Using index 1 SIMPLE t2 NULL ref c c 5 test.t1.a 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2`.`f` AS `f` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t1`.`b` between 4 and 6)) diff --git a/mysql-test/r/skip_records_in_range.result b/mysql-test/r/skip_records_in_range.result index e9a622f52f3..5dec4218bab 100644 --- a/mysql-test/r/skip_records_in_range.result +++ b/mysql-test/r/skip_records_in_range.result @@ -38,7 +38,7 @@ SELECT @trace RLIKE "skipped_due_to_force_index"; SET optimizer_trace="enabled=off"; EXPLAIN FORMAT=TRADITIONAL FOR QUERY 'SELECT a1 FROM t1 WHERE a1 > 'b'' id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range t1_a1_idx,t1_a1_a2_idx t1_a1_idx 257 NULL 2 100.00 Using where; Using index +1 SIMPLE t1 NULL range t1_a1_idx,t1_a1_a2_idx t1_a1_idx 257 NULL 2 100.00 Using index EXPLAIN FORMAT=JSON FOR QUERY 'SELECT a1 FROM t1 WHERE a1 > 'b'' EXPLAIN { @@ -62,7 +62,6 @@ EXPLAIN "rows_examined_per_scan": 2, "rows_produced_per_join": 2, "filtered": "100.00", - "using_where": true, "using_index": true, "cost_info": { "read_cost": "0.47", @@ -88,7 +87,7 @@ SELECT @trace RLIKE "skipped_due_to_force_index"; SET optimizer_trace="enabled=off"; EXPLAIN FORMAT=TRADITIONAL FOR QUERY 'SELECT a1 FROM t1 FORCE INDEX(t1_a1_a2_idx) WHERE a1 > 'b'' id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range t1_a1_a2_idx t1_a1_a2_idx 257 NULL NULL NULL Using where; Using index +1 SIMPLE t1 NULL range t1_a1_a2_idx t1_a1_a2_idx 257 NULL NULL NULL Using index EXPLAIN FORMAT=JSON FOR QUERY 'SELECT a1 FROM t1 FORCE INDEX(t1_a1_a2_idx) WHERE a1 > 'b'' EXPLAIN { @@ -108,7 +107,6 @@ EXPLAIN "a1" ], "key_length": "257", - "using_where": true, "skip_records_in_range_due_to_force": true, "using_index": true, "cost_info": { @@ -343,7 +341,7 @@ SELECT @trace RLIKE "skipped_due_to_force_index"; SET optimizer_trace="enabled=off"; EXPLAIN FORMAT=TRADITIONAL FOR QUERY 'SELECT a1 FROM t1 FORCE INDEX(t1_a1_a2_idx) WHERE a1 >= 'a'' id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range t1_a1_a2_idx t1_a1_a2_idx 257 NULL NULL NULL Using where; Using index +1 SIMPLE t1 NULL range t1_a1_a2_idx t1_a1_a2_idx 257 NULL NULL NULL Using index EXPLAIN FORMAT=JSON FOR QUERY 'SELECT a1 FROM t1 FORCE INDEX(t1_a1_a2_idx) WHERE a1 >= 'a'' EXPLAIN { @@ -363,7 +361,6 @@ EXPLAIN "a1" ], "key_length": "257", - "using_where": true, "skip_records_in_range_due_to_force": true, "using_index": true, "cost_info": { @@ -437,7 +434,7 @@ EXPLAIN FORMAT=TRADITIONAL FOR QUERY 'SELECT t2.a1, t2.a2 FROM t1 FORCE INDEX(t1_a1_a2_idx) JOIN t2 ON (t1.pk_col1 = t2.pk_col2) WHERE t1.a1 > 'a'' id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range t1_a1_a2_idx t1_a1_a2_idx 257 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 NULL range t1_a1_a2_idx t1_a1_a2_idx 257 NULL 3 100.00 Using index 1 SIMPLE t2 NULL index NULL t2_a1_a2_idx 514 NULL 6 100.00 Using where; Using index; Using join buffer (hash join) EXPLAIN FORMAT=JSON FOR QUERY 'SELECT t2.a1, t2.a2 FROM t1 FORCE INDEX(t1_a1_a2_idx) JOIN t2 ON (t1.pk_col1 = t2.pk_col2) @@ -465,7 +462,6 @@ EXPLAIN "rows_examined_per_scan": 3, "rows_produced_per_join": 3, "filtered": "100.00", - "using_where": true, "using_index": true, "cost_info": { "read_cost": "0.59", diff --git a/mysql-test/r/skip_scan_myisam.result b/mysql-test/r/skip_scan_myisam.result index c109477f1b1..637ba9e82f5 100644 --- a/mysql-test/r/skip_scan_myisam.result +++ b/mysql-test/r/skip_scan_myisam.result @@ -426,7 +426,7 @@ include/diff_tables.inc [test.hint_skip_scan, test.no_skip_scan] set optimizer_switch = 'skip_scan=on'; EXPLAIN SELECT a, b, c, d FROM t WHERE a = 5 AND b = 2 AND d >= 98; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t NULL range PRIMARY,b b 8 NULL 1 10.00 Using index condition; Using where +1 SIMPLE t NULL range PRIMARY,b b 8 NULL 1 10.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t`.`a` AS `a`,`test`.`t`.`b` AS `b`,`test`.`t`.`c` AS `c`,`test`.`t`.`d` AS `d` from `test`.`t` where ((`test`.`t`.`b` = 2) and (`test`.`t`.`a` = 5) and (`test`.`t`.`d` >= 98)) FLUSH STATUS; @@ -443,7 +443,7 @@ Handler_read_rnd_next 0 set optimizer_switch = 'skip_scan=off'; EXPLAIN SELECT a, b, c, d FROM t WHERE a = 5 AND b = 2 AND d >= 98; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t NULL range PRIMARY,b b 8 NULL 1 10.00 Using index condition; Using where +1 SIMPLE t NULL range PRIMARY,b b 8 NULL 1 10.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t`.`a` AS `a`,`test`.`t`.`b` AS `b`,`test`.`t`.`c` AS `c`,`test`.`t`.`d` AS `d` from `test`.`t` where ((`test`.`t`.`b` = 2) and (`test`.`t`.`a` = 5) and (`test`.`t`.`d` >= 98)) FLUSH STATUS; diff --git a/mysql-test/r/ssl.result b/mysql-test/r/ssl.result index 59055eaa88d..7ded6f67d6e 100644 --- a/mysql-test/r/ssl.result +++ b/mysql-test/r/ssl.result @@ -179,7 +179,7 @@ honeysuckle honoring explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range fld3 fld3 120 NULL # # Using where; Using index +1 SIMPLE t2 NULL range fld3 fld3 120 NULL # # Using index Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`fld3` AS `fld3` from `test`.`t2` where ((`test`.`t2`.`fld3` >= 'honeysuckle') and (`test`.`t2`.`fld3` <= 'honoring')) order by `test`.`t2`.`fld3` select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3; @@ -1460,19 +1460,19 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` join `test`.`t2` where ((`test`.`t4`.`companynr` = `test`.`t2`.`companynr`) and (`test`.`t2`.`companynr` > 0) and (`test`.`t2`.`companynr` > 0)) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL # # Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL # # Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL # # Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where ((`test`.`t4`.`companynr` > 0) and (`test`.`t4`.`companynr` > 0)) @@ -1496,7 +1496,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (ifnull(`test`.`t2`.`companynr`,1) > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL # # Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) diff --git a/mysql-test/r/ssl_compress.result b/mysql-test/r/ssl_compress.result index 16e3c9ba1c4..4a1476c41bc 100644 --- a/mysql-test/r/ssl_compress.result +++ b/mysql-test/r/ssl_compress.result @@ -176,7 +176,7 @@ honeysuckle honoring explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range fld3 fld3 120 NULL # # Using where; Using index +1 SIMPLE t2 NULL range fld3 fld3 120 NULL # # Using index Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`fld3` AS `fld3` from `test`.`t2` where ((`test`.`t2`.`fld3` >= 'honeysuckle') and (`test`.`t2`.`fld3` <= 'honoring')) order by `test`.`t2`.`fld3` select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3; @@ -1457,19 +1457,19 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` join `test`.`t2` where ((`test`.`t4`.`companynr` = `test`.`t2`.`companynr`) and (`test`.`t2`.`companynr` > 0) and (`test`.`t2`.`companynr` > 0)) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL # # Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL # # Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL # # Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where ((`test`.`t4`.`companynr` > 0) and (`test`.`t4`.`companynr` > 0)) @@ -1493,7 +1493,7 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (ifnull(`test`.`t2`.`companynr`,1) > 0) explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # Using where +1 SIMPLE t4 NULL range PRIMARY PRIMARY 1 NULL # # NULL 1 SIMPLE t2 NULL ALL NULL NULL NULL NULL # # Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t4`.`companynr` AS `companynr`,`test`.`t4`.`companyname` AS `companyname` from `test`.`t4` left join `test`.`t2` on((`test`.`t2`.`companynr` = `test`.`t4`.`companynr`)) where (`test`.`t4`.`companynr` > 0) diff --git a/mysql-test/r/subquery_all.result b/mysql-test/r/subquery_all.result index d894c76539f..108f6fb5c2c 100644 --- a/mysql-test/r/subquery_all.result +++ b/mysql-test/r/subquery_all.result @@ -1487,7 +1487,7 @@ Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,(`test`.` explain select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL index NULL s1 6 NULL 4 100.00 Using index -2 SUBQUERY t2 NULL range s1 s1 6 NULL 4 100.00 Using where; Using index +2 SUBQUERY t2 NULL range s1 s1 6 NULL 4 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,(`test`.`t1`.`s1`,`test`.`t1`.`s1` not in ( (/* select#2 */ select `test`.`t2`.`s1` from `test`.`t2` where (`test`.`t2`.`s1` < 'a2') having true ), (`test`.`t1`.`s1` in on where ((`test`.`t1`.`s1` = ``.`s1`))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1` drop table t1,t2; @@ -7970,7 +7970,7 @@ FROM t1 LIMIT 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL -2 DEPENDENT SUBQUERY t2 NULL ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 100.00 Using index +2 DEPENDENT SUBQUERY t2 NULL ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 100.00 Using offset pushdown; Using index Warnings: Note 1276 Field or reference 'test.t1.id' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select (/* select#2 */ select `test`.`t2`.`position` from `test`.`t2` where (`test`.`t2`.`t1_id` = `test`.`t1`.`id`) order by `test`.`t2`.`t1_id`,`test`.`t2`.`position` limit 10,1) AS `maxkey` from `test`.`t1` limit 1 diff --git a/mysql-test/r/subquery_all_bka.result b/mysql-test/r/subquery_all_bka.result index 91d86a0a40b..44a1a61092a 100644 --- a/mysql-test/r/subquery_all_bka.result +++ b/mysql-test/r/subquery_all_bka.result @@ -1488,7 +1488,7 @@ Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,(`test`.` explain select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL index NULL s1 6 NULL 4 100.00 Using index -2 SUBQUERY t2 NULL range s1 s1 6 NULL 4 100.00 Using where; Using index +2 SUBQUERY t2 NULL range s1 s1 6 NULL 4 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,(`test`.`t1`.`s1`,`test`.`t1`.`s1` not in ( (/* select#2 */ select `test`.`t2`.`s1` from `test`.`t2` where (`test`.`t2`.`s1` < 'a2') having true ), (`test`.`t1`.`s1` in on where ((`test`.`t1`.`s1` = ``.`s1`))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1` drop table t1,t2; @@ -7971,7 +7971,7 @@ FROM t1 LIMIT 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL -2 DEPENDENT SUBQUERY t2 NULL ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 100.00 Using index +2 DEPENDENT SUBQUERY t2 NULL ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 100.00 Using offset pushdown; Using index Warnings: Note 1276 Field or reference 'test.t1.id' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select (/* select#2 */ select `test`.`t2`.`position` from `test`.`t2` where (`test`.`t2`.`t1_id` = `test`.`t1`.`id`) order by `test`.`t2`.`t1_id`,`test`.`t2`.`position` limit 10,1) AS `maxkey` from `test`.`t1` limit 1 diff --git a/mysql-test/r/subquery_all_bka_nobnl.result b/mysql-test/r/subquery_all_bka_nobnl.result index 877935c5a77..991407828a9 100644 --- a/mysql-test/r/subquery_all_bka_nobnl.result +++ b/mysql-test/r/subquery_all_bka_nobnl.result @@ -1488,7 +1488,7 @@ Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,(`test`.` explain select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL index NULL s1 6 NULL 4 100.00 Using index -2 SUBQUERY t2 NULL range s1 s1 6 NULL 4 100.00 Using where; Using index +2 SUBQUERY t2 NULL range s1 s1 6 NULL 4 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,(`test`.`t1`.`s1`,`test`.`t1`.`s1` not in ( (/* select#2 */ select `test`.`t2`.`s1` from `test`.`t2` where (`test`.`t2`.`s1` < 'a2') having true ), (`test`.`t1`.`s1` in on where ((`test`.`t1`.`s1` = ``.`s1`))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1` drop table t1,t2; @@ -7971,7 +7971,7 @@ FROM t1 LIMIT 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL -2 DEPENDENT SUBQUERY t2 NULL ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 100.00 Using index +2 DEPENDENT SUBQUERY t2 NULL ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 100.00 Using offset pushdown; Using index Warnings: Note 1276 Field or reference 'test.t1.id' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select (/* select#2 */ select `test`.`t2`.`position` from `test`.`t2` where (`test`.`t2`.`t1_id` = `test`.`t1`.`id`) order by `test`.`t2`.`t1_id`,`test`.`t2`.`position` limit 10,1) AS `maxkey` from `test`.`t1` limit 1 diff --git a/mysql-test/r/subquery_antijoin.result b/mysql-test/r/subquery_antijoin.result index a241e7a3214..bfb502887c6 100644 --- a/mysql-test/r/subquery_antijoin.result +++ b/mysql-test/r/subquery_antijoin.result @@ -27,7 +27,7 @@ test.t2 analyze status OK set optimizer_switch="firstmatch=on,materialization=off"; select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=off,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=off,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on EXPLAIN SELECT 1 as a FROM dual WHERE NOT EXISTS (SELECT * FROM t1 AS it); id select_type table partitions type possible_keys key key_len ref rows filtered Extra @@ -52,7 +52,7 @@ EXPLAIN SELECT pk FROM t2 as ot WHERE NOT EXISTS (SELECT * FROM t1 AS it WHERE it.uk=ot.pk) AND ot.pk<25; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE ot NULL range PRIMARY PRIMARY 4 NULL 24 100.00 Using where; Using index +1 SIMPLE ot NULL range PRIMARY PRIMARY 4 NULL 24 100.00 Using index 1 SIMPLE it NULL eq_ref uk uk 5 test.ot.pk 1 100.00 Using where; Not exists; Using index Warnings: Note 1276 Field or reference 'test.ot.pk' of SELECT #2 was resolved in SELECT #1 @@ -92,8 +92,7 @@ EXPLAIN }, "used_columns": [ "pk" - ], - "attached_condition": "(`test`.`ot`.`pk` < 25)" + ] } }, { @@ -163,7 +162,7 @@ pk set optimizer_switch="firstmatch=off,materialization=on"; select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=off,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=off,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on EXPLAIN SELECT 1 as a FROM dual WHERE NOT EXISTS (SELECT * FROM t1 AS it); id select_type table partitions type possible_keys key key_len ref rows filtered Extra @@ -188,7 +187,7 @@ EXPLAIN SELECT pk FROM t2 as ot WHERE NOT EXISTS (SELECT * FROM t1 AS it WHERE it.uk=ot.pk) AND ot.pk<25; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE ot NULL range PRIMARY PRIMARY 4 NULL 24 100.00 Using where; Using index +1 SIMPLE ot NULL range PRIMARY PRIMARY 4 NULL 24 100.00 Using index 1 SIMPLE NULL eq_ref 5 test.ot.pk 1 100.00 Using where; Not exists 2 MATERIALIZED it NULL index uk uk 5 NULL 3 100.00 Using index Warnings: @@ -229,8 +228,7 @@ EXPLAIN }, "used_columns": [ "pk" - ], - "attached_condition": "(`test`.`ot`.`pk` < 25)" + ] } }, { diff --git a/mysql-test/r/subquery_bugs.result b/mysql-test/r/subquery_bugs.result index 6b959d12ce3..be2f2b57c2d 100644 --- a/mysql-test/r/subquery_bugs.result +++ b/mysql-test/r/subquery_bugs.result @@ -603,8 +603,7 @@ EXPLAIN -> Table scan on (cost=3.42..3.42 rows=1) -> Materialize with deduplication (cost=0.91..0.91 rows=1) -> Nested loop left join (cost=0.81 rows=1) - -> Filter: (t1.f1 >= 'o') (cost=0.46 rows=1) - -> Covering index range scan on t1 using k1 over ('o' <= f1) (cost=0.46 rows=1) + -> Covering index range scan on t1 using k1 over ('o' <= f1) (cost=0.46 rows=1) -> Single-row covering index lookup on t2 using PRIMARY (pk=t1.pk) (cost=0.35 rows=1) -> Single-row index lookup on t1 using PRIMARY (pk=``.pk) (cost=0.35 rows=1) @@ -645,7 +644,7 @@ WHERE EXISTS ( SELECT * FROM t1 AS t4, t2 AS t5 ) AND t1.f1 = 80 AND t1.pk > t1. EXPLAIN -> Nested loop left join (cost=0.91 rows=1) -> Nested loop semijoin (cost=0.68 rows=1) - -> Filter: ((t1.f1 = 80) and (t1.pk > 80)) (cost=0.46 rows=0.5) + -> Filter: (t1.f1 = 80) (cost=0.46 rows=0.5) -> Index range scan on t1 using PRIMARY over (80 < pk) (cost=0.46 rows=1) -> Nested loop inner join (cost=0.77 rows=2) -> Table scan on t5 (cost=0.45 rows=1) diff --git a/mysql-test/r/subquery_nomat_nosj.result b/mysql-test/r/subquery_nomat_nosj.result index 492f4b8902b..ee10ca3e984 100644 --- a/mysql-test/r/subquery_nomat_nosj.result +++ b/mysql-test/r/subquery_nomat_nosj.result @@ -7970,7 +7970,7 @@ FROM t1 LIMIT 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL -2 DEPENDENT SUBQUERY t2 NULL ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 100.00 Using index +2 DEPENDENT SUBQUERY t2 NULL ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 100.00 Using offset pushdown; Using index Warnings: Note 1276 Field or reference 'test.t1.id' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select (/* select#2 */ select `test`.`t2`.`position` from `test`.`t2` where (`test`.`t2`.`t1_id` = `test`.`t1`.`id`) order by `test`.`t2`.`t1_id`,`test`.`t2`.`position` limit 10,1) AS `maxkey` from `test`.`t1` limit 1 diff --git a/mysql-test/r/subquery_nomat_nosj_bka.result b/mysql-test/r/subquery_nomat_nosj_bka.result index 921ea07340f..3a11d210a22 100644 --- a/mysql-test/r/subquery_nomat_nosj_bka.result +++ b/mysql-test/r/subquery_nomat_nosj_bka.result @@ -7971,7 +7971,7 @@ FROM t1 LIMIT 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL -2 DEPENDENT SUBQUERY t2 NULL ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 100.00 Using index +2 DEPENDENT SUBQUERY t2 NULL ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 100.00 Using offset pushdown; Using index Warnings: Note 1276 Field or reference 'test.t1.id' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select (/* select#2 */ select `test`.`t2`.`position` from `test`.`t2` where (`test`.`t2`.`t1_id` = `test`.`t1`.`id`) order by `test`.`t2`.`t1_id`,`test`.`t2`.`position` limit 10,1) AS `maxkey` from `test`.`t1` limit 1 diff --git a/mysql-test/r/subquery_nomat_nosj_bka_nobnl.result b/mysql-test/r/subquery_nomat_nosj_bka_nobnl.result index 119d2d13167..b61e1a8cc9f 100644 --- a/mysql-test/r/subquery_nomat_nosj_bka_nobnl.result +++ b/mysql-test/r/subquery_nomat_nosj_bka_nobnl.result @@ -7971,7 +7971,7 @@ FROM t1 LIMIT 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL -2 DEPENDENT SUBQUERY t2 NULL ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 100.00 Using index +2 DEPENDENT SUBQUERY t2 NULL ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 100.00 Using offset pushdown; Using index Warnings: Note 1276 Field or reference 'test.t1.id' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select (/* select#2 */ select `test`.`t2`.`position` from `test`.`t2` where (`test`.`t2`.`t1_id` = `test`.`t1`.`id`) order by `test`.`t2`.`t1_id`,`test`.`t2`.`position` limit 10,1) AS `maxkey` from `test`.`t1` limit 1 diff --git a/mysql-test/r/subquery_none.result b/mysql-test/r/subquery_none.result index 2a614c20788..576b2353953 100644 --- a/mysql-test/r/subquery_none.result +++ b/mysql-test/r/subquery_none.result @@ -7969,7 +7969,7 @@ FROM t1 LIMIT 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL -2 DEPENDENT SUBQUERY t2 NULL ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 100.00 Using index +2 DEPENDENT SUBQUERY t2 NULL ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 100.00 Using offset pushdown; Using index Warnings: Note 1276 Field or reference 'test.t1.id' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select (/* select#2 */ select `test`.`t2`.`position` from `test`.`t2` where (`test`.`t2`.`t1_id` = `test`.`t1`.`id`) order by `test`.`t2`.`t1_id`,`test`.`t2`.`position` limit 10,1) AS `maxkey` from `test`.`t1` limit 1 diff --git a/mysql-test/r/subquery_none_bka.result b/mysql-test/r/subquery_none_bka.result index 5991baaf362..b53f6716701 100644 --- a/mysql-test/r/subquery_none_bka.result +++ b/mysql-test/r/subquery_none_bka.result @@ -7970,7 +7970,7 @@ FROM t1 LIMIT 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL -2 DEPENDENT SUBQUERY t2 NULL ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 100.00 Using index +2 DEPENDENT SUBQUERY t2 NULL ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 100.00 Using offset pushdown; Using index Warnings: Note 1276 Field or reference 'test.t1.id' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select (/* select#2 */ select `test`.`t2`.`position` from `test`.`t2` where (`test`.`t2`.`t1_id` = `test`.`t1`.`id`) order by `test`.`t2`.`t1_id`,`test`.`t2`.`position` limit 10,1) AS `maxkey` from `test`.`t1` limit 1 diff --git a/mysql-test/r/subquery_none_bka_nobnl.result b/mysql-test/r/subquery_none_bka_nobnl.result index 0391c6132db..c4596e1f92a 100644 --- a/mysql-test/r/subquery_none_bka_nobnl.result +++ b/mysql-test/r/subquery_none_bka_nobnl.result @@ -7970,7 +7970,7 @@ FROM t1 LIMIT 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL -2 DEPENDENT SUBQUERY t2 NULL ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 100.00 Using index +2 DEPENDENT SUBQUERY t2 NULL ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 100.00 Using offset pushdown; Using index Warnings: Note 1276 Field or reference 'test.t1.id' of SELECT #2 was resolved in SELECT #1 Note 1003 /* select#1 */ select (/* select#2 */ select `test`.`t2`.`position` from `test`.`t2` where (`test`.`t2`.`t1_id` = `test`.`t1`.`id`) order by `test`.`t2`.`t1_id`,`test`.`t2`.`position` limit 10,1) AS `maxkey` from `test`.`t1` limit 1 diff --git a/mysql-test/r/subquery_sj_all.result b/mysql-test/r/subquery_sj_all.result index 2997509f5c9..85906652efc 100644 --- a/mysql-test/r/subquery_sj_all.result +++ b/mysql-test/r/subquery_sj_all.result @@ -327,7 +327,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK explain select * from t1 where a in (select pk from t10 where pk<3); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 103 10.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3)) @@ -4231,7 +4231,7 @@ explain select * from t3 where a in (select kp1 from t1 where kp1<20); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 100.00 Using where 1 SIMPLE NULL eq_ref 5 test.t3.a 1 100.00 NULL -2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using where; Using index +2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` semi join (`test`.`t1`) where ((``.`kp1` = `test`.`t3`.`a`) and (`test`.`t1`.`kp1` < 20)) select * from t3 where a in (select kp1 from t1 where kp1<20); @@ -4294,7 +4294,7 @@ explain select * from t3 where a in id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 100.00 Using where 1 SIMPLE NULL eq_ref 5 test.t3.a 1 100.00 NULL -2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using index condition; Using where; Using MRR +2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using where; Using MRR 2 MATERIALIZED t4 NULL eq_ref PRIMARY PRIMARY 4 test.t1.c 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` semi join (`test`.`t1` join `test`.`t4`) where ((``.`kp1` = `test`.`t3`.`a`) and (`test`.`t4`.`pk` = `test`.`t1`.`c`) and (`test`.`t1`.`kp1` < 20)) @@ -4309,7 +4309,7 @@ EXPLAIN -> Filter: (t1.kp1 is not null) (cost=29.95 rows=40) -> Nested loop inner join (cost=29.95 rows=40) -> Filter: (t1.c is not null) (cost=15.95 rows=40) - -> Index range scan on t1 using kp1 over (NULL < kp1 < 20), with index condition: (t1.kp1 < 20) (cost=15.95 rows=40) + -> Index range scan on t1 using kp1 over (NULL < kp1 < 20) (cost=15.95 rows=40) -> Single-row covering index lookup on t4 using PRIMARY (pk=t1.c) (cost=0.25 rows=1) select * from t3 where a in @@ -7945,7 +7945,7 @@ t2.Code IN (SELECT Country FROM t3 WHERE Language='English' AND Percentage > 10 AND t2.Population > 100000); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range Population,Country Population 4 NULL 1 10 Using index condition; Using MRR; Start temporary +1 SIMPLE t1 NULL range Population,Country Population 4 NULL 1 10 Using MRR; Start temporary 1 SIMPLE t2 NULL eq_ref PRIMARY,Population PRIMARY 12 test.t1.Country 1 10 Using where 1 SIMPLE t3 NULL eq_ref PRIMARY,Percentage PRIMARY 132 test.t1.Country,const 1 10 Using where; End temporary Warnings: @@ -7983,7 +7983,6 @@ EXPLAIN "rows_examined_per_scan": 1, "rows_produced_per_join": 1, "filtered": "100.00", - "index_condition": "(`test`.`t1`.`Population` > 5000000)", "using_MRR": true, "cost_info": { "read_cost": "0.60", @@ -12473,7 +12472,6 @@ EXPLAIN "rows_examined_per_scan": 4, "rows_produced_per_join": 4, "filtered": "100.00", - "index_condition": "(`test`.`sq2_alias2`.`col_int_key` < 2)", "using_MRR": true, "cost_info": { "read_cost": "1.37", diff --git a/mysql-test/r/subquery_sj_all_bka.result b/mysql-test/r/subquery_sj_all_bka.result index c64af0558bd..f9afb4b618d 100644 --- a/mysql-test/r/subquery_sj_all_bka.result +++ b/mysql-test/r/subquery_sj_all_bka.result @@ -328,7 +328,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK explain select * from t1 where a in (select pk from t10 where pk<3); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 103 10.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3)) @@ -4232,7 +4232,7 @@ explain select * from t3 where a in (select kp1 from t1 where kp1<20); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 100.00 Using where 1 SIMPLE NULL eq_ref 5 test.t3.a 1 100.00 NULL -2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using where; Using index +2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` semi join (`test`.`t1`) where ((``.`kp1` = `test`.`t3`.`a`) and (`test`.`t1`.`kp1` < 20)) select * from t3 where a in (select kp1 from t1 where kp1<20); @@ -4295,7 +4295,7 @@ explain select * from t3 where a in id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 100.00 Using where 1 SIMPLE NULL eq_ref 5 test.t3.a 1 100.00 NULL -2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using index condition; Using where; Using MRR +2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using where; Using MRR 2 MATERIALIZED t4 NULL eq_ref PRIMARY PRIMARY 4 test.t1.c 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` semi join (`test`.`t1` join `test`.`t4`) where ((``.`kp1` = `test`.`t3`.`a`) and (`test`.`t4`.`pk` = `test`.`t1`.`c`) and (`test`.`t1`.`kp1` < 20)) @@ -4310,7 +4310,7 @@ EXPLAIN -> Filter: (t1.kp1 is not null) (cost=29.95 rows=40) -> Nested loop inner join (cost=29.95 rows=40) -> Filter: (t1.c is not null) (cost=15.95 rows=40) - -> Index range scan on t1 using kp1 over (NULL < kp1 < 20), with index condition: (t1.kp1 < 20) (cost=15.95 rows=40) + -> Index range scan on t1 using kp1 over (NULL < kp1 < 20) (cost=15.95 rows=40) -> Single-row covering index lookup on t4 using PRIMARY (pk=t1.c) (cost=0.25 rows=1) select * from t3 where a in @@ -7947,7 +7947,7 @@ t2.Code IN (SELECT Country FROM t3 WHERE Language='English' AND Percentage > 10 AND t2.Population > 100000); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range Population,Country Population 4 NULL 1 10 Using index condition; Using MRR; Start temporary +1 SIMPLE t1 NULL range Population,Country Population 4 NULL 1 10 Using MRR; Start temporary 1 SIMPLE t2 NULL eq_ref PRIMARY,Population PRIMARY 12 test.t1.Country 1 10 Using where 1 SIMPLE t3 NULL eq_ref PRIMARY,Percentage PRIMARY 132 test.t1.Country,const 1 10 Using where; End temporary Warnings: @@ -7985,7 +7985,6 @@ EXPLAIN "rows_examined_per_scan": 1, "rows_produced_per_join": 1, "filtered": "100.00", - "index_condition": "(`test`.`t1`.`Population` > 5000000)", "using_MRR": true, "cost_info": { "read_cost": "0.60", @@ -12475,7 +12474,6 @@ EXPLAIN "rows_examined_per_scan": 4, "rows_produced_per_join": 4, "filtered": "100.00", - "index_condition": "(`test`.`sq2_alias2`.`col_int_key` < 2)", "using_MRR": true, "cost_info": { "read_cost": "1.37", diff --git a/mysql-test/r/subquery_sj_all_bka_nobnl.result b/mysql-test/r/subquery_sj_all_bka_nobnl.result index 23681a79d91..7e5b79185b2 100644 --- a/mysql-test/r/subquery_sj_all_bka_nobnl.result +++ b/mysql-test/r/subquery_sj_all_bka_nobnl.result @@ -328,7 +328,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK explain select * from t1 where a in (select pk from t10 where pk<3); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 103 10.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3)) @@ -4231,7 +4231,7 @@ explain select * from t3 where a in (select kp1 from t1 where kp1<20); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 100.00 Using where 1 SIMPLE NULL eq_ref 5 test.t3.a 1 100.00 NULL -2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using where; Using index +2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` semi join (`test`.`t1`) where ((``.`kp1` = `test`.`t3`.`a`) and (`test`.`t1`.`kp1` < 20)) select * from t3 where a in (select kp1 from t1 where kp1<20); @@ -4294,7 +4294,7 @@ explain select * from t3 where a in id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 100.00 Using where 1 SIMPLE NULL eq_ref 5 test.t3.a 1 100.00 NULL -2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using index condition; Using where; Using MRR +2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using where; Using MRR 2 MATERIALIZED t4 NULL eq_ref PRIMARY PRIMARY 4 test.t1.c 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` semi join (`test`.`t1` join `test`.`t4`) where ((``.`kp1` = `test`.`t3`.`a`) and (`test`.`t4`.`pk` = `test`.`t1`.`c`) and (`test`.`t1`.`kp1` < 20)) @@ -4309,7 +4309,7 @@ EXPLAIN -> Filter: (t1.kp1 is not null) (cost=29.95 rows=40) -> Nested loop inner join (cost=29.95 rows=40) -> Filter: (t1.c is not null) (cost=15.95 rows=40) - -> Index range scan on t1 using kp1 over (NULL < kp1 < 20), with index condition: (t1.kp1 < 20) (cost=15.95 rows=40) + -> Index range scan on t1 using kp1 over (NULL < kp1 < 20) (cost=15.95 rows=40) -> Single-row covering index lookup on t4 using PRIMARY (pk=t1.c) (cost=0.25 rows=1) select * from t3 where a in @@ -7945,7 +7945,7 @@ t2.Code IN (SELECT Country FROM t3 WHERE Language='English' AND Percentage > 10 AND t2.Population > 100000); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range Population,Country Population 4 NULL 1 10 Using index condition; Using MRR; Start temporary +1 SIMPLE t1 NULL range Population,Country Population 4 NULL 1 10 Using MRR; Start temporary 1 SIMPLE t2 NULL eq_ref PRIMARY,Population PRIMARY 12 test.t1.Country 1 10 Using where 1 SIMPLE t3 NULL eq_ref PRIMARY,Percentage PRIMARY 132 test.t1.Country,const 1 10 Using where; End temporary Warnings: @@ -7983,7 +7983,6 @@ EXPLAIN "rows_examined_per_scan": 1, "rows_produced_per_join": 1, "filtered": "100.00", - "index_condition": "(`test`.`t1`.`Population` > 5000000)", "using_MRR": true, "cost_info": { "read_cost": "0.60", diff --git a/mysql-test/r/subquery_sj_dupsweed.result b/mysql-test/r/subquery_sj_dupsweed.result index efbf6fb9012..3b70ff20611 100644 --- a/mysql-test/r/subquery_sj_dupsweed.result +++ b/mysql-test/r/subquery_sj_dupsweed.result @@ -325,7 +325,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK explain select * from t1 where a in (select pk from t10 where pk<3); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 103 10.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3)) @@ -7899,7 +7899,7 @@ t2.Code IN (SELECT Country FROM t3 WHERE Language='English' AND Percentage > 10 AND t2.Population > 100000); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range Population,Country Population 4 NULL 1 10 Using where; Start temporary +1 SIMPLE t1 NULL range Population,Country Population 4 NULL 1 10 Start temporary 1 SIMPLE t2 NULL eq_ref PRIMARY,Population PRIMARY 12 test.t1.Country 1 10 Using where 1 SIMPLE t3 NULL eq_ref PRIMARY,Percentage PRIMARY 132 test.t1.Country,const 1 10 Using where; End temporary Warnings: @@ -7946,8 +7946,7 @@ EXPLAIN "used_columns": [ "Country", "Population" - ], - "attached_condition": "(`test`.`t1`.`Population` > 5000000)" + ] } }, { @@ -12404,7 +12403,7 @@ EXPLAIN "col_int_key", "col_varchar_key" ], - "attached_condition": "((`test`.`sq2_alias2`.`col_int_key` < 2) and (`test`.`sq2_alias2`.`col_varchar_key` is not null))" + "attached_condition": "(`test`.`sq2_alias2`.`col_varchar_key` is not null)" } }, { @@ -12699,7 +12698,7 @@ WHERE innr.pk <= 7 ) ; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE innr NULL range PRIMARY,col_varchar_key PRIMARY 4 NULL 1 100.00 Using where; Start temporary +1 SIMPLE innr NULL range PRIMARY,col_varchar_key PRIMARY 4 NULL 1 100.00 Start temporary 1 SIMPLE outr NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t1` `outr` semi join (`test`.`t2` `innr`) where ((`test`.`outr`.`col_varchar_nokey` = `test`.`innr`.`col_varchar_key`) and (`test`.`innr`.`pk` <= 7)) @@ -12780,7 +12779,7 @@ WHERE t3.pk < 3 ); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 1 100.00 Start temporary -1 SIMPLE t3 NULL range PRIMARY,c1_key PRIMARY 4 NULL 1 100.00 Using where; Using join buffer (hash join) +1 SIMPLE t3 NULL range PRIMARY,c1_key PRIMARY 4 NULL 1 100.00 Using join buffer (hash join) 1 SIMPLE t2 NULL ref PRIMARY,c1_key c1_key 6 test.t3.c1 1 33.33 Using where; Using index; End temporary Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c1` AS `c1` from `test`.`t1` join `test`.`t2` semi join (`test`.`t3`) where ((`test`.`t2`.`c1` = `test`.`t3`.`c1`) and (`test`.`t3`.`pk` < 3) and (`test`.`t1`.`i1` >= `test`.`t2`.`pk`)) diff --git a/mysql-test/r/subquery_sj_dupsweed_bka.result b/mysql-test/r/subquery_sj_dupsweed_bka.result index 099d1732781..768b890468a 100644 --- a/mysql-test/r/subquery_sj_dupsweed_bka.result +++ b/mysql-test/r/subquery_sj_dupsweed_bka.result @@ -326,7 +326,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK explain select * from t1 where a in (select pk from t10 where pk<3); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 103 10.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3)) @@ -7900,7 +7900,7 @@ t2.Code IN (SELECT Country FROM t3 WHERE Language='English' AND Percentage > 10 AND t2.Population > 100000); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range Population,Country Population 4 NULL 1 10 Using where; Start temporary +1 SIMPLE t1 NULL range Population,Country Population 4 NULL 1 10 Start temporary 1 SIMPLE t2 NULL eq_ref PRIMARY,Population PRIMARY 12 test.t1.Country 1 10 Using where 1 SIMPLE t3 NULL eq_ref PRIMARY,Percentage PRIMARY 132 test.t1.Country,const 1 10 Using where; End temporary Warnings: @@ -7947,8 +7947,7 @@ EXPLAIN "used_columns": [ "Country", "Population" - ], - "attached_condition": "(`test`.`t1`.`Population` > 5000000)" + ] } }, { @@ -12405,7 +12404,7 @@ EXPLAIN "col_int_key", "col_varchar_key" ], - "attached_condition": "((`test`.`sq2_alias2`.`col_int_key` < 2) and (`test`.`sq2_alias2`.`col_varchar_key` is not null))" + "attached_condition": "(`test`.`sq2_alias2`.`col_varchar_key` is not null)" } }, { @@ -12700,7 +12699,7 @@ WHERE innr.pk <= 7 ) ; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE innr NULL range PRIMARY,col_varchar_key PRIMARY 4 NULL 1 100.00 Using where; Start temporary +1 SIMPLE innr NULL range PRIMARY,col_varchar_key PRIMARY 4 NULL 1 100.00 Start temporary 1 SIMPLE outr NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t1` `outr` semi join (`test`.`t2` `innr`) where ((`test`.`outr`.`col_varchar_nokey` = `test`.`innr`.`col_varchar_key`) and (`test`.`innr`.`pk` <= 7)) @@ -12781,7 +12780,7 @@ WHERE t3.pk < 3 ); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 1 100.00 Start temporary -1 SIMPLE t3 NULL range PRIMARY,c1_key PRIMARY 4 NULL 1 100.00 Using where; Using join buffer (hash join) +1 SIMPLE t3 NULL range PRIMARY,c1_key PRIMARY 4 NULL 1 100.00 Using join buffer (hash join) 1 SIMPLE t2 NULL ref PRIMARY,c1_key c1_key 6 test.t3.c1 1 33.33 Using where; Using index; End temporary Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c1` AS `c1` from `test`.`t1` join `test`.`t2` semi join (`test`.`t3`) where ((`test`.`t2`.`c1` = `test`.`t3`.`c1`) and (`test`.`t3`.`pk` < 3) and (`test`.`t1`.`i1` >= `test`.`t2`.`pk`)) diff --git a/mysql-test/r/subquery_sj_dupsweed_bka_nobnl.result b/mysql-test/r/subquery_sj_dupsweed_bka_nobnl.result index 05998849e3b..2f32851a9cc 100644 --- a/mysql-test/r/subquery_sj_dupsweed_bka_nobnl.result +++ b/mysql-test/r/subquery_sj_dupsweed_bka_nobnl.result @@ -326,7 +326,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK explain select * from t1 where a in (select pk from t10 where pk<3); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 103 10.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3)) @@ -7902,7 +7902,7 @@ t2.Code IN (SELECT Country FROM t3 WHERE Language='English' AND Percentage > 10 AND t2.Population > 100000); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range Population,Country Population 4 NULL 1 10 Using where; Start temporary +1 SIMPLE t1 NULL range Population,Country Population 4 NULL 1 10 Start temporary 1 SIMPLE t2 NULL eq_ref PRIMARY,Population PRIMARY 12 test.t1.Country 1 10 Using where 1 SIMPLE t3 NULL eq_ref PRIMARY,Percentage PRIMARY 132 test.t1.Country,const 1 10 Using where; End temporary Warnings: @@ -7949,8 +7949,7 @@ EXPLAIN "used_columns": [ "Country", "Population" - ], - "attached_condition": "(`test`.`t1`.`Population` > 5000000)" + ] } }, { @@ -12399,7 +12398,7 @@ EXPLAIN "col_int_key", "col_varchar_key" ], - "attached_condition": "((`test`.`sq2_alias2`.`col_int_key` < 2) and (`test`.`sq2_alias2`.`col_varchar_key` is not null))" + "attached_condition": "(`test`.`sq2_alias2`.`col_varchar_key` is not null)" } }, { @@ -12692,7 +12691,7 @@ WHERE innr.pk <= 7 ) ; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE innr NULL range PRIMARY,col_varchar_key PRIMARY 4 NULL 1 100.00 Using where; Start temporary +1 SIMPLE innr NULL range PRIMARY,col_varchar_key PRIMARY 4 NULL 1 100.00 Start temporary 1 SIMPLE outr NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary Warnings: Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t1` `outr` semi join (`test`.`t2` `innr`) where ((`test`.`outr`.`col_varchar_nokey` = `test`.`innr`.`col_varchar_key`) and (`test`.`innr`.`pk` <= 7)) @@ -12773,7 +12772,7 @@ WHERE t3.pk < 3 ); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL -1 SIMPLE t3 NULL range PRIMARY,c1_key PRIMARY 4 NULL 1 100.00 Using where; Start temporary +1 SIMPLE t3 NULL range PRIMARY,c1_key PRIMARY 4 NULL 1 100.00 Start temporary 1 SIMPLE t2 NULL ref PRIMARY,c1_key c1_key 6 test.t3.c1 1 33.33 Using where; Using index; End temporary Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c1` AS `c1` from `test`.`t1` join `test`.`t2` semi join (`test`.`t3`) where ((`test`.`t2`.`c1` = `test`.`t3`.`c1`) and (`test`.`t3`.`pk` < 3) and (`test`.`t1`.`i1` >= `test`.`t2`.`pk`)) diff --git a/mysql-test/r/subquery_sj_firstmatch.result b/mysql-test/r/subquery_sj_firstmatch.result index e7d4dd28894..625c841141d 100644 --- a/mysql-test/r/subquery_sj_firstmatch.result +++ b/mysql-test/r/subquery_sj_firstmatch.result @@ -326,7 +326,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK explain select * from t1 where a in (select pk from t10 where pk<3); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 103 10.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3)) @@ -7960,7 +7960,7 @@ EXPLAIN "Country", "Population" ], - "attached_condition": "((`test`.`t1`.`Country` = `test`.`t2`.`Code`) and (`test`.`t1`.`Population` > 5000000))" + "attached_condition": "(`test`.`t1`.`Country` = `test`.`t2`.`Code`)" } }, { diff --git a/mysql-test/r/subquery_sj_firstmatch_bka.result b/mysql-test/r/subquery_sj_firstmatch_bka.result index bd9ab61c4e0..d461f3a2a65 100644 --- a/mysql-test/r/subquery_sj_firstmatch_bka.result +++ b/mysql-test/r/subquery_sj_firstmatch_bka.result @@ -327,7 +327,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK explain select * from t1 where a in (select pk from t10 where pk<3); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 103 10.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3)) @@ -7961,7 +7961,7 @@ EXPLAIN "Country", "Population" ], - "attached_condition": "((`test`.`t1`.`Country` = `test`.`t2`.`Code`) and (`test`.`t1`.`Population` > 5000000))" + "attached_condition": "(`test`.`t1`.`Country` = `test`.`t2`.`Code`)" } }, { diff --git a/mysql-test/r/subquery_sj_firstmatch_bka_nobnl.result b/mysql-test/r/subquery_sj_firstmatch_bka_nobnl.result index 6d6d3a2853a..6bbc92a3e5b 100644 --- a/mysql-test/r/subquery_sj_firstmatch_bka_nobnl.result +++ b/mysql-test/r/subquery_sj_firstmatch_bka_nobnl.result @@ -327,7 +327,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK explain select * from t1 where a in (select pk from t10 where pk<3); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 103 10.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3)) @@ -7956,7 +7956,7 @@ EXPLAIN "Country", "Population" ], - "attached_condition": "((`test`.`t1`.`Country` = `test`.`t2`.`Code`) and (`test`.`t1`.`Population` > 5000000))" + "attached_condition": "(`test`.`t1`.`Country` = `test`.`t2`.`Code`)" } }, { diff --git a/mysql-test/r/subquery_sj_loosescan.result b/mysql-test/r/subquery_sj_loosescan.result index 391010cac53..568d743cde5 100644 --- a/mysql-test/r/subquery_sj_loosescan.result +++ b/mysql-test/r/subquery_sj_loosescan.result @@ -326,7 +326,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK explain select * from t1 where a in (select pk from t10 where pk<3); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 103 10.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3)) @@ -4186,7 +4186,7 @@ test.t1 analyze status OK test.t3 analyze status OK explain select * from t3 where a in (select kp1 from t1 where kp1<20); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range kp1 kp1 5 NULL 40 2500.00 Using where; Using index; LooseScan +1 SIMPLE t1 NULL range kp1 kp1 5 NULL 40 2500.00 Using index; LooseScan 1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 10.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` semi join (`test`.`t1`) where ((`test`.`t3`.`a` = `test`.`t1`.`kp1`) and (`test`.`t1`.`kp1` < 20)) @@ -4214,7 +4214,7 @@ a 9 explain select * from t3 where a in (select kp1 from t1 where kp1<20) and a<20; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range kp1 kp1 5 NULL 40 2500.00 Using where; Using index; LooseScan +1 SIMPLE t1 NULL range kp1 kp1 5 NULL 40 2500.00 Using index; LooseScan 1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 3.33 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` semi join (`test`.`t1`) where ((`test`.`t3`.`a` = `test`.`t1`.`kp1`) and (`test`.`t1`.`kp1` < 20) and (`test`.`t1`.`kp1` < 20)) @@ -4260,7 +4260,7 @@ EXPLAIN -> Table scan on t3 (cost=1.25 rows=100) -> Hash -> Nested loop semijoin with duplicate removal on kp1 (cost=32.26 rows=40) - -> Filter: ((t1.kp1 < 20) and (t1.c is not null)) (cost=18.26 rows=40) + -> Filter: (t1.c is not null) (cost=18.26 rows=40) -> Index range scan on t1 using kp1 over (NULL < kp1 < 20) (cost=18.26 rows=40) -> Single-row covering index lookup on t4 using PRIMARY (pk=t1.c) (cost=0.25 rows=1) @@ -7824,7 +7824,7 @@ CREATE TABLE t2 LIKE t1; INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff'); EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t2`.`pk` > 0)) @@ -7947,7 +7947,7 @@ EXPLAIN "Language", "Percentage" ], - "attached_condition": "((`test`.`t3`.`Language` = 'English') and (`test`.`t3`.`Percentage` > 10))" + "attached_condition": "(`test`.`t3`.`Language` = 'English')" } }, { @@ -8385,7 +8385,7 @@ CREATE TABLE t2 LIKE t1; INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii','iiii','ffff','ffff','ffff','ffff','ffff',ST_GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')), (2,'f','ffff','ffff','ffff','ffff','ffff','ffff','ffff','ffff','ffff',ST_GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')); EXPLAIN SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t2`.`pk` > 0)) @@ -8394,7 +8394,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`c` = `test`.`t2`.`c`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8404,7 +8404,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`d` = `test`.`t2`.`d`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8413,7 +8413,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`e` = `test`.`t2`.`e`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8423,7 +8423,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`f` = `test`.`t2`.`f`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8433,7 +8433,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`g` = `test`.`t2`.`g`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8443,7 +8443,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`h` = `test`.`t2`.`h`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8453,7 +8453,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`i` = `test`.`t2`.`i`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8463,7 +8463,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`j` = `test`.`t2`.`j`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8473,7 +8473,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`k` = `test`.`t2`.`k`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -12399,7 +12399,7 @@ EXPLAIN "col_int_key", "col_varchar_key" ], - "attached_condition": "((`test`.`sq2_alias2`.`col_int_key` < 2) and (`test`.`sq2_alias2`.`col_varchar_key` is not null))" + "attached_condition": "(`test`.`sq2_alias2`.`col_varchar_key` is not null)" } }, { diff --git a/mysql-test/r/subquery_sj_loosescan_bka.result b/mysql-test/r/subquery_sj_loosescan_bka.result index e03af0d5e4d..069363790be 100644 --- a/mysql-test/r/subquery_sj_loosescan_bka.result +++ b/mysql-test/r/subquery_sj_loosescan_bka.result @@ -327,7 +327,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK explain select * from t1 where a in (select pk from t10 where pk<3); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 103 10.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3)) @@ -4187,7 +4187,7 @@ test.t1 analyze status OK test.t3 analyze status OK explain select * from t3 where a in (select kp1 from t1 where kp1<20); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range kp1 kp1 5 NULL 40 2500.00 Using where; Using index; LooseScan +1 SIMPLE t1 NULL range kp1 kp1 5 NULL 40 2500.00 Using index; LooseScan 1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 10.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` semi join (`test`.`t1`) where ((`test`.`t3`.`a` = `test`.`t1`.`kp1`) and (`test`.`t1`.`kp1` < 20)) @@ -4215,7 +4215,7 @@ a 9 explain select * from t3 where a in (select kp1 from t1 where kp1<20) and a<20; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range kp1 kp1 5 NULL 40 2500.00 Using where; Using index; LooseScan +1 SIMPLE t1 NULL range kp1 kp1 5 NULL 40 2500.00 Using index; LooseScan 1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 3.33 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` semi join (`test`.`t1`) where ((`test`.`t3`.`a` = `test`.`t1`.`kp1`) and (`test`.`t1`.`kp1` < 20) and (`test`.`t1`.`kp1` < 20)) @@ -4261,7 +4261,7 @@ EXPLAIN -> Table scan on t3 (cost=1.25 rows=100) -> Hash -> Nested loop semijoin with duplicate removal on kp1 (cost=32.26 rows=40) - -> Filter: ((t1.kp1 < 20) and (t1.c is not null)) (cost=18.26 rows=40) + -> Filter: (t1.c is not null) (cost=18.26 rows=40) -> Index range scan on t1 using kp1 over (NULL < kp1 < 20) (cost=18.26 rows=40) -> Single-row covering index lookup on t4 using PRIMARY (pk=t1.c) (cost=0.25 rows=1) @@ -7825,7 +7825,7 @@ CREATE TABLE t2 LIKE t1; INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff'); EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t2`.`pk` > 0)) @@ -7948,7 +7948,7 @@ EXPLAIN "Language", "Percentage" ], - "attached_condition": "((`test`.`t3`.`Language` = 'English') and (`test`.`t3`.`Percentage` > 10))" + "attached_condition": "(`test`.`t3`.`Language` = 'English')" } }, { @@ -8386,7 +8386,7 @@ CREATE TABLE t2 LIKE t1; INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii','iiii','ffff','ffff','ffff','ffff','ffff',ST_GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')), (2,'f','ffff','ffff','ffff','ffff','ffff','ffff','ffff','ffff','ffff',ST_GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')); EXPLAIN SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t2`.`pk` > 0)) @@ -8395,7 +8395,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`c` = `test`.`t2`.`c`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8405,7 +8405,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`d` = `test`.`t2`.`d`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8414,7 +8414,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`e` = `test`.`t2`.`e`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8424,7 +8424,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`f` = `test`.`t2`.`f`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8434,7 +8434,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`g` = `test`.`t2`.`g`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8444,7 +8444,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`h` = `test`.`t2`.`h`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8454,7 +8454,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`i` = `test`.`t2`.`i`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8464,7 +8464,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`j` = `test`.`t2`.`j`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8474,7 +8474,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`k` = `test`.`t2`.`k`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -12400,7 +12400,7 @@ EXPLAIN "col_int_key", "col_varchar_key" ], - "attached_condition": "((`test`.`sq2_alias2`.`col_int_key` < 2) and (`test`.`sq2_alias2`.`col_varchar_key` is not null))" + "attached_condition": "(`test`.`sq2_alias2`.`col_varchar_key` is not null)" } }, { diff --git a/mysql-test/r/subquery_sj_loosescan_bka_nobnl.result b/mysql-test/r/subquery_sj_loosescan_bka_nobnl.result index 8bddd48c760..38d9fd4169d 100644 --- a/mysql-test/r/subquery_sj_loosescan_bka_nobnl.result +++ b/mysql-test/r/subquery_sj_loosescan_bka_nobnl.result @@ -327,7 +327,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK explain select * from t1 where a in (select pk from t10 where pk<3); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 103 10.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3)) @@ -4186,7 +4186,7 @@ test.t1 analyze status OK test.t3 analyze status OK explain select * from t3 where a in (select kp1 from t1 where kp1<20); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range kp1 kp1 5 NULL 40 2500.00 Using where; Using index; LooseScan +1 SIMPLE t1 NULL range kp1 kp1 5 NULL 40 2500.00 Using index; LooseScan 1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 10.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` semi join (`test`.`t1`) where ((`test`.`t3`.`a` = `test`.`t1`.`kp1`) and (`test`.`t1`.`kp1` < 20)) @@ -4214,7 +4214,7 @@ a 9 explain select * from t3 where a in (select kp1 from t1 where kp1<20) and a<20; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range kp1 kp1 5 NULL 40 2500.00 Using where; Using index; LooseScan +1 SIMPLE t1 NULL range kp1 kp1 5 NULL 40 2500.00 Using index; LooseScan 1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 3.33 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` semi join (`test`.`t1`) where ((`test`.`t3`.`a` = `test`.`t1`.`kp1`) and (`test`.`t1`.`kp1` < 20) and (`test`.`t1`.`kp1` < 20)) @@ -4258,7 +4258,7 @@ explain format=tree select * from t3 where a in EXPLAIN -> Nested loop inner join (cost=442.26 rows=400) -> Nested loop semijoin with duplicate removal on kp1 (cost=32.26 rows=40) - -> Filter: ((t1.kp1 < 20) and (t1.c is not null)) (cost=18.26 rows=40) + -> Filter: (t1.c is not null) (cost=18.26 rows=40) -> Index range scan on t1 using kp1 over (NULL < kp1 < 20) (cost=18.26 rows=40) -> Single-row covering index lookup on t4 using PRIMARY (pk=t1.c) (cost=0.25 rows=1) -> Filter: (t3.a = t1.kp1) (cost=11.00 rows=10) @@ -7827,7 +7827,7 @@ CREATE TABLE t2 LIKE t1; INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff'); EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t2`.`pk` > 0)) @@ -7950,7 +7950,7 @@ EXPLAIN "Language", "Percentage" ], - "attached_condition": "((`test`.`t3`.`Language` = 'English') and (`test`.`t3`.`Percentage` > 10))" + "attached_condition": "(`test`.`t3`.`Language` = 'English')" } }, { @@ -8388,7 +8388,7 @@ CREATE TABLE t2 LIKE t1; INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii','iiii','ffff','ffff','ffff','ffff','ffff',ST_GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')), (2,'f','ffff','ffff','ffff','ffff','ffff','ffff','ffff','ffff','ffff',ST_GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0))')); EXPLAIN SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t2`.`pk` > 0)) @@ -8397,7 +8397,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`c` = `test`.`t2`.`c`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8407,7 +8407,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`d` = `test`.`t2`.`d`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8416,7 +8416,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`e` = `test`.`t2`.`e`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8426,7 +8426,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`f` = `test`.`t2`.`f`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8436,7 +8436,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`g` = `test`.`t2`.`g`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8446,7 +8446,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`h` = `test`.`t2`.`h`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8456,7 +8456,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`i` = `test`.`t2`.`i`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8466,7 +8466,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`j` = `test`.`t2`.`j`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -8476,7 +8476,7 @@ pk 2 EXPLAIN SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Start temporary +1 SIMPLE t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Start temporary 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`k` = `test`.`t2`.`k`) and (`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`pk` > 0)) @@ -12397,7 +12397,7 @@ EXPLAIN "col_int_key", "col_varchar_key" ], - "attached_condition": "((`test`.`sq2_alias2`.`col_int_key` < 2) and (`test`.`sq2_alias2`.`col_varchar_key` is not null))" + "attached_condition": "(`test`.`sq2_alias2`.`col_varchar_key` is not null)" } }, { diff --git a/mysql-test/r/subquery_sj_mat.result b/mysql-test/r/subquery_sj_mat.result index e7fbafd0428..c08dbe4669a 100644 --- a/mysql-test/r/subquery_sj_mat.result +++ b/mysql-test/r/subquery_sj_mat.result @@ -331,7 +331,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK explain select * from t1 where a in (select pk from t10 where pk<3); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 103 10.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3)) @@ -4430,7 +4430,7 @@ explain select * from t3 where a in (select kp1 from t1 where kp1<20); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 100.00 Using where 1 SIMPLE NULL eq_ref 5 test.t3.a 1 100.00 NULL -2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using where; Using index +2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` semi join (`test`.`t1`) where ((``.`kp1` = `test`.`t3`.`a`) and (`test`.`t1`.`kp1` < 20)) select * from t3 where a in (select kp1 from t1 where kp1<20); @@ -4459,7 +4459,7 @@ explain select * from t3 where a in (select kp1 from t1 where kp1<20) and a<20; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 33.33 Using where 1 SIMPLE NULL eq_ref 5 test.t3.a 1 100.00 NULL -2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using where; Using index +2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` semi join (`test`.`t1`) where ((``.`kp1` = `test`.`t3`.`a`) and (`test`.`t3`.`a` < 20) and (`test`.`t1`.`kp1` < 20)) select * from t3 where a in (select kp1 from t1 where kp1<20) and a<20; @@ -4508,7 +4508,7 @@ EXPLAIN -> Materialize with deduplication (cost=36.26..36.26 rows=40) -> Filter: (t1.kp1 is not null) (cost=32.26 rows=40) -> Nested loop inner join (cost=32.26 rows=40) - -> Filter: ((t1.kp1 < 20) and (t1.c is not null)) (cost=18.26 rows=40) + -> Filter: (t1.c is not null) (cost=18.26 rows=40) -> Index range scan on t1 using kp1 over (NULL < kp1 < 20) (cost=18.26 rows=40) -> Single-row covering index lookup on t4 using PRIMARY (pk=t1.c) (cost=0.25 rows=1) @@ -8115,7 +8115,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE NULL eq_ref 7 test.t1.a 1 100.00 NULL -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`a` = `test`.`t1`.`a`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); @@ -8193,7 +8193,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 10 NULL 1 SIMPLE t2 NULL eq_ref PRIMARY,Population PRIMARY 12 .Country 1 10 Using where 1 SIMPLE t3 NULL eq_ref PRIMARY,Percentage PRIMARY 132 .Country,const 1 10 Using where -2 MATERIALIZED t1 NULL range Population,Country Population 4 NULL 1 10 Using where +2 MATERIALIZED t1 NULL range Population,Country Population 4 NULL 1 10 NULL Warnings: Note 1276 Field or reference 'test.t2.Population' of SELECT #3 was resolved in SELECT #1 Note 1003 /* select#1 */ select `test`.`t2`.`Name` AS `Name` from `test`.`t3` join `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t2`.`Code` = ``.`Country`) and (`test`.`t3`.`Country` = ``.`Country`) and (`test`.`t3`.`Language` = 'English') and (`test`.`t3`.`Percentage` > 10) and (`test`.`t2`.`Population` > 100000) and (`test`.`t1`.`Population` > 5000000)) @@ -8242,8 +8242,7 @@ EXPLAIN "used_columns": [ "Country", "Population" - ], - "attached_condition": "(`test`.`t1`.`Population` > 5000000)" + ] } } } @@ -8690,7 +8689,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE NULL eq_ref 26 test.t1.a,test.t1.b 1 100.00 NULL -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`b` = `test`.`t1`.`b`) and (``.`a` = `test`.`t1`.`a`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0); @@ -8700,7 +8699,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`c` = `test`.`t1`.`c`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0); @@ -8711,7 +8710,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`d` = `test`.`t1`.`d`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0); @@ -8721,7 +8720,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`e` = `test`.`t1`.`e`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0); @@ -8732,7 +8731,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`f` = `test`.`t1`.`f`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0); @@ -8743,7 +8742,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`g` = `test`.`t1`.`g`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0); @@ -8754,7 +8753,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`h` = `test`.`t1`.`h`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0); @@ -8765,7 +8764,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`i` = `test`.`t1`.`i`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0); @@ -8776,7 +8775,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`j` = `test`.`t1`.`j`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0); @@ -8787,7 +8786,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`k` = `test`.`t1`.`k`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0); @@ -13083,7 +13082,7 @@ WHERE innr.pk <= 7 id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 NULL 1 SIMPLE outr NULL ALL NULL NULL NULL NULL 3 33.33 Using where; Using join buffer (hash join) -2 MATERIALIZED innr NULL range PRIMARY,col_varchar_key PRIMARY 4 NULL 1 100.00 Using where +2 MATERIALIZED innr NULL range PRIMARY,col_varchar_key PRIMARY 4 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t1` `outr` semi join (`test`.`t2` `innr`) where ((`test`.`outr`.`col_varchar_nokey` = ``.`col_varchar_key`) and (`test`.`innr`.`pk` <= 7)) SELECT 1 @@ -13166,7 +13165,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using join buffer (hash join) 1 SIMPLE t2 NULL ref PRIMARY,c1_key c1_key 6 .c1 1 33.33 Using where; Using index -2 MATERIALIZED t3 NULL range PRIMARY,c1_key PRIMARY 4 NULL 1 100.00 Using where +2 MATERIALIZED t3 NULL range PRIMARY,c1_key PRIMARY 4 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c1` AS `c1` from `test`.`t1` join `test`.`t2` semi join (`test`.`t3`) where ((`test`.`t2`.`c1` = ``.`c1`) and (`test`.`t3`.`pk` < 3) and (`test`.`t1`.`i1` >= `test`.`t2`.`pk`)) SELECT * diff --git a/mysql-test/r/subquery_sj_mat_bka.result b/mysql-test/r/subquery_sj_mat_bka.result index 0968b6e5fcb..62272cea0a8 100644 --- a/mysql-test/r/subquery_sj_mat_bka.result +++ b/mysql-test/r/subquery_sj_mat_bka.result @@ -332,7 +332,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK explain select * from t1 where a in (select pk from t10 where pk<3); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 103 10.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3)) @@ -4431,7 +4431,7 @@ explain select * from t3 where a in (select kp1 from t1 where kp1<20); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 100.00 Using where 1 SIMPLE NULL eq_ref 5 test.t3.a 1 100.00 NULL -2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using where; Using index +2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` semi join (`test`.`t1`) where ((``.`kp1` = `test`.`t3`.`a`) and (`test`.`t1`.`kp1` < 20)) select * from t3 where a in (select kp1 from t1 where kp1<20); @@ -4460,7 +4460,7 @@ explain select * from t3 where a in (select kp1 from t1 where kp1<20) and a<20; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 33.33 Using where 1 SIMPLE NULL eq_ref 5 test.t3.a 1 100.00 NULL -2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using where; Using index +2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` semi join (`test`.`t1`) where ((``.`kp1` = `test`.`t3`.`a`) and (`test`.`t3`.`a` < 20) and (`test`.`t1`.`kp1` < 20)) select * from t3 where a in (select kp1 from t1 where kp1<20) and a<20; @@ -4509,7 +4509,7 @@ EXPLAIN -> Materialize with deduplication (cost=36.26..36.26 rows=40) -> Filter: (t1.kp1 is not null) (cost=32.26 rows=40) -> Nested loop inner join (cost=32.26 rows=40) - -> Filter: ((t1.kp1 < 20) and (t1.c is not null)) (cost=18.26 rows=40) + -> Filter: (t1.c is not null) (cost=18.26 rows=40) -> Index range scan on t1 using kp1 over (NULL < kp1 < 20) (cost=18.26 rows=40) -> Single-row covering index lookup on t4 using PRIMARY (pk=t1.c) (cost=0.25 rows=1) @@ -8116,7 +8116,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE NULL eq_ref 7 test.t1.a 1 100.00 NULL -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`a` = `test`.`t1`.`a`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); @@ -8194,7 +8194,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 10 NULL 1 SIMPLE t2 NULL eq_ref PRIMARY,Population PRIMARY 12 .Country 1 10 Using where 1 SIMPLE t3 NULL eq_ref PRIMARY,Percentage PRIMARY 132 .Country,const 1 10 Using where -2 MATERIALIZED t1 NULL range Population,Country Population 4 NULL 1 10 Using where +2 MATERIALIZED t1 NULL range Population,Country Population 4 NULL 1 10 NULL Warnings: Note 1276 Field or reference 'test.t2.Population' of SELECT #3 was resolved in SELECT #1 Note 1003 /* select#1 */ select `test`.`t2`.`Name` AS `Name` from `test`.`t3` join `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t2`.`Code` = ``.`Country`) and (`test`.`t3`.`Country` = ``.`Country`) and (`test`.`t3`.`Language` = 'English') and (`test`.`t3`.`Percentage` > 10) and (`test`.`t2`.`Population` > 100000) and (`test`.`t1`.`Population` > 5000000)) @@ -8243,8 +8243,7 @@ EXPLAIN "used_columns": [ "Country", "Population" - ], - "attached_condition": "(`test`.`t1`.`Population` > 5000000)" + ] } } } @@ -8691,7 +8690,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE NULL eq_ref 26 test.t1.a,test.t1.b 1 100.00 NULL -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`b` = `test`.`t1`.`b`) and (``.`a` = `test`.`t1`.`a`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0); @@ -8701,7 +8700,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`c` = `test`.`t1`.`c`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0); @@ -8712,7 +8711,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`d` = `test`.`t1`.`d`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0); @@ -8722,7 +8721,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`e` = `test`.`t1`.`e`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0); @@ -8733,7 +8732,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`f` = `test`.`t1`.`f`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0); @@ -8744,7 +8743,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`g` = `test`.`t1`.`g`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0); @@ -8755,7 +8754,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`h` = `test`.`t1`.`h`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0); @@ -8766,7 +8765,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`i` = `test`.`t1`.`i`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0); @@ -8777,7 +8776,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`j` = `test`.`t1`.`j`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0); @@ -8788,7 +8787,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where; Using join buffer (hash join) -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`k` = `test`.`t1`.`k`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0); @@ -13084,7 +13083,7 @@ WHERE innr.pk <= 7 id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 NULL 1 SIMPLE outr NULL ALL NULL NULL NULL NULL 3 33.33 Using where; Using join buffer (hash join) -2 MATERIALIZED innr NULL range PRIMARY,col_varchar_key PRIMARY 4 NULL 1 100.00 Using where +2 MATERIALIZED innr NULL range PRIMARY,col_varchar_key PRIMARY 4 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t1` `outr` semi join (`test`.`t2` `innr`) where ((`test`.`outr`.`col_varchar_nokey` = ``.`col_varchar_key`) and (`test`.`innr`.`pk` <= 7)) SELECT 1 @@ -13167,7 +13166,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using join buffer (hash join) 1 SIMPLE t2 NULL ref PRIMARY,c1_key c1_key 6 .c1 1 33.33 Using where; Using index -2 MATERIALIZED t3 NULL range PRIMARY,c1_key PRIMARY 4 NULL 1 100.00 Using where +2 MATERIALIZED t3 NULL range PRIMARY,c1_key PRIMARY 4 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c1` AS `c1` from `test`.`t1` join `test`.`t2` semi join (`test`.`t3`) where ((`test`.`t2`.`c1` = ``.`c1`) and (`test`.`t3`.`pk` < 3) and (`test`.`t1`.`i1` >= `test`.`t2`.`pk`)) SELECT * diff --git a/mysql-test/r/subquery_sj_mat_bka_nobnl.result b/mysql-test/r/subquery_sj_mat_bka_nobnl.result index 2d6e5eb7ad2..9e3e8637418 100644 --- a/mysql-test/r/subquery_sj_mat_bka_nobnl.result +++ b/mysql-test/r/subquery_sj_mat_bka_nobnl.result @@ -332,7 +332,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK explain select * from t1 where a in (select pk from t10 where pk<3); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 103 10.00 Using where Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t10`.`pk`) and (`test`.`t10`.`pk` < 3)) @@ -4431,7 +4431,7 @@ explain select * from t3 where a in (select kp1 from t1 where kp1<20); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 100.00 Using where 1 SIMPLE NULL eq_ref 5 test.t3.a 1 100.00 NULL -2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using where; Using index +2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` semi join (`test`.`t1`) where ((``.`kp1` = `test`.`t3`.`a`) and (`test`.`t1`.`kp1` < 20)) select * from t3 where a in (select kp1 from t1 where kp1<20); @@ -4460,7 +4460,7 @@ explain select * from t3 where a in (select kp1 from t1 where kp1<20) and a<20; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 33.33 Using where 1 SIMPLE NULL eq_ref 5 test.t3.a 1 100.00 NULL -2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using where; Using index +2 MATERIALIZED t1 NULL range kp1 kp1 5 NULL 40 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` semi join (`test`.`t1`) where ((``.`kp1` = `test`.`t3`.`a`) and (`test`.`t3`.`a` < 20) and (`test`.`t1`.`kp1` < 20)) select * from t3 where a in (select kp1 from t1 where kp1<20) and a<20; @@ -4509,7 +4509,7 @@ EXPLAIN -> Materialize with deduplication (cost=36.26..36.26 rows=40) -> Filter: (t1.kp1 is not null) (cost=32.26 rows=40) -> Nested loop inner join (cost=32.26 rows=40) - -> Filter: ((t1.kp1 < 20) and (t1.c is not null)) (cost=18.26 rows=40) + -> Filter: (t1.c is not null) (cost=18.26 rows=40) -> Index range scan on t1 using kp1 over (NULL < kp1 < 20) (cost=18.26 rows=40) -> Single-row covering index lookup on t4 using PRIMARY (pk=t1.c) (cost=0.25 rows=1) @@ -8115,7 +8115,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE NULL eq_ref 7 test.t1.a 1 100.00 NULL -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`a` = `test`.`t1`.`a`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); @@ -8193,7 +8193,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 10 NULL 1 SIMPLE t2 NULL eq_ref PRIMARY,Population PRIMARY 12 .Country 1 10 Using where 1 SIMPLE t3 NULL eq_ref PRIMARY,Percentage PRIMARY 132 .Country,const 1 10 Using where -2 MATERIALIZED t1 NULL range Population,Country Population 4 NULL 1 10 Using where +2 MATERIALIZED t1 NULL range Population,Country Population 4 NULL 1 10 NULL Warnings: Note 1276 Field or reference 'test.t2.Population' of SELECT #3 was resolved in SELECT #1 Note 1003 /* select#1 */ select `test`.`t2`.`Name` AS `Name` from `test`.`t3` join `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t2`.`Code` = ``.`Country`) and (`test`.`t3`.`Country` = ``.`Country`) and (`test`.`t3`.`Language` = 'English') and (`test`.`t3`.`Percentage` > 10) and (`test`.`t2`.`Population` > 100000) and (`test`.`t1`.`Population` > 5000000)) @@ -8242,8 +8242,7 @@ EXPLAIN "used_columns": [ "Country", "Population" - ], - "attached_condition": "(`test`.`t1`.`Population` > 5000000)" + ] } } } @@ -8690,7 +8689,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 Using where 1 SIMPLE NULL eq_ref 26 test.t1.a,test.t1.b 1 100.00 NULL -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`b` = `test`.`t1`.`b`) and (``.`a` = `test`.`t1`.`a`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0); @@ -8700,7 +8699,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`c` = `test`.`t1`.`c`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0); @@ -8711,7 +8710,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`d` = `test`.`t1`.`d`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0); @@ -8721,7 +8720,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`e` = `test`.`t1`.`e`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0); @@ -8732,7 +8731,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`f` = `test`.`t1`.`f`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0); @@ -8743,7 +8742,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`g` = `test`.`t1`.`g`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0); @@ -8754,7 +8753,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`h` = `test`.`t1`.`h`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0); @@ -8765,7 +8764,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`i` = `test`.`t1`.`i`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0); @@ -8776,7 +8775,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`j` = `test`.`t1`.`j`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0); @@ -8787,7 +8786,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 Using where -2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 MATERIALIZED t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((``.`k` = `test`.`t1`.`k`) and (``.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0)) SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0); @@ -13079,7 +13078,7 @@ WHERE innr.pk <= 7 id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 NULL 1 SIMPLE outr NULL ALL NULL NULL NULL NULL 3 33.33 Using where -2 MATERIALIZED innr NULL range PRIMARY,col_varchar_key PRIMARY 4 NULL 1 100.00 Using where +2 MATERIALIZED innr NULL range PRIMARY,col_varchar_key PRIMARY 4 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t1` `outr` semi join (`test`.`t2` `innr`) where ((`test`.`outr`.`col_varchar_nokey` = ``.`col_varchar_key`) and (`test`.`innr`.`pk` <= 7)) SELECT 1 @@ -13162,7 +13161,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL 1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 NULL 1 SIMPLE t2 NULL ref PRIMARY,c1_key c1_key 6 .c1 1 33.33 Using where; Using index -2 MATERIALIZED t3 NULL range PRIMARY,c1_key PRIMARY 4 NULL 1 100.00 Using where +2 MATERIALIZED t3 NULL range PRIMARY,c1_key PRIMARY 4 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c1` AS `c1` from `test`.`t1` join `test`.`t2` semi join (`test`.`t3`) where ((`test`.`t2`.`c1` = ``.`c1`) and (`test`.`t3`.`pk` < 3) and (`test`.`t1`.`i1` >= `test`.`t2`.`pk`)) SELECT * diff --git a/mysql-test/r/subquery_sj_mat_nosj.result b/mysql-test/r/subquery_sj_mat_nosj.result index 41231dac436..5ab94f393c6 100644 --- a/mysql-test/r/subquery_sj_mat_nosj.result +++ b/mysql-test/r/subquery_sj_mat_nosj.result @@ -328,7 +328,7 @@ test.t1 analyze status OK explain select * from t1 where a in (select pk from t10 where pk<3); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 103 100.00 Using where -2 SUBQUERY t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where; Using index +2 SUBQUERY t10 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select `test`.`t10`.`pk` from `test`.`t10` where (`test`.`t10`.`pk` < 3) ), (`test`.`t1`.`a` in on where ((`test`.`t1`.`a` = ``.`pk`))))) drop table t0, t1, t2; @@ -4210,7 +4210,7 @@ test.t3 analyze status OK explain select * from t3 where a in (select kp1 from t1 where kp1<20); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 NULL ALL NULL NULL NULL NULL 100 100.00 Using where -2 SUBQUERY t1 NULL range kp1 kp1 5 NULL 40 100.00 Using where; Using index +2 SUBQUERY t1 NULL range kp1 kp1 5 NULL 40 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where (`test`.`t3`.`a`,`test`.`t3`.`a` in ( (/* select#2 */ select `test`.`t1`.`kp1` from `test`.`t1` where (`test`.`t1`.`kp1` < 20) ), (`test`.`t3`.`a` in on where ((`test`.`t3`.`a` = ``.`kp1`))))) select * from t3 where a in (select kp1 from t1 where kp1<20); @@ -4238,7 +4238,7 @@ a explain select * from t3 where a in (select kp1 from t1 where kp1<20) and a<20; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t3 NULL ALL NULL NULL NULL NULL 100 33.33 Using where -2 SUBQUERY t1 NULL range kp1 kp1 5 NULL 40 100.00 Using where; Using index +2 SUBQUERY t1 NULL range kp1 kp1 5 NULL 40 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where ((`test`.`t3`.`a`,`test`.`t3`.`a` in ( (/* select#2 */ select `test`.`t1`.`kp1` from `test`.`t1` where (`test`.`t1`.`kp1` < 20) ), (`test`.`t3`.`a` in on where ((`test`.`t3`.`a` = ``.`kp1`))))) and (`test`.`t3`.`a` < 20)) select * from t3 where a in (select kp1 from t1 where kp1<20) and a<20; @@ -4287,7 +4287,7 @@ EXPLAIN -> Index lookup on using (kp1=t3.a) -> Materialize with deduplication (cost=36.26..36.26 rows=40) -> Nested loop inner join (cost=32.26 rows=40) - -> Filter: ((t1.kp1 < 20) and (t1.c is not null)) (cost=18.26 rows=40) + -> Filter: (t1.c is not null) (cost=18.26 rows=40) -> Index range scan on t1 using kp1 over (NULL < kp1 < 20) (cost=18.26 rows=40) -> Single-row covering index lookup on t4 using PRIMARY (pk=t1.c) (cost=0.25 rows=1) @@ -7812,7 +7812,7 @@ INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff'); EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 2 100.00 Using where -2 SUBQUERY t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 SUBQUERY t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` where (`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select `test`.`t2`.`a` from `test`.`t2` where (`test`.`t2`.`pk` > 0) ), (`test`.`t1`.`a` in on where ((`test`.`t1`.`a` = ``.`a`))))) SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); @@ -7888,7 +7888,7 @@ t2.Population > 100000); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 NULL ALL NULL NULL NULL NULL 16 10 Using where 3 DEPENDENT SUBQUERY t3 NULL unique_subquery PRIMARY,Percentage PRIMARY 132 func,const 1 10 Using where -2 SUBQUERY t1 NULL range Population,Country Population 4 NULL 1 10 Using where +2 SUBQUERY t1 NULL range Population,Country Population 4 NULL 1 10 NULL Warnings: Note 1276 Field or reference 'test.t2.Population' of SELECT #3 was resolved in SELECT #1 Note 1003 /* select#1 */ select `test`.`t2`.`Name` AS `Name` from `test`.`t2` where ((`test`.`t2`.`Code`,`test`.`t2`.`Code` in ( (/* select#2 */ select `test`.`t1`.`Country` from `test`.`t1` where (`test`.`t1`.`Population` > 5000000) ), (`test`.`t2`.`Code` in on where ((`test`.`t2`.`Code` = ``.`Country`))))) and (`test`.`t2`.`Code`,(((`test`.`t2`.`Code`) in t3 on PRIMARY where ((`test`.`t3`.`Language` = 'English') and (`test`.`t3`.`Percentage` > 10) and (`test`.`t2`.`Population` > 100000)))))) @@ -8007,8 +8007,7 @@ EXPLAIN "used_columns": [ "Country", "Population" - ], - "attached_condition": "(`test`.`t1`.`Population` > 5000000)" + ] } } } @@ -8385,7 +8384,7 @@ INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii','iiii','ffff','ffff','ffff','f EXPLAIN SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 2 100.00 Using where -2 SUBQUERY t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +2 SUBQUERY t2 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` where ((`test`.`t1`.`a`,`test`.`t1`.`b`),(`test`.`t1`.`a`,`test`.`t1`.`b`) in ( (/* select#2 */ select `test`.`t2`.`a`,`test`.`t2`.`b` from `test`.`t2` where (`test`.`t2`.`pk` > 0) ), (`test`.`t1`.`a` in on where ((`test`.`t1`.`a` = ``.`a`) and (`test`.`t1`.`b` = ``.`b`))))) SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0); @@ -12481,8 +12480,7 @@ EXPLAIN "used_columns": [ "col_int_key", "col_varchar_key" - ], - "attached_condition": "(`test`.`sq2_alias2`.`col_int_key` < 2)" + ] } }, { diff --git a/mysql-test/r/subquery_sj_none.result b/mysql-test/r/subquery_sj_none.result index d5fe5beb361..57a67f09bc7 100644 --- a/mysql-test/r/subquery_sj_none.result +++ b/mysql-test/r/subquery_sj_none.result @@ -8011,7 +8011,7 @@ EXPLAIN "Country", "Population" ], - "attached_condition": "((`test`.`t1`.`Population` > 5000000) and ((`test`.`t2`.`Code`) = `test`.`t1`.`Country`))" + "attached_condition": "((`test`.`t2`.`Code`) = `test`.`t1`.`Country`)" } } } diff --git a/mysql-test/r/subquery_sj_none_bka.result b/mysql-test/r/subquery_sj_none_bka.result index c805d0394cd..a8164b13d9e 100644 --- a/mysql-test/r/subquery_sj_none_bka.result +++ b/mysql-test/r/subquery_sj_none_bka.result @@ -8012,7 +8012,7 @@ EXPLAIN "Country", "Population" ], - "attached_condition": "((`test`.`t1`.`Population` > 5000000) and ((`test`.`t2`.`Code`) = `test`.`t1`.`Country`))" + "attached_condition": "((`test`.`t2`.`Code`) = `test`.`t1`.`Country`)" } } } diff --git a/mysql-test/r/subquery_sj_none_bka_nobnl.result b/mysql-test/r/subquery_sj_none_bka_nobnl.result index 376885e8419..8be40a0f6c6 100644 --- a/mysql-test/r/subquery_sj_none_bka_nobnl.result +++ b/mysql-test/r/subquery_sj_none_bka_nobnl.result @@ -8019,7 +8019,7 @@ EXPLAIN "Country", "Population" ], - "attached_condition": "((`test`.`t1`.`Population` > 5000000) and ((`test`.`t2`.`Code`) = `test`.`t1`.`Country`))" + "attached_condition": "((`test`.`t2`.`Code`) = `test`.`t1`.`Country`)" } } } diff --git a/mysql-test/r/type_temporal_fractional.result b/mysql-test/r/type_temporal_fractional.result index 55160bd50d4..de0e2a7595c 100644 --- a/mysql-test/r/type_temporal_fractional.result +++ b/mysql-test/r/type_temporal_fractional.result @@ -16903,6 +16903,8 @@ Warning 1292 Truncated incorrect time value: '0000-00-00' Warning 1292 Truncated incorrect time value: '2002-11-24' Warning 1292 Truncated incorrect time value: '0000-00-00' Warning 1292 Truncated incorrect time value: '2002-11-24' +Warning 1292 Truncated incorrect time value: '0000-00-00' +Warning 1292 Truncated incorrect time value: '2002-11-24' DROP VIEW v1; DROP TABLE t1; # diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index accd7209f5d..9127ee9c43d 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2704,8 +2704,8 @@ Warning 4095 Delimiter '.' in position 4 in datetime value '2005.01.02' at row 1 Warning 4095 Delimiter '.' in position 4 in datetime value '2005.01.02' at row 1 is deprecated. Prefer the standard '-'. Warning 4095 Delimiter '.' in position 4 in datetime value '2005.01.04' at row 1 is deprecated. Prefer the standard '-'. Warning 4095 Delimiter '.' in position 4 in datetime value '2005.01.04' at row 1 is deprecated. Prefer the standard '-'. -Warning 4095 Delimiter '.' in position 4 in datetime value '2005.01.02' at row 1 is deprecated. Prefer the standard '-'. Warning 4095 Delimiter '.' in position 4 in datetime value '2005.01.04' at row 1 is deprecated. Prefer the standard '-'. +Warning 4095 Delimiter '.' in position 4 in datetime value '2005.01.02' at row 1 is deprecated. Prefer the standard '-'. SELECT * FROM v1 WHERE td BETWEEN CAST('2005.01.02' AS DATE) AND CAST('2005.01.04' AS DATE); id td 2 2005-01-02 @@ -2717,8 +2717,8 @@ Warning 4095 Delimiter '.' in position 4 in datetime value '2005.01.02' at row 1 Warning 4095 Delimiter '.' in position 4 in datetime value '2005.01.02' at row 1 is deprecated. Prefer the standard '-'. Warning 4095 Delimiter '.' in position 4 in datetime value '2005.01.04' at row 1 is deprecated. Prefer the standard '-'. Warning 4095 Delimiter '.' in position 4 in datetime value '2005.01.04' at row 1 is deprecated. Prefer the standard '-'. -Warning 4095 Delimiter '.' in position 4 in datetime value '2005.01.02' at row 1 is deprecated. Prefer the standard '-'. Warning 4095 Delimiter '.' in position 4 in datetime value '2005.01.04' at row 1 is deprecated. Prefer the standard '-'. +Warning 4095 Delimiter '.' in position 4 in datetime value '2005.01.02' at row 1 is deprecated. Prefer the standard '-'. DROP VIEW v1; DROP TABLE t1; create table t1 (a int); @@ -4557,7 +4557,7 @@ FROM t1 JOIN vlo_1 AS dt ON t1.a=dt.a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 NULL ALL NULL NULL NULL NULL # # Using where 1 PRIMARY NULL ref 5 test.t1.a # # NULL -2 DERIVED t2 NULL ALL NULL NULL NULL NULL # # NULL +2 DERIVED t2 NULL ALL NULL NULL NULL NULL # # Using offset pushdown Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`dt`.`a` AS `a`,`test`.`dt`.`b` AS `b` from `test`.`t1` join `test`.`vlo_1` `dt` where (`test`.`dt`.`a` = `test`.`t1`.`a`) SELECT * @@ -4932,13 +4932,13 @@ a b explain SELECT * FROM v1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL ALL NULL NULL NULL NULL # # NULL -3 DERIVED t1 NULL ALL NULL NULL NULL NULL # # NULL +3 DERIVED t1 NULL ALL NULL NULL NULL NULL # # Using offset pushdown Warnings: Note 1003 /* select#1 */ select `dt`.`a` AS `a`,`dt`.`b` AS `b` from (/* select#3 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` limit 3,3) `dt` explain SELECT * FROM (SELECT * FROM t1 LIMIT 3 OFFSET 3) AS dt; id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL ALL NULL NULL NULL NULL # # NULL -2 DERIVED t1 NULL ALL NULL NULL NULL NULL # # NULL +2 DERIVED t1 NULL ALL NULL NULL NULL NULL # # Using offset pushdown Warnings: Note 1003 /* select#1 */ select `dt`.`a` AS `a`,`dt`.`b` AS `b` from (/* select#2 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` limit 3,3) `dt` DROP VIEW v1; diff --git a/mysql-test/suite/gcol/r/gcol_keys_innodb.result b/mysql-test/suite/gcol/r/gcol_keys_innodb.result index 1368fe7126f..1d8e85ce03f 100644 --- a/mysql-test/suite/gcol/r/gcol_keys_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_keys_innodb.result @@ -366,7 +366,7 @@ b 11 EXPLAIN SELECT b FROM t1 FORCE INDEX(b) WHERE b BETWEEN 1 AND 5; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range b b 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 NULL range b b 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`b` AS `b` from `test`.`t1` FORCE INDEX (`b`) where (`test`.`t1`.`b` between 1 and 5) SELECT b FROM t1 FORCE INDEX(b) WHERE b BETWEEN 1 AND 5; @@ -401,7 +401,7 @@ f1 gc 9 10 EXPLAIN SELECT * FROM t1 WHERE f1 + 1 > 7; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where +1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`gc` AS `gc` from `test`.`t1` where (`test`.`t1`.`gc` > 7) SELECT * FROM information_schema.OPTIMIZER_TRACE; @@ -582,7 +582,7 @@ EXPLAIN SELECT * FROM t1 WHERE f1 + 1 > 7 { { "table": "`t1`", "original_table_condition": "(`t1`.`gc` > 7)", - "final_table_condition ": "(`t1`.`gc` > 7)" + "final_table_condition ": null } ] /* finalizing_table_conditions */ }, @@ -629,7 +629,7 @@ f1 gc 6 7 EXPLAIN SELECT * FROM t1 WHERE f1 + 1 BETWEEN 5 AND 7; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 Using where +1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 3 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`gc` AS `gc` from `test`.`t1` where (`test`.`t1`.`gc` between 5 and 7) # Check that expression isn't transformed for a disabled key @@ -1042,7 +1042,7 @@ f1 gc_int gc_date # INT column & index should be picked EXPLAIN SELECT * FROM t1 WHERE f1 + 1 > 070707; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range gc_int_idx gc_int_idx 5 NULL 4 100.00 Using index condition +1 SIMPLE t1 NULL range gc_int_idx gc_int_idx 5 NULL 4 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`gc_int` AS `gc_int`,`test`.`t1`.`gc_date` AS `gc_date` from `test`.`t1` where (`test`.`t1`.`gc_int` > 70707) SELECT * FROM t1 WHERE f1 + 1 > CAST(070707 AS DATE); @@ -1054,9 +1054,9 @@ f1 gc_int gc_date # DATE column & index should be picked EXPLAIN SELECT * FROM t1 WHERE f1 + 1 > CAST(070707 AS DATE); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range gc_date_idx gc_date_idx 4 NULL 4 100.00 Using index condition +1 SIMPLE t1 NULL range gc_date_idx gc_date_idx 4 NULL 4 100.00 NULL Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`gc_int` AS `gc_int`,`test`.`t1`.`gc_date` AS `gc_date` from `test`.`t1` where (`test`.`t1`.`gc_date` > (cast(70707 as date))) +Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`gc_int` AS `gc_int`,`test`.`t1`.`gc_date` AS `gc_date` from `test`.`t1` where (`test`.`t1`.`gc_date` > cast(70707 as date)) DROP TABLE t1; # # BUG#21229846: WL8170: SIGNAL 11 IN JOIN::MAKE_SUM_FUNC_LIST @@ -1351,7 +1351,7 @@ a b 1 1 EXPLAIN SELECT a, b FROM t WHERE (a OR b) BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t NULL range gc_or gc_or 5 NULL 3 100.00 Using index condition +1 SIMPLE t NULL range gc_or gc_or 5 NULL 3 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t`.`a` AS `a`,`test`.`t`.`b` AS `b` from `test`.`t` where (`test`.`t`.`gc_or` between 1 and 10) SELECT a, b FROM t WHERE (a OR b) BETWEEN 1 AND 10; @@ -1610,7 +1610,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK EXPLAIN SELECT i FROM t1 WHERE gc2 <= 'ksatefksatefx'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range gc2_key,gc2_key_prefix gc2_key 58 NULL 3 100.00 Using where +1 SIMPLE t1 NULL range gc2_key,gc2_key_prefix gc2_key 58 NULL 3 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`i` AS `i` from `test`.`t1` where (`test`.`t1`.`gc2` <= 'ksatefksatefx') SELECT i FROM t1 WHERE gc2 <= 'ksatefksatefx'; @@ -1632,7 +1632,7 @@ i 3 EXPLAIN SELECT COUNT(*) FROM t1 WHERE gc2 <= 'ksatefksatefx'; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range gc2_key,gc2_key_prefix gc2_key 58 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 NULL range gc2_key,gc2_key_prefix gc2_key 58 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select count(0) AS `COUNT(*)` from `test`.`t1` where (`test`.`t1`.`gc2` <= 'ksatefksatefx') SELECT COUNT(*) FROM t1 WHERE gc2 <= 'ksatefksatefx'; diff --git a/mysql-test/suite/gcol/r/gcol_keys_myisam.result b/mysql-test/suite/gcol/r/gcol_keys_myisam.result index a9b074a6510..32be57f299e 100644 --- a/mysql-test/suite/gcol/r/gcol_keys_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_keys_myisam.result @@ -150,7 +150,7 @@ f1 gc 9 10 EXPLAIN SELECT * FROM t1 WHERE f1 + 1 > 7; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 4 100.00 Using index condition +1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 4 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`gc` AS `gc` from `test`.`t1` where (`test`.`t1`.`gc` > 7) SELECT * FROM information_schema.OPTIMIZER_TRACE; @@ -331,16 +331,14 @@ EXPLAIN SELECT * FROM t1 WHERE f1 + 1 > 7 { { "table": "`t1`", "original_table_condition": "(`t1`.`gc` > 7)", - "final_table_condition ": "(`t1`.`gc` > 7)" + "final_table_condition ": null } ] /* finalizing_table_conditions */ }, { "refine_plan": [ { - "table": "`t1`", - "pushed_index_condition": "(`t1`.`gc` > 7)", - "table_condition_attached": null + "table": "`t1`" } ] /* refine_plan */ } @@ -380,7 +378,7 @@ f1 gc 6 7 EXPLAIN SELECT * FROM t1 WHERE f1 + 1 BETWEEN 5 AND 7; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`gc` AS `gc` from `test`.`t1` where (`test`.`t1`.`gc` between 5 and 7) # Check that expression isn't transformed for a disabled key @@ -795,7 +793,7 @@ f1 gc_int gc_date # INT column & index should be picked EXPLAIN SELECT * FROM t1 WHERE f1 + 1 > 070707; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range gc_int_idx gc_int_idx 5 NULL 5 100.00 Using index condition +1 SIMPLE t1 NULL range gc_int_idx gc_int_idx 5 NULL 5 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`gc_int` AS `gc_int`,`test`.`t1`.`gc_date` AS `gc_date` from `test`.`t1` where (`test`.`t1`.`gc_int` > 70707) SELECT * FROM t1 WHERE f1 + 1 > CAST(070707 AS DATE); @@ -807,9 +805,9 @@ f1 gc_int gc_date # DATE column & index should be picked EXPLAIN SELECT * FROM t1 WHERE f1 + 1 > CAST(070707 AS DATE); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range gc_date_idx gc_date_idx 4 NULL 5 100.00 Using index condition +1 SIMPLE t1 NULL range gc_date_idx gc_date_idx 4 NULL 5 100.00 NULL Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`gc_int` AS `gc_int`,`test`.`t1`.`gc_date` AS `gc_date` from `test`.`t1` where (`test`.`t1`.`gc_date` > (cast(70707 as date))) +Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`gc_int` AS `gc_int`,`test`.`t1`.`gc_date` AS `gc_date` from `test`.`t1` where (`test`.`t1`.`gc_date` > cast(70707 as date)) DROP TABLE t1; # # BUG#21229846: WL8170: SIGNAL 11 IN JOIN::MAKE_SUM_FUNC_LIST @@ -904,7 +902,7 @@ a b 1 1 EXPLAIN SELECT a, b FROM t WHERE (a OR b) BETWEEN 1 AND 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t NULL range gc_or gc_or 5 NULL 2 100.00 Using index condition +1 SIMPLE t NULL range gc_or gc_or 5 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t`.`a` AS `a`,`test`.`t`.`b` AS `b` from `test`.`t` where (`test`.`t`.`gc_or` between 1 and 10) SELECT a, b FROM t WHERE (a OR b) BETWEEN 1 AND 10; diff --git a/mysql-test/suite/gcol/r/gcol_select_innodb.result b/mysql-test/suite/gcol/r/gcol_select_innodb.result index e627c6f39aa..59e020688f2 100644 --- a/mysql-test/suite/gcol/r/gcol_select_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_select_innodb.result @@ -65,9 +65,9 @@ a b c 1 -1 -1 explain select * from t3 where c>=-1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range c c 5 NULL 1 100.00 Using index condition +1 SIMPLE t3 NULL range c c 5 NULL 1 100.00 NULL Warnings: -Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` >= (-(1))) +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` >= -(1)) # select_type=SIMPLE, type=ref select * from t1,t3 where t1.c=t3.c and t3.c=-1; a b c a b c @@ -103,7 +103,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE t3 NULL range c c 5 NULL 2 100.00 Using where; Using index 1 SIMPLE t1 NULL ref c c 5 test.t3.c 1 100.00 NULL Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t3` join `test`.`t1` where ((`test`.`t1`.`c` = `test`.`t3`.`c`) and (`test`.`t3`.`c` between (-(2)) and (-(1)))) +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t3` join `test`.`t1` where ((`test`.`t1`.`c` = `test`.`t3`.`c`) and (`test`.`t3`.`c` between -(2) and -(1))) # select_type=UNION, type=system # select_type=UNION RESULT, type= select * from t1 union select * from t2; @@ -182,9 +182,9 @@ a b c 2 -2 -2 explain select * from t3 where c >= -2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range c c 5 NULL 2 100.00 Using index condition +1 SIMPLE t3 NULL range c c 5 NULL 2 100.00 NULL Warnings: -Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` >= (-(2))) +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` >= -(2)) # SELECT * FROM tbl_name WHERE select * from t3 where a between 1 and 2; a b c @@ -192,7 +192,7 @@ a b c 2 -2 -2 explain select * from t3 where a between 1 and 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where +1 SIMPLE t3 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`a` between 1 and 2) # SELECT * FROM tbl_name WHERE @@ -212,9 +212,9 @@ a b c 2 -2 -2 explain select * from t3 where c between -2 and -1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range c c 5 NULL 2 100.00 Using index condition +1 SIMPLE t3 NULL range c c 5 NULL 2 100.00 NULL Warnings: -Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` between (-(2)) and (-(1))) +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` between -(2) and -(1)) # SELECT * FROM tbl_name WHERE ORDER BY select * from t3 where a between 1 and 2 order by b; a b c @@ -222,7 +222,7 @@ a b c 1 -1 -1 explain select * from t3 where a between 1 and 2 order by b; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using filesort +1 SIMPLE t3 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`a` between 1 and 2) order by `test`.`t3`.`b` # bug#20022189: WL411:DEBUG ASSERT AT FIELD_LONG::VAL_INT IN SQL/FIELD.CC @@ -233,7 +233,7 @@ a b c 1 -1 -1 explain select * from t3 where a between 1 and 2 order by c; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using filesort +1 SIMPLE t3 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`a` between 1 and 2) order by `test`.`t3`.`c` # bug#20022189: WL411:DEBUG ASSERT AT FIELD_LONG::VAL_INT IN SQL/FIELD.CC @@ -269,7 +269,7 @@ a b c 1 -1 -1 explain select * from t3 where a between 1 and 2 order by c; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using filesort +1 SIMPLE t3 NULL range PRIMARY PRIMARY 4 NULL 2 100.00 Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`a` between 1 and 2) order by `test`.`t3`.`c` # SELECT * FROM tbl_name WHERE ORDER BY @@ -299,9 +299,9 @@ a b c 1 -1 -1 explain select * from t3 where c between -2 and -1 order by b; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range c c 5 NULL 2 100.00 Using index condition; Using filesort +1 SIMPLE t3 NULL range c c 5 NULL 2 100.00 Using filesort Warnings: -Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` between (-(2)) and (-(1))) order by `test`.`t3`.`b` +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` between -(2) and -(1)) order by `test`.`t3`.`b` # SELECT * FROM tbl_name WHERE ORDER BY select * from t3 where b between -2 and -1 order by c; a b c @@ -319,9 +319,9 @@ a b c 1 -1 -1 explain select * from t3 where c between -2 and -1 order by c; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range c c 5 NULL 2 100.00 Using index condition +1 SIMPLE t3 NULL range c c 5 NULL 2 100.00 NULL Warnings: -Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` between (-(2)) and (-(1))) order by `test`.`t3`.`c` +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` between -(2) and -(1)) order by `test`.`t3`.`c` # SELECT sum() FROM tbl_name GROUP BY select sum(b) from t1 group by b; sum(b) @@ -818,7 +818,7 @@ KEY (col_int_key) INSERT INTO cc (col_int_nokey) VALUES (0),(1),(7),(0),(4),(5); EXPLAIN SELECT pk FROM cc WHERE col_int_key > 3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE cc NULL range col_int_key col_int_key 5 NULL # # Using where; Using index +1 SIMPLE cc NULL range col_int_key col_int_key 5 NULL # # Using index Warnings: Note 1003 /* select#1 */ select `test`.`cc`.`pk` AS `pk` from `test`.`cc` where (`test`.`cc`.`col_int_key` > 3) SELECT pk FROM cc WHERE col_int_key > 3; @@ -828,7 +828,7 @@ pk 6 EXPLAIN SELECT pk FROM cc WHERE col_int_key > 3 ORDER BY 1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE cc NULL range col_int_key col_int_key 5 NULL # # Using where; Using index; Using filesort +1 SIMPLE cc NULL range col_int_key col_int_key 5 NULL # # Using index; Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`cc`.`pk` AS `pk` from `test`.`cc` where (`test`.`cc`.`col_int_key` > 3) order by `test`.`cc`.`pk` SELECT pk FROM cc WHERE col_int_key > 3 ORDER BY 1; @@ -1148,7 +1148,7 @@ Note 1003 /* select#1 */ select `test`.`t1`.`b` AS `b` from `test`.`t1` FORCE IN INSERT INTO t1 (id) VALUES(4),(5),(6),(7),(8),(9),(10); EXPLAIN SELECT b FROM t1 FORCE INDEX(b) WHERE b BETWEEN 1 AND 5; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range b b 4 NULL 3 100.00 Using where; Using index +1 SIMPLE t1 NULL range b b 4 NULL 3 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`b` AS `b` from `test`.`t1` FORCE INDEX (`b`) where (`test`.`t1`.`b` between 1 and 5) EXPLAIN SELECT * FROM t2 AS t1 WHERE b NOT IN (SELECT b FROM t1 FORCE INDEX(b)); @@ -1258,7 +1258,7 @@ FROM t0 AS a0, t0 AS a1, t0 AS a2; EXPLAIN SELECT * FROM t1 WHERE i1 > 41 AND i1 <= 43; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx idx 4 NULL 20 100.00 Using index condition; Using MRR +1 SIMPLE t1 NULL range idx idx 4 NULL 20 100.00 Using MRR Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t1`.`i2` AS `i2`,`test`.`t1`.`v1` AS `v1`,`test`.`t1`.`v2` AS `v2` from `test`.`t1` where ((`test`.`t1`.`i1` > 41) and (`test`.`t1`.`i1` <= 43)) SELECT * FROM t1 @@ -1288,7 +1288,7 @@ ALTER TABLE t1 ADD INDEX idx2(v1); EXPLAIN SELECT * FROM t1 WHERE v1 > 41 AND v1 <= 43; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx2 idx2 5 NULL 20 100.00 Using where; Using MRR +1 SIMPLE t1 NULL range idx2 idx2 5 NULL 20 100.00 Using MRR Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t1`.`i2` AS `i2`,`test`.`t1`.`v1` AS `v1`,`test`.`t1`.`v2` AS `v2` from `test`.`t1` where ((`test`.`t1`.`v1` > 41) and (`test`.`t1`.`v1` <= 43)) SELECT * FROM t1 diff --git a/mysql-test/suite/gcol/r/gcol_select_myisam.result b/mysql-test/suite/gcol/r/gcol_select_myisam.result index d6978e42902..1a7ba557917 100644 --- a/mysql-test/suite/gcol/r/gcol_select_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_select_myisam.result @@ -65,9 +65,9 @@ a b c 1 -1 -1 explain select * from t3 where c>=-1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range c c 5 NULL 2 100.00 Using index condition +1 SIMPLE t3 NULL range c c 5 NULL 2 100.00 NULL Warnings: -Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` >= (-(1))) +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` >= -(1)) # select_type=SIMPLE, type=ref select * from t1,t3 where t1.c=t3.c and t3.c=-1; a b c a b c @@ -103,7 +103,7 @@ id select_type table partitions type possible_keys key key_len ref rows filtered 1 SIMPLE t3 NULL range c c 5 NULL 1 100.00 Using where; Using index 1 SIMPLE t1 NULL ref c c 5 test.t3.c 1 100.00 NULL Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t3` join `test`.`t1` where ((`test`.`t1`.`c` = `test`.`t3`.`c`) and (`test`.`t3`.`c` between (-(2)) and (-(1)))) +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t3` join `test`.`t1` where ((`test`.`t1`.`c` = `test`.`t3`.`c`) and (`test`.`t3`.`c` between -(2) and -(1))) # select_type=UNION, type=system # select_type=UNION RESULT, type= select * from t1 union select * from t2; @@ -182,9 +182,9 @@ a b c 2 -2 -2 explain select * from t3 where c >= -2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range c c 5 NULL 2 100.00 Using index condition +1 SIMPLE t3 NULL range c c 5 NULL 2 100.00 NULL Warnings: -Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` >= (-(2))) +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` >= -(2)) # SELECT * FROM tbl_name WHERE select * from t3 where a between 1 and 2; a b c @@ -192,7 +192,7 @@ a b c 2 -2 -2 explain select * from t3 where a between 1 and 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range PRIMARY PRIMARY 4 NULL 1 100.00 Using index condition +1 SIMPLE t3 NULL range PRIMARY PRIMARY 4 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`a` between 1 and 2) # SELECT * FROM tbl_name WHERE @@ -212,9 +212,9 @@ a b c 2 -2 -2 explain select * from t3 where c between -2 and -1; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range c c 5 NULL 1 100.00 Using index condition +1 SIMPLE t3 NULL range c c 5 NULL 1 100.00 NULL Warnings: -Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` between (-(2)) and (-(1))) +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` between -(2) and -(1)) # bug#20022189: WL411:DEBUG ASSERT AT FIELD_LONG::VAL_INT IN SQL/FIELD.CC CREATE TABLE t4 ( `pk` int(11) NOT NULL , @@ -248,7 +248,7 @@ a b c 1 -1 -1 explain select * from t3 where a between 1 and 2 order by c; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range PRIMARY PRIMARY 4 NULL 1 100.00 Using index condition; Using filesort +1 SIMPLE t3 NULL range PRIMARY PRIMARY 4 NULL 1 100.00 Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`a` between 1 and 2) order by `test`.`t3`.`c` # SELECT * FROM tbl_name WHERE ORDER BY @@ -268,9 +268,9 @@ a b c 2 -2 -2 explain select * from t3 where c between -2 and -1 order by a; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range c c 5 NULL 1 100.00 Using index condition; Using filesort +1 SIMPLE t3 NULL range c c 5 NULL 1 100.00 Using filesort Warnings: -Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` between (-(2)) and (-(1))) order by `test`.`t3`.`a` +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` between -(2) and -(1)) order by `test`.`t3`.`a` # SELECT * FROM tbl_name WHERE ORDER BY select * from t3 where b between -2 and -1 order by b; a b c @@ -288,9 +288,9 @@ a b c 1 -1 -1 explain select * from t3 where c between -2 and -1 order by b; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range c c 5 NULL 1 100.00 Using index condition; Using filesort +1 SIMPLE t3 NULL range c c 5 NULL 1 100.00 Using filesort Warnings: -Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` between (-(2)) and (-(1))) order by `test`.`t3`.`b` +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` between -(2) and -(1)) order by `test`.`t3`.`b` # SELECT * FROM tbl_name WHERE ORDER BY select * from t3 where b between -2 and -1 order by c; a b c @@ -308,9 +308,9 @@ a b c 1 -1 -1 explain select * from t3 where c between -2 and -1 order by c; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t3 NULL range c c 5 NULL 1 100.00 Using index condition +1 SIMPLE t3 NULL range c c 5 NULL 1 100.00 NULL Warnings: -Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` between (-(2)) and (-(1))) order by `test`.`t3`.`c` +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c` from `test`.`t3` where (`test`.`t3`.`c` between -(2) and -(1)) order by `test`.`t3`.`c` # SELECT sum() FROM tbl_name GROUP BY select sum(b) from t1 group by b; sum(b) @@ -657,7 +657,7 @@ FROM t0 AS a0, t0 AS a1, t0 AS a2; EXPLAIN SELECT * FROM t1 WHERE i1 > 41 AND i1 <= 43; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range idx idx 4 NULL 19 100.00 Using index condition; Using MRR +1 SIMPLE t1 NULL range idx idx 4 NULL 19 100.00 Using MRR Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t1`.`i2` AS `i2`,`test`.`t1`.`v1` AS `v1`,`test`.`t1`.`v2` AS `v2` from `test`.`t1` where ((`test`.`t1`.`i1` > 41) and (`test`.`t1`.`i1` <= 43)) SELECT * FROM t1 diff --git a/mysql-test/suite/innodb/r/innodb-index-online.result b/mysql-test/suite/innodb/r/innodb-index-online.result index 7f945ad60a6..0b47c1cdc4e 100644 --- a/mysql-test/suite/innodb/r/innodb-index-online.result +++ b/mysql-test/suite/innodb/r/innodb-index-online.result @@ -160,7 +160,7 @@ t1 0 PRIMARY 1 c1 A 80 NULL NULL BTREE YES NULL t1 1 c2d 1 c2 A 5 NULL NULL YES BTREE YES NULL EXPLAIN SELECT COUNT(*) FROM t1 WHERE c2 > 3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range c2d c2d 5 NULL 32 100.00 Using where; Using index +1 SIMPLE t1 NULL range c2d c2d 5 NULL 32 100.00 Using index Warnings: Note 1003 /* select#1 */ select count(0) AS `COUNT(*)` from `test`.`t1` where (`test`.`t1`.`c2` > 3) SHOW CREATE TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index 6864640c2b3..10019291291 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -838,7 +838,7 @@ create table t1 (a int primary key,b int, c int, d int, e int, f int, g int, h insert into t1 values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1); explain select * from t1 where a > 0 and a < 50; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL # 100.00 Using where +1 SIMPLE t1 NULL range PRIMARY PRIMARY 4 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d`,`test`.`t1`.`e` AS `e`,`test`.`t1`.`f` AS `f`,`test`.`t1`.`g` AS `g`,`test`.`t1`.`h` AS `h`,`test`.`t1`.`i` AS `i`,`test`.`t1`.`j` AS `j`,`test`.`t1`.`k` AS `k`,`test`.`t1`.`l` AS `l`,`test`.`t1`.`m` AS `m`,`test`.`t1`.`n` AS `n`,`test`.`t1`.`o` AS `o`,`test`.`t1`.`p` AS `p`,`test`.`t1`.`q` AS `q`,`test`.`t1`.`r` AS `r`,`test`.`t1`.`s` AS `s`,`test`.`t1`.`t` AS `t`,`test`.`t1`.`u` AS `u`,`test`.`t1`.`v` AS `v`,`test`.`t1`.`w` AS `w`,`test`.`t1`.`x` AS `x`,`test`.`t1`.`y` AS `y`,`test`.`t1`.`z` AS `z`,`test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`a3` AS `a3`,`test`.`t1`.`a4` AS `a4`,`test`.`t1`.`a5` AS `a5`,`test`.`t1`.`a6` AS `a6`,`test`.`t1`.`a7` AS `a7`,`test`.`t1`.`a8` AS `a8`,`test`.`t1`.`a9` AS `a9`,`test`.`t1`.`b1` AS `b1`,`test`.`t1`.`b2` AS `b2`,`test`.`t1`.`b3` AS `b3`,`test`.`t1`.`b4` AS `b4`,`test`.`t1`.`b5` AS `b5`,`test`.`t1`.`b6` AS `b6` from `test`.`t1` where ((`test`.`t1`.`a` > 0) and (`test`.`t1`.`a` < 50)) drop table t1; @@ -1325,7 +1325,7 @@ count(*) 623 explain select * from t1 where c between 1 and 2500; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range c c 5 NULL # 100.00 Using index condition +1 SIMPLE t1 NULL range c c 5 NULL # 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (`test`.`t1`.`c` between 1 and 2500) update t1 set c=a; diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index f98e014106b..babc7104a99 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -1551,7 +1551,7 @@ INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1; INSERT INTO t1 (a,b,c) SELECT a+8,b,c FROM t1; EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range t1_b t1_b 5 NULL 16 100.00 Using index condition; Backward index scan +1 SIMPLE t1 NULL range t1_b t1_b 5 NULL 16 100.00 Backward index scan Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (`test`.`t1`.`b` = 1) order by `test`.`t1`.`a` desc limit 5 SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5; @@ -2153,7 +2153,7 @@ key_len 5 ref NULL rows 10 filtered 100.00 -Extra Using where; Using index +Extra Using index Warnings: Level Note Code 1003 @@ -2911,7 +2911,7 @@ f1 f2 f3 f4 EXPLAIN SELECT * FROM t1 WHERE f2 = 1 AND f4 = TRUE ORDER BY f1 DESC LIMIT 5; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range f2,f4 f4 1 NULL 22 100.00 Using index condition; Using where; Backward index scan +1 SIMPLE t1 NULL range f2,f4 f4 1 NULL 22 100.00 Using where; Backward index scan Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t1`.`f3` AS `f3`,`test`.`t1`.`f4` AS `f4` from `test`.`t1` where ((`test`.`t1`.`f4` = true) and (`test`.`t1`.`f2` = 1)) order by `test`.`t1`.`f1` desc limit 5 DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/monitor.result b/mysql-test/suite/innodb/r/monitor.result index 763b8154cf4..4ecaa577d69 100644 --- a/mysql-test/suite/innodb/r/monitor.result +++ b/mysql-test/suite/innodb/r/monitor.result @@ -281,6 +281,7 @@ innodb_rwlock_s_os_waits disabled innodb_rwlock_x_os_waits disabled innodb_rwlock_sx_os_waits disabled dml_reads disabled +dml_reads_skipped_by_offset_pushdown disabled dml_inserts disabled dml_deletes disabled dml_updates disabled @@ -538,6 +539,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 4 NULL 4 4 NULL 4 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 1 NULL 1 1 NULL 1 enabled dml_deletes 0 NULL 0 0 NULL 0 enabled dml_updates 2 NULL 2 2 NULL 2 enabled @@ -552,6 +554,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 6 NULL 6 6 NULL 6 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 1 NULL 1 1 NULL 1 enabled dml_deletes 2 NULL 2 2 NULL 2 enabled dml_updates 2 NULL 2 2 NULL 2 enabled @@ -566,6 +569,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 6 NULL 6 0 NULL 0 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 1 NULL 1 0 NULL 0 enabled dml_deletes 2 NULL 2 0 NULL 0 enabled dml_updates 2 NULL 2 0 NULL 0 enabled @@ -582,6 +586,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 8 NULL 8 2 NULL 2 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 3 NULL 3 2 NULL 2 enabled dml_deletes 4 NULL 4 2 NULL 2 enabled dml_updates 2 NULL 2 0 NULL 0 enabled @@ -596,6 +601,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 8 NULL 8 2 NULL 2 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 3 NULL 3 2 NULL 2 enabled dml_deletes 4 NULL 4 2 NULL 2 enabled dml_updates 2 NULL 2 0 NULL 0 enabled @@ -610,6 +616,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 8 NULL 8 2 NULL 2 disabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 disabled dml_inserts 3 NULL 3 2 NULL 2 disabled dml_deletes 4 NULL 4 2 NULL 2 disabled dml_updates 2 NULL 2 0 NULL 0 disabled @@ -624,6 +631,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads NULL NULL 0 NULL NULL 0 disabled +dml_reads_skipped_by_offset_pushdown NULL NULL 0 NULL NULL 0 disabled dml_inserts NULL NULL 0 NULL NULL 0 disabled dml_deletes NULL NULL 0 NULL NULL 0 disabled dml_updates NULL NULL 0 NULL NULL 0 disabled @@ -641,6 +649,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads NULL NULL 0 NULL NULL 0 disabled +dml_reads_skipped_by_offset_pushdown NULL NULL 0 NULL NULL 0 disabled dml_inserts 2 NULL 2 2 NULL 2 enabled dml_deletes NULL NULL 0 NULL NULL 0 disabled dml_updates NULL NULL 0 NULL NULL 0 disabled @@ -658,6 +667,7 @@ where name like "file_num_open_files"; name max_count min_count count max_count_reset min_count_reset count_reset status file_num_open_files # # # # # # enabled set global innodb_monitor_disable = file_num_open_files; +set empty_redundant_check_in_range_scan=false; set global innodb_monitor_enable = "icp%"; create table monitor_test(a char(3), b int, c char(2), primary key (a(1), c(1)), key(b)) engine = innodb; @@ -681,6 +691,7 @@ icp_attempts 2 icp_no_match 0 icp_out_of_range 1 icp_match 1 +set empty_redundant_check_in_range_scan=true; drop table monitor_test; set global innodb_monitor_disable = all; set global innodb_monitor_reset_all = all; diff --git a/mysql-test/suite/innodb/r/multi_value_basic.result b/mysql-test/suite/innodb/r/multi_value_basic.result index 708e499a3e8..455d17bb873 100644 --- a/mysql-test/suite/innodb/r/multi_value_basic.result +++ b/mysql-test/suite/innodb/r/multi_value_basic.result @@ -1175,7 +1175,7 @@ id doc_id doc 5 2 {"val": [4, 5]} EXPLAIN SELECT * FROM t FORCE INDEX (mv_doc_id) WHERE doc_id > 0; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t NULL range mv_doc_id mv_doc_id 5 NULL 15 100.00 Using where +1 SIMPLE t NULL range mv_doc_id mv_doc_id 5 NULL 15 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t`.`id` AS `id`,`test`.`t`.`doc_id` AS `doc_id`,`test`.`t`.`doc` AS `doc` from `test`.`t` FORCE INDEX (`mv_doc_id`) where (`test`.`t`.`doc_id` > 0) SELECT * FROM t FORCE INDEX (mv_doc_id) WHERE doc_id > 0; @@ -1195,7 +1195,7 @@ id doc_id doc 4 NULL {"val": [3, 4, 5]} EXPLAIN SELECT * FROM t FORCE INDEX (mv_doc_id) WHERE doc_id >= 1 AND doc_id < 2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t NULL range mv_doc_id mv_doc_id 5 NULL 4 100.00 Using where +1 SIMPLE t NULL range mv_doc_id mv_doc_id 5 NULL 4 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t`.`id` AS `id`,`test`.`t`.`doc_id` AS `doc_id`,`test`.`t`.`doc` AS `doc` from `test`.`t` FORCE INDEX (`mv_doc_id`) where ((`test`.`t`.`doc_id` >= 1) and (`test`.`t`.`doc_id` < 2)) SELECT * FROM t FORCE INDEX (mv_doc_id) WHERE doc_id >= 1 AND doc_id < 2; diff --git a/mysql-test/suite/innodb/t/monitor.test b/mysql-test/suite/innodb/t/monitor.test index 5a8bd2ac156..210525c23ad 100644 --- a/mysql-test/suite/innodb/t/monitor.test +++ b/mysql-test/suite/innodb/t/monitor.test @@ -357,6 +357,7 @@ where name like "file_num_open_files"; set global innodb_monitor_disable = file_num_open_files; # Test ICP module counters +set empty_redundant_check_in_range_scan=false; set global innodb_monitor_enable = "icp%"; create table monitor_test(a char(3), b int, c char(2), @@ -377,7 +378,7 @@ select a from monitor_test where b < 3 for update; --skip_if_hypergraph # Does not support index condition pushdown. select name, count from information_schema.innodb_metrics where name like "icp%"; - +set empty_redundant_check_in_range_scan=true; drop table monitor_test; set global innodb_monitor_disable = all; diff --git a/mysql-test/suite/json/r/json_gcol_innodb.result b/mysql-test/suite/json/r/json_gcol_innodb.result index a6de193ed0c..a0b4699b944 100644 --- a/mysql-test/suite/json/r/json_gcol_innodb.result +++ b/mysql-test/suite/json/r/json_gcol_innodb.result @@ -194,7 +194,7 @@ f1 "zxc" explain select f1 from t1 where gc > "z"; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range gc_idx gc_idx 83 NULL 4 100.00 Using where +1 SIMPLE t1 NULL range gc_idx gc_idx 83 NULL 4 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1` from `test`.`t1` where (`test`.`t1`.`gc` > 'z') select f1 from t1 where gc > @string_literal; @@ -216,7 +216,7 @@ f1 "zxc" explain select f1 from t1 where json_extract(f1,"$") > "z"; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range gc_idx gc_idx 83 NULL 4 100.00 Using where +1 SIMPLE t1 NULL range gc_idx gc_idx 83 NULL 4 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1` from `test`.`t1` where (`test`.`t1`.`gc` > 'z') select f1 from t1 where json_extract(f1,"$") > @string_literal; @@ -240,7 +240,7 @@ f1 "vbn" explain select f1 from t1 where gc > "v" and gc < "z"; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range gc_idx gc_idx 83 NULL 4 100.00 Using where +1 SIMPLE t1 NULL range gc_idx gc_idx 83 NULL 4 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1` from `test`.`t1` where ((`test`.`t1`.`gc` > 'v') and (`test`.`t1`.`gc` < 'z')) select f1 from t1 where gc > @string_lo and gc < @string_hi; @@ -283,7 +283,7 @@ f1 "vbn" explain select f1 from t1 where gc between "v" and "z"; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range gc_idx gc_idx 83 NULL 4 100.00 Using where +1 SIMPLE t1 NULL range gc_idx gc_idx 83 NULL 4 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1` from `test`.`t1` where (`test`.`t1`.`gc` between 'v' and 'z') select f1 from t1 where gc between @string_lo and @string_hi; @@ -307,7 +307,7 @@ Warning 1235 This version of MySQL doesn't yet support 'comparison of JSON in th Warnings: explain select f1 from t1 where json_extract(f1,"$") between "v" and "z"; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range gc_idx gc_idx 83 NULL 4 100.00 Using where +1 SIMPLE t1 NULL range gc_idx gc_idx 83 NULL 4 100.00 NULL Warnings: Warning 1235 This version of MySQL doesn't yet support 'comparison of JSON in the BETWEEN operator' Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1` from `test`.`t1` where (`test`.`t1`.`gc` between 'v' and 'z') diff --git a/mysql-test/suite/opt_trace/r/derived_condition_pushdown.result b/mysql-test/suite/opt_trace/r/derived_condition_pushdown.result index 7107e305ec1..a662cf6437e 100644 --- a/mysql-test/suite/opt_trace/r/derived_condition_pushdown.result +++ b/mysql-test/suite/opt_trace/r/derived_condition_pushdown.result @@ -306,16 +306,14 @@ trace { "table": "`t1`", "original_table_condition": "(`t1`.`f1` > 2)", - "final_table_condition ": "(`t1`.`f1` > 2)" + "final_table_condition ": null } ] }, { "refine_plan": [ { - "table": "`t1`", - "pushed_index_condition": "(`t1`.`f1` > 2)", - "table_condition_attached": null + "table": "`t1`" } ] }, @@ -1795,7 +1793,7 @@ trace { "table": "`t1`", "original_table_condition": "((`t1`.`f1` > 26) and (cast(`t1`.`f1` as decimal(10,2)) > 31))", - "final_table_condition ": "((`t1`.`f1` > 26) and (cast(`t1`.`f1` as decimal(10,2)) > 31))" + "final_table_condition ": "(cast(`t1`.`f1` as decimal(10,2)) > 31)" } ] }, diff --git a/mysql-test/suite/opt_trace/r/eq_range_statistics.result b/mysql-test/suite/opt_trace/r/eq_range_statistics.result index 5534b6cf080..32975fade6d 100644 --- a/mysql-test/suite/opt_trace/r/eq_range_statistics.result +++ b/mysql-test/suite/opt_trace/r/eq_range_statistics.result @@ -1374,7 +1374,7 @@ EXPLAIN SELECT * FROM t1 WHERE a>5 AND (b=2 OR b=3 OR b=4) { { "table": "`t1`", "original_table_condition": "((`t1`.`a` > 5) and ((`t1`.`b` = 2) or (`t1`.`b` = 3) or (`t1`.`b` = 4)))", - "final_table_condition ": "((`t1`.`a` > 5) and ((`t1`.`b` = 2) or (`t1`.`b` = 3) or (`t1`.`b` = 4)))" + "final_table_condition ": "((`t1`.`b` = 2) or (`t1`.`b` = 3) or (`t1`.`b` = 4))" } ] /* finalizing_table_conditions */ }, diff --git a/mysql-test/suite/opt_trace/r/general_no_prot_all.result b/mysql-test/suite/opt_trace/r/general_no_prot_all.result index b316a9fbfb0..63a18623c9d 100644 --- a/mysql-test/suite/opt_trace/r/general_no_prot_all.result +++ b/mysql-test/suite/opt_trace/r/general_no_prot_all.result @@ -7554,7 +7554,7 @@ insert into t6 select * from t6 where d>7 { { "table": "`t6`", "original_table_condition": "(`t6`.`d` > 7)", - "final_table_condition ": "(`t6`.`d` > 7)" + "final_table_condition ": null } ] /* finalizing_table_conditions */ }, @@ -7793,7 +7793,7 @@ update t5, t6 set t6.d=t6.d+t5.c+4-t5.c-4 where d>7000 { { "table": "`t6`", "original_table_condition": "(`t6`.`d` > 7000)", - "final_table_condition ": "(`t6`.`d` > 7000)" + "final_table_condition ": null } ] /* finalizing_table_conditions */ }, @@ -8021,7 +8021,7 @@ delete t6 from t5, t6 where d>7000 { { "table": "`t6`", "original_table_condition": "(`t6`.`d` > 7000)", - "final_table_condition ": "(`t6`.`d` > 7000)" + "final_table_condition ": null } ] /* finalizing_table_conditions */ }, diff --git a/mysql-test/suite/opt_trace/r/general_no_prot_none.result b/mysql-test/suite/opt_trace/r/general_no_prot_none.result index b29a3dd0f7e..8717c12d978 100644 --- a/mysql-test/suite/opt_trace/r/general_no_prot_none.result +++ b/mysql-test/suite/opt_trace/r/general_no_prot_none.result @@ -6137,7 +6137,7 @@ insert into t6 select * from t6 where d>7 { { "table": "`t6`", "original_table_condition": "(`t6`.`d` > 7)", - "final_table_condition ": "(`t6`.`d` > 7)" + "final_table_condition ": null } ] /* finalizing_table_conditions */ }, @@ -6376,7 +6376,7 @@ update t5, t6 set t6.d=t6.d+t5.c+4-t5.c-4 where d>7000 { { "table": "`t6`", "original_table_condition": "(`t6`.`d` > 7000)", - "final_table_condition ": "(`t6`.`d` > 7000)" + "final_table_condition ": null } ] /* finalizing_table_conditions */ }, @@ -6604,7 +6604,7 @@ delete t6 from t5, t6 where d>7000 { { "table": "`t6`", "original_table_condition": "(`t6`.`d` > 7000)", - "final_table_condition ": "(`t6`.`d` > 7000)" + "final_table_condition ": null } ] /* finalizing_table_conditions */ }, diff --git a/mysql-test/suite/opt_trace/r/range_no_prot.result b/mysql-test/suite/opt_trace/r/range_no_prot.result index 00ea372bed5..df192d214f2 100644 --- a/mysql-test/suite/opt_trace/r/range_no_prot.result +++ b/mysql-test/suite/opt_trace/r/range_no_prot.result @@ -2378,7 +2378,7 @@ EXPLAIN SELECT * FROM t2 WHERE key2_1 < 79 OR key2 = 2 { EXPLAIN SELECT * FROM t2 WHERE key1a = 5 and key1b < 10; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL range PRIMARY,i1b PRIMARY 8 NULL 1 100.00 Using index condition +1 SIMPLE t2 NULL range PRIMARY,i1b PRIMARY 8 NULL 1 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`key1a` AS `key1a`,`test`.`t2`.`key1b` AS `key1b`,`test`.`t2`.`key2` AS `key2`,`test`.`t2`.`key2_1` AS `key2_1`,`test`.`t2`.`key2_2` AS `key2_2`,`test`.`t2`.`key3` AS `key3` from `test`.`t2` where ((`test`.`t2`.`key1a` = 5) and (`test`.`t2`.`key1b` < 10)) @@ -2611,16 +2611,14 @@ EXPLAIN SELECT * FROM t2 WHERE key1a = 5 and key1b < 10 { { "table": "`t2`", "original_table_condition": "((`t2`.`key1a` = 5) and (`t2`.`key1b` < 10))", - "final_table_condition ": "((`t2`.`key1a` = 5) and (`t2`.`key1b` < 10))" + "final_table_condition ": null } ] /* finalizing_table_conditions */ }, { "refine_plan": [ { - "table": "`t2`", - "pushed_index_condition": "((`t2`.`key1a` = 5) and (`t2`.`key1b` < 10))", - "table_condition_attached": null + "table": "`t2`" } ] /* refine_plan */ } @@ -3115,7 +3113,7 @@ EXPLAIN SELECT * FROM t2 WHERE (key1b < 10 and key1b > 7) and { "table": "`t2`", "original_table_condition": "((`t2`.`key1b` < 10) and (`t2`.`key1b` > 7) and ((`t2`.`key1a` = 4) or (`t2`.`key1a` = 5)))", - "final_table_condition ": "((`t2`.`key1b` < 10) and (`t2`.`key1b` > 7) and ((`t2`.`key1a` = 4) or (`t2`.`key1a` = 5)))" + "final_table_condition ": "((`t2`.`key1a` = 4) or (`t2`.`key1a` = 5))" } ] /* finalizing_table_conditions */ }, @@ -3123,7 +3121,7 @@ EXPLAIN SELECT * FROM t2 WHERE (key1b < 10 and key1b > 7) and "refine_plan": [ { "table": "`t2`", - "pushed_index_condition": "((`t2`.`key1b` < 10) and (`t2`.`key1b` > 7) and ((`t2`.`key1a` = 4) or (`t2`.`key1a` = 5)))", + "pushed_index_condition": "((`t2`.`key1a` = 4) or (`t2`.`key1a` = 5))", "table_condition_attached": null } ] /* refine_plan */ @@ -3414,7 +3412,7 @@ EXPLAIN SELECT * FROM t1 WHERE (key1 > 1 OR key2 > 2) { EXPLAIN SELECT STRAIGHT_JOIN * FROM t1, t2 WHERE t1.key1=t2.key1a AND t1.key2 > 1020; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range i1,i2 i2 4 NULL 42 100.00 Using index condition +1 SIMPLE t1 NULL range i1,i2 i2 4 NULL 42 100.00 NULL 1 SIMPLE t2 NULL ref PRIMARY PRIMARY 4 test.t1.key1 10 100.00 NULL Warnings: Note 1003 /* select#1 */ select straight_join `test`.`t1`.`key1` AS `key1`,`test`.`t1`.`key2` AS `key2`,`test`.`t1`.`key3` AS `key3`,`test`.`t1`.`key4` AS `key4`,`test`.`t1`.`key5` AS `key5`,`test`.`t1`.`key6` AS `key6`,`test`.`t1`.`key7` AS `key7`,`test`.`t1`.`key8` AS `key8`,`test`.`t2`.`key1a` AS `key1a`,`test`.`t2`.`key1b` AS `key1b`,`test`.`t2`.`key2` AS `key2`,`test`.`t2`.`key2_1` AS `key2_1`,`test`.`t2`.`key2_2` AS `key2_2`,`test`.`t2`.`key3` AS `key3` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`key1a` = `test`.`t1`.`key1`) and (`test`.`t1`.`key2` > 1020)) @@ -3695,7 +3693,7 @@ WHERE t1.key1=t2.key1a AND t1.key2 > 1020 { { "table": "`t1`", "original_table_condition": "(`t1`.`key2` > 1020)", - "final_table_condition ": "(`t1`.`key2` > 1020)" + "final_table_condition ": null }, { "table": "`t2`", @@ -3707,9 +3705,7 @@ WHERE t1.key1=t2.key1a AND t1.key2 > 1020 { { "refine_plan": [ { - "table": "`t1`", - "pushed_index_condition": "(`t1`.`key2` > 1020)", - "table_condition_attached": null + "table": "`t1`" }, { "table": "`t2`" @@ -4955,7 +4951,7 @@ KEY k2 (i1, i2) INSERT INTO t1 VALUES (0,1,'2'),(3,2,'1'); EXPLAIN SELECT * FROM t1 WHERE i1 > '2' ORDER BY i1, i2; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range k1,k2 k2 5 NULL 2 100.00 Using index condition +1 SIMPLE t1 NULL range k1,k2 k2 5 NULL 2 100.00 NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`i1` AS `i1`,`test`.`t1`.`i2` AS `i2`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (`test`.`t1`.`i1` > 2) order by `test`.`t1`.`i1`,`test`.`t1`.`i2` @@ -5276,16 +5272,14 @@ EXPLAIN SELECT * FROM t1 WHERE i1 > '2' ORDER BY i1, i2 { { "table": "`t1`", "original_table_condition": "(`t1`.`i1` > 2)", - "final_table_condition ": "(`t1`.`i1` > 2)" + "final_table_condition ": null } ] /* finalizing_table_conditions */ }, { "refine_plan": [ { - "table": "`t1`", - "pushed_index_condition": "(`t1`.`i1` > 2)", - "table_condition_attached": null + "table": "`t1`" } ] /* refine_plan */ }, @@ -5650,7 +5644,7 @@ INSERT INTO t1 VALUES (1, 1, 9,'a'), (2, 2, 8,'b'), (3, 3, 7,'c'), # Covering ROR intersect not chosen: Index with more keyparts found. EXPLAIN SELECT v FROM t1 WHERE i1 = 1 AND v = 'a' AND pk < 3; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL range PRIMARY,i1_idx,v_idx v_idx 16 NULL 1 100.00 Using where; Using index +1 SIMPLE t1 NULL range PRIMARY,i1_idx,v_idx v_idx 16 NULL 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`v` AS `v` from `test`.`t1` where ((`test`.`t1`.`v` = 'a') and (`test`.`t1`.`i1` = 1) and (`test`.`t1`.`pk` < 3)) @@ -5938,7 +5932,7 @@ EXPLAIN SELECT v FROM t1 WHERE i1 = 1 AND v = 'a' AND pk < 3 { { "table": "`t1`", "original_table_condition": "((`t1`.`v` = 'a') and (`t1`.`i1` = 1) and (`t1`.`pk` < 3))", - "final_table_condition ": "((`t1`.`v` = 'a') and (`t1`.`i1` = 1) and (`t1`.`pk` < 3))" + "final_table_condition ": null } ] /* finalizing_table_conditions */ }, diff --git a/mysql-test/suite/sys_vars/r/all_vars.result b/mysql-test/suite/sys_vars/r/all_vars.result index 5b20f3749be..4f9e44ba678 100644 --- a/mysql-test/suite/sys_vars/r/all_vars.result +++ b/mysql-test/suite/sys_vars/r/all_vars.result @@ -30,6 +30,8 @@ default_collation_for_utf8mb4 default_collation_for_utf8mb4 disabled_storage_engines disabled_storage_engines +empty_redundant_check_in_range_scan +empty_redundant_check_in_range_scan generated_random_password_length generated_random_password_length group_replication_consistency diff --git a/mysql-test/suite/sys_vars/r/innodb_monitor_disable_basic.result b/mysql-test/suite/sys_vars/r/innodb_monitor_disable_basic.result index e4561b180e6..9ebe561b1d8 100644 --- a/mysql-test/suite/sys_vars/r/innodb_monitor_disable_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_monitor_disable_basic.result @@ -281,6 +281,7 @@ innodb_rwlock_s_os_waits disabled innodb_rwlock_x_os_waits disabled innodb_rwlock_sx_os_waits disabled dml_reads disabled +dml_reads_skipped_by_offset_pushdown disabled dml_inserts disabled dml_deletes disabled dml_updates disabled @@ -538,6 +539,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 4 NULL 4 4 NULL 4 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 1 NULL 1 1 NULL 1 enabled dml_deletes 0 NULL 0 0 NULL 0 enabled dml_updates 2 NULL 2 2 NULL 2 enabled @@ -552,6 +554,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 6 NULL 6 6 NULL 6 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 1 NULL 1 1 NULL 1 enabled dml_deletes 2 NULL 2 2 NULL 2 enabled dml_updates 2 NULL 2 2 NULL 2 enabled @@ -566,6 +569,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 6 NULL 6 0 NULL 0 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 1 NULL 1 0 NULL 0 enabled dml_deletes 2 NULL 2 0 NULL 0 enabled dml_updates 2 NULL 2 0 NULL 0 enabled @@ -582,6 +586,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 8 NULL 8 2 NULL 2 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 3 NULL 3 2 NULL 2 enabled dml_deletes 4 NULL 4 2 NULL 2 enabled dml_updates 2 NULL 2 0 NULL 0 enabled @@ -596,6 +601,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 8 NULL 8 2 NULL 2 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 3 NULL 3 2 NULL 2 enabled dml_deletes 4 NULL 4 2 NULL 2 enabled dml_updates 2 NULL 2 0 NULL 0 enabled @@ -610,6 +616,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 8 NULL 8 2 NULL 2 disabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 disabled dml_inserts 3 NULL 3 2 NULL 2 disabled dml_deletes 4 NULL 4 2 NULL 2 disabled dml_updates 2 NULL 2 0 NULL 0 disabled @@ -624,6 +631,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads NULL NULL 0 NULL NULL 0 disabled +dml_reads_skipped_by_offset_pushdown NULL NULL 0 NULL NULL 0 disabled dml_inserts NULL NULL 0 NULL NULL 0 disabled dml_deletes NULL NULL 0 NULL NULL 0 disabled dml_updates NULL NULL 0 NULL NULL 0 disabled @@ -641,6 +649,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads NULL NULL 0 NULL NULL 0 disabled +dml_reads_skipped_by_offset_pushdown NULL NULL 0 NULL NULL 0 disabled dml_inserts 2 NULL 2 2 NULL 2 enabled dml_deletes NULL NULL 0 NULL NULL 0 disabled dml_updates NULL NULL 0 NULL NULL 0 disabled @@ -667,9 +676,9 @@ a select name, count from information_schema.innodb_metrics where name like "icp%"; name count -icp_attempts 1 +icp_attempts 0 icp_no_match 0 -icp_out_of_range 1 +icp_out_of_range 0 icp_match 0 select a from monitor_test where b < 3 for update; a @@ -677,10 +686,10 @@ a select name, count from information_schema.innodb_metrics where name like "icp%"; name count -icp_attempts 2 +icp_attempts 0 icp_no_match 0 -icp_out_of_range 1 -icp_match 1 +icp_out_of_range 0 +icp_match 0 drop table monitor_test; set global innodb_monitor_disable = All; set global innodb_monitor_reset_all = all; diff --git a/mysql-test/suite/sys_vars/r/innodb_monitor_enable_basic.result b/mysql-test/suite/sys_vars/r/innodb_monitor_enable_basic.result index e4561b180e6..9ebe561b1d8 100644 --- a/mysql-test/suite/sys_vars/r/innodb_monitor_enable_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_monitor_enable_basic.result @@ -281,6 +281,7 @@ innodb_rwlock_s_os_waits disabled innodb_rwlock_x_os_waits disabled innodb_rwlock_sx_os_waits disabled dml_reads disabled +dml_reads_skipped_by_offset_pushdown disabled dml_inserts disabled dml_deletes disabled dml_updates disabled @@ -538,6 +539,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 4 NULL 4 4 NULL 4 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 1 NULL 1 1 NULL 1 enabled dml_deletes 0 NULL 0 0 NULL 0 enabled dml_updates 2 NULL 2 2 NULL 2 enabled @@ -552,6 +554,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 6 NULL 6 6 NULL 6 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 1 NULL 1 1 NULL 1 enabled dml_deletes 2 NULL 2 2 NULL 2 enabled dml_updates 2 NULL 2 2 NULL 2 enabled @@ -566,6 +569,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 6 NULL 6 0 NULL 0 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 1 NULL 1 0 NULL 0 enabled dml_deletes 2 NULL 2 0 NULL 0 enabled dml_updates 2 NULL 2 0 NULL 0 enabled @@ -582,6 +586,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 8 NULL 8 2 NULL 2 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 3 NULL 3 2 NULL 2 enabled dml_deletes 4 NULL 4 2 NULL 2 enabled dml_updates 2 NULL 2 0 NULL 0 enabled @@ -596,6 +601,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 8 NULL 8 2 NULL 2 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 3 NULL 3 2 NULL 2 enabled dml_deletes 4 NULL 4 2 NULL 2 enabled dml_updates 2 NULL 2 0 NULL 0 enabled @@ -610,6 +616,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 8 NULL 8 2 NULL 2 disabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 disabled dml_inserts 3 NULL 3 2 NULL 2 disabled dml_deletes 4 NULL 4 2 NULL 2 disabled dml_updates 2 NULL 2 0 NULL 0 disabled @@ -624,6 +631,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads NULL NULL 0 NULL NULL 0 disabled +dml_reads_skipped_by_offset_pushdown NULL NULL 0 NULL NULL 0 disabled dml_inserts NULL NULL 0 NULL NULL 0 disabled dml_deletes NULL NULL 0 NULL NULL 0 disabled dml_updates NULL NULL 0 NULL NULL 0 disabled @@ -641,6 +649,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads NULL NULL 0 NULL NULL 0 disabled +dml_reads_skipped_by_offset_pushdown NULL NULL 0 NULL NULL 0 disabled dml_inserts 2 NULL 2 2 NULL 2 enabled dml_deletes NULL NULL 0 NULL NULL 0 disabled dml_updates NULL NULL 0 NULL NULL 0 disabled @@ -667,9 +676,9 @@ a select name, count from information_schema.innodb_metrics where name like "icp%"; name count -icp_attempts 1 +icp_attempts 0 icp_no_match 0 -icp_out_of_range 1 +icp_out_of_range 0 icp_match 0 select a from monitor_test where b < 3 for update; a @@ -677,10 +686,10 @@ a select name, count from information_schema.innodb_metrics where name like "icp%"; name count -icp_attempts 2 +icp_attempts 0 icp_no_match 0 -icp_out_of_range 1 -icp_match 1 +icp_out_of_range 0 +icp_match 0 drop table monitor_test; set global innodb_monitor_disable = All; set global innodb_monitor_reset_all = all; diff --git a/mysql-test/suite/sys_vars/r/innodb_monitor_reset_all_basic.result b/mysql-test/suite/sys_vars/r/innodb_monitor_reset_all_basic.result index e4561b180e6..9ebe561b1d8 100644 --- a/mysql-test/suite/sys_vars/r/innodb_monitor_reset_all_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_monitor_reset_all_basic.result @@ -281,6 +281,7 @@ innodb_rwlock_s_os_waits disabled innodb_rwlock_x_os_waits disabled innodb_rwlock_sx_os_waits disabled dml_reads disabled +dml_reads_skipped_by_offset_pushdown disabled dml_inserts disabled dml_deletes disabled dml_updates disabled @@ -538,6 +539,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 4 NULL 4 4 NULL 4 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 1 NULL 1 1 NULL 1 enabled dml_deletes 0 NULL 0 0 NULL 0 enabled dml_updates 2 NULL 2 2 NULL 2 enabled @@ -552,6 +554,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 6 NULL 6 6 NULL 6 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 1 NULL 1 1 NULL 1 enabled dml_deletes 2 NULL 2 2 NULL 2 enabled dml_updates 2 NULL 2 2 NULL 2 enabled @@ -566,6 +569,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 6 NULL 6 0 NULL 0 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 1 NULL 1 0 NULL 0 enabled dml_deletes 2 NULL 2 0 NULL 0 enabled dml_updates 2 NULL 2 0 NULL 0 enabled @@ -582,6 +586,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 8 NULL 8 2 NULL 2 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 3 NULL 3 2 NULL 2 enabled dml_deletes 4 NULL 4 2 NULL 2 enabled dml_updates 2 NULL 2 0 NULL 0 enabled @@ -596,6 +601,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 8 NULL 8 2 NULL 2 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 3 NULL 3 2 NULL 2 enabled dml_deletes 4 NULL 4 2 NULL 2 enabled dml_updates 2 NULL 2 0 NULL 0 enabled @@ -610,6 +616,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 8 NULL 8 2 NULL 2 disabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 disabled dml_inserts 3 NULL 3 2 NULL 2 disabled dml_deletes 4 NULL 4 2 NULL 2 disabled dml_updates 2 NULL 2 0 NULL 0 disabled @@ -624,6 +631,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads NULL NULL 0 NULL NULL 0 disabled +dml_reads_skipped_by_offset_pushdown NULL NULL 0 NULL NULL 0 disabled dml_inserts NULL NULL 0 NULL NULL 0 disabled dml_deletes NULL NULL 0 NULL NULL 0 disabled dml_updates NULL NULL 0 NULL NULL 0 disabled @@ -641,6 +649,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads NULL NULL 0 NULL NULL 0 disabled +dml_reads_skipped_by_offset_pushdown NULL NULL 0 NULL NULL 0 disabled dml_inserts 2 NULL 2 2 NULL 2 enabled dml_deletes NULL NULL 0 NULL NULL 0 disabled dml_updates NULL NULL 0 NULL NULL 0 disabled @@ -667,9 +676,9 @@ a select name, count from information_schema.innodb_metrics where name like "icp%"; name count -icp_attempts 1 +icp_attempts 0 icp_no_match 0 -icp_out_of_range 1 +icp_out_of_range 0 icp_match 0 select a from monitor_test where b < 3 for update; a @@ -677,10 +686,10 @@ a select name, count from information_schema.innodb_metrics where name like "icp%"; name count -icp_attempts 2 +icp_attempts 0 icp_no_match 0 -icp_out_of_range 1 -icp_match 1 +icp_out_of_range 0 +icp_match 0 drop table monitor_test; set global innodb_monitor_disable = All; set global innodb_monitor_reset_all = all; diff --git a/mysql-test/suite/sys_vars/r/innodb_monitor_reset_basic.result b/mysql-test/suite/sys_vars/r/innodb_monitor_reset_basic.result index 2876f442342..4b7077a2684 100644 --- a/mysql-test/suite/sys_vars/r/innodb_monitor_reset_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_monitor_reset_basic.result @@ -281,6 +281,7 @@ innodb_rwlock_s_os_waits disabled innodb_rwlock_x_os_waits disabled innodb_rwlock_sx_os_waits disabled dml_reads disabled +dml_reads_skipped_by_offset_pushdown disabled dml_inserts disabled dml_deletes disabled dml_updates disabled @@ -538,6 +539,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 4 NULL 4 4 NULL 4 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 1 NULL 1 1 NULL 1 enabled dml_deletes 0 NULL 0 0 NULL 0 enabled dml_updates 2 NULL 2 2 NULL 2 enabled @@ -552,6 +554,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 6 NULL 6 6 NULL 6 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 1 NULL 1 1 NULL 1 enabled dml_deletes 2 NULL 2 2 NULL 2 enabled dml_updates 2 NULL 2 2 NULL 2 enabled @@ -566,6 +569,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 6 NULL 6 0 NULL 0 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 1 NULL 1 0 NULL 0 enabled dml_deletes 2 NULL 2 0 NULL 0 enabled dml_updates 2 NULL 2 0 NULL 0 enabled @@ -582,6 +586,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 8 NULL 8 2 NULL 2 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 3 NULL 3 2 NULL 2 enabled dml_deletes 4 NULL 4 2 NULL 2 enabled dml_updates 2 NULL 2 0 NULL 0 enabled @@ -596,6 +601,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 8 NULL 8 2 NULL 2 enabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 enabled dml_inserts 3 NULL 3 2 NULL 2 enabled dml_deletes 4 NULL 4 2 NULL 2 enabled dml_updates 2 NULL 2 0 NULL 0 enabled @@ -610,6 +616,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads 8 NULL 8 2 NULL 2 disabled +dml_reads_skipped_by_offset_pushdown 0 NULL 0 0 NULL 0 disabled dml_inserts 3 NULL 3 2 NULL 2 disabled dml_deletes 4 NULL 4 2 NULL 2 disabled dml_updates 2 NULL 2 0 NULL 0 disabled @@ -624,6 +631,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads NULL NULL 0 NULL NULL 0 disabled +dml_reads_skipped_by_offset_pushdown NULL NULL 0 NULL NULL 0 disabled dml_inserts NULL NULL 0 NULL NULL 0 disabled dml_deletes NULL NULL 0 NULL NULL 0 disabled dml_updates NULL NULL 0 NULL NULL 0 disabled @@ -641,6 +649,7 @@ from information_schema.innodb_metrics where name like "dml%"; name max_count min_count count max_count_reset min_count_reset count_reset status dml_reads NULL NULL 0 NULL NULL 0 disabled +dml_reads_skipped_by_offset_pushdown NULL NULL 0 NULL NULL 0 disabled dml_inserts 2 NULL 2 2 NULL 2 enabled dml_deletes NULL NULL 0 NULL NULL 0 disabled dml_updates NULL NULL 0 NULL NULL 0 disabled @@ -667,9 +676,9 @@ a select name, count from information_schema.innodb_metrics where name like "icp%"; name count -icp_attempts 1 +icp_attempts 0 icp_no_match 0 -icp_out_of_range 1 +icp_out_of_range 0 icp_match 0 select a from monitor_test where b < 3 for update; a @@ -677,10 +686,10 @@ a select name, count from information_schema.innodb_metrics where name like "icp%"; name count -icp_attempts 2 +icp_attempts 0 icp_no_match 0 -icp_out_of_range 1 -icp_match 1 +icp_out_of_range 0 +icp_match 0 drop table monitor_test; set global innodb_monitor_disable = All; set global innodb_monitor_reset_all = all; diff --git a/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result b/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result index 00fc6605318..5afaec794c7 100644 --- a/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result +++ b/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result @@ -1,57 +1,57 @@ SET @start_global_value = @@global.optimizer_switch; SELECT @start_global_value; @start_global_value -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on select @@global.optimizer_switch; @@global.optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on select @@session.optimizer_switch; @@session.optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on show global variables like 'optimizer_switch'; Variable_name Value -optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on show session variables like 'optimizer_switch'; Variable_name Value -optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on select * from performance_schema.global_variables where variable_name='optimizer_switch'; VARIABLE_NAME VARIABLE_VALUE -optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on select * from performance_schema.session_variables where variable_name='optimizer_switch'; VARIABLE_NAME VARIABLE_VALUE -optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on set global optimizer_switch=10; set session optimizer_switch=5; select @@global.optimizer_switch; @@global.optimizer_switch -index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,engine_condition_pushdown=off,index_condition_pushdown=off,mrr=off,mrr_cost_based=off,block_nested_loop=off,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=off,duplicateweedout=off,subquery_materialization_cost_based=off,use_index_extensions=off,condition_fanout_filter=off,derived_merge=off,use_invisible_indexes=off,skip_scan=off,hash_join=off,subquery_to_derived=off,prefer_ordering_index=off,hypergraph_optimizer=off,derived_condition_pushdown=off +index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,engine_condition_pushdown=off,index_condition_pushdown=off,mrr=off,mrr_cost_based=off,block_nested_loop=off,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=off,duplicateweedout=off,subquery_materialization_cost_based=off,use_index_extensions=off,condition_fanout_filter=off,derived_merge=off,use_invisible_indexes=off,skip_scan=off,hash_join=off,subquery_to_derived=off,prefer_ordering_index=off,hypergraph_optimizer=off,derived_condition_pushdown=off,offset_pushdown=off select @@session.optimizer_switch; @@session.optimizer_switch -index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,mrr=off,mrr_cost_based=off,block_nested_loop=off,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=off,duplicateweedout=off,subquery_materialization_cost_based=off,use_index_extensions=off,condition_fanout_filter=off,derived_merge=off,use_invisible_indexes=off,skip_scan=off,hash_join=off,subquery_to_derived=off,prefer_ordering_index=off,hypergraph_optimizer=off,derived_condition_pushdown=off +index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,mrr=off,mrr_cost_based=off,block_nested_loop=off,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=off,duplicateweedout=off,subquery_materialization_cost_based=off,use_index_extensions=off,condition_fanout_filter=off,derived_merge=off,use_invisible_indexes=off,skip_scan=off,hash_join=off,subquery_to_derived=off,prefer_ordering_index=off,hypergraph_optimizer=off,derived_condition_pushdown=off,offset_pushdown=off set global optimizer_switch="index_merge_sort_union=on"; set session optimizer_switch="index_merge=off"; select @@global.optimizer_switch; @@global.optimizer_switch -index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=off,index_condition_pushdown=off,mrr=off,mrr_cost_based=off,block_nested_loop=off,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=off,duplicateweedout=off,subquery_materialization_cost_based=off,use_index_extensions=off,condition_fanout_filter=off,derived_merge=off,use_invisible_indexes=off,skip_scan=off,hash_join=off,subquery_to_derived=off,prefer_ordering_index=off,hypergraph_optimizer=off,derived_condition_pushdown=off +index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=off,index_condition_pushdown=off,mrr=off,mrr_cost_based=off,block_nested_loop=off,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=off,duplicateweedout=off,subquery_materialization_cost_based=off,use_index_extensions=off,condition_fanout_filter=off,derived_merge=off,use_invisible_indexes=off,skip_scan=off,hash_join=off,subquery_to_derived=off,prefer_ordering_index=off,hypergraph_optimizer=off,derived_condition_pushdown=off,offset_pushdown=off select @@session.optimizer_switch; @@session.optimizer_switch -index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,mrr=off,mrr_cost_based=off,block_nested_loop=off,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=off,duplicateweedout=off,subquery_materialization_cost_based=off,use_index_extensions=off,condition_fanout_filter=off,derived_merge=off,use_invisible_indexes=off,skip_scan=off,hash_join=off,subquery_to_derived=off,prefer_ordering_index=off,hypergraph_optimizer=off,derived_condition_pushdown=off +index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,mrr=off,mrr_cost_based=off,block_nested_loop=off,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=off,duplicateweedout=off,subquery_materialization_cost_based=off,use_index_extensions=off,condition_fanout_filter=off,derived_merge=off,use_invisible_indexes=off,skip_scan=off,hash_join=off,subquery_to_derived=off,prefer_ordering_index=off,hypergraph_optimizer=off,derived_condition_pushdown=off,offset_pushdown=off show global variables like 'optimizer_switch'; Variable_name Value -optimizer_switch index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=off,index_condition_pushdown=off,mrr=off,mrr_cost_based=off,block_nested_loop=off,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=off,duplicateweedout=off,subquery_materialization_cost_based=off,use_index_extensions=off,condition_fanout_filter=off,derived_merge=off,use_invisible_indexes=off,skip_scan=off,hash_join=off,subquery_to_derived=off,prefer_ordering_index=off,hypergraph_optimizer=off,derived_condition_pushdown=off +optimizer_switch index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=off,index_condition_pushdown=off,mrr=off,mrr_cost_based=off,block_nested_loop=off,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=off,duplicateweedout=off,subquery_materialization_cost_based=off,use_index_extensions=off,condition_fanout_filter=off,derived_merge=off,use_invisible_indexes=off,skip_scan=off,hash_join=off,subquery_to_derived=off,prefer_ordering_index=off,hypergraph_optimizer=off,derived_condition_pushdown=off,offset_pushdown=off show session variables like 'optimizer_switch'; Variable_name Value -optimizer_switch index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,mrr=off,mrr_cost_based=off,block_nested_loop=off,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=off,duplicateweedout=off,subquery_materialization_cost_based=off,use_index_extensions=off,condition_fanout_filter=off,derived_merge=off,use_invisible_indexes=off,skip_scan=off,hash_join=off,subquery_to_derived=off,prefer_ordering_index=off,hypergraph_optimizer=off,derived_condition_pushdown=off +optimizer_switch index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,mrr=off,mrr_cost_based=off,block_nested_loop=off,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=off,duplicateweedout=off,subquery_materialization_cost_based=off,use_index_extensions=off,condition_fanout_filter=off,derived_merge=off,use_invisible_indexes=off,skip_scan=off,hash_join=off,subquery_to_derived=off,prefer_ordering_index=off,hypergraph_optimizer=off,derived_condition_pushdown=off,offset_pushdown=off select * from performance_schema.global_variables where variable_name='optimizer_switch'; VARIABLE_NAME VARIABLE_VALUE -optimizer_switch index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=off,index_condition_pushdown=off,mrr=off,mrr_cost_based=off,block_nested_loop=off,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=off,duplicateweedout=off,subquery_materialization_cost_based=off,use_index_extensions=off,condition_fanout_filter=off,derived_merge=off,use_invisible_indexes=off,skip_scan=off,hash_join=off,subquery_to_derived=off,prefer_ordering_index=off,hypergraph_optimizer=off,derived_condition_pushdown=off +optimizer_switch index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=off,index_condition_pushdown=off,mrr=off,mrr_cost_based=off,block_nested_loop=off,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=off,duplicateweedout=off,subquery_materialization_cost_based=off,use_index_extensions=off,condition_fanout_filter=off,derived_merge=off,use_invisible_indexes=off,skip_scan=off,hash_join=off,subquery_to_derived=off,prefer_ordering_index=off,hypergraph_optimizer=off,derived_condition_pushdown=off,offset_pushdown=off select * from performance_schema.session_variables where variable_name='optimizer_switch'; VARIABLE_NAME VARIABLE_VALUE -optimizer_switch index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,mrr=off,mrr_cost_based=off,block_nested_loop=off,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=off,duplicateweedout=off,subquery_materialization_cost_based=off,use_index_extensions=off,condition_fanout_filter=off,derived_merge=off,use_invisible_indexes=off,skip_scan=off,hash_join=off,subquery_to_derived=off,prefer_ordering_index=off,hypergraph_optimizer=off,derived_condition_pushdown=off +optimizer_switch index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,mrr=off,mrr_cost_based=off,block_nested_loop=off,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=off,duplicateweedout=off,subquery_materialization_cost_based=off,use_index_extensions=off,condition_fanout_filter=off,derived_merge=off,use_invisible_indexes=off,skip_scan=off,hash_join=off,subquery_to_derived=off,prefer_ordering_index=off,hypergraph_optimizer=off,derived_condition_pushdown=off,offset_pushdown=off set session optimizer_switch="default"; select @@session.optimizer_switch; @@session.optimizer_switch -index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=off,index_condition_pushdown=off,mrr=off,mrr_cost_based=off,block_nested_loop=off,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=off,duplicateweedout=off,subquery_materialization_cost_based=off,use_index_extensions=off,condition_fanout_filter=off,derived_merge=off,use_invisible_indexes=off,skip_scan=off,hash_join=off,subquery_to_derived=off,prefer_ordering_index=off,hypergraph_optimizer=off,derived_condition_pushdown=off +index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=off,index_condition_pushdown=off,mrr=off,mrr_cost_based=off,block_nested_loop=off,batched_key_access=off,materialization=off,semijoin=off,loosescan=off,firstmatch=off,duplicateweedout=off,subquery_materialization_cost_based=off,use_index_extensions=off,condition_fanout_filter=off,derived_merge=off,use_invisible_indexes=off,skip_scan=off,hash_join=off,subquery_to_derived=off,prefer_ordering_index=off,hypergraph_optimizer=off,derived_condition_pushdown=off,offset_pushdown=off set global optimizer_switch=1.1; ERROR 42000: Incorrect argument type to variable 'optimizer_switch' set global optimizer_switch=1e1; @@ -77,4 +77,4 @@ ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'd\x00\xEC SET @@global.optimizer_switch = @start_global_value; SELECT @@global.optimizer_switch; @@global.optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on,offset_pushdown=on diff --git a/mysql-test/t/all_persisted_variables.test b/mysql-test/t/all_persisted_variables.test index 0441d2c1e1d..badb0f245ef 100644 --- a/mysql-test/t/all_persisted_variables.test +++ b/mysql-test/t/all_persisted_variables.test @@ -41,7 +41,7 @@ call mtr.add_suppression("\\[Warning\\] .*MY-\\d+.* Changing innodb_extend_and_i call mtr.add_suppression("Failed to initialize TLS for channel: mysql_main"); let $total_global_vars=`SELECT COUNT(*) FROM performance_schema.global_variables where variable_name NOT LIKE 'ndb_%' AND variable_name NOT LIKE 'debug_%'`; -let $total_persistent_vars=448; +let $total_persistent_vars=449; --echo *************************************************************** --echo * 0. Verify that variables present in performance_schema.global diff --git a/mysql-test/t/derived_condition_pushdown.test b/mysql-test/t/derived_condition_pushdown.test index 2497bc58f0e..5d8218c5c27 100644 --- a/mysql-test/t/derived_condition_pushdown.test +++ b/mysql-test/t/derived_condition_pushdown.test @@ -1,6 +1,8 @@ # Tests for WL#8084 - Condition pushdown to derived table --source include/elide_costs.inc +--echo # set to false to conserve original test design +set empty_redundant_check_in_range_scan=false; #setup tables CREATE TABLE t0 ( i0 INTEGER @@ -1327,3 +1329,4 @@ CREATE TABLE t1 (f1 INTEGER); INSERT INTO t1 VALUES (1); SELECT * FROM (SELECT f1 FROM t1 UNION SELECT f1 FROM t1) AS dt WHERE f1 <> 0.5; DROP TABLE t1; +set empty_redundant_check_in_range_scan=true; diff --git a/mysql-test/t/innodb_mrr_cost_icp.test b/mysql-test/t/innodb_mrr_cost_icp.test index cbc3feabe89..3036754d0bb 100644 --- a/mysql-test/t/innodb_mrr_cost_icp.test +++ b/mysql-test/t/innodb_mrr_cost_icp.test @@ -3,6 +3,10 @@ # (Turns off all other 6.0 optimizer switches than MRR and ICP) # +# We want maximum testing of ICP; for that, conditions must not be +# removed before they have a chance to be pushed with ICP. +set empty_redundant_check_in_range_scan=false; + --source include/no_valgrind_without_big.inc set optimizer_switch='index_condition_pushdown=on,mrr=on,mrr_cost_based=on'; @@ -24,7 +28,7 @@ set default_storage_engine=InnoDB; --source include/mrr_tests.inc --source include/mrr_innodb_tests.inc - set default_storage_engine= @save_storage_engine; set optimizer_switch=default; +set empty_redundant_check_in_range_scan=true; \ No newline at end of file diff --git a/mysql-test/t/innodb_mrr_icp.test b/mysql-test/t/innodb_mrr_icp.test index eb1bd2a6521..63a881c7b86 100644 --- a/mysql-test/t/innodb_mrr_icp.test +++ b/mysql-test/t/innodb_mrr_icp.test @@ -21,10 +21,13 @@ if (`select locate('materialization', @@optimizer_switch) > 0`) set @save_storage_engine= @@default_storage_engine; set default_storage_engine=InnoDB; +# We want maximum testing of ICP; for that, conditions must not be +# removed before they have a chance to be pushed with ICP. +set empty_redundant_check_in_range_scan=false; --source include/mrr_tests.inc --source include/mrr_innodb_tests.inc - +set empty_redundant_check_in_range_scan=true; set default_storage_engine= @save_storage_engine; set optimizer_switch=default; diff --git a/mysql-test/t/myisam_icp.test b/mysql-test/t/myisam_icp.test index 0822023be14..79561d3c308 100644 --- a/mysql-test/t/myisam_icp.test +++ b/mysql-test/t/myisam_icp.test @@ -10,7 +10,7 @@ # ICP/MyISAM tests (Index Condition Pushdown) # (Turns off all other 6.0 optimizer switches) # - +set empty_redundant_check_in_range_scan=false; set optimizer_switch='index_condition_pushdown=on'; --disable_query_log @@ -31,3 +31,4 @@ if (`select locate('mrr', @@optimizer_switch) > 0`) --source include/icp_tests.inc set optimizer_switch=default; +set empty_redundant_check_in_range_scan=true; \ No newline at end of file diff --git a/mysql-test/t/myisam_icp_all.test b/mysql-test/t/myisam_icp_all.test index 1876670e056..3b9c30a019f 100644 --- a/mysql-test/t/myisam_icp_all.test +++ b/mysql-test/t/myisam_icp_all.test @@ -7,7 +7,7 @@ --source include/have_myisam.inc set optimizer_switch='semijoin=on,materialization=on,firstmatch=on,loosescan=on,index_condition_pushdown=on,mrr=on'; - +set empty_redundant_check_in_range_scan=false; --source include/icp_tests.inc - +set empty_redundant_check_in_range_scan=true; set optimizer_switch=default; diff --git a/mysql-test/t/myisam_mrr_cost_icp.test b/mysql-test/t/myisam_mrr_cost_icp.test index 31212bee42f..bbe7609b2b3 100644 --- a/mysql-test/t/myisam_mrr_cost_icp.test +++ b/mysql-test/t/myisam_mrr_cost_icp.test @@ -27,10 +27,10 @@ if (`select locate('materialization', @@optimizer_switch) > 0`) set @read_rnd_buffer_size_save= @@read_rnd_buffer_size; set read_rnd_buffer_size=79; select @@read_rnd_buffer_size; - +set empty_redundant_check_in_range_scan=false; -- source include/mrr_tests.inc -- source include/mrr_myisam_tests.inc - +set empty_redundant_check_in_range_scan=true; set @@read_rnd_buffer_size= @read_rnd_buffer_size_save; set optimizer_switch=default; diff --git a/mysql-test/t/myisam_mrr_icp.test b/mysql-test/t/myisam_mrr_icp.test index 147fefd5a89..89f08c86bdd 100644 --- a/mysql-test/t/myisam_mrr_icp.test +++ b/mysql-test/t/myisam_mrr_icp.test @@ -18,7 +18,7 @@ if (`select locate('materialization', @@optimizer_switch) > 0`) set optimizer_switch='materialization=off'; } --enable_query_log - +set empty_redundant_check_in_range_scan=false; set @read_rnd_buffer_size_save= @@read_rnd_buffer_size; set read_rnd_buffer_size=79; select @@read_rnd_buffer_size; @@ -26,5 +26,6 @@ select @@read_rnd_buffer_size; -- source include/mrr_tests.inc -- source include/mrr_myisam_tests.inc set @@read_rnd_buffer_size= @read_rnd_buffer_size_save; +set empty_redundant_check_in_range_scan=true; set optimizer_switch=default; diff --git a/mysql-test/t/offset_pushdown.test b/mysql-test/t/offset_pushdown.test new file mode 100644 index 00000000000..be6bef9b465 --- /dev/null +++ b/mysql-test/t/offset_pushdown.test @@ -0,0 +1,733 @@ +# offset pushdown + +--echo # Initialise +--disable_warnings +--enable_warnings + +--echo # In EXPLAIN, "Using offset pushdown " indicates whether the feature is activated for a given query +--echo # optimizer switch offset_pushdown flag defaults to true +--echo # system variable empty_redundant_check_in_range_scan defaults to true +--echo # table 1 + +CREATE TABLE t1 (a INT , b INT , INDEX(b)); +INSERT INTO t1 VALUES (1, 2), (2, 3), (3, 3), (4, 3); +analyze TABLE t1; +SET empty_redundant_check_in_range_scan=false; +--echo # Shows that offset pushdown works with table scan, later in +--echo # this file we will show it for index scan, range scan and lookup. +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t1 LIMIT 100 OFFSET 1; + +--echo # non-covering index - icp is not disabled +--echo # ICP is used and removes condition FROM server layer +--echo # OFFSET pushdow is therefore active even opt empty_redundant_check_in_range_scan is false. +explain SELECT a,b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +--echo # Also visible in other EXPLAIN formats: +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT a,b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=json SELECT a,b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; + +--echo # The existing MySQL implementation of ICP is that it is off when the chosen index is covering. +--echo # covering index => no icp => condition remains at SQL layer => no offset pushdown without opt empty_redundant_check_in_range_scan +explain SELECT b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +--echo # covering index => no icp => but option empty_redundant_check_in_range_scan active, removes the condition => offset pushdown happens +SET empty_redundant_check_in_range_scan = true; +explain SELECT b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +--echo # ORDER BY (asc): condition removed, ORDER BY desc, condition removed; offset pushdown activated either way +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT b FROM t1 WHERE b > 2 ORDER BY b DESC LIMIT 100 OFFSET 1; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT b FROM t1 WHERE b > 2 ORDER BY b ASC LIMIT 100 OFFSET 1; + +--echo # works whether b OP cond or cond OP b +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT a,b FROM t1 WHERE 2 < b; +CREATE TABLE t3 (a INT , b INT , INDEX(a,b)); +INSERT INTO t3 VALUES (1, 2),(2, 3),(3, 3),(4, 3); +analyze TABLE t3; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT a,b FROM t3 WHERE a = 2 AND b < 2; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT a,b FROM t3 WHERE 2 = a AND b < 2; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT a,b FROM t3 WHERE 2 = a AND 2 < b; + +--echo # t3 is re-used to show that a BETWEEN clause can also be emptied by empty_redundant_check_in_range_scan +--echo # thereby allowing offset pushdown +SET empty_redundant_check_in_range_scan = false; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t3 WHERE a BETWEEN 2 AND 3; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t3 WHERE a BETWEEN 2 AND 3 LIMIT 100 OFFSET 1; +CREATE TABLE comp_1a AS SELECT * FROM t3 WHERE a BETWEEN 2 AND 3; +CREATE TABLE comp_1b AS SELECT * FROM t3 WHERE a BETWEEN 2 AND 3 LIMIT 100 OFFSET 1; +SET empty_redundant_check_in_range_scan = true; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t3 WHERE a BETWEEN 2 AND 3; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t3 WHERE a BETWEEN 2 AND 3 LIMIT 100 OFFSET 1; +CREATE TABLE comp_2a AS SELECT * FROM t3 WHERE a BETWEEN 2 AND 3; +CREATE TABLE comp_2b AS SELECT * FROM t3 WHERE a BETWEEN 2 AND 3 LIMIT 100 OFFSET 1; +checksum TABLE comp_1a; +checksum TABLE comp_2a; +checksum TABLE comp_1b; +checksum TABLE comp_2b; +DROP TABLE comp_1a, comp_2a, comp_1b, comp_2b; +--echo # BETWEEN and type conversion +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t3 WHERE a BETWEEN "b" AND 5; +SELECT * FROM t3 WHERE a BETWEEN "b" AND 5; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t3 WHERE a BETWEEN "2" AND "5"; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t3 WHERE a BETWEEN "2" AND 5; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t3 WHERE a BETWEEN 2 AND "5"; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t3 WHERE a BETWEEN "2.0" AND "5"; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t3 WHERE a BETWEEN "2" AND "5.0"; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +--echo # Empty IS NULL in WHERE clause +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t3 WHERE a IS NULL AND b > 5; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t3 WHERE a IS NULL AND b > 5 LIMIT 100 OFFSET 1; +--echo # reset default +SET empty_redundant_check_in_range_scan = false; +--echo # Offset pushdown is done for for "index lookup" too, and redundant +--echo # conditions are removed even if empty_etc is false. +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t3 WHERE a = 12 LIMIT 100 OFFSET 1; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t3 WHERE a = 12 AND b = 27 LIMIT 100 OFFSET 1; +DROP TABLE t3; + +--echo # show the results are the same with or without the optimization + SET optimizer_switch = 'offset_pushdown=on'; +explain SELECT a,b FROM t1 WHERE b>2 LIMIT 100 OFFSET 1; +CREATE TABLE comp_1 AS SELECT a,b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; + SET optimizer_switch = 'offset_pushdown=off'; +explain SELECT a,b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +CREATE TABLE comp_2 AS SELECT a,b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; + +--echo # checksum for comp_1 and comp_2 should give the same output: +checksum TABLE comp_1; +checksum TABLE comp_2; +DROP TABLE comp_1,comp_2; +--echo #reset default +SET optimizer_switch = 'offset_pushdown=on'; +SET empty_redundant_check_in_range_scan = false; + +--echo # Use with stored procedure +DELIMITER //; +CREATE PROCEDURE p1(p1 integer, p2 integer) +begin + SELECT * FROM t1 WHERE b>2 LIMIT p1 OFFSET p2; +end // +CREATE PROCEDURE p2(p1 integer, p2 integer) +begin + explain SELECT * FROM t1 WHERE b > 2 LIMIT p1 OFFSET p2; +end // +delimiter ;// + +call p2(100,1); +call p1(100,1); +DROP PROCEDURE if EXISTS p1; +DROP PROCEDURE if EXISTS p2; + +--echo # SQL_CALC_FOUND_ROWS disables optimization +explain SELECT a,b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +explain SELECT sql_calc_found_rows a,b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +SELECT sql_calc_found_rows a,b FROM t1 WHERE b > 2 LIMIT 100 OFFSET 1; +SELECT found_rows(); + +--echo # HAVING does, too + +SELECT b FROM t1 HAVING b = 3; +explain SELECT b FROM t1 HAVING b = 3 LIMIT 100 OFFSET 1; +SELECT b FROM t1 HAVING b = 3 LIMIT 100 OFFSET 1; + +--echo # Offset pushdown supports merged derived tables +SET big_tables = 1; +--echo # use InnoDB if we materialize +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM (SELECT * FROM t1) d LIMIT 100 OFFSET 1; +SELECT * FROM (SELECT * FROM t1) d LIMIT 100 OFFSET 1; +--echo # Offset pushdown doesn't support materialized derived tables +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT /*+ no_merge() */ * FROM (SELECT * FROM t1) d LIMIT 100 OFFSET 1; +SELECT /*+ no_merge() */ * FROM (SELECT * FROM t1) d LIMIT 100 OFFSET 1; +--echo # even if an index is used +SELECT /*+ no_merge() no_derived_condition_pushdown()*/ * FROM (SELECT * FROM t1) d WHERE b = 3; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT /*+ no_merge() no_derived_condition_pushdown()*/ * FROM (SELECT * FROM t1) d WHERE b = 3 LIMIT 1 OFFSET 1; +SELECT /*+ no_merge() no_derived_condition_pushdown()*/ * FROM (SELECT * FROM t1) d WHERE b = 3 LIMIT 1 OFFSET 0; +SELECT /*+ no_merge() no_derived_condition_pushdown()*/ * FROM (SELECT * FROM t1) d WHERE b = 3 LIMIT 1 OFFSET 1; +SELECT /*+ no_merge() no_derived_condition_pushdown()*/ * FROM (SELECT * FROM t1) d WHERE b = 3 LIMIT 1 OFFSET 2; +SELECT /*+ no_merge() no_derived_condition_pushdown()*/ * FROM (SELECT * FROM t1) d WHERE b = 3 LIMIT 1 OFFSET 3; +SET big_tables = default; + +--echo # Offset pushdown in a correlated subquery which is executed multiple times: +--echo # check that each result is ok +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT (SELECT b+0*t0.b FROM t1 ORDER BY b LIMIT 1 OFFSET 2) FROM t1 AS t0; +SELECT (SELECT b+0*t0.b FROM t1 ORDER BY b LIMIT 1 OFFSET 2) FROM t1 AS t0; + +--echo # prepared statements: +--echo # check that nothing that is reused is changed +prepare stmt1 FROM 'SELECT * FROM t1 where b < 4 limit 100 OFFSET 1'; +execute stmt1; +execute stmt1; +execute stmt1; +deallocate prepare stmt1; +DROP TABLE t1; +--echo # test +CREATE TABLE t2(a INT , b INT , INDEX(b)); +INSERT INTO t2 VALUES (1, 2), (2, 3), (3, 3), (4, 3),(5,6),(6,7); +analyze TABLE t2; +--echo # With UNION ALL +--echo # without overlap +(SELECT * FROM t2 WHERE b > 4 LIMIT 100 OFFSET 0) UNION ALL (SELECT * FROM t2 WHERE b < 3 LIMIT 100 OFFSET 0) LIMIT 100 OFFSET 0; +(SELECT * FROM t2 WHERE b > 4 LIMIT 100 OFFSET 1) UNION ALL (SELECT * FROM t2 WHERE b < 3 LIMIT 100 OFFSET 0) LIMIT 100 OFFSET 0; +(SELECT * FROM t2 WHERE b > 4 LIMIT 100 OFFSET 0) UNION ALL (SELECT * FROM t2 WHERE b < 3 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 0; +(SELECT * FROM t2 WHERE b > 4 LIMIT 100 OFFSET 1) UNION ALL (SELECT * FROM t2 WHERE b < 3 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 0; +(SELECT * FROM t2 WHERE b > 4 LIMIT 100 OFFSET 0) UNION ALL (SELECT * FROM t2 WHERE b < 3 LIMIT 100 OFFSET 0) LIMIT 100 OFFSET 1; +(SELECT * FROM t2 WHERE b > 4 LIMIT 100 OFFSET 1) UNION ALL (SELECT * FROM t2 WHERE b < 3 LIMIT 100 OFFSET 0) LIMIT 100 OFFSET 1; +(SELECT * FROM t2 WHERE b > 4 LIMIT 100 OFFSET 0) UNION ALL (SELECT * FROM t2 WHERE b < 3 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 1; +--echo # outer OFFSET does not activate offset pushdown +--echo # inner OFFSET activates offset pushdown +(SELECT * FROM t2 WHERE b > 4 LIMIT 100 OFFSET 1) UNION ALL (SELECT * FROM t2 WHERE b < 3 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 1; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree (SELECT * FROM t2 WHERE b > 4 LIMIT 100 OFFSET 1) UNION ALL (SELECT * FROM t2 WHERE b < 3 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 1; +--echo with overlap +(SELECT * FROM t2 WHERE b < 7 LIMIT 100 OFFSET 0) UNION ALL (SELECT * FROM t2 WHERE b < 4 LIMIT 100 OFFSET 0) LIMIT 100 OFFSET 0; +(SELECT * FROM t2 WHERE b < 7 LIMIT 100 OFFSET 1) UNION ALL (SELECT * FROM t2 WHERE b < 4 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 0; +(SELECT * FROM t2 WHERE b < 7 LIMIT 100 OFFSET 1) UNION ALL (SELECT * FROM t2 WHERE b < 4 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 1; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree (SELECT * FROM t2 WHERE b < 7 LIMIT 100 OFFSET 1) UNION ALL (SELECT * FROM t2 WHERE b < 4 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 1; +--echo # With UNION +--echo # Only test with overlap +(SELECT * FROM t2 WHERE b < 7 LIMIT 100 OFFSET 0) UNION (SELECT * FROM t2 WHERE b < 4 LIMIT 100 OFFSET 0) LIMIT 100 OFFSET 0; +(SELECT * FROM t2 WHERE b < 7 LIMIT 100 OFFSET 1) UNION (SELECT * FROM t2 WHERE b < 4 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 0; +(SELECT * FROM t2 WHERE b < 7 LIMIT 100 OFFSET 1) UNION (SELECT * FROM t2 WHERE b < 4 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 1; +--echo # Same behavior as UNION ALL: +--echo # outer OFFSET does not activate offset pushdown +--echo # inner OFFSET activates offset pushdown +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree (SELECT * FROM t2 WHERE b < 7 LIMIT 100 OFFSET 1) UNION (SELECT * FROM t2 WHERE b < 4 LIMIT 100 OFFSET 1) LIMIT 100 OFFSET 1; +--echo HA_POS_ERROR has to disable offset pushdown optimisation although the query otherwise satisfies the condition for said optimisation: + SET optimizer_switch = 'offset_pushdown=off'; +SELECT * FROM t2 WHERE b > 2 LIMIT 18446744073709551615 OFFSET 1; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t2 WHERE b > 2 LIMIT 18446744073709551615 OFFSET 1; + SET optimizer_switch = 'offset_pushdown=on'; +SELECT * FROM t2 LIMIT 18446744073709551615 OFFSET 1; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t2 WHERE b > 2 LIMIT 18446744073709551615 OFFSET 1; +--echo # Fewer calls from sql-layer to handler when the optimization is on: +SET optimizer_switch = 'offset_pushdown=off'; +flush status; +SELECT * FROM t2 WHERE b > 2 LIMIT 100 OFFSET 4; +show status LIKE 'handler_read%'; +SET optimizer_switch = 'offset_pushdown=on'; +flush status; +SELECT * FROM t2 WHERE b > 2 LIMIT 100 OFFSET 4; +show status LIKE 'handler_read%'; +DROP TABLE t2; +--echo # offset pushdown with primary key - feature activated only with empty_redundant_check_in_range_scan +--echo # which removes the unnecessary SQL layer check of the WHERE clause +CREATE TABLE test_pk +(a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a)); +INSERT INTO test_pk VALUES (1,0),(2,1),(3,2),(4,3); +analyze TABLE test_pk; +SET empty_redundant_check_in_range_scan = false; +explain SELECT * FROM test_pk WHERE a > 2 ORDER BY a LIMIT 100 OFFSET 1; +SET empty_redundant_check_in_range_scan = true; +explain SELECT * FROM test_pk WHERE a > 2 ORDER BY a LIMIT 100 OFFSET 1; + +--echo # Query with only constant tables, makes sure changes to EXPLAIN code don't crash +--echo # (no pushdown needed): +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM test_pk WHERE a = 2 LIMIT 100; + +DROP TABLE test_pk; +--echo # Empty redundant condition in index range scan: check different data types +--echo # redundant check removal extended to real numbers (DOUBLE) +CREATE TABLE t6(a DOUBLE, b DOUBLE, c DOUBLE , INDEX(a,b,c)); +INSERT INTO t6 VALUES (1,2,6), (2,3,7), (3,3,8), (4,3,12); +analyze TABLE t6; +SET empty_redundant_check_in_range_scan = false; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t6 WHERE a > 2; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t6 WHERE a = 2 AND b < 5 AND b > 1; +SET empty_redundant_check_in_range_scan = true; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t6 WHERE a > 2; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t6 WHERE a = 2 AND b < 5 AND b > 1; +DROP TABLE t6; +--echo # redundant check removal extended to DECIMAL +CREATE TABLE t6(a DECIMAL, b DECIMAL, c DECIMAL , INDEX(a,b,c)); +INSERT INTO t6 VALUES (1,2,6), (2,3,7), (3,3,8), (4,3,12); +analyze TABLE t6; +SET empty_redundant_check_in_range_scan = false; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t6 WHERE a > 2; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t6 WHERE a = 2 AND b < 5 AND b > 1; +SET empty_redundant_check_in_range_scan = true; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t6 WHERE a > 2; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t6 WHERE a = 2 AND b < 5 AND b > 1; +DROP TABLE t6; +--echo # redundant check removal extended to String +CREATE TABLE people(zipcode CHAR(10),lastname CHAR(10), firstname CHAR(10),address CHAR(10), INDEX (zipcode, lastname, firstname)); +analyze TABLE people; +SET empty_redundant_check_in_range_scan = false; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM people WHERE zipcode > '95054'; +SET empty_redundant_check_in_range_scan = true; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM people WHERE zipcode > '95054'; +DROP TABLE people; +--echo # Test skip scan +CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL, PRIMARY KEY(f1, f2)); +INSERT INTO t1 VALUES + (1,1), (1,2), (1,3), (1,4), (1,5), + (2,1), (2,2), (2,3), (2,4), (2,5); +INSERT INTO t1 SELECT f1, f2 + 5 FROM t1; +INSERT INTO t1 SELECT f1, f2 + 10 FROM t1; +INSERT INTO t1 SELECT f1, f2 + 20 FROM t1; +INSERT INTO t1 SELECT f1, f2 + 40 FROM t1; +ANALYZE TABLE t1; +--echo # first test without LIMIT OFFSET +SET empty_redundant_check_in_range_scan = false; +EXPLAIN SELECT f1, f2 FROM t1 WHERE f2 > 40; +SET empty_redundant_check_in_range_scan = true; +EXPLAIN SELECT f1, f2 FROM t1 WHERE f2 > 40; +--echo #redundant conditions in skip scans can be removed +--echo # test with LIMIT OFFSET +SET empty_redundant_check_in_range_scan = true; +EXPLAIN SELECT f1, f2 FROM t1 WHERE f2 > 40 LIMIT 100 OFFSET 2; +--echo # but skip scan cannot be used together with offset pushdown +DROP TABLE if EXISTS t1; + CREATE TABLE jemp ( + c JSON, + g INT GENERATED ALWAYS AS (c->"$.id"), + INDEX i (g) + ); + + + INSERT INTO jemp (c) VALUES + ('{"id": "1", "name": "Fred"}'), ('{"id": "2", "name": "Wilma"}'), + ('{"id": "3", "name": "Barney"}'), ('{"id": "4", "name": "Betty"}'); +analyze TABLE jemp; + +--echo # without optimization +SET empty_redundant_check_in_range_scan = false; + SELECT c->>"$.name" AS name + FROM jemp WHERE g > 2; + EXPLAIN SELECT c->>"$.name" AS name + FROM jemp WHERE g > 2; +--echo # with optimization +SET empty_redundant_check_in_range_scan = true; + SELECT c->>"$.name" AS name + FROM jemp WHERE g > 2; + EXPLAIN SELECT c->>"$.name" AS name + FROM jemp WHERE g > 2; +--echo # works with offset pushdown + SELECT c->>"$.name" AS name + FROM jemp WHERE g > 2 LIMIT 1 OFFSET 1; + EXPLAIN format=tree SELECT c->>"$.name" AS name + FROM jemp WHERE g > 2; + +DROP TABLE if EXISTS jemp; + +--echo # Inspired by the test for Bug #27578340: INCONSISTENT RESULTS FOR SELECTS FROM TABLE WITH CHAR(N) COLUMN +--echo # AND NO_PAD COLLATION from ctype_uca.test, +--echo # verify that an inequality condition is kept at SQL layer: + +CREATE TABLE t1 ( + f1 CHAR(20) COLLATE utf8mb4_0900_ai_ci # A NO PAD collation. +); +INSERT INTO t1 VALUES ('ABC '); +INSERT INTO t1 VALUES ('XYZ'); +INSERT INTO t1 VALUES ('XYZ '); +INSERT INTO t1 VALUES ('ABC '); + +CREATE INDEX f1_index ON t1 ( f1 ); +analyze table t1; + +set empty_redundant_check_in_range_scan = on; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT CONCAT(f1, '|') FROM t1 WHERE f1 >= 'XYZ '; + +--echo # Now, a PAD SPACE collation, condition is not kept + +ALTER TABLE t1 modify f1 CHAR(20) COLLATE utf8mb4_unicode_ci; +analyze TABLE t1; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT CONCAT(f1, '|') FROM t1 WHERE f1 >= 'XYZ '; + +SET empty_redundant_check_in_range_scan=default; +DROP TABLE t1; +--echo # Can remove DATE +SET empty_redundant_check_in_range_scan = true; +CREATE TABLE t9(a date); + ALTER TABLE t9 ADD INDEX (a); + INSERT INTO t9 VALUES ("20210907"); + INSERT INTO t9 VALUES ("20210907"); + INSERT INTO t9 VALUES ("20210907"); + INSERT INTO t9 VALUES ("20210907"); + INSERT INTO t9 VALUES ("20210907"); + INSERT INTO t9 VALUES ("20210907"); + INSERT INTO t9 VALUES ("20210907"); + INSERT INTO t9 VALUES ("20210907"); + INSERT INTO t9 VALUES ("20210907"); + INSERT INTO t9 VALUES ("20210907"); + INSERT INTO t9 VALUES ("20210907"); + INSERT INTO t9 VALUES ("20210907"); + INSERT INTO t9 VALUES ("20210907"); + INSERT INTO t9 VALUES ("20210907"); + INSERT INTO t9 VALUES ("20210907"); + INSERT INTO t9 VALUES ("20210907"); + analyze TABLE t9; + --replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t9 WHERE a >= "20211001"; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t9 WHERE a >= "2021-10-01"; + +--echo # can remove DATETIME +DROP TABLE if EXISTS t9; +CREATE TABLE t9(a datetime); + ALTER TABLE t9 ADD index(a); + INSERT INTO t9 VALUES ("2021-09-07 12:11"); + INSERT INTO t9 VALUES ("2021-09-07 12:11"); + INSERT INTO t9 VALUES ("2021-09-07 12:11"); + INSERT INTO t9 VALUES ("2021-09-07 12:11"); + INSERT INTO t9 VALUES ("2021-09-07 12:11"); + INSERT INTO t9 VALUES ("2021-09-07 12:11"); +analyze TABLE t9; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t9 WHERE a >= "2022-09-07 12:25"; +--echo # can remove TIMESTAMP +DROP TABLE if EXISTS t9; +CREATE TABLE t9 (a TIMESTAMP); + ALTER TABLE t9 ADD INDEX (a); + INSERT INTO t9 VALUES ("2021-09-07 12:11"); + INSERT INTO t9 VALUES ("2021-09-07 12:11"); + INSERT INTO t9 VALUES ("2021-09-07 12:11"); + INSERT INTO t9 VALUES ("2021-09-07 12:11"); + INSERT INTO t9 VALUES ("2021-09-07 12:11"); + INSERT INTO t9 VALUES ("2021-09-07 12:11"); +analyze TABLE t9; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t9 WHERE a >= "2022-09-07 12:25"; +--echo # can remove TIME +DROP TABLE if EXISTS t9; +CREATE TABLE t9 (a time); + ALTER TABLE t9 ADD INDEX (a); + INSERT INTO t9 VALUES ("1211"); + INSERT INTO t9 VALUES ("1211"); + INSERT INTO t9 VALUES ("1211"); + INSERT INTO t9 VALUES ("1211"); + INSERT INTO t9 VALUES ("1211"); + INSERT INTO t9 VALUES ("1211"); + INSERT INTO t9 VALUES ("1211"); + INSERT INTO t9 VALUES ("1211"); +analyze TABLE t9; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t9 WHERE a >= "1218"; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t9 WHERE a >= "12:18"; +DROP TABLE IF EXISTS t9; +--echo # ORDER BY ASC/DESC with INDEX ASC/DESC +--echo # table t10 has descending index while t11 has normal index +CREATE TABLE t10 ( + c1 INT, c2 INT, + INDEX idx4 (c1 DESC, c2 DESC) +); +INSERT INTO t10 VALUES (1,2),(3,4),(5,6),(7,8),(9,10); +CREATE TABLE t11 ( + c1 INT, c2 INT, + INDEX idx4 (c1 , c2 ) +); +INSERT INTO t11 VALUES (1,2),(3,4),(5,6),(7,8),(9,10); + +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT * FROM t10 WHERE c1 > 2 ORDER BY c1 DESC LIMIT 100 OFFSET 1; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT * FROM t11 WHERE c1 > 2 ORDER BY c1 DESC LIMIT 100 OFFSET 1; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT * FROM t10 WHERE c1 > 2 ORDER BY c1 ASC LIMIT 100 OFFSET 1; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT * FROM t11 WHERE c1 > 2 ORDER BY c1 ASC LIMIT 100 OFFSET 1; +SELECT * FROM t10 WHERE c1 > 2 ORDER BY c1 DESC LIMIT 100 OFFSET 1; +SELECT * FROM t11 WHERE c1 > 2 ORDER BY c1 DESC LIMIT 100 OFFSET 1; +SELECT * FROM t10 WHERE c1 > 2 ORDER BY c1 ASC LIMIT 100 OFFSET 1; +SELECT * FROM t11 WHERE c1 > 2 ORDER BY c1 ASC LIMIT 100 OFFSET 1; + +--echo # Verify that the hint overrules the switch: +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t11 WHERE c1 > 2 ORDER BY c1 ASC LIMIT 100 OFFSET 1; +SET optimizer_switch = 'offset_pushdown=off'; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT * FROM t11 WHERE c1>2 ORDER BY c1 ASC LIMIT 100 OFFSET 1; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT /*+ OFFSET_PUSHDOWN() */ * FROM t11 WHERE c1 > 2 ORDER BY c1 ASC LIMIT 100 OFFSET 1; +SET optimizer_switch='offset_pushdown=on'; + +--echo # Verify that in a LEFT JOIN, the range condition is removed or not, correctly. +--echo # Conditions on left table can be removed: +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t11.c1 > 3 WHERE t11.c1 > 2; +--echo # Condition on right table too, as it's in ON: if the range access has kept only +--echo # rows of t12 with c1>3, this condition will not need to be checked again. +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t12.c1 > 3 WHERE t11.c1 > 2; +--echo # These two don't prove much, as the left join is changed to an inner join +--echo # (as NULL-complemented rows cannot match the WHERE). +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t11.c1 > 3 WHERE t12.c1 > 2; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t12.c1 > 3 WHERE t12.c1 > 2; +--echo # Here the WHERE IS NULL cannot be removed: the range access has kept only +--echo # rows of t12 with c1 NULL, but there can be other NULL-complemented rows, +--echo # and then the WHERE must be checked on them too. This case is properly caught +--echo # by the test: !(func->used_tables() & null_extended) in reduce_cond_for_table(). +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t12.c1 > 3 WHERE t12.c1 IS NULL; + +DROP TABLE t10,t11; +CREATE TABLE t2 (b INT , key(b)); +INSERT INTO t2 VALUES (1),(1),(2),(2),(3),(3); +--echo # Check that offset pushdown is deactivated when DISTINCT is done by doing some grouping +--echo # inside ORDER BY ( "grouped" is true in if() condition in JOIN::offset_pushdown().) +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT /*+ NO_OFFSET_PUSHDOWN() */ DISTINCT b FROM t2 ORDER BY b LIMIT 100 OFFSET 1; +SELECT /*+ NO_OFFSET_PUSHDOWN() */ DISTINCT b FROM t2 ORDER BY b LIMIT 100 OFFSET 1; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT /*+ OFFSET_PUSHDOWN() */ DISTINCT b FROM t2 ORDER BY b LIMIT 100 OFFSET 1; +SELECT /*+ OFFSET_PUSHDOWN() */ DISTINCT b FROM t2 ORDER BY b LIMIT 100 OFFSET 1; +--echo # Check that offset pushdown is deactivated when using index for group-by is used +--echo # (similarly to the previous test: DISTINCT is done by doing some grouping inside ORDER BY) +--echo # in that case "grouped" is true. +analyze TABLE t2; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain SELECT /*+ NO_OFFSET_PUSHDOWN() */ DISTINCT b FROM t2 ORDER BY b LIMIT 100 OFFSET 1; +SELECT /*+ NO_OFFSET_PUSHDOWN() */ DISTINCT b FROM t2 ORDER BY b LIMIT 100 OFFSET 1; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain SELECT /*+ OFFSET_PUSHDOWN() */ DISTINCT b FROM t2 ORDER BY b LIMIT 100 OFFSET 1; +SELECT /*+ OFFSET_PUSHDOWN() */ DISTINCT b FROM t2 ORDER BY b LIMIT 100 OFFSET 1; + +DROP TABLE t2; + +CREATE TABLE t1 (a INT , b INT , c INT , INDEX(a,b,c)); +INSERT INTO t1 VALUES (1,100,1),(2,200,1),(3,300,1),(4,10,2),(5,20,2),(6,30,2),(7,110,3),(8,120,3),(9,130,3); + +CREATE TABLE t2 (a INT , b INT , c INT , INDEX(a,b,c)); +INSERT INTO t2 VALUES (1,110,1),(2,210,1),(4,20,2),(5,30,2),(7,130,3),(8,140,3); +--echo # Subqueries +--echo # DOES NOT WORK on outer queries +--echo # Offset pushdown is evaluated for each JOIN object and can therefore be applied to subqueries if a given JOIN object does qualify for OP. +--echo # Both explain format=tree and actual query output are given since the feature is activated -- easier to maintain if outputs are produced +--echo # Uncorrelated +--echo # Inner query with LIMIT OFFSET +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t1 WHERE a > (SELECT a FROM t1 LIMIT 1 OFFSET 1); +SELECT * FROM t1 WHERE a > (SELECT a FROM t1 LIMIT 1 OFFSET 1); +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t1 WHERE a > (SELECT a FROM t1 WHERE a>2 LIMIT 1 OFFSET 1); +SELECT * FROM t1 WHERE a > (SELECT a FROM t1 WHERE a>2 LIMIT 1 OFFSET 1); +--echo # Offset pushdown outer query - non constant item_subselect - no offset pushdown +--echo # add row for non empty output of following SELECT statement +INSERT INTO t1 values (9,131,1); +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t1 WHERE a = (SELECT max(a) FROM t1 WHERE a > 2) LIMIT 1 OFFSET 1; +SELECT * FROM t1 WHERE a = (SELECT max(a) FROM t1 WHERE a > 2) LIMIT 1 OFFSET 1; +DELETE FROM t1 WHERE a=9 AND b=131 AND c=3; +--echo # both inner and outer queries with LIMIT OFFSET +--echo # non constant item_subselect - no offset pushdown for the outer query +--echo # add row for non empty output of following SELECT statement +INSERT INTO t1 values (4,10,3),(4,10,3),(4,10,3); +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t1 WHERE a =(SELECT a FROM t1 WHERE a > 2 LIMIT 1 OFFSET 1) LIMIT 2 OFFSET 3; +SELECT * FROM t1 WHERE a = (SELECT a FROM t1 WHERE a > 2 LIMIT 1 OFFSET 1) LIMIT 2 OFFSET 3; +DELETE FROM t1 WHERE a=4 AND b=10 AND c=3; +--echo # Correlated was covered before + +--echo # SHOW that JOIN, SELF JOIN do not trigger offset pushdown +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t1 JOIN t2 LIMIT 1 OFFSET 1; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM t1 T1, t1 T2 LIMIT 2 OFFSET 10; + +--echo # Table function are not compatible with offset pushdown +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree SELECT * FROM JSON_TABLE('[{"x":2,"y":"8"},{"x":"3","y":"7"},{"x":"4","y":6}]',"$[1]" COLUMNS(xval VARCHAR(100) PATH "$.x", yval VARCHAR(100) PATH "$.y")) AS jt1 LIMIT 100 OFFSET 1; + +DROP TABLE t1,t2; + +--echo # OFFSET exceeds number of rows: When the offset exceed the number of rows returned by the query without offset, offset pushdown still works +CREATE TABLE t1 (a INT, b INT , INDEX(a,b)); +INSERT INTO t1 VALUES (1,1),(2,2),(3,4),(8,9); +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT * FROM t1 LIMIT 1 OFFSET 5; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t1 LIMIT 1 OFFSET 5; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +DROP TABLE t1; + + +--echo ############################################## +--echo ############################################## +--echo # +--echo BUG2022101200261 +--echo # +--echo ############################################## +--echo ############################################## + + +--echo ############################################## + +--echo # INT comparison + +--echo ############################################## + + +CREATE TABLE t11 ( + c1 INT, c2 INT, + INDEX idx4 (c1 , c2 ) +); +INSERT INTO t11 VALUES (1,2),(3,4),(5,6),(7,8),(9,10); + +--echo # Two items containing t12.c1 > 3 and t12.c1 > 2 +--echo # key_min only contains 3 +--echo # Check that INT comparison works + +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t12.c1 > 3 WHERE t12.c1 > 2; + + +drop table t11; + + + +--echo ############################################## + +--echo # Descending index + +--echo ############################################## + + +CREATE TABLE t10 ( + c1 INT, c2 INT, + INDEX idx4 (c1 DESC, c2 DESC) +); +INSERT INTO t10 VALUES (1,2),(3,4),(5,6),(7,8),(9,10); + +--echo # Make sure the min and the max are swapped when the index was descending + +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT * FROM t10 WHERE c1 > 2 ORDER BY c1 DESC LIMIT 100 OFFSET 1; +drop table t10; + +--echo ############################################## + +--echo # BUG TEST 4: Navigating key_min and key_max; check that store_length fulfills its purpose +--echo ############################################## + + +CREATE TABLE t1 ( +pk INT PRIMARY KEY, +i1 INT, +i2 INT, +v varchar(1), +INDEX i1_idx (i1), +INDEX v_idx (v,i1) +) ENGINE=InnoDB, CHARSET utf8mb4; +INSERT INTO t1 VALUES (1, 1, 9,'a'), (2, 2, 8,'b'), (3, 3, 7,'c'), +(4, 4, 6,'d'), (5, 5, 5,'e'); + + +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT v FROM t1 WHERE i1 = 1 AND v = 'a' AND pk < 3; + +DROP TABLE t1; + + +--echo ############################################## + +--echo # NO_MAX/MIN_RANGE flag + +--echo ############################################## + + +CREATE TABLE t1(pk INT , i4 INT ,INDEX(i4)); + + +INSERT INTO t1 VALUES (1,10), (2,20), (3,30); + +--echo # the comparison for the upper limit is not even performed because NO_MAX_RANGE flag is set + +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999; + +drop table t1; + +--echo ############################################## + +--echo # comparison to NULL + +--echo ############################################## + +--echo # column_A IS NULL is the only comparison we handle +--echo # Following example: 2 items NULL and 18446744073709551614 +--echo # : 1 key_min 18446744073709551614 +--echo # We cannot justify removing NULL. +CREATE TABLE t11 ( + c1 BIGINT UNSIGNED, c2 BIGINT UNSIGNED, + INDEX idx4 (c1 , c2 ) +); +INSERT INTO t11 VALUES (1,2),(3,4),(5,6),(7,8),(9,10); + +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t11.c1 > NULL WHERE t11.c1 > 18446744073709551614; + +--echo # If we try to remove c1>NULL, we get a wrong select output +--echo # The following test verifies that the current implementation produce the same results +--echo # regardless of the status of empty_redundant_check_in_range_scan +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t11.c1 > NULL WHERE t11.c1 > 3; +SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t11.c1 > NULL WHERE t11.c1 > 3; +SET empty_redundant_check_in_range_scan=false; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +EXPLAIN format=tree SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t11.c1 > NULL WHERE t11.c1 > 3; +SELECT * FROM t11 LEFT JOIN t11 AS t12 ON t11.c1 > NULL WHERE t11.c1 > 3; +SET empty_redundant_check_in_range_scan=true; + + +drop table t11; + +--echo ############################################## + +--echo # NOT BETWEEN + +--echo ############################################## + + +--echo # NOT BETWEEN should not be handled by redundant condition removal +--echo # Disjoint intervals, similar to OR clauses, not handled by current design. + +create table ta ( a float default NULL ,b decimal(25,5) DEFAULT NULL, key(a)); +insert into ta values (100,1),(2000,2),(30000,3),(400000,4),(900000,5); +analyze table ta; +--replace_regex /cost=\d+.\d+/cost=***/ /rows=\d+/rows=***/ +explain format=tree select * from ta INNER JOIN ta tb ON ta.b=tb.a where ta.a NOT BETWEEN -1.17549e-38 AND -1.17549e-38; +drop table ta; + diff --git a/mysql-test/t/offset_pushdown_insert_delete_update.test b/mysql-test/t/offset_pushdown_insert_delete_update.test new file mode 100644 index 00000000000..a49d1f7f847 --- /dev/null +++ b/mysql-test/t/offset_pushdown_insert_delete_update.test @@ -0,0 +1,616 @@ +--source include/count_sessions.inc + +SET @old_innodb_lock_wait_timeout= @@global.innodb_lock_wait_timeout; + +SET @@global.innodb_lock_wait_timeout = 1; + + + + +--echo # ---------------------- +--echo # ---------------------- + +--echo # MVCC - INSERT/ UPDATE/ DELETE with OFFSET PUSHDOWN + +--echo # For each, we test +--echo # 1/ INSERT/ UPDATE/ DELETE first in one session then SELECT with OP in another +--echo # 2/ SELECT with OP first in one session then INSERT/ UPDATE/ DELETE in another + +--echo # ---------------------- +--echo # ---------------------- + + +--echo # To keep track of the number of rows skipped by OFFSET pushdown we use: +--echo # SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +--echo # SELECT query +--echo # SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + + + + +CREATE TABLE t3 (a INT, b INT, INDEX(a,b)); +INSERT INTO t3 VALUES (1, 2), (2, 3), (3, 3), (4, 3); + +--echo # ---------------------- +--echo # ---------------------- + +--echo # MVCC INSERT and OFFSET pushdown + +--echo # ---------------------- +--echo # ---------------------- + +--echo # Insert in one session, not committed, SELECT query with OP in another session - check that results are consistent +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; + + + +-- echo # session 1: Trx that inserts a new rows +START TRANSACTION; +INSERT INTO t3 VALUES (6,6); +SELECT * FROM t3; + +--echo # session 2: Trx with SELECT query with OP - check that the inserted row is not accounted for +--echo # neither for the SELECT with and without OFFSET pushdown. +connection con2; +START TRANSACTION; +--replace_regex /cost=[0-9]+.[0-9]+/cost=#.#/ /rows=[0-9]+/rows=##/ +explain format=tree SELECT * FROM t3 WHERE a>1 LIMIT 100 OFFSET 1; +--echo # Both SELECT return the same output! rows skipped differ +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t3 WHERE a > 1 LIMIT 100 OFFSET 1; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t3 WHERE a > 1 LIMIT 100 OFFSET 1; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +rollback; +connection con1; +rollback; + +connection default; +disconnect con1; +disconnect con2; + + + + +--echo # MVCC Insert and Offset pushdown +--echo # Select first with OP - insert then +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; + + +-- echo # session 1: SELECT rows using OP +START TRANSACTION; +explain SELECT * FROM t3 WHERE a>1 LIMIT 100 OFFSET 1; +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t3 WHERE a > 1 LIMIT 100 OFFSET 1; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + + + +--echo # session 2: Insert rows in the table queried by OP +connection con2; +START TRANSACTION; +INSERT INTO t3 VALUES (6,6); +--echo # (6,6) is inserted here +SELECT * FROM t3; + + +connection con1; +--echo # (6,6) is not visible. +SELECT * FROM t3 WHERE a > 1 LIMIT 100 OFFSET 1; +rollback; +connection con2; +rollback; +connection default; +disconnect con1; +disconnect con2; + +--echo # ---------------------- +--echo # ---------------------- + +--echo # MVCC UPDATE with OFFSET pushdown + +--echo # ---------------------- +--echo # ---------------------- + + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; + + +-- echo # session 1: Trx that updates a row +START TRANSACTION; +UPDATE t3 SET a = 8 WHERE a = 4; +SELECT * FROM t3; + +--echo # session 2: Trx with SELECT query with OP - check that the updated row is not accounted for +--echo # neither for the SELECT with and without OFFSET pushdown. +connection con2; +START TRANSACTION; +--echo # Both output the same rows - rows skipped differ +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t3 WHERE a > 1 LIMIT 100 OFFSET 1; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t3 WHERE a > 1 LIMIT 100 OFFSET 1; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +rollback; +connection con1; +rollback; + +connection default; +disconnect con1; +disconnect con2; + + + + +--echo # MVCC UPDATE and Offset pushdown +--echo # Select first with OP - UPDATE then +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; + + +-- echo # session 1: SELECT rows using OP +START TRANSACTION; +explain SELECT * FROM t3 WHERE a>1 LIMIT 100 OFFSET 1; +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t3 WHERE a > 1 LIMIT 100 OFFSET 1; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + + + +--echo # session 2: Insert rows in the table queried by OP +connection con2; +UPDATE t3 SET a = 8 WHERE a =4; +--echo # (8,3) is updated here +SELECT * FROM t3; + + + +connection con1; +--echo # (8,3) is not updated. +SELECT * FROM t3 WHERE a > 1 LIMIT 100 OFFSET 1; +rollback; +connection con2; +rollback; +connection default; +disconnect con1; +disconnect con2; + + +--echo # ---------------------- +--echo # ---------------------- + +--echo # Additional testing for MVCC UPDATE : SELECT first - UPDATE then with VARCHAR + +--echo # ---------------------- +--echo # ---------------------- + +CREATE TABLE t4 ( a INT, b VARCHAR(50), INDEX(a)); +INSERT INTO t4 VALUES (1,'apples'),(2,'bananas'), (3,'oranges'),(4,'pears'); + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; + +start transaction; +EXPLAIN format=tree SELECT * FROM t4 WHERE a > 2 LIMIT 10 OFFSET 1; +--echo # Does not inspect clustered record. +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t4 WHERE a > 2 LIMIT 10 OFFSET 1; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + + +connection con2; +start transaction; +UPDATE t4 SET a = 2 WHERE a > 1; +UPDATE t4 SET b = ' I really do not like fruits' WHERE a = 2; +SELECT * FROM t4; + +connection con1; +--echo # Inspect clustered record - table unchanged +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t4 WHERE a > 2 LIMIT 10 OFFSET 1; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +rollback; + +connection con2; +rollback; + +connection default; +disconnect con1; +disconnect con2; + +DROP TABLE t4; + +--echo # ---------------------- +--echo # ---------------------- + +--echo # With PK access + +--echo # ---------------------- +--echo # ---------------------- + +CREATE TABLE t4 ( a INT, b VARCHAR(50), PRIMARY KEY (a)); +INSERT INTO t4 VALUES (1,'apples'),(2,'bananas'), (3,'oranges'),(4,'pears'); + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; + +start transaction; +EXPLAIN format=tree SELECT * FROM t4 WHERE a > 2 LIMIT 10 OFFSET 1; +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t4 WHERE a > 2 LIMIT 10 OFFSET 1; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + + + +connection con2; +start transaction; +UPDATE t4 SET a = 5 WHERE a = 1; +UPDATE t4 SET b = ' I really do not like fruits' WHERE a = 5; +SELECT * FROM t4; + +connection con1; +--echo # table unchanged +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t4 WHERE a > 2 LIMIT 10 OFFSET 1; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +rollback; + +connection con2; +rollback; + +connection default; +disconnect con1; +disconnect con2; + +DROP TABLE t4; + +--echo # ---------------------- +--echo # ---------------------- + +--echo # MVCC DELETE and OFFSET pushdown + + +--echo # ---------------------- +--echo # ---------------------- + +--echo # Delete row in one session, not committed, SELECT query (including the row to be deleted) +--echo # with OP in another session - check that results are consistent +insert into t3 values (3,10),(3,11),(3,12); +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; + +-- echo # session 1: Trx that delete a row +start transaction; +DELETE FROM t3 WHERE a > 2; +SELECT * FROM t3; + +--echo # session 2 : Trx that SELECTs the "to be deleted" row with OP - check that the deleted rows is not accounted for +--echo # neither for the SELECT with and without OFFSET pushdown. +connection con2; + +explain SELECT * FROM t3 WHERE a = 3 LIMIT 100 OFFSET 1; +--echo # They both output the same - rows skipped differ +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN()*/ * FROM t3 WHERE a=3 LIMIT 100 OFFSET 1; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t3 WHERE a = 3 LIMIT 100 OFFSET 1; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +connection con1; +rollback; +connection default; +disconnect con1; +disconnect con2; + +--echo # ---------------------- +--echo # ---------------------- + +--echo # SELECT first- DELETE NEXT + +--echo # ---------------------- +--echo # ---------------------- + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; + +-- echo # session 1: SELECT with OP +start transaction; +explain SELECT * FROM t3 WHERE a = 3 LIMIT 100 OFFSET 1; +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t3 WHERE a = 3 LIMIT 100 OFFSET 1; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + + +--echo # session 2 : DELETE after SELECT with OP +connection con2; +DELETE FROM t3 WHERE a > 2; +--echo # rows are deleted here +SELECT * FROM t3; + +connection con1; +--echo # rows are not deleted here +SELECT * FROM t3 WHERE a = 3 LIMIT 100 OFFSET 1; +rollback; +connection con2; +rollback; +connection default; +disconnect con1; +disconnect con2; + +DROP TABLE t3; + +--echo # ---------------------- +--echo # ---------------------- + +--echo # SELECT for UPDATE - INSERT with LOCKING READ + +--echo # ---------------------- +--echo # ---------------------- + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; + + + +CREATE TABLE t1 ( + dummy INT PRIMARY KEY, + a INT UNIQUE, + b INT, + KEY (a) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5); + +SELECT @@transaction_isolation; +START TRANSACTION; + +EXPLAIN SELECT * FROM t1 WHERE a < 2 FOR UPDATE; + +SELECT * FROM t1 WHERE a < 2 FOR UPDATE; + +connection con2; + +START TRANSACTION; +--replace_regex /cost=[0-9]+.[0-9]+/cost=#.#/ /rows=[0-9]+/rows=##/ +explain format=tree SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t1 LIMIT 100 OFFSET 1; +--replace_regex /cost=[0-9]+.[0-9]+/cost=#.#/ /rows=[0-9]+/rows=##/ +explain format=tree SELECT * FROM t1 LIMIT 100 OFFSET 1; +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t1 LIMIT 100 OFFSET 1; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t1 LIMIT 100 OFFSET 1; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +ROLLBACK; + +connection con1; + +ROLLBACK; +DROP TABLE t1; + +connection default; +disconnect con1; +disconnect con2; + +--echo # SELECT for update + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; + + + +CREATE TABLE t1 ( + dummy INT PRIMARY KEY, + a INT UNIQUE, + b INT, + KEY (a) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5); + + + +SELECT @@transaction_isolation; +START TRANSACTION; + +EXPLAIN SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t1 WHERE a < 2 LIMIT 100 OFFSET 2 FOR UPDATE; +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t1 WHERE a < 2 LIMIT 100 OFFSET 2 FOR UPDATE; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + + +connection con2; + + +START TRANSACTION; +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t1 VALUES (2,2,2); +ROLLBACK; + +connection con1; + +ROLLBACK; +DROP TABLE t1; + +connection default; +disconnect con1; +disconnect con2; + +--echo # SELECT for update with OP activated in for update + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; + + + +CREATE TABLE t1 ( + dummy INT PRIMARY KEY, + a INT UNIQUE, + b INT, + KEY (a) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5); + +SELECT @@transaction_isolation; +START TRANSACTION; + +EXPLAIN SELECT * FROM t1 WHERE a < 2 LIMIT 100 OFFSET 2 FOR UPDATE; +--echo # does not place a lock on the rows skipped by OFFSET pushdown +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t1 WHERE a < 2 LIMIT 100 OFFSET 2 FOR UPDATE; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + + +connection con2; + + +START TRANSACTION; +--echo # OP is deactivated here +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t1 VALUES (2,2,2); +ROLLBACK; + +connection con1; + +ROLLBACK; +DROP TABLE t1; + +connection default; +disconnect con1; +disconnect con2; + +--echo # ---------------- +--echo # ---------------- + +--echo # Virtual COLUMN - UPDATE + +--echo # ---------------- +--echo # ---------------- + + CREATE TABLE tv ( + a INT DEFAULT NULL, + b INT DEFAULT NULL, + c INT GENERATED ALWAYS AS ((a + b)) VIRTUAL, + KEY c (c) +); + + INSERT INTO tv(a,b) VALUES (1,2),(3,4),(5,6); + +--echo # NON-LOCKING read + + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +start transaction; +EXPLAIN format=tree SELECT * FROM tv WHERE c > 5 LIMIT 1 OFFSET 1; +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM tv WHERE c > 5 LIMIT 1 OFFSET 1; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + + +connection con2; +start transaction; +UPDATE tv SET a = 12 WHERE b > 1; +SELECT * FROM tv; + +connection con1; +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM tv WHERE c > 5 LIMIT 1 OFFSET 1; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +rollback; + +connection con2; +rollback; + +connection default; +disconnect con1; +disconnect con2; + +--echo # ---------------- +--echo # ---------------- + +--echo # Virtual COLUMN: UPDATE with LOCKING READ + +--echo # ---------------- +--echo # ---------------- + + + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +start transaction; +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM tv WHERE c > 5 LIMIT 1 OFFSET 1 FOR UPDATE; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + + +connection con2; +start transaction; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE tv SET a = 15 WHERE b = 2; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE tv SET a = 12 WHERE b > 2; + + +connection con1; +SET @save_skippped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM tv WHERE c > 5 LIMIT 1 OFFSET 1; +SELECT variable_value - @save_skippped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +rollback; + +connection con2; +rollback; + +connection default; +disconnect con1; +disconnect con2; + +DROP TABLE tv; +--echo # Restore orig wait timeout +--source include/wait_until_count_sessions.inc +SET @@global.innodb_lock_wait_timeout = @old_innodb_lock_wait_timeout; +DROP TABLE IF EXISTS t1; \ No newline at end of file diff --git a/mysql-test/t/offset_pushdown_limitations.test b/mysql-test/t/offset_pushdown_limitations.test new file mode 100644 index 00000000000..27b164529f0 --- /dev/null +++ b/mysql-test/t/offset_pushdown_limitations.test @@ -0,0 +1,121 @@ +--echo # Cases where Offset pushdown cannot be used: + +--echo # To keep track of the number of rows skipped by offset pushdown we use: +--echo # SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +--echo # SELECT query +--echo # SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +--source include/count_sessions.inc + +SET @old_innodb_lock_wait_timeout= @@global.innodb_lock_wait_timeout; + +SET @@global.innodb_lock_wait_timeout = 1; + +--echo # 1/ Index scan scenarios +--echo # Exotic scans not compatible with either offset pushing or redundant removal condition +--echo #( no skip scan or group min max already addressed in main test file.) + +--echo # 1/a/ Using intersect() (grep shows it's always with Using where) - OR clause disable with offset pushdown + +--echo # Redundant range condition is not compatible with using intersect +--echo # the where clause is going to stay - even if there is no where clause +--echo # which seems unlikely offset pushdown is not compatible with it anyways + +CREATE TABLE t1 +(a smallint, + b smallint, + c smallint, + KEY a (a), + KEY b (b) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES (1,1,1), (1,1,3),(1,2,7), (2,2,10),(1, 1, 13),(1, 2, 16),(2,1,19); +ANALYZE TABLE t1; +--replace_regex /cost=[0-9]+.[0-9]+/cost=#.#/ /rows=[0-9]+/rows=##/ +EXPLAIN format=tree SELECT * FROM t1 WHERE b = 2 AND a = 2 LIMIT 1 OFFSET 1; +DROP TABLE t1; + +--echo # 1/b/ Using union() - OR clause disabled with offset pushdown + +--echo # Redundant range condition is not compatible with using union +--echo # the where clause is going to stay - even if there is no where clause +--echo # which seems unlikely offset pushdown is not compatible with it anyways (grep shows) + +CREATE TABLE t1 +( + key1 INT NOT NULL, + key2 INT NOT NULL, + key3 INT NOT NULL, + key4 INT NOT NULL, + key5 INT, + key6 INT, + key7 INT NOT NULL, + key8 INT NOT NULL, + INDEX i1(key1), + INDEX i2(key2), + INDEX i3(key3), + INDEX i4(key4), + INDEX i5(key5), + INDEX i6(key6) +); +INSERT INTO t1 VALUES ( 1,1,1,1,1,1,1,1),(2,2,2,2,2,2,2,2); + +let $i=10; +SET @d=2; +while($i) +{ + INSERT INTO t1 SELECT key1+@d, key2+@d, key3+@d, key4+@d, + key5+@d, key6+@d, key7+@d, key8+@d FROM t1; + SET @d=@d*2; + dec $i; +} + +EXPLAIN SELECT * FROM t1 WHERE key1=48 OR key4=2 OR key6=3 LIMIT 1 OFFSET 1; +DROP TABLE t1; + + +--echo # ------------ + +--echo # Multi values index and offset pushdown + +--echo # The three ways that can trigger the use of the multivalue index (MEMBER OF() JSON_CONTAINS() JSON_OVERLAPS()) cannot +--echo # be pushed down by ICP or by empty_redundant_check_in_range_scan + +--echo # Multi values index won't be used together with offset pushdown until that changes + +--echo # ------------ + + CREATE TABLE customers ( + id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + modified DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + custinfo JSON +); + + + INSERT INTO customers VALUES + (NULL, '2022-04-19 10:15:45', '{"user":"Jack","user_id":37,"zipcode":[94582,94536]}'), + (NULL, '2022-04-19 10:15:45', '{"user":"Jill","user_id":22,"zipcode":[94568,94507,94582]}'), + (NULL, '2022-04-19 10:15:45', '{"user":"Bob","user_id":31,"zipcode":[94477,94507]}'), + (NULL, '2022-04-19 10:15:45', '{"user":"Mary","user_id":72,"zipcode":[94536]}'), + (NULL, '2022-04-19 10:15:45', '{"user":"Ted","user_id":56,"zipcode":[94507,94582]}'); + + --echo # add multi value index + ALTER TABLE customers ADD INDEX zips( (CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY)) ); + +--echo # Using where stays - no offset pushdown +--replace_regex /cost=[0-9]+.[0-9]+/cost=#.#/ /rows=[0-9]+/rows=##/ + EXPLAIN SELECT * FROM customers WHERE 94507 MEMBER OF(custinfo->'$.zipcode') LIMIT 1 OFFSET 1; + +--replace_regex /cost=[0-9]+.[0-9]+/cost=#.#/ /rows=[0-9]+/rows=##/ +EXPLAIN format=tree SELECT * FROM customers + WHERE JSON_CONTAINS(custinfo->'$.zipcode', CAST('[94507,94582]' AS JSON)) LIMIT 1 OFFSET 1; + +--replace_regex /cost=[0-9]+.[0-9]+/cost=#.#/ /rows=[0-9]+/rows=##/ +EXPLAIN format=tree SELECT * FROM customers WHERE JSON_OVERLAPS(custinfo->'$.zipcode', CAST('[94507,94582]' AS JSON)) LIMIT 1 OFFSET 1; + +drop table customers; + +# Restore orig wait timeout +--source include/wait_until_count_sessions.inc +SET @@global.innodb_lock_wait_timeout= @old_innodb_lock_wait_timeout; +DROP TABLE IF EXISTS t1; \ No newline at end of file diff --git a/mysql-test/t/offset_pushdown_locking_test.test b/mysql-test/t/offset_pushdown_locking_test.test new file mode 100644 index 00000000000..77b4e9d59b4 --- /dev/null +++ b/mysql-test/t/offset_pushdown_locking_test.test @@ -0,0 +1,1657 @@ +--echo # ------------------------------- +--echo # ------------------------------- + +--source include/count_sessions.inc + +--echo # Content of the test file: + +--echo # Offset pushdown and non-locking read + +--echo # SELECT LIMIT OFFSET FOR UPDATE w/ and w/o OP + +--echo # check locking - insert - # of rows skipped +--echo # READ COMMITED +--echo # LOCK IN SHARE MODE +--echo # READ UNCOMMITTED +--echo # SKIP LOCKED +--echo # NO WAIT +--echo # SERIALIZABLE +--echo # FOR UPDATE with serializable - all read rows have an x-lock -> equivalent to FOR UPDATE with RR +--echo # LOCK IN SHARE MODE with serializable - read rows have a s-lock - no different to LOCK IN SHARE MODE with RR + + + +--echo # To keep track of the number of rows skipped by offset pushdown we use: +--echo # SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +--echo # SELECT query +--echo # SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +--echo # ------------------------------- +--echo # ------------------------------- + +SET @old_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout; + +SET @@global.innodb_lock_wait_timeout = 1; + +--echo # TOP + +--echo # ------------------------------- + +--echo # SELECT LIMIT OFFSET FOR UPDATE w/ and w/o OP +--echo # check locking - insert - # of rows skipped + +--echo # ------------------------------ + +--echo # ------------------------------- + +--echo # Without OP + +--echo # ------------------------------- + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; + +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); + +--echo # Compare locks and count how many rows are skipped +--echo # template query: SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap WHERE a BETWEEN 15 AND 25 LIMIT 100 OFFSET 2 FOR UPDATE; +--echo # To check locking status use: SHOW ENGINE INNODB STATUS; with SET GLOBAL innodb_status_output_locks=ON; SET GLOBAL innodb_status_output=ON; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap WHERE a BETWEEN 15 AND 25 LIMIT 100 OFFSET 2 FOR UPDATE; +--echo # Check that we don't skip any rows + SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +connection con2; +START TRANSACTION; +--echo # Should go through +INSERT INTO t_gap VALUES (9); +INSERT INTO t_gap VALUES (31); +--echo # next key locking +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (11); +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (29); +--echo # gap lock +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (18); +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (23); + +rollback; +connection con1; +rollback; +DROP TABLE t_gap; + +connection default; +disconnect con1; +disconnect con2; + +--echo # ------------------------------- + +--echo # With OP + +--echo # ------------------------------- + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; + +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); + +--echo # Compare locks and count how many rows are skipped +--echo # Template query: SELECT * FROM t_gap WHERE a BETWEEN 15 AND 25 LIMIT 100 OFFSET 2 FOR UPDATE; +--echo # To check locking status use: SHOW ENGINE INNODB STATUS; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap WHERE a BETWEEN 15 AND 25 LIMIT 100 OFFSET 2 FOR UPDATE; +--echo # Check that we only skip one row +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +connection con2; +START TRANSACTION; +--echo # Should go through +INSERT INTO t_gap VALUES (9); +INSERT INTO t_gap VALUES (31); +--echo # next key locking +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (11); +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (29); +--echo # gap lock +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (18); +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (23); + +rollback; +connection con1; +rollback; +DROP TABLE t_gap; + +connection default; +disconnect con1; +disconnect con2; + +--echo # UPDATE statement locks and gaps locks + +--echo # -------------------- +--echo # Without OP +--echo # -------------------- + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; + +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30),(40),(50),(60),(70),(80),(90),(100); + +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap WHERE a BETWEEN 45 AND 65 LIMIT 100 OFFSET 3 FOR UPDATE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +connection con2; +START TRANSACTION; + +--echo # Record LOCKs +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 200 WHERE a = 50; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 300 WHERE a = 60; + + +--echo # Next key locking +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 67 WHERE a = 10; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 42 WHERE a = 20; + +UPDATE t_gap SET a = 200 WHERE a = 40; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 300 WHERE a = 70; + + +--echo # Gap Locks +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 47 WHERE a = 10; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 63 WHERE a = 90; + +--echo # No locks outside next key locking +DELETE FROM t_gap WHERE a=20; +DELETE FROM t_gap WHERE a=90; +INSERT INTO t_gap values (75),(85); +UPDATE t_gap SET a = 85 WHERE a = 80; + + +rollback; +connection con1; +rollback; +DROP TABLE t_gap; + +connection default; +disconnect con1; +disconnect con2; + + +--echo # -------------------- +--echo # With Offset pushdown +--echo # -------------------- + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; + +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30),(40),(50),(60),(70),(80),(90),(100); + +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap WHERE a BETWEEN 45 AND 65 LIMIT 100 OFFSET 3 FOR UPDATE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +connection con2; +START TRANSACTION; + +--echo # Record LOCKs +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 200 WHERE a = 50; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 300 WHERE a = 60; + + +--echo # Next key locking +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 67 WHERE a = 10; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 42 WHERE a = 20; + + +UPDATE t_gap SET a = 200 WHERE a = 40; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 300 WHERE a = 70; + + +--echo # Gap Locks +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 47 WHERE a = 10; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 63 WHERE a = 90; + +--echo # No locks outside next key locking +DELETE FROM t_gap WHERE a=20; +DELETE FROM t_gap WHERE a=90; +INSERT INTO t_gap values (75),(85); +UPDATE t_gap SET a = 85 WHERE a = 80; + +rollback; +connection con1; +rollback; +DROP TABLE t_gap; + +connection default; +disconnect con1; +disconnect con2; + +--echo # --------------------------------------------------- + +--echo # Skipping pk access + +--echo # --------------------------------------------------- + + +--echo # --------------------------------------------------- + +--echo # WITHOUT OP + +--echo # --------------------------------------------------- + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +CREATE TABLE t1 (b INT, PRIMARY KEY (b)); +INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(7); + +connection con1; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ b FROM t1 WHERE b>2 AND b<5 LIMIT 100 OFFSET 100 FOR UPDATE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + + +connection con2; + +start transaction; +UPDATE t1 SET b = 100 WHERE b = 2; +rollback; +start transaction; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t1 SET b = 100 WHERE b = 3; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t1 SET b = 100 WHERE b = 4; +UPDATE t1 SET b = 100 WHERE b = 5; +rollback; +connection con1; +rollback; + +DROP TABLE t1; +connection default; +disconnect con1; +disconnect con2; + +--echo # --------------------------------------------------- + +--echo # WITH OP + +--echo # --------------------------------------------------- +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +CREATE TABLE t1 (b INT, PRIMARY KEY (b)); +INSERT INTO t1 VALUES (1), (2), (3), (4),(5),(7); + +connection con1; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT b FROM t1 WHERE b>2 AND b<5 LIMIT 100 OFFSET 100 FOR UPDATE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + + +connection con2; + +start transaction; +UPDATE t1 SET b = 100 WHERE b = 2; +rollback; +start transaction; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t1 SET b = 100 WHERE b = 3; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t1 SET b = 100 WHERE b = 4; +UPDATE t1 SET b = 100 WHERE b = 5; +rollback; +connection con1; +rollback; + +DROP TABLE t1; +connection default; +disconnect con1; +disconnect con2; + +--echo # --------------------------------------------------- +--echo # --------------------------------------------------- + +--echo # SERIALIZABLE + +--echo # --------------------------------------------------- +--echo # --------------------------------------------------- + +--echo # ------------------------------- + +--echo # Without OP + +--echo # ------------------------------- + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); + +--echo # Compare locks and count how many rows are skipped +--echo # To check locking status use: SHOW ENGINE INNODB STATUS; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap WHERE a BETWEEN 15 AND 25 LIMIT 100 OFFSET 2 FOR UPDATE; +--echo # Check that we don't skip any rows +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +START TRANSACTION; +--echo # Should go through +INSERT INTO t_gap VALUES (9); +INSERT INTO t_gap VALUES (31); +--echo # next key locking +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (11); +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (29); +--echo # gap lock +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (18); +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (23); + +rollback; +connection con1; +rollback; +DROP TABLE t_gap; + +connection default; +disconnect con1; +disconnect con2; + +--echo # ------------------------------- + +--echo # With OP + +--echo # ------------------------------- + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); + +--echo # Compare locks and count how many rows are skipped +--echo # To check locking status use: SHOW ENGINE INNODB STATUS; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap WHERE a BETWEEN 15 AND 25 LIMIT 100 OFFSET 2 FOR UPDATE; +--echo # Check that we only skip one row +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +START TRANSACTION; +--echo # Should go through +INSERT INTO t_gap VALUES (9); +INSERT INTO t_gap VALUES (31); +--echo # next key locking +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (11); +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (29); +--echo # gap lock +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (18); +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (23); + +rollback; +connection con1; +rollback; +DROP TABLE t_gap; + +connection default; +disconnect con1; +disconnect con2; + + +--echo # --------------------------------------------------- +--echo # --------------------------------------------------- + +--echo # READ COMMITED + +--echo # --------------------------------------------------- +--echo # --------------------------------------------------- + + + +--echo # --------------------------------------------------- + + +--echo # Without OP + +--echo # --------------------------------------------------- + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + + + +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 50 FOR UPDATE; +--echo # Check that no rows are skipped +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +--echo # To check locking status use: SHOW ENGINE INNODB STATUS; +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +UPDATE t_gap SET a = 30 WHERE a = 10; +UPDATE t_gap SET a = 30 WHERE a = 20; +UPDATE t_gap SET a = 30 WHERE a = 30; +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +rollback; +connection con1; +rollback; +DROP TABLE t_gap; +connection default; +disconnect con1; +disconnect con2; + +--echo # --------------------------------------------------- + +--echo # With OP + +--echo # --------------------------------------------------- +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + + + +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 50 FOR UPDATE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +--echo # To check locking status use: SHOW ENGINE INNODB STATUS; +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +UPDATE t_gap SET a = 30 WHERE a = 10; +UPDATE t_gap SET a = 30 WHERE a = 20; +UPDATE t_gap SET a = 30 WHERE a = 30; +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +rollback; +connection con1; +rollback; +DROP TABLE t_gap; +connection default; +disconnect con1; +disconnect con2; + + +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; + + +--echo # --------------------------------------------------- + + +--echo # READ COMMITED without OP (bis) + +--echo # --------------------------------------------------- + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + + + +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); + +--echo # +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +--echo # To check locking status use: SHOW ENGINE INNODB STATUS; +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +UPDATE t_gap SET a = 30 WHERE a = 10; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 30 WHERE a = 20; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 30 WHERE a = 30; +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +rollback; +connection con1; +rollback; +DROP TABLE t_gap; +connection default; +disconnect con1; +disconnect con2; + +--echo # --------------------------------------------------- + +--echo # READ COMMITED with OP (bis) + +--echo # --------------------------------------------------- +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + + + +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +--echo # To check locking status use: SHOW ENGINE INNODB STATUS; +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +UPDATE t_gap SET a = 30 WHERE a = 10; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 30 WHERE a = 20; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 30 WHERE a = 30; +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +rollback; +connection con1; +rollback; +DROP TABLE t_gap; +connection default; +disconnect con1; +disconnect con2; + + +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; + +--echo # --------------------------------------------------- + +--echo #READ COMMITTED: Skipping pk access- check lock release + +--echo # --------------------------------------------------- + + +--echo # --------------------------------------------------- + +--echo # WITHOUT OP + +--echo # --------------------------------------------------- + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +CREATE TABLE t1 (b INT, PRIMARY KEY (b)); +INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(7); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ b FROM t1 LIMIT 100 OFFSET 100 FOR UPDATE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + + +connection con2; + +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +UPDATE t1 SET b = 100 WHERE b = 3; +rollback; +connection con1; +rollback; + +DROP TABLE t1; +connection default; +disconnect con1; +disconnect con2; + +--echo # --------------------------------------------------- + +--echo # WITH OP + +--echo # --------------------------------------------------- +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +CREATE TABLE t1 (b INT, PRIMARY KEY (b)); +INSERT INTO t1 VALUES (1), (2), (3), (4),(5),(7); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT b FROM t1 LIMIT 100 OFFSET 100 FOR UPDATE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + + +connection con2; + +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +UPDATE t1 SET b = 100 WHERE b = 3; +rollback; +connection con1; +rollback; + +DROP TABLE t1; +connection default; +disconnect con1; +disconnect con2; + +--echo # --------------------------------------------------- +--echo # --------------------------------------------------- + +--echo # LOCK IN SHARE MODE + +--echo # For RR, check that we can read but not update rows +--echo # For RC, can read, can't write - check what happens for released locks + +--echo # --------------------------------------------------- +--echo # --------------------------------------------------- + + + +--echo # --------------------------------------------------- + +--echo # For RR, check that we can read but not update rows + +--echo # --------------------------------------------------- + +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); + +--echo # --------------------------------------------------- + +--echo # Without OP + +--echo # --------------------------------------------------- +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 50 LOCK IN SHARE MODE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +connection con2; +start transaction; +SELECT * FROM t_gap WHERE a = 10 OR a = 20 OR a = 30; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 100 WHERE a = 10; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 100 WHERE a = 30; + +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (1); +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (15); +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (25); +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (1000); + +rollback; +connection con1; +rollback; + + +connection default; +disconnect con1; +disconnect con2; + +--echo # ----------------------------------- + +--echo # With OP + +--echo # ----------------------------------- +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 50 LOCK IN SHARE MODE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +connection con2; +start transaction; +SELECT * FROM t_gap WHERE a = 10 OR a = 20 OR a = 30; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 30 WHERE a = 10; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t_gap SET a = 30 WHERE a = 30; + +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (1); +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (15); +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (25); +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t_gap VALUES (1000); + +rollback; +connection con1; +rollback; + + +connection default; +disconnect con1; +disconnect con2; + +DROP TABLE t_gap; + +--echo # --------------------------------------------------- + +--echo # For RC, check that we can slide in the gaps + +--echo # --------------------------------------------------- + +CREATE TABLE t_gap (a INT, INDEX(a)); +INSERT INTO t_gap VALUES (10),(20),(30); + +--echo # --------------------------------------------------- + +--echo # Without OP + +--echo # --------------------------------------------------- +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 50 LOCK IN SHARE MODE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT * FROM t_gap WHERE a = 10 OR a = 20 OR a = 30; +UPDATE t_gap SET a = 50 WHERE a = 10; +UPDATE t_gap SET a = 60 WHERE a = 30; + + +INSERT INTO t_gap VALUES (1); +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +INSERT INTO t_gap VALUES (1000); + +rollback; +connection con1; +rollback; + + +connection default; +disconnect con1; +disconnect con2; + + +--echo # --------------------------------------------------- + +--echo # With OP + +--echo # --------------------------------------------------- +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 50 LOCK IN SHARE MODE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT * FROM t_gap WHERE a = 10 OR a = 20 OR a = 30; +UPDATE t_gap SET a = 50 WHERE a = 10; +UPDATE t_gap SET a = 60 WHERE a = 30; + + +INSERT INTO t_gap VALUES (1); +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +INSERT INTO t_gap VALUES (1000); + +rollback; +connection con1; +rollback; + + +connection default; +disconnect con1; +disconnect con2; + + + + + +--echo # --------------------------------------------------- + +--echo # For RC, LOCK IN SHARED MODE places shared lock on all the read rows, so even if they are not displayed the locks stay in place +--echo # but we can still insert in the gaps +--echo # --------------------------------------------------- + +--echo # --------------------------------------------------- + +--echo # Without OP + +--echo # --------------------------------------------------- +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +--echo # how do i check if there is a gap lock? - gap lock is respected +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 1 LOCK IN SHARE MODE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +--echo # not released even though it's not output +UPDATE t_gap SET a = 50 WHERE a = 10; + + + +INSERT INTO t_gap VALUES (1); +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +INSERT INTO t_gap VALUES (1000); + +rollback; +connection con1; +rollback; + + +connection default; +disconnect con1; +disconnect con2; + + +--echo # --------------------------------------------------- + +--echo # With OP + +--echo # --------------------------------------------------- +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 1 LOCK IN SHARE MODE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +--echo # not release even though it's not output +UPDATE t_gap SET a = 50 WHERE a = 10; + +INSERT INTO t_gap VALUES (1); +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +INSERT INTO t_gap VALUES (1000); + +rollback; +connection con1; +rollback; + + +connection default; +disconnect con1; +disconnect con2; + + + + + +--echo # --------------------------------------------------- + +--echo # READ UNCOMMITTED + +--echo # --------------------------------------------------- + + +--echo # --------------------------------------------------- + +--echo # Without OP + +--echo # --------------------------------------------------- +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +start transaction; +SELECT @@transaction_isolation; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 50 FOR UPDATE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +--echo # NO LOCKS placed ! +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +start transaction; +SELECT @@transaction_isolation; +SELECT * FROM t_gap WHERE a = 10 OR a = 20 OR a = 30; +UPDATE t_gap SET a = 50 WHERE a = 10; +UPDATE t_gap SET a = 60 WHERE a = 30; + + +INSERT INTO t_gap VALUES (1); +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +INSERT INTO t_gap VALUES (1000); + +rollback; +connection con1; +rollback; + + +connection default; +disconnect con1; +disconnect con2; + +--echo # --------------------------------------------------- + +--echo # With OP + +--echo # --------------------------------------------------- +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +start transaction; +SELECT @@transaction_isolation; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 50 FOR UPDATE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +--echo # NO LOCKS placed ! +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +start transaction; +SELECT @@transaction_isolation; +SELECT * FROM t_gap WHERE a = 10 OR a = 20 OR a = 30; +UPDATE t_gap SET a = 50 WHERE a = 10; +UPDATE t_gap SET a = 60 WHERE a = 30; + + +INSERT INTO t_gap VALUES (1); +INSERT INTO t_gap VALUES (15); +INSERT INTO t_gap VALUES (25); +INSERT INTO t_gap VALUES (1000); + +rollback; +connection con1; +rollback; + + +connection default; +disconnect con1; +disconnect con2; + +--echo # --------------------------------------------------- + +--echo # SKIP LOCKED + +--echo # --------------------------------------------------- + + +--echo # --------------------------------------------------- + +--echo # Without OP + +--echo # --------------------------------------------------- + +INSERT INTO t_gap VALUES (40),(50),(60); + + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +--echo # No output all locked +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE SKIP LOCKED; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +rollback; +connection con1; +rollback; + + +connection default; +disconnect con1; +disconnect con2; + + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap WHERE a <15 LIMIT 100 OFFSET 1 FOR UPDATE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +--echo # 10 20 locked, 30 skipped by OFFSET - rest : output +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE SKIP LOCKED; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +rollback; +connection con1; +rollback; + + +connection default; +disconnect con1; +disconnect con2; + + +--echo # --------------------------------------------------- + +--echo # With OP + +--echo # --------------------------------------------------- + + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +--echo # No output all locked +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE SKIP LOCKED; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +rollback; +connection con1; +rollback; + + +connection default; +disconnect con1; +disconnect con2; + + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap WHERE a < 15 LIMIT 100 OFFSET 1 FOR UPDATE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +--echo # 10 20 locked, 30 skipped by OFFSET - rest : output +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE SKIP LOCKED; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +rollback; +connection con1; +rollback; + + +connection default; +disconnect con1; +disconnect con2; + +--echo # --------------------------------------------------- + +--echo # NO WAIT + +--echo # --------------------------------------------------- +--echo # --------------------------------------------------- + +--echo # Without OP + +--echo # --------------------------------------------------- + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +--echo # No output all locked + +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +--error ER_LOCK_NOWAIT +SELECT /*+ NO_OFFSET_PUSHDOWN() */ * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE NOWAIT; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +rollback; +connection con1; +rollback; + +connection default; +disconnect con1; +disconnect con2; + +--echo # --------------------------------------------------- + +--echo # With OP + +--echo # --------------------------------------------------- + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +--echo # No output all locked +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +--error ER_LOCK_NOWAIT +SELECT * FROM t_gap LIMIT 100 OFFSET 1 FOR UPDATE NOWAIT; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +rollback; +connection con1; +rollback; + +connection default; +disconnect con1; +disconnect con2; + +--echo # ------------------------------------------------- +--echo # ------------------------------------------------- + + +--echo # End range check for OP at supremum (same for locking and non locking reads) + + +--echo # ------------------------------------------------- +--echo # ------------------------------------------------- +SELECT @@transaction_isolation; +INSERT INTO t_gap SELECT * FROM t_gap; +INSERT INTO t_gap SELECT * FROM t_gap; +INSERT INTO t_gap SELECT * FROM t_gap; +INSERT INTO t_gap SELECT * FROM t_gap; +INSERT INTO t_gap SELECT * FROM t_gap; +INSERT INTO t_gap SELECT * FROM t_gap; +INSERT INTO t_gap SELECT * FROM t_gap; +INSERT INTO t_gap SELECT * FROM t_gap; +INSERT INTO t_gap VALUES (5); + +--echo # Show status shows we skipped less than 1000 OFFSET rows - stopped by end range check on page supremum. +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap WHERE a < 8 LIMIT 1 OFFSET 1000; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +--echo # Show status shows we skipped less than 3000 OFFSET rows - stopped by end range check on page supremum +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t_gap WHERE a < 11 LIMIT 1 OFFSET 3000; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +SET empty_redundant_check_in_range_scan=true; + +DROP TABLE t_gap; + +--echo # ------------------------------------------------- +--echo # ------------------------------------------------- + + +--echo # End range check v ICP_OUT_OF_RANGE + + +--echo # ------------------------------------------------- +--echo # ------------------------------------------------- +CREATE TABLE t2 (a INT, b INT, c INT, INDEX(a,b)); +INSERT INTO t2 VALUES (1,10,4),(2,20,5),(3,30,6),(4,40,12),(5,50,13),(6,60,14),(7,70,15); +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +INSERT INTO t2 SELECT * FROM t2; +--echo # End of range check does not apply with ICP - stopped by ICP out of range before OFFSET 5000 is reached +SET empty_redundant_check_in_range_scan = false; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t2 WHERE a = 1 AND b < 11 LIMIT 1 OFFSET 5000; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +--echo # ICP_OUT_OF_RANGE evaluated before systematic end of range check for locking scenario- no need to check end of range if idx_cond==true +start transaction; +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); +SELECT * FROM t2 WHERE a = 1 AND b < 11 LIMIT 1 OFFSET 5000 FOR UPDATE; +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; +rollback; + + + +DROP TABLE t2; + +--echo # ----------------- +--echo # OP and ICP that hits ICP_NO_MATCH +--echo # ----------------- + +--echo # -- +--echo # RR +--echo # -- + + + +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; + +CREATE TABLE t0 (a VARCHAR(10), b INT, c INT, INDEX(a(10),b)); +insert into t0 values ('banama',1,1),('banana',1,1),('banana',2,3),('banana',3,3),('banaoa',3,6),('banapa',4,9),('banaqa',5,12); + +explain format=tree SELECT a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1; +explain format=tree SELECT /*+ NO_OFFSET_PUSHDOWN() */ a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1; +--echo # row_search_mvcc hits ICP_NO_MATCH for ('banana',1,1),('banana',2,3) because 1 and 2 are smaller than 3 with and without OP +SELECT /*+ NO_OFFSET_PUSHDOWN() */ a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1; +--echo # ('banana',3,3) is skipped by offset pushdown in innodb +SELECT a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1; + +explain format=tree SELECT a,c FROM t0 WHERE a>'banama' AND a<'banaqa' AND b>2 LIMIT 100 offset 1; +--echo # row_search_mvcc hits ICP_OUT_OF_RANGE for ('banaqa',5,12) +SELECT a,c FROM t0 WHERE a>'banama' AND a<'banaqa' AND b>2 LIMIT 100 offset 1; + +--echo # -- +--echo # OP and ICP that hits ICP_NO_MATCH with LOCKING READ +--echo # -- + +--echo # Without OP + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; + + +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); + +SELECT /*+ NO_OFFSET_PUSHDOWN() */ a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1 FOR UPDATE; + +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +--echo # Next key locking interval is (x,y], we can therefore update the 'banama',1,1 +UPDATE t0 SET a = ' pears' WHERE a = 'banama'; +rollback; +start transaction; +--echo # Next key locking interval is (x,y], we cannot therefore insert right of the 'banama',1,1 row +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t0 values ('banama',2,2); +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 1; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 2; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 3 AND c=3; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t0 SET a = 'apples' WHERE a= 'banaoa' AND b = 3 AND c=6; + +rollback; +connection con1; +rollback; + +connection default; +disconnect con1; +disconnect con2; + + +--echo # With OP + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; + + +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); + +SELECT a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1 FOR UPDATE; + +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +start transaction; +SELECT @@transaction_isolation; +--echo # Next key locking interval is (x,y], we can therefore update the 'banama',1,1 +UPDATE t0 SET a = ' pears' WHERE a = 'banama'; +rollback; +start transaction; +--echo # Next key locking interval is (x,y], we cannot therefore insert right of the 'banama',1,1 row +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t0 values ('banama',2,2); +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 1; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 2; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 3 AND c=3; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t0 SET a = 'apples' WHERE a= 'banaoa' AND b = 3 AND c=6; + +rollback; +connection con1; +rollback; + +connection default; +disconnect con1; +disconnect con2; + + + + +--echo # -- +--echo # RC +--echo # -- + +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; + +explain format=tree SELECT a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1; +explain format=tree SELECT /*+ NO_OFFSET_PUSHDOWN() */ a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1; +--echo # row_search_mvcc hits ICP_NO_MATCH for ('banana',1,1),('banana',2,3) because 1 and 2 are smaller than 3 with and without OP +SELECT /*+ NO_OFFSET_PUSHDOWN() */ a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1; +--echo # ('banana',3,3) is skipped by offset pushdown in innodb +SELECT a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1; + +explain format=tree SELECT a,c FROM t0 WHERE a>'banama' AND a<'banaqa' AND b>2 LIMIT 100 offset 1; +--echo # row_search_mvcc hits ICP_OUT_OF_RANGE for ('banaqa',5,12) +SELECT a,c FROM t0 WHERE a>'banama' AND a<'banaqa' AND b>2 LIMIT 100 offset 1; + + +--echo # -- +--echo # RC - OP and ICP that hits ICP_NO_MATCH with LOCKING READ +--echo # -- + +--echo # Without OP - Without ICP +--echo # This test is there to show that ICP does not release the locks in RC for rows that are read and not returned to the client. + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +SET optimizer_switch = 'index_condition_pushdown=off'; + +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); + +SELECT /*+ NO_OFFSET_PUSHDOWN() */ a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1 FOR UPDATE; + +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +--echo # Next key locking interval is (x,y], we can therefore update the 'banama',1,1 +UPDATE t0 SET a = ' pears' WHERE a = 'banama'; +rollback; +start transaction; +INSERT INTO t0 values ('banama',2,2); +rollback; +start transaction; +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 1; +rollback; +start transaction; +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 2; +rollback; +start transaction; +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 3 AND c=3; +rollback; +start transaction; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t0 SET a = 'apples' WHERE a= 'banaoa' AND b = 3 AND c=6; + +rollback; +connection con1; +rollback; + +connection default; +disconnect con1; +disconnect con2; + +SET optimizer_switch = 'index_condition_pushdown=on'; + + +--echo # Without OP + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; + +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); + +SELECT /*+ NO_OFFSET_PUSHDOWN() */ a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1 FOR UPDATE; + +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +--echo # Next key locking interval is (x,y], we can therefore update the 'banama',1,1 +UPDATE t0 SET a = ' pears' WHERE a = 'banama'; +rollback; +start transaction; +--echo # NO Next key locking +INSERT INTO t0 values ('banama',2,2); +rollback; +start transaction; +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 1; +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 2; +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 3 AND c=3; +rollback; +start transaction; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t0 SET a = 'apples' WHERE a= 'banaoa' AND b = 3 AND c=6; + +rollback; +connection con1; +rollback; + +connection default; +disconnect con1; +disconnect con2; + + +--echo # With OP + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; + + +SET @save_skipped_rows = (SELECT variable_value FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'); + +SELECT a,c FROM t0 WHERE a>'banama' AND b>2 LIMIT 100 offset 1 FOR UPDATE; + +SELECT variable_value - @save_skipped_rows FROM performance_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_skipped_by_offset_pushdown'; + +connection con2; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +start transaction; +SELECT @@transaction_isolation; +--echo # Next key locking interval is (x,y], we can therefore update the 'banama',1,1 +UPDATE t0 SET a = ' pears' WHERE a = 'banama'; +rollback; +start transaction; +SELECT @@transaction_isolation; +--echo # Next key locking interval is (x,y], we can therefore update the 'banama',1,1 +UPDATE t0 SET a = ' pears' WHERE a = 'banama'; +rollback; +start transaction; +--echo # NO Next key locking +INSERT INTO t0 values ('banama',2,2); +rollback; +start transaction; +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 1; +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 2; +--echo # Skipped - Not returned lock released +UPDATE t0 SET a = 'apples' WHERE a= 'banana' AND b = 3 AND c=3; +rollback; +start transaction; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t0 SET a = 'apples' WHERE a= 'banaoa' AND b = 3 AND c=6; + +rollback; +connection con1; +rollback; + +connection default; +disconnect con1; +disconnect con2; + + + +DROP TABLE t0; +--source include/wait_until_count_sessions.inc +--echo # Restore orig wait timeout +--echo # BOTTOM +show variables LIKE '%innodb_lock_wait_timeout%'; +SET @@global.innodb_lock_wait_timeout = @old_innodb_lock_wait_timeout; +show variables LIKE '%innodb_lock_wait_timeout%'; +DROP TABLE if EXISTS t2; \ No newline at end of file diff --git a/mysql-test/t/order_by_icp_mrr.test b/mysql-test/t/order_by_icp_mrr.test index f36b6019224..c0581a26df8 100644 --- a/mysql-test/t/order_by_icp_mrr.test +++ b/mysql-test/t/order_by_icp_mrr.test @@ -12,8 +12,8 @@ if (`select locate('materialization', @@optimizer_switch) > 0`) set optimizer_switch='materialization=off'; } --enable_query_log - +set empty_redundant_check_in_range_scan=false; --source include/order_by.inc - +set empty_redundant_check_in_range_scan=true; set optimizer_switch=default; diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 6019169c52d..ab622942064 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -387,6 +387,31 @@ SELECT a FROM t1 WHERE a BETWEEN 60 AND 95; SELECT a FROM t1 WHERE a BETWEEN 60 AND 220; --sorted_result SELECT a FROM t1 WHERE a BETWEEN 200 AND 220; + +# Test of offset pushdown with partition and ASC/DESC order: +# 2 partitions used, no pushdown: +explain SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a DESC LIMIT 1000 OFFSET 1; +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a DESC LIMIT 1000 OFFSET 1; +explain SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a ASC LIMIT 1000 OFFSET 1; +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a ASC LIMIT 1000 OFFSET 1; +# 1 partition, pushdown: +explain SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a DESC LIMIT 1000 OFFSET 1; +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a DESC LIMIT 1000 OFFSET 1; +explain SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a ASC LIMIT 1000 OFFSET 1; +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a ASC LIMIT 1000 OFFSET 1; +# Now change the index to "descending", and do it all over again: +ALTER TABLE t1 DROP INDEX a; +ALTER TABLE t1 ADD INDEX (a DESC); +ANALYZE TABLE t1; +explain SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a DESC LIMIT 1000 OFFSET 1; +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a DESC LIMIT 1000 OFFSET 1; +explain SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a ASC LIMIT 1000 OFFSET 1; +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a ASC LIMIT 1000 OFFSET 1; +explain SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a DESC LIMIT 1000 OFFSET 1; +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a DESC LIMIT 1000 OFFSET 1; +explain SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a ASC LIMIT 1000 OFFSET 1; +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a ASC LIMIT 1000 OFFSET 1; + DROP TABLE t1; # diff --git a/mysql-test/t/range_icp.test b/mysql-test/t/range_icp.test index 279e07c467a..615d4be9792 100644 --- a/mysql-test/t/range_icp.test +++ b/mysql-test/t/range_icp.test @@ -1,5 +1,5 @@ set optimizer_switch='index_condition_pushdown=on'; - +set empty_redundant_check_in_range_scan=false; --disable_query_log if (`select locate('semijoin', @@optimizer_switch) > 0`) { @@ -16,6 +16,6 @@ if (`select locate('mrr', @@optimizer_switch) > 0`) --enable_query_log --source include/range.inc - +set empty_redundant_check_in_range_scan=true; set optimizer_switch=default; diff --git a/mysql-test/t/range_icp_mrr.test b/mysql-test/t/range_icp_mrr.test index 2c63df82bd7..a941d26bc6a 100644 --- a/mysql-test/t/range_icp_mrr.test +++ b/mysql-test/t/range_icp_mrr.test @@ -1,5 +1,5 @@ set optimizer_switch='index_condition_pushdown=on,mrr=on,mrr_cost_based=off'; - +set empty_redundant_check_in_range_scan=false; --disable_query_log if (`select locate('semijoin', @@optimizer_switch) > 0`) { @@ -12,6 +12,6 @@ if (`select locate('materialization', @@optimizer_switch) > 0`) --enable_query_log --source include/range.inc - +set empty_redundant_check_in_range_scan=true; set optimizer_switch=default; diff --git a/mysql-test/t/select_icp_mrr.test b/mysql-test/t/select_icp_mrr.test index a7c1f500748..efe0d2e266d 100644 --- a/mysql-test/t/select_icp_mrr.test +++ b/mysql-test/t/select_icp_mrr.test @@ -5,7 +5,7 @@ # set optimizer_switch='index_condition_pushdown=on,mrr=on,mrr_cost_based=off'; - +set empty_redundant_check_in_range_scan=false; --disable_query_log if (`select locate('semijoin', @@optimizer_switch) > 0`) { @@ -18,5 +18,5 @@ if (`select locate('materialization', @@optimizer_switch) > 0`) --enable_query_log --source include/select.inc - +set empty_redundant_check_in_range_scan=true; set optimizer_switch=default; diff --git a/sql/handler.h b/sql/handler.h index b511aa9fe17..67d14914cef 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -4837,6 +4837,16 @@ class handler { */ virtual void parallel_scan_end(void *scan_ctx [[maybe_unused]]) { return; } + /// Pushes OFFSET to the engine: the engine read functions (rnd_next(), etc) + /// should silently skip that many rows before returning a first row. + /// @param pushed_offset Number of rows to skip. + virtual void set_pushed_offset(ha_rows pushed_offset MY_ATTRIBUTE((unused))) { + assert(false); + } // not implemented by default + + /// Returns the offset pushed to the engine by set_pushed_offset(), or 0 if + /// nothing was pushed. + virtual ha_rows get_pushed_offset() const { return 0; } /** Submit a dd::Table object representing a core DD table having hardcoded data to be filled in by the DDSE. This function can be diff --git a/sql/item.cc b/sql/item.cc index 74df2854de0..43792916ee9 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -9406,6 +9406,7 @@ int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) { volatile double result = item->val_real(); if (item->null_value) return 0; volatile double field_result = field->val_real(); + assert(res_type == REAL_RESULT); if (field_result < result) return -1; else if (field_result > result) diff --git a/sql/join_optimizer/access_path.h b/sql/join_optimizer/access_path.h index 8fcf4969546..8e09a266e60 100644 --- a/sql/join_optimizer/access_path.h +++ b/sql/join_optimizer/access_path.h @@ -38,6 +38,7 @@ #include "sql/join_optimizer/relational_expression.h" #include "sql/join_type.h" #include "sql/mem_root_array.h" +#include "sql/range_optimizer/range_optimizer.h" #include "sql/sql_array.h" #include "sql/sql_class.h" #include "sql/table.h" @@ -915,6 +916,12 @@ struct AccessPath { QUICK_RANGE **ranges; unsigned num_ranges; + uchar *get_ranges_min_key(int j) const { return ranges[j]->min_key; } + uchar *get_ranges_max_key(int j) const { return ranges[j]->max_key; } + uint16 get_ranges_flag(int j) const { return ranges[j]->flag; } + size_t get_ranges_size() const { return num_ranges; } + KEY_PART *get_key_part(int j) const { return &used_key_part[j]; } + unsigned mrr_flags; unsigned mrr_buf_size; diff --git a/sql/join_optimizer/explain_access_path.cc b/sql/join_optimizer/explain_access_path.cc index 1f6f29b753f..581b2a4822c 100644 --- a/sql/join_optimizer/explain_access_path.cc +++ b/sql/join_optimizer/explain_access_path.cc @@ -1393,8 +1393,24 @@ static std::unique_ptr SetObjectMembers( error |= AddMemberToObject(obj, "access_type", "limit"); char buf[256]; if (path->limit_offset().offset == 0) { - snprintf(buf, sizeof(buf), "Limit: %llu row(s)", - path->limit_offset().limit); + if (join && join->tables > join->const_tables && + join->qep_tab[join->const_tables].position() && join->qep_tab[join->const_tables] + .table() + ->file->get_pushed_offset() > 0) { + // Even though offset pushdown happens inside the engine, and is + // thus per-table (like ICP), it is easier implementation-wise to + // show it here. It will not confuse users, because there can only + // be one table. + snprintf(buf, sizeof(buf), + "Limit/Offset: %llu/%llu row(s), with offset pushdown", + path->limit_offset().limit, + join->qep_tab[join->const_tables] + .table() + ->file->get_pushed_offset()); + } else { + snprintf(buf, sizeof(buf), "Limit: %llu row(s)", + path->limit_offset().limit); + } } else if (path->limit_offset().limit == HA_POS_ERROR) { snprintf(buf, sizeof(buf), "Offset: %llu row(s)", path->limit_offset().offset); diff --git a/sql/lex.h b/sql/lex.h index ae6dec7b263..84bde2a820d 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -911,6 +911,8 @@ static const SYMBOL symbols[] = { {SYM_H("NO_ORDER_INDEX", NO_ORDER_INDEX_HINT)}, {SYM_H("DERIVED_CONDITION_PUSHDOWN", DERIVED_CONDITION_PUSHDOWN_HINT)}, {SYM_H("NO_DERIVED_CONDITION_PUSHDOWN", - NO_DERIVED_CONDITION_PUSHDOWN_HINT)}}; + NO_DERIVED_CONDITION_PUSHDOWN_HINT)}, + {SYM_H("NO_OFFSET_PUSHDOWN", NO_OFFSET_PUSHDOWN_HINT)}, + {SYM_H("OFFSET_PUSHDOWN", OFFSET_PUSHDOWN_HINT)}}; #endif /* LEX_INCLUDED */ diff --git a/sql/opt_explain.cc b/sql/opt_explain.cc index 27c39130ff3..90259011d97 100644 --- a/sql/opt_explain.cc +++ b/sql/opt_explain.cc @@ -989,6 +989,9 @@ bool Explain_table_base::explain_key_and_len_index(int key, uint key_length, } bool Explain_table_base::explain_extra_common(int range_scan_type, uint keyno) { + if (table->file->get_pushed_offset() != 0) { + if (push_extra(ET_USING_OFFSET_PUSHDOWN)) return true; + } if (keyno != MAX_KEY && keyno == table->file->pushed_idx_cond_keyno && table->file->pushed_idx_cond) { StringBuffer<160> buff(cs); diff --git a/sql/opt_explain_format.h b/sql/opt_explain_format.h index 6138f5d07c6..1f88727028f 100644 --- a/sql/opt_explain_format.h +++ b/sql/opt_explain_format.h @@ -61,6 +61,7 @@ enum Extra_tag { ET_USING_TEMPORARY, ET_USING_FILESORT, ET_USING_INDEX_CONDITION, + ET_USING_OFFSET_PUSHDOWN, ET_USING, ET_RANGE_CHECKED_FOR_EACH_RECORD, ET_USING_PUSHED_CONDITION, diff --git a/sql/opt_explain_json.cc b/sql/opt_explain_json.cc index 8afdb011a24..15f346fe18d 100644 --- a/sql/opt_explain_json.cc +++ b/sql/opt_explain_json.cc @@ -65,6 +65,7 @@ static const char *json_extra_tags[ET_total] = { "using_temporary_table", // ET_USING_TEMPORARY "using_filesort", // ET_USING_FILESORT "index_condition", // ET_USING_INDEX_CONDITION + "offset pushdown", // ET_USING_OFFSET_PUSHDOWN nullptr, // ET_USING "range_checked_for_each_record", // ET_RANGE_CHECKED_FOR_EACH_RECORD "pushed_condition", // ET_USING_PUSHED_CONDITION diff --git a/sql/opt_explain_traditional.cc b/sql/opt_explain_traditional.cc index 60fe44610f0..b82085f19ad 100644 --- a/sql/opt_explain_traditional.cc +++ b/sql/opt_explain_traditional.cc @@ -49,6 +49,7 @@ static const char *traditional_extra_tags[ET_total] = { "Using temporary", // ET_USING_TEMPORARY "Using filesort", // ET_USING_FILESORT "Using index condition", // ET_USING_INDEX_CONDITION + "Using offset pushdown", // ET_USING_OFFSET_PUSHDOWN "Using", // ET_USING "Range checked for each record", // ET_RANGE_CHECKED_FOR_EACH_RECORD "Using pushed condition", // ET_USING_PUSHED_CONDITION diff --git a/sql/opt_hints.cc b/sql/opt_hints.cc index a5f362d2d77..fc3c121f2ce 100644 --- a/sql/opt_hints.cc +++ b/sql/opt_hints.cc @@ -85,6 +85,7 @@ struct st_opt_hint_info opt_hint_info[] = { {"GROUP_INDEX", false, false, false}, {"ORDER_INDEX", false, false, false}, {"DERIVED_CONDITION_PUSHDOWN", true, true, false}, + {"OFFSET_PUSHDOWN", false, false, false}, {nullptr, false, false, false}}; /** @@ -205,6 +206,7 @@ Opt_hints_qb::Opt_hints_qb(Opt_hints *opt_hints_arg, MEM_ROOT *mem_root_arg, select_number(select_number_arg), subquery_hint(nullptr), semijoin_hint(nullptr), + offset_pushdown_hint(nullptr), join_order_hints(mem_root_arg), join_order_hints_ignored(0) { sys_name.str = buff; @@ -217,6 +219,8 @@ PT_hint *Opt_hints_qb::get_complex_hints(opt_hints_enum type) { if (type == SUBQUERY_HINT_ENUM) return subquery_hint; + if (type == OFFSET_PUSHDOWN_HINT_ENUM) return offset_pushdown_hint; + assert(0); return nullptr; } @@ -525,6 +529,10 @@ void Opt_hints_qb::apply_join_order_hints(JOIN *join) { } } +bool Opt_hints_qb::apply_offset_pushdown_hint() { + return (offset_pushdown_hint && offset_pushdown_hint->switch_on()); +} + void Opt_hints_table::adjust_key_hints(TABLE_LIST *tr) { set_resolved(); if (child_array_ptr()->size() == 0) // No key level hints diff --git a/sql/opt_hints.h b/sql/opt_hints.h index e8c0926354c..af12f88af77 100644 --- a/sql/opt_hints.h +++ b/sql/opt_hints.h @@ -84,6 +84,7 @@ enum opt_hints_enum { GROUP_INDEX_HINT_ENUM, ORDER_INDEX_HINT_ENUM, DERIVED_CONDITION_PUSHDOWN_HINT_ENUM, + OFFSET_PUSHDOWN_HINT_ENUM, MAX_HINT_ENUM }; @@ -373,7 +374,7 @@ class Opt_hints_qb : public Opt_hints { LEX_CSTRING sys_name; // System QB name char buff[32]; // Buffer to hold sys name - PT_qb_level_hint *subquery_hint, *semijoin_hint; + PT_qb_level_hint *subquery_hint, *semijoin_hint, *offset_pushdown_hint; /// Array of join order hints Mem_root_array join_order_hints; @@ -480,6 +481,13 @@ class Opt_hints_qb : public Opt_hints { */ void apply_join_order_hints(JOIN *join); + /** + Checks if [NO_]OFFSET_PUSHDOWN hint is used in the query + @returns true if that's the case + */ + bool active_offset_pushdown_hint() { return offset_pushdown_hint; } + bool apply_offset_pushdown_hint(); + private: void register_join_order_hint(PT_qb_level_hint *hint_arg) { join_order_hints.push_back(hint_arg); diff --git a/sql/parse_tree_hints.cc b/sql/parse_tree_hints.cc index b0f872a6fb5..21c25438ba3 100644 --- a/sql/parse_tree_hints.cc +++ b/sql/parse_tree_hints.cc @@ -270,6 +270,9 @@ bool PT_qb_level_hint::contextualize(Parse_context *pc) { else pc->select->add_base_options(SELECT_STRAIGHT_JOIN); break; + case OFFSET_PUSHDOWN_HINT_ENUM: + qb->offset_pushdown_hint = this; + break; default: assert(0); } @@ -329,6 +332,8 @@ void PT_qb_level_hint::append_args(const THD *thd, String *str) const { break; case JOIN_FIXED_ORDER_HINT_ENUM: break; + case OFFSET_PUSHDOWN_HINT_ENUM: + break; default: assert(false); } diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h index 898db2616ae..b2d223f1ec8 100644 --- a/sql/sql_bitmap.h +++ b/sql/sql_bitmap.h @@ -131,6 +131,8 @@ class Bitmap { } uint bits_set() const { return bitmap_bits_set(&map); } uint get_first_set() const { return bitmap_get_first_set(&map); } + /// For certain functions which require a MY_BITMAP + MY_BITMAP *get_bitmap() { return ↦ } }; template <> diff --git a/sql/sql_const.h b/sql/sql_const.h index ea47ad2975c..865f0e63d30 100644 --- a/sql/sql_const.h +++ b/sql/sql_const.h @@ -222,7 +222,8 @@ constexpr const uint64_t OPTIMIZER_SWITCH_PREFER_ORDERING_INDEX{1ULL << 23}; constexpr const uint64_t OPTIMIZER_SWITCH_HYPERGRAPH_OPTIMIZER{1ULL << 24}; constexpr const uint64_t OPTIMIZER_SWITCH_DERIVED_CONDITION_PUSHDOWN{1ULL << 25}; -constexpr const uint64_t OPTIMIZER_SWITCH_LAST{1ULL << 26}; +constexpr const uint64_t OPTIMIZER_SWITCH_OFFSET_PUSHDOWN{1ULL << 26}; +constexpr const uint64_t OPTIMIZER_SWITCH_LAST{1ULL << 27}; enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED }; diff --git a/sql/sql_hints.yy b/sql/sql_hints.yy index 1abdeb149e0..0a86b64ecb1 100644 --- a/sql/sql_hints.yy +++ b/sql/sql_hints.yy @@ -138,6 +138,8 @@ static bool parse_int(longlong *to, const char *from, size_t from_length) */ %token YYUNDEF 1150 +%token NO_OFFSET_PUSHDOWN_HINT 1056 +%token OFFSET_PUSHDOWN_HINT 1057 /* Please add new tokens right above this line. @@ -351,6 +353,20 @@ opt_qb_name: ; qb_level_hint: + OFFSET_PUSHDOWN_HINT '(' opt_qb_name')' + { + $$= NEW_PTN PT_qb_level_hint($3, true, OFFSET_PUSHDOWN_HINT_ENUM, 0); + if ($$ == NULL) + YYABORT; // OOM + } + | + NO_OFFSET_PUSHDOWN_HINT '(' opt_qb_name')' + { + $$= NEW_PTN PT_qb_level_hint($3, false, OFFSET_PUSHDOWN_HINT_ENUM, 0); + if ($$ == NULL) + YYABORT; // OOM + } + | SEMIJOIN_HINT '(' opt_qb_name semijoin_strategies ')' { $$= NEW_PTN PT_qb_level_hint($3, true, SEMIJOIN_HINT_ENUM, $4); diff --git a/sql/sql_lex_hints.cc b/sql/sql_lex_hints.cc index d3f81d0293c..256a7d54e55 100644 --- a/sql/sql_lex_hints.cc +++ b/sql/sql_lex_hints.cc @@ -226,6 +226,8 @@ void Hint_scanner::add_hint_token_digest() { case NO_ORDER_INDEX_HINT: case DERIVED_CONDITION_PUSHDOWN_HINT: case NO_DERIVED_CONDITION_PUSHDOWN_HINT: + case NO_OFFSET_PUSHDOWN_HINT: + case OFFSET_PUSHDOWN_HINT: break; default: assert(false); diff --git a/sql/sql_optimizer.cc b/sql/sql_optimizer.cc index e044c395821..23560284446 100644 --- a/sql/sql_optimizer.cc +++ b/sql/sql_optimizer.cc @@ -109,6 +109,7 @@ #include "sql/window.h" #include "sql_string.h" #include "template_utils.h" +#include "val_int_compare.h" using std::max; using std::min; @@ -985,9 +986,20 @@ bool JOIN::optimize(bool finalize_access_paths) { if (make_tmp_tables_info()) return true; /* - If we decided to not sort after all, update the cost of the JOIN. - Windowing sorts are handled elsewhere - */ + Should there be an offset in the query, this evaluate whether the offset + should be handled by the storage engine. The optimizer hint + ([NO_]OFFSET_PUSHDOWN) takes precedence over the optimizer switch. + */ + if (query_block->opt_hints_qb && + query_block->opt_hints_qb->active_offset_pushdown_hint()) { + if (query_block->opt_hints_qb->apply_offset_pushdown_hint()) { + offset_pushdown(); + } + } else if (thd->optimizer_switch_flag(OPTIMIZER_SWITCH_OFFSET_PUSHDOWN)) { + offset_pushdown(); + } + /* If we decided to not sort after all, + update the cost of the JOIN.Windowing sorts are handled elsewhere */ if (sort_cost > 0.0 && !explain_flags.any(ESP_USING_FILESORT, ESC_WINDOWING)) { best_read -= sort_cost; @@ -8825,6 +8837,10 @@ static bool test_if_ref(Item_field *left_item, Item *right_item) { return false; // keep predicate } +inline bool is_column_then_constant(Item *left_item, Item *right_item) { + return (left_item->type() == Item::FIELD_ITEM && right_item->const_item()); +} + /** @brief Remove redundant predicates from condition, return the reduced condition. @@ -8845,6 +8861,10 @@ static bool test_if_ref(Item_field *left_item, Item *right_item) { Any tables referred in Item_func_trig_cond(FOUND_MATCH) conditions are aggregated into this null_extended table_map. + We also try to remove redundant inequalities of the form 'field OP value', + withere OP is >, >=, etc, or BETWEEN, and also 'field IS NULL', if the table + is accessed by a range index scan. + @param cond The condition to be 'reduced'. @param null_extended table_map of possibly null-extended outer-tables. @@ -8877,18 +8897,32 @@ static Item *reduce_cond_for_table(Item *cond, table_map null_extended) { } } else { // Or list Item *item; + // deactivate removal of redundant conditions for OR clauses, it creates + // problems when the range condition is not of the same form as + // the operator's. Consider, for example, that WHERE is: c=3 + // OR c>2. The range optimizer may build a single range + // c>2, which has no max value. So when we process c=3 + // here, intending to compare 3 with the min and max of the + // range, we cannot. + auto stored_value = + current_thd->variables.empty_redundant_check_in_range_scan; + current_thd->variables.empty_redundant_check_in_range_scan = false; while ((item = li++)) { Item *upd_item = reduce_cond_for_table(item, null_extended); if (upd_item == nullptr) { + current_thd->variables.empty_redundant_check_in_range_scan = + stored_value; return nullptr; // Term 'true' -> entire Or-cond true } else if (upd_item != item) { li.replace(upd_item); } } + current_thd->variables.empty_redundant_check_in_range_scan = stored_value; } } else if (cond->type() == Item::FUNC_ITEM) { Item_func *func = down_cast(cond); - if (func->functype() == Item_func::TRIG_COND_FUNC) { + auto op_type = func->functype(); + if (op_type == Item_func::TRIG_COND_FUNC) { Item_func_trig_cond *func_trig = down_cast(func); if (func_trig->get_trig_type() == Item_func_trig_cond::FOUND_MATCH) { /* @@ -8907,21 +8941,237 @@ static Item *reduce_cond_for_table(Item *cond, table_map null_extended) { } func->arguments()[0] = upd_arg; } + // Now check if 'func' is already satisfied by use of index range scan + else if (current_thd->variables.empty_redundant_check_in_range_scan && + !(func->used_tables() & null_extended) && + (op_type == Item_func::LT_FUNC || op_type == Item_func::GT_FUNC || + op_type == Item_func::EQ_FUNC || op_type == Item_func::LE_FUNC || + op_type == Item_func::GE_FUNC || op_type == Item_func::BETWEEN || + op_type == Item_func::ISNULL_FUNC)) { + const bool isnull = op_type == Item_func::ISNULL_FUNC; + assert(isnull || func->argument_count() >= 2); + Item *left_item = func->arguments()[0]->real_item(); + Item *right_item = isnull ? nullptr : func->arguments()[1]->real_item(); + { + bool path_1 = + isnull ? true : is_column_then_constant(left_item, right_item); + bool path_2 = + isnull ? false : is_column_then_constant(right_item, left_item); + if ((path_1 || path_2)) { + if (!path_1 && path_2) { + left_item = func->arguments()[1]->real_item(); + right_item = func->arguments()[0]->real_item(); + } + if (isnull && left_item->type() != Item::FIELD_ITEM) { + // if OP is not IS NULL, type() is checked in + // is_column_then_constant() + return cond; + } + Field *field = down_cast(left_item)->field; + JOIN_TAB *join_tab = field->table->reginfo.join_tab; + if (join_tab && join_tab->type() == JT_RANGE && + !(field->type() == MYSQL_TYPE_BIT) && + // Dynamic range is more complex, not supported: + join_tab->use_quick != QS_DYNAMIC_RANGE && + // comparable_in_index() is used by the range optimizer to + // decide if it can handle a range. However this function has a + // special permissive case for equality conditions under binary + // collations, which alas makes it impossible to remove the + // condition. That's why we call the function again below, + // pretending this is not equality. This doesn't apply to IS NULL. + (isnull || + comparable_in_index(cond, field, Field::itRAW, + Item_func::UNKNOWN_FUNC, right_item))) { + // Simple range: no skip-scan/index-merge/etc + if (join_tab->range_scan() && (join_tab->range_scan()->type == + AccessPath::INDEX_RANGE_SCAN)) { + Field_map used_fields; + get_fields_used(join_tab->range_scan(), used_fields.get_bitmap()); + const auto &quick_range_check = + join_tab->range_scan()->index_range_scan(); + + // First clause in if() ensures that Field is used by the range + // scan. Second clause in if() ensures that ranges has size 1. It + // means we do not support disjoint ranges caused by OR operators + // in the WHERE clause (like 'idxcol>3 OR idxcol<5'). Note that an + // AND operator produces a single range (like 'idxcol>3 AND + // idxcol<5'). + if (used_fields.is_set(field->field_index()) && + quick_range_check.get_ranges_size() == 1) { + uchar *key_max = quick_range_check.get_ranges_max_key(0); + uchar *key_min = quick_range_check.get_ranges_min_key(0); + // If we have an index on columns A,B,C, a typical range + // bound is of the type A=3 AND B=4 AND C>5. In that case, + // quick_range_check->ranges[0]->min_key + // is laid out like this: + // NA 3 NB 4 NC 5 + // where NA is one byte (0 here). + // For a range like A IS NULL, min_key will have NA==1. + // In 'func' we have a condition which could be B=constant. + // We are going to search which value this range has for B + // (it is 4). So we have to locate in min_key the value for + // B. 'counter' is an offset in bytes which we calculate, + // and which points to that desired value. + int counter = 0; + // Find the position in the min_key/max_key list of the upper + // bound of interest. It works because the possible scenarii are + // conditioned on the query being a index range scan + uint i = 0; + for (; i < quick_range_check.num_used_key_parts; i++) { + if (field->eq(quick_range_check.get_key_part(i)->field)) { + break; + } + counter += quick_range_check.get_key_part(i)->store_length; + } + assert(i < quick_range_check + .num_used_key_parts); // found 'field' at 'i' + if (!isnull && field->is_nullable()) { + counter++; // skip NULL byte to access the real value + } + key_max += counter; + key_min += counter; + + const KEY_PART *key_part_p = quick_range_check.get_key_part(i); + (void)key_part_p; + TABLE *table = field->table; + my_bitmap_map *old_sets[2]; + // Prefix index not handled: if prefix shorter than item, + // range matches too much, filter is necessary in SQL-layer + if (!(key_part_p->flag & HA_PART_KEY_SEG)) { + // Depending on the operator in 'func', we have to compare + // key_{max,min} with an argument of the operator. We set up + // the necessary comparisons in this array, then common code + // does the comparisons. + // Continuing with the A/B/C example above, we're going to + // see if 'constant' is 4. If so, we can remove B=constant. + Item *cmp_with_min = nullptr, *cmp_with_max = nullptr; + // For BETWEEN, no need to consider path_2, left item is + // always going to be the column, and the right items the + // bound, similarly, the first right item is always going to + // be the lower bound and the second the upper bound + bool negated = false; + if (path_1 && op_type == Item_func::BETWEEN) { + // Not compatible with NOT BETWEEN - same as OR clause, + // disjoint intervals + negated = down_cast(func)->negated; + Item *right_item_2 = func->arguments()[2]->real_item(); + cmp_with_max = right_item_2; + cmp_with_min = right_item; + } + if ((path_1 && (op_type == Item_func::LT_FUNC || + op_type == Item_func::LE_FUNC)) || + (path_2 && (op_type == Item_func::GT_FUNC || + op_type == Item_func::GE_FUNC))) { + cmp_with_max = right_item; + } + if ((path_2 && (op_type == Item_func::LT_FUNC || + op_type == Item_func::LE_FUNC)) || + (path_1 && (op_type == Item_func::GT_FUNC || + op_type == Item_func::GE_FUNC))) { + cmp_with_min = right_item; + } + if (op_type == Item_func::EQ_FUNC) { + cmp_with_max = cmp_with_min = right_item; + } + + // Swap min and max if DESC index + if (key_part_p->flag & HA_REVERSE_SORT) { + std::swap(cmp_with_min, cmp_with_max); + } + if ((cmp_with_max || cmp_with_min) && !negated) { + // Prevent hitting ASSERT_COLUMN_MARKED_FOR_WRITE in + // stored_field_cmp_to_item() + dbug_tmp_use_all_columns(table, old_sets, table->read_set, + table->write_set); + // We handle INT and NULL outside of + // stored_field_cmp_to_item() because it returns 0 for both + // regardless of the values we want to compare. The reason + // for that is that this function was initially designed as + // a comparison function after storing an item into a field + // to evaluate whether there had been some distortion. + // Since we are using it for something different we have to + // handle these two special cases seperately. So we wrote + // the INT comparison outside the function. For comparisons + // to NULL, we also process them outside the function: we do + // not handle them because we cannot identify NULL in the + // field. + auto cmp = [field, key_part_p](Item *cmp_item, + const uchar *key) -> bool { + field->set_key_image(key, key_part_p->length); + // stored_field_cmp_to_item does not compare ints + Item_result res_type = item_cmp_type( + field->result_type(), cmp_item->result_type()); + if (res_type == INT_RESULT) { + Integer_value a(field->val_int(), field->is_unsigned()); + Integer_value b(cmp_item->val_int(), + cmp_item->unsigned_flag); + // < > = comparison to NULL not handled + if (cmp_item->null_value) return false; + return a == b; + } + + bool ret = stored_field_cmp_to_item(current_thd, field, + cmp_item) == 0; + // < > = comparison to NULL not handled + if (cmp_item->null_value) return false; + return ret; + }; + // Only compare if NO_MAX/MIN_RANGE flags aren't set, + // otherwise means that key_min/max might be random + uint16 range_flag = quick_range_check.get_ranges_flag(0); + bool can_remove = true; + if (cmp_with_max) { + if (!(range_flag & NO_MAX_RANGE)) { + can_remove &= cmp(cmp_with_max, key_max); + } else { + can_remove &= false; + } + } - else if (func->functype() == Item_func::EQ_FUNC) { + if (cmp_with_min) { + if (!(range_flag & NO_MIN_RANGE)) { + can_remove &= cmp(cmp_with_min, key_min); + } else { + can_remove &= false; + } + } + dbug_tmp_restore_column_maps(table->read_set, + table->write_set, old_sets); + if (can_remove) { + return nullptr; + } + } + if (isnull && key_part_p->field->is_nullable()) { + // We know that cond is IS NULL, we just have to verify + // that both the upper and lower bounds are NULL as well: + // byte 0 of key_min/key_max is the null-byte. If set, + // key_min/key_max is NULL and the range means IS NULL. + if (*key_min && *key_max) { + return nullptr; + } + } + } + } + } + } + } + } + if (op_type == Item_func::EQ_FUNC) { + // Equality may be achieved with index lookup too: + goto try_eq_func_with_ref; + } + } else if (op_type == Item_func::EQ_FUNC) { + try_eq_func_with_ref: /* - Remove equalities that are guaranteed to be true by use of 'ref' access - method. - Note that ref access implements "table1.field1 <=> - table2.indexed_field2", i.e. if it passed a NULL field1, it will return - NULL indexed_field2 if there are. - Thus the equality "table1.field1 = table2.indexed_field2", - is equivalent to "ref access AND table1.field1 IS NOT NULL" - i.e. "ref access and proper setting/testing of ref->null_rejecting". - Thus, we must be careful, that when we remove equalities below we also - set ref->null_rejecting, and test it at execution; otherwise wrong NULL - matches appear. - So: + Remove equalities that are guaranteed to be true by use of 'ref' + access method. Note that ref access implements "table1.field1 <=> + table2.indexed_field2", i.e. if it passed a NULL field1, it will + return NULL indexed_field2 if there are. Thus the equality + "table1.field1 = table2.indexed_field2", is equivalent to "ref access + AND table1.field1 IS NOT NULL" i.e. "ref access and proper + setting/testing of ref->null_rejecting". Thus, we must be careful, + that when we remove equalities below we also set ref->null_rejecting, + and test it at execution; otherwise wrong NULL matches appear. So: - for the optimization phase, the code which is below, and the code in test_if_ref(), and in add_key_field(), must be kept in sync: if the applicability conditions in one place are relaxed, they should also be diff --git a/sql/sql_optimizer.h b/sql/sql_optimizer.h index c2a0d80bc61..98dc7b3d5ff 100644 --- a/sql/sql_optimizer.h +++ b/sql/sql_optimizer.h @@ -988,6 +988,7 @@ class JOIN { use by 'execute' or 'explain' */ void test_skip_sort(); + void offset_pushdown(); bool alloc_indirection_slices(); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 79942008257..a38ada4db39 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3283,6 +3283,110 @@ bool make_join_readinfo(JOIN *join, uint no_jbuf_after) { return false; } +/** + * Evaluate whether the OFFSET can be assessed in InnoDB. + * + * For SELECT queries whose WHERE clause can be evaluated in InnoDB, it makes + * sense to try and evaluate the offset in the storage engine: the N first + * rows will be discarded inside the engine, not be sent to the + * LimitOffsetiterator, thus saving some buffer copying and CPU. + * + * @return void + * + * @details + * Necessary condition for offset pushdown: + * - There must be an OFFSET + * - Only one table + * - It should not be a temporary internal table (this would require some + * implementation in Temptable and InnoDB-intrinsic) + * - The table should be accessed by a simple access method (using only + * one index - no index merge, or using a table scan) + * - The table in the query must be an InnoDB table + * - no HAVING (sits between table reading and OFFSET applying, and alters + * the result, so OFFSET cannot be applied before HAVING) + * - No aggregation (same, needs all rows) + * - No GROUP BY (same) + * - Check that grouped, group_optimized_away and implicit_grouping are + * false because because they are special forms of grouping where the + * GROUP BY clause is empty at this point + * - No SELECT DISTINCT (same) + * - No ROLLUP (same) + * - No windowing (same) + * - No filesort in sql layer (same) + * - condition must be empty - thereby making sure that there is nothing to + * check up in the SQL layer + * - no post-processing temporary table (it may shuffle or filter rows) + * - no SQL_CALC_FOUND_ROWS (the logic for accurate counting of skipped + * rows, necessary for this, is in the LimitOffsetIterator, not in the + * engine). + * - LIMIT is not an extreme value (or the substraction done to it below + * would be wrong) + * - If there is a range_scan it has to be AccessPath::INDEX_RANGE_SCAN. + * Others types use several read phases possibly with several indexes or may + * jump over rows, which makes compatibility with offset pushdown difficult + * - No partitioned tables if more than one partition is used: The reason + * for that is that the function Partition_helper::handle_ordered_index_scan + * reads rows from the first partition first, then the second partition, etc, + * and does a merge sort to order all these rows. This function can be used + * when there is an ORDER BY clause in the query. Consider for instance a + * partitioned table such that PARTITION BY HASH (pk) PARTITIONS 4, the n + * rows are distributed in the partitions as follows: + * Part 1: row # 0 mod [4]: 4 8 12 16 ... + * Part 2: row # 1 mod [4]: 1 5 9 13 ... + * Part 3: row # 2 mod [4]: 2 6 10 14 ... + * Part 4: row # 3 mod [4]: 3 7 11 15 ... + * Without an ORDER BY, the rows are read partition after partition, + * so first 4 8 12 16 ... then 1 5 9 13 ... etc. If activated, offset + * pushdown is going to discard the p first rows that are read, where p is + * the value of the OFFSET, as would the same query without offset pushdown. + * With an ORDER BY pk, offset pushdown is going to discard the same rows as + * without the ORDER BY which is incorrect. The same query without offset + * pushdown is going to return different rows because it is going to skip + * rows 1 to p. The issue here is how the rows are re-arranged across + * partitions not within a given partition, so this issue does not arise + * when the query reads rows from only one partition. + */ +void JOIN::offset_pushdown() { + ha_rows offset_value = query_expression()->offset_limit_cnt; + if (offset_value != 0 && (primary_tables - const_tables) == 1) { + uint i = const_tables; + QEP_TAB *const tab = &qep_tab[i]; + TABLE *const tbl = tab->table(); + if (!select_distinct && !grouped && !group_optimized_away && + !implicit_grouping && + !(tab->range_scan() && + !(tab->range_scan()->type == AccessPath::INDEX_RANGE_SCAN)) && + !(tbl->part_info && !(tbl->part_info->num_partitions_used() == 1)) && + !(tab->table_ref->is_view_or_derived() || + tab->table_ref->is_table_function() || + tab->table_ref->schema_table) && + (qep_tab->effective_index() != MAX_KEY || qep_tab->type() == JT_ALL) && + tbl->s->db_type()->db_type == DB_TYPE_INNODB && !having_cond && + !query_block->agg_func_used() && !query_block->group_list.first && + query_block->olap == UNSPECIFIED_OLAP_TYPE && + !(query_block->m_windows.elements > 0) && !tab->condition() && + !tab->filesort && !need_tmp_before_win && !calc_found_rows && + !(query_expression()->select_limit_cnt == HA_POS_ERROR)) { + tbl->file->set_pushed_offset( + offset_value); // Offset pushdown is activated, communicate the + // offset value to the handler + query_expression()->offset_limit_cnt = + 0; // Set offset to 0, so that SQL layer does not apply it again + // And remove offset from limit. + assert(offset_value <= query_expression()->select_limit_cnt); + query_expression()->select_limit_cnt -= offset_value; + // Even though the query_expression()'s offset has just been set to 0 for + // this execution plan, we cannot update join->query_block->offset_limit, + // as it's a parse-time object reused by all future optimizations of the + // same query_block. On the other hand, if inside a UNION, + // global_parameters()->offset_limit is used by + // query_block_UNIT::create_access_paths() to set up an iterator. So it + // cannot be out-of-date. Make sure we have no conflict of constraints: + assert(query_expression()->is_simple() || + query_block != query_expression()->global_parameters()); + } + } +} void JOIN_TAB::set_table(TABLE *t) { if (t != nullptr) t->reginfo.join_tab = this; m_qs->set_table(t); diff --git a/sql/sql_select.h b/sql/sql_select.h index 9b5b7acb2d8..3c6d16394e0 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -874,6 +874,7 @@ bool check_field_is_const(Item *cond, const Item *order_item, bool test_if_subpart(ORDER *a, ORDER *b); void calc_group_buffer(JOIN *join, ORDER *group); bool make_join_readinfo(JOIN *join, uint no_jbuf_after); +void offset_pushdown(JOIN *join); bool create_ref_for_key(JOIN *join, JOIN_TAB *j, Key_use *org_keyuse, table_map used_tables); bool types_allow_materialization(Item *outer, Item *inner); diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 42f8d0e4ec8..60666a2b743 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -207,7 +207,8 @@ static constexpr const unsigned long long OPTIMIZER_SWITCH_DEFAULT{ OPTIMIZER_SWITCH_COND_FANOUT_FILTER | OPTIMIZER_SWITCH_DERIVED_MERGE | OPTIMIZER_SKIP_SCAN | OPTIMIZER_SWITCH_HASH_JOIN | OPTIMIZER_SWITCH_PREFER_ORDERING_INDEX | - OPTIMIZER_SWITCH_DERIVED_CONDITION_PUSHDOWN}; + OPTIMIZER_SWITCH_DERIVED_CONDITION_PUSHDOWN | + OPTIMIZER_SWITCH_OFFSET_PUSHDOWN}; static constexpr const unsigned long MYSQLD_NET_RETRY_COUNT{10}; @@ -3423,6 +3424,7 @@ static const char *optimizer_switch_names[] = { "prefer_ordering_index", "hypergraph_optimizer", // Deliberately not documented below. "derived_condition_pushdown", + "offset_pushdown", "default", NullS}; static Sys_var_flagset Sys_optimizer_switch( @@ -3436,7 +3438,7 @@ static Sys_var_flagset Sys_optimizer_switch( " block_nested_loop, batched_key_access, use_index_extensions," " condition_fanout_filter, derived_merge, hash_join," " subquery_to_derived, prefer_ordering_index," - " derived_condition_pushdown} and val is one of " + " derived_condition_pushdown, offset_pushdown} and val is one of " "{on, off, default}", HINT_UPDATEABLE SESSION_VAR(optimizer_switch), CMD_LINE(REQUIRED_ARG), optimizer_switch_names, DEFAULT(OPTIMIZER_SWITCH_DEFAULT), NO_MUTEX_GUARD, @@ -7458,6 +7460,13 @@ static Sys_var_bool Sys_var_print_identified_with_as_hex( SESSION_VAR(print_identified_with_as_hex), CMD_LINE(OPT_ARG), DEFAULT(false)); +static Sys_var_bool Sys_var_empty_redundant_check_in_range_scan( + "empty_redundant_check_in_range_scan", + "From the condition evaluated at the SQL layer, remove any comparison" + " already evaluated by the range index scan method in the storage engine", + SESSION_VAR(empty_redundant_check_in_range_scan), CMD_LINE(OPT_ARG), + DEFAULT(true)); + /** Session only flag to skip printing secondary engine in SHOW CREATE TABLE. diff --git a/sql/system_variables.h b/sql/system_variables.h index 8bf8b2cdc3d..45a28e6fd1c 100644 --- a/sql/system_variables.h +++ b/sql/system_variables.h @@ -285,6 +285,9 @@ struct System_variables { bool old_alter_table; bool big_tables; + /// When true, a redundant condition (meaning that it is enforced by the + /// range access method anyway) in the WHERE clause is removed. + bool empty_redundant_check_in_range_scan; plugin_ref table_plugin; plugin_ref temp_table_plugin; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index f71797dcee6..ad63910ac6a 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1266,6 +1266,9 @@ static SHOW_VAR innodb_status_variables[] = { SHOW_SCOPE_GLOBAL}, {"rows_read", (char *)&export_vars.innodb_rows_read, SHOW_LONG, SHOW_SCOPE_GLOBAL}, + {"rows_skipped_by_offset_pushdown", + (char *)&export_vars.innodb_rows_skipped_by_offset_pushdown, SHOW_LONG, + SHOW_SCOPE_GLOBAL}, {"rows_updated", (char *)&export_vars.innodb_rows_updated, SHOW_LONG, SHOW_SCOPE_GLOBAL}, {"system_rows_deleted", (char *)&export_vars.innodb_system_rows_deleted, @@ -10032,7 +10035,7 @@ int ha_innobase::index_init(uint keynr, /*!< in: key (index) number */ according to index */ { DBUG_TRACE; - + m_scanned_offset = 0; return change_active_index(keynr); } @@ -10778,6 +10781,8 @@ int ha_innobase::rnd_init(bool scan) { assert(table_share->is_missing_primary_key() == (bool)m_prebuilt->clust_index_was_generated); + m_scanned_offset = 0; + int err = change_active_index(table_share->primary_key); /* Don't use semi-consistent read in random row reads (by position). @@ -18426,7 +18431,10 @@ int ha_innobase::end_stmt() { /** MySQL calls this method at the end of each statement */ -int ha_innobase::reset() { return (end_stmt()); } +int ha_innobase::reset() { + m_pushed_offset = m_scanned_offset = 0; + return (end_stmt()); +} /** MySQL calls this function at the start of each SQL statement inside LOCK TABLES. Inside LOCK TABLES the "::external_lock" method does not work to mark diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 810a958327e..e162673df5d 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -36,6 +36,8 @@ this program; if not, write to the Free Software Foundation, Inc., #include "handler.h" #include "mysql/components/services/clone_protocol_service.h" +#include "my_dbug.h" +#include "mysql/plugin.h" #include "row0pread-adapter.h" #include "row0pread-histogram.h" #include "trx0trx.h" @@ -472,6 +474,26 @@ class ha_innobase : public handler { bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes) override; + /** When offset pushdown is activated, it is used to communicate the offset + value to the handler */ + void set_pushed_offset(ha_rows pushed_offset) override { + m_pushed_offset = pushed_offset; + } + /** If non-zero, offset pushdown is activated */ + ha_rows get_pushed_offset() const override { return m_pushed_offset; } + + /// This isn't declared in class 'handler' as it's an implementation detail + /// which is internal to InnoDB. + /** Increments the scanned_offset counter that accounts for the number of rows + that have been skipped during offset pushdown */ + void increment_scanned_offset() { + m_scanned_offset++; + srv_stats.n_rows_skipped_by_offset_pushdown.add( + thd_get_thread_id(m_prebuilt->trx->mysql_thd), 1); + } + /** Retrieves how many rows have been skipped so far due to offset pushdown */ + ha_rows get_scanned_offset() const { return m_scanned_offset; } + private: /** @name Multi Range Read interface @{ */ @@ -678,6 +700,15 @@ class ha_innobase : public handler { /** If mysql has locked with external_lock() */ bool m_mysql_has_locked; + + /** value of the offset used for pushing down the offset to InnoDB. */ + ha_rows m_pushed_offset{0}; + /** + Number of rows that have been skipped in InnoDB, + scanned_offset is incremented up to pushed_offset when offset_pushdown + has determined the offset should be pushed + */ + ha_rows m_scanned_offset{0}; }; struct trx_t; diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h index 71653225cf4..7da8732effb 100644 --- a/storage/innobase/include/srv0mon.h +++ b/storage/innobase/include/srv0mon.h @@ -473,6 +473,7 @@ enum monitor_id_t { /* Data DML related counters */ MONITOR_MODULE_DML_STATS, MONITOR_OLVD_ROW_READ, + MONITOR_OLVD_ROW_SKIPPED_BY_OP, MONITOR_OLVD_ROW_INSERTED, MONITOR_OLVD_ROW_DELETED, MONITOR_OLVD_ROW_UPDTATED, diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index e712399bf65..ac4b20afbd2 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -139,6 +139,9 @@ struct srv_stats_t { /** Number of rows inserted */ ulint_ctr_64_t n_rows_inserted; + /** Number of rows skipped by offset pushdown. */ + ulint_ctr_64_t n_rows_skipped_by_offset_pushdown; + /** Number of system rows read. */ ulint_ctr_64_t n_system_rows_read; @@ -1182,10 +1185,13 @@ struct export_var_t { ulint innodb_rows_inserted; /*!< srv_n_rows_inserted */ ulint innodb_rows_updated; /*!< srv_n_rows_updated */ ulint innodb_rows_deleted; /*!< srv_n_rows_deleted */ - ulint innodb_system_rows_read; /*!< srv_n_system_rows_read */ - ulint innodb_system_rows_inserted; /*!< srv_n_system_rows_inserted */ - ulint innodb_system_rows_updated; /*!< srv_n_system_rows_updated */ - ulint innodb_system_rows_deleted; /*!< srv_n_system_rows_deleted*/ + ulint + innodb_rows_skipped_by_offset_pushdown; /*!< + srv_n_rows_skipped_by_offset_pushdown*/ + ulint innodb_system_rows_read; /*!< srv_n_system_rows_read */ + ulint innodb_system_rows_inserted; /*!< srv_n_system_rows_inserted */ + ulint innodb_system_rows_updated; /*!< srv_n_system_rows_updated */ + ulint innodb_system_rows_deleted; /*!< srv_n_system_rows_deleted*/ ulint innodb_sampled_pages_read; ulint innodb_sampled_pages_skipped; ulint innodb_num_open_files; /*!< fil_n_files_open */ diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index c1c82b5f7d3..9d7d8502238 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -3891,6 +3891,19 @@ static dberr_t row_search_traverse(bool moves_up, ulint match_mode, return (err); } +/** If offset_pushdown determined that the offset should be pushed down to +InnoDB, we check whether we have skipped enough rows to reach the +required offset. +@param[in] prebuilt contains information about offset +pushdown +@return true if offset pushdown is active and not all rows have been skipped, +false otherwise */ +inline bool skip_row_for_offset_pushdown(row_prebuilt_t *prebuilt) { + return (prebuilt->m_mysql_handler != nullptr && + prebuilt->m_mysql_handler->get_pushed_offset() > + prebuilt->m_mysql_handler->get_scanned_offset()); +} + /** Searches for rows in the database using cursor. Function is for temporary tables that are not shared across connections and so lot of complexity is reduced especially locking and transaction related. @@ -4404,6 +4417,7 @@ dberr_t row_search_mvcc(byte *buf, page_cur_mode_t mode, const rec_t *clust_rec; Row_sel_get_clust_rec_for_mysql row_sel_get_clust_rec_for_mysql; dberr_t err = DB_SUCCESS; + dberr_t new_clust_rec_locked = DB_SUCCESS; bool unique_search = false; bool mtr_has_extra_clust_latch = false; bool moves_up = false; @@ -4427,6 +4441,13 @@ dberr_t row_search_mvcc(byte *buf, page_cur_mode_t mode, bool spatial_search = false; ulint end_loop = 0; + // If we do offset pushdown for MySQL, upon entrance here we have either + // skipped no row or skipped all requested rows. + assert(!(prebuilt->m_mysql_handler) || + (prebuilt->m_mysql_handler->get_scanned_offset() == 0 || + prebuilt->m_mysql_handler->get_scanned_offset() == + prebuilt->m_mysql_handler->get_pushed_offset())); + rec_offs_init(offsets_); ut_ad(index && pcur && search_tuple); @@ -4478,6 +4499,51 @@ dberr_t row_search_mvcc(byte *buf, page_cur_mode_t mode, const auto record_buffer = row_sel_get_record_buffer(prebuilt); + /* Lambda function that evaluates whether a record is beyond the upper bound + of a range. Used, among other things, as part of the logic for offset + pushdown when prebuilt->select_lock_type != LOCK_NONE. With offset pushdown + rows are skipped without returning to the handler where end of range is + also assessed. To prevent locking additional rows, we assess end of range + in InnoDB using this function. It is also used to evaluate whether the + supremum of a page is still in the range in the general case. rec is the + record for which we evaluate whether it is out of the range. vrow is the + virtual row. Return true if it's the case, false otherwise */ + auto end_range_check = [&](const rec_t *rec, const dtuple_t *vrow) { + dict_index_t *key_index = prebuilt->index; + + if (end_range_cache == nullptr) { + end_range_cache = static_cast(ut::malloc_withkey( + UT_NEW_THIS_FILE_PSI_KEY, prebuilt->mysql_row_len)); + } + if (clust_templ_for_sec) { + /** Secondary index record but the template + based on PK. */ + key_index = clust_index; + } + + /** Create offsets based on prebuilt index. */ + offsets = rec_get_offsets(rec, prebuilt->index, offsets, ULINT_UNDEFINED, + UT_LOCATION_HERE, &heap); + + if (row_sel_store_mysql_rec( + end_range_cache, prebuilt, rec, vrow, clust_templ_for_sec, + key_index, prebuilt->index, offsets, clust_templ_for_sec, + prebuilt->get_lob_undo(), prebuilt->blob_heap)) { + if (row_search_end_range_check(end_range_cache, rec, prebuilt, + clust_templ_for_sec, offsets, + record_buffer)) { + /** In case of prebuilt->fetch, + set the error in prebuilt->end_range. */ + if (next_buf != nullptr) { + prebuilt->m_end_range = true; + } + + return true; + } + } + return false; + }; + if (UNIV_UNLIKELY(direction == 0)) { trx->op_info = "starting index read"; @@ -4932,40 +4998,9 @@ rec_loop: if (prev_rec != nullptr && !prebuilt->innodb_api && prebuilt->m_mysql_handler->end_range != nullptr && prebuilt->idx_cond == false && end_loop >= 100) { - dict_index_t *key_index = prebuilt->index; - - if (end_range_cache == nullptr) { - end_range_cache = static_cast(ut::malloc_withkey( - UT_NEW_THIS_FILE_PSI_KEY, prebuilt->mysql_row_len)); - } - - if (clust_templ_for_sec) { - /** Secondary index record but the template - based on PK. */ - key_index = clust_index; - } - - /** Create offsets based on prebuilt index. */ - offsets = rec_get_offsets(prev_rec, prebuilt->index, offsets, - ULINT_UNDEFINED, UT_LOCATION_HERE, &heap); - - if (row_sel_store_mysql_rec(end_range_cache, prebuilt, prev_rec, - prev_vrow, clust_templ_for_sec, key_index, - prebuilt->index, offsets, clust_templ_for_sec, - prebuilt->get_lob_undo(), - prebuilt->blob_heap)) { - if (row_search_end_range_check(end_range_cache, prev_rec, prebuilt, - clust_templ_for_sec, offsets, - record_buffer)) { - /** In case of prebuilt->fetch, - set the error in prebuilt->end_range. */ - if (next_buf != nullptr) { - prebuilt->m_end_range = true; - } - - err = DB_RECORD_NOT_FOUND; - goto normal_return; - } + if (end_range_check(prev_rec, prev_vrow)) { + err = DB_RECORD_NOT_FOUND; + goto normal_return; } DEBUG_SYNC_C("allow_insert"); } @@ -5184,8 +5219,9 @@ rec_loop: goto normal_return; } } - /* in case of semi-consistent read, we use SELECT_SKIP_LOCKED, so we don't - waste time on creating a WAITING lock, as we won't wait on it anyway */ + /* in case of semi-consistent read, we use SELECT_SKIP_LOCKED, so we + don't waste time on creating a WAITING lock, as we won't wait on it + anyway */ const bool use_semi_consistent = prebuilt->row_read_type == ROW_READ_TRY_SEMI_CONSISTENT && !unique_search && index == clust_index && !trx_is_high_priority(trx); @@ -5217,7 +5253,8 @@ rec_loop: DEBUG_SYNC_C("semi_consistent_read_would_wait"); ut_a(use_semi_consistent); ut_a(trx->allow_semi_consistent()); - /* The following call returns 'offsets' associated with 'old_vers' */ + /* The following call returns 'offsets' associated with 'old_vers' + */ row_sel_build_committed_vers_for_mysql( clust_index, prebuilt, rec, &offsets, &heap, &old_vers, need_vrow ? &vrow : nullptr, &mtr); @@ -5278,7 +5315,8 @@ rec_loop: !lock_clust_rec_cons_read_sees(rec, index, offsets, trx_get_read_view(trx))) { rec_t *old_vers; - /* The following call returns 'offsets' associated with 'old_vers' */ + /* The following call returns 'offsets' associated with 'old_vers' + */ err = row_sel_build_prev_vers_for_mysql( trx->read_view, clust_index, prebuilt, rec, &offsets, &heap, &old_vers, need_vrow ? &vrow : nullptr, &mtr, @@ -5331,7 +5369,6 @@ rec_loop: } } } - #ifdef UNIV_DEBUG if (did_semi_consistent_read) { ut_a(prebuilt->select_lock_type != LOCK_NONE); @@ -5351,8 +5388,8 @@ rec_loop: /* The record is delete-marked: we can skip it */ /* No need to keep a lock on a delete-marked record in lower isolation - levels - it's similar to when Server sees the WHERE condition doesn't match - and calls unlock_row(). */ + levels - it's similar to when Server sees the WHERE condition doesn't + match and calls unlock_row(). */ prebuilt->try_unlock(true); /* This is an optimization to skip setting the next key lock @@ -5387,7 +5424,17 @@ rec_loop: prebuilt->try_unlock(true); goto idx_cond_failed; case ICP_MATCH: - break; + // If this is a locking read: without offset pushdown, we would lock + // this row later in this function. With offset pushdown, we want no + // behaviour change. So, we do not skip the row yet, wait until we + // have set the lock, then skip the row later in this function. + if ((prebuilt->select_lock_type == LOCK_NONE) && + skip_row_for_offset_pushdown(prebuilt)) { + prebuilt->m_mysql_handler->increment_scanned_offset(); + goto next_rec; + } else { + break; + } } /* Get the clustered index record if needed, if we did not do the @@ -5408,6 +5455,7 @@ rec_loop: mtr_has_extra_clust_latch = true; ut_ad(!vrow); + ut_ad(new_clust_rec_locked == DB_SUCCESS); /* The following call returns 'offsets' associated with 'clust_rec'. Note that 'clust_rec' can be an old version @@ -5424,7 +5472,15 @@ rec_loop: goto next_rec; } - break; + /* when mvcc confirmation is needed: offset pushdown proceeds + similarly to the case where mvcc is not needed. */ + if (skip_row_for_offset_pushdown(prebuilt)) { + prebuilt->m_mysql_handler->increment_scanned_offset(); + // This 'case' label is no locking read, we can skip the row now + goto next_rec; + } else { + break; + } case DB_SKIP_LOCKED: goto next_rec; case DB_SUCCESS_LOCKED_REC: @@ -5435,6 +5491,7 @@ rec_loop: ut_ad(!prebuilt->new_rec_lock[row_prebuilt_t::LOCK_CLUST_PCUR]); prebuilt->new_rec_lock[row_prebuilt_t::LOCK_CLUST_PCUR] = true; } + new_clust_rec_locked = err; // write down that a lock is set on the PK err = DB_SUCCESS; break; default: @@ -5445,9 +5502,9 @@ rec_loop: if (rec_get_deleted_flag(clust_rec, comp)) { /* The record is delete marked: we can skip it */ - /* No need to keep a lock on a delete-marked record in lower isolation - levels - it's similar to when Server sees the WHERE condition doesn't - match and calls unlock_row(). */ + /* No need to keep a lock on a delete-marked record in lower + isolation levels - it's similar to when Server sees the WHERE + condition doesn't match and calls unlock_row(). */ prebuilt->try_unlock(true); goto next_rec; @@ -5518,6 +5575,54 @@ rec_loop: result_rec = rec; } + if (!(prebuilt->select_lock_type == LOCK_NONE) && + skip_row_for_offset_pushdown(prebuilt)) { + // We have to skip the row, and didn't skip it earlier due to locking. + // The following assertion verifies that the only way this can happen + // is: + // - either we did not call row_sel_get_clust_rec_for_mysql(), + // - or we did, and placed a lock on the clustered record. + bool require_clust_record = + (index != clust_index && prebuilt->need_to_access_clustered); + ut_ad(!require_clust_record || + (new_clust_rec_locked == DB_SUCCESS_LOCKED_REC)); + // Imagine a query where the value of OFFSET is larger than the number + // of rows in the range. We must check that we are not at the end of + // the range, before going to the next record; otherwise we would soon + // place a lock on that next record, which would be wrong. + // !prebuilt->idx_cond: if ICP is active, it has already checked for + // end-of-range and returned ICP_OUT_OF_RANGE in that case. + if (rec != nullptr && !prebuilt->innodb_api && + prebuilt->m_mysql_handler->end_range != nullptr && + !prebuilt->idx_cond && end_range_check(rec, vrow)) { + err = DB_RECORD_NOT_FOUND; + new_clust_rec_locked = DB_SUCCESS; // reset + goto normal_return; + } + + prebuilt->m_mysql_handler->increment_scanned_offset(); + // Before we skip this row we must follow the same logic as what + // ha_innobase::unlock_row would. + if (trx->allow_semi_consistent()) { + ut_ad(prebuilt->row_read_type == ROW_READ_WITH_LOCKS); + // If we accessed the clustered record, the clustered lock has + // to be set. In all cases, the unclustered lock has to be set. + ut_ad(!require_clust_record || + prebuilt->new_rec_lock[row_prebuilt_t::LOCK_CLUST_PCUR]); + ut_ad(prebuilt->new_rec_lock[row_prebuilt_t::LOCK_PCUR]); + prebuilt->try_unlock(true); + } + goto next_rec; + } + new_clust_rec_locked = DB_SUCCESS; // reset + /* Checks that enough rows have been skipped that the offset is fully + processed by the time we get to that point when offset pushdown is + activated. */ + assert(!(prebuilt->m_mysql_handler && + prebuilt->m_mysql_handler->get_pushed_offset() != 0) || + (prebuilt->m_mysql_handler->get_pushed_offset() == + prebuilt->m_mysql_handler->get_scanned_offset())); + /* We found a qualifying record 'result_rec'. At this point, 'offsets' are associated with 'result_rec'. */ @@ -5721,6 +5826,7 @@ idx_cond_failed: next_rec: + new_clust_rec_locked = DB_SUCCESS; // reset if (end_loop >= 99 && need_vrow && vrow == nullptr && prev_rec != nullptr) { if (!heap) { heap = mem_heap_create(100, UT_LOCATION_HERE); diff --git a/storage/innobase/srv/srv0mon.cc b/storage/innobase/srv/srv0mon.cc index 3fb0bc8710a..8d68656bb9d 100644 --- a/storage/innobase/srv/srv0mon.cc +++ b/storage/innobase/srv/srv0mon.cc @@ -1277,6 +1277,11 @@ static monitor_info_t innodb_counter_info[] = { static_cast(MONITOR_EXISTING), MONITOR_DEFAULT_START, MONITOR_OLVD_ROW_READ}, + {"dml_reads_skipped_by_offset_pushdown", "dml", + "Number of rows skipped by offset pushdown", + static_cast(MONITOR_EXISTING), MONITOR_DEFAULT_START, + MONITOR_OLVD_ROW_SKIPPED_BY_OP}, + {"dml_inserts", "dml", "Number of rows inserted", static_cast(MONITOR_EXISTING | MONITOR_DEFAULT_ON), MONITOR_DEFAULT_START, MONITOR_OLVD_ROW_INSERTED}, @@ -1818,6 +1823,10 @@ void srv_mon_process_existing_counter( value = srv_stats.n_rows_read; break; + /* innodb_rows_skipped_by_offset_pushdown */ + case MONITOR_OLVD_ROW_SKIPPED_BY_OP: + value = srv_stats.n_rows_skipped_by_offset_pushdown; + break; /* innodb_rows_inserted */ case MONITOR_OLVD_ROW_INSERTED: value = srv_stats.n_rows_inserted; diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 20910d55f9e..a429739e2ae 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -593,6 +593,7 @@ static ulint srv_n_rows_inserted_old = 0; static ulint srv_n_rows_updated_old = 0; static ulint srv_n_rows_deleted_old = 0; static ulint srv_n_rows_read_old = 0; +static ulint srv_n_rows_skipped_by_offset_pushdown_old = 0; static ulint srv_n_system_rows_inserted_old = 0; static ulint srv_n_system_rows_updated_old = 0; @@ -1307,6 +1308,8 @@ static void srv_refresh_innodb_monitor_stats(void) { srv_n_rows_updated_old = srv_stats.n_rows_updated; srv_n_rows_deleted_old = srv_stats.n_rows_deleted; srv_n_rows_read_old = srv_stats.n_rows_read; + srv_n_rows_skipped_by_offset_pushdown_old = + srv_stats.n_rows_skipped_by_offset_pushdown; srv_n_system_rows_inserted_old = srv_stats.n_system_rows_inserted; srv_n_system_rows_updated_old = srv_stats.n_system_rows_updated; @@ -1505,9 +1508,11 @@ bool srv_printf_innodb_monitor(FILE *file, bool nowait, ulint *trx_start_pos, fprintf(file, "Number of rows inserted " ULINTPF ", updated " ULINTPF - ", deleted " ULINTPF ", read " ULINTPF "\n", + ", deleted " ULINTPF ", read " ULINTPF + ", skipped by offset pushdown" ULINTPF "\n", (ulint)srv_stats.n_rows_inserted, (ulint)srv_stats.n_rows_updated, - (ulint)srv_stats.n_rows_deleted, (ulint)srv_stats.n_rows_read); + (ulint)srv_stats.n_rows_deleted, (ulint)srv_stats.n_rows_read, + (ulint)srv_stats.n_rows_skipped_by_offset_pushdown); fprintf( file, "%.2f inserts/s, %.2f updates/s," @@ -1543,6 +1548,8 @@ bool srv_printf_innodb_monitor(FILE *file, bool nowait, ulint *trx_start_pos, srv_n_rows_updated_old = srv_stats.n_rows_updated; srv_n_rows_deleted_old = srv_stats.n_rows_deleted; srv_n_rows_read_old = srv_stats.n_rows_read; + srv_n_rows_skipped_by_offset_pushdown_old = + srv_stats.n_rows_skipped_by_offset_pushdown; srv_n_system_rows_inserted_old = srv_stats.n_system_rows_inserted; srv_n_system_rows_updated_old = srv_stats.n_system_rows_updated; @@ -1682,6 +1689,9 @@ void srv_export_innodb_status(void) { export_vars.innodb_rows_read = srv_stats.n_rows_read; + export_vars.innodb_rows_skipped_by_offset_pushdown = + srv_stats.n_rows_skipped_by_offset_pushdown; + export_vars.innodb_rows_inserted = srv_stats.n_rows_inserted; export_vars.innodb_rows_updated = srv_stats.n_rows_updated;