~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/protocol.cc

  • Committer: Brian Aker
  • Date: 2008-10-06 06:47:29 UTC
  • Revision ID: brian@tangent.org-20081006064729-2i9mhjkzyvow9xsm
RemoveĀ uint.

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>
 
23
#include <drizzled/drizzled_error_messages.h>
24
24
#include <drizzled/sql_state.h>
25
 
#include <libdrizzle/pack.h>
26
25
 
27
26
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
28
27
/* Declared non-static only because of the embedded library. */
29
 
static void net_send_error_packet(Session *session, uint32_t sql_errno, const char *err);
30
 
static void write_eof_packet(Session *session, NET *net,
 
28
static void net_send_error_packet(THD *thd, uint32_t sql_errno, const char *err);
 
29
static void write_eof_packet(THD *thd, NET *net,
31
30
                             uint32_t server_status, uint32_t total_warn_count);
32
31
 
33
32
bool Protocol::net_store_data(const unsigned char *from, size_t length)
116
115
  critical that every error that can be intercepted is issued in one
117
116
  place only, my_message_sql.
118
117
*/
119
 
void net_send_error(Session *session, uint32_t sql_errno, const char *err)
 
118
void net_send_error(THD *thd, uint32_t sql_errno, const char *err)
120
119
{
121
120
  assert(sql_errno);
122
121
  assert(err && err[0]);
125
124
    It's one case when we can push an error even though there
126
125
    is an OK or EOF already.
127
126
  */
128
 
  session->main_da.can_overwrite_status= true;
 
127
  thd->main_da.can_overwrite_status= true;
129
128
 
130
129
  /* Abort multi-result sets */
131
 
  session->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
132
 
 
133
 
  net_send_error_packet(session, sql_errno, err);
134
 
 
135
 
  session->main_da.can_overwrite_status= false;
 
130
  thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
 
131
 
 
132
  net_send_error_packet(thd, sql_errno, err);
 
133
 
 
134
  thd->main_da.can_overwrite_status= false;
136
135
}
137
136
 
138
137
/**
143
142
  - 0               : Marker (1 byte)
144
143
  - affected_rows       : Stored in 1-9 bytes
145
144
  - id          : Stored in 1-9 bytes
146
 
  - server_status       : Copy of session->server_status;  Can be used by client
 
145
  - server_status       : Copy of thd->server_status;  Can be used by client
147
146
  to check if we are inside an transaction.
148
147
  New in 4.0 protocol
149
148
  - warning_count       : Stored in 2 bytes; New in 4.1 protocol
150
149
  - message             : Stored as packed length (1-9 bytes) + message.
151
150
  Is not stored if no message.
152
151
 
153
 
  @param session                   Thread handler
 
152
  @param thd               Thread handler
154
153
  @param affected_rows     Number of rows changed by statement
155
154
  @param id                Auto_increment id for first row (if used)
156
155
  @param message           Message to send to the client (Used by mysql_status)
157
156
*/
158
157
 
159
158
static void
160
 
net_send_ok(Session *session,
 
159
net_send_ok(THD *thd,
161
160
            uint32_t server_status, uint32_t total_warn_count,
162
161
            ha_rows affected_rows, uint64_t id, const char *message)
163
162
{
164
 
  NET *net= &session->net;
 
163
  NET *net= &thd->net;
165
164
  unsigned char buff[DRIZZLE_ERRMSG_SIZE+10],*pos;
166
165
 
167
166
  if (! net->vio)       // hack for re-parsing queries
181
180
  int2store(pos, tmp);
182
181
  pos+= 2;
183
182
 
184
 
  session->main_da.can_overwrite_status= true;
 
183
  thd->main_da.can_overwrite_status= true;
185
184
 
186
185
  if (message && message[0])
187
186
    pos= net_store_data(pos, (unsigned char*) message, strlen(message));
188
187
  my_net_write(net, buff, (size_t) (pos-buff));
189
188
  net_flush(net);
190
189
 
191
 
  session->main_da.can_overwrite_status= false;
 
190
  thd->main_da.can_overwrite_status= false;
192
191
}
193
192
 
194
193
/**
205
204
  we don't want to report the warning count until all data is sent to the
206
205
  client.
207
206
 
208
 
  @param session                Thread handler
 
207
  @param thd            Thread handler
209
208
  @param no_flush       Set to 1 if there will be more data to the client,
210
209
                    like in send_fields().
211
210
*/    
212
211
 
213
212
static void
214
 
net_send_eof(Session *session, uint32_t server_status, uint32_t total_warn_count)
 
213
net_send_eof(THD *thd, uint32_t server_status, uint32_t total_warn_count)
215
214
{
216
 
  NET *net= &session->net;
 
215
  NET *net= &thd->net;
217
216
  /* Set to true if no active vio, to work well in case of --init-file */
218
217
  if (net->vio != 0)
219
218
  {
220
 
    session->main_da.can_overwrite_status= true;
221
 
    write_eof_packet(session, net, server_status, total_warn_count);
 
219
    thd->main_da.can_overwrite_status= true;
 
220
    write_eof_packet(thd, net, server_status, total_warn_count);
222
221
    net_flush(net);
223
 
    session->main_da.can_overwrite_status= false;
 
222
    thd->main_da.can_overwrite_status= false;
224
223
  }
225
224
}
226
225
 
230
229
  write it to the network output buffer.
231
230
*/
232
231
 
233
 
static void write_eof_packet(Session *session, NET *net,
 
232
static void write_eof_packet(THD *thd, NET *net,
234
233
                             uint32_t server_status,
235
234
                             uint32_t total_warn_count)
236
235
{
247
246
    because if 'is_fatal_error' is set the server is not going to execute
248
247
    other queries (see the if test in dispatch_command / COM_QUERY)
249
248
  */
250
 
  if (session->is_fatal_error)
 
249
  if (thd->is_fatal_error)
251
250
    server_status&= ~SERVER_MORE_RESULTS_EXISTS;
252
251
  int2store(buff + 3, server_status);
253
252
  my_net_write(net, buff, 5);
254
253
}
255
254
 
256
 
void net_send_error_packet(Session *session, uint32_t sql_errno, const char *err)
 
255
void net_send_error_packet(THD *thd, uint32_t sql_errno, const char *err)
257
256
{
258
 
  NET *net= &session->net;
 
257
  NET *net= &thd->net;
259
258
  uint32_t length;
260
259
  /*
261
260
    buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + DRIZZLE_ERRMSG_SIZE:512
309
308
/**
310
309
  Send the status of the current statement execution over network.
311
310
 
312
 
  @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
313
312
                Diagnostics_area as the source of status information.
314
313
 
315
314
  In MySQL, there are two types of SQL statements: those that return
356
355
          Diagnostics_area::is_sent is set for debugging purposes only.
357
356
*/
358
357
 
359
 
void net_end_statement(Session *session)
 
358
void net_end_statement(THD *thd)
360
359
{
361
 
  assert(! session->main_da.is_sent);
 
360
  assert(! thd->main_da.is_sent);
362
361
 
363
362
  /* Can not be true, but do not take chances in production. */
364
 
  if (session->main_da.is_sent)
 
363
  if (thd->main_da.is_sent)
365
364
    return;
366
365
 
367
 
  switch (session->main_da.status()) {
 
366
  switch (thd->main_da.status()) {
368
367
  case Diagnostics_area::DA_ERROR:
369
368
    /* The query failed, send error to log and abort bootstrap. */
370
 
    net_send_error(session,
371
 
                   session->main_da.sql_errno(),
372
 
                   session->main_da.message());
 
369
    net_send_error(thd,
 
370
                   thd->main_da.sql_errno(),
 
371
                   thd->main_da.message());
373
372
    break;
374
373
  case Diagnostics_area::DA_EOF:
375
 
    net_send_eof(session,
376
 
                 session->main_da.server_status(),
377
 
                 session->main_da.total_warn_count());
 
374
    net_send_eof(thd,
 
375
                 thd->main_da.server_status(),
 
376
                 thd->main_da.total_warn_count());
378
377
    break;
379
378
  case Diagnostics_area::DA_OK:
380
 
    net_send_ok(session,
381
 
                session->main_da.server_status(),
382
 
                session->main_da.total_warn_count(),
383
 
                session->main_da.affected_rows(),
384
 
                session->main_da.last_insert_id(),
385
 
                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());
386
385
    break;
387
386
  case Diagnostics_area::DA_DISABLED:
388
387
    break;
389
388
  case Diagnostics_area::DA_EMPTY:
390
389
  default:
391
390
    assert(0);
392
 
    net_send_ok(session, session->server_status, session->total_warn_count,
 
391
    net_send_ok(thd, thd->server_status, thd->total_warn_count,
393
392
                0, 0, NULL);
394
393
    break;
395
394
  }
396
 
  session->main_da.is_sent= true;
 
395
  thd->main_da.is_sent= true;
397
396
}
398
397
 
399
398
 
434
433
  Default Protocol functions
435
434
*****************************************************************************/
436
435
 
437
 
void Protocol::init(Session *session_arg)
 
436
void Protocol::init(THD *thd_arg)
438
437
{
439
 
  session=session_arg;
440
 
  packet= &session->packet;
441
 
  convert= &session->convert_buffer;
 
438
  thd=thd_arg;
 
439
  packet= &thd->packet;
 
440
  convert= &thd->convert_buffer;
442
441
}
443
442
 
444
443
/**
447
446
  for the error.
448
447
*/
449
448
 
450
 
void Protocol::end_partial_result_set(Session *session)
 
449
void Protocol::end_partial_result_set(THD *thd)
451
450
{
452
 
  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 */);
453
452
}
454
453
 
455
454
 
456
455
bool Protocol::flush()
457
456
{
458
 
  return net_flush(&session->net);
 
457
  return net_flush(&thd->net);
459
458
}
460
459
 
461
460
 
464
463
 
465
464
  Sum fields has table name empty and field_name.
466
465
 
467
 
  @param Session                Thread data object
 
466
  @param THD            Thread data object
468
467
  @param list           List of items to send to client
469
468
  @param flag           Bit mask with the following functions:
470
469
                        - 1 send number of rows
483
482
  Item *item;
484
483
  unsigned char buff[80];
485
484
  String tmp((char*) buff,sizeof(buff),&my_charset_bin);
486
 
  Protocol_text prot(session);
 
485
  Protocol_text prot(thd);
487
486
  String *local_packet= prot.storage_packet();
488
 
  const CHARSET_INFO * const session_charset= session->variables.character_set_results;
 
487
  const CHARSET_INFO * const thd_charset= thd->variables.character_set_results;
489
488
 
490
489
  if (flags & SEND_NUM_ROWS)
491
490
  {                             // Packet with number of elements
492
491
    unsigned char *pos= net_store_length(buff, list->elements);
493
 
    (void) my_net_write(&session->net, buff, (size_t) (pos-buff));
 
492
    (void) my_net_write(&thd->net, buff, (size_t) (pos-buff));
494
493
  }
495
494
 
496
495
  while ((item=it++))
503
502
    prot.prepare_for_resend();
504
503
 
505
504
 
506
 
    if (prot.store(STRING_WITH_LEN("def"), cs, session_charset) ||
 
505
    if (prot.store(STRING_WITH_LEN("def"), cs, thd_charset) ||
507
506
        prot.store(field.db_name, (uint) strlen(field.db_name),
508
 
                   cs, session_charset) ||
 
507
                   cs, thd_charset) ||
509
508
        prot.store(field.table_name, (uint) strlen(field.table_name),
510
 
                   cs, session_charset) ||
 
509
                   cs, thd_charset) ||
511
510
        prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
512
 
                   cs, session_charset) ||
 
511
                   cs, thd_charset) ||
513
512
        prot.store(field.col_name, (uint) strlen(field.col_name),
514
 
                   cs, session_charset) ||
 
513
                   cs, thd_charset) ||
515
514
        prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
516
 
                   cs, session_charset) ||
 
515
                   cs, thd_charset) ||
