~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2003 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
/**
17
  @file
18
19
  Low level functions for storing data to be send to the MySQL client.
20
  The actual communction is handled by the net_xxx functions in net_serv.cc
21
*/
22
23
#ifdef USE_PRAGMA_IMPLEMENTATION
24
#pragma implementation				// gcc: Class implementation
25
#endif
26
27
#include "mysql_priv.h"
28
#include <stdarg.h>
29
30
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
31
/* Declared non-static only because of the embedded library. */
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);
35
static void write_eof_packet(THD *thd, NET *net,
36
                             uint server_status, uint total_warn_count);
37
38
bool Protocol::net_store_data(const uchar *from, size_t length)
39
{
40
  ulong packet_length=packet->length();
41
  /* 
42
     The +9 comes from that strings of length longer than 16M require
43
     9 bytes to be stored (see net_store_length).
44
  */
45
  if (packet_length+9+length > packet->alloced_length() &&
46
      packet->realloc(packet_length+9+length))
47
    return 1;
48
  uchar *to= net_store_length((uchar*) packet->ptr()+packet_length, length);
49
  memcpy(to,from,length);
50
  packet->length((uint) (to+length-(uchar*) packet->ptr()));
51
  return 0;
52
}
53
54
55
56
57
/*
58
  net_store_data() - extended version with character set conversion.
59
  
60
  It is optimized for short strings whose length after
61
  conversion is garanteed to be less than 251, which accupies
62
  exactly one byte to store length. It allows not to use
63
  the "convert" member as a temporary buffer, conversion
64
  is done directly to the "packet" member.
65
  The limit 251 is good enough to optimize send_fields()
66
  because column, table, database names fit into this limit.
67
*/
68
69
bool Protocol::net_store_data(const uchar *from, size_t length,
70
                              CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
71
{
72
  uint dummy_errors;
73
  /* Calculate maxumum possible result length */
74
  uint conv_length= to_cs->mbmaxlen * length / from_cs->mbminlen;
75
  if (conv_length > 250)
76
  {
77
    /*
78
      For strings with conv_length greater than 250 bytes
79
      we don't know how many bytes we will need to store length: one or two,
80
      because we don't know result length until conversion is done.
81
      For example, when converting from utf8 (mbmaxlen=3) to latin1,
82
      conv_length=300 means that the result length can vary between 100 to 300.
83
      length=100 needs one byte, length=300 needs to bytes.
84
      
85
      Thus conversion directly to "packet" is not worthy.
86
      Let's use "convert" as a temporary buffer.
87
    */
88
    return (convert->copy((const char*) from, length, from_cs,
89
                          to_cs, &dummy_errors) ||
90
            net_store_data((const uchar*) convert->ptr(), convert->length()));
91
  }
92
93
  ulong packet_length= packet->length();
94
  ulong new_length= packet_length + conv_length + 1;
95
96
  if (new_length > packet->alloced_length() && packet->realloc(new_length))
97
    return 1;
98
99
  char *length_pos= (char*) packet->ptr() + packet_length;
100
  char *to= length_pos + 1;
101
102
  to+= copy_and_convert(to, conv_length, to_cs,
103
                        (const char*) from, length, from_cs, &dummy_errors);
104
105
  net_store_length((uchar*) length_pos, to - length_pos - 1);
106
  packet->length((uint) (to - packet->ptr()));
107
  return 0;
108
}
109
110
111
/**
112
  Send a error string to client.
113
114
  Design note:
115
  net_printf_error and net_send_error are low-level functions
116
  that shall be used only when a new connection is being
117
  established or at server startup.
118
119
  For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
120
  critical that every error that can be intercepted is issued in one
121
  place only, my_message_sql.
122
*/
123
void net_send_error(THD *thd, uint sql_errno, const char *err)
124
{
125
  DBUG_ENTER("net_send_error");
126
127
  DBUG_ASSERT(sql_errno);
128
  DBUG_ASSERT(err && err[0]);
129
130
  DBUG_PRINT("enter",("sql_errno: %d  err: %s", sql_errno, err));
131
132
  /*
133
    It's one case when we can push an error even though there
134
    is an OK or EOF already.
135
  */
136
  thd->main_da.can_overwrite_status= TRUE;
137
138
  /* Abort multi-result sets */
139
  thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
140
141
  net_send_error_packet(thd, sql_errno, err);
142
143
  thd->main_da.can_overwrite_status= FALSE;
144
145
  DBUG_VOID_RETURN;
146
}
147
148
/**
149
  Return ok to the client.
150
151
  The ok packet has the following structure:
152
153
  - 0               : Marker (1 byte)
154
  - affected_rows	: Stored in 1-9 bytes
155
  - id		: Stored in 1-9 bytes
156
  - server_status	: Copy of thd->server_status;  Can be used by client
157
  to check if we are inside an transaction.
158
  New in 4.0 protocol
159
  - warning_count	: Stored in 2 bytes; New in 4.1 protocol
160
  - message		: Stored as packed length (1-9 bytes) + message.
161
  Is not stored if no message.
162
163
  @param thd		   Thread handler
164
  @param affected_rows	   Number of rows changed by statement
165
  @param id		   Auto_increment id for first row (if used)
166
  @param message	   Message to send to the client (Used by mysql_status)
167
*/
168
169
void
170
net_send_ok(THD *thd,
171
            uint server_status, uint total_warn_count,
172
            ha_rows affected_rows, ulonglong id, const char *message)
173
{
174
  NET *net= &thd->net;
175
  uchar buff[MYSQL_ERRMSG_SIZE+10],*pos;
176
  DBUG_ENTER("my_ok");
177
178
  if (! net->vio)	// hack for re-parsing queries
179
  {
180
    DBUG_PRINT("info", ("vio present: NO"));
181
    DBUG_VOID_RETURN;
182
  }
183
184
  buff[0]=0;					// No fields
185
  pos=net_store_length(buff+1,affected_rows);
186
  pos=net_store_length(pos, id);
187
  if (thd->client_capabilities & CLIENT_PROTOCOL_41)
188
  {
189
    DBUG_PRINT("info",
190
	       ("affected_rows: %lu  id: %lu  status: %u  warning_count: %u",
191
		(ulong) affected_rows,		
192
		(ulong) id,
193
		(uint) (server_status & 0xffff),
194
		(uint) total_warn_count));
195
    int2store(pos, server_status);
196
    pos+=2;
197
198
    /* We can only return up to 65535 warnings in two bytes */
199
    uint tmp= min(total_warn_count, 65535);
200
    int2store(pos, tmp);
201
    pos+= 2;
202
  }
203
  else if (net->return_status)			// For 4.0 protocol
204
  {
205
    int2store(pos, server_status);
206
    pos+=2;
207
  }
208
  thd->main_da.can_overwrite_status= TRUE;
209
210
  if (message && message[0])
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));
214
215
  thd->main_da.can_overwrite_status= FALSE;
