diff options
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 179 |
1 files changed, 114 insertions, 65 deletions
diff --git a/sql/item.cc b/sql/item.cc index c45727d1e93..609ed45cb7f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -296,23 +296,6 @@ longlong Item::val_int_from_decimal() } -void *Item::operator new(size_t size, Item *reuse, uint *rsize) -{ - if (reuse && size <= reuse->rsize) - { - if (rsize) - (*rsize)= reuse->rsize; - reuse->cleanup(); - delete reuse; - TRASH((void *)reuse, size); - return (void *)reuse; - } - if (rsize) - (*rsize)= (uint) size; - return (void *)sql_alloc((uint)size); -} - - Item::Item(): rsize(0), name(0), orig_name(0), name_length(0), fixed(0), is_autogenerated_name(TRUE), @@ -802,9 +785,41 @@ int Item::save_in_field_no_warnings(Field *field, bool no_conversions) /***************************************************************************** - Item_splocal methods + Item_sp_variable methods *****************************************************************************/ -double Item_splocal::val_real() + +Item_sp_variable::Item_sp_variable(char *sp_var_name_str, + uint sp_var_name_length) + :m_thd(0) +#ifndef DBUG_OFF + , m_sp(0) +#endif +{ + m_name.str= sp_var_name_str; + m_name.length= sp_var_name_length; +} + + +bool Item_sp_variable::fix_fields(THD *thd, Item **) +{ + Item *it; + + m_thd= thd; /* NOTE: this must be set before any this_xxx() */ + it= this_item(); + + DBUG_ASSERT(it->fixed); + + max_length= it->max_length; + decimals= it->decimals; + unsigned_flag= it->unsigned_flag; + fixed= 1; + collation.set(it->collation.collation, it->collation.derivation); + + return FALSE; +} + + +double Item_sp_variable::val_real() { DBUG_ASSERT(fixed); Item *it= this_item(); @@ -814,7 +829,7 @@ double Item_splocal::val_real() } -longlong Item_splocal::val_int() +longlong Item_sp_variable::val_int() { DBUG_ASSERT(fixed); Item *it= this_item(); @@ -824,13 +839,14 @@ longlong Item_splocal::val_int() } -String *Item_splocal::val_str(String *sp) +String *Item_sp_variable::val_str(String *sp) { DBUG_ASSERT(fixed); Item *it= this_item(); String *res= it->val_str(sp); null_value= it->null_value; + if (!res) return NULL; @@ -854,11 +870,12 @@ String *Item_splocal::val_str(String *sp) str_value.set(res->ptr(), res->length(), res->charset()); else res->mark_as_const(); + return &str_value; } -my_decimal *Item_splocal::val_decimal(my_decimal *decimal_value) +my_decimal *Item_sp_variable::val_decimal(my_decimal *decimal_value) { DBUG_ASSERT(fixed); Item *it= this_item(); @@ -868,73 +885,108 @@ my_decimal *Item_splocal::val_decimal(my_decimal *decimal_value) } -bool Item_splocal::is_null() +bool Item_sp_variable::is_null() { - Item *it= this_item(); - return it->is_null(); + return this_item()->is_null(); +} + + +/***************************************************************************** + Item_splocal methods +*****************************************************************************/ + +Item_splocal::Item_splocal(const LEX_STRING &sp_var_name, + uint sp_var_idx, + enum_field_types sp_var_type, + uint pos_in_q) + :Item_sp_variable(sp_var_name.str, sp_var_name.length), + m_var_idx(sp_var_idx), pos_in_query(pos_in_q) +{ + maybe_null= TRUE; + + m_type= sp_map_item_type(sp_var_type); + m_result_type= sp_map_result_type(sp_var_type); } Item * Item_splocal::this_item() { - DBUG_ASSERT(owner == thd->spcont->owner); - return thd->spcont->get_item(m_offset); + DBUG_ASSERT(m_sp == m_thd->spcont->sp); + + return m_thd->spcont->get_item(m_var_idx); +} + +const Item * +Item_splocal::this_item() const +{ + DBUG_ASSERT(m_sp == m_thd->spcont->sp); + + return m_thd->spcont->get_item(m_var_idx); } Item ** -Item_splocal::this_item_addr(THD *thd, Item **addr) +Item_splocal::this_item_addr(THD *thd, Item **) { - DBUG_ASSERT(owner == thd->spcont->owner); - return thd->spcont->get_item_addr(m_offset); + DBUG_ASSERT(m_sp == thd->spcont->sp); + + return thd->spcont->get_item_addr(m_var_idx); } -Item * -Item_splocal::this_const_item() const + +void Item_splocal::print(String *str) { - DBUG_ASSERT(owner == thd->spcont->owner); - return thd->spcont->get_item(m_offset); + str->reserve(m_name.length+8); + str->append(m_name.str, m_name.length); + str->append('@'); + str->qs_append(m_var_idx); } -Item::Type -Item_splocal::type() const + +/***************************************************************************** + Item_case_expr methods +*****************************************************************************/ + +Item_case_expr::Item_case_expr(int case_expr_id) + :Item_sp_variable(STRING_WITH_LEN("case_expr")), + m_case_expr_id(case_expr_id) { - if (thd && thd->spcont) - { - DBUG_ASSERT(owner == thd->spcont->owner); - return thd->spcont->get_item(m_offset)->type(); - } - return NULL_ITEM; // Anything but SUBSELECT_ITEM } -bool Item_splocal::fix_fields(THD *thd_arg, Item **ref) +Item * +Item_case_expr::this_item() { - Item *it; - thd= thd_arg; // Must be set before this_item() - it= this_item(); - DBUG_ASSERT(it->fixed); - max_length= it->max_length; - decimals= it->decimals; - unsigned_flag= it->unsigned_flag; - fixed= 1; - return FALSE; + DBUG_ASSERT(m_sp == m_thd->spcont->sp); + + return m_thd->spcont->get_case_expr(m_case_expr_id); } -void Item_splocal::cleanup() + +const Item * +Item_case_expr::this_item() const { - fixed= 0; + DBUG_ASSERT(m_sp == m_thd->spcont->sp); + + return m_thd->spcont->get_case_expr(m_case_expr_id); } -void Item_splocal::print(String *str) +Item ** +Item_case_expr::this_item_addr(THD *thd, Item **) { - str->reserve(m_name.length+8); - str->append(m_name.str, m_name.length); - str->append('@'); - str->qs_append(m_offset); + DBUG_ASSERT(m_sp == thd->spcont->sp); + + return thd->spcont->get_case_expr_addr(m_case_expr_id); +} + + +void Item_case_expr::print(String *str) +{ + str->append(STRING_WITH_LEN("case_expr@")); + str->qs_append(m_case_expr_id); } @@ -1013,12 +1065,6 @@ bool Item_name_const::fix_fields(THD *thd, Item **ref) } -void Item_name_const::cleanup() -{ - fixed= 0; -} - - void Item_name_const::print(String *str) { str->append(STRING_WITH_LEN("NAME_CONST(")); @@ -3911,6 +3957,9 @@ int Item::save_in_field(Field *field, bool no_conversions) str_value.set_quick(0, 0, cs); return set_field_to_null_with_conversions(field, no_conversions); } + + /* NOTE: If null_value == FALSE, "result" must be not NULL. */ + field->set_notnull(); error=field->store(result->ptr(),result->length(),cs); str_value.set_quick(0, 0, cs); |