maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #09445
Re: Unique Index for blob
Sorry wrong extension
Regards
sachin
On Mon, Mar 28, 2016 at 9:09 PM, Sachin Setia <sachinsetia1001@xxxxxxxxx>
wrote:
> Hello Devlopers
> Hi this is sachin. I applied for gsoc 2016(applied by name sachin setiya)
> My topic was unique index for blob(MyISAM)
> But i already completed some part of it .it is working for blobs varchar
> for definitions like
> create table tbl(abc varchar(2000) , xyz blob ,unique(abc,xyz));
> I have corrected the table2myisam function .
> For documentation you can refer to my gsoc proposal
> If am doing wrong please let me know.
> I am attaching the patch file
> TODO
> Second thing which i need to do is
> to tweak check_definition function to correctly check for definition
> currently I am commenting the function code
> Regards
> sachin
>
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index dfce503..eda9dd6 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -3874,11 +3874,11 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
if (f_is_geom(sql_field->pack_flag) && sql_field->geom_type ==
Field::GEOM_POINT)
column->length= MAX_LEN_GEOM_POINT_FIELD;
- if (!column->length)
- {
- my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name.str);
- DBUG_RETURN(TRUE);
- }
+// if (!column->length) //work
+// {
+// my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name.str);
+// DBUG_RETURN(TRUE);
+// }
}
#ifdef HAVE_SPATIAL
if (key->type == Key::SPATIAL)
@@ -3999,7 +3999,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
if (key_part_length > file->max_key_part_length() &&
key->type != Key::FULLTEXT)
{
- key_part_length= file->max_key_part_length();
+ //key_part_length= file->max_key_part_length(); //work
if (key->type == Key::MULTIPLE)
{
/* not a critical problem */
@@ -4011,8 +4011,13 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
}
else
{
- my_error(ER_TOO_LONG_KEY, MYF(0), key_part_length);
- DBUG_RETURN(TRUE);
+ if(sql_field->sql_type==MYSQL_TYPE_VARCHAR){
+ //its ok we are going to use hash index
+ }else{
+ key_part_length= file->max_key_part_length();
+ my_error(ER_TOO_LONG_KEY, MYF(0), key_part_length);
+ DBUG_RETURN(TRUE);
+ }
}
}
key_part_info->length= (uint16) key_part_length;
@@ -4070,10 +4075,13 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
if (key->type == Key::UNIQUE && !(key_info->flags & HA_NULL_PART_KEY))
unique_key=1;
key_info->key_length=(uint16) key_length;
- if (key_length > max_key_length && key->type != Key::FULLTEXT)
+ if (key_length > max_key_length && key->type != Key::FULLTEXT
+ &&key->type!=Key::UNIQUE) //one more thing key should be varchar
+ //i frankly do not know how to check it may be FIELDFLAG_MAYBE_NULL
+ //will work //work
{
- my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
- DBUG_RETURN(TRUE);
+// my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
+// DBUG_RETURN(TRUE);
}
if (validate_comment_length(thd, &key->key_create_info.comment,
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 4284e22..6d6ebcb 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -402,6 +402,362 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out,
DBUG_RETURN(0);
}
+//work
+
+ typedef struct
+{
+ uint uniques; //total number of uniques
+ /*
+ * unique_keys contain array of chars where 1 means key is unique
+ * with zero length
+ * */
+ char * unique_keys;
+} uniques_keys_arr;
+/*
+ * Find unique keys in keys array
+ *
+ * */
+ //working
+static uniques_keys_arr *
+mysql_find_unique_keys(KEY *keys,uint number_of_keys){
+ //DBUG_ENTER("mysql_find_unique_keys");
+ uniques_keys_arr * u_arr = (uniques_keys_arr *)my_malloc(sizeof(uniques_keys_arr),MYF(MY_WME));
+
+ if(!u_arr)
+ {
+ return NULL;
+ }
+
+ u_arr->uniques=0;
+ u_arr->unique_keys = (char *)my_malloc(sizeof(char)*number_of_keys,MYF(MY_WME));
+ char * temp = u_arr->unique_keys;
+
+ if(!u_arr->unique_keys)
+ {
+ return NULL;
+ }
+
+ for(int i=0;i<number_of_keys;i++)
+ {
+ *temp=0;
+ for(int j=0;j<keys[i].user_defined_key_parts;j++)
+ {
+ if(!keys[i].key_part[j].length ||keys[i].key_part[j].length>1000) //we need
+ //better logic
+ {
+ *temp=1;
+ u_arr->uniques++;
+ goto get_out;
+ }
+ }
+ get_out:{}
+ temp++;
+ }
+ return u_arr;
+}
+/*
+ Convert TABLE object to MyISAM key and column definition
+
+ SYNOPSIS
+ table2myisam_with_uniquedef()
+ table_arg in TABLE object.
+ keydef_out out MyISAM key definition.
+ uniquedef_out out MyISAM unique key defination
+ recinfo_out out MyISAM column definition.
+ records_out out Number of fields.
+
+ DESCRIPTION
+ This function will allocate and initialize MyISAM key and column
+ definition for further use in mi_create or for a check for underlying
+ table conformance in merge engine.
+
+ The caller needs to free *recinfo_out after use. Since *recinfo_out
+ and *keydef_out are allocated with a my_multi_malloc, *keydef_out
+ is freed automatically when *recinfo_out is freed.
+
+ RETURN VALUE
+ 0 OK
+ !0 error code
+*/
+
+int table2myisam_with_uniquedef(TABLE *table_arg, MI_KEYDEF **keydef_out,
+ MI_UNIQUEDEF **uniquedef_out,
+ MI_COLUMNDEF **recinfo_out, uint *records_out)
+{
+ uint i, j, recpos, minpos, fieldpos, temp_length, length;
+ enum ha_base_keytype type= HA_KEYTYPE_BINARY;
+ uchar *record;
+ KEY *pos;
+ MI_KEYDEF *keydef;
+ MI_UNIQUEDEF * uniquedef;
+ MI_COLUMNDEF *recinfo, *recinfo_pos;
+ HA_KEYSEG *keyseg;
+ TABLE_SHARE *share= table_arg->s;
+ uint options= share->db_options_in_use;
+ DBUG_ENTER("table2myisam");
+ //now correct memory allocation
+ uniques_keys_arr * u_key_arr = mysql_find_unique_keys(table_arg->key_info,share->keys);
+ char * t_unique_keys = u_key_arr->unique_keys;
+ share->uniques = u_key_arr->uniques;
+ share->keys-=u_key_arr->uniques;
+ if (!(my_multi_malloc(MYF(MY_WME),
+ recinfo_out, (share->fields * 2 + 2+share->uniques) * sizeof(MI_COLUMNDEF),
+ keydef_out, share->keys * sizeof(MI_KEYDEF),
+ uniquedef_out,
+ (share->uniques) * sizeof(MI_UNIQUEDEF),
+ &keyseg,
+ (share->key_parts + share->keys+share->uniques) * sizeof(HA_KEYSEG),
+ NullS)))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
+ keydef= *keydef_out;
+ recinfo= *recinfo_out;
+ uniquedef=*uniquedef_out;
+ pos= table_arg->key_info;
+ int temp_uniquedef_pointer=0;
+ int temp_keydef_pointer =0;
+ for (i= 0; i < share->keys+share->uniques; i++, pos++)
+ {
+ if(!(*t_unique_keys)){
+ keydef[temp_keydef_pointer].flag= ((uint16) pos->flags & (HA_NOSAME | HA_FULLTEXT | HA_SPATIAL));
+ keydef[temp_keydef_pointer].key_alg= pos->algorithm == HA_KEY_ALG_UNDEF ?
+ (pos->flags & HA_SPATIAL ? HA_KEY_ALG_RTREE : HA_KEY_ALG_BTREE) :
+ pos->algorithm;
+ keydef[temp_keydef_pointer].block_length= pos->block_size;
+ keydef[temp_keydef_pointer].seg= keyseg;
+ keydef[temp_keydef_pointer].keysegs= pos->user_defined_key_parts;
+
+ for (j= 0; j < pos->user_defined_key_parts; j++)
+ {
+ Field *field= pos->key_part[j].field;
+ type= field->key_type();
+ keydef[temp_keydef_pointer].seg[j].flag= pos->key_part[j].key_part_flag;
+
+ if (options & HA_OPTION_PACK_KEYS ||
+ (pos->flags & (HA_PACK_KEY | HA_BINARY_PACK_KEY |
+ HA_SPACE_PACK_USED)))
+ {
+ if (pos->key_part[j].length > 8 &&
+ (type == HA_KEYTYPE_TEXT ||
+ type == HA_KEYTYPE_NUM ||
+ (type == HA_KEYTYPE_BINARY && !field->zero_pack())))
+ {
+ /* No blobs here */
+ if (j == 0)
+ keydef[temp_keydef_pointer].flag|= HA_PACK_KEY;
+ if (!(field->flags & ZEROFILL_FLAG) &&
+ (field->type() == MYSQL_TYPE_STRING ||
+ field->type() == MYSQL_TYPE_VAR_STRING ||
+ ((int) (pos->key_part[j].length - field->decimals())) >= 4))
+ keydef[temp_keydef_pointer].seg[j].flag|= HA_SPACE_PACK;
+ }
+ else if (j == 0 && (!(pos->flags & HA_NOSAME) || pos->key_length > 16))
+ keydef[temp_keydef_pointer].flag|= HA_BINARY_PACK_KEY;
+ }
+ keydef[temp_keydef_pointer].seg[j].type= (int) type;
+ keydef[temp_keydef_pointer].seg[j].start= pos->key_part[j].offset;
+ keydef[temp_keydef_pointer].seg[j].length= pos->key_part[j].length;
+ keydef[temp_keydef_pointer].seg[j].bit_start= keydef[temp_keydef_pointer].seg[j].bit_end=
+ keydef[temp_keydef_pointer].seg[j].bit_length= 0;
+ keydef[temp_keydef_pointer].seg[j].bit_pos= 0;
+ keydef[temp_keydef_pointer].seg[j].language= field->charset_for_protocol()->number;
+
+ if (field->null_ptr)
+ {
+ keydef[temp_keydef_pointer].seg[j].null_bit= field->null_bit;
+ keydef[temp_keydef_pointer].seg[j].null_pos= (uint) (field->null_ptr-
+ (uchar*) table_arg->record[0]);
+ }
+ else
+ {
+ keydef[temp_keydef_pointer].seg[j].null_bit= 0;
+ keydef[temp_keydef_pointer].seg[j].null_pos= 0;
+ }
+ if (field->type() == MYSQL_TYPE_BLOB ||
+ field->type() == MYSQL_TYPE_GEOMETRY)
+ {
+ keydef[temp_keydef_pointer].seg[j].flag|= HA_BLOB_PART;
+ /* save number of bytes used to pack length */
+ keydef[temp_keydef_pointer].seg[j].bit_start= (uint) (field->pack_length() -
+ portable_sizeof_char_ptr);
+ }
+ else if (field->type() == MYSQL_TYPE_BIT)
+ {
+ keydef[temp_keydef_pointer].seg[j].bit_length= ((Field_bit *) field)->bit_len;
+ keydef[temp_keydef_pointer].seg[j].bit_start= ((Field_bit *) field)->bit_ofs;
+ keydef[temp_keydef_pointer].seg[j].bit_pos= (uint) (((Field_bit *) field)->bit_ptr -
+ (uchar*) table_arg->record[0]);
+ }
+ }
+ temp_keydef_pointer++;
+ }
+ else
+ {
+ uniquedef[temp_uniquedef_pointer].seg= keyseg;
+ uniquedef[temp_uniquedef_pointer].null_are_equal = 1; //TODO: what to in this case not sure
+ uniquedef[temp_uniquedef_pointer].keysegs= pos->user_defined_key_parts;
+ for (j= 0; j < pos->user_defined_key_parts; j++)
+ {
+ Field *field= pos->key_part[j].field;
+ type= field->key_type();
+ uniquedef[temp_uniquedef_pointer].seg[j].flag= pos->key_part[j].key_part_flag;
+
+ if (options & HA_OPTION_PACK_KEYS ||
+ (pos->flags & (HA_PACK_KEY | HA_BINARY_PACK_KEY |
+ HA_SPACE_PACK_USED)))
+ {
+ if (pos->key_part[j].length > 8 &&
+ (type == HA_KEYTYPE_TEXT ||
+ type == HA_KEYTYPE_NUM ||
+ (type == HA_KEYTYPE_BINARY && !field->zero_pack())))
+ {
+ /* No blobs here */
+ if (j == 0){}
+ // uniquedef[temp_uniquedef_pointer].flag|= HA_PACK_KEY;
+ if (!(field->flags & ZEROFILL_FLAG) &&
+ (field->type() == MYSQL_TYPE_STRING ||
+ field->type() == MYSQL_TYPE_VAR_STRING ||
+ ((int) (pos->key_part[j].length - field->decimals())) >= 4))
+ uniquedef[temp_uniquedef_pointer].seg[j].flag|= HA_SPACE_PACK;
+ }
+ else if (j == 0 && (!(pos->flags & HA_NOSAME) || pos->key_length > 16)){}
+ // uniquedef[temp_uniquedef_pointer].flag|= HA_BINARY_PACK_KEY;
+ }
+ uniquedef[temp_uniquedef_pointer].seg[j].type= (int) type;
+ uniquedef[temp_uniquedef_pointer].seg[j].start= pos->key_part[j].offset;
+ uniquedef[temp_uniquedef_pointer].seg[j].length= pos->key_part[j].length;
+ uniquedef[temp_uniquedef_pointer].seg[j].bit_start= uniquedef[temp_uniquedef_pointer].seg[j].bit_end=
+ uniquedef[temp_uniquedef_pointer].seg[j].bit_length= 0;
+ uniquedef[temp_uniquedef_pointer].seg[j].bit_pos= 0;
+ uniquedef[temp_uniquedef_pointer].seg[j].language= field->charset_for_protocol()->number;
+
+ if (field->null_ptr)
+ {
+ uniquedef[temp_uniquedef_pointer].seg[j].null_bit= field->null_bit;
+ uniquedef[temp_uniquedef_pointer].seg[j].null_pos= (uint) (field->null_ptr-
+ (uchar*) table_arg->record[0]);
+ }
+ else
+ {
+ uniquedef[temp_uniquedef_pointer].seg[j].null_bit= 0;
+ uniquedef[temp_uniquedef_pointer].seg[j].null_pos= 0;
+ }
+ if (field->type() == MYSQL_TYPE_BLOB ||
+ field->type() == MYSQL_TYPE_GEOMETRY)
+ {
+ uniquedef[temp_uniquedef_pointer].seg[j].flag|= HA_BLOB_PART;
+ /* save number of bytes used to pack length */
+ uniquedef[temp_uniquedef_pointer].seg[j].bit_start= (uint) (field->pack_length() -
+ portable_sizeof_char_ptr);
+ }
+ else if (field->type() == MYSQL_TYPE_BIT)
+ {
+ uniquedef[temp_uniquedef_pointer].seg[j].bit_length= ((Field_bit *) field)->bit_len;
+ uniquedef[temp_uniquedef_pointer].seg[j].bit_start= ((Field_bit *) field)->bit_ofs;
+ uniquedef[temp_uniquedef_pointer].seg[j].bit_pos= (uint) (((Field_bit *) field)->bit_ptr -
+ (uchar*) table_arg->record[0]);
+ }
+ }
+ temp_uniquedef_pointer++;
+ }
+ keyseg+= pos->user_defined_key_parts;
+ t_unique_keys++;
+ }
+ if (table_arg->found_next_number_field)
+ keydef[share->next_number_index].flag|= HA_AUTO_KEY;
+ record= table_arg->record[0];
+ recpos= 0;
+ recinfo_pos= recinfo;
+ while (recpos < (uint) share->stored_rec_length)
+ {
+ Field **field, *found= 0;
+ minpos= share->reclength;
+ length= 0;
+
+ for (field= table_arg->field; *field; field++)
+ {
+ if ((fieldpos= (*field)->offset(record)) >= recpos &&
+ fieldpos <= minpos)
+ {
+ /* skip null fields */
+ if (!(temp_length= (*field)->pack_length_in_rec()))
+ continue; /* Skip null-fields */
+ if (! found || fieldpos < minpos ||
+ (fieldpos == minpos && temp_length < length))
+ {
+ minpos= fieldpos;
+ found= *field;
+ length= temp_length;
+ }
+ }
+ }
+ DBUG_PRINT("loop", ("found: 0x%lx recpos: %d minpos: %d length: %d",
+ (long) found, recpos, minpos, length));
+ if (recpos != minpos)
+ {
+ /* reserve space for null bits */
+ bzero((char*) recinfo_pos, sizeof(*recinfo_pos));
+ recinfo_pos->type= FIELD_NORMAL;
+ recinfo_pos++->length= (uint16) (minpos - recpos);
+ }
+ if (!found)
+ break;
+
+ if (found->flags & BLOB_FLAG)
+ recinfo_pos->type= FIELD_BLOB;
+ else if (found->real_type() == MYSQL_TYPE_TIMESTAMP)
+ {
+ /* pre-MySQL-5.6.4 TIMESTAMP, or MariaDB-5.3+ TIMESTAMP */
+ recinfo_pos->type= FIELD_NORMAL;
+ }
+ else if (found->type() == MYSQL_TYPE_VARCHAR)
+ recinfo_pos->type= FIELD_VARCHAR;
+ else if (!(options & HA_OPTION_PACK_RECORD))
+ recinfo_pos->type= FIELD_NORMAL;
+ else if (found->real_type() == MYSQL_TYPE_TIMESTAMP2)
+ {
+ /*
+ MySQL-5.6.4+ erroneously marks Field_timestampf as FIELD_SKIP_PRESPACE,
+ but only if HA_OPTION_PACK_RECORD is set.
+ */
+ recinfo_pos->type= FIELD_SKIP_PRESPACE;
+ }
+ else if (found->zero_pack())
+ recinfo_pos->type= FIELD_SKIP_ZERO;
+ else
+ recinfo_pos->type= ((length <= 3 ||
+ (found->flags & ZEROFILL_FLAG)) ?
+ FIELD_NORMAL :
+ found->type() == MYSQL_TYPE_STRING ||
+ found->type() == MYSQL_TYPE_VAR_STRING ?
+ FIELD_SKIP_ENDSPACE :
+ FIELD_SKIP_PRESPACE);
+ if (found->null_ptr)
+ {
+ recinfo_pos->null_bit= found->null_bit;
+ recinfo_pos->null_pos= (uint) (found->null_ptr -
+ (uchar*) table_arg->record[0]);
+ }
+ else
+ {
+ recinfo_pos->null_bit= 0;
+ recinfo_pos->null_pos= 0;
+ }
+ (recinfo_pos++)->length= (uint16) length;
+ recpos= minpos + length;
+ DBUG_PRINT("loop", ("length: %d type: %d",
+ recinfo_pos[-1].length,recinfo_pos[-1].type));
+ }
+ //now create records for uniquedefs
+ for(int i=0;i<share->uniques;i++)
+ {
+ (*recinfo_pos).type= FIELD_CHECK;
+ (*recinfo_pos).length= MI_UNIQUE_HASH_LENGTH;
+ recinfo_pos++;
+ }
+ *records_out= (uint) (recinfo_pos - recinfo);
+ DBUG_RETURN(0);
+}
+
/*
Check for underlying table conformance
@@ -456,121 +812,121 @@ int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
uint i, j;
DBUG_ENTER("check_definition");
my_bool mysql_40_compat= table_arg && table_arg->s->frm_version < FRM_VER_TRUE_VARCHAR;
- if ((strict ? t1_keys != t2_keys : t1_keys > t2_keys))
- {
- DBUG_PRINT("error", ("Number of keys differs: t1_keys=%u, t2_keys=%u",
- t1_keys, t2_keys));
- DBUG_RETURN(1);
- }
- if (t1_recs != t2_recs)
- {
- DBUG_PRINT("error", ("Number of recs differs: t1_recs=%u, t2_recs=%u",
- t1_recs, t2_recs));
- DBUG_RETURN(1);
- }
- for (i= 0; i < t1_keys; i++)
- {
- HA_KEYSEG *t1_keysegs= t1_keyinfo[i].seg;
- HA_KEYSEG *t2_keysegs= t2_keyinfo[i].seg;
- if (t1_keyinfo[i].flag & HA_FULLTEXT && t2_keyinfo[i].flag & HA_FULLTEXT)
- continue;
- else if (t1_keyinfo[i].flag & HA_FULLTEXT ||
- t2_keyinfo[i].flag & HA_FULLTEXT)
- {
- DBUG_PRINT("error", ("Key %d has different definition", i));
- DBUG_PRINT("error", ("t1_fulltext= %d, t2_fulltext=%d",
- MY_TEST(t1_keyinfo[i].flag & HA_FULLTEXT),
- MY_TEST(t2_keyinfo[i].flag & HA_FULLTEXT)));
- DBUG_RETURN(1);
- }
- if (t1_keyinfo[i].flag & HA_SPATIAL && t2_keyinfo[i].flag & HA_SPATIAL)
- continue;
- else if (t1_keyinfo[i].flag & HA_SPATIAL ||
- t2_keyinfo[i].flag & HA_SPATIAL)
- {
- DBUG_PRINT("error", ("Key %d has different definition", i));
- DBUG_PRINT("error", ("t1_spatial= %d, t2_spatial=%d",
- MY_TEST(t1_keyinfo[i].flag & HA_SPATIAL),
- MY_TEST(t2_keyinfo[i].flag & HA_SPATIAL)));
- DBUG_RETURN(1);
- }
- if ((!mysql_40_compat &&
- t1_keyinfo[i].key_alg != t2_keyinfo[i].key_alg) ||
- t1_keyinfo[i].keysegs != t2_keyinfo[i].keysegs)
- {
- DBUG_PRINT("error", ("Key %d has different definition", i));
- DBUG_PRINT("error", ("t1_keysegs=%d, t1_key_alg=%d",
- t1_keyinfo[i].keysegs, t1_keyinfo[i].key_alg));
- DBUG_PRINT("error", ("t2_keysegs=%d, t2_key_alg=%d",
- t2_keyinfo[i].keysegs, t2_keyinfo[i].key_alg));
- DBUG_RETURN(1);
- }
- for (j= t1_keyinfo[i].keysegs; j--;)
- {
- uint8 t1_keysegs_j__type= t1_keysegs[j].type;
-
- /*
- Table migration from 4.1 to 5.1. In 5.1 a *TEXT key part is
- always HA_KEYTYPE_VARTEXT2. In 4.1 we had only the equivalent of
- HA_KEYTYPE_VARTEXT1. Since we treat both the same on MyISAM
- level, we can ignore a mismatch between these types.
- */
- if ((t1_keysegs[j].flag & HA_BLOB_PART) &&
- (t2_keysegs[j].flag & HA_BLOB_PART))
- {
- if ((t1_keysegs_j__type == HA_KEYTYPE_VARTEXT2) &&
- (t2_keysegs[j].type == HA_KEYTYPE_VARTEXT1))
- t1_keysegs_j__type= HA_KEYTYPE_VARTEXT1; /* purecov: tested */
- else if ((t1_keysegs_j__type == HA_KEYTYPE_VARBINARY2) &&
- (t2_keysegs[j].type == HA_KEYTYPE_VARBINARY1))
- t1_keysegs_j__type= HA_KEYTYPE_VARBINARY1; /* purecov: inspected */
- }
-
- if ((!mysql_40_compat &&
- t1_keysegs[j].language != t2_keysegs[j].language) ||
- t1_keysegs_j__type != t2_keysegs[j].type ||
- t1_keysegs[j].null_bit != t2_keysegs[j].null_bit ||
- t1_keysegs[j].length != t2_keysegs[j].length ||
- t1_keysegs[j].start != t2_keysegs[j].start)
- {
- DBUG_PRINT("error", ("Key segment %d (key %d) has different "
- "definition", j, i));
- DBUG_PRINT("error", ("t1_type=%d, t1_language=%d, t1_null_bit=%d, "
- "t1_length=%d",
- t1_keysegs[j].type, t1_keysegs[j].language,
- t1_keysegs[j].null_bit, t1_keysegs[j].length));
- DBUG_PRINT("error", ("t2_type=%d, t2_language=%d, t2_null_bit=%d, "
- "t2_length=%d",
- t2_keysegs[j].type, t2_keysegs[j].language,
- t2_keysegs[j].null_bit, t2_keysegs[j].length));
-
- DBUG_RETURN(1);
- }
- }
- }
- for (i= 0; i < t1_recs; i++)
- {
- MI_COLUMNDEF *t1_rec= &t1_recinfo[i];
- MI_COLUMNDEF *t2_rec= &t2_recinfo[i];
- /*
- FIELD_SKIP_ZERO can be changed to FIELD_NORMAL in mi_create,
- see NOTE1 in mi_create.c
- */
- if ((t1_rec->type != t2_rec->type &&
- !(t1_rec->type == (int) FIELD_SKIP_ZERO &&
- t1_rec->length == 1 &&
- t2_rec->type == (int) FIELD_NORMAL)) ||
- t1_rec->length != t2_rec->length ||
- t1_rec->null_bit != t2_rec->null_bit)
- {
- DBUG_PRINT("error", ("Field %d has different definition", i));
- DBUG_PRINT("error", ("t1_type=%d, t1_length=%d, t1_null_bit=%d",
- t1_rec->type, t1_rec->length, t1_rec->null_bit));
- DBUG_PRINT("error", ("t2_type=%d, t2_length=%d, t2_null_bit=%d",
- t2_rec->type, t2_rec->length, t2_rec->null_bit));
- DBUG_RETURN(1);
- }
- }
+// if ((strict ? t1_keys != t2_keys : t1_keys > t2_keys))
+// {
+// DBUG_PRINT("error", ("Number of keys differs: t1_keys=%u, t2_keys=%u",
+// t1_keys, t2_keys));
+// DBUG_RETURN(1);
+// }
+// if (t1_recs != t2_recs)
+// {
+// DBUG_PRINT("error", ("Number of recs differs: t1_recs=%u, t2_recs=%u",
+// t1_recs, t2_recs));
+// DBUG_RETURN(1);
+// }
+// for (i= 0; i < t1_keys; i++)
+// {
+// HA_KEYSEG *t1_keysegs= t1_keyinfo[i].seg;
+// HA_KEYSEG *t2_keysegs= t2_keyinfo[i].seg;
+// if (t1_keyinfo[i].flag & HA_FULLTEXT && t2_keyinfo[i].flag & HA_FULLTEXT)
+// continue;
+// else if (t1_keyinfo[i].flag & HA_FULLTEXT ||
+// t2_keyinfo[i].flag & HA_FULLTEXT)
+// {
+// DBUG_PRINT("error", ("Key %d has different definition", i));
+// DBUG_PRINT("error", ("t1_fulltext= %d, t2_fulltext=%d",
+// MY_TEST(t1_keyinfo[i].flag & HA_FULLTEXT),
+// MY_TEST(t2_keyinfo[i].flag & HA_FULLTEXT)));
+// DBUG_RETURN(1);
+// }
+// if (t1_keyinfo[i].flag & HA_SPATIAL && t2_keyinfo[i].flag & HA_SPATIAL)
+// continue;
+// else if (t1_keyinfo[i].flag & HA_SPATIAL ||
+// t2_keyinfo[i].flag & HA_SPATIAL)
+// {
+// DBUG_PRINT("error", ("Key %d has different definition", i));
+// DBUG_PRINT("error", ("t1_spatial= %d, t2_spatial=%d",
+// MY_TEST(t1_keyinfo[i].flag & HA_SPATIAL),
+// MY_TEST(t2_keyinfo[i].flag & HA_SPATIAL)));
+// DBUG_RETURN(1);
+// }
+// if ((!mysql_40_compat &&
+// t1_keyinfo[i].key_alg != t2_keyinfo[i].key_alg) ||
+// t1_keyinfo[i].keysegs != t2_keyinfo[i].keysegs)
+// {
+// DBUG_PRINT("error", ("Key %d has different definition", i));
+// DBUG_PRINT("error", ("t1_keysegs=%d, t1_key_alg=%d",
+// t1_keyinfo[i].keysegs, t1_keyinfo[i].key_alg));
+// DBUG_PRINT("error", ("t2_keysegs=%d, t2_key_alg=%d",
+// t2_keyinfo[i].keysegs, t2_keyinfo[i].key_alg));
+// DBUG_RETURN(1);
+// }
+// for (j= t1_keyinfo[i].keysegs; j--;)
+// {
+// uint8 t1_keysegs_j__type= t1_keysegs[j].type;
+//
+// /*
+// Table migration from 4.1 to 5.1. In 5.1 a *TEXT key part is
+// always HA_KEYTYPE_VARTEXT2. In 4.1 we had only the equivalent of
+// HA_KEYTYPE_VARTEXT1. Since we treat both the same on MyISAM
+// level, we can ignore a mismatch between these types.
+// */
+// if ((t1_keysegs[j].flag & HA_BLOB_PART) &&
+// (t2_keysegs[j].flag & HA_BLOB_PART))
+// {
+// if ((t1_keysegs_j__type == HA_KEYTYPE_VARTEXT2) &&
+// (t2_keysegs[j].type == HA_KEYTYPE_VARTEXT1))
+// t1_keysegs_j__type= HA_KEYTYPE_VARTEXT1; /* purecov: tested */
+// else if ((t1_keysegs_j__type == HA_KEYTYPE_VARBINARY2) &&
+// (t2_keysegs[j].type == HA_KEYTYPE_VARBINARY1))
+// t1_keysegs_j__type= HA_KEYTYPE_VARBINARY1; /* purecov: inspected */
+// }
+//
+// if ((!mysql_40_compat &&
+// t1_keysegs[j].language != t2_keysegs[j].language) ||
+// t1_keysegs_j__type != t2_keysegs[j].type ||
+// t1_keysegs[j].null_bit != t2_keysegs[j].null_bit ||
+// t1_keysegs[j].length != t2_keysegs[j].length ||
+// t1_keysegs[j].start != t2_keysegs[j].start)
+// {
+// DBUG_PRINT("error", ("Key segment %d (key %d) has different "
+// "definition", j, i));
+// DBUG_PRINT("error", ("t1_type=%d, t1_language=%d, t1_null_bit=%d, "
+// "t1_length=%d",
+// t1_keysegs[j].type, t1_keysegs[j].language,
+// t1_keysegs[j].null_bit, t1_keysegs[j].length));
+// DBUG_PRINT("error", ("t2_type=%d, t2_language=%d, t2_null_bit=%d, "
+// "t2_length=%d",
+// t2_keysegs[j].type, t2_keysegs[j].language,
+// t2_keysegs[j].null_bit, t2_keysegs[j].length));
+//
+// DBUG_RETURN(1);
+// }
+// }
+// }
+// for (i= 0; i < t1_recs; i++)
+// {
+// MI_COLUMNDEF *t1_rec= &t1_recinfo[i];
+// MI_COLUMNDEF *t2_rec= &t2_recinfo[i];
+// /*
+// FIELD_SKIP_ZERO can be changed to FIELD_NORMAL in mi_create,
+// see NOTE1 in mi_create.c
+// */
+// if ((t1_rec->type != t2_rec->type &&
+// !(t1_rec->type == (int) FIELD_SKIP_ZERO &&
+// t1_rec->length == 1 &&
+// t2_rec->type == (int) FIELD_NORMAL)) ||
+// t1_rec->length != t2_rec->length ||
+// t1_rec->null_bit != t2_rec->null_bit)
+// {
+// DBUG_PRINT("error", ("Field %d has different definition", i));
+// DBUG_PRINT("error", ("t1_type=%d, t1_length=%d, t1_null_bit=%d",
+// t1_rec->type, t1_rec->length, t1_rec->null_bit));
+// DBUG_PRINT("error", ("t2_type=%d, t2_length=%d, t2_null_bit=%d",
+// t2_rec->type, t2_rec->length, t2_rec->null_bit));
+// DBUG_RETURN(1);
+// }
+// }
DBUG_RETURN(0);
}
@@ -2005,6 +2361,7 @@ int ha_myisam::create(const char *name, register TABLE *table_arg,
uint create_flags= 0, record_count, i;
char buff[FN_REFLEN];
MI_KEYDEF *keydef;
+ MI_UNIQUEDEF *uniquedef;
MI_COLUMNDEF *recinfo;
MI_CREATE_INFO create_info;
TABLE_SHARE *share= table_arg->s;
@@ -2018,7 +2375,7 @@ int ha_myisam::create(const char *name, register TABLE *table_arg,
break;
}
}
- if ((error= table2myisam(table_arg, &keydef, &recinfo, &record_count)))
+ if ((error= table2myisam_with_uniquedef(table_arg, &keydef,&uniquedef, &recinfo, &record_count)))
DBUG_RETURN(error); /* purecov: inspected */
bzero((char*) &create_info, sizeof(create_info));
create_info.max_rows= share->max_rows;
@@ -2069,7 +2426,7 @@ int ha_myisam::create(const char *name, register TABLE *table_arg,
MY_UNPACK_FILENAME|MY_APPEND_EXT),
share->keys, keydef,
record_count, recinfo,
- 0, (MI_UNIQUEDEF*) 0,
+ share->uniques, uniquedef,
&create_info, create_flags);
my_free(recinfo);
DBUG_RETURN(error);
References