summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2016-12-14 10:11:52 -0800
committerIgor Babaev <igor@askmonty.org>2016-12-14 10:13:52 -0800
commit441fa0056da27e83771a7d7ccd09da8b38f22417 (patch)
tree24689f3e3f96d0ac1fbc1c916535e82a91e02e83 /sql/item.cc
parente9ada862651fdb98f84871e4ec59bef1bb36646d (diff)
downloadmariadb-git-441fa0056da27e83771a7d7ccd09da8b38f22417.tar.gz
Fixed bug mdev-11488.
The patch for bug mdev-10882 tried to fix it by providing an implementation of the virtual method build_clone for the class Item_cache. It's turned out that it is not easy provide a valid implementation for Item_cache::build_clone(). At the same time if the condition that can be pushed into a materialized view contains a cached item this item can be substituted for a basic constant of the same value. In such a way we can avoid building proper clones for Item_cache objects when constructing pushdown conditions.
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc73
1 files changed, 73 insertions, 0 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 880275ec997..ead45f84305 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -9406,6 +9406,17 @@ int Item_cache_int::save_in_field(Field *field, bool no_conversions)
}
+Item *Item_cache_int::convert_to_basic_const_item(THD *thd)
+{
+ Item *new_item;
+ DBUG_ASSERT(value_cached || example != 0);
+ new_item= null_value ?
+ (Item*) new (thd->mem_root) Item_null(thd) :
+ (Item*) new (thd->mem_root) Item_int(thd, val_int(), max_length);
+ return new_item;
+}
+
+
Item_cache_temporal::Item_cache_temporal(THD *thd,
enum_field_types field_type_arg):
Item_cache_int(thd, field_type_arg)
@@ -9561,6 +9572,23 @@ Item *Item_cache_temporal::clone_item(THD *thd)
}
+Item *Item_cache_temporal::convert_to_basic_const_item(THD *thd)
+{
+ Item *new_item;
+ DBUG_ASSERT(value_cached || example != 0);
+ if (null_value)
+ new_item= (Item*) new (thd->mem_root) Item_null(thd);
+ else
+ {
+ MYSQL_TIME ltime;
+ unpack_time(val_datetime_packed(), &ltime);
+ new_item= (Item*) new (thd->mem_root) Item_datetime_literal(thd, &ltime,
+ decimals);
+ }
+ return new_item;
+}
+
+
bool Item_cache_real::cache_value()
{
if (!example)
@@ -9609,6 +9637,18 @@ my_decimal *Item_cache_real::val_decimal(my_decimal *decimal_val)
}
+Item *Item_cache_real::convert_to_basic_const_item(THD *thd)
+{
+ Item *new_item;
+ DBUG_ASSERT(value_cached || example != 0);
+ new_item= null_value ?
+ (Item*) new (thd->mem_root) Item_null(thd) :
+ (Item*) new (thd->mem_root) Item_float(thd, val_real(),
+ decimals);
+ return new_item;
+}
+
+
bool Item_cache_decimal::cache_value()
{
if (!example)
@@ -9660,6 +9700,19 @@ my_decimal *Item_cache_decimal::val_decimal(my_decimal *val)
}
+Item *Item_cache_decimal::convert_to_basic_const_item(THD *thd)
+{
+ Item *new_item;
+ my_decimal decimal_value;
+ my_decimal *result= val_decimal(&decimal_value);
+ DBUG_ASSERT(value_cached || example != 0);
+ new_item= null_value ?
+ (Item*) new (thd->mem_root) Item_null(thd) :
+ (Item*) new (thd->mem_root) Item_decimal(thd, result);
+ return new_item;
+}
+
+
bool Item_cache_str::cache_value()
{
if (!example)
@@ -9739,6 +9792,26 @@ bool Item_cache_row::allocate(THD *thd, uint num)
}
+Item *Item_cache_str::convert_to_basic_const_item(THD *thd)
+{
+ Item *new_item;
+ char buff[MAX_FIELD_WIDTH];
+ String tmp(buff, sizeof(buff), value->charset());
+ String *result= val_str(&tmp);
+ DBUG_ASSERT(value_cached || example != 0);
+ if (null_value)
+ new_item= (Item*) new (thd->mem_root) Item_null(thd);
+ else
+ {
+ uint length= result->length();
+ char *tmp_str= thd->strmake(result->ptr(), length);
+ new_item= new (thd->mem_root) Item_string(thd, tmp_str, length,
+ result->charset());
+ }
+ return new_item;
+}
+
+
bool Item_cache_row::setup(THD *thd, Item *item)
{
example= item;