Comment 4 for bug 727667

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

So, currently test_if_ref()/part_of_refkey() assume that "f3=83" is universally true. This bug was introduced when backporting DS-MRR/ICP/other-related-code into 5.3.

How it worked before the backport
-------------------------------------------------
Before the backport, the part_of_refkey() looked like this:

...
  {
    KEY_PART_INFO *key_part=
      table->key_info[table->reginfo.join_tab->ref.key].key_part;

    for (uint part=0 ; part < ref_parts ; part++,key_part++)
      if (field->eq(key_part->field) &&
   !(key_part->key_part_flag & (HA_PART_KEY_SEG | HA_NULL_PART)))
 return table->reginfo.join_tab->ref.items[part];
  }

The important part here: we check HA_NULL_PART bit. If it is present, equality will not be removed. It serves two purposes:
P1. Handle the case where we get NULL value from ref.items[part], make a lookup in the table, and get a matching record with NULLs. The equality will be checked and will filter the record out.

P2. Also cover ref_or_null access method. When ref_or_null is used, table access can return either the lookup value or a record with NULLs, so the equality is not universally guaranteed. ref_or_null is only employed for NULL-able columns (no point to look for NULLs in non-NULLable column), so if we keep the equality for NULLable columns, we cut off ref_or_null, too.