517
516
        local_packet->realloc(local_packet->length()+12))
518
517
      goto err;
519
518
 
520
519
    /* Store fixed length fields */
521
520
    pos= (char*) local_packet->ptr()+local_packet->length();
522
521
    *pos++= 12;                         // Length of packed fields
523
 
    if (item->collation.collation == &my_charset_bin || session_charset == NULL)
 
522
    if (item->collation.collation == &my_charset_bin || thd_charset == NULL)
524
523
    {
525
524
      /* No conversion */
526
525
      int2store(pos, field.charsetnr);
530
529
    {
531
530
      /* With conversion */
532
531
      uint32_t max_char_len;
533
 
      int2store(pos, session_charset->number);
 
532
      int2store(pos, thd_charset->number);
534
533
      /*
535
534
        For TEXT/BLOB columns, field_length describes the maximum data
536
535
        length in bytes. There is no limit to the number of characters
542
541
        of characters here is limited by the column definition.
543
542
      */
544
543
      max_char_len= field.length / item->collation.collation->mbmaxlen;
545
 
      int4store(pos+2, max_char_len * session_charset->mbmaxlen);
 
544
      int4store(pos+2, max_char_len * thd_charset->mbmaxlen);
546
545
    }
547
546
    pos[6]= field.type;
548
547
    int2store(pos+7,field.flags);
561
560
  if (flags & SEND_EOF)
562
561
  {
563
562
    /*
564
 
      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,
565
564
      to show that there is no cursor.
566
565
      Send no warning information, as it will be sent at statement end.
567
566
    */
568
 
    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);
569
568
  }
