summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2017-01-17 20:17:35 +0100
committerSergei Golubchik <serg@mariadb.org>2017-01-17 20:17:35 +0100
commitf7d030489d2980c9deb733925515099ec256f6d2 (patch)
tree32673a800f903c26be547aa0f752cf4bd93d4923
parentf797ea7124e906fd3abf311d66101a21dce2d27d (diff)
parent6728aae3b34616cc98a7436ff93f318a15949a4b (diff)
downloadmariadb-git-mariadb-10.1.21.tar.gz
Merge branch '10.0' into 10.1mariadb-10.1.21
-rw-r--r--mysql-test/suite/vcol/r/wrong_arena.result61
-rw-r--r--mysql-test/suite/vcol/t/wrong_arena.test35
-rw-r--r--sql/item_cmpfunc.cc22
-rw-r--r--sql/item_cmpfunc.h13
-rw-r--r--sql/item_func.cc5
-rw-r--r--sql/item_func.h1
-rw-r--r--sql/sql_class.cc1
-rw-r--r--sql/sql_class.h20
-rw-r--r--sql/table.cc6
-rw-r--r--storage/connect/filamzip.cpp8
-rw-r--r--storage/connect/ioapi.h5
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));