mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-30 04:26:45 +03:00 
			
		
		
		
	 ac875690f7
			
		
	
	ac875690f7
	
	
	
		
			
			when used in a VIEW. The problem was that wrong function (create_tmp_from_item()) was used to create a temporary field for Item_func_sp. The fix is to use create_tmp_from_field().
		
			
				
	
	
		
			1569 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1569 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* Copyright (C) 2000-2006 MySQL AB
 | |
| 
 | |
|    This program is free software; you can redistribute it and/or modify
 | |
|    it under the terms of the GNU General Public License as published by
 | |
|    the Free Software Foundation; version 2 of the License.
 | |
| 
 | |
|    This program is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|    GNU General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with this program; if not, write to the Free Software
 | |
|    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 | |
| 
 | |
| 
 | |
| /* Function items used by mysql */
 | |
| 
 | |
| #ifdef USE_PRAGMA_INTERFACE
 | |
| #pragma interface			/* gcc class implementation */
 | |
| #endif
 | |
| 
 | |
| #ifdef HAVE_IEEEFP_H
 | |
| extern "C"				/* Bug in BSDI include file */
 | |
| {
 | |
| #include <ieeefp.h>
 | |
| }
 | |
| #endif
 | |
| 
 | |
| class Item_func :public Item_result_field
 | |
| {
 | |
| protected:
 | |
|   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;
 | |
|   bool const_item_cache;
 | |
|   enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC,
 | |
| 		  GE_FUNC,GT_FUNC,FT_FUNC,
 | |
| 		  LIKE_FUNC,ISNULL_FUNC,ISNOTNULL_FUNC,
 | |
| 		  COND_AND_FUNC, COND_OR_FUNC, COND_XOR_FUNC,
 | |
|                   BETWEEN, IN_FUNC, MULT_EQUAL_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, TRIG_COND_FUNC,
 | |
|                   SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
 | |
|                   EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC };
 | |
|   enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
 | |
|                        OPTIMIZE_EQUAL };
 | |
|   enum Type type() const { return FUNC_ITEM; }
 | |
|   virtual enum Functype functype() const   { return UNKNOWN_FUNC; }
 | |
|   Item_func(void):
 | |
|     allowed_arg_cols(1), arg_count(0)
 | |
|   {
 | |
|     with_sum_func= 0;
 | |
|   }
 | |
|   Item_func(Item *a):
 | |
|     allowed_arg_cols(1), arg_count(1)
 | |
|   {
 | |
|     args= tmp_arg;
 | |
|     args[0]= a;
 | |
|     with_sum_func= a->with_sum_func;
 | |
|   }
 | |
|   Item_func(Item *a,Item *b):
 | |
|     allowed_arg_cols(1), arg_count(2)
 | |
|   {
 | |
|     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):
 | |
|     allowed_arg_cols(1)
 | |
|   {
 | |
|     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;
 | |
|     }
 | |
|   }
 | |
|   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= 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):
 | |
|     allowed_arg_cols(1)
 | |
|   {
 | |
|     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 ;
 | |
|     }
 | |
|   }
 | |
|   Item_func(List<Item> &list);
 | |
|   // Constructor used for Item_cond_and/or (see Item comment)
 | |
|   Item_func(THD *thd, Item_func *item);
 | |
|   bool fix_fields(THD *, Item **ref);
 | |
|   table_map used_tables() const;
 | |
|   table_map not_null_tables() const;
 | |
|   void update_used_tables();
 | |
|   bool eq(const Item *item, bool binary_cmp) const;
 | |
|   virtual optimize_type select_optimize() const { return OPTIMIZE_NONE; }
 | |
|   virtual bool have_rev_func() const { return 0; }
 | |
|   virtual Item *key_item() const { return args[0]; }
 | |
|   /*
 | |
|     This method is used for debug purposes to print the name of an
 | |
|     item to the debug log. The second use of this method is as
 | |
|     a helper function of print(), where it is applicable.
 | |
|     To suit both goals it should return a meaningful,
 | |
|     distinguishable and sintactically correct string.  This method
 | |
|     should not be used for runtime type identification, use enum
 | |
|     {Sum}Functype and Item_func::functype()/Item_sum::sum_func()
 | |
|     instead.
 | |
|   */
 | |
|   virtual const char *func_name() const= 0;
 | |
|   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; }
 | |
|   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);
 | |
|   virtual void fix_num_length_and_dec();
 | |
|   void count_only_length();
 | |
|   void count_real_length();
 | |
|   void count_decimal_length();
 | |
|   inline bool get_arg0_date(MYSQL_TIME *ltime, uint fuzzy_date)
 | |
|   {
 | |
|     return (null_value=args[0]->get_date(ltime, fuzzy_date));
 | |
|   }
 | |
|   inline bool get_arg0_time(MYSQL_TIME *ltime)
 | |
|   {
 | |
|     return (null_value=args[0]->get_time(ltime));
 | |
|   }
 | |
|   bool is_null() { 
 | |
|     update_null_value();
 | |
|     return null_value; 
 | |
|   }
 | |
|   void signal_divide_by_null();
 | |
|   friend class udf_handler;
 | |
|   Field *tmp_table_field() { return result_field; }
 | |
|   Field *tmp_table_field(TABLE *t_arg);
 | |
|   Item *get_tmp_table_item(THD *thd);
 | |
| 
 | |
|   my_decimal *val_decimal(my_decimal *);
 | |
| 
 | |
|   bool agg_arg_collations(DTCollation &c, Item **items, uint nitems,
 | |
|                           uint flags)
 | |
|   {
 | |
|     return agg_item_collations(c, func_name(), items, nitems, flags, 1);
 | |
|   }
 | |
|   bool agg_arg_collations_for_comparison(DTCollation &c,
 | |
|                                          Item **items, uint nitems,
 | |
|                                          uint flags)
 | |
|   {
 | |
|     return agg_item_collations_for_comparison(c, func_name(),
 | |
|                                               items, nitems, flags);
 | |
|   }
 | |
|   bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems,
 | |
|                         uint flags, int item_sep)
 | |
|   {
 | |
|     return agg_item_charsets(c, func_name(), items, nitems, flags, item_sep);
 | |
|   }
 | |
|   bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
 | |
|   Item *transform(Item_transformer transformer, uchar *arg);
 | |
