Commit 346dfa00 authored by unknown's avatar unknown

A fix and a test case for Bug#9379 (collation of a parameter marker is

binary).


mysql-test/r/ps.result:
  Test results fixed (Bug#9379)
mysql-test/t/ps.test:
  A test case for Bug#9379 (collation of a parameter marker is binary)
sql/item.cc:
  - set Item_param::collation to str_value collation, if Item_param
  is assigned a string. Reset it to default in Item_param::reset() (on 
  the next execution it can be assigned a number).
sql/item_func.cc:
  - now that item collation can change between executions
  (if this item is Item_param), we need to register the change
  of the execution tree in the rollback list.
parent 207284e8
...@@ -622,3 +622,22 @@ execute stmt using @user_id, @id; ...@@ -622,3 +622,22 @@ execute stmt using @user_id, @id;
partner_id partner_id
deallocate prepare stmt; deallocate prepare stmt;
drop table t1, t2, t3, t4; drop table t1, t2, t3, t4;
prepare stmt from 'select ?=?';
set @a='CHRISTINE ';
set @b='CHRISTINE';
execute stmt using @a, @b;
?=?
1
execute stmt using @a, @b;
?=?
1
set @a=1, @b=2;
execute stmt using @a, @b;
?=?
0
set @a='CHRISTINE ';
set @b='CHRISTINE';
execute stmt using @a, @b;
?=?
1
deallocate prepare stmt;
...@@ -650,3 +650,19 @@ execute stmt using @user_id, @id; ...@@ -650,3 +650,19 @@ execute stmt using @user_id, @id;
execute stmt using @user_id, @id; execute stmt using @user_id, @id;
deallocate prepare stmt; deallocate prepare stmt;
drop table t1, t2, t3, t4; drop table t1, t2, t3, t4;
#
# Bug#9379: make sure that Item::collation is reset when one sets
# a parameter marker from a string variable.
#
prepare stmt from 'select ?=?';
set @a='CHRISTINE ';
set @b='CHRISTINE';
execute stmt using @a, @b;
execute stmt using @a, @b;
set @a=1, @b=2;
execute stmt using @a, @b;
set @a='CHRISTINE ';
set @b='CHRISTINE';
execute stmt using @a, @b;
deallocate prepare stmt;
...@@ -1089,6 +1089,7 @@ void Item_param::reset() ...@@ -1089,6 +1089,7 @@ void Item_param::reset()
to the binary log. to the binary log.
*/ */
str_value.set_charset(&my_charset_bin); str_value.set_charset(&my_charset_bin);
collation.set(&my_charset_bin, DERIVATION_COERCIBLE);
state= NO_VALUE; state= NO_VALUE;
maybe_null= 1; maybe_null= 1;
null_value= 0; null_value= 0;
...@@ -1336,6 +1337,8 @@ bool Item_param::convert_str_value(THD *thd) ...@@ -1336,6 +1337,8 @@ bool Item_param::convert_str_value(THD *thd)
*/ */
str_value_ptr.set(str_value.ptr(), str_value.length(), str_value_ptr.set(str_value.ptr(), str_value.length(),
str_value.charset()); str_value.charset());
/* Synchronize item charset with value charset */
collation.set(str_value.charset(), DERIVATION_COERCIBLE);
} }
return rc; return rc;
} }
......
...@@ -188,7 +188,20 @@ bool Item_func::agg_arg_charsets(DTCollation &coll, ...@@ -188,7 +188,20 @@ bool Item_func::agg_arg_charsets(DTCollation &coll,
break; // we cannot return here, we need to restore "arena". break; // we cannot return here, we need to restore "arena".
} }
conv->fix_fields(thd, 0, &conv); conv->fix_fields(thd, 0, &conv);
*arg= conv; /*
If in statement prepare, then we create a converter for two
constant items, do it once and then reuse it.
If we're in execution of a prepared statement, arena is NULL,
and the conv was created in runtime memory. This can be
the case only if the argument is a parameter marker ('?'),
because for all true constants the charset converter has already
been created in prepare. In this case register the change for
rollback.
*/
if (arena)
*arg= conv;
else
thd->change_item_tree(arg, conv);
} }
if (arena) if (arena)
thd->restore_backup_item_arena(arena, &backup); thd->restore_backup_item_arena(arena, &backup);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment