mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
SET STATEMENT timestamp=xxx ....
fix sys_var->is_default() method (that was using default_val property in a global sys_var object to track per-session state): * move timestamp to a dedicated Sys_var_timestamp class (in fact, rename Sys_var_session_special_double to Sys_var_timestamp) * make session_is_default a virtual method with a special implementation for timestamps * other variables don't have a special behavior for default values and can have session_is_default() to be always false.
This commit is contained in:
@ -147,7 +147,7 @@ sys_var::sys_var(sys_var_chain *chain, const char *name_arg,
|
|||||||
flags(flags_arg), show_val_type(show_val_type_arg),
|
flags(flags_arg), show_val_type(show_val_type_arg),
|
||||||
guard(lock), offset(off), on_check(on_check_func), on_update(on_update_func),
|
guard(lock), offset(off), on_check(on_check_func), on_update(on_update_func),
|
||||||
deprecation_substitute(substitute),
|
deprecation_substitute(substitute),
|
||||||
is_os_charset(FALSE), default_val(FALSE)
|
is_os_charset(FALSE)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
There is a limitation in handle_options() related to short options:
|
There is a limitation in handle_options() related to short options:
|
||||||
@ -790,7 +790,6 @@ int set_var::light_check(THD *thd)
|
|||||||
*/
|
*/
|
||||||
int set_var::update(THD *thd)
|
int set_var::update(THD *thd)
|
||||||
{
|
{
|
||||||
var->set_is_default(value == 0);
|
|
||||||
return value ? var->update(thd, this) : var->set_default(thd, this);
|
return value ? var->update(thd, this) : var->set_default(thd, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,6 @@ protected:
|
|||||||
on_update_function on_update;
|
on_update_function on_update;
|
||||||
const char *const deprecation_substitute;
|
const char *const deprecation_substitute;
|
||||||
bool is_os_charset; ///< true if the value is in character_set_filesystem
|
bool is_os_charset; ///< true if the value is in character_set_filesystem
|
||||||
bool default_val;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
sys_var(sys_var_chain *chain, const char *name_arg, const char *comment,
|
sys_var(sys_var_chain *chain, const char *name_arg, const char *comment,
|
||||||
@ -194,8 +193,15 @@ public:
|
|||||||
return insert_dynamic(array, (uchar*)&option);
|
return insert_dynamic(array, (uchar*)&option);
|
||||||
}
|
}
|
||||||
void do_deprecated_warning(THD *thd);
|
void do_deprecated_warning(THD *thd);
|
||||||
bool is_default() { return default_val; }
|
/**
|
||||||
void set_is_default(bool def) { default_val= def; }
|
whether session value of a sysvar is a default one.
|
||||||
|
|
||||||
|
in this simple implementation we don't distinguish between default
|
||||||
|
and non-default values. for most variables it's ok, they don't treat
|
||||||
|
default values specially. this method is overwritten in descendant
|
||||||
|
classes as necessary.
|
||||||
|
*/
|
||||||
|
virtual bool session_is_default(THD *thd) { return false; }
|
||||||
|
|
||||||
virtual uchar *default_value_ptr(THD *thd)
|
virtual uchar *default_value_ptr(THD *thd)
|
||||||
{ return (uchar*)&option.def_value; }
|
{ return (uchar*)&option.def_value; }
|
||||||
|
@ -2663,7 +2663,7 @@ mysql_execute_command(THD *thd)
|
|||||||
lex->free_arena_for_set_stmt();
|
lex->free_arena_for_set_stmt();
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (v->var->is_default())
|
if (v->var->session_is_default(thd))
|
||||||
o= new set_var(v->type, v->var, &v->base, NULL);
|
o= new set_var(v->type, v->var, &v->base, NULL);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3708,28 +3708,11 @@ static Sys_var_harows Sys_select_limit(
|
|||||||
SESSION_VAR(select_limit), NO_CMD_LINE,
|
SESSION_VAR(select_limit), NO_CMD_LINE,
|
||||||
VALID_RANGE(0, HA_POS_ERROR), DEFAULT(HA_POS_ERROR), BLOCK_SIZE(1));
|
VALID_RANGE(0, HA_POS_ERROR), DEFAULT(HA_POS_ERROR), BLOCK_SIZE(1));
|
||||||
|
|
||||||
static bool update_timestamp(THD *thd, set_var *var)
|
static Sys_var_timestamp Sys_timestamp(
|
||||||
{
|
|
||||||
if (var->value)
|
|
||||||
{
|
|
||||||
my_hrtime_t hrtime = { hrtime_from_time(var->save_result.double_value) };
|
|
||||||
thd->set_time(hrtime);
|
|
||||||
}
|
|
||||||
else // SET timestamp=DEFAULT
|
|
||||||
thd->user_time.val= 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
static double read_timestamp(THD *thd)
|
|
||||||
{
|
|
||||||
return thd->start_time +
|
|
||||||
thd->start_time_sec_part/(double)TIME_SECOND_PART_FACTOR;
|
|
||||||
}
|
|
||||||
static Sys_var_session_special_double Sys_timestamp(
|
|
||||||
"timestamp", "Set the time for this client",
|
"timestamp", "Set the time for this client",
|
||||||
sys_var::ONLY_SESSION, NO_CMD_LINE,
|
sys_var::ONLY_SESSION, NO_CMD_LINE,
|
||||||
VALID_RANGE(0, TIMESTAMP_MAX_VALUE),
|
VALID_RANGE(0, TIMESTAMP_MAX_VALUE),
|
||||||
NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(0),
|
NO_MUTEX_GUARD, IN_BINLOG);
|
||||||
ON_UPDATE(update_timestamp), ON_READ(read_timestamp));
|
|
||||||
|
|
||||||
static bool update_last_insert_id(THD *thd, set_var *var)
|
static bool update_last_insert_id(THD *thd, set_var *var)
|
||||||
{
|
{
|
||||||
|
@ -1657,46 +1657,57 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Sys_var_session_special_double: public Sys_var_double
|
/*
|
||||||
{
|
Dedicated class because of a weird behavior of a default value.
|
||||||
typedef bool (*session_special_update_function)(THD *thd, set_var *var);
|
Assigning timestamp to itself
|
||||||
typedef double (*session_special_read_function)(THD *thd);
|
|
||||||
|
|
||||||
session_special_read_function read_func;
|
SET @@timestamp = @@timestamp
|
||||||
session_special_update_function update_func;
|
|
||||||
|
make it non-default and stops the time flow.
|
||||||
|
*/
|
||||||
|
class Sys_var_timestamp: public Sys_var_double
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
Sys_var_session_special_double(const char *name_arg,
|
Sys_var_timestamp(const char *name_arg,
|
||||||
const char *comment, int flag_args,
|
const char *comment, int flag_args,
|
||||||
CMD_LINE getopt,
|
CMD_LINE getopt,
|
||||||
double min_val, double max_val,
|
double min_val, double max_val,
|
||||||
PolyLock *lock, enum binlog_status_enum binlog_status_arg,
|
PolyLock *lock, enum binlog_status_enum binlog_status_arg)
|
||||||
on_check_function on_check_func,
|
|
||||||
session_special_update_function update_func_arg,
|
|
||||||
session_special_read_function read_func_arg,
|
|
||||||
const char *substitute=0)
|
|
||||||
: Sys_var_double(name_arg, comment, flag_args, 0,
|
: Sys_var_double(name_arg, comment, flag_args, 0,
|
||||||
sizeof(double), getopt, min_val,
|
sizeof(double), getopt, min_val,
|
||||||
max_val, 0, lock, binlog_status_arg, on_check_func, 0,
|
max_val, 0, lock, binlog_status_arg)
|
||||||
substitute),
|
|
||||||
read_func(read_func_arg), update_func(update_func_arg)
|
|
||||||
{
|
{
|
||||||
SYSVAR_ASSERT(scope() == ONLY_SESSION);
|
SYSVAR_ASSERT(scope() == ONLY_SESSION);
|
||||||
SYSVAR_ASSERT(getopt.id < 0); // NO_CMD_LINE, because the offset is fake
|
SYSVAR_ASSERT(getopt.id < 0); // NO_CMD_LINE, because the offset is fake
|
||||||
}
|
}
|
||||||
bool session_update(THD *thd, set_var *var)
|
bool session_update(THD *thd, set_var *var)
|
||||||
{ return update_func(thd, var); }
|
{
|
||||||
|
if (var->value)
|
||||||
|
{
|
||||||
|
my_hrtime_t hrtime = { hrtime_from_time(var->save_result.double_value) };
|
||||||
|
thd->set_time(hrtime);
|
||||||
|
}
|
||||||
|
else // SET timestamp=DEFAULT
|
||||||
|
thd->user_time.val= 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
bool global_update(THD *thd, set_var *var)
|
bool global_update(THD *thd, set_var *var)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(FALSE);
|
DBUG_ASSERT(FALSE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
bool session_is_default(THD *thd)
|
||||||
|
{
|
||||||
|
return thd->user_time.val == 0;
|
||||||
|
}
|
||||||
void session_save_default(THD *thd, set_var *var)
|
void session_save_default(THD *thd, set_var *var)
|
||||||
{ var->value= 0; }
|
{ var->value= 0; }
|
||||||
void global_save_default(THD *thd, set_var *var)
|
void global_save_default(THD *thd, set_var *var)
|
||||||
{ DBUG_ASSERT(FALSE); }
|
{ DBUG_ASSERT(FALSE); }
|
||||||
uchar *session_value_ptr(THD *thd, const LEX_STRING *base)
|
uchar *session_value_ptr(THD *thd, const LEX_STRING *base)
|
||||||
{
|
{
|
||||||
thd->sys_var_tmp.double_value= read_func(thd);
|
thd->sys_var_tmp.double_value= thd->start_time +
|
||||||
|
thd->start_time_sec_part/(double)TIME_SECOND_PART_FACTOR;
|
||||||
return (uchar*) &thd->sys_var_tmp.double_value;
|
return (uchar*) &thd->sys_var_tmp.double_value;
|
||||||
}
|
}
|
||||||
uchar *global_value_ptr(THD *thd, const LEX_STRING *base)
|
uchar *global_value_ptr(THD *thd, const LEX_STRING *base)
|
||||||
|
Reference in New Issue
Block a user