216
  DBUG_PRINT("info", ("OK sent, so no more error sending allowed"));
217
218
  DBUG_VOID_RETURN;
219
}
220
221
static uchar eof_buff[1]= { (uchar) 254 };      /* Marker for end of fields */
222
223
/**
224
  Send eof (= end of result set) to the client.
225
226
  The eof packet has the following structure:
227
228
  - 254		: Marker (1 byte)
229
  - warning_count	: Stored in 2 bytes; New in 4.1 protocol
230
  - status_flag	: Stored in 2 bytes;
231
  For flags like SERVER_MORE_RESULTS_EXISTS.
232
233
  Note that the warning count will not be sent if 'no_flush' is set as
234
  we don't want to report the warning count until all data is sent to the
235
  client.
236
237
  @param thd		Thread handler
238
  @param no_flush	Set to 1 if there will be more data to the client,
239
                    like in send_fields().
240
*/    
241
242
void
243
net_send_eof(THD *thd, uint server_status, uint total_warn_count)
244
{
245
  NET *net= &thd->net;
246
  DBUG_ENTER("net_send_eof");
247
  /* Set to TRUE if no active vio, to work well in case of --init-file */
248
  if (net->vio != 0)
249
  {
250
    thd->main_da.can_overwrite_status= TRUE;
251
    write_eof_packet(thd, net, server_status, total_warn_count);
252
    VOID(net_flush(net));
253
    thd->main_da.can_overwrite_status= FALSE;
254
    DBUG_PRINT("info", ("EOF sent, so no more error sending allowed"));
255
  }
256
  DBUG_VOID_RETURN;
257
}
258
259
260
/**
261
  Format EOF packet according to the current protocol and
262
  write it to the network output buffer.
263
*/
264
265
static void write_eof_packet(THD *thd, NET *net,
266
                             uint server_status,
267
                             uint total_warn_count)
