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