diff options
-rw-r--r-- | mysql-test/suite/vcol/r/wrong_arena.result | 61 | ||||
-rw-r--r-- | mysql-test/suite/vcol/t/wrong_arena.test | 35 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 22 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 13 | ||||
-rw-r--r-- | sql/item_func.cc | 5 | ||||
-rw-r--r-- | sql/item_func.h | 1 | ||||
-rw-r--r-- | sql/sql_class.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 20 | ||||
-rw-r--r-- | sql/table.cc | 6 | ||||
-rw-r--r-- | storage/connect/filamzip.cpp | 8 | ||||
-rw-r--r-- | storage/connect/ioapi.h | 5 |
11 files changed, 122 insertions, 55 deletions
diff --git a/mysql-test/suite/vcol/r/wrong_arena.result b/mysql-test/suite/vcol/r/wrong_arena.result new file mode 100644 index 00000000000..172b59d6c4c --- /dev/null +++ b/mysql-test/suite/vcol/r/wrong_arena.result @@ -0,0 +1,61 @@ +create table t1 (a datetime, +# get_datetime_value +b int as (a > 1), # Arg_comparator +c int as (a in (1,2,3)), # in_datetime +d int as ((a,a) in ((1,1),(2,1),(NULL,1))), # cmp_item_datetime +# other issues +e int as ((a,1) in ((1,1),(2,1),(NULL,1))) # cmp_item_row::alloc_comparators() +); +Warnings: +Warning 1292 Incorrect datetime value: '1' +Warning 1292 Incorrect datetime value: '2' +Warning 1292 Incorrect datetime value: '3' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` datetime DEFAULT NULL, + `b` int(11) AS (a > 1) VIRTUAL, + `c` int(11) AS (a in (1,2,3)) VIRTUAL, + `d` int(11) AS ((a,a) in ((1,1),(2,1),(NULL,1))) VIRTUAL, + `e` int(11) AS ((a,1) in ((1,1),(2,1),(NULL,1))) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +Warnings: +Warning 1292 Incorrect datetime value: '1' +Warning 1292 Incorrect datetime value: '2' +Warning 1292 Incorrect datetime value: '3' +insert t1 (a) values ('2010-10-10 10:10:10'); +select * from t1; +a b c d e +2010-10-10 10:10:10 1 0 0 NULL +Warnings: +Warning 1292 Incorrect datetime value: '1' +Warning 1292 Incorrect datetime value: '1' +Warning 1292 Incorrect datetime value: '2' +Warning 1292 Incorrect datetime value: '1' +Warning 1292 Incorrect datetime value: '1' +Warning 1292 Incorrect datetime value: '2' +select * from t1; +a b c d e +2010-10-10 10:10:10 1 0 0 NULL +Warnings: +Warning 1292 Incorrect datetime value: '1' +Warning 1292 Incorrect datetime value: '2' +Warning 1292 Incorrect datetime value: '1' +Warning 1292 Incorrect datetime value: '1' +Warning 1292 Incorrect datetime value: '2' +drop table t1; +create table t1 (a datetime, +b datetime as (least(a,1)) # Item_func_min_max::get_date +); +insert t1 (a) values ('2010-10-10 10:10:10'); +select * from t1; +a b +2010-10-10 10:10:10 0000-00-00 00:00:00 +Warnings: +Warning 1292 Incorrect datetime value: '1' +select * from t1; +a b +2010-10-10 10:10:10 0000-00-00 00:00:00 +Warnings: +Warning 1292 Incorrect datetime value: '1' +drop table t1; diff --git a/mysql-test/suite/vcol/t/wrong_arena.test b/mysql-test/suite/vcol/t/wrong_arena.test new file mode 100644 index 00000000000..484f1fe685d --- /dev/null +++ b/mysql-test/suite/vcol/t/wrong_arena.test @@ -0,0 +1,35 @@ +# +# This tests various issues when vcol items allocate memory (e.g. more items) +# not in the TABLE::expr_arena. +# + +# +# MDEV-9690 concurrent queries with virtual columns crash in temporal code +# +create table t1 (a datetime, + # get_datetime_value + b int as (a > 1), # Arg_comparator + c int as (a in (1,2,3)), # in_datetime + d int as ((a,a) in ((1,1),(2,1),(NULL,1))), # cmp_item_datetime + # other issues + e int as ((a,1) in ((1,1),(2,1),(NULL,1))) # cmp_item_row::alloc_comparators() +); +show create table t1; +connect con1, localhost, root; +insert t1 (a) values ('2010-10-10 10:10:10'); +select * from t1; +disconnect con1; +connection default; +select * from t1; +drop table t1; + +connect con1, localhost, root; +create table t1 (a datetime, + b datetime as (least(a,1)) # Item_func_min_max::get_date +); +insert t1 (a) values ('2010-10-10 10:10:10'); +select * from t1; +disconnect con1; +connection default; +select * from t1; +drop table t1; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 1a2c85f66a6..7a7b2ca2933 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -620,7 +620,7 @@ int Arg_comparator::set_compare_func(Item_func_or_sum *item, Item_result type) int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg, Item **a1, Item **a2) { - thd= current_thd; + THD *thd= current_thd; owner= owner_arg; set_null= set_null && owner_arg; a= a1; @@ -752,12 +752,10 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, if (cache_arg && item->const_item() && !(item->type() == Item::CACHE_ITEM && item->cmp_type() == TIME_RESULT)) { - Query_arena backup; - Query_arena *save_arena= thd->switch_to_arena_for_cached_items(&backup); - Item_cache_temporal *cache= new (thd->mem_root) Item_cache_temporal(thd, f_type); - if (save_arena) - thd->set_query_arena(save_arena); + if (!thd) + thd= current_thd; + Item_cache_temporal *cache= new (thd->mem_root) Item_cache_temporal(thd, f_type); cache->store_packed(value, item); *cache_arg= cache; *item_arg= cache_arg; @@ -792,12 +790,12 @@ int Arg_comparator::compare_temporal(enum_field_types type) owner->null_value= 1; /* Get DATE/DATETIME/TIME value of the 'a' item. */ - a_value= get_datetime_value(thd, &a, &a_cache, type, &a_is_null); + a_value= get_datetime_value(0, &a, &a_cache, type, &a_is_null); if (a_is_null) return -1; /* Get DATE/DATETIME/TIME value of the 'b' item. */ - b_value= get_datetime_value(thd, &b, &b_cache, type, &b_is_null); + b_value= get_datetime_value(0, &b, &b_cache, type, &b_is_null); if (b_is_null) return -1; @@ -815,10 +813,10 @@ int Arg_comparator::compare_e_temporal(enum_field_types type) longlong a_value, b_value; /* Get DATE/DATETIME/TIME value of the 'a' item. */ - a_value= get_datetime_value(thd, &a, &a_cache, type, &a_is_null); + a_value= get_datetime_value(0, &a, &a_cache, type, &a_is_null); /* Get DATE/DATETIME/TIME value of the 'b' item. */ - b_value= get_datetime_value(thd, &b, &b_cache, type, &b_is_null); + b_value= get_datetime_value(0, &b, &b_cache, type, &b_is_null); return a_is_null || b_is_null ? a_is_null == b_is_null : a_value == b_value; } @@ -3755,7 +3753,7 @@ uchar *in_datetime::get_value(Item *item) Item **tmp_item= lval_cache ? &lval_cache : &item; enum_field_types f_type= tmp_item[0]->field_type_for_temporal_comparison(warn_item); - tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, f_type, &is_null); + tmp.val= get_datetime_value(0, &tmp_item, &lval_cache, f_type, &is_null); if (item->null_value) return 0; tmp.unsigned_flag= 1L; @@ -4020,7 +4018,7 @@ void cmp_item_datetime::store_value(Item *item) Item **tmp_item= lval_cache ? &lval_cache : &item; enum_field_types f_type= tmp_item[0]->field_type_for_temporal_comparison(warn_item); - value= get_datetime_value(thd, &tmp_item, &lval_cache, f_type, &is_null); + value= get_datetime_value(0, &tmp_item, &lval_cache, f_type, &is_null); m_null_value= item->null_value; } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 625af3231fc..697420df0e8 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -55,7 +55,6 @@ class Arg_comparator: public Sql_alloc Arg_comparator *comparators; // used only for compare_row() double precision; /* Fields used in DATE/DATETIME comparison. */ - THD *thd; Item *a_cache, *b_cache; // Cached values of a and b items // when one of arguments is NULL. int set_compare_func(Item_func_or_sum *owner, Item_result type); @@ -70,12 +69,12 @@ public: Arg_comparator(): m_compare_type(STRING_RESULT), m_compare_collation(&my_charset_bin), - set_null(TRUE), comparators(0), thd(0), + set_null(TRUE), comparators(0), a_cache(0), b_cache(0) {}; Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), m_compare_type(STRING_RESULT), m_compare_collation(&my_charset_bin), - set_null(TRUE), comparators(0), thd(0), + set_null(TRUE), comparators(0), a_cache(0), b_cache(0) {}; public: @@ -1194,15 +1193,13 @@ public: class in_datetime :public in_longlong { public: - THD *thd; /* An item used to issue warnings. */ Item *warn_item; /* Cache for the left item. */ Item *lval_cache; in_datetime(Item *warn_item_arg, uint elements) - :in_longlong(elements), thd(current_thd), warn_item(warn_item_arg), - lval_cache(0) {}; + :in_longlong(elements), warn_item(warn_item_arg), lval_cache(0) {}; void set(uint pos,Item *item); uchar *get_value(Item *item); Item *create_item(THD *thd); @@ -1372,14 +1369,13 @@ class cmp_item_datetime : public cmp_item_scalar { longlong value; public: - THD *thd; /* Item used for issuing warnings. */ Item *warn_item; /* Cache for the left item. */ Item *lval_cache; cmp_item_datetime(Item *warn_item_arg) - :thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {} + : warn_item(warn_item_arg), lval_cache(0) {} void store_value(Item *item); int cmp(Item *arg); int compare(cmp_item *ci); @@ -2584,4 +2580,3 @@ extern Ge_creator ge_creator; extern Le_creator le_creator; #endif /* ITEM_CMPFUNC_INCLUDED */ - diff --git a/sql/item_func.cc b/sql/item_func.cc index 5eff7538b61..623ff1128f3 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2767,7 +2767,6 @@ void Item_func_min_max::fix_length_and_dec() decimals=0; max_length=0; maybe_null=0; - thd= current_thd; Item_result tmp_cmp_type= args[0]->cmp_type(); uint string_type_count= 0; uint temporal_type_count= 0; @@ -2909,10 +2908,8 @@ bool Item_func_min_max::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) longlong res= args[i]->val_temporal_packed(Item_func_min_max::field_type()); /* Check if we need to stop (because of error or KILL) and stop the loop */ - if (thd->is_error() || args[i]->null_value) - { + if (args[i]->null_value) return (null_value= 1); - } if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0) min_max= res; diff --git a/sql/item_func.h b/sql/item_func.h index 56d7c190181..ad69054b49c 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1068,7 +1068,6 @@ class Item_func_min_max :public Item_hybrid_func { String tmp_value; int cmp_sign; - THD *thd; public: Item_func_min_max(THD *thd, List<Item> &list, int cmp_sign_arg): Item_hybrid_func(thd, list), cmp_sign(cmp_sign_arg) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index c9592df1b65..7585e49390f 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1085,7 +1085,6 @@ THD::THD(bool is_wsrep_applier) m_internal_handler= NULL; m_binlog_invoker= INVOKER_NONE; - arena_for_cached_items= 0; memset(&invoker_user, 0, sizeof(invoker_user)); memset(&invoker_host, 0, sizeof(invoker_host)); prepare_derived_at_open= FALSE; diff --git a/sql/sql_class.h b/sql/sql_class.h index 3058d81496c..9ae1e5cf23b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3837,27 +3837,7 @@ public: } } -private: - /* - This reference points to the table arena when the expression - for a virtual column is being evaluated - */ - Query_arena *arena_for_cached_items; - public: - void reset_arena_for_cached_items(Query_arena *new_arena) - { - arena_for_cached_items= new_arena; - } - Query_arena *switch_to_arena_for_cached_items(Query_arena *backup) - { - if (!arena_for_cached_items) - return 0; - set_n_backup_active_arena(arena_for_cached_items, backup); - return backup; - } - - void clear_wakeup_ready() { wakeup_ready= false; } /* Sleep waiting for others to wake us up with signal_wakeup_ready(). diff --git a/sql/table.cc b/sql/table.cc index 8f93f8ae286..759a2d05de7 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -6890,7 +6890,9 @@ int update_virtual_fields(THD *thd, TABLE *table, int error __attribute__ ((unused))= 0; DBUG_ASSERT(table && table->vfield); - thd->reset_arena_for_cached_items(table->expr_arena); + Query_arena backup_arena; + thd->set_n_backup_active_arena(table->expr_arena, &backup_arena); + /* Iterate over virtual fields in the table */ for (vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++) { @@ -6908,7 +6910,7 @@ int update_virtual_fields(THD *thd, TABLE *table, DBUG_PRINT("info", ("field '%s' - skipped", vfield->field_name)); } } - thd->reset_arena_for_cached_items(0); + thd->restore_active_arena(table->expr_arena, &backup_arena); DBUG_RETURN(0); } diff --git a/storage/connect/filamzip.cpp b/storage/connect/filamzip.cpp index 65013e170e4..22fe95aebad 100644 --- a/storage/connect/filamzip.cpp +++ b/storage/connect/filamzip.cpp @@ -97,7 +97,7 @@ loopStart: if (!*++pat) return TRUE; goto loopStart; default: - if (mapCaseTable[*s] != mapCaseTable[*p]) + if (mapCaseTable[(unsigned)*s] != mapCaseTable[(unsigned)*p]) goto starCheck; break; } /* endswitch */ @@ -151,7 +151,7 @@ int ZIPUTIL::findEntry(PGLOBAL g, bool next) if (rc == UNZ_END_OF_LIST_OF_FILE) return RC_EF; else if (rc != UNZ_OK) { - sprintf(g->Message, "unzGoToNextFile rc = ", rc); + sprintf(g->Message, "unzGoToNextFile rc = %d", rc); return RC_FX; } // endif rc @@ -261,7 +261,7 @@ bool ZIPUTIL::OpenTable(PGLOBAL g, MODE mode, char *fn) fp->Memory = memory; fp->Mode = mode; fp->File = this; - fp->Handle = NULL; + fp->Handle = 0; } // endif fp } else @@ -297,7 +297,7 @@ bool ZIPUTIL::openEntry(PGLOBAL g) memory = new char[size + 1]; if ((rc = unzReadCurrentFile(zipfile, memory, size)) < 0) { - sprintf(g->Message, "unzReadCurrentFile rc = ", rc); + sprintf(g->Message, "unzReadCurrentFile rc = %d", rc); unzCloseCurrentFile(zipfile); free(memory); memory = NULL; diff --git a/storage/connect/ioapi.h b/storage/connect/ioapi.h index 8dcbdb06e35..4fa73002053 100644 --- a/storage/connect/ioapi.h +++ b/storage/connect/ioapi.h @@ -129,8 +129,9 @@ extern "C" { #endif #endif - - +#ifndef OF +#define OF(args) args +#endif typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); |