The reason for this is that when we were doing substitute-for-best-equal field operation here:
#0 substitute_for_best_equal_field (cond=0xb1fad58, cond_equal=0xb1fadf4, table_join_idx=0xb1f9f10) at sql_select.cc:11412
#1 0x08370cda in JOIN::optimize (this=0xb201db8) at sql_select.cc:1193
#2 0x081b96cb in st_select_lex::optimize_unflattened_subqueries (this=0xb184938) at sql_lex.cc:3126
#3 0x08421fdb in JOIN::optimize_unflattened_subqueries (this=0xb1fbe40) at opt_subselect.cc:4324
#4 0x08371cf2 in JOIN::optimize (this=0xb1fbe40) at sql_select.cc:1504
#5 0x08373a40 in mysql_select (...) at sql_select.cc:2887
and 'cond' was an Item_cond_and with the list of these four arguments:
(gdb) p $i1
$188 = (Item_cond_and *) 0xb1f93c0
(gdb) p $i2
$189 = (Item_func_trig_cond *) 0xb1fa930
(gdb) p $i3
$190 = (Item_equal *) 0xb1f95d0
(gdb) p $i4
$191 = (Item_equal *) 0xb1f96f0
the two last two elements of the list:
(gdb) p ((Item*)cond)->list->first->next->next
$299 = (list_node *) 0xb1f96e8
(gdb) p ((Item*)cond)->list->first->next->next->next
$300 = (list_node *) 0xb1f9808
WERE THE SAME AS JOIN's cond_equal:
(gdb) p this->cond_equal_
$303 = (COND_EQUAL *) 0xb1f945c
(gdb) p this->cond_equal_->current_level->first
$304 = (list_node *) 0xb1f96e8
(gdb) p this->cond_equal_->current_level->first->next
$305 = (list_node *) 0xb1f9808
That is, List<Item> and List<Item_equal> somehow ended up sharing the tail of the list. substitute_for_best_equal_field() eventually executed this part of its code:
/*
This works OK with PS/SP re-execution as changes are made to
the arguments of AND/OR items only
*/
if (new_item != item) li.replace(new_item);
which is ok for the List<Item> but made List<Item_equal> JOIN::cond_equal_ invalid.
The reason for this is that when we were doing substitute- for-best- equal field operation here:
#0 substitute_ for_best_ equal_field (cond=0xb1fad58, cond_equal= 0xb1fadf4, table_join_ idx=0xb1f9f10) at sql_select.cc:11412 lex::optimize_ unflattened_ subqueries (this=0xb184938) at sql_lex.cc:3126 unflattened_ subqueries (this=0xb1fbe40) at opt_subselect. cc:4324
#1 0x08370cda in JOIN::optimize (this=0xb201db8) at sql_select.cc:1193
#2 0x081b96cb in st_select_
#3 0x08421fdb in JOIN::optimize_
#4 0x08371cf2 in JOIN::optimize (this=0xb1fbe40) at sql_select.cc:1504
#5 0x08373a40 in mysql_select (...) at sql_select.cc:2887
and 'cond' was an Item_cond_and with the list of these four arguments:
(gdb) p $i1 trig_cond *) 0xb1fa930
$188 = (Item_cond_and *) 0xb1f93c0
(gdb) p $i2
$189 = (Item_func_
(gdb) p $i3
$190 = (Item_equal *) 0xb1f95d0
(gdb) p $i4
$191 = (Item_equal *) 0xb1f96f0
the two last two elements of the list:
(gdb) p ((Item* )cond)- >list-> first-> next->next
$299 = (list_node *) 0xb1f96e8
(gdb) p ((Item* )cond)- >list-> first-> next->next- >next
$300 = (list_node *) 0xb1f9808
WERE THE SAME AS JOIN's cond_equal:
(gdb) p this->cond_equal_
$303 = (COND_EQUAL *) 0xb1f945c
(gdb) p this->cond_ equal_- >current_ level-> first
$304 = (list_node *) 0xb1f96e8
(gdb) p this->cond_ equal_- >current_ level-> first-> next
$305 = (list_node *) 0xb1f9808
That is, List<Item> and List<Item_equal> somehow ended up sharing the tail of the list. substitute_ for_best_ equal_field( ) eventually executed this part of its code:
/*
li.replace( new_item) ;
This works OK with PS/SP re-execution as changes are made to
the arguments of AND/OR items only
*/
if (new_item != item)
which is ok for the List<Item> but made List<Item_equal> JOIN::cond_equal_ invalid.