summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSachin <sachin.setiya@mariadb.com>2018-11-27 18:04:39 +0530
committerSachin <sachin.setiya@mariadb.com>2018-12-31 20:35:37 +0530
commit05f77a8ec98daab1221a4967cf04c434ba5129eb (patch)
tree62967e0f360f72fc57f4d32eb09fc440f4bf4e4f
parent83b63f622020d248edec8c4fc63f63402c405fd8 (diff)
downloadmariadb-git-05f77a8ec98daab1221a4967cf04c434ba5129eb.tar.gz
Architectre change
-rw-r--r--mysql-test/main/long_unique.result8
-rw-r--r--mysql-test/main/long_unique.test2
-rw-r--r--sql/field.h11
-rw-r--r--sql/sql_table.cc2
-rw-r--r--sql/table.cc100
-rw-r--r--sql/unireg.cc15
-rw-r--r--sql/unireg.h1
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,