mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
MDEV-11485 Split Item_func_between::val_int() into virtual methods in Type_handler
- Removes "Item_result Item_func_opt_neg::m_compare_type" and introduces "Type_handler_hybrid_field_type Item_func_opt_neg::m_comparator" instead. - Removes Item_func_between::compare_as_dates, because the new member m_comparator now contains the precise information about the data type that is used for comparison, which is important for TIME vs DATETIME. - Adds a new method: Type_handler_hybrid_field_type::aggregate_for_comparison(const Type_handler*), as a better replacement for item_cmp_type(), which additionally can handle TIME vs DATE/DATETIME/TIMESTAMP correctly. Additionally, it correctly handles TIMESTAMP which fixes the problem reported in MDEV-11482. The old compare_as_dates/find_date_time_item() based code didn't handle comparison between TIME and TIMESTAMP correctly and erroneously used TIME comparison instead of DATETIME comparison. - Adds a new method: Type_handler_hybrid_field_type::aggregate_for_comparison(Item **, uint nitems), as a better replacement for agg_cmp_type(), which can handle TIME. - Splits Item_func_between::val_int() into pieces val_int_cmp_xxx(), one new method per XXX_RESULT. - Adds a new virtual method Type_handler::Item_func_between_val_int() whose implementations use Item_func_between::val_int_cmp_xxx(). - Makes type_handler_longlong and type_handler_newdecimal public, as they are now needed in item_cmpfunc.cc. Note: This patch does not change Item_func_in to use the new aggregation methods, so it still uses collect_cmp_type()/item_cmp_type() based aggregation. Item_func_in will be changed in a separate patch and item_cmp_type() will be removed.
This commit is contained in:
@@ -23,7 +23,6 @@
|
||||
static Type_handler_tiny type_handler_tiny;
|
||||
static Type_handler_short type_handler_short;
|
||||
static Type_handler_long type_handler_long;
|
||||
static Type_handler_longlong type_handler_longlong;
|
||||
static Type_handler_int24 type_handler_int24;
|
||||
static Type_handler_year type_handler_year;
|
||||
static Type_handler_bit type_handler_bit;
|
||||
@@ -38,7 +37,6 @@ static Type_handler_datetime2 type_handler_datetime2;
|
||||
static Type_handler_timestamp type_handler_timestamp;
|
||||
static Type_handler_timestamp2 type_handler_timestamp2;
|
||||
static Type_handler_olddecimal type_handler_olddecimal;
|
||||
static Type_handler_newdecimal type_handler_newdecimal;
|
||||
static Type_handler_string type_handler_string;
|
||||
static Type_handler_tiny_blob type_handler_tiny_blob;
|
||||
static Type_handler_medium_blob type_handler_medium_blob;
|
||||
@@ -54,6 +52,8 @@ static Type_handler_set type_handler_set;
|
||||
Type_handler_null type_handler_null;
|
||||
Type_handler_row type_handler_row;
|
||||
Type_handler_varchar type_handler_varchar;
|
||||
Type_handler_longlong type_handler_longlong;
|
||||
Type_handler_newdecimal type_handler_newdecimal;
|
||||
|
||||
|
||||
/**
|
||||
@@ -123,6 +123,55 @@ Type_handler_hybrid_field_type::Type_handler_hybrid_field_type()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Collect built-in data type handlers for comparison.
|
||||
This method is very similar to item_cmp_type() defined in item.cc.
|
||||
Now they coexist. Later item_cmp_type() will be removed.
|
||||
In addition to item_cmp_type(), this method correctly aggregates
|
||||
TIME with DATETIME/TIMESTAMP/DATE, so no additional find_date_time_item()
|
||||
is needed after this call.
|
||||
*/
|
||||
void
|
||||
Type_handler_hybrid_field_type::aggregate_for_comparison(const Type_handler *h)
|
||||
{
|
||||
Item_result a= cmp_type();
|
||||
Item_result b= h->cmp_type();
|
||||
if (a == STRING_RESULT && b == STRING_RESULT)
|
||||
m_type_handler= &type_handler_long_blob;
|
||||
else if (a == INT_RESULT && b == INT_RESULT)
|
||||
m_type_handler= &type_handler_longlong;
|
||||
else if (a == ROW_RESULT || b == ROW_RESULT)
|
||||
m_type_handler= &type_handler_row;
|
||||
else if (a == TIME_RESULT || b == TIME_RESULT)
|
||||
{
|
||||
if ((a == TIME_RESULT) + (b == TIME_RESULT) == 1)
|
||||
{
|
||||
/*
|
||||
We're here if there's only one temporal data type:
|
||||
either m_type_handler or h.
|
||||
*/
|
||||
if (b == TIME_RESULT)
|
||||
m_type_handler= h; // Temporal types bit non-temporal types
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
We're here if both m_type_handler and h are temporal data types.
|
||||
*/
|
||||
if (field_type() != MYSQL_TYPE_TIME || h->field_type() != MYSQL_TYPE_TIME)
|
||||
m_type_handler= &type_handler_datetime; // DATETIME bits TIME
|
||||
}
|
||||
}
|
||||
else if ((a == INT_RESULT || a == DECIMAL_RESULT) &&
|
||||
(b == INT_RESULT || b == DECIMAL_RESULT))
|
||||
{
|
||||
m_type_handler= &type_handler_newdecimal;
|
||||
}
|
||||
else
|
||||
m_type_handler= &type_handler_double;
|
||||
}
|
||||
|
||||
|
||||
const Type_handler *
|
||||
Type_handler::get_handler_by_field_type(enum_field_types type)
|
||||
{
|
||||
@@ -1141,3 +1190,43 @@ Type_handler_string_result::Item_func_hybrid_field_type_get_date(
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
longlong Type_handler_row::
|
||||
Item_func_between_val_int(Item_func_between *func) const
|
||||
{
|
||||
DBUG_ASSERT(0);
|
||||
func->null_value= true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
longlong Type_handler_string_result::
|
||||
Item_func_between_val_int(Item_func_between *func) const
|
||||
{
|
||||
return func->val_int_cmp_string();
|
||||
}
|
||||
|
||||
longlong Type_handler_temporal_result::
|
||||
Item_func_between_val_int(Item_func_between *func) const
|
||||
{
|
||||
return func->val_int_cmp_temporal();
|
||||
}
|
||||
|
||||
longlong Type_handler_int_result::
|
||||
Item_func_between_val_int(Item_func_between *func) const
|
||||
{
|
||||
return func->val_int_cmp_int();
|
||||
}
|
||||
|
||||
longlong Type_handler_real_result::
|
||||
Item_func_between_val_int(Item_func_between *func) const
|
||||
{
|
||||
return func->val_int_cmp_real();
|
||||
}
|
||||
|
||||
longlong Type_handler_decimal_result::
|
||||
Item_func_between_val_int(Item_func_between *func) const
|
||||
{
|
||||
return func->val_int_cmp_decimal();
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
Reference in New Issue
Block a user