~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/protocol.cc

MergingĀ mainline

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
  Low level functions for storing data to be send to the MySQL client.
20
20
  The actual communction is handled by the net_xxx functions in net_serv.cc
21
21
*/
22
 
#include <drizzled/server_includes.h>
23
 
#include <drizzled/drizzled_error_messages.h>
24
 
#include <drizzled/sql_state.h>
 
22
 
 
23
#ifdef USE_PRAGMA_IMPLEMENTATION
 
24
#pragma implementation                          // gcc: Class implementation
 
25
#endif
 
26
 
 
27
#include "mysql_priv.h"
 
28
#include <stdarg.h>
25
29
 
26
30
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
27
31
/* Declared non-static only because of the embedded library. */
28
 
static void net_send_error_packet(THD *thd, uint32_t sql_errno, const char *err);
 
32
void net_send_error_packet(THD *thd, uint sql_errno, const char *err);
 
33
void net_send_ok(THD *, uint, uint, ha_rows, ulonglong, const char *);
 
34
void net_send_eof(THD *thd, uint server_status, uint total_warn_count);
29
35
static void write_eof_packet(THD *thd, NET *net,
30
 
                             uint32_t server_status, uint32_t total_warn_count);
 
36
                             uint server_status, uint total_warn_count);
31
37
 
32
 
bool Protocol::net_store_data(const unsigned char *from, size_t length)
 
38
bool Protocol::net_store_data(const uchar *from, size_t length)
33
39
{
34
40
  ulong packet_length=packet->length();
35
41
  /* 
39
45
  if (packet_length+9+length > packet->alloced_length() &&
40
46
      packet->realloc(packet_length+9+length))
41
47
    return 1;
42
 
  unsigned char *to= net_store_length((unsigned char*) packet->ptr()+packet_length, length);
 
48
  uchar *to= net_store_length((uchar*) packet->ptr()+packet_length, length);
43
49
  memcpy(to,from,length);
44
 
  packet->length((uint) (to+length-(unsigned char*) packet->ptr()));
 
50
  packet->length((uint) (to+length-(uchar*) packet->ptr()));
45
51
  return 0;
46
52
}
47
53
 
60
66
  because column, table, database names fit into this limit.
61
67
*/
62
68
 
63
 
bool Protocol::net_store_data(const unsigned char *from, size_t length,
64
 
                              const CHARSET_INFO * const from_cs,
65
 
                                                          const CHARSET_INFO * const to_cs)
 
69
bool Protocol::net_store_data(const uchar *from, size_t length,
 
70
                              CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
66
71
{
67
 
  uint32_t dummy_errors;
 
72
  uint dummy_errors;
68
73
  /* Calculate maxumum possible result length */
69
 
  uint32_t conv_length= to_cs->mbmaxlen * length / from_cs->mbminlen;
 
74
  uint conv_length= to_cs->mbmaxlen * length / from_cs->mbminlen;
70
75
  if (conv_length > 250)
71
76
  {
72
77
    /*
82
87
    */
83
88
    return (convert->copy((const char*) from, length, from_cs,
84
89
                          to_cs, &dummy_errors) ||
85
 
            net_store_data((const unsigned char*) convert->ptr(), convert->length()));
 
90
            net_store_data((const uchar*) convert->ptr(), convert->length()));
86
91
  }
87
92
 
88
93
  ulong packet_length= packet->length();
97
102
  to+= copy_and_convert(to, conv_length, to_cs,
98
103
                        (const char*) from, length, from_cs, &dummy_errors);
99
104
 
100
 
  net_store_length((unsigned char*) length_pos, to - length_pos - 1);
 
105
  net_store_length((uchar*) length_pos, to - length_pos - 1);
101
106
  packet->length((uint) (to - packet->ptr()));
102
107
  return 0;
103
108
}
115
120
  critical that every error that can be intercepted is issued in one
116
121
  place only, my_message_sql.
117
122
*/
118
 
void net_send_error(THD *thd, uint32_t sql_errno, const char *err)
 
123
void net_send_error(THD *thd, uint sql_errno, const char *err)
119
124
{
120
 
  assert(sql_errno);
121
 
  assert(err && err[0]);
 
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));
122
131
 
123
132
  /*
124
133
    It's one case when we can push an error even though there
125
134
    is an OK or EOF already.
126
135
  */
127
 
  thd->main_da.can_overwrite_status= true;
 
136
  thd->main_da.can_overwrite_status= TRUE;
128
137
 
129
138
  /* Abort multi-result sets */
130
139
  thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
131
140
 
132
141
  net_send_error_packet(thd, sql_errno, err);
133
142
 
134
 
  thd->main_da.can_overwrite_status= false;
 
143
  thd->main_da.can_overwrite_status= FALSE;
 
144
 
 
145
  DBUG_VOID_RETURN;
135
146
}
136
147
 
