summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
authorEvgeny Potemkin <epotemkin@mysql.com>2009-12-01 22:41:39 +0300
committerEvgeny Potemkin <epotemkin@mysql.com>2009-12-01 22:41:39 +0300
commit9e5d1bb6647c88e5a60c2a3e7eadc76fd1089135 (patch)
tree1d06fec7c3a7a43683dba7f07e68c2d244161127 /sql/item.cc
parentad36684576874b2eecdc2b1055e017285cae0f75 (diff)
parentc81e23457aca99ea760fbd9143e22b95bb1a7cf2 (diff)
downloadmariadb-git-9e5d1bb6647c88e5a60c2a3e7eadc76fd1089135.tar.gz
Auto-merged fix for the bug#34384.
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc129
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;
}
}