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:
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.
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_info[ table-> reginfo. join_tab- >ref.key] .key_part;
{
KEY_PART_INFO *key_part=
table-
for (uint part=0 ; part < ref_parts ; part++,key_part++) >eq(key_ part->field) && part->key_ part_flag & (HA_PART_KEY_SEG | HA_NULL_PART))) reginfo. join_tab- >ref.items[ part];
if (field-
!(key_
return table->
}
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.