19
19
Low level functions for storing data to be send to the MySQL client.
20
20
The actual communction is handled by the net_xxx functions in net_serv.cc
22
#include <drizzled/server_includes.h>
23
#include <drizzled/drizzled_error_messages.h>
24
#include <drizzled/sql_state.h>
23
#ifdef USE_PRAGMA_IMPLEMENTATION
24
#pragma implementation // gcc: Class implementation
27
#include "mysql_priv.h"
26
30
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
27
31
/* Declared non-static only because of the embedded library. */
28
static void net_send_error_packet(THD *thd, uint32_t sql_errno, const char *err);
32
void net_send_error_packet(THD *thd, uint sql_errno, const char *err);
33
void net_send_ok(THD *, uint, uint, ha_rows, ulonglong, const char *);
34
void net_send_eof(THD *thd, uint server_status, uint total_warn_count);
29
35
static void write_eof_packet(THD *thd, NET *net,
30
uint32_t server_status, uint32_t total_warn_count);
36
uint server_status, uint total_warn_count);
32
bool Protocol::net_store_data(const unsigned char *from, size_t length)
38
bool Protocol::net_store_data(const uchar *from, size_t length)
34
40
ulong packet_length=packet->length();
155
166
@param message Message to send to the client (Used by mysql_status)
159
170
net_send_ok(THD *thd,
160
uint32_t server_status, uint32_t total_warn_count,
161
ha_rows affected_rows, uint64_t id, const char *message)
171
uint server_status, uint total_warn_count,
172
ha_rows affected_rows, ulonglong id, const char *message)
163
174
NET *net= &thd->net;
164
unsigned char buff[DRIZZLE_ERRMSG_SIZE+10],*pos;
175
uchar buff[MYSQL_ERRMSG_SIZE+10],*pos;
166
178
if (! net->vio) // hack for re-parsing queries
180
DBUG_PRINT("info", ("vio present: NO"));
171
184
buff[0]=0; // No fields
172
185
pos=net_store_length(buff+1,affected_rows);
173
186
pos=net_store_length(pos, id);
175
int2store(pos, server_status);
178
/* We can only return up to 65535 warnings in two bytes */
179
uint32_t tmp= cmin(total_warn_count, (uint)65535);
183
thd->main_da.can_overwrite_status= true;
187
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
190
("affected_rows: %lu id: %lu status: %u warning_count: %u",
191
(ulong) affected_rows,
193
(uint) (server_status & 0xffff),
194
(uint) total_warn_count));
195
int2store(pos, server_status);
198
/* We can only return up to 65535 warnings in two bytes */
199
uint tmp= min(total_warn_count, 65535);
203
else if (net->return_status) // For 4.0 protocol
205
int2store(pos, server_status);
208
thd->main_da.can_overwrite_status= TRUE;
185
210
if (message && message[0])
186
pos= net_store_data(pos, (unsigned char*) message, strlen(message));
187
my_net_write(net, buff, (size_t) (pos-buff));
190
thd->main_da.can_overwrite_status= false;
211
pos= net_store_data(pos, (uchar*) message, strlen(message));
212
VOID(my_net_write(net, buff, (size_t) (pos-buff)));
213
VOID(net_flush(net));
215
thd->main_da.can_overwrite_status= FALSE;
216
DBUG_PRINT("info", ("OK sent, so no more error sending allowed"));
221
static uchar eof_buff[1]= { (uchar) 254 }; /* Marker for end of fields */
194
224
Send eof (= end of result set) to the client.
196
226
The eof packet has the following structure:
198
- 254 (DRIZZLE_PROTOCOL_NO_MORE_DATA) : Marker (1 byte)
228
- 254 : Marker (1 byte)
199
229
- warning_count : Stored in 2 bytes; New in 4.1 protocol
200
230
- status_flag : Stored in 2 bytes;
201
231
For flags like SERVER_MORE_RESULTS_EXISTS.
232
265
static void write_eof_packet(THD *thd, NET *net,
233
uint32_t server_status,
234
uint32_t total_warn_count)
236
unsigned char buff[5];
238
Don't send warn count during SP execution, as the warn_list
239
is cleared between substatements, and mysqltest gets confused
241
uint32_t tmp= cmin(total_warn_count, (uint)65535);
242
buff[0]= DRIZZLE_PROTOCOL_NO_MORE_DATA;
243
int2store(buff+1, tmp);
245
The following test should never be true, but it's better to do it
246
because if 'is_fatal_error' is set the server is not going to execute
247
other queries (see the if test in dispatch_command / COM_QUERY)
249
if (thd->is_fatal_error)
250
server_status&= ~SERVER_MORE_RESULTS_EXISTS;
251
int2store(buff + 3, server_status);
252
my_net_write(net, buff, 5);
255
void net_send_error_packet(THD *thd, uint32_t sql_errno, const char *err)
260
buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + DRIZZLE_ERRMSG_SIZE:512
262
unsigned char buff[2+1+SQLSTATE_LENGTH+DRIZZLE_ERRMSG_SIZE], *pos;
267
uint total_warn_count)
269
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
273
Don't send warn count during SP execution, as the warn_list
274
is cleared between substatements, and mysqltest gets confused
276
uint tmp= min(total_warn_count, 65535);
278
int2store(buff+1, tmp);
280
The following test should never be true, but it's better to do it
281
because if 'is_fatal_error' is set the server is not going to execute
282
other queries (see the if test in dispatch_command / COM_QUERY)
284
if (thd->is_fatal_error)
285
server_status&= ~SERVER_MORE_RESULTS_EXISTS;
286
int2store(buff + 3, server_status);
287
VOID(my_net_write(net, buff, 5));
290
VOID(my_net_write(net, eof_buff, 1));
294
Please client to send scrambled_password in old format.
296
@param thd thread handle
304
bool send_old_password_request(THD *thd)
307
return my_net_write(net, eof_buff, 1) || net_flush(net);
311
void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
316
buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + MYSQL_ERRMSG_SIZE:512
318
uchar buff[2+1+SQLSTATE_LENGTH+MYSQL_ERRMSG_SIZE], *pos;
320
DBUG_ENTER("send_error_packet");
264
322
if (net->vio == 0)
326
/* In bootstrap it's ok to print on stderr */
327
fprintf(stderr,"ERROR: %d %s\n",sql_errno,err);
269
332
int2store(buff,sql_errno);
272
/* The first # is to make the protocol backward compatible */
274
pos= (unsigned char*) my_stpcpy((char*) buff+3, drizzle_errno_to_sqlstate(sql_errno));
276
length= (uint) (strmake((char*) pos, err, DRIZZLE_ERRMSG_SIZE-1) -
334
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
336
/* The first # is to make the protocol backward compatible */
338
pos= (uchar*) strmov((char*) buff+3, mysql_errno_to_sqlstate(sql_errno));
340
length= (uint) (strmake((char*) pos, err, MYSQL_ERRMSG_SIZE-1) -
278
342
err= (char*) buff;
280
net_write_command(net,(unsigned char) 255, (unsigned char*) "", 0, (unsigned char*) err, length);
344
VOID(net_write_command(net,(uchar) 255, (uchar*) "", 0, (uchar*) err,
404
469
/* The following will only be used for short strings < 65K */
406
unsigned char *net_store_data(unsigned char *to, const unsigned char *from, size_t length)
471
uchar *net_store_data(uchar *to, const uchar *from, size_t length)
408
473
to=net_store_length_fast(to,length);
409
474
memcpy(to,from,length);
410
475
return to+length;
413
unsigned char *net_store_data(unsigned char *to,int32_t from)
478
uchar *net_store_data(uchar *to,int32 from)
416
uint32_t length=(uint) (int10_to_str(from,buff,10)-buff);
481
uint length=(uint) (int10_to_str(from,buff,10)-buff);
417
482
to=net_store_length_fast(to,length);
418
483
memcpy(to,buff,length);
419
484
return to+length;
422
unsigned char *net_store_data(unsigned char *to,int64_t from)
487
uchar *net_store_data(uchar *to,longlong from)
425
uint32_t length=(uint) (int64_t10_to_str(from,buff,10)-buff);
490
uint length=(uint) (longlong10_to_str(from,buff,10)-buff);
426
491
to=net_store_length_fast(to,length);
427
492
memcpy(to,buff,length);
428
493
return to+length;
476
544
1 Error (Note that in this case the error is not sent to the
479
bool Protocol::send_fields(List<Item> *list, uint32_t flags)
547
bool Protocol::send_fields(List<Item> *list, uint flags)
481
549
List_iterator_fast<Item> it(*list);
483
unsigned char buff[80];
484
552
String tmp((char*) buff,sizeof(buff),&my_charset_bin);
485
553
Protocol_text prot(thd);
486
554
String *local_packet= prot.storage_packet();
487
const CHARSET_INFO * const thd_charset= thd->variables.character_set_results;
555
CHARSET_INFO *thd_charset= thd->variables.character_set_results;
556
DBUG_ENTER("send_fields");
489
558
if (flags & SEND_NUM_ROWS)
490
559
{ // Packet with number of elements
491
unsigned char *pos= net_store_length(buff, list->elements);
560
uchar *pos= net_store_length(buff, list->elements);
492
561
(void) my_net_write(&thd->net, buff, (size_t) (pos-buff));
565
field_types= (enum_field_types*) thd->alloc(sizeof(field_types) *
495
570
while ((item=it++))
498
const CHARSET_INFO * const cs= system_charset_info;
573
CHARSET_INFO *cs= system_charset_info;
499
574
Send_field field;
500
575
item->make_field(&field);
577
/* Keep things compatible for old clients */
578
if (field.type == MYSQL_TYPE_VARCHAR)
579
field.type= MYSQL_TYPE_VAR_STRING;
502
581
prot.prepare_for_resend();
505
if (prot.store(STRING_WITH_LEN("def"), cs, thd_charset) ||
506
prot.store(field.db_name, (uint) strlen(field.db_name),
508
prot.store(field.table_name, (uint) strlen(field.table_name),
510
prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
512
prot.store(field.col_name, (uint) strlen(field.col_name),
514
prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
516
local_packet->realloc(local_packet->length()+12))
519
/* Store fixed length fields */
520
pos= (char*) local_packet->ptr()+local_packet->length();
521
*pos++= 12; // Length of packed fields
522
if (item->collation.collation == &my_charset_bin || thd_charset == NULL)
583
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
525
int2store(pos, field.charsetnr);
526
int4store(pos+2, field.length);
585
if (prot.store(STRING_WITH_LEN("def"), cs, thd_charset) ||
586
prot.store(field.db_name, (uint) strlen(field.db_name),
588
prot.store(field.table_name, (uint) strlen(field.table_name),
590
prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
592
prot.store(field.col_name, (uint) strlen(field.col_name),
594
prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
596
local_packet->realloc(local_packet->length()+12))
598
/* Store fixed length fields */
599
pos= (char*) local_packet->ptr()+local_packet->length();
600
*pos++= 12; // Length of packed fields
601
if (item->collation.collation == &my_charset_bin || thd_charset == NULL)
604
int2store(pos, field.charsetnr);
605
int4store(pos+2, field.length);
609
/* With conversion */
611
int2store(pos, thd_charset->number);
613
For TEXT/BLOB columns, field_length describes the maximum data
614
length in bytes. There is no limit to the number of characters
615
that a TEXT column can store, as long as the data fits into
616
the designated space.
617
For the rest of textual columns, field_length is evaluated as
618
char_count * mbmaxlen, where character count is taken from the
619
definition of the column. In other words, the maximum number
620
of characters here is limited by the column definition.
622
max_char_len= (field.type >= (int) MYSQL_TYPE_TINY_BLOB &&
623
field.type <= (int) MYSQL_TYPE_BLOB) ?
624
field.length / item->collation.collation->mbminlen :
625
field.length / item->collation.collation->mbmaxlen;
626
int4store(pos+2, max_char_len * thd_charset->mbmaxlen);
629
int2store(pos+7,field.flags);
630
pos[9]= (char) field.decimals;
631
pos[10]= 0; // For the future
632
pos[11]= 0; // For the future
530
/* With conversion */
531
uint32_t max_char_len;
532
int2store(pos, thd_charset->number);
534
For TEXT/BLOB columns, field_length describes the maximum data
535
length in bytes. There is no limit to the number of characters
536
that a TEXT column can store, as long as the data fits into
537
the designated space.
538
For the rest of textual columns, field_length is evaluated as
539
char_count * mbmaxlen, where character count is taken from the
540
definition of the column. In other words, the maximum number
541
of characters here is limited by the column definition.
543
max_char_len= field.length / item->collation.collation->mbmaxlen;
544
int4store(pos+2, max_char_len * thd_charset->mbmaxlen);
637
if (prot.store(field.table_name, (uint) strlen(field.table_name),
639
prot.store(field.col_name, (uint) strlen(field.col_name),
641
local_packet->realloc(local_packet->length()+10))
643
pos= (char*) local_packet->ptr()+local_packet->length();
645
#ifdef TO_BE_DELETED_IN_6
646
if (!(thd->client_capabilities & CLIENT_LONG_FLAG))
649
int3store(pos+1,field.length);
653
pos[7]= (char) field.flags;
654
pos[8]= (char) field.decimals;
661
int3store(pos+1,field.length);
665
int2store(pos+7,field.flags);
666
pos[9]= (char) field.decimals;
547
int2store(pos+7,field.flags);
548
pos[9]= (char) field.decimals;
549
pos[10]= 0; // For the future
550
pos[11]= 0; // For the future
553
670
local_packet->length((uint) (pos - local_packet->ptr()));
554
671
if (flags & SEND_DEFAULTS)
555
672
item->send(&prot, &tmp); // Send default value
556
673
if (prot.write())
557
674
break; /* purecov: inspected */
676
field_types[count++]= field.type;
560
680
if (flags & SEND_EOF)
665
791
tocs != &my_charset_bin)
667
793
/* Store with conversion */
668
return net_store_data((unsigned char*) from, length, fromcs, tocs);
794
return net_store_data((uchar*) from, length, fromcs, tocs);
670
796
/* Store without conversion */
671
return net_store_data((unsigned char*) from, length);
675
bool Protocol_text::store(const char *from, size_t length,
676
const CHARSET_INFO * const fromcs,
677
const CHARSET_INFO * const tocs)
679
return store_string_aux(from, length, fromcs, tocs);
683
bool Protocol_text::store(const char *from, size_t length,
684
const CHARSET_INFO * const fromcs)
686
const CHARSET_INFO * const tocs= this->thd->variables.character_set_results;
687
return store_string_aux(from, length, fromcs, tocs);
691
bool Protocol_text::store_tiny(int64_t from)
797
return net_store_data((uchar*) from, length);
801
bool Protocol_text::store(const char *from, size_t length,
802
CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
805
DBUG_ASSERT(field_types == 0 ||
806
field_types[field_pos] == MYSQL_TYPE_DECIMAL ||
807
field_types[field_pos] == MYSQL_TYPE_BIT ||
808
field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL ||
809
(field_types[field_pos] >= MYSQL_TYPE_ENUM &&
810
field_types[field_pos] <= MYSQL_TYPE_GEOMETRY));
813
return store_string_aux(from, length, fromcs, tocs);
817
bool Protocol_text::store(const char *from, size_t length,
818
CHARSET_INFO *fromcs)
820
CHARSET_INFO *tocs= this->thd->variables.character_set_results;
822
DBUG_ASSERT(field_types == 0 ||
823
field_types[field_pos] == MYSQL_TYPE_DECIMAL ||
824
field_types[field_pos] == MYSQL_TYPE_BIT ||
825
field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL ||
826
field_types[field_pos] == MYSQL_TYPE_NEWDATE ||
827
(field_types[field_pos] >= MYSQL_TYPE_ENUM &&
828
field_types[field_pos] <= MYSQL_TYPE_GEOMETRY));
831
return store_string_aux(from, length, fromcs, tocs);
835
bool Protocol_text::store_tiny(longlong from)
838
DBUG_ASSERT(field_types == 0 || field_types[field_pos] == MYSQL_TYPE_TINY);
694
return net_store_data((unsigned char*) buff,
842
return net_store_data((uchar*) buff,
695
843
(size_t) (int10_to_str((int) from, buff, -10) - buff));
699
bool Protocol_text::store_short(int64_t from)
847
bool Protocol_text::store_short(longlong from)
850
DBUG_ASSERT(field_types == 0 ||
851
field_types[field_pos] == MYSQL_TYPE_YEAR ||
852
field_types[field_pos] == MYSQL_TYPE_SHORT);
702
return net_store_data((unsigned char*) buff,
856
return net_store_data((uchar*) buff,
703
857
(size_t) (int10_to_str((int) from, buff, -10) -
708
bool Protocol_text::store_long(int64_t from)
862
bool Protocol_text::store_long(longlong from)
865
DBUG_ASSERT(field_types == 0 ||
866
field_types[field_pos] == MYSQL_TYPE_INT24 ||
867
field_types[field_pos] == MYSQL_TYPE_LONG);
711
return net_store_data((unsigned char*) buff,
871
return net_store_data((uchar*) buff,
712
872
(size_t) (int10_to_str((long int)from, buff,
713
873
(from <0)?-10:10)-buff));
717
bool Protocol_text::store_int64_t(int64_t from, bool unsigned_flag)
877
bool Protocol_text::store_longlong(longlong from, bool unsigned_flag)
880
DBUG_ASSERT(field_types == 0 ||
881
field_types[field_pos] == MYSQL_TYPE_LONGLONG);
720
return net_store_data((unsigned char*) buff,
721
(size_t) (int64_t10_to_str(from,buff,
885
return net_store_data((uchar*) buff,
886
(size_t) (longlong10_to_str(from,buff,
722
887
unsigned_flag ? 10 : -10)-
727
892
bool Protocol_text::store_decimal(const my_decimal *d)
895
DBUG_ASSERT(field_types == 0 ||
896
field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL);
729
899
char buff[DECIMAL_MAX_STR_LENGTH];
730
900
String str(buff, sizeof(buff), &my_charset_bin);
731
901
(void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
732
return net_store_data((unsigned char*) str.ptr(), str.length());
902
return net_store_data((uchar*) str.ptr(), str.length());
736
bool Protocol_text::store(float from, uint32_t decimals, String *buffer)
906
bool Protocol_text::store(float from, uint32 decimals, String *buffer)
909
DBUG_ASSERT(field_types == 0 ||
910
field_types[field_pos] == MYSQL_TYPE_FLOAT);
738
913
buffer->set_real((double) from, decimals, thd->charset());
739
return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
914
return net_store_data((uchar*) buffer->ptr(), buffer->length());
743
bool Protocol_text::store(double from, uint32_t decimals, String *buffer)
918
bool Protocol_text::store(double from, uint32 decimals, String *buffer)
921
DBUG_ASSERT(field_types == 0 ||
922
field_types[field_pos] == MYSQL_TYPE_DOUBLE);
745
925
buffer->set_real(from, decimals, thd->charset());
746
return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
926
return net_store_data((uchar*) buffer->ptr(), buffer->length());
767
960
we support 0-6 decimals for time.
770
bool Protocol_text::store(DRIZZLE_TIME *tm)
963
bool Protocol_text::store(MYSQL_TIME *tm)
966
DBUG_ASSERT(field_types == 0 ||
967
field_types[field_pos] == MYSQL_TYPE_DATETIME ||
968
field_types[field_pos] == MYSQL_TYPE_TIMESTAMP);
774
length= sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d",
973
length= my_sprintf(buff,(buff, "%04d-%02d-%02d %02d:%02d:%02d",
779
978
(int) tm->minute,
781
980
if (tm->second_part)
782
length+= sprintf(buff+length, ".%06d",
783
(int)tm->second_part);
784
return net_store_data((unsigned char*) buff, length);
981
length+= my_sprintf(buff+length,(buff+length, ".%06d",
982
(int)tm->second_part));
983
return net_store_data((uchar*) buff, length);
788
bool Protocol_text::store_date(DRIZZLE_TIME *tm)
987
bool Protocol_text::store_date(MYSQL_TIME *tm)
990
DBUG_ASSERT(field_types == 0 ||
991
field_types[field_pos] == MYSQL_TYPE_DATE);
790
994
char buff[MAX_DATE_STRING_REP_LENGTH];
791
995
size_t length= my_date_to_str(tm, buff);
792
return net_store_data((unsigned char*) buff, length);
996
return net_store_data((uchar*) buff, length);