summaryrefslogtreecommitdiff
path: root/sql/table.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/table.cc')
-rw-r--r--sql/table.cc100
1 files changed, 71 insertions, 29 deletions
diff --git a/sql/table.cc b/sql/table.cc
index 00e0b4c6f23..d37e332401d 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -748,13 +748,7 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end,
if (i == 0)
{
ext_key_parts+= (share->use_ext_keys ? first_keyinfo->user_defined_key_parts*(keys-1) : 0);
- /*
- Some keys can be HA_LONG_UNIQUE_HASH , but we do not know at this point ,
- how many ?, but will always be less than or equal to total num of
- keys. Each HA_LONG_UNIQUE_HASH key require one extra key_part in which
- it stored hash. On safe side we will allocate memory for each key.
- */
- n_length=keys * sizeof(KEY) + (ext_key_parts +keys) * sizeof(KEY_PART_INFO);
+ n_length=keys * sizeof(KEY) + (ext_key_parts) * sizeof(KEY_PART_INFO);
if (!(keyinfo= (KEY*) alloc_root(&share->mem_root,
n_length + len)))
return 1;
@@ -779,6 +773,14 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end,
keyinfo->rec_per_key= rec_per_key;
for (j=keyinfo->user_defined_key_parts ; j-- ; key_part++)
{
+ //It will be handled later
+ //Please note we did not allocated extra n key_parts for long unique(a^1,...a^n)
+ //We have allocated just one key_part and that will point to hash
+ if (keyinfo->algorithm == HA_KEY_ALG_LONG_HASH)
+ {
+ key_part++;
+ break;
+ }
if (strpos + (new_frm_ver >= 1 ? 9 : 7) >= frm_image_end)
return 1;
*rec_per_key++=0;
@@ -807,11 +809,8 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end,
}
if (keyinfo->algorithm == HA_KEY_ALG_LONG_HASH)
{
- keyinfo->flags|= HA_LONG_UNIQUE_HASH | HA_NOSAME;
+ keyinfo->flags|= HA_NOSAME;
keyinfo->key_length= 0;
- share->ext_key_parts++;
- // This empty key_part for storing Hash
- key_part++;
}
/*
@@ -1163,7 +1162,7 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table,
for (field_ptr= table->field; *field_ptr; field_ptr++)
{
Field *field= *field_ptr;
- if (field->vcol_info && (length = field->vcol_info->hash_expr.length))
+ if (field->flags & LONG_UNIQUE_HASH_FIELD)
{
expr_str.length(parse_vcol_keyword.length);
expr_str.append((char*)field->vcol_info->hash_expr.str, length);
@@ -1306,6 +1305,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
bool vers_can_native= false;
const uchar *extra2_field_flags= 0;
size_t extra2_field_flags_length= 0;
+ const uchar* key_info_ptr;
MEM_ROOT *old_root= thd->mem_root;
Virtual_column_info **table_check_constraints;
@@ -1614,6 +1614,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
share->set_use_ext_keys_flag(plugin_hton(se_plugin)->flags & HTON_SUPPORTS_EXTENDED_KEYS);
+ key_info_ptr= disk_buff + 6;
if (create_key_infos(disk_buff + 6, frm_image_end, keys, keyinfo,
new_frm_ver, ext_key_parts,
share, len, &first_keyinfo, keynames))
@@ -1707,6 +1708,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
}
else
{
+ key_info_ptr= disk_buff + 6;
if (create_key_infos(disk_buff + 6, frm_image_end, keys, keyinfo,
new_frm_ver, ext_key_parts,
share, len, &first_keyinfo, keynames))
@@ -2133,8 +2135,6 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
uchar flags= *extra2_field_flags++;
if (flags & VERS_OPTIMIZED_UPDATE)
reg_field->flags|= VERS_UPDATE_UNVERSIONED_FLAG;
- if (flags & EXTRA2_LONG_UNIQUE_HASH_FIELD)
- reg_field->flags|= LONG_UNIQUE_HASH_FIELD;
reg_field->invisible= f_visibility(flags);
}
if (reg_field->invisible == INVISIBLE_USER)
@@ -2215,26 +2215,15 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
1. We need set value in hash key_part
2. Set vcol_info in corresponding db_row_hash_ field
*/
- if (keyinfo->flags & HA_LONG_UNIQUE_HASH)
+ if (keyinfo->algorithm & HA_LONG_UNIQUE_HASH)
{
+ /*
DBUG_ASSERT(share->field[hash_field_used_no]->flags & LONG_UNIQUE_HASH_FIELD);
hash_keypart= keyinfo->key_part + keyinfo->user_defined_key_parts;
- /* Last n fields are unique_index_hash fields*/
- hash_keypart->fieldnr= hash_field_used_no + 1;
- hash_keypart->length= HA_HASH_KEY_LENGTH_WITHOUT_NULL;
- hash_keypart->store_length= hash_keypart->length;
- hash_keypart->type= HA_KEYTYPE_ULONGLONG;
- hash_keypart->key_part_flag= 0;
- hash_keypart->key_type= 32834;
- hash_keypart->offset= share->reclength
- - HA_HASH_FIELD_LENGTH*(share->fields - hash_field_used_no);
- hash_fld= share->field[hash_field_used_no];
temp_key_part= keyinfo->key_part;
- Virtual_column_info *v= new (&share->mem_root) Virtual_column_info();
String hash_str;
hash_str.append(ha_hash_str.str,ha_hash_str.length);
hash_str.append(STRING_WITH_LEN("("));
- for (uint j= 0; j < keyinfo->user_defined_key_parts; j++,
temp_key_part++)
{
if (j)
@@ -2258,9 +2247,62 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
hash_str.append(STRING_WITH_LEN(")"));
char * expr_str= (char *)alloc_root(&share->mem_root, hash_str.length()+1);
strncpy(expr_str, hash_str.ptr(), hash_str.length());
- v->hash_expr.str= expr_str;
- v->hash_expr.length= hash_str.length();
+ //v->hash_expr.str= expr_str;
+ //v->hash_expr.length= hash_str.length();
hash_fld->vcol_info= v;
+ */
+ /* Last n fields are unique_index_hash fields*/
+ hash_keypart->length= HA_HASH_KEY_LENGTH_WITHOUT_NULL;
+ hash_keypart->store_length= hash_keypart->length;
+ hash_keypart->type= HA_KEYTYPE_ULONGLONG;
+ hash_keypart->key_part_flag= 0;
+ hash_keypart->key_type= 32834;
+ hash_keypart->offset= share->reclength
+ - HA_HASH_FIELD_LENGTH*(share->fields - hash_field_used_no);
+ hash_keypart->fieldnr= hash_field_used_no + 1;
+ hash_fld= share->field[hash_field_used_no];
+ /*
+ We have to create Item_func_hash for the fields of long unique(a,b..)
+ But since we do not know how many fields , and which fields are there
+ We will look into frm (we have saved key_info_ptr)
+ */
+ if (new_frm_ver > 10)
+ {
+ //Our goal is to get field no of long unique(a1,a2 .....)
+ key_info_ptr+= keys*8;// Why ? answer in create_key_info
+ uint field_no, length;
+ List<Item *> *field_list= new (share->mem_root) List<Item* >;
+ //We havent reseted the user_defined_key_parts yet, reason below
+ // why +9 becuase frm_version > 1
+ for (uint j= 0; j < keyinfo->user_defined_key_parts; j++,
+ key_info_ptr+=9)
+ {
+ field_no= (uint16) (uint2korr(key_info_ptr) & FIELD_NR_MASK);
+ length= (uint) uint2korr(key_info_ptr + 7);
+ Item *l_item;
+ if(!length)
+ l_item= new(share->mem_root)Item_field(thd, share->field[field_no]);
+ else
+ {
+ l_item= new(share->mem_root)Item_func_left(thd,
+ new(share->mem_root)Item_field(thd, share->field[field_no]),
+ new (share->mem_root)Item_int(thd, length));
+
+ }
+ field_list.push_back(l_item, share->mem_root);
+ }
+ Item_func_hash *hash_item= new(share->mem_root)Item_func_hash(thd, field_list);
+ Virtual_column_info *v= new (&share->mem_root) Virtual_column_info();
+ v->expr= hash_item;
+ share->field[field_no]->vcol_info= v;
+ share->field[field_no]->flags|= LONG_UNIQUE_HASH_FIELD;//Currently not used much
+ keyinfo->user_defined_key_parts= 1;
+ keyinfo->usable_key_parts= 1;
+ keyinfo->ext_key_parts= 1;
+
+ }
+ else
+ assert(0);//We cant have long unique in lower frm_versions;
share->virtual_fields++;
hash_field_used_no--;
}