diff options
Diffstat (limited to 'sql')
81 files changed, 1108 insertions, 1155 deletions
diff --git a/sql/Makefile.am b/sql/Makefile.am index 0167124a892..e2ab55da6a2 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -46,7 +46,7 @@ mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ item_strfunc.h item_timefunc.h item_uniq.h \ item_create.h item_subselect.h item_row.h \ - mysql_priv.h item_geofunc.h \ + mysql_priv.h item_geofunc.h sql_bitmap.h \ procedure.h sql_class.h sql_lex.h sql_list.h \ sql_manager.h sql_map.h sql_string.h unireg.h \ field.h handler.h \ diff --git a/sql/derror.cc b/sql/derror.cc index ad7432f7675..53d0dc5b7e5 100644 --- a/sql/derror.cc +++ b/sql/derror.cc @@ -75,6 +75,7 @@ Please install the latest version of this file.",name); goto err1; } + /* TODO: Convert the character set to server system character set */ if (!(cset= get_charset(head[30],MYF(MY_WME)))) { sql_print_error("Character set #%d is not supported for messagefile '%s'", diff --git a/sql/field.cc b/sql/field.cc index 04e9c45327b..70b8ce6c080 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -334,7 +334,7 @@ void Field::store_time(TIME *ltime,timestamp_type type) bool Field::optimize_range(uint idx) { - return test(table->file->index_flags(idx) & HA_READ_NEXT); + return !test(table->file->index_flags(idx) & HA_WRONG_ASCII_ORDER); } /**************************************************************************** @@ -2850,7 +2850,7 @@ String *Field_timestamp::val_str(String *val_buffer, struct tm tm_tmp; val_buffer->alloc(field_length+1); - char *to=(char*) val_buffer->ptr(),*end=to+field_length; + char *to= (char*) val_buffer->ptr(); val_buffer->length(field_length); #ifdef WORDS_BIGENDIAN @@ -3987,7 +3987,6 @@ longlong Field_string::val_int(void) String *Field_string::val_str(String *val_buffer __attribute__((unused)), String *val_ptr) { - char *end=ptr+field_length; uint length= field_charset->cset->lengthsp(field_charset, ptr, field_length); val_ptr->set((const char*) ptr, length, field_charset); return val_ptr; diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 7f8c99f7c15..f79c5b55927 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -546,7 +546,6 @@ innobase_query_caching_of_table_permitted( { ibool is_autocommit; trx_t* trx; - char* ptr; char norm_name[1000]; ut_a(full_name_len < 999); @@ -606,7 +605,7 @@ innobase_query_caching_of_table_permitted( #ifdef __WIN__ /* Put to lower case */ - ptr = norm_name; + char* ptr = norm_name; while (*ptr != '\0') { *ptr = tolower(*ptr); @@ -1391,7 +1390,6 @@ ha_innobase::open( uint test_if_locked) /* in: not used */ { dict_table_t* ib_table; - int error = 0; char norm_name[1000]; DBUG_ENTER("ha_innobase::open"); diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 52a5398bdd8..a10eeb3c934 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -229,12 +229,6 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked) if (!(file=mi_open(name, mode, test_if_locked))) return (my_errno ? my_errno : -1); - /* Synchronize key cache assignment of the handler */ - KEY_CACHE_VAR *key_cache= table->key_cache ? table->key_cache : - &dflt_key_cache_var; - VOID(mi_extra(file, HA_EXTRA_SET_KEY_CACHE, - (void*) &key_cache->cache)); - if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE)) VOID(mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0)); info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); @@ -698,93 +692,45 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) /* - Assign table indexes to a key cache. + Assign table indexes to a specific key cache. */ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt) { - uint len; - KEY_CACHE_VAR *old_key_cache; - KEY_CACHE_VAR *new_key_cache; - const char *errmsg=0; + KEY_CACHE *new_key_cache= check_opt->key_cache; + const char *errmsg= 0; int error= HA_ADMIN_OK; ulonglong map= ~(ulonglong) 0; TABLE_LIST *table_list= table->pos_in_table_list; - const char *new_key_cache_name= table_list->option ? - (const char *) table_list->option : - DEFAULT_KEY_CACHE_NAME; - KEY_CACHE_ASMT *key_cache_asmt= table->key_cache_asmt; - bool triggered= key_cache_asmt->triggered; - DBUG_ENTER("ha_myisam::assign_to_keycache"); - VOID(pthread_mutex_lock(&LOCK_assign)); - - old_key_cache= key_cache_asmt->key_cache; - /* Check validity of the index references */ - if (!triggered && table_list->use_index) + if (table_list->use_index) { + /* We only come here when the user did specify an index map */ key_map kmap; - get_key_map_from_key_list(&kmap, table, table_list->use_index); - if (kmap.is_set_all()) + if (get_key_map_from_key_list(&kmap, table, table_list->use_index)) { errmsg= thd->net.last_error; error= HA_ADMIN_FAILED; goto err; } - if (!kmap.is_clear_all()) - map= kmap.to_ulonglong(); - } - - len= strlen(new_key_cache_name); - new_key_cache= get_or_create_key_cache(new_key_cache_name, len); - if (old_key_cache == new_key_cache) - { - /* Nothing to do: table is assigned to the same key cache */ - goto ok; + map= kmap.to_ulonglong(); } - if (!new_key_cache || - (!new_key_cache->cache && ha_key_cache(new_key_cache))) - { - if (key_cache_asmt->triggered) - error= HA_ERR_OUT_OF_MEM; - else - { - char buf[ERRMSGSIZE]; - my_snprintf(buf, ERRMSGSIZE, - "Failed to create key cache %s", new_key_cache_name); - errmsg= buf; - error= HA_ADMIN_FAILED; - } - goto err; - } - - reassign_key_cache(key_cache_asmt, new_key_cache); - - VOID(pthread_mutex_unlock(&LOCK_assign)); - error= mi_assign_to_keycache(file, map, new_key_cache, &LOCK_assign); - VOID(pthread_mutex_lock(&LOCK_assign)); - - if (error && !key_cache_asmt->triggered) + if ((error= mi_assign_to_key_cache(file, map, new_key_cache))) { - switch (error) { - default: - char buf[ERRMSGSIZE+20]; - my_snprintf(buf, ERRMSGSIZE, - "Failed to flush to index file (errno: %d)", my_errno); - errmsg= buf; - } + char buf[80]; + my_snprintf(buf, sizeof(buf), + "Failed to flush to index file (errno: %d)", error); + errmsg= buf; error= HA_ADMIN_CORRUPT; - goto err; } - goto ok; - err: - if (!triggered) + if (error != HA_ADMIN_OK) { + /* Send error to user */ MI_CHECK param; myisamchk_init(¶m); param.thd= thd; @@ -793,32 +739,7 @@ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt) param.table_name= table->table_name; param.testflag= 0; mi_check_print_error(¶m, errmsg); - } - - ok: - if (--key_cache_asmt->requests) - { - /* There is a queue of assignments for the table */ - - /* Remove the first member from the queue */ - struct st_my_thread_var *last= key_cache_asmt->queue; - struct st_my_thread_var *thread= last->next; - if (thread->next == thread) - key_cache_asmt->queue= 0; - else - { - last->next= thread->next; - last->next->prev= &last->next; - thread->next= 0; - } - /* Signal the first waiting thread to proceed */ - VOID(pthread_cond_signal(&thread->suspend)); } - - key_cache_asmt->triggered= 0; - - VOID(pthread_mutex_unlock(&LOCK_assign)); - DBUG_RETURN(error); } diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 05da214c1d4..3cd5d96d5f3 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -35,9 +35,11 @@ const char **ha_myisammrg::bas_ext() const { static const char *ext[]= { ".MRG", NullS }; return ext; } + int ha_myisammrg::open(const char *name, int mode, uint test_if_locked) { char name_buff[FN_REFLEN]; + DBUG_PRINT("info", ("ha_myisammrg::open")); if (!(file=myrg_open(fn_format(name_buff,name,"","",2 | 4), mode, test_if_locked))) @@ -45,12 +47,6 @@ int ha_myisammrg::open(const char *name, int mode, uint test_if_locked) DBUG_PRINT("info", ("ha_myisammrg::open exit %d", my_errno)); return (my_errno ? my_errno : -1); } - /* Synchronize key cache assignment for the file */ - KEY_CACHE_VAR *key_cache= table->key_cache ? table->key_cache : - &dflt_key_cache_var; - VOID(myrg_extra(file, HA_EXTRA_SET_KEY_CACHE, - (void*) &key_cache->cache)); - DBUG_PRINT("info", ("ha_myisammrg::open myrg_extrafunc...")) myrg_extrafunc(file, query_cache_invalidate_by_MyISAM_filename_ref); if (!(test_if_locked == HA_OPEN_WAIT_IF_LOCKED || @@ -315,11 +311,11 @@ THR_LOCK_DATA **ha_myisammrg::store_lock(THD *thd, static void split_file_name(const char *file_name, LEX_STRING *db, LEX_STRING *name) { - uint name_length, dir_length, prefix_length; + uint dir_length, prefix_length; char buff[FN_REFLEN]; db->length= 0; - name_length= (uint) (strmake(buff, file_name, sizeof(buff)-1) - buff); + strmake(buff, file_name, sizeof(buff)-1); dir_length= dirname_length(buff); if (dir_length > 1) { diff --git a/sql/handler.cc b/sql/handler.cc index 28f399818c4..5267ddc8986 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1105,76 +1105,104 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, DBUG_RETURN(error != 0); } - /* Use key cacheing on all databases */ +static int NEAR_F delete_file(const char *name,const char *ext,int extflag) +{ + char buff[FN_REFLEN]; + VOID(fn_format(buff,name,"",ext,extflag | 4)); + return(my_delete_with_symlink(buff,MYF(MY_WME))); +} -int ha_key_cache(KEY_CACHE_VAR *key_cache) +void st_ha_check_opt::init() { - if (!key_cache->cache) - { - /* - The following mutex is not really needed as long as keybuff_size is - treated as a long value, but we use the mutex here to guard for future - changes. - */ - pthread_mutex_lock(&LOCK_global_system_variables); - if (!key_cache->block_size) - key_cache->block_size= dflt_key_cache_block_size; - if (!key_cache->buff_size) - key_cache->buff_size= dflt_key_buff_size; - long tmp_buff_size= (long) key_cache->buff_size; - long tmp_block_size= (long) key_cache->block_size; - pthread_mutex_unlock(&LOCK_global_system_variables); - return !init_key_cache(&key_cache->cache, - tmp_block_size, - tmp_buff_size, - key_cache); - } - return 0; + flags= sql_flags= 0; + sort_buffer_size = current_thd->variables.myisam_sort_buff_size; } -int ha_resize_key_cache(KEY_CACHE_VAR *key_cache) + +/***************************************************************************** + Key cache handling. + + This code is only relevant for ISAM/MyISAM tables + + key_cache->cache may be 0 only in the case where a key cache is not + initialized or when we where not able to init the key cache in a previous + call to ha_init_key_cache() (probably out of memory) +*****************************************************************************/ + +/* Init a key cache if it has not been initied before */ + + +int ha_init_key_cache(const char *name, KEY_CACHE *key_cache) { - if (key_cache->cache) + DBUG_ENTER("ha_init_key_cache"); + + if (!key_cache->key_cache_inited) { pthread_mutex_lock(&LOCK_global_system_variables); - long tmp_buff_size= (long) key_cache->buff_size; - long tmp_block_size= (long) key_cache->block_size; + long tmp_buff_size= (long) key_cache->param_buff_size; + long tmp_block_size= (long) key_cache->param_block_size; + uint division_limit= key_cache->param_division_limit; + uint age_threshold= key_cache->param_age_threshold; pthread_mutex_unlock(&LOCK_global_system_variables); - return !resize_key_cache(&key_cache->cache, tmp_block_size, - tmp_buff_size); + DBUG_RETURN(!init_key_cache(key_cache, + tmp_block_size, + tmp_buff_size, + division_limit, age_threshold)); } - return 0; + DBUG_RETURN(0); } -int ha_change_key_cache_param(KEY_CACHE_VAR *key_cache) + +/* Resize key cache */ + +int ha_resize_key_cache(KEY_CACHE *key_cache) { - if (key_cache->cache) + DBUG_ENTER("ha_resize_key_cache"); + + if (key_cache->key_cache_inited) { - change_key_cache_param(key_cache->cache); + pthread_mutex_lock(&LOCK_global_system_variables); + long tmp_buff_size= (long) key_cache->param_buff_size; + long tmp_block_size= (long) key_cache->param_block_size; + uint division_limit= key_cache->param_division_limit; + uint age_threshold= key_cache->param_age_threshold; + pthread_mutex_unlock(&LOCK_global_system_variables); + DBUG_RETURN(!resize_key_cache(key_cache, tmp_block_size, + tmp_buff_size, + division_limit, age_threshold)); } - return 0; + DBUG_RETURN(0); } -int ha_end_key_cache(KEY_CACHE_VAR *key_cache) + +/* Change parameters for key cache (like size) */ + +int ha_change_key_cache_param(KEY_CACHE *key_cache) { - if (key_cache->cache) + if (key_cache->key_cache_inited) { - end_key_cache(&key_cache->cache, 1); - return key_cache->cache ? 1 : 0; + pthread_mutex_lock(&LOCK_global_system_variables); + uint division_limit= key_cache->param_division_limit; + uint age_threshold= key_cache->param_age_threshold; + pthread_mutex_unlock(&LOCK_global_system_variables); + change_key_cache_param(key_cache, division_limit, age_threshold); } return 0; } +/* Free memory allocated by a key cache */ -static int NEAR_F delete_file(const char *name,const char *ext,int extflag) +int ha_end_key_cache(KEY_CACHE *key_cache) { - char buff[FN_REFLEN]; - VOID(fn_format(buff,name,"",ext,extflag | 4)); - return(my_delete_with_symlink(buff,MYF(MY_WME))); + end_key_cache(key_cache, 1); // Can never fail + return 0; } -void st_ha_check_opt::init() +/* Move all tables from one key cache to another one */ + +int ha_change_key_cache(KEY_CACHE *old_key_cache, + KEY_CACHE *new_key_cache) { - flags= sql_flags= 0; - sort_buffer_size = current_thd->variables.myisam_sort_buff_size; + mi_change_key_cache(old_key_cache, new_key_cache); + return 0; } diff --git a/sql/handler.h b/sql/handler.h index c24bf777f01..9089db60d77 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -22,6 +22,7 @@ #endif #include <ft_global.h> +#include <keycache.h> #ifndef NO_HASH #define NO_HASH /* Not yet implemented */ @@ -145,6 +146,7 @@ enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, #define HA_CREATE_USED_AVG_ROW_LENGTH 64 #define HA_CREATE_USED_PACK_KEYS 128 #define HA_CREATE_USED_CHARSET 256 +#define HA_CREATE_USED_DEFAULT_CHARSET 512 typedef struct st_thd_trans { void *bdb_tid; @@ -157,7 +159,7 @@ enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED, typedef struct st_ha_create_information { - CHARSET_INFO *table_charset; + CHARSET_INFO *table_charset, *default_table_charset; char *comment,*password; char *data_file_name, *index_file_name; ulonglong max_rows,min_rows; @@ -186,9 +188,11 @@ typedef struct st_ha_check_opt ulong sort_buffer_size; uint flags; /* isam layer flags (e.g. for myisamchk) */ uint sql_flags; /* sql layer flags - for something myisamchk cannot do */ + KEY_CACHE *key_cache; /* new key cache when changing key cache */ void init(); } HA_CHECK_OPT; + class handler :public Sql_alloc { protected: @@ -390,10 +394,10 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, bool update_create_info); int ha_delete_table(enum db_type db_type, const char *path); void ha_drop_database(char* path); -int ha_key_cache(KEY_CACHE_VAR *key_cache); -int ha_resize_key_cache(KEY_CACHE_VAR *key_cache); -int ha_change_key_cache_param(KEY_CACHE_VAR *key_cache); -int ha_end_key_cache(KEY_CACHE_VAR *key_cache); +int ha_init_key_cache(const char *name, KEY_CACHE *key_cache); +int ha_resize_key_cache(KEY_CACHE *key_cache); +int ha_change_key_cache_param(KEY_CACHE *key_cache); +int ha_end_key_cache(KEY_CACHE *key_cache); int ha_start_stmt(THD *thd); int ha_report_binlog_offset_and_commit(THD *thd, char *log_file_name, my_off_t end_offset); @@ -407,3 +411,5 @@ int ha_autocommit_or_rollback(THD *thd, int error); void ha_set_spin_retries(uint retries); bool ha_flush_logs(void); int ha_recovery_logging(THD *thd, bool on); +int ha_change_key_cache(KEY_CACHE *old_key_cache, + KEY_CACHE *new_key_cache); diff --git a/sql/item.cc b/sql/item.cc index d76ab529db5..9684fd3e518 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1190,6 +1190,15 @@ int Item_string::save_in_field(Field *field, bool no_conversions) -1 : 0; } +int Item_uint::save_in_field(Field *field, bool no_conversions) +{ + /* + TODO: To be fixed when wen have a + field->store(longlong, unsigned_flag) method + */ + return Item_int::save_in_field(field, no_conversions); +} + int Item_int::save_in_field(Field *field, bool no_conversions) { @@ -1347,7 +1356,7 @@ bool Item::send(Protocol *protocol, String *buffer) case MYSQL_TYPE_FLOAT: { float nr; - nr= val(); + nr= (float) val(); if (!null_value) result= protocol->store(nr, decimals, buffer); break; diff --git a/sql/item.h b/sql/item.h index f473ca33676..907b9ea5ad4 100644 --- a/sql/item.h +++ b/sql/item.h @@ -125,9 +125,10 @@ public: optimisation changes in prepared statements */ Item(THD *thd, Item &item); - virtual ~Item() { name=0; } /*lint -e1509 */ + virtual ~Item() { name=0; cleanup(); } /*lint -e1509 */ void set_name(const char *str,uint length, CHARSET_INFO *cs); void init_make_field(Send_field *tmp_field,enum enum_field_types type); + virtual void cleanup() {} virtual void make_field(Send_field *field); virtual bool fix_fields(THD *, struct st_table_list *, Item **); virtual int save_in_field(Field *field, bool no_conversions); @@ -403,6 +404,7 @@ public: double val() { return ulonglong2double((ulonglong)value); } String *val_str(String*); Item *new_item() { return new Item_uint(name,max_length); } + int save_in_field(Field *field, bool no_conversions); bool fix_fields(THD *thd, struct st_table_list *list, Item **item) { bool res= Item::fix_fields(thd, list, item); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 8731e8fbe21..db80428290a 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -397,13 +397,12 @@ int Arg_comparator::compare_row() int Arg_comparator::compare_e_row() { - int res= 0; (*a)->bring_value(); (*b)->bring_value(); uint n= (*a)->cols(); for (uint i= 0; i<n; i++) { - if ((res= !comparators[i].compare())) + if (!comparators[i].compare()) return 0; } return 1; @@ -1096,8 +1095,10 @@ void Item_func_case::fix_length_and_dec() return; - // Aggregate first expression and all THEN expression types - // and collations when string comparison + /* + Aggregate first expression and all THEN expression types + and collations when string comparison + */ if (first_expr_num != -1) { agg[0]= args[first_expr_num]; @@ -1110,7 +1111,7 @@ void Item_func_case::fix_length_and_dec() return; } - if (!else_expr_num != -1 || args[else_expr_num]->maybe_null) + if (else_expr_num == -1 || args[else_expr_num]->maybe_null) maybe_null=1; max_length=0; @@ -1127,6 +1128,7 @@ void Item_func_case::fix_length_and_dec() } } + /* TODO: Fix this so that it prints the whole CASE expression */ void Item_func_case::print(String *str) @@ -1375,6 +1377,7 @@ cmp_item* cmp_item::get_comparator(Item *item) return 0; // to satisfy compiler :) } + cmp_item* cmp_item_sort_string::make_same() { return new cmp_item_sort_string_in_static(cmp_charset); @@ -1395,27 +1398,46 @@ cmp_item* cmp_item_row::make_same() return new cmp_item_row(); } + +cmp_item_row::~cmp_item_row() +{ + DBUG_ENTER("~cmp_item_row"); + DBUG_PRINT("enter",("this: %lx", this)); + if (comparators) + { + for (uint i= 0; i < n; i++) + { + if (comparators[i]) + delete comparators[i]; + } + } + DBUG_VOID_RETURN; +} + + void cmp_item_row::store_value(Item *item) { - THD *thd= current_thd; + DBUG_ENTER("cmp_item_row::store_value"); n= item->cols(); - if ((comparators= (cmp_item **) thd->calloc(sizeof(cmp_item *)*n))) + if (!comparators) + comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n); + if (comparators) { item->bring_value(); item->null_value= 0; for (uint i=0; i < n; i++) - if ((comparators[i]= cmp_item::get_comparator(item->el(i)))) - { - comparators[i]->store_value(item->el(i)); - item->null_value|= item->el(i)->null_value; - } - else - return; + { + if (!comparators[i]) + if (!(comparators[i]= cmp_item::get_comparator(item->el(i)))) + break; // new failed + comparators[i]->store_value(item->el(i)); + item->null_value|= item->el(i)->null_value; + } } - else - return; + DBUG_VOID_RETURN; } + void cmp_item_row::store_value_by_template(cmp_item *t, Item *item) { cmp_item_row *tmpl= (cmp_item_row*) t; @@ -1430,19 +1452,17 @@ void cmp_item_row::store_value_by_template(cmp_item *t, Item *item) item->bring_value(); item->null_value= 0; for (uint i=0; i < n; i++) - if ((comparators[i]= tmpl->comparators[i]->make_same())) - { - comparators[i]->store_value_by_template(tmpl->comparators[i], - item->el(i)); - item->null_value|= item->el(i)->null_value; - } - else - return; + { + if (!(comparators[i]= tmpl->comparators[i]->make_same())) + break; // new failed + comparators[i]->store_value_by_template(tmpl->comparators[i], + item->el(i)); + item->null_value|= item->el(i)->null_value; + } } - else - return; } + int cmp_item_row::cmp(Item *arg) { arg->null_value= 0; @@ -1454,25 +1474,31 @@ int cmp_item_row::cmp(Item *arg) bool was_null= 0; arg->bring_value(); for (uint i=0; i < n; i++) + { if (comparators[i]->cmp(arg->el(i))) { if (!arg->el(i)->null_value) return 1; was_null= 1; } + } return (arg->null_value= was_null); } + int cmp_item_row::compare(cmp_item *c) { - int res; cmp_item_row *cmp= (cmp_item_row *) c; for (uint i=0; i < n; i++) + { + int res; if ((res= comparators[i]->compare(cmp->comparators[i]))) return res; + } return 0; } + bool Item_func_in::nulls_in_row() { Item **arg,**arg_end; @@ -1484,6 +1510,7 @@ bool Item_func_in::nulls_in_row() return 0; } + static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y) { return cs->coll->strnncollsp(cs, @@ -1491,6 +1518,7 @@ static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y) (unsigned char *) y->ptr(),y->length()); } + void Item_func_in::fix_length_and_dec() { Item **arg, **arg_end; @@ -1512,7 +1540,6 @@ void Item_func_in::fix_length_and_dec() { switch (cmp_type) { case STRING_RESULT: - uint i; array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in, cmp_collation.collation); break; diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 081374345d8..51c53e6c136 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -638,17 +638,7 @@ class cmp_item_row :public cmp_item uint n; public: cmp_item_row(): comparators(0), n(0) {} - ~cmp_item_row() - { - if (comparators) - { - for (uint i= 0; i < n; i++) - { - if (comparators[i]) - delete comparators[i]; - } - } - } + ~cmp_item_row(); void store_value(Item *item); int cmp(Item *arg); int compare(cmp_item *arg); @@ -694,7 +684,7 @@ public: cmp_item_string *cmp= (cmp_item_string *)c; return sortcmp(value_res, cmp->value_res, cmp_charset); } - cmp_item * make_same() + cmp_item *make_same() { return new cmp_item_sort_string_in_static(cmp_charset); } @@ -715,7 +705,17 @@ class Item_func_in :public Item_int_func } longlong val_int(); void fix_length_and_dec(); - ~Item_func_in() { delete array; delete in_item; } + ~Item_func_in() + { + cleanup(); /* This is not called by Item::~Item() */ + } + void cleanup() + { + delete array; + delete in_item; + array= 0; + in_item= 0; + } optimize_type select_optimize() const { return array ? OPTIMIZE_KEY : OPTIMIZE_NONE; } void print(String *str); diff --git a/sql/item_create.cc b/sql/item_create.cc index 5c44d8b00ff..1c0588b06a8 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -159,7 +159,7 @@ Item *create_func_from_days(Item* a) Item *create_func_get_lock(Item* a, Item *b) { - current_thd->lex.uncacheable(); + current_thd->lex.uncacheable(UNCACHEABLE_SIDEEFFECT); return new Item_func_get_lock(a, b); } @@ -324,7 +324,7 @@ Item *create_func_radians(Item *a) Item *create_func_release_lock(Item* a) { - current_thd->lex.uncacheable(); + current_thd->lex.uncacheable(UNCACHEABLE_SIDEEFFECT); return new Item_func_release_lock(a); } @@ -445,7 +445,7 @@ Item *create_func_year(Item* a) Item *create_load_file(Item* a) { - current_thd->lex.uncacheable(); + current_thd->lex.uncacheable(UNCACHEABLE_SIDEEFFECT); return new Item_load_file(a); } @@ -472,13 +472,13 @@ Item *create_func_cast(Item *a, Cast_target cast_type, int len, Item *create_func_is_free_lock(Item* a) { - current_thd->lex.uncacheable(); + current_thd->lex.uncacheable(UNCACHEABLE_SIDEEFFECT); return new Item_func_is_free_lock(a); } Item *create_func_is_used_lock(Item* a) { - current_thd->lex.uncacheable(); + current_thd->lex.uncacheable(UNCACHEABLE_SIDEEFFECT); return new Item_func_is_used_lock(a); } @@ -707,3 +707,8 @@ Item *create_func_str_to_date(Item* a,Item* b) { return new Item_func_str_to_date(a, b); } + +Item *create_func_last_day(Item *a) +{ + return new Item_func_last_day(a); +} diff --git a/sql/item_create.h b/sql/item_create.h index 5d6cbe1d58f..083868d87a6 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -150,3 +150,4 @@ Item *create_func_subtime(Item* a,Item* b); Item *create_func_timediff(Item* a,Item* b); Item *create_func_maketime(Item* a,Item* b,Item* c); Item *create_func_str_to_date(Item* a,Item* b); +Item *create_func_last_day(Item *a); diff --git a/sql/item_func.cc b/sql/item_func.cc index 3112c73b188..2a07341d97a 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2321,9 +2321,7 @@ String *user_var_entry::val_str(my_bool *null_value, String *str, bool Item_func_set_user_var::check() { - bool res; DBUG_ENTER("Item_func_set_user_var::check"); - LINT_INIT(res); switch (cached_result_type) { case REAL_RESULT: @@ -2648,6 +2646,8 @@ err: void Item_func_match::init_search(bool no_order) { DBUG_ENTER("Item_func_match::init_search"); + + /* Check if init_search() has been called before */ if (ft_handler) DBUG_VOID_RETURN; @@ -2685,7 +2685,8 @@ void Item_func_match::init_search(bool no_order) ft_tmp= &search_value; } - if (join_key && !no_order) flags|=FT_SORTED; + if (join_key && !no_order) + flags|=FT_SORTED; ft_handler=table->file->ft_init_ext(flags, key, (byte*) ft_tmp->ptr(), ft_tmp->length()); @@ -2743,7 +2744,7 @@ bool Item_func_match::fix_index() { Item_field *item; uint ft_to_key[MAX_KEY], ft_cnt[MAX_KEY], fts=0, keynr; - uint max_cnt=0, mkeys=0; + uint max_cnt=0, mkeys=0, i; if (key == NO_SUCH_KEY) return 0; @@ -2762,7 +2763,7 @@ bool Item_func_match::fix_index() if (!fts) goto err; - for (uint i=1; i < arg_count; i++) + for (i=1; i < arg_count; i++) { item=(Item_field*)args[i]; for (keynr=0 ; keynr < fts ; keynr++) @@ -2947,7 +2948,7 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name, } if (!(item=var->item(thd, var_type, component_name))) return 0; // Impossible - thd->lex.uncacheable(); + thd->lex.uncacheable(UNCACHEABLE_SIDEEFFECT); buff[0]='@'; buff[1]='@'; pos=buff+2; @@ -2987,7 +2988,7 @@ Item *get_system_var(THD *thd, enum_var_type var_type, const char *var_name, DBUG_ASSERT(var != 0); if (!(item=var->item(thd, var_type, &null_lex_string))) return 0; // Impossible - thd->lex.uncacheable(); + thd->lex.uncacheable(UNCACHEABLE_SIDEEFFECT); item->set_name(item_name, 0, system_charset_info); // Will use original name return item; } @@ -3010,7 +3011,6 @@ longlong Item_func_is_free_lock::val_int() String *res=args[0]->val_str(&value); THD *thd=current_thd; ULL *ull; - int error=0; null_value=0; if (!res || !res->length()) diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index dfaf3001a19..f40d38dd4a8 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -324,7 +324,6 @@ null: void Item_func_concat::fix_length_and_dec() { - bool first_coll= 1; max_length=0; if (agg_arg_collations(collation, args, arg_count)) @@ -2018,7 +2017,7 @@ void Item_func_lpad::fix_length_and_dec() String *Item_func_lpad::val_str(String *str) { - uint32 res_byte_length,res_char_length,pad_byte_length,pad_char_length; + uint32 res_char_length,pad_char_length; ulong count= (long) args[1]->val_int(), byte_count; String a1,a3; String *res= args[0]->val_str(&a1); @@ -2028,7 +2027,6 @@ String *Item_func_lpad::val_str(String *str) goto err; null_value=0; - res_byte_length= res->length(); res_char_length= res->numchars(); if (count <= res_char_length) @@ -2037,7 +2035,6 @@ String *Item_func_lpad::val_str(String *str) return res; } - pad_byte_length= pad->length(); pad_char_length= pad->numchars(); byte_count= count * collation.collation->mbmaxlen; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 9fd6dab83f6..a60a35aac6b 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -111,10 +111,12 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) } fix_length_and_dec(); } - if (engine->uncacheable()) + uint8 uncacheable= engine->uncacheable(); + if (uncacheable) { const_item_cache= 0; - used_tables_cache|= RAND_TABLE_BIT; + if (uncacheable & UNCACHEABLE_RAND) + used_tables_cache|= RAND_TABLE_BIT; } fixed= 1; thd->where= save_where; @@ -155,7 +157,7 @@ void Item_subselect::fix_length_and_dec() table_map Item_subselect::used_tables() const { - return (table_map) (engine->dependent() ? used_tables_cache : 0L); + return (table_map) (engine->uncacheable() ? used_tables_cache : 0L); } @@ -558,7 +560,7 @@ Item_in_subselect::single_value_transformer(JOIN *join, } if ((abort_on_null || (upper_not && upper_not->top_level())) && - !select_lex->master_unit()->dependent && !func->eqne_op()) + !select_lex->master_unit()->uncacheable && !func->eqne_op()) { if (substitution) { @@ -644,10 +646,10 @@ Item_in_subselect::single_value_transformer(JOIN *join, (char *)"<no matter>", (char *)in_left_expr_name); - unit->dependent= unit->uncacheable= 1; + unit->uncacheable|= UNCACHEABLE_DEPENDENT; } - select_lex->dependent= select_lex->uncacheable= 1; + select_lex->uncacheable|= UNCACHEABLE_DEPENDENT; Item *item; item= (Item*) select_lex->item_list.head(); @@ -768,12 +770,12 @@ Item_in_subselect::row_value_transformer(JOIN *join) DBUG_RETURN(RES_ERROR); } thd->lex.current_select= current; - unit->dependent= unit->uncacheable= 1; + unit->uncacheable|= UNCACHEABLE_DEPENDENT; } uint n= left_expr->cols(); - select_lex->dependent= select_lex->uncacheable= 1; + select_lex->uncacheable|= UNCACHEABLE_DEPENDENT; select_lex->setup_ref_array(thd, select_lex->order_list.elements + select_lex->group_list.elements); @@ -1047,7 +1049,7 @@ int subselect_single_select_engine::exec() DBUG_RETURN(1); } } - if ((select_lex->dependent || select_lex->uncacheable) && executed) + if (select_lex->uncacheable && executed) { if (join->reinit()) { @@ -1199,24 +1201,13 @@ uint subselect_union_engine::cols() } -bool subselect_single_select_engine::dependent() -{ - return select_lex->dependent; -} - -bool subselect_union_engine::dependent() -{ - return unit->dependent; -} - - -bool subselect_single_select_engine::uncacheable() +uint8 subselect_single_select_engine::uncacheable() { return select_lex->uncacheable; } -bool subselect_union_engine::uncacheable() +uint8 subselect_union_engine::uncacheable() { return unit->uncacheable; } diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 712b3de42ad..3637e025d3c 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -269,8 +269,7 @@ public: virtual void fix_length_and_dec(Item_cache** row)= 0; virtual int exec()= 0; virtual uint cols()= 0; /* return number of columnss in select */ - virtual bool dependent()= 0; /* depended from outer select */ - virtual bool uncacheable()= 0; /* query is uncacheable */ + virtual uint8 uncacheable()= 0; /* query is uncacheable */ enum Item_result type() { return res_type; } virtual void exclude()= 0; bool may_be_null() { return maybe_null; }; @@ -295,8 +294,7 @@ public: void fix_length_and_dec(Item_cache** row); int exec(); uint cols(); - bool dependent(); - bool uncacheable(); + uint8 uncacheable(); void exclude(); table_map upper_select_const_tables(); void print (String *str); @@ -314,8 +312,7 @@ public: void fix_length_and_dec(Item_cache** row); int exec(); uint cols(); - bool dependent(); - bool uncacheable(); + uint8 uncacheable(); void exclude(); table_map upper_select_const_tables(); void print (String *str); @@ -342,8 +339,7 @@ public: void fix_length_and_dec(Item_cache** row); int exec(); uint cols() { return 1; } - bool dependent() { return 1; } - bool uncacheable() { return 1; } + uint8 uncacheable() { return UNCACHEABLE_DEPENDENT; } void exclude(); table_map upper_select_const_tables() { return 0; } void print (String *str); diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 74dd95bf0ab..a3d67e9f7fa 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1642,10 +1642,8 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct, original= 0; quick_group= 0; mark_as_sum_func(); - item_thd= current_thd; - SELECT_LEX *select_lex= item_thd->lex.current_select; order= 0; - group_concat_max_len= item_thd->variables.group_concat_max_len; + group_concat_max_len= current_thd->variables.group_concat_max_len; arg_show_fields= arg_count_field= is_select->elements; @@ -1791,6 +1789,7 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) thd->allow_sum_func= 0; maybe_null= 0; + item_thd= thd; for (i= 0 ; i < arg_count ; i++) { if (args[i]->fix_fields(thd, tables, args + i) || args[i]->check_cols(1)) @@ -1969,6 +1968,7 @@ String* Item_func_group_concat::val_str(String* str) return &result; } + void Item_func_group_concat::print(String *str) { str->append("group_concat(", 13); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index cf71f2b3bef..496ea0ed5c8 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -137,14 +137,12 @@ static bool make_datetime(date_time_format_types format, TIME *ltime, static bool extract_date_time(DATE_TIME_FORMAT *format, const char *val, uint length, TIME *l_time) { - int weekday= 0, yearday= 0, daypart= 0, len; + int weekday= 0, yearday= 0, daypart= 0; int week_number= -1; CHARSET_INFO *cs= &my_charset_bin; int error= 0; bool usa_time= 0; bool sunday_first= 0; - uint part_len= 0; - const char *val_ptr= val; const char *val_end= val + length; const char *ptr= format->format.str; const char *end= ptr+ format->format.length; @@ -237,7 +235,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, /* Second part */ case 'f': tmp= (char*) val_end; - l_time->second_part= my_strtoll10(val, &tmp, &error); + l_time->second_part= (int) my_strtoll10(val, &tmp, &error); val= tmp; break; @@ -1221,7 +1219,7 @@ String *Item_func_sec_to_time::val_str(String *str) sec= (uint) ((ulonglong) seconds % 3600); ltime.day= 0; - ltime.hour= seconds/3600; + ltime.hour= (uint) (seconds/3600); ltime.minute= sec/60; ltime.second= sec % 60; @@ -1385,7 +1383,6 @@ String *Item_func_from_unixtime::val_str(String *str) { struct tm tm_tmp,*start; time_t tmp=(time_t) args[0]->val_int(); - CHARSET_INFO *cs= &my_charset_bin; TIME ltime; if ((null_value=args[0]->null_value)) @@ -1759,6 +1756,7 @@ bool Item_extract::eq(const Item *item, bool binary_cmp) const return 1; } + void Item_typecast::print(String *str) { str->append("cast(", 5); @@ -1768,6 +1766,7 @@ void Item_typecast::print(String *str) str->append(')'); } + void Item_char_typecast::print(String *str) { str->append("cast(", 5); @@ -1851,9 +1850,8 @@ String *Item_datetime_typecast::val_str(String *str) if (!get_arg0_date(<ime,1) && !make_datetime(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME, <ime, str)) - return str; + return str; -null_date: null_value=1; return 0; } @@ -1912,8 +1910,8 @@ String *Item_date_typecast::val_str(String *str) String *Item_func_makedate::val_str(String *str) { TIME l_time; - long daynr= args[1]->val_int(); - long yearnr= args[0]->val_int(); + long daynr= (long) args[1]->val_int(); + long yearnr= (long) args[0]->val_int(); long days; if (args[0]->null_value || args[1]->null_value || @@ -1921,7 +1919,7 @@ String *Item_func_makedate::val_str(String *str) goto err; days= calc_daynr(yearnr,1,1) + daynr - 1; - // Day number from year 0 to 9999-12-31 + /* Day number from year 0 to 9999-12-31 */ if (days >= 0 && days < MAX_DAY_NUMBER) { null_value=0; @@ -2125,7 +2123,8 @@ String *Item_func_timediff::val_str(String *str) microseconds= l_time1.second_part - l_sign*l_time2.second_part; seconds= ((longlong) days*86400L + l_time1.hour*3600L + l_time1.minute*60L + l_time1.second + microseconds/1000000L - - (longlong)l_sign*(l_time2.hour*3600L+l_time2.minute*60L+l_time2.second)); + (longlong)l_sign*(l_time2.hour*3600L+l_time2.minute*60L+ + l_time2.second)); l_time3.neg= 0; if (seconds < 0) @@ -2146,7 +2145,7 @@ String *Item_func_timediff::val_str(String *str) if ((l_time2.neg == l_time1.neg) && l_time1.neg) l_time3.neg= l_time3.neg ? 0 : 1; - calc_time_from_sec(&l_time3, seconds, microseconds); + calc_time_from_sec(&l_time3, (long) seconds, microseconds); if (!make_datetime(l_time1.second_part || l_time2.second_part ? TIME_MICROSECOND : TIME_ONLY, @@ -2168,9 +2167,9 @@ String *Item_func_maketime::val_str(String *str) { TIME ltime; - long hour= args[0]->val_int(); - long minute= args[1]->val_int(); - long second= args[2]->val_int(); + long hour= (long) args[0]->val_int(); + long minute= (long) args[1]->val_int(); + long second= (long) args[2]->val_int(); if ((null_value=(args[0]->null_value || args[1]->null_value || @@ -2186,9 +2185,9 @@ String *Item_func_maketime::val_str(String *str) ltime.neg= 1; hour= -hour; } - ltime.hour= (ulong)hour; - ltime.minute= (ulong)minute; - ltime.second= (ulong)second; + ltime.hour= (ulong) hour; + ltime.minute= (ulong) minute; + ltime.second= (ulong) second; make_time((DATE_TIME_FORMAT *) 0, <ime, str); return str; } @@ -2310,3 +2309,19 @@ String *Item_func_str_to_date::val_str(String *str) return str; return 0; } + + +String *Item_func_last_day::val_str(String *str) +{ + TIME ltime; + if (!get_arg0_date(<ime,0)) + { + uint month_idx= ltime.month-1; + ltime.day= days_in_month[month_idx]; + if ( month_idx == 1 && calc_days_in_year(ltime.year) == 366) + ltime.day+= 1; + if (!make_datetime(DATE_ONLY, <ime, str)) + return str; + } + return 0; +} diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index ef7fa1abfa0..a81b9f28d92 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -809,3 +809,21 @@ public: max_length=MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; } }; + +class Item_func_last_day :public Item_str_func +{ +public: + Item_func_last_day(Item *a) :Item_str_func(a) {} + String *val_str(String *str); + const char *func_name() const { return "last_day"; } + enum_field_types field_type() const { return MYSQL_TYPE_DATE; } + void fix_length_and_dec() + { + decimals=0; + max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; + } + Field *tmp_table_field(TABLE *t_arg) + { + return (new Field_date(maybe_null, name, t_arg, &my_charset_bin)); + } +}; diff --git a/sql/lex.h b/sql/lex.h index 7f3328fa7cb..fd13af348d1 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -551,7 +551,8 @@ static SYMBOL sql_functions[] = { { "IS_FREE_LOCK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_is_free_lock)}, { "IS_USED_LOCK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_is_used_lock)}, { "LAST_INSERT_ID", SYM(LAST_INSERT_ID),0,0}, - { "ISSIMPLE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_issimple)}, + { "ISSIMPLE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_issimple)}, + { "LAST_DAY", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_last_day)}, { "LCASE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_lcase)}, { "LEAST", SYM(LEAST_SYM),0,0}, { "LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)}, diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 12c772e7253..b9032381c45 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -24,7 +24,7 @@ #include <signal.h> #include <thr_lock.h> #include <my_base.h> /* Needed by field.h */ -#include <sql_bitmap.h> +#include "sql_bitmap.h" #ifdef __EMX__ #undef write /* remove pthread.h macro definition for EMX */ @@ -248,6 +248,11 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; #define MY_CHARSET_BIN_MB_MAXLEN 1 +// uncachable cause +#define UNCACHEABLE_DEPENDENT 1 +#define UNCACHEABLE_RAND 2 +#define UNCACHEABLE_SIDEEFFECT 4 + #ifdef EXTRA_DEBUG /* Sync points allow us to force the server to reach a certain line of code @@ -427,10 +432,6 @@ bool check_stack_overrun(THD *thd,char *dummy); void table_cache_init(void); void table_cache_free(void); uint cached_tables(void); -void assign_cache_init(void); -void assign_cache_free(void); -void reassign_key_cache(KEY_CACHE_ASMT *key_cache_asmt, - KEY_CACHE_VAR *new_key_cache); void kill_mysql(void); void close_connection(THD *thd, uint errcode, bool lock); bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, @@ -460,10 +461,11 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* table_list, HA_CHECK_OPT* check_opt); int mysql_optimize_table(THD* thd, TABLE_LIST* table_list, HA_CHECK_OPT* check_opt); -int mysql_assign_to_keycache(THD* thd, TABLE_LIST* table_list); +int mysql_assign_to_keycache(THD* thd, TABLE_LIST* table_list, + LEX_STRING *key_cache_name); int mysql_preload_keys(THD* thd, TABLE_LIST* table_list); -int reassign_keycache_tables(THD* thd, KEY_CACHE_VAR* src_cache, - char *dest_name, bool remove_fl); +int reassign_keycache_tables(THD* thd, KEY_CACHE *src_cache, + KEY_CACHE *dst_cache); bool check_simple_select(); @@ -662,7 +664,7 @@ enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND, extern const Item **not_found_item; Item ** find_item_in_list(Item *item, List<Item> &items, uint *counter, find_item_error_report_type report_error); -void get_key_map_from_key_list(key_map *map, TABLE *table, +bool get_key_map_from_key_list(key_map *map, TABLE *table, List<String> *index_list); bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, const char *table_name, @@ -849,7 +851,7 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, LOCK_error_log, LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, LOCK_slave_list, LOCK_active_mi, LOCK_manager, - LOCK_global_system_variables, LOCK_user_conn, LOCK_assign; + LOCK_global_system_variables, LOCK_user_conn; extern rw_lock_t LOCK_grant; extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager; extern pthread_attr_t connection_attrib; @@ -866,6 +868,7 @@ extern SHOW_COMP_OPTION have_berkeley_db; extern struct system_variables global_system_variables; extern struct system_variables max_system_variables; extern struct rand_struct sql_rand; +extern KEY_CACHE *sql_key_cache; extern const char *opt_date_time_formats[]; extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[]; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 7c432a05786..a0b5d910986 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -355,6 +355,7 @@ struct system_variables max_system_variables; MY_TMPDIR mysql_tmpdir_list; MY_BITMAP temp_pool; +KEY_CACHE *sql_key_cache; CHARSET_INFO *system_charset_info, *files_charset_info ; CHARSET_INFO *national_charset_info, *table_alias_charset; @@ -373,7 +374,6 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count, LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received, LOCK_global_system_variables, - LOCK_assign, LOCK_user_conn, LOCK_slave_list, LOCK_active_mi; rw_lock_t LOCK_grant; pthread_cond_t COND_refresh,COND_thread_count, COND_slave_stopped, @@ -900,7 +900,6 @@ void clean_up(bool print_message) #endif query_cache_destroy(); table_cache_free(); - assign_cache_free(); hostname_cache_free(); item_user_lock_free(); lex_free(); /* Free some memory */ @@ -910,9 +909,8 @@ void clean_up(bool print_message) udf_free(); #endif (void) ha_panic(HA_PANIC_CLOSE); /* close all tables and logs */ - process_key_caches(&ha_end_key_cache); - ha_end_key_cache(&dflt_key_cache_var); - delete_elements(&key_caches, free_key_cache); + delete_elements(&key_caches, (void (*)(const char*, gptr)) free_key_cache); + multi_keycache_free(); end_thr_alarm(1); /* Free allocated memory */ #ifdef USE_RAID end_raid(); @@ -997,7 +995,6 @@ static void clean_up_mutexes() #endif (void) pthread_mutex_destroy(&LOCK_active_mi); (void) pthread_mutex_destroy(&LOCK_global_system_variables); - (void) pthread_mutex_destroy(&LOCK_assign); (void) pthread_cond_destroy(&COND_thread_count); (void) pthread_cond_destroy(&COND_refresh); (void) pthread_cond_destroy(&COND_thread_cache); @@ -1568,14 +1565,14 @@ We will try our best to scrape up some info that will hopefully help diagnose\n\ the problem, but since we have already crashed, something is definitely wrong\n\ and this may fail.\n\n"); fprintf(stderr, "key_buffer_size=%lu\n", - (ulong) dflt_key_cache_var.buff_size); + (ulong) sql_key_cache->key_cache_mem_size); fprintf(stderr, "read_buffer_size=%ld\n", global_system_variables.read_buff_size); fprintf(stderr, "max_used_connections=%ld\n", max_used_connections); fprintf(stderr, "max_connections=%ld\n", max_connections); fprintf(stderr, "threads_connected=%d\n", thread_count); fprintf(stderr, "It is possible that mysqld could use up to \n\ key_buffer_size + (read_buffer_size + sort_buffer_size)*max_connections = %ld K\n\ -bytes of memory\n", ((ulong) dflt_key_cache_var.buff_size + +bytes of memory\n", ((ulong) sql_key_cache->key_cache_mem_size + (global_system_variables.read_buff_size + global_system_variables.sortbuff_size) * max_connections)/ 1024); @@ -2040,7 +2037,6 @@ bool init_global_datetime_format(timestamp_type format_type, { /* Get command line option */ const char *str= opt_date_time_formats[format_type]; - DATE_TIME_FORMAT *format; if (!str) // No specified format { @@ -2071,6 +2067,8 @@ static int init_common_variables(const char *conf_file_name, int argc, max_system_variables.pseudo_thread_id= (ulong)~0; start_time=time((time_t*) 0); + if (init_thread_environment()) + return 1; mysql_init_variables(); #ifdef OS2 @@ -2114,8 +2112,6 @@ static int init_common_variables(const char *conf_file_name, int argc, load_defaults(conf_file_name, groups, &argc, &argv); defaults_argv=argv; get_options(argc,argv); - if (init_thread_environment()) - return 1; if (opt_log || opt_update_log || opt_slow_log || opt_bin_log) strcat(server_version,"-log"); DBUG_PRINT("info",("%s Ver %s for %s on %s\n",my_progname, @@ -2204,7 +2200,6 @@ static int init_thread_environment() (void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_assign, MY_MUTEX_INIT_FAST); (void) my_rwlock_init(&LOCK_grant, NULL); (void) pthread_cond_init(&COND_thread_count,NULL); (void) pthread_cond_init(&COND_refresh,NULL); @@ -2256,7 +2251,6 @@ static int init_server_components() { DBUG_ENTER("init_server_components"); table_cache_init(); - assign_cache_init(); hostname_cache_init(); query_cache_result_size_limit(query_cache_limit); query_cache_set_min_res_unit(query_cache_min_res_unit); @@ -2328,9 +2322,10 @@ Now disabling --log-slave-updates."); if (opt_myisam_log) (void) mi_log(1); - ha_key_cache(&dflt_key_cache_var); - process_key_caches(&ha_key_cache); - + /* call ha_init_key_cache() on all key caches to init them */ + process_key_caches(&ha_init_key_cache); + /* We must set dflt_key_cache in case we are using ISAM tables */ + dflt_key_cache= sql_key_cache; #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) if (locked_in_memory && !geteuid()) @@ -2796,7 +2791,7 @@ int main(int argc, char **argv) but we started a bad tradition by calling it MySQL from the start and we are now stuck with it. */ - if (my_strcasecmp(argv[1],"mysql")) + if (my_strcasecmp(system_charset_info, argv[1],"mysql")) load_default_groups[3]= argv[1]; start_mode= 1; Service.Init(argv[1], mysql_service); @@ -2817,7 +2812,7 @@ int main(int argc, char **argv) opt_argc= 2; // Skip service-name opt_argv=argv; start_mode= 1; - if (my_strcasecmp(argv[2],"mysql")) + if (my_strcasecmp(system_charset_info, argv[2],"mysql")) load_default_groups[3]= argv[2]; Service.Init(argv[2], mysql_service); return 0; @@ -4320,26 +4315,29 @@ replicating a LOAD DATA INFILE command.", IO_SIZE, 0}, {"key_buffer_size", OPT_KEY_BUFFER_SIZE, "The size of the buffer used for index blocks for MyISAM tables. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common.", - (gptr*) &dflt_key_cache_var.buff_size, - (gptr*) &dflt_key_cache_var.buff_size, 0, - (enum get_opt_var_type) (GET_ULL | GET_ASK_ADDR), + (gptr*) &dflt_key_cache_var.param_buff_size, + (gptr*) 0, + 0, (enum get_opt_var_type) (GET_ULL | GET_ASK_ADDR), REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE, 0}, {"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE, "The default size of key cache blocks", - (gptr*) &dflt_key_cache_var.block_size, - (gptr*) &dflt_key_cache_var.block_size, 0, GET_ULONG, - REQUIRED_ARG, KEY_CACHE_BLOCK_SIZE , 512, 1024*16, MALLOC_OVERHEAD, 512, 0}, + (gptr*) &dflt_key_cache_var.param_block_size, + (gptr*) 0, + 0, (enum get_opt_var_type) (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, + KEY_CACHE_BLOCK_SIZE , 512, 1024*16, MALLOC_OVERHEAD, 512, 0}, {"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT, "The minimum percentage of warm blocks in key cache", - (gptr*) &dflt_key_cache_var.division_limit, - (gptr*) &dflt_key_cache_var.division_limit, 0, GET_ULONG, - REQUIRED_ARG, 100, 1, 100, 0, 1, 0}, + (gptr*) &dflt_key_cache_var.param_division_limit, + (gptr*) 0, + 0, (enum get_opt_var_type) (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100, + 1, 100, 0, 1, 0}, {"key_cache_division_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD, "This characterizes the number of hits a hot block has to be untouched until it is considered aged enough to be downgraded to a warm block. This specifies the percentage ratio of that number of hits to the total number of blocks in key cache", - (gptr*) &dflt_key_cache_var.age_threshold, - (gptr*) &dflt_key_cache_var.age_threshold, 0, GET_ULONG, - REQUIRED_ARG, 300, 100, ~0L, 0, 100, 0}, + (gptr*) &dflt_key_cache_var.param_age_threshold, + (gptr*) 0, + 0, (enum get_opt_var_type) (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, + 300, 100, ~0L, 0, 100, 0}, {"long_query_time", OPT_LONG_QUERY_TIME, "Log all queries that have taken more than long_query_time seconds to execute to file.", (gptr*) &global_system_variables.long_query_time, @@ -4758,19 +4756,19 @@ struct show_var_st status_vars[]= { {"Handler_rollback", (char*) &ha_rollback_count, SHOW_LONG}, {"Handler_update", (char*) &ha_update_count, SHOW_LONG}, {"Handler_write", (char*) &ha_write_count, SHOW_LONG}, - {"Key_blocks_used", (char*) &dflt_key_cache_var.blocks_used, - SHOW_LONG_CONST}, - {"Key_read_requests", (char*) &dflt_key_cache_var.cache_r_requests, - SHOW_LONG}, - {"Key_reads", (char*) &dflt_key_cache_var.cache_read, - SHOW_LONG}, - {"Key_write_requests", (char*) &dflt_key_cache_var.cache_w_requests, - SHOW_LONG}, - {"Key_writes", (char*) &dflt_key_cache_var.cache_write, - SHOW_LONG}, + {"Key_blocks_not_flushed", (char*) &dflt_key_cache_var.global_blocks_changed, + SHOW_KEY_CACHE_LONG}, + {"Key_blocks_used", (char*) &dflt_key_cache_var.global_blocks_used, + SHOW_KEY_CACHE_LONG}, + {"Key_read_requests", (char*) &dflt_key_cache_var.global_cache_r_requests, + SHOW_KEY_CACHE_LONG}, + {"Key_reads", (char*) &dflt_key_cache_var.global_cache_read, + SHOW_KEY_CACHE_LONG}, + {"Key_write_requests", (char*) &dflt_key_cache_var.global_cache_w_requests, + SHOW_KEY_CACHE_LONG}, + {"Key_writes", (char*) &dflt_key_cache_var.global_cache_write, + SHOW_KEY_CACHE_LONG}, {"Max_used_connections", (char*) &max_used_connections, SHOW_LONG}, - {"Not_flushed_key_blocks", (char*) &dflt_key_cache_var.blocks_changed, - SHOW_LONG_CONST}, {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_CONST}, {"Open_tables", (char*) 0, SHOW_OPENTABLES}, {"Open_files", (char*) &my_file_opened, SHOW_LONG_CONST}, @@ -4984,8 +4982,9 @@ static void mysql_init_variables(void) threads.empty(); thread_cache.empty(); key_caches.empty(); - if (!get_or_create_key_cache(DEFAULT_KEY_CACHE_NAME, - strlen(DEFAULT_KEY_CACHE_NAME))) + multi_keycache_init(); + if (!(sql_key_cache= get_or_create_key_cache(default_key_cache_base.str, + default_key_cache_base.length))) exit(1); /* Initialize structures that is used when processing options */ @@ -5075,9 +5074,9 @@ static void mysql_init_variables(void) have_crypt=SHOW_OPTION_NO; #endif #ifdef HAVE_COMPRESS - SHOW_COMP_OPTION have_compress= SHOW_OPTION_YES; + have_compress= SHOW_OPTION_YES; #else - SHOW_COMP_OPTION have_compress= SHOW_OPTION_NO; + have_compress= SHOW_OPTION_NO; #endif #ifdef HAVE_LIBWRAP libwrapName= NullS; @@ -5608,18 +5607,18 @@ mysql_getopt_value(const char *keyname, uint key_length, case OPT_KEY_CACHE_DIVISION_LIMIT: case OPT_KEY_CACHE_AGE_THRESHOLD: { - KEY_CACHE_VAR *key_cache; + KEY_CACHE *key_cache; if (!(key_cache= get_or_create_key_cache(keyname, key_length))) exit(1); switch (option->id) { case OPT_KEY_BUFFER_SIZE: - return (gptr*) &key_cache->buff_size; + return (gptr*) &key_cache->param_buff_size; case OPT_KEY_CACHE_BLOCK_SIZE: - return (gptr*) &key_cache->block_size; + return (gptr*) &key_cache->param_block_size; case OPT_KEY_CACHE_DIVISION_LIMIT: - return (gptr*) &key_cache->division_limit; + return (gptr*) &key_cache->param_division_limit; case OPT_KEY_CACHE_AGE_THRESHOLD: - return (gptr*) &key_cache->age_threshold; + return (gptr*) &key_cache->param_age_threshold; } } } @@ -5699,13 +5698,6 @@ static void get_options(int argc,char **argv) init_global_datetime_format(TIMESTAMP_DATETIME, &global_system_variables.datetime_format)) exit(1); - - /* Set up default values for a key cache */ - KEY_CACHE_VAR *key_cache= &dflt_key_cache_var; - dflt_key_cache_block_size= key_cache->block_size; - dflt_key_buff_size= key_cache->buff_size; - dflt_key_cache_division_limit= key_cache->division_limit; - dflt_key_cache_age_threshold= key_cache->age_threshold; } diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 932aceebdbb..4fdcd093132 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -83,7 +83,6 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) table_map removed_tables= 0, outer_tables= 0, used_tables= 0; table_map where_tables= 0; Item *item; - COND *org_conds= conds; int error; if (conds) diff --git a/sql/protocol.cc b/sql/protocol.cc index 8ba3cdec8e0..e1347ff3c6f 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -120,6 +120,10 @@ void send_error(THD *thd, uint sql_errno, const char *err) #endif /* EMBEDDED_LIBRARY*/ thd->is_fatal_error=0; // Error message is given thd->net.report_error= 0; + + /* Abort multi-result sets */ + thd->lex.found_colon= 0; + thd->server_status= ~SERVER_MORE_RESULTS_EXISTS; DBUG_VOID_RETURN; } @@ -298,6 +302,8 @@ send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message) pos=net_store_data((char*) pos, message, strlen(message)); VOID(my_net_write(net,buff,(uint) (pos-buff))); VOID(net_flush(net)); + /* We can't anymore send an error to the client */ + thd->net.report_error= 0; DBUG_VOID_RETURN; } @@ -338,7 +344,14 @@ send_eof(THD *thd, bool no_flush) uint tmp= min(thd->total_warn_count, 65535); buff[0]=254; int2store(buff+1, tmp); - int2store(buff+3, 0); // No flags yet + /* + The following test should never be true, but it's better to do it + because if 'is_fatal_error' is set the server is not going to execute + other queries (see the if test in dispatch_command / COM_QUERY) + */ + if (thd->is_fatal_error) + thd->server_status= ~SERVER_MORE_RESULTS_EXISTS; + int2store(buff+3, thd->server_status); VOID(my_net_write(net,(char*) buff,5)); VOID(net_flush(net)); } diff --git a/sql/protocol_cursor.cc b/sql/protocol_cursor.cc index 19e3bb06d74..563a2d41019 100644 --- a/sql/protocol_cursor.cc +++ b/sql/protocol_cursor.cc @@ -30,7 +30,7 @@ bool Protocol_cursor::send_fields(List<Item> *list, uint flag) { List_iterator_fast<Item> it(*list); Item *item; - MYSQL_FIELD *field, *client_field; + MYSQL_FIELD *client_field; DBUG_ENTER("send_fields"); if (prepare_for_send(list)) @@ -71,9 +71,9 @@ bool Protocol_cursor::send_fields(List<Item> *list, uint flag) String tmp(buff, sizeof(buff), default_charset_info), *res; if (!(res=item->val_str(&tmp))) - client_field->def= strdup_root(alloc, ""); + client_field->def= (char*) ""; else - client_field->def= strdup_root(alloc, tmp.ptr()); + client_field->def= strmake_root(alloc, res->ptr(), res->length()); } else client_field->def=0; diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index aba887be070..0d2da91e015 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -254,7 +254,7 @@ static int find_target_pos(LEX_MASTER_INFO *mi, IO_CACHE *log, char *errmsg) it is reworked. Event's log_pos used to be preserved through log-slave-updates to make code in repl_failsafe.cc work (this function, SHOW NEW MASTER); but on the other side it caused unexpected - values in Exec_master_log_pos in A->B->C replication setup, + values in Exec_Master_Log_Pos in A->B->C replication setup, synchronization problems in master_pos_wait(), ... So we (Dmitri & Guilhem) removed it. @@ -623,7 +623,6 @@ err: int show_slave_hosts(THD* thd) { List<Item> field_list; - NET* net = &thd->net; Protocol *protocol= thd->protocol; DBUG_ENTER("show_slave_hosts"); diff --git a/sql/set_var.cc b/sql/set_var.cc index 76fb2e0a4b3..9b7be4afacc 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -60,11 +60,6 @@ #include "ha_innodb.h" #endif -ulonglong dflt_key_buff_size; -uint dflt_key_cache_block_size; -uint dflt_key_cache_division_limit; -uint dflt_key_cache_age_threshold; - static HASH system_variable_hash; const char *bool_type_names[]= { "OFF", "ON", NullS }; TYPELIB bool_typelib= @@ -97,7 +92,7 @@ static void fix_myisam_max_sort_file_size(THD *thd, enum_var_type type); static void fix_max_binlog_size(THD *thd, enum_var_type type); static void fix_max_relay_log_size(THD *thd, enum_var_type type); static void fix_max_connections(THD *thd, enum_var_type type); -static KEY_CACHE_VAR *create_key_cache(const char *name, uint length); +static KEY_CACHE *create_key_cache(const char *name, uint length); void fix_sql_mode_var(THD *thd, enum_var_type type); static byte *get_error_count(THD *thd); static byte *get_warning_count(THD *thd); @@ -148,11 +143,15 @@ sys_var_thd_ulong sys_interactive_timeout("interactive_timeout", sys_var_thd_ulong sys_join_buffer_size("join_buffer_size", &SV::join_buff_size); sys_var_key_buffer_size sys_key_buffer_size("key_buffer_size"); -sys_var_key_cache_block_size sys_key_cache_block_size("key_cache_block_size"); -sys_var_key_cache_division_limit - sys_key_cache_division_limit("key_cache_division_limit"); -sys_var_key_cache_age_threshold - sys_key_cache_age_threshold("key_cache_age_threshold"); +sys_var_key_cache_long sys_key_cache_block_size("key_cache_block_size", + offsetof(KEY_CACHE, + param_block_size)); +sys_var_key_cache_long sys_key_cache_division_limit("key_cache_division_limit", + offsetof(KEY_CACHE, + param_division_limit)); +sys_var_key_cache_long sys_key_cache_age_threshold("key_cache_age_threshold", + offsetof(KEY_CACHE, + param_age_threshold)); sys_var_bool_ptr sys_local_infile("local_infile", &opt_local_infile); sys_var_thd_bool sys_log_warnings("log_warnings", &SV::log_warnings); @@ -1266,7 +1265,13 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) } switch (type()) { case SHOW_LONG: - return new Item_uint((int32) *(ulong*) value_ptr(thd, var_type, base)); + { + ulong value; + pthread_mutex_lock(&LOCK_global_system_variables); + value= *(ulong*) value_ptr(thd, var_type, base); + pthread_mutex_unlock(&LOCK_global_system_variables); + return new Item_uint((int32) value); + } case SHOW_LONGLONG: { longlong value; @@ -1771,142 +1776,158 @@ void sys_var_collation_server::set_default(THD *thd, enum_var_type type) } -static LEX_STRING default_key_cache_base= {(char *) DEFAULT_KEY_CACHE_NAME, 7}; +LEX_STRING default_key_cache_base= {(char *) "default", 7 }; -static KEY_CACHE_VAR zero_key_cache= - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +static KEY_CACHE zero_key_cache; -static KEY_CACHE_VAR *get_key_cache(LEX_STRING *cache_name) +KEY_CACHE *get_key_cache(LEX_STRING *cache_name) { - if (!cache_name || !cache_name->str || !cache_name->length || - cache_name->str == default_key_cache_base.str || - (cache_name->length == default_key_cache_base.length && - !memcmp(cache_name->str, default_key_cache_base.str, - default_key_cache_base.length))) + safe_mutex_assert_owner(&LOCK_global_system_variables); + if (!cache_name || ! cache_name->length) cache_name= &default_key_cache_base; - return ((KEY_CACHE_VAR*) find_named(&key_caches, - cache_name->str, cache_name->length, - 0)); + return ((KEY_CACHE*) find_named(&key_caches, + cache_name->str, cache_name->length, 0)); } + byte *sys_var_key_cache_param::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base) { - KEY_CACHE_VAR *key_cache= get_key_cache(base); + KEY_CACHE *key_cache= get_key_cache(base); if (!key_cache) key_cache= &zero_key_cache; return (byte*) key_cache + offset ; } + bool sys_var_key_buffer_size::update(THD *thd, set_var *var) { ulonglong tmp= var->save_result.ulonglong_value; - LEX_STRING *base_name= &var->base; + KEY_CACHE *key_cache; + bool error= 0; + + /* If no basename, assume it's for the key cache named 'default' */ if (!base_name->length) base_name= &default_key_cache_base; - KEY_CACHE_VAR *key_cache= get_key_cache(base_name); + + pthread_mutex_lock(&LOCK_global_system_variables); + key_cache= get_key_cache(base_name); if (!key_cache) { + /* Key cache didn't exists */ if (!tmp) // Tried to delete cache - return 0; // Ok, nothing to do - if (!(key_cache= create_key_cache(base_name->str, - base_name->length))) - return 1; + goto end; // Ok, nothing to do + if (!(key_cache= create_key_cache(base_name->str, base_name->length))) + { + error= 1; + goto end; + } } + + /* + Abort if some other thread is changing the key cache + TODO: This should be changed so that we wait until the previous + assignment is done and then do the new assign + */ + if (key_cache->in_init) + goto end; + if (!tmp) // Zero size means delete { - if (!key_cache->cache) - return 0; - /* Delete not default key caches */ - if (key_cache != &dflt_key_cache_var) + if (key_cache == sql_key_cache) + goto end; // Ignore default key cache + + if (key_cache->key_cache_inited) // If initied { /* - Move tables using this key cache to the default key cache - and remove this key cache if no tables are assigned to it + Move tables using this key cache to the default key cache + and clear the old key cache. */ NAMED_LIST *list; - key_cache= (KEY_CACHE_VAR *) find_named(&key_caches, base_name->str, + key_cache= (KEY_CACHE *) find_named(&key_caches, base_name->str, base_name->length, &list); - delete list; - int rc= reassign_keycache_tables(thd, key_cache, - default_key_cache_base.str, 1); - my_free((char*) key_cache, MYF(0)); - return rc; - + key_cache->in_init= 1; + pthread_mutex_unlock(&LOCK_global_system_variables); + error= reassign_keycache_tables(thd, key_cache, sql_key_cache); + pthread_mutex_lock(&LOCK_global_system_variables); + key_cache->in_init= 0; } - return 0; + /* + We don't delete the key cache as some running threads my still be + in the key cache code with a pointer to the deleted (empty) key cache + */ + goto end; } - key_cache->buff_size= (ulonglong) getopt_ull_limit_value(tmp, option_limits); + key_cache->param_buff_size= + (ulonglong) getopt_ull_limit_value(tmp, option_limits); + + /* If key cache didn't existed initialize it, else resize it */ + key_cache->in_init= 1; + pthread_mutex_unlock(&LOCK_global_system_variables); - if (!key_cache->cache) - return (bool)(ha_key_cache(key_cache)); + if (!key_cache->key_cache_inited) + error= (bool) (ha_init_key_cache("", key_cache)); else - return (bool)(ha_resize_key_cache(key_cache)); -} + error= (bool)(ha_resize_key_cache(key_cache)); -bool sys_var_key_cache_block_size::update(THD *thd, set_var *var) -{ - ulong tmp= var->value->val_int(); - LEX_STRING *base_name= &var->base; - if (!base_name->length) - base_name= &default_key_cache_base; - KEY_CACHE_VAR *key_cache= get_key_cache(base_name); - - if (!key_cache && !(key_cache= create_key_cache(base_name->str, - base_name->length))) - return 1; - - key_cache->block_size= (ulong) getopt_ull_limit_value(tmp, option_limits); + pthread_mutex_lock(&LOCK_global_system_variables); + key_cache->in_init= 0; - if (key_cache->cache) - /* Do not build a new key cache here */ - return (bool) (ha_resize_key_cache(key_cache)); - return 0; +end: + pthread_mutex_unlock(&LOCK_global_system_variables); + return error; } -bool sys_var_key_cache_division_limit::update(THD *thd, set_var *var) + +bool sys_var_key_cache_long::update(THD *thd, set_var *var) { - ulong tmp= var->value->val_int(); + ulong tmp= (ulong) var->value->val_int(); LEX_STRING *base_name= &var->base; + bool error= 0; + if (!base_name->length) base_name= &default_key_cache_base; - KEY_CACHE_VAR *key_cache= get_key_cache(base_name); + + pthread_mutex_lock(&LOCK_global_system_variables); + KEY_CACHE *key_cache= get_key_cache(base_name); if (!key_cache && !(key_cache= create_key_cache(base_name->str, base_name->length))) - return 1; + { + error= 1; + goto end; + } - key_cache->division_limit= + /* + Abort if some other thread is changing the key cache + TODO: This should be changed so that we wait until the previous + assignment is done and then do the new assign + */ + if (key_cache->in_init) + goto end; + + *((ulong*) (((char*) key_cache) + offset))= (ulong) getopt_ull_limit_value(tmp, option_limits); - if (key_cache->cache) - /* Do not build a new key cache here */ - return (bool) (ha_change_key_cache_param(key_cache)); - return 0; -} + /* + Don't create a new key cache if it didn't exist + (key_caches are created only when the user sets block_size) + */ + key_cache->in_init= 1; -bool sys_var_key_cache_age_threshold::update(THD *thd, set_var *var) -{ - ulong tmp= var->value->val_int(); - LEX_STRING *base_name= &var->base; - if (!base_name->length) - base_name= &default_key_cache_base; - KEY_CACHE_VAR *key_cache= get_key_cache(base_name); - - if (!key_cache && !(key_cache= create_key_cache(base_name->str, - base_name->length))) - return 1; - - key_cache->division_limit= - (ulong) getopt_ull_limit_value(tmp, option_limits); + pthread_mutex_unlock(&LOCK_global_system_variables); - if (key_cache->cache) - /* Do not build a new key cache here */ - return (bool) (ha_change_key_cache_param(key_cache)); - return 0; + error= (bool) (ha_resize_key_cache(key_cache)); + + pthread_mutex_lock(&LOCK_global_system_variables); + key_cache->in_init= 0; + +end: + pthread_mutex_unlock(&LOCK_global_system_variables); + return error; } @@ -2392,7 +2413,6 @@ byte *sys_var_thd_sql_mode::value_ptr(THD *thd, enum_var_type type, ulong val; char buff[256]; String tmp(buff, sizeof(buff), &my_charset_latin1); - my_bool found= 0; tmp.length(0); val= ((type == OPT_GLOBAL) ? global_system_variables.*offset : @@ -2506,13 +2526,14 @@ gptr find_named(I_List<NAMED_LIST> *list, const char *name, uint length, } -void delete_elements(I_List<NAMED_LIST> *list, void (*free_element)(gptr)) +void delete_elements(I_List<NAMED_LIST> *list, + void (*free_element)(const char *name, gptr)) { NAMED_LIST *element; DBUG_ENTER("delete_elements"); while ((element= list->get())) { - (*free_element)(element->data); + (*free_element)(element->name, element->data); delete element; } DBUG_VOID_RETURN; @@ -2521,63 +2542,68 @@ void delete_elements(I_List<NAMED_LIST> *list, void (*free_element)(gptr)) /* Key cache functions */ -static KEY_CACHE_VAR *create_key_cache(const char *name, uint length) +static KEY_CACHE *create_key_cache(const char *name, uint length) { - KEY_CACHE_VAR *key_cache; - DBUG_PRINT("info",("Creating key cache: %.*s length: %d", length, name, - length)); - if (length != default_key_cache_base.length || - memcmp(name, default_key_cache_base.str, length)) - { - if ((key_cache= (KEY_CACHE_VAR*) my_malloc(sizeof(KEY_CACHE_VAR), - MYF(MY_ZEROFILL | MY_WME)))) - { - if (!new NAMED_LIST(&key_caches, name, length, (gptr) key_cache)) - { - my_free((char*) key_cache, MYF(0)); - key_cache= 0; - } - } - } - else + KEY_CACHE *key_cache; + DBUG_ENTER("create_key_cache"); + DBUG_PRINT("enter",("name: %.*s", length, name)); + + if ((key_cache= (KEY_CACHE*) my_malloc(sizeof(KEY_CACHE), + MYF(MY_ZEROFILL | MY_WME)))) { - key_cache= &dflt_key_cache_var; if (!new NAMED_LIST(&key_caches, name, length, (gptr) key_cache)) + { + my_free((char*) key_cache, MYF(0)); key_cache= 0; + } + else + { + /* + Set default values for a key cache + The values in dflt_key_cache_var is set by my_getopt() at startup + + We don't set 'buff_size' as this is used to enable the key cache + */ + key_cache->param_block_size= dflt_key_cache_var.param_block_size; + key_cache->param_division_limit= dflt_key_cache_var.param_division_limit; + key_cache->param_age_threshold= dflt_key_cache_var.param_age_threshold; + } } - - return key_cache; + DBUG_RETURN(key_cache); } -KEY_CACHE_VAR *get_or_create_key_cache(const char *name, uint length) +KEY_CACHE *get_or_create_key_cache(const char *name, uint length) { LEX_STRING key_cache_name; + KEY_CACHE *key_cache; + key_cache_name.str= (char *) name; key_cache_name.length= length; - KEY_CACHE_VAR *key_cache= get_key_cache(&key_cache_name); - if (!key_cache) + pthread_mutex_lock(&LOCK_global_system_variables); + if (!(key_cache= get_key_cache(&key_cache_name))) key_cache= create_key_cache(name, length); + pthread_mutex_unlock(&LOCK_global_system_variables); return key_cache; } -void free_key_cache(gptr key_cache) +void free_key_cache(const char *name, KEY_CACHE *key_cache) { - if (key_cache != (gptr) &dflt_key_cache_var) - my_free(key_cache, MYF(0)); + ha_end_key_cache(key_cache); + my_free((char*) key_cache, MYF(0)); } -bool process_key_caches(int (* func) (KEY_CACHE_VAR *)) -{ +bool process_key_caches(int (* func) (const char *name, KEY_CACHE *)) +{ I_List_iterator<NAMED_LIST> it(key_caches); NAMED_LIST *element; + while ((element= it++)) { - KEY_CACHE_VAR *key_cache= (KEY_CACHE_VAR *) element->data; - if (key_cache != &dflt_key_cache_var) - func(key_cache); + KEY_CACHE *key_cache= (KEY_CACHE *) element->data; + func(element->name, key_cache); } return 0; } diff --git a/sql/set_var.h b/sql/set_var.h index c799eec750a..58ae53190e0 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -30,11 +30,6 @@ class set_var; typedef struct system_variables SV; extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib; -extern ulonglong dflt_key_buff_size; -extern uint dflt_key_cache_block_size; -extern uint dflt_key_cache_division_limit; -extern uint dflt_key_cache_age_threshold; - enum enum_var_type { OPT_DEFAULT, OPT_SESSION, OPT_GLOBAL @@ -546,73 +541,40 @@ public: byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); }; + class sys_var_key_cache_param :public sys_var { protected: - uint offset; + size_t offset; public: - sys_var_key_cache_param(const char *name_arg) - :sys_var(name_arg) - { - offset= 0; - } + sys_var_key_cache_param(const char *name_arg, size_t offset_arg) + :sys_var(name_arg), offset(offset_arg) + {} byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); + bool check_default(enum_var_type type) { return 1; } + bool is_struct() { return 1; } }; + class sys_var_key_buffer_size :public sys_var_key_cache_param { public: sys_var_key_buffer_size(const char *name_arg) - :sys_var_key_cache_param(name_arg) - { - offset= offsetof(KEY_CACHE_VAR, buff_size); - } + :sys_var_key_cache_param(name_arg, offsetof(KEY_CACHE, param_buff_size)) + {} bool update(THD *thd, set_var *var); SHOW_TYPE type() { return SHOW_LONGLONG; } - bool check_default(enum_var_type type) { return 1; } - bool is_struct() { return 1; } -}; - -class sys_var_key_cache_block_size :public sys_var_key_cache_param -{ -public: - sys_var_key_cache_block_size(const char *name_arg) - :sys_var_key_cache_param(name_arg) - { - offset= offsetof(KEY_CACHE_VAR, block_size); - } - bool update(THD *thd, set_var *var); - SHOW_TYPE type() { return SHOW_LONG; } - bool check_default(enum_var_type type) { return 1; } - bool is_struct() { return 1; } }; -class sys_var_key_cache_division_limit :public sys_var_key_cache_param -{ -public: - sys_var_key_cache_division_limit(const char *name_arg) - :sys_var_key_cache_param(name_arg) - { - offset= offsetof(KEY_CACHE_VAR, division_limit); - } - bool update(THD *thd, set_var *var); - SHOW_TYPE type() { return SHOW_LONG; } - bool check_default(enum_var_type type) { return 1; } - bool is_struct() { return 1; } -}; -class sys_var_key_cache_age_threshold :public sys_var_key_cache_param +class sys_var_key_cache_long :public sys_var_key_cache_param { public: - sys_var_key_cache_age_threshold(const char *name_arg) - :sys_var_key_cache_param(name_arg) - { - offset= offsetof(KEY_CACHE_VAR, age_threshold); - } + sys_var_key_cache_long(const char *name_arg, size_t offset_arg) + :sys_var_key_cache_param(name_arg, offset_arg) + {} bool update(THD *thd, set_var *var); SHOW_TYPE type() { return SHOW_LONG; } - bool check_default(enum_var_type type) { return 1; } - bool is_struct() { return 1; } }; @@ -781,7 +743,7 @@ public: uint name_length_arg, gptr data_arg) :name_length(name_length_arg), data(data_arg) { - name= my_memdup((byte*) name_arg, name_length, MYF(MY_WME)); + name= my_strdup_with_length((byte*) name_arg, name_length, MYF(MY_WME)); links->push_back(this); } inline bool cmp(const char *name_cmp, uint length) @@ -792,11 +754,16 @@ public: { my_free((char*) name, MYF(0)); } + friend bool process_key_caches(int (* func) (const char *name, + KEY_CACHE *)); + friend void delete_elements(I_List<NAMED_LIST> *list, + void (*free_element)(const char*, gptr)); }; /* updated in sql_acl.cc */ extern sys_var_thd_bool sys_old_passwords; +extern LEX_STRING default_key_cache_base; /* For sql_yacc */ struct sys_var_with_base @@ -819,9 +786,11 @@ extern sys_var_str sys_charset_system; CHARSET_INFO *get_old_charset_by_name(const char *old_name); gptr find_named(I_List<NAMED_LIST> *list, const char *name, uint length, NAMED_LIST **found); -void delete_elements(I_List<NAMED_LIST> *list, void (*free_element)(gptr)); /* key_cache functions */ -KEY_CACHE_VAR *get_or_create_key_cache(const char *name, uint length); -void free_key_cache(gptr key_cache); -bool process_key_caches(int (* func) (KEY_CACHE_VAR *)); +KEY_CACHE *get_key_cache(LEX_STRING *cache_name); +KEY_CACHE *get_or_create_key_cache(const char *name, uint length); +void free_key_cache(const char *name, KEY_CACHE *key_cache); +bool process_key_caches(int (* func) (const char *name, KEY_CACHE *)); +void delete_elements(I_List<NAMED_LIST> *list, + void (*free_element)(const char*, gptr)); diff --git a/sql/share/charsets/cp850.xml b/sql/share/charsets/cp850.xml index ae2aebf13fa..d750bac37e2 100644 --- a/sql/share/charsets/cp850.xml +++ b/sql/share/charsets/cp850.xml @@ -15,13 +15,13 @@ 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 30 - 02 02 02 02 02 02 02 02 02 02 02 02 02 02 01 01 - 01 02 01 02 02 02 02 02 02 01 01 10 10 10 10 10 + 01 02 02 02 02 02 02 02 02 02 02 02 02 02 01 01 + 01 02 01 02 02 02 02 02 02 01 01 02 10 01 10 10 02 02 02 02 02 01 10 10 10 10 10 10 10 10 10 10 - 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 - 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 - 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 - 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 10 10 10 10 10 01 01 01 10 10 10 10 10 10 10 10 + 10 10 10 10 10 10 02 01 10 10 10 10 10 10 10 10 + 02 01 01 01 01 02 01 01 01 10 10 10 10 10 01 10 + 01 02 01 01 02 01 10 02 01 01 01 01 02 01 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 20 </map> </ctype> @@ -82,13 +82,13 @@ 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006a 006b 006c 006d 006e 006f 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007a 007b 007c 007d 007e 007f 00c7 00fc 00e9 00e2 00e4 00e0 00e5 00e7 00ea 00eb 00e8 00ef 00ee 00ec 00c4 00c5 -00c9 00e6 00c6 00f4 00f6 00f2 00fb 00f9 00ff 00d6 00dc 00a2 00a3 00a5 20a7 0192 -00e1 00ed 00f3 00fa 00f1 00d1 00aa 00ba 00bf 2310 00ac 00bd 00bc 00a1 00ab 00bb -2591 2592 2593 2502 2524 2561 2562 2556 2555 2563 2551 2557 255d 255c 255b 2510 -2514 2534 252c 251c 2500 253c 255e 255f 255a 2554 2569 2566 2560 2550 256c 2567 -2568 2564 2565 2559 2558 2552 2553 256b 256a 2518 250c 2588 2584 258c 2590 2580 -03b1 00df 0393 03c0 03a3 03c3 00b5 03c4 03a6 0398 03a9 03b4 221e 03c6 03b5 2229 -2261 00b1 2265 2264 2320 2321 00f7 2248 00b0 2219 00b7 221a 207f 00b2 25a0 00a0 +00c9 00e6 00c6 00f4 00f6 00f2 00fb 00f9 00ff 00d6 00dc 00f8 00a3 00d8 00d7 0192 +00e1 00ed 00f3 00fa 00f1 00d1 00aa 00ba 00bf 00ae 00ac 00bd 00bc 00a1 00ab 00bb +2591 2592 2593 2502 2524 00c1 00c2 00c0 00a9 2563 2551 2557 255d 00a2 00a5 2510 +2514 2534 252c 251c 2500 253c 00e3 00c3 255a 2554 2569 2566 2560 2550 256c 00a4 +00f0 00d0 00ca 00cb 00c8 0131 00cd 00ce 00cf 2518 250c 2588 2584 00a6 00cc 2580 +00d3 00df 00d4 00d2 00f5 00d5 00b5 00fe 00de 00da 00db 00d9 00fd 00dd 00af 00b4 +00ad 00b1 2017 00be 00b6 00a7 00f7 00b8 00b0 00a8 00b7 00b9 00b3 00b2 25a0 00a0 </map> </unicode> @@ -99,18 +99,18 @@ 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F - 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F - 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F - 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F - 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F - 43 59 45 41 5C 41 5B 43 45 45 45 49 49 49 5C 5B - 45 5C 5C 4F 5D 4F 55 55 59 5D 59 24 24 24 24 24 - 41 49 4F 55 4E 4E A6 A7 3F A9 AA AB AC 21 22 22 - B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF - C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF - D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF - E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF - F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + 40 41 51 53 55 59 63 65 67 69 74 76 78 7A 7C 80 + 8E 90 92 94 97 99 A3 A5 A7 A9 AE B1 B2 B3 B4 B5 + B6 41 51 53 55 59 63 65 67 69 74 76 78 7A 7C 80 + 8E 90 92 94 97 99 A3 A5 A7 A9 AE B7 B8 B9 BA BB + 54 A1 5D 47 4B 43 4D 54 5F 61 5B 71 6F 6B 4B 4D + 5D 4F 4F 86 8A 82 9F 9B AD 8A A1 8C E3 8C BD BE + 45 6D 84 9D 7E 7E EA FA FF EE EC FD FC CE EB FB + DC DD DE C3 C9 45 47 43 E9 D5 CF D1 D3 E2 E5 C5 + C6 CB CA C8 C2 CC 49 49 D2 D0 D7 D6 D4 CD D8 E4 + 57 57 5F 61 5B 73 6D 6F 71 C7 C4 DB DA E6 6B D9 + 84 96 86 82 88 88 F5 B0 B0 9D 9F 9B AB AB EF F4 + ED F1 C1 FE F6 E7 BF BC F0 E8 F7 F9 F3 F2 DF E0 </map> </collation> diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index c01df3b53cd..c40765ebf94 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -291,11 +291,8 @@ character-set=latin2 "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index e67c430c4f7..98540e1bd0a 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -285,11 +285,8 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 5f77163eeda..44c9399b821 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -293,11 +293,8 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index baecefb8494..e4f7c27610b 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -282,11 +282,8 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to use --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL. Otherwise you will get problems if you get an unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 09e63ddd804..dec488567ff 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -287,11 +287,8 @@ character-set=latin7 "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 0956db6681e..c41c927d539 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -282,11 +282,8 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 2cc98971915..0425a709950 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -294,11 +294,8 @@ character-set=latin1 "Falscher Parameter oder falsche Kombination von Parametern für START SLAVE UNTIL", "Es wird empfohlen, mit --skip-slave-start zu starten, wenn mit START SLAVE UNTIL eine Schritt-für-Schritt-Replikation ausgeführt wird. Ansonsten gibt es Probleme, wenn der Slave-Server unerwartet neu startet", "SQL-Thread soll nicht gestartet werden. Daher werden UNTIL-Optionen ignoriert", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 84e48d2f284..3cf5bbf592d 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -282,11 +282,8 @@ character-set=greek "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index da71f4b7da6..f1b719ba716 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -284,11 +284,8 @@ character-set=latin2 "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 4ed4d477ab8..ed39950e9f1 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -282,11 +282,8 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index d28cc026159..9760cd3f9e8 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -284,11 +284,8 @@ character-set=ujis "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index b0c4bf9463e..10eed3bb2de 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -282,11 +282,8 @@ character-set=euckr "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 1e9028de1d7..7149eea8b10 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -284,11 +284,8 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 942c18cc045..dc96d39f8dc 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -284,11 +284,8 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 17e6df6c443..b2b2e52ad75 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -286,11 +286,8 @@ character-set=latin2 "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index fdf428c9b6d..c4a150d79bf 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -283,11 +283,8 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 8f4fdb3a702..dce141da20a 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -286,11 +286,8 @@ character-set=latin2 "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 2ef6a2c553b..27c1b49f4f0 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -284,11 +284,8 @@ character-set=koi8r "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "ëÅÛ ÚÁÐÒÏÓÏ× ÎÅ ÍÏÖÅÔ ÕÓÔÁÎÏ×ÉÔØ ÒÁÚÍÅÒ %lu, ÎÏ×ÙÊ ÒÁÚÍÅÒ ËÅÛÁ ÚÐÒÏÓÏ× - %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index cddc1059f44..5311fa016dc 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -277,11 +277,8 @@ character-set=cp1250 "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 466e7d478b6..9355e8fc0c4 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -290,11 +290,8 @@ character-set=latin2 "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index de8a245c7f9..3cdcc3967d7 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -284,11 +284,8 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index d8695db30a4..17dcdb89ae6 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -282,11 +282,8 @@ character-set=latin1 "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Felaktigt %s namn '%-.100s'", -"tabell", -"databas", -"kolumn", -"index", -"katalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "Storleken av "Query cache" kunde inte sättas till %lu, ny storlek är %lu", "Kolumn '%-.64s' kan inte vara del av ett FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 3a37ee02731..99a09afde6c 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -287,11 +287,8 @@ character-set=koi8u "Wrong parameter or combination of parameters for START SLAVE UNTIL", "It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart", "SQL thread is not to be started so UNTIL options are ignored", -"Incorrect %s name '%-.100s'", -"table", -"database", -"column", -"index", -"catalog", +"Incorrect index name '%-.100s'", +"Incorrect catalog name '%-.100s'", "ëÅÛ ÚÁÐÉÔ¦× ÎÅÓÐÒÏÍÏÖÅÎ ×ÓÔÁÎÏ×ÉÔÉ ÒÏÚÍ¦Ò %lu, ÎÏ×ÉÊ ÒÏÚÍ¦Ò ËÅÛÁ ÚÁÐÉÔ¦× - %lu", "Column '%-.64s' cannot be part of FULLTEXT index", +"Unknown key cache '%-.100s'", diff --git a/sql/slave.cc b/sql/slave.cc index 561b32b668c..329324efa3d 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1965,7 +1965,7 @@ int show_master_info(THD* thd, MASTER_INFO* mi) sizeof(mi->user))); field_list.push_back(new Item_return_int("Master_Port", 7, MYSQL_TYPE_LONG)); - field_list.push_back(new Item_return_int("Connect_retry", 10, + field_list.push_back(new Item_return_int("Connect_Retry", 10, MYSQL_TYPE_LONG)); field_list.push_back(new Item_empty_string("Master_Log_File", FN_REFLEN)); @@ -1979,24 +1979,24 @@ int show_master_info(THD* thd, MASTER_INFO* mi) FN_REFLEN)); field_list.push_back(new Item_empty_string("Slave_IO_Running", 3)); field_list.push_back(new Item_empty_string("Slave_SQL_Running", 3)); - field_list.push_back(new Item_empty_string("Replicate_do_db", 20)); - field_list.push_back(new Item_empty_string("Replicate_ignore_db", 20)); - field_list.push_back(new Item_empty_string("Replicate_do_table", 20)); - field_list.push_back(new Item_empty_string("Replicate_ignore_table", 23)); - field_list.push_back(new Item_empty_string("Replicate_wild_do_table", 24)); - field_list.push_back(new Item_empty_string("Replicate_wild_ignore_table", + field_list.push_back(new Item_empty_string("Replicate_Do_DB", 20)); + field_list.push_back(new Item_empty_string("Replicate_Ignore_DB", 20)); + field_list.push_back(new Item_empty_string("Replicate_Do_Table", 20)); + field_list.push_back(new Item_empty_string("Replicate_Ignore_Table", 23)); + field_list.push_back(new Item_empty_string("Replicate_Wild_Do_Table", 24)); + field_list.push_back(new Item_empty_string("Replicate_Wild_Ignore_Table", 28)); - field_list.push_back(new Item_return_int("Last_errno", 4, MYSQL_TYPE_LONG)); - field_list.push_back(new Item_empty_string("Last_error", 20)); - field_list.push_back(new Item_return_int("Skip_counter", 10, + field_list.push_back(new Item_return_int("Last_Errno", 4, MYSQL_TYPE_LONG)); + field_list.push_back(new Item_empty_string("Last_Error", 20)); + field_list.push_back(new Item_return_int("Skip_Counter", 10, MYSQL_TYPE_LONG)); - field_list.push_back(new Item_return_int("Exec_master_log_pos", 10, + field_list.push_back(new Item_return_int("Exec_Master_Log_Pos", 10, MYSQL_TYPE_LONGLONG)); - field_list.push_back(new Item_return_int("Relay_log_space", 10, + field_list.push_back(new Item_return_int("Relay_Log_Space", 10, MYSQL_TYPE_LONGLONG)); - field_list.push_back(new Item_empty_string("Until_condition", 6)); + field_list.push_back(new Item_empty_string("Until_Condition", 6)); field_list.push_back(new Item_empty_string("Until_Log_File", FN_REFLEN)); - field_list.push_back(new Item_return_int("Until_Log_pos", 10, + field_list.push_back(new Item_return_int("Until_Log_Pos", 10, MYSQL_TYPE_LONGLONG)); field_list.push_back(new Item_empty_string("Master_SSL_Allowed", 7)); field_list.push_back(new Item_empty_string("Master_SSL_CA_File", @@ -2009,7 +2009,7 @@ int show_master_info(THD* thd, MASTER_INFO* mi) sizeof(mi->ssl_cipher))); field_list.push_back(new Item_empty_string("Master_SSL_Key", sizeof(mi->ssl_key))); - field_list.push_back(new Item_return_int("Seconds_behind_master", 10, + field_list.push_back(new Item_return_int("Seconds_Behind_Master", 10, MYSQL_TYPE_LONGLONG)); if (protocol->send_fields(&field_list, 1)) @@ -2362,7 +2362,7 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type) thd->options = ((opt_log_slave_updates) ? OPTION_BIN_LOG:0) | OPTION_AUTO_IS_NULL; /* - It's nonsense to constraint the slave threads with max_join_size; if a + It's nonsense to constrain the slave threads with max_join_size; if a query succeeded on master, we HAVE to execute it. */ thd->variables.max_join_size= HA_POS_ERROR; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index b54e6a95bc5..bcfa9c6dec5 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -632,8 +632,8 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh, if (acl_user) { /* OK. User found and password checked continue validation */ - Vio *vio=thd->net.vio; #ifdef HAVE_OPENSSL + Vio *vio=thd->net.vio; SSL *ssl= (SSL*) vio->ssl_arg; #endif @@ -3457,7 +3457,7 @@ int mysql_revoke_all(THD *thd, List <LEX_USER> &list) { uint counter; int result; - ACL_USER *acl_user; ACL_DB *acl_db; + ACL_DB *acl_db; TABLE_LIST tables[4]; DBUG_ENTER("mysql_revoke_all"); @@ -3471,7 +3471,7 @@ int mysql_revoke_all(THD *thd, List <LEX_USER> &list) List_iterator <LEX_USER> user_list(list); while ((lex_user=user_list++)) { - if (!(acl_user= check_acl_user(lex_user, &counter))) + if (!check_acl_user(lex_user, &counter)) { sql_print_error("REVOKE ALL PRIVILEGES, GRANT: User '%s'@'%s' not exists", lex_user->user.str, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3976ebd81f4..7a657841845 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -142,7 +142,8 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild) OPEN_TABLE_LIST *table; TABLE *entry=(TABLE*) hash_element(&open_cache,idx); - if ((!entry->real_name)) + DBUG_ASSERT(entry->real_name); + if ((!entry->real_name)) // To be removed continue; // Shouldn't happen if (wild) { @@ -772,8 +773,6 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, reg1 TABLE *table; char key[MAX_DBKEY_LENGTH]; uint key_length; - KEY_CACHE_ASMT *key_cache_asmt; - KEY_CACHE_VAR *key_cache; DBUG_ENTER("open_table"); /* find a unused table in the open table cache */ @@ -816,76 +815,6 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, DBUG_RETURN(0); } - VOID(pthread_mutex_lock(&LOCK_assign)); - key_cache_asmt= (KEY_CACHE_ASMT*) hash_search(&assign_cache, - (byte*) key, key_length) ; - if (thd->open_options & HA_OPEN_TO_ASSIGN) - { - /* When executing a CACHE INDEX command*/ - if (key_cache_asmt) - { - if (key_cache_asmt->requests++) - { - /* Another thread are assigning this table to some key cache*/ - - /* Put the assignment request into the queue of such requests */ - struct st_my_thread_var *last; - struct st_my_thread_var *thread= thd->mysys_var; - if (! (last= key_cache_asmt->queue)) - thread->next= thread; - else - { - thread->next= last->next; - last->next= thread; - } - key_cache_asmt->queue= thread; - - /* Wait until the request can be processed */ - do - { - VOID(pthread_cond_wait(&thread->suspend, &LOCK_assign)); - } - while (thread->next); - } - } - else - { - /* - The table has not been explicitly assigned to any key cache yet; - by default it's assigned to the default key cache; - */ - - if (!(key_cache_asmt= - (KEY_CACHE_ASMT *) my_malloc(sizeof(*key_cache_asmt), - MYF(MY_WME | MY_ZEROFILL))) || - !(key_cache_asmt->db_name= my_strdup(db, MYF(MY_WME))) || - !(key_cache_asmt->table_name= my_strdup(table_name, MYF(MY_WME))) || - !(key_cache_asmt->table_key= my_memdup((const byte *) key, - key_length, MYF(MY_WME)))) - { - VOID(pthread_mutex_unlock(&LOCK_assign)); - - if (key_cache_asmt) - { - if (key_cache_asmt->db_name) - my_free((gptr) key_cache_asmt->db_name, MYF(0)); - if (key_cache_asmt->table_name) - my_free((gptr) key_cache_asmt->table_name, MYF(0)); - my_free((gptr) key_cache_asmt, MYF(0)); - } - DBUG_RETURN(NULL); - } - key_cache_asmt->key_length= key_length; - key_cache_asmt->key_cache= &dflt_key_cache_var; - VOID(my_hash_insert(&assign_cache, (byte *) key_cache_asmt)); - key_cache_asmt->requests++; - } - key_cache_asmt->to_reassign= 0; - } - - key_cache= key_cache_asmt ? key_cache_asmt->key_cache : &dflt_key_cache_var; - VOID(pthread_mutex_unlock(&LOCK_assign)); - VOID(pthread_mutex_lock(&LOCK_open)); if (!thd->open_tables) @@ -929,8 +858,6 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, table->prev->next=table->next; /* Remove from unused list */ table->next->prev=table->prev; - table->key_cache= key_cache; - table->key_cache_asmt= key_cache_asmt; } else { @@ -944,8 +871,6 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, VOID(pthread_mutex_unlock(&LOCK_open)); DBUG_RETURN(NULL); } - table->key_cache= key_cache; - table->key_cache_asmt= key_cache_asmt; if (open_unireg_entry(thd, table,db,table_name,alias) || !(table->table_cache_key=memdup_root(&table->mem_root,(char*) key, key_length))) @@ -963,8 +888,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, } table->in_use=thd; - check_unused(); - + check_unused(); // Debugging call VOID(pthread_mutex_unlock(&LOCK_open)); if (refresh) @@ -1071,8 +995,8 @@ bool reopen_table(TABLE *table,bool locked) tmp.grant= table->grant; /* Replace table in open list */ - tmp.next=table->next; - tmp.prev=table->prev; + tmp.next= table->next; + tmp.prev= table->prev; if (table->file) VOID(closefrm(table)); // close file, free everything @@ -1740,54 +1664,6 @@ bool rm_temporary_table(enum db_type base, char *path) DBUG_RETURN(error); } -static void free_assign_entry(KEY_CACHE_ASMT *key_cache_asmt) -{ - DBUG_ENTER("free_assign_entry"); - my_free((gptr) key_cache_asmt->table_key, MYF(0)); - my_free((gptr) key_cache_asmt, MYF(0)); - DBUG_VOID_RETURN; -} - -static byte *assign_cache_key(const byte *record,uint *length, - my_bool not_used __attribute__((unused))) -{ - KEY_CACHE_ASMT *entry=(KEY_CACHE_ASMT *) record; - *length=entry->key_length; - return (byte*) entry->table_key; -} - -void assign_cache_init(void) -{ - VOID(hash_init(&assign_cache, &my_charset_bin, - table_cache_size+16, 0, 0, assign_cache_key, - (hash_free_key) free_assign_entry,0)); -} - -void assign_cache_free(void) -{ - DBUG_ENTER("assign_cache_free"); - hash_free(&assign_cache); - DBUG_VOID_RETURN; -} - -void reassign_key_cache(KEY_CACHE_ASMT *key_cache_asmt, - KEY_CACHE_VAR *new_key_cache) -{ - if (key_cache_asmt->prev) - { - /* Unlink key_cache_asmt from the assignment list for the old key cache */ - if ((*key_cache_asmt->prev= key_cache_asmt->next)) - key_cache_asmt->next->prev= key_cache_asmt->prev; - } - /* Link key_cache_asmt into the assignment list for the new key cache */ - key_cache_asmt->prev= &new_key_cache->assign_list; - if ((key_cache_asmt->next= new_key_cache->assign_list)) - key_cache_asmt->next->prev= &key_cache_asmt->next; - new_key_cache->assign_list= key_cache_asmt; - - key_cache_asmt->key_cache= new_key_cache; -} - /***************************************************************************** ** find field in list or tables. if field is unqualifed and unique, @@ -2215,7 +2091,21 @@ bool setup_tables(TABLE_LIST *tables) } -void get_key_map_from_key_list(key_map *map, TABLE *table, +/* + Create a key_map from a list of index names + + SYNOPSIS + get_key_map_from_key_list() + map key_map to fill in + table Table + index_list List of index names + + RETURN + 0 ok; In this case *map will includes the choosed index + 1 error +*/ + +bool get_key_map_from_key_list(key_map *map, TABLE *table, List<String> *index_list) { List_iterator_fast<String> it(*index_list); @@ -2231,13 +2121,14 @@ void get_key_map_from_key_list(key_map *map, TABLE *table, my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), name->c_ptr(), table->real_name); map->set_all(); - return; + return 1; } map->set_bit(pos-1); } - return; + return 0; } + /**************************************************************************** This just drops in all fields instead of current '*' field Returns pointer to last inserted field if ok @@ -2488,7 +2379,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) DBUG_ENTER("mysql_create_index"); bzero((char*) &create_info,sizeof(create_info)); create_info.db_type=DB_TYPE_DEFAULT; - create_info.table_charset= thd->variables.collation_database; + 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, FALSE, @@ -2505,7 +2396,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop) DBUG_ENTER("mysql_drop_index"); bzero((char*) &create_info,sizeof(create_info)); create_info.db_type=DB_TYPE_DEFAULT; - create_info.table_charset= thd->variables.collation_database; + 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, FALSE, diff --git a/sql/sql_class.h b/sql/sql_class.h index 7a8dc067256..b19caf057e6 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -509,7 +509,7 @@ public: PREP_STMT *last_prepared_stmt; #ifndef DBUG_OFF uint dbug_sentry; // watch out for memory corruption -#endif +#endif struct st_my_thread_var *mysys_var; enum enum_server_command command; uint32 server_id; @@ -531,9 +531,9 @@ public: THD_TRANS stmt; // Trans for current statement uint bdb_lock_count; - /* + /* Tables changed in transaction (that must be invalidated in query cache). - List contain only transactional tables, that not invalidated in query + List contain only transactional tables, that not invalidated in query cache (instead of full list of changed in transaction tables). */ CHANGED_TABLE_LIST* changed_tables; @@ -551,7 +551,7 @@ public: #endif #ifdef SIGNAL_WITH_VIO_CLOSE Vio* active_vio; -#endif +#endif /* next_insert_id is set on SET INSERT_ID= #. This is used as the next generated auto_increment value in handler.cc @@ -573,9 +573,9 @@ public: sent_row_count, examined_row_count; table_map used_tables; USER_CONN *user_connect; - CHARSET_INFO *db_charset; + CHARSET_INFO *db_charset; List<TABLE> temporary_tables_should_be_free; // list of temporary tables - List <MYSQL_ERROR> warn_list; + List <MYSQL_ERROR> warn_list; uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END]; uint total_warn_count; ulong query_id, warn_id, version, options, thread_id, col_access; @@ -609,6 +609,7 @@ public: bool prepare_command; bool tmp_table_used; bool charset_is_system_charset, charset_is_collation_connection; + bool slow_command; /* If we do a purge of binary logs, log index info of the threads diff --git a/sql/sql_db.cc b/sql/sql_db.cc index b7d6c642398..5481b1b266f 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -60,10 +60,12 @@ static bool write_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create) if ((file=my_create(path, CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0) { ulong length; - CHARSET_INFO *cs= (create && create->table_charset) ? - create->table_charset : + CHARSET_INFO *cs= (create && create->default_table_charset) ? + create->default_table_charset : thd->variables.collation_database; - length= my_sprintf(buf,(buf, "default-character-set=%s\ndefault-collation=%s\n", cs->csname,cs->name)); + length= my_sprintf(buf,(buf, + "default-character-set=%s\ndefault-collation=%s\n", + cs->csname,cs->name)); /* Error is written by my_write */ if (!my_write(file,(byte*) buf, length, MYF(MY_NABP+MY_WME))) @@ -99,7 +101,7 @@ static bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create) uint nbytes; bzero((char*) create,sizeof(*create)); - create->table_charset= global_system_variables.collation_database; + create->default_table_charset= global_system_variables.collation_database; if ((file=my_open(path, O_RDONLY | O_SHARE, MYF(0))) >= 0) { IO_CACHE cache; @@ -116,16 +118,17 @@ static bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create) { if (!strncmp(buf,"default-character-set", (pos-buf))) { - if (!(create->table_charset=get_charset_by_csname(pos+1, - MY_CS_PRIMARY, - MYF(0)))) + if (!(create->default_table_charset= get_charset_by_csname(pos+1, + MY_CS_PRIMARY, + MYF(0)))) { sql_print_error(ER(ER_UNKNOWN_CHARACTER_SET),pos+1); } } else if (!strncmp(buf,"default-collation", (pos-buf))) { - if (!(create->table_charset=get_charset_by_name(pos+1, MYF(0)))) + if (!(create->default_table_charset= get_charset_by_name(pos+1, + MYF(0)))) { sql_print_error(ER(ER_UNKNOWN_COLLATION),pos+1); } @@ -262,7 +265,6 @@ int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) char path[FN_REFLEN+16]; long result=1; int error = 0; - uint create_options = create_info ? create_info->options : 0; DBUG_ENTER("mysql_alter_db"); VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); @@ -286,8 +288,8 @@ int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) */ if (thd->db && !strcmp(thd->db,db)) { - thd->db_charset= (create_info && create_info->table_charset) ? - create_info->table_charset : + thd->db_charset= (create_info && create_info->default_table_charset) ? + create_info->default_table_charset : global_system_variables.collation_database; thd->variables.collation_database= thd->db_charset; } @@ -609,7 +611,7 @@ bool mysql_change_db(THD *thd, const char *name) } if ((db_length > NAME_LEN) || check_db_name(dbname)) { - net_printf(thd, ER_WRONG_NAME, ER(ER_DATABASE), dbname); + net_printf(thd, ER_WRONG_DB_NAME, dbname); x_free(dbname); DBUG_RETURN(1); } @@ -653,8 +655,8 @@ bool mysql_change_db(THD *thd, const char *name) #endif strmov(path+unpack_dirname(path,path), MY_DB_OPT_FILE); load_db_opt(thd, path, &create); - thd->db_charset= create.table_charset ? - create.table_charset : + thd->db_charset= create.default_table_charset ? + create.default_table_charset : global_system_variables.collation_database; thd->variables.collation_database= thd->db_charset; DBUG_RETURN(0); @@ -675,7 +677,7 @@ int mysqld_show_create_db(THD *thd, char *dbname, if (check_db_name(dbname)) { - net_printf(thd,ER_WRONG_NAME, ER(ER_DATABASE), dbname); + net_printf(thd,ER_WRONG_DB_NAME, dbname); DBUG_RETURN(1); } @@ -731,12 +733,13 @@ int mysqld_show_create_db(THD *thd, char *dbname, to= strxmov(to,"/*!32312 IF NOT EXISTS*/ ", NullS); to=strxmov(to,"`",dbname,"`", NullS); - if (create.table_charset) + if (create.default_table_charset) { - int cl= (create.table_charset->state & MY_CS_PRIMARY) ? 0 : 1; + int cl= (create.default_table_charset->state & MY_CS_PRIMARY) ? 0 : 1; to= strxmov(to," /*!40100" - " DEFAULT CHARACTER SET ",create.table_charset->csname, - cl ? " COLLATE " : "", cl ? create.table_charset->name : "", + " DEFAULT CHARACTER SET ",create.default_table_charset->csname, + cl ? " COLLATE " : "", + cl ? create.default_table_charset->name : "", " */",NullS); } protocol->store(path, (uint) (to-path), system_charset_info); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 2985f7e04a0..4bab7be255c 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -66,6 +66,9 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, DBUG_RETURN(1); } + if (thd->lex.duplicates == DUP_IGNORE) + thd->lex.select_lex.no_error= 1; + /* Test if the user wants to delete all rows */ if (!using_limit && const_cond && (!conds || conds->val_int()) && !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE))) @@ -560,8 +563,8 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) HA_CREATE_INFO create_info; table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK); bzero((char*) &create_info,sizeof(create_info)); - create_info.auto_increment_value= table->file->auto_increment_value; - create_info.table_charset=table->table_charset; + create_info.auto_increment_value= table->file->auto_increment_value; + create_info.default_table_charset= table->table_charset; db_type table_type=table->db_type; strmov(path,table->path); @@ -605,7 +608,6 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) } bzero((char*) &create_info,sizeof(create_info)); - create_info.table_charset=table_list->table->table_charset; *fn_ext(path)=0; // Remove the .frm extension error= ha_create_table(path,&create_info,1) ? -1 : 0; diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index bce1022d5c0..405cfdb5bdc 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -242,8 +242,8 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, { if (err != HA_ERR_KEY_NOT_FOUND && err != HA_ERR_END_OF_FILE) { - sql_print_error("mysql_ha_read: Got error %d when reading table", - err); + sql_print_error("mysql_ha_read: Got error %d when reading table '%s'", + err, tables->real_name); table->file->print_error(err,MYF(0)); goto err; } @@ -253,7 +253,6 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, continue; if (num_rows >= offset_limit) { - String *packet = &thd->packet; Item *item; protocol->prepare_for_resend(); it.rewind(); @@ -298,7 +297,20 @@ static TABLE **find_table_ptr_by_name(THD *thd, const char *db, !my_strcasecmp(system_charset_info, (is_alias ? table->table_name : table->real_name), table_name)) + { + if (table->version != refresh_version) + { + VOID(pthread_mutex_lock(&LOCK_open)); + if (close_thread_table(thd, ptr)) + { + /* Tell threads waiting for refresh that something has happened */ + VOID(pthread_cond_broadcast(&COND_refresh)); + } + VOID(pthread_mutex_unlock(&LOCK_open)); + continue; + } break; + } ptr= &(table->next); } return ptr; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 9077d4c6a2d..4484cdbe248 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1488,6 +1488,8 @@ void select_insert::send_error(uint errcode,const char *err) bool select_insert::send_eof() { int error,error2; + DBUG_ENTER("select_insert::send_eof"); + if (!(error=table->file->extra(HA_EXTRA_NO_CACHE))) error=table->file->activate_all_index(thd); table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); @@ -1521,20 +1523,18 @@ bool select_insert::send_eof() table->file->print_error(error,MYF(0)); //TODO error should be sent at the query processing end ::send_error(thd); - return 1; + DBUG_RETURN(1); } + + char buff[160]; + if (info.handle_duplicates == DUP_IGNORE) + sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, + (ulong) (info.records - info.copied), (ulong) thd->cuted_fields); else - { - char buff[160]; - if (info.handle_duplicates == DUP_IGNORE) - sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, - (ulong) (info.records - info.copied), (ulong) thd->cuted_fields); - else - sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, - (ulong) info.deleted, (ulong) thd->cuted_fields); - ::send_ok(thd,info.copied+info.deleted,last_insert_id,buff); - return 0; - } + sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, + (ulong) info.deleted, (ulong) thd->cuted_fields); + ::send_ok(thd,info.copied+info.deleted,last_insert_id,buff); + DBUG_RETURN(0); } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 5fa6c088a16..9b74073b64e 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -432,7 +432,7 @@ int yylex(void *arg, void *yythd) reg1 uchar c; int tokval, result_state; uint length; - enum my_lex_states state,prev_state; + enum my_lex_states state; LEX *lex= &(((THD *)yythd)->lex); YYSTYPE *yylval=(YYSTYPE*) arg; CHARSET_INFO *cs= ((THD *) yythd)->charset(); @@ -441,7 +441,7 @@ int yylex(void *arg, void *yythd) lex->yylval=yylval; // The global state lex->tok_start=lex->tok_end=lex->ptr; - prev_state=state=lex->next_state; + state=lex->next_state; lex->next_state=MY_LEX_OPERATOR_OR_IDENT; LINT_INIT(c); for (;;) @@ -870,7 +870,7 @@ int yylex(void *arg, void *yythd) case MY_LEX_COLON: // optional line terminator if (yyPeek()) { - if (((THD *)yythd)->client_capabilities & CLIENT_MULTI_QUERIES) + if (((THD *)yythd)->client_capabilities & CLIENT_MULTI_STATEMENTS) { lex->found_colon=(char*)lex->ptr; ((THD *)yythd)->server_status |= SERVER_MORE_RESULTS_EXISTS; @@ -965,7 +965,8 @@ void st_select_lex_node::init_query() { options= 0; linkage= UNSPECIFIED_TYPE; - no_error= no_table_names_allowed= uncacheable= dependent= 0; + no_error= no_table_names_allowed= 0; + uncacheable= 0; } void st_select_lex_node::init_select() @@ -1174,7 +1175,7 @@ void st_select_lex_unit::exclude_level() */ void st_select_lex_unit::exclude_tree() { - SELECT_LEX_UNIT *units= 0, **units_last= &units; + SELECT_LEX_UNIT *units= 0; for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) { // unlink current level from global SELECTs list @@ -1215,12 +1216,12 @@ void st_select_lex::mark_as_dependent(SELECT_LEX *last) for (SELECT_LEX *s= this; s && s != last; s= s->outer_select()) - if ( !s->dependent ) + if (!(s->uncacheable & UNCACHEABLE_DEPENDENT)) { // Select is dependent of outer select - s->dependent= s->uncacheable= 1; + s->uncacheable|= UNCACHEABLE_DEPENDENT; SELECT_LEX_UNIT *munit= s->master_unit(); - munit->dependent= munit->uncacheable= 1; + munit->uncacheable|= UNCACHEABLE_DEPENDENT; //Tables will be reopened many times for (TABLE_LIST *tbl= s->get_table_list(); tbl; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index be931c56247..d2345165eb9 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -84,6 +84,7 @@ enum enum_sql_command { #define DESCRIBE_NORMAL 1 #define DESCRIBE_EXTENDED 2 + typedef List<Item> List_item; typedef struct st_lex_master_info @@ -226,9 +227,14 @@ public: }; ulong options; + /* + result of this query can't be cached, bit field, can be : + UNCACHEABLE_DEPENDENT + UNCACHEABLE_RAND + UNCACHEABLE_SIDEEFFECT + */ + uint8 uncacheable; enum sub_select_type linkage; - bool dependent; /* dependent from outer select subselect */ - bool uncacheable; /* result of this query can't be cached */ bool no_table_names_allowed; /* used for global order by */ bool no_error; /* suppress error message (convert it to warnings) */ @@ -513,7 +519,7 @@ typedef struct st_lex sql_exchange *exchange; select_result *result; Item *default_value; - LEX_STRING *comment; + LEX_STRING *comment, name_and_length; LEX_USER *grant_user; gptr yacc_yyss,yacc_yyvs; THD *thd; @@ -565,7 +571,7 @@ typedef struct st_lex bool derived_tables; bool safe_to_cache_query; st_lex() {} - inline void uncacheable() + inline void uncacheable(uint8 cause) { safe_to_cache_query= 0; @@ -580,7 +586,8 @@ typedef struct st_lex un != &unit; sl= sl->outer_select(), un= sl->master_unit()) { - sl->uncacheable = un->uncacheable= 1; + sl->uncacheable|= cause; + un->uncacheable|= cause; } } } LEX; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b3c17167a3a..9f4b10682ba 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -44,7 +44,6 @@ #define MIN_HANDSHAKE_SIZE 6 #endif /* HAVE_OPENSSL */ -extern "C" pthread_mutex_t THR_LOCK_keycache; #ifdef SOLARIS extern "C" int gethostname(char *name, int namelen); #endif @@ -129,7 +128,7 @@ static int get_or_create_user_conn(THD *thd, const char *user, USER_RESOURCES *mqh) { int return_val=0; - uint temp_len, user_len, host_len; + uint temp_len, user_len; char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2]; struct user_conn *uc; @@ -137,7 +136,6 @@ static int get_or_create_user_conn(THD *thd, const char *user, DBUG_ASSERT(host != 0); user_len=strlen(user); - host_len=strlen(host); temp_len= (strmov(strmov(temp_user, user)+1, host) - temp_user)+1; (void) pthread_mutex_lock(&LOCK_user_conn); if (!(uc = (struct user_conn *) hash_search(&hash_user_connections, @@ -1069,6 +1067,14 @@ void free_items(Item *item) delete item; } + /* This works because items are allocated with sql_alloc() */ + +void cleanup_items(Item *item) +{ + for (; item ; item=item->next) + item->cleanup(); +} + int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) { TABLE* table; @@ -1085,7 +1091,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) if (!db || check_db_name(db)) { - net_printf(thd,ER_WRONG_NAME, ER(ER_DATABASE), db ? db : "NULL"); + net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); goto err; } if (lower_case_table_names) @@ -1185,10 +1191,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, Commands which will always take a long time should be marked with this so that they will not get logged to the slow query log */ - bool slow_command=FALSE; DBUG_ENTER("dispatch_command"); thd->command=command; + thd->slow_command=FALSE; thd->set_time(); VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query_id=query_id; @@ -1224,7 +1230,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, uint tbl_len= *(uchar*) (packet + db_len + 1); statistic_increment(com_other, &LOCK_status); - slow_command= TRUE; + thd->slow_command= TRUE; db= thd->alloc(db_len + tbl_len + 2); tbl_name= strmake(db, packet + 1, db_len)+1; strmake(tbl_name, packet + db_len + 2, tbl_len); @@ -1345,14 +1351,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd, while (!thd->killed && !thd->is_fatal_error && thd->lex.found_colon) { char *packet= thd->lex.found_colon; - /* + /* Multiple queries exits, execute them individually */ if (thd->lock || thd->open_tables || thd->derived_tables) - close_thread_tables(thd); + close_thread_tables(thd); ulong length= thd->query_length-(ulong)(thd->lex.found_colon-thd->query); - + /* Remove garbage at start of query */ while (my_isspace(thd->charset(), *packet) && length > 0) { @@ -1429,7 +1435,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, // null test to handle EOM if (!db || !strip_sp(db) || check_db_name(db)) { - net_printf(thd,ER_WRONG_NAME, ER(ER_DATABASE), db ? db : "NULL"); + net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); break; } if (check_access(thd,CREATE_ACL,db,0,1,0)) @@ -1445,7 +1451,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, // null test to handle EOM if (!db || !strip_sp(db) || check_db_name(db)) { - net_printf(thd,ER_WRONG_NAME, ER(ER_DATABASE), db ? db : "NULL"); + net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); break; } if (check_access(thd,DROP_ACL,db,0,1,0)) @@ -1463,7 +1469,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, case COM_BINLOG_DUMP: { statistic_increment(com_other,&LOCK_status); - slow_command = TRUE; + thd->slow_command = TRUE; if (check_global_access(thd, REPL_SLAVE_ACL)) break; mysql_log.write(thd,command, 0); @@ -1576,6 +1582,23 @@ bool dispatch_command(enum enum_server_command command, THD *thd, kill_one_thread(thd,id); break; } + case COM_SET_OPTION: + { + statistic_increment(com_stat[SQLCOM_SET_OPTION], &LOCK_status); + enum_mysql_set_option command= (enum_mysql_set_option) uint2korr(packet); + switch (command) { + case MYSQL_OPTION_MULTI_STATEMENTS_ON: + thd->client_capabilities|= CLIENT_MULTI_STATEMENTS; + break; + case MYSQL_OPTION_MULTI_STATEMENTS_OFF: + thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS; + break; + default: + send_error(thd, ER_UNKNOWN_COM_ERROR); + break; + } + break; + } case COM_DEBUG: statistic_increment(com_other,&LOCK_status); if (check_global_access(thd, SUPER_ACL)) @@ -1606,7 +1629,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->end_time(); // Set start time /* If not reading from backup and if the query took too long */ - if (!slow_command && !thd->user_time) // do not log 'slow_command' queries + if (!thd->slow_command && !thd->user_time) // do not log 'slow_command' queries { thd->proc_info="logging slow query"; @@ -1947,6 +1970,7 @@ mysql_execute_command(THD *thd) check_table_access(thd,SELECT_ACL, tables,0) || check_global_access(thd, FILE_ACL)) goto error; /* purecov: inspected */ + thd->slow_command=TRUE; res = mysql_backup_table(thd, tables); break; @@ -1957,6 +1981,7 @@ mysql_execute_command(THD *thd) check_table_access(thd, INSERT_ACL, tables,0) || check_global_access(thd, FILE_ACL)) goto error; /* purecov: inspected */ + thd->slow_command=TRUE; res = mysql_restore_table(thd, tables); break; } @@ -1966,7 +1991,7 @@ mysql_execute_command(THD *thd) check_access(thd, INDEX_ACL, tables->db, &tables->grant.privilege, 0, 0)) goto error; - res = mysql_assign_to_keycache(thd, tables); + res= mysql_assign_to_keycache(thd, tables, &lex->name_and_length); break; } case SQLCOM_PRELOAD_KEYS: @@ -1974,7 +1999,7 @@ mysql_execute_command(THD *thd) if (check_db_used(thd, tables) || check_access(thd, INDEX_ACL, tables->db, &tables->grant.privilege, 0, 0)) - goto error; + goto error; res = mysql_preload_keys(thd, tables); break; } @@ -2046,7 +2071,7 @@ mysql_execute_command(THD *thd) #endif if (strlen(tables->real_name) > NAME_LEN) { - net_printf(thd,ER_WRONG_NAME, ER(ER_TABLE), tables->real_name); + net_printf(thd,ER_WRONG_TABLE_NAME, tables->real_name); break; } LOCK_ACTIVE_MI; @@ -2091,7 +2116,7 @@ mysql_execute_command(THD *thd) #endif if (strlen(tables->real_name) > NAME_LEN) { - net_printf(thd, ER_WRONG_NAME, ER(ER_TABLE), tables->alias); + net_printf(thd, ER_WRONG_TABLE_NAME, tables->alias); res=0; break; } @@ -2108,6 +2133,19 @@ mysql_execute_command(THD *thd) break; } #endif + /* + If we are using SET CHARSET without DEFAULT, add an implicite + DEFAULT to not confuse old users. (This may change). + */ + if ((lex->create_info.used_fields & + (HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) == + HA_CREATE_USED_CHARSET) + { + lex->create_info.used_fields&= ~HA_CREATE_USED_CHARSET; + lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; + lex->create_info.default_table_charset= lex->create_info.table_charset; + lex->create_info.table_charset= 0; + } if (select_lex->item_list.elements) // With select { select_result *result; @@ -2173,6 +2211,7 @@ mysql_execute_command(THD *thd) if (grant_option && check_grant(thd,INDEX_ACL,tables)) goto error; #endif + thd->slow_command=TRUE; if (end_active_trans(thd)) res= -1; else @@ -2223,7 +2262,7 @@ mysql_execute_command(THD *thd) ulong priv=0; if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN)) { - net_printf(thd, ER_WRONG_NAME, ER(ER_TABLE), lex->name); + net_printf(thd, ER_WRONG_TABLE_NAME, lex->name); res=0; break; } @@ -2263,6 +2302,7 @@ mysql_execute_command(THD *thd) res= -1; else { + thd->slow_command=TRUE; res= mysql_alter_table(thd, select_lex->db, lex->name, &lex->create_info, tables, lex->create_list, @@ -2352,6 +2392,7 @@ mysql_execute_command(THD *thd) if (check_db_used(thd,tables) || check_table_access(thd,SELECT_ACL | INSERT_ACL, tables,0)) goto error; /* purecov: inspected */ + thd->slow_command=TRUE; res = mysql_repair_table(thd, tables, &lex->check_opt); /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) @@ -2368,8 +2409,9 @@ mysql_execute_command(THD *thd) case SQLCOM_CHECK: { if (check_db_used(thd,tables) || - check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables,0)) + check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables,0)) goto error; /* purecov: inspected */ + thd->slow_command=TRUE; res = mysql_check_table(thd, tables, &lex->check_opt); break; } @@ -2378,6 +2420,7 @@ mysql_execute_command(THD *thd) if (check_db_used(thd,tables) || check_table_access(thd,SELECT_ACL | INSERT_ACL, tables,0)) goto error; /* purecov: inspected */ + thd->slow_command=TRUE; res = mysql_analyze_table(thd, tables, &lex->check_opt); /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) @@ -2398,6 +2441,7 @@ mysql_execute_command(THD *thd) if (check_db_used(thd,tables) || check_table_access(thd,SELECT_ACL | INSERT_ACL, tables,0)) goto error; /* purecov: inspected */ + thd->slow_command=TRUE; if (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) { /* Use ALTER TABLE */ @@ -2409,7 +2453,7 @@ mysql_execute_command(THD *thd) bzero((char*) &create_info,sizeof(create_info)); create_info.db_type=DB_TYPE_DEFAULT; create_info.row_type=ROW_TYPE_DEFAULT; - create_info.table_charset=default_charset_info; + create_info.default_table_charset=default_charset_info; res= mysql_alter_table(thd, NullS, NullS, &create_info, tables, lex->create_list, lex->key_list, lex->drop_list, lex->alter_list, @@ -2797,7 +2841,7 @@ mysql_execute_command(THD *thd) remove_escape(db); // Fix escaped '_' if (check_db_name(db)) { - net_printf(thd,ER_WRONG_NAME, ER(ER_DATABASE), db); + net_printf(thd,ER_WRONG_DB_NAME, db); goto error; } #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -2962,7 +3006,7 @@ mysql_execute_command(THD *thd) { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - net_printf(thd,ER_WRONG_NAME, ER(ER_DATABASE), lex->name); + net_printf(thd,ER_WRONG_DB_NAME, lex->name); break; } /* @@ -2990,7 +3034,7 @@ mysql_execute_command(THD *thd) { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - net_printf(thd, ER_WRONG_NAME, ER(ER_DATABASE), lex->name); + net_printf(thd, ER_WRONG_DB_NAME, lex->name); break; } /* @@ -3023,7 +3067,7 @@ mysql_execute_command(THD *thd) { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - net_printf(thd, ER_WRONG_NAME, ER(ER_DATABASE), lex->name); + net_printf(thd, ER_WRONG_DB_NAME, lex->name); break; } if (check_access(thd,ALTER_ACL,lex->name,0,1,0)) @@ -3040,7 +3084,7 @@ mysql_execute_command(THD *thd) { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - net_printf(thd,ER_WRONG_NAME, ER(ER_DATABASE), lex->name); + net_printf(thd,ER_WRONG_DB_NAME, lex->name); break; } if (check_access(thd,DROP_ACL,lex->name,0,1,0)) @@ -4290,7 +4334,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (check_table_name(table->table.str,table->table.length) || table->db.str && check_db_name(table->db.str)) { - net_printf(thd, ER_WRONG_NAME, ER(ER_TABLE), table->table.str); + net_printf(thd, ER_WRONG_TABLE_NAME, table->table.str); DBUG_RETURN(0); } @@ -4620,15 +4664,24 @@ void kill_one_thread(THD *thd, ulong id) static void refresh_status(void) { - pthread_mutex_lock(&THR_LOCK_keycache); pthread_mutex_lock(&LOCK_status); for (struct show_var_st *ptr=status_vars; ptr->name; ptr++) { if (ptr->type == SHOW_LONG) - *(ulong*) ptr->value=0; + *(ulong*) ptr->value= 0; + else if (ptr->type == SHOW_KEY_CACHE_LONG) + { + /* + Reset value in 'default' key cache. + This needs to be recoded when we have thread specific key values + */ + char *value= (((char*) sql_key_cache) + + (uint) ((char*) (ptr->value) - + (char*) &dflt_key_cache_var)); + *(ulong*) value= 0; + } } pthread_mutex_unlock(&LOCK_status); - pthread_mutex_unlock(&THR_LOCK_keycache); } @@ -4644,7 +4697,7 @@ static bool append_file_to_dir(THD *thd, char **filename_ptr, char *table_name) if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 || !test_if_hard_path(*filename_ptr)) { - my_error(ER_WRONG_NAME, MYF(0), ER(ER_TABLE), *filename_ptr); + my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr); return 1; } /* Fix is using unix filename format on dos */ diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 2fa08e2d649..354214a4da5 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1056,10 +1056,9 @@ void mysql_stmt_reset(THD *thd, char *packet) void mysql_stmt_free(THD *thd, char *packet) { ulong stmt_id= uint4korr(packet); - PREP_STMT *stmt; DBUG_ENTER("mysql_stmt_free"); - if (!(stmt=find_prepared_statement(thd, stmt_id, "close"))) + if (!find_prepared_statement(thd, stmt_id, "close")) { send_error(thd); // Not seen by the client DBUG_VOID_RETURN; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index ecad84ba0cb..c30409fd0cb 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -961,8 +961,8 @@ void kill_zombie_dump_threads(uint32 slave_server_id) int change_master(THD* thd, MASTER_INFO* mi) { int thread_mask; - const char* errmsg=0; - bool need_relay_log_purge=1; + const char* errmsg= 0; + bool need_relay_log_purge= 1; DBUG_ENTER("change_master"); lock_slave_threads(mi); @@ -1055,6 +1055,37 @@ int change_master(THD* thd, MASTER_INFO* mi) mi->rli.group_relay_log_pos= mi->rli.event_relay_log_pos= lex_mi->relay_log_pos; } + /* + If user did specify neither host nor port nor any log name nor any log + pos, i.e. he specified only user/password/master_connect_retry, he probably + wants replication to resume from where it had left, i.e. from the + coordinates of the **SQL** thread (imagine the case where the I/O is ahead + of the SQL; restarting from the coordinates of the I/O would lose some + events which is probably unwanted when you are just doing minor changes + like changing master_connect_retry). + A side-effect is that if only the I/O thread was started, this thread may + restart from ''/4 after the CHANGE MASTER. That's a minor problem (it is a + much more unlikely situation than the one we are fixing here). + Note: coordinates of the SQL thread must be read here, before the + 'if (need_relay_log_purge)' block which resets them. + */ + if (!lex_mi->host && !lex_mi->port && + !lex_mi->log_file_name && !lex_mi->pos && + need_relay_log_purge) + { + /* + Sometimes mi->rli.master_log_pos == 0 (it happens when the SQL thread is + not initialized), so we use a max(). + What happens to mi->rli.master_log_pos during the initialization stages + of replication is not 100% clear, so we guard against problems using + max(). + */ + mi->master_log_pos = max(BIN_LOG_HEADER_SIZE, + mi->rli.group_master_log_pos); + strmake(mi->master_log_name, mi->rli.group_master_log_name, + sizeof(mi->master_log_name)-1); + } + flush_master_info(mi); if (need_relay_log_purge) { @@ -1087,10 +1118,21 @@ int change_master(THD* thd, MASTER_INFO* mi) } mi->rli.group_master_log_pos = mi->master_log_pos; DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos)); - /* If changing RELAY_LOG_FILE or RELAY_LOG_POS, this will be nonsense: */ + + /* + Coordinates in rli were spoilt by the 'if (need_relay_log_purge)' block, + so restore them to good values. If we left them to ''/0, that would work; + but that would fail in the case of 2 successive CHANGE MASTER (without a + START SLAVE in between): because first one would set the coords in mi to + the good values of those in rli, the set those in rli to ''/0, then + second CHANGE MASTER would set the coords in mi to those of rli, i.e. to + ''/0: we have lost all copies of the original good coordinates. + That's why we always save good coords in rli. + */ mi->rli.group_master_log_pos= mi->master_log_pos; strmake(mi->rli.group_master_log_name,mi->master_log_name, sizeof(mi->rli.group_master_log_name)-1); + if (!mi->rli.group_master_log_name[0]) // uninitialized case mi->rli.group_master_log_pos=0; @@ -1251,8 +1293,8 @@ int show_binlog_info(THD* thd) field_list.push_back(new Item_empty_string("File", FN_REFLEN)); field_list.push_back(new Item_return_int("Position",20, MYSQL_TYPE_LONGLONG)); - field_list.push_back(new Item_empty_string("Binlog_do_db",255)); - field_list.push_back(new Item_empty_string("Binlog_ignore_db",255)); + field_list.push_back(new Item_empty_string("Binlog_Do_DB",255)); + field_list.push_back(new Item_empty_string("Binlog_Ignore_DB",255)); if (protocol->send_fields(&field_list, 1)) DBUG_RETURN(-1); @@ -1291,9 +1333,7 @@ int show_binlogs(THD* thd) { IO_CACHE *index_file; char fname[FN_REFLEN]; - NET* net = &thd->net; List<Item> field_list; - String *packet = &thd->packet; uint length; Protocol *protocol= thd->protocol; DBUG_ENTER("show_binlogs"); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c7f9de2ef6d..44b403c0bb1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5590,6 +5590,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) int error; bool found=0; COND *on_expr=join_tab->on_expr, *select_cond=join_tab->select_cond; + my_bool *report_error= &(join->thd->net.report_error); if (!(error=(*join_tab->read_first_record)(join_tab))) { @@ -5628,9 +5629,9 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) else info->file->unlock_row(); } - } while (!(error=info->read_record(info))); + } while (!(error=info->read_record(info)) && !(*report_error)); } - if (error > 0) // Fatal error + if (error > 0 || (*report_error)) // Fatal error return -1; if (!found && on_expr) @@ -7227,7 +7228,7 @@ remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having) entry->file->info(HA_STATUS_VARIABLE); if (entry->db_type == DB_TYPE_HEAP || (!entry->blob_fields && - ((ALIGN_SIZE(reclength) +sizeof(HASH_LINK)) * entry->file->records < + ((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->records < thd->variables.sortbuff_size))) error=remove_dup_with_hash_index(join->thd, entry, field_count, first_field, @@ -7737,8 +7738,6 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, Item *itemptr=*order->item; if (itemptr->type() == Item::INT_ITEM) { /* Order by position */ - Item *item=0; - uint count= (uint) ((Item_int*)itemptr)->value; if (!count || count > fields.elements) { @@ -9040,10 +9039,12 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) ((sl == first)? ((sl->linkage == DERIVED_TABLE_TYPE) ? "DERIVED": - ((sl->dependent)?"DEPENDENT SUBQUERY": + ((sl->uncacheable & UNCACHEABLE_DEPENDENT)? + "DEPENDENT SUBQUERY": (sl->uncacheable?"UNCACHEABLE SUBQUERY": "SUBQUERY"))): - ((sl->dependent)?"DEPENDENT UNION": + ((sl->uncacheable & UNCACHEABLE_DEPENDENT)? + "DEPENDENT UNION": sl->uncacheable?"UNCACHEABLE UNION": "UNION"))), result); diff --git a/sql/sql_select.h b/sql/sql_select.h index 24854713a0e..5f0370a5a32 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -166,11 +166,23 @@ class JOIN :public Sql_alloc JOIN *tmp_join; // copy of this JOIN to be used with temporary tables ROLLUP rollup; // Used with rollup - bool select_distinct, //Is select distinct? - no_order, simple_order, simple_group, - skip_sort_order, need_tmp, - hidden_group_fields, - buffer_result; + bool select_distinct; // Set if SELECT DISTINCT + + /* + simple_xxxxx is set if ORDER/GROUP BY doesn't include any references + to other tables than the first non-constant table in the JOIN. + It's also set if ORDER/GROUP BY is empty. + */ + bool simple_order, simple_group; + /* + Is set only in case if we have a GROUP BY clause + and no ORDER BY after constant elimination of 'order'. + */ + bool no_order; + /* Is set if we have a GROUP BY and we have ORDER BY on a constant. */ + bool skip_sort_order; + + bool need_tmp, hidden_group_fields, buffer_result; DYNAMIC_ARRAY keyuse; Item::cond_result cond_value; List<Item> all_fields; // to store all fields that used in query diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 95a6ebb36fb..e24102a5094 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -702,7 +702,6 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, restore_record(table,default_values); // Get empty record Field **ptr,*field; - String *packet= &thd->packet; for (ptr=table->field; (field= *ptr) ; ptr++) { if (!wild || !wild[0] || @@ -892,7 +891,6 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list) if (protocol->send_fields(&field_list,1)) DBUG_RETURN(1); - String *packet= &thd->packet; KEY *key_info=table->key_info; table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME); for (uint i=0 ; i < table->keys ; i++,key_info++) @@ -1253,7 +1251,7 @@ store_create_info(THD *thd, TABLE *table, String *packet) !(thd->variables.sql_mode & MODE_MYSQL323) && !(thd->variables.sql_mode & MODE_MYSQL40)) { - packet->append(" CHARSET=", 9); + packet->append(" DEFAULT CHARSET=", 17); packet->append(table->table_charset->csname); if (!(table->table_charset->state & MY_CS_PRIMARY)) { @@ -1589,6 +1587,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables, if (protocol->send_fields(&field_list,1)) DBUG_RETURN(1); /* purecov: inspected */ null_lex_str.str= 0; // For sys_var->value_ptr() + null_lex_str.length= 0; pthread_mutex_lock(mutex); for (; variables->name; variables++) @@ -1848,6 +1847,10 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables, break; #endif /* HAVE_OPENSSL */ + case SHOW_KEY_CACHE_LONG: + value= (value-(char*) &dflt_key_cache_var)+ (char*) sql_key_cache; + end= int10_to_str(*(long*) value, buff, 10); + break; case SHOW_UNDEF: // Show never happen case SHOW_SYS: break; // Return empty string diff --git a/sql/sql_table.cc b/sql/sql_table.cc index d2d1926ea06..8504a408605 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -422,6 +422,12 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, for (field_no=0; (sql_field=it++) ; field_no++) { if (!sql_field->charset) + sql_field->charset= create_info->default_table_charset; + /* + table_charset is set in ALTER TABLE if we want change character set + for all varchar/char columns + */ + if (create_info->table_charset) sql_field->charset= create_info->table_charset; sql_field->create_length_to_internal_length(); @@ -437,7 +443,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, if (check_column_name(sql_field->field_name)) { - my_error(ER_WRONG_NAME, MYF(0), ER(ER_COLUMN), sql_field->field_name); + my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name); DBUG_RETURN(-1); } @@ -461,7 +467,9 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, { /* Field redefined */ sql_field->sql_type= dup_field->sql_type; - sql_field->charset= dup_field->charset ? dup_field->charset : create_info->table_charset; + 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(); @@ -484,8 +492,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, it.rewind(); while ((sql_field=it++)) { - if (!sql_field->charset) - sql_field->charset = create_info->table_charset; + DBUG_ASSERT(sql_field->charset); + switch (sql_field->sql_type) { case FIELD_TYPE_BLOB: case FIELD_TYPE_MEDIUM_BLOB: @@ -888,7 +896,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, } if (!key_info->name || check_column_name(key_info->name)) { - my_error(ER_WRONG_NAME, MYF(0), ER(ER_INDEX), key_info->name); + my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name); DBUG_RETURN(-1); } if (!(key_info->flags & HA_NULL_PART_KEY)) @@ -1625,13 +1633,26 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) -1 error */ -int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables) +int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, + LEX_STRING *key_cache_name) { + HA_CHECK_OPT check_opt; + KEY_CACHE *key_cache; DBUG_ENTER("mysql_assign_to_keycache"); - DBUG_RETURN(mysql_admin_table(thd, tables, 0, - "assign_to_keycache", TL_READ, 0, - HA_OPEN_TO_ASSIGN, 0, - &handler::assign_to_keycache)); + + check_opt.init(); + pthread_mutex_lock(&LOCK_global_system_variables); + if (!(key_cache= get_key_cache(key_cache_name))) + { + pthread_mutex_unlock(&LOCK_global_system_variables); + my_error(ER_UNKNOWN_KEY_CACHE, MYF(0), key_cache_name->str); + DBUG_RETURN(-1); + } + 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)); } @@ -1642,78 +1663,34 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables) reassign_keycache_tables() thd Thread object src_cache Reference to the key cache to clean up - dest_name Name of the cache to assign tables to - remove_fl Flag to destroy key cache when all tables are reassigned + dest_cache New key cache - RETURN VALUES + NOTES + This is called when one sets a key cache size to zero, in which + case we have to move the tables associated to this key cache to + the "default" one. + + One has to ensure that one never calls this function while + some other thread is changing the key cache. This is assured by + the caller setting src_cache->in_init before calling this function. + + We don't delete the old key cache as there may still be pointers pointing + to it for a while after this function returns. + + RETURN VALUES 0 ok - -1 error */ -int reassign_keycache_tables(THD* thd, KEY_CACHE_VAR* src_cache, - char *dest_name, bool remove_fl) +int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache, + KEY_CACHE *dst_cache) { - int rc= 0; - TABLE_LIST table; - KEY_CACHE_ASMT *key_cache_asmt; - DBUG_ENTER("reassign_keycache_tables"); - VOID(pthread_mutex_lock(&LOCK_assign)); - for (key_cache_asmt= src_cache->assign_list ; - key_cache_asmt; - key_cache_asmt= key_cache_asmt->next) - key_cache_asmt->to_reassign = 1; - key_cache_asmt= src_cache->assign_list; - while (key_cache_asmt) - { - if (key_cache_asmt->to_reassign) - { - bool refresh; - VOID(pthread_mutex_unlock(&LOCK_assign)); - bzero((byte *) &table, sizeof(table)); - table.option= dest_name; - table.db= key_cache_asmt->db_name; - table.alias= table.real_name= key_cache_asmt->table_name; - thd->open_options|= HA_OPEN_TO_ASSIGN; - while (!(table.table=open_table(thd,table.db, - table.real_name,table.alias, - &refresh)) && refresh) ; - thd->open_options&= ~HA_OPEN_TO_ASSIGN; - if (!table.table) - DBUG_RETURN(-1); - table.table->pos_in_table_list= &table; - key_cache_asmt->triggered= 1; - rc= table.table->file->assign_to_keycache(thd, 0); - close_thread_tables(thd); - if (rc) - DBUG_RETURN(rc); - VOID(pthread_mutex_lock(&LOCK_assign)); - key_cache_asmt= src_cache->assign_list; - continue; - } - else - key_cache_asmt= key_cache_asmt->next; - } - - while (src_cache->assignments) - { - struct st_my_thread_var *waiting_thread= my_thread_var; - pthread_cond_wait(&waiting_thread->suspend, &LOCK_assign); - } - if (src_cache->extra_info) - { - my_free((char *) src_cache->extra_info, MYF(0)); - src_cache->extra_info= 0; - } - - if (remove_fl && !src_cache->assign_list && src_cache != &dflt_key_cache_var) - { - end_key_cache(&src_cache->cache, 1); - src_cache->buff_size= 0; - src_cache->block_size= 0; - } - VOID(pthread_mutex_unlock(&LOCK_assign)); + DBUG_ASSERT(src_cache != dst_cache); + DBUG_ASSERT(src_cache->in_init); + 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); } @@ -1766,7 +1743,6 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, char *src_db= thd->db; char *src_table= table_ident->table.str; int err; - DBUG_ENTER("mysql_create_like_table"); /* @@ -1777,7 +1753,7 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, check_table_name(src_table,table_ident->table.length)) || table_ident->db.str && check_db_name((src_db= table_ident->db.str))) { - my_error(ER_WRONG_NAME, MYF(0), ER(ER_TABLE), src_table); + my_error(ER_WRONG_TABLE_NAME, MYF(0), src_table); DBUG_RETURN(-1); } @@ -1978,7 +1954,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ulonglong next_insert_id; uint save_time_stamp,db_create_options, used_fields; enum db_type old_db_type,new_db_type; - thr_lock_type lock_type; DBUG_ENTER("mysql_alter_table"); thd->proc_info="init"; @@ -2126,8 +2101,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, create_info->max_rows=table->max_rows; if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH)) create_info->avg_row_length=table->avg_row_length; - if (!(used_fields & HA_CREATE_USED_CHARSET)) - create_info->table_charset=table->table_charset; + 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 List_iterator<Alter_drop> drop_it(drop_list); @@ -2821,7 +2796,6 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) for (table= tables; table; table= table->next) { char table_name[NAME_LEN*2+2]; - bool fatal_error= 0; TABLE *t; strxmov(table_name, table->db ,".", table->real_name, NullS); diff --git a/sql/sql_test.cc b/sql/sql_test.cc index c14d30f8d34..6763181ce4a 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -28,9 +28,6 @@ #include <sys/malloc.h> #endif -/* Intern key cache variables */ -extern "C" pthread_mutex_t THR_LOCK_keycache; - static const char *lock_descriptions[] = { "No lock", @@ -229,7 +226,9 @@ static int dl_compare(TABLE_LOCK_INFO *a,TABLE_LOCK_INFO *b) return 1; } -static void push_locks_into_array(DYNAMIC_ARRAY *ar, THR_LOCK_DATA *data, bool wait, const char *text) + +static void push_locks_into_array(DYNAMIC_ARRAY *ar, THR_LOCK_DATA *data, + bool wait, const char *text) { if (data) { @@ -238,31 +237,34 @@ static void push_locks_into_array(DYNAMIC_ARRAY *ar, THR_LOCK_DATA *data, bool w { TABLE_LOCK_INFO table_lock_info; table_lock_info.thread_id=table->in_use->thread_id; - memcpy(table_lock_info.table_name, table->table_cache_key, table->key_length); + memcpy(table_lock_info.table_name, table->table_cache_key, + table->key_length); table_lock_info.table_name[strlen(table_lock_info.table_name)]='.'; table_lock_info.waiting=wait; table_lock_info.lock_text=text; - table_lock_info.type=table->reginfo.lock_type; // obtainable also from THR_LOCK_DATA + // lock_type is also obtainable from THR_LOCK_DATA + table_lock_info.type=table->reginfo.lock_type; VOID(push_dynamic(ar,(gptr) &table_lock_info)); } } } -/* - Regarding MERGE tables: -For now, the best option is to use the common TABLE *pointer for all -cases; The drawback is that for MERGE tables we will see many locks -for the merge tables even if some of them are for individual tables. -The way to solve this is to add to 'THR_LOCK' structure a pointer to -the filename and use this when printing the data. -(We can for now ignore this and just print the same name for all merge -table parts; Please add the above as a comment to the display_lock -function so that we can easily add this if we ever need this. +/* + Regarding MERGE tables: + + For now, the best option is to use the common TABLE *pointer for all + cases; The drawback is that for MERGE tables we will see many locks + for the merge tables even if some of them are for individual tables. + The way to solve this is to add to 'THR_LOCK' structure a pointer to + the filename and use this when printing the data. + (We can for now ignore this and just print the same name for all merge + table parts; Please add the above as a comment to the display_lock + function so that we can easily add this if we ever need this. */ -static void display_table_locks (void) +static void display_table_locks(void) { LIST *list; DYNAMIC_ARRAY saved_table_locks; @@ -301,6 +303,36 @@ end: } +static int print_key_cache_status(const char *name, KEY_CACHE *key_cache) +{ + if (!key_cache->key_cache_inited) + { + printf("%s: Not in use\n", name); + } + else + { + printf("%s\n\ +Buffer_size: %10lu\n\ +Block_size: %10lu\n\ +Division_limit: %10lu\n\ +Age_limit: %10lu\n\ +blocks used: %10lu\n\ +not flushed: %10lu\n\ +w_requests: %10lu\n\ +writes: %10lu\n\ +r_requests: %10lu\n\ +reads: %10lu\n\n", + name, + (ulong) key_cache->param_buff_size, key_cache->param_block_size, + key_cache->param_division_limit, key_cache->param_age_threshold, + key_cache->global_blocks_used,key_cache->global_blocks_changed, + key_cache->global_cache_w_requests,key_cache->global_cache_write, + key_cache->global_cache_r_requests,key_cache->global_cache_read); + } + return 0; +} + + void mysql_print_status(THD *thd) { char current_dir[FN_REFLEN]; @@ -320,19 +352,8 @@ void mysql_print_status(THD *thd) /* Print key cache status */ if (thd) thd->proc_info="key cache"; - pthread_mutex_lock(&THR_LOCK_keycache); - printf("key_cache status:\n\ -blocks used:%10lu\n\ -not flushed:%10lu\n\ -w_requests: %10lu\n\ -writes: %10lu\n\ -r_requests: %10lu\n\ -reads: %10lu\n", - dflt_key_cache_var.blocks_used,dflt_key_cache_var.blocks_changed, - dflt_key_cache_var.cache_w_requests,dflt_key_cache_var.cache_write, - dflt_key_cache_var.cache_r_requests,dflt_key_cache_var.cache_read); - pthread_mutex_unlock(&THR_LOCK_keycache); - + puts("\nKey caches:"); + process_key_caches(print_key_cache_status); if (thd) thd->proc_info="status"; pthread_mutex_lock(&LOCK_status); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 93541d66d65..5292299f928 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -249,11 +249,11 @@ int st_select_lex_unit::exec() ulonglong add_rows=0; DBUG_ENTER("st_select_lex_unit::exec"); - if (executed && !(dependent || uncacheable)) + if (executed && !uncacheable) DBUG_RETURN(0); executed= 1; - if ((dependent || uncacheable) || !item || !item->assigned()) + if (uncacheable || !item || !item->assigned()) { if (optimized && item && item->assigned()) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index bb37c58004f..0dbe14fd2ab 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -588,7 +588,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); IDENT IDENT_QUOTED TEXT_STRING REAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident ident_or_text UNDERSCORE_CHARSET IDENT_sys TEXT_STRING_sys TEXT_STRING_literal - NCHAR_STRING opt_component + NCHAR_STRING opt_component key_cache_name %type <lex_str_ptr> opt_table_alias @@ -925,7 +925,7 @@ create: bzero((char*) &lex->create_info,sizeof(lex->create_info)); lex->create_info.options=$2 | $4; lex->create_info.db_type= (enum db_type) lex->thd->variables.table_type; - lex->create_info.table_charset= thd->variables.collation_database; + lex->create_info.default_table_charset= thd->variables.collation_database; lex->name=0; } create2 @@ -950,7 +950,7 @@ create: lex->col_list.empty(); } | CREATE DATABASE opt_if_not_exists ident - { Lex->create_info.table_charset=NULL; } + { Lex->create_info.default_table_charset=NULL; } opt_create_database_options { LEX *lex=Lex; @@ -1037,10 +1037,10 @@ create_database_options: | create_database_options create_database_option {}; create_database_option: - COLLATE_SYM collation_name_or_default - { Lex->create_info.table_charset=$2; } + opt_default COLLATE_SYM collation_name_or_default + { Lex->create_info.default_table_charset=$3; } | opt_default charset charset_name_or_default - { Lex->create_info.table_charset=$3; } + { Lex->create_info.default_table_charset=$3; } ; opt_table_options: @@ -1100,11 +1100,21 @@ create_table_option: table_list->next=0; lex->create_info.used_fields|= HA_CREATE_USED_UNION; } - | opt_default charset opt_equal charset_name_or_default + | DEFAULT charset opt_equal charset_name_or_default { - Lex->create_info.table_charset= $4; + Lex->create_info.default_table_charset= $4; + Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; + } + | charset opt_equal charset_name_or_default + { + Lex->create_info.table_charset= $3; Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET; } + | DEFAULT COLLATE_SYM opt_equal collation_name_or_default + { + Lex->create_info.table_charset= $4; + Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; + } | COLLATE_SYM opt_equal collation_name_or_default { Lex->create_info.table_charset= $3; @@ -1578,6 +1588,11 @@ key_or_index: KEY_SYM {} | INDEX {}; +opt_keys_or_index: + /* empty */ {} + | keys_or_index + ; + keys_or_index: KEYS {} | INDEX {} @@ -1644,7 +1659,7 @@ alter: lex->select_lex.db=lex->name=0; bzero((char*) &lex->create_info,sizeof(lex->create_info)); lex->create_info.db_type= DB_TYPE_DEFAULT; - lex->create_info.table_charset= thd->variables.collation_database; + lex->create_info.default_table_charset= thd->variables.collation_database; lex->create_info.row_type= ROW_TYPE_NOT_USED; lex->alter_keys_onoff=LEAVE_AS_IS; lex->tablespace_op=NO_TABLESPACE_OP; @@ -1990,13 +2005,12 @@ table_to_table: }; keycache: - CACHE_SYM INDEX + CACHE_SYM INDEX keycache_list IN_SYM key_cache_name { LEX *lex=Lex; - lex->sql_command=SQLCOM_ASSIGN_TO_KEYCACHE; + lex->sql_command= SQLCOM_ASSIGN_TO_KEYCACHE; + lex->name_and_length= $5; } - keycache_list - {} ; keycache_list: @@ -2004,30 +2018,23 @@ keycache_list: | keycache_list ',' assign_to_keycache; assign_to_keycache: - table_ident cache_keys_spec IN_SYM ident + table_ident cache_keys_spec { LEX *lex=Lex; SELECT_LEX *sel= &lex->select_lex; if (!sel->add_table_to_list(lex->thd, $1, NULL, 0, TL_READ, sel->get_use_index(), - (List<String> *)0, - &($4))) - YYABORT; - } - | - table_ident cache_keys_spec IN_SYM DEFAULT - { - LEX *lex=Lex; - SELECT_LEX *sel= &lex->select_lex; - if (!sel->add_table_to_list(lex->thd, $1, NULL, 0, - TL_READ, - sel->get_use_index(), - (List<String> *)0)) + (List<String> *)0)) YYABORT; } ; +key_cache_name: + ident { $$= $1; } + | DEFAULT { $$ = default_key_cache_base; } + ; + preload: LOAD INDEX INTO CACHE_SYM { @@ -2056,19 +2063,22 @@ preload_keys: ; cache_keys_spec: - keys_or_index { Select->interval_list.empty(); } + { Select->interval_list.empty(); } cache_key_list_or_empty { LEX *lex=Lex; SELECT_LEX *sel= &lex->select_lex; sel->use_index= sel->interval_list; - sel->use_index_ptr= &sel->use_index; } ; cache_key_list_or_empty: - /* empty */ - | '(' key_usage_list2 ')' {} + /* empty */ { Lex->select_lex.use_index_ptr= 0; } + | opt_keys_or_index '(' key_usage_list2 ')' + { + SELECT_LEX *sel= &Lex->select_lex; + sel->use_index_ptr= &sel->use_index; + } ; opt_ignore_leaves: @@ -2197,7 +2207,7 @@ select_option: YYABORT; Select->options|= OPTION_FOUND_ROWS; } - | SQL_NO_CACHE_SYM { Lex->uncacheable(); } + | SQL_NO_CACHE_SYM { Lex->safe_to_cache_query=0; } | SQL_CACHE_SYM { Lex->select_lex.options|= OPTION_TO_QUERY_CACHE; @@ -2466,12 +2476,12 @@ simple_expr: | '@' ident_or_text SET_VAR expr { $$= new Item_func_set_user_var($2,$4); - Lex->uncacheable(); + Lex->uncacheable(UNCACHEABLE_RAND); } | '@' ident_or_text { $$= new Item_func_get_user_var($2); - Lex->uncacheable(); + Lex->uncacheable(UNCACHEABLE_RAND); } | '@' '@' opt_var_ident_type ident_or_text opt_component { @@ -2587,7 +2597,7 @@ simple_expr: | ENCRYPT '(' expr ')' { $$= new Item_func_encrypt($3); - Lex->uncacheable(); + Lex->uncacheable(UNCACHEABLE_RAND); } | ENCRYPT '(' expr ',' expr ')' { $$= new Item_func_encrypt($3,$5); } | DECODE_SYM '(' expr ',' TEXT_STRING_literal ')' @@ -2755,9 +2765,9 @@ simple_expr: | POSITION_SYM '(' no_in_expr IN_SYM expr ')' { $$ = new Item_func_locate($5,$3); } | RAND '(' expr ')' - { $$= new Item_func_rand($3); Lex->uncacheable();} + { $$= new Item_func_rand($3); Lex->uncacheable(UNCACHEABLE_RAND);} | RAND '(' ')' - { $$= new Item_func_rand(); Lex->uncacheable();} + { $$= new Item_func_rand(); Lex->uncacheable(UNCACHEABLE_RAND);} | REPLACE '(' expr ',' expr ',' expr ')' { $$= new Item_func_replace($3,$5,$7); } | RIGHT '(' expr ',' expr ')' @@ -2884,7 +2894,7 @@ simple_expr: | BENCHMARK_SYM '(' ULONG_NUM ',' expr ')' { $$=new Item_func_benchmark($3,$5); - Lex->uncacheable(); + Lex->uncacheable(UNCACHEABLE_SIDEEFFECT); } | EXTRACT_SYM '(' interval FROM expr ')' { $$=new Item_extract( $3, $5); }; @@ -3464,7 +3474,7 @@ procedure_clause: lex->proc_list.next= (byte**) &lex->proc_list.first; if (add_proc_to_list(lex->thd, new Item_field(NULL,NULL,$2.str))) YYABORT; - Lex->uncacheable(); + Lex->uncacheable(UNCACHEABLE_SIDEEFFECT); } '(' procedure_list ')'; @@ -3518,7 +3528,7 @@ into: LEX *lex=Lex; if (!lex->describe) { - lex->uncacheable(); + lex->uncacheable(UNCACHEABLE_SIDEEFFECT); if (!(lex->exchange= new sql_exchange($3.str,0))) YYABORT; if (!(lex->result= new select_export(lex->exchange))) @@ -3531,7 +3541,7 @@ into: LEX *lex=Lex; if (!lex->describe) { - lex->uncacheable(); + lex->uncacheable(UNCACHEABLE_SIDEEFFECT); if (!(lex->exchange= new sql_exchange($3.str,1))) YYABORT; if (!(lex->result= new select_dump(lex->exchange))) @@ -3540,7 +3550,7 @@ into: } | INTO select_var_list_init { - Lex->uncacheable(); + Lex->uncacheable(UNCACHEABLE_SIDEEFFECT); } ; @@ -3895,7 +3905,8 @@ opt_delete_options: opt_delete_option: QUICK { Select->options|= OPTION_QUICK; } - | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }; + | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; } + | IGNORE_SYM { Lex->duplicates= DUP_IGNORE; }; truncate: TRUNCATE_SYM opt_table_sym table_name diff --git a/sql/strfunc.cc b/sql/strfunc.cc index 1db2124bcee..d00e57df5a1 100644 --- a/sql/strfunc.cc +++ b/sql/strfunc.cc @@ -112,7 +112,7 @@ uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match) found_pos= pos; } } - return(found_count == 1 && part_match ? found_count : 0); + return(found_count == 1 && part_match ? found_pos : 0); } diff --git a/sql/structs.h b/sql/structs.h index 352823cceb2..37208e63400 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -173,7 +173,7 @@ enum SHOW_TYPE SHOW_SSL_CTX_SESS_TIMEOUTS, SHOW_SSL_CTX_SESS_CACHE_FULL, SHOW_SSL_GET_CIPHER_LIST, #endif /* HAVE_OPENSSL */ - SHOW_RPL_STATUS, SHOW_SLAVE_RUNNING + SHOW_RPL_STATUS, SHOW_SLAVE_RUNNING, SHOW_KEY_CACHE_LONG }; enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED}; diff --git a/sql/table.cc b/sql/table.cc index 14853011510..e87cafd5275 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1134,7 +1134,8 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo, int2store(fileinfo+30,create_info->table_options); fileinfo[32]=0; // No filename anymore int4store(fileinfo+34,create_info->avg_row_length); - fileinfo[38]= create_info->table_charset?create_info->table_charset->number:0; + fileinfo[38]= (create_info->default_table_charset ? + create_info->default_table_charset->number : 0); fileinfo[40]= (uchar) create_info->row_type; fileinfo[41]= (uchar) create_info->raid_type; fileinfo[42]= (uchar) create_info->raid_chunks; @@ -1165,7 +1166,8 @@ void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table) create_info->raid_type=table->raid_type; create_info->raid_chunks=table->raid_chunks; create_info->raid_chunksize=table->raid_chunksize; - create_info->table_charset=table->table_charset; + create_info->default_table_charset=table->table_charset; + create_info->table_charset= 0; DBUG_VOID_RETURN; } diff --git a/sql/table.h b/sql/table.h index b9c6a72bb09..4dcd24b2aff 100644 --- a/sql/table.h +++ b/sql/table.h @@ -56,30 +56,6 @@ typedef struct st_filesort_info } FILESORT_INFO; -/* Table key cache assignment descriptor */ -/* - In future the similar structure is to be used for - an assignment of an index to a key cache: the index name will be added. - The name of the database catalog will be added as well. - The descriptors for the current assignments are put in the - assignment cache: assign_cache. If a table is not found in the cache - it is considered assigned to the default key cache. -*/ -typedef struct st_key_cache_asmt -{ - char *db_name; /* db the table belongs to */ - char *table_name; /* the name of the table */ - char *table_key; /* key for the assignment cache */ - uint key_length; /* the length of this key */ - struct st_key_cache_var *key_cache; /* reference to the key cache */ - struct st_key_cache_asmt **prev; /* links in the chain all assignments */ - struct st_key_cache_asmt *next; /* to this cache */ - struct st_my_thread_var *queue; /* queue of requests for assignment */ - uint requests; /* number of current requests */ - bool to_reassign; /* marked when reassigning all cache */ - bool triggered; /* marked when assignment is triggered*/ -} KEY_CACHE_ASMT; - /* Table cache entry struct */ class Field_timestamp; @@ -87,13 +63,11 @@ class Field_blob; struct st_table { handler *file; - KEY_CACHE_VAR *key_cache; /* Ref to the key cache the table assigned to*/ - KEY_CACHE_ASMT *key_cache_asmt;/* Only when opened for key cache assignment */ - Field **field; /* Pointer to fields */ + Field **field; /* Pointer to fields */ Field_blob **blob_field; /* Pointer to blob fields */ HASH name_hash; /* hash of field names */ byte *record[2]; /* Pointer to records */ - byte *default_values; /* Record with default values for INSERT */ + byte *default_values; /* Default values for INSERT */ byte *insert_values; /* used by INSERT ... UPDATE */ uint fields; /* field count */ uint reclength; /* Recordlength */ diff --git a/sql/time.cc b/sql/time.cc index e696918dee3..fe22b80d59d 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -357,7 +357,6 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags) const char *end=str+length; const uchar *format_position; bool found_delimitier= 0, found_space= 0; - DATE_TIME_FORMAT *format; DBUG_ENTER("str_to_TIME"); DBUG_PRINT("ENTER",("str: %.*s",length,str)); diff --git a/sql/uniques.cc b/sql/uniques.cc index 4514de834a8..f289fd11f5b 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -132,7 +132,8 @@ bool Unique::get(TABLE *table) bzero((char*) &sort_param,sizeof(sort_param)); sort_param.max_rows= elements; sort_param.sort_form=table; - sort_param.sort_length=sort_param.ref_length=tree.size_of_element; + sort_param.rec_length= sort_param.sort_length=sort_param.ref_length= + tree.size_of_element; sort_param.keys= max_in_memory_size / sort_param.sort_length; sort_param.not_killable=1; diff --git a/sql/unireg.h b/sql/unireg.h index 8d62959317d..2da25edd72a 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -68,7 +68,8 @@ #define MAX_DATETIME_FULL_WIDTH 29 /* YYYY-MM-DD HH:MM:SS.###### AM */ #define MAX_DATETIME_WIDTH 19 /* YYYY-MM-DD HH:MM:SS */ -#define MAX_TABLES (sizeof(table_map)*8-2) /* Max tables in join */ +#define MAX_TABLES (sizeof(table_map)*8-3) /* Max tables in join */ +#define PARAM_TABLE_BIT (((table_map) 1) << (sizeof(table_map)*8-3)) #define OUTER_REF_TABLE_BIT (((table_map) 1) << (sizeof(table_map)*8-2)) #define RAND_TABLE_BIT (((table_map) 1) << (sizeof(table_map)*8-1)) #define MAX_FIELDS 4096 /* Limit in the .frm file */ @@ -145,10 +146,10 @@ #define MTYP_NOEMPTY_BIT 128 /* - * Minimum length pattern before Turbo Boyer-Moore is used - * for SELECT "text" LIKE "%pattern%", excluding the two - * wildcards in class Item_func_like. - */ + Minimum length pattern before Turbo Boyer-Moore is used + for SELECT "text" LIKE "%pattern%", excluding the two + wildcards in class Item_func_like. +*/ #define MIN_TURBOBM_PATTERN_LEN 3 /* @@ -160,7 +161,9 @@ #define BIN_LOG_HEADER_SIZE 4 #define FLOATING_POINT_BUFFER 331 - /* Include prototypes for unireg */ +#define DEFAULT_KEY_CACHE_NAME "default" + +/* Include prototypes for unireg */ #include "mysqld_error.h" #include "structs.h" /* All structs we need */ |