137
148
/**
155
166
  @param message           Message to send to the client (Used by mysql_status)
156
167
*/
157
168
 
158
 
static void
 
169
void
159
170
net_send_ok(THD *thd,
160
 
            uint32_t server_status, uint32_t total_warn_count,
161
 
            ha_rows affected_rows, uint64_t id, const char *message)
 
171
            uint server_status, uint total_warn_count,
 
172
            ha_rows affected_rows, ulonglong id, const char *message)
162
173
{
163
174
  NET *net= &thd->net;
164
 
  unsigned char buff[DRIZZLE_ERRMSG_SIZE+10],*pos;
 
175
  uchar buff[MYSQL_ERRMSG_SIZE+10],*pos;
 
176
  DBUG_ENTER("my_ok");
165
177
 
166
178
  if (! net->vio)       // hack for re-parsing queries
167
179
  {
168
 
    return;
 
180
    DBUG_PRINT("info", ("vio present: NO"));
 
181
    DBUG_VOID_RETURN;
169
182
  }
170
183
 
171
184
  buff[0]=0;                                    // No fields
172
185
  pos=net_store_length(buff+1,affected_rows);
173
186
  pos=net_store_length(pos, id);
174
 
 
175
 
  int2store(pos, server_status);
176
 
  pos+=2;
177
 
 
178
 
  /* We can only return up to 65535 warnings in two bytes */
179
 
  uint32_t tmp= cmin(total_warn_count, (uint)65535);
180
 
  int2store(pos, tmp);
181
 
  pos+= 2;
182
 
 
183
 
  thd->main_da.can_overwrite_status= true;
 
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;
184
209
 
185
210
  if (message && message[0])
186
 
    pos= net_store_data(pos, (unsigned char*) message, strlen(message));
187
 
  my_net_write(net, buff, (size_t) (pos-buff));
188
 
  net_flush(net);
189
 
 
190
 
  thd->main_da.can_overwrite_status= false;
 
211
    pos= net_store_data(pos, (uchar*) message, strlen(message));
 
212
  VOID(my_net_write(net, buff, (size_t) (pos-buff)));
 
213
  VOID(net_flush(net));
 
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;
191
219
}
192
220
 
 
221
static uchar eof_buff[1]= { (uchar) 254 };      /* Marker for end of fields */
 
222
 
193
223
/**
194
224
  Send eof (= end of result set) to the client.
195
225
 
196
226
  The eof packet has the following structure:
197
227
 
198
 
  - 254 (DRIZZLE_PROTOCOL_NO_MORE_DATA) : Marker (1 byte)
 
228
  - 254         : Marker (1 byte)
199
229
  - warning_count       : Stored in 2 bytes; New in 4.1 protocol
200
230
  - status_flag : Stored in 2 bytes;
201
231
  For flags like SERVER_MORE_RESULTS_EXISTS.
209
239
                    like in send_fields().
210
240
*/    
211
241
 
212
 
static void
213
 
net_send_eof(THD *thd, uint32_t server_status, uint32_t total_warn_count)
 
242
void
 
243
net_send_eof(THD *thd, uint server_status, uint total_warn_count)
214
244
{
215
245
  NET *net= &thd->net;
216
 
  /* Set to true if no active vio, to work well in case of --init-file */
 
246
  DBUG_ENTER("net_send_eof");
 
247
  /* Set to TRUE if no active vio, to work well in case of --init-file */
217
248
  if (net->vio != 0)
218
249
  {
219
 
    thd->main_da.can_overwrite_status= true;
 
250
    thd->main_da.can_overwrite_status= TRUE;
220
251
    write_eof_packet(thd, net, server_status, total_warn_count);
221
 
    net_flush(net);
222
 
    thd->main_da.can_overwrite_status= false;
 
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"));
223
255
  }
 
256
  DBUG_VOID_RETURN;
224
257
}
225
258
 
226
259
 
230
263
*/
231
264
 
232
265
static void write_eof_packet(THD *thd, NET *net,
233
 
                             uint32_t server_status,
234
 
                             uint32_t total_warn_count)
 
266
                             uint server_status,
 
267
                             uint total_warn_count)
235
268
{
236
 
  unsigned char buff[5];
237
 
  /*
238
 
    Don't send warn count during SP execution, as the warn_list
239
 
    is cleared between substatements, and mysqltest gets confused
240
 
  */
241
 
  uint32_t tmp= cmin(total_warn_count, (uint)65535);
242
 
  buff[0]= DRIZZLE_PROTOCOL_NO_MORE_DATA;
243
 
  int2store(buff+1, tmp);
244
 
  /*
245
 
    The following test should never be true, but it's better to do it
246
 
    because if 'is_fatal_error' is set the server is not going to execute
247
 
    other queries (see the if test in dispatch_command / COM_QUERY)
248
 
  */
249
 
  if (thd->is_fatal_error)
250
 
    server_status&= ~SERVER_MORE_RESULTS_EXISTS;
251
 
  int2store(buff + 3, server_status);
252
 
  my_net_write(net, buff, 5);
 
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));
253
291
}
254
292
 
