diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2022-08-24 09:22:34 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2022-08-24 09:22:34 +0300 |
commit | bdd80e3fb1cb653c367099639bec46840eca86e1 (patch) | |
tree | ab3d208ab5102d7f7db1b222a7a4531012a0ebcd /sql/sql_class.cc | |
parent | dc11fd07fdaf7316d340569f97a84fa0fd2d307e (diff) | |
parent | 5b4c832c7ebd59d9f5a5e7feef570568e20e5b86 (diff) | |
download | mariadb-git-bdd80e3fb1cb653c367099639bec46840eca86e1.tar.gz |
Merge 10.6 into 10.7
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r-- | sql/sql_class.cc | 80 |
1 files changed, 56 insertions, 24 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc index c07c70f55a4..3661df5de69 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3663,6 +3663,41 @@ void select_max_min_finder_subselect::cleanup() } +void select_max_min_finder_subselect::set_op(const Type_handler *th) +{ + if (th->is_val_native_ready()) + { + op= &select_max_min_finder_subselect::cmp_native; + return; + } + + switch (th->cmp_type()) { + case REAL_RESULT: + op= &select_max_min_finder_subselect::cmp_real; + break; + case INT_RESULT: + op= &select_max_min_finder_subselect::cmp_int; + break; + case STRING_RESULT: + op= &select_max_min_finder_subselect::cmp_str; + break; + case DECIMAL_RESULT: + op= &select_max_min_finder_subselect::cmp_decimal; + break; + case TIME_RESULT: + if (th->field_type() == MYSQL_TYPE_TIME) + op= &select_max_min_finder_subselect::cmp_time; + else + op= &select_max_min_finder_subselect::cmp_str; + break; + case ROW_RESULT: + // This case should never be chosen + DBUG_ASSERT(0); + op= 0; + } +} + + int select_max_min_finder_subselect::send_data(List<Item> &items) { DBUG_ENTER("select_max_min_finder_subselect::send_data"); @@ -3681,30 +3716,7 @@ int select_max_min_finder_subselect::send_data(List<Item> &items) if (!cache) { cache= val_item->get_cache(thd); - switch (val_item->cmp_type()) { - case REAL_RESULT: - op= &select_max_min_finder_subselect::cmp_real; - break; - case INT_RESULT: - op= &select_max_min_finder_subselect::cmp_int; - break; - case STRING_RESULT: - op= &select_max_min_finder_subselect::cmp_str; - break; - case DECIMAL_RESULT: - op= &select_max_min_finder_subselect::cmp_decimal; - break; - case TIME_RESULT: - if (val_item->field_type() == MYSQL_TYPE_TIME) - op= &select_max_min_finder_subselect::cmp_time; - else - op= &select_max_min_finder_subselect::cmp_str; - break; - case ROW_RESULT: - // This case should never be chosen - DBUG_ASSERT(0); - op= 0; - } + set_op(val_item->type_handler()); } cache->store(val_item); it->store(0, cache); @@ -3798,6 +3810,26 @@ bool select_max_min_finder_subselect::cmp_str() return (sortcmp(val1, val2, cache->collation.collation) < 0); } + +bool select_max_min_finder_subselect::cmp_native() +{ + NativeBuffer<STRING_BUFFER_USUAL_SIZE> cvalue, mvalue; + Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0); + bool cvalue_is_null= cache->val_native(thd, &cvalue); + bool mvalue_is_null= maxmin->val_native(thd, &mvalue); + + /* Ignore NULLs for ANY and keep them for ALL subqueries */ + if (cvalue_is_null) + return (is_all && !mvalue_is_null) || (!is_all && mvalue_is_null); + if (mvalue_is_null) + return !is_all; + + const Type_handler *th= cache->type_handler(); + return fmax ? th->cmp_native(cvalue, mvalue) > 0 : + th->cmp_native(cvalue, mvalue) < 0; +} + + int select_exists_subselect::send_data(List<Item> &items) { DBUG_ENTER("select_exists_subselect::send_data"); |