summaryrefslogtreecommitdiff
path: root/sql/item.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item.h')
-rw-r--r--sql/item.h245
1 files changed, 173 insertions, 72 deletions
diff --git a/sql/item.h b/sql/item.h
index 4e737d09952..01573c9e6ea 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1843,6 +1843,94 @@ inline Item* get_item_copy (THD *thd, MEM_ROOT *mem_root, T* item)
bool cmp_items(Item *a, Item *b);
+/**
+ Array of items, e.g. function or aggerate function arguments.
+*/
+class Item_args
+{
+protected:
+ Item **args, *tmp_arg[2];
+ uint arg_count;
+ bool alloc_arguments(THD *thd, uint count);
+ void set_arguments(THD *thd, List<Item> &list);
+ bool walk_args(Item_processor processor, bool walk_subquery, void *arg)
+ {
+ for (uint i= 0; i < arg_count; i++)
+ {
+ if (args[i]->walk(processor, walk_subquery, arg))
+ return true;
+ }
+ return false;
+ }
+ bool transform_args(THD *thd, Item_transformer transformer, uchar *arg);
+ void propagate_equal_fields(THD *, const Item::Context &, COND_EQUAL *);
+public:
+ Item_args(void)
+ :args(NULL), arg_count(0)
+ { }
+ Item_args(Item *a)
+ :args(tmp_arg), arg_count(1)
+ {
+ args[0]= a;
+ }
+ Item_args(Item *a, Item *b)
+ :args(tmp_arg), arg_count(2)
+ {
+ args[0]= a; args[1]= b;
+ }
+ Item_args(THD *thd, Item *a, Item *b, Item *c)
+ {
+ arg_count= 0;
+ if ((args= (Item**) thd_alloc(thd, sizeof(Item*) * 3)))
+ {
+ arg_count= 3;
+ args[0]= a; args[1]= b; args[2]= c;
+ }
+ }
+ Item_args(THD *thd, Item *a, Item *b, Item *c, Item *d)
+ {
+ arg_count= 0;
+ if ((args= (Item**) thd_alloc(thd, sizeof(Item*) * 4)))
+ {
+ arg_count= 4;
+ args[0]= a; args[1]= b; args[2]= c; args[3]= d;
+ }
+ }
+ Item_args(THD *thd, Item *a, Item *b, Item *c, Item *d, Item* e)
+ {
+ arg_count= 5;
+ if ((args= (Item**) thd_alloc(thd, sizeof(Item*) * 5)))
+ {
+ arg_count= 5;
+ args[0]= a; args[1]= b; args[2]= c; args[3]= d; args[4]= e;
+ }
+ }
+ Item_args(THD *thd, List<Item> &list)
+ {
+ set_arguments(thd, list);
+ }
+ Item_args(THD *thd, const Item_args *other);
+ inline Item **arguments() const { return args; }
+ inline uint argument_count() const { return arg_count; }
+ inline void remove_arguments() { arg_count=0; }
+};
+
+
+class Item_spvar_args: public Item_args
+{
+ TABLE *m_table;
+public:
+ Item_spvar_args():Item_args(), m_table(NULL) { }
+ ~Item_spvar_args();
+ bool row_create_items(THD *thd, List<Spvar_definition> *list);
+ Field *get_row_field(uint i) const
+ {
+ DBUG_ASSERT(m_table);
+ return m_table->field[i];
+ }
+};
+
+
/*
Class to be used to enumerate all field references in an item tree. This
includes references to outside but not fields of the tables within a
@@ -2076,9 +2164,12 @@ class Item_splocal :public Item_sp_variable,
public Rewritable_query_parameter,
public Type_handler_hybrid_field_type
{
+protected:
uint m_var_idx;
Type m_type;
+
+ bool append_value_for_log(THD *thd, String *str);
public:
Item_splocal(THD *thd, const LEX_STRING &sp_var_name, uint sp_var_idx,
enum_field_types sp_var_type,
@@ -2104,6 +2195,10 @@ public:
{ return Type_handler_hybrid_field_type::result_type(); }
enum Item_result cmp_type () const
{ return Type_handler_hybrid_field_type::cmp_type(); }
+ uint cols() { return this_item()->cols(); }
+ Item* element_index(uint i) { return this_item()->element_index(i); }
+ Item** addr(uint i) { return this_item()->addr(i); }
+ bool check_cols(uint c);
private:
bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
@@ -2123,6 +2218,20 @@ public:
};
+class Item_splocal_row: public Item_splocal
+{
+public:
+ Item_splocal_row(THD *thd, const LEX_STRING &sp_var_name,
+ uint sp_var_idx, uint pos_in_q, uint len_in_q)
+ :Item_splocal(thd, sp_var_name, sp_var_idx, MYSQL_TYPE_NULL,
+ pos_in_q, len_in_q)
+ {
+ set_handler(&type_handler_row);
+ }
+ enum Type type() const { return ROW_ITEM; }
+};
+
+
/**
An Item_splocal variant whose data type becomes known only at
sp_rcontext creation time, e.g. "DECLARE var1 t1.col1%TYPE".
@@ -2156,6 +2265,37 @@ public:
{ return tmp_table_field_from_field_type(table, false, true); }
};
+
+/**
+ SP variables that are fields of a ROW.
+ DELCARE r ROW(a INT,b INT);
+ SELECT r.a; -- This is handled by Item_splocal_row_field
+*/
+class Item_splocal_row_field :public Item_splocal
+{
+ LEX_STRING m_field_name;
+ uint m_field_idx;
+ bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
+public:
+ Item_splocal_row_field(THD *thd,
+ const LEX_STRING &sp_var_name,
+ const LEX_STRING &sp_field_name,
+ uint sp_var_idx, uint sp_field_idx,
+ enum_field_types sp_var_type,
+ uint pos_in_q= 0, uint len_in_q= 0)
+ :Item_splocal(thd, sp_var_name, sp_var_idx, sp_var_type,
+ pos_in_q, len_in_q),
+ m_field_name(sp_field_name),
+ m_field_idx(sp_field_idx)
+ { }
+ Item *this_item();
+ const Item *this_item() const;
+ Item **this_item_addr(THD *thd, Item **);
+ bool append_for_log(THD *thd, String *str);
+ void print(String *str, enum_query_type query_type);
+};
+
+
/*****************************************************************************
Item_splocal inline implementation.
*****************************************************************************/
@@ -2599,6 +2739,39 @@ public:
};
+/**
+ Item_field for the ROW data type
+*/
+class Item_field_row: public Item_field,
+ public Item_spvar_args
+{
+public:
+ Item_field_row(THD *thd, Field *field)
+ :Item_field(thd, field),
+ Item_spvar_args()
+ { }
+
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_field_row>(thd, mem_root, this); }
+
+ const Type_handler *type_handler() const { return &type_handler_row; }
+ Item_result result_type() const{ return ROW_RESULT ; }
+ Item_result cmp_type() const { return ROW_RESULT; }
+ uint cols() { return arg_count; }
+ Item* element_index(uint i) { return arg_count ? args[i] : this; }
+ Item** addr(uint i) { return arg_count ? args + i : NULL; }
+ bool check_cols(uint c)
+ {
+ if (cols() != c)
+ {
+ my_error(ER_OPERAND_COLUMNS, MYF(0), c);
+ return true;
+ }
+ return false;
+ }
+};
+
+
/*
@brief
Item_temptable_field is the same as Item_field, except that print()
@@ -3785,78 +3958,6 @@ public:
};
-/**
- Array of items, e.g. function or aggerate function arguments.
-*/
-class Item_args
-{
-protected:
- Item **args, *tmp_arg[2];
- uint arg_count;
- void set_arguments(THD *thd, List<Item> &list);
- bool walk_args(Item_processor processor, bool walk_subquery, void *arg)
- {
- for (uint i= 0; i < arg_count; i++)
- {
- if (args[i]->walk(processor, walk_subquery, arg))
- return true;
- }
- return false;
- }
- bool transform_args(THD *thd, Item_transformer transformer, uchar *arg);
- void propagate_equal_fields(THD *, const Item::Context &, COND_EQUAL *);
-public:
- Item_args(void)
- :args(NULL), arg_count(0)
- { }
- Item_args(Item *a)
- :args(tmp_arg), arg_count(1)
- {
- args[0]= a;
- }
- Item_args(Item *a, Item *b)
- :args(tmp_arg), arg_count(2)
- {
- args[0]= a; args[1]= b;
- }
- Item_args(THD *thd, Item *a, Item *b, Item *c)
- {
- arg_count= 0;
- if ((args= (Item**) thd_alloc(thd, sizeof(Item*) * 3)))
- {
- arg_count= 3;
- args[0]= a; args[1]= b; args[2]= c;
- }
- }
- Item_args(THD *thd, Item *a, Item *b, Item *c, Item *d)
- {
- arg_count= 0;
- if ((args= (Item**) thd_alloc(thd, sizeof(Item*) * 4)))
- {
- arg_count= 4;
- args[0]= a; args[1]= b; args[2]= c; args[3]= d;
- }
- }
- Item_args(THD *thd, Item *a, Item *b, Item *c, Item *d, Item* e)
- {
- arg_count= 5;
- if ((args= (Item**) thd_alloc(thd, sizeof(Item*) * 5)))
- {
- arg_count= 5;
- args[0]= a; args[1]= b; args[2]= c; args[3]= d; args[4]= e;
- }
- }
- Item_args(THD *thd, List<Item> &list)
- {
- set_arguments(thd, list);
- }
- Item_args(THD *thd, const Item_args *other);
- inline Item **arguments() const { return args; }
- inline uint argument_count() const { return arg_count; }
- inline void remove_arguments() { arg_count=0; }
-};
-
-
class Used_tables_and_const_cache
{
public: