~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. */
202.1.17 by Monty Taylor
Patch from andrey - made some functions static as they are not used outside of protocol.cc.
32
static void net_send_error_packet(THD *thd, uint sql_errno, const char *err);
1 by brian
clean slate
33
static void write_eof_packet(THD *thd, NET *net,
34
                             uint server_status, uint total_warn_count);
35
36
bool Protocol::net_store_data(const uchar *from, size_t length)
37
{
38
  ulong packet_length=packet->length();
39
  /* 
40
     The +9 comes from that strings of length longer than 16M require
41
     9 bytes to be stored (see net_store_length).
42
  */
43
  if (packet_length+9+length > packet->alloced_length() &&
44
      packet->realloc(packet_length+9+length))
45
    return 1;
46
  uchar *to= net_store_length((uchar*) packet->ptr()+packet_length, length);
47
  memcpy(to,from,length);
48
  packet->length((uint) (to+length-(uchar*) packet->ptr()));
49
  return 0;
50
}
51
52
53
54
55
/*
56
  net_store_data() - extended version with character set conversion.
57
  
58
  It is optimized for short strings whose length after
59
  conversion is garanteed to be less than 251, which accupies
60
  exactly one byte to store length. It allows not to use
61
  the "convert" member as a temporary buffer, conversion
62
  is done directly to the "packet" member.
63
  The limit 251 is good enough to optimize send_fields()
64
  because column, table, database names fit into this limit.
65
*/
66
67
bool Protocol::net_store_data(const uchar *from, size_t length,
68
                              CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
69
{
70
  uint dummy_errors;
71
  /* Calculate maxumum possible result length */
72
  uint conv_length= to_cs->mbmaxlen * length / from_cs->mbminlen;
73
  if (conv_length > 250)
74
  {
75
    /*
76
      For strings with conv_length greater than 250 bytes
77
      we don't know how many bytes we will need to store length: one or two,
78
      because we don't know result length until conversion is done.
79
      For example, when converting from utf8 (mbmaxlen=3) to latin1,
80
      conv_length=300 means that the result length can vary between 100 to 300.
81
      length=100 needs one byte, length=300 needs to bytes.
82
      
83
      Thus conversion directly to "packet" is not worthy.
84
      Let's use "convert" as a temporary buffer.
85
    */
86
    return (convert->copy((const char*) from, length, from_cs,
87
                          to_cs, &dummy_errors) ||
88
            net_store_data((const uchar*) convert->ptr(), convert->length()));
89
  }
90
91
  ulong packet_length= packet->length();
92
  ulong new_length= packet_length + conv_length + 1;
93
94
  if (new_length > packet->alloced_length() && packet->realloc(new_length))
95
    return 1;
96
97
  char *length_pos= (char*) packet->ptr() + packet_length;
98
  char *to= length_pos + 1;
99
100
  to+= copy_and_convert(to, conv_length, to_cs,
101
                        (const char*) from, length, from_cs, &dummy_errors);
102
103
  net_store_length((uchar*) length_pos, to - length_pos - 1);
104
  packet->length((uint) (to - packet->ptr()));
105
  return 0;
106
}
107
108
109
/**
110
  Send a error string to client.
111
112
  Design note:
113
  net_printf_error and net_send_error are low-level functions
114
  that shall be used only when a new connection is being
115
  established or at server startup.
116
117
  For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
118
  critical that every error that can be intercepted is issued in one
119
  place only, my_message_sql.
120
*/
121
void net_send_error(THD *thd, uint sql_errno, const char *err)
122
{
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
123
  assert(sql_errno);
124
  assert(err && err[0]);
1 by brian
clean slate
125
126
  /*
127
    It's one case when we can push an error even though there
128
    is an OK or EOF already.
129
  */
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
130
  thd->main_da.can_overwrite_status= true;
1 by brian
clean slate
131
132
  /* Abort multi-result sets */
133
  thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
134
135
  net_send_error_packet(thd, sql_errno, err);
136
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
137
  thd->main_da.can_overwrite_status= false;
1 by brian
clean slate
138
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
139
  return;
1 by brian
clean slate
140
}
141
142
/**
143
  Return ok to the client.
144
145
  The ok packet has the following structure:
146
147
  - 0               : Marker (1 byte)
148
  - affected_rows	: Stored in 1-9 bytes
149
  - id		: Stored in 1-9 bytes
150
  - server_status	: Copy of thd->server_status;  Can be used by client
151
  to check if we are inside an transaction.
152
  New in 4.0 protocol
153
  - warning_count	: Stored in 2 bytes; New in 4.1 protocol
154
  - message		: Stored as packed length (1-9 bytes) + message.
155
  Is not stored if no message.
156
157
  @param thd		   Thread handler
158
  @param affected_rows	   Number of rows changed by statement
159
  @param id		   Auto_increment id for first row (if used)
160
  @param message	   Message to send to the client (Used by mysql_status)
161
*/
162
202.1.17 by Monty Taylor
Patch from andrey - made some functions static as they are not used outside of protocol.cc.
163
static void
1 by brian
clean slate
164
net_send_ok(THD *thd,
165
            uint server_status, uint total_warn_count,
151 by Brian Aker
Ulonglong to uint64_t
166
            ha_rows affected_rows, uint64_t id, const char *message)
1 by brian
clean slate
167
{
168
  NET *net= &thd->net;
169
  uchar buff[MYSQL_ERRMSG_SIZE+10],*pos;
170
171
  if (! net->vio)	// hack for re-parsing queries
172
  {
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
173
    return;
1 by brian
clean slate
174
  }
175
176
  buff[0]=0;					// No fields
177
  pos=net_store_length(buff+1,affected_rows);
178
  pos=net_store_length(pos, id);
179
  if (thd->client_capabilities & CLIENT_PROTOCOL_41)
180
  {
181
    int2store(pos, server_status);
182
    pos+=2;
183
184
    /* We can only return up to 65535 warnings in two bytes */
185
    uint tmp= min(total_warn_count, 65535);
186
    int2store(pos, tmp);
187
    pos+= 2;
188
  }
189
  else if (net->return_status)			// For 4.0 protocol
190
  {
191
    int2store(pos, server_status);
192
    pos+=2;
193
  }
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
194
  thd->main_da.can_overwrite_status= true;
1 by brian
clean slate
195
196
  if (message && message[0])
197
    pos= net_store_data(pos, (uchar*) message, strlen(message));
198
  VOID(my_net_write(net, buff, (size_t) (pos-buff)));
199
  VOID(net_flush(net));
200
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
201
  thd->main_da.can_overwrite_status= false;
1 by brian
clean slate
202
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
203
  return;
1 by brian
clean slate
204
}
205
206
static uchar eof_buff[1]= { (uchar) 254 };      /* Marker for end of fields */
207
208
/**
209
  Send eof (= end of result set) to the client.
210
211
  The eof packet has the following structure:
212
213
  - 254		: Marker (1 byte)
214
  - warning_count	: Stored in 2 bytes; New in 4.1 protocol
215
  - status_flag	: Stored in 2 bytes;
216
  For flags like SERVER_MORE_RESULTS_EXISTS.
217
218
  Note that the warning count will not be sent if 'no_flush' is set as
219
  we don't want to report the warning count until all data is sent to the
220
  client.
221
222
  @param thd		Thread handler
223
  @param no_flush	Set to 1 if there will be more data to the client,
224
                    like in send_fields().
225
*/    
226
202.1.17 by Monty Taylor
Patch from andrey - made some functions static as they are not used outside of protocol.cc.
227
static void
1 by brian
clean slate
228
net_send_eof(THD *thd, uint server_status, uint total_warn_count)
229
{
230
  NET *net= &thd->net;
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
231
  /* Set to true if no active vio, to work well in case of --init-file */
1 by brian
clean slate
232
  if (net->vio != 0)
233
  {
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
234
    thd->main_da.can_overwrite_status= true;
1 by brian
clean slate
235
    write_eof_packet(thd, net, server_status, total_warn_count);
236
    VOID(net_flush(net));
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
237
    thd->main_da.can_overwrite_status= false;
1 by brian
clean slate
238
  }
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
239
  return;
1 by brian
clean slate
240
}
241
242
243
/**
244
  Format EOF packet according to the current protocol and
245
  write it to the network output buffer.
246
*/
247
248
static void write_eof_packet(THD *thd, NET *net,
249
                             uint server_status,
250
                             uint total_warn_count)
251
{
252
  if (thd->client_capabilities & CLIENT_PROTOCOL_41)
253
  {
254
    uchar buff[5];
255
    /*
256
      Don't send warn count during SP execution, as the warn_list
257
      is cleared between substatements, and mysqltest gets confused
258
    */
259
    uint tmp= min(total_warn_count, 65535);
260
    buff[0]= 254;
261
    int2store(buff+1, tmp);
262
    /*
263
      The following test should never be true, but it's better to do it
264
      because if 'is_fatal_error' is set the server is not going to execute
265
      other queries (see the if test in dispatch_command / COM_QUERY)
266
    */
267
    if (thd->is_fatal_error)
268
      server_status&= ~SERVER_MORE_RESULTS_EXISTS;
269
    int2store(buff + 3, server_status);
270
    VOID(my_net_write(net, buff, 5));
271
  }
272
  else
273
    VOID(my_net_write(net, eof_buff, 1));
274
}
275
276
void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
277
{
278
  NET *net= &thd->net;
279
  uint length;
280
  /*
281
    buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + MYSQL_ERRMSG_SIZE:512
282
  */
283
  uchar buff[2+1+SQLSTATE_LENGTH+MYSQL_ERRMSG_SIZE], *pos;
284
285
  if (net->vio == 0)
286
  {
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
287
    return;
1 by brian
clean slate
288
  }
289
290
  int2store(buff,sql_errno);
291
  pos= buff+2;
292
  if (thd->client_capabilities & CLIENT_PROTOCOL_41)
293
  {
294
    /* The first # is to make the protocol backward compatible */
295
    buff[2]= '#';
296
    pos= (uchar*) strmov((char*) buff+3, mysql_errno_to_sqlstate(sql_errno));
297
  }
298
  length= (uint) (strmake((char*) pos, err, MYSQL_ERRMSG_SIZE-1) -
299
                  (char*) buff);
300
  err= (char*) buff;
301
302
  VOID(net_write_command(net,(uchar) 255, (uchar*) "", 0, (uchar*) err,
303
                         length));
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
304
  return;
1 by brian
clean slate
305
}
306
307
308
/**
309
  Faster net_store_length when we know that length is less than 65536.
310
  We keep a separate version for that range because it's widely used in
311
  libmysql.
312
313
  uint is used as agrument type because of MySQL type conventions:
314
  - uint for 0..65536
315
  - ulong for 0..4294967296
151 by Brian Aker
Ulonglong to uint64_t
316
  - uint64_t for bigger numbers.
1 by brian
clean slate
317
*/
318
319
static uchar *net_store_length_fast(uchar *packet, uint length)
320
{
321
  if (length < 251)
322
  {
323
    *packet=(uchar) length;
324
    return packet+1;
325
  }
326
  *packet++=252;
327
  int2store(packet,(uint) length);
328
  return packet+2;
329
}
330
331
/**
332
  Send the status of the current statement execution over network.
333
334
  @param  thd   in fact, carries two parameters, NET for the transport and
335
                Diagnostics_area as the source of status information.
336
337
  In MySQL, there are two types of SQL statements: those that return
338
  a result set and those that return status information only.
339
340
  If a statement returns a result set, it consists of 3 parts:
341
  - result set meta-data
342
  - variable number of result set rows (can be 0)
343
  - followed and terminated by EOF or ERROR packet
344
345
  Once the  client has seen the meta-data information, it always
346
  expects an EOF or ERROR to terminate the result set. If ERROR is
347
  received, the result set rows are normally discarded (this is up
348
  to the client implementation, libmysql at least does discard them).
349
  EOF, on the contrary, means "successfully evaluated the entire
350
  result set". Since we don't know how many rows belong to a result
351
  set until it's evaluated, EOF/ERROR is the indicator of the end
352
  of the row stream. Note, that we can not buffer result set rows
353
  on the server -- there may be an arbitrary number of rows. But
354
  we do buffer the last packet (EOF/ERROR) in the Diagnostics_area and
355
  delay sending it till the very end of execution (here), to be able to
356
  change EOF to an ERROR if commit failed or some other error occurred
357
  during the last cleanup steps taken after execution.
358
359
  A statement that does not return a result set doesn't send result
360
  set meta-data either. Instead it returns one of:
361
  - OK packet
362
  - ERROR packet.
363
  Similarly to the EOF/ERROR of the previous statement type, OK/ERROR
364
  packet is "buffered" in the diagnostics area and sent to the client
365
  in the end of statement.
366
367
  @pre  The diagnostics area is assigned or disabled. It can not be empty
368
        -- we assume that every SQL statement or COM_* command
369
        generates OK, ERROR, or EOF status.
370
371
  @post The status information is encoded to protocol format and sent to the
372
        client.
373
374
  @return We conventionally return void, since the only type of error
375
          that can happen here is a NET (transport) error, and that one
376
          will become visible when we attempt to read from the NET the
377
          next command.
378
          Diagnostics_area::is_sent is set for debugging purposes only.
379
*/
380
381
void net_end_statement(THD *thd)
382
{
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
383
  assert(! thd->main_da.is_sent);
1 by brian
clean slate
384
385
  /* Can not be true, but do not take chances in production. */
386
  if (thd->main_da.is_sent)
387
    return;
388
389
  switch (thd->main_da.status()) {
390
  case Diagnostics_area::DA_ERROR:
391
    /* The query failed, send error to log and abort bootstrap. */
392
    net_send_error(thd,
393
                   thd->main_da.sql_errno(),
394
                   thd->main_da.message());
395
    break;
396
  case Diagnostics_area::DA_EOF:
397
    net_send_eof(thd,
398
                 thd->main_da.server_status(),
399
                 thd->main_da.total_warn_count());
400
    break;
401
  case Diagnostics_area::DA_OK:
402
    net_send_ok(thd,
403
                thd->main_da.server_status(),
404
                thd->main_da.total_warn_count(),
405
                thd->main_da.affected_rows(),
406
                thd->main_da.last_insert_id(),
407
                thd->main_da.message());
408
    break;
409
  case Diagnostics_area::DA_DISABLED:
410
    break;
411
  case Diagnostics_area::DA_EMPTY:
412
  default:
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
413
    assert(0);
1 by brian
clean slate
414
    net_send_ok(thd, thd->server_status, thd->total_warn_count,
415
                0, 0, NULL);
416
    break;
417
  }
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
418
  thd->main_da.is_sent= true;
1 by brian
clean slate
419
}
420
421
422
/****************************************************************************
423
  Functions used by the protocol functions (like net_send_ok) to store
424
  strings and numbers in the header result packet.
425
****************************************************************************/
426
427
/* The following will only be used for short strings < 65K */
428
429
uchar *net_store_data(uchar *to, const uchar *from, size_t length)
430
{
431
  to=net_store_length_fast(to,length);
432
  memcpy(to,from,length);
433
  return to+length;
434
}
435
205 by Brian Aker
uint32 -> uin32_t
436
uchar *net_store_data(uchar *to,int32_t from)
1 by brian
clean slate
437
{
438
  char buff[20];
439
  uint length=(uint) (int10_to_str(from,buff,10)-buff);
440
  to=net_store_length_fast(to,length);
441
  memcpy(to,buff,length);
442
  return to+length;
443
}
444
152 by Brian Aker
longlong replacement
445
uchar *net_store_data(uchar *to,int64_t from)
1 by brian
clean slate
446
{
447
  char buff[22];
152 by Brian Aker
longlong replacement
448
  uint length=(uint) (int64_t10_to_str(from,buff,10)-buff);
1 by brian
clean slate
449
  to=net_store_length_fast(to,length);
450
  memcpy(to,buff,length);
451
  return to+length;
452
}
453
454
455
/*****************************************************************************
456
  Default Protocol functions
457
*****************************************************************************/
458
459
void Protocol::init(THD *thd_arg)
460
{
461
  thd=thd_arg;
462
  packet= &thd->packet;
463
  convert= &thd->convert_buffer;
464
}
465
466
/**
467
  Finish the result set with EOF packet, as is expected by the client,
468
  if there is an error evaluating the next row and a continue handler
469
  for the error.
470
*/
471
472
void Protocol::end_partial_result_set(THD *thd)
473
{
474
  net_send_eof(thd, thd->server_status, 0 /* no warnings, we're inside SP */);
475
}
476
477
478
bool Protocol::flush()
479
{
480
  return net_flush(&thd->net);
481
}
482
483
484
/**
485
  Send name and type of result to client.
486
487
  Sum fields has table name empty and field_name.
488
489
  @param THD		Thread data object
490
  @param list	        List of items to send to client
491
  @param flag	        Bit mask with the following functions:
492
                        - 1 send number of rows
493
                        - 2 send default values
494
                        - 4 don't write eof packet
495
496
  @retval
497
    0	ok
498
  @retval
499
    1	Error  (Note that in this case the error is not sent to the
500
    client)
501
*/
502
bool Protocol::send_fields(List<Item> *list, uint flags)
503
{
504
  List_iterator_fast<Item> it(*list);
505
  Item *item;
506
  uchar buff[80];
507
  String tmp((char*) buff,sizeof(buff),&my_charset_bin);
508
  Protocol_text prot(thd);
509
  String *local_packet= prot.storage_packet();
510
  CHARSET_INFO *thd_charset= thd->variables.character_set_results;
511
512
  if (flags & SEND_NUM_ROWS)
513
  {				// Packet with number of elements
514
    uchar *pos= net_store_length(buff, list->elements);
515
    (void) my_net_write(&thd->net, buff, (size_t) (pos-buff));
516
  }
517
518
  while ((item=it++))
519
  {
520
    char *pos;
521
    CHARSET_INFO *cs= system_charset_info;
522
    Send_field field;
523
    item->make_field(&field);
524
525
    prot.prepare_for_resend();
526
527
    if (thd->client_capabilities & CLIENT_PROTOCOL_41)
528
    {
529
      if (prot.store(STRING_WITH_LEN("def"), cs, thd_charset) ||
530
	  prot.store(field.db_name, (uint) strlen(field.db_name),
531
		     cs, thd_charset) ||
532
	  prot.store(field.table_name, (uint) strlen(field.table_name),
533
		     cs, thd_charset) ||
534
	  prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
535
		     cs, thd_charset) ||
536
	  prot.store(field.col_name, (uint) strlen(field.col_name),
537
		     cs, thd_charset) ||
538
	  prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
539
		     cs, thd_charset) ||
540
	  local_packet->realloc(local_packet->length()+12))
541
	goto err;
542
      /* Store fixed length fields */
543
      pos= (char*) local_packet->ptr()+local_packet->length();
544
      *pos++= 12;				// Length of packed fields
545
      if (item->collation.collation == &my_charset_bin || thd_charset == NULL)
546
      {
547
        /* No conversion */
548
        int2store(pos, field.charsetnr);
549
        int4store(pos+2, field.length);
550
      }
551
      else
552
      {
553
        /* With conversion */
554
        uint max_char_len;
555
        int2store(pos, thd_charset->number);
556
        /*
557
          For TEXT/BLOB columns, field_length describes the maximum data
558
          length in bytes. There is no limit to the number of characters
559
          that a TEXT column can store, as long as the data fits into
560
          the designated space.
561
          For the rest of textual columns, field_length is evaluated as
562
          char_count * mbmaxlen, where character count is taken from the
563
          definition of the column. In other words, the maximum number
564
          of characters here is limited by the column definition.
565
        */
120 by Brian Aker
Removed TINY BLOB.
566
        max_char_len= field.length / item->collation.collation->mbmaxlen;
1 by brian
clean slate
567
        int4store(pos+2, max_char_len * thd_charset->mbmaxlen);
568
      }
569
      pos[6]= field.type;
570
      int2store(pos+7,field.flags);
571
      pos[9]= (char) field.decimals;
572
      pos[10]= 0;				// For the future
573
      pos[11]= 0;				// For the future
574
      pos+= 12;
575
    }
576
    else
577
    {
578
      if (prot.store(field.table_name, (uint) strlen(field.table_name),
579
		     cs, thd_charset) ||
580
	  prot.store(field.col_name, (uint) strlen(field.col_name),
581
		     cs, thd_charset) ||
582
	  local_packet->realloc(local_packet->length()+10))
583
	goto err;
584
      pos= (char*) local_packet->ptr()+local_packet->length();
585
586
	pos[0]=3;
587
	int3store(pos+1,field.length);
588
	pos[4]=1;
589
	pos[5]=field.type;
590
	pos[6]=3;
591
	int2store(pos+7,field.flags);
592
	pos[9]= (char) field.decimals;
593
	pos+= 10;
594
    }
595
    local_packet->length((uint) (pos - local_packet->ptr()));
596
    if (flags & SEND_DEFAULTS)
597
      item->send(&prot, &tmp);			// Send default value
598
    if (prot.write())
599
      break;					/* purecov: inspected */
600
  }
