diff options
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 137 |
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; } |