2 Copyright (c) 2004-2007 MySQL AB, 2009 Sun Microsystems, Inc.
3 Use is subject to license terms.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; version 2 of the License.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <mysql_com.h>
27 static uchar eof_buff
[1]= { (char) 254 }; /* Marker for end of fields */
28 static const char ERROR_PACKET_CODE
= (char) 255;
31 int net_send_ok(struct st_net
*net
, unsigned long connection_id
,
35 The format of a packet
37 1-9 affected rows count
39 2 thread return status
41 1-9 + message length message to send (isn't stored if no message)
44 uchar
*pos
= buff
.buffer
;
46 /* check that we have space to hold mandatory fields */
49 enum { OK_PACKET_CODE
= 0 };
50 *pos
++= OK_PACKET_CODE
;
51 pos
= net_store_length(pos
, (ulonglong
) 0);
52 pos
= net_store_length(pos
, (ulonglong
) connection_id
);
53 int2store(pos
, *net
->return_status
);
55 /* We don't support warnings, so store 0 for total warning count */
59 size_t position
= pos
- buff
.buffer
; /* we might need it for message */
63 buff
.reserve(position
, 9 + strlen(message
));
64 store_to_protocol_packet(&buff
, message
, &position
);
67 return my_net_write(net
, buff
.buffer
, position
) || net_flush(net
);
71 int net_send_error(struct st_net
*net
, uint sql_errno
)
73 const char *err
= message(sql_errno
);
74 char buff
[1 + // packet type code
75 2 + // sql error number
76 1 + SQLSTATE_LENGTH
+ // sql state
77 MYSQL_ERRMSG_SIZE
]; // message
80 *pos
++= ERROR_PACKET_CODE
;
81 int2store(pos
, sql_errno
);
83 /* The first # is to make the protocol backward compatible */
85 memcpy(pos
, errno_to_sqlstate(sql_errno
), SQLSTATE_LENGTH
);
86 pos
+= SQLSTATE_LENGTH
;
87 pos
= strmake(pos
, err
, MYSQL_ERRMSG_SIZE
- 1) + 1;
88 return (my_net_write(net
, (uchar
*) buff
, (size_t) (pos
- buff
)) ||
93 int net_send_error_323(struct st_net
*net
, uint sql_errno
)
95 const char *err
= message(sql_errno
);
96 char buff
[1 + // packet type code
97 2 + // sql error number
98 MYSQL_ERRMSG_SIZE
]; // message
101 *pos
++= ERROR_PACKET_CODE
;
102 int2store(pos
, sql_errno
);
104 pos
= strmake(pos
, err
, MYSQL_ERRMSG_SIZE
- 1) + 1;
105 return (my_net_write(net
, (uchar
*) buff
, (size_t) (pos
- buff
)) ||
109 char *net_store_length(char *pkg
, uint length
)
111 uchar
*packet
=(uchar
*) pkg
;
114 *packet
=(uchar
) length
;
115 return (char*) packet
+1;
118 int2store(packet
,(uint
) length
);
119 return (char*) packet
+2;
123 int store_to_protocol_packet(Buffer
*buf
, const char *string
, size_t *position
,
128 /* reserve max amount of bytes needed to store length */
129 if (buf
->reserve(*position
, 9))
131 currpos
= (net_store_length(buf
->buffer
+ *position
,
132 (ulonglong
) string_len
) - buf
->buffer
);
133 if (buf
->append(currpos
, string
, string_len
))
135 *position
= *position
+ string_len
+ (currpos
- *position
);
143 int store_to_protocol_packet(Buffer
*buf
, const char *string
,
148 string_len
= strlen(string
);
149 return store_to_protocol_packet(buf
, string
, position
, string_len
);
153 int send_eof(struct st_net
*net
)
155 uchar buff
[1 + /* eof packet code */
156 2 + /* warning count */
157 2]; /* server status */
160 int2store(buff
+1, 0);
161 int2store(buff
+3, 0);
162 return my_net_write(net
, buff
, sizeof(buff
));
166 int send_fields(struct st_net
*net
, LIST
*fields
)
174 /* send the number of fileds */
175 net_store_length(small_buff
, (uint
) list_length(fields
));
176 if (my_net_write(net
, small_buff
, (uint
) 1))
182 field
= (LEX_STRING
*) tmp
->data
;
184 store_to_protocol_packet(&send_buff
,
185 (char*) "", &position
); /* catalog name */
186 store_to_protocol_packet(&send_buff
,
187 (char*) "", &position
); /* db name */
188 store_to_protocol_packet(&send_buff
,
189 (char*) "", &position
); /* table name */
190 store_to_protocol_packet(&send_buff
,
191 (char*) "", &position
); /* table name alias */
192 store_to_protocol_packet(&send_buff
,
193 field
->str
, &position
); /* column name */
194 store_to_protocol_packet(&send_buff
,
195 field
->str
, &position
); /* column name alias */
196 send_buff
.reserve(position
, 12);
197 if (send_buff
.is_error())
199 send_buff
.buffer
[position
++]= 12;
200 int2store(send_buff
.buffer
+ position
, 1); /* charsetnr */
201 int4store(send_buff
.buffer
+ position
+ 2,
202 field
->length
); /* field length */
203 send_buff
.buffer
[position
+6]= (char) MYSQL_TYPE_STRING
; /* type */
204 int2store(send_buff
.buffer
+ position
+ 7, 0); /* flags */
205 send_buff
.buffer
[position
+ 9]= (char) 0; /* decimals */
206 send_buff
.buffer
[position
+ 10]= 0;
207 send_buff
.buffer
[position
+ 11]= 0;
209 if (my_net_write(net
, send_buff
.buffer
, (uint
) position
+1))
214 if (my_net_write(net
, eof_buff
, 1))