summaryrefslogtreecommitdiff
path: root/sql/table.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2011-12-31 03:36:20 -0800
committerIgor Babaev <igor@askmonty.org>2011-12-31 03:36:20 -0800
commitec2828e4f7f973361a9fd6c06bd913103b5115bd (patch)
tree2aa5cce450b1a5e6017b3427af80b8968d3ff62c /sql/table.cc
parent7714496dc1c72d01fd214cb7737ca4216a982e0f (diff)
parentb6b5f9fabe4866a8753e81e1f80593b645f35d8e (diff)
downloadmariadb-git-ec2828e4f7f973361a9fd6c06bd913103b5115bd.tar.gz
Merged MWL#247 into the latest 5.3.
Diffstat (limited to 'sql/table.cc')
-rw-r--r--sql/table.cc238
1 files changed, 217 insertions, 21 deletions
diff --git a/sql/table.cc b/sql/table.cc
index 7b417b95319..fd1cb4b3ebd 100644
--- a/sql/table.cc
+++ b/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
*****************************************************************************/