~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/protocol.cc

  • Committer: Monty Taylor
  • Date: 2008-07-01 14:33:36 UTC
  • mto: (28.1.12 backport_patch)
  • mto: This revision was merged to the branch mainline in revision 34.
  • Revision ID: monty@inaugust.com-20080701143336-8uihm7dhpu92rt0q
Somehow missed moving password.c. Duh.

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)
235
 
{
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);
253
 
}
254
 
 
255
 
void net_send_error_packet(THD *thd, uint32_t sql_errno, const char *err)
256
 
{
257
 
  NET *net= &thd->net;
258
 
  uint32_t length;
259
 
  /*
260
 
    buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + DRIZZLE_ERRMSG_SIZE:512
261
 
  */
262
 
  unsigned char buff[2+1+SQLSTATE_LENGTH+DRIZZLE_ERRMSG_SIZE], *pos;
 
266
                             uint server_status,
 
267
                             uint total_warn_count)
 
268
{
 
269
  if (thd->client_capabilities & CLIENT_PROTOCOL_41)
 
270
  {
 
271
    uchar buff[5];
 
272
    /*
 
273
      Don't send warn count during SP execution, as the warn_list
 
274
      is cleared between substatements, and mysqltest gets confused
 
275
    */
 
276
    uint tmp= min(total_warn_count, 65535);
 
277
    buff[0]= 254;
 
278
    int2store(buff+1, tmp);
 
279
    /*
 
280
      The following test should never be true, but it's better to do it
 
281
      because if 'is_fatal_error' is set the server is not going to execute
 
282
      other queries (see the if test in dispatch_command / COM_QUERY)
 
283
    */
 
284
    if (thd->is_fatal_error)
 
285
      server_status&= ~SERVER_MORE_RESULTS_EXISTS;
 
286
    int2store(buff + 3, server_status);
 
287
    VOID(my_net_write(net, buff, 5));
 
288
  }
 
289
  else
 
290
    VOID(my_net_write(net, eof_buff, 1));
 
291
}
 
292
 
 
293
/**
 
294
  Please client to send scrambled_password in old format.
 
295
     
 
296
  @param thd thread handle
 
297
 
 
298
  @retval
 
299
    0  ok
 
300
  @retval
 
301
   !0  error
 
302
*/
 
303
 
 
304
bool send_old_password_request(THD *thd)
 
305
{
 
306
  NET *net= &thd->net;
 
307
  return my_net_write(net, eof_buff, 1) || net_flush(net);
 
308
}
 
309
 
 
310
 
 
311
void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
 
312
{
 
313
  NET *net= &thd->net;
 
314
  uint length;
 
315
  /*
 
316
    buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + MYSQL_ERRMSG_SIZE:512
 
317
  */
 
318
  uchar buff[2+1+SQLSTATE_LENGTH+MYSQL_ERRMSG_SIZE], *pos;
 
319
 
 
320
  DBUG_ENTER("send_error_packet");
263
321
 
264
322
  if (net->vio == 0)
265
323
  {
266
 
    return;
 
324
    if (thd->bootstrap)
 
325
    {
 
326
      /* In bootstrap it's ok to print on stderr */
 
327
      fprintf(stderr,"ERROR: %d  %s\n",sql_errno,err);
 
328
    }
 
329
    DBUG_VOID_RETURN;
267
330
  }
268
331
 
269
332
  int2store(buff,sql_errno);
270
333
  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) -
 
334
  if (thd->client_capabilities & CLIENT_PROTOCOL_41)
 
335
  {
 
336
    /* The first # is to make the protocol backward compatible */
 
337
    buff[2]= '#';
 
338
    pos= (uchar*) strmov((char*) buff+3, mysql_errno_to_sqlstate(sql_errno));
 
339
  }
 
340
  length= (uint) (strmake((char*) pos, err, MYSQL_ERRMSG_SIZE-1) -
277
341
                  (char*) buff);
278
342
  err= (char*) buff;
279
343
 
280
 
  net_write_command(net,(unsigned char) 255, (unsigned char*) "", 0, (unsigned char*) err, length);
281
 
  return;
 
