Comment 2 for bug 836532

Revision history for this message
Sergey Petrunia (sergefp) wrote :

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.