255
 
void net_send_error_packet(THD *thd, uint32_t sql_errno, const char *err)
 
293
void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
256
294
{
257
295
  NET *net= &thd->net;
258
 
  uint32_t length;
 
296
  uint length;
259
297
  /*
260
 
    buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + DRIZZLE_ERRMSG_SIZE:512
 
298
    buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + MYSQL_ERRMSG_SIZE:512
261
299
  */
262
 
  unsigned char buff[2+1+SQLSTATE_LENGTH+DRIZZLE_ERRMSG_SIZE], *pos;
 
300
  uchar buff[2+1+SQLSTATE_LENGTH+MYSQL_ERRMSG_SIZE], *pos;
 
301
 
 
302
  DBUG_ENTER("send_error_packet");
263
303
 
264
304
  if (net->vio == 0)
265
305
  {
266
 
    return;
 
306
    DBUG_VOID_RETURN;
267
307
  }
268
308
 
269
309
  int2store(buff,sql_errno);
270
310
  pos= buff+2;
271
 
 
272
 
  /* The first # is to make the protocol backward compatible */
273
 
  buff[2]= '#';
274
 
  pos= (unsigned char*) my_stpcpy((char*) buff+3, drizzle_errno_to_sqlstate(sql_errno));
275
 
 
276
 
  length= (uint) (strmake((char*) pos, err, DRIZZLE_ERRMSG_SIZE-1) -
 
311
  if (thd->client_capabilities & CLIENT_PROTOCOL_41)
 
312
  {
 
313
    /* The first # is to make the protocol backward compatible */
 
314
    buff[2]= '#';
 
315
    pos= (uchar*) strmov((char*) buff+3, mysql_errno_to_sqlstate(sql_errno));
 
316
  }
 
317
  length= (uint) (strmake((char*) pos, err, MYSQL_ERRMSG_SIZE-1) -
277
318
                  (char*) buff);
278
319
  err= (char*) buff;
279
320
 
280
 
  net_write_command(net,(unsigned char) 255, (unsigned char*) "", 0, (unsigned char*) err, length);
281
 
  return;
 
321
  VOID(net_write_command(net,(uchar) 255, (uchar*) "", 0, (uchar*) err,
 
322
                         length));
 
323
  DBUG_VOID_RETURN;
282
324
}
283
325
 
284
326
 
287
329
  We keep a separate version for that range because it's widely used in
288
330
  libmysql.
289
331
 
290
 
  uint32_t is used as agrument type because of MySQL type conventions:
291
 
  - uint32_t for 0..65536
 
332
  uint is used as agrument type because of MySQL type conventions:
 
333
  - uint for 0..65536
292
334
  - ulong for 0..4294967296
293
 
  - uint64_t for bigger numbers.
 
335
  - ulonglong for bigger numbers.
294
336
*/
295
337
 
296
 
static unsigned char *net_store_length_fast(unsigned char *packet, uint32_t length)
 
338
static uchar *net_store_length_fast(uchar *packet, uint length)
297
339
{
298
340
  if (length < 251)
299
341
  {
300
 
    *packet=(unsigned char) length;
 
342
    *packet=(uchar) length;
301
343
    return packet+1;
302
344
  }
303
345
  *packet++=252;
357
399
 
358
400
void net_end_statement(THD *thd)
359
401
{
360
 
  assert(! thd->main_da.is_sent);
 
402
  DBUG_ASSERT(! thd->main_da.is_sent);
361
403
 
362
404
  /* Can not be true, but do not take chances in production. */
363
405
  if (thd->main_da.is_sent)
387
429
    break;
388
430
  case Diagnostics_area::DA_EMPTY:
389
431
  default:
390
 
    assert(0);
 
432
    DBUG_ASSERT(0);
391
433
    net_send_ok(thd, thd->server_status, thd->total_warn_count,
392
434
                0, 0, NULL);
393
435
    break;
394
436
  }
395
 
  thd->main_da.is_sent= true;
 
437
  thd->main_da.is_sent= TRUE;
396
438
}
397
439
 
398
440
 
403
445
 
404
446
/* The following will only be used for short strings < 65K */
405
447
 
406
 
unsigned char *net_store_data(unsigned char *to, const unsigned char *from, size_t length)
 
448
uchar *net_store_data(uchar *to, const uchar *from, size_t length)
407
449
{
408
450
  to=net_store_length_fast(to,length);
409
451
  memcpy(to,from,length);
410
452
  return to+length;
411
453
}
412
454
 
413
 
unsigned char *net_store_data(unsigned char *to,int32_t from)
 
455
uchar *net_store_data(uchar *to,int32 from)
414
456
{
415
457
  char buff[20];
416
 
  uint32_t length=(uint) (int10_to_str(from,buff,10)-buff);
 
458
  uint length=(uint) (int10_to_str(from,buff,10)-buff);
417
459
  to=net_store_length_fast(to,length);
418
460
  memcpy(to,buff,length);
419
461
  return to+length;
420
462
}
421
463
 
422
 
unsigned char *net_store_data(unsigned char *to,int64_t from)
 
464
uchar *net_store_data(uchar *to,longlong from)
423
465
{
424
466
  char buff[22];
425
 
  uint32_t length=(uint) (int64_t10_to_str(from,buff,10)-buff);
 
467
  uint length=(uint) (longlong10_to_str(from,buff,10)-buff);
426
468
  to=net_store_length_fast(to,length);
427
469
  memcpy(to,buff,length);
428
470
  return to+length;
438
480
  thd=thd_arg;
439
481
  packet= &thd->packet;
440
482
  convert= &thd->convert_buffer;
 
483
#ifndef DBUG_OFF
 
484
  field_types= 0;
 
485
#endif
441
486
}
442
487
 
443
488
/**
476
521
    1   Error  (Note that in this case the error is not sent to the
477
522
    client)
478
523
*/
479
 
bool Protocol::send_fields(List<Item> *list, uint32_t flags)
 
524
bool Protocol::send_fields(List<Item> *list, uint flags)
480
525
{
481
526
  List_iterator_fast<Item> it(*list);
482
527
  Item *item;
483
 
  unsigned char buff[80];
 
528
  uchar buff[80];
484
529
  String tmp((char*) buff,sizeof(buff),&my_charset_bin);
485
530
  Protocol_text prot(thd);
486
531
  String *local_packet= prot.storage_packet();
487
 
  const CHARSET_INFO * const thd_charset= thd->variables.character_set_results;
 
532
  CHARSET_INFO *thd_charset= thd->variables.character_set_results;
 
533
  DBUG_ENTER("send_fields");
488
534
 
489
535
  if (flags & SEND_NUM_ROWS)
490
536
  {                             // Packet with number of elements
491
 
    unsigned char *pos= net_store_length(buff, list->elements);
 
537
    uchar *pos= net_store_length(buff, list->elements);
492
538
    (void) my_net_write(&thd->net, buff, (size_t) (pos-buff));
493
539
  }
494
540
 
 
541
#ifndef DBUG_OFF
 
542
  field_types= (enum_field_types*) thd->alloc(sizeof(field_types) *
 
543
                                              list->elements);
 
544
  uint count= 0;
 
545
#endif
 
546
 
495
547
  while ((item=it++))
496
548
  {
497
549
    char *pos;
498
 
    const CHARSET_INFO * const cs= system_charset_info;
 
550
    CHARSET_INFO *cs= system_charset_info;
499
551
    Send_field field;
500
552
    item->make_field(&field);
501
553
 
502
554
    prot.prepare_for_resend();
503
555
 
504
 
 
505
 
    if (prot.store(STRING_WITH_LEN("def"), cs, thd_charset) ||
506
 
        prot.store(field.db_name, (uint) strlen(field.db_name),
507
 
                   cs, thd_charset) ||
508
 
        prot.store(field.table_name, (uint) strlen(field.table_name),
509
 
                   cs, thd_charset) ||
510
 
        prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
511
 
                   cs, thd_charset) ||
512
 
        prot.store(field.col_name, (uint) strlen(field.col_name),
513
 
                   cs, thd_charset) ||
514
 
        prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
515
 
                   cs, thd_charset) ||
516
 
        local_packet->realloc(local_packet->length()+12))
517
 
      goto err;
518
 
 
519
 
    /* Store fixed length fields */
520
 
    pos= (char*) local_packet->ptr()+local_packet->length();
521
 
    *pos++= 12;                         // Length of packed fields
522
 
    if (item->collation.collation == &my_charset_bin || thd_charset == NULL)
 
556
    if (thd->client_capabilities & CLIENT_PROTOCOL_41)
523
557
    {
524
 
      /* No conversion */
525
 
      int2store(pos, field.charsetnr);
526
 
      int4store(pos+2, field.length);
 
558
      if (prot.store(STRING_WITH_LEN("def"), cs, thd_charset) ||
 
559
          prot.store(field.db_name, (uint) strlen(field.db_name),
 
560
                     cs, thd_charset) ||
 
561
          prot.store(field.table_name, (uint) strlen(field.table_name),
 
562
                     cs, thd_charset) ||
 
563
          prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
 
564
                     cs, thd_charset) ||
 
565
          prot.store(field.col_name, (uint) strlen(field.col_name),
 
566
                     cs, thd_charset) ||
 
567
          prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
 
568
                     cs, thd_charset) ||
 
569
          local_packet->realloc(local_packet->length()+12))
 