268
{
269
  if (thd->client_capabilities & CLIENT_PROTOCOL_41)
270
  {
271
    uchar buff[5];
272
    /*
273
      Don't send warn count during SP execution, as the warn_list
274
      is cleared between substatements, and mysqltest gets confused
275
    */
276
    uint tmp= min(total_warn_count, 65535);
277
    buff[0]= 254;
278
    int2store(buff+1, tmp);
279
    /*
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)
283
    */
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));
288
  }
289
  else
290
    VOID(my_net_write(net, eof_buff, 1));
291
}
292
293
/**
294
  Please client to send scrambled_password in old format.
295
     
296
  @param thd thread handle
297
298
  @retval
299
    0  ok
300
  @retval
301
   !0  error
302
*/
303
304
bool send_old_password_request(THD *thd)
305
{
306
  NET *net= &thd->net;
307
  return my_net_write(net, eof_buff, 1) || net_flush(net);
308
}
309
310
311
void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
312
{
313
  NET *net= &thd->net;
314
  uint length;
315
  /*
316
    buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + MYSQL_ERRMSG_SIZE:512
317
  */
318
  uchar buff[2+1+SQLSTATE_LENGTH+MYSQL_ERRMSG_SIZE], *pos;
319
320
  DBUG_ENTER("send_error_packet");
321
322
  if (net->vio == 0)
323
  {
324
    if (thd->bootstrap)
325
    {
326
      /* In bootstrap it's ok to print on stderr */
327
      fprintf(stderr,"ERROR: %d  %s\n",sql_errno,err);
328
    }
329
    DBUG_VOID_RETURN;
330
  }
331
332
  int2store(buff,sql_errno);
333
  pos= buff+2;
334
  if (thd->client_capabilities & CLIENT_PROTOCOL_41)
335
  {
336
    /* The first # is to make the protocol backward compatible */
337
    buff[2]= '#';
338
    pos= (uchar*) strmov((char*) buff+3, mysql_errno_to_sqlstate(sql_errno));
339
  }
340
  length= (uint) (strmake((char*) pos, err, MYSQL_ERRMSG_SIZE-1) -
341
                  (char*) buff);
342
  err= (char*) buff;
343
344
  VOID(net_write_command(net,(uchar) 255, (uchar*) "", 0, (uchar*) err,
345
                         length));
346
  DBUG_VOID_RETURN;
347
}
348
349
350
/**
351
  Faster net_store_length when we know that length is less than 65536.
352
  We keep a separate version for that range because it's widely used in
353
  libmysql.
354
355
  uint is used as agrument type because of MySQL type conventions:
356
  - uint for 0..65536
357
  - ulong for 0..4294967296
358
  - ulonglong for bigger numbers.
359
*/
360
361
static uchar *net_store_length_fast(uchar *packet, uint length)
362
{
363
  if (length < 251)
364
  {
365
    *packet=(uchar) length;
366
    return packet+1;
367
  }
368
  *packet++=252;
369
  int2store(packet,(uint) length);
370
  return packet+2;
371
}
372
373
/**
374
  Send the status of the current statement execution over network.
375
376
  @param  thd   in fact, carries two parameters, NET for the transport and
377
                Diagnostics_area as the source of status information.
378
379
  In MySQL, there are two types of SQL statements: those that return
380
  a result set and those that return status information only.
381
382
  If a statement returns a result set, it consists of 3 parts:
383
  - result set meta-data
384
  - variable number of result set rows (can be 0)
385
  - followed and terminated by EOF or ERROR packet
386
387
  Once the  client has seen the meta-data information, it always
388
  expects an EOF or ERROR to terminate the result set. If ERROR is
389
  received, the result set rows are normally discarded (this is up
390
  to the client implementation, libmysql at least does discard them).
391
  EOF, on the contrary, means "successfully evaluated the entire
392
  result set". Since we don't know how many rows belong to a result
393
  set until it's evaluated, EOF/ERROR is the indicator of the end
394
  of the row stream. Note, that we can not buffer result set rows
395
  on the server -- there may be an arbitrary number of rows. But
396
  we do buffer the last packet (EOF/ERROR) in the Diagnostics_area and
397
  delay sending it till the very end of execution (here), to be able to
398
  change EOF to an ERROR if commit failed or some other error occurred
399
  during the last cleanup steps taken after execution.
400
401
  A statement that does not return a result set doesn't send result
402
  set meta-data either. Instead it returns one of:
403
  - OK packet
404
  - ERROR packet.
405
  Similarly to the EOF/ERROR of the previous statement type, OK/ERROR
406
  packet is "buffered" in the diagnostics area and sent to the client
407
  in the end of statement.
408
409
  @pre  The diagnostics area is assigned or disabled. It can not be empty
410
        -- we assume that every SQL statement or COM_* command
411
        generates OK, ERROR, or EOF status.
412
413
  @post The status information is encoded to protocol format and sent to the
414
        client.
415
416
  @return We conventionally return void, since the only type of error
417
          that can happen here is a NET (transport) error, and that one
418
          will become visible when we attempt to read from the NET the
419
          next command.
420
          Diagnostics_area::is_sent is set for debugging purposes only.
421
*/
422
423
void net_end_statement(THD *thd)
424
{
425
  DBUG_ASSERT(! thd->main_da.is_sent);
426
427
  /* Can not be true, but do not take chances in production. */
428
  if (thd->main_da.is_sent)
429
    return;
430
431
  switch (thd->main_da.status()) {
432
  case Diagnostics_area::DA_ERROR:
433
    /* The query failed, send error to log and abort bootstrap. */
434
    net_send_error(thd,
435
                   thd->main_da.sql_errno(),
436
                   thd->main_da.message());
437
    break;
438
  case Diagnostics_area::DA_EOF:
439
    net_send_eof(thd,
440
                 thd->main_da.server_status(),
441
                 thd->main_da.total_warn_count());
442
    break;
443
  case Diagnostics_area::DA_OK:
444
    net_send_ok(thd,
445
                thd->main_da.server_status(),
446
                thd->main_da.total_warn_count(),
447
                thd->main_da.affected_rows(),
448
                thd->main_da.last_insert_id(),
449
                thd->main_da.message());
450
    break;
451
  case Diagnostics_area::DA_DISABLED:
452
    break;
453
  case Diagnostics_area::DA_EMPTY:
454
  default:
455
    DBUG_ASSERT(0);
456
    net_send_ok(thd, thd->server_status, thd->total_warn_count,
457
                0, 0, NULL);
458
    break;
459
  }
460
  thd->main_da.is_sent= TRUE;
461
}
462
463
464
/****************************************************************************
465
  Functions used by the protocol functions (like net_send_ok) to store
466
  strings and numbers in the header result packet.
467
****************************************************************************/
468
469
/* The following will only be used for short strings < 65K */
470
471
uchar *net_store_data(uchar *to, const uchar *from, size_t length)
472
{
473
  to=net_store_length_fast(to,length);
474
  memcpy(to,from,length);
475
  return to+length;
476
}
477
478
uchar *net_store_data(uchar *to,int32 from)
479
{
480
  char buff[20];
481
  uint length=(uint) (int10_to_str(from,buff,10)-buff);
482
  to=net_store_length_fast(to,length);
483
  memcpy(to,buff,length);
484
  return to+length;
485
}
486
487
uchar *net_store_data(uchar *to,longlong from)
488
{
489
  char buff[22];
490
  uint length=(uint) (longlong10_to_str(from,buff,10)-buff);
491
  to=net_store_length_fast(to,length);
492
  memcpy(to,buff,length);
493
  return to+length;
494
}
495
496
497
/*****************************************************************************
498
  Default Protocol functions
499
*****************************************************************************/
500
501
void Protocol::init(THD *thd_arg)
502
{
503
  thd=thd_arg;
504
  packet= &thd->packet;
505
  convert= &thd->convert_buffer;
506
#ifndef DBUG_OFF
507
  field_types= 0;
508
#endif
509
}
510
511
/**
512
  Finish the result set with EOF packet, as is expected by the client,
513
  if there is an error evaluating the next row and a continue handler
514
  for the error.
515
*/
516
517
void Protocol::end_partial_result_set(THD *thd)
518
{
519
  net_send_eof(thd, thd->server_status, 0 /* no warnings, we're inside SP */);
520
}
521
522
523
bool Protocol::flush()
524
{
525
  return net_flush(&thd->net);
526
}
527
528
529
/**
530
  Send name and type of result to client.
531
532
  Sum fields has table name empty and field_name.
533
534
  @param THD		Thread data object
535
  @param list	        List of items to send to client
536
  @param flag	        Bit mask with the following functions:
537
                        - 1 send number of rows
538
                        - 2 send default values
539
                        - 4 don't write eof packet
540
541
  @retval
542
    0	ok
543
  @retval
544
    1	Error  (Note that in this case the error is not sent to the
545
    client)
546
*/
547
bool Protocol::send_fields(List<Item> *list, uint flags)
548
{
549
  List_iterator_fast<Item> it(*list);
550
  Item *item;
551
  uchar buff[80];
552
  String tmp((char*) buff,sizeof(buff),&my_charset_bin);
553
  Protocol_text prot(thd);
554
  String *local_packet= prot.storage_packet();
555
  CHARSET_INFO *thd_charset= thd->variables.character_set_results;
556
  DBUG_ENTER("send_fields");
557
558
  if (flags & SEND_NUM_ROWS)
559
  {				// Packet with number of elements
560
    uchar *pos= net_store_length(buff, list->elements);
561
    (void) my_net_write(&thd->net, buff, (size_t) (pos-buff));
562
  }
563
564
#ifndef DBUG_OFF
565
  field_types= (enum_field_types*) thd->alloc(sizeof(field_types) *
566
					      list->elements);
567
  uint count= 0;
568
#endif
569
570
  while ((item=it++))
571
  {
572
    char *pos;
573
    CHARSET_INFO *cs= system_charset_info;
574
    Send_field field;
575
    item->make_field(&field);
576
577
    /* Keep things compatible for old clients */
578
    if (field.type == MYSQL_TYPE_VARCHAR)
579
      field.type= MYSQL_TYPE_VAR_STRING;
580
581
    prot.prepare_for_resend();
582
583
    if (thd->client_capabilities & CLIENT_PROTOCOL_41)
584
    {
585
      if (prot.store(STRING_WITH_LEN("def"), cs, thd_charset) ||
586
	  prot.store(field.db_name, (uint) strlen(field.db_name),
587
		     cs, thd_charset) ||
588
	  prot.store(field.table_name, (uint) strlen(field.table_name),
589
		     cs, thd_charset) ||
590
	  prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
591
		     cs, thd_charset) ||
592
	  prot.store(field.col_name, (uint) strlen(field.col_name),
593
		     cs, thd_charset) ||
594
	  prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
595
		     cs, thd_charset) ||
596
	  local_packet->realloc(local_packet->length()+12))
597
	goto err;
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)
602
      {
603
        /* No conversion */
604
        int2store(pos, field.charsetnr);
605
        int4store(pos+2, field.length);
606
      }
