Below is the list of changes that have just been committed into a local
5.0 repository of knielsen. When knielsen does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.2211 06/06/29 15:41:09 knielsen@stripped +4 -0
BUG#20769: Dangling pointer in ctype_recoding test case.
In some functions dealing with strings and character sets, the wrong
pointers were saved for restoration in THD::rollback_item_tree_changes().
This could potentially cause random corruption or crashes.
Fixed by passing the original Item ** locations, not local stack copies.
sql/item_strfunc.cc
1.272 06/06/29 15:41:05 knielsen@stripped +8 -25
Pass original Item **'s to agg_arg_charsets(), not local copies, to ensure
proper restoration in THD::rollback_item_tree_changes().
sql/item_func.h
1.141 06/06/29 15:41:05 knielsen@stripped +2 -2
Function agg_item_charsets() now handles non-consequtive Item *'s.
sql/item.h
1.201 06/06/29 15:41:05 knielsen@stripped +4 -2
Function agg_item_charsets() now handles non-consequtive Item *'s.
sql/item.cc
1.225 06/06/29 15:41:05 knielsen@stripped +24 -14
Function agg_item_charsets() now handles non-consequtive Item *'s.
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: knielsen
# Host: rt.int.sifira.dk
# Root: /usr/local/mysql/mysql-5.0-release
--- 1.224/sql/item.cc 2006-05-18 20:25:38 +02:00
+++ 1.225/sql/item.cc 2006-06-29 15:41:05 +02:00
@@ -1315,35 +1315,36 @@
static
-void my_coll_agg_error(Item** args, uint count, const char *fname)
+void my_coll_agg_error(Item** args, uint count, const char *fname,
+ int item_sep)
{
if (count == 2)
- my_coll_agg_error(args[0]->collation, args[1]->collation, fname);
+ my_coll_agg_error(args[0]->collation, args[item_sep]->collation, fname);
else if (count == 3)
- my_coll_agg_error(args[0]->collation, args[1]->collation,
- args[2]->collation, fname);
+ my_coll_agg_error(args[0]->collation, args[item_sep]->collation,
+ args[2*item_sep]->collation, fname);
else
my_error(ER_CANT_AGGREGATE_NCOLLATIONS,MYF(0),fname);
}
bool agg_item_collations(DTCollation &c, const char *fname,
- Item **av, uint count, uint flags)
+ Item **av, uint count, uint flags, int item_sep)
{
uint i;
c.set(av[0]->collation);
for (i= 1; i < count; i++)
{
- if (c.aggregate(av[i]->collation, flags))
+ if (c.aggregate(av[i*item_sep]->collation, flags))
{
- my_coll_agg_error(av, count, fname);
+ my_coll_agg_error(av, count, fname, item_sep);
return TRUE;
}
}
if ((flags & MY_COLL_DISALLOW_NONE) &&
c.derivation == DERIVATION_NONE)
{
- my_coll_agg_error(av, count, fname);
+ my_coll_agg_error(av, count, fname, item_sep);
return TRUE;
}
return FALSE;
@@ -1377,13 +1378,22 @@
For functions with more than two arguments:
collect(A,B,C) ::= collect(collect(A,B),C)
+
+ Since this function calls THD::change_item_tree() on the passed Item **
+ pointers, it is necessary to pass the original Item **'s, not copies.
+ Otherwise their values will not be properly restored (see BUG#20769).
+ If the items are not consecutive (eg. args[2] and args[5]), use the
+ item_sep argument, ie.
+
+ agg_item_charsets(coll, fname, &args[2], 2, flags, 3)
+
*/
bool agg_item_charsets(DTCollation &coll, const char *fname,
- Item **args, uint nargs, uint flags)
+ Item **args, uint nargs, uint flags, int item_sep)
{
Item **arg, **last, *safe_args[2];
- if (agg_item_collations(coll, fname, args, nargs, flags))
+ if (agg_item_collations(coll, fname, args, nargs, flags, item_sep))
return TRUE;
/*
@@ -1396,7 +1406,7 @@
if (nargs >=2 && nargs <= 3)
{
safe_args[0]= args[0];
- safe_args[1]= args[1];
+ safe_args[1]= args[item_sep];
}
THD *thd= current_thd;
@@ -1408,7 +1418,7 @@
*/
arena= thd->activate_stmt_arena_if_needed(&backup);
- for (arg= args, last= args + nargs; arg < last; arg++)
+ for (arg= args, last= args + item_sep*nargs; arg != last; arg+= item_sep)
{
Item* conv;
uint32 dummy_offset;
@@ -1423,9 +1433,9 @@
{
/* restore the original arguments for better error message */
args[0]= safe_args[0];
- args[1]= safe_args[1];
+ args[item_sep]= safe_args[1];
}
- my_coll_agg_error(args, nargs, fname);
+ my_coll_agg_error(args, nargs, fname, item_sep);
res= TRUE;
break; // we cannot return here, we need to restore "arena".
}
--- 1.200/sql/item.h 2006-06-14 21:54:05 +02:00
+++ 1.201/sql/item.h 2006-06-29 15:41:05 +02:00
@@ -1075,12 +1075,14 @@
};
bool agg_item_collations(DTCollation &c, const char *name,
- Item **items, uint nitems, uint flags= 0);
+ Item **items, uint nitems, uint flags= 0,
+ int item_sep= 1);
bool agg_item_collations_for_comparison(DTCollation &c, const char *name,
Item **items, uint nitems,
uint flags= 0);
bool agg_item_charsets(DTCollation &c, const char *name,
- Item **items, uint nitems, uint flags= 0);
+ Item **items, uint nitems, uint flags= 0,
+ int item_sep= 1);
class Item_num: public Item
--- 1.140/sql/item_func.h 2006-05-15 13:28:10 +02:00
+++ 1.141/sql/item_func.h 2006-06-29 15:41:05 +02:00
@@ -178,9 +178,9 @@
items, nitems, flags);
}
bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems,
- uint flags= 0)
+ uint flags= 0, int item_sep= 1)
{
- return agg_item_charsets(c, func_name(), items, nitems, flags);
+ return agg_item_charsets(c, func_name(), items, nitems, flags, item_sep);
}
bool walk(Item_processor processor, byte *arg);
Item *transform(Item_transformer transformer, byte *arg);
--- 1.271/sql/item_strfunc.cc 2006-06-26 22:50:50 +02:00
+++ 1.272/sql/item_strfunc.cc 2006-06-29 15:41:05 +02:00
@@ -982,15 +982,11 @@
void Item_func_insert::fix_length_and_dec()
{
- Item *cargs[2];
ulonglong max_result_length;
- cargs[0]= args[0];
- cargs[1]= args[3];
- if (agg_arg_charsets(collation, cargs, 2, MY_COLL_ALLOW_CONV))
+ // Handle character set for args[0] and args[3].
+ if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 3))
return;
- args[0]= cargs[0];
- args[3]= cargs[1];
max_result_length= ((ulonglong) args[0]->max_length+
(ulonglong) args[3]->max_length);
if (max_result_length >= MAX_BLOB_WIDTH)
@@ -1497,13 +1493,9 @@
}
else
{
- Item *cargs[2];
- cargs[0]= args[1];
- cargs[1]= args[0];
- if (agg_arg_charsets(collation, cargs, 2, MY_COLL_CMP_CONV))
+ // Handle character set for args[1] and args[0].
+ if (agg_arg_charsets(collation, &args[1], 2, MY_COLL_CMP_CONV, -1))
return;
- args[0]= cargs[1];
- args[1]= cargs[0];
}
}
@@ -2162,14 +2154,9 @@
void Item_func_rpad::fix_length_and_dec()
{
- Item *cargs[2];
-
- cargs[0]= args[0];
- cargs[1]= args[2];
- if (agg_arg_charsets(collation, cargs, 2, MY_COLL_ALLOW_CONV))
+ // Handle character set for args[0] and args[2].
+ if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 2))
return;
- args[0]= cargs[0];
- args[2]= cargs[1];
if (args[1]->const_item())
{
ulonglong length= ((ulonglong) args[1]->val_int() *
@@ -2249,13 +2236,9 @@
void Item_func_lpad::fix_length_and_dec()
{
- Item *cargs[2];
- cargs[0]= args[0];
- cargs[1]= args[2];
- if (agg_arg_charsets(collation, cargs, 2, MY_COLL_ALLOW_CONV))
+ // Handle character set for args[0] and args[2].
+ if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 2))
return;
- args[0]= cargs[0];
- args[2]= cargs[1];
if (args[1]->const_item())
{
| Thread |
|---|
| • bk commit into 5.0 tree (knielsen:1.2211) BUG#20769 | knielsen | 29 Jun |