601
602
  if (flags & SEND_EOF)
603
  {
604
    /*
605
      Mark the end of meta-data result set, and store thd->server_status,
606
      to show that there is no cursor.
607
      Send no warning information, as it will be sent at statement end.
608
    */
609
    write_eof_packet(thd, &thd->net, thd->server_status, thd->total_warn_count);
610
  }
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
611
  return(prepare_for_send(list));
1 by brian
clean slate
612
613
err:
614
  my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES),
615
             MYF(0));	/* purecov: inspected */
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
616
  return(1);				/* purecov: inspected */
1 by brian
clean slate
617
}
618
619
620
bool Protocol::write()
621
{
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
622
  return(my_net_write(&thd->net, (uchar*) packet->ptr(),
1 by brian
clean slate
623
                           packet->length()));
624
}
625
626
627
/**
628
  Send \\0 end terminated string.
629
630
  @param from	NullS or \\0 terminated string
631
632
  @note
633
    In most cases one should use store(from, length) instead of this function
634
635
  @retval
636
    0		ok
637
  @retval
638
    1		error
639
*/
640
641
bool Protocol::store(const char *from, CHARSET_INFO *cs)
642
{
643
  if (!from)
644
    return store_null();
645
  uint length= strlen(from);
646
  return store(from, length, cs);
647
}
648
649
650
/**
651
  Send a set of strings as one long string with ',' in between.
652
*/
653
654
bool Protocol::store(I_List<i_string>* str_list)
655
{
656
  char buf[256];
657
  String tmp(buf, sizeof(buf), &my_charset_bin);
205 by Brian Aker
uint32 -> uin32_t
658
  uint32_t len;
1 by brian
clean slate
659
  I_List_iterator<i_string> it(*str_list);
660
  i_string* s;
661
662
  tmp.length(0);
663
  while ((s=it++))
664
  {
665
    tmp.append(s->ptr);
666
    tmp.append(',');
667
  }
668
  if ((len= tmp.length()))
669
    len--;					// Remove last ','
670
  return store((char*) tmp.ptr(), len,  tmp.charset());
671
}
672
673
674
/****************************************************************************
675
  Functions to handle the simple (default) protocol where everything is
676
  This protocol is the one that is used by default between the MySQL server
677
  and client when you are not using prepared statements.
678
679
  All data are sent as 'packed-string-length' followed by 'string-data'
680
****************************************************************************/
681
682
void Protocol_text::prepare_for_resend()
683
{
684
  packet->length(0);
685
}
686
687
bool Protocol_text::store_null()
688
{
689
  char buff[1];
690
  buff[0]= (char)251;
691
  return packet->append(buff, sizeof(buff), PACKET_BUFFER_EXTRA_ALLOC);
692
}
693
694
695
/**
696
  Auxilary function to convert string to the given character set
697
  and store in network buffer.
698
*/
699
700
bool Protocol::store_string_aux(const char *from, size_t length,
701
                                CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
702
{
703
  /* 'tocs' is set 0 when client issues SET character_set_results=NULL */
704
  if (tocs && !my_charset_same(fromcs, tocs) &&
705
      fromcs != &my_charset_bin &&
706
      tocs != &my_charset_bin)
707
  {
708
    /* Store with conversion */
709
    return net_store_data((uchar*) from, length, fromcs, tocs);
710
  }
711
  /* Store without conversion */
712
  return net_store_data((uchar*) from, length);
713
}
714
715
716
bool Protocol_text::store(const char *from, size_t length,
717
                          CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
718
{
719
  return store_string_aux(from, length, fromcs, tocs);
720
}
721
722
723
bool Protocol_text::store(const char *from, size_t length,
724
                          CHARSET_INFO *fromcs)
725
{
726
  CHARSET_INFO *tocs= this->thd->variables.character_set_results;
727
  return store_string_aux(from, length, fromcs, tocs);
728
}
729
730
152 by Brian Aker
longlong replacement
731
bool Protocol_text::store_tiny(int64_t from)
1 by brian
clean slate
732
{
733
  char buff[20];
734
  return net_store_data((uchar*) buff,
735
			(size_t) (int10_to_str((int) from, buff, -10) - buff));
736
}
737
738
152 by Brian Aker
longlong replacement
739
bool Protocol_text::store_short(int64_t from)
1 by brian
clean slate
740
{
741
  char buff[20];
742
  return net_store_data((uchar*) buff,
743
			(size_t) (int10_to_str((int) from, buff, -10) -
744
                                  buff));
745
}
746
747
152 by Brian Aker
longlong replacement
748
bool Protocol_text::store_long(int64_t from)
1 by brian
clean slate
749
{
750
  char buff[20];
751
  return net_store_data((uchar*) buff,
752
			(size_t) (int10_to_str((long int)from, buff,
753
                                               (from <0)?-10:10)-buff));
754
}
755
756
152 by Brian Aker
longlong replacement
757
bool Protocol_text::store_int64_t(int64_t from, bool unsigned_flag)
1 by brian
clean slate
758
{
759
  char buff[22];
760
  return net_store_data((uchar*) buff,
152 by Brian Aker
longlong replacement
761
			(size_t) (int64_t10_to_str(from,buff,
1 by brian
clean slate
762
                                                    unsigned_flag ? 10 : -10)-
763
                                  buff));
764
}
765
766
767
bool Protocol_text::store_decimal(const my_decimal *d)
768
{
769
  char buff[DECIMAL_MAX_STR_LENGTH];
770
  String str(buff, sizeof(buff), &my_charset_bin);
771
  (void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
772
  return net_store_data((uchar*) str.ptr(), str.length());
773
}
774
775
205 by Brian Aker
uint32 -> uin32_t
776
bool Protocol_text::store(float from, uint32_t decimals, String *buffer)
1 by brian
clean slate
777
{
778
  buffer->set_real((double) from, decimals, thd->charset());
779
  return net_store_data((uchar*) buffer->ptr(), buffer->length());
780
}
781
782
205 by Brian Aker
uint32 -> uin32_t
783
bool Protocol_text::store(double from, uint32_t decimals, String *buffer)
1 by brian
clean slate
784
{
785
  buffer->set_real(from, decimals, thd->charset());
786
  return net_store_data((uchar*) buffer->ptr(), buffer->length());
787
}
788
789
790
bool Protocol_text::store(Field *field)
791
{
792
  if (field->is_null())
793
    return store_null();
794
  char buff[MAX_FIELD_WIDTH];
795
  String str(buff,sizeof(buff), &my_charset_bin);
796
  CHARSET_INFO *tocs= this->thd->variables.character_set_results;
797
798
  field->val_str(&str);
799
800
  return store_string_aux(str.ptr(), str.length(), str.charset(), tocs);
801
}
802
803
804
/**
805
  @todo
806
    Second_part format ("%06") needs to change when 
807
    we support 0-6 decimals for time.
808
*/
809
810
bool Protocol_text::store(MYSQL_TIME *tm)
811
{
812
  char buff[40];
813
  uint length;
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
814
  length= sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d",
1 by brian
clean slate
815
			   (int) tm->year,
816
			   (int) tm->month,
817
			   (int) tm->day,
818
			   (int) tm->hour,
819
			   (int) tm->minute,
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
820
			   (int) tm->second);
1 by brian
clean slate
821
  if (tm->second_part)
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
822
    length+= sprintf(buff+length, ".%06d",
823
                                     (int)tm->second_part);
1 by brian
clean slate
824
  return net_store_data((uchar*) buff, length);
825
}
826
827
828
bool Protocol_text::store_date(MYSQL_TIME *tm)
829
{
830
  char buff[MAX_DATE_STRING_REP_LENGTH];
831
  size_t length= my_date_to_str(tm, buff);
832
  return net_store_data((uchar*) buff, length);
833
}
834
835
836
/**
837
  @todo 
838
    Second_part format ("%06") needs to change when 
839
    we support 0-6 decimals for time.
840
*/
841
842
bool Protocol_text::store_time(MYSQL_TIME *tm)
843
{
844
  char buff[40];
845
  uint length;
846
  uint day= (tm->year || tm->month) ? 0 : tm->day;
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
847
  length= sprintf(buff, "%s%02ld:%02d:%02d",
1 by brian
clean slate
848
			   tm->neg ? "-" : "",
849
			   (long) day*24L+(long) tm->hour,
850
			   (int) tm->minute,
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
851
			   (int) tm->second);
1 by brian
clean slate
852
  if (tm->second_part)
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
853
    length+= sprintf(buff+length, ".%06d", (int)tm->second_part);
1 by brian
clean slate
854
  return net_store_data((uchar*) buff, length);
855
}
856