344
  VOID(net_write_command(net,(uchar) 255, (uchar*) "", 0, (uchar*) err,
 
345
                         length));
 
346
  DBUG_VOID_RETURN;
282
347
}
283
348
 
284
349
 
287
352
  We keep a separate version for that range because it's widely used in
288
353
  libmysql.
289
354
 
290
 
  uint32_t is used as agrument type because of MySQL type conventions:
291
 
  - uint32_t for 0..65536
 
355
  uint is used as agrument type because of MySQL type conventions:
 
356
  - uint for 0..65536
292
357
  - ulong for 0..4294967296
293
 
  - uint64_t for bigger numbers.
 
358
  - ulonglong for bigger numbers.
294
359
*/
295
360
 
296
 
static unsigned char *net_store_length_fast(unsigned char *packet, uint32_t length)
 
361
static uchar *net_store_length_fast(uchar *packet, uint length)
297
362
{
298
363
  if (length < 251)
299
364
  {
300
 
    *packet=(unsigned char) length;
 
365
    *packet=(uchar) length;
301
366
    return packet+1;
302
367
  }
303
368
  *packet++=252;
357
422
 
358
423
void net_end_statement(THD *thd)
359
424
{
360
 
  assert(! thd->main_da.is_sent);
 
425
  DBUG_ASSERT(! thd->main_da.is_sent);
361
426
 
362
427
  /* Can not be true, but do not take chances in production. */
363
428
  if (thd->main_da.is_sent)
387
452
    break;
388
453
  case Diagnostics_area::DA_EMPTY:
389
454
  default:
390
 
    assert(0);
 
455
    DBUG_ASSERT(0);
391
456
    net_send_ok(thd, thd->server_status, thd->total_warn_count,
392
457
                0, 0, NULL);
393
458
    break;
394
459
  }
395
 
  thd->main_da.is_sent= true;
 
460
  thd->main_da.is_sent= TRUE;
396
461
}
397
462
 
398
463
 
403
468
 
404
469
/* The following will only be used for short strings < 65K */
405
470
 
406
 
unsigned char *net_store_data(unsigned char *to, const unsigned char *from, size_t length)
 
471
uchar *net_store_data(uchar *to, const uchar *from, size_t length)
407
472
{
408
473
  to=net_store_length_fast(to,length);
409
474
  memcpy(to,from,length);
410
475
  return to+length;
411
476
}
412
477
 
413
 
unsigned char *net_store_data(unsigned char *to,int32_t from)
 
478
uchar *net_store_data(uchar *to,int32 from)
414
479
{
415
480
  char buff[20];
416
 
  uint32_t length=(uint) (int10_to_str(from,buff,10)-buff);
 
481
  uint length=(uint) (int10_to_str(from,buff,10)-buff);
417
482
  to=net_store_length_fast(to,length);
418
483
  memcpy(to,buff,length);
419
484
  return to+length;
420
485
}
421
486
 
422
 
unsigned char *net_store_data(unsigned char *to,int64_t from)
 
487
uchar *net_store_data(uchar *to,longlong from)
423
488
{
424
489
  char buff[22];
425
 
  uint32_t length=(uint) (int64_t10_to_str(from,buff,10)-buff);
 
490
  uint length=(uint) (longlong10_to_str(from,buff,10)-buff);
426
491
  to=net_store_length_fast(to,length);
427
492
  memcpy(to,buff,length);
428
493
  return to+length;
438
503
  thd=thd_arg;
439
504
  packet= &thd->packet;
440
505
  convert= &thd->convert_buffer;
 
506
#ifndef DBUG_OFF
 
507
  field_types= 0;
 
508
#endif
441
509
}
442
510
 
443
511
/**
476
544
    1   Error  (Note that in this case the error is not sent to the
477
545
    client)
478
546
*/
479
 
bool Protocol::send_fields(List<Item> *list, uint32_t flags)
 
