diff options
author | Igor Babaev <igor@askmonty.org> | 2016-12-14 10:11:52 -0800 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2016-12-14 10:13:52 -0800 |
commit | 441fa0056da27e83771a7d7ccd09da8b38f22417 (patch) | |
tree | 24689f3e3f96d0ac1fbc1c916535e82a91e02e83 /sql/item.cc | |
parent | e9ada862651fdb98f84871e4ec59bef1bb36646d (diff) | |
download | mariadb-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.cc | 73 |
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(), <ime); + new_item= (Item*) new (thd->mem_root) Item_datetime_literal(thd, <ime, + 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; |