~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/protocol.cc

  • Committer: Monty Taylor
  • Date: 2008-08-16 21:06:22 UTC
  • Revision ID: monty@inaugust.com-20080816210622-zpnn13unyinqzn72
Updated po files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
  The actual communction is handled by the net_xxx functions in net_serv.cc
21
21
*/
22
22
#include <drizzled/server_includes.h>
23
 
#include <drizzled/error.h>
24
 
#include <drizzled/sql_state.h>
25
 
#include <libdrizzle/pack.h>
26
 
#include <drizzled/protocol.h>
27
 
#include <drizzled/session.h>
 
23
#include <drizzled/drizzled_error_messages.h>
28
24
 
29
25
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
30
26
/* Declared non-static only because of the embedded library. */
31
 
static void net_send_error_packet(Session *session, uint32_t sql_errno, const char *err);
32
 
static void write_eof_packet(Session *session, NET *net,
33
 
                             uint32_t server_status, uint32_t total_warn_count);
 
27
static void net_send_error_packet(THD *thd, uint sql_errno, const char *err);
 
28
static void write_eof_packet(THD *thd, NET *net,
 
29
                             uint server_status, uint total_warn_count);
34
30
 
35
 
bool Protocol::net_store_data(const unsigned char *from, size_t length)
 
31
bool Protocol::net_store_data(const uchar *from, size_t length)
36
32
{
37
 
  size_t packet_length= packet->length();
38
 
  /*
 
33
  ulong packet_length=packet->length();
 
34
  /* 
39
35
     The +9 comes from that strings of length longer than 16M require
40
36
     9 bytes to be stored (see net_store_length).
41
37
  */
42
38
  if (packet_length+9+length > packet->alloced_length() &&
43
39
      packet->realloc(packet_length+9+length))
44
40
    return 1;
45
 
  unsigned char *to= net_store_length((unsigned char*) packet->ptr()+packet_length, length);
 
41
  uchar *to= net_store_length((uchar*) packet->ptr()+packet_length, length);
46
42
  memcpy(to,from,length);
47
 
  packet->length((size_t) (to+length-(unsigned char*) packet->ptr()));
 
43
  packet->length((uint) (to+length-(uchar*) packet->ptr()));
48
44
  return 0;
49
45
}
50
46
 
53
49
 
54
50
/*
55
51
  net_store_data() - extended version with character set conversion.
56
 
 
 
52
  
57
53
  It is optimized for short strings whose length after
58
54
  conversion is garanteed to be less than 251, which accupies
59
55
  exactly one byte to store length. It allows not to use
63
59
  because column, table, database names fit into this limit.
64
60
*/
65
61
 
66
 
bool Protocol::net_store_data(const unsigned char *from, size_t length,
 
62
bool Protocol::net_store_data(const uchar *from, size_t length,
67
63
                              const CHARSET_INFO * const from_cs,
68
64
                                                          const CHARSET_INFO * const to_cs)
69
65
{
70
 
  uint32_t dummy_errors;
 
66
  uint dummy_errors;
71
67
  /* Calculate maxumum possible result length */
72
 
  uint32_t conv_length= to_cs->mbmaxlen * length / from_cs->mbminlen;
 
68
  uint conv_length= to_cs->mbmaxlen * length / from_cs->mbminlen;
73
69
  if (conv_length > 250)
74
70
  {
75
71
    /*
79
75
      For example, when converting from utf8 (mbmaxlen=3) to latin1,
80
76
      conv_length=300 means that the result length can vary between 100 to 300.
81
77
      length=100 needs one byte, length=300 needs to bytes.
82
 
 
 
78
      
83
79
      Thus conversion directly to "packet" is not worthy.
84
80
      Let's use "convert" as a temporary buffer.
85
81
    */
86
82
    return (convert->copy((const char*) from, length, from_cs,
87
83
                          to_cs, &dummy_errors) ||
88
 
            net_store_data((const unsigned char*) convert->ptr(), convert->length()));
 
84
            net_store_data((const uchar*) convert->ptr(), convert->length()));
89
85
  }
90
86
 
91
 
  size_t packet_length= packet->length();
92
 
  size_t new_length= packet_length + conv_length + 1;
 
87
  ulong packet_length= packet->length();
 
88
  ulong new_length= packet_length + conv_length + 1;
93
89
 
94
90
  if (new_length > packet->alloced_length() && packet->realloc(new_length))
95
91
    return 1;
100
96
  to+= copy_and_convert(to, conv_length, to_cs,
101
97
                        (const char*) from, length, from_cs, &dummy_errors);
102
98
 
103
 
  net_store_length((unsigned char*) length_pos, to - length_pos - 1);
 
99
  net_store_length((uchar*) length_pos, to - length_pos - 1);
104
100
  packet->length((uint) (to - packet->ptr()));
105
101
  return 0;
106
102
}
118
114
  critical that every error that can be intercepted is issued in one
