diff --git a/mysql-test/r/func_debug.result b/mysql-test/r/func_debug.result index 02df7eec471..f55bfca80f5 100644 --- a/mysql-test/r/func_debug.result +++ b/mysql-test/r/func_debug.result @@ -173,29 +173,29 @@ SELECT DATE'2001-01-01' IN ('2001-01-01','2001-02-02'); DATE'2001-01-01' IN ('2001-01-01','2001-02-02') 1 Warnings: -Note 1105 DBUG: [0] arg=1 handler=0 (datetime) -Note 1105 DBUG: [1] arg=2 handler=0 (datetime) +Note 1105 DBUG: [0] arg=1 handler=0 (date) +Note 1105 DBUG: [1] arg=2 handler=0 (date) Note 1105 DBUG: types_compatible=yes bisect=yes SELECT DATE'2001-01-01' IN ('2001-01-01','2001-02-02',NULL); DATE'2001-01-01' IN ('2001-01-01','2001-02-02',NULL) 1 Warnings: -Note 1105 DBUG: [0] arg=1 handler=0 (datetime) -Note 1105 DBUG: [1] arg=2 handler=0 (datetime) +Note 1105 DBUG: [0] arg=1 handler=0 (date) +Note 1105 DBUG: [1] arg=2 handler=0 (date) Note 1105 DBUG: types_compatible=yes bisect=yes SELECT DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02'); DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02') 0 Warnings: -Note 1105 DBUG: [0] arg=1 handler=0 (datetime) -Note 1105 DBUG: [1] arg=2 handler=0 (datetime) +Note 1105 DBUG: [0] arg=1 handler=0 (date) +Note 1105 DBUG: [1] arg=2 handler=0 (date) Note 1105 DBUG: types_compatible=yes bisect=yes SELECT DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02',NULL); DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02',NULL) 0 Warnings: -Note 1105 DBUG: [0] arg=1 handler=0 (datetime) -Note 1105 DBUG: [1] arg=2 handler=0 (datetime) +Note 1105 DBUG: [0] arg=1 handler=0 (date) +Note 1105 DBUG: [1] arg=2 handler=0 (date) Note 1105 DBUG: types_compatible=yes bisect=yes # Column predicant, compatible types, bisect CREATE TABLE t1 (a INT UNSIGNED); @@ -354,38 +354,38 @@ CREATE TABLE t1 (a DATE); SELECT a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) FROM t1; a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) Warnings: -Note 1105 DBUG: [0] arg=1 handler=0 (datetime) -Note 1105 DBUG: [1] arg=2 handler=0 (datetime) -Note 1105 DBUG: [2] arg=3 handler=0 (datetime) -Note 1105 DBUG: [3] arg=4 handler=0 (datetime) -Note 1105 DBUG: [4] arg=5 handler=0 (datetime) +Note 1105 DBUG: [0] arg=1 handler=0 (date) +Note 1105 DBUG: [1] arg=2 handler=0 (date) +Note 1105 DBUG: [2] arg=3 handler=0 (date) +Note 1105 DBUG: [3] arg=4 handler=0 (date) +Note 1105 DBUG: [4] arg=5 handler=0 (date) Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) FROM t1; a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) Warnings: -Note 1105 DBUG: [0] arg=1 handler=0 (datetime) -Note 1105 DBUG: [1] arg=2 handler=0 (datetime) -Note 1105 DBUG: [2] arg=3 handler=0 (datetime) -Note 1105 DBUG: [3] arg=4 handler=0 (datetime) -Note 1105 DBUG: [4] arg=5 handler=0 (datetime) +Note 1105 DBUG: [0] arg=1 handler=0 (date) +Note 1105 DBUG: [1] arg=2 handler=0 (date) +Note 1105 DBUG: [2] arg=3 handler=0 (date) +Note 1105 DBUG: [3] arg=4 handler=0 (date) +Note 1105 DBUG: [4] arg=5 handler=0 (date) Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) FROM t1; a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) Warnings: -Note 1105 DBUG: [0] arg=1 handler=0 (datetime) -Note 1105 DBUG: [1] arg=2 handler=0 (datetime) -Note 1105 DBUG: [2] arg=3 handler=0 (datetime) -Note 1105 DBUG: [3] arg=4 handler=0 (datetime) -Note 1105 DBUG: [4] arg=5 handler=0 (datetime) +Note 1105 DBUG: [0] arg=1 handler=0 (date) +Note 1105 DBUG: [1] arg=2 handler=0 (date) +Note 1105 DBUG: [2] arg=3 handler=0 (date) +Note 1105 DBUG: [3] arg=4 handler=0 (date) +Note 1105 DBUG: [4] arg=5 handler=0 (date) Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) FROM t1; a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) Warnings: -Note 1105 DBUG: [0] arg=1 handler=0 (datetime) -Note 1105 DBUG: [1] arg=2 handler=0 (datetime) -Note 1105 DBUG: [2] arg=3 handler=0 (datetime) -Note 1105 DBUG: [3] arg=4 handler=0 (datetime) -Note 1105 DBUG: [4] arg=5 handler=0 (datetime) +Note 1105 DBUG: [0] arg=1 handler=0 (date) +Note 1105 DBUG: [1] arg=2 handler=0 (date) +Note 1105 DBUG: [2] arg=3 handler=0 (date) +Note 1105 DBUG: [3] arg=4 handler=0 (date) +Note 1105 DBUG: [4] arg=5 handler=0 (date) Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; CREATE TABLE t1 (a TIME); @@ -610,26 +610,26 @@ CREATE TABLE t1 (a DATE); SELECT DATE'2001-01-01' IN (a,'2001-01-01') FROM t1; DATE'2001-01-01' IN (a,'2001-01-01') Warnings: -Note 1105 DBUG: [0] arg=1 handler=0 (datetime) -Note 1105 DBUG: [1] arg=2 handler=0 (datetime) +Note 1105 DBUG: [0] arg=1 handler=0 (date) +Note 1105 DBUG: [1] arg=2 handler=0 (date) Note 1105 DBUG: types_compatible=yes bisect=no SELECT DATE'2001-01-01' IN (a,'2001-01-01',NULL) FROM t1; DATE'2001-01-01' IN (a,'2001-01-01',NULL) Warnings: -Note 1105 DBUG: [0] arg=1 handler=0 (datetime) -Note 1105 DBUG: [1] arg=2 handler=0 (datetime) +Note 1105 DBUG: [0] arg=1 handler=0 (date) +Note 1105 DBUG: [1] arg=2 handler=0 (date) Note 1105 DBUG: types_compatible=yes bisect=no SELECT DATE'2001-01-01' NOT IN (a,'2001-01-01') FROM t1; DATE'2001-01-01' NOT IN (a,'2001-01-01') Warnings: -Note 1105 DBUG: [0] arg=1 handler=0 (datetime) -Note 1105 DBUG: [1] arg=2 handler=0 (datetime) +Note 1105 DBUG: [0] arg=1 handler=0 (date) +Note 1105 DBUG: [1] arg=2 handler=0 (date) Note 1105 DBUG: types_compatible=yes bisect=no SELECT DATE'2001-01-01' NOT IN (a,'2001-01-01',NULL) FROM t1; DATE'2001-01-01' NOT IN (a,'2001-01-01',NULL) Warnings: -Note 1105 DBUG: [0] arg=1 handler=0 (datetime) -Note 1105 DBUG: [1] arg=2 handler=0 (datetime) +Note 1105 DBUG: [0] arg=1 handler=0 (date) +Note 1105 DBUG: [1] arg=2 handler=0 (date) Note 1105 DBUG: types_compatible=yes bisect=no DROP TABLE t1; CREATE TABLE t1 (a TIME); @@ -1147,25 +1147,25 @@ SELECT a IN (1,DATE'2001-01-01') FROM t1; a IN (1,DATE'2001-01-01') Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (double) -Note 1105 DBUG: [1] arg=2 handler=1 (datetime) +Note 1105 DBUG: [1] arg=2 handler=1 (date) Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,DATE'2001-01-01',NULL) FROM t1; a IN (1,DATE'2001-01-01',NULL) Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (double) -Note 1105 DBUG: [1] arg=2 handler=1 (datetime) +Note 1105 DBUG: [1] arg=2 handler=1 (date) Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,DATE'2001-01-01') FROM t1; a NOT IN (1,DATE'2001-01-01') Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (double) -Note 1105 DBUG: [1] arg=2 handler=1 (datetime) +Note 1105 DBUG: [1] arg=2 handler=1 (date) Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,DATE'2001-01-01',NULL) FROM t1; a NOT IN (1,DATE'2001-01-01',NULL) Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (double) -Note 1105 DBUG: [1] arg=2 handler=1 (datetime) +Note 1105 DBUG: [1] arg=2 handler=1 (date) Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,TIMESTAMP'2001-01-01 10:20:30') FROM t1; a IN (1,TIMESTAMP'2001-01-01 10:20:30') diff --git a/sql/item.cc b/sql/item.cc index bb3dd1a1c6a..617a612aeea 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -9101,101 +9101,14 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) Item *item= *ref; if (item->basic_const_item()) return; // Can't be better - - Item *new_item= NULL; - Item_result res_type= item_cmp_type(comp_item, item); - const char *name= item->name.str; // Alloced on THD::mem_root - MEM_ROOT *mem_root= thd->mem_root; - - switch (res_type) { - case TIME_RESULT: + Type_handler_hybrid_field_type cmp(comp_item->type_handler_for_comparison()); + if (!cmp.aggregate_for_comparison(item->type_handler_for_comparison())) { - bool is_null; - Item **ref_copy= ref; - /* the following call creates a constant and puts it in new_item */ - enum_field_types type= item->field_type_for_temporal_comparison(comp_item); - get_datetime_value(thd, &ref_copy, &new_item, type, &is_null); - if (is_null) - new_item= new (mem_root) Item_null(thd, name); - break; + Item *new_item= cmp.type_handler()-> + make_const_item_for_comparison(thd, item, comp_item); + if (new_item) + thd->change_item_tree(ref, new_item); } - case STRING_RESULT: - { - char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff),&my_charset_bin),*result; - result=item->val_str(&tmp); - if (item->null_value) - new_item= new (mem_root) Item_null(thd, name); - else - { - uint length= result->length(); - char *tmp_str= thd->strmake(result->ptr(), length); - new_item= new (mem_root) Item_string(thd, name, tmp_str, length, result->charset()); - } - break; - } - case INT_RESULT: - { - longlong result=item->val_int(); - uint length=item->max_length; - bool null_value=item->null_value; - new_item= (null_value ? (Item*) new (mem_root) Item_null(thd, name) : - (Item*) new (mem_root) Item_int(thd, name, result, length)); - break; - } - case ROW_RESULT: - if (item->type() == Item::ROW_ITEM && comp_item->type() == Item::ROW_ITEM) - { - /* - Substitute constants only in Item_row's. Don't affect other Items - with ROW_RESULT (eg Item_singlerow_subselect). - - For such Items more optimal is to detect if it is constant and replace - it with Item_row. This would optimize queries like this: - SELECT * FROM t1 WHERE (a,b) = (SELECT a,b FROM t2 LIMIT 1); - */ - Item_row *item_row= (Item_row*) item; - Item_row *comp_item_row= (Item_row*) comp_item; - uint col; - new_item= 0; - /* - If item and comp_item are both Item_row's and have same number of cols - then process items in Item_row one by one. - We can't ignore NULL values here as this item may be used with <=>, in - which case NULL's are significant. - */ - DBUG_ASSERT(item->result_type() == comp_item->result_type()); - DBUG_ASSERT(item_row->cols() == comp_item_row->cols()); - col= item_row->cols(); - while (col-- > 0) - resolve_const_item(thd, item_row->addr(col), - comp_item_row->element_index(col)); - break; - } - /* Fallthrough */ - case REAL_RESULT: - { // It must REAL_RESULT - double result= item->val_real(); - uint length=item->max_length,decimals=item->decimals; - bool null_value=item->null_value; - new_item= (null_value ? (Item*) new (mem_root) Item_null(thd, name) : (Item*) - new (mem_root) Item_float(thd, name, result, decimals, length)); - break; - } - case DECIMAL_RESULT: - { - my_decimal decimal_value; - my_decimal *result= item->val_decimal(&decimal_value); - uint length= item->max_length, decimals= item->decimals; - bool null_value= item->null_value; - new_item= (null_value ? - (Item*) new (mem_root) Item_null(thd, name) : - (Item*) new (mem_root) Item_decimal(thd, name, result, length, decimals)); - break; - } - } - if (new_item) - thd->change_item_tree(ref, new_item); } /** diff --git a/sql/item.h b/sql/item.h index c24ac19e439..7ccbbb4264b 100644 --- a/sql/item.h +++ b/sql/item.h @@ -733,6 +733,10 @@ public: { return Type_handler::get_handler_by_field_type(field_type()); } + const Type_handler *type_handler_for_comparison() const + { + return type_handler()->type_handler_for_comparison(); + } virtual const Type_handler *real_type_handler() const { return type_handler(); @@ -1317,23 +1321,6 @@ public: return f_type == MYSQL_TYPE_TIME ? val_time_packed() : val_datetime_packed(); } - enum_field_types field_type_for_temporal_comparison(const Item *other) const - { - if (cmp_type() == TIME_RESULT) - { - if (other->cmp_type() == TIME_RESULT) - return Field::field_type_merge(field_type(), other->field_type()); - else - return field_type(); - } - else - { - if (other->cmp_type() == TIME_RESULT) - return other->field_type(); - DBUG_ASSERT(0); // Two non-temporal data types, we should not get to here - return MYSQL_TYPE_DATETIME; - } - } bool get_seconds(ulonglong *sec, ulong *sec_part); virtual bool get_date_result(MYSQL_TIME *ltime, ulonglong fuzzydate) { return get_date(ltime,fuzzydate); } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index faf8f23ffa1..f7f3f991cde 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -552,20 +552,20 @@ bool Arg_comparator::set_cmp_func_string() } -bool Arg_comparator::set_cmp_func_temporal() +bool Arg_comparator::set_cmp_func_time() { - enum_field_types f_type= a[0]->field_type_for_temporal_comparison(b[0]); m_compare_collation= &my_charset_numeric; - if (f_type == MYSQL_TYPE_TIME) - { - func= is_owner_equal_func() ? &Arg_comparator::compare_e_time : - &Arg_comparator::compare_time; - } - else - { - func= is_owner_equal_func() ? &Arg_comparator::compare_e_datetime : - &Arg_comparator::compare_datetime; - } + func= is_owner_equal_func() ? &Arg_comparator::compare_e_time : + &Arg_comparator::compare_time; + return false; +} + + +bool Arg_comparator::set_cmp_func_datetime() +{ + m_compare_collation= &my_charset_numeric; + func= is_owner_equal_func() ? &Arg_comparator::compare_e_datetime : + &Arg_comparator::compare_datetime; return false; } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index db2f0cf02b4..63b13be2879 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -82,7 +82,8 @@ public: bool set_cmp_func_for_row_arguments(); bool set_cmp_func_row(); bool set_cmp_func_string(); - bool set_cmp_func_temporal(); + bool set_cmp_func_time(); + bool set_cmp_func_datetime(); bool set_cmp_func_int(); bool set_cmp_func_real(); bool set_cmp_func_decimal(); diff --git a/sql/sql_type.cc b/sql/sql_type.cc index abf0b77481e..fbf6c0900e0 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -457,7 +457,19 @@ const Type_handler *Type_handler_time_common::type_handler_for_comparison() cons return &type_handler_time; } -const Type_handler *Type_handler_temporal_with_date::type_handler_for_comparison() const +const Type_handler *Type_handler_date_common::type_handler_for_comparison() const +{ + return &type_handler_newdate; +} + + +const Type_handler *Type_handler_datetime_common::type_handler_for_comparison() const +{ + return &type_handler_datetime; +} + + +const Type_handler *Type_handler_timestamp_common::type_handler_for_comparison() const { return &type_handler_datetime; } @@ -652,9 +664,14 @@ Type_handler_hybrid_field_type::aggregate_for_comparison(const Type_handler *h) { /* We're here if both m_type_handler and h are temporal data types. + - If both data types are TIME, we preserve TIME. + - If both data types are DATE, we preserve DATE. + Preserving DATE is needed for EXPLAIN FORMAT=JSON, + to print DATE constants using proper format: + 'YYYY-MM-DD' rather than 'YYYY-MM-DD 00:00:00'. */ - if (field_type() != MYSQL_TYPE_TIME || h->field_type() != MYSQL_TYPE_TIME) - m_type_handler= &type_handler_datetime; // DATETIME bits TIME + if (field_type() != h->field_type()) + m_type_handler= &type_handler_datetime; } } else if ((a == INT_RESULT || a == DECIMAL_RESULT) && @@ -1917,9 +1934,15 @@ bool Type_handler_string_result::set_comparator_func(Arg_comparator *cmp) const return cmp->set_cmp_func_string(); } -bool Type_handler_temporal_result::set_comparator_func(Arg_comparator *cmp) const +bool Type_handler_time_common::set_comparator_func(Arg_comparator *cmp) const { - return cmp->set_cmp_func_temporal(); + return cmp->set_cmp_func_time(); +} + +bool +Type_handler_temporal_with_date::set_comparator_func(Arg_comparator *cmp) const +{ + return cmp->set_cmp_func_datetime(); } @@ -4211,3 +4234,113 @@ bool Type_handler:: } /***************************************************************************/ + +Item *Type_handler_int_result:: + make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const +{ + longlong result= item->val_int(); + if (item->null_value) + return new (thd->mem_root) Item_null(thd, item->name.str); + return new (thd->mem_root) Item_int(thd, item->name.str, result, + item->max_length); +} + + +Item *Type_handler_real_result:: + make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const +{ + double result= item->val_real(); + if (item->null_value) + return new (thd->mem_root) Item_null(thd, item->name.str); + return new (thd->mem_root) Item_float(thd, item->name.str, result, + item->decimals, item->max_length); +} + + +Item *Type_handler_decimal_result:: + make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const +{ + my_decimal decimal_value; + my_decimal *result= item->val_decimal(&decimal_value); + if (item->null_value) + return new (thd->mem_root) Item_null(thd, item->name.str); + return new (thd->mem_root) Item_decimal(thd, item->name.str, result, + item->max_length, item->decimals); +} + + +Item *Type_handler_string_result:: + make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const +{ + StringBuffer tmp; + String *result= item->val_str(&tmp); + if (item->null_value) + return new (thd->mem_root) Item_null(thd, item->name.str); + uint length= result->length(); + char *tmp_str= thd->strmake(result->ptr(), length); + return new (thd->mem_root) Item_string(thd, item->name.str, + tmp_str, length, result->charset()); +} + + +Item *Type_handler_time_common:: + make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const +{ + Item_cache_temporal *cache; + longlong value= item->val_time_packed(); + if (item->null_value) + return new (thd->mem_root) Item_null(thd, item->name.str); + cache= new (thd->mem_root) Item_cache_temporal(thd, field_type()); + if (cache) + cache->store_packed(value, item); + return cache; +} + + +Item *Type_handler_temporal_with_date:: + make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const +{ + Item_cache_temporal *cache; + longlong value= item->val_datetime_packed(); + if (item->null_value) + return new (thd->mem_root) Item_null(thd, item->name.str); + cache= new (thd->mem_root) Item_cache_temporal(thd, field_type()); + if (cache) + cache->store_packed(value, item); + return cache; +} + + +Item *Type_handler_row:: + make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const +{ + if (item->type() == Item::ROW_ITEM && cmp->type() == Item::ROW_ITEM) + { + /* + Substitute constants only in Item_row's. Don't affect other Items + with ROW_RESULT (eg Item_singlerow_subselect). + + For such Items more optimal is to detect if it is constant and replace + it with Item_row. This would optimize queries like this: + SELECT * FROM t1 WHERE (a,b) = (SELECT a,b FROM t2 LIMIT 1); + */ + Item_row *item_row= (Item_row*) item; + Item_row *comp_item_row= (Item_row*) cmp; + uint col; + /* + If item and comp_item are both Item_row's and have same number of cols + then process items in Item_row one by one. + We can't ignore NULL values here as this item may be used with <=>, in + which case NULL's are significant. + */ + DBUG_ASSERT(item->result_type() == cmp->result_type()); + DBUG_ASSERT(item_row->cols() == comp_item_row->cols()); + col= item_row->cols(); + while (col-- > 0) + resolve_const_item(thd, item_row->addr(col), + comp_item_row->element_index(col)); + } + return NULL; +} + +/***************************************************************************/ diff --git a/sql/sql_type.h b/sql/sql_type.h index b4564b293dd..c6e62efa8d5 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -746,6 +746,26 @@ public: virtual bool subquery_type_allows_materialization(const Item *inner, const Item *outer) const= 0; + /** + Make a simple constant replacement item for a constant "src", + so the new item can futher be used for comparison with "cmp", e.g.: + src = cmp -> replacement = cmp + + "this" is the type handler that is used to compare "src" and "cmp". + + @param thd - current thread, for mem_root + @param src - The item that we want to replace. It's a const item, + but it can be complex enough to calculate on every row. + @param cmp - The src's comparand. + @retval - a pointer to the created replacement Item + @retval - NULL, if could not create a replacement (e.g. on EOM). + NULL is also returned for ROWs, because instead of replacing + a Item_row to a new Item_row, Type_handler_row just replaces + its elements. + */ + virtual Item *make_const_item_for_comparison(THD *thd, + Item *src, + Item *cmp) const= 0; virtual Item_cache *Item_get_cache(THD *thd, const Item *item) const= 0; virtual bool set_comparator_func(Arg_comparator *cmp) const= 0; virtual bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func, @@ -935,6 +955,7 @@ public: DBUG_ASSERT(0); return false; } + Item *make_const_item_for_comparison(THD *thd, Item *src, Item *cmp) const; Item_cache *Item_get_cache(THD *thd, const Item *item) const; bool set_comparator_func(Arg_comparator *cmp) const; bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func, @@ -1137,6 +1158,7 @@ public: SORT_FIELD_ATTR *attr) const; bool Item_save_in_value(Item *item, st_value *value) const; int Item_save_in_field(Item *item, Field *field, bool no_conversions) const; + Item *make_const_item_for_comparison(THD *thd, Item *src, Item *cmp) const; Item_cache *Item_get_cache(THD *thd, const Item *item) const; bool set_comparator_func(Arg_comparator *cmp) const; bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func, @@ -1201,6 +1223,7 @@ public: return Item_send_str(item, protocol, buf); } int Item_save_in_field(Item *item, Field *field, bool no_conversions) const; + Item *make_const_item_for_comparison(THD *thd, Item *src, Item *cmp) const; Item_cache *Item_get_cache(THD *thd, const Item *item) const; bool set_comparator_func(Arg_comparator *cmp) const; bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func, @@ -1257,6 +1280,7 @@ public: SORT_FIELD_ATTR *attr) const; bool Item_save_in_value(Item *item, st_value *value) const; int Item_save_in_field(Item *item, Field *field, bool no_conversions) const; + Item *make_const_item_for_comparison(THD *thd, Item *src, Item *cmp) const; Item_cache *Item_get_cache(THD *thd, const Item *item) const; bool set_comparator_func(Arg_comparator *cmp) const; bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func, @@ -1318,7 +1342,6 @@ public: bool subquery_type_allows_materialization(const Item *inner, const Item *outer) const; Item_cache *Item_get_cache(THD *thd, const Item *item) const; - bool set_comparator_func(Arg_comparator *cmp) const; bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const; bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const; bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const; @@ -1401,6 +1424,7 @@ public: Item *source_expr, Item *source_const) const; bool subquery_type_allows_materialization(const Item *inner, const Item *outer) const; + Item *make_const_item_for_comparison(THD *thd, Item *src, Item *cmp) const; Item_cache *Item_get_cache(THD *thd, const Item *item) const; bool set_comparator_func(Arg_comparator *cmp) const; bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func, @@ -1693,6 +1717,8 @@ public: String *print_item_value(THD *thd, Item *item, String *str) const; bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func, Item **items, uint nitems) const; + Item *make_const_item_for_comparison(THD *thd, Item *src, Item *cmp) const; + bool set_comparator_func(Arg_comparator *cmp) const; cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const; in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const; }; @@ -1729,13 +1755,14 @@ class Type_handler_temporal_with_date: public Type_handler_temporal_result { public: virtual ~Type_handler_temporal_with_date() {} - const Type_handler *type_handler_for_comparison() const; bool Item_save_in_value(Item *item, st_value *value) const; bool Item_send(Item *item, Protocol *protocol, st_value *buf) const { return Item_send_date(item, protocol, buf); } int Item_save_in_field(Item *item, Field *field, bool no_conversions) const; + Item *make_const_item_for_comparison(THD *thd, Item *src, Item *cmp) const; + bool set_comparator_func(Arg_comparator *cmp) const; cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const; in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const; }; @@ -1747,6 +1774,7 @@ class Type_handler_date_common: public Type_handler_temporal_with_date public: virtual ~Type_handler_date_common() {} const Name name() const { return m_name_date; } + const Type_handler *type_handler_for_comparison() const; enum_field_types field_type() const { return MYSQL_TYPE_DATE; } enum_mysql_timestamp_type mysql_timestamp_type() const { @@ -1790,6 +1818,7 @@ class Type_handler_datetime_common: public Type_handler_temporal_with_date public: virtual ~Type_handler_datetime_common() {} const Name name() const { return m_name_datetime; } + const Type_handler *type_handler_for_comparison() const; enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } enum_mysql_timestamp_type mysql_timestamp_type() const { @@ -1846,6 +1875,7 @@ class Type_handler_timestamp_common: public Type_handler_temporal_with_date public: virtual ~Type_handler_timestamp_common() {} const Name name() const { return m_name_timestamp; } + const Type_handler *type_handler_for_comparison() const; enum_field_types field_type() const { return MYSQL_TYPE_TIMESTAMP; } enum_mysql_timestamp_type mysql_timestamp_type() const {