607
      else
608
      {
609
        /* With conversion */
610
        uint max_char_len;
611
        int2store(pos, thd_charset->number);
612
        /*
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.
621
        */
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);
627
      }
628
      pos[6]= field.type;
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
633
      pos+= 12;
634
    }
635
    else
636
    {
637
      if (prot.store(field.table_name, (uint) strlen(field.table_name),
638
		     cs, thd_charset) ||
639
	  prot.store(field.col_name, (uint) strlen(field.col_name),
640
		     cs, thd_charset) ||
641
	  local_packet->realloc(local_packet->length()+10))
642
	goto err;
643
      pos= (char*) local_packet->ptr()+local_packet->length();
644
645
#ifdef TO_BE_DELETED_IN_6
646
      if (!(thd->client_capabilities & CLIENT_LONG_FLAG))
647
      {
648
	pos[0]=3;
649
	int3store(pos+1,field.length);
650
	pos[4]=1;
651
	pos[5]=field.type;
652
	pos[6]=2;
653
	pos[7]= (char) field.flags;
654
	pos[8]= (char) field.decimals;
655
	pos+= 9;
656
      }
657
      else
658
#endif
659
      {
660
	pos[0]=3;
661
	int3store(pos+1,field.length);
662
	pos[4]=1;
663
	pos[5]=field.type;
664
	pos[6]=3;
665
	int2store(pos+7,field.flags);
666
	pos[9]= (char) field.decimals;
667
	pos+= 10;
668
      }
669
    }