119
115
  place only, my_message_sql.
120
116
*/
121
 
void net_send_error(Session *session, uint32_t sql_errno, const char *err)
 
117
void net_send_error(THD *thd, uint sql_errno, const char *err)
122
118
{
123
119
  assert(sql_errno);
124
120
  assert(err && err[0]);
127
123
    It's one case when we can push an error even though there
128
124
    is an OK or EOF already.
129
125
  */
130
 
  session->main_da.can_overwrite_status= true;
 
126
  thd->main_da.can_overwrite_status= true;
131
127
 
132
128
  /* Abort multi-result sets */
133
 
  session->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
134
 
 
135
 
  net_send_error_packet(session, sql_errno, err);
136
 
 
137
 
  session->main_da.can_overwrite_status= false;
 
129
  thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
 
130
 
 
131
  net_send_error_packet(thd, sql_errno, err);
 
132
 
 
133
  thd->main_da.can_overwrite_status= false;
138
134
}
139
135
 
140
136
/**
145
141
  - 0               : Marker (1 byte)
146
142
  - affected_rows       : Stored in 1-9 bytes
147
143
  - id          : Stored in 1-9 bytes
148
 
  - server_status       : Copy of session->server_status;  Can be used by client
 
144
  - server_status       : Copy of thd->server_status;  Can be used by client
149
145
  to check if we are inside an transaction.
150
146
  New in 4.0 protocol
151
147
  - warning_count       : Stored in 2 bytes; New in 4.1 protocol
152
148
  - message             : Stored as packed length (1-9 bytes) + message.
153
149
  Is not stored if no message.
154
150
 
155
 
  @param session                   Thread handler
 
151
  @param thd               Thread handler
156
152
  @param affected_rows     Number of rows changed by statement
157
153
  @param id                Auto_increment id for first row (if used)
158
154
  @param message           Message to send to the client (Used by mysql_status)
159
155
*/
160
156
 
161
157
static void
162
 