547
bool Protocol::send_fields(List<Item> *list, uint flags)
480
548
{
481
549
  List_iterator_fast<Item> it(*list);
482
550
  Item *item;
483
 
  unsigned char buff[80];
 
551
  uchar buff[80];
484
552
  String tmp((char*) buff,sizeof(buff),&my_charset_bin);
485
553
  Protocol_text prot(thd);
486
554
  String *local_packet= prot.storage_packet();
487
 
  const CHARSET_INFO * const thd_charset= thd->variables.character_set_results;
 
555
  CHARSET_INFO *thd_charset= thd->variables.character_set_results;
 
556
  DBUG_ENTER("send_fields");
488
557
 
489
558
  if (flags & SEND_NUM_ROWS)
490
559
  {                             // Packet with number of elements
491
 
    unsigned char *pos= net_store_length(buff, list->elements);
 
560
    uchar *pos= net_store_length(buff, list->elements);
492
561
    (void) my_net_write(&thd->net, buff, (size_t) (pos-buff));
493
562
  }
494
563
 
 
564
#ifndef DBUG_OFF
 
565
  field_types= (enum_field_types*) thd->alloc(sizeof(field_types) *
 
566
                                              list->elements);
 
567
  uint count= 0;
 
568
#endif
 
569
 
495
570
  while ((item=it++))
496
571
  {
497
572
    char *pos;
498
 
    const CHARSET_INFO * const cs= system_charset_info;
 
573
    CHARSET_INFO *cs= system_charset_info;
499
574
    Send_field field;
500
575
    item->make_field(&field);
501
576
 
 
577
    /* Keep things compatible for old clients */
 
578
    if (field.type == MYSQL_TYPE_VARCHAR)
 
579
      field.type= MYSQL_TYPE_VAR_STRING;
 
580
 
502
581
    prot.prepare_for_resend();
503
582
 
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)
 
583
    if (thd->client_capabilities & CLIENT_PROTOCOL_41)
523
584
    {
524
 
      /* No conversion */
525
 
      int2store(pos, field.charsetnr);
526
 
      int4store(pos+2, field.length);
 
585
      if (prot.store(STRING_WITH_LEN("def"), cs, thd_charset) ||
 
586
          prot.store(field.db_name, (uint) strlen(field.db_name),
 
587
                     cs, thd_charset) ||
 
588
          prot.store(field.table_name, (uint) strlen(field.table_name),
 
589
                     cs, thd_charset) ||
 
590
          prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
 
591
                     cs, thd_charset) ||
 
592
          prot.store(field.col_name, (uint) strlen(field.col_name),
 
593
                     cs, thd_charset) ||
 
594
          prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
 
595
                     cs, thd_charset) ||
 
596
          local_packet->realloc(local_packet->length()+12))
 
597
        goto err;
 
598
      /* Store fixed length fields */
 
599
      pos= (char*) local_packet->ptr()+local_packet->length();
 
600
      *pos++= 12;                               // Length of packed fields
 
601
      if (item->collation.collation == &my_charset_bin || thd_charset == NULL)
 
602
      {
 
603
        /* No conversion */
 
604
        int2store(pos, field.charsetnr);
 
605
        int4store(pos+2, field.length);
 
606
      }
 
607
      else
 
608
      {
 
609
        /* With conversion */
 
610
        uint max_char_len;
 
611
        int2store(pos, thd_charset->number);
 
612
        /*
 
613
          For TEXT/BLOB columns, field_length describes the maximum data
 
614
          length in bytes. There is no limit to the number of characters
 
615
          that a TEXT column can store, as long as the data fits into
 
616
          the designated space.
 
617
          For the rest of textual columns, field_length is evaluated as
 
618
          char_count * mbmaxlen, where character count is taken from the
 
619
          definition of the column. In other words, the maximum number
 
620
          of characters here is limited by the column definition.
 
621
        */
 
622
        max_char_len= (field.type >= (int) MYSQL_TYPE_TINY_BLOB &&
 
623
                      field.type <= (int) MYSQL_TYPE_BLOB) ?
 
624
                      field.length / item->collation.collation->mbminlen :
 
625
                      field.length / item->collation.collation->mbmaxlen;
 
626
        int4store(pos+2, max_char_len * thd_charset->mbmaxlen);
 
627
      }
 
628
      pos[6]= field.type;
 
629
      int2store(pos+7,field.flags);
 
630
      pos[9]= (char) field.decimals;
 
631
      pos[10]= 0;                               // For the future
 
