diff options
author | Evgeny Potemkin <epotemkin@mysql.com> | 2009-12-01 22:41:39 +0300 |
---|---|---|
committer | Evgeny Potemkin <epotemkin@mysql.com> | 2009-12-01 22:41:39 +0300 |
commit | 9e5d1bb6647c88e5a60c2a3e7eadc76fd1089135 (patch) | |
tree | 1d06fec7c3a7a43683dba7f07e68c2d244161127 /sql/item.cc | |
parent | ad36684576874b2eecdc2b1055e017285cae0f75 (diff) | |
parent | c81e23457aca99ea760fbd9143e22b95bb1a7cf2 (diff) | |
download | mariadb-git-9e5d1bb6647c88e5a60c2a3e7eadc76fd1089135.tar.gz |
Auto-merged fix for the bug#34384.
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 129 |
1 files changed, 111 insertions, 18 deletions
diff --git a/sql/item.cc b/sql/item.cc index 8fef62aacc1..3bd4744764e 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -7104,7 +7104,22 @@ int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) Item_cache* Item_cache::get_cache(const Item *item) { - switch (item->result_type()) { + return get_cache(item, item->result_type()); +} + + +/** + Get a cache item of given type. + + @param item value to be cached + @param type required type of cache + + @return cache item +*/ + +Item_cache* Item_cache::get_cache(const Item *item, const Item_result type) +{ + switch (type) { case INT_RESULT: return new Item_cache_int(); case REAL_RESULT: @@ -7122,6 +7137,12 @@ Item_cache* Item_cache::get_cache(const Item *item) } } +void Item_cache::store(Item *item) +{ + if (item) + example= item; + value_cached= FALSE; +} void Item_cache::print(String *str, enum_query_type query_type) { @@ -7133,17 +7154,19 @@ void Item_cache::print(String *str, enum_query_type query_type) str->append(')'); } - -void Item_cache_int::store(Item *item) +void Item_cache_int::cache_value() { - value= item->val_int_result(); - null_value= item->null_value; - unsigned_flag= item->unsigned_flag; + value_cached= TRUE; + value= example->val_int_result(); + null_value= example->null_value; + unsigned_flag= example->unsigned_flag; } void Item_cache_int::store(Item *item, longlong val_arg) { + /* An explicit values is given, save it. */ + value_cached= TRUE; value= val_arg; null_value= item->null_value; unsigned_flag= item->unsigned_flag; @@ -7153,6 +7176,8 @@ void Item_cache_int::store(Item *item, longlong val_arg) String *Item_cache_int::val_str(String *str) { DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); str->set(value, default_charset()); return str; } @@ -7161,21 +7186,49 @@ String *Item_cache_int::val_str(String *str) my_decimal *Item_cache_int::val_decimal(my_decimal *decimal_val) { DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); int2my_decimal(E_DEC_FATAL_ERROR, value, unsigned_flag, decimal_val); return decimal_val; } +double Item_cache_int::val_real() +{ + DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); + return (double) value; +} -void Item_cache_real::store(Item *item) +longlong Item_cache_int::val_int() { - value= item->val_result(); - null_value= item->null_value; + DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); + return value; } +void Item_cache_real::cache_value() +{ + value_cached= TRUE; + value= example->val_result(); + null_value= example->null_value; +} + + +double Item_cache_real::val_real() +{ + DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); + return value; +} longlong Item_cache_real::val_int() { DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); return (longlong) rint(value); } @@ -7183,6 +7236,8 @@ longlong Item_cache_real::val_int() String* Item_cache_real::val_str(String *str) { DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); str->set_real(value, decimals, default_charset()); return str; } @@ -7191,15 +7246,18 @@ String* Item_cache_real::val_str(String *str) my_decimal *Item_cache_real::val_decimal(my_decimal *decimal_val) { DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); double2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val); return decimal_val; } -void Item_cache_decimal::store(Item *item) +void Item_cache_decimal::cache_value() { - my_decimal *val= item->val_decimal_result(&decimal_value); - if (!(null_value= item->null_value) && val != &decimal_value) + value_cached= TRUE; + my_decimal *val= example->val_decimal_result(&decimal_value); + if (!(null_value= example->null_value) && val != &decimal_value) my_decimal2decimal(val, &decimal_value); } @@ -7207,6 +7265,8 @@ double Item_cache_decimal::val_real() { DBUG_ASSERT(fixed); double res; + if (!value_cached) + cache_value(); my_decimal2double(E_DEC_FATAL_ERROR, &decimal_value, &res); return res; } @@ -7215,6 +7275,8 @@ longlong Item_cache_decimal::val_int() { DBUG_ASSERT(fixed); longlong res; + if (!value_cached) + cache_value(); my_decimal2int(E_DEC_FATAL_ERROR, &decimal_value, unsigned_flag, &res); return res; } @@ -7222,6 +7284,8 @@ longlong Item_cache_decimal::val_int() String* Item_cache_decimal::val_str(String *str) { DBUG_ASSERT(fixed); + if (!value_cached) + cache_value(); my_decimal_round(E_DEC_FATAL_ERROR, &decimal_value, decimals, FALSE, &decimal_value); my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value, 0, 0, 0, str); @@ -7231,15 +7295,18 @@ String* Item_cache_decimal::val_str(String *str) my_decimal *Item_cache_decimal::val_decimal(my_decimal *val) { DBUG_ASSERT(fixed); + if (!value_cached) + cache_value(); return &decimal_value; } -void Item_cache_str::store(Item *item) +void Item_cache_str::cache_value() { - value_buff.set(buffer, sizeof(buffer), item->collation.collation); - value= item->str_result(&value_buff); - if ((null_value= item->null_value)) + value_cached= TRUE; + value_buff.set(buffer, sizeof(buffer), example->collation.collation); + value= example->str_result(&value_buff); + if ((null_value= example->null_value)) value= 0; else if (value != &value_buff) { @@ -7261,6 +7328,8 @@ double Item_cache_str::val_real() DBUG_ASSERT(fixed == 1); int err_not_used; char *end_not_used; + if (!value_cached) + cache_value(); if (value) return my_strntod(value->charset(), (char*) value->ptr(), value->length(), &end_not_used, &err_not_used); @@ -7272,6 +7341,8 @@ longlong Item_cache_str::val_int() { DBUG_ASSERT(fixed == 1); int err; + if (!value_cached) + cache_value(); if (value) return my_strntoll(value->charset(), value->ptr(), value->length(), 10, (char**) 0, &err); @@ -7279,9 +7350,21 @@ longlong Item_cache_str::val_int() return (longlong)0; } + +String* Item_cache_str::val_str(String *str) +{ + DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); + return value; +} + + my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val) { DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); if (value) string2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val); else @@ -7292,6 +7375,8 @@ my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val) int Item_cache_str::save_in_field(Field *field, bool no_conversions) { + if (!value_cached) + cache_value(); int res= Item_cache::save_in_field(field, no_conversions); return (is_varbinary && field->type() == MYSQL_TYPE_STRING && value->length() < field->field_length) ? 1 : res; @@ -7326,11 +7411,19 @@ bool Item_cache_row::setup(Item * item) void Item_cache_row::store(Item * item) { + for (uint i= 0; i < item_count; i++) + values[i]->store(item->element_index(i)); +} + + +void Item_cache_row::cache_value() +{ + value_cached= TRUE; null_value= 0; - item->bring_value(); + example->bring_value(); for (uint i= 0; i < item_count; i++) { - values[i]->store(item->element_index(i)); + values[i]->cache_value(); null_value|= values[i]->null_value; } } |