Skip to content

Commit 70815ed

Browse files
committed
Merge branch '10.3' into 10.4
2 parents fdb9b05 + 7e8a580 commit 70815ed

File tree

4 files changed

+194
-1
lines changed

4 files changed

+194
-1
lines changed

mysql-test/main/join.result

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3346,3 +3346,59 @@ id select_type table type possible_keys key key_len ref rows Extra
33463346
1 SIMPLE t0 ALL NULL NULL NULL NULL 10 Using where
33473347
1 SIMPLE t1 ref a a 5 test.t0.a 1
33483348
drop table t0,t1;
3349+
#
3350+
# MDEV-21383: Possible range plan is not used under certain conditions
3351+
#
3352+
drop table if exists t10, t1000, t03;
3353+
create table t10(a int);
3354+
insert into t10 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
3355+
create table t1000(a int);
3356+
insert into t1000 select A.a + B.a* 10 + C.a * 100 from t10 A, t10 B, t10 C;
3357+
create table t03(a int);
3358+
insert into t03 values (0),(1),(2);
3359+
create table t1 (
3360+
stationid int
3361+
);
3362+
insert into t1 select a from t10;
3363+
CREATE TABLE t2 (
3364+
stationId int,
3365+
startTime int,
3366+
filler char(100),
3367+
key1 int,
3368+
key2 int,
3369+
key(key1),
3370+
key(key2),
3371+
PRIMARY KEY (`stationId`,`startTime`)
3372+
);
3373+
insert into t2 select
3374+
A.a,
3375+
B.a,
3376+
repeat('filler=data-', 4),
3377+
B.a,
3378+
1
3379+
from
3380+
t03 A,
3381+
t1000 B;
3382+
analyze table t2;
3383+
Table Op Msg_type Msg_text
3384+
test.t2 analyze status OK
3385+
create table t3(a int, filler char(100), key(a));
3386+
insert into t3 select A.a+1000*B.a, 'filler-data' from t1000 A, t10 B;
3387+
# This should produce a join order of t1,t2,t3
3388+
# t2 should have type=range, key=PRIMARY key_len=8 (not type=ALL or key_len<8)
3389+
explain
3390+
SELECT *
3391+
FROM
3392+
t1,t2,t3
3393+
WHERE
3394+
t2.startTime <= 100 and
3395+
t2.stationId = t1.stationId and
3396+
(t1.stationid = 1 or t1.stationid = 2 or t1.stationid = 3) and
3397+
key1 >0 and
3398+
t2.key2=t3.a;
3399+
id select_type table type possible_keys key key_len ref rows Extra
3400+
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using where
3401+
1 SIMPLE t2 range PRIMARY,key1,key2 PRIMARY 8 NULL 219 Using index condition; Using where; Using join buffer (flat, BNL join)
3402+
1 SIMPLE t3 ref a a 5 test.t2.key2 1
3403+
drop table t1,t2,t3;
3404+
drop table t1000,t10,t03;

mysql-test/main/join.test

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1749,3 +1749,68 @@ show keys from t1;
17491749
explain select * from t0,t1 where t0.a=t1.a;
17501750

17511751
drop table t0,t1;
1752+
1753+
--echo #
1754+
--echo # MDEV-21383: Possible range plan is not used under certain conditions
1755+
--echo #
1756+
1757+
--disable_warnings
1758+
drop table if exists t10, t1000, t03;
1759+
--enable_warnings
1760+
1761+
create table t10(a int);
1762+
insert into t10 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
1763+
1764+
create table t1000(a int);
1765+
insert into t1000 select A.a + B.a* 10 + C.a * 100 from t10 A, t10 B, t10 C;
1766+
1767+
create table t03(a int);
1768+
insert into t03 values (0),(1),(2);
1769+
1770+
1771+
create table t1 (
1772+
stationid int
1773+
);
1774+
insert into t1 select a from t10;
1775+
1776+
CREATE TABLE t2 (
1777+
stationId int,
1778+
startTime int,
1779+
filler char(100),
1780+
key1 int,
1781+
key2 int,
1782+
key(key1),
1783+
key(key2),
1784+
PRIMARY KEY (`stationId`,`startTime`)
1785+
);
1786+
1787+
insert into t2 select
1788+
A.a,
1789+
B.a,
1790+
repeat('filler=data-', 4),
1791+
B.a,
1792+
1
1793+
from
1794+
t03 A,
1795+
t1000 B;
1796+
analyze table t2;
1797+
1798+
create table t3(a int, filler char(100), key(a));
1799+
insert into t3 select A.a+1000*B.a, 'filler-data' from t1000 A, t10 B;
1800+
1801+
--echo # This should produce a join order of t1,t2,t3
1802+
--echo # t2 should have type=range, key=PRIMARY key_len=8 (not type=ALL or key_len<8)
1803+
explain
1804+
SELECT *
1805+
FROM
1806+
t1,t2,t3
1807+
WHERE
1808+
t2.startTime <= 100 and
1809+
t2.stationId = t1.stationId and
1810+
(t1.stationid = 1 or t1.stationid = 2 or t1.stationid = 3) and
1811+
key1 >0 and
1812+
t2.key2=t3.a;
1813+
1814+
drop table t1,t2,t3;
1815+
drop table t1000,t10,t03;
1816+