632
      pos[11]= 0;                               // For the future
 
633
      pos+= 12;
527
634
    }
528
635
    else
529
636
    {
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);
 
637
      if (prot.store(field.table_name, (uint) strlen(field.table_name),
 
638
                     cs, thd_charset) ||
 
639
          prot.store(field.col_name, (uint) strlen(field.col_name),
 
640
                     cs, thd_charset) ||
 
641
          local_packet->realloc(local_packet->length()+10))
 
642
        goto err;
 
643
      pos= (char*) local_packet->ptr()+local_packet->length();
 
644
 
 
645
#ifdef TO_BE_DELETED_IN_6
 
646
      if (!(thd->client_capabilities & CLIENT_LONG_FLAG))
 
647
      {
 
648
        pos[0]=3;
 
649
        int3store(pos+1,field.length);
 
650
        pos[4]=1;
 
651
        pos[5]=field.type;
 
652
        pos[6]=2;
 
653
        pos[7]= (char) field.flags;
 
654
        pos[8]= (char) field.decimals;
 
655
        pos+= 9;
 
656
      }
 
657
      else
 
658
#endif
 
659
      {
 
660
        pos[0]=3;
 
661
        int3store(pos+1,field.length);
 
662
        pos[4]=1;
 
663
        pos[5]=field.type;
 
664
        pos[6]=3;
 
665
        int2store(pos+7,field.flags);
 
666
        pos[9]= (char) field.decimals;
 
667
        pos+= 10;
 
668
      }
545
669
    }
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
670
    local_packet->length((uint) (pos - local_packet->ptr()));
554
671
    if (flags & SEND_DEFAULTS)
555
672
      item->send(&prot, &tmp);                  // Send default value
556
673
    if (prot.write())
557
674
      break;                                    /* purecov: inspected */
 
675
#ifndef DBUG_OFF
 
676
    field_types[count++]= field.type;
 
677
#endif
558
678
  }
559
679
 
560
680
  if (flags & SEND_EOF)
566
686
    */
567
687
    write_eof_packet(thd, &thd->net, thd->server_status, thd->total_warn_count);
568
688
  }
569
 
  return(prepare_for_send(list));
 
689
  DBUG_RETURN(prepare_for_send(list));
570
690
 
571
691
err:
572
692
  my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES),
573
693
             MYF(0));   /* purecov: inspected */
574
 
  return(1);                            /* purecov: inspected */
 
694
  DBUG_RETURN(1);                               /* purecov: inspected */
575
695
}
576
696
 
577
697
 
