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