mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / sql / protocol.cc
bloba74f6084df469fee4461e7132610222e8ba5c81b
1 /* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 /**
18 @file
20 Low level functions for storing data to be send to the MySQL client.
21 The actual communction is handled by the net_xxx functions in net_serv.cc
24 #ifdef USE_PRAGMA_IMPLEMENTATION
25 #pragma implementation // gcc: Class implementation
26 #endif
28 #include "mysql_priv.h"
29 #include <stdarg.h>
31 static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
32 /* Declared non-static only because of the embedded library. */
33 bool net_send_error_packet(THD *thd, uint sql_errno, const char *err);
34 bool net_send_ok(THD *, uint, uint, ha_rows, ulonglong, const char *);
35 bool net_send_eof(THD *thd, uint server_status, uint total_warn_count);
36 #ifndef EMBEDDED_LIBRARY
37 static bool write_eof_packet(THD *thd, NET *net,
38 uint server_status, uint total_warn_count);
39 #endif
41 #ifndef EMBEDDED_LIBRARY
42 bool Protocol::net_store_data(const uchar *from, size_t length)
43 #else
44 bool Protocol_binary::net_store_data(const uchar *from, size_t length)
45 #endif
47 ulong packet_length=packet->length();
48 /*
49 The +9 comes from that strings of length longer than 16M require
50 9 bytes to be stored (see net_store_length).
52 if (packet_length+9+length > packet->alloced_length() &&
53 packet->realloc(packet_length+9+length))
54 return 1;
55 uchar *to= net_store_length((uchar*) packet->ptr()+packet_length, length);
56 memcpy(to,from,length);
57 packet->length((uint) (to+length-(uchar*) packet->ptr()));
58 return 0;
62 /**
63 Send a error string to client.
65 Design note:
67 net_printf_error and net_send_error are low-level functions
68 that shall be used only when a new connection is being
69 established or at server startup.
71 For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
72 critical that every error that can be intercepted is issued in one
73 place only, my_message_sql.
75 @param thd Thread handler
76 @param sql_errno The error code to send
77 @param err A pointer to the error message
79 @return
80 @retval FALSE The message was sent to the client
81 @retval TRUE An error occurred and the message wasn't sent properly
84 bool net_send_error(THD *thd, uint sql_errno, const char *err)
86 DBUG_ENTER("net_send_error");
88 DBUG_ASSERT(!thd->spcont);
89 DBUG_ASSERT(sql_errno);
90 DBUG_ASSERT(err && err[0]);
92 DBUG_PRINT("enter",("sql_errno: %d err: %s", sql_errno, err));
93 bool error;
96 It's one case when we can push an error even though there
97 is an OK or EOF already.
99 thd->main_da.can_overwrite_status= TRUE;
101 /* Abort multi-result sets */
102 thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
104 error= net_send_error_packet(thd, sql_errno, err);
106 thd->main_da.can_overwrite_status= FALSE;
108 DBUG_RETURN(error);
112 Return ok to the client.
114 The ok packet has the following structure:
116 - 0 : Marker (1 byte)
117 - affected_rows : Stored in 1-9 bytes
118 - id : Stored in 1-9 bytes
119 - server_status : Copy of thd->server_status; Can be used by client
120 to check if we are inside an transaction.
121 New in 4.0 protocol
122 - warning_count : Stored in 2 bytes; New in 4.1 protocol
123 - message : Stored as packed length (1-9 bytes) + message.
124 Is not stored if no message.
126 @param thd Thread handler
127 @param server_status The server status
128 @param total_warn_count Total number of warnings
129 @param affected_rows Number of rows changed by statement
130 @param id Auto_increment id for first row (if used)
131 @param message Message to send to the client (Used by mysql_status)
133 @return
134 @retval FALSE The message was successfully sent
135 @retval TRUE An error occurred and the messages wasn't sent properly
139 #ifndef EMBEDDED_LIBRARY
140 bool
141 net_send_ok(THD *thd,
142 uint server_status, uint total_warn_count,
143 ha_rows affected_rows, ulonglong id, const char *message)
145 NET *net= &thd->net;
146 uchar buff[MYSQL_ERRMSG_SIZE+10],*pos;
147 bool error= FALSE;
148 DBUG_ENTER("my_ok");
150 if (! net->vio) // hack for re-parsing queries
152 DBUG_PRINT("info", ("vio present: NO"));
153 DBUG_RETURN(FALSE);
156 buff[0]=0; // No fields
157 pos=net_store_length(buff+1,affected_rows);
158 pos=net_store_length(pos, id);
159 if (thd->client_capabilities & CLIENT_PROTOCOL_41)
161 DBUG_PRINT("info",
162 ("affected_rows: %lu id: %lu status: %u warning_count: %u",
163 (ulong) affected_rows,
164 (ulong) id,
165 (uint) (server_status & 0xffff),
166 (uint) total_warn_count));
167 int2store(pos, server_status);
168 pos+=2;
170 /* We can only return up to 65535 warnings in two bytes */
171 uint tmp= min(total_warn_count, 65535);
172 int2store(pos, tmp);
173 pos+= 2;
175 else if (net->return_status) // For 4.0 protocol
177 int2store(pos, server_status);
178 pos+=2;
180 thd->main_da.can_overwrite_status= TRUE;
182 if (message && message[0])
183 pos= net_store_data(pos, (uchar*) message, strlen(message));
184 error= my_net_write(net, buff, (size_t) (pos-buff));
185 if (!error)
186 error= net_flush(net);
188 thd->main_da.can_overwrite_status= FALSE;
189 DBUG_PRINT("info", ("OK sent, so no more error sending allowed"));
191 DBUG_RETURN(error);
194 static uchar eof_buff[1]= { (uchar) 254 }; /* Marker for end of fields */
197 Send eof (= end of result set) to the client.
199 The eof packet has the following structure:
201 - 254 : Marker (1 byte)
202 - warning_count : Stored in 2 bytes; New in 4.1 protocol
203 - status_flag : Stored in 2 bytes;
204 For flags like SERVER_MORE_RESULTS_EXISTS.
206 Note that the warning count will not be sent if 'no_flush' is set as
207 we don't want to report the warning count until all data is sent to the
208 client.
210 @param thd Thread handler
211 @param server_status The server status
212 @param total_warn_count Total number of warnings
214 @return
215 @retval FALSE The message was successfully sent
216 @retval TRUE An error occurred and the message wasn't sent properly
219 bool
220 net_send_eof(THD *thd, uint server_status, uint total_warn_count)
222 NET *net= &thd->net;
223 bool error= FALSE;
224 DBUG_ENTER("net_send_eof");
225 /* Set to TRUE if no active vio, to work well in case of --init-file */
226 if (net->vio != 0)
228 thd->main_da.can_overwrite_status= TRUE;
229 error= write_eof_packet(thd, net, server_status, total_warn_count);
230 if (!error)
231 error= net_flush(net);
232 thd->main_da.can_overwrite_status= FALSE;
233 DBUG_PRINT("info", ("EOF sent, so no more error sending allowed"));
235 DBUG_RETURN(error);
240 Format EOF packet according to the current protocol and
241 write it to the network output buffer.
243 @param thd The thread handler
244 @param net The network handler
245 @param server_status The server status
246 @param total_warn_count The number of warnings
249 @return
250 @retval FALSE The message was sent successfully
251 @retval TRUE An error occurred and the messages wasn't sent properly
254 static bool write_eof_packet(THD *thd, NET *net,
255 uint server_status,
256 uint total_warn_count)
258 bool error;
259 if (thd->client_capabilities & CLIENT_PROTOCOL_41)
261 uchar buff[5];
263 Don't send warn count during SP execution, as the warn_list
264 is cleared between substatements, and mysqltest gets confused
266 uint tmp= min(total_warn_count, 65535);
267 buff[0]= 254;
268 int2store(buff+1, tmp);
270 The following test should never be true, but it's better to do it
271 because if 'is_fatal_error' is set the server is not going to execute
272 other queries (see the if test in dispatch_command / COM_QUERY)
274 if (thd->is_fatal_error)
275 server_status&= ~SERVER_MORE_RESULTS_EXISTS;
276 int2store(buff + 3, server_status);
277 error= my_net_write(net, buff, 5);
279 else
280 error= my_net_write(net, eof_buff, 1);
282 return error;
286 Please client to send scrambled_password in old format.
288 @param thd thread handle
290 @retval
291 0 ok
292 @retval
293 !0 error
296 bool send_old_password_request(THD *thd)
298 NET *net= &thd->net;
299 return my_net_write(net, eof_buff, 1) || net_flush(net);
304 @param thd Thread handler
305 @param sql_errno The error code to send
306 @param err A pointer to the error message
308 @return
309 @retval FALSE The message was successfully sent
310 @retval TRUE An error occurred and the messages wasn't sent properly
313 bool net_send_error_packet(THD *thd, uint sql_errno, const char *err)
315 NET *net= &thd->net;
316 uint length;
318 buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + MYSQL_ERRMSG_SIZE:512
320 uchar buff[2+1+SQLSTATE_LENGTH+MYSQL_ERRMSG_SIZE], *pos;
322 DBUG_ENTER("send_error_packet");
324 if (net->vio == 0)
326 if (thd->bootstrap)
328 /* In bootstrap it's ok to print on stderr */
329 fprintf(stderr,"ERROR: %d %s\n",sql_errno,err);
331 DBUG_RETURN(FALSE);
334 if (net->return_errno)
335 { // new client code; Add errno before message
336 int2store(buff,sql_errno);
337 pos= buff+2;
338 if (thd->client_capabilities & CLIENT_PROTOCOL_41)
340 /* The first # is to make the protocol backward compatible */
341 buff[2]= '#';
342 pos= (uchar*) strmov((char*) buff+3, mysql_errno_to_sqlstate(sql_errno));
344 length= (uint) (strmake((char*) pos, err, MYSQL_ERRMSG_SIZE-1) -
345 (char*) buff);
346 err= (char*) buff;
348 else
350 length=(uint) strlen(err);
351 set_if_smaller(length,MYSQL_ERRMSG_SIZE-1);
353 DBUG_RETURN(net_write_command(net,(uchar) 255, (uchar*) "", 0, (uchar*) err,
354 length));
357 #endif /* EMBEDDED_LIBRARY */
360 Faster net_store_length when we know that length is less than 65536.
361 We keep a separate version for that range because it's widely used in
362 libmysql.
364 uint is used as agrument type because of MySQL type conventions:
365 - uint for 0..65536
366 - ulong for 0..4294967296
367 - ulonglong for bigger numbers.
370 static uchar *net_store_length_fast(uchar *packet, uint length)
372 if (length < 251)
374 *packet=(uchar) length;
375 return packet+1;
377 *packet++=252;
378 int2store(packet,(uint) length);
379 return packet+2;
383 Send the status of the current statement execution over network.
385 @param thd in fact, carries two parameters, NET for the transport and
386 Diagnostics_area as the source of status information.
388 In MySQL, there are two types of SQL statements: those that return
389 a result set and those that return status information only.
391 If a statement returns a result set, it consists of 3 parts:
392 - result set meta-data
393 - variable number of result set rows (can be 0)
394 - followed and terminated by EOF or ERROR packet
396 Once the client has seen the meta-data information, it always
397 expects an EOF or ERROR to terminate the result set. If ERROR is
398 received, the result set rows are normally discarded (this is up
399 to the client implementation, libmysql at least does discard them).
400 EOF, on the contrary, means "successfully evaluated the entire
401 result set". Since we don't know how many rows belong to a result
402 set until it's evaluated, EOF/ERROR is the indicator of the end
403 of the row stream. Note, that we can not buffer result set rows
404 on the server -- there may be an arbitrary number of rows. But
405 we do buffer the last packet (EOF/ERROR) in the Diagnostics_area and
406 delay sending it till the very end of execution (here), to be able to
407 change EOF to an ERROR if commit failed or some other error occurred
408 during the last cleanup steps taken after execution.
410 A statement that does not return a result set doesn't send result
411 set meta-data either. Instead it returns one of:
412 - OK packet
413 - ERROR packet.
414 Similarly to the EOF/ERROR of the previous statement type, OK/ERROR
415 packet is "buffered" in the diagnostics area and sent to the client
416 in the end of statement.
418 @pre The diagnostics area is assigned or disabled. It can not be empty
419 -- we assume that every SQL statement or COM_* command
420 generates OK, ERROR, or EOF status.
422 @post The status information is encoded to protocol format and sent to the
423 client.
425 @return We conventionally return void, since the only type of error
426 that can happen here is a NET (transport) error, and that one
427 will become visible when we attempt to read from the NET the
428 next command.
429 Diagnostics_area::is_sent is set for debugging purposes only.
432 void net_end_statement(THD *thd)
434 DBUG_ASSERT(! thd->main_da.is_sent);
436 /* Can not be true, but do not take chances in production. */
437 if (thd->main_da.is_sent)
438 return;
440 bool error= FALSE;
442 switch (thd->main_da.status()) {
443 case Diagnostics_area::DA_ERROR:
444 /* The query failed, send error to log and abort bootstrap. */
445 error= net_send_error(thd,
446 thd->main_da.sql_errno(),
447 thd->main_da.message());
448 break;
449 case Diagnostics_area::DA_EOF:
450 error= net_send_eof(thd,
451 thd->main_da.server_status(),
452 thd->main_da.total_warn_count());
453 break;
454 case Diagnostics_area::DA_OK:
455 error= net_send_ok(thd,
456 thd->main_da.server_status(),
457 thd->main_da.total_warn_count(),
458 thd->main_da.affected_rows(),
459 thd->main_da.last_insert_id(),
460 thd->main_da.message());
461 break;
462 case Diagnostics_area::DA_DISABLED:
463 break;
464 case Diagnostics_area::DA_EMPTY:
465 default:
466 DBUG_ASSERT(0);
467 error= net_send_ok(thd, thd->server_status, thd->total_warn_count,
468 0, 0, NULL);
469 break;
471 if (!error)
472 thd->main_da.is_sent= TRUE;
476 /****************************************************************************
477 Functions used by the protocol functions (like net_send_ok) to store
478 strings and numbers in the header result packet.
479 ****************************************************************************/
481 /* The following will only be used for short strings < 65K */
483 uchar *net_store_data(uchar *to, const uchar *from, size_t length)
485 to=net_store_length_fast(to,length);
486 memcpy(to,from,length);
487 return to+length;
490 uchar *net_store_data(uchar *to,int32 from)
492 char buff[20];
493 uint length=(uint) (int10_to_str(from,buff,10)-buff);
494 to=net_store_length_fast(to,length);
495 memcpy(to,buff,length);
496 return to+length;
499 uchar *net_store_data(uchar *to,longlong from)
501 char buff[22];
502 uint length=(uint) (longlong10_to_str(from,buff,10)-buff);
503 to=net_store_length_fast(to,length);
504 memcpy(to,buff,length);
505 return to+length;
509 /*****************************************************************************
510 Default Protocol functions
511 *****************************************************************************/
513 void Protocol::init(THD *thd_arg)
515 thd=thd_arg;
516 packet= &thd->packet;
517 convert= &thd->convert_buffer;
518 #ifndef DBUG_OFF
519 field_types= 0;
520 #endif
524 Finish the result set with EOF packet, as is expected by the client,
525 if there is an error evaluating the next row and a continue handler
526 for the error.
529 void Protocol::end_partial_result_set(THD *thd_arg)
531 net_send_eof(thd_arg, thd_arg->server_status, 0 /* no warnings, we're inside SP */);
535 bool Protocol::flush()
537 #ifndef EMBEDDED_LIBRARY
538 bool error;
539 thd->main_da.can_overwrite_status= TRUE;
540 error= net_flush(&thd->net);
541 thd->main_da.can_overwrite_status= FALSE;
542 return error;
543 #else
544 return 0;
545 #endif
548 #ifndef EMBEDDED_LIBRARY
551 Send name and type of result to client.
553 Sum fields has table name empty and field_name.
555 @param THD Thread data object
556 @param list List of items to send to client
557 @param flag Bit mask with the following functions:
558 - 1 send number of rows
559 - 2 send default values
560 - 4 don't write eof packet
562 @retval
563 0 ok
564 @retval
565 1 Error (Note that in this case the error is not sent to the
566 client)
568 bool Protocol::send_fields(List<Item> *list, uint flags)
570 List_iterator_fast<Item> it(*list);
571 Item *item;
572 uchar buff[80];
573 String tmp((char*) buff,sizeof(buff),&my_charset_bin);
574 Protocol_text prot(thd);
575 String *local_packet= prot.storage_packet();
576 CHARSET_INFO *thd_charset= thd->variables.character_set_results;
577 DBUG_ENTER("send_fields");
579 if (flags & SEND_NUM_ROWS)
580 { // Packet with number of elements
581 uchar *pos= net_store_length(buff, list->elements);
582 if (my_net_write(&thd->net, buff, (size_t) (pos-buff)))
583 DBUG_RETURN(1);
586 #ifndef DBUG_OFF
587 field_types= (enum_field_types*) thd->alloc(sizeof(field_types) *
588 list->elements);
589 uint count= 0;
590 #endif
592 while ((item=it++))
594 char *pos;
595 CHARSET_INFO *cs= system_charset_info;
596 Send_field field;
597 item->make_field(&field);
599 /* Keep things compatible for old clients */
600 if (field.type == MYSQL_TYPE_VARCHAR)
601 field.type= MYSQL_TYPE_VAR_STRING;
603 prot.prepare_for_resend();
605 if (thd->client_capabilities & CLIENT_PROTOCOL_41)
607 if (prot.store(STRING_WITH_LEN("def"), cs, thd_charset) ||
608 prot.store(field.db_name, (uint) strlen(field.db_name),
609 cs, thd_charset) ||
610 prot.store(field.table_name, (uint) strlen(field.table_name),
611 cs, thd_charset) ||
612 prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
613 cs, thd_charset) ||
614 prot.store(field.col_name, (uint) strlen(field.col_name),
615 cs, thd_charset) ||
616 prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
617 cs, thd_charset) ||
618 local_packet->realloc(local_packet->length()+12))
619 goto err;
620 /* Store fixed length fields */
621 pos= (char*) local_packet->ptr()+local_packet->length();
622 *pos++= 12; // Length of packed fields
623 /* inject a NULL to test the client */
624 DBUG_EXECUTE_IF("poison_rs_fields", pos[-1]= 0xfb;);
625 if (item->collation.collation == &my_charset_bin || thd_charset == NULL)
627 /* No conversion */
628 int2store(pos, field.charsetnr);
629 int4store(pos+2, field.length);
631 else
633 /* With conversion */
634 ulonglong max_length;
635 uint32 field_length;
636 int2store(pos, thd_charset->number);
638 For TEXT/BLOB columns, field_length describes the maximum data
639 length in bytes. There is no limit to the number of characters
640 that a TEXT column can store, as long as the data fits into
641 the designated space.
642 For the rest of textual columns, field_length is evaluated as
643 char_count * mbmaxlen, where character count is taken from the
644 definition of the column. In other words, the maximum number
645 of characters here is limited by the column definition.
647 When one has a LONG TEXT column with a single-byte
648 character set, and the connection character set is multi-byte, the
649 client may get fields longer than UINT_MAX32, due to
650 <character set column> -> <character set connection> conversion.
651 In that case column max length does not fit into the 4 bytes
652 reserved for it in the protocol.
654 max_length= (field.type >= MYSQL_TYPE_TINY_BLOB &&
655 field.type <= MYSQL_TYPE_BLOB) ?
656 field.length / item->collation.collation->mbminlen :
657 field.length / item->collation.collation->mbmaxlen;
658 max_length*= thd_charset->mbmaxlen;
659 field_length= (max_length > UINT_MAX32) ?
660 UINT_MAX32 : (uint32) max_length;
661 int4store(pos + 2, field_length);
663 pos[6]= field.type;
664 int2store(pos+7,field.flags);
665 pos[9]= (char) field.decimals;
666 pos[10]= 0; // For the future
667 pos[11]= 0; // For the future
668 pos+= 12;
670 else
672 if (prot.store(field.table_name, (uint) strlen(field.table_name),
673 cs, thd_charset) ||
674 prot.store(field.col_name, (uint) strlen(field.col_name),
675 cs, thd_charset) ||
676 local_packet->realloc(local_packet->length()+10))
677 goto err;
678 pos= (char*) local_packet->ptr()+local_packet->length();
680 #ifdef TO_BE_DELETED_IN_6
681 if (!(thd->client_capabilities & CLIENT_LONG_FLAG))
683 pos[0]=3;
684 int3store(pos+1,field.length);
685 pos[4]=1;
686 pos[5]=field.type;
687 pos[6]=2;
688 pos[7]= (char) field.flags;
689 pos[8]= (char) field.decimals;
690 pos+= 9;
692 else
693 #endif
695 pos[0]=3;
696 int3store(pos+1,field.length);
697 pos[4]=1;
698 pos[5]=field.type;
699 pos[6]=3;
700 int2store(pos+7,field.flags);
701 pos[9]= (char) field.decimals;
702 pos+= 10;
705 local_packet->length((uint) (pos - local_packet->ptr()));
706 if (flags & SEND_DEFAULTS)
707 item->send(&prot, &tmp); // Send default value
708 if (prot.write())
709 DBUG_RETURN(1);
710 #ifndef DBUG_OFF
711 field_types[count++]= field.type;
712 #endif
715 if (flags & SEND_EOF)
718 Mark the end of meta-data result set, and store thd->server_status,
719 to show that there is no cursor.
720 Send no warning information, as it will be sent at statement end.
722 if (write_eof_packet(thd, &thd->net, thd->server_status,
723 thd->total_warn_count))
724 DBUG_RETURN(1);
726 DBUG_RETURN(prepare_for_send(list));
728 err:
729 my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES),
730 MYF(0)); /* purecov: inspected */
731 DBUG_RETURN(1); /* purecov: inspected */
735 bool Protocol::write()
737 DBUG_ENTER("Protocol::write");
738 DBUG_RETURN(my_net_write(&thd->net, (uchar*) packet->ptr(),
739 packet->length()));
741 #endif /* EMBEDDED_LIBRARY */
745 Send \\0 end terminated string.
747 @param from NullS or \\0 terminated string
749 @note
750 In most cases one should use store(from, length) instead of this function
752 @retval
753 0 ok
754 @retval
755 1 error
758 bool Protocol::store(const char *from, CHARSET_INFO *cs)
760 if (!from)
761 return store_null();
762 uint length= strlen(from);
763 return store(from, length, cs);
768 Send a set of strings as one long string with ',' in between.
771 bool Protocol::store(I_List<i_string>* str_list)
773 char buf[256];
774 String tmp(buf, sizeof(buf), &my_charset_bin);
775 uint32 len;
776 I_List_iterator<i_string> it(*str_list);
777 i_string* s;
779 tmp.length(0);
780 while ((s=it++))
782 tmp.append(s->ptr);
783 tmp.append(',');
785 if ((len= tmp.length()))
786 len--; // Remove last ','
787 return store((char*) tmp.ptr(), len, tmp.charset());
791 /****************************************************************************
792 Functions to handle the simple (default) protocol where everything is
793 This protocol is the one that is used by default between the MySQL server
794 and client when you are not using prepared statements.
796 All data are sent as 'packed-string-length' followed by 'string-data'
797 ****************************************************************************/
799 #ifndef EMBEDDED_LIBRARY
800 void Protocol_text::prepare_for_resend()
802 packet->length(0);
803 #ifndef DBUG_OFF
804 field_pos= 0;
805 #endif
808 bool Protocol_text::store_null()
810 #ifndef DBUG_OFF
811 field_pos++;
812 #endif
813 char buff[1];
814 buff[0]= (char)251;
815 return packet->append(buff, sizeof(buff), PACKET_BUFFER_EXTRA_ALLOC);
817 #endif
821 Auxilary function to convert string to the given character set
822 and store in network buffer.
825 bool Protocol::store_string_aux(const char *from, size_t length,
826 CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
828 /* 'tocs' is set 0 when client issues SET character_set_results=NULL */
829 if (tocs && !my_charset_same(fromcs, tocs) &&
830 fromcs != &my_charset_bin &&
831 tocs != &my_charset_bin)
833 uint dummy_errors;
834 return (convert->copy(from, length, fromcs, tocs, &dummy_errors) ||
835 net_store_data((uchar*) convert->ptr(), convert->length()));
837 return net_store_data((uchar*) from, length);
841 bool Protocol_text::store(const char *from, size_t length,
842 CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
844 #ifndef DBUG_OFF
845 DBUG_ASSERT(field_types == 0 ||
846 field_types[field_pos] == MYSQL_TYPE_DECIMAL ||
847 field_types[field_pos] == MYSQL_TYPE_BIT ||
848 field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL ||
849 (field_types[field_pos] >= MYSQL_TYPE_ENUM &&
850 field_types[field_pos] <= MYSQL_TYPE_GEOMETRY));
851 field_pos++;
852 #endif
853 return store_string_aux(from, length, fromcs, tocs);
857 bool Protocol_text::store(const char *from, size_t length,
858 CHARSET_INFO *fromcs)
860 CHARSET_INFO *tocs= this->thd->variables.character_set_results;
861 #ifndef DBUG_OFF
862 DBUG_PRINT("info", ("Protocol_text::store field %u (%u): %.*s", field_pos,
863 field_count, (int) length, (length == 0 ? "" : from)));
864 DBUG_ASSERT(field_pos < field_count);
865 DBUG_ASSERT(field_types == 0 ||
866 field_types[field_pos] == MYSQL_TYPE_DECIMAL ||
867 field_types[field_pos] == MYSQL_TYPE_BIT ||
868 field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL ||
869 field_types[field_pos] == MYSQL_TYPE_NEWDATE ||
870 (field_types[field_pos] >= MYSQL_TYPE_ENUM &&
871 field_types[field_pos] <= MYSQL_TYPE_GEOMETRY));
872 field_pos++;
873 #endif
874 return store_string_aux(from, length, fromcs, tocs);
878 bool Protocol_text::store_tiny(longlong from)
880 #ifndef DBUG_OFF
881 DBUG_ASSERT(field_types == 0 || field_types[field_pos] == MYSQL_TYPE_TINY);
882 field_pos++;
883 #endif
884 char buff[20];
885 return net_store_data((uchar*) buff,
886 (size_t) (int10_to_str((int) from, buff, -10) - buff));
890 bool Protocol_text::store_short(longlong from)
892 #ifndef DBUG_OFF
893 DBUG_ASSERT(field_types == 0 ||
894 field_types[field_pos] == MYSQL_TYPE_YEAR ||
895 field_types[field_pos] == MYSQL_TYPE_SHORT);
896 field_pos++;
897 #endif
898 char buff[20];
899 return net_store_data((uchar*) buff,
900 (size_t) (int10_to_str((int) from, buff, -10) -
901 buff));
905 bool Protocol_text::store_long(longlong from)
907 #ifndef DBUG_OFF
908 DBUG_ASSERT(field_types == 0 ||
909 field_types[field_pos] == MYSQL_TYPE_INT24 ||
910 field_types[field_pos] == MYSQL_TYPE_LONG);
911 field_pos++;
912 #endif
913 char buff[20];
914 return net_store_data((uchar*) buff,
915 (size_t) (int10_to_str((long int)from, buff,
916 (from <0)?-10:10)-buff));
920 bool Protocol_text::store_longlong(longlong from, bool unsigned_flag)
922 #ifndef DBUG_OFF
923 DBUG_ASSERT(field_types == 0 ||
924 field_types[field_pos] == MYSQL_TYPE_LONGLONG);
925 field_pos++;
926 #endif
927 char buff[22];
928 return net_store_data((uchar*) buff,
929 (size_t) (longlong10_to_str(from,buff,
930 unsigned_flag ? 10 : -10)-
931 buff));
935 bool Protocol_text::store_decimal(const my_decimal *d)
937 #ifndef DBUG_OFF
938 DBUG_ASSERT(field_types == 0 ||
939 field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL);
940 field_pos++;
941 #endif
942 char buff[DECIMAL_MAX_STR_LENGTH];
943 String str(buff, sizeof(buff), &my_charset_bin);
944 (void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
945 return net_store_data((uchar*) str.ptr(), str.length());
949 bool Protocol_text::store(float from, uint32 decimals, String *buffer)
951 #ifndef DBUG_OFF
952 DBUG_ASSERT(field_types == 0 ||
953 field_types[field_pos] == MYSQL_TYPE_FLOAT);
954 field_pos++;
955 #endif
956 buffer->set_real((double) from, decimals, thd->charset());
957 return net_store_data((uchar*) buffer->ptr(), buffer->length());
961 bool Protocol_text::store(double from, uint32 decimals, String *buffer)
963 #ifndef DBUG_OFF
964 DBUG_ASSERT(field_types == 0 ||
965 field_types[field_pos] == MYSQL_TYPE_DOUBLE);
966 field_pos++;
967 #endif
968 buffer->set_real(from, decimals, thd->charset());
969 return net_store_data((uchar*) buffer->ptr(), buffer->length());
973 bool Protocol_text::store(Field *field)
975 if (field->is_null())
976 return store_null();
977 #ifndef DBUG_OFF
978 field_pos++;
979 #endif
980 char buff[MAX_FIELD_WIDTH];
981 String str(buff,sizeof(buff), &my_charset_bin);
982 CHARSET_INFO *tocs= this->thd->variables.character_set_results;
983 #ifndef DBUG_OFF
984 TABLE *table= field->table;
985 my_bitmap_map *old_map= 0;
986 if (table->file)
987 old_map= dbug_tmp_use_all_columns(table, table->read_set);
988 #endif
990 field->val_str(&str);
991 #ifndef DBUG_OFF
992 if (old_map)
993 dbug_tmp_restore_column_map(table->read_set, old_map);
994 #endif
996 return store_string_aux(str.ptr(), str.length(), str.charset(), tocs);
1001 @todo
1002 Second_part format ("%06") needs to change when
1003 we support 0-6 decimals for time.
1006 bool Protocol_text::store(MYSQL_TIME *tm)
1008 #ifndef DBUG_OFF
1009 DBUG_ASSERT(field_types == 0 ||
1010 field_types[field_pos] == MYSQL_TYPE_DATETIME ||
1011 field_types[field_pos] == MYSQL_TYPE_TIMESTAMP);
1012 field_pos++;
1013 #endif
1014 char buff[40];
1015 uint length;
1016 length= sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d",
1017 (int) tm->year, (int) tm->month,
1018 (int) tm->day, (int) tm->hour,
1019 (int) tm->minute, (int) tm->second);
1020 if (tm->second_part)
1021 length+= sprintf(buff+length, ".%06d", (int) tm->second_part);
1022 return net_store_data((uchar*) buff, length);
1026 bool Protocol_text::store_date(MYSQL_TIME *tm)
1028 #ifndef DBUG_OFF
1029 DBUG_ASSERT(field_types == 0 ||
1030 field_types[field_pos] == MYSQL_TYPE_DATE);
1031 field_pos++;
1032 #endif
1033 char buff[MAX_DATE_STRING_REP_LENGTH];
1034 size_t length= my_date_to_str(tm, buff);
1035 return net_store_data((uchar*) buff, length);
1040 @todo
1041 Second_part format ("%06") needs to change when
1042 we support 0-6 decimals for time.
1045 bool Protocol_text::store_time(MYSQL_TIME *tm)
1047 #ifndef DBUG_OFF
1048 DBUG_ASSERT(field_types == 0 ||
1049 field_types[field_pos] == MYSQL_TYPE_TIME);
1050 field_pos++;
1051 #endif
1052 char buff[40];
1053 uint length;
1054 uint day= (tm->year || tm->month) ? 0 : tm->day;
1055 length= sprintf(buff, "%s%02ld:%02d:%02d", tm->neg ? "-" : "",
1056 (long) day*24L+(long) tm->hour, (int) tm->minute,
1057 (int) tm->second);
1058 if (tm->second_part)
1059 length+= sprintf(buff+length, ".%06d", (int) tm->second_part);
1060 return net_store_data((uchar*) buff, length);
1064 /****************************************************************************
1065 Functions to handle the binary protocol used with prepared statements
1067 Data format:
1069 [ok:1] reserved ok packet
1070 [null_field:(field_count+7+2)/8] reserved to send null data. The size is
1071 calculated using:
1072 bit_fields= (field_count+7+2)/8;
1073 2 bits are reserved for identifying type
1074 of package.
1075 [[length]data] data field (the length applies only for
1076 string/binary/time/timestamp fields and
1077 rest of them are not sent as they have
1078 the default length that client understands
1079 based on the field type
1080 [..]..[[length]data] data
1081 ****************************************************************************/
1083 bool Protocol_binary::prepare_for_send(List<Item> *item_list)
1085 Protocol::prepare_for_send(item_list);
1086 bit_fields= (field_count+9)/8;
1087 if (packet->alloc(bit_fields+1))
1088 return 1;
1089 /* prepare_for_resend will be called after this one */
1090 return 0;
1094 void Protocol_binary::prepare_for_resend()
1096 packet->length(bit_fields+1);
1097 bzero((uchar*) packet->ptr(), 1+bit_fields);
1098 field_pos=0;
1102 bool Protocol_binary::store(const char *from, size_t length,
1103 CHARSET_INFO *fromcs)
1105 CHARSET_INFO *tocs= thd->variables.character_set_results;
1106 field_pos++;
1107 return store_string_aux(from, length, fromcs, tocs);
1110 bool Protocol_binary::store(const char *from, size_t length,
1111 CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
1113 field_pos++;
1114 return store_string_aux(from, length, fromcs, tocs);
1117 bool Protocol_binary::store_null()
1119 uint offset= (field_pos+2)/8+1, bit= (1 << ((field_pos+2) & 7));
1120 /* Room for this as it's allocated in prepare_for_send */
1121 char *to= (char*) packet->ptr()+offset;
1122 *to= (char) ((uchar) *to | (uchar) bit);
1123 field_pos++;
1124 return 0;
1128 bool Protocol_binary::store_tiny(longlong from)
1130 char buff[1];
1131 field_pos++;
1132 buff[0]= (uchar) from;
1133 return packet->append(buff, sizeof(buff), PACKET_BUFFER_EXTRA_ALLOC);
1137 bool Protocol_binary::store_short(longlong from)
1139 field_pos++;
1140 char *to= packet->prep_append(2, PACKET_BUFFER_EXTRA_ALLOC);
1141 if (!to)
1142 return 1;
1143 int2store(to, (int) from);
1144 return 0;
1148 bool Protocol_binary::store_long(longlong from)
1150 field_pos++;
1151 char *to= packet->prep_append(4, PACKET_BUFFER_EXTRA_ALLOC);
1152 if (!to)
1153 return 1;
1154 int4store(to, from);
1155 return 0;
1159 bool Protocol_binary::store_longlong(longlong from, bool unsigned_flag)
1161 field_pos++;
1162 char *to= packet->prep_append(8, PACKET_BUFFER_EXTRA_ALLOC);
1163 if (!to)
1164 return 1;
1165 int8store(to, from);
1166 return 0;
1169 bool Protocol_binary::store_decimal(const my_decimal *d)
1171 #ifndef DBUG_OFF
1172 DBUG_ASSERT(field_types == 0 ||
1173 field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL);
1174 field_pos++;
1175 #endif
1176 char buff[DECIMAL_MAX_STR_LENGTH];
1177 String str(buff, sizeof(buff), &my_charset_bin);
1178 (void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
1179 return store(str.ptr(), str.length(), str.charset());
1182 bool Protocol_binary::store(float from, uint32 decimals, String *buffer)
1184 field_pos++;
1185 char *to= packet->prep_append(4, PACKET_BUFFER_EXTRA_ALLOC);
1186 if (!to)
1187 return 1;
1188 float4store(to, from);
1189 return 0;
1193 bool Protocol_binary::store(double from, uint32 decimals, String *buffer)
1195 field_pos++;
1196 char *to= packet->prep_append(8, PACKET_BUFFER_EXTRA_ALLOC);
1197 if (!to)
1198 return 1;
1199 float8store(to, from);
1200 return 0;
1204 bool Protocol_binary::store(Field *field)
1207 We should not increment field_pos here as send_binary() will call another
1208 protocol function to do this for us
1210 if (field->is_null())
1211 return store_null();
1212 return field->send_binary(this);
1216 bool Protocol_binary::store(MYSQL_TIME *tm)
1218 char buff[12],*pos;
1219 uint length;
1220 field_pos++;
1221 pos= buff+1;
1223 int2store(pos, tm->year);
1224 pos[2]= (uchar) tm->month;
1225 pos[3]= (uchar) tm->day;
1226 pos[4]= (uchar) tm->hour;
1227 pos[5]= (uchar) tm->minute;
1228 pos[6]= (uchar) tm->second;
1229 int4store(pos+7, tm->second_part);
1230 if (tm->second_part)
1231 length=11;
1232 else if (tm->hour || tm->minute || tm->second)
1233 length=7;
1234 else if (tm->year || tm->month || tm->day)
1235 length=4;
1236 else
1237 length=0;
1238 buff[0]=(char) length; // Length is stored first
1239 return packet->append(buff, length+1, PACKET_BUFFER_EXTRA_ALLOC);
1242 bool Protocol_binary::store_date(MYSQL_TIME *tm)
1244 tm->hour= tm->minute= tm->second=0;
1245 tm->second_part= 0;
1246 return Protocol_binary::store(tm);
1250 bool Protocol_binary::store_time(MYSQL_TIME *tm)
1252 char buff[13], *pos;
1253 uint length;
1254 field_pos++;
1255 pos= buff+1;
1256 pos[0]= tm->neg ? 1 : 0;
1257 if (tm->hour >= 24)
1259 /* Fix if we come from Item::send */
1260 uint days= tm->hour/24;
1261 tm->hour-= days*24;
1262 tm->day+= days;
1264 int4store(pos+1, tm->day);
1265 pos[5]= (uchar) tm->hour;
1266 pos[6]= (uchar) tm->minute;
1267 pos[7]= (uchar) tm->second;
1268 int4store(pos+8, tm->second_part);
1269 if (tm->second_part)
1270 length=12;
1271 else if (tm->hour || tm->minute || tm->second || tm->day)
1272 length=8;
1273 else
1274 length=0;
1275 buff[0]=(char) length; // Length is stored first
1276 return packet->append(buff, length+1, PACKET_BUFFER_EXTRA_ALLOC);