~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/protocol.cc

  • Committer: Monty Taylor
  • Date: 2008-10-20 08:48:34 UTC
  • mfrom: (520.1.22 drizzle)
  • Revision ID: monty@inaugust.com-20081020084834-xpb3w01vkcp55o02
Merged trunk.

Show diffs side-by-side

added added

removed removed

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