Skip to content

Commit

Permalink
MDEV-11344 Split Arg_comparator::set_compare_func() into virtual meth…
Browse files Browse the repository at this point in the history
…ods in Type_handler

This patch:
- Introduces a new virtuial method Type_handler::set_comparator_func
  and moves pieces of the code from the switch in
  Arg_comparator::set_compare_func into the corresponding
  Type_handler_xxx::set_comparator_func.
- Adds Type_handler::get_handler_by_cmp_type()
- Moves Type_handler_hybrid_field_type::get_handler_by_result_type() to
  a static method Type_handler::get_handler_by_result_type(),
  for symmetry with similar methods:
  * Type_handler::get_handler_by_field_type()
  * Type_handler::get_handler_by_real_type()
  * Type_handler::get_handler_by_cmp_type()
- Introduces Type_handler_row, to unify the code for the scalar
  data types and the ROW data type (currently for comparison purposes only).
- Adds public type_handler_row, as it's now needed in item_row.h
- Makes type_handler_null public, as it's now needed in item_cmpfunc.h
  Note, other type_handler_xxx will become public as well later.
- Removes the global variable Arg_comparator::comparator_matrix,
  as it's not needed any more.
  • Loading branch information
Alexander Barkov committed Dec 16, 2016
1 parent cb16d75 commit 2637828
Show file tree
Hide file tree
Showing 6 changed files with 248 additions and 117 deletions.
208 changes: 114 additions & 94 deletions sql/item_cmpfunc.cc
Expand Up @@ -522,78 +522,6 @@ void Item_bool_rowready_func2::fix_length_and_dec()
}


int Arg_comparator::set_compare_func(Item_func_or_sum *item, Item_result type)
{
owner= item;
func= comparator_matrix[type]
[is_owner_equal_func()];

switch (type) {
case TIME_RESULT:
m_compare_collation= &my_charset_numeric;
break;
case ROW_RESULT:
{
uint n= (*a)->cols();
if (n != (*b)->cols())
{
my_error(ER_OPERAND_COLUMNS, MYF(0), n);
comparators= 0;
return 1;
}
if (!(comparators= new Arg_comparator[n]))
return 1;
for (uint i=0; i < n; i++)
{
if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
{
my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
return 1;
}
if (comparators[i].set_cmp_func(owner, (*a)->addr(i),
(*b)->addr(i), set_null))
return 1;
}
break;
}
case INT_RESULT:
{
if (func == &Arg_comparator::compare_int_signed)
{
if ((*a)->unsigned_flag)
func= (((*b)->unsigned_flag)?
&Arg_comparator::compare_int_unsigned :
&Arg_comparator::compare_int_unsigned_signed);
else if ((*b)->unsigned_flag)
func= &Arg_comparator::compare_int_signed_unsigned;
}
else if (func== &Arg_comparator::compare_e_int)
{
if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
func= &Arg_comparator::compare_e_int_diff_signedness;
}
break;
}
case STRING_RESULT:
case DECIMAL_RESULT:
break;
case REAL_RESULT:
{
if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
{
precision= 5 / log_10[MY_MAX((*a)->decimals, (*b)->decimals) + 1];
if (func == &Arg_comparator::compare_real)
func= &Arg_comparator::compare_real_fixed;
else if (func == &Arg_comparator::compare_e_real)
func= &Arg_comparator::compare_e_real_fixed;
}
break;
}
}
return 0;
}


