diff options
author | Roy Lyseng <roy.lyseng@oracle.com> | 2012-12-21 09:53:42 +0100 |
---|---|---|
committer | Roy Lyseng <roy.lyseng@oracle.com> | 2012-12-21 09:53:42 +0100 |
commit | 8b1d1cf5c0359f082d8a2930e7ea3ea119bc5ac9 (patch) | |
tree | 79c2a5d1c358ea18f9d7b7b91ae2995add41808f /sql/item_cmpfunc.cc | |
parent | 7817b8134201ae33dabbad38586581af8786f302 (diff) | |
download | mariadb-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.cc | 22 |
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); |