|   Item* compile(Item_analyzer analyzer, uchar **arg_p,
 | |
|                 Item_transformer transformer, uchar *arg_t);
 | |
|   void traverse_cond(Cond_traverser traverser,
 | |
|                      void * arg, traverse_order order);
 | |
|   bool is_expensive_processor(uchar *arg);
 | |
|   virtual bool is_expensive() { return 0; }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_real_func :public Item_func
 | |
| {
 | |
| public:
 | |
|   Item_real_func() :Item_func() {}
 | |
|   Item_real_func(Item *a) :Item_func(a) {}
 | |
|   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);
 | |
|   my_decimal *val_decimal(my_decimal *decimal_value);
 | |
|   longlong val_int()
 | |
|     { DBUG_ASSERT(fixed == 1); return (longlong) rint(val_real()); }
 | |
|   enum Item_result result_type () const { return REAL_RESULT; }
 | |
|   void fix_length_and_dec()
 | |
|   { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_numhybrid: public Item_func
 | |
| {
 | |
| protected:
 | |
|   Item_result hybrid_type;
 | |
| public:
 | |
|   Item_func_numhybrid(Item *a) :Item_func(a), hybrid_type(REAL_RESULT)
 | |
|   {}
 | |
|   Item_func_numhybrid(Item *a,Item *b)
 | |
|     :Item_func(a,b), hybrid_type(REAL_RESULT)
 | |
|   {}
 | |
|   Item_func_numhybrid(List<Item> &list)
 | |
|     :Item_func(list), hybrid_type(REAL_RESULT)
 | |
|   {}
 | |
| 
 | |
|   enum Item_result result_type () const { return hybrid_type; }
 | |
|   void fix_length_and_dec();
 | |
|   void fix_num_length_and_dec();
 | |
|   virtual void find_num_type()= 0; /* To be called from fix_length_and_dec */
 | |
| 
 | |
|   double val_real();
 | |
|   longlong val_int();
 | |
|   my_decimal *val_decimal(my_decimal *);
 | |
|   String *val_str(String*str);
 | |
| 
 | |
|   virtual longlong int_op()= 0;
 | |
|   virtual double real_op()= 0;
 | |
|   virtual my_decimal *decimal_op(my_decimal *)= 0;
 | |
|   virtual String *str_op(String *)= 0;
 | |
|   bool is_null() { update_null_value(); return null_value; }
 | |
| };
 | |
| 
 | |
| /* function where type of result detected by first argument */
 | |
| class Item_func_num1: public Item_func_numhybrid
 | |
| {
 | |
| public:
 | |
|   Item_func_num1(Item *a) :Item_func_numhybrid(a) {}
 | |
|   Item_func_num1(Item *a, Item *b) :Item_func_numhybrid(a, b) {}
 | |
| 
 | |
|   void fix_num_length_and_dec();
 | |
|   void find_num_type();
 | |
|   String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
 | |
| };
 | |
| 
 | |
| 
 | |
| /* Base class for operations like '+', '-', '*' */
 | |
| class Item_num_op :public Item_func_numhybrid
 | |
| {
 | |
|  public:
 | |
|   Item_num_op(Item *a,Item *b) :Item_func_numhybrid(a, b) {}
 | |
|   virtual void result_precision()= 0;
 | |
|   void print(String *str) { print_op(str); }
 | |
|   void find_num_type();
 | |
|   String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
 | |
|   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_int_func :public Item_func
 | |
| {
 | |
| public:
 | |
|   Item_int_func() :Item_func() { max_length= 21; }
 | |
|   Item_int_func(Item *a) :Item_func(a) { max_length= 21; }
 | |
|   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; }
 | |
|   Item_int_func(THD *thd, Item_int_func *item) :Item_func(thd, item) {}
 | |
|   double val_real();
 | |
|   String *val_str(String*str);
 | |
|   enum Item_result result_type () const { return INT_RESULT; }
 | |
|   void fix_length_and_dec() {}
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_connection_id :public Item_int_func
 | |
| {
 | |
|   longlong value;
 | |
| 
 | |
| public:
 | |
|   Item_func_connection_id() {}
 | |
|   const char *func_name() const { return "connection_id"; }
 | |
|   void fix_length_and_dec();
 | |
|   bool fix_fields(THD *thd, Item **ref);
 | |
|   longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_signed :public Item_int_func
 | |
| {
 | |
| public:
 | |
|   Item_func_signed(Item *a) :Item_int_func(a) {}
 | |
|   const char *func_name() const { return "cast_as_signed"; }
 | |
|   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);
 | |
|   uint decimal_precision() const { return args[0]->decimal_precision(); }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_unsigned :public Item_func_signed
 | |
| {
 | |
| public:
 | |
|   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);
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_decimal_typecast :public Item_func
 | |
| {
 | |
|   my_decimal decimal_value;
 | |
| public:
 | |
|   Item_decimal_typecast(Item *a, int len, int dec) :Item_func(a)
 | |
|   {
 | |
|     decimals= dec;
 | |
|     max_length= my_decimal_precision_to_length(len, dec, unsigned_flag);
 | |
|   }
 | |
|   String *val_str(String *str);
 | |
|   double val_real();
 | |
|   longlong val_int();
 | |
|   my_decimal *val_decimal(my_decimal*);
 | |
|   enum Item_result result_type () const { return DECIMAL_RESULT; }
 | |
|   enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
 | |
|   void fix_length_and_dec() {};
 | |
|   const char *func_name() const { return "decimal_typecast"; }
 | |
|   void print(String *);
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_additive_op :public Item_num_op
 | |
| {
 | |
| public:
 | |
|   Item_func_additive_op(Item *a,Item *b) :Item_num_op(a,b) {}
 | |
|   void result_precision();
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_plus :public Item_func_additive_op
 | |
| {
 | |
| public:
 | |
|   Item_func_plus(Item *a,Item *b) :Item_func_additive_op(a,b) {}
 | |
|   const char *func_name() const { return "+"; }
 | |
|   longlong int_op();
 | |
|   double real_op();
 | |
|   my_decimal *decimal_op(my_decimal *);
 | |
| };
 | |
| 
 | |
| class Item_func_minus :public Item_func_additive_op
 | |
| {
 | |
| public:
 | |
|   Item_func_minus(Item *a,Item *b) :Item_func_additive_op(a,b) {}
 | |
|   const char *func_name() const { return "-"; }
 | |
|   longlong int_op();
 | |
|   double real_op();
 | |
|   my_decimal *decimal_op(my_decimal *);
 | |
|   void fix_length_and_dec();
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_mul :public Item_num_op
 | |
| {
 | |
| public:
 | |
|   Item_func_mul(Item *a,Item *b) :Item_num_op(a,b) {}
 | |
|   const char *func_name() const { return "*"; }
 | |
|   longlong int_op();
 | |
|   double real_op();
 | |
|   my_decimal *decimal_op(my_decimal *);
 | |
|   void result_precision();
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_div :public Item_num_op
 | |
| {
 | |
| public:
 | |
|   uint prec_increment;
 | |
|   Item_func_div(Item *a,Item *b) :Item_num_op(a,b) {}
 | |
|   longlong int_op() { DBUG_ASSERT(0); return 0; }
 | |
|   double real_op();
 | |
|   my_decimal *decimal_op(my_decimal *);
 | |
|   const char *func_name() const { return "/"; }
 | |
|   void fix_length_and_dec();
 | |
|   void result_precision();
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_int_div :public Item_int_func
 | |
| {
 | |
| public:
 | |
|   Item_func_int_div(Item *a,Item *b) :Item_int_func(a,b)
 | |
|   {}
 | |
|   longlong val_int();
 | |
|   const char *func_name() const { return "DIV"; }
 | |
|   void fix_length_and_dec();
 | |
|   void print(String *str) { print_op(str); }
 | |
|   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_mod :public Item_num_op
 | |
| {
 | |
| public:
 | |
|   Item_func_mod(Item *a,Item *b) :Item_num_op(a,b) {}
 | |
|   longlong int_op();
 | |
|   double real_op();
 | |
|   my_decimal *decimal_op(my_decimal *);
 | |
|   const char *func_name() const { return "%"; }
 | |
|   void result_precision();
 | |
|   void fix_length_and_dec();
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_neg :public Item_func_num1
 | |
| {
 | |
| public:
 | |
|   Item_func_neg(Item *a) :Item_func_num1(a) {}
 | |
|   double real_op();
 | |
|   longlong int_op();
 | |
|   my_decimal *decimal_op(my_decimal *);
 | |
|   const char *func_name() const { return "-"; }
 | |
|   void fix_length_and_dec();
 | |
|   void fix_num_length_and_dec();
 | |
|   uint decimal_precision() const { return args[0]->decimal_precision(); }
 | |
|   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_abs :public Item_func_num1
 | |
| {
 | |
| public:
 | |
|   Item_func_abs(Item *a) :Item_func_num1(a) {}
 | |
|   double real_op();
 | |
|   longlong int_op();
 | |
|   my_decimal *decimal_op(my_decimal *);
 | |
|   const char *func_name() const { return "abs"; }
 | |
|   void fix_length_and_dec();
 | |
|   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
 | |
| };
 | |
| 
 | |
| // A class to handle logarithmic and trigonometric functions
 | |
| 
 | |
| class Item_dec_func :public Item_real_func
 | |
| {
 | |
|  public:
 | |
|   Item_dec_func(Item *a) :Item_real_func(a) {}
 | |
|   Item_dec_func(Item *a,Item *b) :Item_real_func(a,b) {}
 | |
|   void fix_length_and_dec()
 | |
|   {
 | |
|     decimals=NOT_FIXED_DEC; max_length=float_length(decimals);
 | |
|     maybe_null=1;
 | |
|   }
 | |
|   inline double fix_result(double value)
 | |
|   {
 | |
| #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;
 | |
|     return 0.0;
 | |
| #endif
 | |
|   }
 | |
| };
 | |
| 
 | |
| class Item_func_exp :public Item_dec_func
 | |
| {
 | |
| public:
 | |
|   Item_func_exp(Item *a) :Item_dec_func(a) {}
 | |
|   double val_real();
 | |
|   const char *func_name() const { return "exp"; }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_ln :public Item_dec_func
 | |
| {
 | |
| public:
 | |
|   Item_func_ln(Item *a) :Item_dec_func(a) {}
 | |
|   double val_real();
 | |
|   const char *func_name() const { return "ln"; }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_log :public Item_dec_func
 | |
| {
 | |
| public:
 | |
|   Item_func_log(Item *a) :Item_dec_func(a) {}
 | |
|   Item_func_log(Item *a,Item *b) :Item_dec_func(a,b) {}
 | |
|   double val_real();
 | |
|   const char *func_name() const { return "log"; }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_log2 :public Item_dec_func
 | |
| {
 | |
| public:
 | |
|   Item_func_log2(Item *a) :Item_dec_func(a) {}
 | |
|   double val_real();
 | |
|   const char *func_name() const { return "log2"; }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_log10 :public Item_dec_func
 | |
| {
 | |
| public:
 | |
|   Item_func_log10(Item *a) :Item_dec_func(a) {}
 | |
|   double val_real();
 | |
|   const char *func_name() const { return "log10"; }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_sqrt :public Item_dec_func
 | |
| {
 | |
| public:
 | |
|   Item_func_sqrt(Item *a) :Item_dec_func(a) {}
 | |
|   double val_real();
 | |
|   const char *func_name() const { return "sqrt"; }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_pow :public Item_dec_func
 | |
| {
 | |
| public:
 | |
|   Item_func_pow(Item *a,Item *b) :Item_dec_func(a,b) {}
 | |
|   double val_real();
 | |
|   const char *func_name() const { return "pow"; }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_acos :public Item_dec_func
 | |
| {
 | |
| public:
 | |
|   Item_func_acos(Item *a) :Item_dec_func(a) {}
 | |
|   double val_real();
 | |
|   const char *func_name() const { return "acos"; }
 | |
| };
 | |
| 
 | |
| class Item_func_asin :public Item_dec_func
 | |
| {
 | |
| public:
 | |
|   Item_func_asin(Item *a) :Item_dec_func(a) {}
 | |
|   double val_real();
 | |
|   const char *func_name() const { return "asin"; }
 | |
| };
 | |
| 
 | |
| class Item_func_atan :public Item_dec_func
 | |
| {
 | |
| public:
 | |
|   Item_func_atan(Item *a) :Item_dec_func(a) {}
 | |
|   Item_func_atan(Item *a,Item *b) :Item_dec_func(a,b) {}
 | |
|   double val_real();
 | |
|   const char *func_name() const { return "atan"; }
 | |
| };
 | |
| 
 | |
| class Item_func_cos :public Item_dec_func
 | |
| {
 | |
| public:
 | |
|   Item_func_cos(Item *a) :Item_dec_func(a) {}
 | |
|   double val_real();
 | |
|   const char *func_name() const { return "cos"; }
 | |
| };
 | |
| 
 | |
| class Item_func_sin :public Item_dec_func
 | |
| {
 | |
| public:
 | |
|   Item_func_sin(Item *a) :Item_dec_func(a) {}
 | |
|   double val_real();
 | |
|   const char *func_name() const { return "sin"; }
 | |
| };
 | |
| 
 | |
| class Item_func_tan :public Item_dec_func
 | |
| {
 | |
| public:
 | |
|   Item_func_tan(Item *a) :Item_dec_func(a) {}
 | |
|   double val_real();
 | |
|   const char *func_name() const { return "tan"; }
 | |
| };
 | |
| 
 | |
| class Item_func_integer :public Item_int_func
 | |
| {
 | |
| public:
 | |
|   inline Item_func_integer(Item *a) :Item_int_func(a) {}
 | |
|   void fix_length_and_dec();
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_int_val :public Item_func_num1
 | |
| {
 | |
| public:
 | |
|   Item_func_int_val(Item *a) :Item_func_num1(a) {}
 | |
|   void fix_num_length_and_dec();
 | |
|   void find_num_type();
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_ceiling :public Item_func_int_val
 | |
| {
 | |
| public:
 | |
|   Item_func_ceiling(Item *a) :Item_func_int_val(a) {}
 | |
|   const char *func_name() const { return "ceiling"; }
 | |
|   longlong int_op();
 | |
|   double real_op();
 | |
|   my_decimal *decimal_op(my_decimal *);
 | |
|   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_floor :public Item_func_int_val
 | |
| {
 | |
| public:
 | |
|   Item_func_floor(Item *a) :Item_func_int_val(a) {}
 | |
|   const char *func_name() const { return "floor"; }
 | |
|   longlong int_op();
 | |
|   double real_op();
 | |
|   my_decimal *decimal_op(my_decimal *);
 | |
|   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
 | |
| };
 | |
| 
 | |
| /* This handles round and truncate */
 | |
| 
 | |
| class Item_func_round :public Item_func_num1
 | |
| {
 | |
|   bool truncate;
 | |
| public:
 | |
|   Item_func_round(Item *a, Item *b, bool trunc_arg)
 | |
|     :Item_func_num1(a,b), truncate(trunc_arg) {}
 | |
|   const char *func_name() const { return truncate ? "truncate" : "round"; }
 | |
|   double real_op();
 | |
|   longlong int_op();
 | |
|   my_decimal *decimal_op(my_decimal *);
 | |
|   void fix_length_and_dec();
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_rand :public Item_real_func
 | |
| {
 | |
|   struct rand_struct *rand;
 | |
| public:
 | |
|   Item_func_rand(Item *a) :Item_real_func(a), rand(0) {}
 | |
|   Item_func_rand()	  :Item_real_func() {}
 | |
|   double val_real();
 | |
|   const char *func_name() const { return "rand"; }
 | |
|   bool const_item() const { return 0; }
 | |
|   void update_used_tables();
 | |
|   bool fix_fields(THD *thd, Item **ref);
 | |
| private:
 | |
|   void seed_random (Item * val);  
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_sign :public Item_int_func
 | |
| {
 | |
| public:
 | |
|   Item_func_sign(Item *a) :Item_int_func(a) {}
 | |
|   const char *func_name() const { return "sign"; }
 | |
|   longlong val_int();
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_units :public Item_real_func
 | |
| {
 | |
|   char *name;
 | |
|   double mul,add;
 | |
| public:
 | |
|   Item_func_units(char *name_arg,Item *a,double mul_arg,double add_arg)
 | |
|     :Item_real_func(a),name(name_arg),mul(mul_arg),add(add_arg) {}
 | |
|   double val_real();
 | |
|   const char *func_name() const { return name; }
 | |
|   void fix_length_and_dec()
 | |
|   { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_min_max :public Item_func
 | |
| {
 | |
|   Item_result cmp_type;
 | |
|   String tmp_value;
 | |
|   int cmp_sign;
 | |
|   /* TRUE <=> arguments should be compared in the DATETIME context. */
 | |
|   bool compare_as_dates;
 | |
|   /* An item used for issuing warnings while string to DATETIME conversion. */
 | |
|   Item *datetime_item;
 | |
|   THD *thd;
 | |
| 
 | |
| public:
 | |
|   Item_func_min_max(List<Item> &list,int cmp_sign_arg) :Item_func(list),
 | |
|     cmp_type(INT_RESULT), cmp_sign(cmp_sign_arg), compare_as_dates(FALSE),
 | |
|     datetime_item(0) {}
 | |
|   double val_real();
 | |
|   longlong val_int();
 | |
|   String *val_str(String *);
 | |
|   my_decimal *val_decimal(my_decimal *);
 | |
|   void fix_length_and_dec();
 | |
|   enum Item_result result_type () const { return cmp_type; }
 | |
|   bool result_as_longlong() { return compare_as_dates; };
 | |
|   uint cmp_datetimes(ulonglong *value);
 | |
| };
 | |
| 
 | |
| class Item_func_min :public Item_func_min_max
 | |
| {
 | |
| public:
 | |
|   Item_func_min(List<Item> &list) :Item_func_min_max(list,1) {}
 | |
|   const char *func_name() const { return "least"; }
 | |
| };
 | |
| 
 | |
| class Item_func_max :public Item_func_min_max
 | |
| {
 | |
| public:
 | |
|   Item_func_max(List<Item> &list) :Item_func_min_max(list,-1) {}
 | |
|   const char *func_name() const { return "greatest"; }
 | |
| };
 | |
| 
 | |
| 
 | |
| /* 
 | |
|   Objects of this class are used for ROLLUP queries to wrap up 
 | |
|   each constant item referred to in GROUP BY list. 
 | |
| */
 | |
| 
 | |
| class Item_func_rollup_const :public Item_func
 | |
| {
 | |
| public:
 | |
|   Item_func_rollup_const(Item *a) :Item_func(a)
 | |
|   {
 | |
|     name= a->name;
 | |
|     name_length= a->name_length;
 | |
|   }
 | |
|   double val_real() { return args[0]->val_real(); }
 | |
|   longlong val_int() { return args[0]->val_int(); }
 | |
|   String *val_str(String *str) { return args[0]->val_str(str); }
 | |
|   my_decimal *val_decimal(my_decimal *dec) { return args[0]->val_decimal(dec); }
 | |
|   const char *func_name() const { return "rollup_const"; }
 | |
|   bool const_item() const { return 0; }
 | |
|   Item_result result_type() const { return args[0]->result_type(); }
 | |
|   void fix_length_and_dec()
 | |
|   {
 | |
|     collation= args[0]->collation;
 | |
|     max_length= args[0]->max_length;
 | |
|     decimals=args[0]->decimals; 
 | |
|   }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_length :public Item_int_func
 | |
| {
 | |
|   String value;
 | |
| public:
 | |
|   Item_func_length(Item *a) :Item_int_func(a) {}
 | |
|   longlong val_int();
 | |
|   const char *func_name() const { return "length"; }
 | |
|   void fix_length_and_dec() { max_length=10; }
 | |
| };
 | |
| 
 | |
| class Item_func_bit_length :public Item_func_length
 | |
| {
 | |
| public:
 | |
|   Item_func_bit_length(Item *a) :Item_func_length(a) {}
 | |
|   longlong val_int()
 | |
|     { DBUG_ASSERT(fixed == 1); return Item_func_length::val_int()*8; }
 | |
|   const char *func_name() const { return "bit_length"; }
 | |
| };
 | |
| 
 | |
| class Item_func_char_length :public Item_int_func
 | |
| {
 | |
|   String value;
 | |
| public:
 | |
|   Item_func_char_length(Item *a) :Item_int_func(a) {}
 | |
|   longlong val_int();
 | |
|   const char *func_name() const { return "char_length"; }
 | |
|   void fix_length_and_dec() { max_length=10; }
 | |
| };
 | |
| 
 | |
| 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();
 | |
|   void print(String *str);
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_field :public Item_int_func
 | |
| {
 | |
|   String value,tmp;
 | |
|   Item_result cmp_type;
 | |
|   DTCollation cmp_collation;
 | |
| public:
 | |
|   Item_func_field(List<Item> &list) :Item_int_func(list) {}
 | |
|   longlong val_int();
 | |
|   const char *func_name() const { return "field"; }
 | |
|   void fix_length_and_dec();
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_ascii :public Item_int_func
 | |
| {
 | |
|   String value;
 | |
| public:
 | |
|   Item_func_ascii(Item *a) :Item_int_func(a) {}
 | |
|   longlong val_int();
 | |
|   const char *func_name() const { return "ascii"; }
 | |
|   void fix_length_and_dec() { max_length=3; }
 | |
| };
 | |
| 
 | |
| class Item_func_ord :public Item_int_func
 | |
| {
 | |
|   String value;
 | |
| public:
 | |
|   Item_func_ord(Item *a) :Item_int_func(a) {}
 | |
|   longlong val_int();
 | |
|   const char *func_name() const { return "ord"; }
 | |
| };
 | |
| 
 | |
| 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();
 | |
| };
 | |
| 
 | |
| /* Base class for all bit functions: '~', '|', '^', '&', '>>', '<<' */
 | |
| 
 | |
| class Item_func_bit: public Item_int_func
 | |
| {
 | |
| 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
 | |
| {
 | |
| public:
 | |
|   Item_func_bit_or(Item *a, Item *b) :Item_func_bit(a, b) {}
 | |
|   longlong val_int();
 | |
|   const char *func_name() const { return "|"; }
 | |
| };
 | |
| 
 | |
| class Item_func_bit_and :public Item_func_bit
 | |
| {
 | |
| public:
 | |
|   Item_func_bit_and(Item *a, Item *b) :Item_func_bit(a, b) {}
 | |
|   longlong val_int();
 | |
|   const char *func_name() const { return "&"; }
 | |
| };
 | |
| 
 | |
| class Item_func_bit_count :public Item_int_func
 | |
| {
 | |
| public:
 | |
|   Item_func_bit_count(Item *a) :Item_int_func(a) {}
 | |
|   longlong val_int();
 | |
|   const char *func_name() const { return "bit_count"; }
 | |
|   void fix_length_and_dec() { max_length=2; }
 | |
| };
 | |
| 
 | |
| class Item_func_shift_left :public Item_func_bit
 | |
| {
 | |
| public:
 | |
|   Item_func_shift_left(Item *a, Item *b) :Item_func_bit(a, b) {}
 | |
|   longlong val_int();
 | |
|   const char *func_name() const { return "<<"; }
 | |
| };
 | |
| 
 | |
| class Item_func_shift_right :public Item_func_bit
 | |
| {
 | |
| public:
 | |
|   Item_func_shift_right(Item *a, Item *b) :Item_func_bit(a, b) {}
 | |
|   longlong val_int();
 | |
|   const char *func_name() const { return ">>"; }
 | |
| };
 | |
| 
 | |
| class Item_func_bit_neg :public Item_func_bit
 | |
| {
 | |
| 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_last_insert_id :public Item_int_func
 | |
| {
 | |
| public:
 | |
|   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()
 | |
|   {
 | |
|     if (arg_count)
 | |
|       max_length= args[0]->max_length;
 | |
|   }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_benchmark :public Item_int_func
 | |
| {
 | |
| public:
 | |
|   Item_func_benchmark(Item *count_expr, Item *expr)
 | |
|     :Item_int_func(count_expr, expr)
 | |
|   {}
 | |
|   longlong val_int();
 | |
|   const char *func_name() const { return "benchmark"; }
 | |
|   void fix_length_and_dec() { max_length=1; maybe_null=0; }
 | |
|   void print(String *str);
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_sleep :public Item_int_func
 | |
| {
 | |
| public:
 | |
|   Item_func_sleep(Item *a) :Item_int_func(a) {}
 | |
|   bool const_item() const { return 0; }
 | |
|   const char *func_name() const { return "sleep"; }
 | |
|   void update_used_tables()
 | |
|   {
 | |
|     Item_int_func::update_used_tables();
 | |
|     used_tables_cache|= RAND_TABLE_BIT;
 | |
|   }
 | |
|   longlong val_int();
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| #ifdef HAVE_DLOPEN
 | |
| 
 | |
| class Item_udf_func :public Item_func
 | |
| {
 | |
| protected:
 | |
|   udf_handler udf;
 | |
| 
 | |
| 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) {}
 | |
|   const char *func_name() const { return udf.name(); }
 | |
|   enum Functype functype() const   { return UDF_FUNC; }
 | |
|   bool fix_fields(THD *thd, Item **ref)
 | |
|   {
 | |
|     DBUG_ASSERT(fixed == 0);
 | |
|     bool res= udf.fix_fields(thd, 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; }
 | |
|   bool is_expensive() { return 1; }
 | |
|   void print(String *str);
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_udf_float :public Item_udf_func
 | |
| {
 | |
|  public:
 | |
|   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) {}
 | |
|   longlong val_int()
 | |
|   {
 | |
|     DBUG_ASSERT(fixed == 1);
 | |
|     return (longlong) rint(Item_func_udf_float::val_real());
 | |
|   }
 | |
|   my_decimal *val_decimal(my_decimal *dec_buf)
 | |
|   {
 | |
|     double res=val_real();
 | |
|     if (null_value)
 | |
|       return NULL;
 | |
|     double2my_decimal(E_DEC_FATAL_ERROR, res, dec_buf);
 | |
|     return dec_buf;
 | |
|   }
 | |
|   double val_real();
 | |
|   String *val_str(String *str);
 | |
|   void fix_length_and_dec() { fix_num_length_and_dec(); }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_udf_int :public Item_udf_func
 | |
| {
 | |
| 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) {}
 | |
|   longlong val_int();
 | |
|   double val_real() { return (double) Item_func_udf_int::val_int(); }
 | |
|   String *val_str(String *str);
 | |
|   enum Item_result result_type () const { return INT_RESULT; }
 | |
|   void fix_length_and_dec() { decimals= 0; max_length= 21; }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_udf_decimal :public Item_udf_func
 | |
| {
 | |
| public:
 | |
|   Item_func_udf_decimal(udf_func *udf_arg)
 | |
|     :Item_udf_func(udf_arg) {}
 | |
|   Item_func_udf_decimal(udf_func *udf_arg, List<Item> &list)
 | |
|     :Item_udf_func(udf_arg, list) {}
 | |
|   longlong val_int();
 | |
|   double val_real();
 | |
|   my_decimal *val_decimal(my_decimal *);
 | |
|   String *val_str(String *str);
 | |
|   enum Item_result result_type () const { return DECIMAL_RESULT; }
 | |
|   void fix_length_and_dec();
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_udf_str :public Item_udf_func
 | |
| {
 | |
| 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) {}
 | |
|   String *val_str(String *);
 | |
|   double val_real()
 | |
|   {
 | |
|     int err_not_used;
 | |
|     char *end_not_used;
 | |
|     String *res;
 | |
|     res= val_str(&str_value);
 | |
|     return res ? my_strntod(res->charset(),(char*) res->ptr(), 
 | |
|                             res->length(), &end_not_used, &err_not_used) : 0.0;
 | |
|   }
 | |
|   longlong val_int()
 | |
|   {
 | |
|     int err_not_used;
 | |
|     String *res;  res=val_str(&str_value);
 | |
|     return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10,
 | |
|                              (char**) 0, &err_not_used) : (longlong) 0;
 | |
|   }
 | |
|   my_decimal *val_decimal(my_decimal *dec_buf)
 | |
|   {
 | |
|     String *res=val_str(&str_value);
 | |
|     if (!res)
 | |
|       return NULL;
 | |
|     string2my_decimal(E_DEC_FATAL_ERROR, res, dec_buf);
 | |
|     return dec_buf;
 | |
|   }
 | |
|   enum Item_result result_type () const { return STRING_RESULT; }
 | |
|   void fix_length_and_dec();
 | |
| };
 | |
| 
 | |
| #else /* Dummy functions to get sql_yacc.cc compiled */
 | |
| 
 | |
| 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) {}
 | |
|   double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; }
 | |
| };
 | |
| 
 | |
| 
 | |
| 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) {}
 | |
|   longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_udf_decimal :public Item_int_func
 | |
| {
 | |
| public:
 | |
|   Item_func_udf_decimal(udf_func *udf_arg)
 | |
|     :Item_int_func() {}
 | |
|   Item_func_udf_decimal(udf_func *udf_arg, List<Item> &list)
 | |
|     :Item_int_func(list) {}
 | |
|   my_decimal *val_decimal(my_decimal *) { DBUG_ASSERT(fixed == 1); return 0; }
 | |
| };
 | |
| 
 | |
| 
 | |
| 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) {}
 | |
|   String *val_str(String *)
 | |
|     { DBUG_ASSERT(fixed == 1); null_value=1; return 0; }
 | |
|   double val_real() { 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; }
 | |
| };
 | |
| 
 | |
| #endif /* HAVE_DLOPEN */
 | |
| 
 | |
| /*
 | |
| ** User level locks
 | |
| */
 | |
| 
 | |
| class User_level_lock;
 | |
| void item_user_lock_init(void);
 | |
| void item_user_lock_release(User_level_lock *ull);
 | |
| void item_user_lock_free(void);
 | |
| 
 | |
| class Item_func_get_lock :public Item_int_func
 | |
| {
 | |
|   String value;
 | |
|  public:
 | |
|   Item_func_get_lock(Item *a,Item *b) :Item_int_func(a,b) {}
 | |
|   longlong val_int();
 | |
|   const char *func_name() const { return "get_lock"; }
 | |
|   void fix_length_and_dec() { max_length=1; maybe_null=1;}
 | |
| };
 | |
| 
 | |
| class Item_func_release_lock :public Item_int_func
 | |
| {
 | |
|   String value;
 | |
| public:
 | |
|   Item_func_release_lock(Item *a) :Item_int_func(a) {}
 | |
|   longlong val_int();
 | |
|   const char *func_name() const { return "release_lock"; }
 | |
|   void fix_length_and_dec() { max_length=1; maybe_null=1;}
 | |
| };
 | |
| 
 | |
| /* replication functions */
 | |
| 
 | |
| class Item_master_pos_wait :public Item_int_func
 | |
| {
 | |
|   String value;
 | |
| public:
 | |
|   Item_master_pos_wait(Item *a,Item *b) :Item_int_func(a,b) {}
 | |
|   Item_master_pos_wait(Item *a,Item *b,Item *c) :Item_int_func(a,b,c) {}
 | |
|   longlong val_int();
 | |
|   const char *func_name() const { return "master_pos_wait"; }
 | |
|   void fix_length_and_dec() { max_length=21; maybe_null=1;}
 | |
| };
 | |
| 
 | |
| 
 | |
| /* Handling of user definable variables */
 | |
| 
 | |
| class user_var_entry;
 | |
| 
 | |
| class Item_func_set_user_var :public Item_func
 | |
| {
 | |
|   enum Item_result cached_result_type;
 | |
|   user_var_entry *entry;
 | |
|   char buffer[MAX_FIELD_WIDTH];
 | |
|   String value;
 | |
|   my_decimal decimal_buff;
 | |
|   bool null_item;
 | |
|   union
 | |
|   {
 | |
|     longlong vint;
 | |
|     double vreal;
 | |
|     String *vstr;
 | |
|     my_decimal *vdec;
 | |
|   } save_result;
 | |
| 
 | |
| public:
 | |
|   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)
 | |
|   {}
 | |
|   enum Functype functype() const { return SUSERVAR_FUNC; }
 | |
|   double val_real();
 | |
|   longlong val_int();
 | |
|   String *val_str(String *str);
 | |
|   my_decimal *val_decimal(my_decimal *);
 | |
|   double val_result();
 | |
|   longlong val_int_result();
 | |
|   String *str_result(String *str);
 | |
|   my_decimal *val_decimal_result(my_decimal *);
 | |
|   bool update_hash(void *ptr, uint length, enum Item_result type,
 | |
|   		   CHARSET_INFO *cs, Derivation dv, bool unsigned_arg);
 | |
|   bool send(Protocol *protocol, String *str_arg);
 | |
|   void make_field(Send_field *tmp_field);
 | |
|   bool check(bool use_result_field);
 | |
|   bool update();
 | |
|   enum Item_result result_type () const { return cached_result_type; }
 | |
|   bool fix_fields(THD *thd, Item **ref);
 | |
|   void fix_length_and_dec();
 | |
|   void print(String *str);
 | |
|   void print_as_stmt(String *str);
 | |
|   const char *func_name() const { return "set_user_var"; }
 | |
|   int save_in_field(Field *field, bool no_conversions,
 | |
|                     bool can_use_result_field);
 | |
|   int save_in_field(Field *field, bool no_conversions)
 | |
|   {
 | |
|     return save_in_field(field, no_conversions, 1);
 | |
|   }
 | |
|   void save_org_in_field(Field *field) { (void)save_in_field(field, 1, 0); }
 | |
|   bool register_field_in_read_map(uchar *arg);
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_get_user_var :public Item_func,
 | |
|                               private Settable_routine_parameter
 | |
| {
 | |
|   user_var_entry *var_entry;
 | |
|   Item_result m_cached_result_type;
 | |
| 
 | |
| public:
 | |
|   LEX_STRING name; // keep it public
 | |
|   Item_func_get_user_var(LEX_STRING a):
 | |
|     Item_func(), m_cached_result_type(STRING_RESULT), name(a) {}
 | |
|   enum Functype functype() const { return GUSERVAR_FUNC; }
 | |
|   LEX_STRING get_name() { return name; }
 | |
|   double val_real();
 | |
|   longlong val_int();
 | |
|   my_decimal *val_decimal(my_decimal*);
 | |
|   String *val_str(String* str);
 | |
|   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)
 | |
|   */
 | |
|   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;
 | |
| private:
 | |
|   bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
 | |
| 
 | |
| public:
 | |
|   Settable_routine_parameter *get_settable_routine_parameter()
 | |
|   {
 | |
|     return this;
 | |
|   }
 | |
| };
 | |
| 
 | |
| 
 | |
| /*
 | |
|   This item represents user variable used as out parameter (e.g in LOAD DATA),
 | |
|   and it is supposed to be used only for this purprose. So it is simplified
 | |
|   a lot. Actually you should never obtain its value.
 | |
| 
 | |
|   The only two reasons for this thing being an Item is possibility to store it
 | |
|   in List<Item> and desire to place this code somewhere near other functions
 | |
|   working with user variables.
 | |
| */
 | |
| class Item_user_var_as_out_param :public Item
 | |
| {
 | |
|   LEX_STRING name;
 | |
|   user_var_entry *entry;
 | |
| public:
 | |
|   Item_user_var_as_out_param(LEX_STRING a) : name(a) {}
 | |
|   /* We should return something different from FIELD_ITEM here */
 | |
|   enum Type type() const { return STRING_ITEM;}
 | |
|   double val_real();
 | |
|   longlong val_int();
 | |
|   String *val_str(String *str);
 | |
|   my_decimal *val_decimal(my_decimal *decimal_buffer);
 | |
|   /* fix_fields() binds variable name with its entry structure */
 | |
|   bool fix_fields(THD *thd, Item **ref);
 | |
|   void print(String *str);
 | |
|   void set_null_value(CHARSET_INFO* cs);
 | |
|   void set_value(const char *str, uint length, CHARSET_INFO* cs);
 | |
| };
 | |
| 
 | |
| 
 | |
| /* 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, Item **ref);
 | |
|   /*
 | |
|     Stubs for pure virtual methods. Should never be called: this
 | |
|     item is always substituted with a constant in fix_fields().
 | |
|   */
 | |
|   double val_real()         { 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); }
 | |
|   /* TODO: fix to support views */
 | |
|   const char *func_name() const { return "get_system_var"; }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_inet_aton : public Item_int_func
 | |
| {
 | |
| public:
 | |
|   Item_func_inet_aton(Item *a) :Item_int_func(a) {}
 | |
|   longlong val_int();
 | |
|   const char *func_name() const { return "inet_aton"; }
 | |
|   void fix_length_and_dec() { decimals= 0; max_length= 21; maybe_null= 1; unsigned_flag= 1;}
 | |
| };
 | |
| 
 | |
| 
 | |
| /* for fulltext search */
 | |
| #include <ft_global.h>
 | |
| 
 | |
| class Item_func_match :public Item_real_func
 | |
| {
 | |
| public:
 | |
|   uint key, flags;
 | |
|   bool join_key;
 | |
|   DTCollation cmp_collation;
 | |
|   FT_INFO *ft_handler;
 | |
|   TABLE *table;
 | |
|   Item_func_match *master;   // for master-slave optimization
 | |
|   Item *concat_ws;           // Item_func_concat_ws
 | |
|   String value;              // value of concat_ws
 | |
|   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_ws(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;
 | |
|     concat_ws= 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, Item **ref);
 | |
|   bool eq(const Item *, bool binary_cmp) const;
 | |
|   /* The following should be safe, even if we compare doubles */
 | |
|   longlong val_int() { DBUG_ASSERT(fixed == 1); return val_real() != 0.0; }
 | |
|   double val_real();
 | |
|   void print(String *str);
 | |
| 
 | |
|   bool fix_index();
 | |
|   void init_search(bool no_order);
 | |
| };
 | |
| 
 | |
| 
 | |
| 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
 | |
| {
 | |
|   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_is_used_lock :public Item_int_func
 | |
| {
 | |
|   String value;
 | |
| public:
 | |
|   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 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_CAST_DECIMAL
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_row_count :public Item_int_func
 | |
| {
 | |
| public:
 | |
|   Item_func_row_count() :Item_int_func() {}
 | |
|   longlong val_int();
 | |
|   const char *func_name() const { return "row_count"; }
 | |
|   void fix_length_and_dec() { decimals= 0; maybe_null=0; }
 | |
| };
 | |
| 
 | |
| 
 | |
| /*
 | |
|  *
 | |
|  * Stored FUNCTIONs
 | |
|  *
 | |
|  */
 | |
| 
 | |
| class sp_head;
 | |
| class sp_name;
 | |
| struct st_sp_security_context;
 | |
| 
 | |
| class Item_func_sp :public Item_func
 | |
| {
 | |
| private:
 | |
|   Name_resolution_context *context;
 | |
|   sp_name *m_name;
 | |
|   mutable sp_head *m_sp;
 | |
|   TABLE *dummy_table;
 | |
|   uchar result_buf[64];
 | |
|   /*
 | |
|      The result field of the concrete stored function.
 | |
|   */
 | |
|   Field *sp_result_field;
 | |
| 
 | |
|   bool execute();
 | |
|   bool execute_impl(THD *thd);
 | |
|   bool init_result_field(THD *thd);
 | |
|   
 | |
| public:
 | |
| 
 | |
|   Item_func_sp(Name_resolution_context *context_arg, sp_name *name);
 | |
| 
 | |
|   Item_func_sp(Name_resolution_context *context_arg,
 | |
|                sp_name *name, List<Item> &list);
 | |
| 
 | |
|   virtual ~Item_func_sp()
 | |
|   {}
 | |
| 
 | |
|   void update_used_tables();
 | |
| 
 | |
|   void cleanup();
 | |
| 
 | |
|   const char *func_name() const;
 | |
| 
 | |
|   enum enum_field_types field_type() const;
 | |
| 
 | |
|   Field *tmp_table_field(TABLE *t_arg);
 | |
| 
 | |
|   void make_field(Send_field *tmp_field);
 | |
| 
 | |
|   Item_result result_type() const;
 | |
| 
 | |
|   longlong val_int()
 | |
|   {
 | |
|     if (execute())
 | |
|       return (longlong) 0;
 | |
|     return sp_result_field->val_int();
 | |
|   }
 | |
| 
 | |
|   double val_real()
 | |
|   {
 | |
|     if (execute())
 | |
|       return 0.0;
 | |
|     return sp_result_field->val_real();
 | |
|   }
 | |
| 
 | |
|   my_decimal *val_decimal(my_decimal *dec_buf)
 | |
|   {
 | |
|     if (execute())
 | |
|       return NULL;
 | |
|     return sp_result_field->val_decimal(dec_buf);
 | |
|   }
 | |
| 
 | |
|   String *val_str(String *str)
 | |
|   {
 | |
|     String buf;
 | |
|     char buff[20];
 | |
|     buf.set(buff, 20, str->charset());
 | |
|     buf.length(0);
 | |
|     if (execute())
 | |
|       return NULL;
 | |
|     /*
 | |
|       result_field will set buf pointing to internal buffer
 | |
|       of the resul_field. Due to this it will change any time
 | |
|       when SP is executed. In order to prevent occasional
 | |
|       corruption of returned value, we make here a copy.
 | |
|     */
 | |
|     sp_result_field->val_str(&buf);
 | |
|     str->copy(buf);
 | |
|     return str;
 | |
|   }
 | |
| 
 | |
|   virtual bool change_context_processor(uchar *cntx)
 | |
|     { context= (Name_resolution_context *)cntx; return FALSE; }
 | |
| 
 | |
|   bool sp_check_access(THD * thd);
 | |
|   virtual enum Functype functype() const { return FUNC_SP; }
 | |
| 
 | |
|   bool fix_fields(THD *thd, Item **ref);
 | |
|   void fix_length_and_dec(void);
 | |
|   bool is_expensive() { return 1; }
 | |
| 
 | |
|   inline Field *get_sp_result_field()
 | |
|   {
 | |
|     return sp_result_field;
 | |
|   }
 | |
| };
 | |
| 
 | |
| 
 | |
| class Item_func_found_rows :public Item_int_func
 | |
| {
 | |
| public:
 | |
|   Item_func_found_rows() :Item_int_func() {}
 | |
|   longlong val_int();
 | |
|   const char *func_name() const { return "found_rows"; }
 | |
|   void fix_length_and_dec() { decimals= 0; maybe_null=0; }
 | |
| };
 | |
| 
 | |
| 
 | |
| void uuid_short_init();
 | |
| 
 | |
| class Item_func_uuid_short :public Item_int_func
 | |
| {
 | |
| public:
 | |
|   Item_func_uuid_short() :Item_int_func() {}
 | |
|   const char *func_name() const { return "uuid_short"; }
 | |
|   longlong val_int();
 | |
|   void fix_length_and_dec()
 | |
|   { max_length= 21; unsigned_flag=1; }
 | |
|   bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
 | |
| };
 | |
| 
 |