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;
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
select @@xxxxxxxxxx;
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);
}
/*
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.
@ -2282,29 +2330,27 @@ Item_func_set_user_var::update()
switch (cached_result_type) {
case REAL_RESULT:
{
double value=args[0]->val();
res= update_hash((void*) &value,sizeof(value), REAL_RESULT,
&my_charset_bin, DERIVATION_NONE);
res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal),
REAL_RESULT, &my_charset_bin, DERIVATION_NONE);
break;
}
case INT_RESULT:
{
longlong value=args[0]->val_int();
res= update_hash((void*) &value, sizeof(longlong), INT_RESULT,
&my_charset_bin, DERIVATION_NONE);
res= update_hash((void*) &save_result.vint, sizeof(save_result.vint),
INT_RESULT, &my_charset_bin, DERIVATION_NONE);
break;
}
break;
case STRING_RESULT:
{
String *tmp;
tmp=args[0]->val_str(&value);
if (!tmp) // Null value
if (!save_result.vstr) // Null value
res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin,
DERIVATION_NONE);
else
res= update_hash((void*) tmp->ptr(), tmp->length(), STRING_RESULT,
tmp->charset(), args[0]->collation.derivation);
res= update_hash((void*) save_result.vstr->ptr(),
save_result.vstr->length(), STRING_RESULT,
save_result.vstr->charset(),
args[0]->collation.derivation);
break;
}
case ROW_RESULT:
@ -2319,18 +2365,21 @@ Item_func_set_user_var::update()
double Item_func_set_user_var::val()
{
check();
update(); // Store expression
return entry->val(&null_value);
}
longlong Item_func_set_user_var::val_int()
{
check();
update(); // Store expression
return entry->val_int(&null_value);
}
String *Item_func_set_user_var::val_str(String *str)
{
check();
update(); // Store expression
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;
char buffer[MAX_FIELD_WIDTH];
String value;
union
{
longlong vint;
double vreal;
String *vstr;
} save_result;
String save_buff;
public:
Item_func_set_user_var(LEX_STRING a,Item *b)
@ -910,6 +918,7 @@ public:
String *val_str(String *str);
bool update_hash(void *ptr, uint length, enum Item_result type,
CHARSET_INFO *cs, Derivation dv);
bool check();
bool update();
enum Item_result result_type () const { return cached_result_type; }
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
*/
@ -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);
}
bool sys_var_long_ptr::update(THD *thd, set_var *var)
{
ulonglong tmp= var->value->val_int();
if (thd->net.report_error)
return 1;
ulonglong tmp= var->save_result.ulonglong_value;
pthread_mutex_lock(&LOCK_global_system_variables);
if (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)
{
ulonglong tmp= var->value->val_int();
if (thd->net.report_error)
return 1;
ulonglong tmp= var->save_result.ulonglong_value;
pthread_mutex_lock(&LOCK_global_system_variables);
if (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)
{
ulonglong tmp= var->value->val_int();
if (thd->net.report_error)
return 1;
ulonglong tmp= var->save_result.ulonglong_value;
/* Don't use bigger value than given with --maximum-variable-name=.. */
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)
{
ulonglong tmp= var->value->val_int();
if (thd->net.report_error)
return 1;
ulonglong tmp= var->save_result.ulonglong_value;
/* Don't use bigger value than given with --maximum-variable-name=.. */
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);
}
bool sys_var_thd_ulonglong::update(THD *thd, set_var *var)
{
ulonglong tmp= var->value->val_int();
if (thd->net.report_error)
return 1;
ulonglong tmp= var->save_result.ulonglong_value;
if ((ulonglong) 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)
{
ulonglong tmp= var->value->val_int();
if (thd->net.report_error)
return 1;
ulonglong tmp= var->save_result.ulonglong_value;
NAMED_LIST *list;
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)
{
time_t tmp= (time_t) var->value->val_int();
if (thd->net.report_error)
return 1;
thd->set_time(tmp);
thd->set_time((time_t) var->save_result.ulonglong_value);
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)
{
ulonglong tmp= var->value->val_int();
if (thd->net.report_error)
return 1;
thd->insert_id(tmp);
thd->insert_id(var->save_result.ulonglong_value);
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)
{
ulonglong tmp= var->value->val_int();
if (thd->net.report_error)
return 1;
thd->next_insert_id= tmp;
thd->next_insert_id= var->save_result.ulonglong_value;
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)
{
var->save_result.ulonglong_value= var->value->val_int();
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (thd->master_access & SUPER_ACL)
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);
UNLOCK_ACTIVE_MI;
var->save_result.ulong_value= (ulong) var->value->val_int();
return result;
}
@ -1903,7 +1885,7 @@ bool sys_var_slave_skip_counter::update(THD *thd, set_var *var)
if (!active_mi->rli.slave_running)
{
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.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)
{
ulong tmp= (ulong) var->value->val_int();
if (thd->net.report_error)
return 1;
thd->rand.seed1= tmp;
thd->rand.seed1= (ulong) var->save_result.ulonglong_value;
return 0;
}
bool sys_var_rand_seed2::update(THD *thd, set_var *var)
{
ulong tmp= (ulong) var->value->val_int();
if (thd->net.report_error)
return 1;
thd->rand.seed2= tmp;
thd->rand.seed2= (ulong) var->save_result.ulonglong_value;
return 0;
}
@ -2153,6 +2127,8 @@ int sql_set_variables(THD *thd, List<set_var_base> *var_list)
if ((error=var->check(thd)))
DBUG_RETURN(error);
}
if (thd->net.report_error)
DBUG_RETURN(1);
it.rewind();
while ((var=it++))
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)
{
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)
{}
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_set(THD *thd, set_var *var, TYPELIB *enum_names);
virtual bool update(THD *thd, set_var *var)=0;
@ -656,6 +656,7 @@ public:
{
CHARSET_INFO *charset;
ulong ulong_value;
ulonglong ulonglong_value;
} save_result;
LEX_STRING base; /* for structs */