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