/**
Prepare the comparator (set the comparison function) for comparing
items *a1 and *a2 in the context of 'type'.
Expand All @@ -615,9 +543,51 @@ int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg,
set_null= set_null && owner_arg;
a= a1;
b= a2;
m_compare_type= item_cmp_type(*a1, *a2);
m_compare_handler= Type_handler::get_handler_by_cmp_type(item_cmp_type(*a1,
*a2));
return m_compare_handler->set_comparator_func(this);
}

if (m_compare_type == STRING_RESULT &&

bool Arg_comparator::set_cmp_func_for_row_arguments()
{
uint n= (*a)->cols();
if (n != (*b)->cols())
{
my_error(ER_OPERAND_COLUMNS, MYF(0), n);
comparators= 0;
return true;
}
if (!(comparators= new Arg_comparator[n]))
return true;
for (uint i=0; i < n; i++)
{
if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
{
my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
return true;
}
if (comparators[i].set_cmp_func(owner, (*a)->addr(i),
(*b)->addr(i), set_null))
return true;
}
return false;
}


bool Arg_comparator::set_cmp_func_row()
{
func= is_owner_equal_func() ? &Arg_comparator::compare_e_row :
&Arg_comparator::compare_row;
return set_cmp_func_for_row_arguments();
}


bool Arg_comparator::set_cmp_func_string()
{
func= is_owner_equal_func() ? &Arg_comparator::compare_e_string :
&Arg_comparator::compare_string;
if (compare_type() == STRING_RESULT &&
(*a)->result_type() == STRING_RESULT &&
(*b)->result_type() == STRING_RESULT)
{
Expand All @@ -626,37 +596,87 @@ int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg,
generated item, like in natural join
*/
if (owner->agg_arg_charsets_for_comparison(&m_compare_collation, a, b))
return 1;
return true;
}
a= cache_converted_constant(thd, a, &a_cache, compare_type());
b= cache_converted_constant(thd, b, &b_cache, compare_type());
return false;
}


if (m_compare_type == TIME_RESULT)
bool Arg_comparator::set_cmp_func_temporal()
{
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)
{
enum_field_types f_type= a[0]->field_type_for_temporal_comparison(b[0]);
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;
}
return 0;
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;
}
return false;
}