570
        goto err;
 
571
      /* Store fixed length fields */
 
572
      pos= (char*) local_packet->ptr()+local_packet->length();
 
573
      *pos++= 12;                               // Length of packed fields
 
574
      if (item->collation.collation == &my_charset_bin || thd_charset == NULL)
 
575
      {
 
576
        /* No conversion */
 
577
        int2store(pos, field.charsetnr);
 
578
        int4store(pos+2, field.length);
 
579
      }
 
580
      else
 
581
      {
 
582
        /* With conversion */
 
583
        uint max_char_len;
 
584
        int2store(pos, thd_charset->number);
 
585
        /*
 
586
          For TEXT/BLOB columns, field_length describes the maximum data
 
587
          length in bytes. There is no limit to the number of characters
 
588
          that a TEXT column can store, as long as the data fits into
 
589
          the designated space.
 
590
          For the rest of textual columns, field_length is evaluated as
 
591
          char_count * mbmaxlen, where character count is taken from the
 
592
          definition of the column. In other words, the maximum number
 
593
          of characters here is limited by the column definition.
 
594
        */
 
595
        max_char_len= field.length / item->collation.collation->mbmaxlen;
 
596
        int4store(pos+2, max_char_len * thd_charset->mbmaxlen);
 
597
      }
 
