summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc49
1 files changed, 30 insertions, 19 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 823b8470f4a..7d7bced4872 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -422,7 +422,6 @@ Item::Item(THD *thd):
maybe_null=null_value=with_sum_func=with_field=0;
in_rollup= 0;
with_subselect= 0;
- cmp_context= IMPOSSIBLE_RESULT;
/* Initially this item is not attached to any JOIN_TAB. */
join_tab_idx= MAX_TABLES;
@@ -468,8 +467,7 @@ Item::Item(THD *thd, Item *item):
with_field(item->with_field),
fixed(item->fixed),
is_autogenerated_name(item->is_autogenerated_name),
- with_subselect(item->has_subquery()),
- cmp_context(item->cmp_context)
+ with_subselect(item->has_subquery())
{
next= thd->free_list; // Put in free list
thd->free_list= this;
@@ -5371,7 +5369,7 @@ Item_equal *Item_field::find_item_equal(COND_EQUAL *cond_equal)
bool Item_field::can_be_substituted_to_equal_item(const Context &ctx,
const Item_equal *item_equal)
{
- if (cmp_context == STRING_RESULT &&
+ if (ctx.compare_type() == STRING_RESULT &&
ctx.compare_collation() != item_equal->compare_collation())
return false;
return ctx.subst_constraint() == ANY_SUBST ||
@@ -5440,31 +5438,33 @@ Item *Item_field::propagate_equal_fields(THD *thd,
{
if (no_const_subst)
return this;
- item_equal= find_item_equal((COND_EQUAL *) arg);
+ item_equal= find_item_equal(arg);
Item *item= 0;
if (item_equal)
{
- if (!can_be_substituted_to_equal_item(ctx, item_equal))
+ /*
+ Disable const propagation for items used in different comparison contexts.
+ This must be done because, for example, Item_hex_string->val_int() is not
+ the same as (Item_hex_string->val_str() in BINARY column)->val_int().
+ We cannot simply disable the replacement in a particular context (
+ e.g. <bin_col> = <int_col> AND <bin_col> = <hex_string>) since
+ Items don't know the context they are in and there are functions like
+ IF (<hex_string>, 'yes', 'no').
+ */
+ if (!can_be_substituted_to_equal_item(ctx, item_equal) ||
+ !ctx.has_compatible_context(item_equal->compare_type()))
{
item_equal= NULL;
return this;
}
item= item_equal->get_const();
}
- /*
- Disable const propagation for items used in different comparison contexts.
- This must be done because, for example, Item_hex_string->val_int() is not
- the same as (Item_hex_string->val_str() in BINARY column)->val_int().
- We cannot simply disable the replacement in a particular context (
- e.g. <bin_col> = <int_col> AND <bin_col> = <hex_string>) since
- Items don't know the context they are in and there are functions like
- IF (<hex_string>, 'yes', 'no').
- */
- if (!item || !has_compatible_context(item))
+ if (!item)
item= this;
else if (field && (field->flags & ZEROFILL_FLAG) && IS_NUM(field->type()))
{
- if (item && (cmp_context == STRING_RESULT || cmp_context == IMPOSSIBLE_RESULT))
+ DBUG_ASSERT(ctx.compare_type() != STRING_RESULT);
+ if (item && (ctx.subst_constraint() == IDENTITY_SUBST))
convert_zerofill_number_to_string(thd, &item, (Field_num *)field);
else
item= this;
@@ -5521,8 +5521,19 @@ Item *Item_field::replace_equal_field(THD *thd, uchar *arg)
Item *const_item2= item_equal->get_const();
if (const_item2)
{
- if (!has_compatible_context(const_item2))
- return this;
+ /*
+ Currently we don't allow to create Item_equal with compare_type()
+ different from its Item_field's cmp_type().
+ Field_xxx::test_if_equality_guarantees_uniqueness() prevent this.
+ Also, Item_field::propagate_equal_fields() does not allow to assign
+ this->item_equal to any instances of Item_equal if "this" is used
+ in a non-native comparison context, or with an incompatible collation.
+ So the fact that we have (item_equal != NULL) means that the currently
+ processed function (the owner of "this") uses the field in its native
+ comparison context, and it's safe to replace it to the constant from
+ item_equal.
+ */
+ DBUG_ASSERT(cmp_type() == item_equal->compare_type());
return const_item2;
}
Item_field *subst=