diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/contributors.h | 2 | ||||
-rw-r--r-- | sql/field.cc | 1 | ||||
-rw-r--r-- | sql/field.h | 28 | ||||
-rw-r--r-- | sql/handler.cc | 95 | ||||
-rw-r--r-- | sql/handler.h | 3 | ||||
-rw-r--r-- | sql/item.cc | 17 | ||||
-rw-r--r-- | sql/item_geofunc.cc | 5 | ||||
-rw-r--r-- | sql/item_subselect.cc | 58 | ||||
-rw-r--r-- | sql/item_subselect.h | 34 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 6 | ||||
-rw-r--r-- | sql/lex.h | 3 | ||||
-rw-r--r-- | sql/log.cc | 2 | ||||
-rw-r--r-- | sql/log.h | 4 | ||||
-rw-r--r-- | sql/log_event.cc | 63 | ||||
-rw-r--r-- | sql/log_event_old.cc | 52 | ||||
-rw-r--r-- | sql/opt_range.cc | 2 | ||||
-rw-r--r-- | sql/slave.cc | 11 | ||||
-rw-r--r-- | sql/slave.h | 4 | ||||
-rw-r--r-- | sql/sp_head.cc | 10 | ||||
-rw-r--r-- | sql/sql_acl.cc | 12 | ||||
-rw-r--r-- | sql/sql_help.cc | 11 | ||||
-rw-r--r-- | sql/sql_lex.cc | 29 | ||||
-rw-r--r-- | sql/sql_locale.h | 2 | ||||
-rw-r--r-- | sql/sql_plugin.h | 2 | ||||
-rw-r--r-- | sql/sql_reload.cc | 3 | ||||
-rw-r--r-- | sql/sql_select.cc | 6 | ||||
-rw-r--r-- | sql/sql_show.cc | 24 | ||||
-rw-r--r-- | sql/sql_statistics.cc | 9 | ||||
-rw-r--r-- | sql/sql_update.cc | 2 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 103 | ||||
-rw-r--r-- | sql/table.cc | 34 | ||||
-rw-r--r-- | sql/threadpool_unix.cc | 6 | ||||
-rw-r--r-- | sql/winservice.c | 13 |
33 files changed, 441 insertions, 215 deletions
diff --git a/sql/contributors.h b/sql/contributors.h index 04f8b74aa65..76674d654e5 100644 --- a/sql/contributors.h +++ b/sql/contributors.h @@ -46,7 +46,7 @@ struct show_table_contributors_st show_table_contributors[]= { /* Smaller sponsors, newer per year */ {"Verkkokauppa.com", "Finland", "Sponsor of the MariaDB Foundation"}, - {"Webyog", "Bangalore", "Sponsor of the MariaDB Foundation"}, + {"Virtuozzo", "https://virtuozzo.com/", "Sponsor of the MariaDB Foundation"}, /* Sponsors of important features */ {"Google", "USA", "Sponsoring encryption, parallel replication and GTID"}, diff --git a/sql/field.cc b/sql/field.cc index a7c655087c7..ae815187019 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2038,6 +2038,7 @@ Field_str::Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, if (charset_arg->state & MY_CS_BINSORT) flags|=BINARY_FLAG; field_derivation= DERIVATION_IMPLICIT; + field_repertoire= my_charset_repertoire(charset_arg); } diff --git a/sql/field.h b/sql/field.h index ca13fa9b9c2..30f24ecc1bb 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1215,11 +1215,12 @@ public: { return binary() ? &my_charset_bin : charset(); } virtual CHARSET_INFO *sort_charset(void) const { return charset(); } virtual bool has_charset(void) const { return FALSE; } - virtual void set_charset(CHARSET_INFO *charset_arg) { } virtual enum Derivation derivation(void) const { return DERIVATION_IMPLICIT; } virtual uint repertoire(void) const { return MY_REPERTOIRE_UNICODE30; } - virtual void set_derivation(enum Derivation derivation_arg) { } + virtual void set_derivation(enum Derivation derivation_arg, + uint repertoire_arg) + { } virtual int set_time() { return 1; } bool set_warning(Sql_condition::enum_warning_level, unsigned int code, int cuted_increment) const; @@ -1537,8 +1538,10 @@ public: class Field_str :public Field { protected: + // TODO-10.2: Reuse DTCollation instead of these three members CHARSET_INFO *field_charset; enum Derivation field_derivation; + uint field_repertoire; public: bool can_be_substituted_to_equal_item(const Context &ctx, const Item_equal *item_equal); @@ -1551,15 +1554,15 @@ public: int store(longlong nr, bool unsigned_val)=0; int store_decimal(const my_decimal *); int store(const char *to,uint length,CHARSET_INFO *cs)=0; - uint repertoire(void) const - { - return my_charset_repertoire(field_charset); - } + uint repertoire(void) const { return field_repertoire; } CHARSET_INFO *charset(void) const { return field_charset; } - void set_charset(CHARSET_INFO *charset_arg) { field_charset= charset_arg; } enum Derivation derivation(void) const { return field_derivation; } - virtual void set_derivation(enum Derivation derivation_arg) - { field_derivation= derivation_arg; } + void set_derivation(enum Derivation derivation_arg, + uint repertoire_arg) + { + field_derivation= derivation_arg; + field_repertoire= repertoire_arg; + } bool binary() const { return field_charset == &my_charset_bin; } uint32 max_display_length() { return field_length; } friend class Create_field; @@ -2992,10 +2995,9 @@ public: packlength= 4; if (set_packlength) { - uint32 l_char_length= len_arg/cs->mbmaxlen; - packlength= l_char_length <= 255 ? 1 : - l_char_length <= 65535 ? 2 : - l_char_length <= 16777215 ? 3 : 4; + packlength= len_arg <= 255 ? 1 : + len_arg <= 65535 ? 2 : + len_arg <= 16777215 ? 3 : 4; } } Field_blob(uint32 packlength_arg) diff --git a/sql/handler.cc b/sql/handler.cc index 147221abb97..947ca005cdb 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -6333,3 +6333,98 @@ bool HA_CREATE_INFO::check_conflicting_charset_declarations(CHARSET_INFO *cs) } return false; } + +/* Remove all indexes for a given table from global index statistics */ + +static +int del_global_index_stats_for_table(THD *thd, uchar* cache_key, uint cache_key_length) +{ + int res = 0; + DBUG_ENTER("del_global_index_stats_for_table"); + + mysql_mutex_lock(&LOCK_global_index_stats); + + for (uint i= 0; i < global_index_stats.records;) + { + INDEX_STATS *index_stats = + (INDEX_STATS*) my_hash_element(&global_index_stats, i); + + /* We search correct db\0table_name\0 string */ + if (index_stats && + index_stats->index_name_length >= cache_key_length && + !memcmp(index_stats->index, cache_key, cache_key_length)) + { + res= my_hash_delete(&global_index_stats, (uchar*)index_stats); + /* + In our HASH implementation on deletion one elements + is moved into a place where a deleted element was, + and the last element is moved into the empty space. + Thus we need to re-examine the current element, but + we don't have to restart the search from the beginning. + */ + } + else + i++; + } + + mysql_mutex_unlock(&LOCK_global_index_stats); + DBUG_RETURN(res); +} + +/* Remove a table from global table statistics */ + +int del_global_table_stat(THD *thd, LEX_STRING *db, LEX_STRING *table) +{ + TABLE_STATS *table_stats; + int res = 0; + uchar *cache_key; + uint cache_key_length; + DBUG_ENTER("del_global_table_stat"); + + cache_key_length= db->length + 1 + table->length + 1; + + if(!(cache_key= (uchar *)my_malloc(cache_key_length, + MYF(MY_WME | MY_ZEROFILL)))) + { + /* Out of memory error already given */ + res = 1; + goto end; + } + + memcpy(cache_key, db->str, db->length); + memcpy(cache_key + db->length + 1, table->str, table->length); + + res= del_global_index_stats_for_table(thd, cache_key, cache_key_length); + + mysql_mutex_lock(&LOCK_global_table_stats); + + if((table_stats= (TABLE_STATS*) my_hash_search(&global_table_stats, + cache_key, + cache_key_length))) + res= my_hash_delete(&global_table_stats, (uchar*)table_stats); + + my_free(cache_key); + mysql_mutex_unlock(&LOCK_global_table_stats); + +end: + DBUG_RETURN(res); +} + +/* Remove a index from global index statistics */ + +int del_global_index_stat(THD *thd, TABLE* table, KEY* key_info) +{ + INDEX_STATS *index_stats; + uint key_length= table->s->table_cache_key.length + key_info->name_length + 1; + int res = 0; + DBUG_ENTER("del_global_index_stat"); + mysql_mutex_lock(&LOCK_global_index_stats); + + if((index_stats= (INDEX_STATS*) my_hash_search(&global_index_stats, + key_info->cache_name, + key_length))) + res= my_hash_delete(&global_index_stats, (uchar*)index_stats); + + mysql_mutex_unlock(&LOCK_global_index_stats); + DBUG_RETURN(res); +} diff --git a/sql/handler.h b/sql/handler.h index 3ffe4d03596..9b9480556e3 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -4286,4 +4286,7 @@ inline const char *table_case_name(HA_CREATE_INFO *info, const char *name) void print_keydup_error(TABLE *table, KEY *key, const char *msg, myf errflag); void print_keydup_error(TABLE *table, KEY *key, myf errflag); + +int del_global_index_stat(THD *thd, TABLE* table, KEY* key_info); +int del_global_table_stat(THD *thd, LEX_STRING *db, LEX_STRING *table); #endif /* HANDLER_INCLUDED */ diff --git a/sql/item.cc b/sql/item.cc index adf70312b37..71df93f3ffc 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -186,9 +186,6 @@ bool Item::get_time_with_conversion(THD *thd, MYSQL_TIME *ltime, */ String *Item::val_str_ascii(String *str) { - if (!(collation.collation->state & MY_CS_NONASCII)) - return val_str(str); - DBUG_ASSERT(str != &str_value); uint errors; @@ -196,11 +193,15 @@ String *Item::val_str_ascii(String *str) if (!res) return 0; - if ((null_value= str->copy(res->ptr(), res->length(), - collation.collation, &my_charset_latin1, - &errors))) - return 0; - + if (!(res->charset()->state & MY_CS_NONASCII)) + str= res; + else + { + if ((null_value= str->copy(res->ptr(), res->length(), collation.collation, + &my_charset_latin1, &errors))) + return 0; + } + return str; } diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index a515f292975..76e4a85e865 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -1,6 +1,5 @@ -/* - Copyright (c) 2003-2007 MySQL AB, 2009, 2010 Sun Microsystems, Inc. - Use is subject to license terms. +/* Copyright (c) 2003, 2016, Oracle and/or its affiliates. + Copyright (c) 2011, 2016, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 1812110b1e6..301856ea3b8 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -84,7 +84,6 @@ void Item_subselect::init(st_select_lex *select_lex, DBUG_PRINT("enter", ("select_lex: 0x%lx this: 0x%lx", (ulong) select_lex, (ulong) this)); unit= select_lex->master_unit(); - thd= unit->thd; if (unit->item) { @@ -103,7 +102,7 @@ void Item_subselect::init(st_select_lex *select_lex, Item can be changed in JOIN::prepare while engine in JOIN::optimize => we do not copy old_engine here */ - thd->change_item_tree((Item**)&unit->item, this); + unit->thd->change_item_tree((Item**)&unit->item, this); engine->change_result(this, result, TRUE); } } @@ -118,9 +117,9 @@ void Item_subselect::init(st_select_lex *select_lex, NO_MATTER : outer_select->parsing_place); if (unit->is_union()) - engine= new subselect_union_engine(thd, unit, result, this); + engine= new subselect_union_engine(unit, result, this); else - engine= new subselect_single_select_engine(thd, select_lex, result, this); + engine= new subselect_single_select_engine(select_lex, result, this); } { SELECT_LEX *upper= unit->outer_select(); @@ -234,6 +233,10 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) uint8 uncacheable; bool res; + thd= thd_param; + + DBUG_ASSERT(unit->thd == thd); + status_var_increment(thd_param->status_var.feature_subquery); DBUG_ASSERT(fixed == 0); @@ -256,7 +259,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) return TRUE; - if (!(res= engine->prepare())) + if (!(res= engine->prepare(thd))) { // all transformation is done (used by prepared statements) changed= 1; @@ -3168,9 +3171,12 @@ bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref) { uint outer_cols_num; List<Item> *inner_cols; - char const *save_where= thd->where; + char const *save_where= thd_arg->where; DBUG_ENTER("Item_in_subselect::fix_fields"); + thd= thd_arg; + DBUG_ASSERT(unit->thd == thd); + if (test_strategy(SUBS_SEMI_JOIN)) DBUG_RETURN( !( (*ref)= new (thd->mem_root) Item_int(thd, 1)) ); @@ -3287,7 +3293,8 @@ bool Item_in_subselect::setup_mat_engine() if (!(mat_engine= new subselect_hash_sj_engine(thd, this, select_engine))) DBUG_RETURN(TRUE); - if (mat_engine->init(&select_engine->join->fields_list, + if (mat_engine->prepare(thd) || + mat_engine->init(&select_engine->join->fields_list, engine->get_identifier())) DBUG_RETURN(TRUE); @@ -3404,10 +3411,10 @@ void subselect_engine::set_thd(THD *thd_arg) subselect_single_select_engine:: -subselect_single_select_engine(THD *thd_arg, st_select_lex *select, +subselect_single_select_engine(st_select_lex *select, select_result_interceptor *result_arg, Item_subselect *item_arg) - :subselect_engine(thd_arg, item_arg, result_arg), + :subselect_engine(item_arg, result_arg), prepared(0), executed(0), select_lex(select), join(0) { @@ -3488,10 +3495,10 @@ void subselect_uniquesubquery_engine::cleanup() } -subselect_union_engine::subselect_union_engine(THD *thd_arg, st_select_lex_unit *u, +subselect_union_engine::subselect_union_engine(st_select_lex_unit *u, select_result_interceptor *result_arg, Item_subselect *item_arg) - :subselect_engine(thd_arg, item_arg, result_arg) + :subselect_engine(item_arg, result_arg) { unit= u; unit->item= item_arg; @@ -3524,10 +3531,11 @@ subselect_union_engine::subselect_union_engine(THD *thd_arg, st_select_lex_unit @retval 1 if error */ -int subselect_single_select_engine::prepare() +int subselect_single_select_engine::prepare(THD *thd) { if (prepared) return 0; + set_thd(thd); if (select_lex->join) { select_lex->cleanup(); @@ -3556,12 +3564,13 @@ int subselect_single_select_engine::prepare() return 0; } -int subselect_union_engine::prepare() +int subselect_union_engine::prepare(THD *thd_arg) { + set_thd(thd_arg); return unit->prepare(thd, result, SELECT_NO_UNLOCK); } -int subselect_uniquesubquery_engine::prepare() +int subselect_uniquesubquery_engine::prepare(THD *) { /* Should never be called. */ DBUG_ASSERT(FALSE); @@ -5026,13 +5035,14 @@ subselect_hash_sj_engine::~subselect_hash_sj_engine() } -int subselect_hash_sj_engine::prepare() +int subselect_hash_sj_engine::prepare(THD *thd_arg) { /* Create and optimize the JOIN that will be used to materialize the subquery if not yet created. */ - return materialize_engine->prepare(); + set_thd(thd_arg); + return materialize_engine->prepare(thd); } @@ -5407,7 +5417,7 @@ int subselect_hash_sj_engine::exec() if (strategy == PARTIAL_MATCH_MERGE) { pm_engine= - new subselect_rowid_merge_engine(thd, (subselect_uniquesubquery_engine*) + new subselect_rowid_merge_engine((subselect_uniquesubquery_engine*) lookup_engine, tmp_table, count_pm_keys, has_covering_null_row, @@ -5416,6 +5426,7 @@ int subselect_hash_sj_engine::exec() item, result, semi_join_conds->argument_list()); if (!pm_engine || + pm_engine->prepare(thd) || ((subselect_rowid_merge_engine*) pm_engine)-> init(nn_key_parts, &partial_match_key_parts)) { @@ -5433,13 +5444,14 @@ int subselect_hash_sj_engine::exec() if (strategy == PARTIAL_MATCH_SCAN) { if (!(pm_engine= - new subselect_table_scan_engine(thd, (subselect_uniquesubquery_engine*) + new subselect_table_scan_engine((subselect_uniquesubquery_engine*) lookup_engine, tmp_table, item, result, semi_join_conds->argument_list(), has_covering_null_row, has_covering_null_columns, - count_columns_with_nulls))) + count_columns_with_nulls)) || + pm_engine->prepare(thd)) { /* This is an irrecoverable error. */ res= 1; @@ -5888,14 +5900,14 @@ void Ordered_key::print(String *str) subselect_partial_match_engine::subselect_partial_match_engine( - THD *thd_arg, subselect_uniquesubquery_engine *engine_arg, + subselect_uniquesubquery_engine *engine_arg, TABLE *tmp_table_arg, Item_subselect *item_arg, select_result_interceptor *result_arg, List<Item> *equi_join_conds_arg, bool has_covering_null_row_arg, bool has_covering_null_columns_arg, uint count_columns_with_nulls_arg) - :subselect_engine(thd_arg, item_arg, result_arg), + :subselect_engine(item_arg, result_arg), tmp_table(tmp_table_arg), lookup_engine(engine_arg), equi_join_conds(equi_join_conds_arg), has_covering_null_row(has_covering_null_row_arg), @@ -6508,7 +6520,7 @@ end: subselect_table_scan_engine::subselect_table_scan_engine( - THD *thd_arg, subselect_uniquesubquery_engine *engine_arg, + subselect_uniquesubquery_engine *engine_arg, TABLE *tmp_table_arg, Item_subselect *item_arg, select_result_interceptor *result_arg, @@ -6516,7 +6528,7 @@ subselect_table_scan_engine::subselect_table_scan_engine( bool has_covering_null_row_arg, bool has_covering_null_columns_arg, uint count_columns_with_nulls_arg) - :subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg, item_arg, + :subselect_partial_match_engine(engine_arg, tmp_table_arg, item_arg, result_arg, equi_join_conds_arg, has_covering_null_row_arg, has_covering_null_columns_arg, diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 670d0a66639..54848c4ebf7 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -750,7 +750,7 @@ public: INDEXSUBQUERY_ENGINE, HASH_SJ_ENGINE, ROWID_MERGE_ENGINE, TABLE_SCAN_ENGINE}; - subselect_engine(THD *thd_arg, Item_subselect *si, + subselect_engine(Item_subselect *si, select_result_interceptor *res) { result= res; @@ -758,7 +758,6 @@ public: cmp_type= res_type= STRING_RESULT; res_field_type= MYSQL_TYPE_VAR_STRING; maybe_null= 0; - set_thd(thd_arg); } virtual ~subselect_engine() {}; // to satisfy compiler virtual void cleanup()= 0; @@ -769,7 +768,7 @@ public: */ void set_thd(THD *thd_arg); THD * get_thd() { return thd; } - virtual int prepare()= 0; + virtual int prepare(THD *)= 0; virtual void fix_length_and_dec(Item_cache** row)= 0; /* Execute the engine @@ -824,11 +823,11 @@ class subselect_single_select_engine: public subselect_engine st_select_lex *select_lex; /* corresponding select_lex */ JOIN * join; /* corresponding JOIN structure */ public: - subselect_single_select_engine(THD *thd_arg, st_select_lex *select, + subselect_single_select_engine(st_select_lex *select, select_result_interceptor *result, Item_subselect *item); void cleanup(); - int prepare(); + int prepare(THD *thd); void fix_length_and_dec(Item_cache** row); int exec(); uint cols(); @@ -858,11 +857,11 @@ class subselect_union_engine: public subselect_engine { st_select_lex_unit *unit; /* corresponding unit structure */ public: - subselect_union_engine(THD *thd_arg, st_select_lex_unit *u, + subselect_union_engine(st_select_lex_unit *u, select_result_interceptor *result, Item_subselect *item); void cleanup(); - int prepare(); + int prepare(THD *); void fix_length_and_dec(Item_cache** row); int exec(); uint cols(); @@ -915,11 +914,11 @@ public: // constructor can assign THD because it will be called after JOIN::prepare subselect_uniquesubquery_engine(THD *thd_arg, st_join_table *tab_arg, Item_subselect *subs, Item *where) - :subselect_engine(thd_arg, subs, 0), tab(tab_arg), cond(where) + :subselect_engine(subs, 0), tab(tab_arg), cond(where) {} ~subselect_uniquesubquery_engine(); void cleanup(); - int prepare(); + int prepare(THD *); void fix_length_and_dec(Item_cache** row); int exec(); uint cols() { return 1; } @@ -1047,7 +1046,7 @@ public: subselect_hash_sj_engine(THD *thd_arg, Item_subselect *in_predicate, subselect_single_select_engine *old_engine) - : subselect_engine(thd_arg, in_predicate, NULL), + : subselect_engine(in_predicate, NULL), tmp_table(NULL), is_materialized(FALSE), materialize_engine(old_engine), materialize_join(NULL), semi_join_conds(NULL), lookup_engine(NULL), count_partial_match_columns(0), count_null_only_columns(0), @@ -1057,7 +1056,7 @@ public: bool init(List<Item> *tmp_columns, uint subquery_id); void cleanup(); - int prepare(); + int prepare(THD *); int exec(); virtual void print(String *str, enum_query_type query_type); uint cols() @@ -1336,15 +1335,14 @@ protected: protected: virtual bool partial_match()= 0; public: - subselect_partial_match_engine(THD *thd_arg, - subselect_uniquesubquery_engine *engine_arg, + subselect_partial_match_engine(subselect_uniquesubquery_engine *engine_arg, TABLE *tmp_table_arg, Item_subselect *item_arg, select_result_interceptor *result_arg, List<Item> *equi_join_conds_arg, bool has_covering_null_row_arg, bool has_covering_null_columns_arg, uint count_columns_with_nulls_arg); - int prepare() { return 0; } + int prepare(THD *thd_arg) { set_thd(thd_arg); return 0; } int exec(); void fix_length_and_dec(Item_cache**) {} uint cols() { /* TODO: what is the correct value? */ return 1; } @@ -1431,8 +1429,7 @@ protected: bool exists_complementing_null_row(MY_BITMAP *keys_to_complement); bool partial_match(); public: - subselect_rowid_merge_engine(THD *thd_arg, - subselect_uniquesubquery_engine *engine_arg, + subselect_rowid_merge_engine(subselect_uniquesubquery_engine *engine_arg, TABLE *tmp_table_arg, uint merge_keys_count_arg, bool has_covering_null_row_arg, bool has_covering_null_columns_arg, @@ -1440,7 +1437,7 @@ public: Item_subselect *item_arg, select_result_interceptor *result_arg, List<Item> *equi_join_conds_arg) - :subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg, + :subselect_partial_match_engine(engine_arg, tmp_table_arg, item_arg, result_arg, equi_join_conds_arg, has_covering_null_row_arg, has_covering_null_columns_arg, @@ -1459,8 +1456,7 @@ class subselect_table_scan_engine: public subselect_partial_match_engine protected: bool partial_match(); public: - subselect_table_scan_engine(THD *thd_arg, - subselect_uniquesubquery_engine *engine_arg, + subselect_table_scan_engine(subselect_uniquesubquery_engine *engine_arg, TABLE *tmp_table_arg, Item_subselect *item_arg, select_result_interceptor *result_arg, List<Item> *equi_join_conds_arg, diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 991dde632e2..398b618fb73 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -939,9 +939,8 @@ void Item_func_monthname::fix_length_and_dec() { THD* thd= current_thd; CHARSET_INFO *cs= thd->variables.collation_connection; - uint32 repertoire= my_charset_repertoire(cs); locale= thd->variables.lc_time_names; - collation.set(cs, DERIVATION_COERCIBLE, repertoire); + collation.set(cs, DERIVATION_COERCIBLE, locale->repertoire()); decimals=0; max_length= locale->max_month_name_length * collation.collation->mbmaxlen; maybe_null=1; @@ -1086,9 +1085,8 @@ void Item_func_dayname::fix_length_and_dec() { THD* thd= current_thd; CHARSET_INFO *cs= thd->variables.collation_connection; - uint32 repertoire= my_charset_repertoire(cs); locale= thd->variables.lc_time_names; - collation.set(cs, DERIVATION_COERCIBLE, repertoire); + collation.set(cs, DERIVATION_COERCIBLE, locale->repertoire()); decimals=0; max_length= locale->max_day_name_length * collation.collation->mbmaxlen; maybe_null=1; diff --git a/sql/lex.h b/sql/lex.h index 22ff4e6d360..85bd20a5f37 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -47,12 +47,9 @@ SYM_GROUP sym_group_rtree= {"RTree keys", "HAVE_RTREE_KEYS"}; static SYMBOL symbols[] = { { "&&", SYM(AND_AND_SYM)}, - { "<", SYM(LT)}, { "<=", SYM(LE)}, { "<>", SYM(NE)}, { "!=", SYM(NE)}, - { "=", SYM(EQ)}, - { ">", SYM(GT_SYM)}, { ">=", SYM(GE)}, { "<<", SYM(SHIFT_LEFT)}, { ">>", SYM(SHIFT_RIGHT)}, diff --git a/sql/log.cc b/sql/log.cc index a938dcbc9f8..bf8695e06da 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. Copyright (c) 2009, 2016, MariaDB This program is free software; you can redistribute it and/or modify diff --git a/sql/log.h b/sql/log.h index 9bf80d6e603..cdb2b9ce4b7 100644 --- a/sql/log.h +++ b/sql/log.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2005, 2012, Oracle and/or its affiliates. - Copyright (c) 2009, 2012, Monty Program Ab +/* Copyright (c) 2005, 2016, Oracle and/or its affiliates. + Copyright (c) 2009, 2016, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/sql/log_event.cc b/sql/log_event.cc index ea0afddafbe..afa58afc21d 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. Copyright (c) 2009, 2016, MariaDB This program is free software; you can redistribute it and/or modify @@ -3743,10 +3743,25 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, if (time_zone_len) copy_str_and_move(&time_zone_str, &start, time_zone_len); - if (user.length > 0) + if (user.length) + { copy_str_and_move((const char **)&(user.str), &start, user.length); - if (host.length > 0) + } + else + { + user.str= (char *) start++; + user.str[0]= '\0'; + } + + if (host.length) + { copy_str_and_move((const char **)&(host.str), &start, host.length); + } + else + { + host.str= (char *) start++; + host.str[0]= '\0'; + } /** if time_zone_len or catalog_len are 0, then time_zone and catalog @@ -9824,9 +9839,6 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) /* When the open and locking succeeded, we check all tables to ensure that they still have the correct type. - - We can use a down cast here since we know that every table added - to the tables_to_lock is a RPL_TABLE_LIST. */ { @@ -9845,10 +9857,37 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) NOTE: The base tables are added here are removed when close_thread_tables is called. */ - RPL_TABLE_LIST *ptr= rgi->tables_to_lock; - for (uint i= 0 ; ptr && (i < rgi->tables_to_lock_count); - ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global), i++) + TABLE_LIST *table_list_ptr= rgi->tables_to_lock; + for (uint i=0 ; table_list_ptr && (i < rgi->tables_to_lock_count); + table_list_ptr= table_list_ptr->next_global, i++) { + /* + Below if condition takes care of skipping base tables that + make up the MERGE table (which are added by open_tables() + call). They are added next to the merge table in the list. + For eg: If RPL_TABLE_LIST is t3->t1->t2 (where t1 and t2 + are base tables for merge table 't3'), open_tables will modify + the list by adding t1 and t2 again immediately after t3 in the + list (*not at the end of the list*). New table_to_lock list will + look like t3->t1'->t2'->t1->t2 (where t1' and t2' are TABLE_LIST + objects added by open_tables() call). There is no flag(or logic) in + open_tables() that can skip adding these base tables to the list. + So the logic here should take care of skipping them. + + tables_to_lock_count logic will take care of skipping base tables + that are added at the end of the list. + For eg: If RPL_TABLE_LIST is t1->t2->t3, open_tables will modify + the list into t1->t2->t3->t1'->t2'. t1' and t2' will be skipped + because tables_to_lock_count logic in this for loop. + */ + if (table_list_ptr->parent_l) + continue; + /* + We can use a down cast here since we know that every table added + to the tables_to_lock is a RPL_TABLE_LIST (or child table which is + skipped above). + */ + RPL_TABLE_LIST *ptr= static_cast<RPL_TABLE_LIST*>(table_list_ptr); DBUG_ASSERT(ptr->m_tabledef_valid); TABLE *conv_table; if (!ptr->m_tabledef.compatible_with(thd, rgi, ptr->table, &conv_table)) @@ -9890,6 +9929,12 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) TABLE_LIST *ptr= rgi->tables_to_lock; for (uint i=0 ; ptr && (i < rgi->tables_to_lock_count); ptr= ptr->next_global, i++) { + /* + Please see comment in above 'for' loop to know the reason + for this if condition + */ + if (ptr->parent_l) + continue; rgi->m_table_map.set_table(ptr->table_id, ptr->table); /* Following is passing flag about triggers on the server. The problem was diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index ff2f7b156d5..0502f20d2b1 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2007, 2013, Oracle and/or its affiliates. +/* Copyright (c) 2007, 2016, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -120,16 +120,25 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, rpl_group_info *rgi) /* When the open and locking succeeded, we check all tables to ensure that they still have the correct type. - - We can use a down cast here since we know that every table added - to the tables_to_lock is a RPL_TABLE_LIST. */ { - RPL_TABLE_LIST *ptr= rgi->tables_to_lock; - for (uint i= 0 ; ptr&& (i< rgi->tables_to_lock_count); - ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global), i++) + TABLE_LIST *table_list_ptr= rgi->tables_to_lock; + for (uint i=0 ; table_list_ptr&& (i< rgi->tables_to_lock_count); + table_list_ptr= table_list_ptr->next_global, i++) { + /* + Please see comment in log_event.cc-Rows_log_event::do_apply_event() + function for the explanation of the below if condition + */ + if (table_list_ptr->parent_l) + continue; + /* + We can use a down cast here since we know that every table added + to the tables_to_lock is a RPL_TABLE_LIST(or child table which is + skipped above). + */ + RPL_TABLE_LIST *ptr=static_cast<RPL_TABLE_LIST*>(table_list_ptr); DBUG_ASSERT(ptr->m_tabledef_valid); TABLE *conv_table; if (!ptr->m_tabledef.compatible_with(thd, rgi, ptr->table, &conv_table)) @@ -162,7 +171,15 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, rpl_group_info *rgi) */ TABLE_LIST *ptr= rgi->tables_to_lock; for (uint i=0; ptr && (i < rgi->tables_to_lock_count); ptr= ptr->next_global, i++) + { + /* + Please see comment in log_event.cc-Rows_log_event::do_apply_event() + function for the explanation of the below if condition + */ + if (ptr->parent_l) + continue; rgi->m_table_map.set_table(ptr->table_id, ptr->table); + } #ifdef HAVE_QUERY_CACHE query_cache.invalidate_locked_for_write(thd, rgi->tables_to_lock); #endif @@ -1420,16 +1437,25 @@ int Old_rows_log_event::do_apply_event(rpl_group_info *rgi) /* When the open and locking succeeded, we check all tables to ensure that they still have the correct type. - - We can use a down cast here since we know that every table added - to the tables_to_lock is a RPL_TABLE_LIST. */ { - RPL_TABLE_LIST *ptr= rgi->tables_to_lock; - for (uint i= 0 ; ptr&& (i< rgi->tables_to_lock_count); - ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global), i++) + TABLE_LIST *table_list_ptr= rgi->tables_to_lock; + for (uint i=0; table_list_ptr&& (i< rgi->tables_to_lock_count); + table_list_ptr= static_cast<RPL_TABLE_LIST*>(table_list_ptr->next_global), i++) { + /* + Please see comment in log_event.cc-Rows_log_event::do_apply_event() + function for the explanation of the below if condition + */ + if (table_list_ptr->parent_l) + continue; + /* + We can use a down cast here since we know that every table added + to the tables_to_lock is a RPL_TABLE_LIST (or child table which is + skipped above). + */ + RPL_TABLE_LIST *ptr=static_cast<RPL_TABLE_LIST*>(table_list_ptr); TABLE *conv_table; if (ptr->m_tabledef.compatible_with(thd, rgi, ptr->table, &conv_table)) { diff --git a/sql/opt_range.cc b/sql/opt_range.cc index b262b0c4191..1dc8f73a99d 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -7114,7 +7114,7 @@ SEL_TREE *Item_func_in::get_func_mm_tree(RANGE_OPT_PARAM *param, DBUG_RETURN(NULL); } SEL_TREE *tree2; - for (; i < array->count; i++) + for (; i < array->used_count; i++) { if (array->compare_elems(i, i-1)) { diff --git a/sql/slave.cc b/sql/slave.cc index 5410192a8dd..3929ebee59a 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. - Copyright (c) 2008, 2015, MariaDB +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. + Copyright (c) 2009, 2016, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -4355,7 +4355,8 @@ int check_temp_dir(char* tmp_file) mysql_mutex_lock(&LOCK_thread_count); if (check_temp_dir_run) { - result= check_temp_dir_result; + if ((result= check_temp_dir_result)) + my_message(result, tmp_file, MYF(0)); goto end; } check_temp_dir_run= 1; @@ -4390,7 +4391,6 @@ int check_temp_dir(char* tmp_file) mysql_file_delete(key_file_misc, tmp_file, MYF(0)); end: - check_temp_dir_result= result; mysql_mutex_unlock(&LOCK_thread_count); DBUG_RETURN(result); } @@ -4672,11 +4672,14 @@ pthread_handler_t handle_slave_sql(void *arg) if (check_temp_dir(rli->slave_patternload_file)) { + check_temp_dir_result= thd->get_stmt_da()->sql_errno(); rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(), NULL, "Unable to use slave's temporary directory %s - %s", slave_load_tmpdir, thd->get_stmt_da()->message()); goto err; } + else + check_temp_dir_result= 0; /* Load the set of seen GTIDs, if we did not already. */ if (rpl_load_gtid_slave_state(thd)) diff --git a/sql/slave.h b/sql/slave.h index ca89064d773..7f412c1091c 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -1,5 +1,5 @@ -/* - Copyright (c) 2000, 2010, Oracle and/or its affiliates. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. + Copyright (c) 2009, 2016, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/sql/sp_head.cc b/sql/sp_head.cc index cb598b367e7..29427c3834a 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1,6 +1,6 @@ /* - Copyright (c) 2002, 2013, Oracle and/or its affiliates. - Copyright (c) 2011, 2013, Monty Program Ab + Copyright (c) 2002, 2016, Oracle and/or its affiliates. + Copyright (c) 2011, 2016, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -534,8 +534,10 @@ sp_name::init_qname(THD *thd) bool check_routine_name(LEX_STRING *ident) { - if (!ident || !ident->str || !ident->str[0] || - ident->str[ident->length-1] == ' ') + DBUG_ASSERT(ident); + DBUG_ASSERT(ident->str); + + if (!ident->str[0] || ident->str[ident->length-1] == ' ') { my_error(ER_SP_WRONG_NAME, MYF(0), ident->str); return TRUE; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 7db7d2cf3fb..d2ef9b4690d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -7382,8 +7382,7 @@ bool check_grant_db(THD *thd, const char *db) len= (uint) (end - helping) + 1; /* - If a role is set, we need to check for privileges - here aswell + If a role is set, we need to check for privileges here as well. */ if (sctx->priv_role[0]) { @@ -7397,11 +7396,10 @@ bool check_grant_db(THD *thd, const char *db) for (uint idx=0 ; idx < column_priv_hash.records ; idx++) { - GRANT_TABLE *grant_table= (GRANT_TABLE*) - my_hash_element(&column_priv_hash, - idx); + GRANT_TABLE *grant_table= (GRANT_TABLE*) my_hash_element(&column_priv_hash, + idx); if (len < grant_table->key_length && - !memcmp(grant_table->hash_key,helping,len) && + !memcmp(grant_table->hash_key, helping, len) && compare_hostname(&grant_table->host, sctx->host, sctx->ip)) { error= FALSE; /* Found match. */ @@ -7409,7 +7407,7 @@ bool check_grant_db(THD *thd, const char *db) } if (sctx->priv_role[0] && len2 < grant_table->key_length && - !memcmp(grant_table->hash_key,helping2,len) && + !memcmp(grant_table->hash_key, helping2, len2) && (!grant_table->host.hostname || !grant_table->host.hostname[0])) { error= FALSE; /* Found role match */ diff --git a/sql/sql_help.cc b/sql/sql_help.cc index a0e836da203..d71a6caf813 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -667,7 +667,7 @@ SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, uint mlen, TRUE Error and send_error already commited */ -bool mysqld_help(THD *thd, const char *mask) +static bool mysqld_help_internal(THD *thd, const char *mask) { Protocol *protocol= thd->protocol; SQL_SELECT *select; @@ -849,3 +849,12 @@ error2: DBUG_RETURN(TRUE); } + +bool mysqld_help(THD *thd, const char *mask) +{ + ulonglong sql_mode_backup= thd->variables.sql_mode; + thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH; + bool rc= mysqld_help_internal(thd, mask); + thd->variables.sql_mode= sql_mode_backup; + return rc; +} diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 31fc5f9712c..b62838f46f2 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1697,32 +1697,35 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) return (BIN_NUM); case MY_LEX_CMP_OP: // Incomplete comparison operator + lip->next_state= MY_LEX_START; // Allow signed numbers if (state_map[(uchar) lip->yyPeek()] == MY_LEX_CMP_OP || state_map[(uchar) lip->yyPeek()] == MY_LEX_LONG_CMP_OP) - lip->yySkip(); - if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0))) { - lip->next_state= MY_LEX_START; // Allow signed numbers - return(tokval); + lip->yySkip(); + if ((tokval= find_keyword(lip, 2, 0))) + return(tokval); + lip->yyUnget(); } - state = MY_LEX_CHAR; // Something fishy found - break; + return(c); case MY_LEX_LONG_CMP_OP: // Incomplete comparison operator + lip->next_state= MY_LEX_START; if (state_map[(uchar) lip->yyPeek()] == MY_LEX_CMP_OP || state_map[(uchar) lip->yyPeek()] == MY_LEX_LONG_CMP_OP) { lip->yySkip(); if (state_map[(uchar) lip->yyPeek()] == MY_LEX_CMP_OP) + { lip->yySkip(); + if ((tokval= find_keyword(lip, 3, 0))) + return(tokval); + lip->yyUnget(); + } + if ((tokval= find_keyword(lip, 2, 0))) + return(tokval); + lip->yyUnget(); } - if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0))) - { - lip->next_state= MY_LEX_START; // Found long op - return(tokval); - } - state = MY_LEX_CHAR; // Something fishy found - break; + return(c); case MY_LEX_BOOL: if (c != lip->yyPeek()) diff --git a/sql/sql_locale.h b/sql/sql_locale.h index 8357a9ecba4..8559bb55cd9 100644 --- a/sql/sql_locale.h +++ b/sql/sql_locale.h @@ -61,6 +61,8 @@ public: grouping(grouping_par), errmsgs(errmsgs_par) {} + uint repertoire() const + { return is_ascii ? MY_REPERTOIRE_ASCII : MY_REPERTOIRE_EXTENDED; } }; /* Exported variables */ diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index 2bfdcb29dfc..efa48b22ce8 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -152,7 +152,7 @@ typedef int (*plugin_type_init)(struct st_plugin_int *); extern I_List<i_string> *opt_plugin_load_list_ptr; extern char *opt_plugin_dir_ptr; -extern char opt_plugin_dir[FN_REFLEN]; +extern MYSQL_PLUGIN_IMPORT char opt_plugin_dir[FN_REFLEN]; extern const LEX_STRING plugin_type_names[]; extern ulong plugin_maturity; extern TYPELIB plugin_maturity_values; diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 089f60a2dd8..b99ddf45333 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -1,4 +1,5 @@ -/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2016, Oracle and/or its affiliates. + Copyright (c) 2011, 2016, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 48257265a6a..86a7309315a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -15899,7 +15899,8 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, case STRING_RESULT: DBUG_ASSERT(item->collation.collation); new_field= item->make_string_field(table); - new_field->set_derivation(item->collation.derivation); + new_field->set_derivation(item->collation.derivation, + item->collation.repertoire); break; case DECIMAL_RESULT: new_field= Field_new_decimal::create_from_item(mem_root, item); @@ -16132,7 +16133,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, modify_item); case Item::TYPE_HOLDER: result= ((Item_type_holder *)item)->make_field_by_type(table); - result->set_derivation(item->collation.derivation); + result->set_derivation(item->collation.derivation, + item->collation.repertoire); return result; default: // Dosen't have to be stored return 0; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 1cbad7e9ea0..8ec44bad966 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -816,12 +816,24 @@ ignore_db_dirs_process_additions() for (i= 0; i < ignore_db_dirs_array.elements; i++) { get_dynamic(&ignore_db_dirs_array, (uchar *) &dir, i); - if (my_hash_insert(&ignore_db_dirs_hash, (uchar *) dir)) + if (my_hash_insert(&ignore_db_dirs_hash, (uchar *)dir)) + { + /* ignore duplicates from the config file */ + if (my_hash_search(&ignore_db_dirs_hash, (uchar *)dir->str, dir->length)) + { + sql_print_warning("Duplicate ignore-db-dir directory name '%.*s' " + "found in the config file(s). Ignoring the duplicate.", + (int) dir->length, dir->str); + my_free(dir); + goto continue_loop; + } + return true; + } ptr= strnmov(ptr, dir->str, dir->length); - if (i + 1 < ignore_db_dirs_array.elements) - ptr= strmov(ptr, ","); + *(ptr++)= ','; +continue_loop: /* Set the transferred array element to NULL to avoid double free in case of error. @@ -830,6 +842,12 @@ ignore_db_dirs_process_additions() set_dynamic(&ignore_db_dirs_array, (uchar *) &dir, i); } + if (ptr > opt_ignore_db_dirs) + { + ptr--; + DBUG_ASSERT(*ptr == ','); + } + /* make sure the string is terminated */ DBUG_ASSERT(ptr - opt_ignore_db_dirs <= (ptrdiff_t) len); *ptr= 0; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 28e76ae43f1..4020cbc70c4 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -29,6 +29,7 @@ #include "sql_statistics.h" #include "opt_range.h" #include "my_atomic.h" +#include "sql_show.h" /* The system variable 'use_stat_tables' can take one of the @@ -3193,6 +3194,10 @@ int delete_statistics_for_table(THD *thd, LEX_STRING *db, LEX_STRING *tab) rc= 1; } + err= del_global_table_stat(thd, db, tab); + if (err & !rc) + rc= 1; + thd->restore_stmt_binlog_format(save_binlog_format); close_system_tables(thd, &open_tables_backup); @@ -3339,6 +3344,10 @@ int delete_statistics_for_index(THD *thd, TABLE *tab, KEY *key_info, } } + err= del_global_index_stat(thd, tab, key_info); + if (err && !rc) + rc= 1; + thd->restore_stmt_binlog_format(save_binlog_format); close_system_tables(thd, &open_tables_backup); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 4221025da28..a23f71977aa 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1612,7 +1612,7 @@ bool mysql_multi_update(THD *thd, DBUG_RETURN(TRUE); } - thd->abort_on_warning= thd->is_strict_mode(); + thd->abort_on_warning= !ignore && thd->is_strict_mode(); List<Item> total_list; res= mysql_select(thd, &select_lex->ref_pointer_array, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e614692bd70..9131b99d95e 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2015, Oracle and/or its affiliates. - Copyright (c) 2010, 2015, MariaDB + Copyright (c) 2010, 2016, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1212,7 +1212,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token ENGINES_SYM %token ENGINE_SYM %token ENUM -%token EQ /* OPERATOR */ %token EQUAL_SYM /* OPERATOR */ %token ERROR_SYM %token ERRORS @@ -1262,7 +1261,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token GRANTS %token GROUP_SYM /* SQL-2003-R */ %token GROUP_CONCAT_SYM -%token GT_SYM /* OPERATOR */ %token HANDLER_SYM %token HARD_SYM %token HASH_SYM @@ -1342,7 +1340,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token LONG_SYM %token LOOP_SYM %token LOW_PRIORITY -%token LT /* OPERATOR */ %token MASTER_CONNECT_RETRY_SYM %token MASTER_GTID_POS_SYM %token MASTER_HOST_SYM @@ -1702,7 +1699,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %left XOR %left AND_SYM AND_AND_SYM %left BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE -%left EQ EQUAL_SYM GE GT_SYM LE LT NE IS LIKE REGEXP IN_SYM +%left '=' EQUAL_SYM GE '>' LE '<' NE IS LIKE REGEXP IN_SYM %left '|' %left '&' %left SHIFT_LEFT SHIFT_RIGHT @@ -2238,66 +2235,66 @@ master_defs: ; master_def: - MASTER_HOST_SYM EQ TEXT_STRING_sys + MASTER_HOST_SYM '=' TEXT_STRING_sys { Lex->mi.host = $3.str; } - | MASTER_USER_SYM EQ TEXT_STRING_sys + | MASTER_USER_SYM '=' TEXT_STRING_sys { Lex->mi.user = $3.str; } - | MASTER_PASSWORD_SYM EQ TEXT_STRING_sys + | MASTER_PASSWORD_SYM '=' TEXT_STRING_sys { Lex->mi.password = $3.str; } - | MASTER_PORT_SYM EQ ulong_num + | MASTER_PORT_SYM '=' ulong_num { Lex->mi.port = $3; } - | MASTER_CONNECT_RETRY_SYM EQ ulong_num + | MASTER_CONNECT_RETRY_SYM '=' ulong_num { Lex->mi.connect_retry = $3; } - | MASTER_SSL_SYM EQ ulong_num + | MASTER_SSL_SYM '=' ulong_num { Lex->mi.ssl= $3 ? LEX_MASTER_INFO::LEX_MI_ENABLE : LEX_MASTER_INFO::LEX_MI_DISABLE; } - | MASTER_SSL_CA_SYM EQ TEXT_STRING_sys + | MASTER_SSL_CA_SYM '=' TEXT_STRING_sys { Lex->mi.ssl_ca= $3.str; } - | MASTER_SSL_CAPATH_SYM EQ TEXT_STRING_sys + | MASTER_SSL_CAPATH_SYM '=' TEXT_STRING_sys { Lex->mi.ssl_capath= $3.str; } - | MASTER_SSL_CERT_SYM EQ TEXT_STRING_sys + | MASTER_SSL_CERT_SYM '=' TEXT_STRING_sys { Lex->mi.ssl_cert= $3.str; } - | MASTER_SSL_CIPHER_SYM EQ TEXT_STRING_sys + | MASTER_SSL_CIPHER_SYM '=' TEXT_STRING_sys { Lex->mi.ssl_cipher= $3.str; } - | MASTER_SSL_KEY_SYM EQ TEXT_STRING_sys + | MASTER_SSL_KEY_SYM '=' TEXT_STRING_sys { Lex->mi.ssl_key= $3.str; } - | MASTER_SSL_VERIFY_SERVER_CERT_SYM EQ ulong_num + | MASTER_SSL_VERIFY_SERVER_CERT_SYM '=' ulong_num { Lex->mi.ssl_verify_server_cert= $3 ? LEX_MASTER_INFO::LEX_MI_ENABLE : LEX_MASTER_INFO::LEX_MI_DISABLE; } - | MASTER_SSL_CRL_SYM EQ TEXT_STRING_sys + | MASTER_SSL_CRL_SYM '=' TEXT_STRING_sys { Lex->mi.ssl_crl= $3.str; } - | MASTER_SSL_CRLPATH_SYM EQ TEXT_STRING_sys + | MASTER_SSL_CRLPATH_SYM '=' TEXT_STRING_sys { Lex->mi.ssl_crlpath= $3.str; } - | MASTER_HEARTBEAT_PERIOD_SYM EQ NUM_literal + | MASTER_HEARTBEAT_PERIOD_SYM '=' NUM_literal { Lex->mi.heartbeat_period= (float) $3->val_real(); if (Lex->mi.heartbeat_period > SLAVE_MAX_HEARTBEAT_PERIOD || @@ -2324,15 +2321,15 @@ master_def: } Lex->mi.heartbeat_opt= LEX_MASTER_INFO::LEX_MI_ENABLE; } - | IGNORE_SERVER_IDS_SYM EQ '(' ignore_server_id_list ')' + | IGNORE_SERVER_IDS_SYM '=' '(' ignore_server_id_list ')' { Lex->mi.repl_ignore_server_ids_opt= LEX_MASTER_INFO::LEX_MI_ENABLE; } - | DO_DOMAIN_IDS_SYM EQ '(' do_domain_id_list ')' + | DO_DOMAIN_IDS_SYM '=' '(' do_domain_id_list ')' { Lex->mi.repl_do_domain_ids_opt= LEX_MASTER_INFO::LEX_MI_ENABLE; } - | IGNORE_DOMAIN_IDS_SYM EQ '(' ignore_domain_id_list ')' + | IGNORE_DOMAIN_IDS_SYM '=' '(' ignore_domain_id_list ')' { Lex->mi.repl_ignore_domain_ids_opt= LEX_MASTER_INFO::LEX_MI_ENABLE; } @@ -2380,11 +2377,11 @@ ignore_domain_id: ; master_file_def: - MASTER_LOG_FILE_SYM EQ TEXT_STRING_sys + MASTER_LOG_FILE_SYM '=' TEXT_STRING_sys { Lex->mi.log_file_name = $3.str; } - | MASTER_LOG_POS_SYM EQ ulonglong_num + | MASTER_LOG_POS_SYM '=' ulonglong_num { /* If the user specified a value < BIN_LOG_HEADER_SIZE, adjust it @@ -2399,29 +2396,29 @@ master_file_def: */ Lex->mi.pos= MY_MAX(BIN_LOG_HEADER_SIZE, $3); } - | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys + | RELAY_LOG_FILE_SYM '=' TEXT_STRING_sys { Lex->mi.relay_log_name = $3.str; } - | RELAY_LOG_POS_SYM EQ ulong_num + | RELAY_LOG_POS_SYM '=' ulong_num { Lex->mi.relay_log_pos = $3; /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */ Lex->mi.relay_log_pos= MY_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos); } - | MASTER_USE_GTID_SYM EQ CURRENT_POS_SYM + | MASTER_USE_GTID_SYM '=' CURRENT_POS_SYM { if (Lex->mi.use_gtid_opt != LEX_MASTER_INFO::LEX_GTID_UNCHANGED) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MASTER_use_gtid")); Lex->mi.use_gtid_opt= LEX_MASTER_INFO::LEX_GTID_CURRENT_POS; } - | MASTER_USE_GTID_SYM EQ SLAVE_POS_SYM + | MASTER_USE_GTID_SYM '=' SLAVE_POS_SYM { if (Lex->mi.use_gtid_opt != LEX_MASTER_INFO::LEX_GTID_UNCHANGED) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MASTER_use_gtid")); Lex->mi.use_gtid_opt= LEX_MASTER_INFO::LEX_GTID_SLAVE_POS; } - | MASTER_USE_GTID_SYM EQ NO_SYM + | MASTER_USE_GTID_SYM '=' NO_SYM { if (Lex->mi.use_gtid_opt != LEX_MASTER_INFO::LEX_GTID_UNCHANGED) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MASTER_use_gtid")); @@ -3325,7 +3322,7 @@ opt_set_signal_information: ; signal_information_item_list: - signal_condition_information_item_name EQ signal_allowed_expr + signal_condition_information_item_name '=' signal_allowed_expr { Set_signal_information *info; info= &thd->m_parser_state->m_yacc.m_set_signal_info; @@ -3334,7 +3331,7 @@ signal_information_item_list: info->m_item[index]= $3; } | signal_information_item_list ',' - signal_condition_information_item_name EQ signal_allowed_expr + signal_condition_information_item_name '=' signal_allowed_expr { Set_signal_information *info; info= &thd->m_parser_state->m_yacc.m_set_signal_info; @@ -3470,7 +3467,7 @@ statement_information: ; statement_information_item: - simple_target_specification EQ statement_information_item_name + simple_target_specification '=' statement_information_item_name { $$= new (thd->mem_root) Statement_information_item($3, $1); if ($$ == NULL) @@ -3527,7 +3524,7 @@ condition_information: ; condition_information_item: - simple_target_specification EQ condition_information_item_name + simple_target_specification '=' condition_information_item_name { $$= new (thd->mem_root) Condition_information_item($3, $1); if ($$ == NULL) @@ -4872,7 +4869,7 @@ opt_linear: opt_key_algo: /* empty */ { Lex->part_info->key_algorithm= partition_info::KEY_ALGORITHM_NONE;} - | ALGORITHM_SYM EQ real_ulong_num + | ALGORITHM_SYM '=' real_ulong_num { switch ($3) { case 1: @@ -6332,7 +6329,7 @@ srid_option: /* empty */ { Lex->last_field->srid= 0; } | - REF_SYSTEM_ID_SYM EQ NUM + REF_SYSTEM_ID_SYM '=' NUM { Lex->last_field->srid=atoi($3.str); } @@ -7644,7 +7641,7 @@ opt_place: opt_to: /* empty */ {} | TO_SYM {} - | EQ {} + | '=' {} | AS {} ; @@ -7762,7 +7759,7 @@ slave_until: (lex->mi.relay_log_name && lex->mi.relay_log_pos))) my_yyabort_error((ER_BAD_SLAVE_UNTIL_COND, MYF(0))); } - | UNTIL_SYM MASTER_GTID_POS_SYM EQ TEXT_STRING_sys + | UNTIL_SYM MASTER_GTID_POS_SYM '=' TEXT_STRING_sys { Lex->mi.gtid_pos_str = $4; } @@ -8657,13 +8654,13 @@ bool_pri: if ($$ == NULL) MYSQL_YYABORT; } - | bool_pri comp_op predicate %prec EQ + | bool_pri comp_op predicate %prec '=' { $$= (*$2)(0)->create(thd, $1, $3); if ($$ == NULL) MYSQL_YYABORT; } - | bool_pri comp_op all_or_any '(' subselect ')' %prec EQ + | bool_pri comp_op all_or_any '(' subselect ')' %prec '=' { $$= all_any_subquery_creator(thd, $1, $2, $3, $5); if ($$ == NULL) @@ -8887,11 +8884,11 @@ not2: ; comp_op: - EQ { $$ = &comp_eq_creator; } + '=' { $$ = &comp_eq_creator; } | GE { $$ = &comp_ge_creator; } - | GT_SYM { $$ = &comp_gt_creator; } + | '>' { $$ = &comp_gt_creator; } | LE { $$ = &comp_le_creator; } - | LT { $$ = &comp_lt_creator; } + | '<' { $$ = &comp_lt_creator; } | NE { $$ = &comp_ne_creator; } ; @@ -10984,7 +10981,7 @@ date_time_type: table_alias: /* empty */ | AS - | EQ + | '=' ; opt_table_alias: @@ -11897,7 +11894,7 @@ ident_eq_value: ; equal: - EQ {} + '=' {} | SET_VAR {} ; @@ -12663,7 +12660,7 @@ opt_extended_describe: opt_format_json: /* empty */ {} - | FORMAT_SYM EQ ident_or_text + | FORMAT_SYM '=' ident_or_text { if (!my_strcasecmp(system_charset_info, $3.str, "JSON")) Lex->explain_json= true; @@ -14926,11 +14923,11 @@ handler_rkey_function: ; handler_rkey_mode: - EQ { $$=HA_READ_KEY_EXACT; } + '=' { $$=HA_READ_KEY_EXACT; } | GE { $$=HA_READ_KEY_OR_NEXT; } | LE { $$=HA_READ_KEY_OR_PREV; } - | GT_SYM { $$=HA_READ_AFTER_KEY; } - | LT { $$=HA_READ_BEFORE_KEY; } + | '>' { $$=HA_READ_AFTER_KEY; } + | '<' { $$=HA_READ_BEFORE_KEY; } ; /* GRANT / REVOKE */ @@ -15769,7 +15766,7 @@ no_definer: ; definer: - DEFINER_SYM EQ user_or_role + DEFINER_SYM '=' user_or_role { Lex->definer= $3; Lex->ssl_type= SSL_TYPE_NOT_SPECIFIED; @@ -15785,11 +15782,11 @@ definer: **************************************************************************/ view_algorithm: - ALGORITHM_SYM EQ UNDEFINED_SYM + ALGORITHM_SYM '=' UNDEFINED_SYM { Lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED; } - | ALGORITHM_SYM EQ MERGE_SYM + | ALGORITHM_SYM '=' MERGE_SYM { Lex->create_view_algorithm= VIEW_ALGORITHM_MERGE; } - | ALGORITHM_SYM EQ TEMPTABLE_SYM + | ALGORITHM_SYM '=' TEMPTABLE_SYM { Lex->create_view_algorithm= VIEW_ALGORITHM_TMPTABLE; } ; diff --git a/sql/table.cc b/sql/table.cc index a90eb2eee15..f7dddd92553 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3442,18 +3442,23 @@ bool get_field(MEM_ROOT *mem, Field *field, String *res) { char buff[MAX_FIELD_WIDTH], *to; String str(buff,sizeof(buff),&my_charset_bin); - uint length; + bool rc; + THD *thd= field->get_thd(); + ulonglong sql_mode_backup= thd->variables.sql_mode; + thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH; field->val_str(&str); - if (!(length= str.length())) + if ((rc= !str.length() || + !(to= strmake_root(mem, str.ptr(), str.length())))) { res->length(0); - return 1; + goto ex; } - if (!(to= strmake_root(mem, str.ptr(), length))) - length= 0; // Safety fix - res->set(to, length, field->charset()); - return 0; + res->set(to, str.length(), field->charset()); + +ex: + thd->variables.sql_mode= sql_mode_backup; + return rc; } @@ -3472,17 +3477,10 @@ bool get_field(MEM_ROOT *mem, Field *field, String *res) char *get_field(MEM_ROOT *mem, Field *field) { - char buff[MAX_FIELD_WIDTH], *to; - String str(buff,sizeof(buff),&my_charset_bin); - uint length; - - field->val_str(&str); - length= str.length(); - if (!length || !(to= (char*) alloc_root(mem,length+1))) - return NullS; - memcpy(to,str.ptr(),(uint) length); - to[length]=0; - return to; + String str; + bool rc= get_field(mem, field, &str); + DBUG_ASSERT(rc || str.ptr()[str.length()] == '\0'); + return rc ? NullS : (char *) str.ptr(); } /* diff --git a/sql/threadpool_unix.cc b/sql/threadpool_unix.cc index 89a2036cb10..9e2ffc9aee0 100644 --- a/sql/threadpool_unix.cc +++ b/sql/threadpool_unix.cc @@ -169,6 +169,7 @@ struct pool_timer_t volatile uint64 next_timeout_check; int tick_interval; bool shutdown; + pthread_t timer_thread_id; }; static pool_timer_t pool_timer; @@ -606,12 +607,12 @@ void check_stall(thread_group_t *thread_group) static void start_timer(pool_timer_t* timer) { - pthread_t thread_id; DBUG_ENTER("start_timer"); mysql_mutex_init(key_timer_mutex,&timer->mutex, NULL); mysql_cond_init(key_timer_cond, &timer->cond, NULL); timer->shutdown = false; - mysql_thread_create(key_timer_thread,&thread_id, NULL, timer_thread, timer); + mysql_thread_create(key_timer_thread, &timer->timer_thread_id, NULL, + timer_thread, timer); DBUG_VOID_RETURN; } @@ -623,6 +624,7 @@ static void stop_timer(pool_timer_t *timer) timer->shutdown = true; mysql_cond_signal(&timer->cond); mysql_mutex_unlock(&timer->mutex); + pthread_join(timer->timer_thread_id, NULL); DBUG_VOID_RETURN; } diff --git a/sql/winservice.c b/sql/winservice.c index 1cf9f8d7823..74e9e56acc6 100644 --- a/sql/winservice.c +++ b/sql/winservice.c @@ -81,8 +81,10 @@ void normalize_path(char *path, size_t size) and services. We do not want to mess up with these installations. We will just ignore such services, pretending it is not MySQL. - ´@return - TRUE, if this service should be excluded from UI lists etc (OEM install) + We also exclude MySQL5.7+ since we cannot upgrade it (and it is not an upgrade anyway) + + @return + TRUE, if this service should be excluded from UI lists etc FALSE otherwise. */ BOOL exclude_service(mysqld_service_properties *props) @@ -104,7 +106,12 @@ BOOL exclude_service(mysqld_service_properties *props) if (strstr(buf, exclude_patterns[i])) return TRUE; } - + if ((props->version_major == 0) || + (props->version_major > 5 && props->version_major < 10) || + (props->version_major == 5 && props->version_minor > 6)) + { + return TRUE; + } return FALSE; } |