MDEV-12717 Change Item_equal to operate Type_handler rather than Item_result
This commit is contained in:
parent
aea54a11a6
commit
cc694792c9
45
sql/field.cc
45
sql/field.cc
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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=
|
||||
|
@ -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();
|
||||
|
@ -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; }
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user