670
    local_packet->length((uint) (pos - local_packet->ptr()));
671
    if (flags & SEND_DEFAULTS)
672
      item->send(&prot, &tmp);			// Send default value
673
    if (prot.write())
674
      break;					/* purecov: inspected */
675
#ifndef DBUG_OFF
676
    field_types[count++]= field.type;
677
#endif
678
  }
679
680
  if (flags & SEND_EOF)
681
  {
682
    /*
683
      Mark the end of meta-data result set, and store thd->server_status,
684
      to show that there is no cursor.
685
      Send no warning information, as it will be sent at statement end.
686
    */
687
    write_eof_packet(thd, &thd->net, thd->server_status, thd->total_warn_count);
688
  }
689
  DBUG_RETURN(prepare_for_send(list));
690
691
err:
692
  my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES),
693
             MYF(0));	/* purecov: inspected */
694
  DBUG_RETURN(1);				/* purecov: inspected */
695
}
696
697
698
bool Protocol::write()
699
{
700
  DBUG_ENTER("Protocol::write");
701
  DBUG_RETURN(my_net_write(&thd->net, (uchar*) packet->ptr(),
702
                           packet->length()));
703
}
704
705
706
/**
707
  Send \\0 end terminated string.
708
709
  @param from	NullS or \\0 terminated string
710
711
  @note
712
    In most cases one should use store(from, length) instead of this function
713
714
  @retval
715
    0		ok
716
  @retval
717
    1		error
718
*/
719
720
bool Protocol::store(const char *from, CHARSET_INFO *cs)
721
{
722
  if (!from)
723
    return store_null();
724
  uint length= strlen(from);
725
  return store(from, length, cs);
726
}
727
728
729
/**
730
  Send a set of strings as one long string with ',' in between.
731
*/
732
733
bool Protocol::store(I_List<i_string>* str_list)
734
{
735
  char buf[256];
736
  String tmp(buf, sizeof(buf), &my_charset_bin);
737
  uint32 len;
738
  I_List_iterator<i_string> it(*str_list);
739
  i_string* s;
740
741
  tmp.length(0);
742
  while ((s=it++))
743
  {
744
    tmp.append(s->ptr);
745
    tmp.append(',');
746
  }
747
  if ((len= tmp.length()))
748
    len--;					// Remove last ','
749
  return store((char*) tmp.ptr(), len,  tmp.charset());
750
}
751
752
753
/****************************************************************************
754
  Functions to handle the simple (default) protocol where everything is
755
  This protocol is the one that is used by default between the MySQL server
756
  and client when you are not using prepared statements.
757
758
  All data are sent as 'packed-string-length' followed by 'string-data'
759
****************************************************************************/
760
761
void Protocol_text::prepare_for_resend()
762
{
763
  packet->length(0);
764
#ifndef DBUG_OFF
765
  field_pos= 0;
766
#endif
767
}
768
769
bool Protocol_text::store_null()
770
{
771
#ifndef DBUG_OFF
772
  field_pos++;
773
#endif
774
  char buff[1];
775
  buff[0]= (char)251;
776
  return packet->append(buff, sizeof(buff), PACKET_BUFFER_EXTRA_ALLOC);
777
}
778
779
780
/**
781
  Auxilary function to convert string to the given character set
782
  and store in network buffer.
783
*/
784
785
bool Protocol::store_string_aux(const char *from, size_t length,
786
                                CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
787
{
788
  /* 'tocs' is set 0 when client issues SET character_set_results=NULL */
789
  if (tocs && !my_charset_same(fromcs, tocs) &&
790
      fromcs != &my_charset_bin &&
791
      tocs != &my_charset_bin)
792
  {
793
    /* Store with conversion */
794
    return net_store_data((uchar*) from, length, fromcs, tocs);
795
  }
796
  /* Store without conversion */
797
  return net_store_data((uchar*) from, length);
798
}
799
800
801
bool Protocol_text::store(const char *from, size_t length,
802
                          CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
803
{
804
#ifndef DBUG_OFF
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));
811
  field_pos++;
812
#endif
813
  return store_string_aux(from, length, fromcs, tocs);
814
}
815
816
817
bool Protocol_text::store(const char *from, size_t length,
818
                          CHARSET_INFO *fromcs)
