diff --git a/mysql-test/main/range.result b/mysql-test/main/range.result index 1e3d05e81e0..bf4a490ebec 100644 --- a/mysql-test/main/range.result +++ b/mysql-test/main/range.result @@ -3824,5 +3824,20 @@ id MIN(id) 8 8 DROP TABLE t1; # +# MDEV-31237 Assertion `!(tab->select && tab->select->quick)' failed +# in make_join_readinfo +# +CREATE TABLE lineitem (l_orderkey int, l_linenumber int, l_receiptDATE date DEFAULT NULL, PRIMARY KEY (l_orderkey,l_linenumber), KEY i_l_receiptdate (l_receiptDATE), KEY i_l_orderkey (l_orderkey)) ENGINE=InnoDB; +INSERT INTO lineitem VALUES (291,1,'1994-06-23'),(291,2,'1994-06-19'), +(291,3,'1994-03-24'),(292,1,'1992-03-18'),(292,2,'1992-04-20'); +EXPLAIN SELECT DISTINCT l_orderkey FROM lineitem FORCE KEY (i_l_orderkey, i_l_receiptdate) WHERE l_orderkey > 1 ORDER BY l_receiptdate; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range i_l_orderkey i_l_orderkey 4 NULL 5 Using where; Using temporary; Using filesort +SELECT DISTINCT l_orderkey FROM lineitem FORCE KEY (i_l_orderkey, i_l_receiptdate) WHERE l_orderkey > 1 ORDER BY l_receiptdate; +l_orderkey +292 +291 +DROP TABLE lineitem; +# # End of 11.0 tests # diff --git a/mysql-test/main/range.test b/mysql-test/main/range.test index 5911fc45741..f20970939d9 100644 --- a/mysql-test/main/range.test +++ b/mysql-test/main/range.test @@ -2602,6 +2602,18 @@ WHERE (b > 'TX' OR b BETWEEN 'NE' AND 'SC') AND id IN (1,7,8) AND a = 5 GROUP BY id; DROP TABLE t1; +--echo # +--echo # MDEV-31237 Assertion `!(tab->select && tab->select->quick)' failed +--echo # in make_join_readinfo +--echo # + +CREATE TABLE lineitem (l_orderkey int, l_linenumber int, l_receiptDATE date DEFAULT NULL, PRIMARY KEY (l_orderkey,l_linenumber), KEY i_l_receiptdate (l_receiptDATE), KEY i_l_orderkey (l_orderkey)) ENGINE=InnoDB; +INSERT INTO lineitem VALUES (291,1,'1994-06-23'),(291,2,'1994-06-19'), + (291,3,'1994-03-24'),(292,1,'1992-03-18'),(292,2,'1992-04-20'); +EXPLAIN SELECT DISTINCT l_orderkey FROM lineitem FORCE KEY (i_l_orderkey, i_l_receiptdate) WHERE l_orderkey > 1 ORDER BY l_receiptdate; +SELECT DISTINCT l_orderkey FROM lineitem FORCE KEY (i_l_orderkey, i_l_receiptdate) WHERE l_orderkey > 1 ORDER BY l_receiptdate; +DROP TABLE lineitem; + --echo # --echo # End of 11.0 tests --echo # diff --git a/mysql-test/main/range_mrr_icp.result b/mysql-test/main/range_mrr_icp.result index b9d74cb3c18..569080cc283 100644 --- a/mysql-test/main/range_mrr_icp.result +++ b/mysql-test/main/range_mrr_icp.result @@ -3821,6 +3821,21 @@ id MIN(id) 8 8 DROP TABLE t1; # +# MDEV-31237 Assertion `!(tab->select && tab->select->quick)' failed +# in make_join_readinfo +# +CREATE TABLE lineitem (l_orderkey int, l_linenumber int, l_receiptDATE date DEFAULT NULL, PRIMARY KEY (l_orderkey,l_linenumber), KEY i_l_receiptdate (l_receiptDATE), KEY i_l_orderkey (l_orderkey)) ENGINE=InnoDB; +INSERT INTO lineitem VALUES (291,1,'1994-06-23'),(291,2,'1994-06-19'), +(291,3,'1994-03-24'),(292,1,'1992-03-18'),(292,2,'1992-04-20'); +EXPLAIN SELECT DISTINCT l_orderkey FROM lineitem FORCE KEY (i_l_orderkey, i_l_receiptdate) WHERE l_orderkey > 1 ORDER BY l_receiptdate; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range i_l_orderkey i_l_orderkey 4 NULL 5 Using where; Using temporary; Using filesort +SELECT DISTINCT l_orderkey FROM lineitem FORCE KEY (i_l_orderkey, i_l_receiptdate) WHERE l_orderkey > 1 ORDER BY l_receiptdate; +l_orderkey +292 +291 +DROP TABLE lineitem; +# # End of 11.0 tests # set optimizer_switch=@mrr_icp_extra_tmp; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ec1ecfd8580..cec3aa1f91f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -15373,7 +15373,16 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after) push_index_cond(tab, tab->ref.key); break; case JT_NEXT: // Index scan - DBUG_ASSERT(!(tab->select && tab->select->quick)); + DBUG_ASSERT(!tab->quick); + if (tab->select) + { + /* + select->quick may be set if there was a possible range and + it had a higher cost than a table scan. + */ + delete tab->select->quick; + tab->select->quick=0; + } if (tab->use_quick == 2) { join->thd->set_status_no_good_index_used();