if (m_compare_type == INT_RESULT &&
(*a)->field_type() == MYSQL_TYPE_YEAR &&
bool Arg_comparator::set_cmp_func_int()
{
func= is_owner_equal_func() ? &Arg_comparator::compare_e_int :
&Arg_comparator::compare_int_signed;
if ((*a)->field_type() == MYSQL_TYPE_YEAR &&
(*b)->field_type() == MYSQL_TYPE_YEAR)
{
m_compare_type= TIME_RESULT;
func= is_owner_equal_func() ? &Arg_comparator::compare_e_datetime :
&Arg_comparator::compare_datetime;
}
else if (func == &Arg_comparator::compare_int_signed)
{
if ((*a)->unsigned_flag)
func= (((*b)->unsigned_flag)?
&Arg_comparator::compare_int_unsigned :
&Arg_comparator::compare_int_unsigned_signed);
else if ((*b)->unsigned_flag)
func= &Arg_comparator::compare_int_signed_unsigned;
}
else if (func== &Arg_comparator::compare_e_int)
{
if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
func= &Arg_comparator::compare_e_int_diff_signedness;
}
a= cache_converted_constant(thd, a, &a_cache, compare_type());
b= cache_converted_constant(thd, b, &b_cache, compare_type());
return false;
}


a= cache_converted_constant(thd, a, &a_cache, m_compare_type);
b= cache_converted_constant(thd, b, &b_cache, m_compare_type);
return set_compare_func(owner_arg, m_compare_type);
bool Arg_comparator::set_cmp_func_real()
{
func= is_owner_equal_func() ? &Arg_comparator::compare_e_real :
&Arg_comparator::compare_real;
if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
{
precision= 5 / log_10[MY_MAX((*a)->decimals, (*b)->decimals) + 1];
if (func == &Arg_comparator::compare_real)
func= &Arg_comparator::compare_real_fixed;
else if (func == &Arg_comparator::compare_e_real)
func= &Arg_comparator::compare_e_real_fixed;
}
a= cache_converted_constant(thd, a, &a_cache, compare_type());
b= cache_converted_constant(thd, b, &b_cache, compare_type());
return false;
}


bool Arg_comparator::set_cmp_func_decimal()
{
func= is_owner_equal_func() ? &Arg_comparator::compare_e_decimal :
&Arg_comparator::compare_decimal;
a= cache_converted_constant(thd, a, &a_cache, compare_type());
b= cache_converted_constant(thd, b, &b_cache, compare_type());
return false;
}


Expand Down
21 changes: 15 additions & 6 deletions sql/item_cmpfunc.h
Expand Up @@ -47,7 +47,7 @@ typedef int (*Item_field_cmpfunc)(Item *f1, Item *f2, void *arg);
class Arg_comparator: public Sql_alloc
{
Item **a, **b;
Item_result m_compare_type;
const Type_handler *m_compare_handler;
CHARSET_INFO *m_compare_collation;
arg_cmp_func func;
Item_func_or_sum *owner;
Expand All @@ -58,7 +58,7 @@ class Arg_comparator: public Sql_alloc
THD *thd;
Item *a_cache, *b_cache; // Cached values of a and b items
// when one of arguments is NULL.
int set_compare_func(Item_func_or_sum *owner, Item_result type);

int set_cmp_func(Item_func_or_sum *owner_arg, Item **a1, Item **a2);

int compare_temporal(enum_field_types type);
Expand All @@ -68,17 +68,26 @@ class Arg_comparator: public Sql_alloc
/* Allow owner function to use string buffers. */
String value1, value2;

Arg_comparator(): m_compare_type(STRING_RESULT),
Arg_comparator():
m_compare_handler(&type_handler_null),
m_compare_collation(&my_charset_bin),
set_null(TRUE), comparators(0), thd(0),
a_cache(0), b_cache(0) {};
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2),
m_compare_type(STRING_RESULT),
m_compare_handler(&type_handler_null),
m_compare_collation(&my_charset_bin),
set_null(TRUE), comparators(0), thd(0),
a_cache(0), b_cache(0) {};

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_int();
bool set_cmp_func_real();
bool set_cmp_func_decimal();

inline int set_cmp_func(Item_func_or_sum *owner_arg,
Item **a1, Item **a2, bool set_null_arg)
{
Expand Down Expand Up @@ -110,13 +119,13 @@ class Arg_comparator: public Sql_alloc

Item** cache_converted_constant(THD *thd, Item **value, Item **cache,
Item_result type);
static arg_cmp_func comparator_matrix [6][2];
inline bool is_owner_equal_func()
{
return (owner->type() == Item::FUNC_ITEM &&
((Item_func*)owner)->functype() == Item_func::EQUAL_FUNC);
}
Item_result compare_type() const { return m_compare_type; }
const Type_handler *compare_type_handler() const { return m_compare_handler; }
Item_result compare_type() const { return m_compare_handler->cmp_type(); }
CHARSET_INFO *compare_collation() const { return m_compare_collation; }
Arg_comparator *subcomparators() const { return comparators; }
void cleanup()
Expand Down
1 change: 1 addition & 0 deletions sql/item_row.h
Expand Up @@ -56,6 +56,7 @@ class Item_row: public Item,
{}

enum Type type() const { return ROW_ITEM; };
const Type_handler *type_handler() const { return &type_handler_row; }
void illegal_method_call(const char *);
bool is_null() { return null_value; }
void make_field(THD *thd, Send_field *)
Expand Down
8 changes: 0 additions & 8 deletions sql/mysqld.cc
Expand Up @@ -309,14 +309,6 @@ static my_bool opt_autocommit; ///< for --autocommit command-line option
*/
static my_bool opt_verbose= 0;

arg_cmp_func Arg_comparator::comparator_matrix[6][2] =
{{&Arg_comparator::compare_string, &Arg_comparator::compare_e_string},
{&Arg_comparator::compare_real, &Arg_comparator::compare_e_real},
{&Arg_comparator::compare_int_signed, &Arg_comparator::compare_e_int},
{&Arg_comparator::compare_row, &Arg_comparator::compare_e_row},
{&Arg_comparator::compare_decimal, &Arg_comparator::compare_e_decimal},
{&Arg_comparator::compare_datetime, &Arg_comparator::compare_e_datetime}};

/* Timer info to be used by the SQL layer */
MY_TIMER_INFO sys_timer_info;

Expand Down

0 comments on commit 2637828

Please sign in to comment.