20
20
The actual communction is handled by the net_xxx functions in net_serv.cc
22
22
#include <drizzled/server_includes.h>
23
#include <drizzled/drizzled_error_messages.h>
23
#include <drizzled/error.h>
24
#include <drizzled/sql_state.h>
25
#include <libdrizzle/pack.h>
26
#include <drizzled/protocol.h>
27
#include <drizzled/session.h>
25
29
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
26
30
/* Declared non-static only because of the embedded library. */
27
static void net_send_error_packet(THD *thd, uint sql_errno, const char *err);
28
static void write_eof_packet(THD *thd, NET *net,
29
uint server_status, uint total_warn_count);
31
static void net_send_error_packet(Session *session, uint32_t sql_errno, const char *err);
32
static void write_eof_packet(Session *session, NET *net,
33
uint32_t server_status, uint32_t total_warn_count);
31
bool Protocol::net_store_data(const uchar *from, size_t length)
35
bool Protocol::net_store_data(const unsigned char *from, size_t length)
33
ulong packet_length=packet->length();
37
size_t packet_length= packet->length();
35
39
The +9 comes from that strings of length longer than 16M require
36
40
9 bytes to be stored (see net_store_length).
38
42
if (packet_length+9+length > packet->alloced_length() &&
39
43
packet->realloc(packet_length+9+length))
41
uchar *to= net_store_length((uchar*) packet->ptr()+packet_length, length);
45
unsigned char *to= net_store_length((unsigned char*) packet->ptr()+packet_length, length);
42
46
memcpy(to,from,length);
43
packet->length((uint) (to+length-(uchar*) packet->ptr()));
47
packet->length((size_t) (to+length-(unsigned char*) packet->ptr()));
59
63
because column, table, database names fit into this limit.
62
bool Protocol::net_store_data(const uchar *from, size_t length,
66
bool Protocol::net_store_data(const unsigned char *from, size_t length,
63
67
const CHARSET_INFO * const from_cs,
64
68
const CHARSET_INFO * const to_cs)
70
uint32_t dummy_errors;
67
71
/* Calculate maxumum possible result length */
68
uint conv_length= to_cs->mbmaxlen * length / from_cs->mbminlen;
72
uint32_t conv_length= to_cs->mbmaxlen * length / from_cs->mbminlen;
69
73
if (conv_length > 250)
75
79
For example, when converting from utf8 (mbmaxlen=3) to latin1,
76
80
conv_length=300 means that the result length can vary between 100 to 300.
77
81
length=100 needs one byte, length=300 needs to bytes.
79
83
Thus conversion directly to "packet" is not worthy.
80
84
Let's use "convert" as a temporary buffer.
82
86
return (convert->copy((const char*) from, length, from_cs,
83
87
to_cs, &dummy_errors) ||
84
net_store_data((const uchar*) convert->ptr(), convert->length()));
88
net_store_data((const unsigned char*) convert->ptr(), convert->length()));
87
ulong packet_length= packet->length();
88
ulong new_length= packet_length + conv_length + 1;
91
size_t packet_length= packet->length();
92
size_t new_length= packet_length + conv_length + 1;
90
94
if (new_length > packet->alloced_length() && packet->realloc(new_length))
96
100
to+= copy_and_convert(to, conv_length, to_cs,
97
101
(const char*) from, length, from_cs, &dummy_errors);
99
net_store_length((uchar*) length_pos, to - length_pos - 1);
103
net_store_length((unsigned char*) length_pos, to - length_pos - 1);
100
104
packet->length((uint) (to - packet->ptr()));
114
118
critical that every error that can be intercepted is issued in one
115
119
place only, my_message_sql.
117
void net_send_error(THD *thd, uint sql_errno, const char *err)
121
void net_send_error(Session *session, uint32_t sql_errno, const char *err)
119
123
assert(sql_errno);
120
124
assert(err && err[0]);
123
127
It's one case when we can push an error even though there
124
128
is an OK or EOF already.
126
thd->main_da.can_overwrite_status= true;
130
session->main_da.can_overwrite_status= true;
128
132
/* Abort multi-result sets */
129
thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
131
net_send_error_packet(thd, sql_errno, err);
133
thd->main_da.can_overwrite_status= false;
133
session->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
135
net_send_error_packet(session, sql_errno, err);
137
session->main_da.can_overwrite_status= false;
141
145
- 0 : Marker (1 byte)
142
146
- affected_rows : Stored in 1-9 bytes
143
147
- id : Stored in 1-9 bytes
144
- server_status : Copy of thd->server_status; Can be used by client
148
- server_status : Copy of session->server_status; Can be used by client
145
149
to check if we are inside an transaction.
146
150
New in 4.0 protocol
147
151
- warning_count : Stored in 2 bytes; New in 4.1 protocol
148
152
- message : Stored as packed length (1-9 bytes) + message.
149
153
Is not stored if no message.
151
@param thd Thread handler
155
@param session Thread handler
152
156
@param affected_rows Number of rows changed by statement
153
157
@param id Auto_increment id for first row (if used)
154
158
@param message Message to send to the client (Used by mysql_status)
158
net_send_ok(THD *thd,
159
uint server_status, uint total_warn_count,
162
net_send_ok(Session *session,
163
uint32_t server_status, uint32_t total_warn_count,
160
164
ha_rows affected_rows, uint64_t id, const char *message)
163
uchar buff[DRIZZLE_ERRMSG_SIZE+10],*pos;
166
NET *net= &session->net;
167
unsigned char buff[DRIZZLE_ERRMSG_SIZE+10],*pos;
165
169
if (! net->vio) // hack for re-parsing queries
177
181
/* We can only return up to 65535 warnings in two bytes */
178
uint tmp= min(total_warn_count, (uint)65535);
182
uint32_t tmp= cmin(total_warn_count, (uint)65535);
179
183
int2store(pos, tmp);
182
thd->main_da.can_overwrite_status= true;
186
session->main_da.can_overwrite_status= true;
184
188
if (message && message[0])
185
pos= net_store_data(pos, (uchar*) message, strlen(message));
186
VOID(my_net_write(net, buff, (size_t) (pos-buff)));
187
VOID(net_flush(net));
189
pos= net_store_data(pos, (unsigned char*) message, strlen(message));
190
my_net_write(net, buff, (size_t) (pos-buff));
189
thd->main_da.can_overwrite_status= false;
193
session->main_da.can_overwrite_status= false;
203
207
we don't want to report the warning count until all data is sent to the
206
@param thd Thread handler
210
@param session Thread handler
207
211
@param no_flush Set to 1 if there will be more data to the client,
208
212
like in send_fields().
212
net_send_eof(THD *thd, uint server_status, uint total_warn_count)
216
net_send_eof(Session *session, uint32_t server_status, uint32_t total_warn_count)
218
NET *net= &session->net;
215
219
/* Set to true if no active vio, to work well in case of --init-file */
216
220
if (net->vio != 0)
218
thd->main_da.can_overwrite_status= true;
219
write_eof_packet(thd, net, server_status, total_warn_count);
220
VOID(net_flush(net));
221
thd->main_da.can_overwrite_status= false;
222
session->main_da.can_overwrite_status= true;
223
write_eof_packet(session, net, server_status, total_warn_count);
225
session->main_da.can_overwrite_status= false;
228
232
write it to the network output buffer.
231
static void write_eof_packet(THD *thd, NET *net,
233
uint total_warn_count)
235
static void write_eof_packet(Session *session, NET *net,
236
uint32_t server_status,
237
uint32_t total_warn_count)
239
unsigned char buff[5];
237
241
Don't send warn count during SP execution, as the warn_list
238
242
is cleared between substatements, and mysqltest gets confused
240
uint tmp= min(total_warn_count, (uint)65535);
244
uint32_t tmp= cmin(total_warn_count, (uint)65535);
241
245
buff[0]= DRIZZLE_PROTOCOL_NO_MORE_DATA;
242
246
int2store(buff+1, tmp);
245
249
because if 'is_fatal_error' is set the server is not going to execute
246
250
other queries (see the if test in dispatch_command / COM_QUERY)
248
if (thd->is_fatal_error)
252
if (session->is_fatal_error)
249
253
server_status&= ~SERVER_MORE_RESULTS_EXISTS;
250
254
int2store(buff + 3, server_status);
251
VOID(my_net_write(net, buff, 5));
255
my_net_write(net, buff, 5);
254
void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
258
void net_send_error_packet(Session *session, uint32_t sql_errno, const char *err)
260
NET *net= &session->net;
259
263
buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + DRIZZLE_ERRMSG_SIZE:512
261
uchar buff[2+1+SQLSTATE_LENGTH+DRIZZLE_ERRMSG_SIZE], *pos;
265
unsigned char buff[2+1+SQLSTATE_LENGTH+DRIZZLE_ERRMSG_SIZE], *pos;
263
267
if (net->vio == 0)
271
275
/* The first # is to make the protocol backward compatible */
273
pos= (uchar*) stpcpy((char*) buff+3, drizzle_errno_to_sqlstate(sql_errno));
277
pos= (unsigned char*) strcpy((char*) buff+3, drizzle_errno_to_sqlstate(sql_errno));
278
pos+= strlen(drizzle_errno_to_sqlstate(sql_errno));
275
length= (uint) (strmake((char*) pos, err, DRIZZLE_ERRMSG_SIZE-1) -
280
char *tmp= strncpy((char*)pos, err, DRIZZLE_ERRMSG_SIZE-1);
281
tmp+= strlen((char*)pos);
283
length= (uint32_t)(tmp-(char*)buff);
277
284
err= (char*) buff;
279
VOID(net_write_command(net,(uchar) 255, (uchar*) "", 0, (uchar*) err,
286
net_write_command(net,(unsigned char) 255, (unsigned char*) "", 0, (unsigned char*) err, length);
287
293
We keep a separate version for that range because it's widely used in
290
uint is used as agrument type because of MySQL type conventions:
296
uint32_t is used as agrument type because of MySQL type conventions:
297
- uint32_t for 0..65536
292
298
- ulong for 0..4294967296
293
299
- uint64_t for bigger numbers.
296
static uchar *net_store_length_fast(uchar *packet, uint length)
302
static unsigned char *net_store_length_fast(unsigned char *packet, uint32_t length)
298
304
if (length < 251)
300
*packet=(uchar) length;
306
*packet=(unsigned char) length;
304
int2store(packet,(uint) length);
310
int2store(packet,(uint32_t) length);
309
316
Send the status of the current statement execution over network.
311
@param thd in fact, carries two parameters, NET for the transport and
318
@param session in fact, carries two parameters, NET for the transport and
312
319
Diagnostics_area as the source of status information.
314
321
In MySQL, there are two types of SQL statements: those that return
355
362
Diagnostics_area::is_sent is set for debugging purposes only.
358
void net_end_statement(THD *thd)
365
void net_end_statement(Session *session)
360
assert(! thd->main_da.is_sent);
367
assert(! session->main_da.is_sent);
362
369
/* Can not be true, but do not take chances in production. */
363
if (thd->main_da.is_sent)
370
if (session->main_da.is_sent)
366
switch (thd->main_da.status()) {
373
switch (session->main_da.status()) {
367
374
case Diagnostics_area::DA_ERROR:
368
375
/* The query failed, send error to log and abort bootstrap. */
370
thd->main_da.sql_errno(),
371
thd->main_da.message());
376
net_send_error(session,
377
session->main_da.sql_errno(),
378
session->main_da.message());
373
380
case Diagnostics_area::DA_EOF:
375
thd->main_da.server_status(),
376
thd->main_da.total_warn_count());
381
net_send_eof(session,
382
session->main_da.server_status(),
383
session->main_da.total_warn_count());
378
385
case Diagnostics_area::DA_OK:
380
thd->main_da.server_status(),
381
thd->main_da.total_warn_count(),
382
thd->main_da.affected_rows(),
383
thd->main_da.last_insert_id(),
384
thd->main_da.message());
387
session->main_da.server_status(),
388
session->main_da.total_warn_count(),
389
session->main_da.affected_rows(),
390
session->main_da.last_insert_id(),
391
session->main_da.message());
386
393
case Diagnostics_area::DA_DISABLED:
388
395
case Diagnostics_area::DA_EMPTY:
391
net_send_ok(thd, thd->server_status, thd->total_warn_count,
397
//TODO: Something is being masked here by commenting this out
399
net_send_ok(session, session->server_status, session->total_warn_count,
395
thd->main_da.is_sent= true;
403
session->main_da.is_sent= true;
404
412
/* The following will only be used for short strings < 65K */
406
uchar *net_store_data(uchar *to, const uchar *from, size_t length)
414
unsigned char *net_store_data(unsigned char *to, const unsigned char *from, size_t length)
408
416
to=net_store_length_fast(to,length);
409
417
memcpy(to,from,length);
410
418
return to+length;
413
uchar *net_store_data(uchar *to,int32_t from)
421
unsigned char *net_store_data(unsigned char *to,int32_t from)
416
uint length=(uint) (int10_to_str(from,buff,10)-buff);
424
uint32_t length=(uint) (int10_to_str(from,buff,10)-buff);
417
425
to=net_store_length_fast(to,length);
418
426
memcpy(to,buff,length);
419
427
return to+length;
422
uchar *net_store_data(uchar *to,int64_t from)
430
unsigned char *net_store_data(unsigned char *to,int64_t from)
425
uint length=(uint) (int64_t10_to_str(from,buff,10)-buff);
433
uint32_t length=(uint) (int64_t10_to_str(from,buff,10)-buff);
426
434
to=net_store_length_fast(to,length);
427
435
memcpy(to,buff,length);
428
436
return to+length;
433
441
Default Protocol functions
434
442
*****************************************************************************/
436
void Protocol::init(THD *thd_arg)
444
void Protocol::init(Session *session_arg)
439
packet= &thd->packet;
440
convert= &thd->convert_buffer;
447
packet= &session->packet;
448
convert= &session->convert_buffer;
449
void Protocol::end_partial_result_set(THD *thd)
457
void Protocol::end_partial_result_set(Session *session)
451
net_send_eof(thd, thd->server_status, 0 /* no warnings, we're inside SP */);
459
net_send_eof(session, session->server_status, 0 /* no warnings, we're inside SP */);
455
463
bool Protocol::flush()
457
return net_flush(&thd->net);
465
return net_flush(&session->net);
476
484
1 Error (Note that in this case the error is not sent to the
479
bool Protocol::send_fields(List<Item> *list, uint flags)
487
bool Protocol::send_fields(List<Item> *list, uint32_t flags)
481
489
List_iterator_fast<Item> it(*list);
491
unsigned char buff[80];
484
492
String tmp((char*) buff,sizeof(buff),&my_charset_bin);
485
Protocol_text prot(thd);
493
Protocol_text prot(session);
486
494
String *local_packet= prot.storage_packet();
487
const CHARSET_INFO * const thd_charset= thd->variables.character_set_results;
495
const CHARSET_INFO * const session_charset= session->variables.character_set_results;
489
497
if (flags & SEND_NUM_ROWS)
490
498
{ // Packet with number of elements
491
uchar *pos= net_store_length(buff, list->elements);
492
(void) my_net_write(&thd->net, buff, (size_t) (pos-buff));
499
unsigned char *pos= net_store_length(buff, list->elements);
500
(void) my_net_write(&session->net, buff, (size_t) (pos-buff));
495
503
while ((item=it++))
502
510
prot.prepare_for_resend();
505
if (prot.store(STRING_WITH_LEN("def"), cs, thd_charset) ||
513
if (prot.store(STRING_WITH_LEN("def"), cs, session_charset) ||
506
514
prot.store(field.db_name, (uint) strlen(field.db_name),
515
cs, session_charset) ||
508
516
prot.store(field.table_name, (uint) strlen(field.table_name),
517
cs, session_charset) ||
510
518
prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
519
cs, session_charset) ||
512
520
prot.store(field.col_name, (uint) strlen(field.col_name),
521
cs, session_charset) ||
514
522
prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
523
cs, session_charset) ||
516
524
local_packet->realloc(local_packet->length()+12))
519
527
/* Store fixed length fields */
520
528
pos= (char*) local_packet->ptr()+local_packet->length();
521
529
*pos++= 12; // Length of packed fields
522
if (item->collation.collation == &my_charset_bin || thd_charset == NULL)
530
if (item->collation.collation == &my_charset_bin || session_charset == NULL)
524
532
/* No conversion */
525
533
int2store(pos, field.charsetnr);
541
549
of characters here is limited by the column definition.
543
551
max_char_len= field.length / item->collation.collation->mbmaxlen;
544
int4store(pos+2, max_char_len * thd_charset->mbmaxlen);
552
int4store(pos+2, max_char_len * session_charset->mbmaxlen);
546
554
pos[6]= field.type;
547
555
int2store(pos+7,field.flags);
560
568
if (flags & SEND_EOF)
563
Mark the end of meta-data result set, and store thd->server_status,
571
Mark the end of meta-data result set, and store session->server_status,
564
572
to show that there is no cursor.
565
573
Send no warning information, as it will be sent at statement end.
567
write_eof_packet(thd, &thd->net, thd->server_status, thd->total_warn_count);
575
write_eof_packet(session, &session->net, session->server_status, session->total_warn_count);
569
577
return(prepare_for_send(list));
640
bool Protocol::store(String *str)
642
return store((char*) str->ptr(), str->length(), str->charset());
645
void Protocol::free()
632
651
/****************************************************************************
633
652
Functions to handle the simple (default) protocol where everything is
634
653
This protocol is the one that is used by default between the MySQL server
665
684
tocs != &my_charset_bin)
667
686
/* Store with conversion */
668
return net_store_data((uchar*) from, length, fromcs, tocs);
687
return net_store_data((unsigned char*) from, length, fromcs, tocs);
670
689
/* Store without conversion */
671
return net_store_data((uchar*) from, length);
690
return net_store_data((unsigned char*) from, length);
683
702
bool Protocol_text::store(const char *from, size_t length,
684
703
const CHARSET_INFO * const fromcs)
686
const CHARSET_INFO * const tocs= this->thd->variables.character_set_results;
705
const CHARSET_INFO * const tocs= this->session->variables.character_set_results;
687
706
return store_string_aux(from, length, fromcs, tocs);
691
710
bool Protocol_text::store_tiny(int64_t from)
694
return net_store_data((uchar*) buff,
713
return net_store_data((unsigned char*) buff,
695
714
(size_t) (int10_to_str((int) from, buff, -10) - buff));
699
718
bool Protocol_text::store_short(int64_t from)
702
return net_store_data((uchar*) buff,
721
return net_store_data((unsigned char*) buff,
703
722
(size_t) (int10_to_str((int) from, buff, -10) -
708
727
bool Protocol_text::store_long(int64_t from)
711
return net_store_data((uchar*) buff,
730
return net_store_data((unsigned char*) buff,
712
731
(size_t) (int10_to_str((long int)from, buff,
713
732
(from <0)?-10:10)-buff));
717
736
bool Protocol_text::store_int64_t(int64_t from, bool unsigned_flag)
720
return net_store_data((uchar*) buff,
739
return net_store_data((unsigned char*) buff,
721
740
(size_t) (int64_t10_to_str(from,buff,
722
741
unsigned_flag ? 10 : -10)-
729
748
char buff[DECIMAL_MAX_STR_LENGTH];
730
749
String str(buff, sizeof(buff), &my_charset_bin);
731
750
(void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
732
return net_store_data((uchar*) str.ptr(), str.length());
751
return net_store_data((unsigned char*) str.ptr(), str.length());
736
755
bool Protocol_text::store(float from, uint32_t decimals, String *buffer)
738
buffer->set_real((double) from, decimals, thd->charset());
739
return net_store_data((uchar*) buffer->ptr(), buffer->length());
757
buffer->set_real((double) from, decimals, session->charset());
758
return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
743
762
bool Protocol_text::store(double from, uint32_t decimals, String *buffer)
745
buffer->set_real(from, decimals, thd->charset());
746
return net_store_data((uchar*) buffer->ptr(), buffer->length());
764
buffer->set_real(from, decimals, session->charset());
765
return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
766
Second_part format ("%06") needs to change when
785
Second_part format ("%06") needs to change when
767
786
we support 0-6 decimals for time.
770
789
bool Protocol_text::store(DRIZZLE_TIME *tm)
774
793
length= sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d",
790
809
char buff[MAX_DATE_STRING_REP_LENGTH];
791
810
size_t length= my_date_to_str(tm, buff);
792
return net_store_data((uchar*) buff, length);
811
return net_store_data((unsigned char*) buff, length);
798
Second_part format ("%06") needs to change when
817
Second_part format ("%06") needs to change when
799
818
we support 0-6 decimals for time.
802
821
bool Protocol_text::store_time(DRIZZLE_TIME *tm)
806
uint day= (tm->year || tm->month) ? 0 : tm->day;
825
uint32_t day= (tm->year || tm->month) ? 0 : tm->day;
807
826
length= sprintf(buff, "%s%02ld:%02d:%02d",
808
827
tm->neg ? "-" : "",
809
828
(long) day*24L+(long) tm->hour,