sql/opt_range.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9654,6 +9654,8 @@ and_all_keys(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
96549654
}
96559655
if (key1->type == SEL_ARG::MAYBE_KEY)
96569656
{
9657+
if (key2->type == SEL_ARG::KEY_RANGE)
9658+
return key2;
96579659
key1->right= key1->left= &null_element;
96589660
key1->next= key1->prev= 0;
96599661
}

sql/sql_select.cc

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11143,6 +11143,74 @@ make_outerjoin_info(JOIN *join)
1114311143
}
1114411144

1114511145

11146+
/*
11147+
@brief
11148+
Build a temporary join prefix condition for JOIN_TABs up to the last tab
11149+
11150+
@param ret OUT the condition is returned here
11151+
11152+
@return
11153+
false OK
11154+
true Out of memory
11155+
11156+
@detail
11157+
Walk through the join prefix (from the first table to the last_tab) and
11158+
build a condition:
11159+
11160+
join_tab_1_cond AND join_tab_2_cond AND ... AND last_tab_conds
11161+
11162+
The condition is only intended to be used by the range optimizer, so:
11163+
- it is not normalized (can have Item_cond_and inside another
11164+
Item_cond_and)
11165+
- it does not include join->exec_const_cond and other similar conditions.
11166+
*/
11167+
11168+
bool build_tmp_join_prefix_cond(JOIN *join, JOIN_TAB *last_tab, Item **ret)
11169+
{
11170+
THD *const thd= join->thd;
11171+
Item_cond_and *all_conds= NULL;
11172+
11173+
Item *res= NULL;
11174+
11175+
// Pick the ON-expression. Use the same logic as in get_sargable_cond():
11176+
if (last_tab->on_expr_ref)
11177+
res= *last_tab->on_expr_ref;
11178+
else if (last_tab->table->pos_in_table_list &&
11179+
last_tab->table->pos_in_table_list->embedding &&
11180+
!last_tab->table->pos_in_table_list->embedding->sj_on_expr)
11181+
{
11182+
res= last_tab->table->pos_in_table_list->embedding->on_expr;
11183+
}
11184+
11185+
for (JOIN_TAB *tab= first_depth_first_tab(join);
11186+
tab;
11187+
tab= next_depth_first_tab(join, tab))
11188+
{
11189+
if (tab->select_cond)
11190+
{
11191+
if (!res)
11192+
res= tab->select_cond;
11193+
else
11194+
{
11195+
if (!all_conds)
11196+
{
11197+
if (!(all_conds= new (thd->mem_root)Item_cond_and(thd, res,
11198+
tab->select_cond)))
11199+
return true;
11200+
res= all_conds;
11201+
}
11202+
else
11203+
all_conds->add(tab->select_cond, thd->mem_root);
11204+
}
11205+
}
11206+
if (tab == last_tab)
11207+
break;
11208+
}
11209+
*ret= all_conds? all_conds: res;
11210+
return false;
11211+
}
11212+
11213+
1114611214
static bool
1114711215
make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
1114811216
{
@@ -11520,7 +11588,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
1152011588
{
1152111589
/* Join with outer join condition */
1152211590
COND *orig_cond=sel->cond;
11523-
sel->cond= and_conds(thd, sel->cond, *tab->on_expr_ref);
11591+
11592+
if (build_tmp_join_prefix_cond(join, tab, &sel->cond))
11593+
return true;
1152411594

1152511595
/*
1152611596
We can't call sel->cond->fix_fields,

0 commit comments

Comments
 (0)