summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-03-13 22:33:52 +0100
committerSergei Golubchik <sergii@pisem.net>2013-03-13 22:33:52 +0100
commit372bc22bfaacd5c6959b99729a68e2d2a3b923a4 (patch)
treea7b6962b5af81e99e35a2daf72148d93cab0c415
parentd24c8d9af104219bf2e42b89a585c4ba5c6facfa (diff)
downloadmariadb-git-372bc22bfaacd5c6959b99729a68e2d2a3b923a4.tar.gz
MDEV-4265 5.5 is slower than 5.3 because of many str_to_datetime calls
get_datetime_value() should not double-cache its own Item_cache_temporal items, but it *should* cache other Item_cache items, such as Item_cache_str. sql/item.h: shortcut, to avoid going through the switch in Item::cmp_type() sql/item_cmpfunc.cc: even if the item is Item_cache_str - it still needs to be converted and cached. sql/item_timefunc.h: all descendants of Item_temporal_func always have cmp_type==TIME_RESULT. Even Item_date_add_interval, that might have field_type == MYSQL_TYPE_STRING.
-rw-r--r--mysql-test/r/cache_temporal_4265.result11
-rw-r--r--mysql-test/t/cache_temporal_4265.test11
-rw-r--r--sql/item.h1
-rw-r--r--sql/item_cmpfunc.cc3
-rw-r--r--sql/item_timefunc.h1
-rw-r--r--sql/sql_time.cc3
6 files changed, 29 insertions, 1 deletions
diff --git a/mysql-test/r/cache_temporal_4265.result b/mysql-test/r/cache_temporal_4265.result
new file mode 100644
index 00000000000..b8f13e465de
--- /dev/null
+++ b/mysql-test/r/cache_temporal_4265.result
@@ -0,0 +1,11 @@
+create table t1 (a date);
+insert t1 values ('2000-01-02'), ('2001-02-03'), ('2002-03-04');
+set debug_dbug='d,str_to_datetime_warn';
+select * from t1 where a > date_add('2000-01-01', interval 5 day);
+a
+2001-02-03
+2002-03-04
+Warnings:
+Note 1003 2000-01-01
+Note 1003 2000-01-06
+drop table t1;
diff --git a/mysql-test/t/cache_temporal_4265.test b/mysql-test/t/cache_temporal_4265.test
new file mode 100644
index 00000000000..6135438f023
--- /dev/null
+++ b/mysql-test/t/cache_temporal_4265.test
@@ -0,0 +1,11 @@
+#
+# MDEV-4265 5.5 is slower than 5.3 because of many str_to_datetime calls
+#
+--source include/have_debug.inc
+
+create table t1 (a date);
+insert t1 values ('2000-01-02'), ('2001-02-03'), ('2002-03-04');
+set debug_dbug='d,str_to_datetime_warn';
+select * from t1 where a > date_add('2000-01-01', interval 5 day);
+drop table t1;
+
diff --git a/sql/item.h b/sql/item.h
index bdf6fbe548e..901ebd3b6d8 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -4030,6 +4030,7 @@ public:
bool cache_value();
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
int save_in_field(Field *field, bool no_conversions);
+ Item_result cmp_type() const { return TIME_RESULT; }
void store_packed(longlong val_arg, Item *example);
/*
Having a clone_item method tells optimizer that this object
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 9a0ed877bf1..daa6c43830d 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -906,7 +906,8 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
}
if ((*is_null= item->null_value))
return ~(ulonglong) 0;
- if (cache_arg && item->const_item() && item->type() != Item::CACHE_ITEM)
+ 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);
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 3e3cd698efc..9b2db9e816e 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -491,6 +491,7 @@ public:
enum Item_result result_type () const { return STRING_RESULT; }
CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
+ Item_result cmp_type() const { return TIME_RESULT; }
String *val_str(String *str);
longlong val_int();
double val_real();
diff --git a/sql/sql_time.cc b/sql/sql_time.cc
index 57dbd979933..dadf579b2e7 100644
--- a/sql/sql_time.cc
+++ b/sql/sql_time.cc
@@ -302,6 +302,9 @@ str_to_datetime_with_warn(CHARSET_INFO *cs,
make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
str, length, flags & TIME_TIME_ONLY ?
MYSQL_TIMESTAMP_TIME : ts_type, NullS);
+ DBUG_EXECUTE_IF("str_to_datetime_warn",
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+ ER_YES, str););
return ts_type;
}