summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <evgen@moonbone.local>2006-06-17 01:57:25 +0400
committerunknown <evgen@moonbone.local>2006-06-17 01:57:25 +0400
commit707de39a53c3a9d40cabc968475e83f45a754e2e (patch)
treedb342732a1b4d4b8c9c730075c5e4a1404d25e8f
parentde292d67996bb238b43f4eaca3257e0a47544271 (diff)
parentca22a81b1c84ce81e1e9ea2c3ace7be1848027d8 (diff)
downloadmariadb-git-707de39a53c3a9d40cabc968475e83f45a754e2e.tar.gz
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
-rw-r--r--mysql-test/r/func_str.result15
-rw-r--r--mysql-test/t/func_str.test12
-rw-r--r--sql/item_cmpfunc.cc32
-rw-r--r--sql/item_strfunc.cc23
4 files changed, 58 insertions, 24 deletions
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index a17661d26d0..1485809ba70 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -1023,6 +1023,21 @@ NULL
select ifnull(load_file("lkjlkj"),"it's null");
ifnull(load_file("lkjlkj"),"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
create table t1 (d decimal default null);
insert into t1 values (null);
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index 7f809dbc4a1..b13fe039261 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -673,6 +673,18 @@ drop table t1;
select load_file("lkjlkj");
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
#
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index db1af9de0a2..15a05fe7050 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -85,21 +85,21 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems)
items will be used for aggregation.
If there are DATE/TIME fields/functions in the list and no string
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
All constant items in the list will be converted to a DATE/TIME using
found field or result field of found function.
Implementation notes:
- The code is equvalent to:
- 1. Check the list for presense of a STRING field/function.
+ The code is equivalent to:
+ 1. Check the list for presence of a STRING field/function.
Collect the is_const flag.
2. Get a Field* object to use for type coercion
3. Perform type conversion.
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.
- 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
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)
static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
{
uint i;
- Item::Type res;
- char *buff= NULL;
+ Item::Type res= (Item::Type)0;
+ /* Used only for date/time fields, max_length = 19 */
+ char buff[20];
uchar null_byte;
Field *field= NULL;
@@ -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);
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);
break;
}
}
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++)
{
if (!items[i]->const_item() && items[i]->result_type() == STRING_RESULT &&
!items[i]->result_as_longlong())
{
+ if (res == Item::FUNC_ITEM)
+ delete field;
field= 0;
break;
}
@@ -207,10 +200,7 @@ static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
}
if (res == Item::FUNC_ITEM && field)
- {
delete field;
- my_free(buff, MYF(MY_WME));
- }
}
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index c7fa049a0d5..a51ebd39147 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -154,7 +154,15 @@ String *Item_func_md5::val_str(String *str)
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)
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)
if (!(res=args[0]->val_str(str)))
goto null;
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++)
{
if (res->length() == 0)