net_send_ok(Session *session,
163
 
            uint32_t server_status, uint32_t total_warn_count,
 
158
net_send_ok(THD *thd,
 
159
            uint server_status, uint total_warn_count,
164
160
            ha_rows affected_rows, uint64_t id, const char *message)
165
161
{
166
 
  NET *net= &session->net;
167
 
  unsigned char buff[DRIZZLE_ERRMSG_SIZE+10],*pos;
 
162
  NET *net= &thd->net;
 
163
  uchar buff[DRIZZLE_ERRMSG_SIZE+10],*pos;
168
164
 
169
165
  if (! net->vio)       // hack for re-parsing queries
170
166
  {
179
175
  pos+=2;
180
176
 
181
177
  /* We can only return up to 65535 warnings in two bytes */
182
 
  uint32_t tmp= cmin(total_warn_count, (uint)65535);
 
178
  uint tmp= min(total_warn_count, (uint)65535);
183
179
  int2store(pos, tmp);
184
180
  pos+= 2;
185
181
 
186
 
  session->main_da.can_overwrite_status= true;
 
182
  thd->main_da.can_overwrite_status= true;
187
183
 
188
184
  if (message && message[0])
189
 
    pos= net_store_data(pos, (unsigned char*) message, strlen(message));
190
 
  my_net_write(net, buff, (size_t) (pos-buff));
191
 
  net_flush(net);
 
185
    pos= net_store_data(pos, (uchar*) message, strlen(message));
 
186
  VOID(my_net_write(net, buff, (size_t) (pos-buff)));
 
187
  VOID(net_flush(net));
192
188
 
193
 
  session->main_da.can_overwrite_status= false;
 
189
  thd->main_da.can_overwrite_status= false;
194
190
}
195
191
 
196
192
/**
207
203
  we don't want to report the warning count until all data is sent to the
208
204
  client.
209
205
 
210
 
  @param session                Thread handler
 
206
  @param thd            Thread handler
211
207
  @param no_flush       Set to 1 if there will be more data to the client,
212
208
                    like in send_fields().
213
 
*/
 
209
*/    
214
210
 
215
211
static void
216
 
net_send_eof(Session *session, uint32_t server_status, uint32_t total_warn_count)
 
212
net_send_eof(THD *thd, uint server_status, uint total_warn_count)
217
213
{
218
 
  NET *net= &session->net;
 
214
  NET *net= &thd->net;
219
215
  /* Set to true if no active vio, to work well in case of --init-file */
220
216
  if (net->vio != 0)
221
217
  {
222
 
    session->main_da.can_overwrite_status= true;
223
 
    write_eof_packet(session, net, server_status, total_warn_count);
224
 
    net_flush(net);
225
 
    session->main_da.can_overwrite_status= false;
 
218
    thd->main_da.can_overwrite_status= true;
 
219
    write_eof_packet(thd, net, server_status, total_warn_count);
 
220
    VOID(net_flush(net));
 
221
    thd->main_da.can_overwrite_status= false;
226
222
  }
227
223
}
228
224
 
232
228
  write it to the network output buffer.
233
229
*/
234
230
 
235
 
static void write_eof_packet(Session *session, NET *net,
236
 
                             uint32_t server_status,
237
 
                             uint32_t total_warn_count)
 
231
static void write_eof_packet(THD *thd, NET *net,
 
232
                             uint server_status,
 
233
                             uint total_warn_count)
238
234
{
239
 
  unsigned char buff[5];
 
235
  uchar buff[5];
240
236
  /*
241
237
    Don't send warn count during SP execution, as the warn_list
242
238
    is cleared between substatements, and mysqltest gets confused
243
239
  */
244
 
  uint32_t tmp= cmin(total_warn_count, (uint)65535);
 
240
  uint tmp= min(total_warn_count, (uint)65535);
245
241
  buff[0]= DRIZZLE_PROTOCOL_NO_MORE_DATA;
246
242
  int2store(buff+1, tmp);
247
243
  /*
249
245
    because if 'is_fatal_error' is set the server is not going to execute
250
246
    other queries (see the if test in dispatch_command / COM_QUERY)
251
247
  */
252
 
  if (session->is_fatal_error)
 
248
  if (thd->is_fatal_error)
253
249
    server_status&= ~SERVER_MORE_RESULTS_EXISTS;
254
250
  int2store(buff + 3, server_status);
255
 
  my_net_write(net, buff, 5);
 
251
  VOID(my_net_write(net, buff, 5));
256
252
}
257
253
 
258
 
void net_send_error_packet(Session *session, uint32_t sql_errno, const char *err)
 
254
void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
259
255
{
260
 
  NET *net= &session->net;
261
 
  uint32_t length;
 
256
  NET *net= &thd->net;
 
257
  uint length;
262
258
  /*
263
259
    buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + DRIZZLE_ERRMSG_SIZE:512
264
260
  */
265
 
  unsigned char buff[2+1+SQLSTATE_LENGTH+DRIZZLE_ERRMSG_SIZE], *pos;
 
261
  uchar buff[2+1+SQLSTATE_LENGTH+DRIZZLE_ERRMSG_SIZE], *pos;
266
262
 
267
263
  if (net->vio == 0)
268
264
  {
274
270
 
275
271
  /* The first # is to make the protocol backward compatible */
276
272
  buff[2]= '#';
277
 
  pos= (unsigned char*) strcpy((char*) buff+3, drizzle_errno_to_sqlstate(sql_errno));
278
 
  pos+= strlen(drizzle_errno_to_sqlstate(sql_errno));
 
273
  pos= (uchar*) stpcpy((char*) buff+3, drizzle_errno_to_sqlstate(sql_errno));
279
274
 
280
 
  char *tmp= strncpy((char*)pos, err, DRIZZLE_ERRMSG_SIZE-1);
281
 
  tmp+= strlen((char*)pos);
282
 
  tmp[0]= '\0';
283
 
  length= (uint32_t)(tmp-(char*)buff);
 
275
  length= (uint) (strmake((char*) pos, err, DRIZZLE_ERRMSG_SIZE-1) -
 
276
                  (char*) buff);
284
277
  err= (char*) buff;
285
278
 
286
 
  net_write_command(net,(unsigned char) 255, (unsigned char*) "", 0, (unsigned char*) err, length);
 
279
  VOID(net_write_command(net,(uchar) 255, (uchar*) "", 0, (uchar*) err,
 
280
                         length));
287
281
  return;
288
282
}
289
283
 
293
287
  We keep a separate version for that range because it's widely used in
294
288
  libmysql.
295
289
 
296
 
  uint32_t is used as agrument type because of MySQL type conventions:
297
 
  - uint32_t for 0..65536
 
290
  uint is used as agrument type because of MySQL type conventions:
 
291
  - uint for 0..65536
298
292
  - ulong for 0..4294967296
299
293
  - uint64_t for bigger numbers.
300
294
*/
301
295
 
302
 
static unsigned char *net_store_length_fast(unsigned char *packet, uint32_t length)
 
296
static uchar *net_store_length_fast(uchar *packet, uint length)
303
297
{
304
298
  if (length < 251)
305
299
  {
306
 
    *packet=(unsigned char) length;
 
300
    *packet=(uchar) length;
307
301
    return packet+1;
308
302
  }
309
303
  *packet++=252;
310
 
  int2store(packet,(uint32_t) length);
311
 
 
 
304
  int2store(packet,(uint) length);
312
305
  return packet+2;
313
306
}
314
307
 
315
308
/**
316
309
  Send the status of the current statement execution over network.
317
310
 
318
 
  @param  session   in fact, carries two parameters, NET for the transport and
 
311
  @param  thd   in fact, carries two parameters, NET for the transport and
319
312
                Diagnostics_area as the source of status information.
320
313
 
321
314
  In MySQL, there are two types of SQL statements: those that return
362
355
          Diagnostics_area::is_sent is set for debugging purposes only.
363
356
*/
364
357
 
365
 
void net_end_statement(Session *session)
 
358
void net_end_statement(THD *thd)
366
359
{
367
 
  assert(! session->main_da.is_sent);
 
360
  assert(! thd->main_da.is_sent);
368
361
 
369
362
  /* Can not be true, but do not take chances in production. */
370
 
  if (session->main_da.is_sent)
 
363
  if (thd->main_da.is_sent)
371
364
    return;
372
365
 
373
 
  switch (session->main_da.status()) {
 
366
  switch (thd->main_da.status()) {
374
367
  case Diagnostics_area::DA_ERROR:
375
368
    /* The query failed, send error to log and abort bootstrap. */
376
 
    net_send_error(session,
377
 
                   session->main_da.sql_errno(),
378
 
                   session->main_da.message());
 
369
    net_send_error(thd,
 
370
                   thd->main_da.sql_errno(),
 
371
                   thd->main_da.message());
379
372
    break;
380
373
  case Diagnostics_area::DA_EOF:
381
 
    net_send_eof(session,
382
 
                 session->main_da.server_status(),
383
 
                 session->main_da.total_warn_count());
 
374
    net_send_eof(thd,
 
375
                 thd->main_da.server_status(),
 
376
                 thd->main_da.total_warn_count());
384
377
    break;
385
378
  case Diagnostics_area::DA_OK:
386
 
    net_send_ok(session,
387
 
                session->main_da.server_status(),
388
 
                session->main_da.total_warn_count(),
389
 
                session->main_da.affected_rows(),
390
 
                session->main_da.last_insert_id(),
391
 
                session->main_da.message());
 
379
    net_send_ok(thd,
 
380
                thd->main_da.server_status(),
 
381
                thd->main_da.total_warn_count(),
 
382
                thd->main_da.affected_rows(),
 
383
                thd->main_da.last_insert_id(),
 
384
                thd->main_da.message());
392
385
    break;
393
386
  case Diagnostics_area::DA_DISABLED:
394
387
    break;
395
388
  case Diagnostics_area::DA_EMPTY:
396
389
  default:
397
 
    //TODO: Something is being masked here by commenting this out
398
 
    //  assert(0);
399
 
    net_send_ok(session, session->server_status, session->total_warn_count,
 
390
    assert(0);
 
391
    net_send_ok(thd, thd->server_status, thd->total_warn_count,
400
392
                0, 0, NULL);
401
393
    break;
402
394
  }
403
 
  session->main_da.is_sent= true;
 
395
  thd->main_da.is_sent= true;
404
396
}
405
397
 
406
398
 
411
403
 
412
404
/* The following will only be used for short strings < 65K */
413
405
 
414
 
unsigned char *net_store_data(unsigned char *to, const unsigned char *from, size_t length)
 
406
uchar *net_store_data(uchar *to, const uchar *from, size_t length)
415
407
{
416
408
  to=net_store_length_fast(to,length);
417
409
  memcpy(to,from,length);
418
410
  return to+length;
419
411
}
420
412
 
421
 
unsigned char *net_store_data(unsigned char *to,int32_t from)
 
413
uchar *net_store_data(uchar *to,int32_t from)
422
414
{
423
415
  char buff[20];
424
 
  uint32_t length=(uint) (int10_to_str(from,buff,10)-buff);
 
416
  uint length=(uint) (int10_to_str(from,buff,10)-buff);
425
417
  to=net_store_length_fast(to,length);
426
418
  memcpy(to,buff,length);
427
419
  return to+length;
428
420
}
429
421
 
430
 
unsigned char *net_store_data(unsigned char *to,int64_t from)
 
422
uchar *net_store_data(uchar *to,int64_t from)
431
423
{
432
424
  char buff[22];
433
 
  uint32_t length=(uint) (int64_t10_to_str(from,buff,10)-buff);
 
425
  uint length=(uint) (int64_t10_to_str(from,buff,10)-buff);
434
426
  to=net_store_length_fast(to,length);
435
427
  memcpy(to,buff,length);
436
428
  return to+length;
441
433
  Default Protocol functions
442
434
*****************************************************************************/
443
435
 
444
 
void Protocol::init(Session *session_arg)
 
436
void Protocol::init(THD *thd_arg)
445
437
{
446
 
  session=session_arg;
447
 
  packet= &session->packet;
448
 
  convert= &session->convert_buffer;
 
438
  thd=thd_arg;
 
439
  packet= &thd->packet;
 
440
  convert= &thd->convert_buffer;
449
441
}
450
442
 
451
443
/**
454
446
  for the error.
455
447
*/
456
448
 
457
 
void Protocol::end_partial_result_set(Session *session)
 
449
void Protocol::end_partial_result_set(THD *thd)
458
450
{
459
 
  net_send_eof(session, session->server_status, 0 /* no warnings, we're inside SP */);
 
451
  net_send_eof(thd, thd->server_status, 0 /* no warnings, we're inside SP */);
460
452
}
461
453
 
462
454
 
463
455
bool Protocol::flush()
464
456
{
465
 
  return net_flush(&session->net);
 
457
  return net_flush(&thd->net);
466
458
}
467
459
 
468
460
 
471
463
 
472
464
  Sum fields has table name empty and field_name.
473
465
 
474
 
  @param Session                Thread data object
 
466
  @param THD            Thread data object
475
467
  @param list           List of items to send to client
476
468
  @param flag           Bit mask with the following functions:
477
469
                        - 1 send number of rows
484
476
    1   Error  (Note that in this case the error is not sent to the
485
477
    client)
486
478
*/
487
 
bool Protocol::send_fields(List<Item> *list, uint32_t flags)
 
479
bool Protocol::send_fields(List<Item> *list, uint flags)
488
480
{
489
481
  List_iterator_fast<Item> it(*list);
490
482
  Item *item;
491
 
  unsigned char buff[80];
 
483
  uchar buff[80];
492
484
  String tmp((char*) buff,sizeof(buff),&my_charset_bin);
493
 
  Protocol_text prot(session);
 
485
  Protocol_text prot(thd);
494
486
  String *local_packet= prot.storage_packet();
495
 
  const CHARSET_INFO * const session_charset= default_charset_info;
 
487
  const CHARSET_INFO * const thd_charset= thd->variables.character_set_results;
496
488
 
497
489
  if (flags & SEND_NUM_ROWS)
498
490
  {                             // Packet with number of elements
499
 
    unsigned char *pos= net_store_length(buff, list->elements);
500
 
    (void) my_net_write(&session->net, buff, (size_t) (pos-buff));
 
491
    uchar *pos= net_store_length(buff, list->elements);
 
492
    (void) my_net_write(&thd->net, buff, (size_t) (pos-buff));
501
493
  }
502
494
 
503
495
  while ((item=it++))
510
502
    prot.prepare_for_resend();
511
503
 
512
504
 
513
 
    if (prot.store(STRING_WITH_LEN("def"), cs, session_charset) ||
 
505
    if (prot.store(STRING_WITH_LEN("def"), cs, thd_charset) ||
514
506
        prot.store(field.db_name, (uint) strlen(field.db_name),
515
 
                   cs, session_charset) ||
 
507
                   cs, thd_charset) ||
516
508
        prot.store(field.table_name, (uint) strlen(field.table_name),
517
 
                   cs, session_charset) ||
 
509
                   cs, thd_charset) ||
518
510
        prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
519
 
                   cs, session_charset) ||
 
511
                   cs, thd_charset) ||
520
512
        prot.store(field.col_name, (uint) strlen(field.col_name),
521
 
                   cs, session_charset) ||
 
513
                   cs, thd_charset) ||
522
514
        prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
523
 
                   cs, session_charset) ||
 
515
                   cs, thd_charset) ||
524
516
        local_packet->realloc(local_packet->length()+12))
525
517
      goto err;
526
518
 
527
519
    /* Store fixed length fields */
528
520
    pos= (char*) local_packet->ptr()+local_packet->length();
529
521
    *pos++= 12;                         // Length of packed fields
530
 
    if (item->collation.collation == &my_charset_bin || session_charset == NULL)
 
522
    if (item->collation.collation == &my_charset_bin || thd_charset == NULL)
531
523
    {
532
524
      /* No conversion */
533
525
      int2store(pos, field.charsetnr);
536
528
    else
537
529
    {
538
530
      /* With conversion */
539
 
      uint32_t max_char_len;
540
 
      int2store(pos, session_charset->number);
 
531
      uint max_char_len;
 
532
      int2store(pos, thd_charset->number);
541
533
      /*
542
534
        For TEXT/BLOB columns, field_length describes the maximum data
543
535
        length in bytes. There is no limit to the number of characters
549
541
        of characters here is limited by the column definition.
550
542
      */
551
543
      max_char_len= field.length / item->collation.collation->mbmaxlen;
552
 
      int4store(pos+2, max_char_len * session_charset->mbmaxlen);
 
544
      int4store(pos+2, max_char_len * thd_charset->mbmaxlen);
553
545
    }
554
546
    pos[6]= field.type;
555
547
    int2store(pos+7,field.flags);
568
560
  if (flags & SEND_EOF)
569
561
  {
570
562
    /*
571
 
      Mark the end of meta-data result set, and store session->server_status,
 
563
      Mark the end of meta-data result set, and store thd->server_status,
572
564
      to show that there is no cursor.
573
565
      Send no warning information, as it will be sent at statement end.
574
566
    */
575
 
    write_eof_packet(session, &session->net, session->server_status, session->total_warn_count);
 
567
    write_eof_packet(thd, &thd->net, thd->server_status, thd->total_warn_count);
576
568
  }
577
569
  return(prepare_for_send(list));
578
570
 
585
577
 
586
578
bool Protocol::write()
587
579
{
588
 
  return(my_net_write(&session->net, (unsigned char*) packet->ptr(),
 
580
  return(my_net_write(&thd->net, (uchar*) packet->ptr(),
589
581
                           packet->length()));
590
582
}
591
583
 
593
585
/**
594
586
  Send \\0 end terminated string.
595
587
 
596
 
  @param from   NULL or \\0 terminated string
 
588
  @param from   NullS or \\0 terminated string
597
589
 
598
590
  @note
599
591
    In most cases one should use store(from, length) instead of this function
608
600
{
609
601
  if (!from)
610
602
    return store_null();
611
 
  uint32_t length= strlen(from);
 
603
  uint length= strlen(from);
612
604
  return store(from, length, cs);
613
605
}
614
606
 
637
629
}
638
630
 
639
631
 
640
 
bool Protocol::store(String *str)
641
 
{
642
 
  return store((char*) str->ptr(), str->length(), str->charset());
643
 
}
644
 
 
645
 
void Protocol::free()
646
 
{
647
 
  packet->free();
648
 
}
649
 
 
650
 
 
651
632
/****************************************************************************
652
633
  Functions to handle the simple (default) protocol where everything is
653
634
  This protocol is the one that is used by default between the MySQL server
684
665
      tocs != &my_charset_bin)
685
666
  {
686
667
    /* Store with conversion */
687
 
    return net_store_data((unsigned char*) from, length, fromcs, tocs);
 
668
    return net_store_data((uchar*) from, length, fromcs, tocs);
688
669
  }
689
670
  /* Store without conversion */
690
 
  return net_store_data((unsigned char*) from, length);
 
671
  return net_store_data((uchar*) from, length);
691
672
}
692
673
 
693
674
 
702
683
bool Protocol_text::store(const char *from, size_t length,
703
684
                          const CHARSET_INFO * const fromcs)
704
685
{
705
 
  const CHARSET_INFO * const tocs= default_charset_info;
 
686
  const CHARSET_INFO * const tocs= this->thd->variables.character_set_results;
706
687
  return store_string_aux(from, length, fromcs, tocs);
707
688
}
708
689
 
710
691
bool Protocol_text::store_tiny(int64_t from)
711
692
{
712
693
  char buff[20];
713
 
  return net_store_data((unsigned char*) buff,
 
694
  return net_store_data((uchar*) buff,
714
695
                        (size_t) (int10_to_str((int) from, buff, -10) - buff));
715
696
}
716
697
 
718
699
bool Protocol_text::store_short(int64_t from)
719
700
{
720
701
  char buff[20];
721
 
  return net_store_data((unsigned char*) buff,
 
702
  return net_store_data((uchar*) buff,
722
703
                        (size_t) (int10_to_str((int) from, buff, -10) -
723
704
                                  buff));
724
705
}
727
708
bool Protocol_text::store_long(int64_t from)
728
709
{
729
710
  char buff[20];
730
 
  return net_store_data((unsigned char*) buff,
 
711
  return net_store_data((uchar*) buff,
731
712
                        (size_t) (int10_to_str((long int)from, buff,
732
713
                                               (from <0)?-10:10)-buff));
733
714
}
736
717
bool Protocol_text::store_int64_t(int64_t from, bool unsigned_flag)
737
718
{
738
719
  char buff[22];
739
 
  return net_store_data((unsigned char*) buff,
 
720
  return net_store_data((uchar*) buff,
740
721
                        (size_t) (int64_t10_to_str(from,buff,
741
722
                                                    unsigned_flag ? 10 : -10)-
742
723
                                  buff));
748
729
  char buff[DECIMAL_MAX_STR_LENGTH];
749
730
  String str(buff, sizeof(buff), &my_charset_bin);
750
731
  (void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
751
 
  return net_store_data((unsigned char*) str.ptr(), str.length());
 
732
  return net_store_data((uchar*) str.ptr(), str.length());
752
733
}
753
734
 
754
735
 
755
736
bool Protocol_text::store(float from, uint32_t decimals, String *buffer)
756
737
{
757
 
  buffer->set_real((double) from, decimals, session->charset());
758
 
  return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
 
738
  buffer->set_real((double) from, decimals, thd->charset());
 
739
  return net_store_data((uchar*) buffer->ptr(), buffer->length());
759
740
}
760
741
 
761
742
 
762
743
bool Protocol_text::store(double from, uint32_t decimals, String *buffer)
763
744
{
764
 
  buffer->set_real(from, decimals, session->charset());
765
 
  return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
 
745
  buffer->set_real(from, decimals, thd->charset());
 
746
  return net_store_data((uchar*) buffer->ptr(), buffer->length());
766
747
}
767
748
 
768
749
 
772
753
    return store_null();
773
754
  char buff[MAX_FIELD_WIDTH];
774
755
  String str(buff,sizeof(buff), &my_charset_bin);
775
 
  const CHARSET_INFO * const tocs= default_charset_info;
 
756
  const CHARSET_INFO * const tocs= this->thd->variables.character_set_results;
776
757
 
777
758
  field->val_str(&str);
778
759
 
782
763
 
783
764
/**
784
765
  @todo
785
 
    Second_part format ("%06") needs to change when
 
766
    Second_part format ("%06") needs to change when 
786
767
    we support 0-6 decimals for time.
787
768
*/
788
769
 
789
770
bool Protocol_text::store(DRIZZLE_TIME *tm)
790
771
{
791
772
  char buff[40];
792
 
  uint32_t length;
 
773
  uint length;
793
774
  length= sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d",
794
775
                           (int) tm->year,
795
776
                           (int) tm->month,
800
781
  if (tm->second_part)
801
782
    length+= sprintf(buff+length, ".%06d",
802
783
                                     (int)tm->second_part);
803
 
  return net_store_data((unsigned char*) buff, length);
 
784
  return net_store_data((uchar*) buff, length);
804
785
}
805
786
 
806
787
 
808
789
{
809
790
  char buff[MAX_DATE_STRING_REP_LENGTH];
810
791
  size_t length= my_date_to_str(tm, buff);
811
 
  return net_store_data((unsigned char*) buff, length);
 
792
  return net_store_data((uchar*) buff, length);
812
793
}
813
794
 
814
795
 
815
796
/**
816
 
  @todo
817
 
    Second_part format ("%06") needs to change when
 
797
  @todo 
 
798
    Second_part format ("%06") needs to change when 
818
799
    we support 0-6 decimals for time.
819
800
*/
820
801
 
821
802
bool Protocol_text::store_time(DRIZZLE_TIME *tm)
822
803
{
823
804
  char buff[40];
824
 
  uint32_t length;
825
 
  uint32_t day= (tm->year || tm->month) ? 0 : tm->day;
 
805
  uint length;
 
806
  uint day= (tm->year || tm->month) ? 0 : tm->day;
826
807
  length= sprintf(buff, "%s%02ld:%02d:%02d",
827
808
                           tm->neg ? "-" : "",
828
809
                           (long) day*24L+(long) tm->hour,
830
811
                           (int) tm->second);
831
812
  if (tm->second_part)
832
813
    length+= sprintf(buff+length, ".%06d", (int)tm->second_part);
833
 
  return net_store_data((unsigned char*) buff, length);
 
814
  return net_store_data((uchar*) buff, length);
834
815
}
835
816