mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
Merge gbichot@213.136.52.20:/home/bk/mysql-4.1
into mysql.com:/home/mysql_src/mysql-4.1
This commit is contained in:
commit
7722d99eb2
5 changed files with 149 additions and 48 deletions
|
@ -21,6 +21,7 @@ set @q:='abc';
|
|||
insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'));
|
||||
set @a:=5;
|
||||
insert into t1 values (@a),(@a);
|
||||
insert into t1 values (@a),(@a),(@a*5);
|
||||
select * from t1;
|
||||
n
|
||||
12345678901234
|
||||
|
@ -45,6 +46,36 @@ abcn1
|
|||
abcn1n2
|
||||
5
|
||||
5
|
||||
NULL
|
||||
NULL
|
||||
NULL
|
||||
select * from t1;
|
||||
n
|
||||
12345678901234
|
||||
-12345678901234
|
||||
0
|
||||
-1
|
||||
12.5
|
||||
-12.5
|
||||
This is a test
|
||||
|
||||
abc'def
|
||||
abc\def
|
||||
abc'def
|
||||
NULL
|
||||
NULL
|
||||
0
|
||||
1
|
||||
2
|
||||
5
|
||||
abc
|
||||
abcn1
|
||||
abcn1n2
|
||||
5
|
||||
5
|
||||
NULL
|
||||
NULL
|
||||
NULL
|
||||
show binlog events from 141;
|
||||
Log_name Pos Event_type Server_id Orig_log_pos Info
|
||||
slave-bin.000001 141 User var 2 141 @i1=12345678901234
|
||||
|
@ -63,13 +94,16 @@ slave-bin.000001 719 User var 2 719 @s5='abc'def'
|
|||
slave-bin.000001 761 Query 1 761 use `test`; insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5)
|
||||
slave-bin.000001 851 User var 2 851 @n1=NULL
|
||||
slave-bin.000001 877 Query 1 877 use `test`; insert into t1 values (@n1)
|
||||
slave-bin.000001 939 Query 1 939 use `test`; insert into t1 values (@n2)
|
||||
slave-bin.000001 1001 Query 1 1001 use `test`; insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1)
|
||||
slave-bin.000001 1089 User var 2 1089 @a=2
|
||||
slave-bin.000001 1131 Query 1 1131 use `test`; insert into t1 values (@a+(@b:=@a+1))
|
||||
slave-bin.000001 1203 User var 2 1203 @q='abc'
|
||||
slave-bin.000001 1240 Query 1 1240 use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'))
|
||||
slave-bin.000001 1344 User var 2 1344 @a=5
|
||||
slave-bin.000001 1386 Query 1 1386 use `test`; insert into t1 values (@a),(@a)
|
||||
slave-bin.000001 939 User var 2 939 @n2=NULL
|
||||
slave-bin.000001 965 Query 1 965 use `test`; insert into t1 values (@n2)
|
||||
slave-bin.000001 1027 Query 1 1027 use `test`; insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1)
|
||||
slave-bin.000001 1115 User var 2 1115 @a=2
|
||||
slave-bin.000001 1157 Query 1 1157 use `test`; insert into t1 values (@a+(@b:=@a+1))
|
||||
slave-bin.000001 1229 User var 2 1229 @q='abc'
|
||||
slave-bin.000001 1266 Query 1 1266 use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'))
|
||||
slave-bin.000001 1370 User var 2 1370 @a=5
|
||||
slave-bin.000001 1412 Query 1 1412 use `test`; insert into t1 values (@a),(@a)
|
||||
slave-bin.000001 1478 User var 2 1478 @a=NULL
|
||||
slave-bin.000001 1503 Query 1 1503 use `test`; insert into t1 values (@a),(@a),(@a*5)
|
||||
drop table t1;
|
||||
stop slave;
|
||||
|
|
|
@ -5,6 +5,10 @@ set @a := connection_id() + 3;
|
|||
select @a - connection_id();
|
||||
@a - connection_id()
|
||||
3
|
||||
set @b := 1;
|
||||
select @b;
|
||||
@b
|
||||
1
|
||||
CREATE TABLE t1 ( i int not null, v int not null,index (i));
|
||||
insert into t1 values (1,1),(1,3),(2,1);
|
||||
create table t2 (i int not null, unique (i));
|
||||
|
|
|
@ -29,13 +29,16 @@ insert into t1 values (@i1), (@i2), (@i3), (@i4);
|
|||
insert into t1 values (@r1), (@r2);
|
||||
insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5);
|
||||
insert into t1 values (@n1);
|
||||
insert into t1 values (@n2);
|
||||
insert into t1 values (@n2); # not explicitely set before
|
||||
insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1);
|
||||
insert into t1 values (@a+(@b:=@a+1));
|
||||
set @q:='abc';
|
||||
insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'));
|
||||
set @a:=5;
|
||||
insert into t1 values (@a),(@a);
|
||||
connection master1; # see if variable is reset in binlog when thread changes
|
||||
insert into t1 values (@a),(@a),(@a*5);
|
||||
select * from t1;
|
||||
save_master_pos;
|
||||
connection slave;
|
||||
sync_with_master;
|
||||
|
|
|
@ -8,6 +8,9 @@ set @a := foo;
|
|||
set @a := connection_id() + 3;
|
||||
select @a - connection_id();
|
||||
|
||||
set @b := 1;
|
||||
select @b;
|
||||
|
||||
# Check using and setting variables with SELECT DISTINCT
|
||||
|
||||
CREATE TABLE t1 ( i int not null, v int not null,index (i));
|
||||
|
|
135
sql/item_func.cc
135
sql/item_func.cc
|
@ -2071,6 +2071,16 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
|
|||
entry->value=0;
|
||||
entry->length=0;
|
||||
entry->update_query_id=0;
|
||||
/*
|
||||
If we are here, we were called from a SET or a query which sets a
|
||||
variable. Imagine it is this:
|
||||
INSERT INTO t SELECT @a:=10, @a:=@a+1.
|
||||
Then when we have a Item_func_get_user_var (because of the @a+1) so we
|
||||
think we have to write the value of @a to the binlog. But before that,
|
||||
we have a Item_func_set_user_var to create @a (@a:=10), in this we mark
|
||||
the variable as "already logged" (line below) so that it won't be logged
|
||||
by Item_func_get_user_var (because that's not necessary).
|
||||
*/
|
||||
entry->used_query_id=current_thd->query_id;
|
||||
entry->type=STRING_RESULT;
|
||||
memcpy(entry->name.str, name.str, name.length+1);
|
||||
|
@ -2083,7 +2093,10 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
|
|||
return entry;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
When a user variable is updated (in a SET command or a query like SELECT @a:=
|
||||
).
|
||||
*/
|
||||
|
||||
bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables,
|
||||
Item **ref)
|
||||
|
@ -2093,6 +2106,11 @@ bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables,
|
|||
!(entry= get_variable(&thd->user_vars, name, 1)))
|
||||
return 1;
|
||||
entry->type= cached_result_type;
|
||||
/*
|
||||
Remember the last query which updated it, this way a query can later know
|
||||
if this variable is a constant item in the query (it is if update_query_id
|
||||
is different from query_id).
|
||||
*/
|
||||
entry->update_query_id=thd->query_id;
|
||||
return 0;
|
||||
}
|
||||
|
@ -2315,53 +2333,92 @@ longlong Item_func_get_user_var::val_int()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
When a user variable is invoked from an update query (INSERT, UPDATE etc),
|
||||
stores this variable and its value in thd->user_var_events, so that it can be
|
||||
written to the binlog (will be written just before the query is written, see
|
||||
log.cc).
|
||||
*/
|
||||
|
||||
void Item_func_get_user_var::fix_length_and_dec()
|
||||
{
|
||||
BINLOG_USER_VAR_EVENT *user_var_event;
|
||||
THD *thd=current_thd;
|
||||
BINLOG_USER_VAR_EVENT *user_var_event;
|
||||
maybe_null=1;
|
||||
decimals=NOT_FIXED_DEC;
|
||||
max_length=MAX_BLOB_WIDTH;
|
||||
|
||||
if ((var_entry= get_variable(&thd->user_vars, name, 0)))
|
||||
{
|
||||
if (opt_bin_log && is_update_query(thd->lex.sql_command) &&
|
||||
var_entry->used_query_id != thd->query_id)
|
||||
{
|
||||
uint size;
|
||||
/*
|
||||
First we need to store value of var_entry, when the next situation
|
||||
appers:
|
||||
> set @a:=1;
|
||||
> insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1);
|
||||
We have to write to binlog value @a= 1;
|
||||
*/
|
||||
size= ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)) + var_entry->length;
|
||||
if (!(user_var_event= (BINLOG_USER_VAR_EVENT *) thd->alloc(size)))
|
||||
goto err;
|
||||
var_entry= get_variable(&thd->user_vars, name, 0);
|
||||
|
||||
user_var_event->value= (char*) user_var_event +
|
||||
ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT));
|
||||
user_var_event->user_var_event= var_entry;
|
||||
user_var_event->type= var_entry->type;
|
||||
user_var_event->charset_number= var_entry->collation.collation->number;
|
||||
if (!var_entry->value)
|
||||
{
|
||||
/* NULL value*/
|
||||
user_var_event->length= 0;
|
||||
user_var_event->value= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
user_var_event->length= var_entry->length;
|
||||
memcpy(user_var_event->value, var_entry->value,
|
||||
var_entry->length);
|
||||
}
|
||||
var_entry->used_query_id= thd->query_id;
|
||||
if (insert_dynamic(&thd->user_var_events, (gptr) &user_var_event))
|
||||
goto err;
|
||||
}
|
||||
if (!(opt_bin_log && is_update_query(thd->lex.sql_command)))
|
||||
return;
|
||||
|
||||
if (!var_entry)
|
||||
{
|
||||
/*
|
||||
If the variable does not exist, it's NULL, but we want to create it so
|
||||
that it gets into the binlog (if it didn't, the slave could be
|
||||
influenced by a variable of the same name previously set by another
|
||||
thread).
|
||||
We create it like if it had been explicitely set with SET before.
|
||||
The 'new' mimicks what sql_yacc.yy does when 'SET @a=10;'.
|
||||
sql_set_variables() is what is called from 'case SQLCOM_SET_OPTION'
|
||||
in dispatch_command()). Instead of building a one-element list to pass to
|
||||
sql_set_variables(), we could instead manually call check() and update();
|
||||
this would save memory and time; but calling sql_set_variables() makes one
|
||||
unique place to maintain (sql_set_variables()).
|
||||
*/
|
||||
|
||||
List<set_var_base> tmp_var_list;
|
||||
tmp_var_list.push_back(new set_var_user(new Item_func_set_user_var(name,
|
||||
new Item_null())));
|
||||
if (sql_set_variables(thd, &tmp_var_list)) /* this will create the variable */
|
||||
goto err;
|
||||
if (!(var_entry= get_variable(&thd->user_vars, name, 0)))
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
If this variable was already stored in user_var_events by this query
|
||||
(because it's used in more than one place in the query), don't store
|
||||
it.
|
||||
*/
|
||||
else if (var_entry->used_query_id == thd->query_id)
|
||||
return;
|
||||
|
||||
uint size;
|
||||
/*
|
||||
First we need to store value of var_entry, when the next situation
|
||||
appers:
|
||||
> set @a:=1;
|
||||
> insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1);
|
||||
We have to write to binlog value @a= 1;
|
||||
*/
|
||||
size= ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)) + var_entry->length;
|
||||
if (!(user_var_event= (BINLOG_USER_VAR_EVENT *) thd->alloc(size)))
|
||||
goto err;
|
||||
|
||||
user_var_event->value= (char*) user_var_event +
|
||||
ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT));
|
||||
user_var_event->user_var_event= var_entry;
|
||||
user_var_event->type= var_entry->type;
|
||||
user_var_event->charset_number= var_entry->collation.collation->number;
|
||||
if (!var_entry->value)
|
||||
{
|
||||
/* NULL value*/
|
||||
user_var_event->length= 0;
|
||||
user_var_event->value= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
user_var_event->length= var_entry->length;
|
||||
memcpy(user_var_event->value, var_entry->value,
|
||||
var_entry->length);
|
||||
}
|
||||
/* Mark that this variable has been used by this query */
|
||||
var_entry->used_query_id= thd->query_id;
|
||||
if (insert_dynamic(&thd->user_var_events, (gptr) &user_var_event))
|
||||
goto err;
|
||||
|
||||
return;
|
||||
|
||||
err:
|
||||
|
|
Loading…
Reference in a new issue