summaryrefslogtreecommitdiff
path: root/sql/sys_vars.ic
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2017-03-30 12:57:31 +0300
committerAleksey Midenkov <midenok@gmail.com>2017-05-05 20:36:34 +0300
commit9e9af76eaf4eec4f105e029975ec5a142ec7e8f2 (patch)
treed03fcddae7dc34bf47e250d8697b1da8eb415015 /sql/sys_vars.ic
parentb240671c04248400ec7954e56dacfeab45ee5343 (diff)
downloadmariadb-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.ic162
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; }
+};