diff options
author | Joerg Bruehe <joerg@mysql.com> | 2008-12-10 21:14:50 +0100 |
---|---|---|
committer | Joerg Bruehe <joerg@mysql.com> | 2008-12-10 21:14:50 +0100 |
commit | 2181c959183262b6b7f64c67b12f2715d8528572 (patch) | |
tree | 0808625d28751a07f6894b2bffcf47fcf1e71fbf /sql | |
parent | 96e0bf50d942258722b25e9d17d209d40eaacd28 (diff) | |
parent | ba816c14a9bc8012759da9d58f858f1e73bec708 (diff) | |
download | mariadb-git-2181c959183262b6b7f64c67b12f2715d8528572.tar.gz |
Merge main 5.1 into 5.1-build
Diffstat (limited to 'sql')
36 files changed, 728 insertions, 425 deletions
diff --git a/sql/field.cc b/sql/field.cc index 8a70377920c..b32cbe66d89 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5814,6 +5814,7 @@ int Field_newdate::store_time(MYSQL_TIME *ltime,timestamp_type time_type) { char buff[MAX_DATE_STRING_REP_LENGTH]; String str(buff, sizeof(buff), &my_charset_latin1); + tmp= 0; make_date((DATE_TIME_FORMAT *) 0, ltime, &str); set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, str.ptr(), str.length(), MYSQL_TIMESTAMP_DATE, 1); @@ -6056,6 +6057,7 @@ int Field_datetime::store_time(MYSQL_TIME *ltime,timestamp_type time_type) { char buff[MAX_DATE_STRING_REP_LENGTH]; String str(buff, sizeof(buff), &my_charset_latin1); + tmp= 0; make_datetime((DATE_TIME_FORMAT *) 0, ltime, &str); set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, str.ptr(), str.length(), MYSQL_TIMESTAMP_DATETIME,1); diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index d5e7828c57e..8752cd9a34c 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -2813,8 +2813,42 @@ uint ha_partition::lock_count() const void ha_partition::unlock_row() { + DBUG_ENTER("ha_partition::unlock_row"); m_file[m_last_part]->unlock_row(); - return; + DBUG_VOID_RETURN; +} + + +/** + Use semi consistent read if possible + + SYNOPSIS + try_semi_consistent_read() + yes Turn on semi consistent read + + RETURN VALUE + NONE + + DESCRIPTION + See handler.h: + Tell the engine whether it should avoid unnecessary lock waits. + If yes, in an UPDATE or DELETE, if the row under the cursor was locked + by another transaction, the engine may try an optimistic read of + the last committed row value under the cursor. + Note: prune_partitions are already called before this call, so using + pruning is OK. +*/ +void ha_partition::try_semi_consistent_read(bool yes) +{ + handler **file; + DBUG_ENTER("ha_partition::try_semi_consistent_read"); + + for (file= m_file; *file; file++) + { + if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file))) + (*file)->try_semi_consistent_read(yes); + } + DBUG_VOID_RETURN; } diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 83395f428cd..b2adf35d623 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -325,6 +325,10 @@ public: Call to unlock rows not to be updated in transaction */ virtual void unlock_row(); + /* + Call to hint about semi consistent read + */ + virtual void try_semi_consistent_read(bool); /* ------------------------------------------------------------------------- diff --git a/sql/handler.cc b/sql/handler.cc index 92ebc53121b..938fb9a63ba 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3627,7 +3627,7 @@ int ha_init_key_cache(const char *name, KEY_CACHE *key_cache) if (!key_cache->key_cache_inited) { pthread_mutex_lock(&LOCK_global_system_variables); - ulong tmp_buff_size= (ulong) key_cache->param_buff_size; + size_t tmp_buff_size= (size_t) key_cache->param_buff_size; uint tmp_block_size= (uint) key_cache->param_block_size; uint division_limit= key_cache->param_division_limit; uint age_threshold= key_cache->param_age_threshold; @@ -3651,7 +3651,7 @@ int ha_resize_key_cache(KEY_CACHE *key_cache) if (key_cache->key_cache_inited) { pthread_mutex_lock(&LOCK_global_system_variables); - long tmp_buff_size= (long) key_cache->param_buff_size; + size_t tmp_buff_size= (size_t) 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; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 3fd925c1182..c5de0b3df08 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -810,11 +810,11 @@ Arg_comparator::can_compare_as_dates(Item *a, Item *b, ulonglong *const_value) obtained value */ -ulonglong +longlong get_time_value(THD *thd, Item ***item_arg, Item **cache_arg, Item *warn_item, bool *is_null) { - ulonglong value; + longlong value; Item *item= **item_arg; MYSQL_TIME ltime; @@ -826,7 +826,7 @@ get_time_value(THD *thd, Item ***item_arg, Item **cache_arg, else { *is_null= item->get_time(<ime); - value= !*is_null ? TIME_to_ulonglong_datetime(<ime) : 0; + value= !*is_null ? (longlong) TIME_to_ulonglong_datetime(<ime) : 0; } /* Do not cache GET_USER_VAR() function as its const_item() may return TRUE @@ -951,11 +951,11 @@ void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1) obtained value */ -ulonglong +longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, Item *warn_item, bool *is_null) { - ulonglong value= 0; + longlong value= 0; String buf, *str= 0; Item *item= **item_arg; @@ -993,7 +993,7 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, enum_field_types f_type= warn_item->field_type(); timestamp_type t_type= f_type == MYSQL_TYPE_DATE ? MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME; - value= get_date_from_str(thd, str, t_type, warn_item->name, &error); + value= (longlong) get_date_from_str(thd, str, t_type, warn_item->name, &error); /* If str did not contain a valid date according to the current SQL_MODE, get_date_from_str() has already thrown a warning, @@ -1047,7 +1047,7 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, int Arg_comparator::compare_datetime() { bool a_is_null, b_is_null; - ulonglong a_value, b_value; + longlong a_value, b_value; /* Get DATE/DATETIME/TIME value of the 'a' item. */ a_value= (*get_value_func)(thd, &a, &a_cache, *b, &a_is_null); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 2bf39e6da8d..c2227fa04e0 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -42,8 +42,8 @@ class Arg_comparator: public Sql_alloc bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE, CMP_DATE_WITH_STR, CMP_STR_WITH_DATE }; - ulonglong (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg, - Item *warn_item, bool *is_null); + longlong (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg, + Item *warn_item, bool *is_null); public: DTCollation cmp_collation; @@ -1012,7 +1012,7 @@ public: */ class cmp_item_datetime :public cmp_item { - ulonglong value; + longlong value; public: THD *thd; /* Item used for issuing warnings. */ diff --git a/sql/item_func.cc b/sql/item_func.cc index 37f67d1a40e..3cf1671bfa7 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1301,8 +1301,10 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value) void Item_func_div::result_precision() { - uint arg_prec= args[0]->decimal_precision() + prec_increment; - uint precision=min(arg_prec, DECIMAL_MAX_PRECISION); + uint precision=min(args[0]->decimal_precision() + + args[1]->decimals + prec_increment, + DECIMAL_MAX_PRECISION); + /* Integer operations keep unsigned_flag if one of arguments is unsigned */ if (result_type() == INT_RESULT) unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag; @@ -2257,7 +2259,7 @@ void Item_func_min_max::fix_length_and_dec() uint Item_func_min_max::cmp_datetimes(ulonglong *value) { - ulonglong min_max; + longlong min_max; uint min_max_idx= 0; LINT_INIT(min_max); @@ -2265,7 +2267,7 @@ uint Item_func_min_max::cmp_datetimes(ulonglong *value) { Item **arg= args + i; bool is_null; - ulonglong res= get_datetime_value(thd, &arg, 0, datetime_item, &is_null); + longlong res= get_datetime_value(thd, &arg, 0, datetime_item, &is_null); if ((null_value= args[i]->null_value)) return 0; if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0) @@ -3808,11 +3810,14 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name, bool Item_func_set_user_var::set_entry(THD *thd, bool create_if_not_exists) { - if (thd == entry_thd && entry) + if (entry && thd->thread_id == entry_thread_id) goto end; // update entry->update_query_id for PS - entry_thd= thd; if (!(entry= get_variable(&thd->user_vars, name, create_if_not_exists))) + { + entry_thread_id= 0; return TRUE; + } + entry_thread_id= thd->thread_id; /* Remember the last query which updated it, this way a query can later know if this variable is a constant item in the query (it is if update_query_id @@ -4850,6 +4855,7 @@ void Item_func_get_system_var::fix_length_and_dec() max_length= MAX_BLOB_WIDTH; decimals=NOT_FIXED_DEC; break; + case SHOW_BOOL: case SHOW_MY_BOOL: unsigned_flag= FALSE; max_length= 1; @@ -4877,6 +4883,7 @@ enum Item_result Item_func_get_system_var::result_type() const { switch (var->show_type()) { + case SHOW_BOOL: case SHOW_MY_BOOL: case SHOW_INT: case SHOW_LONG: @@ -4899,6 +4906,7 @@ enum_field_types Item_func_get_system_var::field_type() const { switch (var->show_type()) { + case SHOW_BOOL: case SHOW_MY_BOOL: case SHOW_INT: case SHOW_LONG: @@ -4917,6 +4925,10 @@ enum_field_types Item_func_get_system_var::field_type() const } +/* + Uses var, var_type, component, cache_present, used_query_id, thd, + cached_llval, null_value, cached_null_value +*/ #define get_sys_var_safe(type) \ do { \ type value; \ @@ -4970,6 +4982,7 @@ longlong Item_func_get_system_var::val_int() case SHOW_LONG: get_sys_var_safe (ulong); case SHOW_LONGLONG: get_sys_var_safe (longlong); case SHOW_HA_ROWS: get_sys_var_safe (ha_rows); + case SHOW_BOOL: get_sys_var_safe (bool); case SHOW_MY_BOOL: get_sys_var_safe (my_bool); case SHOW_DOUBLE: { @@ -5067,6 +5080,7 @@ String* Item_func_get_system_var::val_str(String* str) case SHOW_LONG: case SHOW_LONGLONG: case SHOW_HA_ROWS: + case SHOW_BOOL: case SHOW_MY_BOOL: str->set (val_int(), collation.collation); break; @@ -5159,6 +5173,7 @@ double Item_func_get_system_var::val_real() case SHOW_LONG: case SHOW_LONGLONG: case SHOW_HA_ROWS: + case SHOW_BOOL: case SHOW_MY_BOOL: cached_dval= (double) val_int(); cache_present|= GET_SYS_VAR_CACHE_DOUBLE; @@ -5381,7 +5396,9 @@ bool Item_func_match::fix_index() for (keynr=0 ; keynr < table->s->keys ; keynr++) { if ((table->key_info[keynr].flags & HA_FULLTEXT) && - (table->s->keys_in_use.is_set(keynr))) + (flags & FT_BOOL ? table->keys_in_use_for_query.is_set(keynr) : + table->s->keys_in_use.is_set(keynr))) + { ft_to_key[fts]=keynr; ft_cnt[fts]=0; diff --git a/sql/item_func.h b/sql/item_func.h index 6fb87612b31..298f701f1ee 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1295,16 +1295,16 @@ class Item_func_set_user_var :public Item_func enum Item_result cached_result_type; user_var_entry *entry; /* - The entry_thd variable is used: + The entry_thread_id variable is used: 1) to skip unnecessary updates of the entry field (see above); 2) to reset the entry field that was initialized in the other thread (for example, an item tree of a trigger that updates user variables - may be shared between several connections, and the entry_thd field + may be shared between several connections, and the entry_thread_id field prevents updates of one connection user variables from a concurrent connection calling the same trigger that initially updated some user variable it the first connection context). */ - THD *entry_thd; + my_thread_id entry_thread_id; char buffer[MAX_FIELD_WIDTH]; String value; my_decimal decimal_buff; @@ -1321,7 +1321,7 @@ public: LEX_STRING name; // keep it public Item_func_set_user_var(LEX_STRING a,Item *b) :Item_func(b), cached_result_type(INT_RESULT), - entry(NULL), entry_thd(NULL), name(a) + entry(NULL), entry_thread_id(0), name(a) {} enum Functype functype() const { return SUSERVAR_FUNC; } double val_real(); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 390f94945aa..843a48ae118 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2504,6 +2504,8 @@ void Item_char_typecast::fix_length_and_dec() and thus avoid unnecessary character set conversion. - If the argument is not a number, then from_cs is set to the argument's charset. + + Note (TODO): we could use repertoire technique here. */ from_cs= (args[0]->result_type() == INT_RESULT || args[0]->result_type() == DECIMAL_RESULT || @@ -2511,12 +2513,13 @@ void Item_char_typecast::fix_length_and_dec() (cast_cs->mbminlen == 1 ? cast_cs : &my_charset_latin1) : args[0]->collation.collation; charset_conversion= (cast_cs->mbmaxlen > 1) || - !my_charset_same(from_cs, cast_cs) && - from_cs != &my_charset_bin && - cast_cs != &my_charset_bin; + (!my_charset_same(from_cs, cast_cs) && + from_cs != &my_charset_bin && + cast_cs != &my_charset_bin); collation.set(cast_cs, DERIVATION_IMPLICIT); - char_length= (cast_length >= 0) ? cast_length : - args[0]->max_length/from_cs->mbmaxlen; + char_length= (cast_length >= 0) ? + cast_length : + args[0]->max_length / args[0]->collation.collation->mbmaxlen; max_length= char_length * cast_cs->mbmaxlen; } diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index cfcf5fab080..99240b1c759 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -429,6 +429,7 @@ public: { return save_time_in_field(field); } + bool result_as_longlong() { return TRUE; } }; diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc index 651ff22d198..208ddefb890 100644 --- a/sql/my_decimal.cc +++ b/sql/my_decimal.cc @@ -214,7 +214,7 @@ my_decimal *date2my_decimal(MYSQL_TIME *ltime, my_decimal *dec) date = (ltime->year*100L + ltime->month)*100L + ltime->day; if (ltime->time_type > MYSQL_TIMESTAMP_DATE) date= ((date*100L + ltime->hour)*100L+ ltime->minute)*100L + ltime->second; - if (int2my_decimal(E_DEC_FATAL_ERROR, date, FALSE, dec)) + if (int2my_decimal(E_DEC_FATAL_ERROR, ltime->neg ? -date : date, FALSE, dec)) return dec; if (ltime->second_part) { diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f07a01cc8d8..6703a9de1e1 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -548,6 +548,7 @@ protected: #define UNCACHEABLE_PREPARE 16 /* For uncorrelated SELECT in an UNION with some correlated SELECTs */ #define UNCACHEABLE_UNITED 32 +#define UNCACHEABLE_CHECKOPTION 64 /* Used to check GROUP BY list in the MODE_ONLY_FULL_GROUP_BY mode */ #define UNDEF_POS (-1) @@ -1767,10 +1768,9 @@ int mysql_load(THD *thd, sql_exchange *ex, TABLE_LIST *table_list, int write_record(THD *thd, TABLE *table, COPY_INFO *info); /* sql_manager.cc */ -extern ulong volatile manager_status; -extern bool volatile manager_thread_in_use, mqh_used; -extern pthread_t manager_thread; -pthread_handler_t handle_manager(void *arg); +extern bool volatile mqh_used; +void start_handle_manager(); +void stop_handle_manager(); bool mysql_manager_submit(void (*action)()); @@ -2174,8 +2174,8 @@ void make_date(const DATE_TIME_FORMAT *format, const MYSQL_TIME *l_time, void make_time(const DATE_TIME_FORMAT *format, const MYSQL_TIME *l_time, String *str); int my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b); -ulonglong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, - Item *warn_item, bool *is_null); +longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, + Item *warn_item, bool *is_null); int test_if_number(char *str,int *res,bool allow_wildcards); void change_byte(uchar *,uint,char,char); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ce35e4c76b5..e995cc7e6ce 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -733,7 +733,7 @@ uint connection_count= 0; /* Function declarations */ pthread_handler_t signal_hand(void *arg); -static void mysql_init_variables(void); +static int mysql_init_variables(void); static void get_options(int *argc,char **argv); extern "C" my_bool mysqld_get_one_option(int, const struct my_option *, char *); static void set_server_version(void); @@ -784,16 +784,6 @@ static void close_connections(void) kill_cached_threads++; flush_thread_cache(); - /* kill flush thread */ - (void) pthread_mutex_lock(&LOCK_manager); - if (manager_thread_in_use) - { - DBUG_PRINT("quit", ("killing manager thread: 0x%lx", - (ulong)manager_thread)); - (void) pthread_cond_signal(&COND_manager); - } - (void) pthread_mutex_unlock(&LOCK_manager); - /* kill connection thread */ #if !defined(__WIN__) && !defined(__NETWARE__) DBUG_PRINT("quit", ("waiting for select thread: 0x%lx", @@ -1196,6 +1186,7 @@ void clean_up(bool print_message) if (cleanup_done++) return; /* purecov: inspected */ + stop_handle_manager(); release_ddl_log(); /* @@ -3141,12 +3132,12 @@ static int init_common_variables(const char *conf_file_name, int argc, if (!rpl_filter || !binlog_filter) { sql_perror("Could not allocate replication and binlog filters"); - exit(1); + return 1; } - if (init_thread_environment()) + if (init_thread_environment() || + mysql_init_variables()) return 1; - mysql_init_variables(); #ifdef HAVE_TZNAME { @@ -3377,12 +3368,14 @@ static int init_common_variables(const char *conf_file_name, int argc, sys_init_connect.value_length= strlen(opt_init_connect); else sys_init_connect.value=my_strdup("",MYF(0)); + sys_init_connect.is_os_charset= TRUE; sys_init_slave.value_length= 0; if ((sys_init_slave.value= opt_init_slave)) sys_init_slave.value_length= strlen(opt_init_slave); else sys_init_slave.value=my_strdup("",MYF(0)); + sys_init_slave.is_os_charset= TRUE; /* check log options and issue warnings if needed */ if (opt_log && opt_logname && !(log_output_options & LOG_FILE) && @@ -3745,7 +3738,10 @@ version 5.0 and above. It is replaced by the binary log."); { /* as opt_bin_log==0, no need to free opt_bin_logname */ if (!(opt_bin_logname= my_strdup(opt_update_logname, MYF(MY_WME)))) - exit(EXIT_OUT_OF_MEMORY); + { + sql_print_error("Out of memory"); + return EXIT_OUT_OF_MEMORY; + } sql_print_error("The update log is no longer supported by MySQL in \ version 5.0 and above. It is replaced by the binary log. Now starting MySQL \ with --log-bin='%s' instead.",opt_bin_logname); @@ -4033,17 +4029,6 @@ server."); #ifndef EMBEDDED_LIBRARY -static void create_maintenance_thread() -{ - if (flush_time && flush_time != ~(ulong) 0L) - { - pthread_t hThread; - if (pthread_create(&hThread,&connection_attrib,handle_manager,0)) - sql_print_warning("Can't create thread to manage maintenance"); - } -} - - static void create_shutdown_thread() { #ifdef __WIN__ @@ -4358,7 +4343,7 @@ we force server id to 2, but this MySQL server will not act as a slave."); execute_ddl_log_recovery(); create_shutdown_thread(); - create_maintenance_thread(); + start_handle_manager(); if (Events::init(opt_noacl)) unireg_abort(1); @@ -4368,6 +4353,9 @@ we force server id to 2, but this MySQL server will not act as a slave."); : mysqld_unix_port), mysqld_port, MYSQL_COMPILATION_COMMENT); +#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY) + Service.SetRunning(); +#endif /* Signal threads waiting for server to be started */ @@ -7348,6 +7336,7 @@ SHOW_VAR status_vars[]= { {NullS, NullS, SHOW_LONG} }; +#ifndef EMBEDDED_LIBRARY static void print_version(void) { set_server_version(); @@ -7359,7 +7348,6 @@ static void print_version(void) server_version,SYSTEM_TYPE,MACHINE_TYPE, MYSQL_COMPILATION_COMMENT); } -#ifndef EMBEDDED_LIBRARY static void usage(void) { if (!(default_charset_info= get_charset_by_csname(default_character_set_name, @@ -7424,7 +7412,7 @@ To see what values a running MySQL server is using, type\n\ as these are initialized by my_getopt. */ -static void mysql_init_variables(void) +static int mysql_init_variables(void) { /* Things reset to zero */ opt_skip_slave_start= opt_reckless_slave = 0; @@ -7505,7 +7493,10 @@ static void mysql_init_variables(void) key_caches.empty(); if (!(dflt_key_cache= get_or_create_key_cache(default_key_cache_base.str, default_key_cache_base.length))) - exit(1); + { + sql_print_error("Cannot allocate the keycache"); + return 1; + } /* set key_cache_hash.default_value = dflt_key_cache */ multi_keycache_init(); @@ -7648,6 +7639,7 @@ static void mysql_init_variables(void) tmpenv = DEFAULT_MYSQL_HOME; (void) strmake(mysql_home, tmpenv, sizeof(mysql_home)-1); #endif + return 0; } @@ -7708,9 +7700,11 @@ mysqld_get_one_option(int optid, #endif break; #include <sslopt-case.h> +#ifndef EMBEDDED_LIBRARY case 'V': print_version(); exit(0); +#endif /*EMBEDDED_LIBRARY*/ case 'W': if (!argument) global_system_variables.log_warnings++; @@ -7939,14 +7933,14 @@ mysqld_get_one_option(int optid, if (gethostname(myhostname,sizeof(myhostname)) < 0) { sql_perror("Can't start server: cannot get my own hostname!"); - exit(1); + return 1; } ent=gethostbyname(myhostname); } if (!ent) { sql_perror("Can't start server: cannot resolve hostname!"); - exit(1); + return 1; } my_bind_addr = (ulong) ((in_addr*)ent->h_addr_list[0])->s_addr; } @@ -8143,8 +8137,8 @@ mysqld_get_one_option(int optid, case OPT_FT_BOOLEAN_SYNTAX: if (ft_boolean_check_syntax_string((uchar*) argument)) { - fprintf(stderr, "Invalid ft-boolean-syntax string: %s\n", argument); - exit(1); + sql_print_error("Invalid ft-boolean-syntax string: %s\n", argument); + return 1; } strmake(ft_boolean_syntax, argument, sizeof(ft_boolean_syntax)-1); break; diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc index 7ff06d5bdf5..f41fa08f828 100644 --- a/sql/nt_servc.cc +++ b/sql/nt_servc.cc @@ -255,10 +255,6 @@ void NTService::ServiceMain(DWORD argc, LPTSTR *argv) if (!pService->StartService()) goto error; - // Check that the service is now running. - if (!pService->SetStatus(SERVICE_RUNNING,NO_ERROR, 0, 0, 0)) - goto error; - // wait for exit event WaitForSingleObject (pService->hExitEvent, INFINITE); @@ -274,9 +270,18 @@ error: return; } -/** - starts the appliaction thread. -*/ + + +void NTService::SetRunning() +{ + if (pService) + pService->SetStatus(SERVICE_RUNNING,NO_ERROR, 0, 0, 0); +} + + +/* ------------------------------------------------------------------------ + StartService() - starts the application thread + -------------------------------------------------------------------------- */ BOOL NTService::StartService() { diff --git a/sql/nt_servc.h b/sql/nt_servc.h index 525f709388b..2f0d07df543 100644 --- a/sql/nt_servc.h +++ b/sql/nt_servc.h @@ -60,7 +60,19 @@ class NTService BOOL IsService(LPCSTR ServiceName); BOOL got_service_option(char **argv, char *service_option); BOOL is_super_user(); - void Stop(void); //to be called from app. to stop service + + /* + SetRunning() is to be called by the application + when initialization completes and it can accept + stop request + */ + void SetRunning(void); + + /* + Stop() is to be called by the application to stop + the service + */ + void Stop(void); protected: LPSTR ServiceName; diff --git a/sql/parse_file.cc b/sql/parse_file.cc index d8cbc7ff174..d3ece194dcd 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -90,7 +90,6 @@ write_escaped_string(IO_CACHE *file, LEX_STRING *val_s) @param file pointer to IO_CACHE structure for writing @param base pointer to data structure @param parameter pointer to parameter descriptor - @param old_version for returning back old version number value @retval FALSE OK @@ -100,8 +99,7 @@ write_escaped_string(IO_CACHE *file, LEX_STRING *val_s) static my_bool -write_parameter(IO_CACHE *file, uchar* base, File_option *parameter, - ulonglong *old_version) +write_parameter(IO_CACHE *file, uchar* base, File_option *parameter) { char num_buf[20]; // buffer for numeric operations // string for numeric operations @@ -129,15 +127,6 @@ write_parameter(IO_CACHE *file, uchar* base, File_option *parameter, DBUG_RETURN(TRUE); break; } - case FILE_OPTIONS_REV: - { - ulonglong *val_i= (ulonglong *)(base + parameter->offset); - *old_version= (*val_i)++; - num.set(*val_i, &my_charset_bin); - if (my_b_append(file, (const uchar *)num.ptr(), num.length())) - DBUG_RETURN(TRUE); - break; - } case FILE_OPTIONS_TIMESTAMP: { /* string have to be allocated already */ @@ -207,7 +196,6 @@ write_parameter(IO_CACHE *file, uchar* base, File_option *parameter, @param base base address for parameter reading (structure like TABLE) @param parameters parameters description - @param max_versions number of versions to save @retval FALSE OK @@ -219,13 +207,11 @@ write_parameter(IO_CACHE *file, uchar* base, File_option *parameter, my_bool sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, const LEX_STRING *type, - uchar* base, File_option *parameters, - uint max_versions) + uchar* base, File_option *parameters) { File handler; IO_CACHE file; char path[FN_REFLEN+1]; // +1 to put temporary file name for sure - ulonglong old_version= ULONGLONG_MAX; int path_end; File_option *param; DBUG_ENTER("sql_create_definition_file"); @@ -272,7 +258,7 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, if (my_b_append(&file, (const uchar *)param->name.str, param->name.length) || my_b_append(&file, (const uchar *)STRING_WITH_LEN("=")) || - write_parameter(&file, base, param, &old_version) || + write_parameter(&file, base, param) || my_b_append(&file, (const uchar *)STRING_WITH_LEN("\n"))) goto err_w_cache; } @@ -286,55 +272,6 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, } path[path_end]='\0'; -#ifdef FRM_ARCHIVE - // archive copies management: disabled unused feature (see bug #17823). - if (!access(path, F_OK)) - { - if (old_version != ULONGLONG_MAX && max_versions != 0) - { - // save backup - char path_arc[FN_REFLEN]; - // backup old version - char path_to[FN_REFLEN]; - - // check archive directory existence - fn_format(path_arc, "arc", dir->str, "", MY_UNPACK_FILENAME); - if (access(path_arc, F_OK)) - { - if (my_mkdir(path_arc, 0777, MYF(MY_WME))) - { - DBUG_RETURN(TRUE); - } - } - - my_snprintf(path_to, FN_REFLEN, "%s/%s-%04lu", - path_arc, file_name->str, (ulong) old_version); - if (my_rename(path, path_to, MYF(MY_WME))) - { - DBUG_RETURN(TRUE); - } - - // remove very old version - if (old_version > max_versions) - { - my_snprintf(path_to, FN_REFLEN, "%s/%s-%04lu", - path_arc, file_name->str, - (ulong)(old_version - max_versions)); - if (!access(path_arc, F_OK) && my_delete(path_to, MYF(MY_WME))) - { - DBUG_RETURN(TRUE); - } - } - } - else - { - if (my_delete(path, MYF(MY_WME))) // no backups - { - DBUG_RETURN(TRUE); - } - } - } -#endif//FRM_ARCHIVE { // rename temporary file @@ -361,8 +298,6 @@ err_w_file: @param schema name of given schema @param old_name original file name @param new_name new file name - @param revision revision number - @param num_view_backups number of backups @retval 0 OK @@ -371,8 +306,7 @@ err_w_file: */ my_bool rename_in_schema_file(THD *thd, const char *schema, const char *old_name, - const char *new_name, ulonglong revision, - uint num_view_backups) + const char *new_name) { char old_path[FN_REFLEN], new_path[FN_REFLEN], arc_path[FN_REFLEN]; @@ -387,28 +321,6 @@ my_bool rename_in_schema_file(THD *thd, /* check if arc_dir exists: disabled unused feature (see bug #17823). */ build_table_filename(arc_path, sizeof(arc_path) - 1, schema, "arc", "", 0); -#ifdef FRM_ARCHIVE - if (revision > 0 && !access(arc_path, F_OK)) - { - char old_name_buf[FN_REFLEN], new_name_buf[FN_REFLEN]; - ulonglong limit= ((revision > num_view_backups) ? - revision - num_view_backups : 0); - - VOID(tablename_to_filename(old_name, old_name_buf, sizeof(old_name_buf))); - VOID(tablename_to_filename(new_name, new_name_buf, sizeof(new_name_buf))); - - for (; revision > limit ; revision--) - { - my_snprintf(old_path, FN_REFLEN, "%s/%s%s-%04lu", - arc_path, old_name_buf, reg_ext, (ulong) revision); - (void) unpack_filename(old_path, old_path); - my_snprintf(new_path, FN_REFLEN, "%s/%s%s-%04lu", - arc_path, new_name_buf, reg_ext, (ulong) revision); - (void) unpack_filename(new_path, new_path); - my_rename(old_path, new_path, MYF(0)); - } - } -#else//FRM_ARCHIVE { // remove obsolete 'arc' directory and files if any MY_DIR *new_dirp; if ((new_dirp = my_dir(arc_path, MYF(MY_DONT_SORT)))) @@ -417,7 +329,6 @@ my_bool rename_in_schema_file(THD *thd, (void) mysql_rm_arc_files(thd, new_dirp, arc_path); } } -#endif//FRM_ARCHIVE return 0; } @@ -846,7 +757,6 @@ File_parser::parse(uchar* base, MEM_ROOT *mem_root, break; } case FILE_OPTIONS_ULONGLONG: - case FILE_OPTIONS_REV: if (!(eol= strchr(ptr, '\n'))) { my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), diff --git a/sql/parse_file.h b/sql/parse_file.h index c05b2853b9a..cfac69cc471 100644 --- a/sql/parse_file.h +++ b/sql/parse_file.h @@ -23,7 +23,6 @@ enum file_opt_type { FILE_OPTIONS_STRING, /**< String (LEX_STRING) */ FILE_OPTIONS_ESTRING, /**< Escaped string (LEX_STRING) */ FILE_OPTIONS_ULONGLONG, /**< ulonglong parameter (ulonglong) */ - FILE_OPTIONS_REV, /**< Revision version number (ulonglong) */ FILE_OPTIONS_TIMESTAMP, /**< timestamp (LEX_STRING have to be allocated with length 20 (19+1) */ FILE_OPTIONS_STRLIST, /**< list of escaped strings @@ -81,11 +80,10 @@ File_parser *sql_parse_prepare(const LEX_STRING *file_name, my_bool sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, const LEX_STRING *type, - uchar* base, File_option *parameters, uint versions); + uchar* base, File_option *parameters); my_bool rename_in_schema_file(THD *thd, const char *schema, const char *old_name, - const char *new_name, ulonglong revision, - uint num_view_backups); + const char *new_name); class File_parser: public Sql_alloc { diff --git a/sql/set_var.cc b/sql/set_var.cc index 9054b9cfb01..46ccb2fab48 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -77,7 +77,6 @@ extern ulong ndb_report_thresh_binlog_mem_usage; extern CHARSET_INFO *character_set_filesystem; -static DYNAMIC_ARRAY fixed_show_vars; static HASH system_variable_hash; const char *bool_type_names[]= { "OFF", "ON", NullS }; @@ -174,13 +173,21 @@ sys_auto_increment_offset(&vars, "auto_increment_offset", static sys_var_bool_ptr sys_automatic_sp_privileges(&vars, "automatic_sp_privileges", &sp_automatic_privileges); -static sys_var_const_str sys_basedir(&vars, "basedir", mysql_home); +static sys_var_const sys_back_log(&vars, "back_log", + OPT_GLOBAL, SHOW_LONG, + (uchar*) &back_log); +static sys_var_const_os_str sys_basedir(&vars, "basedir", mysql_home); static sys_var_long_ptr sys_binlog_cache_size(&vars, "binlog_cache_size", &binlog_cache_size); static sys_var_thd_binlog_format sys_binlog_format(&vars, "binlog_format", &SV::binlog_format); static sys_var_thd_ulong sys_bulk_insert_buff_size(&vars, "bulk_insert_buffer_size", &SV::bulk_insert_buff_size); +static sys_var_const_os sys_character_sets_dir(&vars, + "character_sets_dir", + OPT_GLOBAL, SHOW_CHAR, + (uchar*) + mysql_charsets_dir); static sys_var_character_set_sv sys_character_set_server(&vars, "character_set_server", &SV::collation_server, &default_charset_info, 0, @@ -226,7 +233,7 @@ static sys_var_long_ptr sys_concurrent_insert(&vars, "concurrent_insert", &myisam_concurrent_insert); static sys_var_long_ptr sys_connect_timeout(&vars, "connect_timeout", &connect_timeout); -static sys_var_const_str sys_datadir(&vars, "datadir", mysql_real_data_home); +static sys_var_const_os_str sys_datadir(&vars, "datadir", mysql_real_data_home); #ifndef DBUG_OFF static sys_var_thd_dbug sys_dbug(&vars, "debug"); #endif @@ -249,14 +256,31 @@ static sys_var_long_ptr sys_expire_logs_days(&vars, "expire_logs_days", &expire_logs_days); static sys_var_bool_ptr sys_flush(&vars, "flush", &myisam_flush); static sys_var_long_ptr sys_flush_time(&vars, "flush_time", &flush_time); -static sys_var_str sys_ft_boolean_syntax(&vars, "ft_boolean_syntax", - sys_check_ftb_syntax, - sys_update_ftb_syntax, - sys_default_ftb_syntax, - ft_boolean_syntax); +static sys_var_str sys_ft_boolean_syntax(&vars, "ft_boolean_syntax", + sys_check_ftb_syntax, + sys_update_ftb_syntax, + sys_default_ftb_syntax, + ft_boolean_syntax); +static sys_var_const sys_ft_max_word_len(&vars, "ft_max_word_len", + OPT_GLOBAL, SHOW_LONG, + (uchar*) &ft_max_word_len); +static sys_var_const sys_ft_min_word_len(&vars, "ft_min_word_len", + OPT_GLOBAL, SHOW_LONG, + (uchar*) &ft_min_word_len); +static sys_var_const sys_ft_query_expansion_limit(&vars, + "ft_query_expansion_limit", + OPT_GLOBAL, SHOW_LONG, + (uchar*) + &ft_query_expansion_limit); +static sys_var_const sys_ft_stopword_file(&vars, "ft_stopword_file", + OPT_GLOBAL, SHOW_CHAR_PTR, + (uchar*) &ft_stopword_file); sys_var_str sys_init_connect(&vars, "init_connect", 0, sys_update_init_connect, sys_default_init_connect,0); +static sys_var_const sys_init_file(&vars, "init_file", + OPT_GLOBAL, SHOW_CHAR_PTR, + (uchar*) &opt_init_file); sys_var_str sys_init_slave(&vars, "init_slave", 0, sys_update_init_slave, sys_default_init_slave,0); @@ -274,14 +298,37 @@ static sys_var_key_cache_long sys_key_cache_division_limit(&vars, "key_cache_div static sys_var_key_cache_long sys_key_cache_age_threshold(&vars, "key_cache_age_threshold", offsetof(KEY_CACHE, param_age_threshold)); +static sys_var_const sys_language(&vars, "language", + OPT_GLOBAL, SHOW_CHAR, + (uchar*) language); +static sys_var_const sys_large_files_support(&vars, "large_files_support", + OPT_GLOBAL, SHOW_BOOL, + (uchar*) &opt_large_files); +static sys_var_const sys_large_page_size(&vars, "large_page_size", + OPT_GLOBAL, SHOW_INT, + (uchar*) &opt_large_page_size); +static sys_var_const sys_large_pages(&vars, "large_pages", + OPT_GLOBAL, SHOW_MY_BOOL, + (uchar*) &opt_large_pages); static sys_var_bool_ptr sys_local_infile(&vars, "local_infile", &opt_local_infile); +#ifdef HAVE_MLOCKALL +static sys_var_const sys_locked_in_memory(&vars, "locked_in_memory", + OPT_GLOBAL, SHOW_MY_BOOL, + (uchar*) &locked_in_memory); +#endif +static sys_var_const sys_log_bin(&vars, "log_bin", + OPT_GLOBAL, SHOW_BOOL, + (uchar*) &opt_bin_log); static sys_var_trust_routine_creators sys_trust_routine_creators(&vars, "log_bin_trust_routine_creators", &trust_function_creators); static sys_var_bool_ptr sys_trust_function_creators(&vars, "log_bin_trust_function_creators", &trust_function_creators); +static sys_var_const sys_log_error(&vars, "log_error", + OPT_GLOBAL, SHOW_CHAR, + (uchar*) log_error_file); static sys_var_bool_ptr sys_log_queries_not_using_indexes(&vars, "log_queries_not_using_indexes", &opt_log_queries_not_using_indexes); @@ -296,7 +343,17 @@ static sys_var_thd_bool sys_sql_low_priority_updates(&vars, "sql_low_priority_up &SV::low_priority_updates, fix_low_priority_updates); #endif -static sys_var_thd_ulong sys_max_allowed_packet(&vars, "max_allowed_packet", +static sys_var_const sys_lower_case_file_system(&vars, + "lower_case_file_system", + OPT_GLOBAL, SHOW_MY_BOOL, + (uchar*) + &lower_case_file_system); +static sys_var_const sys_lower_case_table_names(&vars, + "lower_case_table_names", + OPT_GLOBAL, SHOW_INT, + (uchar*) + &lower_case_table_names); +static sys_var_thd_ulong_session_readonly sys_max_allowed_packet(&vars, "max_allowed_packet", &SV::max_allowed_packet); static sys_var_long_ptr sys_max_binlog_cache_size(&vars, "max_binlog_cache_size", &max_binlog_cache_size); @@ -359,6 +416,10 @@ static sys_var_thd_ulong sys_multi_range_count(&vars, "multi_range_count", static sys_var_long_ptr sys_myisam_data_pointer_size(&vars, "myisam_data_pointer_size", &myisam_data_pointer_size); static sys_var_thd_ulonglong sys_myisam_max_sort_file_size(&vars, "myisam_max_sort_file_size", &SV::myisam_max_sort_file_size, fix_myisam_max_sort_file_size, 1); +static sys_var_const sys_myisam_recover_options(&vars, "myisam_recover_options", + OPT_GLOBAL, SHOW_CHAR_PTR, + (uchar*) + &myisam_recover_options_str); static sys_var_thd_ulong sys_myisam_repair_threads(&vars, "myisam_repair_threads", &SV::myisam_repair_threads); static sys_var_thd_ulong sys_myisam_sort_buffer_size(&vars, "myisam_sort_buffer_size", &SV::myisam_sort_buff_size); static sys_var_bool_ptr sys_myisam_use_mmap(&vars, "myisam_use_mmap", @@ -369,7 +430,14 @@ static sys_var_thd_enum sys_myisam_stats_method(&vars, "myisam_stats_met &myisam_stats_method_typelib, NULL); -static sys_var_thd_ulong sys_net_buffer_length(&vars, "net_buffer_length", +#ifdef __NT__ +/* purecov: begin inspected */ +static sys_var_const sys_named_pipe(&vars, "named_pipe", + OPT_GLOBAL, SHOW_MY_BOOL, + (uchar*) &opt_enable_named_pipe); +/* purecov: end */ +#endif +static sys_var_thd_ulong_session_readonly sys_net_buffer_length(&vars, "net_buffer_length", &SV::net_buffer_length); static sys_var_thd_ulong sys_net_read_timeout(&vars, "net_read_timeout", &SV::net_read_timeout, @@ -387,12 +455,29 @@ static sys_var_bool_ptr_readonly sys_old_mode(&vars, "old", sys_var_thd_bool sys_old_alter_table(&vars, "old_alter_table", &SV::old_alter_table); sys_var_thd_bool sys_old_passwords(&vars, "old_passwords", &SV::old_passwords); +static sys_var_const sys_open_files_limit(&vars, "open_files_limit", + OPT_GLOBAL, SHOW_LONG, + (uchar*) + &open_files_limit); static sys_var_thd_ulong sys_optimizer_prune_level(&vars, "optimizer_prune_level", &SV::optimizer_prune_level); static sys_var_thd_ulong sys_optimizer_search_depth(&vars, "optimizer_search_depth", &SV::optimizer_search_depth); +static sys_var_const sys_pid_file(&vars, "pid_file", + OPT_GLOBAL, SHOW_CHAR, + (uchar*) pidfile_name); +static sys_var_const_os sys_plugin_dir(&vars, "plugin_dir", + OPT_GLOBAL, SHOW_CHAR, + (uchar*) opt_plugin_dir); +static sys_var_const sys_port(&vars, "port", + OPT_GLOBAL, SHOW_INT, + (uchar*) &mysqld_port); static sys_var_thd_ulong sys_preload_buff_size(&vars, "preload_buffer_size", &SV::preload_buff_size); +static sys_var_const sys_protocol_version(&vars, "protocol_version", + OPT_GLOBAL, SHOW_INT, + (uchar*) + &protocol_version); static sys_var_thd_ulong sys_read_buff_size(&vars, "read_buffer_size", &SV::read_buff_size); static sys_var_opt_readonly sys_readonly(&vars, "read_only", &opt_readonly); @@ -414,7 +499,46 @@ static sys_var_thd_ulong sys_query_alloc_block_size(&vars, "query_alloc_block_si static sys_var_thd_ulong sys_query_prealloc_size(&vars, "query_prealloc_size", &SV::query_prealloc_size, 0, fix_thd_mem_root); -static sys_var_readonly sys_tmpdir(&vars, "tmpdir", OPT_GLOBAL, SHOW_CHAR, get_tmpdir); +#ifdef HAVE_SMEM +/* purecov: begin tested */ +static sys_var_const sys_shared_memory(&vars, "shared_memory", + OPT_GLOBAL, SHOW_MY_BOOL, + (uchar*) + &opt_enable_shared_memory); +static sys_var_const sys_shared_memory_base_name(&vars, + "shared_memory_base_name", + OPT_GLOBAL, SHOW_CHAR_PTR, + (uchar*) + &shared_memory_base_name); +/* purecov: end */ +#endif +static sys_var_const sys_skip_external_locking(&vars, + "skip_external_locking", + OPT_GLOBAL, SHOW_MY_BOOL, + (uchar*) + &my_disable_locking); +static sys_var_const sys_skip_networking(&vars, "skip_networking", + OPT_GLOBAL, SHOW_BOOL, + (uchar*) &opt_disable_networking); +static sys_var_const sys_skip_show_database(&vars, "skip_show_database", + OPT_GLOBAL, SHOW_BOOL, + (uchar*) &opt_skip_show_db); +#ifdef HAVE_SYS_UN_H +static sys_var_const sys_socket(&vars, "socket", + OPT_GLOBAL, SHOW_CHAR_PTR, + (uchar*) &mysqld_unix_port); +#endif +#ifdef HAVE_THR_SETCONCURRENCY +/* purecov: begin tested */ +static sys_var_const sys_thread_concurrency(&vars, "thread_concurrency", + OPT_GLOBAL, SHOW_LONG, + (uchar*) &concurrency); +/* purecov: end */ +#endif +static sys_var_const sys_thread_stack(&vars, "thread_stack", + OPT_GLOBAL, SHOW_LONG, + (uchar*) &my_thread_stack_size); +static sys_var_readonly_os sys_tmpdir(&vars, "tmpdir", OPT_GLOBAL, SHOW_CHAR, get_tmpdir); static sys_var_thd_ulong sys_trans_alloc_block_size(&vars, "transaction_alloc_block_size", &SV::trans_alloc_block_size, 0, fix_trans_mem_root); @@ -465,17 +589,17 @@ static sys_var_thd_sql_mode sys_sql_mode(&vars, "sql_mode", #ifdef HAVE_OPENSSL extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher, *opt_ssl_key; -static sys_var_const_str_ptr sys_ssl_ca(&vars, "ssl_ca", &opt_ssl_ca); -static sys_var_const_str_ptr sys_ssl_capath(&vars, "ssl_capath", &opt_ssl_capath); -static sys_var_const_str_ptr sys_ssl_cert(&vars, "ssl_cert", &opt_ssl_cert); -static sys_var_const_str_ptr sys_ssl_cipher(&vars, "ssl_cipher", &opt_ssl_cipher); -static sys_var_const_str_ptr sys_ssl_key(&vars, "ssl_key", &opt_ssl_key); +static sys_var_const_os_str_ptr sys_ssl_ca(&vars, "ssl_ca", &opt_ssl_ca); +static sys_var_const_os_str_ptr sys_ssl_capath(&vars, "ssl_capath", &opt_ssl_capath); +static sys_var_const_os_str_ptr sys_ssl_cert(&vars, "ssl_cert", &opt_ssl_cert); +static sys_var_const_os_str_ptr sys_ssl_cipher(&vars, "ssl_cipher", &opt_ssl_cipher); +static sys_var_const_os_str_ptr sys_ssl_key(&vars, "ssl_key", &opt_ssl_key); #else -static sys_var_const_str sys_ssl_ca(&vars, "ssl_ca", NULL); -static sys_var_const_str sys_ssl_capath(&vars, "ssl_capath", NULL); -static sys_var_const_str sys_ssl_cert(&vars, "ssl_cert", NULL); -static sys_var_const_str sys_ssl_cipher(&vars, "ssl_cipher", NULL); -static sys_var_const_str sys_ssl_key(&vars, "ssl_key", NULL); +static sys_var_const_os_str sys_ssl_ca(&vars, "ssl_ca", NULL); +static sys_var_const_os_str sys_ssl_capath(&vars, "ssl_capath", NULL); +static sys_var_const_os_str sys_ssl_cert(&vars, "ssl_cert", NULL); +static sys_var_const_os_str sys_ssl_cipher(&vars, "ssl_cipher", NULL); +static sys_var_const_os_str sys_ssl_key(&vars, "ssl_key", NULL); #endif static sys_var_thd_enum sys_updatable_views_with_limit(&vars, "updatable_views_with_limit", @@ -764,59 +888,6 @@ static sys_var_log_output sys_var_log_output_state(&vars, "log_output", &log_out &log_output_typelib, 0); -/* - Additional variables (not derived from sys_var class, not accessible as - @@varname in SELECT or SET). Sorted in alphabetical order to facilitate - maintenance - SHOW VARIABLES will sort its output. - TODO: remove this list completely -*/ - -#define FIXED_VARS_SIZE (sizeof(fixed_vars) / sizeof(SHOW_VAR)) -static SHOW_VAR fixed_vars[]= { - {"back_log", (char*) &back_log, SHOW_LONG}, - {"character_sets_dir", mysql_charsets_dir, SHOW_CHAR}, - {"ft_max_word_len", (char*) &ft_max_word_len, SHOW_LONG}, - {"ft_min_word_len", (char*) &ft_min_word_len, SHOW_LONG}, - {"ft_query_expansion_limit",(char*) &ft_query_expansion_limit, SHOW_LONG}, - {"ft_stopword_file", (char*) &ft_stopword_file, SHOW_CHAR_PTR}, - {"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR}, - {"language", language, SHOW_CHAR}, - {"large_files_support", (char*) &opt_large_files, SHOW_BOOL}, - {"large_page_size", (char*) &opt_large_page_size, SHOW_INT}, - {"large_pages", (char*) &opt_large_pages, SHOW_MY_BOOL}, -#ifdef HAVE_MLOCKALL - {"locked_in_memory", (char*) &locked_in_memory, SHOW_MY_BOOL}, -#endif - {"log_bin", (char*) &opt_bin_log, SHOW_BOOL}, - {"log_error", (char*) log_error_file, SHOW_CHAR}, - {"lower_case_file_system", (char*) &lower_case_file_system, SHOW_MY_BOOL}, - {"lower_case_table_names", (char*) &lower_case_table_names, SHOW_INT}, - {"myisam_recover_options", (char*) &myisam_recover_options_str, SHOW_CHAR_PTR}, -#ifdef __NT__ - {"named_pipe", (char*) &opt_enable_named_pipe, SHOW_MY_BOOL}, -#endif - {"open_files_limit", (char*) &open_files_limit, SHOW_LONG}, - {"pid_file", (char*) pidfile_name, SHOW_CHAR}, - {"plugin_dir", (char*) opt_plugin_dir, SHOW_CHAR}, - {"port", (char*) &mysqld_port, SHOW_INT}, - {"protocol_version", (char*) &protocol_version, SHOW_INT}, -#ifdef HAVE_SMEM - {"shared_memory", (char*) &opt_enable_shared_memory, SHOW_MY_BOOL}, - {"shared_memory_base_name", (char*) &shared_memory_base_name, SHOW_CHAR_PTR}, -#endif - {"skip_external_locking", (char*) &my_disable_locking, SHOW_MY_BOOL}, - {"skip_networking", (char*) &opt_disable_networking, SHOW_BOOL}, - {"skip_show_database", (char*) &opt_skip_show_db, SHOW_BOOL}, -#ifdef HAVE_SYS_UN_H - {"socket", (char*) &mysqld_unix_port, SHOW_CHAR_PTR}, -#endif -#ifdef HAVE_THR_SETCONCURRENCY - {"thread_concurrency", (char*) &concurrency, SHOW_LONG}, -#endif - {"thread_stack", (char*) &my_thread_stack_size, SHOW_LONG}, -}; - - bool sys_var::check(THD *thd, set_var *var) { var->save_result.ulonglong_value= var->value->val_int(); @@ -865,6 +936,7 @@ bool update_sys_var_str(sys_var_str *var_str, rw_lock_t *var_mutex, old_value= var_str->value; var_str->value= res; var_str->value_length= new_length; + var_str->is_os_charset= FALSE; rw_unlock(var_mutex); my_free(old_value, MYF(MY_ALLOW_ZERO_PTR)); return 0; @@ -1734,6 +1806,13 @@ err: } +CHARSET_INFO *sys_var::charset(THD *thd) +{ + return is_os_charset ? thd->variables.character_set_filesystem : + system_charset_info; +} + + bool sys_var_thd_enum::update(THD *thd, set_var *var) { if (var->type == OPT_GLOBAL) @@ -2734,6 +2813,18 @@ uchar *sys_var_max_user_conn::value_ptr(THD *thd, enum_var_type type, } +bool sys_var_thd_ulong_session_readonly::check(THD *thd, set_var *var) +{ + if (var->type != OPT_GLOBAL) + { + my_error(ER_VARIABLE_IS_READONLY, MYF(0), "SESSION", name, "GLOBAL"); + return TRUE; + } + + return sys_var_thd_ulong::check(thd, var); +} + + bool sys_var_thd_lc_time_names::check(THD *thd, set_var *var) { MY_LOCALE *locale_match; @@ -3123,14 +3214,12 @@ static int show_cmp(SHOW_VAR *a, SHOW_VAR *b) SHOW_VAR* enumerate_sys_vars(THD *thd, bool sorted) { int count= system_variable_hash.records, i; - int fixed_count= fixed_show_vars.elements; - int size= sizeof(SHOW_VAR) * (count + fixed_count + 1); + int size= sizeof(SHOW_VAR) * (count + 1); SHOW_VAR *result= (SHOW_VAR*) thd->alloc(size); if (result) { - SHOW_VAR *show= result + fixed_count; - memcpy(result, fixed_show_vars.buffer, fixed_count * sizeof(SHOW_VAR)); + SHOW_VAR *show= result; for (i= 0; i < count; i++) { @@ -3143,7 +3232,7 @@ SHOW_VAR* enumerate_sys_vars(THD *thd, bool sorted) /* sort into order */ if (sorted) - my_qsort(result, count + fixed_count, sizeof(SHOW_VAR), + my_qsort(result, count, sizeof(SHOW_VAR), (qsort_cmp) show_cmp); /* make last element empty */ @@ -3171,13 +3260,6 @@ int set_var_init() for (sys_var *var=vars.first; var; var= var->next, count++); - if (my_init_dynamic_array(&fixed_show_vars, sizeof(SHOW_VAR), - FIXED_VARS_SIZE + 64, 64)) - goto error; - - fixed_show_vars.elements= FIXED_VARS_SIZE; - memcpy(fixed_show_vars.buffer, fixed_vars, sizeof(fixed_vars)); - if (hash_init(&system_variable_hash, system_charset_info, count, 0, 0, (hash_get_key) get_sys_var_length, 0, HASH_UNIQUE)) goto error; @@ -3205,28 +3287,6 @@ error: void set_var_free() { hash_free(&system_variable_hash); - delete_dynamic(&fixed_show_vars); -} - - -/* - Add elements to the dynamic list of read-only system variables. - - SYNOPSIS - mysql_append_static_vars() - show_vars Pointer to start of array - count Number of elements - - RETURN VALUES - 0 SUCCESS - otherwise FAILURE -*/ -int mysql_append_static_vars(const SHOW_VAR *show_vars, uint count) -{ - for (; count > 0; count--, show_vars++) - if (insert_dynamic(&fixed_show_vars, (uchar*) show_vars)) - return 1; - return 0; } diff --git a/sql/set_var.h b/sql/set_var.h index 9681c955a98..b6c67d1ab4a 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -71,9 +71,18 @@ public: sys_after_update_func after_update; bool no_support_one_shot; + /* + true if the value is in character_set_filesystem, + false otherwise. + Note that we can't use a pointer to the charset as the system var is + instantiated in global scope and the charset pointers are initialized + later. + */ + bool is_os_charset; sys_var(const char *name_arg, sys_after_update_func func= NULL, Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG) :name(name_arg), after_update(func), no_support_one_shot(1), + is_os_charset (FALSE), binlog_status(binlog_status_arg), m_allow_empty_value(TRUE) {} @@ -107,6 +116,7 @@ public: { return option_limits == 0; } virtual bool is_struct() { return 0; } virtual bool is_readonly() const { return 0; } + CHARSET_INFO *charset(THD *thd); virtual sys_var_pluginvar *cast_pluginvar() { return 0; } protected: @@ -291,6 +301,18 @@ public: }; +class sys_var_const_os_str: public sys_var_const_str +{ +public: + sys_var_const_os_str(sys_var_chain *chain, const char *name_arg, + const char *value_arg) + :sys_var_const_str(chain, name_arg, value_arg) + { + is_os_charset= TRUE; + } +}; + + class sys_var_const_str_ptr :public sys_var { public: @@ -320,6 +342,18 @@ public: }; +class sys_var_const_os_str_ptr :public sys_var_const_str_ptr +{ +public: + sys_var_const_os_str_ptr(sys_var_chain *chain, const char *name_arg, + char **value_arg) + :sys_var_const_str_ptr(chain, name_arg, value_arg) + { + is_os_charset= TRUE; + } +}; + + class sys_var_enum :public sys_var { uint *value; @@ -929,6 +963,63 @@ public: }; +class sys_var_readonly_os: public sys_var_readonly +{ +public: + sys_var_readonly_os(sys_var_chain *chain, const char *name_arg, enum_var_type type, + SHOW_TYPE show_type_arg, + sys_value_ptr_func value_ptr_func_arg) + :sys_var_readonly(chain, name_arg, type, show_type_arg, value_ptr_func_arg) + { + is_os_charset= TRUE; + } +}; + + +/** + Global-only, read-only variable. E.g. command line option. +*/ + +class sys_var_const: public sys_var +{ +public: + enum_var_type var_type; + SHOW_TYPE show_type_value; + uchar *ptr; + sys_var_const(sys_var_chain *chain, const char *name_arg, enum_var_type type, + SHOW_TYPE show_type_arg, uchar *ptr_arg) + :sys_var(name_arg), var_type(type), + show_type_value(show_type_arg), ptr(ptr_arg) + { chain_sys_var(chain); } + bool update(THD *thd, set_var *var) { return 1; } + bool check_default(enum_var_type type) { return 1; } + bool check_type(enum_var_type type) { return type != var_type; } + bool check_update_type(Item_result type) { return 1; } + uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base) + { + return ptr; + } + SHOW_TYPE show_type() { return show_type_value; } + bool is_readonly() const { return 1; } +}; + + +class sys_var_const_os: public sys_var_const +{ +public: + enum_var_type var_type; + SHOW_TYPE show_type_value; + uchar *ptr; + sys_var_const_os(sys_var_chain *chain, const char *name_arg, + enum_var_type type, + SHOW_TYPE show_type_arg, uchar *ptr_arg) + :sys_var_const(chain, name_arg, type, show_type_arg, ptr_arg) + { + is_os_charset= TRUE; + } +}; + + class sys_var_have_option: public sys_var { protected: @@ -1024,6 +1115,29 @@ public: }; +/** + * @brief This is a specialization of sys_var_thd_ulong that implements a + read-only session variable. The class overrides check() and check_default() + to achieve the read-only property for the session part of the variable. + */ +class sys_var_thd_ulong_session_readonly : public sys_var_thd_ulong +{ +public: + sys_var_thd_ulong_session_readonly(sys_var_chain *chain_arg, + const char *name_arg, ulong SV::*offset_arg, + sys_check_func c_func= NULL, + sys_after_update_func au_func= NULL, + Binlog_status_enum bl_status_arg= NOT_IN_BINLOG): + sys_var_thd_ulong(chain_arg, name_arg, offset_arg, c_func, au_func, bl_status_arg) + { } + bool check(THD *thd, set_var *var); + bool check_default(enum_var_type type) + { + return type != OPT_GLOBAL || !option_limits; + } +}; + + class sys_var_microseconds :public sys_var_thd { ulonglong SV::*offset; @@ -1294,7 +1408,6 @@ struct sys_var_with_base int set_var_init(); void set_var_free(); -int mysql_append_static_vars(const SHOW_VAR *show_vars, uint count); SHOW_VAR* enumerate_sys_vars(THD *thd, bool sorted); int mysql_add_sys_var_chain(sys_var *chain, struct my_option *long_options); int mysql_del_sys_var_chain(sys_var *chain); diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index b86007408fb..fd75fee9737 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -6151,3 +6151,6 @@ WARN_PLUGIN_DELETE_BUILTIN WARN_PLUGIN_BUSY eng "Plugin is busy and will be uninstalled on shutdown" + +ER_VARIABLE_IS_READONLY + eng "%s variable '%s' is read-only. Use SET %s to assign the value" diff --git a/sql/slave.cc b/sql/slave.cc index 0040b69f8de..43b70f29a68 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -49,6 +49,7 @@ #define MAX_SLAVE_RETRY_PAUSE 5 bool use_slave_mask = 0; MY_BITMAP slave_error_mask; +char slave_skip_error_names[SHOW_VAR_FUNC_BUFF_SIZE]; typedef bool (*CHECK_KILLED_FUNC)(THD*,void*); @@ -275,6 +276,64 @@ err: } +/** + Convert slave skip errors bitmap into a printable string. +*/ + +static void print_slave_skip_errors(void) +{ + /* + To be safe, we want 10 characters of room in the buffer for a number + plus terminators. Also, we need some space for constant strings. + 10 characters must be sufficient for a number plus {',' | '...'} + plus a NUL terminator. That is a max 6 digit number. + */ + const size_t MIN_ROOM= 10; + DBUG_ENTER("print_slave_skip_errors"); + DBUG_ASSERT(sizeof(slave_skip_error_names) > MIN_ROOM); + DBUG_ASSERT(MAX_SLAVE_ERROR <= 999999); // 6 digits + + if (!use_slave_mask || bitmap_is_clear_all(&slave_error_mask)) + { + /* purecov: begin tested */ + memcpy(slave_skip_error_names, STRING_WITH_LEN("OFF")); + /* purecov: end */ + } + else if (bitmap_is_set_all(&slave_error_mask)) + { + /* purecov: begin tested */ + memcpy(slave_skip_error_names, STRING_WITH_LEN("ALL")); + /* purecov: end */ + } + else + { + char *buff= slave_skip_error_names; + char *bend= buff + sizeof(slave_skip_error_names); + int errnum; + + for (errnum= 1; errnum < MAX_SLAVE_ERROR; errnum++) + { + if (bitmap_is_set(&slave_error_mask, errnum)) + { + if (buff + MIN_ROOM >= bend) + break; /* purecov: tested */ + buff= int10_to_str(errnum, buff, 10); + *buff++= ','; + } + } + if (buff != slave_skip_error_names) + buff--; // Remove last ',' + if (errnum < MAX_SLAVE_ERROR) + { + /* Couldn't show all errors */ + buff= strmov(buff, "..."); /* purecov: tested */ + } + *buff=0; + } + DBUG_PRINT("init", ("error_names: '%s'", slave_skip_error_names)); + DBUG_VOID_RETURN; +} + /* Init function to set up array for errors that should be skipped for slave @@ -314,6 +373,8 @@ void init_slave_skip_errors(const char* arg) while (!my_isdigit(system_charset_info,*p) && *p) p++; } + /* Convert slave skip errors bitmap into a printable string. */ + print_slave_skip_errors(); DBUG_VOID_RETURN; } diff --git a/sql/slave.h b/sql/slave.h index dc2d668c97b..abd63315e62 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -98,6 +98,7 @@ class Master_info; extern ulong master_retry_count; extern MY_BITMAP slave_error_mask; +extern char slave_skip_error_names[]; extern bool use_slave_mask; extern char *slave_load_tmpdir; extern char *master_info_file, *relay_log_info_file; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index a31373cdb27..ea664cd5091 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3095,7 +3095,10 @@ bool reopen_table(TABLE *table) for (key=0 ; key < table->s->keys ; key++) { for (part=0 ; part < table->key_info[key].usable_key_parts ; part++) + { table->key_info[key].key_part[part].field->table= table; + table->key_info[key].key_part[part].field->orig_table= table; + } } if (table->triggers) table->triggers->set_table(table); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index bde20c54a97..ecda2b33d5b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -311,7 +311,7 @@ void thd_inc_row_count(THD *thd) Dumps a text description of a thread, its security context (user, host) and the current query. - @param thd current thread context + @param thd thread context @param buffer pointer to preferred result buffer @param length length of buffer @param max_query_len how many chars of query to copy (0 for all) @@ -385,7 +385,17 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length, } if (str.c_ptr_safe() == buffer) return buffer; - return thd->strmake(str.ptr(), str.length()); + + /* + We have to copy the new string to the destination buffer because the string + was reallocated to a larger buffer to be able to fit. + */ + DBUG_ASSERT(buffer != NULL); + length= min(str.length(), length-1); + memcpy(buffer, str.c_ptr_quick(), length); + /* Make sure that the new string is null terminated */ + buffer[length]= '\0'; + return buffer; } /** diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 0db88d7dd90..c538dfb08bc 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -1099,7 +1099,6 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, /* .frm archive: Those archives are obsolete, but following code should exist to remove existent "arc" directories. - See #ifdef FRM_ARCHIVE directives for obsolete code. */ char newpath[FN_REFLEN]; MY_DIR *new_dirp; @@ -1268,7 +1267,6 @@ static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error) NOTE A support of "arc" directories is obsolete, however this function should exist to remove existent "arc" directories. - See #ifdef FRM_ARCHIVE directives for obsolete code. */ long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path) { diff --git a/sql/sql_manager.cc b/sql/sql_manager.cc index 171ab55145a..b082f65bfb9 100644 --- a/sql/sql_manager.cc +++ b/sql/sql_manager.cc @@ -23,8 +23,9 @@ #include "mysql_priv.h" -ulong volatile manager_status; -bool volatile manager_thread_in_use; + +static bool volatile manager_thread_in_use; +static bool abort_manager; pthread_t manager_thread; pthread_mutex_t LOCK_manager; @@ -63,7 +64,6 @@ bool mysql_manager_submit(void (*action)()) pthread_handler_t handle_manager(void *arg __attribute__((unused))) { int error = 0; - ulong status; struct timespec abstime; bool reset_flush_time = TRUE; struct handler_cb *cb= NULL; @@ -72,7 +72,6 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused))) pthread_detach_this_thread(); manager_thread = pthread_self(); - manager_status = 0; manager_thread_in_use = 1; for (;;) @@ -87,16 +86,14 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused))) set_timespec(abstime, flush_time); reset_flush_time = FALSE; } - while (!manager_status && (!error || error == EINTR) && !abort_loop) + while ((!error || error == EINTR) && !abort_manager) error= pthread_cond_timedwait(&COND_manager, &LOCK_manager, &abstime); } else { - while (!manager_status && (!error || error == EINTR) && !abort_loop) + while ((!error || error == EINTR) && !abort_manager) error= pthread_cond_wait(&COND_manager, &LOCK_manager); } - status = manager_status; - manager_status = 0; if (cb == NULL) { cb= cb_list; @@ -104,7 +101,7 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused))) } pthread_mutex_unlock(&LOCK_manager); - if (abort_loop) + if (abort_manager) break; if (error == ETIMEDOUT || error == ETIME) @@ -121,11 +118,42 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused))) my_free((uchar*)cb, MYF(0)); cb= next; } - - if (status) - DBUG_PRINT("error", ("manager did not handle something: %lx", status)); } manager_thread_in_use = 0; + DBUG_LEAVE; // Can't use DBUG_RETURN after my_thread_end my_thread_end(); - DBUG_RETURN(NULL); + return (NULL); } + + +/* Start handle manager thread */ +void start_handle_manager() +{ + DBUG_ENTER("start_handle_manager"); + abort_manager = false; + if (flush_time && flush_time != ~(ulong) 0L) + { + pthread_t hThread; + if (pthread_create(&hThread,&connection_attrib,handle_manager,0)) + sql_print_warning("Can't create handle_manager thread"); + } + DBUG_VOID_RETURN; +} + + +/* Initiate shutdown of handle manager thread */ +void stop_handle_manager() +{ + DBUG_ENTER("stop_handle_manager"); + abort_manager = true; + pthread_mutex_lock(&LOCK_manager); + if (manager_thread_in_use) + { + DBUG_PRINT("quit", ("initiate shutdown of handle manager thread: 0x%lx", + (ulong)manager_thread)); + pthread_cond_signal(&COND_manager); + } + pthread_mutex_unlock(&LOCK_manager); + DBUG_VOID_RETURN; +} + diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 932b7a67b4d..eac7a50417a 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1660,64 +1660,38 @@ public: static sys_var_chain vars = { NULL, NULL }; +static sys_var_const sys_log_slave_updates(&vars, "log_slave_updates", + OPT_GLOBAL, SHOW_MY_BOOL, + (uchar*) &opt_log_slave_updates); +static sys_var_const sys_relay_log(&vars, "relay_log", + OPT_GLOBAL, SHOW_CHAR_PTR, + (uchar*) &opt_relay_logname); +static sys_var_const sys_relay_log_index(&vars, "relay_log_index", + OPT_GLOBAL, SHOW_CHAR_PTR, + (uchar*) &opt_relaylog_index_name); +static sys_var_const sys_relay_log_info_file(&vars, "relay_log_info_file", + OPT_GLOBAL, SHOW_CHAR_PTR, + (uchar*) &relay_log_info_file); static sys_var_bool_ptr sys_relay_log_purge(&vars, "relay_log_purge", &relay_log_purge); +static sys_var_const sys_relay_log_space_limit(&vars, + "relay_log_space_limit", + OPT_GLOBAL, SHOW_LONGLONG, + (uchar*) + &relay_log_space_limit); +static sys_var_const sys_slave_load_tmpdir(&vars, "slave_load_tmpdir", + OPT_GLOBAL, SHOW_CHAR_PTR, + (uchar*) &slave_load_tmpdir); static sys_var_long_ptr sys_slave_net_timeout(&vars, "slave_net_timeout", &slave_net_timeout); +static sys_var_const sys_slave_skip_errors(&vars, "slave_skip_errors", + OPT_GLOBAL, SHOW_CHAR, + (uchar*) slave_skip_error_names); static sys_var_long_ptr sys_slave_trans_retries(&vars, "slave_transaction_retries", &slave_trans_retries); static sys_var_sync_binlog_period sys_sync_binlog_period(&vars, "sync_binlog", &sync_binlog_period); static sys_var_slave_skip_counter sys_slave_skip_counter(&vars, "sql_slave_skip_counter"); -static int show_slave_skip_errors(THD *thd, SHOW_VAR *var, char *buff); - - -static SHOW_VAR fixed_vars[]= { - {"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_MY_BOOL}, - {"relay_log" , (char*) &opt_relay_logname, SHOW_CHAR_PTR}, - {"relay_log_index", (char*) &opt_relaylog_index_name, SHOW_CHAR_PTR}, - {"relay_log_info_file", (char*) &relay_log_info_file, SHOW_CHAR_PTR}, - {"relay_log_space_limit", (char*) &relay_log_space_limit, SHOW_LONGLONG}, - {"slave_load_tmpdir", (char*) &slave_load_tmpdir, SHOW_CHAR_PTR}, - {"slave_skip_errors", (char*) &show_slave_skip_errors, SHOW_FUNC}, -}; - -static int show_slave_skip_errors(THD *thd, SHOW_VAR *var, char *buff) -{ - var->type=SHOW_CHAR; - var->value= buff; - if (!use_slave_mask || bitmap_is_clear_all(&slave_error_mask)) - { - var->value= const_cast<char *>("OFF"); - } - else if (bitmap_is_set_all(&slave_error_mask)) - { - var->value= const_cast<char *>("ALL"); - } - else - { - /* 10 is enough assuming errors are max 4 digits */ - int i; - var->value= buff; - for (i= 1; - i < MAX_SLAVE_ERROR && - (buff - var->value) < SHOW_VAR_FUNC_BUFF_SIZE; - i++) - { - if (bitmap_is_set(&slave_error_mask, i)) - { - buff= int10_to_str(i, buff, 10); - *buff++= ','; - } - } - if (var->value != buff) - buff--; // Remove last ',' - if (i < MAX_SLAVE_ERROR) - buff= strmov(buff, "..."); // Couldn't show all errors - *buff=0; - } - return 0; -} bool sys_var_slave_skip_counter::check(THD *thd, set_var *var) { @@ -1765,8 +1739,6 @@ bool sys_var_sync_binlog_period::update(THD *thd, set_var *var) int init_replication_sys_vars() { - mysql_append_static_vars(fixed_vars, sizeof(fixed_vars) / sizeof(SHOW_VAR)); - if (mysql_add_sys_var_chain(vars.first, my_long_options)) { /* should not happen */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 61b43d1e209..261a5c40c3b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -402,11 +402,21 @@ inline int setup_without_group(THD *thd, Item **ref_pointer_array, { int res; nesting_map save_allow_sum_func=thd->lex->allow_sum_func ; + /* + Need to save the value, so we can turn off only the new NON_AGG_FIELD + additions coming from the WHERE + */ + uint8 saved_flag= thd->lex->current_select->full_group_by_flag; DBUG_ENTER("setup_without_group"); thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level); res= setup_conds(thd, tables, leaves, conds); + /* it's not wrong to have non-aggregated columns in a WHERE */ + if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) + thd->lex->current_select->full_group_by_flag= saved_flag | + (thd->lex->current_select->full_group_by_flag & ~NON_AGG_FIELD_USED); + thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level; res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields, order); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 02cfba8fae0..aa62b98bd13 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -83,6 +83,7 @@ static void store_key_options(THD *thd, String *packet, TABLE *table, static void append_algorithm(TABLE_LIST *table, String *buff); +static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table); /*************************************************************************** ** List all table types supported @@ -2072,7 +2073,8 @@ static bool show_status_array(THD *thd, const char *wild, enum enum_var_type value_type, struct system_status_var *status_var, const char *prefix, TABLE *table, - bool ucase_names) + bool ucase_names, + COND *cond) { MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, long); char * const buff= (char *) &buff_data; @@ -2082,8 +2084,13 @@ static bool show_status_array(THD *thd, const char *wild, int len; LEX_STRING null_lex_str; SHOW_VAR tmp, *var; + COND *partial_cond= 0; + enum_check_fields save_count_cuted_fields= thd->count_cuted_fields; + bool res= FALSE; + CHARSET_INFO *charset= system_charset_info; DBUG_ENTER("show_status_array"); + thd->count_cuted_fields= CHECK_FIELD_WARN; null_lex_str.str= 0; // For sys_var->value_ptr() null_lex_str.length= 0; @@ -2091,6 +2098,7 @@ static bool show_status_array(THD *thd, const char *wild, if (*prefix) *prefix_end++= '_'; len=name_buffer + sizeof(name_buffer) - prefix_end; + partial_cond= make_cond_for_info_schema(cond, table->pos_in_table_list); for (; variables->name; variables++) { @@ -2099,6 +2107,9 @@ static bool show_status_array(THD *thd, const char *wild, if (ucase_names) make_upper(name_buffer); + restore_record(table, s->default_values); + table->field[0]->store(name_buffer, strlen(name_buffer), + system_charset_info); /* if var->type is SHOW_FUNC, call the function. Repeat as necessary, if new var is again SHOW_FUNC @@ -2110,12 +2121,13 @@ static bool show_status_array(THD *thd, const char *wild, if (show_type == SHOW_ARRAY) { show_status_array(thd, wild, (SHOW_VAR *) var->value, value_type, - status_var, name_buffer, table, ucase_names); + status_var, name_buffer, table, ucase_names, partial_cond); } else { if (!(wild && wild[0] && wild_case_compare(system_charset_info, - name_buffer, wild))) + name_buffer, wild)) && + (!partial_cond || partial_cond->val_int())) { char *value=var->value; const char *pos, *end; // We assign a lot of const's @@ -2124,9 +2136,10 @@ static bool show_status_array(THD *thd, const char *wild, if (show_type == SHOW_SYS) { - show_type= ((sys_var*) value)->show_type(); - value= (char*) ((sys_var*) value)->value_ptr(thd, value_type, - &null_lex_str); + sys_var *var= ((sys_var *) value); + show_type= var->show_type(); + value= (char*) var->value_ptr(thd, value_type, &null_lex_str); + charset= var->charset(thd); } pos= end= buff; @@ -2202,21 +2215,23 @@ static bool show_status_array(THD *thd, const char *wild, DBUG_ASSERT(0); break; } - restore_record(table, s->default_values); - table->field[0]->store(name_buffer, strlen(name_buffer), - system_charset_info); - table->field[1]->store(pos, (uint32) (end - pos), system_charset_info); + table->field[1]->store(pos, (uint32) (end - pos), charset); + thd->count_cuted_fields= CHECK_FIELD_IGNORE; table->field[1]->set_notnull(); pthread_mutex_unlock(&LOCK_global_system_variables); if (schema_table_store_record(thd, table)) - DBUG_RETURN(TRUE); + { + res= TRUE; + goto end; + } } } } - - DBUG_RETURN(FALSE); +end: + thd->count_cuted_fields= save_count_cuted_fields; + DBUG_RETURN(res); } @@ -3498,6 +3513,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, TABLE_SHARE *share= show_table->s; handler *file= show_table->file; handlerton *tmp_db_type= share->db_type(); + bool is_partitioned= FALSE; if (share->tmp_table == SYSTEM_TMP_TABLE) table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs); else if (share->tmp_table) @@ -3514,7 +3530,10 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, #ifdef WITH_PARTITION_STORAGE_ENGINE if (share->db_type() == partition_hton && share->partition_info_len) + { tmp_db_type= share->default_part_db_type; + is_partitioned= TRUE; + } #endif tmp_buff= (char *) ha_resolve_storage_engine_name(tmp_db_type); table->field[4]->store(tmp_buff, strlen(tmp_buff), cs); @@ -3559,9 +3578,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, NullS); } #ifdef WITH_PARTITION_STORAGE_ENGINE - if (show_table->s->db_type() == partition_hton && - show_table->part_info != NULL && - show_table->part_info->no_parts > 0) + if (is_partitioned) ptr= strmov(ptr, " partitioned"); #endif if (share->transactional != HA_CHOICE_UNDEF) @@ -5244,7 +5261,7 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond) rw_rdlock(&LOCK_system_variables_hash); res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars), - option_type, NULL, "", tables->table, upper_case_names); + option_type, NULL, "", tables->table, upper_case_names, cond); rw_unlock(&LOCK_system_variables_hash); DBUG_RETURN(res); } @@ -5287,7 +5304,7 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond) res= show_status_array(thd, wild, (SHOW_VAR *)all_status_vars.buffer, option_type, tmp1, "", tables->table, - upper_case_names); + upper_case_names, cond); pthread_mutex_unlock(&LOCK_status); DBUG_RETURN(res); } @@ -6013,9 +6030,10 @@ ST_FIELD_INFO schema_fields_info[]= {"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, {"SCHEMA_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database", SKIP_OPEN_TABLE}, - {"DEFAULT_CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, + {"DEFAULT_CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0, + SKIP_OPEN_TABLE}, + {"DEFAULT_COLLATION_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, - {"DEFAULT_COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, {"SQL_PATH", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; @@ -6049,7 +6067,8 @@ ST_FIELD_INFO tables_fields_info[]= {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE}, {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE}, {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time", OPEN_FULL_TABLE}, - {"TABLE_COLLATION", 64, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY}, + {"TABLE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 1, "Collation", + OPEN_FRM_ONLY}, {"CHECKSUM", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", OPEN_FULL_TABLE}, {"CREATE_OPTIONS", 255, MYSQL_TYPE_STRING, 0, 1, "Create_options", @@ -6080,8 +6099,10 @@ ST_FIELD_INFO columns_fields_info[]= 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY}, {"NUMERIC_SCALE", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG, 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY}, - {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY}, - {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY}, + {"CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 1, 0, + OPEN_FRM_ONLY}, + {"COLLATION_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 1, "Collation", + OPEN_FRM_ONLY}, {"COLUMN_TYPE", 65535, MYSQL_TYPE_STRING, 0, 0, "Type", OPEN_FRM_ONLY}, {"COLUMN_KEY", 3, MYSQL_TYPE_STRING, 0, 0, "Key", OPEN_FRM_ONLY}, {"EXTRA", 27, MYSQL_TYPE_STRING, 0, 0, "Extra", OPEN_FRM_ONLY}, @@ -6093,10 +6114,10 @@ ST_FIELD_INFO columns_fields_info[]= ST_FIELD_INFO charsets_fields_info[]= { - {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset", - SKIP_OPEN_TABLE}, - {"DEFAULT_COLLATE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Default collation", + {"CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "Charset", SKIP_OPEN_TABLE}, + {"DEFAULT_COLLATE_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, + "Default collation", SKIP_OPEN_TABLE}, {"DESCRIPTION", 60, MYSQL_TYPE_STRING, 0, 0, "Description", SKIP_OPEN_TABLE}, {"MAXLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Maxlen", SKIP_OPEN_TABLE}, @@ -6106,8 +6127,9 @@ ST_FIELD_INFO charsets_fields_info[]= ST_FIELD_INFO collation_fields_info[]= { - {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Collation", SKIP_OPEN_TABLE}, - {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset", + {"COLLATION_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "Collation", + SKIP_OPEN_TABLE}, + {"CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "Charset", SKIP_OPEN_TABLE}, {"ID", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE}, @@ -6170,8 +6192,10 @@ ST_FIELD_INFO events_fields_info[]= ST_FIELD_INFO coll_charset_app_fields_info[]= { - {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, - {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"COLLATION_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0, + SKIP_OPEN_TABLE}, + {"CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0, + SKIP_OPEN_TABLE}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; @@ -6200,7 +6224,7 @@ ST_FIELD_INFO proc_fields_info[]= SKIP_OPEN_TABLE}, {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, "Created", SKIP_OPEN_TABLE}, {"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, "Modified", SKIP_OPEN_TABLE}, - {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, + {"SQL_MODE", 32*256, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, {"ROUTINE_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Comment", SKIP_OPEN_TABLE}, {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE}, @@ -6449,7 +6473,7 @@ ST_FIELD_INFO variables_fields_info[]= { {"VARIABLE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Variable_name", SKIP_OPEN_TABLE}, - {"VARIABLE_VALUE", 20480, MYSQL_TYPE_STRING, 0, 1, "Value", SKIP_OPEN_TABLE}, + {"VARIABLE_VALUE", 1024, MYSQL_TYPE_STRING, 0, 1, "Value", SKIP_OPEN_TABLE}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; @@ -6608,9 +6632,9 @@ ST_SCHEMA_TABLE schema_tables[]= {"FILES", files_fields_info, create_schema_table, fill_schema_files, 0, 0, -1, -1, 0, 0}, {"GLOBAL_STATUS", variables_fields_info, create_schema_table, - fill_status, make_old_format, 0, -1, -1, 0, 0}, + fill_status, make_old_format, 0, 0, -1, 0, 0}, {"GLOBAL_VARIABLES", variables_fields_info, create_schema_table, - fill_variables, make_old_format, 0, -1, -1, 0, 0}, + fill_variables, make_old_format, 0, 0, -1, 0, 0}, {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table, get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0, OPEN_TABLE_ONLY}, @@ -6635,14 +6659,14 @@ ST_SCHEMA_TABLE schema_tables[]= {"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table, fill_schema_schema_privileges, 0, 0, -1, -1, 0, 0}, {"SESSION_STATUS", variables_fields_info, create_schema_table, - fill_status, make_old_format, 0, -1, -1, 0, 0}, + fill_status, make_old_format, 0, 0, -1, 0, 0}, {"SESSION_VARIABLES", variables_fields_info, create_schema_table, - fill_variables, make_old_format, 0, -1, -1, 0, 0}, + fill_variables, make_old_format, 0, 0, -1, 0, 0}, {"STATISTICS", stat_fields_info, create_schema_table, get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0, OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE}, {"STATUS", variables_fields_info, create_schema_table, fill_status, - make_old_format, 0, -1, -1, 1, 0}, + make_old_format, 0, 0, -1, 1, 0}, {"TABLES", tables_fields_info, create_schema_table, get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0, OPTIMIZE_I_S_TABLE}, @@ -6658,7 +6682,7 @@ ST_SCHEMA_TABLE schema_tables[]= {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table, fill_schema_user_privileges, 0, 0, -1, -1, 0, 0}, {"VARIABLES", variables_fields_info, create_schema_table, fill_variables, - make_old_format, 0, -1, -1, 1, 0}, + make_old_format, 0, 0, -1, 1, 0}, {"VIEWS", view_fields_info, create_schema_table, get_all_tables, 0, get_schema_views_record, 1, 2, 0, OPEN_VIEW_ONLY|OPTIMIZE_I_S_TABLE}, diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 20721a809cb..3b2142060a3 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4293,6 +4293,12 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, goto send_result; } + if (table->schema_table) + { + result_code= HA_ADMIN_NOT_IMPLEMENTED; + goto send_result; + } + if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify) { /* purecov: begin inspected */ diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 32389bde44c..5c8b1d96646 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -682,7 +682,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, trigname.trigger_table.length= tables->table_name_length; if (sql_create_definition_file(NULL, &trigname_file, &trigname_file_type, - (uchar*)&trigname, trigname_file_parameters, 0)) + (uchar*)&trigname, trigname_file_parameters)) return 1; /* @@ -800,7 +800,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, /* Create trigger definition file. */ if (!sql_create_definition_file(NULL, &file, &triggers_file_type, - (uchar*)this, triggers_file_parameters, 0)) + (uchar*)this, triggers_file_parameters)) return 0; err_with_cleanup: @@ -876,8 +876,7 @@ static bool save_trigger_file(Table_triggers_list *triggers, const char *db, TRG_EXT, 0); file.str= file_buff; return sql_create_definition_file(NULL, &file, &triggers_file_type, - (uchar*)triggers, triggers_file_parameters, - 0); + (uchar*)triggers, triggers_file_parameters); } @@ -1806,8 +1805,7 @@ Table_triggers_list::change_table_name_in_trignames(const char *db_name, trigname.trigger_table= *new_table_name; if (sql_create_definition_file(NULL, &trigname_file, &trigname_file_type, - (uchar*)&trigname, trigname_file_parameters, - 0)) + (uchar*)&trigname, trigname_file_parameters)) return trigger; } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index ff47f5e4cd7..f448fb7ab50 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -715,6 +715,11 @@ int mysql_update(THD *thd, else table->file->unlock_row(); thd->row_count++; + if (thd->is_error()) + { + error= 1; + break; + } } dup_key_found= 0; /* @@ -1470,6 +1475,32 @@ multi_update::initialize_tables(JOIN *join) } table->prepare_for_position(); + /* + enable uncacheable flag if we update a view with check option + and check option has a subselect, otherwise, the check option + can be evaluated after the subselect was freed as independent + (See full_local in JOIN::join_free()). + */ + if (table_ref->check_option && !join->select_lex->uncacheable) + { + SELECT_LEX_UNIT *tmp_unit; + SELECT_LEX *sl; + for (tmp_unit= join->select_lex->first_inner_unit(); + tmp_unit; + tmp_unit= tmp_unit->next_unit()) + { + for (sl= tmp_unit->first_select(); sl; sl= sl->next_select()) + { + if (sl->master_unit()->item) + { + join->select_lex->uncacheable|= UNCACHEABLE_CHECKOPTION; + goto loop_end; + } + } + } + } +loop_end: + if (table == first_table_for_update && table_ref->check_option) { table_map unupdated_tables= table_ref->check_option->used_tables() & diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 83e8d5907cf..be66f7c2d80 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -655,7 +655,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, } VOID(pthread_mutex_unlock(&LOCK_open)); - if (view->revision != 1) + if (mode != VIEW_CREATE_NEW) query_cache_invalidate3(thd, view, 0); start_waiting_global_read_lock(thd); if (res) @@ -673,12 +673,8 @@ err: } -/* index of revision number in following table */ -static const int revision_number_position= 8; /* number of required parameters for making view */ -static const int required_view_parameters= 16; -/* number of backups */ -static const int num_view_backups= 3; +static const int required_view_parameters= 14; /* table of VIEW .frm field descriptors @@ -711,9 +707,6 @@ static File_option view_parameters[]= {{ C_STRING_WITH_LEN("with_check_option")}, my_offsetof(TABLE_LIST, with_check), FILE_OPTIONS_ULONGLONG}, - {{ C_STRING_WITH_LEN("revision")}, - my_offsetof(TABLE_LIST, revision), - FILE_OPTIONS_REV}, {{ C_STRING_WITH_LEN("timestamp")}, my_offsetof(TABLE_LIST, timestamp), FILE_OPTIONS_TIMESTAMP}, @@ -921,18 +914,9 @@ loop_out: } /* - read revision number - TODO: read dependence list, too, to process cascade/restrict TODO: special cascade/restrict procedure for alter? */ - if (parser->parse((uchar*)view, thd->mem_root, - view_parameters + revision_number_position, 1, - &file_parser_dummy_hook)) - { - error= thd->is_error() ? -1 : 0; - goto err; - } } else { @@ -997,7 +981,7 @@ loop_out: } if (sql_create_definition_file(&dir, &file, view_file_type, - (uchar*)view, view_parameters, num_view_backups)) + (uchar*)view, view_parameters)) { error= thd->is_error() ? -1 : 1; goto err; @@ -1065,8 +1049,9 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, if (table->index_hints && table->index_hints->elements) { - my_error(ER_WRONG_USAGE, MYF(0), "index hints", "VIEW"); - DBUG_RETURN(TRUE); + my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), + table->index_hints->head()->key_name.str, table->table_name); + DBUG_RETURN(TRUE); } /* check loop via view definition */ @@ -1963,8 +1948,7 @@ mysql_rename_view(THD *thd, goto err; /* rename view and it's backups */ - if (rename_in_schema_file(thd, view->db, view->table_name, new_name, - view_def.revision - 1, num_view_backups)) + if (rename_in_schema_file(thd, view->db, view->table_name, new_name)) goto err; dir.str= dir_buff; @@ -1979,12 +1963,10 @@ mysql_rename_view(THD *thd, file.length= pathstr.length - dir.length; if (sql_create_definition_file(&dir, &file, view_file_type, - (uchar*)&view_def, view_parameters, - num_view_backups)) + (uchar*)&view_def, view_parameters)) { /* restore renamed view in case of error */ - rename_in_schema_file(thd, view->db, new_name, view->table_name, - view_def.revision - 1, num_view_backups); + rename_in_schema_file(thd, view->db, new_name, view->table_name); goto err; } } else diff --git a/sql/table.h b/sql/table.h index 38a66f9f426..91747fd23e8 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1244,7 +1244,6 @@ struct TABLE_LIST st_lex_user definer; /* definer of view */ ulonglong file_version; /* version of file's field set */ ulonglong updatable_view; /* VIEW can be updated */ - ulonglong revision; /* revision control number */ /** @brief The declared algorithm, if this is a view. @details One of diff --git a/sql/tztime.cc b/sql/tztime.cc index 1028cfb7c1b..53870915973 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1072,6 +1072,7 @@ Time_zone_system::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const localtime_r(&tmp_t, &tmp_tm); localtime_to_TIME(tmp, &tmp_tm); tmp->time_type= MYSQL_TIMESTAMP_DATETIME; + adjust_leap_second(tmp); } @@ -1156,6 +1157,7 @@ Time_zone_utc::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const gmtime_r(&tmp_t, &tmp_tm); localtime_to_TIME(tmp, &tmp_tm); tmp->time_type= MYSQL_TIMESTAMP_DATETIME; + adjust_leap_second(tmp); } @@ -1259,6 +1261,7 @@ void Time_zone_db::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const { ::gmt_sec_to_TIME(tmp, t, tz_info); + adjust_leap_second(tmp); } @@ -2279,6 +2282,24 @@ my_tz_find(THD *thd, const String *name) } +/** + Convert leap seconds into non-leap + + This function will convert the leap seconds added by the OS to + non-leap seconds, e.g. 23:59:59, 23:59:60 -> 23:59:59, 00:00:01 ... + This check is not checking for years on purpose : although it's not a + complete check this way it doesn't require looking (and having installed) + the leap seconds table. + + @param[in,out] broken down time structure as filled in by the OS +*/ + +void Time_zone::adjust_leap_second(MYSQL_TIME *t) +{ + if (t->second == 60 || t->second == 61) + t->second= 59; +} + #endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */ diff --git a/sql/tztime.h b/sql/tztime.h index 3d77a3eefa3..9bf103519c4 100644 --- a/sql/tztime.h +++ b/sql/tztime.h @@ -55,6 +55,9 @@ public: allocated on MEM_ROOT and should not require destruction. */ virtual ~Time_zone() {}; + +protected: + static inline void adjust_leap_second(MYSQL_TIME *t); }; extern Time_zone * my_tz_UTC; |