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
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
28 #include "mysql_priv.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
);
41 #ifndef EMBEDDED_LIBRARY
42 bool Protocol::net_store_data(const uchar
*from
, size_t length
)
44 bool Protocol_binary::net_store_data(const uchar
*from
, size_t length
)
47 ulong packet_length
=packet
->length();
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
))
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()));
63 Send a error string to client.
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
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
));
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
;
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.
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)
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
141 net_send_ok(THD
*thd
,
142 uint server_status
, uint total_warn_count
,
143 ha_rows affected_rows
, ulonglong id
, const char *message
)
146 uchar buff
[MYSQL_ERRMSG_SIZE
+10],*pos
;
150 if (! net
->vio
) // hack for re-parsing queries
152 DBUG_PRINT("info", ("vio present: NO"));
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
)
162 ("affected_rows: %lu id: %lu status: %u warning_count: %u",
163 (ulong
) affected_rows
,
165 (uint
) (server_status
& 0xffff),
166 (uint
) total_warn_count
));
167 int2store(pos
, server_status
);
170 /* We can only return up to 65535 warnings in two bytes */
171 uint tmp
= min(total_warn_count
, 65535);
175 else if (net
->return_status
) // For 4.0 protocol
177 int2store(pos
, server_status
);
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
));
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"));
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
210 @param thd Thread handler
211 @param server_status The server status
212 @param total_warn_count Total number of warnings
215 @retval FALSE The message was successfully sent
216 @retval TRUE An error occurred and the message wasn't sent properly
220 net_send_eof(THD
*thd
, uint server_status
, uint total_warn_count
)
224 DBUG_ENTER("net_send_eof");
225 /* Set to TRUE if no active vio, to work well in case of --init-file */
228 thd
->main_da
.can_overwrite_status
= TRUE
;
229 error
= write_eof_packet(thd
, net
, server_status
, total_warn_count
);
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"));
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
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
,
256 uint total_warn_count
)
259 if (thd
->client_capabilities
& CLIENT_PROTOCOL_41
)
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);
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);
280 error
= my_net_write(net
, eof_buff
, 1);
286 Please client to send scrambled_password in old format.
288 @param thd thread handle
296 bool send_old_password_request(THD
*thd
)
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
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
)
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");
328 /* In bootstrap it's ok to print on stderr */
329 fprintf(stderr
,"ERROR: %d %s\n",sql_errno
,err
);
334 if (net
->return_errno
)
335 { // new client code; Add errno before message
336 int2store(buff
,sql_errno
);
338 if (thd
->client_capabilities
& CLIENT_PROTOCOL_41
)
340 /* The first # is to make the protocol backward compatible */
342 pos
= (uchar
*) strmov((char*) buff
+3, mysql_errno_to_sqlstate(sql_errno
));
344 length
= (uint
) (strmake((char*) pos
, err
, MYSQL_ERRMSG_SIZE
-1) -
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
,
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
364 uint is used as agrument type because of MySQL type conventions:
366 - ulong for 0..4294967296
367 - ulonglong for bigger numbers.
370 static uchar
*net_store_length_fast(uchar
*packet
, uint length
)
374 *packet
=(uchar
) length
;
378 int2store(packet
,(uint
) length
);
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:
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
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
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
)
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());
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());
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());
462 case Diagnostics_area::DA_DISABLED
:
464 case Diagnostics_area::DA_EMPTY
:
467 error
= net_send_ok(thd
, thd
->server_status
, thd
->total_warn_count
,
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
);
490 uchar
*net_store_data(uchar
*to
,int32 from
)
493 uint length
=(uint
) (int10_to_str(from
,buff
,10)-buff
);
494 to
=net_store_length_fast(to
,length
);
495 memcpy(to
,buff
,length
);
499 uchar
*net_store_data(uchar
*to
,longlong from
)
502 uint length
=(uint
) (longlong10_to_str(from
,buff
,10)-buff
);
503 to
=net_store_length_fast(to
,length
);
504 memcpy(to
,buff
,length
);
509 /*****************************************************************************
510 Default Protocol functions
511 *****************************************************************************/
513 void Protocol::init(THD
*thd_arg
)
516 packet
= &thd
->packet
;
517 convert
= &thd
->convert_buffer
;
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
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
539 thd
->main_da
.can_overwrite_status
= TRUE
;
540 error
= net_flush(&thd
->net
);
541 thd
->main_da
.can_overwrite_status
= FALSE
;
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
565 1 Error (Note that in this case the error is not sent to the
568 bool Protocol::send_fields(List
<Item
> *list
, uint flags
)
570 List_iterator_fast
<Item
> it(*list
);
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
)))
587 field_types
= (enum_field_types
*) thd
->alloc(sizeof(field_types
) *
595 CHARSET_INFO
*cs
= system_charset_info
;
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
),
610 prot
.store(field
.table_name
, (uint
) strlen(field
.table_name
),
612 prot
.store(field
.org_table_name
, (uint
) strlen(field
.org_table_name
),
614 prot
.store(field
.col_name
, (uint
) strlen(field
.col_name
),
616 prot
.store(field
.org_col_name
, (uint
) strlen(field
.org_col_name
),
618 local_packet
->realloc(local_packet
->length()+12))
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
)
628 int2store(pos
, field
.charsetnr
);
629 int4store(pos
+2, field
.length
);
633 /* With conversion */
634 ulonglong max_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
);
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
672 if (prot
.store(field
.table_name
, (uint
) strlen(field
.table_name
),
674 prot
.store(field
.col_name
, (uint
) strlen(field
.col_name
),
676 local_packet
->realloc(local_packet
->length()+10))
678 pos
= (char*) local_packet
->ptr()+local_packet
->length();
680 #ifdef TO_BE_DELETED_IN_6
681 if (!(thd
->client_capabilities
& CLIENT_LONG_FLAG
))
684 int3store(pos
+1,field
.length
);
688 pos
[7]= (char) field
.flags
;
689 pos
[8]= (char) field
.decimals
;
696 int3store(pos
+1,field
.length
);
700 int2store(pos
+7,field
.flags
);
701 pos
[9]= (char) field
.decimals
;
705 local_packet
->length((uint
) (pos
- local_packet
->ptr()));
706 if (flags
& SEND_DEFAULTS
)
707 item
->send(&prot
, &tmp
); // Send default value
711 field_types
[count
++]= field
.type
;
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
))
726 DBUG_RETURN(prepare_for_send(list
));
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(),
741 #endif /* EMBEDDED_LIBRARY */
745 Send \\0 end terminated string.
747 @param from NullS or \\0 terminated string
750 In most cases one should use store(from, length) instead of this function
758 bool Protocol::store(const char *from
, CHARSET_INFO
*cs
)
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
)
774 String
tmp(buf
, sizeof(buf
), &my_charset_bin
);
776 I_List_iterator
<i_string
> it(*str_list
);
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()
808 bool Protocol_text::store_null()
815 return packet
->append(buff
, sizeof(buff
), PACKET_BUFFER_EXTRA_ALLOC
);
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
)
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
)
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
));
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
;
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
));
874 return store_string_aux(from
, length
, fromcs
, tocs
);
878 bool Protocol_text::store_tiny(longlong from
)
881 DBUG_ASSERT(field_types
== 0 || field_types
[field_pos
] == MYSQL_TYPE_TINY
);
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
)
893 DBUG_ASSERT(field_types
== 0 ||
894 field_types
[field_pos
] == MYSQL_TYPE_YEAR
||
895 field_types
[field_pos
] == MYSQL_TYPE_SHORT
);
899 return net_store_data((uchar
*) buff
,
900 (size_t) (int10_to_str((int) from
, buff
, -10) -
905 bool Protocol_text::store_long(longlong from
)
908 DBUG_ASSERT(field_types
== 0 ||
909 field_types
[field_pos
] == MYSQL_TYPE_INT24
||
910 field_types
[field_pos
] == MYSQL_TYPE_LONG
);
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
)
923 DBUG_ASSERT(field_types
== 0 ||
924 field_types
[field_pos
] == MYSQL_TYPE_LONGLONG
);
928 return net_store_data((uchar
*) buff
,
929 (size_t) (longlong10_to_str(from
,buff
,
930 unsigned_flag
? 10 : -10)-
935 bool Protocol_text::store_decimal(const my_decimal
*d
)
938 DBUG_ASSERT(field_types
== 0 ||
939 field_types
[field_pos
] == MYSQL_TYPE_NEWDECIMAL
);
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
)
952 DBUG_ASSERT(field_types
== 0 ||
953 field_types
[field_pos
] == MYSQL_TYPE_FLOAT
);
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
)
964 DBUG_ASSERT(field_types
== 0 ||
965 field_types
[field_pos
] == MYSQL_TYPE_DOUBLE
);
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())
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
;
984 TABLE
*table
= field
->table
;
985 my_bitmap_map
*old_map
= 0;
987 old_map
= dbug_tmp_use_all_columns(table
, table
->read_set
);
990 field
->val_str(&str
);
993 dbug_tmp_restore_column_map(table
->read_set
, old_map
);
996 return store_string_aux(str
.ptr(), str
.length(), str
.charset(), tocs
);
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
)
1009 DBUG_ASSERT(field_types
== 0 ||
1010 field_types
[field_pos
] == MYSQL_TYPE_DATETIME
||
1011 field_types
[field_pos
] == MYSQL_TYPE_TIMESTAMP
);
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
)
1029 DBUG_ASSERT(field_types
== 0 ||
1030 field_types
[field_pos
] == MYSQL_TYPE_DATE
);
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
);
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
)
1048 DBUG_ASSERT(field_types
== 0 ||
1049 field_types
[field_pos
] == MYSQL_TYPE_TIME
);
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
,
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
1069 [ok:1] reserved ok packet
1070 [null_field:(field_count+7+2)/8] reserved to send null data. The size is
1072 bit_fields= (field_count+7+2)/8;
1073 2 bits are reserved for identifying type
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))
1089 /* prepare_for_resend will be called after this one */
1094 void Protocol_binary::prepare_for_resend()
1096 packet
->length(bit_fields
+1);
1097 bzero((uchar
*) packet
->ptr(), 1+bit_fields
);
1102 bool Protocol_binary::store(const char *from
, size_t length
,
1103 CHARSET_INFO
*fromcs
)
1105 CHARSET_INFO
*tocs
= thd
->variables
.character_set_results
;
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
)
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
);
1128 bool Protocol_binary::store_tiny(longlong from
)
1132 buff
[0]= (uchar
) from
;
1133 return packet
->append(buff
, sizeof(buff
), PACKET_BUFFER_EXTRA_ALLOC
);
1137 bool Protocol_binary::store_short(longlong from
)
1140 char *to
= packet
->prep_append(2, PACKET_BUFFER_EXTRA_ALLOC
);
1143 int2store(to
, (int) from
);
1148 bool Protocol_binary::store_long(longlong from
)
1151 char *to
= packet
->prep_append(4, PACKET_BUFFER_EXTRA_ALLOC
);
1154 int4store(to
, from
);
1159 bool Protocol_binary::store_longlong(longlong from
, bool unsigned_flag
)
1162 char *to
= packet
->prep_append(8, PACKET_BUFFER_EXTRA_ALLOC
);
1165 int8store(to
, from
);
1169 bool Protocol_binary::store_decimal(const my_decimal
*d
)
1172 DBUG_ASSERT(field_types
== 0 ||
1173 field_types
[field_pos
] == MYSQL_TYPE_NEWDECIMAL
);
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
)
1185 char *to
= packet
->prep_append(4, PACKET_BUFFER_EXTRA_ALLOC
);
1188 float4store(to
, from
);
1193 bool Protocol_binary::store(double from
, uint32 decimals
, String
*buffer
)
1196 char *to
= packet
->prep_append(8, PACKET_BUFFER_EXTRA_ALLOC
);
1199 float8store(to
, from
);
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
)
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
)
1232 else if (tm
->hour
|| tm
->minute
|| tm
->second
)
1234 else if (tm
->year
|| tm
->month
|| tm
->day
)
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;
1246 return Protocol_binary::store(tm
);
1250 bool Protocol_binary::store_time(MYSQL_TIME
*tm
)
1252 char buff
[13], *pos
;
1256 pos
[0]= tm
->neg
? 1 : 0;
1259 /* Fix if we come from Item::send */
1260 uint days
= tm
->hour
/24;
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
)
1271 else if (tm
->hour
|| tm
->minute
|| tm
->second
|| tm
->day
)
1275 buff
[0]=(char) length
; // Length is stored first
1276 return packet
->append(buff
, length
+1, PACKET_BUFFER_EXTRA_ALLOC
);