summaryrefslogtreecommitdiff
path: root/sql/table.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2012-03-02 15:03:20 -0800
committerIgor Babaev <igor@askmonty.org>2012-03-02 15:03:20 -0800
commit8bc5045ea377f39701f421cc7ae00756f79962d2 (patch)
tree751d8bbe4d3844ab9dc16d0c07855e40028cbabc /sql/table.cc
parent8b469eb5151cb1b7da00cee3a7b42c10bd7ff51e (diff)
parent2521ac0c7f2450d588fa1704a6eef785da8812a9 (diff)
downloadmariadb-git-8bc5045ea377f39701f421cc7ae00756f79962d2.tar.gz
Merge MWL #247 from mariadb 5.3 -> mariadb 5.5.
Diffstat (limited to 'sql/table.cc')
-rw-r--r--sql/table.cc259
1 files changed, 236 insertions, 23 deletions
diff --git a/sql/table.cc b/sql/table.cc
index 8f4f034bf2a..016f79607d0 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -753,10 +753,12 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
uchar forminfo[288];
uchar *record;
uchar *disk_buff, *strpos, *null_flags, *null_pos;
- ulong pos, record_offset, *rec_per_key, rec_buff_length;
+ ulong pos, record_offset;
+ ulong *rec_per_key= NULL;
+ ulong rec_buff_length;
handler *handler_file= 0;
KEY *keyinfo;
- KEY_PART_INFO *key_part;
+ KEY_PART_INFO *key_part= NULL;
SQL_CRYPT *crypted=0;
Field **field_ptr, *reg_field;
const char **interval_array;
@@ -767,6 +769,13 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
char *vcol_screen_pos;
uchar *UNINIT_VAR(options);
uchar *extra_segment_buff= 0;
+ 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");
new_field_pack_flag= head[27];
@@ -861,18 +870,37 @@ 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= reinterpret_cast<KEY_PART_INFO*>(keyinfo+keys);
- strpos=disk_buff+6;
+ /*
+ At this point we don't have enough information read from the frm file
+ to get a proper handlerton for the interesting engine in order to get
+ properties of this engine.
+ */
+ /* Currently only InnoDB can use extended keys */
+ share->set_use_ext_keys_flag(legacy_db_type == DB_TYPE_INNODB);
+
+ 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= reinterpret_cast<KEY_PART_INFO*> (keyinfo+keys);
+ }
+ strpos= disk_buff+6;
- if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
- sizeof(ulong)*key_parts)))
- goto err;
+ /*
+ 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.
+
+ When in the future we support others schemes of extending of
+ secondary keys with components of the primary key we'll have
+ to change the type of this flag for an enumeration type.
+ */
for (i=0 ; i < keys ; i++, keyinfo++)
{
@@ -894,6 +922,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= 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++)
@@ -922,6 +976,35 @@ 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;
+ keyinfo->ext_key_flags= keyinfo->flags;
+ keyinfo->ext_key_part_map= 0;
+ 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;
@@ -1522,11 +1605,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(primary_key_name, &share->keynames,
FIND_TYPE_NO_PREFIX) - 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++)
{
@@ -1545,6 +1655,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;
@@ -1556,6 +1711,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;
@@ -1570,7 +1726,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)
@@ -1622,7 +1781,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);
@@ -2261,7 +2421,7 @@ 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;
@@ -2269,7 +2429,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
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 ;
@@ -2280,11 +2440,11 @@ 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];
+ Field *field= key_part->field= outparam->field[key_part->fieldnr - 1];
if (field->key_length() != key_part->length &&
!(field->flags & BLOB_FLAG))
@@ -2298,6 +2458,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;
}
}
@@ -3225,7 +3387,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)
@@ -5737,9 +5899,11 @@ bool TABLE::add_tmp_key(uint key, uint key_parts,
keyinfo= key_info + key;
keyinfo->key_part= key_part_info;
keyinfo->usable_key_parts= keyinfo->key_parts = key_parts;
+ keyinfo->ext_key_parts= keyinfo->key_parts;
keyinfo->key_length=0;
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
keyinfo->flags= HA_GENERATED_KEY;
+ keyinfo->ext_key_flags= keyinfo->flags;
if (unique)
keyinfo->flags|= HA_NOSAME;
sprintf(buf, "key%i", key);
@@ -5808,6 +5972,47 @@ bool 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
+*/
+
+uint 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 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.
@@ -6477,6 +6682,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
*****************************************************************************/