summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorRoy Lyseng <roy.lyseng@oracle.com>2012-12-21 09:53:42 +0100
committerRoy Lyseng <roy.lyseng@oracle.com>2012-12-21 09:53:42 +0100
commit8b1d1cf5c0359f082d8a2930e7ea3ea119bc5ac9 (patch)
tree79c2a5d1c358ea18f9d7b7b91ae2995add41808f /sql/item_cmpfunc.cc
parent7817b8134201ae33dabbad38586581af8786f302 (diff)
downloadmariadb-git-8b1d1cf5c0359f082d8a2930e7ea3ea119bc5ac9.tar.gz
Bug#15972635: Incorrect results returned in 32 table join with HAVING
The problem is a shift operation that is not 64-bit safe. The consequence is that used tables information for a join with 32 tables or more will be incorrect. Fixed by adding a type cast in Item_sum::update_used_tables(). Also used the opportunity to fix some other potential bugs by adding an explicit type-cast to an integer in a left-shift operation. Some of them were quite harmless, but was fixed in order to get the same signed-ness as the other operand of the operation it was used in. sql/item_cmpfunc.cc Adjusted signed-ness for some integers in left-shift. sql/item_subselect.cc Added type-cast to nesting_map (which is a 32/64 bit type, so potential bug for deeply nested queries). sql/item_sum.cc Added type-cast to nesting_map (32/64-bit type) and table_map (64-bit type). sql/opt_range.cc Added type-cast to ulonglong (which is a 64-bit type). sql/sql_base.cc Added type-cast to nesting_map (which is a 32/64-bit type). sql/sql_select.cc Added type-cast to nesting_map (32/64-bit type) and key_part_map (64-bit type). sql/strfunc.cc Changed type-cast from longlong to ulonglong, to preserve signed-ness.
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r--sql/item_cmpfunc.cc22
1 files changed, 11 insertions, 11 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 47e576e7fdf..4dc41d29794 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -220,15 +220,15 @@ static uint collect_cmp_types(Item **items, uint nitems, bool skip_nulls= FALSE)
items[i]->result_type() == ROW_RESULT) &&
cmp_row_type(items[0], items[i]))
return 0;
- found_types|= 1<< (uint)item_cmp_type(left_result,
- items[i]->result_type());
+ found_types|= 1U << (uint)item_cmp_type(left_result,
+ items[i]->result_type());
}
/*
Even if all right-hand items are NULLs and we are skipping them all, we need
at least one type bit in the found_type bitmask.
*/
if (skip_nulls && !found_types)
- found_types= 1 << (uint)left_result;
+ found_types= 1U << (uint)left_result;
return found_types;
}
@@ -2897,12 +2897,12 @@ Item *Item_func_case::find_item(String *str)
cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
DBUG_ASSERT(cmp_type != ROW_RESULT);
DBUG_ASSERT(cmp_items[(uint)cmp_type]);
- if (!(value_added_map & (1<<(uint)cmp_type)))
+ if (!(value_added_map & (1U << (uint)cmp_type)))
{
cmp_items[(uint)cmp_type]->store_value(args[first_expr_num]);
if ((null_value=args[first_expr_num]->null_value))
return else_expr_num != -1 ? args[else_expr_num] : 0;
- value_added_map|= 1<<(uint)cmp_type;
+ value_added_map|= 1U << (uint)cmp_type;
}
if (!cmp_items[(uint)cmp_type]->cmp(args[i]) && !args[i]->null_value)
return args[i + 1];
@@ -3107,7 +3107,7 @@ void Item_func_case::fix_length_and_dec()
nagg++;
if (!(found_types= collect_cmp_types(agg, nagg)))
return;
- if (found_types & (1 << STRING_RESULT))
+ if (found_types & (1U << STRING_RESULT))
{
/*
If we'll do string comparison, we also need to aggregate
@@ -3147,7 +3147,7 @@ void Item_func_case::fix_length_and_dec()
}
for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
{
- if (found_types & (1 << i) && !cmp_items[i])
+ if (found_types & (1U << i) && !cmp_items[i])
{
DBUG_ASSERT((Item_result)i != ROW_RESULT);
if (!(cmp_items[i]=
@@ -3956,7 +3956,7 @@ void Item_func_in::fix_length_and_dec()
}
for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
{
- if (found_types & 1 << i)
+ if (found_types & (1U << i))
{
(type_cnt)++;
cmp_type= (Item_result) i;
@@ -4139,7 +4139,7 @@ void Item_func_in::fix_length_and_dec()
{
for (i= 0; i <= (uint) DECIMAL_RESULT; i++)
{
- if (found_types & (1 << i) && !cmp_items[i])
+ if (found_types & (1U << i) && !cmp_items[i])
{
if ((Item_result)i == STRING_RESULT &&
agg_arg_charsets_for_comparison(cmp_collation, args, arg_count))
@@ -4229,12 +4229,12 @@ longlong Item_func_in::val_int()
Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
in_item= cmp_items[(uint)cmp_type];
DBUG_ASSERT(in_item);
- if (!(value_added_map & (1 << (uint)cmp_type)))
+ if (!(value_added_map & (1U << (uint)cmp_type)))
{
in_item->store_value(args[0]);
if ((null_value= args[0]->null_value))
return 0;
- value_added_map|= 1 << (uint)cmp_type;
+ value_added_map|= 1U << (uint)cmp_type;
}
if (!in_item->cmp(args[i]) && !args[i]->null_value)
return (longlong) (!negated);