Commit 7d77a065 authored by unknown's avatar unknown

Bug #16881: password() and union select

  This was only demonstrated by the use of PASSWORD(), it was not related to
  that function at all. The calculation of the size of a field in the results
  of a UNION did not take into account the possible growth of a string field
  when being converted to the aggregated character set.


mysql-test/r/union.result:
  Add new results
mysql-test/t/union.test:
  Add new regression test
sql/item.cc:
  Fix calculation of max_length when figuring out the type of a column in
  a UNION. It needs to take into account any expansion of field size due to
  charset conversions.
parent 836499e9
...@@ -1351,3 +1351,8 @@ drop table t1; ...@@ -1351,3 +1351,8 @@ drop table t1;
(select avg(1)) union (select avg(1)) union (select avg(1)); (select avg(1)) union (select avg(1)) union (select avg(1));
avg(1) avg(1)
NULL NULL
select _utf8'12' union select _latin1'12345';
12
12
12345
End of 5.0 tests
...@@ -841,3 +841,10 @@ drop table t1; ...@@ -841,3 +841,10 @@ drop table t1;
(select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union
(select avg(1)) union (select avg(1)) union (select avg(1)); (select avg(1)) union (select avg(1)) union (select avg(1));
#
# Bug #16881: password() and union select
# (The issue was poor handling of character set aggregation.)
#
select _utf8'12' union select _latin1'12345';
--echo End of 5.0 tests
...@@ -6053,14 +6053,13 @@ bool Item_type_holder::join_types(THD *thd, Item *item) ...@@ -6053,14 +6053,13 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
max_length= my_decimal_precision_to_length(precision, decimals, max_length= my_decimal_precision_to_length(precision, decimals,
unsigned_flag); unsigned_flag);
} }
else
max_length= max(max_length, display_length(item));
switch (Field::result_merge_type(fld_type)) switch (Field::result_merge_type(fld_type))
{ {
case STRING_RESULT: case STRING_RESULT:
{ {
const char *old_cs, *old_derivation; const char *old_cs, *old_derivation;
uint32 old_max_chars= max_length / collation.collation->mbmaxlen;
old_cs= collation.collation->name; old_cs= collation.collation->name;
old_derivation= collation.derivation_name(); old_derivation= collation.derivation_name();
if (collation.aggregate(item->collation, MY_COLL_ALLOW_CONV)) if (collation.aggregate(item->collation, MY_COLL_ALLOW_CONV))
...@@ -6072,6 +6071,14 @@ bool Item_type_holder::join_types(THD *thd, Item *item) ...@@ -6072,6 +6071,14 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
"UNION"); "UNION");
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
/*
To figure out max_length, we have to take into account possible
expansion of the size of the values because of character set
conversions.
*/
max_length= max(old_max_chars * collation.collation->mbmaxlen,
display_length(item) / item->collation.collation->mbmaxlen *
collation.collation->mbmaxlen);
break; break;
} }
case REAL_RESULT: case REAL_RESULT:
...@@ -6090,7 +6097,8 @@ bool Item_type_holder::join_types(THD *thd, Item *item) ...@@ -6090,7 +6097,8 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
max_length= (fld_type == MYSQL_TYPE_FLOAT) ? FLT_DIG+6 : DBL_DIG+7; max_length= (fld_type == MYSQL_TYPE_FLOAT) ? FLT_DIG+6 : DBL_DIG+7;
break; break;
} }
default:; default:
max_length= max(max_length, display_length(item));
}; };
maybe_null|= item->maybe_null; maybe_null|= item->maybe_null;
get_full_info(item); get_full_info(item);
......
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