~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to drizzled/show.cc

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-10-02 14:17:48 UTC
  • mfrom: (1.1.1 upstream)
  • mto: (2.1.17 sid)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20101002141748-m6vbfbfjhrw1153e
Tags: 2010.09.1802-1
* New upstream release.
* Removed pid-file argument hack.
* Updated GPL-2 address to be new address.
* Directly copy in drizzledump.1 since debian doesn't have sphinx 1.0 yet.
* Link to jquery from libjs-jquery. Add it as a depend.
* Add drizzled.8 symlink to the install files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
#include <drizzled/lock.h>
40
40
#include <drizzled/item/return_date_time.h>
41
41
#include <drizzled/item/empty_string.h>
42
 
#include "drizzled/plugin/registry.h"
43
42
#include "drizzled/session_list.h"
44
43
#include <drizzled/message/schema.pb.h>
45
44
#include <drizzled/plugin/client.h>
49
48
#include "drizzled/pthread_globals.h"
50
49
#include "drizzled/internal/m_string.h"
51
50
#include "drizzled/internal/my_sys.h"
 
51
#include "drizzled/message/statement_transform.h"
 
52
 
52
53
 
53
54
#include <sys/stat.h>
54
55
 
69
70
  return str ? str : "<nil>";
70
71
}
71
72
 
72
 
