1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

support 'parallel' updates and rallback of whole statement in case of error in evalueting value which should be assigned

(BUG#1484)


mysql-test/r/variables.result:
  test of swaping variables
mysql-test/t/variables.test:
  test of swaping variables
sql/item_func.cc:
  new method of user variables to pre-fetch value
sql/item_func.h:
  new method of user variables to pre-fetch value
sql/set_var.cc:
  check() methods fetch & store value
sql/set_var.h:
  check() methods fetch & store value
This commit is contained in:
unknown
2003-10-24 17:28:32 +03:00
parent 5ee2807c49
commit ce2c46ddd6
6 changed files with 136 additions and 59 deletions

View File

@ -365,3 +365,27 @@ ERROR HY000: Unknown system variable 'xxxxxxxxxx'
select 1; select 1;
1 1
1 1
select @@global.max_user_connections,@@local.max_join_size;
@@global.max_user_connections @@session.max_join_size
100 200
set @svc=@@global.max_user_connections, @svj=@@local.max_join_size;
select @@global.max_user_connections,@@local.max_join_size;
@@global.max_user_connections @@session.max_join_size
100 200
set @@global.max_user_connections=111,@@local.max_join_size=222;
select @@global.max_user_connections,@@local.max_join_size;
@@global.max_user_connections @@session.max_join_size
111 222
set @@global.max_user_connections=@@local.max_join_size,@@local.max_join_size=@@global.max_user_connections;
select @@global.max_user_connections,@@local.max_join_size;
@@global.max_user_connections @@session.max_join_size
222 111
set @@global.max_user_connections=@svc, @@local.max_join_size=@svj;
select @@global.max_user_connections,@@local.max_join_size;
@@global.max_user_connections @@session.max_join_size
100 200
set @a=1, @b=2;
set @a=@b, @b=@a;
select @a, @b;
@a @b
2 1

View File

@ -263,3 +263,20 @@ drop table t1,t2;
--error 1193 --error 1193
select @@xxxxxxxxxx; select @@xxxxxxxxxx;
select 1; select 1;
#
# swap
#
select @@global.max_user_connections,@@local.max_join_size;
set @svc=@@global.max_user_connections, @svj=@@local.max_join_size;
select @@global.max_user_connections,@@local.max_join_size;
set @@global.max_user_connections=111,@@local.max_join_size=222;
select @@global.max_user_connections,@@local.max_join_size;
set @@global.max_user_connections=@@local.max_join_size,@@local.max_join_size=@@global.max_user_connections;
select @@global.max_user_connections,@@local.max_join_size;
set @@global.max_user_connections=@svc, @@local.max_join_size=@svj;
select @@global.max_user_connections,@@local.max_join_size;
set @a=1, @b=2;
set @a=@b, @b=@a;
select @a, @b;

View File

@ -2255,6 +2255,54 @@ String *user_var_entry::val_str(my_bool *null_value, String *str,
return(str); return(str);
} }
/*
This functions is invoked on SET @variable or @variable:= expression.
Evaluete (and check expression), store results.
SYNOPSYS
Item_func_set_user_var::check()
NOTES
For now it always return OK. All problem with value evalueting
will be catched by thd->net.report_error check in sql_set_variables().
RETURN
0 - OK.
*/
bool
Item_func_set_user_var::check()
{
bool res;
DBUG_ENTER("Item_func_set_user_var::check");
LINT_INIT(res);
switch (cached_result_type) {
case REAL_RESULT:
{
save_result.vreal= args[0]->val();
break;
}
case INT_RESULT:
{
save_result.vint= args[0]->val_int();
break;
}
break;
case STRING_RESULT:
{
save_result.vstr= args[0]->val_str(&value);
break;
}
case ROW_RESULT:
default:
// This case should never be choosen
DBUG_ASSERT(0);
break;
}
DBUG_RETURN(0);
}
/* /*
This functions is invoked on SET @variable or @variable:= expression. This functions is invoked on SET @variable or @variable:= expression.
@ -2282,29 +2330,27 @@ Item_func_set_user_var::update()
switch (cached_result_type) { switch (cached_result_type) {
case REAL_RESULT: case REAL_RESULT:
{ {
double value=args[0]->val(); res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal),
res= update_hash((void*) &value,sizeof(value), REAL_RESULT, REAL_RESULT, &my_charset_bin, DERIVATION_NONE);
&my_charset_bin, DERIVATION_NONE);
break; break;
} }
case INT_RESULT: case INT_RESULT:
{ {
longlong value=args[0]->val_int(); res= update_hash((void*) &save_result.vint, sizeof(save_result.vint),
res= update_hash((void*) &value, sizeof(longlong), INT_RESULT, INT_RESULT, &my_charset_bin, DERIVATION_NONE);
&my_charset_bin, DERIVATION_NONE);
break; break;
} }
break; break;
case STRING_RESULT: case STRING_RESULT:
{ {
String *tmp; if (!save_result.vstr) // Null value
tmp=args[0]->val_str(&value);
if (!tmp) // Null value
res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin, res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin,
DERIVATION_NONE); DERIVATION_NONE);
else else
res= update_hash((void*) tmp->ptr(), tmp->length(), STRING_RESULT, res= update_hash((void*) save_result.vstr->ptr(),
tmp->charset(), args[0]->collation.derivation); save_result.vstr->length(), STRING_RESULT,
save_result.vstr->charset(),
args[0]->collation.derivation);
break; break;
} }
case ROW_RESULT: case ROW_RESULT:
@ -2319,18 +2365,21 @@ Item_func_set_user_var::update()
double Item_func_set_user_var::val() double Item_func_set_user_var::val()
{ {
check();
update(); // Store expression update(); // Store expression
return entry->val(&null_value); return entry->val(&null_value);
} }
longlong Item_func_set_user_var::val_int() longlong Item_func_set_user_var::val_int()
{ {
check();
update(); // Store expression update(); // Store expression
return entry->val_int(&null_value); return entry->val_int(&null_value);
} }
String *Item_func_set_user_var::val_str(String *str) String *Item_func_set_user_var::val_str(String *str)
{ {
check();
update(); // Store expression update(); // Store expression
return entry->val_str(&null_value, str, decimals); return entry->val_str(&null_value, str, decimals);
} }

View File

@ -900,6 +900,14 @@ class Item_func_set_user_var :public Item_func
user_var_entry *entry; user_var_entry *entry;
char buffer[MAX_FIELD_WIDTH]; char buffer[MAX_FIELD_WIDTH];
String value; String value;
union
{
longlong vint;
double vreal;
String *vstr;
} save_result;
String save_buff;
public: public:
Item_func_set_user_var(LEX_STRING a,Item *b) Item_func_set_user_var(LEX_STRING a,Item *b)
@ -910,6 +918,7 @@ public:
String *val_str(String *str); String *val_str(String *str);
bool update_hash(void *ptr, uint length, enum Item_result type, bool update_hash(void *ptr, uint length, enum Item_result type,
CHARSET_INFO *cs, Derivation dv); CHARSET_INFO *cs, Derivation dv);
bool check();
bool update(); bool update();
enum Item_result result_type () const { return cached_result_type; } enum Item_result result_type () const { return cached_result_type; }
bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref); bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref);

View File

@ -716,6 +716,12 @@ struct show_var_st init_vars[]= {
}; };
bool sys_var::check(THD *thd, set_var *var)
{
var->save_result.ulonglong_value= var->value->val_int();
return 0;
}
/* /*
Functions to check and update variables Functions to check and update variables
*/ */
@ -964,12 +970,9 @@ static void fix_max_connections(THD *thd, enum_var_type type)
resize_thr_alarm(max_connections + max_insert_delayed_threads + 10); resize_thr_alarm(max_connections + max_insert_delayed_threads + 10);
} }
bool sys_var_long_ptr::update(THD *thd, set_var *var) bool sys_var_long_ptr::update(THD *thd, set_var *var)
{ {
ulonglong tmp= var->value->val_int(); ulonglong tmp= var->save_result.ulonglong_value;
if (thd->net.report_error)
return 1;
pthread_mutex_lock(&LOCK_global_system_variables); pthread_mutex_lock(&LOCK_global_system_variables);
if (option_limits) if (option_limits)
*value= (ulong) getopt_ull_limit_value(tmp, option_limits); *value= (ulong) getopt_ull_limit_value(tmp, option_limits);
@ -988,9 +991,7 @@ void sys_var_long_ptr::set_default(THD *thd, enum_var_type type)
bool sys_var_ulonglong_ptr::update(THD *thd, set_var *var) bool sys_var_ulonglong_ptr::update(THD *thd, set_var *var)
{ {
ulonglong tmp= var->value->val_int(); ulonglong tmp= var->save_result.ulonglong_value;
if (thd->net.report_error)
return 1;
pthread_mutex_lock(&LOCK_global_system_variables); pthread_mutex_lock(&LOCK_global_system_variables);
if (option_limits) if (option_limits)
*value= (ulonglong) getopt_ull_limit_value(tmp, option_limits); *value= (ulonglong) getopt_ull_limit_value(tmp, option_limits);
@ -1037,9 +1038,7 @@ byte *sys_var_enum::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
bool sys_var_thd_ulong::update(THD *thd, set_var *var) bool sys_var_thd_ulong::update(THD *thd, set_var *var)
{ {
ulonglong tmp= var->value->val_int(); ulonglong tmp= var->save_result.ulonglong_value;
if (thd->net.report_error)
return 1;
/* Don't use bigger value than given with --maximum-variable-name=.. */ /* Don't use bigger value than given with --maximum-variable-name=.. */
if ((ulong) tmp > max_system_variables.*offset) if ((ulong) tmp > max_system_variables.*offset)
@ -1078,9 +1077,7 @@ byte *sys_var_thd_ulong::value_ptr(THD *thd, enum_var_type type,
bool sys_var_thd_ha_rows::update(THD *thd, set_var *var) bool sys_var_thd_ha_rows::update(THD *thd, set_var *var)
{ {
ulonglong tmp= var->value->val_int(); ulonglong tmp= var->save_result.ulonglong_value;
if (thd->net.report_error)
return 1;
/* Don't use bigger value than given with --maximum-variable-name=.. */ /* Don't use bigger value than given with --maximum-variable-name=.. */
if ((ha_rows) tmp > max_system_variables.*offset) if ((ha_rows) tmp > max_system_variables.*offset)
@ -1123,12 +1120,9 @@ byte *sys_var_thd_ha_rows::value_ptr(THD *thd, enum_var_type type,
return (byte*) &(thd->variables.*offset); return (byte*) &(thd->variables.*offset);
} }
bool sys_var_thd_ulonglong::update(THD *thd, set_var *var) bool sys_var_thd_ulonglong::update(THD *thd, set_var *var)
{ {
ulonglong tmp= var->value->val_int(); ulonglong tmp= var->save_result.ulonglong_value;
if (thd->net.report_error)
return 1;
if ((ulonglong) tmp > max_system_variables.*offset) if ((ulonglong) tmp > max_system_variables.*offset)
tmp= max_system_variables.*offset; tmp= max_system_variables.*offset;
@ -1700,9 +1694,7 @@ void sys_var_collation_server::set_default(THD *thd, enum_var_type type)
bool sys_var_key_buffer_size::update(THD *thd, set_var *var) bool sys_var_key_buffer_size::update(THD *thd, set_var *var)
{ {
ulonglong tmp= var->value->val_int(); ulonglong tmp= var->save_result.ulonglong_value;
if (thd->net.report_error)
return 1;
NAMED_LIST *list; NAMED_LIST *list;
LEX_STRING *base_name= &var->base; LEX_STRING *base_name= &var->base;
@ -1799,11 +1791,7 @@ int set_var_collation_client::update(THD *thd)
bool sys_var_timestamp::update(THD *thd, set_var *var) bool sys_var_timestamp::update(THD *thd, set_var *var)
{ {
time_t tmp= (time_t) var->value->val_int(); thd->set_time((time_t) var->save_result.ulonglong_value);
if (thd->net.report_error)
return 1;
thd->set_time(tmp);
return 0; return 0;
} }
@ -1824,11 +1812,7 @@ byte *sys_var_timestamp::value_ptr(THD *thd, enum_var_type type,
bool sys_var_last_insert_id::update(THD *thd, set_var *var) bool sys_var_last_insert_id::update(THD *thd, set_var *var)
{ {
ulonglong tmp= var->value->val_int(); thd->insert_id(var->save_result.ulonglong_value);
if (thd->net.report_error)
return 1;
thd->insert_id(tmp);
return 0; return 0;
} }
@ -1843,11 +1827,7 @@ byte *sys_var_last_insert_id::value_ptr(THD *thd, enum_var_type type,
bool sys_var_insert_id::update(THD *thd, set_var *var) bool sys_var_insert_id::update(THD *thd, set_var *var)
{ {
ulonglong tmp= var->value->val_int(); thd->next_insert_id= var->save_result.ulonglong_value;
if (thd->net.report_error)
return 1;
thd->next_insert_id= tmp;
return 0; return 0;
} }
@ -1860,6 +1840,7 @@ byte *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type,
bool sys_var_pseudo_thread_id::check(THD *thd, set_var *var) bool sys_var_pseudo_thread_id::check(THD *thd, set_var *var)
{ {
var->save_result.ulonglong_value= var->value->val_int();
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (thd->master_access & SUPER_ACL) if (thd->master_access & SUPER_ACL)
return 0; return 0;
@ -1887,6 +1868,7 @@ bool sys_var_slave_skip_counter::check(THD *thd, set_var *var)
} }
pthread_mutex_unlock(&active_mi->rli.run_lock); pthread_mutex_unlock(&active_mi->rli.run_lock);
UNLOCK_ACTIVE_MI; UNLOCK_ACTIVE_MI;
var->save_result.ulong_value= (ulong) var->value->val_int();
return result; return result;
} }
@ -1903,7 +1885,7 @@ bool sys_var_slave_skip_counter::update(THD *thd, set_var *var)
if (!active_mi->rli.slave_running) if (!active_mi->rli.slave_running)
{ {
pthread_mutex_lock(&active_mi->rli.data_lock); pthread_mutex_lock(&active_mi->rli.data_lock);
active_mi->rli.slave_skip_counter= (ulong) var->value->val_int(); active_mi->rli.slave_skip_counter= var->save_result.ulong_value;
pthread_mutex_unlock(&active_mi->rli.data_lock); pthread_mutex_unlock(&active_mi->rli.data_lock);
} }
pthread_mutex_unlock(&active_mi->rli.run_lock); pthread_mutex_unlock(&active_mi->rli.run_lock);
@ -1914,21 +1896,13 @@ bool sys_var_slave_skip_counter::update(THD *thd, set_var *var)
bool sys_var_rand_seed1::update(THD *thd, set_var *var) bool sys_var_rand_seed1::update(THD *thd, set_var *var)
{ {
ulong tmp= (ulong) var->value->val_int(); thd->rand.seed1= (ulong) var->save_result.ulonglong_value;
if (thd->net.report_error)
return 1;
thd->rand.seed1= tmp;
return 0; return 0;
} }
bool sys_var_rand_seed2::update(THD *thd, set_var *var) bool sys_var_rand_seed2::update(THD *thd, set_var *var)
{ {
ulong tmp= (ulong) var->value->val_int(); thd->rand.seed2= (ulong) var->save_result.ulonglong_value;
if (thd->net.report_error)
return 1;
thd->rand.seed2= tmp;
return 0; return 0;
} }
@ -2153,6 +2127,8 @@ int sql_set_variables(THD *thd, List<set_var_base> *var_list)
if ((error=var->check(thd))) if ((error=var->check(thd)))
DBUG_RETURN(error); DBUG_RETURN(error);
} }
if (thd->net.report_error)
DBUG_RETURN(1);
it.rewind(); it.rewind();
while ((var=it++)) while ((var=it++))
error|= var->update(thd); // Returns 0, -1 or 1 error|= var->update(thd); // Returns 0, -1 or 1
@ -2215,7 +2191,8 @@ int set_var::update(THD *thd)
int set_var_user::check(THD *thd) int set_var_user::check(THD *thd)
{ {
return user_var_item->fix_fields(thd,0, (Item**) 0) ? -1 : 0; return (user_var_item->fix_fields(thd,0, (Item**) 0) ||
user_var_item->check()) ? -1 : 0;
} }

View File

@ -57,7 +57,7 @@ public:
:name(name_arg),after_update(func) :name(name_arg),after_update(func)
{} {}
virtual ~sys_var() {} virtual ~sys_var() {}
virtual bool check(THD *thd, set_var *var) { return 0; } virtual bool check(THD *thd, set_var *var);
bool check_enum(THD *thd, set_var *var, TYPELIB *enum_names); bool check_enum(THD *thd, set_var *var, TYPELIB *enum_names);
bool check_set(THD *thd, set_var *var, TYPELIB *enum_names); bool check_set(THD *thd, set_var *var, TYPELIB *enum_names);
virtual bool update(THD *thd, set_var *var)=0; virtual bool update(THD *thd, set_var *var)=0;
@ -656,6 +656,7 @@ public:
{ {
CHARSET_INFO *charset; CHARSET_INFO *charset;
ulong ulong_value; ulong ulong_value;
ulonglong ulonglong_value;
} save_result; } save_result;
LEX_STRING base; /* for structs */ LEX_STRING base; /* for structs */