578
698
bool Protocol::write()
579
699
{
580
 
  return(my_net_write(&thd->net, (unsigned char*) packet->ptr(),
 
700
  DBUG_ENTER("Protocol::write");
 
701
  DBUG_RETURN(my_net_write(&thd->net, (uchar*) packet->ptr(),
581
702
                           packet->length()));
582
703
}
583
704
 
585
706
/**
586
707
  Send \\0 end terminated string.
587
708
 
588
 
  @param from   NULL or \\0 terminated string
 
709
  @param from   NullS or \\0 terminated string
589
710
 
590
711
  @note
591
712
    In most cases one should use store(from, length) instead of this function
596
717
    1           error
597
718
*/
598
719
 
599
 
bool Protocol::store(const char *from, const CHARSET_INFO * const cs)
 
720
bool Protocol::store(const char *from, CHARSET_INFO *cs)
600
721
{
601
722
  if (!from)
602
723
    return store_null();
603
 
  uint32_t length= strlen(from);
 
724
  uint length= strlen(from);
604
725
  return store(from, length, cs);
605
726
}
606
727
 
613
734
{
614
735
  char buf[256];
615
736
  String tmp(buf, sizeof(buf), &my_charset_bin);
616
 
  uint32_t len;
 
737
  uint32 len;
617
738
  I_List_iterator<i_string> it(*str_list);
618
739
  i_string* s;
619
740
 
640
761
void Protocol_text::prepare_for_resend()
641
762
{
642
763
  packet->length(0);
 
764
#ifndef DBUG_OFF
 
765
  field_pos= 0;
 
766
#endif
643
767
}
644
768
 
645
769
bool Protocol_text::store_null()
646
770
{
 
771
#ifndef DBUG_OFF
 
772
  field_pos++;
 
773
#endif
647
774
  char buff[1];
648
775
  buff[0]= (char)251;
649
776
  return packet->append(buff, sizeof(buff), PACKET_BUFFER_EXTRA_ALLOC);
656
783
*/
657
784
 
658
785
bool Protocol::store_string_aux(const char *from, size_t length,
659
 
                                const CHARSET_INFO * const fromcs,
660
 
                                                                const CHARSET_INFO * const tocs)
 
786
                                CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
661
787
{
662
788
  /* 'tocs' is set 0 when client issues SET character_set_results=NULL */
663
789
  if (tocs && !my_charset_same(fromcs, tocs) &&
665
791
      tocs != &my_charset_bin)
666
792
  {
667
793
    /* Store with conversion */
668
 
    return net_store_data((unsigned char*) from, length, fromcs, tocs);
 
794
    return net_store_data((uchar*) from, length, fromcs, tocs);
669
795
  }
670
796
  /* 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
 
{
 
797
  return net_store_data((uchar*) from, length);
 
798
}
 
799
 
 
800
 
 
801
bool Protocol_text::store(const char *from, size_t length,
 
802
                          CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
 
803
{
 
804
#ifndef DBUG_OFF
 
805
  DBUG_ASSERT(field_types == 0 ||
 
806
              field_types[field_pos] == MYSQL_TYPE_DECIMAL ||
 
807
              field_types[field_pos] == MYSQL_TYPE_BIT ||
 
808
              field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL ||
 
809
              (field_types[field_pos] >= MYSQL_TYPE_ENUM &&
 
810
               field_types[field_pos] <= MYSQL_TYPE_GEOMETRY));
 
811
  field_pos++;
 
812
#endif
 
813
  return store_string_aux(from, length, fromcs, tocs);
 
814
}
 
815
 
 
816
 
 
817
bool Protocol_text::store(const char *from, size_t length,
 
818
                          CHARSET_INFO *fromcs)
 
819
{
 
820
  CHARSET_INFO *tocs= this->thd->variables.character_set_results;
 
821
#ifndef DBUG_OFF
 
822
  DBUG_ASSERT(field_types == 0 ||
 
823
              field_types[field_pos] == MYSQL_TYPE_DECIMAL ||
 
824
              field_types[field_pos] == MYSQL_TYPE_BIT ||
 
825
              field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL ||
 
826
              field_types[field_pos] == MYSQL_TYPE_NEWDATE ||
 
827
              (field_types[field_pos] >= MYSQL_TYPE_ENUM &&
 
828
               field_types[field_pos] <= MYSQL_TYPE_GEOMETRY));
 
829
  field_pos++;
 
830
#endif
 
831
  return store_string_aux(from, length, fromcs, tocs);
 
832
}
 
833
 
 
834
 
 
835
bool Protocol_text::store_tiny(longlong from)
 
836
{
 
837
#ifndef DBUG_OFF
 
838
  DBUG_ASSERT(field_types == 0 || field_types[field_pos] == MYSQL_TYPE_TINY);
 
839
  field_pos++;
 
840
#endif
693
841
  char buff[20];
694
 
  return net_store_data((unsigned char*) buff,
 
842
  return net_store_data((uchar*) buff,
695
843
                        (size_t) (int10_to_str((int) from, buff, -10) - buff));
696
844
}
697
845
 
698
846
 
699
 
bool Protocol_text::store_short(int64_t from)
 
847
bool Protocol_text::store_short(longlong from)
700
848
{
 
849
#ifndef DBUG_OFF
 
850
  DBUG_ASSERT(field_types == 0 ||
 
851
              field_types[field_pos] == MYSQL_TYPE_YEAR ||
 
852
              field_types[field_pos] == MYSQL_TYPE_SHORT);
 
853
  field_pos++;
 
854
#endif
701
855
  char buff[20];
702
 
  return net_store_data((unsigned char*) buff,
 
856
  return net_store_data((uchar*) buff,
703
857
                        (size_t) (int10_to_str((int) from, buff, -10) -
704
858
                                  buff));
705
859
}
706
860
 
707
861
 
708
 
bool Protocol_text::store_long(int64_t from)
 
862
bool Protocol_text::store_long(longlong from)
709
863
{
 
864
#ifndef DBUG_OFF
 
865
  DBUG_ASSERT(field_types == 0 ||
 
866
              field_types[field_pos] == MYSQL_TYPE_INT24 ||
 
867
              field_types[field_pos] == MYSQL_TYPE_LONG);
 
868
  field_pos++;
 
869
#endif
710
870
  char buff[20];
711
 
  return net_store_data((unsigned char*) buff,
 
871
  return net_store_data((uchar*) buff,
712
872
                        (size_t) (int10_to_str((long int)from, buff,
713
873
                                               (from <0)?-10:10)-buff));
714
874
}
715
875
 
716
876
 
717
 
bool Protocol_text::store_int64_t(int64_t from, bool unsigned_flag)
 
877
bool Protocol_text::store_longlong(longlong from, bool unsigned_flag)
718
878
{
 
879
#ifndef DBUG_OFF
 
880
  DBUG_ASSERT(field_types == 0 ||
 
881
              field_types[field_pos] == MYSQL_TYPE_LONGLONG);
 
882
  field_pos++;
 
883
#endif
719
884
  char buff[22];
720
 
  return net_store_data((unsigned char*) buff,
721
 
                        (size_t) (int64_t10_to_str(from,buff,
 
885
  return net_store_data((uchar*) buff,
 
886
                        (size_t) (longlong10_to_str(from,buff,
722
887
                                                    unsigned_flag ? 10 : -10)-
723
888
                                  buff));
724
889
}
726
891
 
727
892
bool Protocol_text::store_decimal(const my_decimal *d)
728
893
{
 
894
#ifndef DBUG_OFF
 
895
  DBUG_ASSERT(field_types == 0 ||
 
896
              field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL);
 
897
  field_pos++;
 
898
#endif
729
899
  char buff[DECIMAL_MAX_STR_LENGTH];
730
900
  String str(buff, sizeof(buff), &my_charset_bin);
731
901
  (void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
732
 
  return net_store_data((unsigned char*) str.ptr(), str.length());
 
902
  return net_store_data((uchar*) str.ptr(), str.length());
733
903
}
734
904
 
735
905
 
736
 
bool Protocol_text::store(float from, uint32_t decimals, String *buffer)
 
906
bool Protocol_text::store(float from, uint32 decimals, String *buffer)
737
907
{
 
908
#ifndef DBUG_OFF
 
909
  DBUG_ASSERT(field_types == 0 ||
 
910
              field_types[field_pos] == MYSQL_TYPE_FLOAT);
 
911
  field_pos++;
 
912
#endif
738
913
  buffer->set_real((double) from, decimals, thd->charset());
739
 
  return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
 
914
  return net_store_data((uchar*) buffer->ptr(), buffer->length());
740
915
}
741
916
 
742
917
 
743
 
bool Protocol_text::store(double from, uint32_t decimals, String *buffer)
 
918
bool Protocol_text::store(double from, uint32 decimals, String *buffer)
744
919
{
 
920
#ifndef DBUG_OFF
 
921
  DBUG_ASSERT(field_types == 0 ||
 
922
              field_types[field_pos] == MYSQL_TYPE_DOUBLE);
 
923
  field_pos++;
 
924
#endif
745
925
  buffer->set_real(from, decimals, thd->charset());
746
 
  return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
 
926
  return net_store_data((uchar*) buffer->ptr(), buffer->length());
747
927
}
748
928
 
749
929
 
751
931
{
752
932
  if (field->is_null())
753
933
    return store_null();
 
934
#ifndef DBUG_OFF
 
935
  field_pos++;
 
936
#endif
754
937
  char buff[MAX_FIELD_WIDTH];
755
938
  String str(buff,sizeof(buff), &my_charset_bin);
756
 
  const CHARSET_INFO * const tocs= this->thd->variables.character_set_results;
 
939
  CHARSET_INFO *tocs= this->thd->variables.character_set_results;
 
940
#ifndef DBUG_OFF
 
941
  TABLE *table= field->table;
 
942
  my_bitmap_map *old_map= 0;
 
943
  if (table->file)
 
944
    old_map= dbug_tmp_use_all_columns(table, table->read_set);
 
945
#endif
757
946
 
758
947
  field->val_str(&str);
 
948
#ifndef DBUG_OFF
 
949
  if (old_map)
 
950
    dbug_tmp_restore_column_map(table->read_set, old_map);
 
951
#endif
759
952
 
760
953
  return store_string_aux(str.ptr(), str.length(), str.charset(), tocs);
761
954
}
767
960
    we support 0-6 decimals for time.
768
961
*/
769
962
 
770
 
bool Protocol_text::store(DRIZZLE_TIME *tm)
 
963
bool Protocol_text::store(MYSQL_TIME *tm)
771
964
{
 
965
#ifndef DBUG_OFF
 
966
  DBUG_ASSERT(field_types == 0 ||
 
967
              field_types[field_pos] == MYSQL_TYPE_DATETIME ||
 
968
              field_types[field_pos] == MYSQL_TYPE_TIMESTAMP);
 
969
  field_pos++;
 
970
#endif
772
971
  char buff[40];
773
 
  uint32_t length;
774
 
  length= sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d",
 
972
  uint length;
 
973
  length= my_sprintf(buff,(buff, "%04d-%02d-%02d %02d:%02d:%02d",
775
974
                           (int) tm->year,
776
975
                           (int) tm->month,
777
976
                           (int) tm->day,
778
977
                           (int) tm->hour,
779
978
                           (int) tm->minute,
780
 
                           (int) tm->second);
 
979
                           (int) tm->second));
781
980
  if (tm->second_part)
782
 
    length+= sprintf(buff+length, ".%06d",
783
 
                                     (int)tm->second_part);
784
 
  return net_store_data((unsigned char*) buff, length);
 
981
    length+= my_sprintf(buff+length,(buff+length, ".%06d",
 
982
                                     (int)tm->second_part));
 
983
  return net_store_data((uchar*) buff, length);
785
984
}
786
985
 
787
986
 
788
 
bool Protocol_text::store_date(DRIZZLE_TIME *tm)
 
987
bool Protocol_text::store_date(MYSQL_TIME *tm)
789
988
{
 
989
#ifndef DBUG_OFF
 
990
  DBUG_ASSERT(field_types == 0 ||
 
991
              field_types[field_pos] == MYSQL_TYPE_DATE);
 
992
  field_pos++;
 
993
#endif
790
994
  char buff[MAX_DATE_STRING_REP_LENGTH];
791
995
  size_t length= my_date_to_str(tm, buff);
792
 
  return net_store_data((unsigned char*) buff, length);
 
996
  return net_store_data((uchar*) buff, length);
793
997
}
794
998
 
795
999
 
799
1003
    we support 0-6 decimals for time.
800
1004
*/
801
1005
 
802
 
bool Protocol_text::store_time(DRIZZLE_TIME *tm)
 
1006
bool Protocol_text::store_time(MYSQL_TIME *tm)
803
1007
{
 
1008
#ifndef DBUG_OFF
 
1009
  DBUG_ASSERT(field_types == 0 ||
 
1010
              field_types[field_pos] == MYSQL_TYPE_TIME);
 
1011
  field_pos++;
 
1012
#endif
804
1013
  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",
 
1014
  uint length;
 
1015
  uint day= (tm->year || tm->month) ? 0 : tm->day;
 
1016
  length= my_sprintf(buff,(buff, "%s%02ld:%02d:%02d",
808
1017
                           tm->neg ? "-" : "",
809
1018
                           (long) day*24L+(long) tm->hour,
810
1019
                           (int) tm->minute,
811
 
                           (int) tm->second);
 
1020
                           (int) tm->second));
812
1021
  if (tm->second_part)
813
 
    length+= sprintf(buff+length, ".%06d", (int)tm->second_part);
814
 
  return net_store_data((unsigned char*) buff, length);
 
1022
    length+= my_sprintf(buff+length,(buff+length, ".%06d", (int)tm->second_part));
 
1023
  return net_store_data((uchar*) buff, length);
815
1024
}
816
1025