MDEV-12717 Change Item_equal to operate Type_handler rather than Item_result

This commit is contained in:
Alexander Barkov 2017-05-07 01:02:37 +04:00
parent aea54a11a6
commit cc694792c9
6 changed files with 71 additions and 22 deletions

View File

@ -1179,7 +1179,7 @@ bool Field::test_if_equality_guarantees_uniqueness(const Item *item) const
bool Field::can_be_substituted_to_equal_item(const Context &ctx,
const Item_equal *item_equal)
{
DBUG_ASSERT(item_equal->compare_type() != STRING_RESULT);
DBUG_ASSERT(item_equal->compare_type_handler()->cmp_type() != STRING_RESULT);
DBUG_ASSERT(cmp_type() != STRING_RESULT);
switch (ctx.subst_constraint()) {
case ANY_SUBST:
@ -1192,7 +1192,7 @@ bool Field::can_be_substituted_to_equal_item(const Context &ctx,
Items don't know the context they are in and there are functions like
IF (<hex_string>, 'yes', 'no').
*/
return ctx.compare_type() == item_equal->compare_type();
return ctx.compare_type_handler() == item_equal->compare_type_handler();
case IDENTITY_SUBST:
return true;
}
@ -1308,7 +1308,7 @@ Item *Field_num::get_equal_zerofill_const_item(THD *thd, const Context &ctx,
break;
}
DBUG_ASSERT(const_item->const_item());
DBUG_ASSERT(ctx.compare_type() != STRING_RESULT);
DBUG_ASSERT(ctx.compare_type_handler()->cmp_type() != STRING_RESULT);
return const_item;
}
@ -2013,11 +2013,11 @@ bool Field_str::test_if_equality_guarantees_uniqueness(const Item *item) const
bool Field_str::can_be_substituted_to_equal_item(const Context &ctx,
const Item_equal *item_equal)
{
DBUG_ASSERT(item_equal->compare_type() == STRING_RESULT);
DBUG_ASSERT(item_equal->compare_type_handler()->cmp_type() == STRING_RESULT);
switch (ctx.subst_constraint()) {
case ANY_SUBST:
return ctx.compare_type() == item_equal->compare_type() &&
(ctx.compare_type() != STRING_RESULT ||
return ctx.compare_type_handler() == item_equal->compare_type_handler() &&
(ctx.compare_type_handler()->cmp_type() != STRING_RESULT ||
ctx.compare_collation() == item_equal->compare_collation());
case IDENTITY_SUBST:
return ((charset()->state & MY_CS_BINSORT) &&
@ -5859,6 +5859,39 @@ int Field_time::store_decimal(const my_decimal *d)
}
bool Field_time::can_be_substituted_to_equal_item(const Context &ctx,
const Item_equal *item_equal)
{
DBUG_ASSERT(item_equal->compare_type_handler()->cmp_type() != STRING_RESULT);
switch (ctx.subst_constraint()) {
case ANY_SUBST:
/*
A TIME field in a DATETIME comparison can be substituted to
Item_equal with TIME comparison.
SET timestamp=UNIX_TIMESTAMP('2015-08-30 10:20:30');
CREATE OR REPLACE TABLE t1 (a TIME);
INSERT INTO t1 VALUES ('00:00:00'),('00:00:01');
SELECT * FROM t1 WHERE a>=TIMESTAMP'2015-08-30 00:00:00'
AND a='00:00:00';
The above query can be simplified to:
SELECT * FROM t1 WHERE TIME'00:00:00'>=TIMESTAMP'2015-08-30 00:00:00'
AND a='00:00:00';
And further to:
SELECT * FROM t1 WHERE a=TIME'00:00:00';
*/
if (ctx.compare_type_handler() == &type_handler_datetime &&
item_equal->compare_type_handler() == &type_handler_time)
return true;
return ctx.compare_type_handler() == item_equal->compare_type_handler();
case IDENTITY_SUBST:
return true;
}
return false;
}
Item *Field_time::get_equal_const_item(THD *thd, const Context &ctx,
Item *const_item)
{

View File

@ -380,10 +380,10 @@ public:
m_compare_collation(cs)
{ DBUG_ASSERT(h == h->type_handler_for_comparison()); }
Subst_constraint subst_constraint() const { return m_subst_constraint; }
Item_result compare_type() const
const Type_handler *compare_type_handler() const
{
DBUG_ASSERT(m_subst_constraint == ANY_SUBST);
return m_compare_handler->cmp_type();
return m_compare_handler;
}
CHARSET_INFO *compare_collation() const
{
@ -2645,6 +2645,8 @@ public:
:Field_temporal(ptr_arg, length_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg), curdays(0)
{}
bool can_be_substituted_to_equal_item(const Context &ctx,
const Item_equal *item_equal);
const Type_handler *type_handler() const { return &type_handler_time; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; }
Copy_func *get_copy_func(const Field *from) const

View File

@ -6031,7 +6031,8 @@ Item *Item_field::replace_equal_field(THD *thd, uchar *arg)
comparison context, and it's safe to replace it to the constant from
item_equal.
*/
DBUG_ASSERT(cmp_type() == item_equal->compare_type());
DBUG_ASSERT(type_handler()->type_handler_for_comparison()->cmp_type() ==
item_equal->compare_type_handler()->cmp_type());
return const_item2;
}
Item_field *subst=

View File

@ -6021,10 +6021,11 @@ Item *Item_bool_rowready_func2::negated_item(THD *thd)
of the type Item_field or Item_direct_view_ref(Item_field).
*/
Item_equal::Item_equal(THD *thd, Item *f1, Item *f2, bool with_const_item):
Item_equal::Item_equal(THD *thd, const Type_handler *handler,
Item *f1, Item *f2, bool with_const_item):
Item_bool_func(thd), eval_item(0), cond_false(0), cond_true(0),
context_field(NULL), link_equal_fields(FALSE),
m_compare_type(item_cmp_type(f1, f2)),
m_compare_handler(handler),
m_compare_collation(f2->collation.collation)
{
const_item_cache= 0;
@ -6050,7 +6051,7 @@ Item_equal::Item_equal(THD *thd, Item *f1, Item *f2, bool with_const_item):
Item_equal::Item_equal(THD *thd, Item_equal *item_equal):
Item_bool_func(thd), eval_item(0), cond_false(0), cond_true(0),
context_field(NULL), link_equal_fields(FALSE),
m_compare_type(item_equal->m_compare_type),
m_compare_handler(item_equal->m_compare_handler),
m_compare_collation(item_equal->m_compare_collation)
{
const_item_cache= 0;
@ -6093,7 +6094,7 @@ void Item_equal::add_const(THD *thd, Item *c)
return;
}
Item *const_item= get_const();
switch (Item_equal::compare_type()) {
switch (Item_equal::compare_type_handler()->cmp_type()) {
case TIME_RESULT:
{
enum_field_types f_type= context_field->field_type();

View File

@ -2899,14 +2899,15 @@ class Item_equal: public Item_bool_func
bool link_equal_fields;
Item_result m_compare_type;
const Type_handler *m_compare_handler;
CHARSET_INFO *m_compare_collation;
String cmp_value1, cmp_value2;
public:
COND_EQUAL *upper_levels; /* multiple equalities of upper and levels */
Item_equal(THD *thd, Item *f1, Item *f2, bool with_const_item);
Item_equal(THD *thd, const Type_handler *handler,
Item *f1, Item *f2, bool with_const_item);
Item_equal(THD *thd, Item_equal *item_equal);
/* Currently the const item is always the first in the list of equal items */
inline Item* get_const() { return with_const ? equal_items.head() : NULL; }
@ -2939,7 +2940,7 @@ public:
bool walk(Item_processor processor, bool walk_subquery, void *arg);
Item *transform(THD *thd, Item_transformer transformer, uchar *arg);
virtual void print(String *str, enum_query_type query_type);
Item_result compare_type() const { return m_compare_type; }
const Type_handler *compare_type_handler() const { return m_compare_handler; }
CHARSET_INFO *compare_collation() const { return m_compare_collation; }
void set_context_field(Item_field *ctx_field) { context_field= ctx_field; }

View File

@ -12829,10 +12829,15 @@ static bool check_simple_equality(THD *thd, const Item::Context &ctx,
else
{
/* None of the fields was found in multiple equalities */
Item_equal *item_equal= new (thd->mem_root) Item_equal(thd,
orig_left_item,
orig_right_item,
FALSE);
Type_handler_hybrid_field_type
tmp(orig_left_item->type_handler_for_comparison());
if (tmp.aggregate_for_comparison(orig_right_item->
type_handler_for_comparison()))
return false;
Item_equal *item_equal=
new (thd->mem_root) Item_equal(thd, tmp.type_handler(),
orig_left_item, orig_right_item,
false);
item_equal->set_context_field((Item_field*)left_item);
cond_equal->current_level.push_back(item_equal, thd->mem_root);
}
@ -12917,8 +12922,14 @@ static bool check_simple_equality(THD *thd, const Item::Context &ctx,
}
else
{
item_equal= new (thd->mem_root) Item_equal(thd, const_item2,
orig_field_item, TRUE);
Type_handler_hybrid_field_type
tmp(orig_left_item->type_handler_for_comparison());
if (tmp.aggregate_for_comparison(orig_right_item->
type_handler_for_comparison()))
return false;
item_equal= new (thd->mem_root) Item_equal(thd, tmp.type_handler(),
const_item2,
orig_field_item, true);
item_equal->set_context_field(field_item);
cond_equal->current_level.push_back(item_equal, thd->mem_root);
}