Zhixuan Zhu wrote:
> Test case:
> Create table test (id int);
> Insert into test values (1);
> Insert into test values (2);
> Select * from test where 2<4 and id > 1;
> Run mysqld in gdb and break after JOIN::optimize (like in JOIN::exec):
> (gdb) p ((Item_cond*)(thd->lex->select_lex.where))->func_name()
> $28 = 0x846df2e "and"
> (gdb) p
> $29 = 0
> The where condition is all removed with just an empty "and" left.
Your mistake is in that you use a wrong casting:
conds= remove_eq_conds(thd, conds, cond_value) ;
conds [=thd->lex->select_lex.where] is simplified into 'id > 1'
This condition is represented by an item of the Item_func type.
This type differs from the Item_cond type that is base class only
for Item_cond_and, Item_cond_or and Item_cond_xor.
> -----Original Message-----
> From: Igor.Babaev@stripped [mailto:Igor.Babaev@stripped]
> Sent: Friday, June 12, 2009 6:50 PM
> To: Zhixuan Zhu
> Subject: Re: Question about optimizer removing const conditions
> Zhixuan Zhu wrote:
>> No condition is actually returned from remove_eq_cond() for that
> statement and that's the weird part. Yes I guess we can do some trick in
> sql_select.cc. But we try not to hack the kernel but stay at the
> interface API level. We are in rnd_init() call for the DML statement and
> try to get the execution plan from the thd structure. For DML we can
> only get [thd->lex->select_lex.where] which carries the filters of the
> where clause. It's been always successful until this one.
>> We did the similar handling for SELECT but get the conditions from
> [thd->lex->select_lex.join]. For DML "join" is always null though.
>> But why after all the optimization the valid condition gets dropped?
> I can't tell you this without any test case.