static void store_key_options(String *packet, Table *table, KEY *key_info);
73
 
 
74
 
 
75
73
int wild_case_compare(const CHARSET_INFO * const cs, const char *str, const char *wildstr)
76
74
{
77
75
  register int flag;
157
155
  if (session->client->sendFields(&field_list))
158
156
    return true;
159
157
  {
160
 
    session->client->store(table_list->table->alias);
 
158
    session->client->store(table_list->table->getAlias());
161
159
  }
162
160
 
163
161
  session->client->store(buffer.ptr(), buffer.length());
191
189
  @returns true if errors are detected, false otherwise.
192
190
*/
193
191
 
194
 
static bool store_db_create_info(const char *dbname, string &buffer, bool if_not_exists)
 
192
static bool store_db_create_info(SchemaIdentifier &schema_identifier, string &buffer, bool if_not_exists)
195
193
{
196
194
  message::Schema schema;
197
195
 
198
 
  bool found= plugin::StorageEngine::getSchemaDefinition(dbname, schema);
 
196
  bool found= plugin::StorageEngine::getSchemaDefinition(schema_identifier, schema);
199
197
  if (not found)
200
198
    return false;
201
199
 
217
215
  return true;
218
216
}
219
217
 
220
 
bool mysqld_show_create_db(Session *session, const char *dbname, bool if_not_exists)
 
218
bool mysqld_show_create_db(Session &session, SchemaIdentifier &schema_identifier, bool if_not_exists)
221
219
{
 
220
  message::Schema schema_message;
222
221
  string buffer;
223
222
 
224
 
  if (not store_db_create_info(dbname, buffer, if_not_exists))
225
 
  {
226
 
    /*
227
 
      This assumes that the only reason for which store_db_create_info()
228
 
      can fail is incorrect database name (which is the case now).
229
 
    */
230
 
    my_error(ER_BAD_DB_ERROR, MYF(0), dbname);
 
223
  if (not plugin::StorageEngine::getSchemaDefinition(schema_identifier, schema_message))
 
224
  {
 
225
    /*
 
226
      This assumes that the only reason for which store_db_create_info()
 
227
      can fail is incorrect database name (which is the case now).
 
228
    */
 
229
    my_error(ER_BAD_DB_ERROR, MYF(0), schema_identifier.getSQLPath().c_str());
 
230
    return true;
 
231
  }
 
232
 
 
233
  if (not store_db_create_info(schema_identifier, buffer, if_not_exists))
 
234
  {
 
235
    /*
 
236
      This assumes that the only reason for which store_db_create_info()
 
237
      can fail is incorrect database name (which is the case now).
 
238
    */
 
239
    my_error(ER_BAD_DB_ERROR, MYF(0), schema_identifier.getSQLPath().c_str());
231
240
    return true;
232
241
  }
233
242
 
235
244
  field_list.push_back(new Item_empty_string("Database",NAME_CHAR_LEN));
236
245
  field_list.push_back(new Item_empty_string("Create Database",1024));
237
246
 
238
 
  if (session->client->sendFields(&field_list))
239
 
    return true;
240
 
 
241
 
  session->client->store(dbname, strlen(dbname));
242
 
  session->client->store(buffer);
243
 
 
244
 
  if (session->client->flush())
245
 
    return true;
246
 
 
247
 
  session->my_eof();
 
247
  if (session.client->sendFields(&field_list))
 
248
    return true;
 
249
 
 
250
  session.client->store(schema_message.name());
 
251
  session.client->store(buffer);
 
252
 
 
253
  if (session.client->flush())
 
254
    return true;
 
255
 
 
256
  session.my_eof();
248
257
 
249
258
  return false;
250
259
}
277
286
 
278
287
#define LIST_PROCESS_HOST_LEN 64
279
288
 
280
 
static bool get_field_default_value(Field *timestamp_field,
281
 
                                    Field *field, String *def_value,
282
 
                                    bool quoted)
283
 
{
284
 
  bool has_default;
285
 
  bool has_now_default;
286
 
 
287
 
  /*
288
 
     We are using CURRENT_TIMESTAMP instead of NOW because it is
289
 
     more standard
290
 
  */
291
 
  has_now_default= (timestamp_field == field &&
292
 
                    field->unireg_check != Field::TIMESTAMP_UN_FIELD);
293
 
 
294
 
  has_default= (field->type() != DRIZZLE_TYPE_BLOB &&
295
 
                !(field->flags & NO_DEFAULT_VALUE_FLAG) &&
296
 
                field->unireg_check != Field::NEXT_NUMBER);
297
 
 
298
 
  def_value->length(0);
299
 
  if (has_default)
300
 
  {
301
 
    if (has_now_default)
302
 
      def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
303
 
    else if (!field->is_null())
304
 
    {                                             // Not null by default
305
 
      char tmp[MAX_FIELD_WIDTH];
306
 
      String type(tmp, sizeof(tmp), field->charset());
307
 
      field->val_str(&type);
308
 
      if (type.length())
309
 
      {
310
 
        String def_val;
311
 
        uint32_t dummy_errors;
312
 
        /* convert to system_charset_info == utf8 */
313
 
        def_val.copy(type.ptr(), type.length(), field->charset(),
314
 
                     system_charset_info, &dummy_errors);
315
 
        if (quoted)
316
 
          append_unescaped(def_value, def_val.ptr(), def_val.length());
317
 
        else
318
 
          def_value->append(def_val.ptr(), def_val.length());
319
 
      }
320
 
      else if (quoted)
321
 
        def_value->append(STRING_WITH_LEN("''"));
322
 
    }
323
 
    else if (field->maybe_null() && quoted)
324
 
      def_value->append(STRING_WITH_LEN("NULL"));    // Null as default
325
 
    else
326
 
      return false;
327
 
  }
328
 
  return has_default;
329
 
}
330
 
 
331
289
/*
332
290
  Build a CREATE TABLE statement for a table.
333
291
 
348
306
 
349
307
int store_create_info(TableList *table_list, String *packet, bool is_if_not_exists)
350
308
{
351
 
  List<Item> field_list;
352
 
  char tmp[MAX_FIELD_WIDTH], *for_str, def_value_buf[MAX_FIELD_WIDTH];
353
 
  const char *alias;
354
 
  string buff;
355
 
  String type(tmp, sizeof(tmp), system_charset_info);
356
 
  String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
357
 
  Field **ptr,*field;
358
 
  uint32_t primary_key;
359
 
  KEY *key_info;
360
309
  Table *table= table_list->table;
361
 
  Cursor *cursor= table->cursor;
362
 
  TableShare *share= table->s;
363
 
  HA_CREATE_INFO create_info;
364
 
  bool show_table_options= false;
365
 
  my_bitmap_map *old_map;
366
310
 
367
311
  table->restoreRecordAsDefault(); // Get empty record
368
312
 
369
 
  if (share->tmp_table)
370
 
    packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
371
 
  else
372
 
    packet->append(STRING_WITH_LEN("CREATE TABLE "));
373
 
  if (is_if_not_exists)
374
 
    packet->append(STRING_WITH_LEN("IF NOT EXISTS "));
375
 
  alias= share->table_name.str;
376
 
 
377
 
  packet->append_identifier(alias, strlen(alias));
378
 
  packet->append(STRING_WITH_LEN(" (\n"));
379
 
  /*
380
 
    We need this to get default values from the table
381
 
    We have to restore the read_set if we are called from insert in case
382
 
    of row based replication.
383
 
  */
384
 
  old_map= table->use_all_columns(table->read_set);
385
 
 
386
 
  for (ptr=table->field ; (field= *ptr); ptr++)
387
 
  {
388
 
    uint32_t flags = field->flags;
389
 
 
390
 
    if (ptr != table->field)
391
 
      packet->append(STRING_WITH_LEN(",\n"));
392
 
 
393
 
    packet->append(STRING_WITH_LEN("  "));
394
 
    packet->append_identifier(field->field_name, strlen(field->field_name));
395
 
    packet->append(' ');
396
 
    // check for surprises from the previous call to Field::sql_type()
397
 
    if (type.ptr() != tmp)
398
 
      type.set(tmp, sizeof(tmp), system_charset_info);
399
 
    else
400
 
      type.set_charset(system_charset_info);
401
 
 
402
 
    field->sql_type(type);
403
 
    packet->append(type.ptr(), type.length(), system_charset_info);
404
 
 
405
 
    if (field->has_charset())
406
 
    {
407
 
      if (field->charset() != share->table_charset)
408
 
      {
409
 
        packet->append(STRING_WITH_LEN(" CHARACTER SET "));
410
 
        packet->append(field->charset()->csname);
411
 
      }
412
 
 
413
 
      /*
414
 
        For string types dump collation name only if
415
 
        collation is not primary for the given charset
416
 
      */
417
 
      if (!(field->charset()->state & MY_CS_PRIMARY))
418
 
      {
419
 
        packet->append(STRING_WITH_LEN(" COLLATE "));
420
 
        packet->append(field->charset()->name);
421
 
      }
422
 
    }
423
 
 
424
 
    if (flags & NOT_NULL_FLAG)
425
 
      packet->append(STRING_WITH_LEN(" NOT NULL"));
426
 
    else if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
427
 
    {
428
 
      /*
429
 
        TIMESTAMP field require explicit NULL flag, because unlike
430
 
        all other fields they are treated as NOT NULL by default.
431
 
      */
432
 
      packet->append(STRING_WITH_LEN(" NULL"));
433
 
    }
434
 
    {
435
 
      /*
436
 
        Add field flags about FIELD FORMAT (FIXED or DYNAMIC)
437
 
        and about STORAGE (DISK or MEMORY).
438
 
      */
439
 
      enum column_format_type column_format= (enum column_format_type)
440
 
        ((flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
441
 
      if (column_format)
442
 
      {
443
 
        packet->append(STRING_WITH_LEN(" /*!"));
444
 
        packet->append(STRING_WITH_LEN(" COLUMN_FORMAT"));
445
 
        if (column_format == COLUMN_FORMAT_TYPE_FIXED)
446
 
          packet->append(STRING_WITH_LEN(" FIXED */"));
447
 
        else
448
 
          packet->append(STRING_WITH_LEN(" DYNAMIC */"));
449
 
      }
450
 
    }
451
 
    if (get_field_default_value(table->timestamp_field, field, &def_value, 1))
452
 
    {
453
 
      packet->append(STRING_WITH_LEN(" DEFAULT "));
454
 
      packet->append(def_value.ptr(), def_value.length(), system_charset_info);
455
 
    }
456
 
 
457
 
    if (table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_DN_FIELD)
458
 
      packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
459
 
 
460
 
    if (field->unireg_check == Field::NEXT_NUMBER)
461
 
      packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
462
 
 
463
 
    if (field->comment.length)
464
 
    {
465
 
      packet->append(STRING_WITH_LEN(" COMMENT "));
466
 
      append_unescaped(packet, field->comment.str, field->comment.length);
467
 
    }
468
 
  }
469
 
 
470
 
  key_info= table->key_info;
471
 
  memset(&create_info, 0, sizeof(create_info));
472
 
  /* Allow update_create_info to update row type */
473
 
  create_info.row_type= share->row_type;
474
 
  cursor->update_create_info(&create_info);
475
 
  primary_key= share->primary_key;
476
 
 
477
 
  for (uint32_t i=0 ; i < share->keys ; i++,key_info++)
478
 
  {
479
 
    KEY_PART_INFO *key_part= key_info->key_part;
480
 
    bool found_primary=0;
481
 
    packet->append(STRING_WITH_LEN(",\n  "));
482
 
 
483
 
    if (i == primary_key && is_primary_key(key_info))
484
 
    {
485
 
      found_primary=1;
486
 
      /*
487
 
        No space at end, because a space will be added after where the
488
 
        identifier would go, but that is not added for primary key.
489
 
      */
490
 
      packet->append(STRING_WITH_LEN("PRIMARY KEY"));
491
 
    }
492
 
    else if (key_info->flags & HA_NOSAME)
493
 
      packet->append(STRING_WITH_LEN("UNIQUE KEY "));
494
 
    else
495
 
      packet->append(STRING_WITH_LEN("KEY "));
496
 
 
497
 
    if (!found_primary)
498
 
     packet->append_identifier(key_info->name, strlen(key_info->name));
499
 
 
500
 
    packet->append(STRING_WITH_LEN(" ("));
501
 
 
502
 
    for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
503
 
    {
504
 
      if (j)
505
 
        packet->append(',');
506
 
 
507
 
      if (key_part->field)
508
 
        packet->append_identifier(key_part->field->field_name,
509
 
                                  strlen(key_part->field->field_name));
510
 
      if (key_part->field &&
511
 
          (key_part->length !=
512
 
           table->field[key_part->fieldnr-1]->key_length()))
513
 
      {
514
 
        buff.assign("(");
515
 
        buff.append(to_string((int32_t) key_part->length /
516
 
                              key_part->field->charset()->mbmaxlen));
517
 
        buff.append(")");
518
 
        packet->append(buff.c_str(), buff.length());
519
 
      }
520
 
    }
521
 
    packet->append(')');
522
 
    store_key_options(packet, table, key_info);
523
 
  }
524
 
 
525
 
  /*
526
 
    Get possible foreign key definitions stored in InnoDB and append them
527
 
    to the CREATE TABLE statement
528
 
  */
529
 
 
530
 
  if ((for_str= cursor->get_foreign_key_create_info()))
531
 
  {
532
 
    packet->append(for_str, strlen(for_str));
533
 
    cursor->free_foreign_key_create_info(for_str);
534
 
  }
535
 
 
536
 
  packet->append(STRING_WITH_LEN("\n)"));
537
 
  {
538
 
    show_table_options= true;
539
 
    /*
540
 
      Get possible table space definitions and append them
541
 
      to the CREATE TABLE statement
542
 
    */
543
 
 
544
 
    /* 
545
 
      We should always store engine since we will now be 
546
 
      making sure engines accept options (aka... no
547
 
      dangling arguments for engines.
548
 
    */
549
 
    packet->append(STRING_WITH_LEN(" ENGINE="));
550
 
    packet->append(cursor->engine->getName().c_str());
551
 
 
552
 
    if (share->db_create_options & HA_OPTION_PACK_KEYS)
553
 
      packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
554
 
    if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
555
 
      packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
556
 
    if (create_info.row_type != ROW_TYPE_DEFAULT)
557
 
    {
558
 
      packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
559
 
      packet->append(ha_row_type[(uint32_t) create_info.row_type]);
560
 
    }
561
 
    if (table->s->hasKeyBlockSize())
562
 
    {
563
 
      packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
564
 
      buff= to_string(table->s->getKeyBlockSize());
565
 
      packet->append(buff.c_str(), buff.length());
566
 
    }
567
 
    if (share->block_size)
568
 
    {
569
 
      packet->append(STRING_WITH_LEN(" BLOCK_SIZE="));
570
 
      buff= to_string(share->block_size);
571
 
      packet->append(buff.c_str(), buff.length());
572
 
    }
573
 
    table->cursor->append_create_info(packet);
574
 
    if (share->hasComment() && share->getCommentLength())
575
 
    {
576
 
      packet->append(STRING_WITH_LEN(" COMMENT="));
577
 
      append_unescaped(packet, share->getComment(),
578
 
                       share->getCommentLength());
579
 
    }
580
 
  }
581
 
  table->restore_column_map(old_map);
 
313
  string create_sql;
 
314
 
 
315
  enum drizzled::message::TransformSqlError transform_err;
 
316
 
 
317
  (void)is_if_not_exists;
 
318
 
 
319
  transform_err= message::transformTableDefinitionToSql(*(table->getShare()->getTableProto()),
 
320
                                                        create_sql,
 
321
                                                        message::DRIZZLE,
 
322
                                                        false);
 
323
 
 
324
  packet->append(create_sql.c_str(), create_sql.length(), default_charset_info);
 
325
 
582
326
  return(0);
583
327
}
584
328
 
585
 
static void store_key_options(String *packet, Table *table, KEY *key_info)
586
 
{
587
 
  char *end, buff[32];
588
 
 
589
 
  if (key_info->algorithm == HA_KEY_ALG_BTREE)
590
 
    packet->append(STRING_WITH_LEN(" USING BTREE"));
591
 
 
592
 
  if (key_info->algorithm == HA_KEY_ALG_HASH)
593
 
    packet->append(STRING_WITH_LEN(" USING HASH"));
594
 
 
595
 
  if ((key_info->flags & HA_USES_BLOCK_SIZE) &&
596
 
      table->s->getKeyBlockSize() != key_info->block_size)
597
 
  {
598
 
    packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
599
 
    end= internal::int64_t10_to_str(key_info->block_size, buff, 10);
600
 
    packet->append(buff, (uint32_t) (end - buff));
601
 
  }
602
 
 
603
 
  assert(test(key_info->flags & HA_USES_COMMENT) ==
604
 
              (key_info->comment.length > 0));
605
 
  if (key_info->flags & HA_USES_COMMENT)
606
 
  {
607
 
    packet->append(STRING_WITH_LEN(" COMMENT "));
608
 
    append_unescaped(packet, key_info->comment.str,
609
 
                     key_info->comment.length);
610
 
  }
611
 
}
612
 
 
613
 
 
614
329
/****************************************************************************
615
330
  Return info about all processes
616
331
  returns for each thread: thread id, user, host, db, command, info
644
359
  {}
645
360
};
646
361
 
647
 
/*****************************************************************************
648
 
  Status functions
649
 
*****************************************************************************/
650
 
 
651
 
static vector<drizzle_show_var *> all_status_vars;
652
 
static vector<drizzle_show_var *> com_status_vars;
653
 
static bool status_vars_inited= 0;
654
 
static int show_var_cmp(const void *var1, const void *var2)
655
 
{
656
 
  return strcmp(((drizzle_show_var*)var1)->name, ((drizzle_show_var*)var2)->name);
657
 
}
658
 
 
659
 
class show_var_cmp_functor
660
 
{
661
 
  public:
662
 
  show_var_cmp_functor() { }
663
 
  inline bool operator()(const drizzle_show_var *var1, const drizzle_show_var *var2) const
664
 
  {
665
 
    int val= strcmp(var1->name, var2->name);
666
 
    return (val < 0);
667
 
  }
668
 
};
669
 
 
670
 
class show_var_remove_if
671
 
{
672
 
  public:
673
 
  show_var_remove_if() { }
674
 
  inline bool operator()(const drizzle_show_var *curr) const
675
 
  {
676
 
    return (curr->type == SHOW_UNDEF);
677
 
  }
678
 
};
679
 
 
680
 
drizzle_show_var *getFrontOfStatusVars()
681
 
{
682
 
  return all_status_vars.front();
683
 
}
684
 
 
685
 
drizzle_show_var *getCommandStatusVars()
686
 
{
687
 
  return com_status_vars.front();
688
 
}
689
 
 
690
 
/*
691
 
  Adds an array of drizzle_show_var entries to the output of SHOW STATUS
692
 
 
693
 
  SYNOPSIS
694
 
    add_status_vars(drizzle_show_var *list)
695
 
    list - an array of drizzle_show_var entries to add to all_status_vars
696
 
           the last entry must be {0,0,SHOW_UNDEF}
697
 
 
698
 
  NOTE
699
 
    The handling of all_status_vars[] is completely internal, it's allocated
700
 
    automatically when something is added to it, and deleted completely when
701
 
    the last entry is removed.
702
 
 
703
 
    As a special optimization, if add_status_vars() is called before
704
 
    init_status_vars(), it assumes "startup mode" - neither concurrent access
705
 
    to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
706
 
*/
707
 
int add_status_vars(drizzle_show_var *list)
708
 
{
709
 
  int res= 0;
710
 
  if (status_vars_inited)
711
 
    pthread_mutex_lock(&LOCK_status);
712
 
  while (list->name)
713
 
    all_status_vars.insert(all_status_vars.begin(), list++);
714
 
  if (status_vars_inited)
715
 
    sort(all_status_vars.begin(), all_status_vars.end(),
716
 
         show_var_cmp_functor());
717
 
  if (status_vars_inited)
718
 
    pthread_mutex_unlock(&LOCK_status);
719
 
  return res;
720
 
}
721
 
 
722
 
int add_com_status_vars(drizzle_show_var *list)
723
 
{
724
 
  int res= 0;
725
 
 
726
 
  while (list->name)
727
 
    com_status_vars.insert(com_status_vars.begin(), list++);
728
 
  if (status_vars_inited)
729
 
    sort(com_status_vars.begin(), com_status_vars.end(),
730
 
         show_var_cmp_functor());
731
 
 
732
 
  return res;
733
 
}
734
 
 
735
 
/*
736
 
  Make all_status_vars[] usable for SHOW STATUS
737
 
 
738
 
  NOTE
739
 
    See add_status_vars(). Before init_status_vars() call, add_status_vars()
740
 
    works in a special fast "startup" mode. Thus init_status_vars()
741
 
    should be called as late as possible but before enabling multi-threading.
742
 
*/
743
 
void init_status_vars()
744
 
{
745
 
  status_vars_inited= 1;
746
 
  sort(all_status_vars.begin(), all_status_vars.end(),
747
 
       show_var_cmp_functor());
748
 
  sort(com_status_vars.begin(), com_status_vars.end(),
749
 
       show_var_cmp_functor());
750
 
}
751
 
 
752
 
void reset_status_vars()
753
 
{
754
 
  vector<drizzle_show_var *>::iterator p;
755
 
 
756
 
  p= all_status_vars.begin();
757
 
  while (p != all_status_vars.end())
758
 
  {
759
 
    /* Note that SHOW_LONG_NOFLUSH variables are not reset */
760
 
    if ((*p)->type == SHOW_LONG)
761
 
      (*p)->value= 0;
762
 
    ++p;
763
 
  }
764
 
 
765
 
  p= com_status_vars.begin();
766
 
  while (p != com_status_vars.end())
767
 
  {
768
 
    /* Note that SHOW_LONG_NOFLUSH variables are not reset */
769
 
    if ((*p)->type == SHOW_LONG)
770
 
      (*p)->value= 0;
771
 
    ++p;
772
 
  }
773
 
}
774
 
 
775
 
/*
776
 
  catch-all cleanup function, cleans up everything no matter what
777
 
 
778
 
  DESCRIPTION
779
 
    This function is not strictly required if all add_to_status/
780
 
    remove_status_vars are properly paired, but it's a safety measure that
781
 
    deletes everything from the all_status_vars vector even if some
782
 
    remove_status_vars were forgotten
783
 
*/
784
 
void free_status_vars()
785
 
{
786
 
  all_status_vars.clear();
787
 
  com_status_vars.clear();
788
 
}
789
 
 
790
 
/*
791
 
  Removes an array of drizzle_show_var entries from the output of SHOW STATUS
792
 
 
793
 
  SYNOPSIS
794
 
    remove_status_vars(drizzle_show_var *list)
795
 
    list - an array of drizzle_show_var entries to remove to all_status_vars
796
 
           the last entry must be {0,0,SHOW_UNDEF}
797
 
 
798
 
  NOTE
799
 
    there's lots of room for optimizing this, especially in non-sorted mode,
800
 
    but nobody cares - it may be called only in case of failed plugin
801
 
    initialization in the mysqld startup.
802
 
*/
803
 
 
804
 
void remove_status_vars(drizzle_show_var *list)
805
 
{
806
 
  if (status_vars_inited)
807
 
  {
808
 
    pthread_mutex_lock(&LOCK_status);
809
 
    drizzle_show_var *all= all_status_vars.front();
810
 
    int a= 0, b= all_status_vars.size(), c= (a+b)/2;
811
 
 
812
 
    for (; list->name; list++)
813
 
    {
814
 
      int res= 0;
815
 
      for (a= 0, b= all_status_vars.size(); b-a > 1; c= (a+b)/2)
816
 
      {
817
 
        res= show_var_cmp(list, all+c);
818
 
        if (res < 0)
819
 
          b= c;
820
 
        else if (res > 0)
821
 
          a= c;
822
 
        else
823
 
          break;
824
 
      }
825
 
      if (res == 0)
826
 
        all[c].type= SHOW_UNDEF;
827
 
    }
828
 
    /* removes all the SHOW_UNDEF elements from the vector */
829
 
    all_status_vars.erase(std::remove_if(all_status_vars.begin(),
830
 
                            all_status_vars.end(),show_var_remove_if()),
831
 
                            all_status_vars.end());
832
 
    pthread_mutex_unlock(&LOCK_status);
833
 
  }
834
 
  else
835
 
  {
836
 
    drizzle_show_var *all= all_status_vars.front();
837
 
    uint32_t i;
838
 
    for (; list->name; list++)
839
 
    {
840
 
      for (i= 0; i < all_status_vars.size(); i++)
841
 
      {
842
 
        if (show_var_cmp(list, all+i))
843
 
          continue;
844
 
        all[i].type= SHOW_UNDEF;
845
 
        break;
846
 
      }
847
 
    }
848
 
    /* removes all the SHOW_UNDEF elements from the vector */
849
 
    all_status_vars.erase(std::remove_if(all_status_vars.begin(),
850
 
                            all_status_vars.end(),show_var_remove_if()),
851
 
                            all_status_vars.end());
852
 
  }
853
 
}
854
 
 
855
 
/* collect status for all running threads */
856
 
 
857
 
void calc_sum_of_all_status(system_status_var *to)
858
 
{
859
 
  /* Ensure that thread id not killed during loop */
860
 
  pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
861
 
 
862
 
  /* Get global values as base */
863
 
  *to= global_status_var;
864
 
 
865
 
  /* Add to this status from existing threads */
866
 
  for(SessionList::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it )
867
 
  {
868
 
    add_to_status(to, &((*it)->status_var));
869
 
  }
870
 
 
871
 
  pthread_mutex_unlock(&LOCK_thread_count);
872
 
  return;
873
 
}
874
 
 
875
362
} /* namespace drizzled */