summaryrefslogtreecommitdiff
path: root/sql/item.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item.h')
-rw-r--r--sql/item.h356
1 files changed, 306 insertions, 50 deletions
diff --git a/sql/item.h b/sql/item.h
index 237a8f7efac..5a760db23f5 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -22,6 +22,7 @@
class Protocol;
struct st_table_list;
void item_init(void); /* Init item functions */
+class Item_field;
/*
@@ -110,6 +111,7 @@ public:
};
typedef bool (Item::*Item_processor)(byte *arg);
+typedef Item* (Item::*Item_transformer) (byte *arg);
class Item {
Item(const Item &); /* Prevent use of these */
@@ -118,8 +120,9 @@ public:
static void *operator new(size_t size) {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); }
- static void operator delete(void *ptr,size_t size) {}
- static void operator delete(void *ptr,size_t size, MEM_ROOT *mem_root) {}
+ static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); }
+ static void operator delete(void *ptr,size_t size, MEM_ROOT *mem_root)
+ { TRASH(ptr, size); }
enum Type {FIELD_ITEM, FUNC_ITEM, SUM_FUNC_ITEM, STRING_ITEM,
INT_ITEM, REAL_ITEM, NULL_ITEM, VARBIN_ITEM,
@@ -127,7 +130,7 @@ public:
PROC_ITEM,COND_ITEM, REF_ITEM, FIELD_STD_ITEM,
FIELD_VARIANCE_ITEM, INSERT_VALUE_ITEM,
SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER,
- PARAM_ITEM};
+ PARAM_ITEM, TRIGGER_FIELD_ITEM};
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
@@ -137,8 +140,11 @@ public:
*/
String str_value;
my_string name; /* Name from select */
+ /* Original item name (if it was renamed)*/
+ my_string orig_name;
Item *next;
uint32 max_length;
+ uint name_length; /* Length of name */
uint8 marker,decimals;
my_bool maybe_null; /* If item may be null */
my_bool null_value; /* if item is null */
@@ -158,18 +164,16 @@ public:
optimisation changes in prepared statements
*/
Item(THD *thd, Item *item);
- virtual ~Item() { name=0; } /*lint -e1509 */
+ virtual ~Item()
+ {
+ name=0;
+ } /*lint -e1509 */
void set_name(const char *str,uint length, CHARSET_INFO *cs);
+ void rename(char *new_name);
void init_make_field(Send_field *tmp_field,enum enum_field_types type);
- virtual void cleanup()
- {
- DBUG_ENTER("Item::cleanup");
- DBUG_PRINT("info", ("Type: %d", (int)type()));
- fixed=0;
- marker= 0;
- DBUG_VOID_RETURN;
- }
+ virtual void cleanup();
virtual void make_field(Send_field *field);
+ Field *make_string_field(TABLE *table);
virtual bool fix_fields(THD *, struct st_table_list *, Item **);
/*
should be used in case where we are sure that we do not need
@@ -177,6 +181,7 @@ public:
*/
inline void quick_fix_field() { fixed= 1; }
/* Function returns 1 on overflow and -1 on fatal errors */
+ int save_in_field_no_warnings(Field *field, bool no_conversions);
virtual int save_in_field(Field *field, bool no_conversions);
virtual void save_org_in_field(Field *field)
{ (void) save_in_field(field, 1); }
@@ -188,7 +193,7 @@ public:
virtual enum_field_types field_type() const;
virtual enum Type type() const =0;
/* valXXX methods must return NULL or 0 or 0.0 if null_value is set. */
- virtual double val()=0;
+ virtual double val_real()=0;
virtual longlong val_int()=0;
/*
Return string representation of this item object.
@@ -219,7 +224,7 @@ public:
virtual Field *get_tmp_table_field() { return 0; }
virtual Field *tmp_table_field(TABLE *t_arg) { return 0; }
virtual const char *full_name() const { return name ? name : "???"; }
- virtual double val_result() { return val(); }
+ virtual double val_result() { return val_real(); }
virtual longlong val_int_result() { return val_int(); }
virtual String *str_result(String* tmp) { return val_str(tmp); }
/* bit map of tables used by item */
@@ -305,9 +310,22 @@ public:
return (this->*processor)(arg);
}
+ virtual Item* transform(Item_transformer transformer, byte *arg)
+ {
+ return (this->*transformer)(arg);
+ }
+
virtual bool remove_dependence_processor(byte * arg) { return 0; }
virtual bool remove_fixed(byte * arg) { fixed= 0; return 0; }
+ virtual bool cleanup_processor(byte *arg);
+ virtual bool collect_item_field_processor(byte * arg) { return 0; }
+ virtual Item *equal_fields_propagator(byte * arg) { return this; }
+ virtual Item *set_no_const_sub(byte *arg) { return this; }
+ virtual bool replace_equal_field_processor(byte * arg) { return 0; }
+ virtual Item *this_item() { return this; } /* For SPs mostly. */
+ virtual Item *this_const_item() const { return const_cast<Item*>(this); } /* For SPs mostly. */
+
// Row emulation
virtual uint cols() { return 1; }
virtual Item* el(uint i) { return this; }
@@ -319,6 +337,7 @@ public:
virtual void bring_value() {}
Field *tmp_table_field_from_field_type(TABLE *table);
+ virtual Item_field *filed_for_view_update() { return 0; }
virtual Item *neg_transformer(THD *thd) { return NULL; }
virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
@@ -330,6 +349,104 @@ public:
};
+// A local SP variable (incl. parameters), used in runtime
+class Item_splocal : public Item
+{
+private:
+
+ uint m_offset;
+ LEX_STRING m_name;
+
+public:
+
+ Item_splocal(LEX_STRING name, uint offset)
+ : m_offset(offset), m_name(name)
+ {
+ Item::maybe_null= TRUE;
+ }
+
+ Item *this_item();
+ Item *this_const_item() const;
+
+ inline uint get_offset()
+ {
+ return m_offset;
+ }
+
+ // Abstract methods inherited from Item. Just defer the call to
+ // the item in the frame
+ enum Type type() const;
+
+ inline double val_real()
+ {
+ Item *it= this_item();
+ double ret= it->val_real();
+ Item::null_value= it->null_value;
+ return ret;
+ }
+
+ inline longlong val_int()
+ {
+ Item *it= this_item();
+ longlong ret= it->val_int();
+ Item::null_value= it->null_value;
+ return ret;
+ }
+
+ inline String *val_str(String *sp)
+ {
+ Item *it= this_item();
+ String *ret= it->val_str(sp);
+ Item::null_value= it->null_value;
+ return ret;
+ }
+
+ inline bool is_null()
+ {
+ Item *it= this_item();
+ bool ret= it->is_null();
+ Item::null_value= it->null_value;
+ return ret;
+ }
+
+ inline void make_field(Send_field *field)
+ {
+ Item *it= this_item();
+
+ it->set_name(m_name.str, m_name.length, system_charset_info);
+ it->make_field(field);
+ }
+
+ inline Item_result result_type() const
+ {
+ return this_const_item()->result_type();
+ }
+
+ inline bool const_item() const
+ {
+ return TRUE;
+ }
+
+ inline int save_in_field(Field *field, bool no_conversions)
+ {
+ return this_item()->save_in_field(field, no_conversions);
+ }
+
+ void print(String *str)
+ {
+ str->reserve(m_name.length+8);
+ str->append(m_name.str, m_name.length);
+ str->append('@');
+ str->qs_append(m_offset);
+ }
+
+ inline bool send(Protocol *protocol, String *str)
+ {
+ return this_item()->send(protocol, str);
+ }
+};
+
+
class Item_num: public Item
{
public:
@@ -355,6 +472,7 @@ public:
const char *db_name;
const char *table_name;
const char *field_name;
+ bool alias_name_used; /* true if item was resolved against alias */
/*
Cached value of index for this field in table->field array, used by prep.
stmts for speeding up their re-execution. Holds NO_CACHED_FIELD_INDEX
@@ -374,19 +492,37 @@ public:
const char *full_name() const;
void cleanup();
bool remove_dependence_processor(byte * arg);
+ void print(String *str);
+
+ friend bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
+ const char *table_name, List_iterator<Item> *it,
+ bool any_privileges, bool allocate_view_names);
};
+class Item_equal;
+class COND_EQUAL;
class Item_field :public Item_ident
{
+protected:
void set_field(Field *field);
public:
Field *field,*result_field;
+ Item_equal *item_equal;
+ bool no_const_subst;
+ /*
+ if any_privileges set to TRUE then here real effective privileges will
+ be stored
+ */
+ uint have_privileges;
+ /* field need any privileges (for VIEW creation) */
+ bool any_privileges;
Item_field(const char *db_par,const char *table_name_par,
const char *field_name_par)
:Item_ident(db_par,table_name_par,field_name_par),
- field(0), result_field(0)
+ field(0), result_field(0), item_equal(0), no_const_subst(0),
+ have_privileges(0), any_privileges(0)
{ collation.set(DERIVATION_IMPLICIT); }
/*
Constructor needed to process subselect with temporary tables (see Item)
@@ -406,7 +542,7 @@ public:
Item_field(Field *field);
enum Type type() const { return FIELD_ITEM; }
bool eq(const Item *item, bool binary_cmp) const;
- double val();
+ double val_real();
longlong val_int();
String *val_str(String*);
double val_result();
@@ -434,8 +570,15 @@ public:
bool get_time(TIME *ltime);
bool is_null() { return field->is_null(); }
Item *get_tmp_table_item(THD *thd);
+ bool collect_item_field_processor(byte * arg);
void cleanup();
+ Item_equal *find_item_equal(COND_EQUAL *cond_equal);
+ Item *equal_fields_propagator(byte *arg);
+ Item *set_no_const_sub(byte *arg);
+ bool replace_equal_field_processor(byte *arg);
inline uint32 max_disp_length() { return field->max_length(); }
+ Item_field *filed_for_view_update() { return this; }
+ Item *safe_charset_converter(CHARSET_INFO *tocs);
friend class Item_default_value;
friend class Item_insert_value;
friend class st_select_lex_unit;
@@ -454,7 +597,7 @@ public:
}
enum Type type() const { return NULL_ITEM; }
bool eq(const Item *item, bool binary_cmp) const;
- double val();
+ double val_real();
longlong val_int();
String *val_str(String *str);
int save_in_field(Field *field, bool no_conversions);
@@ -543,7 +686,7 @@ public:
enum Type type() const { return item_type; }
enum_field_types field_type() const { return param_type; }
- double val();
+ double val_real();
longlong val_int();
String *val_str(String*);
bool get_time(TIME *tm);
@@ -578,7 +721,7 @@ public:
*/
virtual table_map used_tables() const
{ return state != NO_VALUE ? (table_map)0 : PARAM_TABLE_BIT; }
- void print(String *str) { str->append('?'); }
+ void print(String *str);
/* parameter never equal to other parameter of other item */
bool eq(const Item *item, bool binary_cmp) const { return 0; }
bool is_null()
@@ -602,7 +745,7 @@ public:
enum Item_result result_type () const { return INT_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
- double val() { DBUG_ASSERT(fixed == 1); return (double) value; }
+ double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; }
String *val_str(String*);
int save_in_field(Field *field, bool no_conversions);
bool basic_const_item() const { return 1; }
@@ -614,13 +757,24 @@ public:
};
+class Item_static_int_func :public Item_int
+{
+ const char *func_name;
+public:
+ Item_static_int_func(const char *str_arg, longlong i, uint length)
+ :Item_int(NullS, i, length), func_name(str_arg)
+ {}
+ void print(String *str) { str->append(func_name); }
+};
+
+
class Item_uint :public Item_int
{
public:
Item_uint(const char *str_arg, uint length);
Item_uint(uint32 i) :Item_int((longlong) i, 10)
{ unsigned_flag= 1; }
- double val()
+ double val_real()
{ DBUG_ASSERT(fixed == 1); return ulonglong2double((ulonglong)value); }
String *val_str(String*);
Item *new_item() { return new Item_uint(name,max_length); }
@@ -632,29 +786,24 @@ public:
class Item_real :public Item_num
{
+ char *presentation;
public:
double value;
// Item_real() :value(0) {}
- Item_real(const char *str_arg, uint length) :value(my_atof(str_arg))
- {
- name=(char*) str_arg;
- decimals=(uint8) nr_of_decimals(str_arg);
- max_length=length;
- fixed= 1;
- }
+ Item_real(const char *str_arg, uint length);
Item_real(const char *str,double val_arg,uint decimal_par,uint length)
:value(val_arg)
{
- name=(char*) str;
+ presentation= name=(char*) str;
decimals=(uint8) decimal_par;
max_length=length;
fixed= 1;
}
- Item_real(double value_par) :value(value_par) { fixed= 1; }
+ Item_real(double value_par) :presentation(0), value(value_par) { fixed= 1; }
int save_in_field(Field *field, bool no_conversions);
enum Type type() const { return REAL_ITEM; }
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
- double val() { DBUG_ASSERT(fixed == 1); return value; }
+ double val_real() { DBUG_ASSERT(fixed == 1); return value; }
longlong val_int()
{
DBUG_ASSERT(fixed == 1);
@@ -666,6 +815,19 @@ public:
void cleanup() {}
Item *new_item() { return new Item_real(name,value,decimals,max_length); }
Item_num *neg() { value= -value; return this; }
+ void print(String *str);
+};
+
+
+class Item_static_real_func :public Item_real
+{
+ const char *func_name;
+public:
+ Item_static_real_func(const char *str, double val_arg, uint decimal_par,
+ uint length)
+ :Item_real(NullS, val_arg, decimal_par, length), func_name(str)
+ {}
+ void print(String *str) { str->append(func_name); }
};
@@ -712,7 +874,7 @@ public:
fixed= 1;
}
enum Type type() const { return STRING_ITEM; }
- double val()
+ double val_real()
{
DBUG_ASSERT(fixed == 1);
int err;
@@ -733,7 +895,7 @@ public:
}
int save_in_field(Field *field, bool no_conversions);
enum Item_result result_type () const { return STRING_RESULT; }
- enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
+ enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
bool basic_const_item() const { return 1; }
bool eq(const Item *item, bool binary_cmp) const;
Item *new_item()
@@ -749,6 +911,20 @@ public:
void cleanup() {}
};
+
+class Item_static_string_func :public Item_string
+{
+ const char *func_name;
+public:
+ Item_static_string_func(const char *name_par, const char *str, uint length,
+ CHARSET_INFO *cs,
+ Derivation dv= DERIVATION_COERCIBLE)
+ :Item_string(NullS, str, length, cs, dv), func_name(name_par)
+ {}
+ void print(String *str) { str->append(func_name); }
+};
+
+
/* for show tables */
class Item_datetime :public Item_string
@@ -783,24 +959,31 @@ public:
};
-class Item_varbinary :public Item
+class Item_hex_string: public Item
{
public:
- Item_varbinary(const char *str,uint str_length);
+ Item_hex_string(): Item() {}
+ Item_hex_string(const char *str,uint str_length);
enum Type type() const { return VARBIN_ITEM; }
- double val()
- { DBUG_ASSERT(fixed == 1); return (double) Item_varbinary::val_int(); }
+ double val_real()
+ { DBUG_ASSERT(fixed == 1); return (double) Item_hex_string::val_int(); }
longlong val_int();
bool basic_const_item() const { return 1; }
String *val_str(String*) { DBUG_ASSERT(fixed == 1); return &str_value; }
int save_in_field(Field *field, bool no_conversions);
enum Item_result result_type () const { return STRING_RESULT; }
- enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
+ enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
// to prevent drop fixed flag (no need parent cleanup call)
void cleanup() {}
};
+class Item_bin_string: public Item_hex_string
+{
+public:
+ Item_bin_string(const char *str,uint str_length);
+};
+
class Item_result_field :public Item /* Item with result field */
{
public:
@@ -834,7 +1017,7 @@ public:
Item **ref;
Item_ref(const char *db_par, const char *table_name_par,
const char *field_name_par)
- :Item_ident(db_par, table_name_par, field_name_par), ref(0) {}
+ :Item_ident(db_par, table_name_par, field_name_par), result_field(0), ref(0) {}
/*
This constructor is used in two scenarios:
A) *item = NULL
@@ -850,7 +1033,7 @@ public:
with Bar, and if we have a more broader set of problems like this.
*/
Item_ref(Item **item, const char *table_name_par, const char *field_name_par)
- :Item_ident(NullS, table_name_par, field_name_par), ref(item)
+ :Item_ident(NullS, table_name_par, field_name_par), result_field(0), ref(item)
{
DBUG_ASSERT(item);
if (*item)
@@ -858,11 +1041,11 @@ public:
}
/* Constructor need to process subselect with temporary tables (see Item) */
- Item_ref(THD *thd, Item_ref *item) :Item_ident(thd, item), ref(item->ref) {}
+ Item_ref(THD *thd, Item_ref *item) :Item_ident(thd, item), result_field(item->result_field), ref(item->ref) {}
enum Type type() const { return REF_ITEM; }
bool eq(const Item *item, bool binary_cmp) const
{ return ref && (*ref)->eq(item, binary_cmp); }
- double val()
+ double val_real()
{
DBUG_ASSERT(fixed);
double tmp=(*ref)->val_result();
@@ -894,7 +1077,10 @@ public:
DBUG_ASSERT(fixed);
return (null_value=(*ref)->get_date_result(ltime,fuzzydate));
}
- bool send(Protocol *prot, String *tmp){ return (*ref)->send(prot, tmp); }
+ double val_result();
+ longlong val_int_result();
+ String *str_result(String* tmp);
+ bool send(Protocol *prot, String *tmp);
void make_field(Send_field *field) { (*ref)->make_field(field); }
bool fix_fields(THD *, struct st_table_list *, Item **);
int save_in_field(Field *field, bool no_conversions)
@@ -907,13 +1093,17 @@ public:
return depended_from ? OUTER_REF_TABLE_BIT : (*ref)->used_tables();
}
void set_result_field(Field *field) { result_field= field; }
+ Field *get_tmp_table_field() { return result_field; }
bool is_result_field() { return 1; }
void save_in_result_field(bool no_conversions)
{
(*ref)->save_in_field(result_field, no_conversions);
}
Item *real_item() { return *ref; }
+ bool walk(Item_processor processor, byte *arg)
+ { return (*ref)->walk(processor, arg); }
void print(String *str);
+ void cleanup();
};
@@ -970,7 +1160,7 @@ public:
Item_ref_null_helper(Item_in_subselect* master, Item **item,
const char *table_name_par, const char *field_name_par):
Item_ref(item, table_name_par, field_name_par), owner(master) {}
- double val();
+ double val_real();
longlong val_int();
String* val_str(String* s);
bool get_date(TIME *ltime, uint fuzzydate);
@@ -1038,7 +1228,7 @@ public:
enum Type type() const { return COPY_STR_ITEM; }
enum Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const { return cached_field_type; }
- double val()
+ double val_real()
{
int err;
return (null_value ? 0.0 :
@@ -1142,6 +1332,19 @@ public:
return arg->walk(processor, args) ||
(this->*processor)(args);
}
+
+ /*
+ This method like the walk method traverses the item tree, but
+ at the same time it can replace some nodes in the tree
+ */
+ Item *transform(Item_transformer transformer, byte *args)
+ {
+ Item *new_item= arg->transform(transformer, args);
+ if (!new_item)
+ return 0;
+ arg= new_item;
+ return (this->*transformer)(args);
+ }
};
class Item_insert_value : public Item_field
@@ -1166,6 +1369,59 @@ public:
}
};
+
+/*
+ We need this two enums here instead of sql_lex.h because
+ at least one of them is used by Item_trigger_field interface.
+
+ Time when trigger is invoked (i.e. before or after row actually
+ inserted/updated/deleted).
+*/
+enum trg_action_time_type
+{
+ TRG_ACTION_BEFORE= 0, TRG_ACTION_AFTER= 1
+};
+
+/*
+ Event on which trigger is invoked.
+*/
+enum trg_event_type
+{
+ TRG_EVENT_INSERT= 0 , TRG_EVENT_UPDATE= 1, TRG_EVENT_DELETE= 2
+};
+
+/*
+ Represents NEW/OLD version of field of row which is
+ changed/read in trigger.
+
+ Note: For this item actual binding to Field object happens not during
+ fix_fields() (like for Item_field) but during parsing of trigger
+ definition, when table is opened, with special setup_field() call.
+*/
+class Item_trigger_field : public Item_field
+{
+public:
+ /* Is this item represents row from NEW or OLD row ? */
+ enum row_version_type {OLD_ROW, NEW_ROW};
+ row_version_type row_version;
+ /* Next in list of all Item_trigger_field's in trigger */
+ Item_trigger_field *next_trg_field;
+
+ Item_trigger_field(row_version_type row_ver_par,
+ const char *field_name_par):
+ Item_field((const char *)NULL, (const char *)NULL, field_name_par),
+ row_version(row_ver_par)
+ {}
+ void setup_field(THD *thd, TABLE *table, enum trg_event_type event);
+ enum Type type() const { return TRIGGER_FIELD_ITEM; }
+ bool eq(const Item *item, bool binary_cmp) const;
+ bool fix_fields(THD *, struct st_table_list *, Item **);
+ void print(String *str);
+ table_map used_tables() const { return (table_map)0L; }
+ void cleanup();
+};
+
+
class Item_cache: public Item
{
protected:
@@ -1202,7 +1458,7 @@ public:
Item_cache_int(): Item_cache(), value(0) {}
void store(Item *item);
- double val() { DBUG_ASSERT(fixed == 1); return (double) value; }
+ double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; }
longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
String* val_str(String *str)
{
@@ -1220,7 +1476,7 @@ public:
Item_cache_real(): Item_cache(), value(0) {}
void store(Item *item);
- double val() { DBUG_ASSERT(fixed == 1); return value; }
+ double val_real() { DBUG_ASSERT(fixed == 1); return value; }
longlong val_int()
{
DBUG_ASSERT(fixed == 1);
@@ -1242,7 +1498,7 @@ public:
Item_cache_str(): Item_cache(), value(0) { }
void store(Item *item);
- double val();
+ double val_real();
longlong val_int();
String* val_str(String *) { DBUG_ASSERT(fixed == 1); return value; }
enum Item_result result_type() const { return STRING_RESULT; }
@@ -1274,7 +1530,7 @@ public:
{
illegal_method_call((const char*)"make_field");
};
- double val()
+ double val_real()
{
illegal_method_call((const char*)"val");
return 0;
@@ -1325,7 +1581,7 @@ public:
Item_result result_type () const { return item_type; }
enum Type type() const { return TYPE_HOLDER; }
- double val();
+ double val_real();
longlong val_int();
String *val_str(String*);
bool join_types(THD *thd, Item *);