summaryrefslogtreecommitdiff
path: root/sql/item_func.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_func.h')
-rw-r--r--sql/item_func.h441
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; }
};