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