570
569
  return(prepare_for_send(list));
571
570
 
578
577
 
579
578
bool Protocol::write()
580
579
{
581
 
  return(my_net_write(&session->net, (unsigned char*) packet->ptr(),
 
580
  return(my_net_write(&thd->net, (unsigned char*) packet->ptr(),
582
581
                           packet->length()));
583
582
}
584
583
 
684
683
bool Protocol_text::store(const char *from, size_t length,
685
684
                          const CHARSET_INFO * const fromcs)
686
685
{
687
 
  const CHARSET_INFO * const tocs= this->session->variables.character_set_results;
 
686
  const CHARSET_INFO * const tocs= this->thd->variables.character_set_results;
688
687
  return store_string_aux(from, length, fromcs, tocs);
689
688
}
690
689
 
736
735
 
737
736
bool Protocol_text::store(float from, uint32_t decimals, String *buffer)
738
737
{
739
 
  buffer->set_real((double) from, decimals, session->charset());
 
738
  buffer->set_real((double) from, decimals, thd->charset());
740
739
  return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
741
740
}
742
741
 
743
742
 
744
743
bool Protocol_text::store(double from, uint32_t decimals, String *buffer)
745
744
{
746
 
  buffer->set_real(from, decimals, session->charset());
 
745
  buffer->set_real(from, decimals, thd->charset());
747
746
  return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
748
747
}
749
748
 
754
753
    return store_null();
755
754
  char buff[MAX_FIELD_WIDTH];
756
755
  String str(buff,sizeof(buff), &my_charset_bin);
757
 
  const CHARSET_INFO * const tocs= this->session->variables.character_set_results;
 
756
  const CHARSET_INFO * const tocs= this->thd->variables.character_set_results;
758
757
 
759
758
  field->val_str(&str);
760
759