1 #ifndef PROTOCOL_INCLUDED
2 #define PROTOCOL_INCLUDED
3 
4 /* Copyright (c) 2002, 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 #ifdef USE_PRAGMA_INTERFACE
20 #pragma interface			/* gcc class implementation */
21 #endif
22 
23 #include "sql_error.h"
24 #include "my_decimal.h"                         /* my_decimal */
25 #include "sql_type.h"
26 
27 class i_string;
28 class Field;
29 class Send_field;
30 class THD;
31 class Item_param;
32 struct TABLE_LIST;
33 typedef struct st_mysql_field MYSQL_FIELD;
34 typedef struct st_mysql_rows MYSQL_ROWS;
35 
36 class Protocol
37 {
38 protected:
39   String *packet;
40   /* Used by net_store_data() for charset conversions */
41   String *convert;
42   uint field_pos;
43 #ifndef DBUG_OFF
44   const Type_handler **field_handlers;
valid_handler(uint pos,protocol_send_type_t type)45   bool valid_handler(uint pos, protocol_send_type_t type) const
46   {
47     return field_handlers == 0 ||
48            field_handlers[field_pos]->protocol_send_type() == type;
49   }
50 #endif
51   uint field_count;
52 #ifndef EMBEDDED_LIBRARY
53   bool net_store_data(const uchar *from, size_t length);
54   bool net_store_data_cs(const uchar *from, size_t length,
55                       CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
56 #else
57   virtual bool net_store_data(const uchar *from, size_t length);
58   virtual bool net_store_data_cs(const uchar *from, size_t length,
59                       CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
60   char **next_field;
61   MYSQL_FIELD *next_mysql_field;
62   MEM_ROOT *alloc;
63 #endif
64   /*
65     The following two are low-level functions that are invoked from
66     higher-level store_xxx() funcs.  The data is stored into this->packet.
67   */
68   bool store_string_aux(const char *from, size_t length,
69                         CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
70 
71   virtual bool send_ok(uint server_status, uint statement_warn_count,
72                        ulonglong affected_rows, ulonglong last_insert_id,
73                        const char *message, bool skip_flush);
74 
75   virtual bool send_eof(uint server_status, uint statement_warn_count);
76 
77   virtual bool send_error(uint sql_errno, const char *err_msg,
78                           const char *sql_state);
79 
80 public:
81   THD	 *thd;
Protocol(THD * thd_arg)82   Protocol(THD *thd_arg) { init(thd_arg); }
~Protocol()83   virtual ~Protocol() {}
84   void init(THD* thd_arg);
85 
86   enum { SEND_NUM_ROWS= 1, SEND_EOF= 2 };
87   virtual bool send_result_set_metadata(List<Item> *list, uint flags);
88   bool send_list_fields(List<Field> *list, const TABLE_LIST *table_list);
89   bool send_result_set_row(List<Item> *row_items);
90 
91   bool store(I_List<i_string> *str_list);
92   bool store(const char *from, CHARSET_INFO *cs);
storage_packet()93   String *storage_packet() { return packet; }
free()94   inline void free() { packet->free(); }
95   virtual bool write();
store(int from)96   inline  bool store(int from)
97   { return store_long((longlong) from); }
store(uint32 from)98   inline  bool store(uint32 from)
99   { return store_long((longlong) from); }
store(longlong from)100   inline  bool store(longlong from)
101   { return store_longlong((longlong) from, 0); }
store(ulonglong from)102   inline  bool store(ulonglong from)
103   { return store_longlong((longlong) from, 1); }
store(String * str)104   inline bool store(String *str)
105   { return store((char*) str->ptr(), str->length(), str->charset()); }
106 
prepare_for_send(uint num_columns)107   virtual bool prepare_for_send(uint num_columns)
108   {
109     field_count= num_columns;
110     return 0;
111   }
112   virtual bool flush();
113   virtual void end_partial_result_set(THD *thd);
114   virtual void prepare_for_resend()=0;
115 
116   virtual bool store_null()=0;
117   virtual bool store_tiny(longlong from)=0;
118   virtual bool store_short(longlong from)=0;
119   virtual bool store_long(longlong from)=0;
120   virtual bool store_longlong(longlong from, bool unsigned_flag)=0;
121   virtual bool store_decimal(const my_decimal *)=0;
122   virtual bool store(const char *from, size_t length, CHARSET_INFO *cs)=0;
123   virtual bool store(const char *from, size_t length,
124   		     CHARSET_INFO *fromcs, CHARSET_INFO *tocs)=0;
store_str(const char * s,CHARSET_INFO * fromcs,CHARSET_INFO * tocs)125   bool store_str(const char *s, CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
126   {
127     DBUG_ASSERT(s);
128     return store(s, (uint) strlen(s), fromcs, tocs);
129   }
store_str(const LEX_CSTRING & s,CHARSET_INFO * fromcs,CHARSET_INFO * tocs)130   bool store_str(const LEX_CSTRING &s, CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
131   {
132     return store(s.str, (uint) s.length, fromcs, tocs);
133   }
134   virtual bool store(float from, uint32 decimals, String *buffer)=0;
135   virtual bool store(double from, uint32 decimals, String *buffer)=0;
136   virtual bool store(MYSQL_TIME *time, int decimals)=0;
137   virtual bool store_date(MYSQL_TIME *time)=0;
138   virtual bool store_time(MYSQL_TIME *time, int decimals)=0;
139   virtual bool store(Field *field)=0;
140 
141   virtual bool send_out_parameters(List<Item_param> *sp_params)=0;
142 #ifdef EMBEDDED_LIBRARY
143   bool begin_dataset();
144   bool begin_dataset(THD *thd, uint numfields);
remove_last_row()145   virtual void remove_last_row() {}
146 #else
remove_last_row()147   void remove_last_row() {}
148 #endif
149   enum enum_protocol_type
150   {
151     /*
152       Before adding a new type, please make sure
153       there is enough storage for it in Query_cache_query_flags.
154     */
155     PROTOCOL_TEXT= 0, PROTOCOL_BINARY= 1, PROTOCOL_LOCAL= 2
156   };
157   virtual enum enum_protocol_type type()= 0;
158 
159   void end_statement();
160 
161   friend int send_answer_1(Protocol *protocol, String *s1, String *s2,
162                            String *s3);
163   friend int send_header_2(Protocol *protocol, bool for_category);
164 };
165 
166 
167 /** Class used for the old (MySQL 4.0 protocol). */
168 
169 class Protocol_text :public Protocol
170 {
171 public:
172   Protocol_text(THD *thd_arg, ulong prealloc= 0)
Protocol(thd_arg)173    :Protocol(thd_arg)
174   {
175     if (prealloc)
176       packet->alloc(prealloc);
177   }
178   virtual void prepare_for_resend();
179   virtual bool store_null();
180   virtual bool store_tiny(longlong from);
181   virtual bool store_short(longlong from);
182   virtual bool store_long(longlong from);
183   virtual bool store_longlong(longlong from, bool unsigned_flag);
184   virtual bool store_decimal(const my_decimal *);
185   virtual bool store(const char *from, size_t length, CHARSET_INFO *cs);
186   virtual bool store(const char *from, size_t length,
187   		     CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
188   virtual bool store(MYSQL_TIME *time, int decimals);
189   virtual bool store_date(MYSQL_TIME *time);
190   virtual bool store_time(MYSQL_TIME *time, int decimals);
191   virtual bool store(float nr, uint32 decimals, String *buffer);
192   virtual bool store(double from, uint32 decimals, String *buffer);
193   virtual bool store(Field *field);
194 
195   virtual bool send_out_parameters(List<Item_param> *sp_params);
196 #ifdef EMBEDDED_LIBRARY
197   void remove_last_row();
198 #endif
199   bool store_field_metadata(const THD *thd, const Send_field &field,
200                             CHARSET_INFO *charset_for_protocol,
201                             uint pos);
202   bool store_field_metadata(THD *thd, Item *item, uint pos);
203   bool store_field_metadata_for_list_fields(const THD *thd, Field *field,
204                                             const TABLE_LIST *table_list,
205                                             uint pos);
type()206   virtual enum enum_protocol_type type() { return PROTOCOL_TEXT; };
207 };
208 
209 
210 class Protocol_binary :public Protocol
211 {
212 private:
213   uint bit_fields;
214 public:
Protocol_binary(THD * thd_arg)215   Protocol_binary(THD *thd_arg) :Protocol(thd_arg) {}
216   virtual bool prepare_for_send(uint num_columns);
217   virtual void prepare_for_resend();
218 #ifdef EMBEDDED_LIBRARY
219   virtual bool write();
220   bool net_store_data(const uchar *from, size_t length);
221   bool net_store_data_cs(const uchar *from, size_t length,
222                       CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
223 #endif
224   virtual bool store_null();
225   virtual bool store_tiny(longlong from);
226   virtual bool store_short(longlong from);
227   virtual bool store_long(longlong from);
228   virtual bool store_longlong(longlong from, bool unsigned_flag);
229   virtual bool store_decimal(const my_decimal *);
230   virtual bool store(const char *from, size_t length, CHARSET_INFO *cs);
231   virtual bool store(const char *from, size_t length,
232   		     CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
233   virtual bool store(MYSQL_TIME *time, int decimals);
234   virtual bool store_date(MYSQL_TIME *time);
235   virtual bool store_time(MYSQL_TIME *time, int decimals);
236   virtual bool store(float nr, uint32 decimals, String *buffer);
237   virtual bool store(double from, uint32 decimals, String *buffer);
238   virtual bool store(Field *field);
239 
240   virtual bool send_out_parameters(List<Item_param> *sp_params);
241 
type()242   virtual enum enum_protocol_type type() { return PROTOCOL_BINARY; };
243 };
244 
245 
246 /*
247   A helper for "ANALYZE $stmt" which looks a real network procotol but doesn't
248   write results to the network.
249 
250   At first glance, class select_send looks like a more appropriate place to
251   implement the "write nothing" hook. This is not true, because
252     - we need to evaluate the value of every item, and do it the way
253       select_send does it (i.e. call item->val_int() or val_real() or...)
254     - select_send::send_data() has some other code, like telling the storage
255       engine that the row can be unlocked. We want to keep that also.
256   as a result, "ANALYZE $stmt" uses a select_send_analyze which still uses
257   select_send::send_data() & co., and also uses  Protocol_discard object.
258 */
259 
260 class Protocol_discard : public Protocol_text
261 {
262 public:
Protocol_discard(THD * thd_arg)263   Protocol_discard(THD *thd_arg) : Protocol_text(thd_arg) {}
write()264   bool write() { return 0; }
send_result_set_metadata(List<Item> *,uint)265   bool send_result_set_metadata(List<Item> *, uint) { return 0; }
send_eof(uint,uint)266   bool send_eof(uint, uint) { return 0; }
prepare_for_resend()267   void prepare_for_resend() { IF_DBUG(field_pos= 0,); }
268 
269   /*
270     Provide dummy overrides for any storage methods so that we
271     avoid allocating and copying of data
272   */
store_null()273   bool store_null() { return false; }
store_tiny(longlong)274   bool store_tiny(longlong) { return false; }
store_short(longlong)275   bool store_short(longlong) { return false; }
store_long(longlong)276   bool store_long(longlong) { return false; }
store_longlong(longlong,bool)277   bool store_longlong(longlong, bool) { return false; }
store_decimal(const my_decimal *)278   bool store_decimal(const my_decimal *) { return false; }
store(const char *,size_t,CHARSET_INFO *)279   bool store(const char *, size_t, CHARSET_INFO *) { return false; }
store(const char *,size_t,CHARSET_INFO *,CHARSET_INFO *)280   bool store(const char *, size_t, CHARSET_INFO *, CHARSET_INFO *) { return false; }
store(MYSQL_TIME *,int)281   bool store(MYSQL_TIME *, int) { return false; }
store_date(MYSQL_TIME *)282   bool store_date(MYSQL_TIME *) { return false; }
store_time(MYSQL_TIME *,int)283   bool store_time(MYSQL_TIME *, int) { return false; }
store(float,uint32,String *)284   bool store(float, uint32, String *) { return false; }
store(double,uint32,String *)285   bool store(double, uint32, String *) { return false; }
store(Field *)286   bool store(Field *) { return false; }
287 
288 };
289 
290 
291 void send_warning(THD *thd, uint sql_errno, const char *err=0);
292 bool net_send_error(THD *thd, uint sql_errno, const char *err,
293                     const char* sqlstate);
294 void net_send_progress_packet(THD *thd);
295 uchar *net_store_data(uchar *to,const uchar *from, size_t length);
296 uchar *net_store_data(uchar *to,int32 from);
297 uchar *net_store_data(uchar *to,longlong from);
298 
299 #endif /* PROTOCOL_INCLUDED */
300