Commit e6e0937d authored by hf@deer.(none)'s avatar hf@deer.(none)

Proposed fix for #2093

it happens because of the LEFT JOINT optimization in add_key_part()
This optimization does exactly the same in JOIN and in WHERE conditions 
Not right.
I moved that optimization one level upper.
parent 1485d9b4
...@@ -667,3 +667,20 @@ left outer join t2 using (f2) ...@@ -667,3 +667,20 @@ left outer join t2 using (f2)
left outer join t3 using (f3); left outer join t3 using (f3);
Unknown column 'test.t2.f3' in 'on clause' Unknown column 'test.t2.f3' in 'on clause'
drop table t1,t2,t3; drop table t1,t2,t3;
create table t1 (a1 int, a2 int);
create table t2 (b1 int not null, b2 int);
create table t3 (c1 int, c2 int);
insert into t1 values (1,2), (2,2), (3,2);
insert into t2 values (1,3), (2,3);
insert into t3 values (2,4), (3,4);
select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null;
a1 a2 b1 b2 c1 c2
1 2 1 3 NULL NULL
2 2 2 3 NULL NULL
3 2 NULL NULL 3 4
explain select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null;
table type possible_keys key key_len ref rows Extra
t1 ALL NULL NULL NULL NULL 3
t2 ALL NULL NULL NULL NULL 2
t3 ALL NULL NULL NULL NULL 2
drop table t1, t2, t3;
...@@ -437,3 +437,16 @@ select * from t1 ...@@ -437,3 +437,16 @@ select * from t1
left outer join t2 using (f2) left outer join t2 using (f2)
left outer join t3 using (f3); left outer join t3 using (f3);
drop table t1,t2,t3; drop table t1,t2,t3;
create table t1 (a1 int, a2 int);
create table t2 (b1 int not null, b2 int);
create table t3 (c1 int, c2 int);
insert into t1 values (1,2), (2,2), (3,2);
insert into t2 values (1,3), (2,3);
insert into t3 values (2,4), (3,4);
select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null;
explain select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null;
drop table t1, t2, t3;
...@@ -1683,10 +1683,6 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field) ...@@ -1683,10 +1683,6 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
} }
} }
} }
/* Mark that we can optimize LEFT JOIN */
if (key_field->val->type() == Item::NULL_ITEM &&
!key_field->field->real_maybe_null())
key_field->field->table->reginfo.not_exists_optimize=1;
} }
...@@ -1777,13 +1773,26 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, ...@@ -1777,13 +1773,26 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
{ {
KEY_FIELD *key_fields,*end; KEY_FIELD *key_fields,*end;
KEY_FIELD *field;
if (!(key_fields=(KEY_FIELD*) if (!(key_fields=(KEY_FIELD*)
thd->alloc(sizeof(key_fields[0])*(thd->cond_count+1)*2))) thd->alloc(sizeof(key_fields[0])*(thd->cond_count+1)*2)))
return TRUE; /* purecov: inspected */ return TRUE; /* purecov: inspected */
and_level=0; end=key_fields; and_level=0; field=end=key_fields;
if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64))
return TRUE;
if (cond) if (cond)
{
add_key_fields(join_tab,&end,&and_level,cond,normal_tables); add_key_fields(join_tab,&end,&and_level,cond,normal_tables);
for (; field != end ; field++)
{
add_key_part(keyuse,field);
/* Mark that we can optimize LEFT JOIN */
if (field->val->type() == Item::NULL_ITEM &&
!field->field->real_maybe_null())
field->field->table->reginfo.not_exists_optimize=1;
}
}
for (i=0 ; i < tables ; i++) for (i=0 ; i < tables ; i++)
{ {
if (join_tab[i].on_expr) if (join_tab[i].on_expr)
...@@ -1792,11 +1801,16 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, ...@@ -1792,11 +1801,16 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
join_tab[i].table->map); join_tab[i].table->map);
} }
} }
if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64))
return TRUE;
/* fill keyuse with found key parts */ /* fill keyuse with found key parts */
for (KEY_FIELD *field=key_fields ; field != end ; field++) for (; field != end ; field++)
{
add_key_part(keyuse,field); add_key_part(keyuse,field);
/* Mark that we can optimize LEFT JOIN */
if (field->field->table == join_tab->table &&
field->val->type() == Item::NULL_ITEM &&
!field->field->real_maybe_null())
join_tab->table->reginfo.not_exists_optimize=1;
}
} }
if (thd->lex.select->ftfunc_list.elements) if (thd->lex.select->ftfunc_list.elements)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment