Commit f4741532 authored by unknown's avatar unknown

Merge moonbone.local:/home/evgen/bk-trees/mysql-4.1-opt

into moonbone.local:/work/tmp_merge-5.0-opt-mysql


mysql-test/r/cast.result:
  Auto merged
mysql-test/r/func_str.result:
  Auto merged
mysql-test/t/func_str.test:
  Auto merged
sql/item_cmpfunc.cc:
  Auto merged
sql/item_cmpfunc.h:
  Auto merged
sql/item_strfunc.cc:
  Auto merged
parents abc76e93 6ca6756b
...@@ -1023,6 +1023,21 @@ NULL ...@@ -1023,6 +1023,21 @@ NULL
select ifnull(load_file("lkjlkj"),"it's null"); select ifnull(load_file("lkjlkj"),"it's null");
ifnull(load_file("lkjlkj"),"it's null") ifnull(load_file("lkjlkj"),"it's null")
it's null it's null
create table t1 (f1 varchar(4), f2 varchar(64), unique key k1 (f1,f2));
insert into t1 values ( 'test',md5('test')), ('test', sha('test'));
select * from t1 where f1='test' and (f2= md5("test") or f2= md5("TEST"));
f1 f2
test 098f6bcd4621d373cade4e832627b4f6
select * from t1 where f1='test' and (f2= md5("TEST") or f2= md5("test"));
f1 f2
test 098f6bcd4621d373cade4e832627b4f6
select * from t1 where f1='test' and (f2= sha("test") or f2= sha("TEST"));
f1 f2
test a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
select * from t1 where f1='test' and (f2= sha("TEST") or f2= sha("test"));
f1 f2
test a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
drop table t1;
End of 4.1 tests End of 4.1 tests
create table t1 (d decimal default null); create table t1 (d decimal default null);
insert into t1 values (null); insert into t1 values (null);
......
...@@ -673,6 +673,18 @@ drop table t1; ...@@ -673,6 +673,18 @@ drop table t1;
select load_file("lkjlkj"); select load_file("lkjlkj");
select ifnull(load_file("lkjlkj"),"it's null"); select ifnull(load_file("lkjlkj"),"it's null");
#
# Bug#15351: Wrong collation used for comparison of md5() and sha()
# parameter can lead to a wrong result.
#
create table t1 (f1 varchar(4), f2 varchar(64), unique key k1 (f1,f2));
insert into t1 values ( 'test',md5('test')), ('test', sha('test'));
select * from t1 where f1='test' and (f2= md5("test") or f2= md5("TEST"));
select * from t1 where f1='test' and (f2= md5("TEST") or f2= md5("test"));
select * from t1 where f1='test' and (f2= sha("test") or f2= sha("TEST"));
select * from t1 where f1='test' and (f2= sha("TEST") or f2= sha("test"));
drop table t1;
--echo End of 4.1 tests --echo End of 4.1 tests
# #
......
...@@ -85,21 +85,21 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems) ...@@ -85,21 +85,21 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems)
items will be used for aggregation. items will be used for aggregation.
If there are DATE/TIME fields/functions in the list and no string If there are DATE/TIME fields/functions in the list and no string
fields/functions in the list then: fields/functions in the list then:
The INT_RESULT type will be used for aggregation instead of orginal The INT_RESULT type will be used for aggregation instead of original
result type of any DATE/TIME field/function in the list result type of any DATE/TIME field/function in the list
All constant items in the list will be converted to a DATE/TIME using All constant items in the list will be converted to a DATE/TIME using
found field or result field of found function. found field or result field of found function.
Implementation notes: Implementation notes:
The code is equvalent to: The code is equivalent to:
1. Check the list for presense of a STRING field/function. 1. Check the list for presence of a STRING field/function.
Collect the is_const flag. Collect the is_const flag.
2. Get a Field* object to use for type coercion 2. Get a Field* object to use for type coercion
3. Perform type conversion. 3. Perform type conversion.
1 and 2 are implemented in 2 loops. The first searches for a DATE/TIME 1 and 2 are implemented in 2 loops. The first searches for a DATE/TIME
field/function and checks presense of a STRING field/function. field/function and checks presence of a STRING field/function.
The second loop works only if a DATE/TIME field/function is found. The second loop works only if a DATE/TIME field/function is found.
It checks presense of a STRING field/function in the rest of the list. It checks presence of a STRING field/function in the rest of the list.
TODO TODO
1) The current implementation can produce false comparison results for 1) The current implementation can produce false comparison results for
...@@ -122,8 +122,9 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems) ...@@ -122,8 +122,9 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems)
static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems) static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
{ {
uint i; uint i;
Item::Type res; Item::Type res= (Item::Type)0;
char *buff= NULL; /* Used only for date/time fields, max_length = 19 */
char buff[20];
uchar null_byte; uchar null_byte;
Field *field= NULL; Field *field= NULL;
...@@ -149,28 +150,20 @@ static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems) ...@@ -149,28 +150,20 @@ static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
{ {
field= items[i]->tmp_table_field_from_field_type(0); field= items[i]->tmp_table_field_from_field_type(0);
if (field) if (field)
buff= alloc_root(thd->mem_root, field->max_length());
if (!buff || !field)
{
if (field)
delete field;
if (buff)
my_free(buff, MYF(MY_WME));
field= 0;
}
else
field->move_field(buff, &null_byte, 0); field->move_field(buff, &null_byte, 0);
break; break;
} }
} }
if (field) if (field)
{ {
/* Check the rest of the list for presense of a string field/function. */ /* Check the rest of the list for presence of a string field/function. */
for (i++ ; i < nitems; i++) for (i++ ; i < nitems; i++)
{ {
if (!items[i]->const_item() && items[i]->result_type() == STRING_RESULT && if (!items[i]->const_item() && items[i]->result_type() == STRING_RESULT &&
!items[i]->result_as_longlong()) !items[i]->result_as_longlong())
{ {
if (res == Item::FUNC_ITEM)
delete field;
field= 0; field= 0;
break; break;
} }
...@@ -207,10 +200,7 @@ static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems) ...@@ -207,10 +200,7 @@ static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
} }
if (res == Item::FUNC_ITEM && field) if (res == Item::FUNC_ITEM && field)
{
delete field; delete field;
my_free(buff, MYF(MY_WME));
}
} }
......
...@@ -154,7 +154,15 @@ String *Item_func_md5::val_str(String *str) ...@@ -154,7 +154,15 @@ String *Item_func_md5::val_str(String *str)
void Item_func_md5::fix_length_and_dec() void Item_func_md5::fix_length_and_dec()
{ {
max_length=32; max_length=32;
/*
The MD5() function treats its parameter as being a case sensitive. Thus
we set binary collation on it so different instances of MD5() will be
compared properly.
*/
args[0]->collation.set(
get_charset_by_csname(args[0]->collation.collation->csname,
MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE);
} }
...@@ -195,7 +203,15 @@ String *Item_func_sha::val_str(String *str) ...@@ -195,7 +203,15 @@ String *Item_func_sha::val_str(String *str)
void Item_func_sha::fix_length_and_dec() void Item_func_sha::fix_length_and_dec()
{ {
max_length=SHA1_HASH_SIZE*2; // size of hex representation of hash max_length=SHA1_HASH_SIZE*2; // size of hex representation of hash
/*
The SHA() function treats its parameter as being a case sensitive. Thus
we set binary collation on it so different instances of MD5() will be
compared properly.
*/
args[0]->collation.set(
get_charset_by_csname(args[0]->collation.collation->csname,
MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE);
} }
...@@ -294,7 +310,8 @@ String *Item_func_concat::val_str(String *str) ...@@ -294,7 +310,8 @@ String *Item_func_concat::val_str(String *str)
if (!(res=args[0]->val_str(str))) if (!(res=args[0]->val_str(str)))
goto null; goto null;
use_as_buff= &tmp_value; use_as_buff= &tmp_value;
is_const= args[0]->const_item(); /* Item_subselect in --ps-protocol mode will state it as a non-const */
is_const= args[0]->const_item() || !args[0]->used_tables();
for (i=1 ; i < arg_count ; i++) for (i=1 ; i < arg_count ; i++)
{ {
if (res->length() == 0) if (res->length() == 0)
......
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