598
      pos[6]= field.type;
 
599
      int2store(pos+7,field.flags);
 
600
      pos[9]= (char) field.decimals;
 
601
      pos[10]= 0;                               // For the future
 
602
      pos[11]= 0;                               // For the future
 
603
      pos+= 12;
527
604
    }
528
605
    else
529
606
    {
530
 
      /* With conversion */
531
 
      uint32_t max_char_len;
532
 
      int2store(pos, thd_charset->number);
533
 
      /*
534
 
        For TEXT/BLOB columns, field_length describes the maximum data
535
 
        length in bytes. There is no limit to the number of characters
536
 
        that a TEXT column can store, as long as the data fits into
537
 
        the designated space.
538
 
        For the rest of textual columns, field_length is evaluated as
539
 
        char_count * mbmaxlen, where character count is taken from the
540
 
        definition of the column. In other words, the maximum number
541
 
        of characters here is limited by the column definition.
542
 
      */
543
 
      max_char_len= field.length / item->collation.collation->mbmaxlen;
544
 
      int4store(pos+2, max_char_len * thd_charset->mbmaxlen);
 
607
      if (prot.store(field.table_name, (uint) strlen(field.table_name),
 
608
                     cs, thd_charset) ||
 
609
          prot.store(field.col_name, (uint) strlen(field.col_name),
 
610
                     cs, thd_charset) ||
 
611
          local_packet->realloc(local_packet->length()+10))
 
612
        goto err;
 
613
      pos= (char*) local_packet->ptr()+local_packet->length();
 
614
 
 
615
#ifdef TO_BE_DELETED_IN_6
 
616
      if (!(thd->client_capabilities & CLIENT_LONG_FLAG))
 
617
      {
 
618
        pos[0]=3;
 
619
        int3store(pos+1,field.length);
 
620
        pos[4]=1;
 
621
        pos[5]=field.type;
 
622
        pos[6]=2;
 
623
        pos[7]= (char) field.flags;
 
624
        pos[8]= (char) field.decimals;
 
625
        pos+= 9;
 
626
      }
 
627
      else
 
628
#endif
 
629
      {
 
630
        pos[0]=3;
 
631
        int3store(pos+1,field.length);
 
632
        pos[4]=1;
 
633
        pos[5]=field.type;
 
634
        pos[6]=3;
 
635
        int2store(pos+7,field.flags);
 
636
        pos[9]= (char) field.decimals;
 
637
        pos+= 10;
 
638
      }
545
639
    }
546
 
    pos[6]= field.type;
547
 
    int2store(pos+7,field.flags);
548
 
    pos[9]= (char) field.decimals;
549
 
    pos[10]= 0;                         // For the future
550
 
    pos[11]= 0;                         // For the future
551
 
    pos+= 12;
552
 
 
553
640
    local_packet->length((uint) (pos - local_packet->ptr()));
554
641
    if (flags & SEND_DEFAULTS)
555
642
      item->send(&prot, &tmp);                  // Send default value
556
643
    if (prot.write())
557
644
      break;                                    /* purecov: inspected */
 
645
#ifndef DBUG_OFF
 
646
    field_types[count++]= field.type;
 
647
#endif
558
648
  }
559
649
 
560
650
  if (flags & SEND_EOF)
566
656
    */
567
657
    write_eof_packet(thd, &thd->net, thd->server_status, thd->total_warn_count);
568
658
  }
569
 
  return(prepare_for_send(list));
 
659
  DBUG_RETURN(prepare_for_send(list));
570
660
 
571
661
err:
572
662
  my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES),
573
663
             MYF(0));   /* purecov: inspected */
574
 
  return(1);                            /* purecov: inspected */
 
664
  DBUG_RETURN(1);                               /* purecov: inspected */
