diff options
author | Sachin <sachin.setiya@mariadb.com> | 2018-11-27 18:04:39 +0530 |
---|---|---|
committer | Sachin <sachin.setiya@mariadb.com> | 2018-12-31 20:35:37 +0530 |
commit | 05f77a8ec98daab1221a4967cf04c434ba5129eb (patch) | |
tree | 62967e0f360f72fc57f4d32eb09fc440f4bf4e4f | |
parent | 83b63f622020d248edec8c4fc63f63402c405fd8 (diff) | |
download | mariadb-git-05f77a8ec98daab1221a4967cf04c434ba5129eb.tar.gz |
Architectre change
-rw-r--r-- | mysql-test/main/long_unique.result | 8 | ||||
-rw-r--r-- | mysql-test/main/long_unique.test | 2 | ||||
-rw-r--r-- | sql/field.h | 11 | ||||
-rw-r--r-- | sql/sql_table.cc | 2 | ||||
-rw-r--r-- | sql/table.cc | 100 | ||||
-rw-r--r-- | sql/unireg.cc | 15 | ||||
-rw-r--r-- | sql/unireg.h | 1 |
7 files changed, 87 insertions, 52 deletions
diff --git a/mysql-test/main/long_unique.result b/mysql-test/main/long_unique.result index 9fbe63d4e7a..c8b44b35cb7 100644 --- a/mysql-test/main/long_unique.result +++ b/mysql-test/main/long_unique.result @@ -367,7 +367,7 @@ Key Start Len Index Type 1 3063 8 multip. ulonglong NULL 2 3055 8 multip. ulonglong NULL 3 3047 8 multip. ulonglong NULL -4 3039 8 multip. ulonglong prefix NULL +4 3039 8 multip. ulonglong NULL select * from information_schema.columns where table_schema = 'test' and table_name = 't1'; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT IS_GENERATED GENERATION_EXPRESSION def test t1 a 1 NULL YES blob 65535 65535 NULL NULL NULL NULL NULL blob UNI select,insert,update,references NEVER NULL @@ -721,9 +721,9 @@ Recordlength: 5092 table description: Key Start Len Index Type -1 5081 8 multip. ulonglong prefix NULL -2 5073 8 multip. ulonglong prefix NULL -3 5065 8 multip. ulonglong prefix NULL +1 5081 8 multip. ulonglong NULL +2 5073 8 multip. ulonglong NULL +3 5065 8 multip. ulonglong NULL 4 5057 8 multip. ulonglong NULL select * from information_schema.columns where table_schema = 'test' and table_name = 't1'; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT IS_GENERATED GENERATION_EXPRESSION diff --git a/mysql-test/main/long_unique.test b/mysql-test/main/long_unique.test index c87019492a7..65fcdfcc9e4 100644 --- a/mysql-test/main/long_unique.test +++ b/mysql-test/main/long_unique.test @@ -198,7 +198,7 @@ show create table t1; alter table t1 add column db_row_hash_7 int, add column db_row_hash_5 int , add column db_row_hash_4 int ; alter table t1 drop column db_row_hash_7,drop column db_row_hash_3, drop column db_row_hash_4; desc t1; ---echo #this show now break anything; +--echo #this should not break anything; --error ER_DUP_ENTRY insert into t1 values(1,2,3,4,5,6,23,5,6); --echo #this should also drop the unique index; diff --git a/sql/field.h b/sql/field.h index bd7cdd1e60d..09c642f4137 100644 --- a/sql/field.h +++ b/sql/field.h @@ -543,7 +543,6 @@ public: LEX_CSTRING name; /* Name of constraint */ /* see VCOL_* (VCOL_FIELD_REF, ...) */ uint flags; - LEX_CSTRING hash_expr; Virtual_column_info() : vcol_type((enum_vcol_info_type)VCOL_TYPE_NONE), @@ -553,14 +552,8 @@ public: { name.str= NULL; name.length= 0; - hash_expr.str= NULL; - hash_expr.length= 0; }; - ~Virtual_column_info() - { - if (!hash_expr.length) - my_free((void *)hash_expr.str); - } + ~Virtual_column_info(); enum_vcol_info_type get_vcol_type() const { return vcol_type; @@ -1090,7 +1083,7 @@ public: virtual int cmp(const uchar *,const uchar *)=0; virtual int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0U) { return memcmp(a,b,pack_length()); } - virtual int cmp_offset(long row_offset) + virtual int cmp_offset(my_ptrdiff_t row_offset) { return cmp(ptr,ptr+row_offset); } virtual int cmp_binary_offset(uint row_offset) { return cmp_binary(ptr, ptr+row_offset); }; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a97db42886c..888e07c24fe 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4172,7 +4172,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, (key_part_length >= KEY_DEFAULT_PACK_LENGTH && (sql_field->real_field_type() == MYSQL_TYPE_STRING || sql_field->real_field_type() == MYSQL_TYPE_VARCHAR || - sql_field->pack_flag & FIELDFLAG_BLOB))) + sql_field->pack_flag & FIELDFLAG_BLOB))&& !is_hash_field_added) { if ((column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) || sql_field->real_field_type() == MYSQL_TYPE_VARCHAR) 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--; } diff --git a/sql/unireg.cc b/sql/unireg.cc index 44e24554691..95e4b7bf713 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -39,7 +39,7 @@ /* threshold for safe_alloca */ #define ALLOCA_THRESHOLD 2048 -static uint pack_keys(uchar *,uint, KEY *, ulong); +static uint pack_keys(uchar *,uint, KEY *, ulong, uint); static bool pack_header(THD *, uchar *, List<Create_field> &, HA_CREATE_INFO *, ulong, handler *); static bool pack_vcols(String *, List<Create_field> &, List<Virtual_column_info> *); @@ -101,8 +101,6 @@ static uchar *extra2_write_field_properties(uchar *pos, uchar flags= cf->invisible; if (cf->flags & VERS_UPDATE_UNVERSIONED_FLAG) flags|= VERS_OPTIMIZED_UPDATE; - if (cf->flags & LONG_UNIQUE_HASH_FIELD) - flags|= EXTRA2_LONG_UNIQUE_HASH_FIELD; *pos++= flags; } return pos; @@ -295,7 +293,10 @@ LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING *table, extra2_size+= 1 + (create_fields.elements > 255 ? 3 : 1) + create_fields.elements; } - + uint e_unique_hash_extra_parts= 0; + for (i= 0; i < keys; i++) + if (key_info[i].algorithm == HA_KEY_ALG_LONG_HASH) + e_unique_hash_extra_parts+= key_info[i].keyparts - 1; key_buff_length= uint4korr(fileinfo+47); frm.length= FRM_HEADER_SIZE; // fileinfo; @@ -363,12 +364,11 @@ LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING *table, if (has_extra2_field_flags_) pos= extra2_write_field_properties(pos, create_fields); - int4store(pos, filepos); // end of the extra2 segment pos+= 4; DBUG_ASSERT(pos == frm_ptr + uint2korr(fileinfo+6)); - key_info_length= pack_keys(pos, keys, key_info, data_offset); + key_info_length= pack_keys(pos, keys, key_info, data_offset, e_unique_hash_extra_parts); if (key_info_length > UINT_MAX16) { my_printf_error(ER_CANT_CREATE_TABLE, @@ -530,7 +530,7 @@ err_frm: /* Pack keyinfo and keynames to keybuff for save in form-file. */ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo, - ulong data_offset) + ulong data_offset, uint e_unique_hash_extra_parts) { uint key_parts,length; uchar *pos, *keyname_pos; @@ -592,6 +592,7 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo, } } + key_parts-= e_unique_hash_extra_parts; if (key_count > 127 || key_parts > 127) { keybuff[0]= (key_count & 0x7f) | 0x80; diff --git a/sql/unireg.h b/sql/unireg.h index 1e360d61e36..18b95ea3f6f 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -180,7 +180,6 @@ enum extra2_frm_value_type { enum extra2_field_flags { VERS_OPTIMIZED_UPDATE= 1 << INVISIBLE_MAX_BITS, - EXTRA2_LONG_UNIQUE_HASH_FIELD= 1 << HASH_FIELD_MASK_SHIFT }; int rea_create_table(THD *thd, LEX_CUSTRING *frm, |