diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-01 18:15:00 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-01 18:15:00 +0000 |
commit | a2a2e32c02643a0cec111511220227703fda1cd5 (patch) | |
tree | 69cc2b631234c2a8e026b9cd4d72676c61c594df /sql/item_cmpfunc.cc | |
parent | Releasing progress-linux version 1:10.11.8-1~progress7.99u1. (diff) | |
download | mariadb-a2a2e32c02643a0cec111511220227703fda1cd5.tar.xz mariadb-a2a2e32c02643a0cec111511220227703fda1cd5.zip |
Merging upstream version 1:11.4.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r-- | sql/item_cmpfunc.cc | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 9d76c9e4..880634fc 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -392,6 +392,9 @@ static bool convert_const_to_int(THD *thd, Item_field *field_item, This directly contradicts the manual (number and a string should be compared as doubles), but seems to provide more "intuitive" behavior in some cases (but less intuitive in others). + + This method should be moved to Type_handler::convert_item_for_comparison() + eventually. */ void Item_func::convert_const_compared_to_int_field(THD *thd) { @@ -412,6 +415,43 @@ void Item_func::convert_const_compared_to_int_field(THD *thd) } +bool Item_func::aggregate_args2_for_comparison_with_conversion( + THD *thd, + Type_handler_hybrid_field_type *th) +{ + DBUG_ASSERT(arg_count >= 2); + for (bool done= false ; !done ; ) + { + if (th->aggregate_for_comparison(func_name_cstring(), args, 2, false)) + return true; + if (thd->lex->is_ps_or_view_context_analysis()) + return false; + done= true; + for (uint subject= 0; subject < 2; subject++) + { + uint other_side= subject == 0 ? 1 : 0; + /* See comment in convert_const_to_int() */ + if (!args[subject]->with_sum_func() && + args[subject]->can_eval_in_optimize()) + { + Item *item= th->type_handler()->convert_item_for_comparison(thd, + args[subject], + args[other_side]); + if (!item) + return true; // An error happened, e.g. EOM + if (item != args[subject]) + { + thd->change_item_tree(&args[subject], item); + done= false; // Aggregate again, using the replacement item + break; + } + } + } + } + return false; +} + + /* Iterate through arguments and compare them to the original arguments in "old_args". If some argument was replaced: @@ -487,7 +527,7 @@ bool Item_bool_rowready_func2::fix_length_and_dec(THD *thd) Item_args old_args(args[0], args[1]); convert_const_compared_to_int_field(thd); Type_handler_hybrid_field_type tmp; - if (tmp.aggregate_for_comparison(func_name_cstring(), args, 2, false) || + if (aggregate_args2_for_comparison_with_conversion(thd, &tmp) || tmp.type_handler()->Item_bool_rowready_func2_fix_length_and_dec(thd, this)) { @@ -2810,7 +2850,10 @@ Item_func_nullif::fix_length_and_dec(THD *thd) set_maybe_null(); m_arg0= args[0]; convert_const_compared_to_int_field(thd); - if (cmp.set_cmp_func(thd, this, &args[0], &args[1], true/*set_null*/)) + Type_handler_hybrid_field_type tmp; + if (aggregate_args2_for_comparison_with_conversion(thd, &tmp) || + cmp.set_cmp_func(thd, this, tmp.type_handler(), + &args[0], &args[1], true/*set_null*/)) return true; /* A special code for EXECUTE..PREPARE. @@ -7970,3 +8013,4 @@ Item *Item_equal::multiple_equality_transformer(THD *thd, uchar *arg) break; } } + |