diff options
Diffstat (limited to 'sql/item_func.h')
-rw-r--r-- | sql/item_func.h | 441 |
1 files changed, 263 insertions, 178 deletions
diff --git a/sql/item_func.h b/sql/item_func.h index 3627af4ebb1..51f9d3fb36f 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -17,7 +17,7 @@ /* Function items used by mysql */ -#ifdef __GNUC__ +#ifdef USE_PRAGMA_INTERFACE #pragma interface /* gcc class implementation */ #endif @@ -31,7 +31,12 @@ extern "C" /* Bug in BSDI include file */ class Item_func :public Item_result_field { protected: - Item **args,*tmp_arg[2]; + Item **args, *tmp_arg[2]; + /* + Allowed numbers of columns in result (usually 1, which means scalar value) + 0 means get this number from first argument + */ + uint allowed_arg_cols; public: uint arg_count; table_map used_tables_cache, not_null_tables_cache; @@ -39,63 +44,74 @@ public: enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC, GE_FUNC,GT_FUNC,FT_FUNC, LIKE_FUNC,NOTLIKE_FUNC,ISNULL_FUNC,ISNOTNULL_FUNC, - COND_AND_FUNC,COND_OR_FUNC,COND_XOR_FUNC,BETWEEN,IN_FUNC,INTERVAL_FUNC}; + COND_AND_FUNC, COND_OR_FUNC, COND_XOR_FUNC, BETWEEN, IN_FUNC, + INTERVAL_FUNC, ISNOTNULLTEST_FUNC, + SP_EQUALS_FUNC, SP_DISJOINT_FUNC,SP_INTERSECTS_FUNC, + SP_TOUCHES_FUNC,SP_CROSSES_FUNC,SP_WITHIN_FUNC, + SP_CONTAINS_FUNC,SP_OVERLAPS_FUNC, + SP_STARTPOINT,SP_ENDPOINT,SP_EXTERIORRING, + SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN, + NOT_FUNC, NOT_ALL_FUNC, NOW_FUNC, VAR_VALUE_FUNC}; enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL }; enum Type type() const { return FUNC_ITEM; } virtual enum Functype functype() const { return UNKNOWN_FUNC; } - Item_func(void) + Item_func(void): + allowed_arg_cols(1), arg_count(0) { - arg_count=0; with_sum_func=0; + with_sum_func= 0; } - Item_func(Item *a) + Item_func(Item *a): + allowed_arg_cols(1), arg_count(1) { - arg_count=1; - args=tmp_arg; - args[0]=a; - with_sum_func=a->with_sum_func; + args= tmp_arg; + args[0]= a; + with_sum_func= a->with_sum_func; } - Item_func(Item *a,Item *b) + Item_func(Item *a,Item *b): + allowed_arg_cols(1), arg_count(2) { - arg_count=2; - args=tmp_arg; - args[0]=a; args[1]=b; - with_sum_func=a->with_sum_func || b->with_sum_func; + args= tmp_arg; + args[0]= a; args[1]= b; + with_sum_func= a->with_sum_func || b->with_sum_func; } - Item_func(Item *a,Item *b,Item *c) + Item_func(Item *a,Item *b,Item *c): + allowed_arg_cols(1) { - arg_count=0; - if ((args=(Item**) sql_alloc(sizeof(Item*)*3))) + arg_count= 0; + if ((args= (Item**) sql_alloc(sizeof(Item*)*3))) { - arg_count=3; - args[0]=a; args[1]=b; args[2]=c; - with_sum_func=a->with_sum_func || b->with_sum_func || c->with_sum_func; + arg_count= 3; + args[0]= a; args[1]= b; args[2]= c; + with_sum_func= a->with_sum_func || b->with_sum_func || c->with_sum_func; } } - Item_func(Item *a,Item *b,Item *c,Item *d) + Item_func(Item *a,Item *b,Item *c,Item *d): + allowed_arg_cols(1) { - arg_count=0; - if ((args=(Item**) sql_alloc(sizeof(Item*)*4))) + arg_count= 0; + if ((args= (Item**) sql_alloc(sizeof(Item*)*4))) { - arg_count=4; - args[0]=a; args[1]=b; args[2]=c; args[3]=d; - with_sum_func=a->with_sum_func || b->with_sum_func || c->with_sum_func || - d->with_sum_func; + arg_count= 4; + args[0]= a; args[1]= b; args[2]= c; args[3]= d; + with_sum_func= a->with_sum_func || b->with_sum_func || + c->with_sum_func || d->with_sum_func; } } - Item_func(Item *a,Item *b,Item *c,Item *d,Item* e) + Item_func(Item *a,Item *b,Item *c,Item *d,Item* e): + allowed_arg_cols(1) { - arg_count=5; - if ((args=(Item**) sql_alloc(sizeof(Item*)*5))) + arg_count= 5; + if ((args= (Item**) sql_alloc(sizeof(Item*)*5))) { - args[0]=a; args[1]=b; args[2]=c; args[3]=d; args[4]=e; - with_sum_func=a->with_sum_func || b->with_sum_func || c->with_sum_func || - d->with_sum_func || e->with_sum_func ; + args[0]= a; args[1]= b; args[2]= c; args[3]= d; args[4]= e; + with_sum_func= a->with_sum_func || b->with_sum_func || + c->with_sum_func || d->with_sum_func || e->with_sum_func ; } } Item_func(List<Item> &list); - ~Item_func() {} /* Nothing to do; Items are freed automaticly */ - bool fix_fields(THD *,struct st_table_list *); - void make_field(Send_field *field); + // Constructor used for Item_cond_and/or (see Item comment) + Item_func(THD *thd, Item_func *item); + bool fix_fields(THD *,struct st_table_list *, Item **ref); table_map used_tables() const; table_map not_null_tables() const; void update_used_tables(); @@ -106,15 +122,17 @@ public: virtual const char *func_name() const { return "?"; } virtual bool const_item() const { return const_item_cache; } inline Item **arguments() const { return args; } + void set_arguments(List<Item> &list); inline uint argument_count() const { return arg_count; } inline void remove_arguments() { arg_count=0; } - virtual void split_sum_func(List<Item> &fields); + void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields); void print(String *str); void print_op(String *str); + void print_args(String *str, uint from); void fix_num_length_and_dec(); - inline bool get_arg0_date(TIME *ltime,bool fuzzy_date) + inline bool get_arg0_date(TIME *ltime, uint fuzzy_date) { - return (null_value=args[0]->get_date(ltime,fuzzy_date)); + return (null_value=args[0]->get_date(ltime, fuzzy_date)); } inline bool get_arg0_time(TIME *ltime) { @@ -122,8 +140,28 @@ public: } bool is_null() { (void) val_int(); return null_value; } friend class udf_handler; - unsigned int size_of() { return sizeof(*this);} + Field *tmp_table_field() { return result_field; } Field *tmp_table_field(TABLE *t_arg); + Item *get_tmp_table_item(THD *thd); + + bool agg_arg_collations(DTCollation &c, Item **items, uint nitems, + uint flags= 0) + { + return agg_item_collations(c, func_name(), items, nitems, flags); + } + bool agg_arg_collations_for_comparison(DTCollation &c, + Item **items, uint nitems, + uint flags= 0) + { + return agg_item_collations_for_comparison(c, func_name(), + items, nitems, flags); + } + bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems, + uint flags= 0) + { + return agg_item_charsets(c, func_name(), items, nitems, flags); + } + bool walk(Item_processor processor, byte *arg); }; @@ -135,10 +173,9 @@ public: Item_real_func(Item *a,Item *b) :Item_func(a,b) {} Item_real_func(List<Item> &list) :Item_func(list) {} String *val_str(String*str); - longlong val_int() { return (longlong) val(); } + longlong val_int() { DBUG_ASSERT(fixed == 1); return (longlong) val(); } enum Item_result result_type () const { return REAL_RESULT; } void fix_length_and_dec() { decimals=NOT_FIXED_DEC; max_length=float_length(decimals); } - unsigned int size_of() { return sizeof(*this);} }; @@ -150,11 +187,10 @@ public: Item_num_func(Item *a) :Item_func(a),hybrid_type(REAL_RESULT) {} Item_num_func(Item *a,Item *b) :Item_func(a,b),hybrid_type(REAL_RESULT) {} String *val_str(String*str); - longlong val_int() { return (longlong) val(); } + longlong val_int() { DBUG_ASSERT(fixed == 1); return (longlong) val(); } enum Item_result result_type () const { return hybrid_type; } void fix_length_and_dec() { fix_num_length_and_dec(); } bool is_null() { (void) val(); return null_value; } - unsigned int size_of() { return sizeof(*this);} }; @@ -170,7 +206,6 @@ class Item_num_op :public Item_func void fix_length_and_dec() { fix_num_length_and_dec(); find_num_type(); } void find_num_type(void); bool is_null() { (void) val(); return null_value; } - unsigned int size_of() { return sizeof(*this);} }; @@ -182,7 +217,8 @@ public: Item_int_func(Item *a,Item *b) :Item_func(a,b) { max_length=21; } Item_int_func(Item *a,Item *b,Item *c) :Item_func(a,b,c) { max_length=21; } Item_int_func(List<Item> &list) :Item_func(list) { max_length=21; } - double val() { return (double) val_int(); } + Item_int_func(THD *thd, Item_int_func *item) :Item_func(thd, item) {} + double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } String *val_str(String*str); enum Item_result result_type () const { return INT_RESULT; } void fix_length_and_dec() {} @@ -193,21 +229,30 @@ class Item_func_signed :public Item_int_func { public: Item_func_signed(Item *a) :Item_int_func(a) {} - double val() { return args[0]->val(); } - longlong val_int() { return args[0]->val_int(); } + const char *func_name() const { return "cast_as_signed"; } + double val() + { + double tmp= args[0]->val(); + null_value= args[0]->null_value; + return tmp; + } + longlong val_int(); + longlong val_int_from_str(int *error); void fix_length_and_dec() { max_length=args[0]->max_length; unsigned_flag=0; } + void print(String *str); }; -class Item_func_unsigned :public Item_int_func +class Item_func_unsigned :public Item_func_signed { public: - Item_func_unsigned(Item *a) :Item_int_func(a) {} - double val() { return args[0]->val(); } - longlong val_int() { return args[0]->val_int(); } + Item_func_unsigned(Item *a) :Item_func_signed(a) {} + const char *func_name() const { return "cast_as_unsigned"; } void fix_length_and_dec() { max_length=args[0]->max_length; unsigned_flag=1; } + longlong val_int(); + void print(String *str); }; @@ -252,6 +297,18 @@ public: }; +class Item_func_int_div :public Item_num_op +{ +public: + Item_func_int_div(Item *a,Item *b) :Item_num_op(a,b) + { hybrid_type=INT_RESULT; } + double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } + longlong val_int(); + const char *func_name() const { return "DIV"; } + void fix_length_and_dec(); +}; + + class Item_func_mod :public Item_num_op { public: @@ -303,6 +360,7 @@ class Item_dec_func :public Item_real_func #ifndef HAVE_FINITE return value; #else + /* The following should be safe, even if we compare doubles */ if (finite(value) && value != POSTFIX_ERROR) return value; null_value=1; @@ -467,13 +525,13 @@ class Item_func_rand :public Item_real_func { struct rand_struct *rand; public: - Item_func_rand(Item *a) :Item_real_func(a) {} - Item_func_rand() :Item_real_func() {} + Item_func_rand(Item *a) :Item_real_func(a), rand(0) {} + Item_func_rand() :Item_real_func() {} double val(); const char *func_name() const { return "rand"; } bool const_item() const { return 0; } - table_map used_tables() const { return RAND_TABLE_BIT; } - void fix_length_and_dec(); + void update_used_tables(); + bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref); }; @@ -496,7 +554,6 @@ class Item_func_units :public Item_real_func double val(); const char *func_name() const { return name; } void fix_length_and_dec() { decimals=NOT_FIXED_DEC; max_length=float_length(decimals); } - unsigned int size_of() { return sizeof(*this);} }; @@ -507,13 +564,12 @@ class Item_func_min_max :public Item_func int cmp_sign; public: Item_func_min_max(List<Item> &list,int cmp_sign_arg) :Item_func(list), - cmp_sign(cmp_sign_arg) {} + cmp_type(INT_RESULT), cmp_sign(cmp_sign_arg) {} double val(); longlong val_int(); String *val_str(String *); void fix_length_and_dec(); enum Item_result result_type () const { return cmp_type; } - unsigned int size_of() { return sizeof(*this);} table_map not_null_tables() const { return 0; } }; @@ -540,14 +596,14 @@ public: longlong val_int(); const char *func_name() const { return "length"; } void fix_length_and_dec() { max_length=10; } - unsigned int size_of() { return sizeof(*this);} }; class Item_func_bit_length :public Item_func_length { public: Item_func_bit_length(Item *a) :Item_func_length(a) {} - longlong val_int() { return Item_func_length::val_int()*8; } + longlong val_int() + { DBUG_ASSERT(fixed == 1); return Item_func_length::val_int()*8; } const char *func_name() const { return "bit_length"; } }; @@ -559,52 +615,42 @@ public: longlong val_int(); const char *func_name() const { return "char_length"; } void fix_length_and_dec() { max_length=10; } - unsigned int size_of() { return sizeof(*this);} +}; + +class Item_func_coercibility :public Item_int_func +{ +public: + Item_func_coercibility(Item *a) :Item_int_func(a) {} + longlong val_int(); + const char *func_name() const { return "coercibility"; } + void fix_length_and_dec() { max_length=10; maybe_null= 0; } + table_map not_null_tables() const { return 0; } }; class Item_func_locate :public Item_int_func { String value1,value2; + DTCollation cmp_collation; public: Item_func_locate(Item *a,Item *b) :Item_int_func(a,b) {} Item_func_locate(Item *a,Item *b,Item *c) :Item_int_func(a,b,c) {} const char *func_name() const { return "locate"; } longlong val_int(); - void fix_length_and_dec() { maybe_null=0; max_length=11; } - unsigned int size_of() { return sizeof(*this);} + void fix_length_and_dec(); + void print(String *str); }; class Item_func_field :public Item_int_func { - Item *item; String value,tmp; + Item_result cmp_type; + DTCollation cmp_collation; public: - Item_func_field(Item *a,List<Item> &list) :Item_int_func(list),item(a) {} - ~Item_func_field() { delete item; } + Item_func_field(List<Item> &list) :Item_int_func(list) {} longlong val_int(); - bool fix_fields(THD *thd,struct st_table_list *tlist) - { - return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist)); - } - void split_sum_func(List<Item> &fields); - void update_used_tables() - { - item->update_used_tables(); - Item_func::update_used_tables(); - used_tables_cache|= item->used_tables(); - const_item_cache&= item->const_item(); - } const char *func_name() const { return "field"; } - void fix_length_and_dec() - { - maybe_null=0; max_length=3; - used_tables_cache|= item->used_tables(); - not_null_tables_cache= item->not_null_tables(); - const_item_cache&= item->const_item(); - with_sum_func= with_sum_func || item->with_sum_func; - } - unsigned int size_of() { return sizeof(*this);} + void fix_length_and_dec(); }; @@ -616,7 +662,6 @@ public: longlong val_int(); const char *func_name() const { return "ascii"; } void fix_length_and_dec() { max_length=3; } - unsigned int size_of() { return sizeof(*this);} }; class Item_func_ord :public Item_int_func @@ -626,7 +671,6 @@ public: Item_func_ord(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "ord"; } - unsigned int size_of() { return sizeof(*this);} }; class Item_func_find_in_set :public Item_int_func @@ -634,12 +678,12 @@ class Item_func_find_in_set :public Item_int_func String value,value2; uint enum_value; ulonglong enum_bit; + DTCollation cmp_collation; public: Item_func_find_in_set(Item *a,Item *b) :Item_int_func(a,b),enum_value(0) {} longlong val_int(); const char *func_name() const { return "find_in_set"; } void fix_length_and_dec(); - unsigned int size_of() { return sizeof(*this);} }; /* Base class for all bit functions: '~', '|', '^', '&', '>>', '<<' */ @@ -650,6 +694,7 @@ public: Item_func_bit(Item *a, Item *b) :Item_int_func(a, b) {} Item_func_bit(Item *a) :Item_int_func(a) {} void fix_length_and_dec() { unsigned_flag= 1; } + void print(String *str) { print_op(str); } }; class Item_func_bit_or :public Item_func_bit @@ -699,15 +744,18 @@ public: Item_func_bit_neg(Item *a) :Item_func_bit(a) {} longlong val_int(); const char *func_name() const { return "~"; } + void print(String *str) { Item_func::print(str); } }; -class Item_func_set_last_insert_id :public Item_int_func + +class Item_func_last_insert_id :public Item_int_func { public: - Item_func_set_last_insert_id(Item *a) :Item_int_func(a) {} + Item_func_last_insert_id() :Item_int_func() {} + Item_func_last_insert_id(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "last_insert_id"; } - void fix_length_and_dec() { max_length=args[0]->max_length; } + void fix_length_and_dec() { if (arg_count) max_length= args[0]->max_length; } }; class Item_func_benchmark :public Item_int_func @@ -720,7 +768,7 @@ class Item_func_benchmark :public Item_int_func longlong val_int(); const char *func_name() const { return "benchmark"; } void fix_length_and_dec() { max_length=1; maybe_null=0; } - unsigned int size_of() { return sizeof(*this);} + void print(String *str); }; @@ -735,18 +783,19 @@ public: Item_udf_func(udf_func *udf_arg) :Item_func(), udf(udf_arg) {} Item_udf_func(udf_func *udf_arg, List<Item> &list) :Item_func(list), udf(udf_arg) {} - ~Item_udf_func() {} const char *func_name() const { return udf.name(); } - bool fix_fields(THD *thd,struct st_table_list *tables) + bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref) { - bool res=udf.fix_fields(thd,tables,this,arg_count,args); - used_tables_cache=udf.used_tables_cache; - const_item_cache=udf.const_item_cache; + DBUG_ASSERT(fixed == 0); + bool res= udf.fix_fields(thd, tables, this, arg_count, args); + used_tables_cache= udf.used_tables_cache; + const_item_cache= udf.const_item_cache; + fixed= 1; return res; } + void cleanup(); Item_result result_type () const { return udf.result_type(); } table_map not_null_tables() const { return 0; } - unsigned int size_of() { return sizeof(*this);} }; @@ -756,8 +805,8 @@ class Item_func_udf_float :public Item_udf_func Item_func_udf_float(udf_func *udf_arg) :Item_udf_func(udf_arg) {} Item_func_udf_float(udf_func *udf_arg, List<Item> &list) :Item_udf_func(udf_arg,list) {} - ~Item_func_udf_float() {} - longlong val_int() { return (longlong) Item_func_udf_float::val(); } + longlong val_int() + { DBUG_ASSERT(fixed == 1); return (longlong) Item_func_udf_float::val(); } double val(); String *val_str(String *str); void fix_length_and_dec() { fix_num_length_and_dec(); } @@ -770,7 +819,6 @@ public: Item_func_udf_int(udf_func *udf_arg) :Item_udf_func(udf_arg) {} Item_func_udf_int(udf_func *udf_arg, List<Item> &list) :Item_udf_func(udf_arg,list) {} - ~Item_func_udf_int() {} longlong val_int(); double val() { return (double) Item_func_udf_int::val_int(); } String *val_str(String *str); @@ -785,17 +833,21 @@ public: Item_func_udf_str(udf_func *udf_arg) :Item_udf_func(udf_arg) {} Item_func_udf_str(udf_func *udf_arg, List<Item> &list) :Item_udf_func(udf_arg,list) {} - ~Item_func_udf_str() {} String *val_str(String *); double val() { - String *res; res=val_str(&str_value); - return res ? atof(res->c_ptr()) : 0.0; + int err; + String *res; + char *end_not_used; + res=val_str(&str_value); + return res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(), + &end_not_used, &err) : 0.0; } longlong val_int() { + int err; String *res; res=val_str(&str_value); - return res ? strtoll(res->c_ptr(),(char**) 0,10) : (longlong) 0; + return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10,(char**) 0,&err) : (longlong) 0; } enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec(); @@ -808,8 +860,7 @@ class Item_func_udf_float :public Item_real_func public: Item_func_udf_float(udf_func *udf_arg) :Item_real_func() {} Item_func_udf_float(udf_func *udf_arg, List<Item> &list) :Item_real_func(list) {} - ~Item_func_udf_float() {} - double val() { return 0.0; } + double val() { DBUG_ASSERT(fixed == 1); return 0.0; } }; @@ -818,8 +869,7 @@ class Item_func_udf_int :public Item_int_func public: Item_func_udf_int(udf_func *udf_arg) :Item_int_func() {} Item_func_udf_int(udf_func *udf_arg, List<Item> &list) :Item_int_func(list) {} - ~Item_func_udf_int() {} - longlong val_int() { return 0; } + longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; } }; @@ -828,10 +878,10 @@ class Item_func_udf_str :public Item_func public: Item_func_udf_str(udf_func *udf_arg) :Item_func() {} Item_func_udf_str(udf_func *udf_arg, List<Item> &list) :Item_func(list) {} - ~Item_func_udf_str() {} - String *val_str(String *) { null_value=1; return 0; } - double val() { null_value=1; return 0.0; } - longlong val_int() { null_value=1; return 0; } + String *val_str(String *) + { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } + double val() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; } + longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec() { maybe_null=1; max_length=0; } }; @@ -842,9 +892,9 @@ public: ** User level locks */ -class ULL; +class User_level_lock; void item_user_lock_init(void); -void item_user_lock_release(ULL *ull); +void item_user_lock_release(User_level_lock *ull); void item_user_lock_free(void); class Item_func_get_lock :public Item_int_func @@ -855,7 +905,6 @@ class Item_func_get_lock :public Item_int_func longlong val_int(); const char *func_name() const { return "get_lock"; } void fix_length_and_dec() { max_length=1; maybe_null=1;} - unsigned int size_of() { return sizeof(*this);} }; class Item_func_release_lock :public Item_int_func @@ -866,7 +915,6 @@ class Item_func_release_lock :public Item_int_func longlong val_int(); const char *func_name() const { return "release_lock"; } void fix_length_and_dec() { max_length=1; maybe_null=1;} - unsigned int size_of() { return sizeof(*this);} }; /* replication functions */ @@ -880,7 +928,6 @@ class Item_master_pos_wait :public Item_int_func longlong val_int(); const char *func_name() const { return "master_pos_wait"; } void fix_length_and_dec() { max_length=21; maybe_null=1;} - unsigned int size_of() { return sizeof(*this);} }; @@ -891,34 +938,44 @@ class user_var_entry; class Item_func_set_user_var :public Item_func { enum Item_result cached_result_type; - LEX_STRING name; user_var_entry *entry; char buffer[MAX_FIELD_WIDTH]; String value; + union + { + longlong vint; + double vreal; + String *vstr; + } save_result; + String save_buff; + public: - Item_func_set_user_var(LEX_STRING a,Item *b): - Item_func(b), name(a), value(buffer,sizeof(buffer)) {} + LEX_STRING name; // keep it public + Item_func_set_user_var(LEX_STRING a,Item *b) + :Item_func(b), cached_result_type(INT_RESULT), name(a) + {} double val(); longlong val_int(); String *val_str(String *str); - bool update_hash(const void *ptr, uint length, enum Item_result type); + bool update_hash(void *ptr, uint length, enum Item_result type, + CHARSET_INFO *cs, Derivation dv); + bool check(); bool update(); enum Item_result result_type () const { return cached_result_type; } - bool fix_fields(THD *thd,struct st_table_list *tables); + bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref); void fix_length_and_dec(); void print(String *str); const char *func_name() const { return "set_user_var"; } - unsigned int size_of() { return sizeof(*this);} }; class Item_func_get_user_var :public Item_func { - LEX_STRING name; user_var_entry *var_entry; public: + LEX_STRING name; // keep it public Item_func_get_user_var(LEX_STRING a): Item_func(), name(a) {} double val(); @@ -927,12 +984,40 @@ public: void fix_length_and_dec(); void print(String *str); enum Item_result result_type() const; + /* + We must always return variables as strings to guard against selects of type + select @t1:=1,@t1,@t:="hello",@t from foo where (@t1:= t2.b) + */ + enum_field_types field_type() const { return MYSQL_TYPE_STRING; } + enum Functype functype() const { return VAR_VALUE_FUNC; } const char *func_name() const { return "get_user_var"; } bool const_item() const; table_map used_tables() const { return const_item() ? 0 : RAND_TABLE_BIT; } bool eq(const Item *item, bool binary_cmp) const; - unsigned int size_of() { return sizeof(*this);} +}; + + +/* A system variable */ + +class Item_func_get_system_var :public Item_func +{ + sys_var *var; + enum_var_type var_type; + LEX_STRING component; +public: + Item_func_get_system_var(sys_var *var_arg, enum_var_type var_type_arg, + LEX_STRING *component_arg, const char *name_arg, + size_t name_len_arg); + bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref); + /* + Stubs for pure virtual methods. Should never be called: this + item is always substituted with a constant in fix_fields(). + */ + double val() { DBUG_ASSERT(0); return 0.0; } + longlong val_int() { DBUG_ASSERT(0); return 0; } + String* val_str(String*) { DBUG_ASSERT(0); return 0; } + void fix_length_and_dec() { DBUG_ASSERT(0); } }; @@ -952,92 +1037,92 @@ public: class Item_func_match :public Item_real_func { public: - List<Item> fields; - String value; - TABLE *table; - Item_func_match *master; - FT_INFO * ft_handler; - Item *concat; - byte *record; - uint key, mode; + uint key, flags; bool join_key; - - Item_func_match(List<Item> &a, Item *b): Item_real_func(b), - fields(a), table(0), master(0), ft_handler(0), - concat(0), key(0), join_key(0) - {} - ~Item_func_match() + DTCollation cmp_collation; + FT_INFO *ft_handler; + TABLE *table; + Item_func_match *master; // for master-slave optimization + Item *concat; // Item_func_concat_ws + String value; // value of concat + String search_value; // key_item()'s value converted to cmp_collation + + Item_func_match(List<Item> &a, uint b): Item_real_func(a), key(0), flags(b), + join_key(0), ft_handler(0), table(0), master(0), concat(0) { } + void cleanup() { + DBUG_ENTER("Item_func_match"); + Item_real_func::cleanup(); if (!master && ft_handler) { ft_handler->please->close_search(ft_handler); - ft_handler=0; - if(join_key) - table->file->ft_handler=0; - table->fulltext_searched=0; } if (concat) + { delete concat; + concat= 0; + } + ft_handler= 0; + DBUG_VOID_RETURN; } enum Functype functype() const { return FT_FUNC; } + const char *func_name() const { return "match"; } void update_used_tables() {} table_map not_null_tables() const { return 0; } - bool fix_fields(THD *thd,struct st_table_list *tlist); + bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref); bool eq(const Item *, bool binary_cmp) const; - longlong val_int() { return val()!=0.0; } + /* The following should be safe, even if we compare doubles */ + longlong val_int() { DBUG_ASSERT(fixed == 1); return val()!=0.0; } double val(); + void print(String *str); bool fix_index(); void init_search(bool no_order); - unsigned int size_of() { return sizeof(*this);} }; -class Item_func_match_nl :public Item_func_match +class Item_func_bit_xor : public Item_func_bit { public: - Item_func_match_nl(List<Item> &a, Item *b) - :Item_func_match(a,b) - { mode=FT_NL; } - const char *func_name() const { return "match_nl"; } + Item_func_bit_xor(Item *a, Item *b) :Item_func_bit(a, b) {} + longlong val_int(); + const char *func_name() const { return "^"; } }; +class Item_func_is_free_lock :public Item_int_func +{ + String value; +public: + Item_func_is_free_lock(Item *a) :Item_int_func(a) {} + longlong val_int(); + const char *func_name() const { return "is_free_lock"; } + void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;} +}; -class Item_func_match_bool :public Item_func_match +class Item_func_is_used_lock :public Item_int_func { + String value; public: - Item_func_match_bool(List<Item> &a, Item *b) - :Item_func_match(a,b) - { mode=FT_BOOL; } - const char *func_name() const { return "match_bool"; } + Item_func_is_used_lock(Item *a) :Item_int_func(a) {} + longlong val_int(); + const char *func_name() const { return "is_used_lock"; } + void fix_length_and_dec() { decimals=0; max_length=10; maybe_null=1;} }; /* For type casts */ -enum Item_cast +enum Cast_target { ITEM_CAST_BINARY, ITEM_CAST_SIGNED_INT, ITEM_CAST_UNSIGNED_INT, ITEM_CAST_DATE, ITEM_CAST_TIME, ITEM_CAST_DATETIME, ITEM_CAST_CHAR }; -Item *create_func_cast(Item *a, Item_cast cast_type); - - -class Item_func_bit_xor : public Item_func_bit -{ -public: - Item_func_bit_xor(Item *a, Item *b) :Item_func_bit(a, b) {} - longlong val_int(); - const char *func_name() const { return "^"; } -}; -class Item_func_is_free_lock :public Item_int_func +class Item_func_found_rows :public Item_int_func { - String value; public: - Item_func_is_free_lock(Item *a) :Item_int_func(a) {} + Item_func_found_rows() :Item_int_func() {} longlong val_int(); - const char *func_name() const { return "check_lock"; } - void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;} - unsigned int size_of() { return sizeof(*this);} + const char *func_name() const { return "found_rows"; } + void fix_length_and_dec() { decimals= 0; maybe_null=0; } }; |