mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merged MWL#247 into the latest 5.3.
This commit is contained in:
238
sql/table.cc
238
sql/table.cc
@ -707,6 +707,13 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
||||
enum legacy_db_type legacy_db_type;
|
||||
my_bitmap_map *bitmaps;
|
||||
bool null_bits_are_used;
|
||||
KEY first_keyinfo;
|
||||
uint len;
|
||||
KEY_PART_INFO *first_key_part= NULL;
|
||||
uint ext_key_parts= 0;
|
||||
uint first_key_parts= 0;
|
||||
keyinfo= &first_keyinfo;
|
||||
share->ext_key_parts= 0;
|
||||
DBUG_ENTER("open_binary_frm");
|
||||
|
||||
LINT_INIT(options);
|
||||
@ -800,18 +807,28 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
||||
share->keys_for_keyread.init(0);
|
||||
share->keys_in_use.init(keys);
|
||||
|
||||
n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
|
||||
if (!(keyinfo = (KEY*) alloc_root(&share->mem_root,
|
||||
n_length + uint2korr(disk_buff+4))))
|
||||
goto err; /* purecov: inspected */
|
||||
bzero((char*) keyinfo,n_length);
|
||||
share->key_info= keyinfo;
|
||||
key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys);
|
||||
strpos=disk_buff+6;
|
||||
/* Currently only InnoDB can use extended keys */
|
||||
share->set_use_ext_keys_flag(legacy_db_type == DB_TYPE_INNODB);
|
||||
|
||||
if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
|
||||
sizeof(ulong)*key_parts)))
|
||||
goto err;
|
||||
len= (uint) uint2korr(disk_buff+4);
|
||||
if (!keys)
|
||||
{
|
||||
if (!(keyinfo = (KEY*) alloc_root(&share->mem_root, len)))
|
||||
goto err;
|
||||
bzero((char*) keyinfo, len);
|
||||
key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys);
|
||||
}
|
||||
strpos= disk_buff+6;
|
||||
|
||||
/*
|
||||
If share->use_ext_keys is set to TRUE we assume that any key
|
||||
can be extended by the components of the primary key whose
|
||||
definition is read first from the frm file.
|
||||
For each key only those fields of the assumed primary key are
|
||||
added that are not included in the proper key definition.
|
||||
If after all it turns out that there is no primary key the
|
||||
added components are removed from each key.
|
||||
*/
|
||||
|
||||
for (i=0 ; i < keys ; i++, keyinfo++)
|
||||
{
|
||||
@ -833,6 +850,32 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
||||
strpos+=4;
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
ext_key_parts= key_parts +
|
||||
(share->use_ext_keys ? first_keyinfo.key_parts*(keys-1) : 0);
|
||||
|
||||
n_length=keys*sizeof(KEY)+ext_key_parts*sizeof(KEY_PART_INFO);
|
||||
if (!(keyinfo= (KEY*) alloc_root(&share->mem_root,
|
||||
n_length + len)))
|
||||
goto err; /* purecov: inspected */
|
||||
bzero((char*) keyinfo,n_length);
|
||||
share->key_info= keyinfo;
|
||||
key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys);
|
||||
|
||||
if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
|
||||
sizeof(ulong)*ext_key_parts)))
|
||||
goto err;
|
||||
first_key_part= key_part;
|
||||
first_key_parts= first_keyinfo.key_parts;
|
||||
keyinfo->flags= first_keyinfo.flags;
|
||||
keyinfo->key_length= first_keyinfo.key_length;
|
||||
keyinfo->key_parts= first_keyinfo.key_parts;
|
||||
keyinfo->algorithm= first_keyinfo.algorithm;
|
||||
if (new_frm_ver >= 3)
|
||||
keyinfo->block_size= first_keyinfo.block_size;
|
||||
}
|
||||
|
||||
keyinfo->key_part= key_part;
|
||||
keyinfo->rec_per_key= rec_per_key;
|
||||
for (j=keyinfo->key_parts ; j-- ; key_part++)
|
||||
@ -861,6 +904,31 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
||||
}
|
||||
key_part->store_length=key_part->length;
|
||||
}
|
||||
keyinfo->ext_key_parts= keyinfo->key_parts;
|
||||
if (share->use_ext_keys && i)
|
||||
{
|
||||
keyinfo->ext_key_flags= keyinfo->flags | HA_NOSAME;
|
||||
keyinfo->ext_key_part_map= 0;
|
||||
for (j= 0; j<first_key_parts && keyinfo->ext_key_parts<MAX_REF_PARTS; j++)
|
||||
{
|
||||
uint key_parts= keyinfo->key_parts;
|
||||
KEY_PART_INFO* curr_key_part= keyinfo->key_part;
|
||||
KEY_PART_INFO* curr_key_part_end= curr_key_part+key_parts;
|
||||
for ( ; curr_key_part < curr_key_part_end; curr_key_part++)
|
||||
{
|
||||
if (curr_key_part->fieldnr == first_key_part[j].fieldnr)
|
||||
break;
|
||||
}
|
||||
if (curr_key_part == curr_key_part_end)
|
||||
{
|
||||
*key_part++= first_key_part[j];
|
||||
*rec_per_key++= 0;
|
||||
keyinfo->ext_key_parts++;
|
||||
keyinfo->ext_key_part_map|= 1 << j;
|
||||
}
|
||||
}
|
||||
}
|
||||
share->ext_key_parts+= keyinfo->ext_key_parts;
|
||||
}
|
||||
keynames=(char*) key_part;
|
||||
strpos+= (strmov(keynames, (char *) strpos) - keynames)+1;
|
||||
@ -1423,11 +1491,38 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
||||
/* Fix key->name and key_part->field */
|
||||
if (key_parts)
|
||||
{
|
||||
uint add_first_key_parts= 0;
|
||||
uint primary_key=(uint) (find_type((char*) primary_key_name,
|
||||
&share->keynames, 3) - 1);
|
||||
longlong ha_option= handler_file->ha_table_flags();
|
||||
keyinfo= share->key_info;
|
||||
key_part= keyinfo->key_part;
|
||||
|
||||
if (share->use_ext_keys)
|
||||
{
|
||||
if (primary_key >= MAX_KEY)
|
||||
{
|
||||
add_first_key_parts= 0;
|
||||
share->set_use_ext_keys_flag(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
add_first_key_parts= first_key_parts;
|
||||
/*
|
||||
Do not add components of the primary key starting from
|
||||
the major component defined over the beginning of a field.
|
||||
*/
|
||||
for (i= 0; i < first_key_parts; i++)
|
||||
{
|
||||
uint fieldnr= keyinfo[0].key_part[i].fieldnr;
|
||||
if (share->field[fieldnr-1]->key_length() !=
|
||||
keyinfo[0].key_part[i].length)
|
||||
{
|
||||
add_first_key_parts= i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint key=0 ; key < share->keys ; key++,keyinfo++)
|
||||
{
|
||||
@ -1446,6 +1541,51 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
||||
keyinfo->name_length+1);
|
||||
}
|
||||
|
||||
if (ext_key_parts > share->key_parts && key)
|
||||
{
|
||||
KEY_PART_INFO *new_key_part= (keyinfo-1)->key_part+
|
||||
(keyinfo-1)->ext_key_parts;
|
||||
|
||||
/*
|
||||
Do not extend the key that contains a component
|
||||
defined over the beginning of a field.
|
||||
*/
|
||||
for (i= 0; i < keyinfo->key_parts; i++)
|
||||
{
|
||||
uint fieldnr= keyinfo->key_part[i].fieldnr;
|
||||
if (share->field[fieldnr-1]->key_length() !=
|
||||
keyinfo->key_part[i].length)
|
||||
{
|
||||
add_first_key_parts= 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (add_first_key_parts < keyinfo->ext_key_parts-keyinfo->key_parts)
|
||||
{
|
||||
share->ext_key_parts-= keyinfo->ext_key_parts;
|
||||
key_part_map ext_key_part_map= keyinfo->ext_key_part_map;
|
||||
keyinfo->ext_key_parts= keyinfo->key_parts;
|
||||
keyinfo->ext_key_flags= keyinfo->flags;
|
||||
keyinfo->ext_key_part_map= 0;
|
||||
for (i= 0; i < add_first_key_parts; i++)
|
||||
{
|
||||
if (ext_key_part_map & 1<<i)
|
||||
{
|
||||
keyinfo->ext_key_part_map|= 1<<i;
|
||||
keyinfo->ext_key_parts++;
|
||||
}
|
||||
}
|
||||
share->ext_key_parts+= keyinfo->ext_key_parts;
|
||||
}
|
||||
if (new_key_part != keyinfo->key_part)
|
||||
{
|
||||
memmove(new_key_part, keyinfo->key_part,
|
||||
sizeof(KEY_PART_INFO) * keyinfo->ext_key_parts);
|
||||
keyinfo->key_part= new_key_part;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fix fulltext keys for old .frm files */
|
||||
if (share->key_info[key].flags & HA_FULLTEXT)
|
||||
share->key_info[key].algorithm= HA_KEY_ALG_FULLTEXT;
|
||||
@ -1457,6 +1597,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
||||
declare this as a primary key.
|
||||
*/
|
||||
primary_key=key;
|
||||
key_part= keyinfo->key_part;
|
||||
for (i=0 ; i < keyinfo->key_parts ;i++)
|
||||
{
|
||||
uint fieldnr= key_part[i].fieldnr;
|
||||
@ -1471,7 +1612,10 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0 ; i < keyinfo->key_parts ; key_part++,i++)
|
||||
key_part= keyinfo->key_part;
|
||||
uint key_parts= share->use_ext_keys ? keyinfo->ext_key_parts :
|
||||
keyinfo->key_parts;
|
||||
for (i=0; i < key_parts; key_part++, i++)
|
||||
{
|
||||
Field *field;
|
||||
if (new_field_pack_flag <= 1)
|
||||
@ -1523,7 +1667,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
||||
{
|
||||
share->keys_for_keyread.set_bit(key);
|
||||
field->part_of_key.set_bit(key);
|
||||
field->part_of_key_not_clustered.set_bit(key);
|
||||
if (i < keyinfo->key_parts)
|
||||
field->part_of_key_not_clustered.set_bit(key);
|
||||
}
|
||||
if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
|
||||
field->part_of_sortkey.set_bit(key);
|
||||
@ -2198,15 +2343,15 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
|
||||
KEY *key_info, *key_info_end;
|
||||
KEY_PART_INFO *key_part;
|
||||
uint n_length;
|
||||
n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
|
||||
n_length= share->keys*sizeof(KEY) + share->ext_key_parts*sizeof(KEY_PART_INFO);
|
||||
if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
|
||||
goto err;
|
||||
outparam->key_info= key_info;
|
||||
key_part= (my_reinterpret_cast(KEY_PART_INFO*) (key_info+share->keys));
|
||||
|
||||
|
||||
memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
|
||||
memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
|
||||
share->key_parts));
|
||||
share->ext_key_parts));
|
||||
|
||||
for (key_info_end= key_info + share->keys ;
|
||||
key_info < key_info_end ;
|
||||
@ -2217,9 +2362,9 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
|
||||
key_info->table= outparam;
|
||||
key_info->key_part= key_part;
|
||||
|
||||
for (key_part_end= key_part+ key_info->key_parts ;
|
||||
key_part < key_part_end ;
|
||||
key_part++)
|
||||
key_part_end= key_part + (share->use_ext_keys ? key_info->ext_key_parts :
|
||||
key_info->key_parts) ;
|
||||
for ( ; key_part < key_part_end; key_part++)
|
||||
{
|
||||
Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
|
||||
|
||||
@ -2235,6 +2380,8 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
|
||||
field->field_length= key_part->length;
|
||||
}
|
||||
}
|
||||
if (!share->use_ext_keys)
|
||||
key_part+= key_info->ext_key_parts-key_info->key_parts;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3140,7 +3287,7 @@ uint calculate_key_len(TABLE *table, uint key, const uchar *buf,
|
||||
|
||||
KEY *key_info= table->s->key_info+key;
|
||||
KEY_PART_INFO *key_part= key_info->key_part;
|
||||
KEY_PART_INFO *end_key_part= key_part + key_info->key_parts;
|
||||
KEY_PART_INFO *end_key_part= key_part + table->actual_n_key_parts(key_info);
|
||||
uint length= 0;
|
||||
|
||||
while (key_part < end_key_part && keypart_map)
|
||||
@ -5419,6 +5566,47 @@ bool st_table::is_filled_at_execution()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Get actual number of key components
|
||||
|
||||
@param keyinfo
|
||||
|
||||
@details
|
||||
The function calculates actual number of key components, possibly including
|
||||
components of extended keys, taken into consideration by the optimizer for the
|
||||
key described by the parameter keyinfo.
|
||||
|
||||
@return number of considered key components
|
||||
*/
|
||||
|
||||
inline uint st_table::actual_n_key_parts(KEY *keyinfo)
|
||||
{
|
||||
return optimizer_flag(in_use, OPTIMIZER_SWITCH_EXTENDED_KEYS) ?
|
||||
keyinfo->ext_key_parts : keyinfo->key_parts;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Get actual key flags for a table key
|
||||
|
||||
@param keyinfo
|
||||
|
||||
@details
|
||||
The function finds out actual key flags taken into consideration by the
|
||||
optimizer for the key described by the parameter keyinfo.
|
||||
|
||||
@return actual key flags
|
||||
*/
|
||||
|
||||
ulong st_table::actual_key_flags(KEY *keyinfo)
|
||||
{
|
||||
return optimizer_flag(in_use, OPTIMIZER_SWITCH_EXTENDED_KEYS) ?
|
||||
keyinfo->ext_key_flags : keyinfo->flags;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Cleanup this table for re-execution.
|
||||
|
||||
@ -6014,6 +6202,14 @@ bool TABLE_LIST::change_refs_to_fields()
|
||||
}
|
||||
|
||||
|
||||
uint TABLE_SHARE::actual_n_key_parts(THD *thd)
|
||||
{
|
||||
return use_ext_keys &&
|
||||
optimizer_flag(thd, OPTIMIZER_SWITCH_EXTENDED_KEYS) ?
|
||||
ext_key_parts : key_parts;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Instansiate templates
|
||||
*****************************************************************************/
|
||||
|
Reference in New Issue
Block a user