summaryrefslogtreecommitdiff
path: root/sql/item.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item.h')
-rw-r--r--sql/item.h239
1 files changed, 163 insertions, 76 deletions
diff --git a/sql/item.h b/sql/item.h
index ab9c93e207d..900442a45e9 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -383,8 +383,6 @@ public:
{ return (void*) sql_alloc((uint) size); }
static void *operator new(size_t size, MEM_ROOT *mem_root)
{ return (void*) alloc_root(mem_root, (uint) size); }
- /* Special for SP local variable assignment - reusing slots */
- static void *operator new(size_t size, Item *reuse, uint *rsize);
static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); }
static void operator delete(void *ptr, MEM_ROOT *mem_root) {}
@@ -713,13 +711,13 @@ public:
current value and pointer to current Item otherwise.
*/
virtual Item *this_item() { return this; }
+ virtual const Item *this_item() const { return this; }
+
/*
For SP local variable returns address of pointer to Item representing its
current value and pointer passed via parameter otherwise.
*/
virtual Item **this_item_addr(THD *thd, Item **addr) { return addr; }
- /* For SPs mostly. */
- virtual Item *this_const_item() const { return const_cast<Item*>(this); }
// Row emulation
virtual uint cols() { return 1; }
@@ -748,21 +746,32 @@ public:
class sp_head;
-/*
- A reference to local SP variable (incl. reference to SP parameter), used in
- runtime.
-
- NOTE
- This item has a "value" item, defined as
- this_item() = thd->spcont->get_item(m_offset)
- and it delegates everything to that item (if !this_item() then this item
- poses as Item_null) except for name, which is the name of SP local
- variable.
-*/
-class Item_splocal : public Item
+/*****************************************************************************
+ The class is a base class for representation of stored routine variables in
+ the Item-hierarchy. There are the following kinds of SP-vars:
+ - local variables (Item_splocal);
+ - CASE expression (Item_case_expr);
+*****************************************************************************/
+
+class Item_sp_variable :public Item
{
- uint m_offset;
+protected:
+ /*
+ THD, which is stored in fix_fields() and is used in this_item() to avoid
+ current_thd use.
+ */
+ THD *m_thd;
+
+public:
+ LEX_STRING m_name;
+
+ /*
+ Buffer, pointing to the string value of the item. We need it to
+ protect internal buffer from changes. See comment to analogous
+ member in Item_param for more details.
+ */
+ String str_value_ptr;
public:
#ifndef DBUG_OFF
@@ -770,11 +779,74 @@ public:
Routine to which this Item_splocal belongs. Used for checking if correct
runtime context is used for variable handling.
*/
- sp_head *owner;
+ sp_head *m_sp;
#endif
- LEX_STRING m_name;
- THD *thd;
+public:
+ Item_sp_variable(char *sp_var_name_str, uint sp_var_name_length);
+
+public:
+ bool fix_fields(THD *thd, Item **);
+
+ double val_real();
+ longlong val_int();
+ String *val_str(String *sp);
+ my_decimal *val_decimal(my_decimal *decimal_value);
+ bool is_null();
+
+public:
+ inline void make_field(Send_field *field);
+
+ inline bool const_item() const;
+
+ inline int save_in_field(Field *field, bool no_conversions);
+ inline bool send(Protocol *protocol, String *str);
+};
+
+/*****************************************************************************
+ Item_sp_variable inline implementation.
+*****************************************************************************/
+
+inline void Item_sp_variable::make_field(Send_field *field)
+{
+ Item *it= this_item();
+
+ if (name)
+ it->set_name(name, (uint) strlen(name), system_charset_info);
+ else
+ it->set_name(m_name.str, m_name.length, system_charset_info);
+ it->make_field(field);
+}
+
+inline bool Item_sp_variable::const_item() const
+{
+ return TRUE;
+}
+
+inline int Item_sp_variable::save_in_field(Field *field, bool no_conversions)
+{
+ return this_item()->save_in_field(field, no_conversions);
+}
+
+inline bool Item_sp_variable::send(Protocol *protocol, String *str)
+{
+ return this_item()->send(protocol, str);
+}
+
+
+/*****************************************************************************
+ A reference to local SP variable (incl. reference to SP parameter), used in
+ runtime.
+*****************************************************************************/
+
+class Item_splocal :public Item_sp_variable
+{
+ uint m_var_idx;
+
+ Type m_type;
+ Item_result m_result_type;
+
+public:
/*
Position of this reference to SP variable in the statement (the
statement itself is in sp_instr_stmt::m_query).
@@ -787,78 +859,94 @@ public:
*/
uint pos_in_query;
- Item_splocal(LEX_STRING name, uint offset, uint pos_in_q=0)
- : m_offset(offset), m_name(name), thd(0), pos_in_query(pos_in_q)
- {
- maybe_null= TRUE;
- }
-
- /* For error printing */
- inline LEX_STRING *my_name(LEX_STRING *get_name)
- {
- if (!get_name)
- return &m_name;
- (*get_name)= m_name;
- return get_name;
- }
+ Item_splocal(const LEX_STRING &sp_var_name, uint sp_var_idx,
+ enum_field_types sp_var_type, uint pos_in_q= 0);
bool is_splocal() { return 1; } /* Needed for error checking */
Item *this_item();
+ const Item *this_item() const;
Item **this_item_addr(THD *thd, Item **);
- Item *this_const_item() const;
- bool fix_fields(THD *, Item **);
- void cleanup();
+ void print(String *str);
- inline uint get_offset()
- {
- return m_offset;
- }
+public:
+ inline const LEX_STRING *my_name() const;
- // Abstract methods inherited from Item. Just defer the call to
- // the item in the frame
- enum Type type() const;
+ inline uint get_var_idx() const;
- double val_real();
- longlong val_int();
- String *val_str(String *sp);
- my_decimal *val_decimal(my_decimal *);
- bool is_null();
- void print(String *str);
+ inline enum Type type() const;
+ inline Item_result result_type() const;
+};
- void make_field(Send_field *field)
- {
- Item *it= this_item();
+/*****************************************************************************
+ Item_splocal inline implementation.
+*****************************************************************************/
- if (name)
- it->set_name(name, (uint) strlen(name), system_charset_info);
- else
- it->set_name(m_name.str, m_name.length, system_charset_info);
- it->make_field(field);
- }
+inline const LEX_STRING *Item_splocal::my_name() const
+{
+ return &m_name;
+}
- Item_result result_type() const
- {
- return this_const_item()->result_type();
- }
+inline uint Item_splocal::get_var_idx() const
+{
+ return m_var_idx;
+}
- bool const_item() const
- {
- return TRUE;
- }
+inline enum Item::Type Item_splocal::type() const
+{
+ return m_type;
+}
- int save_in_field(Field *field, bool no_conversions)
- {
- return this_item()->save_in_field(field, no_conversions);
- }
+inline Item_result Item_splocal::result_type() const
+{
+ return m_result_type;
+}
- bool send(Protocol *protocol, String *str)
- {
- return this_item()->send(protocol, str);
- }
+
+/*****************************************************************************
+ A reference to case expression in SP, used in runtime.
+*****************************************************************************/
+
+class Item_case_expr :public Item_sp_variable
+{
+public:
+ Item_case_expr(int case_expr_id);
+
+public:
+ Item *this_item();
+ const Item *this_item() const;
+ Item **this_item_addr(THD *thd, Item **);
+
+ inline enum Type type() const;
+ inline Item_result result_type() const;
+
+public:
+ /*
+ NOTE: print() is intended to be used from views and for debug.
+ Item_case_expr can not occur in views, so here it is only for debug
+ purposes.
+ */
+ void print(String *str);
+
+private:
+ int m_case_expr_id;
};
+/*****************************************************************************
+ Item_case_expr inline implementation.
+*****************************************************************************/
+
+inline enum Item::Type Item_case_expr::type() const
+{
+ return this_item()->type();
+}
+
+inline Item_result Item_case_expr::result_type() const
+{
+ return this_item()->result_type();
+}
+
/*
NAME_CONST(given_name, const_value).
@@ -885,7 +973,6 @@ public:
}
bool fix_fields(THD *, Item **);
- void cleanup();
enum Type type() const;
double val_real();