575
665
}
576
666
 
577
667
 
578
668
bool Protocol::write()
579
669
{
580
 
  return(my_net_write(&thd->net, (unsigned char*) packet->ptr(),
 
670
  DBUG_ENTER("Protocol::write");
 
671
  DBUG_RETURN(my_net_write(&thd->net, (uchar*) packet->ptr(),
581
672
                           packet->length()));
582
673
}
583
674
 
585
676
/**
586
677
  Send \\0 end terminated string.
587
678
 
588
 
  @param from   NULL or \\0 terminated string
 
679
  @param from   NullS or \\0 terminated string
589
680
 
590
681
  @note
591
682
    In most cases one should use store(from, length) instead of this function
596
687
    1           error
597
688
*/
598
689
 
599
 
bool Protocol::store(const char *from, const CHARSET_INFO * const cs)
 
690
bool Protocol::store(const char *from, CHARSET_INFO *cs)
600
691
{
601
692
  if (!from)
602
693
    return store_null();
603
 
  uint32_t length= strlen(from);
 
694
  uint length= strlen(from);
604
695
  return store(from, length, cs);
605
696
}
606
697
 
613
704
{
614
705
  char buf[256];
615
706
  String tmp(buf, sizeof(buf), &my_charset_bin);
616
 
  uint32_t len;
 
707
  uint32 len;
617
708
  I_List_iterator<i_string> it(*str_list);
618
709
  i_string* s;
619
710
 
640
731
void Protocol_text::prepare_for_resend()
641
732
{
642
733
  packet->length(0);
 
734
#ifndef DBUG_OFF
 
735
  field_pos= 0;
 
736
#endif
643
737
}
644
738
 
645
739
bool Protocol_text::store_null()
646
740
{
 
741
#ifndef DBUG_OFF
 
742
  field_pos++;
 
743
#endif
647
744
  char buff[1];
648
745
  buff[0]= (char)251;
649
746
  return packet->append(buff, sizeof(buff), PACKET_BUFFER_EXTRA_ALLOC);
656
753
*/
657
754
 
658
755
bool Protocol::store_string_aux(const char *from, size_t length,
659
 
                                const CHARSET_INFO * const fromcs,
660
 
                                                                const CHARSET_INFO * const tocs)
 
756
                                CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
661
757
{
662
758
  /* 'tocs' is set 0 when client issues SET character_set_results=NULL */
663
759
  if (tocs && !my_charset_same(fromcs, tocs) &&
665
761
      tocs != &my_charset_bin)
666
762
  {
667
763
    /* Store with conversion */
668
 
    return net_store_data((unsigned char*) from, length, fromcs, tocs);
 
764
    return net_store_data((uchar*) from, length, fromcs, tocs);
669
765
  }
670
766
  /* Store without conversion */
671
 
  return net_store_data((unsigned char*) from, length);
672
 
}
673
 
 
674
 
 
675
 
bool Protocol_text::store(const char *from, size_t length,
676
 
                          const CHARSET_INFO * const fromcs,
677
 
                                                  const CHARSET_INFO * const tocs)
678
 
{
679
 
  return store_string_aux(from, length, fromcs, tocs);
680
 
}
681
 
 
682
 
 
683
 
bool Protocol_text::store(const char *from, size_t length,
684
 
                          const CHARSET_INFO * const fromcs)
685
 
{
686
 
  const CHARSET_INFO * const tocs= this->thd->variables.character_set_results;
687
 
  return store_string_aux(from, length, fromcs, tocs);
688
 
}
689
 
 
690
 
 
691
 
bool Protocol_text::store_tiny(int64_t from)
692
 
{
 
767
  return net_store_data((uchar*) from, length);
 
768
}
 
769
 
 
770
 
 
771
bool Protocol_text::store(const char *from, size_t length,
 
772
                          CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
 
773
{
 
774
#ifndef DBUG_OFF
 
775
  DBUG_ASSERT(field_types == 0 ||
 
776
              field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL ||
 
777
              (field_types[field_pos] >= MYSQL_TYPE_ENUM && field_types[field_pos] <= MYSQL_TYPE_STRING));
 
778
  field_pos++;
 
779
#endif
 
780
  return store_string_aux(from, length, fromcs, tocs);
 
781
}
 
782
 
 
783
 
 
784
bool Protocol_text::store(const char *from, size_t length,
 
785
                          CHARSET_INFO *fromcs)
 
786
{
 
787
  CHARSET_INFO *tocs= this->thd->variables.character_set_results;
 
788
#ifndef DBUG_OFF
 
789
  DBUG_ASSERT(field_types == 0 ||
 
790
              field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL ||
 
791
              field_types[field_pos] == MYSQL_TYPE_NEWDATE ||
 
792
              (field_types[field_pos] >= MYSQL_TYPE_ENUM && field_types[field_pos] <= MYSQL_TYPE_STRING));
 
793
  field_pos++;
 
794
#endif
 
795
  return store_string_aux(from, length, fromcs, tocs);
 
796
}
 
797
 
 
798
 
 
799
bool Protocol_text::store_tiny(longlong from)
 
800
{
 
801
#ifndef DBUG_OFF
 
802
  DBUG_ASSERT(field_types == 0 || field_types[field_pos] == MYSQL_TYPE_TINY);
 
803
  field_pos++;
 
804
#endif
693
805
  char buff[20];
694
 
  return net_store_data((unsigned char*) buff,
 
806
  return net_store_data((uchar*) buff,
695
807
                        (size_t) (int10_to_str((int) from, buff, -10) - buff));
696
808
}
697
809
 
698
810
 
699
 
bool Protocol_text::store_short(int64_t from)
 
811
bool Protocol_text::store_short(longlong from)
700
812
{
 
813
#ifndef DBUG_OFF
 
814
  DBUG_ASSERT(field_types == 0 ||
 
815
              field_types[field_pos] == MYSQL_TYPE_YEAR ||
 
816
              field_types[field_pos] == MYSQL_TYPE_SHORT);
 
817
  field_pos++;
 
818
#endif
701
819
  char buff[20];
702
 
  return net_store_data((unsigned char*) buff,
 
820
  return net_store_data((uchar*) buff,
703
821
                        (size_t) (int10_to_str((int) from, buff, -10) -
704
822
                                  buff));
705
823
}
706
824
 
707
825
 
708
 
bool Protocol_text::store_long(int64_t from)
 
826
bool Protocol_text::store_long(longlong from)
709
827
{
 
828
#ifndef DBUG_OFF
 
829
  DBUG_ASSERT(field_types == 0 ||
 
830
              field_types[field_pos] == MYSQL_TYPE_LONG);
 
831
  field_pos++;
 
832
#endif
710
833
  char buff[20];
711
 
  return net_store_data((unsigned char*) buff,
 
834
  return net_store_data((uchar*) buff,
712
835
                        (size_t) (int10_to_str((long int)from, buff,
713
836
                                               (from <0)?-10:10)-buff));
714
837
}
715
838
 
716
839
 
717
 
bool Protocol_text::store_int64_t(int64_t from, bool unsigned_flag)
 
840
bool Protocol_text::store_longlong(longlong from, bool unsigned_flag)
718
841
{
 
842
#ifndef DBUG_OFF
 
843
  DBUG_ASSERT(field_types == 0 ||
 
844
              field_types[field_pos] == MYSQL_TYPE_LONGLONG);
 
845
  field_pos++;
 
846
#endif
719
847
  char buff[22];
720
 
  return net_store_data((unsigned char*) buff,
721
 
                        (size_t) (int64_t10_to_str(from,buff,
 
848
  return net_store_data((uchar*) buff,
 
849
                        (size_t) (longlong10_to_str(from,buff,
722
850
                                                    unsigned_flag ? 10 : -10)-
723
851
                                  buff));
724
852
}
726
854
 
727
855
bool Protocol_text::store_decimal(const my_decimal *d)
728
856
{
 
857
#ifndef DBUG_OFF
 
858
  DBUG_ASSERT(field_types == 0 ||
 
859
              field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL);
 
860
  field_pos++;
 
861
#endif
729
862
  char buff[DECIMAL_MAX_STR_LENGTH];
730
863
  String str(buff, sizeof(buff), &my_charset_bin);
731
864
  (void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
732
 
  return net_store_data((unsigned char*) str.ptr(), str.length());
 
865
  return net_store_data((uchar*) str.ptr(), str.length());
733
866
}
734
867
 
735
868
 
736
 
bool Protocol_text::store(float from, uint32_t decimals, String *buffer)
 
869
bool Protocol_text::store(float from, uint32 decimals, String *buffer)
737
870
{
 
871
#ifndef DBUG_OFF
 
872
  DBUG_ASSERT(field_types == 0 ||
 
873
              field_types[field_pos] == MYSQL_TYPE_FLOAT);
 
874
  field_pos++;
 
875
#endif
738
876
  buffer->set_real((double) from, decimals, thd->charset());
739
 
  return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
 
877
  return net_store_data((uchar*) buffer->ptr(), buffer->length());
740
878
}
741
879
 
742
880
 
743
 
bool Protocol_text::store(double from, uint32_t decimals, String *buffer)
 
881
bool Protocol_text::store(double from, uint32 decimals, String *buffer)
744
882
{
 
883
#ifndef DBUG_OFF
 
884
  DBUG_ASSERT(field_types == 0 ||
 
885
              field_types[field_pos] == MYSQL_TYPE_DOUBLE);
 
886
  field_pos++;
 
887
#endif
745
888
  buffer->set_real(from, decimals, thd->charset());
746
 
  return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
 
889
  return net_store_data((uchar*) buffer->ptr(), buffer->length());
747
890
}
748
891
 
749
892
 
751
894
{
752
895
  if (field->is_null())
753
896
    return store_null();
 
897
#ifndef DBUG_OFF
 
898
  field_pos++;
 
899
#endif
754
900
  char buff[MAX_FIELD_WIDTH];
755
901
  String str(buff,sizeof(buff), &my_charset_bin);
756
 
  const CHARSET_INFO * const tocs= this->thd->variables.character_set_results;
 
902
  CHARSET_INFO *tocs= this->thd->variables.character_set_results;
 
903
#ifndef DBUG_OFF
 
904
  TABLE *table= field->table;
 
905
  my_bitmap_map *old_map= 0;
 
906
  if (table->file)
 
907
    old_map= dbug_tmp_use_all_columns(table, table->read_set);
 
908
#endif
757
909
 
758
910
  field->val_str(&str);
 
911
#ifndef DBUG_OFF
 
912
  if (old_map)
 
913
    dbug_tmp_restore_column_map(table->read_set, old_map);
 
914
#endif
759
915
 
760
916
  return store_string_aux(str.ptr(), str.length(), str.charset(), tocs);
761
917
}
767
923
    we support 0-6 decimals for time.
768
924
*/
769
925
 
770
 
bool Protocol_text::store(DRIZZLE_TIME *tm)
 
926
bool Protocol_text::store(MYSQL_TIME *tm)
771
927
{
 
928
#ifndef DBUG_OFF
 
929
  DBUG_ASSERT(field_types == 0 ||
 
930
              field_types[field_pos] == MYSQL_TYPE_DATETIME ||
 
931
              field_types[field_pos] == MYSQL_TYPE_TIMESTAMP);
 
932
  field_pos++;
 
933
#endif
772
934
  char buff[40];
773
 
  uint32_t length;
774
 
  length= sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d",
 
935
  uint length;
 
936
  length= my_sprintf(buff,(buff, "%04d-%02d-%02d %02d:%02d:%02d",
775
937
                           (int) tm->year,
776
938
                           (int) tm->month,
777
939
                           (int) tm->day,
778
940
                           (int) tm->hour,
779
941
                           (int) tm->minute,
780
 
                           (int) tm->second);
 
942
                           (int) tm->second));
781
943
  if (tm->second_part)
782
 
    length+= sprintf(buff+length, ".%06d",
783
 
                                     (int)tm->second_part);
784
 
  return net_store_data((unsigned char*) buff, length);
 
944
    length+= my_sprintf(buff+length,(buff+length, ".%06d",
 
945
                                     (int)tm->second_part));
 
946
  return net_store_data((uchar*) buff, length);
785
947
}
786
948
 
787
949
 
788
 
bool Protocol_text::store_date(DRIZZLE_TIME *tm)
 
950
bool Protocol_text::store_date(MYSQL_TIME *tm)
789
951
{
 
952
#ifndef DBUG_OFF
 
953
  DBUG_ASSERT(field_types == 0 ||
 
954
              field_types[field_pos] == MYSQL_TYPE_DATE);
 
955
  field_pos++;
 
956
#endif
790
957
  char buff[MAX_DATE_STRING_REP_LENGTH];
791
958
  size_t length= my_date_to_str(tm, buff);
792
 
  return net_store_data((unsigned char*) buff, length);
 
959
  return net_store_data((uchar*) buff, length);
793
960
}
794
961
 
795
962
 
799
966
    we support 0-6 decimals for time.
800
967
*/
801
968
 
802
 
bool Protocol_text::store_time(DRIZZLE_TIME *tm)
 
969
bool Protocol_text::store_time(MYSQL_TIME *tm)
803
970
{
 
971
#ifndef DBUG_OFF
 
972
  DBUG_ASSERT(field_types == 0 ||
 
973
              field_types[field_pos] == MYSQL_TYPE_TIME);
 
974
  field_pos++;
 
975
#endif
804
976
  char buff[40];
805
 
  uint32_t length;
806
 
  uint32_t day= (tm->year || tm->month) ? 0 : tm->day;
807
 
  length= sprintf(buff, "%s%02ld:%02d:%02d",
 
977
  uint length;
 
978
  uint day= (tm->year || tm->month) ? 0 : tm->day;
 
979
  length= my_sprintf(buff,(buff, "%s%02ld:%02d:%02d",
808
980
                           tm->neg ? "-" : "",
809
981
                           (long) day*24L+(long) tm->hour,
810
982
                           (int) tm->minute,
811
 
                           (int) tm->second);
 
983
                           (int) tm->second));
812
984
  if (tm->second_part)
813
 
    length+= sprintf(buff+length, ".%06d", (int)tm->second_part);
814
 
  return net_store_data((unsigned char*) buff, length);
 
985
    length+= my_sprintf(buff+length,(buff+length, ".%06d", (int)tm->second_part));
 
986
  return net_store_data((uchar*) buff, length);
815
987
}
816
988