1 #ifndef PROCEDURE_INCLUDED
2 #define PROCEDURE_INCLUDED
3 
4 /* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; version 2 of the License.
9 
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335  USA */
18 
19 /* When using sql procedures */
20 
21 #ifdef USE_PRAGMA_INTERFACE
22 #pragma interface				/* gcc class implementation */
23 #endif
24 
25 /*
26   It is necessary to include set_var.h instead of item.h because there
27   are dependencies on include order for set_var.h and item.h. This
28   will be resolved later.
29 */
30 #include "sql_class.h"                          /* select_result, set_var.h: THD */
31 #include "set_var.h"                            /* Item */
32 
33 #define PROC_NO_SORT 1				/**< Bits in flags */
34 #define PROC_GROUP   2				/**< proc must have group */
35 
36 /* Procedure items used by procedures to store values for send_result_set_metadata */
37 
38 class Item_proc :public Item
39 {
40 public:
Item_proc(THD * thd,const char * name_par)41   Item_proc(THD *thd, const char *name_par): Item(thd)
42   {
43      this->name.str=    name_par;
44      this->name.length= strlen(name_par);
45   }
type()46   enum Type type() const { return Item::PROC_ITEM; }
create_tmp_field_ex(TABLE * table,Tmp_field_src * src,const Tmp_field_param * param)47   Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src,
48                              const Tmp_field_param *param)
49   {
50     /*
51       We can get to here when using a CURSOR for a query with PROCEDURE:
52         DECLARE c CURSOR FOR SELECT * FROM t1 PROCEDURE analyse();
53         OPEN c;
54     */
55     return create_tmp_field_ex_simple(table, src, param);
56   }
57   virtual void set(double nr)=0;
58   virtual void set(const char *str,uint length,CHARSET_INFO *cs)=0;
59   virtual void set(longlong nr)=0;
60   const Type_handler *type_handler() const=0;
set(const char * str)61   void set(const char *str) { set(str,(uint) strlen(str), default_charset()); }
size_of()62   unsigned int size_of() { return sizeof(*this);}
check_vcol_func_processor(void * arg)63   bool check_vcol_func_processor(void *arg)
64   {
65     DBUG_ASSERT(0); // impossible
66     return mark_unsupported_function("proc", arg, VCOL_IMPOSSIBLE);
67   }
get_date(THD * thd,MYSQL_TIME * ltime,date_mode_t fuzzydate)68   bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
69   {
70     return type_handler()->Item_get_date_with_warn(thd, this, ltime, fuzzydate);
71   }
get_copy(THD * thd)72   Item* get_copy(THD *thd) { return 0; }
73 };
74 
75 class Item_proc_real :public Item_proc
76 {
77   double value;
78 public:
Item_proc_real(THD * thd,const char * name_par,uint dec)79   Item_proc_real(THD *thd, const char *name_par, uint dec):
80     Item_proc(thd, name_par)
81   {
82      decimals=dec; max_length=float_length(dec);
83   }
type_handler()84   const Type_handler *type_handler() const { return &type_handler_double; }
set(double nr)85   void set(double nr) { value=nr; }
set(longlong nr)86   void set(longlong nr) { value=(double) nr; }
set(const char * str,uint length,CHARSET_INFO * cs)87   void set(const char *str,uint length,CHARSET_INFO *cs)
88   {
89     int err_not_used;
90     char *end_not_used;
91     value= my_strntod(cs,(char*) str,length, &end_not_used, &err_not_used);
92   }
val_real()93   double val_real() { return value; }
val_int()94   longlong val_int() { return (longlong) value; }
val_str(String * s)95   String *val_str(String *s)
96   {
97     s->set_real(value,decimals,default_charset());
98     return s;
99   }
100   my_decimal *val_decimal(my_decimal *);
size_of()101   unsigned int size_of() { return sizeof(*this);}
102 };
103 
104 class Item_proc_int :public Item_proc
105 {
106   longlong value;
107 public:
Item_proc_int(THD * thd,const char * name_par)108   Item_proc_int(THD *thd, const char *name_par): Item_proc(thd, name_par)
109   { max_length=11; }
type_handler()110   const Type_handler *type_handler() const { return &type_handler_longlong; }
set(double nr)111   void set(double nr) { value=(longlong) nr; }
set(longlong nr)112   void set(longlong nr) { value=nr; }
set(const char * str,uint length,CHARSET_INFO * cs)113   void set(const char *str,uint length, CHARSET_INFO *cs)
114   { int err; value=my_strntoll(cs,str,length,10,NULL,&err); }
val_real()115   double val_real() { return (double) value; }
val_int()116   longlong val_int() { return value; }
val_str(String * s)117   String *val_str(String *s) { s->set(value, default_charset()); return s; }
118   my_decimal *val_decimal(my_decimal *);
size_of()119   unsigned int size_of() { return sizeof(*this);}
120 };
121 
122 
123 class Item_proc_string :public Item_proc
124 {
125 public:
Item_proc_string(THD * thd,const char * name_par,uint length)126   Item_proc_string(THD *thd, const char *name_par, uint length):
127     Item_proc(thd, name_par) { this->max_length=length; }
type_handler()128   const Type_handler *type_handler() const { return &type_handler_varchar; }
set(double nr)129   void set(double nr) { str_value.set_real(nr, 2, default_charset()); }
set(longlong nr)130   void set(longlong nr) { str_value.set(nr, default_charset()); }
set(const char * str,uint length,CHARSET_INFO * cs)131   void set(const char *str, uint length, CHARSET_INFO *cs)
132   { str_value.copy(str,length,cs); }
val_real()133   double val_real()
134   {
135     int err_not_used;
136     char *end_not_used;
137     CHARSET_INFO *cs= str_value.charset();
138     return my_strntod(cs, (char*) str_value.ptr(), str_value.length(),
139 		      &end_not_used, &err_not_used);
140   }
val_int()141   longlong val_int()
142   {
143     int err;
144     CHARSET_INFO *cs=str_value.charset();
145     return my_strntoll(cs,str_value.ptr(),str_value.length(),10,NULL,&err);
146   }
val_str(String *)147   String *val_str(String*)
148   {
149     return null_value ? (String*) 0 : (String*) &str_value;
150   }
151   my_decimal *val_decimal(my_decimal *);
size_of()152   unsigned int size_of() { return sizeof(*this);}
153 };
154 
155 /* The procedure class definitions */
156 
157 class Procedure {
158 protected:
159   List<Item> *fields;
160   select_result *result;
161 public:
162   const uint flags;
163   ORDER *group,*param_fields;
Procedure(select_result * res,uint flags_par)164   Procedure(select_result *res,uint flags_par) :result(res),flags(flags_par),
165     group(0),param_fields(0) {}
~Procedure()166   virtual ~Procedure() {group=param_fields=0; fields=0; }
167   virtual void add(void)=0;
168   virtual void end_group(void)=0;
169   virtual int send_row(List<Item> &fields)=0;
170   virtual bool change_columns(THD *thd, List<Item> &fields)= 0;
update_refs(void)171   virtual void update_refs(void) {}
end_of_records()172   virtual int end_of_records() { return 0; }
173 };
174 
175 Procedure *setup_procedure(THD *thd,ORDER *proc_param,select_result *result,
176 			   List<Item> &field_list,int *error);
177 
178 #endif /* PROCEDURE_INCLUDED */
179