819
{
820
  CHARSET_INFO *tocs= this->thd->variables.character_set_results;
821
#ifndef DBUG_OFF
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));
829
  field_pos++;
830
#endif
831
  return store_string_aux(from, length, fromcs, tocs);
832
}
833
834
835
bool Protocol_text::store_tiny(longlong from)
836
{
837
#ifndef DBUG_OFF
838
  DBUG_ASSERT(field_types == 0 || field_types[field_pos] == MYSQL_TYPE_TINY);
839
  field_pos++;
840
#endif
841
  char buff[20];
842
  return net_store_data((uchar*) buff,
843
			(size_t) (int10_to_str((int) from, buff, -10) - buff));
844
}
845
846
847
bool Protocol_text::store_short(longlong from)
848
{
849
#ifndef DBUG_OFF
850
  DBUG_ASSERT(field_types == 0 ||
851
	      field_types[field_pos] == MYSQL_TYPE_YEAR ||
852
	      field_types[field_pos] == MYSQL_TYPE_SHORT);
853
  field_pos++;
854
#endif
855
  char buff[20];
856
  return net_store_data((uchar*) buff,
857
			(size_t) (int10_to_str((int) from, buff, -10) -
858
                                  buff));
859
}
860
861
862
bool Protocol_text::store_long(longlong from)
863
{
864
#ifndef DBUG_OFF
865
  DBUG_ASSERT(field_types == 0 ||
866
              field_types[field_pos] == MYSQL_TYPE_INT24 ||
867
              field_types[field_pos] == MYSQL_TYPE_LONG);
868
  field_pos++;
869
#endif
870
  char buff[20];
871
  return net_store_data((uchar*) buff,
872
			(size_t) (int10_to_str((long int)from, buff,
873
                                               (from <0)?-10:10)-buff));
874
}
875
876
877
bool Protocol_text::store_longlong(longlong from, bool unsigned_flag)
878
{
879
#ifndef DBUG_OFF
880
  DBUG_ASSERT(field_types == 0 ||
881
	      field_types[field_pos] == MYSQL_TYPE_LONGLONG);
882
  field_pos++;
883
#endif
884
  char buff[22];
885
  return net_store_data((uchar*) buff,
886
			(size_t) (longlong10_to_str(from,buff,
887
                                                    unsigned_flag ? 10 : -10)-
888
                                  buff));
889
}
890
891
892
bool Protocol_text::store_decimal(const my_decimal *d)
893
{
894
#ifndef DBUG_OFF
895
  DBUG_ASSERT(field_types == 0 ||
896
              field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL);
897
  field_pos++;
898
#endif
899
  char buff[DECIMAL_MAX_STR_LENGTH];
900
  String str(buff, sizeof(buff), &my_charset_bin);
901
  (void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
902
  return net_store_data((uchar*) str.ptr(), str.length());
903
}
904
905
906
bool Protocol_text::store(float from, uint32 decimals, String *buffer)
907
{
908
#ifndef DBUG_OFF
909
  DBUG_ASSERT(field_types == 0 ||
910
	      field_types[field_pos] == MYSQL_TYPE_FLOAT);
911
  field_pos++;
912
#endif
913
  buffer->set_real((double) from, decimals, thd->charset());
914
  return net_store_data((uchar*) buffer->ptr(), buffer->length());
915
}
916
917
918
bool Protocol_text::store(double from, uint32 decimals, String *buffer)
919
{
920
#ifndef DBUG_OFF
921
  DBUG_ASSERT(field_types == 0 ||
922
	      field_types[field_pos] == MYSQL_TYPE_DOUBLE);
923
  field_pos++;
924
#endif
925
  buffer->set_real(from, decimals, thd->charset());
926
  return net_store_data((uchar*) buffer->ptr(), buffer->length());
927
}
928
929
930
bool Protocol_text::store(Field *field)
931
{
932
  if (field->is_null())
933
    return store_null();
934
#ifndef DBUG_OFF
935
  field_pos++;
936
#endif
937
  char buff[MAX_FIELD_WIDTH];
938
  String str(buff,sizeof(buff), &my_charset_bin);
939
  CHARSET_INFO *tocs= this->thd->variables.character_set_results;
940
#ifndef DBUG_OFF
941
  TABLE *table= field->table;
942
  my_bitmap_map *old_map= 0;
943
  if (table->file)
944
    old_map= dbug_tmp_use_all_columns(table, table->read_set);
945
#endif
946
947
  field->val_str(&str);
948
#ifndef DBUG_OFF
949
  if (old_map)
950
    dbug_tmp_restore_column_map(table->read_set, old_map);
951
#endif
952
953
  return store_string_aux(str.ptr(), str.length(), str.charset(), tocs);
954
}
955
956
957
/**
958
  @todo
959
    Second_part format ("%06") needs to change when 
960
    we support 0-6 decimals for time.
961
*/
962
963
bool Protocol_text::store(MYSQL_TIME *tm)
964
{
965
#ifndef DBUG_OFF
966
  DBUG_ASSERT(field_types == 0 ||
967
	      field_types[field_pos] == MYSQL_TYPE_DATETIME ||
968
	      field_types[field_pos] == MYSQL_TYPE_TIMESTAMP);
969
  field_pos++;
970
#endif
971
  char buff[40];
972
  uint length;
973
  length= my_sprintf(buff,(buff, "%04d-%02d-%02d %02d:%02d:%02d",
974
			   (int) tm->year,
975
			   (int) tm->month,
976
			   (int) tm->day,
977
			   (int) tm->hour,
978
			   (int) tm->minute,
979
			   (int) tm->second));
980
  if (tm->second_part)
981
    length+= my_sprintf(buff+length,(buff+length, ".%06d",
982
                                     (int)tm->second_part));
983
  return net_store_data((uchar*) buff, length);
984
}
985
986
987
bool Protocol_text::store_date(MYSQL_TIME *tm)
988
{
989
#ifndef DBUG_OFF
990
  DBUG_ASSERT(field_types == 0 ||
991
	      field_types[field_pos] == MYSQL_TYPE_DATE);
992
  field_pos++;
993
#endif
994
  char buff[MAX_DATE_STRING_REP_LENGTH];
995
  size_t length= my_date_to_str(tm, buff);
996
  return net_store_data((uchar*) buff, length);
997
}
998
999
1000
/**
1001
  @todo 
1002
    Second_part format ("%06") needs to change when 
1003
    we support 0-6 decimals for time.
1004
*/
1005
1006
bool Protocol_text::store_time(MYSQL_TIME *tm)
1007
{
1008
#ifndef DBUG_OFF
1009
  DBUG_ASSERT(field_types == 0 ||
1010
	      field_types[field_pos] == MYSQL_TYPE_TIME);
1011
  field_pos++;
1012
#endif
1013
  char buff[40];
1014
  uint length;
1015
  uint day= (tm->year || tm->month) ? 0 : tm->day;
1016
  length= my_sprintf(buff,(buff, "%s%02ld:%02d:%02d",
1017
			   tm->neg ? "-" : "",
1018
			   (long) day*24L+(long) tm->hour,
1019
			   (int) tm->minute,
1020
			   (int) tm->second));
1021
  if (tm->second_part)
1022
    length+= my_sprintf(buff+length,(buff+length, ".%06d", (int)tm->second_part));
1023
  return net_store_data((uchar*) buff, length);
1024
}
1025