1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Merge in fix for BUG#727667

This commit is contained in:
Sergey Petrunya
2011-03-25 12:47:44 +03:00
11 changed files with 109 additions and 22 deletions

View File

@ -6611,10 +6611,12 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
j->ref.has_record= FALSE;
j->ref.null_rejecting= 0;
j->ref.disable_cache= FALSE;
j->ref.null_ref_part= NO_REF_PART;
keyuse=org_keyuse;
store_key **ref_key= j->ref.key_copy;
uchar *key_buff=j->ref.key_buff, *null_ref_key= 0;
uint null_ref_part= NO_REF_PART;
bool keyuse_uses_no_tables= TRUE;
if (ftkey)
{
@ -6668,7 +6670,10 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
instead of JT_REF_OR_NULL in case if field can't be null
*/
if ((keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL) && maybe_null)
{
null_ref_key= key_buff;
null_ref_part= i;
}
key_buff+= keyinfo->key_part[i].store_length;
}
} /* not ftkey */
@ -6683,6 +6688,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
/* Must read with repeat */
j->type= null_ref_key ? JT_REF_OR_NULL : JT_REF;
j->ref.null_ref_key= null_ref_key;
j->ref.null_ref_part= null_ref_part;
}
else if (keyuse_uses_no_tables)
{
@ -15356,8 +15362,12 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
*****************************************************************************/
/**
Check if "left_item=right_item" equality is guaranteed to be true by use of
[eq]ref access on left_item->field->table.
@return
1 if right_item is used removable reference key on left_item
TRUE if right_item is used removable reference key on left_item
FALSE otherwise
*/
bool test_if_ref(Item *root_cond, Item_field *left_item,Item *right_item)
@ -15370,7 +15380,11 @@ bool test_if_ref(Item *root_cond, Item_field *left_item,Item *right_item)
(!join_tab->first_inner ||
*join_tab->first_inner->on_expr_ref == root_cond))
{
// Cond guards
/*
If ref access uses "Full scan on NULL key" (i.e. it actually alternates
between ref access and full table scan), then no equality can be
guaranteed to be true.
*/
for (uint i = 0; i < join_tab->ref.key_parts; i++)
{
if (join_tab->ref.cond_guards[i])
@ -15378,7 +15392,7 @@ bool test_if_ref(Item *root_cond, Item_field *left_item,Item *right_item)
return FALSE;
}
}
//
Item *ref_item=part_of_refkey(field->table,field);
if (ref_item && ref_item->eq(right_item,1))
{
@ -15680,6 +15694,29 @@ make_cond_after_sjm(Item *root_cond, Item *cond, table_map tables,
}
/*
@brief
Check if
- @table uses "ref"-like access
- it is based on "@field=certain_item" equality
- the equality will be true for any record returned by the access method
and return the certain_item if yes.
@detail
Equality won't necessarily hold if:
- the used index covers only part of the @field.
Suppose, we have a CHAR(5) field and INDEX(field(3)). if you make a lookup
for 'abc', you will get both record with 'abc' and with 'abcde'.
- The type of access is actually ref_or_null, and so @field can be either
a value or NULL.
@return
Item that the field will be equal to
NULL if no such item
*/
static Item *
part_of_refkey(TABLE *table,Field *field)
{
@ -15688,17 +15725,30 @@ part_of_refkey(TABLE *table,Field *field)
return (Item*) 0; // field from outer non-select (UPDATE,...)
uint ref_parts= join_tab->ref.key_parts;
if (ref_parts)
if (ref_parts) /* if it's ref/eq_ref/ref_or_null */
{
uint key= join_tab->ref.key;
KEY *key_info= join_tab->get_keyinfo_by_key_no(key);
KEY_PART_INFO *key_part= key_info->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 join_tab->ref.items[part];
{
if (field->eq(key_part->field))
{
/*
Found the field in the key. Check that
1. ref_or_null doesn't alternate this component between a value and
a NULL
2. index fully covers the key
*/
if (part != join_tab->ref.null_ref_part && // (1)
!(key_part->key_part_flag & HA_PART_KEY_SEG)) // (2)
{
return join_tab->ref.items[part];
}
break;
}
}
}
return (Item*) 0;
}