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-1301 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 (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 | /* The real writing is done only in write() */ |
234 | virtual bool write() { return 0; } |
235 | virtual bool send_result_set_metadata(List<Item> *list, uint flags) |
236 | { |
237 | // Don't pas Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF flags |
238 | return Protocol_text::send_result_set_metadata(list, 0); |
239 | } |
240 | |
241 | // send_error is intentionally not overloaded. |
242 | virtual bool send_eof(uint server_status, uint statement_warn_count) |
243 | { |
244 | return 0; |
245 | } |
246 | |
247 | void prepare_for_resend() |
248 | { |
249 | #ifndef DBUG_OFF |
250 | field_pos= 0; |
251 | #endif |
252 | } |
253 | |
254 | /* |
255 | Provide dummy overrides for any storage methods so that we |
256 | avoid allocating and copying of data |
257 | */ |
258 | virtual bool store_null() |
259 | { return false; } |
260 | virtual bool store_tiny(longlong from) |
261 | { return false; } |
262 | virtual bool store_short(longlong from) |
263 | { return false; } |
264 | virtual bool store_long(longlong from) |
265 | { return false; } |
266 | virtual bool store_longlong(longlong from, bool unsigned_flag) |
267 | { return false; } |
268 | virtual bool store_decimal(const my_decimal *) |
269 | { return false; } |
270 | virtual bool store(const char *from, size_t length, CHARSET_INFO *cs) |
271 | { return false; } |
272 | virtual bool store(const char *from, size_t length, |
273 | CHARSET_INFO *fromcs, CHARSET_INFO *tocs) |
274 | { return false; } |
275 | virtual bool store(MYSQL_TIME *time, int decimals) |
276 | { return false; } |
277 | virtual bool store_date(MYSQL_TIME *time) |
278 | { return false; } |
279 | virtual bool store_time(MYSQL_TIME *time, int decimals) |
280 | { return false; } |
281 | virtual bool store(float nr, uint32 decimals, String *buffer) |
282 | { return false; } |
283 | virtual bool store(double from, uint32 decimals, String *buffer) |
284 | { return false; } |
285 | virtual bool store(Field *field) |
286 | { 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 | |