diff options
author | unknown <bell@sanja.is.com.ua> | 2004-04-08 23:50:10 +0300 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2004-04-08 23:50:10 +0300 |
commit | 38f6c83e7faa799325d8f533aba56cedf3a0dc9c (patch) | |
tree | 562e5280dd8a63f7e243056e1e8a9e5f4747b2a7 /sql | |
parent | 52a62ce0b08832401741a1340b983620194d9fe6 (diff) | |
parent | e51447b1430e854fa0df1f37821e722cdb65d2bb (diff) | |
download | mariadb-git-38f6c83e7faa799325d8f533aba56cedf3a0dc9c.tar.gz |
merge
sql/mysql_priv.h:
Auto merged
sql/sql_select.cc:
Auto merged
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 98 | ||||
-rw-r--r-- | sql/field.h | 3 | ||||
-rw-r--r-- | sql/ha_myisam.cc | 4 | ||||
-rw-r--r-- | sql/handler.cc | 138 | ||||
-rw-r--r-- | sql/handler.h | 28 | ||||
-rw-r--r-- | sql/mysql_priv.h | 25 | ||||
-rw-r--r-- | sql/opt_range.cc | 341 | ||||
-rw-r--r-- | sql/opt_range.h | 15 | ||||
-rw-r--r-- | sql/sql_insert.cc | 8 | ||||
-rw-r--r-- | sql/sql_parse.cc | 46 | ||||
-rw-r--r-- | sql/sql_select.cc | 74 | ||||
-rw-r--r-- | sql/sql_table.cc | 1895 | ||||
-rw-r--r-- | sql/table.cc | 1 | ||||
-rw-r--r-- | sql/unireg.cc | 53 |
14 files changed, 1430 insertions, 1299 deletions
diff --git a/sql/field.cc b/sql/field.cc index 2da84ba1316..d865d2cc9e9 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4359,7 +4359,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs) set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED); error= 1; } - memcpy(ptr+2,from,length); + memcpy(ptr+HA_KEY_BLOB_LENGTH,from,length); int2store(ptr, length); return error; } @@ -4388,18 +4388,18 @@ int Field_varstring::store(longlong nr) double Field_varstring::val_real(void) { int not_used; - uint length=uint2korr(ptr)+2; + uint length=uint2korr(ptr)+HA_KEY_BLOB_LENGTH; CHARSET_INFO *cs=charset(); - return my_strntod(cs,ptr+2,length,(char**)0, ¬_used); + return my_strntod(cs, ptr+HA_KEY_BLOB_LENGTH, length, (char**)0, ¬_used); } longlong Field_varstring::val_int(void) { int not_used; - uint length=uint2korr(ptr)+2; + uint length=uint2korr(ptr)+HA_KEY_BLOB_LENGTH; CHARSET_INFO *cs=charset(); - return my_strntoll(cs,ptr+2,length,10,NULL, ¬_used); + return my_strntoll(cs,ptr+HA_KEY_BLOB_LENGTH,length,10,NULL, ¬_used); } @@ -4407,7 +4407,7 @@ String *Field_varstring::val_str(String *val_buffer __attribute__((unused)), String *val_ptr) { uint length=uint2korr(ptr); - val_ptr->set((const char*) ptr+2,length,field_charset); + val_ptr->set((const char*) ptr+HA_KEY_BLOB_LENGTH,length,field_charset); return val_ptr; } @@ -4417,18 +4417,21 @@ int Field_varstring::cmp(const char *a_ptr, const char *b_ptr) uint a_length=uint2korr(a_ptr); uint b_length=uint2korr(b_ptr); int diff; - diff=my_strnncoll(field_charset, - (const uchar*)a_ptr+2,min(a_length,b_length), - (const uchar*)b_ptr+2,min(a_length,b_length)); + diff= my_strnncoll(field_charset, + (const uchar*) a_ptr+HA_KEY_BLOB_LENGTH, + min(a_length,b_length), + (const uchar*) b_ptr+HA_KEY_BLOB_LENGTH, + min(a_length,b_length)); return diff ? diff : (int) (a_length - b_length); } void Field_varstring::sort_string(char *to,uint length) { uint tot_length=uint2korr(ptr); - tot_length=my_strnxfrm(field_charset, - (unsigned char *) to, length, - (unsigned char *)ptr+2, tot_length); + tot_length= my_strnxfrm(field_charset, + (uchar*) to, length, + (uchar*) ptr+HA_KEY_BLOB_LENGTH, + tot_length); if (tot_length < length) field_charset->cset->fill(field_charset, to+tot_length,length-tot_length, binary() ? (char) 0 : ' '); @@ -4453,7 +4456,7 @@ char *Field_varstring::pack(char *to, const char *from, uint max_length) if (max_length > 255) *to++= (char) (length >> 8); if (length) - memcpy(to, from+2, length); + memcpy(to, from+HA_KEY_BLOB_LENGTH, length); return to+length; } @@ -4473,7 +4476,7 @@ const char *Field_varstring::unpack(char *to, const char *from) to[1] = *from++; } if (length) - memcpy(to+2, from, length); + memcpy(to+HA_KEY_BLOB_LENGTH, from, length); return from+length; } @@ -4484,8 +4487,8 @@ int Field_varstring::pack_cmp(const char *a, const char *b, uint key_length) uint b_length; if (key_length > 255) { - a_length=uint2korr(a); a+=2; - b_length=uint2korr(b); b+=2; + a_length=uint2korr(a); a+= 2; + b_length=uint2korr(b); b+= 2; } else { @@ -4493,32 +4496,32 @@ int Field_varstring::pack_cmp(const char *a, const char *b, uint key_length) b_length= (uint) (uchar) *b++; } return my_strnncoll(field_charset, - (const uchar *)a,a_length, - (const uchar *)b,b_length); + (const uchar*) a, a_length, + (const uchar*) b, b_length); } int Field_varstring::pack_cmp(const char *b, uint key_length) { - char *a=ptr+2; - uint a_length=uint2korr(ptr); + char *a= ptr+HA_KEY_BLOB_LENGTH; + uint a_length= uint2korr(ptr); uint b_length; if (key_length > 255) { - b_length=uint2korr(b); b+=2; + b_length=uint2korr(b); b+= 2; } else { b_length= (uint) (uchar) *b++; } return my_strnncoll(field_charset, - (const uchar *)a,a_length, - (const uchar *)b,b_length); + (const uchar*) a, a_length, + (const uchar*) b, b_length); } uint Field_varstring::packed_col_length(const char *data_ptr, uint length) { if (length > 255) - return uint2korr(data_ptr)+2; + return uint2korr(data_ptr)+HA_KEY_BLOB_LENGTH; else return (uint) ((uchar) *data_ptr)+1; } @@ -4531,22 +4534,21 @@ uint Field_varstring::max_packed_col_length(uint max_length) void Field_varstring::get_key_image(char *buff, uint length, CHARSET_INFO *cs, imagetype type) { - length-= HA_KEY_BLOB_LENGTH; uint f_length=uint2korr(ptr); if (f_length > length) f_length= length; int2store(buff,length); - memcpy(buff+2,ptr+2,length); + memcpy(buff+HA_KEY_BLOB_LENGTH, ptr+HA_KEY_BLOB_LENGTH, length); #ifdef HAVE_purify if (f_length < length) - bzero(buff+2+f_length, (length-f_length)); + bzero(buff+HA_KEY_BLOB_LENGTH+f_length, (length-f_length)); #endif } void Field_varstring::set_key_image(char *buff,uint length, CHARSET_INFO *cs) { length=uint2korr(buff); // Real length is here - (void) Field_varstring::store(buff+2, length, cs); + (void) Field_varstring::store(buff+HA_KEY_BLOB_LENGTH, length, cs); } @@ -4799,7 +4801,6 @@ int Field_blob::cmp_binary(const char *a_ptr, const char *b_ptr, void Field_blob::get_key_image(char *buff,uint length, CHARSET_INFO *cs, imagetype type) { - length-= HA_KEY_BLOB_LENGTH; uint32 blob_length= get_length(ptr); char *blob; @@ -4838,18 +4839,18 @@ void Field_blob::get_key_image(char *buff,uint length, Must clear this as we do a memcmp in opt_range.cc to detect identical keys */ - bzero(buff+2+blob_length, (length-blob_length)); + bzero(buff+HA_KEY_BLOB_LENGTH+blob_length, (length-blob_length)); length=(uint) blob_length; } int2store(buff,length); get_ptr(&blob); - memcpy(buff+2,blob,length); + memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length); } void Field_blob::set_key_image(char *buff,uint length, CHARSET_INFO *cs) { - length=uint2korr(buff); - (void) Field_blob::store(buff+2,length,cs); + length= uint2korr(buff); + (void) Field_blob::store(buff+HA_KEY_BLOB_LENGTH, length, cs); } @@ -4857,16 +4858,16 @@ int Field_blob::key_cmp(const byte *key_ptr, uint max_key_length) { char *blob1; uint blob_length=get_length(ptr); - max_key_length-=2; memcpy_fixed(&blob1,ptr+packlength,sizeof(char*)); return Field_blob::cmp(blob1,min(blob_length, max_key_length), - (char*) key_ptr+2,uint2korr(key_ptr)); + (char*) key_ptr+HA_KEY_BLOB_LENGTH, + uint2korr(key_ptr)); } int Field_blob::key_cmp(const byte *a,const byte *b) { - return Field_blob::cmp((char*) a+2,uint2korr(a), - (char*) b+2,uint2korr(b)); + return Field_blob::cmp((char*) a+HA_KEY_BLOB_LENGTH, uint2korr(a), + (char*) b+HA_KEY_BLOB_LENGTH, uint2korr(b)); } @@ -4882,8 +4883,8 @@ void Field_blob::sort_string(char *to,uint length) memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); blob_length=my_strnxfrm(field_charset, - (unsigned char *)to, length, - (unsigned char *)blob, blob_length); + (uchar*) to, length, + (uchar*) blob, blob_length); if (blob_length < length) field_charset->cset->fill(field_charset, to+blob_length, length-blob_length, @@ -4965,8 +4966,8 @@ int Field_blob::pack_cmp(const char *a, const char *b, uint key_length) b_length= (uint) (uchar) *b++; } return my_strnncoll(field_charset, - (const uchar *)a,a_length, - (const uchar *)b,b_length); + (const uchar*) a, a_length, + (const uchar*) b, b_length); } @@ -4988,8 +4989,8 @@ int Field_blob::pack_cmp(const char *b, uint key_length) b_length= (uint) (uchar) *b++; } return my_strnncoll(field_charset, - (const uchar *)a,a_length, - (const uchar *)b,b_length); + (const uchar*) a, a_length, + (const uchar*) b, b_length); } /* Create a packed key that will be used for storage from a MySQL row */ @@ -5025,7 +5026,7 @@ char *Field_blob::pack_key_from_key_image(char *to, const char *from, if (max_length > 255) *to++= (char) (length >> 8); if (length) - memcpy(to, from+2, length); + memcpy(to, from+HA_KEY_BLOB_LENGTH, length); return to+length; } @@ -5048,11 +5049,12 @@ uint Field_blob::max_packed_col_length(uint max_length) void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs, imagetype type) { - length-= HA_KEY_BLOB_LENGTH; - ulong blob_length= get_length(ptr); char *blob; const char *dummy; MBR mbr; + ulong blob_length= get_length(ptr); + Geometry_buffer buffer; + Geometry *gobj; if (blob_length < SRID_SIZE) { @@ -5060,8 +5062,6 @@ void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs, return; } get_ptr(&blob); - Geometry_buffer buffer; - Geometry *gobj; gobj= Geometry::create_from_wkb(&buffer, blob + SRID_SIZE, blob_length - SRID_SIZE); if (gobj->get_mbr(&mbr, &dummy)) @@ -5554,7 +5554,7 @@ uint32 calc_pack_length(enum_field_types type,uint32 length) switch (type) { case FIELD_TYPE_STRING: case FIELD_TYPE_DECIMAL: return (length); - case FIELD_TYPE_VAR_STRING: return (length+2); + case FIELD_TYPE_VAR_STRING: return (length+HA_KEY_BLOB_LENGTH); case FIELD_TYPE_YEAR: case FIELD_TYPE_TINY : return 1; case FIELD_TYPE_SHORT : return 2; diff --git a/sql/field.h b/sql/field.h index 8ebc7412c35..4efabcead18 100644 --- a/sql/field.h +++ b/sql/field.h @@ -212,7 +212,8 @@ public: { memcpy(buff,ptr,length); } inline void set_image(char *buff,uint length, CHARSET_INFO *cs) { memcpy(ptr,buff,length); } - virtual void get_key_image(char *buff,uint length, CHARSET_INFO *cs, imagetype type) + virtual void get_key_image(char *buff,uint length, CHARSET_INFO *cs, + imagetype type) { get_image(buff,length,cs); } virtual void set_key_image(char *buff,uint length, CHARSET_INFO *cs) { set_image(buff,length,cs); } diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index c56009dc0aa..b9d6cec38aa 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -867,7 +867,9 @@ void ha_myisam::start_bulk_insert(ha_rows rows) THD *thd=current_thd; ulong size= min(thd->variables.read_buff_size, table->avg_row_length*rows); - mi_extra(file, HA_EXTRA_WRITE_CACHE, (void*)&size); + /* don't enable row cache if too few rows */ + if (!rows && rows > MI_MIN_ROWS_TO_USE_WRITE_CACHE) + mi_extra(file, HA_EXTRA_WRITE_CACHE, (void*) &size); can_enable_indexes= (file->s->state.key_map == set_bits(ulonglong, file->s->base.keys)); diff --git a/sql/handler.cc b/sql/handler.cc index ddf2e68db47..2b22563bc3c 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1287,3 +1287,141 @@ int ha_change_key_cache(KEY_CACHE *old_key_cache, mi_change_key_cache(old_key_cache, new_key_cache); return 0; } + + +/* + Read first row between two ranges. + Store ranges for future calls to read_range_next + + SYNOPSIS + read_range_first() + start_key Start key. Is 0 if no min range + end_key End key. Is 0 if no max range + sorted Set to 1 if result should be sorted per key + + NOTES + Record is read into table->record[0] + + RETURN + 0 Found row + HA_ERR_END_OF_FILE No rows in range + # Error code +*/ + +int handler::read_range_first(const key_range *start_key, + const key_range *end_key, + bool sorted) +{ + int result; + DBUG_ENTER("handler::read_range_first"); + + end_range= 0; + if (end_key) + { + end_range= &save_end_range; + save_end_range= *end_key; + key_compare_result_on_equal= ((end_key->flag == HA_READ_BEFORE_KEY) ? 1 : + (end_key->flag == HA_READ_AFTER_KEY) ? -1 : 0); + } + range_key_part= table->key_info[active_index].key_part; + + + if (!start_key) // Read first record + result= index_first(table->record[0]); + else + result= index_read(table->record[0], + start_key->key, + start_key->length, + start_key->flag); + if (result) + DBUG_RETURN((result == HA_ERR_KEY_NOT_FOUND || + result == HA_ERR_END_OF_FILE) ? HA_ERR_END_OF_FILE : + result); + + DBUG_RETURN (compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE); +} + + +/* + Read next row between two ranges. + + SYNOPSIS + read_range_next() + eq_range Set to 1 if start_key == end_key + + NOTES + Record is read into table->record[0] + + RETURN + 0 Found row + HA_ERR_END_OF_FILE No rows in range + # Error code +*/ + +int handler::read_range_next(bool eq_range) +{ + int result; + DBUG_ENTER("handler::read_range_next"); + + if (eq_range) + result= index_next_same(table->record[0], + end_range->key, + end_range->length); + else + result= index_next(table->record[0]); + if (result) + DBUG_RETURN(result); + DBUG_RETURN(compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE); +} + + +/* + Compare if found key is over max-value + + SYNOPSIS + compare_key + range key to compare to row + + NOTES + For this to work, the row must be stored in table->record[0] + + RETURN + 0 Key is equal to range or 'range' == 0 (no range) + -1 Key is less than range + 1 Key is larger than range +*/ + +int handler::compare_key(key_range *range) +{ + KEY_PART_INFO *key_part= range_key_part; + uint store_length; + + if (!range) + return 0; // No max range + + for (const char *key=range->key, *end=key+range->length; + key < end; + key+= store_length, key_part++) + { + int cmp; + store_length= key_part->store_length; + if (key_part->null_bit) + { + if (*key) + { + if (!key_part->field->is_null()) + return 1; + continue; + } + else if (key_part->field->is_null()) + return 0; + key++; // Skip null byte + store_length--; + } + if ((cmp=key_part->field->key_cmp((byte*) key, key_part->length)) < 0) + return -1; + if (cmp > 0) + return 1; + } + return key_compare_result_on_equal; +} diff --git a/sql/handler.h b/sql/handler.h index 80a3c2e7f1b..4cb6ab86a37 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -92,10 +92,10 @@ /* - Bits in index_ddl_flags(KEY *wanted_index) - for what ddl you can do with index - If none is set, the wanted type of index is not supported - by the handler at all. See WorkLog 1563. + Bits in index_ddl_flags(KEY *wanted_index) + for what ddl you can do with index + If none is set, the wanted type of index is not supported + by the handler at all. See WorkLog 1563. */ #define HA_DDL_SUPPORT 1 /* Supported by handler */ #define HA_DDL_WITH_LOCK 2 /* Can create/drop with locked table */ @@ -218,6 +218,14 @@ typedef struct st_ha_check_opt } HA_CHECK_OPT; +typedef struct st_key_range +{ + const byte *key; + uint length; + enum ha_rkey_function flag; +} key_range; + + class handler :public Sql_alloc { protected: @@ -239,6 +247,12 @@ public: time_t create_time; /* When table was created */ time_t check_time; time_t update_time; + + /* The following are for read_range() */ + key_range save_end_range, *end_range; + KEY_PART_INFO *range_key_part; + int key_compare_result_on_equal; + uint errkey; /* Last dup key */ uint sortkey, key_used_on_scan; uint active_index; @@ -250,6 +264,7 @@ public: bool auto_increment_column_changed; bool implicit_emptied; /* Can be !=0 only if HEAP */ + handler(TABLE *table_arg) :table(table_arg), ref(0), data_file_length(0), max_data_file_length(0), index_file_length(0), delete_length(0), auto_increment_value(0), @@ -298,6 +313,11 @@ public: { return (my_errno=HA_ERR_WRONG_COMMAND); } + virtual int handler::read_range_first(const key_range *start_key, + const key_range *end_key, + bool sorted); + virtual int handler::read_range_next(bool eq_range); + int handler::compare_key(key_range *range); virtual int ft_init() { return -1; } virtual FT_INFO *ft_init_ext(uint flags,uint inx,const byte *key, uint keylen) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 78e0efa7ceb..7b73897eb18 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -516,23 +516,11 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name, List<create_field> &fields, List<Key> &keys,List<Alter_drop> &drop_list, List<Alter_column> &alter_list, - uint order_num, ORDER *order, int alter_flags, + uint order_num, ORDER *order, uint alter_flags, enum enum_duplicates handle_duplicates, enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS, enum tablespace_op_type tablespace_op=NO_TABLESPACE_OP, bool simple_alter=0); -int real_alter_table(THD *thd, char *new_db, char *new_name, - HA_CREATE_INFO *create_info, - TABLE_LIST *table_list, - TABLE *table, - List<create_field> &fields, - List<Key> &keys,List<Alter_drop> &drop_list, - List<Alter_column> &alter_list, - uint order_num, ORDER *order, int alter_flags, - enum enum_duplicates handle_duplicates, - enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS, - enum tablespace_op_type tablespace_op=NO_TABLESPACE_OP, - bool simple_alter=0); int mysql_create_like_table(THD *thd, TABLE_LIST *table, HA_CREATE_INFO *create_info, Table_ident *src_table); @@ -544,10 +532,6 @@ bool mysql_rename_table(enum db_type base, int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys); int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop_list); -int mysql_add_column(THD *thd, TABLE_LIST *table_list, - List<create_field> &fields); -int mysql_drop_column(THD *thd, TABLE_LIST *table_list, - List<Alter_drop> &drop_list); int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields, List<Item> &values,COND *conds, uint order_num, ORDER *order, ha_rows limit, @@ -951,9 +935,10 @@ void unlock_table_names(THD *thd, TABLE_LIST *table_list, void unireg_init(ulong options); void unireg_end(void); -int mysql_create_frm(THD *thd, my_string file_name,HA_CREATE_INFO *create_info, - List<create_field> &create_field, - uint key_count,KEY *key_info,handler *db_type); +bool mysql_create_frm(THD *thd, my_string file_name, + HA_CREATE_INFO *create_info, + List<create_field> &create_field, + uint key_count,KEY *key_info,handler *db_type); int rea_create_table(THD *thd, my_string file_name,HA_CREATE_INFO *create_info, List<create_field> &create_field, uint key_count,KEY *key_info); diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 38ff7f14c40..3ef1323893f 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -177,11 +177,11 @@ public: if (maybe_null && *min_value) { **min_key=1; - bzero(*min_key+1,length); + bzero(*min_key+1,length-1); } else - memcpy(*min_key,min_value,length+(int) maybe_null); - (*min_key)+= length+(int) maybe_null; + memcpy(*min_key,min_value,length); + (*min_key)+= length; } if (!(max_flag & NO_MAX_RANGE) && !(max_key_flag & (NO_MAX_RANGE | NEAR_MAX))) @@ -189,18 +189,18 @@ public: if (maybe_null && *max_value) { **max_key=1; - bzero(*max_key+1,length); + bzero(*max_key+1,length-1); } else - memcpy(*max_key,max_value,length+(int) maybe_null); - (*max_key)+= length+(int) maybe_null; + memcpy(*max_key,max_value,length); + (*max_key)+= length; } } void store_min_key(KEY_PART *key,char **range_key, uint *range_key_flag) { SEL_ARG *key_tree= first(); - key_tree->store(key[key_tree->part].part_length, + key_tree->store(key[key_tree->part].store_length, range_key,*range_key_flag,range_key,NO_MAX_RANGE); *range_key_flag|= key_tree->min_flag; if (key_tree->next_key_part && @@ -213,7 +213,7 @@ public: void store_max_key(KEY_PART *key,char **range_key, uint *range_key_flag) { SEL_ARG *key_tree= last(); - key_tree->store(key[key_tree->part].part_length, + key_tree->store(key[key_tree->part].store_length, range_key, NO_MIN_RANGE, range_key,*range_key_flag); (*range_key_flag)|= key_tree->max_flag; if (key_tree->next_key_part && @@ -646,6 +646,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, MEM_ROOT *old_root,alloc; SEL_TREE *tree; KEY_PART *key_parts; + KEY *key_info; PARAM param; /* set up parameter that is passed to all functions */ @@ -671,24 +672,26 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC); my_pthread_setspecific_ptr(THR_MALLOC,&alloc); - for (idx=0 ; idx < head->keys ; idx++) + key_info= head->key_info; + for (idx=0 ; idx < head->keys ; idx++, key_info++) { + KEY_PART_INFO *key_part_info; if (!keys_to_use.is_set(idx)) continue; - KEY *key_info= &head->key_info[idx]; if (key_info->flags & HA_FULLTEXT) continue; // ToDo: ft-keys in non-ft ranges, if possible SerG param.key[param.keys]=key_parts; - for (uint part=0 ; part < key_info->key_parts ; part++,key_parts++) + key_part_info= key_info->key_part; + for (uint part=0 ; part < key_info->key_parts ; + part++, key_parts++, key_part_info++) { - key_parts->key=param.keys; - key_parts->part=part; - key_parts->part_length= key_info->key_part[part].length; - key_parts->field= key_info->key_part[part].field; - key_parts->null_bit= key_info->key_part[part].null_bit; - if (key_parts->field->type() == FIELD_TYPE_BLOB) - key_parts->part_length+=HA_KEY_BLOB_LENGTH; + key_parts->key= param.keys; + key_parts->part= part; + key_parts->length= key_part_info->length; + key_parts->store_length= key_part_info->store_length; + key_parts->field= key_part_info->field; + key_parts->null_bit= key_part_info->null_bit; key_parts->image_type = (key_info->flags & HA_SPATIAL) ? Field::itMBR : Field::itRAW; } @@ -1043,18 +1046,26 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part, DBUG_RETURN(0); // Can only optimize strings offset=maybe_null; - length=key_part->part_length; - if (field->type() == FIELD_TYPE_BLOB) + length=key_part->store_length; + + if (length != key_part->length + maybe_null) { - offset+=HA_KEY_BLOB_LENGTH; - field_length=key_part->part_length-HA_KEY_BLOB_LENGTH; + /* key packed with length prefix */ + offset+= HA_KEY_BLOB_LENGTH; + field_length= length - HA_KEY_BLOB_LENGTH; } else { - if (length < field_length) - length=field_length; // Only if overlapping key + if (unlikely(length < field_length)) + { + /* + This can only happen in a table created with UNIREG where one key + overlaps many fields + */ + length= field_length; + } else - field_length=length; + field_length= length; } length+=offset; if (!(min_str= (char*) alloc_root(param->mem_root, length*2))) @@ -1067,7 +1078,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part, res->ptr(), res->length(), ((Item_func_like*)(param->cond))->escape, wild_one, wild_many, - field_length, + field_length-maybe_null, min_str+offset, max_str+offset, &min_length, &max_length); if (like_error) // Can't optimize with LIKE @@ -1105,13 +1116,13 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part, if (field->key_type() == HA_KEYTYPE_VARTEXT) copies= 2; str= str2= (char*) alloc_root(param->mem_root, - (key_part->part_length+maybe_null)*copies+1); + (key_part->store_length)*copies+1); if (!str) DBUG_RETURN(0); if (maybe_null) *str= (char) field->is_real_null(); // Set to 1 if null - field->get_key_image(str+maybe_null,key_part->part_length, - field->charset(),key_part->image_type); + field->get_key_image(str+maybe_null, key_part->length, + field->charset(), key_part->image_type); if (copies == 2) { /* @@ -1120,16 +1131,17 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part, all rows between 'X' and 'X ...' */ uint length= uint2korr(str+maybe_null); - str2= str+ key_part->part_length + maybe_null; + str2= str+ key_part->store_length; /* remove end space */ while (length > 0 && str[length+HA_KEY_BLOB_LENGTH+maybe_null-1] == ' ') length--; int2store(str+maybe_null, length); /* Create key that is space filled */ memcpy(str2, str, length + HA_KEY_BLOB_LENGTH + maybe_null); - bfill(str2+ length+ HA_KEY_BLOB_LENGTH +maybe_null, - key_part->part_length-length - HA_KEY_BLOB_LENGTH, ' '); - int2store(str2+maybe_null, key_part->part_length - HA_KEY_BLOB_LENGTH); + my_fill_8bit(field->charset(), + str2+ length+ HA_KEY_BLOB_LENGTH +maybe_null, + key_part->length-length, ' '); + int2store(str2+maybe_null, key_part->length); } if (!(tree=new SEL_ARG(field,str,str2))) DBUG_RETURN(0); // out of memory @@ -1156,39 +1168,39 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part, tree->max_flag=NO_MAX_RANGE; break; case Item_func::SP_EQUALS_FUNC: - tree->min_flag=GEOM_FLAG | HA_READ_MBR_EQUAL;// NEAR_MIN;//512; - tree->max_flag=NO_MAX_RANGE; - break; + tree->min_flag=GEOM_FLAG | HA_READ_MBR_EQUAL;// NEAR_MIN;//512; + tree->max_flag=NO_MAX_RANGE; + break; case Item_func::SP_DISJOINT_FUNC: - tree->min_flag=GEOM_FLAG | HA_READ_MBR_DISJOINT;// NEAR_MIN;//512; - tree->max_flag=NO_MAX_RANGE; - break; + tree->min_flag=GEOM_FLAG | HA_READ_MBR_DISJOINT;// NEAR_MIN;//512; + tree->max_flag=NO_MAX_RANGE; + break; case Item_func::SP_INTERSECTS_FUNC: - tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512; - tree->max_flag=NO_MAX_RANGE; - break; + tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512; + tree->max_flag=NO_MAX_RANGE; + break; case Item_func::SP_TOUCHES_FUNC: - tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512; - tree->max_flag=NO_MAX_RANGE; - break; + tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512; + tree->max_flag=NO_MAX_RANGE; + break; case Item_func::SP_CROSSES_FUNC: - tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512; - tree->max_flag=NO_MAX_RANGE; - break; + tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512; + tree->max_flag=NO_MAX_RANGE; + break; case Item_func::SP_WITHIN_FUNC: - tree->min_flag=GEOM_FLAG | HA_READ_MBR_WITHIN;// NEAR_MIN;//512; - tree->max_flag=NO_MAX_RANGE; - break; + tree->min_flag=GEOM_FLAG | HA_READ_MBR_WITHIN;// NEAR_MIN;//512; + tree->max_flag=NO_MAX_RANGE; + break; case Item_func::SP_CONTAINS_FUNC: - tree->min_flag=GEOM_FLAG | HA_READ_MBR_CONTAIN;// NEAR_MIN;//512; - tree->max_flag=NO_MAX_RANGE; - break; + tree->min_flag=GEOM_FLAG | HA_READ_MBR_CONTAIN;// NEAR_MIN;//512; + tree->max_flag=NO_MAX_RANGE; + break; case Item_func::SP_OVERLAPS_FUNC: - tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512; - tree->max_flag=NO_MAX_RANGE; - break; + tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512; + tree->max_flag=NO_MAX_RANGE; + break; default: break; @@ -2236,7 +2248,7 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree, uint tmp_min_flag,tmp_max_flag,keynr; char *tmp_min_key=min_key,*tmp_max_key=max_key; - key_tree->store(param->key[idx][key_tree->part].part_length, + key_tree->store(param->key[idx][key_tree->part].store_length, &tmp_min_key,min_key_flag,&tmp_max_key,max_key_flag); uint min_key_length= (uint) (tmp_min_key- param->min_key); uint max_key_length= (uint) (tmp_max_key- param->max_key); @@ -2332,8 +2344,14 @@ get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree) { QUICK_SELECT *quick; DBUG_ENTER("get_quick_select"); - if ((quick=new QUICK_SELECT(param->thd, param->table, - param->real_keynr[idx]))) + + if (param->table->key_info[param->real_keynr[idx]].flags & HA_SPATIAL) + quick=new QUICK_SELECT_GEOM(param->thd, param->table, param->real_keynr[idx], + 0); + else + quick=new QUICK_SELECT(param->thd, param->table, param->real_keynr[idx]); + + if (quick) { if (quick->error || get_quick_keys(param,quick,param->key[idx],key_tree,param->min_key,0, @@ -2373,7 +2391,7 @@ get_quick_keys(PARAM *param,QUICK_SELECT *quick,KEY_PART *key, return 1; } char *tmp_min_key=min_key,*tmp_max_key=max_key; - key_tree->store(key[key_tree->part].part_length, + key_tree->store(key[key_tree->part].store_length, &tmp_min_key,min_key_flag,&tmp_max_key,max_key_flag); if (key_tree->next_key_part && @@ -2491,19 +2509,17 @@ static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length) { for (const char *end=key+length ; key < end; - key+= key_part++->part_length) + key+= key_part++->store_length) { - if (key_part->null_bit) - { - if (*key++) - return 1; - } + if (key_part->null_bit && *key) + return 1; } return 0; } + /**************************************************************************** -** Create a QUICK RANGE based on a key + Create a QUICK RANGE based on a key ****************************************************************************/ QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref) @@ -2541,9 +2557,8 @@ QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref) { key_part->part=part; key_part->field= key_info->key_part[part].field; - key_part->part_length= key_info->key_part[part].length; - if (key_part->field->type() == FIELD_TYPE_BLOB) - key_part->part_length+=HA_KEY_BLOB_LENGTH; + key_part->length= key_info->key_part[part].length; + key_part->store_length= key_info->key_part[part].store_length; key_part->null_bit= key_info->key_part[part].null_bit; } if (quick->ranges.push_back(range)) @@ -2585,111 +2600,74 @@ int QUICK_SELECT::get_next() for (;;) { int result; + key_range start_key, end_key; if (range) - { // Already read through key - result=((range->flag & (EQ_RANGE | GEOM_FLAG)) ? - file->index_next_same(record, (byte*) range->min_key, - range->min_length) : - file->index_next(record)); - - if (!result) - { - if ((range->flag & GEOM_FLAG) || !cmp_next(*it.ref())) - DBUG_RETURN(0); - } - else if (result != HA_ERR_END_OF_FILE) + { + // Already read through key + result= file->read_range_next(test(range->flag & EQ_RANGE)); + if (result != HA_ERR_END_OF_FILE) DBUG_RETURN(result); } - if (!(range=it++)) + if (!(range= it++)) DBUG_RETURN(HA_ERR_END_OF_FILE); // All ranges used - if (range->flag & GEOM_FLAG) - { - if ((result = file->index_read(record, - (byte*) (range->min_key), - range->min_length, - (ha_rkey_function)(range->flag ^ - GEOM_FLAG)))) - { - if (result != HA_ERR_KEY_NOT_FOUND) - DBUG_RETURN(result); - range=0; // Not found, to next range - continue; - } - DBUG_RETURN(0); - } + start_key.key= range->min_key; + start_key.length= range->min_length; + start_key.flag= ((range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY : + (range->flag & EQ_RANGE) ? + HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT); + end_key.key= range->max_key; + end_key.length= range->max_length; + /* + We use READ_AFTER_KEY here because if we are reading on a key + prefix we want to find all keys with this prefix + */ + end_key.flag= (range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY : + HA_READ_AFTER_KEY); - if (range->flag & NO_MIN_RANGE) // Read first record - { - int local_error; - if ((local_error=file->index_first(record))) - DBUG_RETURN(local_error); // Empty table - if (cmp_next(range) == 0) - DBUG_RETURN(0); - range=0; // No matching records; go to next range - continue; - } - if ((result = file->index_read(record, - (byte*) (range->min_key + - test(range->flag & GEOM_FLAG)), - range->min_length, - (range->flag & NEAR_MIN) ? - HA_READ_AFTER_KEY: - (range->flag & EQ_RANGE) ? - HA_READ_KEY_EXACT : - HA_READ_KEY_OR_NEXT))) + result= file->read_range_first(range->min_length ? &start_key : 0, + range->max_length ? &end_key : 0, + sorted); + if (range->flag == (UNIQUE_RANGE | EQ_RANGE)) + range=0; // Stop searching - { - if (result != HA_ERR_KEY_NOT_FOUND) - DBUG_RETURN(result); - range=0; // Not found, to next range - continue; - } - if (cmp_next(range) == 0) - { - if (range->flag == (UNIQUE_RANGE | EQ_RANGE)) - range=0; // Stop searching - DBUG_RETURN(0); // Found key is in range - } - range=0; // To next range + if (result != HA_ERR_END_OF_FILE) + DBUG_RETURN(result); + range=0; // No matching rows; go to next range } } -/* - Compare if found key is over max-value - Returns 0 if key <= range->max_key -*/ +/* Get next for geometrical indexes */ -int QUICK_SELECT::cmp_next(QUICK_RANGE *range_arg) +int QUICK_SELECT_GEOM::get_next() { - if (range_arg->flag & NO_MAX_RANGE) - return 0; /* key can't be to large */ + DBUG_ENTER(" QUICK_SELECT_GEOM::get_next"); - KEY_PART *key_part=key_parts; - for (char *key=range_arg->max_key, *end=key+range_arg->max_length; - key < end; - key+= key_part++->part_length) + for (;;) { - int cmp; - if (key_part->null_bit) + int result; + if (range) { - if (*key++) - { - if (!key_part->field->is_null()) - return 1; - continue; - } - else if (key_part->field->is_null()) - return 0; + // Already read through key + result= file->index_next_same(record, (byte*) range->min_key, + range->min_length); + if (result != HA_ERR_END_OF_FILE) + DBUG_RETURN(result); } - if ((cmp=key_part->field->key_cmp((byte*) key, key_part->part_length)) < 0) - return 0; - if (cmp > 0) - return 1; + + if (!(range= it++)) + DBUG_RETURN(HA_ERR_END_OF_FILE); // All ranges used + + result= file->index_read(record, + (byte*) range->min_key, + range->min_length, + (ha_rkey_function)(range->flag ^ GEOM_FLAG)); + if (result != HA_ERR_KEY_NOT_FOUND) + DBUG_RETURN(result); + range=0; // Not found, to next range } - return (range_arg->flag & NEAR_MAX) ? 1 : 0; // Exact match } @@ -2841,15 +2819,18 @@ int QUICK_SELECT_DESC::cmp_prev(QUICK_RANGE *range_arg) return 0; /* key can't be to small */ KEY_PART *key_part = key_parts; + uint store_length; + for (char *key = range_arg->min_key, *end = key + range_arg->min_length; key < end; - key += key_part++->part_length) + key += store_length, key_part++) { int cmp; + store_length= key_part->store_length; if (key_part->null_bit) { // this key part allows null values; NULL is lower than everything else - if (*key++) + if (*key) { // the range is expecting a null value if (!key_part->field->is_null()) @@ -2858,9 +2839,11 @@ int QUICK_SELECT_DESC::cmp_prev(QUICK_RANGE *range_arg) } else if (key_part->field->is_null()) return 1; // null -- outside the range + key++; + store_length--; } if ((cmp = key_part->field->key_cmp((byte*) key, - key_part->part_length)) > 0) + key_part->length)) > 0) return 0; if (cmp < 0) return 1; @@ -2888,23 +2871,20 @@ bool QUICK_SELECT_DESC::range_reads_after_key(QUICK_RANGE *range_arg) bool QUICK_SELECT_DESC::test_if_null_range(QUICK_RANGE *range_arg, uint used_key_parts) { - uint offset,end; + uint offset, end; KEY_PART *key_part = key_parts, *key_part_end= key_part+used_key_parts; for (offset= 0, end = min(range_arg->min_length, range_arg->max_length) ; offset < end && key_part != key_part_end ; - offset += key_part++->part_length) + offset+= key_part++->store_length) { - uint null_length=test(key_part->null_bit); if (!memcmp((char*) range_arg->min_key+offset, (char*) range_arg->max_key+offset, - key_part->part_length + null_length)) - { - offset+=null_length; + key_part->store_length)) continue; - } - if (null_length && range_arg->min_key[offset]) + + if (key_part->null_bit && range_arg->min_key[offset]) return 1; // min_key is null and max_key isn't // Range doesn't cover NULL. This is ok if there is no more null parts break; @@ -2946,33 +2926,34 @@ static void print_key(KEY_PART *key_part,const char *key,uint used_length) { char buff[1024]; + const char *key_end= key+used_length; String tmp(buff,sizeof(buff),&my_charset_bin); + uint store_length; - for (uint length=0; - length < used_length ; - length+=key_part->part_length, key+=key_part->part_length, key_part++) + for (; key < key_end; key+=store_length, key_part++) { - Field *field=key_part->field; - if (length != 0) - fputc('/',DBUG_FILE); + Field *field= key_part->field; + store_length= key_part->store_length; + if (field->real_maybe_null()) { - length++; // null byte is not in part_length - if (*key++) + if (*key) { fwrite("NULL",sizeof(char),4,DBUG_FILE); continue; } + key++; // Skip null byte + store_length--; } - field->set_key_image((char*) key,key_part->part_length - - ((field->type() == FIELD_TYPE_BLOB) ? - HA_KEY_BLOB_LENGTH : 0), - field->charset()); + field->set_key_image((char*) key, key_part->length, field->charset()); field->val_str(&tmp); fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE); + if (key+store_length < key_end) + fputc('/',DBUG_FILE); } } + static void print_quick(QUICK_SELECT *quick,const key_map* needed_reg) { QUICK_RANGE *range; diff --git a/sql/opt_range.h b/sql/opt_range.h index bf10c02c295..2df9d93e1ef 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -35,7 +35,7 @@ typedef struct st_key_part { - uint16 key,part,part_length; + uint16 key,part, store_length, length; uint8 null_bit; Field *field; Field::imagetype image_type; @@ -68,7 +68,7 @@ class QUICK_RANGE :public Sql_alloc { class QUICK_SELECT { public: - bool next,dont_free; + bool next,dont_free,sorted; int error; uint index, max_used_key_length, used_key_parts; TABLE *head; @@ -89,11 +89,20 @@ public: int init() { return error=file->index_init(index); } virtual int get_next(); virtual bool reverse_sorted() { return 0; } - int cmp_next(QUICK_RANGE *range); bool unique_key_range(); }; +class QUICK_SELECT_GEOM: public QUICK_SELECT +{ +public: + QUICK_SELECT_GEOM(THD *thd, TABLE *table, uint index_arg, bool no_alloc) + :QUICK_SELECT(thd, table, index_arg, no_alloc) + {}; + virtual int get_next(); +}; + + class QUICK_SELECT_DESC: public QUICK_SELECT { public: diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index c6aff403f5b..cc2ba29dbd8 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -260,6 +260,14 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, thd->proc_info="update"; if (duplic != DUP_ERROR) table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); + /* + let's *try* to start bulk inserts. It won't necessary + start them as values_list.elements should be greater than + some - handler dependent - threshold. + So we call start_bulk_insert to perform nesessary checks on + values_list.elements, and - if nothing else - to initialize + the code to make the call of end_bulk_insert() below safe. + */ if (lock_type != TL_WRITE_DELAYED) table->file->start_bulk_insert(values_list.elements); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0a501dd86c2..b6ce2424c96 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4908,6 +4908,52 @@ Item * all_any_subquery_creator(Item *left_expr, /* + CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with + the proper arguments. This isn't very fast but it should work for most + cases. + + In the future ALTER TABLE will notice that only added indexes + and create these one by one for the existing table without having to do + a full rebuild. + + One should normally create all indexes with CREATE TABLE or ALTER TABLE. +*/ + +int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) +{ + List<create_field> fields; + List<Alter_drop> drop; + List<Alter_column> alter; + HA_CREATE_INFO create_info; + DBUG_ENTER("mysql_create_index"); + bzero((char*) &create_info,sizeof(create_info)); + create_info.db_type=DB_TYPE_DEFAULT; + create_info.default_table_charset= thd->variables.collation_database; + DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name, + &create_info, table_list, + fields, keys, drop, alter, 0, (ORDER*)0, + ALTER_ADD_INDEX, DUP_ERROR)); +} + + +int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop) +{ + List<create_field> fields; + List<Key> keys; + List<Alter_column> alter; + HA_CREATE_INFO create_info; + DBUG_ENTER("mysql_drop_index"); + bzero((char*) &create_info,sizeof(create_info)); + create_info.db_type=DB_TYPE_DEFAULT; + create_info.default_table_charset= thd->variables.collation_database; + DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name, + &create_info, table_list, + fields, keys, drop, alter, 0, (ORDER*)0, + ALTER_DROP_INDEX, DUP_ERROR)); +} + + +/* Multi update query pre-check SYNOPSIS diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c634dd0ab0e..bdc5091d386 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3746,7 +3746,8 @@ make_join_readinfo(JOIN *join, uint options) table->key_read=1; table->file->extra(HA_EXTRA_KEYREAD); } - else if (!table->used_keys.is_clear_all() && ! (tab->select && tab->select->quick)) + else if (!table->used_keys.is_clear_all() && + !(tab->select && tab->select->quick)) { // Only read index tree tab->index=find_shortest_key(table, & table->used_keys); tab->table->file->index_init(tab->index); @@ -6907,6 +6908,7 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx, key_part_end=key_part+table->key_info[idx].key_parts; key_part_map const_key_parts=table->const_key_parts[idx]; int reverse=0; + DBUG_ENTER("test_if_order_by_key"); for (; order ; order=order->next, const_key_parts>>=1) { @@ -6917,25 +6919,24 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx, Skip key parts that are constants in the WHERE clause. These are already skipped in the ORDER BY by const_expression_in_where() */ - while (const_key_parts & 1) - { - key_part++; const_key_parts>>=1; - } + for (; const_key_parts & 1 ; const_key_parts>>= 1) + key_part++; + if (key_part == key_part_end || key_part->field != field) - return 0; + DBUG_RETURN(0); /* set flag to 1 if we can use read-next on key, else to -1 */ - flag=(order->asc == !(key_part->key_part_flag & HA_REVERSE_SORT)) - ? 1 : -1; + flag= ((order->asc == !(key_part->key_part_flag & HA_REVERSE_SORT)) ? 1 : -1); if (reverse && flag != reverse) - return 0; + DBUG_RETURN(0); reverse=flag; // Remember if reverse key_part++; } *used_key_parts= (uint) (key_part - table->key_info[idx].key_part); - return reverse; + DBUG_RETURN(reverse); } + static uint find_shortest_key(TABLE *table, const key_map *usable_keys) { uint min_length= (uint) ~0; @@ -6958,18 +6959,20 @@ static uint find_shortest_key(TABLE *table, const key_map *usable_keys) } /* + Test if a second key is the subkey of the first one. + SYNOPSIS is_subkey() - key_part - first key parts - ref_key_part - second key parts - ref_key_part_end - last+1 part of the second key - DESCRIPTION - Test if a second key is the subkey of the first one. + key_part First key parts + ref_key_part Second key parts + ref_key_part_end Last+1 part of the second key + NOTE Second key MUST be shorter than the first one. + RETURN - 1 - is the subkey - 0 - otherwise + 1 is a subkey + 0 no sub key */ inline bool @@ -6983,20 +6986,21 @@ is_subkey(KEY_PART_INFO *key_part, KEY_PART_INFO *ref_key_part, } /* + Test if we can use one of the 'usable_keys' instead of 'ref' key for sorting + SYNOPSIS test_if_subkey() - ref - number of key, used for WHERE clause - usable_keys - keys for testing - DESCRIPTION - Test if we can use one of the 'usable_keys' instead of 'ref' key. + ref Number of key, used for WHERE clause + usable_keys Keys for testing + RETURN - MAX_KEY - if we can't use other key - the number of found key - otherwise + MAX_KEY If we can't use other key + the number of found key Otherwise */ static uint test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts, - const key_map& usable_keys) + const key_map *usable_keys) { uint nr; uint min_length= (uint) ~0; @@ -7007,7 +7011,7 @@ test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts, for (nr= 0 ; nr < table->keys ; nr++) { - if (usable_keys.is_set(nr) && + if (usable_keys->is_set(nr) && table->key_info[nr].key_length < min_length && table->key_info[nr].key_parts >= ref_key_parts && is_subkey(table->key_info[nr].key_part, ref_key_part, @@ -7051,12 +7055,12 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, if ((*tmp_order->item)->type() != Item::FIELD_ITEM) { usable_keys.clear_all(); - break; + DBUG_RETURN(0); } - usable_keys.intersect( - ((Item_field*) (*tmp_order->item))->field->part_of_sortkey); + usable_keys.intersect(((Item_field*) (*tmp_order->item))-> + field->part_of_sortkey); if (usable_keys.is_clear_all()) - break; // No usable keys + DBUG_RETURN(0); // No usable keys } ref_key= -1; @@ -7092,9 +7096,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, keys */ if (table->used_keys.is_set(ref_key)) - usable_keys.merge(table->used_keys); + usable_keys.intersect(table->used_keys); if ((new_ref_key= test_if_subkey(order, table, ref_key, ref_key_parts, - usable_keys)) < MAX_KEY) + &usable_keys)) < MAX_KEY) { /* Found key that can be used to retrieve data in sorted order */ if (tab->ref.key >= 0) @@ -7154,6 +7158,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, /* fall through */ } } + else if (select && select->quick) + select->quick->sorted= 1; DBUG_RETURN(1); /* No need to sort */ } } @@ -7292,9 +7298,9 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, For impossible ranges (like when doing a lookup on NULL on a NOT NULL field, quick will contain an empty record set. */ - if (!(select->quick= tab->type == JT_FT ? - new FT_SELECT(thd, table, tab->ref.key) : - get_quick_select_for_ref(thd, table, &tab->ref))) + if (!(select->quick= (tab->type == JT_FT ? + new FT_SELECT(thd, table, tab->ref.key) : + get_quick_select_for_ref(thd, table, &tab->ref)))) goto err; } } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 17ea4cd540e..d5f77bf545d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -34,19 +34,19 @@ const char *primary_key_name= "PRIMARY"; static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end); static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end); static int copy_data_between_tables(TABLE *from,TABLE *to, - List<create_field> &create, - enum enum_duplicates handle_duplicates, - uint order_num, ORDER *order, - ha_rows *copied,ha_rows *deleted); + List<create_field> &create, + enum enum_duplicates handle_duplicates, + uint order_num, ORDER *order, + ha_rows *copied,ha_rows *deleted); /* delete (drop) tables. SYNOPSIS mysql_rm_table() - thd Thread handle - tables List of tables to delete - if_exists If 1, don't give error if one table doesn't exists + thd Thread handle + tables List of tables to delete + if_exists If 1, don't give error if one table doesn't exists NOTES Will delete all tables that can be deleted and give a compact error @@ -57,13 +57,13 @@ static int copy_data_between_tables(TABLE *from,TABLE *to, Wait if global_read_lock (FLUSH TABLES WITH READ LOCK) is set. RETURN - 0 ok. In this case ok packet is sent to user - -1 Error (Error message given but not sent to user) + 0 ok. In this case ok packet is sent to user + -1 Error (Error message given but not sent to user) */ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, - my_bool drop_temporary) + my_bool drop_temporary) { int error= 0; DBUG_ENTER("mysql_rm_table"); @@ -79,7 +79,7 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, if (thd->global_read_lock) { my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0), - tables->real_name); + tables->real_name); error= 1; goto err; } @@ -111,23 +111,23 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, SYNOPSIS mysql_rm_table_part2_with_lock() - thd Thread handle - tables List of tables to delete - if_exists If 1, don't give error if one table doesn't exists - dont_log_query Don't write query to log files + thd Thread handle + tables List of tables to delete + if_exists If 1, don't give error if one table doesn't exists + dont_log_query Don't write query to log files NOTES Works like documented in mysql_rm_table(), but don't check global_read_lock and don't send_ok packet to server. RETURN - 0 ok - 1 error + 0 ok + 1 error */ int mysql_rm_table_part2_with_lock(THD *thd, - TABLE_LIST *tables, bool if_exists, - bool drop_temporary, bool dont_log_query) + TABLE_LIST *tables, bool if_exists, + bool drop_temporary, bool dont_log_query) { int error; thd->mysys_var->current_mutex= &LOCK_open; @@ -135,7 +135,7 @@ int mysql_rm_table_part2_with_lock(THD *thd, VOID(pthread_mutex_lock(&LOCK_open)); error=mysql_rm_table_part2(thd,tables, if_exists, drop_temporary, - dont_log_query); + dont_log_query); pthread_mutex_unlock(&LOCK_open); @@ -152,12 +152,12 @@ int mysql_rm_table_part2_with_lock(THD *thd, SYNOPSIS mysql_rm_table_part2() - thd Thread handler - tables Tables to drop - if_exists If set, don't give an error if table doesn't exists. - In this case we give an warning of level 'NOTE' - drop_temporary Only drop temporary tables - dont_log_query Don't log the query + thd Thread handler + tables Tables to drop + if_exists If set, don't give an error if table doesn't exists. + In this case we give an warning of level 'NOTE' + drop_temporary Only drop temporary tables + dont_log_query Don't log the query TODO: When logging to the binary log, we should log @@ -170,16 +170,16 @@ int mysql_rm_table_part2_with_lock(THD *thd, not all. RETURN - 0 ok - 1 Error - -1 Thread was killed + 0 ok + 1 Error + -1 Thread was killed */ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, - bool drop_temporary, bool dont_log_query) + bool drop_temporary, bool dont_log_query) { TABLE_LIST *table; - char path[FN_REFLEN], *alias; + char path[FN_REFLEN], *alias; String wrong_tables; int error; bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0; @@ -195,7 +195,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, if (!close_temporary_table(thd, db, table->real_name)) { tmp_table_deleted=1; - continue; // removed temporary table + continue; // removed temporary table } error=0; @@ -204,13 +204,13 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, abort_locked_tables(thd,db,table->real_name); while (remove_table_from_cache(thd,db,table->real_name) && !thd->killed) { - dropping_tables++; - (void) pthread_cond_wait(&COND_refresh,&LOCK_open); - dropping_tables--; + dropping_tables++; + (void) pthread_cond_wait(&COND_refresh,&LOCK_open); + dropping_tables--; } drop_locked_tables(thd,db,table->real_name); if (thd->killed) - DBUG_RETURN(-1); + DBUG_RETURN(-1); alias= (lower_case_table_names == 2) ? table->alias : table->real_name; /* remove form file and isam files */ strxmov(path, mysql_data_home, "/", db, "/", alias, reg_ext, NullS); @@ -219,37 +219,37 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, if (drop_temporary || access(path,F_OK)) { if (if_exists) - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, - ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), - table->real_name); + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), + table->real_name); else - error= 1; + error= 1; } else { char *end; db_type table_type= get_table_type(path); - *(end=fn_ext(path))=0; // Remove extension for delete + *(end=fn_ext(path))=0; // Remove extension for delete error=ha_delete_table(table_type, path); if (error == ENOENT && if_exists) - error = 0; + error = 0; if (error == HA_ERR_ROW_IS_REFERENCED) { - /* the table is referenced by a foreign key constraint */ - foreign_key_error=1; + /* the table is referenced by a foreign key constraint */ + foreign_key_error=1; } if (!error || error == ENOENT) { - /* Delete the table definition file */ - strmov(end,reg_ext); - if (!(error=my_delete(path,MYF(MY_WME)))) - some_tables_deleted=1; + /* Delete the table definition file */ + strmov(end,reg_ext); + if (!(error=my_delete(path,MYF(MY_WME)))) + some_tables_deleted=1; } } if (error) { if (wrong_tables.length()) - wrong_tables.append(','); + wrong_tables.append(','); wrong_tables.append(String(table->real_name,system_charset_info)); } } @@ -262,10 +262,10 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, mysql_update_log.write(thd, thd->query,thd->query_length); if (mysql_bin_log.is_open()) { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, - tmp_table_deleted && !some_tables_deleted); - mysql_bin_log.write(&qinfo); + thd->clear_error(); + Query_log_event qinfo(thd, thd->query, thd->query_length, + tmp_table_deleted && !some_tables_deleted); + mysql_bin_log.write(&qinfo); } } } @@ -285,19 +285,16 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, int quick_rm_table(enum db_type base,const char *db, - const char *table_name) + const char *table_name) { char path[FN_REFLEN]; int error=0; - if (snprintf(path, sizeof(path), "%s/%s/%s%s", - mysql_data_home, db, table_name, reg_ext)>= (int)sizeof(path)) - return 1; + my_snprintf(path, sizeof(path), "%s/%s/%s%s", + mysql_data_home, db, table_name, reg_ext); unpack_filename(path,path); if (my_delete(path,MYF(0))) error=1; /* purecov: inspected */ - if (snprintf(path, sizeof(path), "%s/%s/%s", - mysql_data_home, db, table_name)>= (int)sizeof(path)) - return 1; + my_snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home, db, table_name); unpack_filename(path,path); return ha_delete_table(base,path) || error; } @@ -331,32 +328,32 @@ static int sort_keys(KEY *a, KEY *b) return 1; } else if (b->flags & HA_NOSAME) - return 1; // Prefer b + return 1; // Prefer b if ((a->flags ^ b->flags) & HA_FULLTEXT) { return (a->flags & HA_FULLTEXT) ? 1 : -1; } /* - Prefer original key order. usable_key_parts contains here + Prefer original key order. usable_key_parts contains here the original key position. */ return ((a->usable_key_parts < b->usable_key_parts) ? -1 : - (a->usable_key_parts > b->usable_key_parts) ? 1 : - 0); + (a->usable_key_parts > b->usable_key_parts) ? 1 : + 0); } /* Check TYPELIB (set or enum) for duplicates - + SYNOPSIS check_duplicates_in_interval() set_or_name "SET" or "ENUM" string for warning message - name name of the checked column - typelib list of values for the column + name name of the checked column + typelib list of values for the column DESCRIPTION - This function prints an warning for each value in list + This function prints an warning for each value in list which has some duplicates on its right RETURN VALUES @@ -364,7 +361,7 @@ static int sort_keys(KEY *a, KEY *b) */ void check_duplicates_in_interval(const char *set_or_name, - const char *name, TYPELIB *typelib) + const char *name, TYPELIB *typelib) { unsigned int old_count= typelib->count; const char **old_type_names= typelib->type_names; @@ -379,9 +376,9 @@ void check_duplicates_in_interval(const char *set_or_name, if (find_type((char*)*cur_value,typelib,1)) { push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_NOTE, - ER_DUPLICATED_VALUE_IN_TYPE, - ER(ER_DUPLICATED_VALUE_IN_TYPE), - name,*cur_value,set_or_name); + ER_DUPLICATED_VALUE_IN_TYPE, + ER(ER_DUPLICATED_VALUE_IN_TYPE), + name,*cur_value,set_or_name); } } typelib->count= old_count; @@ -393,34 +390,34 @@ void check_duplicates_in_interval(const char *set_or_name, SYNOPSIS mysql_prepare_table() - thd Thread object - create_info Create information (like MAX_ROWS) - fields List of fields to create - keys List of keys to create + thd Thread object + create_info Create information (like MAX_ROWS) + fields List of fields to create + keys List of keys to create DESCRIPTION Prepares the table and key structures for table creation. RETURN VALUES - 0 ok - -1 error + 0 ok + -1 error */ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, - List<create_field> &fields, - List<Key> &keys, bool tmp_table, uint &db_options, - handler *file, KEY *&key_info_buffer, - uint &key_count, int select_field_count) + List<create_field> &fields, + List<Key> &keys, bool tmp_table, uint &db_options, + handler *file, KEY *&key_info_buffer, + uint *key_count, int select_field_count) { - const char *key_name; - create_field *sql_field,*dup_field; - uint field,null_fields,blob_columns; - ulong pos; - KEY *key_info; + const char *key_name; + create_field *sql_field,*dup_field; + uint field,null_fields,blob_columns; + ulong pos; + KEY *key_info; KEY_PART_INFO *key_part_info; - int timestamps= 0, timestamps_with_niladic= 0; - int field_no,dup_no; - int select_field_pos,auto_increment=0; + int timestamps= 0, timestamps_with_niladic= 0; + int field_no,dup_no; + int select_field_pos,auto_increment=0; DBUG_ENTER("mysql_prepare_table"); List_iterator<create_field> it(fields),it2(fields); @@ -450,13 +447,13 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp); DBUG_RETURN(-1); } - + sql_field->create_length_to_internal_length(); /* Don't pack keys in old tables if the user has requested this */ if ((sql_field->flags & BLOB_FLAG) || - sql_field->sql_type == FIELD_TYPE_VAR_STRING && - create_info->row_type != ROW_TYPE_FIXED) + sql_field->sql_type == FIELD_TYPE_VAR_STRING && + create_info->row_type != ROW_TYPE_FIXED) { db_options|=HA_OPTION_PACK_RECORD; } @@ -473,35 +470,35 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++) { if (my_strcasecmp(system_charset_info, - sql_field->field_name, - dup_field->field_name) == 0) + sql_field->field_name, + dup_field->field_name) == 0) { - /* - If this was a CREATE ... SELECT statement, accept a field - redefinition if we are changing a field in the SELECT part - */ - if (field_no < select_field_pos || dup_no >= select_field_pos) - { - my_error(ER_DUP_FIELDNAME,MYF(0),sql_field->field_name); - DBUG_RETURN(-1); - } - else - { - /* Field redefined */ - sql_field->sql_type= dup_field->sql_type; - sql_field->charset= (dup_field->charset ? - dup_field->charset : - create_info->default_table_charset); - sql_field->length= dup_field->length; - sql_field->pack_length= dup_field->pack_length; - sql_field->create_length_to_internal_length(); - sql_field->decimals= dup_field->decimals; - sql_field->flags= dup_field->flags; - sql_field->unireg_check= dup_field->unireg_check; - it2.remove(); // Remove first (create) definition - select_field_pos--; - break; - } + /* + If this was a CREATE ... SELECT statement, accept a field + redefinition if we are changing a field in the SELECT part + */ + if (field_no < select_field_pos || dup_no >= select_field_pos) + { + my_error(ER_DUP_FIELDNAME,MYF(0),sql_field->field_name); + DBUG_RETURN(-1); + } + else + { + /* Field redefined */ + sql_field->sql_type= dup_field->sql_type; + sql_field->charset= (dup_field->charset ? + dup_field->charset : + create_info->default_table_charset); + sql_field->length= dup_field->length; + sql_field->pack_length= dup_field->pack_length; + sql_field->create_length_to_internal_length(); + sql_field->decimals= dup_field->decimals; + sql_field->flags= dup_field->flags; + sql_field->unireg_check= dup_field->unireg_check; + it2.remove(); // Remove first (create) definition + select_field_pos--; + break; + } } } it2.rewind(); @@ -522,11 +519,11 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, case FIELD_TYPE_TINY_BLOB: case FIELD_TYPE_LONG_BLOB: sql_field->pack_flag=FIELDFLAG_BLOB | - pack_length_to_packflag(sql_field->pack_length - - portable_sizeof_char_ptr); + pack_length_to_packflag(sql_field->pack_length - + portable_sizeof_char_ptr); if (sql_field->charset->state & MY_CS_BINSORT) - sql_field->pack_flag|=FIELDFLAG_BINARY; - sql_field->length=8; // Unireg field length + sql_field->pack_flag|=FIELDFLAG_BINARY; + sql_field->length=8; // Unireg field length sql_field->unireg_check=Field::BLOB_FIELD; blob_columns++; break; @@ -534,49 +531,49 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, #ifdef HAVE_SPATIAL if (!(file->table_flags() & HA_HAS_GEOMETRY)) { - my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED), - MYF(0), "GEOMETRY"); - DBUG_RETURN(-1); + my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED), + MYF(0), "GEOMETRY"); + DBUG_RETURN(-1); } sql_field->pack_flag=FIELDFLAG_GEOM | - pack_length_to_packflag(sql_field->pack_length - - portable_sizeof_char_ptr); + pack_length_to_packflag(sql_field->pack_length - + portable_sizeof_char_ptr); if (sql_field->charset->state & MY_CS_BINSORT) - sql_field->pack_flag|=FIELDFLAG_BINARY; - sql_field->length=8; // Unireg field length + sql_field->pack_flag|=FIELDFLAG_BINARY; + sql_field->length=8; // Unireg field length sql_field->unireg_check=Field::BLOB_FIELD; blob_columns++; break; #else my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED), MYF(0), - sym_group_geom.name, sym_group_geom.needed_define); + sym_group_geom.name, sym_group_geom.needed_define); DBUG_RETURN(-1); #endif /*HAVE_SPATIAL*/ case FIELD_TYPE_VAR_STRING: case FIELD_TYPE_STRING: sql_field->pack_flag=0; if (sql_field->charset->state & MY_CS_BINSORT) - sql_field->pack_flag|=FIELDFLAG_BINARY; + sql_field->pack_flag|=FIELDFLAG_BINARY; break; case FIELD_TYPE_ENUM: sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) | - FIELDFLAG_INTERVAL; + FIELDFLAG_INTERVAL; if (sql_field->charset->state & MY_CS_BINSORT) - sql_field->pack_flag|=FIELDFLAG_BINARY; + sql_field->pack_flag|=FIELDFLAG_BINARY; sql_field->unireg_check=Field::INTERVAL_FIELD; check_duplicates_in_interval("ENUM",sql_field->field_name, - sql_field->interval); + sql_field->interval); break; case FIELD_TYPE_SET: sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) | - FIELDFLAG_BITFIELD; + FIELDFLAG_BITFIELD; if (sql_field->charset->state & MY_CS_BINSORT) - sql_field->pack_flag|=FIELDFLAG_BINARY; + sql_field->pack_flag|=FIELDFLAG_BINARY; sql_field->unireg_check=Field::BIT_FIELD; check_duplicates_in_interval("SET",sql_field->field_name, - sql_field->interval); + sql_field->interval); break; - case FIELD_TYPE_DATE: // Rest of string types + case FIELD_TYPE_DATE: // Rest of string types case FIELD_TYPE_NEWDATE: case FIELD_TYPE_TIME: case FIELD_TYPE_DATETIME: @@ -587,27 +584,27 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, /* We should replace old TIMESTAMP fields with their newer analogs */ if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD) { - if (!timestamps) - { - sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD; - timestamps_with_niladic++; - } - else - sql_field->unireg_check= Field::NONE; + if (!timestamps) + { + sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD; + timestamps_with_niladic++; + } + else + sql_field->unireg_check= Field::NONE; } else if (sql_field->unireg_check != Field::NONE) - timestamps_with_niladic++; - + timestamps_with_niladic++; + timestamps++; /* fall-through */ default: sql_field->pack_flag=(FIELDFLAG_NUMBER | - (sql_field->flags & UNSIGNED_FLAG ? 0 : - FIELDFLAG_DECIMAL) | - (sql_field->flags & ZEROFILL_FLAG ? - FIELDFLAG_ZEROFILL : 0) | - f_settype((uint) sql_field->sql_type) | - (sql_field->decimals << FIELDFLAG_DEC_SHIFT)); + (sql_field->flags & UNSIGNED_FLAG ? 0 : + FIELDFLAG_DECIMAL) | + (sql_field->flags & ZEROFILL_FLAG ? + FIELDFLAG_ZEROFILL : 0) | + f_settype((uint) sql_field->sql_type) | + (sql_field->decimals << FIELDFLAG_DEC_SHIFT)); break; } if (!(sql_field->flags & NOT_NULL_FLAG)) @@ -644,13 +641,13 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, List_iterator<Key> key_iterator(keys); uint key_parts=0, fk_key_count=0; - List<Key> keys_in_order; // Add new keys here + List<Key> keys_in_order; // Add new keys here bool primary_key=0,unique_key=0; Key *key; uint tmp, key_number; /* Calculate number of key segements */ - key_count=0; + *key_count= 0; while ((key=key_iterator++)) { @@ -659,16 +656,16 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, fk_key_count++; foreign_key *fk_key= (foreign_key*) key; if (fk_key->ref_columns.elements && - fk_key->ref_columns.elements != fk_key->columns.elements) + fk_key->ref_columns.elements != fk_key->columns.elements) { - my_error(ER_WRONG_FK_DEF, MYF(0), fk_key->name ? fk_key->name : - "foreign key without name", - ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF)); - DBUG_RETURN(-1); + my_error(ER_WRONG_FK_DEF, MYF(0), fk_key->name ? fk_key->name : + "foreign key without name", + ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF)); + DBUG_RETURN(-1); } continue; } - key_count++; + (*key_count)++; tmp=max(file->max_key_parts(),MAX_REF_PARTS); if (key->columns.elements > tmp) { @@ -682,23 +679,23 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } key_parts+=key->columns.elements; if (key->name && !tmp_table && - !my_strcasecmp(system_charset_info,key->name,primary_key_name)) + !my_strcasecmp(system_charset_info,key->name,primary_key_name)) { my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name); DBUG_RETURN(-1); } } tmp=min(file->max_keys(), MAX_KEY); - if (key_count > tmp) + if (*key_count > tmp) { my_error(ER_TOO_MANY_KEYS,MYF(0),tmp); DBUG_RETURN(-1); } - key_info_buffer=key_info=(KEY*) sql_calloc(sizeof(KEY)*key_count); + key_info_buffer=key_info=(KEY*) sql_calloc(sizeof(KEY)* *key_count); key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts); if (!key_info_buffer || ! key_part_info) - DBUG_RETURN(-1); // Out of memory + DBUG_RETURN(-1); // Out of memory key_iterator.rewind(); key_number=0; @@ -709,25 +706,25 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, switch(key->type){ case Key::MULTIPLE: - key_info->flags = 0; - break; + key_info->flags = 0; + break; case Key::FULLTEXT: - key_info->flags = HA_FULLTEXT; - break; + key_info->flags = HA_FULLTEXT; + break; case Key::SPATIAL: #ifdef HAVE_SPATIAL - key_info->flags = HA_SPATIAL; - break; + key_info->flags = HA_SPATIAL; + break; #else - my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0), - sym_group_geom.name, sym_group_geom.needed_define); - DBUG_RETURN(-1); + my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); + DBUG_RETURN(-1); #endif case Key::FOREIGN_KEY: - key_number--; // Skip this key + key_number--; // Skip this key continue; default: - key_info->flags = HA_NOSAME; + key_info->flags = HA_NOSAME; } key_info->key_parts=(uint8) key->columns.elements; @@ -739,8 +736,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { if (!(file->table_flags() & HA_CAN_FULLTEXT)) { - my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0)); - DBUG_RETURN(-1); + my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0)); + DBUG_RETURN(-1); } } /* @@ -756,9 +753,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { if (key_info->key_parts != 1) { - my_printf_error(ER_WRONG_ARGUMENTS, - ER(ER_WRONG_ARGUMENTS),MYF(0),"SPATIAL INDEX"); - DBUG_RETURN(-1); + my_printf_error(ER_WRONG_ARGUMENTS, + ER(ER_WRONG_ARGUMENTS),MYF(0),"SPATIAL INDEX"); + DBUG_RETURN(-1); } } else @@ -767,17 +764,17 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, #ifdef HAVE_RTREE_KEYS if ((key_info->key_parts & 1) == 1) { - my_printf_error(ER_WRONG_ARGUMENTS, - ER(ER_WRONG_ARGUMENTS),MYF(0),"RTREE INDEX"); - DBUG_RETURN(-1); + my_printf_error(ER_WRONG_ARGUMENTS, + ER(ER_WRONG_ARGUMENTS),MYF(0),"RTREE INDEX"); + DBUG_RETURN(-1); } /* TODO: To be deleted */ my_printf_error(ER_NOT_SUPPORTED_YET, ER(ER_NOT_SUPPORTED_YET), - MYF(0), "RTREE INDEX"); + MYF(0), "RTREE INDEX"); DBUG_RETURN(-1); #else my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0), - sym_group_rtree.name, sym_group_rtree.needed_define); + sym_group_rtree.name, sym_group_rtree.needed_define); DBUG_RETURN(-1); #endif } @@ -789,106 +786,106 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, it.rewind(); field=0; while ((sql_field=it++) && - my_strcasecmp(system_charset_info, - column->field_name, - sql_field->field_name)) - field++; + my_strcasecmp(system_charset_info, + column->field_name, + sql_field->field_name)) + field++; if (!sql_field) { - my_printf_error(ER_KEY_COLUMN_DOES_NOT_EXITS, - ER(ER_KEY_COLUMN_DOES_NOT_EXITS),MYF(0), - column->field_name); - DBUG_RETURN(-1); + my_printf_error(ER_KEY_COLUMN_DOES_NOT_EXITS, + ER(ER_KEY_COLUMN_DOES_NOT_EXITS),MYF(0), + column->field_name); + DBUG_RETURN(-1); } /* for fulltext keys keyseg length is 1 for blobs (it's ignored in - ft code anyway, and 0 (set to column width later) for char's. - it has to be correct col width for char's, as char data are not - prefixed with length (unlike blobs, where ft code takes data length - from a data prefix, ignoring column->length). + ft code anyway, and 0 (set to column width later) for char's. + it has to be correct col width for char's, as char data are not + prefixed with length (unlike blobs, where ft code takes data length + from a data prefix, ignoring column->length). */ if (key->type == Key::FULLTEXT) { - if ((sql_field->sql_type != FIELD_TYPE_STRING && - sql_field->sql_type != FIELD_TYPE_VAR_STRING && - !f_is_blob(sql_field->pack_flag)) || - sql_field->charset == &my_charset_bin || - sql_field->charset->state & MY_CS_NONTEXT || // ucs2 doesn't work yet - (ft_key_charset && sql_field->charset != ft_key_charset)) - { - my_printf_error(ER_BAD_FT_COLUMN,ER(ER_BAD_FT_COLUMN),MYF(0), - column->field_name); - DBUG_RETURN(-1); - } - ft_key_charset=sql_field->charset; - /* - for fulltext keys keyseg length is 1 for blobs (it's ignored in ft - code anyway, and 0 (set to column width later) for char's. it has - to be correct col width for char's, as char data are not prefixed - with length (unlike blobs, where ft code takes data length from a - data prefix, ignoring column->length). - */ - column->length=test(f_is_blob(sql_field->pack_flag)); + if ((sql_field->sql_type != FIELD_TYPE_STRING && + sql_field->sql_type != FIELD_TYPE_VAR_STRING && + !f_is_blob(sql_field->pack_flag)) || + sql_field->charset == &my_charset_bin || + sql_field->charset->state & MY_CS_NONTEXT || // ucs2 doesn't work yet + (ft_key_charset && sql_field->charset != ft_key_charset)) + { + my_printf_error(ER_BAD_FT_COLUMN,ER(ER_BAD_FT_COLUMN),MYF(0), + column->field_name); + DBUG_RETURN(-1); + } + ft_key_charset=sql_field->charset; + /* + for fulltext keys keyseg length is 1 for blobs (it's ignored in ft + code anyway, and 0 (set to column width later) for char's. it has + to be correct col width for char's, as char data are not prefixed + with length (unlike blobs, where ft code takes data length from a + data prefix, ignoring column->length). + */ + column->length=test(f_is_blob(sql_field->pack_flag)); } else { - column->length*= sql_field->charset->mbmaxlen; - - if (f_is_blob(sql_field->pack_flag)) - { - if (!(file->table_flags() & HA_BLOB_KEY)) - { - my_printf_error(ER_BLOB_USED_AS_KEY,ER(ER_BLOB_USED_AS_KEY),MYF(0), - column->field_name); - DBUG_RETURN(-1); - } - if (!column->length) - { - my_printf_error(ER_BLOB_KEY_WITHOUT_LENGTH, - ER(ER_BLOB_KEY_WITHOUT_LENGTH),MYF(0), - column->field_name); - DBUG_RETURN(-1); - } - } + column->length*= sql_field->charset->mbmaxlen; + + if (f_is_blob(sql_field->pack_flag)) + { + if (!(file->table_flags() & HA_BLOB_KEY)) + { + my_printf_error(ER_BLOB_USED_AS_KEY,ER(ER_BLOB_USED_AS_KEY),MYF(0), + column->field_name); + DBUG_RETURN(-1); + } + if (!column->length) + { + my_printf_error(ER_BLOB_KEY_WITHOUT_LENGTH, + ER(ER_BLOB_KEY_WITHOUT_LENGTH),MYF(0), + column->field_name); + DBUG_RETURN(-1); + } + } #ifdef HAVE_SPATIAL - if (key->type == Key::SPATIAL) - { - if (!column->length ) - { - /* - BAR: 4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case - Lately we'll extend this code to support more dimensions - */ - column->length=4*sizeof(double); - } - } + if (key->type == Key::SPATIAL) + { + if (!column->length ) + { + /* + BAR: 4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case + Lately we'll extend this code to support more dimensions + */ + column->length=4*sizeof(double); + } + } #endif - if (!(sql_field->flags & NOT_NULL_FLAG)) - { - if (key->type == Key::PRIMARY) - { - /* Implicitly set primary key fields to NOT NULL for ISO conf. */ - sql_field->flags|= NOT_NULL_FLAG; - sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL; - } - else - key_info->flags|= HA_NULL_PART_KEY; - if (!(file->table_flags() & HA_NULL_KEY)) - { - my_printf_error(ER_NULL_COLUMN_IN_INDEX,ER(ER_NULL_COLUMN_IN_INDEX), - MYF(0),column->field_name); - DBUG_RETURN(-1); - } - if (key->type == Key::SPATIAL) - { - my_error(ER_SPATIAL_CANT_HAVE_NULL, MYF(0)); - DBUG_RETURN(-1); - } - } - if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER) - { - if (column_nr == 0 || (file->table_flags() & HA_AUTO_PART_KEY)) - auto_increment--; // Field is used - } + if (!(sql_field->flags & NOT_NULL_FLAG)) + { + if (key->type == Key::PRIMARY) + { + /* Implicitly set primary key fields to NOT NULL for ISO conf. */ + sql_field->flags|= NOT_NULL_FLAG; + sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL; + } + else + key_info->flags|= HA_NULL_PART_KEY; + if (!(file->table_flags() & HA_NULL_KEY)) + { + my_printf_error(ER_NULL_COLUMN_IN_INDEX,ER(ER_NULL_COLUMN_IN_INDEX), + MYF(0),column->field_name); + DBUG_RETURN(-1); + } + if (key->type == Key::SPATIAL) + { + my_error(ER_SPATIAL_CANT_HAVE_NULL, MYF(0)); + DBUG_RETURN(-1); + } + } + if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER) + { + if (column_nr == 0 || (file->table_flags() & HA_AUTO_PART_KEY)) + auto_increment--; // Field is used + } } key_part_info->fieldnr= field; @@ -897,79 +894,77 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, uint length=sql_field->pack_length; if (column->length) { - if (f_is_blob(sql_field->pack_flag)) - { - if ((length=column->length) > file->max_key_length() || - length > file->max_key_part_length()) - { - length=min(file->max_key_length(), file->max_key_part_length()); - if (key->type == Key::MULTIPLE) - { - /* not a critical problem */ - char warn_buff[MYSQL_ERRMSG_SIZE]; - if (snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY), - length)>= (int)sizeof(warn_buff)) - DBUG_RETURN(-1); - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_TOO_LONG_KEY, warn_buff); - } - else - { - my_error(ER_TOO_LONG_KEY,MYF(0),length); - DBUG_RETURN(-1); - } - } - } - else if (!f_is_geom(sql_field->pack_flag) && - (column->length > length || - ((f_is_packed(sql_field->pack_flag) || - ((file->table_flags() & HA_NO_PREFIX_CHAR_KEYS) && - (key_info->flags & HA_NOSAME))) && - column->length != length))) - { - my_error(ER_WRONG_SUB_KEY,MYF(0)); - DBUG_RETURN(-1); - } - else if (!(file->table_flags() & HA_NO_PREFIX_CHAR_KEYS)) - length=column->length; + if (f_is_blob(sql_field->pack_flag)) + { + if ((length=column->length) > file->max_key_length() || + length > file->max_key_part_length()) + { + length=min(file->max_key_length(), file->max_key_part_length()); + if (key->type == Key::MULTIPLE) + { + /* not a critical problem */ + char warn_buff[MYSQL_ERRMSG_SIZE]; + my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY), + length); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TOO_LONG_KEY, warn_buff); + } + else + { + my_error(ER_TOO_LONG_KEY,MYF(0),length); + DBUG_RETURN(-1); + } + } + } + else if (!f_is_geom(sql_field->pack_flag) && + (column->length > length || + ((f_is_packed(sql_field->pack_flag) || + ((file->table_flags() & HA_NO_PREFIX_CHAR_KEYS) && + (key_info->flags & HA_NOSAME))) && + column->length != length))) + { + my_error(ER_WRONG_SUB_KEY,MYF(0)); + DBUG_RETURN(-1); + } + else if (!(file->table_flags() & HA_NO_PREFIX_CHAR_KEYS)) + length=column->length; } else if (length == 0) { - my_printf_error(ER_WRONG_KEY_COLUMN, ER(ER_WRONG_KEY_COLUMN), MYF(0), - column->field_name); - DBUG_RETURN(-1); + my_printf_error(ER_WRONG_KEY_COLUMN, ER(ER_WRONG_KEY_COLUMN), MYF(0), + column->field_name); + DBUG_RETURN(-1); } if (length > file->max_key_part_length()) { - length=file->max_key_part_length(); - if (key->type == Key::MULTIPLE) - { - /* not a critical problem */ - char warn_buff[MYSQL_ERRMSG_SIZE]; - if (snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY), - length)>= (int)sizeof(warn_buff)) - DBUG_RETURN(-1); - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_TOO_LONG_KEY, warn_buff); - } - else - { - my_error(ER_TOO_LONG_KEY,MYF(0),length); - DBUG_RETURN(-1); - } + length=file->max_key_part_length(); + if (key->type == Key::MULTIPLE) + { + /* not a critical problem */ + char warn_buff[MYSQL_ERRMSG_SIZE]; + my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY), + length); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TOO_LONG_KEY, warn_buff); + } + else + { + my_error(ER_TOO_LONG_KEY,MYF(0),length); + DBUG_RETURN(-1); + } } key_part_info->length=(uint16) length; /* Use packed keys for long strings on the first column */ if (!(db_options & HA_OPTION_NO_PACK_KEYS) && - (length >= KEY_DEFAULT_PACK_LENGTH && - (sql_field->sql_type == FIELD_TYPE_STRING || - sql_field->sql_type == FIELD_TYPE_VAR_STRING || - sql_field->pack_flag & FIELDFLAG_BLOB))) + (length >= KEY_DEFAULT_PACK_LENGTH && + (sql_field->sql_type == FIELD_TYPE_STRING || + sql_field->sql_type == FIELD_TYPE_VAR_STRING || + sql_field->pack_flag & FIELDFLAG_BLOB))) { - if (column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) - key_info->flags|= HA_BINARY_PACK_KEY; - else - key_info->flags|= HA_PACK_KEY; + if (column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) + key_info->flags|= HA_BINARY_PACK_KEY; + else + key_info->flags|= HA_PACK_KEY; } key_length+=length; key_part_info++; @@ -977,25 +972,25 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, /* Create the key name based on the first column (if not given) */ if (column_nr == 0) { - if (key->type == Key::PRIMARY) - { - if (primary_key) - { - my_error(ER_MULTIPLE_PRI_KEY,MYF(0)); - DBUG_RETURN(-1); - } - key_name=primary_key_name; - primary_key=1; - } - else if (!(key_name = key->name)) - key_name=make_unique_key_name(sql_field->field_name, - key_info_buffer,key_info); - if (check_if_keyname_exists(key_name,key_info_buffer,key_info)) - { - my_error(ER_DUP_KEYNAME,MYF(0),key_name); - DBUG_RETURN(-1); - } - key_info->name=(char*) key_name; + if (key->type == Key::PRIMARY) + { + if (primary_key) + { + my_error(ER_MULTIPLE_PRI_KEY,MYF(0)); + DBUG_RETURN(-1); + } + key_name=primary_key_name; + primary_key=1; + } + else if (!(key_name = key->name)) + key_name=make_unique_key_name(sql_field->field_name, + key_info_buffer,key_info); + if (check_if_keyname_exists(key_name,key_info_buffer,key_info)) + { + my_error(ER_DUP_KEYNAME,MYF(0),key_name); + DBUG_RETURN(-1); + } + key_info->name=(char*) key_name; } } if (!key_info->name || check_column_name(key_info->name)) @@ -1026,25 +1021,27 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, DBUG_RETURN(-1); } /* Sort keys in optimized order */ - qsort((gptr) key_info_buffer, key_count, sizeof(KEY), (qsort_cmp) sort_keys); + qsort((gptr) key_info_buffer, *key_count, sizeof(KEY), + (qsort_cmp) sort_keys); DBUG_RETURN(0); } + /* Create a table SYNOPSIS mysql_create_table() - thd Thread object - db Database - table_name Table name - create_info Create information (like MAX_ROWS) - fields List of fields to create - keys List of keys to create - tmp_table Set to 1 if this is an internal temporary table - (From ALTER TABLE) - no_log Don't log the query to binary log. + thd Thread object + db Database + table_name Table name + create_info Create information (like MAX_ROWS) + fields List of fields to create + keys List of keys to create + tmp_table Set to 1 if this is an internal temporary table + (From ALTER TABLE) + no_log Don't log the query to binary log. DESCRIPTION If one creates a temporary table, this is automaticly opened @@ -1055,23 +1052,23 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, and must be zero for standard create of table. RETURN VALUES - 0 ok - -1 error + 0 ok + -1 error */ int mysql_create_table(THD *thd,const char *db, const char *table_name, - HA_CREATE_INFO *create_info, - List<create_field> &fields, - List<Key> &keys,bool tmp_table,bool no_log, - uint select_field_count) + HA_CREATE_INFO *create_info, + List<create_field> &fields, + List<Key> &keys,bool tmp_table,bool no_log, + uint select_field_count) { - char path[FN_REFLEN]; - const char *alias; - int error= -1; - uint db_options, key_count; - KEY *key_info_buffer; - handler *file; - enum db_type new_db_type; + char path[FN_REFLEN]; + const char *alias; + int error= -1; + uint db_options, key_count; + KEY *key_info_buffer; + handler *file; + enum db_type new_db_type; DBUG_ENTER("mysql_create_table"); /* Check for duplicate fields and check type of table to create */ @@ -1085,10 +1082,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, { create_info->db_type= new_db_type; push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_USING_OTHER_HANDLER, - ER(ER_WARN_USING_OTHER_HANDLER), - ha_get_storage_engine(new_db_type), - table_name); + ER_WARN_USING_OTHER_HANDLER, + ER(ER_WARN_USING_OTHER_HANDLER), + ha_get_storage_engine(new_db_type), + table_name); } db_options=create_info->table_options; if (create_info->row_type == ROW_TYPE_DYNAMIC) @@ -1104,24 +1101,22 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, } if (mysql_prepare_table(thd, create_info, fields, - keys, tmp_table, db_options, file, - key_info_buffer, key_count, - select_field_count)) + keys, tmp_table, db_options, file, + key_info_buffer, &key_count, + select_field_count)) DBUG_RETURN(-1); /* Check if table exists */ if (create_info->options & HA_LEX_CREATE_TMP_TABLE) { - if (snprintf(path, sizeof(path), "%s%s%lx_%lx_%x%s", - mysql_tmpdir, tmp_file_prefix, current_pid, thd->thread_id, - thd->tmp_table++, reg_ext)>= (int)sizeof(path)) - DBUG_RETURN(-1); + my_snprintf(path, sizeof(path), "%s%s%lx_%lx_%x%s", + mysql_tmpdir, tmp_file_prefix, current_pid, thd->thread_id, + thd->tmp_table++, reg_ext); create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE; } else - if (snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home, db, - alias, reg_ext)>= (int)sizeof(path)) - DBUG_RETURN(-1); + my_snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home, db, + alias, reg_ext); unpack_filename(path,path); /* Check if table already exists */ if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) @@ -1129,7 +1124,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, { if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) { - create_info->table_existed= 1; // Mark that table existed + create_info->table_existed= 1; // Mark that table existed DBUG_RETURN(0); } my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias); @@ -1144,24 +1139,24 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, { if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) { - create_info->table_existed= 1; // Mark that table existed - error= 0; - } + create_info->table_existed= 1; // Mark that table existed + error= 0; + } else - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); + my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); goto end; } } thd->proc_info="creating table"; - create_info->table_existed= 0; // Mark that table is created + create_info->table_existed= 0; // Mark that table is created if (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE) create_info->data_file_name= create_info->index_file_name= 0; create_info->table_options=db_options; if (rea_create_table(thd, path, create_info, fields, key_count, - key_info_buffer)) + key_info_buffer)) { /* my_error(ER_CANT_CREATE_TABLE,MYF(0),table_name,my_errno); */ goto end; @@ -1184,8 +1179,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, { thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, - test(create_info->options & - HA_LEX_CREATE_TMP_TABLE)); + test(create_info->options & + HA_LEX_CREATE_TMP_TABLE)); mysql_bin_log.write(&qinfo); } } @@ -1215,37 +1210,39 @@ static char * make_unique_key_name(const char *field_name,KEY *start,KEY *end) { char buff[MAX_FIELD_NAME],*buff_end; - int remain; if (!check_if_keyname_exists(field_name,start,end) && my_strcasecmp(system_charset_info,field_name,primary_key_name)) - return (char*) field_name; // Use fieldname - buff_end=strmake(buff,field_name,MAX_FIELD_NAME-4); - /*ingo 2004-04-07 only 3 chars + '\0' left, so need to limit to 2 digit*/ + return (char*) field_name; // Use fieldname + buff_end=strmake(buff,field_name, sizeof(buff)-4); + + /* + Only 3 chars + '\0' left, so need to limit to 2 digit + This is ok as we can't have more than 100 keys anyway + */ for (uint i=2 ; i< 100; i++) { - remain= (int)sizeof(buff)- (buff_end- buff); - if (snprintf(buff_end, remain, "_%d", i)>= remain) - return NULL; + *buff_end= '_'; + int10_to_str(i, buff_end+1, 10); if (!check_if_keyname_exists(buff,start,end)) return sql_strdup(buff); } - /*ingo 2004-04-07 dedicated return is inevitable*/ - return NULL; + return (char*) "not_specified"; // Should never happen } + /**************************************************************************** ** Create table from a list of fields and items ****************************************************************************/ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, - const char *db, const char *name, - List<create_field> *extra_fields, - List<Key> *keys, - List<Item> *items, - MYSQL_LOCK **lock) + const char *db, const char *name, + List<create_field> *extra_fields, + List<Key> *keys, + List<Item> *items, + MYSQL_LOCK **lock) { - TABLE tmp_table; // Used during 'create_field()' + TABLE tmp_table; // Used during 'create_field()' TABLE *table; tmp_table.table_name=0; uint select_field_count= items->elements; @@ -1259,7 +1256,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, tmp_table.null_row=tmp_table.maybe_null=0; tmp_table.blob_ptr_size=portable_sizeof_char_ptr; tmp_table.db_low_byte_first= test(create_info->db_type == DB_TYPE_MYISAM || - create_info->db_type == DB_TYPE_HEAP); + create_info->db_type == DB_TYPE_HEAP); while ((item=it++)) { @@ -1269,18 +1266,18 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, field=item->tmp_table_field(&tmp_table); else field=create_tmp_field(thd, &tmp_table, item, item->type(), - (Item ***) 0, &tmp_field,0,0); + (Item ***) 0, &tmp_field,0,0); if (!field || - !(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ? - ((Item_field *)item)->field : - (Field*) 0)))) + !(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ? + ((Item_field *)item)->field : + (Field*) 0)))) DBUG_RETURN(0); extra_fields->push_back(cr_field); } /* create and lock table */ /* QQ: This should be done atomic ! */ if (mysql_create_table(thd,db,name,create_info,*extra_fields, - *keys,0,1,select_field_count)) // no logging + *keys,0,1,select_field_count)) // no logging DBUG_RETURN(0); if (!(table=open_table(thd,db,name,name,(bool*) 0))) { @@ -1307,10 +1304,10 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, bool mysql_rename_table(enum db_type base, - const char *old_db, - const char *old_name, - const char *new_db, - const char *new_name) + const char *old_db, + const char *old_name, + const char *new_db, + const char *new_name) { char from[FN_REFLEN], to[FN_REFLEN]; char tmp_from[NAME_LEN+1], tmp_to[NAME_LEN+1]; @@ -1329,12 +1326,10 @@ mysql_rename_table(enum db_type base, my_casedn_str(system_charset_info, tmp_to); new_name= tmp_to; } - if (snprintf(from, sizeof(from), "%s/%s/%s", - mysql_data_home, old_db, old_name)>= (int)sizeof(from)) - DBUG_RETURN(1); - if (snprintf(to, sizeof(to), "%s/%s/%s", - mysql_data_home, new_db, new_name)>= (int)sizeof(to)) - DBUG_RETURN(1); + my_snprintf(from, sizeof(from), "%s/%s/%s", + mysql_data_home, old_db, old_name); + my_snprintf(to, sizeof(to), "%s/%s/%s", + mysql_data_home, new_db, new_name); fn_format(from,from,"","",4); fn_format(to,to, "","",4); @@ -1359,10 +1354,10 @@ mysql_rename_table(enum db_type base, SYNOPSIS wait_while_table_is_used() - thd Thread handler - table Table to remove from cache - function HA_EXTRA_PREPARE_FOR_DELETE if table is to be deleted - HA_EXTRA_FORCE_REOPEN if table is not be used + thd Thread handler + table Table to remove from cache + function HA_EXTRA_PREPARE_FOR_DELETE if table is to be deleted + HA_EXTRA_FORCE_REOPEN if table is not be used NOTES When returning, the table will be unusable for other threads until the table is closed. @@ -1373,7 +1368,7 @@ mysql_rename_table(enum db_type base, */ static void wait_while_table_is_used(THD *thd,TABLE *table, - enum ha_extra_function function) + enum ha_extra_function function) { DBUG_PRINT("enter",("table: %s", table->real_name)); DBUG_ENTER("wait_while_table_is_used"); @@ -1381,11 +1376,11 @@ static void wait_while_table_is_used(THD *thd,TABLE *table, VOID(table->file->extra(function)); /* Mark all tables that are in use as 'old' */ - mysql_lock_abort(thd, table); // end threads waiting on lock + mysql_lock_abort(thd, table); // end threads waiting on lock /* Wait until all there are no other threads that has this table open */ while (remove_table_from_cache(thd,table->table_cache_key, - table->real_name)) + table->real_name)) { dropping_tables++; (void) pthread_cond_wait(&COND_refresh,&LOCK_open); @@ -1399,8 +1394,8 @@ static void wait_while_table_is_used(THD *thd,TABLE *table, SYNOPSIS close_cached_table() - thd Thread handler - table Table to remove from cache + thd Thread handler + table Table to remove from cache NOTES Function ends by signaling threads waiting for the table to try to @@ -1410,17 +1405,17 @@ static void wait_while_table_is_used(THD *thd,TABLE *table, Lock on LOCK_open Win32 clients must also have a WRITE LOCK on the table ! */ - + static bool close_cached_table(THD *thd, TABLE *table) { DBUG_ENTER("close_cached_table"); - + wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DELETE); /* Close lock if this is not got with LOCK TABLES */ if (thd->lock) { mysql_unlock_tables(thd, thd->lock); - thd->lock=0; // Start locked threads + thd->lock=0; // Start locked threads } /* Close all copies of 'table'. This also frees all LOCK TABLES lock */ thd->open_tables=unlink_open_table(thd,thd->open_tables,table); @@ -1431,7 +1426,7 @@ static bool close_cached_table(THD *thd, TABLE *table) } static int send_check_errmsg(THD *thd, TABLE_LIST* table, - const char* operator_name, const char* errmsg) + const char* operator_name, const char* errmsg) { Protocol *protocol= thd->protocol; @@ -1448,15 +1443,15 @@ static int send_check_errmsg(THD *thd, TABLE_LIST* table, static int prepare_for_restore(THD* thd, TABLE_LIST* table, - HA_CHECK_OPT *check_opt) + HA_CHECK_OPT *check_opt) { DBUG_ENTER("prepare_for_restore"); if (table->table) // do not overwrite existing tables on restore { DBUG_RETURN(send_check_errmsg(thd, table, "restore", - "table exists, will not overwrite on restore" - )); + "table exists, will not overwrite on restore" + )); } else { @@ -1466,25 +1461,24 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, char* db = thd->db ? thd->db : table->db; if (fn_format_relative_to_data_home(src_path, table_name, backup_dir, - reg_ext)) + reg_ext)) DBUG_RETURN(-1); // protect buffer overflow - if (snprintf(dst_path, sizeof(dst_path), "%s/%s/%s", - mysql_real_data_home, db, table_name)>= (int)sizeof(dst_path)) - DBUG_RETURN(-1); + my_snprintf(dst_path, sizeof(dst_path), "%s/%s/%s", + mysql_real_data_home, db, table_name); if (lock_and_wait_for_table_name(thd,table)) DBUG_RETURN(-1); if (my_copy(src_path, - fn_format(dst_path, dst_path,"", reg_ext, 4), - MYF(MY_WME))) + fn_format(dst_path, dst_path,"", reg_ext, 4), + MYF(MY_WME))) { pthread_mutex_lock(&LOCK_open); unlock_table_name(thd, table); pthread_mutex_unlock(&LOCK_open); DBUG_RETURN(send_check_errmsg(thd, table, "restore", - "Failed copying .frm file")); + "Failed copying .frm file")); } if (mysql_truncate(thd, table, 1)) { @@ -1492,7 +1486,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, unlock_table_name(thd, table); pthread_mutex_unlock(&LOCK_open); DBUG_RETURN(send_check_errmsg(thd, table, "restore", - "Failed generating table from .frm file")); + "Failed generating table from .frm file")); } } @@ -1511,7 +1505,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, - HA_CHECK_OPT *check_opt) + HA_CHECK_OPT *check_opt) { int error= 0; TABLE tmp_table, *table; @@ -1520,13 +1514,13 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, if (!(check_opt->sql_flags & TT_USEFRM)) DBUG_RETURN(0); - if (!(table= table_list->table)) /* if open_ltable failed */ + if (!(table= table_list->table)) /* if open_ltable failed */ { char name[FN_REFLEN]; strxmov(name, mysql_data_home, "/", table_list->db, "/", - table_list->real_name, NullS); + table_list->real_name, NullS); if (openfrm(name, "", 0, 0, 0, &tmp_table)) - DBUG_RETURN(0); // Can't open frm file + DBUG_RETURN(0); // Can't open frm file table= &tmp_table; } @@ -1549,18 +1543,14 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, like ISAM or MyISAM */ if (!ext[0] || !ext[1]) - goto end; // No data file + goto end; // No data file - strxmov(from, table->path, ext[1], NullS); // Name of data file + strxmov(from, table->path, ext[1], NullS); // Name of data file if (!my_stat(from, &stat_info, MYF(0))) - goto end; // Can't use USE_FRM flag + goto end; // Can't use USE_FRM flag - if (snprintf(tmp, sizeof(tmp), "%s-%lx_%lx", - from, current_pid, thd->thread_id)>= (int)sizeof(tmp)) - { - error= -1; - goto end; - } + my_snprintf(tmp, sizeof(tmp), "%s-%lx_%lx", + from, current_pid, thd->thread_id); /* If we could open the table, close it */ if (table_list->table) @@ -1580,7 +1570,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, unlock_table_name(thd, table_list); pthread_mutex_unlock(&LOCK_open); error= send_check_errmsg(thd, table_list, "repair", - "Failed renaming data file"); + "Failed renaming data file"); goto end; } if (mysql_truncate(thd, table_list, 1)) @@ -1589,7 +1579,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, unlock_table_name(thd, table_list); pthread_mutex_unlock(&LOCK_open); error= send_check_errmsg(thd, table_list, "repair", - "Failed generating table from .frm file"); + "Failed generating table from .frm file"); goto end; } if (my_rename(tmp, from, MYF(MY_WME))) @@ -1598,7 +1588,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, unlock_table_name(thd, table_list); pthread_mutex_unlock(&LOCK_open); error= send_check_errmsg(thd, table_list, "repair", - "Failed restoring .MYD file"); + "Failed restoring .MYD file"); goto end; } @@ -1615,21 +1605,21 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, end: if (table == &tmp_table) - closefrm(table); // Free allocated memory + closefrm(table); // Free allocated memory DBUG_RETURN(error); } static int mysql_admin_table(THD* thd, TABLE_LIST* tables, - HA_CHECK_OPT* check_opt, - const char *operator_name, - thr_lock_type lock_type, - bool open_for_modify, - uint extra_open_options, - int (*prepare_func)(THD *, TABLE_LIST *, - HA_CHECK_OPT *), - int (handler::*operator_func) - (THD *, HA_CHECK_OPT *)) + HA_CHECK_OPT* check_opt, + const char *operator_name, + thr_lock_type lock_type, + bool open_for_modify, + uint extra_open_options, + int (*prepare_func)(THD *, TABLE_LIST *, + HA_CHECK_OPT *), + int (handler::*operator_func) + (THD *, HA_CHECK_OPT *)) { TABLE_LIST *table; List<Item> field_list; @@ -1666,9 +1656,9 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, if (prepare_func) { switch ((*prepare_func)(thd, table, check_opt)) { - case 1: continue; // error, message written to net - case -1: goto err; // error, message could be written to net - default: ; // should be 0 otherwise + case 1: continue; // error, message written to net + case -1: goto err; // error, message could be written to net + default: ; // should be 0 otherwise } } @@ -1680,11 +1670,11 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, protocol->store(operator_name, system_charset_info); protocol->store("error",5, system_charset_info); if (!(err_msg=thd->net.last_error)) - err_msg=ER(ER_CHECK_NO_SUCH_TABLE); + err_msg=ER(ER_CHECK_NO_SUCH_TABLE); protocol->store(err_msg, system_charset_info); thd->net.last_error[0]=0; if (protocol->write()) - goto err; + goto err; continue; } table->table->pos_in_table_list= table; @@ -1695,14 +1685,12 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, protocol->store(table_name, system_charset_info); protocol->store(operator_name, system_charset_info); protocol->store("error", 5, system_charset_info); - if (snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY), - table_name)>= (int)sizeof(buff)) - goto err; + my_snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY), table_name); protocol->store(buff, system_charset_info); close_thread_tables(thd); - table->table=0; // For query cache + table->table=0; // For query cache if (protocol->write()) - goto err; + goto err; continue; } @@ -1711,20 +1699,20 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, { pthread_mutex_lock(&LOCK_open); const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open, - "Waiting to get writelock"); + "Waiting to get writelock"); mysql_lock_abort(thd,table->table); while (remove_table_from_cache(thd, table->table->table_cache_key, - table->table->real_name) && - ! thd->killed) + table->table->real_name) && + ! thd->killed) { - dropping_tables++; - (void) pthread_cond_wait(&COND_refresh,&LOCK_open); - dropping_tables--; + dropping_tables++; + (void) pthread_cond_wait(&COND_refresh,&LOCK_open); + dropping_tables--; } thd->exit_cond(old_message); pthread_mutex_unlock(&LOCK_open); if (thd->killed) - goto err; + goto err; open_for_modify=0; } @@ -1739,11 +1727,11 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, switch (result_code) { case HA_ADMIN_NOT_IMPLEMENTED: { - char buf[ERRMSGSIZE+20]; - uint length=my_snprintf(buf, ERRMSGSIZE, - ER(ER_CHECK_NOT_IMPLEMENTED), operator_name); - protocol->store("error", 5, system_charset_info); - protocol->store(buf, length, system_charset_info); + char buf[ERRMSGSIZE+20]; + uint length=my_snprintf(buf, ERRMSGSIZE, + ER(ER_CHECK_NOT_IMPLEMENTED), operator_name); + protocol->store("error", 5, system_charset_info); + protocol->store(buf, length, system_charset_info); } break; @@ -1779,26 +1767,26 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, protocol->store("Invalid argument",16, system_charset_info); break; - default: // Probably HA_ADMIN_INTERNAL_ERROR + default: // Probably HA_ADMIN_INTERNAL_ERROR protocol->store("error", 5, system_charset_info); protocol->store("Unknown - internal error during operation", 41 - , system_charset_info); + , system_charset_info); fatal_error=1; break; } if (fatal_error) - table->table->version=0; // Force close of table + table->table->version=0; // Force close of table else if (open_for_modify) { pthread_mutex_lock(&LOCK_open); remove_table_from_cache(thd, table->table->table_cache_key, - table->table->real_name); + table->table->real_name); pthread_mutex_unlock(&LOCK_open); /* May be something modified consequently we have to invalidate cache */ query_cache_invalidate3(thd, table->table, 0); } close_thread_tables(thd); - table->table=0; // For query cache + table->table=0; // For query cache if (protocol->write()) goto err; } @@ -1806,7 +1794,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, send_eof(thd); DBUG_RETURN(0); err: - close_thread_tables(thd); // Shouldn't be needed + close_thread_tables(thd); // Shouldn't be needed if (table) table->table=0; DBUG_RETURN(-1); @@ -1817,8 +1805,8 @@ int mysql_backup_table(THD* thd, TABLE_LIST* table_list) { DBUG_ENTER("mysql_backup_table"); DBUG_RETURN(mysql_admin_table(thd, table_list, 0, - "backup", TL_READ, 0, 0, 0, - &handler::backup)); + "backup", TL_READ, 0, 0, 0, + &handler::backup)); } @@ -1826,9 +1814,9 @@ int mysql_restore_table(THD* thd, TABLE_LIST* table_list) { DBUG_ENTER("mysql_restore_table"); DBUG_RETURN(mysql_admin_table(thd, table_list, 0, - "restore", TL_WRITE, 1, 0, - &prepare_for_restore, - &handler::restore)); + "restore", TL_WRITE, 1, 0, + &prepare_for_restore, + &handler::restore)); } @@ -1836,9 +1824,9 @@ int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) { DBUG_ENTER("mysql_repair_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, - "repair", TL_WRITE, 1, HA_OPEN_FOR_REPAIR, - &prepare_for_repair, - &handler::repair)); + "repair", TL_WRITE, 1, HA_OPEN_FOR_REPAIR, + &prepare_for_repair, + &handler::repair)); } @@ -1846,8 +1834,8 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) { DBUG_ENTER("mysql_optimize_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, - "optimize", TL_WRITE, 1,0,0, - &handler::optimize)); + "optimize", TL_WRITE, 1,0,0, + &handler::optimize)); } @@ -1856,16 +1844,16 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) SYNOPSIS mysql_assign_to_keycache() - thd Thread object - tables Table list (one table only) + thd Thread object + tables Table list (one table only) RETURN VALUES - 0 ok - -1 error + 0 ok + -1 error */ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, - LEX_STRING *key_cache_name) + LEX_STRING *key_cache_name) { HA_CHECK_OPT check_opt; KEY_CACHE *key_cache; @@ -1882,8 +1870,8 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, pthread_mutex_unlock(&LOCK_global_system_variables); check_opt.key_cache= key_cache; DBUG_RETURN(mysql_admin_table(thd, tables, &check_opt, - "assign_to_keycache", TL_READ_NO_INSERT, 0, - 0, 0, &handler::assign_to_keycache)); + "assign_to_keycache", TL_READ_NO_INSERT, 0, + 0, 0, &handler::assign_to_keycache)); } @@ -1892,9 +1880,9 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, SYNOPSIS reassign_keycache_tables() - thd Thread object - src_cache Reference to the key cache to clean up - dest_cache New key cache + thd Thread object + src_cache Reference to the key cache to clean up + dest_cache New key cache NOTES This is called when one sets a key cache size to zero, in which @@ -1909,20 +1897,20 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, to it for a while after this function returns. RETURN VALUES - 0 ok + 0 ok */ -int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache, - KEY_CACHE *dst_cache) +int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache, + KEY_CACHE *dst_cache) { DBUG_ENTER("reassign_keycache_tables"); DBUG_ASSERT(src_cache != dst_cache); DBUG_ASSERT(src_cache->in_init); - src_cache->param_buff_size= 0; // Free key cache + src_cache->param_buff_size= 0; // Free key cache ha_resize_key_cache(src_cache); ha_change_key_cache(src_cache, dst_cache); - DBUG_RETURN(0); + DBUG_RETURN(0); } @@ -1931,20 +1919,20 @@ int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache, SYNOPSIS mysql_preload_keys() - thd Thread object - tables Table list (one table only) + thd Thread object + tables Table list (one table only) RETURN VALUES - 0 ok - -1 error + 0 ok + -1 error */ int mysql_preload_keys(THD* thd, TABLE_LIST* tables) { DBUG_ENTER("mysql_preload_keys"); DBUG_RETURN(mysql_admin_table(thd, tables, 0, - "preload_keys", TL_READ, 0, 0, 0, - &handler::preload_keys)); + "preload_keys", TL_READ, 0, 0, 0, + &handler::preload_keys)); } @@ -1953,19 +1941,19 @@ int mysql_preload_keys(THD* thd, TABLE_LIST* tables) SYNOPSIS mysql_create_like_table() - thd Thread object - table Table list (one table only) + thd Thread object + table Table list (one table only) create_info Create info table_ident Src table_ident RETURN VALUES - 0 ok - -1 error + 0 ok + -1 error */ -int mysql_create_like_table(THD* thd, TABLE_LIST* table, - HA_CREATE_INFO *create_info, - Table_ident *table_ident) +int mysql_create_like_table(THD* thd, TABLE_LIST* table, + HA_CREATE_INFO *create_info, + Table_ident *table_ident) { TABLE **tmp_table; char src_path[FN_REFLEN], dst_path[FN_REFLEN]; @@ -1988,11 +1976,11 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, my_error(ER_WRONG_TABLE_NAME, MYF(0), src_table); DBUG_RETURN(-1); } - + src_tables_list.db= table_ident->db.str ? table_ident->db.str : thd->db; src_tables_list.real_name= table_ident->table.str; src_tables_list.next= 0; - + if (lock_and_wait_for_table_name(thd, &src_tables_list)) goto err; @@ -2000,8 +1988,8 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, strxmov(src_path, (*tmp_table)->path, reg_ext, NullS); else { - strxmov(src_path, mysql_data_home, "/", src_db, "/", src_table, - reg_ext, NullS); + strxmov(src_path, mysql_data_home, "/", src_db, "/", src_table, + reg_ext, NullS); if (access(src_path, F_OK)) { my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table); @@ -2012,56 +2000,54 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, /* Validate the destination table - skip the destination table name checking as this is already + skip the destination table name checking as this is already validated. */ if (create_info->options & HA_LEX_CREATE_TMP_TABLE) { if (find_temporary_table(thd, db, table_name)) goto table_exists; - if (snprintf(dst_path, sizeof(dst_path), "%s%s%lx_%lx_%x%s", - mysql_tmpdir, tmp_file_prefix, current_pid, - thd->thread_id, thd->tmp_table++, reg_ext)>= - (int)sizeof(dst_path)) - DBUG_RETURN(-1); + my_snprintf(dst_path, sizeof(dst_path), "%s%s%lx_%lx_%x%s", + mysql_tmpdir, tmp_file_prefix, current_pid, + thd->thread_id, thd->tmp_table++, reg_ext); create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE; } else { - strxmov(dst_path, mysql_data_home, "/", db, "/", table_name, - reg_ext, NullS); + strxmov(dst_path, mysql_data_home, "/", db, "/", table_name, + reg_ext, NullS); if (!access(dst_path, F_OK)) goto table_exists; } - /* + /* Create a new table by copying from source table - */ + */ if (my_copy(src_path, dst_path, MYF(MY_WME|MY_DONT_OVERWRITE_FILE))) goto err; /* - As mysql_truncate don't work on a new table at this stage of - creation, instead create the table directly (for both normal + As mysql_truncate don't work on a new table at this stage of + creation, instead create the table directly (for both normal and temporary tables). */ - *fn_ext(dst_path)= 0; + *fn_ext(dst_path)= 0; err= ha_create_table(dst_path, create_info, 1); - + if (create_info->options & HA_LEX_CREATE_TMP_TABLE) { if (err || !open_temporary_table(thd, dst_path, db, table_name, 1)) { - (void) rm_temporary_table(create_info->db_type, - dst_path); /* purecov: inspected */ + (void) rm_temporary_table(create_info->db_type, + dst_path); /* purecov: inspected */ goto err; /* purecov: inspected */ } } else if (err) { - (void) quick_rm_table(create_info->db_type, db, - table_name); /* purecov: inspected */ - goto err; /* purecov: inspected */ + (void) quick_rm_table(create_info->db_type, db, + table_name); /* purecov: inspected */ + goto err; /* purecov: inspected */ } // Must be written before unlock @@ -2070,22 +2056,21 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, { thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, - test(create_info->options & - HA_LEX_CREATE_TMP_TABLE)); + test(create_info->options & + HA_LEX_CREATE_TMP_TABLE)); mysql_bin_log.write(&qinfo); } res= 0; goto err; - + table_exists: if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) { char warn_buff[MYSQL_ERRMSG_SIZE]; - if (snprintf(warn_buff, sizeof(warn_buff), - ER(ER_TABLE_EXISTS_ERROR), table_name)>= (int)sizeof(warn_buff)) - DBUG_RETURN(-1); - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_TABLE_EXISTS_ERROR,warn_buff); + my_snprintf(warn_buff, sizeof(warn_buff), + ER(ER_TABLE_EXISTS_ERROR), table_name); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TABLE_EXISTS_ERROR,warn_buff); res= 0; } else @@ -2109,8 +2094,8 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) DBUG_ENTER("mysql_analyze_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, - "analyze", lock_type, 1,0,0, - &handler::analyze)); + "analyze", lock_type, 1,0,0, + &handler::analyze)); } @@ -2124,15 +2109,15 @@ int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt) DBUG_ENTER("mysql_check_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, - "check", lock_type, - 0, HA_OPEN_FOR_REPAIR, 0, - &handler::check)); + "check", lock_type, + 0, HA_OPEN_FOR_REPAIR, 0, + &handler::check)); } /* table_list should contain just one table */ int mysql_discard_or_import_tablespace(THD *thd, - TABLE_LIST *table_list, - enum tablespace_op_type tablespace_op) + TABLE_LIST *table_list, + enum tablespace_op_type tablespace_op) { TABLE *table; my_bool discard; @@ -2150,8 +2135,8 @@ int mysql_discard_or_import_tablespace(THD *thd, discard = FALSE; thd->tablespace_op=TRUE; /* we set this flag so that ha_innobase::open - and ::external_lock() do not complain when we - lock the table */ + and ::external_lock() do not complain when we + lock the table */ mysql_ha_closeall(thd, table_list); if (!(table=open_ltable(thd,table_list,TL_WRITE))) @@ -2159,7 +2144,7 @@ int mysql_discard_or_import_tablespace(THD *thd, thd->tablespace_op=FALSE; DBUG_RETURN(-1); } - + error=table->file->discard_or_import_tablespace(discard); thd->proc_info="end"; @@ -2194,6 +2179,8 @@ err: DBUG_RETURN(error); } + +#ifdef NOT_USED /* CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with the proper arguments. This isn't very fast but it should work for most @@ -2201,38 +2188,38 @@ err: One should normally create all indexes with CREATE TABLE or ALTER TABLE. */ -int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) +int mysql_create_indexes(THD *thd, TABLE_LIST *table_list, List<Key> &keys) { List<create_field> fields; List<Alter_drop> drop; List<Alter_column> alter; HA_CREATE_INFO create_info; - int rc; - uint idx; - uint db_options; - uint key_count; - TABLE *table; - Field **f_ptr; - KEY *key_info_buffer; - char path[FN_REFLEN]; + int rc; + uint idx; + uint db_options; + uint key_count; + TABLE *table; + Field **f_ptr; + KEY *key_info_buffer; + char path[FN_REFLEN+1]; DBUG_ENTER("mysql_create_index"); /* - Try to use online generation of index. - This requires that all indexes can be created online. - Otherwise, the old alter table procedure is executed. + Try to use online generation of index. + This requires that all indexes can be created online. + Otherwise, the old alter table procedure is executed. - Open the table to have access to the correct table handler. - */ + Open the table to have access to the correct table handler. + */ if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) DBUG_RETURN(-1); /* - The add_index method takes an array of KEY structs for the new indexes. - Preparing a new table structure generates this array. - It needs a list with all fields of the table, which does not need to - be correct in every respect. The field names are important. - */ + The add_index method takes an array of KEY structs for the new indexes. + Preparing a new table structure generates this array. + It needs a list with all fields of the table, which does not need to + be correct in every respect. The field names are important. + */ for (f_ptr= table->field; *f_ptr; f_ptr++) { create_field *c_fld= new create_field(*f_ptr, *f_ptr); @@ -2244,20 +2231,20 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) create_info.default_table_charset= thd->variables.collation_database; db_options= 0; if (mysql_prepare_table(thd, &create_info, fields, - keys, /*tmp_table*/ 0, db_options, table->file, - key_info_buffer, key_count, - /*select_field_count*/ 0)) + keys, /*tmp_table*/ 0, db_options, table->file, + key_info_buffer, key_count, + /*select_field_count*/ 0)) DBUG_RETURN(-1); /* - Check if all keys can be generated with the add_index method. - If anyone cannot, then take the old way. - */ + Check if all keys can be generated with the add_index method. + If anyone cannot, then take the old way. + */ for (idx=0; idx< key_count; idx++) { DBUG_PRINT("info", ("creating index %s", key_info_buffer[idx].name)); if (!(table->file->index_ddl_flags(key_info_buffer+idx)& - (HA_DDL_ONLINE| HA_DDL_WITH_LOCK))) + (HA_DDL_ONLINE| HA_DDL_WITH_LOCK))) break ; } if ((idx < key_count)|| !key_count) @@ -2269,68 +2256,68 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) /* Cleanup the fields list. We do not want to create existing fields. */ fields.delete_elements(); if (real_alter_table(thd, table_list->db, table_list->real_name, - &create_info, table_list, table, - fields, keys, drop, alter, 0, (ORDER*)0, - ALTER_ADD_INDEX, DUP_ERROR)) - /*don't need to free((gptr) key_info_buffer);*/ + &create_info, table_list, table, + fields, keys, drop, alter, 0, (ORDER*)0, + ALTER_ADD_INDEX, DUP_ERROR)) + /* Don't need to free((gptr) key_info_buffer);*/ DBUG_RETURN(-1); } else { if (table->file->add_index(table, key_info_buffer, key_count)|| - (snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home, - table_list->db, (lower_case_table_names == 2)? - table_list->alias: table_list->real_name, reg_ext)>= - (int)sizeof(path))|| - ! unpack_filename(path, path)|| - mysql_create_frm(thd, path, &create_info, - fields, key_count, key_info_buffer, table->file)) - /*don't need to free((gptr) key_info_buffer);*/ + (my_snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home, + table_list->db, (lower_case_table_names == 2) ? + table_list->alias: table_list->real_name, reg_ext) >= + (int) sizeof(path)) || + ! unpack_filename(path, path) || + mysql_create_frm(thd, path, &create_info, + fields, key_count, key_info_buffer, table->file)) + /* don't need to free((gptr) key_info_buffer);*/ DBUG_RETURN(-1); } - - /*don't need to free((gptr) key_info_buffer);*/ + /* don't need to free((gptr) key_info_buffer);*/ DBUG_RETURN(0); } -int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop) +int mysql_drop_indexes(THD *thd, TABLE_LIST *table_list, + List<Alter_drop> &drop) { List<create_field> fields; - List<Key> keys; + List<Key> keys; List<Alter_column> alter; HA_CREATE_INFO create_info; - uint idx; - uint db_options; - uint key_count; - uint *key_numbers; - TABLE *table; - Field **f_ptr; - KEY *key_info; - KEY *key_info_buffer; - char path[FN_REFLEN]; + uint idx; + uint db_options; + uint key_count; + uint *key_numbers; + TABLE *table; + Field **f_ptr; + KEY *key_info; + KEY *key_info_buffer; + char path[FN_REFLEN]; DBUG_ENTER("mysql_drop_index"); /* - Try to use online generation of index. - This requires that all indexes can be created online. - Otherwise, the old alter table procedure is executed. + Try to use online generation of index. + This requires that all indexes can be created online. + Otherwise, the old alter table procedure is executed. - Open the table to have access to the correct table handler. - */ + Open the table to have access to the correct table handler. + */ if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) DBUG_RETURN(-1); /* - The drop_index method takes an array of key numbers. - It cannot get more entries than keys in the table. - */ + The drop_index method takes an array of key numbers. + It cannot get more entries than keys in the table. + */ key_numbers= (uint*) thd->alloc(sizeof(uint*)*table->keys); key_count= 0; /* - Get the number of each key and check if it can be created online. - */ + Get the number of each key and check if it can be created online. + */ List_iterator<Alter_drop> drop_it(drop); Alter_drop *drop_key; while ((drop_key= drop_it++)) @@ -2340,7 +2327,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop) for (idx=0; idx< table->keys; idx++, key_info++) { if (!my_strcasecmp(system_charset_info, key_info->name, drop_key->name)) - break; + break; } if (idx>= table->keys) { @@ -2349,12 +2336,12 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop) DBUG_RETURN(-1); } /* - Check if the key can be generated with the add_index method. - If anyone cannot, then take the old way. - */ + Check if the key can be generated with the add_index method. + If anyone cannot, then take the old way. + */ DBUG_PRINT("info", ("dropping index %s", table->key_info[idx].name)); if (!(table->file->index_ddl_flags(table->key_info+idx)& - (HA_DDL_ONLINE| HA_DDL_WITH_LOCK))) + (HA_DDL_ONLINE| HA_DDL_WITH_LOCK))) break ; key_numbers[key_count++]= idx; } @@ -2366,9 +2353,9 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop) if ((drop_key)|| (drop.elements<= 0)) { if (real_alter_table(thd, table_list->db, table_list->real_name, - &create_info, table_list, table, - fields, keys, drop, alter, 0, (ORDER*)0, - ALTER_DROP_INDEX, DUP_ERROR)) + &create_info, table_list, table, + fields, keys, drop, alter, 0, (ORDER*)0, + ALTER_DROP_INDEX, DUP_ERROR)) /*don't need to free((gptr) key_numbers);*/ DBUG_RETURN(-1); } @@ -2376,17 +2363,17 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop) { db_options= 0; if (table->file->drop_index(table, key_numbers, key_count)|| - mysql_prepare_table(thd, &create_info, fields, - keys, /*tmp_table*/ 0, db_options, table->file, - key_info_buffer, key_count, - /*select_field_count*/ 0)|| - (snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home, - table_list->db, (lower_case_table_names == 2)? - table_list->alias: table_list->real_name, reg_ext)>= - (int)sizeof(path))|| - ! unpack_filename(path, path)|| - mysql_create_frm(thd, path, &create_info, - fields, key_count, key_info_buffer, table->file)) + mysql_prepare_table(thd, &create_info, fields, + keys, /*tmp_table*/ 0, db_options, table->file, + key_info_buffer, key_count, + /*select_field_count*/ 0)|| + (snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home, + table_list->db, (lower_case_table_names == 2)? + table_list->alias: table_list->real_name, reg_ext)>= + (int)sizeof(path))|| + ! unpack_filename(path, path)|| + mysql_create_frm(thd, path, &create_info, + fields, key_count, key_info_buffer, table->file)) /*don't need to free((gptr) key_numbers);*/ DBUG_RETURN(-1); } @@ -2394,117 +2381,35 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop) /*don't need to free((gptr) key_numbers);*/ DBUG_RETURN(0); } +#endif /* NOT_USED */ -int mysql_add_column(THD *thd, TABLE_LIST *table_list, - List<create_field> &fields) -{ - List<Alter_drop> drop; - List<Key> keys; - List<Alter_column> alter; - HA_CREATE_INFO create_info; - DBUG_ENTER("mysql_add_column"); - bzero((char*) &create_info,sizeof(create_info)); - create_info.db_type=DB_TYPE_DEFAULT; - create_info.default_table_charset= thd->variables.collation_database; - TABLE *table; - if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) - DBUG_RETURN(-1); - - DBUG_RETURN(real_alter_table(thd,table_list->db,table_list->real_name, - &create_info, table_list, table, - fields, keys, drop, alter, 0, (ORDER*)0, - ALTER_ADD_COLUMN, DUP_ERROR)); -} -int mysql_drop_column(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop) -{ - List<create_field> fields; - List<Key> keys; - List<Alter_column> alter; - HA_CREATE_INFO create_info; - DBUG_ENTER("mysql_drop_column"); - bzero((char*) &create_info,sizeof(create_info)); - create_info.db_type=DB_TYPE_DEFAULT; - create_info.default_table_charset= thd->variables.collation_database; - TABLE *table; - if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) - DBUG_RETURN(-1); - - DBUG_RETURN(real_alter_table(thd,table_list->db,table_list->real_name, - &create_info, table_list, table, - fields, keys, drop, alter, 0, (ORDER*)0, - ALTER_DROP_COLUMN, DUP_ERROR)); -} +/* + Alter table +*/ int mysql_alter_table(THD *thd,char *new_db, char *new_name, - HA_CREATE_INFO *create_info, - TABLE_LIST *table_list, - List<create_field> &fields, - List<Key> &keys,List<Alter_drop> &drop_list, - List<Alter_column> &alter_list, - uint order_num, ORDER *order, int alter_flags, - enum enum_duplicates handle_duplicates, - enum enum_enable_or_disable keys_onoff, - enum tablespace_op_type tablespace_op, - bool simple_alter) + HA_CREATE_INFO *create_info, + TABLE_LIST *table_list, + List<create_field> &fields, + List<Key> &keys,List<Alter_drop> &drop_list, + List<Alter_column> &alter_list, + uint order_num, ORDER *order, uint alter_flags, + enum enum_duplicates handle_duplicates, + enum enum_enable_or_disable keys_onoff, + enum tablespace_op_type tablespace_op, + bool simple_alter) { - DBUG_ENTER("mysql_alter_table"); - - mysql_ha_closeall(thd, table_list); - - /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */ - if (tablespace_op != NO_TABLESPACE_OP) - DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list, - tablespace_op)); - - if (alter_flags == ALTER_ADD_INDEX) - DBUG_RETURN(mysql_create_index(thd, table_list, keys)); - - if (alter_flags == ALTER_DROP_INDEX) - DBUG_RETURN(mysql_drop_index(thd, table_list, drop_list)); - - if (alter_flags == ALTER_ADD_COLUMN) - DBUG_RETURN(mysql_add_column(thd, table_list, fields)); - - if (alter_flags == ALTER_DROP_COLUMN) - DBUG_RETURN(mysql_drop_column(thd, table_list, drop_list)); - - TABLE *table; - if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) - DBUG_RETURN(-1); - - DBUG_RETURN(real_alter_table(thd, new_db, new_name, - create_info, table_list, table, fields, - keys, drop_list, alter_list, - order_num, order, alter_flags, - handle_duplicates, keys_onoff, - tablespace_op, simple_alter)); -} - -int real_alter_table(THD *thd,char *new_db, char *new_name, - HA_CREATE_INFO *create_info, - TABLE_LIST *table_list, - TABLE *table, - List<create_field> &fields, - List<Key> &keys,List<Alter_drop> &drop_list, - List<Alter_column> &alter_list, - uint order_num, ORDER *order, int alter_flags, - enum enum_duplicates handle_duplicates, - enum enum_enable_or_disable keys_onoff, - enum tablespace_op_type tablespace_op, - bool simple_alter) -{ - TABLE *new_table; + TABLE *table,*new_table; int error; char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN]; char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias; char index_file[FN_REFLEN], data_file[FN_REFLEN]; - bool use_timestamp=0; ha_rows copied,deleted; ulonglong next_insert_id; uint db_create_options, used_fields; enum db_type old_db_type,new_db_type; - DBUG_ENTER("real_alter_table"); + DBUG_ENTER("mysql_alter_table"); thd->proc_info="init"; table_name=table_list->real_name; @@ -2512,11 +2417,18 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, db=table_list->db; if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db)) - { new_db= db; - } used_fields=create_info->used_fields; + mysql_ha_closeall(thd, table_list); + + /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */ + if (tablespace_op != NO_TABLESPACE_OP) + DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list, + tablespace_op)); + if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) + DBUG_RETURN(-1); + /* Check that we are not trying to rename to an existing table */ if (new_name) { @@ -2526,17 +2438,17 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, { if (lower_case_table_names != 2) { - my_casedn_str(system_charset_info, new_name_buff); - new_alias= new_name; // Create lower case table name + my_casedn_str(system_charset_info, new_name_buff); + new_alias= new_name; // Create lower case table name } my_casedn_str(system_charset_info, new_name); } if (new_db == db && - !my_strcasecmp(table_alias_charset, new_name_buff, table_name)) + !my_strcasecmp(table_alias_charset, new_name_buff, table_name)) { /* - Source and destination table names are equal: make later check - easier. + Source and destination table names are equal: make later check + easier. */ new_alias= new_name= table_name; } @@ -2544,21 +2456,21 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, { if (table->tmp_table) { - if (find_temporary_table(thd,new_db,new_name_buff)) - { - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name_buff); - DBUG_RETURN(-1); - } + if (find_temporary_table(thd,new_db,new_name_buff)) + { + my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name_buff); + DBUG_RETURN(-1); + } } else { - if (!access(fn_format(new_name_buff,new_name_buff,new_db,reg_ext,0), - F_OK)) - { - /* Table will be closed in do_command() */ - my_error(ER_TABLE_EXISTS_ERROR,MYF(0), new_alias); - DBUG_RETURN(-1); - } + if (!access(fn_format(new_name_buff,new_name_buff,new_db,reg_ext,0), + F_OK)) + { + /* Table will be closed in do_command() */ + my_error(ER_TABLE_EXISTS_ERROR,MYF(0), new_alias); + DBUG_RETURN(-1); + } } } } @@ -2573,10 +2485,10 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, { create_info->db_type= new_db_type; push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_USING_OTHER_HANDLER, - ER(ER_WARN_USING_OTHER_HANDLER), - ha_get_storage_engine(new_db_type), - new_name); + ER_WARN_USING_OTHER_HANDLER, + ER(ER_WARN_USING_OTHER_HANDLER), + ha_get_storage_engine(new_db_type), + new_name); } if (create_info->row_type == ROW_TYPE_NOT_USED) create_info->row_type=table->row_type; @@ -2593,15 +2505,15 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, error=0; if (!access(new_name_buff,F_OK)) { - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name); - error= -1; + my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name); + error= -1; } else { - *fn_ext(new_name)=0; - close_cached_table(thd, table); - if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias)) - error= -1; + *fn_ext(new_name)=0; + close_cached_table(thd, table); + if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias)) + error= -1; } VOID(pthread_mutex_unlock(&LOCK_open)); } @@ -2610,7 +2522,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, { switch (keys_onoff) { case LEAVE_AS_IS: - break; + break; case ENABLE: VOID(pthread_mutex_lock(&LOCK_open)); wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); @@ -2627,11 +2539,11 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, break; } } - if (error==HA_ERR_WRONG_COMMAND) + if (error == HA_ERR_WRONG_COMMAND) { push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, - ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), - table->table_name); + ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), + table->table_name); error=0; } if (!error) @@ -2639,18 +2551,18 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); - mysql_bin_log.write(&qinfo); + thd->clear_error(); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + mysql_bin_log.write(&qinfo); } send_ok(thd); } else { table->file->print_error(error, MYF(0)); - error=-1; + error= -1; } - table_list->table=0; // For query cache + table_list->table=0; // For query cache query_cache_invalidate3(thd, table_list, 0); DBUG_RETURN(error); } @@ -2667,12 +2579,12 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET)) create_info->default_table_charset= table->table_charset; - restore_record(table,default_values); // Empty record for DEFAULT + restore_record(table,default_values); // Empty record for DEFAULT List_iterator<Alter_drop> drop_it(drop_list); List_iterator<create_field> def_it(fields); List_iterator<Alter_column> alter_it(alter_list); - List<create_field> create_list; // Add new fields here - List<Key> key_list; // Add new keys here + List<create_field> create_list; // Add new fields here + List<Key> key_list; // Add new keys here create_field *def; /* @@ -2688,16 +2600,16 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, while ((drop=drop_it++)) { if (drop->type == Alter_drop::COLUMN && - !my_strcasecmp(system_charset_info,field->field_name, drop->name)) + !my_strcasecmp(system_charset_info,field->field_name, drop->name)) { - /* Reset auto_increment value if it was dropped */ - if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER && - !(used_fields & HA_CREATE_USED_AUTO)) - { - create_info->auto_increment_value=0; - create_info->used_fields|=HA_CREATE_USED_AUTO; - } - break; + /* Reset auto_increment value if it was dropped */ + if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER && + !(used_fields & HA_CREATE_USED_AUTO)) + { + create_info->auto_increment_value=0; + create_info->used_fields|=HA_CREATE_USED_AUTO; + } + break; } } if (drop) @@ -2710,47 +2622,43 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, while ((def=def_it++)) { if (def->change && - !my_strcasecmp(system_charset_info,field->field_name, def->change)) - break; + !my_strcasecmp(system_charset_info,field->field_name, def->change)) + break; } if (def) - { // Field is changed + { // Field is changed def->field=field; - if (def->sql_type == FIELD_TYPE_TIMESTAMP) - use_timestamp=1; if (!def->after) { - create_list.push_back(def); - def_it.remove(); + create_list.push_back(def); + def_it.remove(); } } else - { // Use old field value + { // Use old field value create_list.push_back(def=new create_field(field,field)); - if (def->sql_type == FIELD_TYPE_TIMESTAMP) - use_timestamp=1; - alter_it.rewind(); // Change default if ALTER + alter_it.rewind(); // Change default if ALTER Alter_column *alter; while ((alter=alter_it++)) { - if (!my_strcasecmp(system_charset_info,field->field_name, alter->name)) - break; + if (!my_strcasecmp(system_charset_info,field->field_name, alter->name)) + break; } if (alter) { - if (def->sql_type == FIELD_TYPE_BLOB) - { - my_error(ER_BLOB_CANT_HAVE_DEFAULT,MYF(0),def->change); - DBUG_RETURN(-1); - } - def->def=alter->def; // Use new default - alter_it.remove(); + if (def->sql_type == FIELD_TYPE_BLOB) + { + my_error(ER_BLOB_CANT_HAVE_DEFAULT,MYF(0),def->change); + DBUG_RETURN(-1); + } + def->def=alter->def; // Use new default + alter_it.remove(); } } } def_it.rewind(); List_iterator<create_field> find_it(create_list); - while ((def=def_it++)) // Add new columns + while ((def=def_it++)) // Add new columns { if (def->change && ! def->field) { @@ -2765,17 +2673,17 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, { create_field *find; find_it.rewind(); - while ((find=find_it++)) // Add new columns + while ((find=find_it++)) // Add new columns { - if (!my_strcasecmp(system_charset_info,def->after, find->field_name)) - break; + if (!my_strcasecmp(system_charset_info,def->after, find->field_name)) + break; } if (!find) { - my_error(ER_BAD_FIELD_ERROR,MYF(0),def->after,table_name); - DBUG_RETURN(-1); + my_error(ER_BAD_FIELD_ERROR,MYF(0),def->after,table_name); + DBUG_RETURN(-1); } - find_it.after(def); // Put element after this + find_it.after(def); // Put element after this } } if (alter_list.elements) @@ -2807,8 +2715,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, while ((drop=drop_it++)) { if (drop->type == Alter_drop::KEY && - !my_strcasecmp(system_charset_info,key_name, drop->name)) - break; + !my_strcasecmp(system_charset_info,key_name, drop->name)) + break; } if (drop) { @@ -2821,60 +2729,60 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, for (uint j=0 ; j < key_info->key_parts ; j++,key_part++) { if (!key_part->field) - continue; // Wrong field (from UNIREG) + continue; // Wrong field (from UNIREG) const char *key_part_name=key_part->field->field_name; create_field *cfield; field_it.rewind(); while ((cfield=field_it++)) { - if (cfield->change) - { - if (!my_strcasecmp(system_charset_info, key_part_name, - cfield->change)) - break; - } - else if (!my_strcasecmp(system_charset_info, - key_part_name, cfield->field_name)) - break; + if (cfield->change) + { + if (!my_strcasecmp(system_charset_info, key_part_name, + cfield->change)) + break; + } + else if (!my_strcasecmp(system_charset_info, + key_part_name, cfield->field_name)) + break; } if (!cfield) - continue; // Field is removed + continue; // Field is removed uint key_part_length=key_part->length; - if (cfield->field) // Not new field - { // Check if sub key - if (cfield->field->type() != FIELD_TYPE_BLOB && - (cfield->field->pack_length() == key_part_length || - cfield->length <= key_part_length / - key_part->field->charset()->mbmaxlen)) - key_part_length=0; // Use whole field + if (cfield->field) // Not new field + { // Check if sub key + if (cfield->field->type() != FIELD_TYPE_BLOB && + (cfield->field->pack_length() == key_part_length || + cfield->length <= key_part_length / + key_part->field->charset()->mbmaxlen)) + key_part_length=0; // Use whole field } key_part_length /= key_part->field->charset()->mbmaxlen; key_parts.push_back(new key_part_spec(cfield->field_name, - key_part_length)); + key_part_length)); } if (key_parts.elements) key_list.push_back(new Key(key_info->flags & HA_SPATIAL ? Key::SPATIAL : - (key_info->flags & HA_NOSAME ? - (!my_strcasecmp(system_charset_info, - key_name, primary_key_name) ? - Key::PRIMARY : Key::UNIQUE) : - (key_info->flags & HA_FULLTEXT ? - Key::FULLTEXT : Key::MULTIPLE)), - key_name, - key_info->algorithm, - key_parts)); + (key_info->flags & HA_NOSAME ? + (!my_strcasecmp(system_charset_info, + key_name, primary_key_name) ? + Key::PRIMARY : Key::UNIQUE) : + (key_info->flags & HA_FULLTEXT ? + Key::FULLTEXT : Key::MULTIPLE)), + key_name, + key_info->algorithm, + key_parts)); } { Key *key; - while ((key=key_it++)) // Add new keys + while ((key=key_it++)) // Add new keys { if (key->type != Key::FOREIGN_KEY) - key_list.push_back(key); + key_list.push_back(key); if (key->name && - !my_strcasecmp(system_charset_info,key->name,primary_key_name)) + !my_strcasecmp(system_charset_info,key->name,primary_key_name)) { - my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name); - DBUG_RETURN(-1); + my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name); + DBUG_RETURN(-1); } } } @@ -2891,9 +2799,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, } db_create_options=table->db_create_options & ~(HA_OPTION_PACK_RECORD); - if (snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix, - current_pid, thd->thread_id)>= (int)sizeof(tmp_name)) - goto err; + my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix, + current_pid, thd->thread_id); create_info->db_type=new_db_type; if (!create_info->comment) create_info->comment=table->comment; @@ -2909,7 +2816,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, if (create_info->table_options & (HA_OPTION_DELAY_KEY_WRITE | HA_OPTION_NO_DELAY_KEY_WRITE)) db_create_options&= ~(HA_OPTION_DELAY_KEY_WRITE | - HA_OPTION_NO_DELAY_KEY_WRITE); + HA_OPTION_NO_DELAY_KEY_WRITE); create_info->table_options|= db_create_options; if (table->tmp_table) @@ -2940,31 +2847,31 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, Remove old table and symlinks. */ - if (!strcmp(db, new_db)) // Ignore symlink if db changed + if (!strcmp(db, new_db)) // Ignore symlink if db changed { if (create_info->index_file_name) { /* Fix index_file_name to have 'tmp_name' as basename */ strmov(index_file, tmp_name); create_info->index_file_name=fn_same(index_file, - create_info->index_file_name, - 1); + create_info->index_file_name, + 1); } if (create_info->data_file_name) { /* Fix data_file_name to have 'tmp_name' as basename */ strmov(data_file, tmp_name); create_info->data_file_name=fn_same(data_file, - create_info->data_file_name, - 1); + create_info->data_file_name, + 1); } } else create_info->data_file_name=create_info->index_file_name=0; if ((error=mysql_create_table(thd, new_db, tmp_name, - create_info, - create_list,key_list,1,1,0))) // no logging + create_info, + create_list,key_list,1,1,0))) // no logging DBUG_RETURN(error); if (table->tmp_table) @@ -2972,9 +2879,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, else { char path[FN_REFLEN]; - if (snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home, - new_db, tmp_name)>= (int)sizeof(path)) - goto err; + my_snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home, + new_db, tmp_name); fn_format(path,path,"","",4); new_table=open_temporary_table(thd, path, new_db, tmp_name,0); } @@ -2984,24 +2890,24 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, goto err; } - - /* - We don't want update TIMESTAMP fields during ALTER TABLE + + /* + We don't want update TIMESTAMP fields during ALTER TABLE and copy_data_between_tables uses only write_row() for new_table so don't need to set up timestamp_on_update_now member. */ new_table->timestamp_default_now= 0; new_table->next_number_field=new_table->found_next_number_field; - thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields + thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields thd->cuted_fields=0L; thd->proc_info="copy to tmp table"; - next_insert_id=thd->next_insert_id; // Remember for loggin + next_insert_id=thd->next_insert_id; // Remember for loggin copied=deleted=0; if (!new_table->is_view) error=copy_data_between_tables(table,new_table,create_list, - handle_duplicates, - order_num, order, &copied, &deleted); - thd->last_insert_id=next_insert_id; // Needed for correct log + handle_duplicates, + order_num, order, &copied, &deleted); + thd->last_insert_id=next_insert_id; // Needed for correct log thd->count_cuted_fields= CHECK_FIELD_IGNORE; if (table->tmp_table) @@ -3010,8 +2916,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, if (error) { /* - The following function call will free the new_table pointer, - in close_temporary_table(), so we can safely directly jump to err + The following function call will free the new_table pointer, + in close_temporary_table(), so we can safely directly jump to err */ close_temporary_table(thd,new_db,tmp_name); goto err; @@ -3025,7 +2931,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, /* Remove link to old table and rename the new one */ close_temporary_table(thd,table->table_cache_key,table_name); if (rename_temporary_table(thd, new_table, new_db, new_alias)) - { // Fatal error + { // Fatal error close_temporary_table(thd,new_db,tmp_name); my_free((gptr) new_table,MYF(0)); goto err; @@ -3040,7 +2946,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, goto end_temporary; } - intern_close_table(new_table); /* close temporary table */ + intern_close_table(new_table); /* close temporary table */ my_free((gptr) new_table,MYF(0)); VOID(pthread_mutex_lock(&LOCK_open)); if (error) @@ -3057,9 +2963,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, */ thd->proc_info="rename result table"; - if (snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix, - current_pid, thd->thread_id)>= (int)sizeof(old_name)) - goto err; + my_snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix, + current_pid, thd->thread_id); if (new_name != table_name || new_db != db) { if (!access(new_name_buff,F_OK)) @@ -3080,18 +2985,18 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, Win32 and InnoDB can't drop a table that is in use, so we must close the original table at before doing the rename */ - table_name=thd->strdup(table_name); // must be saved + table_name=thd->strdup(table_name); // must be saved if (close_cached_table(thd, table)) - { // Aborted + { // Aborted VOID(quick_rm_table(new_db_type,new_db,tmp_name)); VOID(pthread_mutex_unlock(&LOCK_open)); goto err; } - table=0; // Marker that table is closed + table=0; // Marker that table is closed } #if (!defined( __WIN__) && !defined( __EMX__) && !defined( OS2)) else - table->file->extra(HA_EXTRA_FORCE_REOPEN); // Don't use this file anymore + table->file->extra(HA_EXTRA_FORCE_REOPEN); // Don't use this file anymore #endif @@ -3102,8 +3007,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, VOID(quick_rm_table(new_db_type,new_db,tmp_name)); } else if (mysql_rename_table(new_db_type,new_db,tmp_name,new_db, - new_alias)) - { // Try to get everything back + new_alias)) + { // Try to get everything back error=1; VOID(quick_rm_table(new_db_type,new_db,new_alias)); VOID(quick_rm_table(new_db_type,new_db,tmp_name)); @@ -3120,7 +3025,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, VOID(pthread_mutex_unlock(&LOCK_open)); goto err; } - if (thd->lock || new_name != table_name) // True if WIN32 + if (thd->lock || new_name != table_name) // True if WIN32 { /* Not table locking or alter table with rename @@ -3141,14 +3046,14 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, { VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Use new file remove_table_from_cache(thd,db,table_name); // Mark all in-use copies old - mysql_lock_abort(thd,table); // end threads waiting on lock + mysql_lock_abort(thd,table); // end threads waiting on lock } VOID(quick_rm_table(old_db_type,db,old_name)); if (close_data_tables(thd,db,table_name) || - reopen_tables(thd,1,0)) - { // This shouldn't happen + reopen_tables(thd,1,0)) + { // This shouldn't happen if (table) - close_cached_table(thd,table); // Remove lock for table + close_cached_table(thd,table); // Remove lock for table VOID(pthread_mutex_unlock(&LOCK_open)); goto err; } @@ -3182,9 +3087,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, shutdown. */ char path[FN_REFLEN]; - if (snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home, - new_db, table_name)>= (int)sizeof(path)) - goto err; + my_snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home, + new_db, table_name); fn_format(path,path,"","",4); table=open_temporary_table(thd, path, new_db, tmp_name,0); if (table) @@ -3194,18 +3098,17 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, } else sql_print_error("Warning: Could not open BDB table %s.%s after rename\n", - new_db,table_name); + new_db,table_name); (void) berkeley_flush_logs(); } #endif - table_list->table=0; // For query cache + table_list->table=0; // For query cache query_cache_invalidate3(thd, table_list, 0); end_temporary: - if (snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO), - (ulong) (copied + deleted), (ulong) deleted, - (ulong) thd->cuted_fields)>= (int)sizeof(tmp_name)) - goto err; + my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO), + (ulong) (copied + deleted), (ulong) deleted, + (ulong) thd->cuted_fields); send_ok(thd,copied+deleted,0L,tmp_name); thd->some_tables_deleted=0; DBUG_RETURN(0); @@ -3217,11 +3120,11 @@ end_temporary: static int copy_data_between_tables(TABLE *from,TABLE *to, - List<create_field> &create, - enum enum_duplicates handle_duplicates, - uint order_num, ORDER *order, - ha_rows *copied, - ha_rows *deleted) + List<create_field> &create, + enum enum_duplicates handle_duplicates, + uint order_num, ORDER *order, + ha_rows *copied, + ha_rows *deleted) { int error; Copy_field *copy,*copy_end; @@ -3238,7 +3141,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, DBUG_ENTER("copy_data_between_tables"); if (!(copy= new Copy_field[to->fields])) - DBUG_RETURN(-1); /* purecov: inspected */ + DBUG_RETURN(-1); /* purecov: inspected */ to->file->external_lock(thd,F_WRLCK); from->file->info(HA_STATUS_VARIABLE); @@ -3259,21 +3162,21 @@ copy_data_between_tables(TABLE *from,TABLE *to, if (order) { from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE), - MYF(MY_FAE | MY_ZEROFILL)); + MYF(MY_FAE | MY_ZEROFILL)); bzero((char*) &tables,sizeof(tables)); tables.table = from; tables.alias = tables.real_name= from->real_name; - tables.db = from->table_cache_key; + tables.db = from->table_cache_key; error=1; if (thd->lex->select_lex.setup_ref_array(thd, order_num) || - setup_order(thd, thd->lex->select_lex.ref_pointer_array, - &tables, fields, all_fields, order) || - !(sortorder=make_unireg_sortorder(order, &length)) || - (from->sort.found_records = filesort(thd, from, sortorder, length, - (SQL_SELECT *) 0, HA_POS_ERROR, - &examined_rows)) - == HA_POS_ERROR) + setup_order(thd, thd->lex->select_lex.ref_pointer_array, + &tables, fields, all_fields, order) || + !(sortorder=make_unireg_sortorder(order, &length)) || + (from->sort.found_records = filesort(thd, from, sortorder, length, + (SQL_SELECT *) 0, HA_POS_ERROR, + &examined_rows)) + == HA_POS_ERROR) goto err; }; @@ -3310,12 +3213,12 @@ copy_data_between_tables(TABLE *from,TABLE *to, if ((error=to->file->write_row((byte*) to->record[0]))) { if ((handle_duplicates != DUP_IGNORE && - handle_duplicates != DUP_REPLACE) || - (error != HA_ERR_FOUND_DUPP_KEY && - error != HA_ERR_FOUND_DUPP_UNIQUE)) + handle_duplicates != DUP_REPLACE) || + (error != HA_ERR_FOUND_DUPP_KEY && + error != HA_ERR_FOUND_DUPP_UNIQUE)) { - to->file->print_error(error,MYF(0)); - break; + to->file->print_error(error,MYF(0)); + break; } delete_count++; } @@ -3324,7 +3227,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, } end_read_record(&info); free_io_cache(from); - delete [] copy; // This is never 0 + delete [] copy; // This is never 0 if (to->file->end_bulk_insert() && !error) { @@ -3375,7 +3278,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) strxmov(table_name, table->db ,".", table->real_name, NullS); t= table->table= open_ltable(thd, table, TL_READ_NO_INSERT); - thd->clear_error(); // these errors shouldn't get client + thd->clear_error(); // these errors shouldn't get client protocol->prepare_for_resend(); protocol->store(table_name, system_charset_info); @@ -3391,54 +3294,54 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) t->pos_in_table_list= table; if (t->file->table_flags() & HA_HAS_CHECKSUM && - !(check_opt->flags & T_EXTEND)) - protocol->store((ulonglong)t->file->checksum()); + !(check_opt->flags & T_EXTEND)) + protocol->store((ulonglong)t->file->checksum()); else if (!(t->file->table_flags() & HA_HAS_CHECKSUM) && - (check_opt->flags & T_QUICK)) - protocol->store_null(); + (check_opt->flags & T_QUICK)) + protocol->store_null(); else { - /* calculating table's checksum */ - ha_checksum crc= 0; - - /* InnoDB must be told explicitly to retrieve all columns, because - this function does not set field->query_id in the columns to the - current query id */ - t->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); - - if (t->file->rnd_init(1)) - protocol->store_null(); - else - { - while (!t->file->rnd_next(t->record[0])) - { - ha_checksum row_crc= 0; - if (t->record[0] != (byte*) t->field[0]->ptr) - row_crc= my_checksum(row_crc, t->record[0], - ((byte*) t->field[0]->ptr) - t->record[0]); - - for (uint i= 0; i < t->fields; i++ ) - { - Field *f= t->field[i]; - if (f->type() == FIELD_TYPE_BLOB) - { - String tmp; - f->val_str(&tmp); - row_crc= my_checksum(row_crc, (byte*) tmp.ptr(), tmp.length()); - } - else - row_crc= my_checksum(row_crc, (byte*) f->ptr, - f->pack_length()); - } - - crc+= row_crc; - } - protocol->store((ulonglong)crc); - } + /* calculating table's checksum */ + ha_checksum crc= 0; + + /* InnoDB must be told explicitly to retrieve all columns, because + this function does not set field->query_id in the columns to the + current query id */ + t->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); + + if (t->file->rnd_init(1)) + protocol->store_null(); + else + { + while (!t->file->rnd_next(t->record[0])) + { + ha_checksum row_crc= 0; + if (t->record[0] != (byte*) t->field[0]->ptr) + row_crc= my_checksum(row_crc, t->record[0], + ((byte*) t->field[0]->ptr) - t->record[0]); + + for (uint i= 0; i < t->fields; i++ ) + { + Field *f= t->field[i]; + if (f->type() == FIELD_TYPE_BLOB) + { + String tmp; + f->val_str(&tmp); + row_crc= my_checksum(row_crc, (byte*) tmp.ptr(), tmp.length()); + } + else + row_crc= my_checksum(row_crc, (byte*) f->ptr, + f->pack_length()); + } + + crc+= row_crc; + } + protocol->store((ulonglong)crc); + } } thd->clear_error(); close_thread_tables(thd); - table->table=0; // For query cache + table->table=0; // For query cache } if (protocol->write()) goto err; @@ -3448,7 +3351,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) DBUG_RETURN(0); err: - close_thread_tables(thd); // Shouldn't be needed + close_thread_tables(thd); // Shouldn't be needed if (table) table->table=0; DBUG_RETURN(-1); diff --git a/sql/table.cc b/sql/table.cc index f137abf2ef7..1b7d30560ef 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -553,7 +553,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, keyinfo->key_length+= HA_KEY_NULL_LENGTH; } if (field->type() == FIELD_TYPE_BLOB || - field->type() == FIELD_TYPE_GEOMETRY || field->real_type() == FIELD_TYPE_VAR_STRING) { if (field->type() == FIELD_TYPE_BLOB) diff --git a/sql/unireg.cc b/sql/unireg.cc index 4af1c832b57..8d3e304b5da 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -46,12 +46,29 @@ static bool make_empty_rec(int file, enum db_type table_type, List<create_field> &create_fields, uint reclength,uint null_fields); +/* + Create a frm (table definition) file + + SYNOPSIS + mysql_create_frm() + thd Thread handler + file_name Name of file (including database and .frm) + create_info create info parameters + create_fields Fields to create + keys number of keys to create + key_info Keys to create + db_file Handler to use. May be zero, in which case we use + create_info->db_type + RETURN + 0 ok + 1 error +*/ -int mysql_create_frm(THD *thd, my_string file_name, - HA_CREATE_INFO *create_info, - List<create_field> &create_fields, - uint keys, KEY *key_info, - handler *db_file) +bool mysql_create_frm(THD *thd, my_string file_name, + HA_CREATE_INFO *create_info, + List<create_field> &create_fields, + uint keys, KEY *key_info, + handler *db_file) { uint reclength,info_length,screens,key_info_length,maxlength,null_fields; File file; @@ -166,9 +183,29 @@ err: err2: VOID(my_close(file,MYF(MY_WME))); err3: + my_delete(file_name,MYF(0)); DBUG_RETURN(1); } /* mysql_create_frm */ + +/* + Create a frm (table definition) file and the tables + + SYNOPSIS + mysql_create_frm() + thd Thread handler + file_name Name of file (including database and .frm) + create_info create info parameters + create_fields Fields to create + keys number of keys to create + key_info Keys to create + db_file Handler to use. May be zero, in which case we use + create_info->db_type + RETURN + 0 ok + 1 error +*/ + int rea_create_table(THD *thd, my_string file_name, HA_CREATE_INFO *create_info, List<create_field> &create_fields, @@ -179,12 +216,8 @@ int rea_create_table(THD *thd, my_string file_name, if (mysql_create_frm(thd, file_name, create_info, create_fields, keys, key_info, NULL) || ha_create_table(file_name,create_info,0)) - goto err; + DBUG_RETURN(1); DBUG_RETURN(0); - -err: - my_delete(file_name,MYF(0)); - DBUG_RETURN(1); } /* rea_create_table */ |