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;i1000) //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;iuniques;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);