summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/my_time.h2
-rw-r--r--sql/event_data_objects.cc27
-rw-r--r--sql/event_db_repository.cc10
-rw-r--r--sql/mysql_priv.h2
-rw-r--r--sql/strfunc.cc30
5 files changed, 60 insertions, 11 deletions
diff --git a/include/my_time.h b/include/my_time.h
index d0f2fc323d8..6f053e71000 100644
--- a/include/my_time.h
+++ b/include/my_time.h
@@ -100,6 +100,8 @@ int my_TIME_to_str(const MYSQL_TIME *l_time, char *to);
/*
The following must be sorted so that simple intervals comes first.
(get_interval_value() depends on this)
+ When updating this enum please update
+ LEX_STRING interval_type_to_name[] in sql/time.cc
*/
enum interval_type
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index 4b9aa43b14b..afd10350bb5 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -886,14 +886,29 @@ Event_queue_element::load_from_row(TABLE *table)
goto error;
/*
- In DB the values start from 1 but enum interval_type starts
- from 0
+ We load the interval type from disk as string and then map it to
+ an integer. This decouples the values of enum interval_type
+ and values actually stored on disk. Therefore the type can be
+ reordered without risking incompatibilities of data between versions.
*/
if (!table->field[ET_FIELD_TRANSIENT_INTERVAL]->is_null())
- interval= (interval_type) ((ulonglong)
- table->field[ET_FIELD_TRANSIENT_INTERVAL]->val_int() - 1);
- else
- interval= (interval_type) 0;
+ {
+ int i;
+ char buff[MAX_FIELD_WIDTH];
+ String str(buff, sizeof(buff), &my_charset_bin);
+ LEX_STRING tmp;
+
+ table->field[ET_FIELD_TRANSIENT_INTERVAL]->val_str(&str);
+ if (!(tmp.length= str.length()))
+ goto error;
+
+ tmp.str= str.c_ptr_safe();
+
+ i= find_string_in_array(interval_type_to_name, &tmp, system_charset_info);
+ if (i < 0)
+ goto error;
+ interval= (interval_type) i;
+ }
table->field[ET_FIELD_LAST_EXECUTED]->get_date(&last_executed,
TIME_NO_ZERO_DATE);
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index 464c26044c7..3d30aff669b 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -188,11 +188,11 @@ mysql_event_fill_row(THD *thd, TABLE *table, Event_parse_data *et,
fields[ET_FIELD_INTERVAL_EXPR]->store((longlong)et->expression, TRUE);
fields[ET_FIELD_TRANSIENT_INTERVAL]->set_notnull();
- /*
- In the enum (C) intervals start from 0 but in mysql enum valid values
- start from 1. Thus +1 offset is needed!
- */
- fields[ET_FIELD_TRANSIENT_INTERVAL]->store((longlong)et->interval+1, TRUE);
+
+ fields[ET_FIELD_TRANSIENT_INTERVAL]->
+ store(interval_type_to_name[et->interval].str,
+ interval_type_to_name[et->interval].length,
+ scs);
fields[ET_FIELD_EXECUTE_AT]->set_null();
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 339ca9d965a..89a3a30c338 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1481,6 +1481,8 @@ uint find_type2(TYPELIB *lib, const char *find, uint length, CHARSET_INFO *cs);
void unhex_type2(TYPELIB *lib);
uint check_word(TYPELIB *lib, const char *val, const char *end,
const char **end_of_word);
+int find_string_in_array(LEX_STRING * const haystack, LEX_STRING * const needle,
+ CHARSET_INFO *cs);
bool is_keyword(const char *name, uint len);
diff --git a/sql/strfunc.cc b/sql/strfunc.cc
index 2525703172f..ef769a5b16e 100644
--- a/sql/strfunc.cc
+++ b/sql/strfunc.cc
@@ -312,3 +312,33 @@ outp:
return (uint32) (to - to_start);
}
+
+
+/*
+ Searches for a LEX_STRING in an LEX_STRING array.
+
+ SYNOPSIS
+ find_string_in_array()
+ heap The array
+ needle The string to search for
+
+ NOTE
+ The last LEX_STRING in the array should have str member set to NULL
+
+ RETURN VALUES
+ -1 Not found
+ >=0 Ordinal position
+*/
+
+int find_string_in_array(LEX_STRING * const haystack, LEX_STRING * const needle,
+ CHARSET_INFO * const cs)
+{
+ const LEX_STRING *pos;
+ for (pos= haystack; pos->str; pos++)
+ if (!cs->coll->strnncollsp(cs, (uchar *) pos->str, pos->length,
+ (uchar *) needle->str, needle->length, 0))
+ {
+ return (pos - haystack);
+ }
+ return -1;
+}