diff options
author | Michael Widenius <monty@askmonty.org> | 2012-06-27 17:22:23 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2012-06-27 17:22:23 +0300 |
commit | aa67a198e8a29f2fdae84846cc1d8e74c2d47a83 (patch) | |
tree | 47719240f2509a3fa373f54852b54d552ac6e844 /sql/item_cmpfunc.cc | |
parent | 9ebda8764d2e94096924c0a0181f5773d836114a (diff) | |
parent | 072097174c8b91299fe74a3cd7c5248e6e3cfc57 (diff) | |
download | mariadb-git-aa67a198e8a29f2fdae84846cc1d8e74c2d47a83.tar.gz |
automatic merge with 5.5
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r-- | sql/item_cmpfunc.cc | 70 |
1 files changed, 60 insertions, 10 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 5f1a863d8fd..2a0ca19a4e9 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1504,6 +1504,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref) } if (args[1]->maybe_null) maybe_null=1; + with_subselect= 1; with_sum_func= with_sum_func || args[1]->with_sum_func; with_field= with_field || args[1]->with_field; used_tables_cache|= args[1]->used_tables(); @@ -3032,6 +3033,11 @@ void Item_func_case::fix_length_and_dec() nagg++; if (!(found_types= collect_cmp_types(agg, nagg))) return; + + Item *date_arg= 0; + if (found_types & (1 << TIME_RESULT)) + date_arg= find_date_time_item(args, arg_count, 0); + if (found_types & (1 << STRING_RESULT)) { /* @@ -3071,16 +3077,12 @@ void Item_func_case::fix_length_and_dec() change_item_tree_if_needed(thd, &args[nagg * 2], agg[nagg + 1]); } - Item *date_arg= 0; for (i= 0; i <= (uint)TIME_RESULT; i++) { if (found_types & (1 << i) && !cmp_items[i]) { DBUG_ASSERT((Item_result)i != ROW_RESULT); - if ((Item_result)i == TIME_RESULT) - date_arg= find_date_time_item(args, arg_count, 0); - if (!(cmp_items[i]= cmp_item::get_comparator((Item_result)i, date_arg, cmp_collation.collation))) @@ -4051,15 +4053,15 @@ void Item_func_in::fix_length_and_dec() } else { + if (found_types & (1 << TIME_RESULT)) + date_arg= find_date_time_item(args, arg_count, 0); + if (found_types & (1 << STRING_RESULT) && + agg_arg_charsets_for_comparison(cmp_collation, args, arg_count)) + return; for (i= 0; i <= (uint) TIME_RESULT; i++) { if (found_types & (1 << i) && !cmp_items[i]) { - if ((Item_result)i == STRING_RESULT && - agg_arg_charsets_for_comparison(cmp_collation, args, arg_count)) - return; - if ((Item_result)i == TIME_RESULT) - date_arg= find_date_time_item(args, arg_count, 0); if (!cmp_items[i] && !(cmp_items[i]= cmp_item::get_comparator((Item_result)i, date_arg, cmp_collation.collation))) @@ -4255,6 +4257,22 @@ Item_cond::fix_fields(THD *thd, Item **ref) if (abort_on_null) item->top_level_item(); + /* + replace degraded condition: + was: <field> + become: <field> = 1 + */ + if (item->type() == FIELD_ITEM) + { + Query_arena backup, *arena; + Item *new_item; + arena= thd->activate_stmt_arena_if_needed(&backup); + if ((new_item= new Item_func_ne(item, new Item_int(0, 1)))) + li.replace(item= new_item); + if (arena) + thd->restore_active_arena(arena, &backup); + } + // item can be substituted in fix_fields if ((!item->fixed && item->fix_fields(thd, li.ref())) || @@ -4939,6 +4957,7 @@ Item_func_regex::fix_fields(THD *thd, Item **ref) return TRUE; /* purecov: inspected */ with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func; with_field= args[0]->with_field || args[1]->with_field; + with_subselect|= args[0]->with_subselect | args[1]->with_subselect; max_length= 1; decimals= 0; @@ -5308,6 +5327,28 @@ Item *Item_func_not::neg_transformer(THD *thd) /* NOT(x) -> x */ } +bool Item_func_not::fix_fields(THD *thd, Item **ref) +{ + if (args[0]->type() == FIELD_ITEM) + { + /* replace "NOT <field>" with "<filed> == 0" */ + Query_arena backup, *arena; + Item *new_item; + bool rc= TRUE; + arena= thd->activate_stmt_arena_if_needed(&backup); + if ((new_item= new Item_func_eq(args[0], new Item_int(0, 1)))) + { + new_item->name= name; + rc= (*ref= new_item)->fix_fields(thd, ref); + } + if (arena) + thd->restore_active_arena(arena, &backup); + return rc; + } + return Item_func::fix_fields(thd, ref); +} + + Item *Item_bool_rowready_func2::neg_transformer(THD *thd) { Item *item= negated_item(); @@ -5540,7 +5581,15 @@ void Item_equal::add_const(Item *c, Item *f) else { Item_func_eq *func= new Item_func_eq(c, const_item); - func->set_cmp_func(); + if (func->set_cmp_func()) + { + /* + Setting a comparison function fails when trying to compare + incompatible charsets. Charset compatibility is checked earlier, + except for constant subqueries where we may do it here. + */ + return; + } func->quick_fix_field(); cond_false= !func->val_int(); } @@ -5730,6 +5779,7 @@ bool Item_equal::fix_fields(THD *thd, Item **ref) used_tables_cache|= item->used_tables(); tmp_table_map= item->not_null_tables(); not_null_tables_cache|= tmp_table_map; + DBUG_ASSERT(!item->with_sum_func && !item->with_subselect); if (item->maybe_null) maybe_null= 1; if (!item->get_item_equal()) |