summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc137
1 files changed, 82 insertions, 55 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 7de32423927..f4b2e549667 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -5063,9 +5063,7 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length)
switch (field_type()) {
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
- field= new Field_new_decimal((uchar*) 0, max_length, null_ptr, 0,
- Field::NONE, name, decimals, 0,
- unsigned_flag);
+ field= Field_new_decimal::create_from_item(this);
break;
case MYSQL_TYPE_TINY:
field= new Field_tiny((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
@@ -7182,7 +7180,7 @@ Item_cache* Item_cache::get_cache(const Item *item, const Item_result type)
{
switch (type) {
case INT_RESULT:
- return new Item_cache_int();
+ return new Item_cache_int(item->field_type());
case REAL_RESULT:
return new Item_cache_real();
case DECIMAL_RESULT:
@@ -7204,8 +7202,9 @@ Item_cache* Item_cache::get_cache(const Item *item, const Item_result type)
void Item_cache::store(Item *item)
{
- if (item)
- example= item;
+ example= item;
+ if (!item)
+ null_value= TRUE;
value_cached= FALSE;
}
@@ -7219,12 +7218,15 @@ void Item_cache::print(String *str, enum_query_type query_type)
str->append(')');
}
-void Item_cache_int::cache_value()
+bool Item_cache_int::cache_value()
{
+ if (!example)
+ return FALSE;
value_cached= TRUE;
value= example->val_int_result();
null_value= example->null_value;
unsigned_flag= example->unsigned_flag;
+ return TRUE;
}
@@ -7241,8 +7243,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();
+ if (!value_cached && !cache_value())
+ return NULL;
str->set(value, default_charset());
return str;
}
@@ -7251,8 +7253,8 @@ 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();
+ if (!value_cached && !cache_value())
+ return NULL;
int2my_decimal(E_DEC_FATAL_ERROR, value, unsigned_flag, decimal_val);
return decimal_val;
}
@@ -7260,31 +7262,37 @@ my_decimal *Item_cache_int::val_decimal(my_decimal *decimal_val)
double Item_cache_int::val_real()
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached)
- cache_value();
+ if (!value_cached && !cache_value())
+ return 0.0;
return (double) value;
}
longlong Item_cache_int::val_int()
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached)
- cache_value();
+ if (!value_cached && !cache_value())
+ return 0;
return value;
}
-void Item_cache_datetime::cache_value_int()
+bool Item_cache_datetime::cache_value_int()
{
+ if (!example)
+ return FALSE;
+
value_cached= TRUE;
/* Assume here that the underlying item will do correct conversion.*/
int_value= example->val_int_result();
null_value= example->null_value;
unsigned_flag= example->unsigned_flag;
+ return TRUE;
}
-void Item_cache_datetime::cache_value()
+bool Item_cache_datetime::cache_value()
{
+ if (!example)
+ return FALSE;
str_value_cached= TRUE;
/* Assume here that the underlying item will do correct conversion.*/
String *res= example->str_result(&str_value);
@@ -7292,6 +7300,7 @@ void Item_cache_datetime::cache_value()
str_value.copy(*res);
null_value= example->null_value;
unsigned_flag= example->unsigned_flag;
+ return TRUE;
}
@@ -7308,8 +7317,8 @@ void Item_cache_datetime::store(Item *item, longlong val_arg)
String *Item_cache_datetime::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- if (!str_value_cached)
- cache_value();
+ if (!str_value_cached && !cache_value())
+ return NULL;
return &str_value;
}
@@ -7317,8 +7326,8 @@ String *Item_cache_datetime::val_str(String *str)
my_decimal *Item_cache_datetime::val_decimal(my_decimal *decimal_val)
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached)
- cache_value_int();
+ if (!value_cached && !cache_value_int())
+ return NULL;
int2my_decimal(E_DEC_FATAL_ERROR, int_value, unsigned_flag, decimal_val);
return decimal_val;
}
@@ -7326,40 +7335,43 @@ my_decimal *Item_cache_datetime::val_decimal(my_decimal *decimal_val)
double Item_cache_datetime::val_real()
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached)
- cache_value_int();
+ if (!value_cached && !cache_value_int())
+ return 0.0;
return (double) int_value;
}
longlong Item_cache_datetime::val_int()
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached)
- cache_value_int();
+ if (!value_cached && !cache_value_int())
+ return 0;
return int_value;
}
-void Item_cache_real::cache_value()
+bool Item_cache_real::cache_value()
{
+ if (!example)
+ return FALSE;
value_cached= TRUE;
value= example->val_result();
null_value= example->null_value;
+ return TRUE;
}
double Item_cache_real::val_real()
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached)
- cache_value();
+ if (!value_cached && !cache_value())
+ return 0.0;
return value;
}
longlong Item_cache_real::val_int()
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached)
- cache_value();
+ if (!value_cached && !cache_value())
+ return 0;
return (longlong) rint(value);
}
@@ -7367,8 +7379,8 @@ longlong Item_cache_real::val_int()
String* Item_cache_real::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached)
- cache_value();
+ if (!value_cached && !cache_value())
+ return NULL;
str->set_real(value, decimals, default_charset());
return str;
}
@@ -7377,27 +7389,30 @@ 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();
+ if (!value_cached && !cache_value())
+ return NULL;
double2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val);
return decimal_val;
}
-void Item_cache_decimal::cache_value()
+bool Item_cache_decimal::cache_value()
{
+ if (!example)
+ return FALSE;
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);
+ return TRUE;
}
double Item_cache_decimal::val_real()
{
DBUG_ASSERT(fixed);
double res;
- if (!value_cached)
- cache_value();
+ if (!value_cached && !cache_value())
+ return NULL;
my_decimal2double(E_DEC_FATAL_ERROR, &decimal_value, &res);
return res;
}
@@ -7406,8 +7421,8 @@ longlong Item_cache_decimal::val_int()
{
DBUG_ASSERT(fixed);
longlong res;
- if (!value_cached)
- cache_value();
+ if (!value_cached && !cache_value())
+ return 0;
my_decimal2int(E_DEC_FATAL_ERROR, &decimal_value, unsigned_flag, &res);
return res;
}
@@ -7415,8 +7430,8 @@ longlong Item_cache_decimal::val_int()
String* Item_cache_decimal::val_str(String *str)
{
DBUG_ASSERT(fixed);
- if (!value_cached)
- cache_value();
+ if (!value_cached && !cache_value())
+ return NULL;
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);
@@ -7426,14 +7441,16 @@ 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();
+ if (!value_cached && !cache_value())
+ return NULL;
return &decimal_value;
}
-void Item_cache_str::cache_value()
+bool Item_cache_str::cache_value()
{
+ if (!example)
+ return FALSE;
value_cached= TRUE;
value_buff.set(buffer, sizeof(buffer), example->collation.collation);
value= example->str_result(&value_buff);
@@ -7452,6 +7469,7 @@ void Item_cache_str::cache_value()
value_buff.copy(*value);
value= &value_buff;
}
+ return TRUE;
}
double Item_cache_str::val_real()
@@ -7459,8 +7477,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_cached && !cache_value())
+ return 0.0;
if (value)
return my_strntod(value->charset(), (char*) value->ptr(),
value->length(), &end_not_used, &err_not_used);
@@ -7472,8 +7490,8 @@ longlong Item_cache_str::val_int()
{
DBUG_ASSERT(fixed == 1);
int err;
- if (!value_cached)
- cache_value();
+ if (!value_cached && !cache_value())
+ return 0;
if (value)
return my_strntoll(value->charset(), value->ptr(),
value->length(), 10, (char**) 0, &err);
@@ -7485,8 +7503,8 @@ longlong Item_cache_str::val_int()
String* Item_cache_str::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached)
- cache_value();
+ if (!value_cached && !cache_value())
+ return 0;
return value;
}
@@ -7494,8 +7512,8 @@ String* Item_cache_str::val_str(String *str)
my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val)
{
DBUG_ASSERT(fixed == 1);
- if (!value_cached)
- cache_value();
+ if (!value_cached && !cache_value())
+ return NULL;
if (value)
string2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val);
else
@@ -7506,8 +7524,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();
+ if (!value_cached && !cache_value())
+ return 0;
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;
@@ -7542,13 +7560,21 @@ bool Item_cache_row::setup(Item * item)
void Item_cache_row::store(Item * item)
{
+ example= item;
+ if (!item)
+ {
+ null_value= TRUE;
+ return;
+ }
for (uint i= 0; i < item_count; i++)
values[i]->store(item->element_index(i));
}
-void Item_cache_row::cache_value()
+bool Item_cache_row::cache_value()
{
+ if (!example)
+ return FALSE;
value_cached= TRUE;
null_value= 0;
example->bring_value();
@@ -7557,6 +7583,7 @@ void Item_cache_row::cache_value()
values[i]->cache_value();
null_value|= values[i]->null_value;
}
+ return TRUE;
}