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,
398
net_send_ok(session, session->server_status, session->total_warn_count,
395
thd->main_da.is_sent= true;
402
session->main_da.is_sent= true;
404
411
/* The following will only be used for short strings < 65K */
406
uchar *net_store_data(uchar *to, const uchar *from, size_t length)
413
unsigned char *net_store_data(unsigned char *to, const unsigned char *from, size_t length)
408
415
to=net_store_length_fast(to,length);
409
416
memcpy(to,from,length);
410
417
return to+length;
413
uchar *net_store_data(uchar *to,int32_t from)
420
unsigned char *net_store_data(unsigned char *to,int32_t from)
416
uint length=(uint) (int10_to_str(from,buff,10)-buff);
423
uint32_t length=(uint) (int10_to_str(from,buff,10)-buff);
417
424
to=net_store_length_fast(to,length);
418
425
memcpy(to,buff,length);
419
426
return to+length;
422
uchar *net_store_data(uchar *to,int64_t from)
429
unsigned char *net_store_data(unsigned char *to,int64_t from)
425
uint length=(uint) (int64_t10_to_str(from,buff,10)-buff);
432
uint32_t length=(uint) (int64_t10_to_str(from,buff,10)-buff);
426
433
to=net_store_length_fast(to,length);
427
434
memcpy(to,buff,length);
428
435
return to+length;
433
440
Default Protocol functions
434
441
*****************************************************************************/
436
void Protocol::init(THD *thd_arg)
443
void Protocol::init(Session *session_arg)
439
packet= &thd->packet;
440
convert= &thd->convert_buffer;
446
packet= &session->packet;
447
convert= &session->convert_buffer;
449
void Protocol::end_partial_result_set(THD *thd)
456
void Protocol::end_partial_result_set(Session *session)
451
net_send_eof(thd, thd->server_status, 0 /* no warnings, we're inside SP */);
458
net_send_eof(session, session->server_status, 0 /* no warnings, we're inside SP */);
455
462
bool Protocol::flush()
457
return net_flush(&thd->net);
464
return net_flush(&session->net);
476
483
1 Error (Note that in this case the error is not sent to the
479
bool Protocol::send_fields(List<Item> *list, uint flags)
486
bool Protocol::send_fields(List<Item> *list, uint32_t flags)
481
488
List_iterator_fast<Item> it(*list);
490
unsigned char buff[80];
484
491
String tmp((char*) buff,sizeof(buff),&my_charset_bin);
485
Protocol_text prot(thd);
492
Protocol_text prot(session);
486
493
String *local_packet= prot.storage_packet();
487
const CHARSET_INFO * const thd_charset= thd->variables.character_set_results;
494
const CHARSET_INFO * const session_charset= default_charset_info;
489
496
if (flags & SEND_NUM_ROWS)
490
497
{ // 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));
498
unsigned char *pos= net_store_length(buff, list->elements);
499
(void) my_net_write(&session->net, buff, (size_t) (pos-buff));
495
502
while ((item=it++))
502
509
prot.prepare_for_resend();
505
if (prot.store(STRING_WITH_LEN("def"), cs, thd_charset) ||
512
if (prot.store(STRING_WITH_LEN("def"), cs, session_charset) ||
506
513
prot.store(field.db_name, (uint) strlen(field.db_name),
514
cs, session_charset) ||
508
515
prot.store(field.table_name, (uint) strlen(field.table_name),
516
cs, session_charset) ||
510
517
prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
518
cs, session_charset) ||
512
519
prot.store(field.col_name, (uint) strlen(field.col_name),
520
cs, session_charset) ||
514
521
prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
522
cs, session_charset) ||
516
523
local_packet->realloc(local_packet->length()+12))
519
526
/* Store fixed length fields */
520
527
pos= (char*) local_packet->ptr()+local_packet->length();
521
528
*pos++= 12; // Length of packed fields
522
if (item->collation.collation == &my_charset_bin || thd_charset == NULL)
529
if (item->collation.collation == &my_charset_bin || session_charset == NULL)
524
531
/* No conversion */
525
532
int2store(pos, field.charsetnr);
530
537
/* With conversion */
532
int2store(pos, thd_charset->number);
538
uint32_t max_char_len;
539
int2store(pos, session_charset->number);
534
541
For TEXT/BLOB columns, field_length describes the maximum data
535
542
length in bytes. There is no limit to the number of characters
541
548
of characters here is limited by the column definition.
543
550
max_char_len= field.length / item->collation.collation->mbmaxlen;
544
int4store(pos+2, max_char_len * thd_charset->mbmaxlen);
551
int4store(pos+2, max_char_len * session_charset->mbmaxlen);
546
553
pos[6]= field.type;
547
554
int2store(pos+7,field.flags);
560
567
if (flags & SEND_EOF)
563
Mark the end of meta-data result set, and store thd->server_status,
570
Mark the end of meta-data result set, and store session->server_status,
564
571
to show that there is no cursor.
565
572
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);
574
write_eof_packet(session, &session->net, session->server_status, session->total_warn_count);
569
576
return(prepare_for_send(list));
639
bool Protocol::store(String *str)
641
return store((char*) str->ptr(), str->length(), str->charset());
644
void Protocol::free()
632
650
/****************************************************************************
633
651
Functions to handle the simple (default) protocol where everything is
634
652
This protocol is the one that is used by default between the MySQL server
665
683
tocs != &my_charset_bin)
667
685
/* Store with conversion */
668
return net_store_data((uchar*) from, length, fromcs, tocs);
686
return net_store_data((unsigned char*) from, length, fromcs, tocs);
670
688
/* Store without conversion */
671
return net_store_data((uchar*) from, length);
689
return net_store_data((unsigned char*) from, length);
683
701
bool Protocol_text::store(const char *from, size_t length,
684
702
const CHARSET_INFO * const fromcs)
686
const CHARSET_INFO * const tocs= this->thd->variables.character_set_results;
704
const CHARSET_INFO * const tocs= default_charset_info;
687
705
return store_string_aux(from, length, fromcs, tocs);
691
709
bool Protocol_text::store_tiny(int64_t from)
694
return net_store_data((uchar*) buff,
712
return net_store_data((unsigned char*) buff,
695
713
(size_t) (int10_to_str((int) from, buff, -10) - buff));
699
717
bool Protocol_text::store_short(int64_t from)
702
return net_store_data((uchar*) buff,
720
return net_store_data((unsigned char*) buff,
703
721
(size_t) (int10_to_str((int) from, buff, -10) -
708
726
bool Protocol_text::store_long(int64_t from)
711
return net_store_data((uchar*) buff,
729
return net_store_data((unsigned char*) buff,
712
730
(size_t) (int10_to_str((long int)from, buff,
713
731
(from <0)?-10:10)-buff));
717
735
bool Protocol_text::store_int64_t(int64_t from, bool unsigned_flag)
720
return net_store_data((uchar*) buff,
738
return net_store_data((unsigned char*) buff,
721
739
(size_t) (int64_t10_to_str(from,buff,
722
740
unsigned_flag ? 10 : -10)-
729
747
char buff[DECIMAL_MAX_STR_LENGTH];
730
748
String str(buff, sizeof(buff), &my_charset_bin);
731
749
(void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
732
return net_store_data((uchar*) str.ptr(), str.length());
750
return net_store_data((unsigned char*) str.ptr(), str.length());
736
754
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());
756
buffer->set_real((double) from, decimals, session->charset());
757
return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
743
761
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());
763
buffer->set_real(from, decimals, session->charset());
764
return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
766
Second_part format ("%06") needs to change when
784
Second_part format ("%06") needs to change when
767
785
we support 0-6 decimals for time.
770
788
bool Protocol_text::store(DRIZZLE_TIME *tm)
774
792
length= sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d",
790
808
char buff[MAX_DATE_STRING_REP_LENGTH];
791
809
size_t length= my_date_to_str(tm, buff);
792
return net_store_data((uchar*) buff, length);
810
return net_store_data((unsigned char*) buff, length);
798
Second_part format ("%06") needs to change when
816
Second_part format ("%06") needs to change when
799
817
we support 0-6 decimals for time.
802
820
bool Protocol_text::store_time(DRIZZLE_TIME *tm)
806
uint day= (tm->year || tm->month) ? 0 : tm->day;
824
uint32_t day= (tm->year || tm->month) ? 0 : tm->day;
807
825
length= sprintf(buff, "%s%02ld:%02d:%02d",
808
826
tm->neg ? "-" : "",
809
827
(long) day*24L+(long) tm->hour,