diff options
author | Aleksey Midenkov <midenok@gmail.com> | 2017-03-30 12:57:31 +0300 |
---|---|---|
committer | Aleksey Midenkov <midenok@gmail.com> | 2017-05-05 20:36:34 +0300 |
commit | 9e9af76eaf4eec4f105e029975ec5a142ec7e8f2 (patch) | |
tree | d03fcddae7dc34bf47e250d8697b1da8eb415015 /sql/sys_vars.ic | |
parent | b240671c04248400ec7954e56dacfeab45ee5343 (diff) | |
download | mariadb-git-9e9af76eaf4eec4f105e029975ec5a142ec7e8f2.tar.gz |
SQL: vers_current_time refactoring [closes #117]
* session sysvars;
* moved value parsing to set variable phase;
* renamed 'temporal_current_timestamp' to 'vers_current_time'.
Diffstat (limited to 'sql/sys_vars.ic')
-rw-r--r-- | sql/sys_vars.ic | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/sql/sys_vars.ic b/sql/sys_vars.ic index 780450b484b..76bf8631630 100644 --- a/sql/sys_vars.ic +++ b/sql/sys_vars.ic @@ -2485,3 +2485,165 @@ public: bool global_update(THD *thd, set_var *var); uchar *global_value_ptr(THD *thd, const LEX_STRING *base); }; + + +class Sys_var_vers_asof: public sys_var +{ +public: + Sys_var_vers_asof( + const char *name_arg, + const char *comment, + int flag_args, + ptrdiff_t off, + size_t size, + CMD_LINE getopt, + enum charset_enum is_os_charset_arg, + const char *def_val, + on_check_function on_check_func=0, + on_update_function on_update_func=0) : + sys_var( + &all_sys_vars, + name_arg, + comment, + flag_args, + off, + getopt.id, + getopt.arg_type, + SHOW_CHAR, + (intptr) def_val, + 0, + VARIABLE_NOT_IN_BINLOG, + on_check_func, + on_update_func, + 0) + { + option.var_type|= GET_STR; + if (global_update(def_val)) + { + DBUG_ASSERT(false); + } + } + + bool do_check(THD *thd, set_var *var) + { return false; } + + bool update(String &in, st_vers_current_time &out) + { + if (in.length() == 3 && + 0 == my_strcasecmp( + in.charset(), + "ALL", + in.ptr())) + { + out.type= FOR_SYSTEM_TIME_ALL; + } + else if (in.length() == 3 && + 0 == my_strcasecmp( + in.charset(), + "NOW", + in.ptr())) + { + out.type= FOR_SYSTEM_TIME_UNSPECIFIED; + } + else + { + MYSQL_TIME_STATUS status; + if (str_to_datetime( + in.ptr(), + in.length(), + &out.ltime, + flags, + &status) || + out.ltime.time_type != MYSQL_TIMESTAMP_DATETIME || + (status.warnings & ~MYSQL_TIME_NOTE_TRUNCATED) != 0) + { + return true; + } + out.type= FOR_SYSTEM_TIME_AS_OF; + } + return false; + } + bool update(THD *thd, set_var *var, st_vers_current_time &out) + { + Item *item= var->value; + + switch (item->result_type()) + { + case TIME_RESULT: + { + if (item->get_date(&out.ltime, 0)) + break; + out.type= FOR_SYSTEM_TIME_AS_OF; + return false; + } + + case STRING_RESULT: + { + String *str= item->val_str(); + if (!str || update(*str, out)) + break; + return false; + } + default: + break; + } + String *str= item->val_str(); + const char *cstr= str ? str->c_ptr_safe() : "NULL"; + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name.str, cstr); + return true; + } + bool global_update(const char *in) + { + String s(in, &my_charset_utf8_general_ci); + return update(s, global_var(st_vers_current_time)); + } + bool option_updated() + { + return global_update(global_var(st_vers_current_time).str_value); + } + bool global_update(THD *thd, set_var *var) + { + return update(thd, var, global_var(st_vers_current_time)); + } + bool session_update(THD *thd, set_var *var) + { + return update(thd, var, session_var(thd, st_vers_current_time)); + } + uchar *valptr(THD *thd, st_vers_current_time &val) + { + switch (val.type) + { + case FOR_SYSTEM_TIME_UNSPECIFIED: + return (uchar*) thd->strdup("NOW"); + case FOR_SYSTEM_TIME_ALL: + return (uchar*) thd->strdup("ALL"); + case FOR_SYSTEM_TIME_AS_OF: + { + uchar *buf= (uchar*) thd->alloc(MAX_DATE_STRING_REP_LENGTH); + if (buf) + { + if (!my_datetime_to_str(&val.ltime, (char*) buf, 6)) + { + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "vers_current_time", "NULL (wrong datetime)"); + return (uchar*) thd->strdup("Error: wrong datetime"); + } + } + return buf; + } + default: + break; + } + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "vers_current_time", "NULL (wrong range type)"); + return (uchar*) thd->strdup("Error: wrong range type"); + } + void session_save_default(THD *thd, set_var *var) + { DBUG_ASSERT(false); } + void global_save_default(THD *thd, set_var *var) + { DBUG_ASSERT(false); } + uchar *session_value_ptr(THD *thd, const LEX_STRING *base) + { return valptr(thd, session_var(thd, st_vers_current_time)); } + uchar *global_value_ptr(THD *thd, const LEX_STRING *base) + { return valptr(thd, global_var(st_vers_current_time)); } + uchar *default_value_ptr(THD *thd) + { return (uchar *)option.def_value; } +}; |