~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/show.cc

Merged Nathan from lp:~nlws/drizzle/fix-string-c-ptr-overrun

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
#include <drizzled/error.h>
29
29
#include <drizzled/tztime.h>
30
30
#include <drizzled/data_home.h>
 
31
#include <drizzled/item/blob.h>
31
32
#include <drizzled/item/cmpfunc.h>
32
 
#include <drizzled/virtual_column_info.h>
 
33
#include <drizzled/item/return_int.h>
 
34
#include <drizzled/item/empty_string.h>
 
35
#include <drizzled/item/return_date_time.h>
33
36
#include <drizzled/sql_base.h>
34
37
#include <drizzled/db.h>
35
38
#include <drizzled/field/timestamp.h>
36
 
#include <drizzled/field/fdecimal.h>
 
39
#include <drizzled/field/decimal.h>
 
40
#include <drizzled/lock.h>
 
41
#include <drizzled/item/return_date_time.h>
 
42
#include <drizzled/item/empty_string.h>
 
43
#include "drizzled/plugin_registry.h"
37
44
 
38
45
#include <string>
 
46
#include <iostream>
 
47
#include <sstream>
 
48
#include <vector>
 
49
#include <algorithm>
 
50
 
 
51
using namespace std;
 
52
 
 
53
extern "C"
 
54
int show_var_cmp(const void *var1, const void *var2);
39
55
 
40
56
inline const char *
41
57
str_or_nil(const char *str)
46
62
/* Match the values of enum ha_choice */
47
63
static const char *ha_choice_values[] = {"", "0", "1"};
48
64
 
49
 
static void store_key_options(Session *session, String *packet, Table *table,
50
 
                              KEY *key_info);
51
 
 
 
65
static void store_key_options(String *packet, Table *table, KEY *key_info);
 
66
 
 
67
static vector<InfoSchemaTable *> all_schema_tables;
 
68
 
 
69
Table *create_schema_table(Session *session, TableList *table_list);
 
70
int make_old_format(Session *session, InfoSchemaTable *schema_table);
 
71
 
 
72
void add_infoschema_table(InfoSchemaTable *schema_table)
 
73
{
 
74
  if (schema_table->create_table == NULL)
 
75
    schema_table->create_table= create_schema_table;
 
76
  if (schema_table->old_format == NULL)
 
77
    schema_table->old_format= make_old_format;
 
78
  if (schema_table->idx_field1 == 0)
 
79
    schema_table->idx_field1= -1;
 
80
  if (schema_table->idx_field2)
 
81
   schema_table->idx_field2= -1;
 
82
 
 
83
  all_schema_tables.push_back(schema_table);
 
84
}
 
85
 
 
86
void remove_infoschema_table(InfoSchemaTable *table)
 
87
{
 
88
  all_schema_tables.erase(remove_if(all_schema_tables.begin(),
 
89
                                    all_schema_tables.end(),
 
90
                                    bind2nd(equal_to<InfoSchemaTable *>(),
 
91
                                            table)),
 
92
                          all_schema_tables.end());
 
93
}
52
94
 
53
95
 
54
96
int wild_case_compare(const CHARSET_INFO * const cs, const char *str,const char *wildstr)
101
143
** List all table types supported
102
144
***************************************************************************/
103
145
 
104
 
static bool show_plugins(Session *session, plugin_ref plugin,
105
 
                            void *arg)
 
146
class ShowPlugins : public unary_function<st_plugin_int *, bool>
106
147
{
107
 
  Table *table= (Table*) arg;
108
 
  struct st_mysql_plugin *plug= plugin_decl(plugin);
109
 
  struct st_plugin_dl *plugin_dl= plugin_dlib(plugin);
110
 
  const CHARSET_INFO * const cs= system_charset_info;
111
 
 
112
 
  restore_record(table, s->default_values);
113
 
 
114
 
  table->field[0]->store(plugin_name(plugin)->str,
115
 
                         plugin_name(plugin)->length, cs);
116
 
 
117
 
  if (plug->version)
118
 
  {
119
 
    table->field[1]->store(plug->version, strlen(plug->version), cs);
120
 
    table->field[1]->set_notnull();
121
 
  }
122
 
  else
123
 
    table->field[1]->set_null();
124
 
 
125
 
  switch (plugin_state(plugin)) {
126
 
  /* case PLUGIN_IS_FREED: does not happen */
127
 
  case PLUGIN_IS_DELETED:
128
 
    table->field[2]->store(STRING_WITH_LEN("DELETED"), cs);
129
 
    break;
130
 
  case PLUGIN_IS_UNINITIALIZED:
131
 
    table->field[2]->store(STRING_WITH_LEN("INACTIVE"), cs);
132
 
    break;
133
 
  case PLUGIN_IS_READY:
134
 
    table->field[2]->store(STRING_WITH_LEN("ACTIVE"), cs);
135
 
    break;
136
 
  default:
137
 
    assert(0);
138
 
  }
139
 
 
140
 
  table->field[3]->store(plugin_type_names[plug->type].str,
141
 
                         plugin_type_names[plug->type].length,
142
 
                         cs);
143
 
 
144
 
  if (plugin_dl)
145
 
  {
146
 
    table->field[4]->store(plugin_dl->dl.str, plugin_dl->dl.length, cs);
147
 
    table->field[4]->set_notnull();
148
 
  }
149
 
  else
150
 
  {
151
 
    table->field[4]->set_null();
152
 
  }
153
 
 
154
 
  if (plug->author)
155
 
  {
156
 
    table->field[5]->store(plug->author, strlen(plug->author), cs);
 
148
  Session *session;
 
149
  Table *table;
 
150
public:
 
151
  ShowPlugins(Session *session_arg, Table *table_arg)
 
152
    : session(session_arg), table(table_arg) {}
 
153
 
 
154
  result_type operator() (argument_type plugin)
 
155
  {
 
156
    struct drizzled_plugin_manifest *plug= plugin_decl(plugin);
 
157
    const CHARSET_INFO * const cs= system_charset_info;
 
158
  
 
159
    table->restoreRecordAsDefault();
 
160
  
 
161
    table->field[0]->store(plugin_name(plugin)->str,
 
162
                           plugin_name(plugin)->length, cs);
 
163
  
 
164
    if (plug->version)
 
165
    {
 
166
      table->field[1]->store(plug->version, strlen(plug->version), cs);
 
167
      table->field[1]->set_notnull();
 
168
    }
 
169
    else
 
170
      table->field[1]->set_null();
 
171
  
 
172
    if (plugin->isInited)
 
173
      table->field[2]->store(STRING_WITH_LEN("ACTIVE"), cs);
 
174
    else
 
175
      table->field[2]->store(STRING_WITH_LEN("INACTIVE"), cs);
 
176
  
 
177
    if (plug->author)
 
178
    {
 
179
      table->field[3]->store(plug->author, strlen(plug->author), cs);
 
180
      table->field[3]->set_notnull();
 
181
    }
 
182
    else
 
183
      table->field[3]->set_null();
 
184
  
 
185
    if (plug->descr)
 
186
    {
 
187
      table->field[4]->store(plug->descr, strlen(plug->descr), cs);
 
188
      table->field[4]->set_notnull();
 
189
    }
 
190
    else
 
191
      table->field[4]->set_null();
 
192
  
 
193
    switch (plug->license) {
 
194
    case PLUGIN_LICENSE_GPL:
 
195
      table->field[5]->store(PLUGIN_LICENSE_GPL_STRING,
 
196
                             strlen(PLUGIN_LICENSE_GPL_STRING), cs);
 
197
      break;
 
198
    case PLUGIN_LICENSE_BSD:
 
199
      table->field[5]->store(PLUGIN_LICENSE_BSD_STRING,
 
200
                             strlen(PLUGIN_LICENSE_BSD_STRING), cs);
 
201
      break;
 
202
    case PLUGIN_LICENSE_LGPL:
 
203
      table->field[5]->store(PLUGIN_LICENSE_LGPL_STRING,
 
204
                             strlen(PLUGIN_LICENSE_LGPL_STRING), cs);
 
205
      break;
 
206
    default:
 
207
      table->field[5]->store(PLUGIN_LICENSE_PROPRIETARY_STRING,
 
208
                             strlen(PLUGIN_LICENSE_PROPRIETARY_STRING), cs);
 
209
      break;
 
210
    }
157
211
    table->field[5]->set_notnull();
158
 
  }
159
 
  else
160
 
    table->field[5]->set_null();
161
 
 
162
 
  if (plug->descr)
163
 
  {
164
 
    table->field[6]->store(plug->descr, strlen(plug->descr), cs);
165
 
    table->field[6]->set_notnull();
166
 
  }
167
 
  else
168
 
    table->field[6]->set_null();
169
 
 
170
 
  switch (plug->license) {
171
 
  case PLUGIN_LICENSE_GPL:
172
 
    table->field[7]->store(PLUGIN_LICENSE_GPL_STRING, 
173
 
                           strlen(PLUGIN_LICENSE_GPL_STRING), cs);
174
 
    break;
175
 
  case PLUGIN_LICENSE_BSD:
176
 
    table->field[7]->store(PLUGIN_LICENSE_BSD_STRING, 
177
 
                           strlen(PLUGIN_LICENSE_BSD_STRING), cs);
178
 
    break;
179
 
  default:
180
 
    table->field[7]->store(PLUGIN_LICENSE_PROPRIETARY_STRING, 
181
 
                           strlen(PLUGIN_LICENSE_PROPRIETARY_STRING), cs);
182
 
    break;
183
 
  }
184
 
  table->field[7]->set_notnull();
185
 
 
186
 
  return schema_table_store_record(session, table);
187
 
}
 
212
  
 
213
    return schema_table_store_record(session, table);
 
214
  }
 
215
};
188
216
 
189
217
 
190
218
int fill_plugins(Session *session, TableList *tables, COND *)
191
219
{
192
220
  Table *table= tables->table;
193
221
 
194
 
  if (plugin_foreach_with_mask(session, show_plugins, DRIZZLE_ANY_PLUGIN,
195
 
                               ~PLUGIN_IS_FREED, table))
196
 
    return(1);
197
 
 
 
222
  PluginRegistry &registry= PluginRegistry::getPluginRegistry();
 
223
  vector<st_plugin_int *> plugins= registry.get_list(true);
 
224
  vector<st_plugin_int *>::iterator iter=
 
225
    find_if(plugins.begin(), plugins.end(), ShowPlugins(session, table));
 
226
  if (iter != plugins.end())
 
227
    return 1;
198
228
  return(0);
199
229
}
200
230
 
245
275
    return(FIND_FILES_DIR);
246
276
  }
247
277
 
248
 
  for (i=0 ; i < (uint) dirp->number_off_files  ; i++)
 
278
  for (i=0 ; i < (uint32_t) dirp->number_off_files  ; i++)
249
279
  {
250
280
    char uname[NAME_LEN + 1];                   /* Unencoded name */
251
281
    file=dirp->dir_entry+i;
252
282
    if (dir)
253
283
    {                                           /* Return databases */
254
 
      if ((file->name[0] == '.' && 
 
284
      if ((file->name[0] == '.' &&
255
285
          ((file->name[1] == '.' && file->name[2] == '\0') ||
256
286
            file->name[1] == '\0')))
257
287
        continue;                               /* . or .. */
277
307
      file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
278
308
      if (wild && wild_compare(uname, wild, 0))
279
309
        continue;
280
 
      if (!(file_name= 
 
310
      if (!(file_name=
281
311
            session->make_lex_string(file_name, uname, file_name_len, true)))
282
312
      {
283
313
        my_dirend(dirp);
286
316
    }
287
317
    else
288
318
    {
289
 
        // Return only .frm files which aren't temp files.
290
 
      if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),reg_ext) ||
 
319
      // Return only .frm files which aren't temp files.
 
320
      if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),".dfe") ||
291
321
          is_prefix(file->name, TMP_FILE_PREFIX))
292
322
        continue;
293
323
      *ext=0;
294
324
      file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
295
325
      if (wild)
296
326
      {
297
 
        if (lower_case_table_names)
298
 
        {
299
 
          if (wild_case_compare(files_charset_info, uname, wild))
300
 
            continue;
301
 
        }
302
 
        else if (wild_compare(uname, wild, 0))
303
 
          continue;
 
327
        if (lower_case_table_names)
 
328
        {
 
329
          if (wild_case_compare(files_charset_info, uname, wild))
 
330
            continue;
 
331
        }
 
332
        else if (wild_compare(uname, wild, 0))
 
333
          continue;
304
334
      }
305
335
    }
306
 
    if (!(file_name= 
 
336
    if (!(file_name=
307
337
          session->make_lex_string(file_name, uname, file_name_len, true)) ||
308
338
        files->push_back(file_name))
309
339
    {
317
347
}
318
348
 
319
349
 
320
 
bool
321
 
mysqld_show_create(Session *session, TableList *table_list)
 
350
bool drizzled_show_create(Session *session, TableList *table_list)
322
351
{
323
352
  Protocol *protocol= session->protocol;
324
353
  char buff[2048];
327
356
  /* Only one table for now, but VIEW can involve several tables */
328
357
  if (open_normal_and_derived_tables(session, table_list, 0))
329
358
  {
330
 
    if (session->is_error() && session->main_da.sql_errno() != ER_VIEW_INVALID)
331
 
      return(true);
 
359
    if (session->is_error())
 
360
      return true;
332
361
 
333
362
    /*
334
363
      Clear all messages with 'error' level status and
335
 
      issue a warning with 'warning' level status in 
 
364
      issue a warning with 'warning' level status in
336
365
      case of invalid view and last error is ER_VIEW_INVALID
337
366
    */
338
367
    drizzle_reset_errors(session, true);
341
370
 
342
371
  buffer.length(0);
343
372
 
344
 
  if (store_create_info(session, table_list, &buffer, NULL))
345
 
    return(true);
 
373
  if (store_create_info(table_list, &buffer, NULL))
 
374
    return true;
346
375
 
347
376
  List<Item> field_list;
348
377
  {
352
381
                                               cmax(buffer.length(),(uint32_t)1024)));
353
382
  }
354
383
 
355
 
  if (protocol->send_fields(&field_list,
356
 
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
357
 
    return(true);
358
 
  protocol->prepare_for_resend();
 
384
  if (protocol->sendFields(&field_list,
 
385
                           Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
 
386
  {
 
387
    return true;
 
388
  }
 
389
  protocol->prepareForResend();
359
390
  {
360
391
    if (table_list->schema_table)
361
392
      protocol->store(table_list->schema_table->table_name,
367
398
  protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
368
399
 
369
400
  if (protocol->write())
370
 
    return(true);
 
401
    return true;
371
402
 
372
 
  my_eof(session);
373
 
  return(false);
 
403
  session->my_eof();
 
404
  return false;
374
405
}
375
406
 
376
407
bool mysqld_show_create_db(Session *session, char *dbname,
380
411
  String buffer(buff, sizeof(buff), system_charset_info);
381
412
  Protocol *protocol=session->protocol;
382
413
 
383
 
  if (store_db_create_info(session, dbname, &buffer, create_info))
 
414
  if (store_db_create_info(dbname, &buffer, create_info))
384
415
  {
385
 
    /* 
 
416
    /*
386
417
      This assumes that the only reason for which store_db_create_info()
387
418
      can fail is incorrect database name (which is the case now).
388
419
    */
389
420
    my_error(ER_BAD_DB_ERROR, MYF(0), dbname);
390
 
    return(true);    
 
421
    return true;
391
422
  }
392
423
 
393
424
  List<Item> field_list;
394
425
  field_list.push_back(new Item_empty_string("Database",NAME_CHAR_LEN));
395
426
  field_list.push_back(new Item_empty_string("Create Database",1024));
396
427
 
397
 
  if (protocol->send_fields(&field_list,
398
 
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
399
 
    return(true);
 
428
  if (protocol->sendFields(&field_list,
 
429
                           Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
 
430
    return true;
400
431
 
401
 
  protocol->prepare_for_resend();
 
432
  protocol->prepareForResend();
402
433
  protocol->store(dbname, strlen(dbname), system_charset_info);
403
434
  protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
404
435
 
405
436
  if (protocol->write())
406
 
    return(true);
407
 
  my_eof(session);
408
 
  return(false);
 
437
    return true;
 
438
  session->my_eof();
 
439
  return false;
409
440
}
410
441
 
411
442
 
429
460
  Field **ptr,*field;
430
461
  for (ptr=table->field ; (field= *ptr); ptr++)
431
462
  {
432
 
    if (!wild || !wild[0] || 
 
463
    if (!wild || !wild[0] ||
433
464
        !wild_case_compare(system_charset_info, field->field_name,wild))
434
465
    {
435
466
      field_list.push_back(new Item_field(field));
436
467
    }
437
468
  }
438
 
  restore_record(table, s->default_values);              // Get empty record
 
469
  table->restoreRecordAsDefault();              // Get empty record
439
470
  table->use_all_columns();
440
 
  if (session->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS))
441
 
    return;
442
 
  my_eof(session);
443
 
  return;
444
 
}
445
 
 
446
 
 
447
 
/*
448
 
  Go through all character combinations and ensure that sql_lex.cc can
449
 
  parse it as an identifier.
450
 
 
451
 
  SYNOPSIS
452
 
  require_quotes()
453
 
  name                  attribute name
454
 
  name_length           length of name
455
 
 
456
 
  RETURN
457
 
    #   Pointer to conflicting character
458
 
    0   No conflicting character
459
 
*/
460
 
 
461
 
static const char *require_quotes(const char *name, uint32_t name_length)
462
 
{
463
 
  uint32_t length;
464
 
  bool pure_digit= true;
465
 
  const char *end= name + name_length;
466
 
 
467
 
  for (; name < end ; name++)
468
 
  {
469
 
    unsigned char chr= (unsigned char) *name;
470
 
    length= my_mbcharlen(system_charset_info, chr);
471
 
    if (length == 1 && !system_charset_info->ident_map[chr])
472
 
      return name;
473
 
    if (length == 1 && (chr < '0' || chr > '9'))
474
 
      pure_digit= false;
475
 
  }
476
 
  if (pure_digit)
477
 
    return name;
478
 
  return 0;
479
 
}
480
 
 
481
 
 
482
 
/*
483
 
  Quote the given identifier if needed and append it to the target string.
484
 
  If the given identifier is empty, it will be quoted.
485
 
 
486
 
  SYNOPSIS
487
 
  append_identifier()
488
 
  session                   thread handler
489
 
  packet                target string
490
 
  name                  the identifier to be appended
491
 
  name_length           length of the appending identifier
492
 
*/
493
 
 
494
 
void
495
 
append_identifier(Session *session, String *packet, const char *name, uint32_t length)
496
 
{
497
 
  const char *name_end;
498
 
  char quote_char;
499
 
  int q= get_quote_char_for_identifier(session, name, length);
500
 
 
501
 
  if (q == EOF)
502
 
  {
503
 
    packet->append(name, length, packet->charset());
504
 
    return;
505
 
  }
506
 
 
507
 
  /*
508
 
    The identifier must be quoted as it includes a quote character or
509
 
   it's a keyword
510
 
  */
511
 
 
512
 
  packet->reserve(length*2 + 2);
513
 
  quote_char= (char) q;
514
 
  packet->append(&quote_char, 1, system_charset_info);
515
 
 
516
 
  for (name_end= name+length ; name < name_end ; name+= length)
517
 
  {
518
 
    unsigned char chr= (unsigned char) *name;
519
 
    length= my_mbcharlen(system_charset_info, chr);
520
 
    /*
521
 
      my_mbcharlen can return 0 on a wrong multibyte
522
 
      sequence. It is possible when upgrading from 4.0,
523
 
      and identifier contains some accented characters.
524
 
      The manual says it does not work. So we'll just
525
 
      change length to 1 not to hang in the endless loop.
526
 
    */
527
 
    if (!length)
528
 
      length= 1;
529
 
    if (length == 1 && chr == (unsigned char) quote_char)
530
 
      packet->append(&quote_char, 1, system_charset_info);
531
 
    packet->append(name, length, system_charset_info);
532
 
  }
533
 
  packet->append(&quote_char, 1, system_charset_info);
 
471
  if (session->protocol->sendFields(&field_list, Protocol::SEND_DEFAULTS))
 
472
    return;
 
473
  session->my_eof();
534
474
}
535
475
 
536
476
 
539
479
 
540
480
  SYNOPSIS
541
481
    get_quote_char_for_identifier()
542
 
    session             Thread handler
543
 
    name        name to quote
544
 
    length      length of name
545
482
 
546
483
  IMPLEMENTATION
547
484
    Force quoting in the following cases:
557
494
    #     Quote character
558
495
*/
559
496
 
560
 
int get_quote_char_for_identifier(Session *session, const char *name, uint32_t length)
 
497
int get_quote_char_for_identifier()
561
498
{
562
 
  if (length &&
563
 
      !is_keyword(name,length) &&
564
 
      !require_quotes(name, length) &&
565
 
      !(session->options & OPTION_QUOTE_SHOW_CREATE))
566
 
    return EOF;
567
499
  return '`';
568
500
}
569
501
 
570
502
 
571
503
/* Append directory name (if exists) to CREATE INFO */
572
504
 
573
 
static void append_directory(Session *,
574
 
                             String *packet, const char *dir_type,
 
505
static void append_directory(String *packet, const char *dir_type,
575
506
                             const char *filename)
576
507
{
577
508
  if (filename)
588
519
 
589
520
#define LIST_PROCESS_HOST_LEN 64
590
521
 
591
 
static bool get_field_default_value(Session *,
592
 
                                    Field *timestamp_field,
 
522
static bool get_field_default_value(Field *timestamp_field,
593
523
                                    Field *field, String *def_value,
594
524
                                    bool quoted)
595
525
{
596
526
  bool has_default;
597
527
  bool has_now_default;
598
528
 
599
 
  /* 
 
529
  /*
600
530
     We are using CURRENT_TIMESTAMP instead of NOW because it is
601
531
     more standard
602
532
  */
603
533
  has_now_default= (timestamp_field == field &&
604
534
                    field->unireg_check != Field::TIMESTAMP_UN_FIELD);
605
 
    
 
535
 
606
536
  has_default= (field->type() != DRIZZLE_TYPE_BLOB &&
607
537
                !(field->flags & NO_DEFAULT_VALUE_FLAG) &&
608
 
                field->unireg_check != Field::NEXT_NUMBER
609
 
                  && has_now_default);
 
538
                field->unireg_check != Field::NEXT_NUMBER);
610
539
 
611
540
  def_value->length(0);
612
541
  if (has_default)
636
565
    else if (field->maybe_null() && quoted)
637
566
      def_value->append(STRING_WITH_LEN("NULL"));    // Null as default
638
567
    else
639
 
      return 0;
640
 
 
 
568
      return false;
641
569
  }
642
570
  return has_default;
643
571
}
647
575
 
648
576
  SYNOPSIS
649
577
    store_create_info()
650
 
    session               The thread
651
578
    table_list        A list containing one table to write statement
652
579
                      for.
653
580
    packet            Pointer to a string where statement will be
656
583
                      to tailor the format of the statement.  Can be
657
584
                      NULL, in which case only SQL_MODE is considered
658
585
                      when building the statement.
659
 
  
 
586
 
660
587
  NOTE
661
588
    Currently always return 0, but might return error code in the
662
589
    future.
663
 
    
 
590
 
664
591
  RETURN
665
592
    0       OK
666
593
 */
667
594
 
668
 
int store_create_info(Session *session, TableList *table_list, String *packet,
669
 
                      HA_CREATE_INFO *create_info_arg)
 
595
int store_create_info(TableList *table_list, String *packet, HA_CREATE_INFO *create_info_arg)
670
596
{
671
597
  List<Item> field_list;
672
598
  char tmp[MAX_FIELD_WIDTH], *for_str, def_value_buf[MAX_FIELD_WIDTH];
673
599
  const char *alias;
674
 
  std::string buff;
 
600
  string buff;
675
601
  String type(tmp, sizeof(tmp), system_charset_info);
676
602
  String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
677
603
  Field **ptr,*field;
679
605
  KEY *key_info;
680
606
  Table *table= table_list->table;
681
607
  handler *file= table->file;
682
 
  TABLE_SHARE *share= table->s;
 
608
  TableShare *share= table->s;
683
609
  HA_CREATE_INFO create_info;
684
610
  bool show_table_options= false;
685
611
  my_bitmap_map *old_map;
686
612
 
687
 
  restore_record(table, s->default_values); // Get empty record
 
613
  table->restoreRecordAsDefault(); // Get empty record
688
614
 
689
615
  if (share->tmp_table)
690
616
    packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
700
626
    if (lower_case_table_names == 2)
701
627
      alias= table->alias;
702
628
    else
703
 
    {
704
629
      alias= share->table_name.str;
705
 
    }
706
630
  }
707
 
  append_identifier(session, packet, alias, strlen(alias));
 
631
  packet->append_identifier(alias, strlen(alias));
708
632
  packet->append(STRING_WITH_LEN(" (\n"));
709
633
  /*
710
634
    We need this to get default values from the table
721
645
      packet->append(STRING_WITH_LEN(",\n"));
722
646
 
723
647
    packet->append(STRING_WITH_LEN("  "));
724
 
    append_identifier(session,packet,field->field_name, strlen(field->field_name));
 
648
    packet->append_identifier(field->field_name, strlen(field->field_name));
725
649
    packet->append(' ');
726
650
    // check for surprises from the previous call to Field::sql_type()
727
651
    if (type.ptr() != tmp)
729
653
    else
730
654
      type.set_charset(system_charset_info);
731
655
 
732
 
    if (field->vcol_info)
733
 
    {
734
 
      packet->append(STRING_WITH_LEN("VIRTUAL "));
735
 
    }
736
 
 
737
656
    field->sql_type(type);
738
657
    packet->append(type.ptr(), type.length(), system_charset_info);
739
658
 
740
 
    if (field->vcol_info)
741
 
    {
742
 
      packet->append(STRING_WITH_LEN(" AS ("));
743
 
      packet->append(field->vcol_info->expr_str.str,
744
 
                     field->vcol_info->expr_str.length,
745
 
                     system_charset_info);
746
 
      packet->append(STRING_WITH_LEN(")"));
747
 
      if (field->is_stored)
748
 
        packet->append(STRING_WITH_LEN(" STORED"));
749
 
    }
750
 
    
751
659
    if (field->has_charset())
752
660
    {
753
661
      if (field->charset() != share->table_charset)
754
662
      {
755
 
        packet->append(STRING_WITH_LEN(" CHARACTER SET "));
756
 
        packet->append(field->charset()->csname);
 
663
        packet->append(STRING_WITH_LEN(" CHARACTER SET "));
 
664
        packet->append(field->charset()->csname);
757
665
      }
758
 
      /* 
759
 
        For string types dump collation name only if 
760
 
        collation is not primary for the given charset
 
666
 
 
667
      /*
 
668
        For string types dump collation name only if
 
669
        collation is not primary for the given charset
761
670
      */
762
671
      if (!(field->charset()->state & MY_CS_PRIMARY))
763
672
      {
764
 
        packet->append(STRING_WITH_LEN(" COLLATE "));
765
 
        packet->append(field->charset()->name);
 
673
        packet->append(STRING_WITH_LEN(" COLLATE "));
 
674
        packet->append(field->charset()->name);
766
675
      }
767
676
    }
768
677
 
786
695
      if (column_format)
787
696
      {
788
697
        packet->append(STRING_WITH_LEN(" /*!"));
789
 
        packet->append(STRING_WITH_LEN(DRIZZLE_VERSION_TABLESPACE_IN_FRM_STR));
790
698
        packet->append(STRING_WITH_LEN(" COLUMN_FORMAT"));
791
699
        if (column_format == COLUMN_FORMAT_TYPE_FIXED)
792
700
          packet->append(STRING_WITH_LEN(" FIXED */"));
794
702
          packet->append(STRING_WITH_LEN(" DYNAMIC */"));
795
703
      }
796
704
    }
797
 
    if (!field->vcol_info &&
798
 
        get_field_default_value(session, table->timestamp_field,
799
 
                                field, &def_value, 1))
 
705
    if (get_field_default_value(table->timestamp_field, field, &def_value, 1))
800
706
    {
801
707
      packet->append(STRING_WITH_LEN(" DEFAULT "));
802
708
      packet->append(def_value.ptr(), def_value.length(), system_charset_info);
843
749
      packet->append(STRING_WITH_LEN("KEY "));
844
750
 
845
751
    if (!found_primary)
846
 
     append_identifier(session, packet, key_info->name, strlen(key_info->name));
 
752
     packet->append_identifier(key_info->name, strlen(key_info->name));
847
753
 
848
754
    packet->append(STRING_WITH_LEN(" ("));
849
755
 
853
759
        packet->append(',');
854
760
 
855
761
      if (key_part->field)
856
 
        append_identifier(session,packet,key_part->field->field_name,
857
 
                          strlen(key_part->field->field_name));
 
762
        packet->append_identifier(key_part->field->field_name,
 
763
                                  strlen(key_part->field->field_name));
858
764
      if (key_part->field &&
859
765
          (key_part->length !=
860
766
           table->field[key_part->fieldnr-1]->key_length()))
867
773
      }
868
774
    }
869
775
    packet->append(')');
870
 
    store_key_options(session, packet, table, key_info);
 
776
    store_key_options(packet, table, key_info);
871
777
  }
872
778
 
873
779
  /*
949
855
    if (share->page_checksum != HA_CHOICE_UNDEF)
950
856
    {
951
857
      packet->append(STRING_WITH_LEN(" PAGE_CHECKSUM="));
952
 
      packet->append(ha_choice_values[(uint) share->page_checksum], 1);
 
858
      packet->append(ha_choice_values[(uint32_t) share->page_checksum], 1);
953
859
    }
954
860
    if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
955
861
      packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
956
862
    if (create_info.row_type != ROW_TYPE_DEFAULT)
957
863
    {
958
864
      packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
959
 
      packet->append(ha_row_type[(uint) create_info.row_type]);
960
 
    }
961
 
    if (share->transactional != HA_CHOICE_UNDEF)
962
 
    {
963
 
      packet->append(STRING_WITH_LEN(" TRANSACTIONAL="));
964
 
      packet->append(ha_choice_values[(uint) share->transactional], 1);
 
865
      packet->append(ha_row_type[(uint32_t) create_info.row_type]);
965
866
    }
966
867
    if (table->s->key_block_size)
967
868
    {
986
887
      packet->append(STRING_WITH_LEN(" CONNECTION="));
987
888
      append_unescaped(packet, share->connect_string.str, share->connect_string.length);
988
889
    }
989
 
    append_directory(session, packet, "DATA",  create_info.data_file_name);
990
 
    append_directory(session, packet, "INDEX", create_info.index_file_name);
 
890
    append_directory(packet, "DATA",  create_info.data_file_name);
 
891
    append_directory(packet, "INDEX", create_info.index_file_name);
991
892
  }
992
893
  table->restore_column_map(old_map);
993
894
  return(0);
1009
910
  @param  session           The current thread instance.
1010
911
  @param  dbname        The name of the database.
1011
912
  @param  buffer        A String instance where the statement is stored.
1012
 
  @param  create_info   If not NULL, the options member influences the resulting 
 
913
  @param  create_info   If not NULL, the options member influences the resulting
1013
914
                        CRATE statement.
1014
915
 
1015
916
  @returns true if errors are detected, false otherwise.
1016
917
*/
1017
918
 
1018
 
bool store_db_create_info(Session *session, const char *dbname, String *buffer,
1019
 
                          HA_CREATE_INFO *create_info)
 
919
bool store_db_create_info(const char *dbname, String *buffer, HA_CREATE_INFO *create_info)
1020
920
{
1021
921
  HA_CREATE_INFO create;
1022
922
  uint32_t create_options = create_info ? create_info->options : 0;
1030
930
  else
1031
931
  {
1032
932
    if (check_db_dir_existence(dbname))
1033
 
      return(true);
 
933
      return true;
1034
934
 
1035
 
    load_db_opt_by_name(session, dbname, &create);
 
935
    load_db_opt_by_name(dbname, &create);
1036
936
  }
1037
937
 
1038
938
  buffer->length(0);
1041
941
  buffer->append(STRING_WITH_LEN("CREATE DATABASE "));
1042
942
 
1043
943
  if (create_options & HA_LEX_CREATE_IF_NOT_EXISTS)
1044
 
    buffer->append(STRING_WITH_LEN("/*!32312 IF NOT EXISTS*/ "));
1045
 
 
1046
 
  append_identifier(session, buffer, dbname, strlen(dbname));
1047
 
 
1048
 
  if (create.default_table_charset)
1049
 
  {
1050
 
    buffer->append(STRING_WITH_LEN(" /*!40100"));
1051
 
    buffer->append(STRING_WITH_LEN(" DEFAULT CHARACTER SET "));
1052
 
    buffer->append(create.default_table_charset->csname);
1053
 
    if (!(create.default_table_charset->state & MY_CS_PRIMARY))
1054
 
    {
1055
 
      buffer->append(STRING_WITH_LEN(" COLLATE "));
1056
 
      buffer->append(create.default_table_charset->name);
1057
 
    }
1058
 
    buffer->append(STRING_WITH_LEN(" */"));
1059
 
  }
1060
 
 
1061
 
  return(false);
 
944
    buffer->append(STRING_WITH_LEN("IF NOT EXISTS "));
 
945
 
 
946
  buffer->append_identifier(dbname, strlen(dbname));
 
947
 
 
948
  return false;
1062
949
}
1063
950
 
1064
 
static void store_key_options(Session *,
1065
 
                              String *packet, Table *table,
1066
 
                              KEY *key_info)
 
951
static void store_key_options(String *packet, Table *table, KEY *key_info)
1067
952
{
1068
953
  char *end, buff[32];
1069
954
 
1078
963
  {
1079
964
    packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
1080
965
    end= int64_t10_to_str(key_info->block_size, buff, 10);
1081
 
    packet->append(buff, (uint) (end - buff));
 
966
    packet->append(buff, (uint32_t) (end - buff));
1082
967
  }
1083
968
 
1084
 
  assert(test(key_info->flags & HA_USES_COMMENT) == 
 
969
  assert(test(key_info->flags & HA_USES_COMMENT) ==
1085
970
              (key_info->comment.length > 0));
1086
971
  if (key_info->flags & HA_USES_COMMENT)
1087
972
  {
1088
973
    packet->append(STRING_WITH_LEN(" COMMENT "));
1089
 
    append_unescaped(packet, key_info->comment.str, 
 
974
    append_unescaped(packet, key_info->comment.str,
1090
975
                     key_info->comment.length);
1091
976
  }
1092
977
}
1101
986
public:
1102
987
  static void *operator new(size_t size)
1103
988
  {
1104
 
    return (void*) sql_alloc((uint) size);
 
989
    return (void*) sql_alloc((uint32_t) size);
1105
990
  }
1106
991
  static void operator delete(void *, size_t)
1107
992
  { TRASH(ptr, size); }
1108
993
 
1109
 
  ulong thread_id;
 
994
  my_thread_id thread_id;
1110
995
  time_t start_time;
1111
996
  uint32_t   command;
1112
997
  const char *user,*host,*db,*proc_info,*state_info;
1117
1002
template class I_List<thread_info>;
1118
1003
#endif
1119
1004
 
1120
 
void mysqld_list_processes(Session *session,const char *user, bool verbose)
 
1005
void mysqld_list_processes(Session *session,const char *user, bool)
1121
1006
{
1122
1007
  Item *field;
1123
1008
  List<Item> field_list;
1124
1009
  I_List<thread_info> thread_infos;
1125
 
  ulong max_query_length= (verbose ? session->variables.max_allowed_packet :
1126
 
                           PROCESS_LIST_WIDTH);
1127
1010
  Protocol *protocol= session->protocol;
1128
1011
 
1129
1012
  field_list.push_back(new Item_int("Id", 0, MY_INT32_NUM_DECIMAL_DIGITS));
1130
1013
  field_list.push_back(new Item_empty_string("User",16));
1131
1014
  field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
1132
1015
  field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
1133
 
  field->maybe_null=1;
 
1016
  field->maybe_null= true;
1134
1017
  field_list.push_back(new Item_empty_string("Command",16));
1135
1018
  field_list.push_back(new Item_return_int("Time",7, DRIZZLE_TYPE_LONG));
1136
1019
  field_list.push_back(field=new Item_empty_string("State",30));
1137
 
  field->maybe_null=1;
1138
 
  field_list.push_back(field=new Item_empty_string("Info",max_query_length));
1139
 
  field->maybe_null=1;
1140
 
  if (protocol->send_fields(&field_list,
1141
 
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
 
1020
  field->maybe_null= true;
 
1021
  field_list.push_back(field=new Item_empty_string("Info", PROCESS_LIST_WIDTH));
 
1022
  field->maybe_null= true;
 
1023
  if (protocol->sendFields(&field_list,
 
1024
                           Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
1142
1025
    return;
1143
1026
 
1144
1027
  pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1145
1028
  if (!session->killed)
1146
1029
  {
1147
 
    I_List_iterator<Session> it(threads);
1148
1030
    Session *tmp;
1149
 
    while ((tmp=it++))
 
1031
    for( vector<Session*>::iterator it= session_list.begin(); it != session_list.end(); ++it )
1150
1032
    {
1151
 
      Security_context *tmp_sctx= tmp->security_ctx;
 
1033
      tmp= *it;
 
1034
      Security_context *tmp_sctx= &tmp->security_ctx;
1152
1035
      struct st_my_thread_var *mysys_var;
1153
 
      if ((tmp->vio_ok() || tmp->system_thread) && (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
 
1036
      if (tmp->protocol->isConnected() && (!user || (tmp_sctx->user.c_str() && !strcmp(tmp_sctx->user.c_str(), user))))
1154
1037
      {
1155
1038
        thread_info *session_info= new thread_info;
1156
1039
 
1157
1040
        session_info->thread_id=tmp->thread_id;
1158
 
        session_info->user= session->strdup(tmp_sctx->user ? tmp_sctx->user :
1159
 
                                    (tmp->system_thread ?
1160
 
                                     "system user" : "unauthenticated user"));
1161
 
        session_info->host= session->strdup(tmp_sctx->ip);
 
1041
        session_info->user= session->strdup(tmp_sctx->user.c_str() ? tmp_sctx->user.c_str() : "unauthenticated user");
 
1042
        session_info->host= session->strdup(tmp_sctx->ip.c_str());
1162
1043
        if ((session_info->db=tmp->db))             // Safe test
1163
1044
          session_info->db=session->strdup(session_info->db);
1164
1045
        session_info->command=(int) tmp->command;
1165
1046
        if ((mysys_var= tmp->mysys_var))
1166
1047
          pthread_mutex_lock(&mysys_var->mutex);
1167
 
        session_info->proc_info= (char*) (tmp->killed == Session::KILL_CONNECTION? "Killed" : 0);
1168
 
        session_info->state_info= (char*) (tmp->net.reading_or_writing ?
1169
 
                                       (tmp->net.reading_or_writing == 2 ?
1170
 
                                        "Writing to net" :
1171
 
                                        session_info->command == COM_SLEEP ? NULL :
1172
 
                                        "Reading from net") :
 
1048
 
 
1049
        if (tmp->killed == Session::KILL_CONNECTION)
 
1050
          session_info->proc_info= (char*) "Killed";
 
1051
        else
 
1052
          session_info->proc_info= command_name[session_info->command].str;
 
1053
 
 
1054
        session_info->state_info= (char*) (tmp->protocol->isWriting() ?
 
1055
                                           "Writing to net" :
 
1056
                                           tmp->protocol->isReading() ?
 
1057
                                           (session_info->command == COM_SLEEP ?
 
1058
                                            NULL : "Reading from net") :
1173
1059
                                       tmp->get_proc_info() ? tmp->get_proc_info() :
1174
1060
                                       tmp->mysys_var &&
1175
1061
                                       tmp->mysys_var->current_cond ?
1178
1064
          pthread_mutex_unlock(&mysys_var->mutex);
1179
1065
 
1180
1066
        session_info->start_time= tmp->start_time;
1181
 
        session_info->query=0;
1182
 
        if (tmp->query)
1183
 
        {
1184
 
          /* 
1185
 
            query_length is always set to 0 when we set query = NULL; see
1186
 
                  the comment in session.h why this prevents crashes in possible
1187
 
            races with query_length
1188
 
          */
1189
 
          uint32_t length= cmin((uint32_t)max_query_length, tmp->query_length);
1190
 
          session_info->query=(char*) session->strmake(tmp->query,length);
1191
 
        }
 
1067
        session_info->query= NULL;
 
1068
        if (tmp->process_list_info[0])
 
1069
          session_info->query= session->strdup(tmp->process_list_info);
1192
1070
        thread_infos.append(session_info);
1193
1071
      }
1194
1072
    }
1196
1074
  pthread_mutex_unlock(&LOCK_thread_count);
1197
1075
 
1198
1076
  thread_info *session_info;
1199
 
  time_t now= my_time(0);
 
1077
  time_t now= time(NULL);
1200
1078
  while ((session_info=thread_infos.get()))
1201
1079
  {
1202
 
    protocol->prepare_for_resend();
 
1080
    protocol->prepareForResend();
1203
1081
    protocol->store((uint64_t) session_info->thread_id);
1204
1082
    protocol->store(session_info->user, system_charset_info);
1205
1083
    protocol->store(session_info->host, system_charset_info);
1206
1084
    protocol->store(session_info->db, system_charset_info);
1207
 
    if (session_info->proc_info)
1208
 
      protocol->store(session_info->proc_info, system_charset_info);
1209
 
    else
1210
 
      protocol->store(command_name[session_info->command].str, system_charset_info);
 
1085
    protocol->store(session_info->proc_info, system_charset_info);
 
1086
 
1211
1087
    if (session_info->start_time)
1212
1088
      protocol->store((uint32_t) (now - session_info->start_time));
1213
1089
    else
1214
 
      protocol->store_null();
 
1090
      protocol->store();
 
1091
 
1215
1092
    protocol->store(session_info->state_info, system_charset_info);
1216
1093
    protocol->store(session_info->query, system_charset_info);
 
1094
 
1217
1095
    if (protocol->write())
1218
1096
      break; /* purecov: inspected */
1219
1097
  }
1220
 
  my_eof(session);
 
1098
  session->my_eof();
1221
1099
  return;
1222
1100
}
1223
1101
 
1226
1104
  Table *table= tables->table;
1227
1105
  const CHARSET_INFO * const cs= system_charset_info;
1228
1106
  char *user;
1229
 
  time_t now= my_time(0);
 
1107
  time_t now= time(NULL);
 
1108
  size_t length;
 
1109
 
 
1110
  if (now == (time_t)-1)
 
1111
    return 1;
1230
1112
 
1231
1113
  user= NULL;
1232
1114
 
1234
1116
 
1235
1117
  if (!session->killed)
1236
1118
  {
1237
 
    I_List_iterator<Session> it(threads);
1238
1119
    Session* tmp;
1239
1120
 
1240
 
    while ((tmp= it++))
 
1121
    for( vector<Session*>::iterator it= session_list.begin(); it != session_list.end(); ++it )
1241
1122
    {
1242
 
      Security_context *tmp_sctx= tmp->security_ctx;
 
1123
      tmp= *it;
 
1124
      Security_context *tmp_sctx= &tmp->security_ctx;
1243
1125
      struct st_my_thread_var *mysys_var;
1244
1126
      const char *val;
1245
1127
 
1246
 
      if ((!tmp->vio_ok() && !tmp->system_thread))
 
1128
      if (! tmp->protocol->isConnected())
1247
1129
        continue;
1248
1130
 
1249
 
      restore_record(table, s->default_values);
 
1131
      table->restoreRecordAsDefault();
1250
1132
      /* ID */
1251
1133
      table->field[0]->store((int64_t) tmp->thread_id, true);
1252
1134
      /* USER */
1253
 
      val= tmp_sctx->user ? tmp_sctx->user :
1254
 
            (tmp->system_thread ? "system user" : "unauthenticated user");
 
1135
      val= tmp_sctx->user.c_str() ? tmp_sctx->user.c_str() : "unauthenticated user";
1255
1136
      table->field[1]->store(val, strlen(val), cs);
1256
1137
      /* HOST */
1257
 
      table->field[2]->store(tmp_sctx->ip, strlen(tmp_sctx->ip), cs);
 
1138
      table->field[2]->store(tmp_sctx->ip.c_str(), strlen(tmp_sctx->ip.c_str()), cs);
1258
1139
      /* DB */
1259
1140
      if (tmp->db)
1260
1141
      {
1274
1155
      table->field[5]->store((uint32_t)(tmp->start_time ?
1275
1156
                                      now - tmp->start_time : 0), true);
1276
1157
      /* STATE */
1277
 
      val= (char*) (tmp->net.reading_or_writing ?
1278
 
                    (tmp->net.reading_or_writing == 2 ?
1279
 
                     "Writing to net" :
1280
 
                     tmp->command == COM_SLEEP ? NULL :
1281
 
                     "Reading from net") :
 
1158
      val= (char*) (tmp->protocol->isWriting() ?
 
1159
                    "Writing to net" :
 
1160
                    tmp->protocol->isReading() ?
 
1161
                    (tmp->command == COM_SLEEP ?
 
1162
                     NULL : "Reading from net") :
1282
1163
                    tmp->get_proc_info() ? tmp->get_proc_info() :
1283
1164
                    tmp->mysys_var &&
1284
1165
                    tmp->mysys_var->current_cond ?
1292
1173
      if (mysys_var)
1293
1174
        pthread_mutex_unlock(&mysys_var->mutex);
1294
1175
 
1295
 
      /* INFO */
1296
 
      if (tmp->query)
 
1176
      length= strlen(tmp->process_list_info);
 
1177
 
 
1178
      if (length)
1297
1179
      {
1298
 
        table->field[7]->store(tmp->query,
1299
 
                               cmin((uint32_t)PROCESS_LIST_INFO_WIDTH,
1300
 
                                   tmp->query_length), cs);
 
1180
        table->field[7]->store(tmp->process_list_info, length, cs);
1301
1181
        table->field[7]->set_notnull();
1302
1182
      }
1303
1183
 
1317
1197
  Status functions
1318
1198
*****************************************************************************/
1319
1199
 
1320
 
static DYNAMIC_ARRAY all_status_vars;
 
1200
static vector<SHOW_VAR *> all_status_vars;
1321
1201
static bool status_vars_inited= 0;
1322
 
static int show_var_cmp(const void *var1, const void *var2)
 
1202
int show_var_cmp(const void *var1, const void *var2)
1323
1203
{
1324
1204
  return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
1325
1205
}
1326
1206
 
1327
 
/*
1328
 
  deletes all the SHOW_UNDEF elements from the array and calls
1329
 
  delete_dynamic() if it's completely empty.
1330
 
*/
1331
 
static void shrink_var_array(DYNAMIC_ARRAY *array)
 
1207
class show_var_cmp_functor
1332
1208
{
1333
 
  uint32_t a,b;
1334
 
  SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
 
1209
  public:
 
1210
  show_var_cmp_functor() { }
 
1211
  inline bool operator()(const SHOW_VAR *var1, const SHOW_VAR *var2) const
 
1212
  {
 
1213
    int val= strcmp(var1->name, var2->name);
 
1214
    return (val < 0);
 
1215
  }
 
1216
};
1335
1217
 
1336
 
  for (a= b= 0; b < array->elements; b++)
1337
 
    if (all[b].type != SHOW_UNDEF)
1338
 
      all[a++]= all[b];
1339
 
  if (a)
 
1218
class show_var_remove_if
 
1219
{
 
1220
  public:
 
1221
  show_var_remove_if() { }
 
1222
  inline bool operator()(const SHOW_VAR *curr) const
1340
1223
  {
1341
 
    memset(all+a, 0, sizeof(SHOW_VAR)); // writing NULL-element to the end
1342
 
    array->elements= a;
 
1224
    return (curr->type == SHOW_UNDEF);
1343
1225
  }
1344
 
  else // array is completely empty - delete it
1345
 
    delete_dynamic(array);
1346
 
}
 
1226
};
1347
1227
 
1348
1228
/*
1349
1229
  Adds an array of SHOW_VAR entries to the output of SHOW STATUS
1361
1241
    As a special optimization, if add_status_vars() is called before
1362
1242
    init_status_vars(), it assumes "startup mode" - neither concurrent access
1363
1243
    to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
1364
 
 
1365
 
    The last entry of the all_status_vars[] should always be {0,0,SHOW_UNDEF}
1366
1244
*/
1367
1245
int add_status_vars(SHOW_VAR *list)
1368
1246
{
1369
1247
  int res= 0;
1370
1248
  if (status_vars_inited)
1371
1249
    pthread_mutex_lock(&LOCK_status);
1372
 
  if (!all_status_vars.buffer && // array is not allocated yet - do it now
1373
 
      my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20))
1374
 
  {
1375
 
    res= 1;
1376
 
    goto err;
1377
 
  }
1378
1250
  while (list->name)
1379
 
    res|= insert_dynamic(&all_status_vars, (unsigned char*)list++);
1380
 
  res|= insert_dynamic(&all_status_vars, (unsigned char*)list); // appending NULL-element
1381
 
  all_status_vars.elements--; // but next insert_dynamic should overwite it
 
1251
    all_status_vars.insert(all_status_vars.begin(), list++);
1382
1252
  if (status_vars_inited)
1383
 
    sort_dynamic(&all_status_vars, show_var_cmp);
1384
 
err:
 
1253
    sort(all_status_vars.begin(), all_status_vars.end(),
 
1254
         show_var_cmp_functor());
1385
1255
  if (status_vars_inited)
1386
1256
    pthread_mutex_unlock(&LOCK_status);
1387
1257
  return res;
1397
1267
*/
1398
1268
void init_status_vars()
1399
1269
{
1400
 
  status_vars_inited=1;
1401
 
  sort_dynamic(&all_status_vars, show_var_cmp);
 
1270
  status_vars_inited= 1;
 
1271
  sort(all_status_vars.begin(), all_status_vars.end(),
 
1272
       show_var_cmp_functor());
1402
1273
}
1403
1274
 
1404
1275
void reset_status_vars()
1405
1276
{
1406
 
  SHOW_VAR *ptr= (SHOW_VAR*) all_status_vars.buffer;
1407
 
  SHOW_VAR *last= ptr + all_status_vars.elements;
1408
 
  for (; ptr < last; ptr++)
 
1277
  vector<SHOW_VAR *>::iterator p= all_status_vars.begin();
 
1278
  while (p != all_status_vars.end())
1409
1279
  {
1410
1280
    /* Note that SHOW_LONG_NOFLUSH variables are not reset */
1411
 
    if (ptr->type == SHOW_LONG)
1412
 
      *(ulong*) ptr->value= 0;
1413
 
  }  
 
1281
    if ((*p)->type == SHOW_LONG)
 
1282
      (*p)->value= 0;
 
1283
    ++p;
 
1284
  }
1414
1285
}
1415
1286
 
1416
1287
/*
1419
1290
  DESCRIPTION
1420
1291
    This function is not strictly required if all add_to_status/
1421
1292
    remove_status_vars are properly paired, but it's a safety measure that
1422
 
    deletes everything from the all_status_vars[] even if some
 
1293
    deletes everything from the all_status_vars vector even if some
1423
1294
    remove_status_vars were forgotten
1424
1295
*/
1425
1296
void free_status_vars()
1426
1297
{
1427
 
  delete_dynamic(&all_status_vars);
 
1298
  all_status_vars.clear();
1428
1299
}
1429
1300
 
1430
1301
/*
1446
1317
  if (status_vars_inited)
1447
1318
  {
1448
1319
    pthread_mutex_lock(&LOCK_status);
1449
 
    SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
1450
 
    int a= 0, b= all_status_vars.elements, c= (a+b)/2;
 
1320
    SHOW_VAR *all= all_status_vars.front();
 
1321
    int a= 0, b= all_status_vars.size(), c= (a+b)/2;
1451
1322
 
1452
1323
    for (; list->name; list++)
1453
1324
    {
1454
1325
      int res= 0;
1455
 
      for (a= 0, b= all_status_vars.elements; b-a > 1; c= (a+b)/2)
 
1326
      for (a= 0, b= all_status_vars.size(); b-a > 1; c= (a+b)/2)
1456
1327
      {
1457
1328
        res= show_var_cmp(list, all+c);
1458
1329
        if (res < 0)
1465
1336
      if (res == 0)
1466
1337
        all[c].type= SHOW_UNDEF;
1467
1338
    }
1468
 
    shrink_var_array(&all_status_vars);
 
1339
    /* removes all the SHOW_UNDEF elements from the vector */
 
1340
    all_status_vars.erase(std::remove_if(all_status_vars.begin(),
 
1341
                            all_status_vars.end(),show_var_remove_if()),
 
1342
                            all_status_vars.end());
1469
1343
    pthread_mutex_unlock(&LOCK_status);
1470
1344
  }
1471
1345
  else
1472
1346
  {
1473
 
    SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
 
1347
    SHOW_VAR *all= all_status_vars.front();
1474
1348
    uint32_t i;
1475
1349
    for (; list->name; list++)
1476
1350
    {
1477
 
      for (i= 0; i < all_status_vars.elements; i++)
 
1351
      for (i= 0; i < all_status_vars.size(); i++)
1478
1352
      {
1479
1353
        if (show_var_cmp(list, all+i))
1480
1354
          continue;
1482
1356
        break;
1483
1357
      }
1484
1358
    }
1485
 
    shrink_var_array(&all_status_vars);
 
1359
    /* removes all the SHOW_UNDEF elements from the vector */
 
1360
    all_status_vars.erase(std::remove_if(all_status_vars.begin(),
 
1361
                            all_status_vars.end(),show_var_remove_if()),
 
1362
                            all_status_vars.end());
1486
1363
  }
1487
1364
}
1488
1365
 
1499
1376
                              const char *prefix, Table *table,
1500
1377
                              bool ucase_names)
1501
1378
{
1502
 
  MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, long);
 
1379
  MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, int64_t);
1503
1380
  char * const buff= (char *) &buff_data;
1504
1381
  char *prefix_end;
1505
1382
  /* the variable name should not be longer than 64 characters */
1506
1383
  char name_buffer[64];
1507
1384
  int len;
1508
 
  LEX_STRING null_lex_str;
1509
1385
  SHOW_VAR tmp, *var;
1510
1386
 
1511
 
  null_lex_str.str= 0;                          // For sys_var->value_ptr()
1512
 
  null_lex_str.length= 0;
 
1387
  prefix_end= strncpy(name_buffer, prefix, sizeof(name_buffer)-1);
 
1388
  prefix_end+= strlen(prefix);
1513
1389
 
1514
 
  prefix_end=my_stpncpy(name_buffer, prefix, sizeof(name_buffer)-1);
1515
1390
  if (*prefix)
1516
1391
    *prefix_end++= '_';
1517
1392
  len=name_buffer + sizeof(name_buffer) - prefix_end;
1518
1393
 
1519
1394
  for (; variables->name; variables++)
1520
1395
  {
1521
 
    my_stpncpy(prefix_end, variables->name, len);
 
1396
    strncpy(prefix_end, variables->name, len);
1522
1397
    name_buffer[sizeof(name_buffer)-1]=0;       /* Safety */
1523
1398
    if (ucase_names)
1524
1399
      make_upper(name_buffer);
1528
1403
      Repeat as necessary, if new var is again SHOW_FUNC
1529
1404
    */
1530
1405
    for (var=variables; var->type == SHOW_FUNC; var= &tmp)
1531
 
      ((mysql_show_var_func)((st_show_var_func_container *)var->value)->func)(session, &tmp, buff);
 
1406
      ((mysql_show_var_func)((st_show_var_func_container *)var->value)->func)(&tmp, buff);
1532
1407
 
1533
1408
    SHOW_TYPE show_type=var->type;
1534
1409
    if (show_type == SHOW_ARRAY)
1543
1418
      {
1544
1419
        char *value=var->value;
1545
1420
        const char *pos, *end;                  // We assign a lot of const's
1546
 
 
1547
1421
        pthread_mutex_lock(&LOCK_global_system_variables);
1548
1422
 
1549
1423
        if (show_type == SHOW_SYS)
1550
1424
        {
1551
1425
          show_type= ((sys_var*) value)->show_type();
1552
 
          value=     (char*) ((sys_var*) value)->value_ptr(session, value_type,
1553
 
                                                           &null_lex_str);
 
1426
          value= (char*) ((sys_var*) value)->value_ptr(session, value_type,
 
1427
                                                       &null_lex_str);
1554
1428
        }
1555
1429
 
1556
1430
        pos= end= buff;
1570
1444
          value= ((char *) status_var + (ulong) value);
1571
1445
          /* fall through */
1572
1446
        case SHOW_LONG:
1573
 
        case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
1574
1447
          end= int10_to_str(*(long*) value, buff, 10);
1575
1448
          break;
1576
1449
        case SHOW_LONGLONG_STATUS:
1579
1452
        case SHOW_LONGLONG:
1580
1453
          end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1581
1454
          break;
 
1455
        case SHOW_SIZE:
 
1456
          {
 
1457
            stringstream ss (stringstream::in);
 
1458
            ss << *(size_t*) value;
 
1459
 
 
1460
            string str= ss.str();
 
1461
            strncpy(buff, str.c_str(), str.length());
 
1462
            end= buff+ str.length();
 
1463
          }
 
1464
          break;
1582
1465
        case SHOW_HA_ROWS:
1583
1466
          end= int64_t10_to_str((int64_t) *(ha_rows*) value, buff, 10);
1584
1467
          break;
1585
1468
        case SHOW_BOOL:
1586
 
          end= my_stpcpy(buff, *(bool*) value ? "ON" : "OFF");
 
1469
          end+= sprintf(buff,"%s", *(bool*) value ? "ON" : "OFF");
1587
1470
          break;
1588
1471
        case SHOW_MY_BOOL:
1589
 
          end= my_stpcpy(buff, *(bool*) value ? "ON" : "OFF");
 
1472
          end+= sprintf(buff,"%s", *(bool*) value ? "ON" : "OFF");
1590
1473
          break;
1591
1474
        case SHOW_INT:
 
1475
        case SHOW_INT_NOFLUSH: // the difference lies in refresh_status()
1592
1476
          end= int10_to_str((long) *(uint32_t*) value, buff, 10);
1593
1477
          break;
1594
1478
        case SHOW_HAVE:
1595
1479
        {
1596
 
          SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
1597
 
          pos= show_comp_option_name[(int) tmp];
 
1480
          SHOW_COMP_OPTION tmp_option= *(SHOW_COMP_OPTION *)value;
 
1481
          pos= show_comp_option_name[(int) tmp_option];
1598
1482
          end= strchr(pos, '\0');
1599
1483
          break;
1600
1484
        }
1627
1511
          assert(0);
1628
1512
          break;
1629
1513
        }
1630
 
        restore_record(table, s->default_values);
 
1514
        table->restoreRecordAsDefault();
1631
1515
        table->field[0]->store(name_buffer, strlen(name_buffer),
1632
1516
                               system_charset_info);
1633
1517
        table->field[1]->store(pos, (uint32_t) (end - pos), system_charset_info);
1636
1520
        pthread_mutex_unlock(&LOCK_global_system_variables);
1637
1521
 
1638
1522
        if (schema_table_store_record(session, table))
1639
 
          return(true);
 
1523
          return true;
1640
1524
      }
1641
1525
    }
1642
1526
  }
1643
1527
 
1644
 
  return(false);
 
1528
  return false;
1645
1529
}
1646
1530
 
1647
1531
 
1649
1533
 
1650
1534
void calc_sum_of_all_status(STATUS_VAR *to)
1651
1535
{
1652
 
 
1653
1536
  /* Ensure that thread id not killed during loop */
1654
1537
  pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1655
1538
 
1656
 
  I_List_iterator<Session> it(threads);
1657
 
  Session *tmp;
1658
 
  
1659
1539
  /* Get global values as base */
1660
1540
  *to= global_status_var;
1661
 
  
 
1541
 
1662
1542
  /* Add to this status from existing threads */
1663
 
  while ((tmp= it++))
1664
 
    add_to_status(to, &tmp->status_var);
1665
 
  
 
1543
  for( vector<Session*>::iterator it= session_list.begin(); it != session_list.end(); ++it )
 
1544
  {
 
1545
    add_to_status(to, &((*it)->status_var));
 
1546
  }
 
1547
 
1666
1548
  pthread_mutex_unlock(&LOCK_thread_count);
1667
1549
  return;
1668
1550
}
1669
1551
 
1670
1552
 
1671
1553
/* This is only used internally, but we need it here as a forward reference */
1672
 
extern ST_SCHEMA_TABLE schema_tables[];
 
1554
extern InfoSchemaTable schema_tables[];
1673
1555
 
1674
1556
typedef struct st_lookup_field_values
1675
1557
{
1697
1579
  int error;
1698
1580
  if ((error= table->file->ha_write_row(table->record[0])))
1699
1581
  {
1700
 
    TMP_TABLE_PARAM *param= table->pos_in_table_list->schema_table_param;
 
1582
    Tmp_Table_Param *param= table->pos_in_table_list->schema_table_param;
1701
1583
 
1702
 
    if (create_myisam_from_heap(session, table, param->start_recinfo, 
 
1584
    if (create_myisam_from_heap(session, table, param->start_recinfo,
1703
1585
                                &param->recinfo, error, 0))
1704
 
      return 1;
 
1586
      return true;
1705
1587
  }
1706
 
  return 0;
 
1588
  return false;
1707
1589
}
1708
1590
 
1709
1591
 
1710
 
int make_table_list(Session *session, SELECT_LEX *sel,
 
1592
int make_table_list(Session *session, Select_Lex *sel,
1711
1593
                    LEX_STRING *db_name, LEX_STRING *table_name)
1712
1594
{
1713
1595
  Table_ident *table_ident;
1720
1602
 
1721
1603
 
1722
1604
/**
1723
 
  @brief    Get lookup value from the part of 'WHERE' condition 
 
1605
  @brief    Get lookup value from the part of 'WHERE' condition
1724
1606
 
1725
 
  @details This function gets lookup value from 
1726
 
           the part of 'WHERE' condition if it's possible and 
 
1607
  @details This function gets lookup value from
 
1608
           the part of 'WHERE' condition if it's possible and
1727
1609
           fill appropriate lookup_field_vals struct field
1728
1610
           with this value.
1729
1611
 
1730
1612
  @param[in]      session                   thread handler
1731
1613
  @param[in]      item_func             part of WHERE condition
1732
1614
  @param[in]      table                 I_S table
1733
 
  @param[in, out] lookup_field_vals     Struct which holds lookup values 
 
1615
  @param[in, out] lookup_field_vals     Struct which holds lookup values
1734
1616
 
1735
1617
  @return
1736
1618
    0             success
1738
1620
*/
1739
1621
 
1740
1622
bool get_lookup_value(Session *session, Item_func *item_func,
1741
 
                      TableList *table, 
 
1623
                      TableList *table,
1742
1624
                      LOOKUP_FIELD_VALUES *lookup_field_vals)
1743
1625
{
1744
 
  ST_SCHEMA_TABLE *schema_table= table->schema_table;
 
1626
  InfoSchemaTable *schema_table= table->schema_table;
1745
1627
  ST_FIELD_INFO *field_info= schema_table->fields_info;
1746
1628
  const char *field_name1= schema_table->idx_field1 >= 0 ?
1747
1629
    field_info[schema_table->idx_field1].field_name : "";
1804
1686
 
1805
1687
 
1806
1688
/**
1807
 
  @brief    Calculates lookup values from 'WHERE' condition 
 
1689
  @brief    Calculates lookup values from 'WHERE' condition
1808
1690
 
1809
1691
  @details This function calculates lookup value(database name, table name)
1810
 
           from 'WHERE' condition if it's possible and 
 
1692
           from 'WHERE' condition if it's possible and
1811
1693
           fill lookup_field_vals struct fields with these values.
1812
1694
 
1813
1695
  @param[in]      session                   thread handler
1814
1696
  @param[in]      cond                  WHERE condition
1815
1697
  @param[in]      table                 I_S table
1816
 
  @param[in, out] lookup_field_vals     Struct which holds lookup values 
 
1698
  @param[in, out] lookup_field_vals     Struct which holds lookup values
1817
1699
 
1818
1700
  @return
1819
1701
    0             success
1870
1752
  {
1871
1753
    Item_field *item_field= (Item_field*)item;
1872
1754
    const CHARSET_INFO * const cs= system_charset_info;
1873
 
    ST_SCHEMA_TABLE *schema_table= table->schema_table;
 
1755
    InfoSchemaTable *schema_table= table->schema_table;
1874
1756
    ST_FIELD_INFO *field_info= schema_table->fields_info;
1875
1757
    const char *field_name1= schema_table->idx_field1 >= 0 ?
1876
1758
      field_info[schema_table->idx_field1].field_name : "";
1962
1844
  @param[in]      session                   thread handler
1963
1845
  @param[in]      cond                  WHERE condition
1964
1846
  @param[in]      tables                I_S table
1965
 
  @param[in, out] lookup_field_values   Struct which holds lookup values 
 
1847
  @param[in, out] lookup_field_values   Struct which holds lookup values
1966
1848
 
1967
1849
  @return
1968
1850
    0             success
2005
1887
}
2006
1888
 
2007
1889
 
2008
 
enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
 
1890
enum enum_schema_tables get_schema_table_idx(InfoSchemaTable *schema_table)
2009
1891
{
2010
1892
  return (enum enum_schema_tables) (schema_table - &schema_tables[0]);
2011
1893
}
2022
1904
    idx_field_vals        idx_field_vals->db_name contains db name or
2023
1905
                          wild string
2024
1906
    with_i_schema         returns 1 if we added 'IS' name to list
2025
 
                          otherwise returns 0 
 
1907
                          otherwise returns 0
2026
1908
 
2027
1909
  RETURN
2028
1910
    zero                  success
2046
1928
      LIKE clause (see also get_index_field_values() function)
2047
1929
    */
2048
1930
    if (!lookup_field_vals->db_value.str ||
2049
 
        !wild_case_compare(system_charset_info, 
 
1931
        !wild_case_compare(system_charset_info,
2050
1932
                           INFORMATION_SCHEMA_NAME.c_str(),
2051
1933
                           lookup_field_vals->db_value.str))
2052
1934
    {
2090
1972
}
2091
1973
 
2092
1974
 
2093
 
struct st_add_schema_table 
 
1975
struct st_add_schema_table
2094
1976
{
2095
1977
  List<LEX_STRING> *files;
2096
1978
  const char *wild;
2097
1979
};
2098
1980
 
2099
1981
 
2100
 
static bool add_schema_table(Session *session, plugin_ref plugin,
2101
 
                                void* p_data)
 
1982
class AddSchemaTable : public unary_function<InfoSchemaTable *, bool>
2102
1983
{
2103
 
  LEX_STRING *file_name= 0;
2104
 
  st_add_schema_table *data= (st_add_schema_table *)p_data;
2105
 
  List<LEX_STRING> *file_list= data->files;
2106
 
  const char *wild= data->wild;
2107
 
  ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
2108
 
 
2109
 
  if (schema_table->hidden)
2110
 
      return(0);
2111
 
  if (wild)
 
1984
  Session *session;
 
1985
  st_add_schema_table *data;
 
1986
public:
 
1987
  AddSchemaTable(Session *session_arg, st_add_schema_table *data_arg)
 
1988
    : session(session_arg), data(data_arg) {}
 
1989
  result_type operator() (argument_type schema_table)
2112
1990
  {
2113
 
    if (lower_case_table_names)
 
1991
    LEX_STRING *file_name= 0;
 
1992
    List<LEX_STRING> *file_list= data->files;
 
1993
    const char *wild= data->wild;
 
1994
  
 
1995
    if (schema_table->hidden)
 
1996
        return(0);
 
1997
    if (wild)
2114
1998
    {
2115
 
      if (wild_case_compare(files_charset_info,
2116
 
                            schema_table->table_name,
2117
 
                            wild))
 
1999
      if (lower_case_table_names)
 
2000
      {
 
2001
        if (wild_case_compare(files_charset_info,
 
2002
                              schema_table->table_name,
 
2003
                              wild))
 
2004
          return(0);
 
2005
      }
 
2006
      else if (wild_compare(schema_table->table_name, wild, 0))
2118
2007
        return(0);
2119
2008
    }
2120
 
    else if (wild_compare(schema_table->table_name, wild, 0))
 
2009
  
 
2010
    if ((file_name= session->make_lex_string(file_name, schema_table->table_name,
 
2011
                                         strlen(schema_table->table_name),
 
2012
                                         true)) &&
 
2013
        !file_list->push_back(file_name))
2121
2014
      return(0);
 
2015
    return(1);
2122
2016
  }
2123
 
 
2124
 
  if ((file_name= session->make_lex_string(file_name, schema_table->table_name,
2125
 
                                       strlen(schema_table->table_name),
2126
 
                                       true)) &&
2127
 
      !file_list->push_back(file_name))
2128
 
    return(0);
2129
 
  return(1);
2130
 
}
 
2017
};
2131
2018
 
2132
2019
 
2133
2020
int schema_tables_add(Session *session, List<LEX_STRING> *files, const char *wild)
2134
2021
{
2135
2022
  LEX_STRING *file_name= 0;
2136
 
  ST_SCHEMA_TABLE *tmp_schema_table= schema_tables;
 
2023
  InfoSchemaTable *tmp_schema_table= schema_tables;
2137
2024
  st_add_schema_table add_data;
2138
2025
 
2139
2026
  for (; tmp_schema_table->table_name; tmp_schema_table++)
2152
2039
      else if (wild_compare(tmp_schema_table->table_name, wild, 0))
2153
2040
        continue;
2154
2041
    }
2155
 
    if ((file_name= 
 
2042
    if ((file_name=
2156
2043
         session->make_lex_string(file_name, tmp_schema_table->table_name,
2157
2044
                              strlen(tmp_schema_table->table_name), true)) &&
2158
2045
        !files->push_back(file_name))
2162
2049
 
2163
2050
  add_data.files= files;
2164
2051
  add_data.wild= wild;
2165
 
  if (plugin_foreach(session, add_schema_table,
2166
 
                     DRIZZLE_INFORMATION_SCHEMA_PLUGIN, &add_data))
2167
 
    return(1);
2168
 
 
2169
 
  return(0);
 
2052
  vector<InfoSchemaTable *>::iterator iter=
 
2053
    find_if(all_schema_tables.begin(), all_schema_tables.end(),
 
2054
           AddSchemaTable(session, &add_data));
 
2055
  if (iter != all_schema_tables.end())
 
2056
    return 1;
 
2057
  return 0 ;
2170
2058
}
2171
2059
 
2172
2060
 
2201
2089
  {
2202
2090
    if (with_i_schema)
2203
2091
    {
2204
 
      if (find_schema_table(session, lookup_field_vals->table_value.str))
 
2092
      if (find_schema_table(lookup_field_vals->table_value.str))
2205
2093
      {
2206
2094
        if (table_names->push_back(&lookup_field_vals->table_value))
2207
2095
          return 1;
2208
2096
      }
2209
2097
    }
2210
2098
    else
2211
 
    {    
 
2099
    {
2212
2100
      if (table_names->push_back(&lookup_field_vals->table_value))
2213
2101
        return 1;
2214
2102
    }
2262
2150
    @retval       1           error
2263
2151
*/
2264
2152
 
2265
 
static int 
 
2153
static int
2266
2154
fill_schema_show_cols_or_idxs(Session *session, TableList *tables,
2267
 
                              ST_SCHEMA_TABLE *schema_table,
 
2155
                              InfoSchemaTable *schema_table,
2268
2156
                              Open_tables_state *open_tables_state_backup)
2269
2157
{
2270
2158
  LEX *lex= session->lex;
2288
2176
    Let us set fake sql_command so views won't try to merge
2289
2177
    themselves into main statement. If we don't do this,
2290
2178
    SELECT * from information_schema.xxxx will cause problems.
2291
 
    SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()' 
 
2179
    SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
2292
2180
  */
2293
2181
  lex->sql_command= SQLCOM_SHOW_FIELDS;
2294
2182
  res= open_normal_and_derived_tables(session, show_table_list,
2298
2186
    get_all_tables() returns 1 on failure and 0 on success thus
2299
2187
    return only these and not the result code of ::process_table()
2300
2188
 
2301
 
    We should use show_table_list->alias instead of 
 
2189
    We should use show_table_list->alias instead of
2302
2190
    show_table_list->table_name because table_name
2303
2191
    could be changed during opening of I_S tables. It's safe
2304
 
    to use alias because alias contains original table name 
2305
 
    in this case(this part of code is used only for 
 
2192
    to use alias because alias contains original table name
 
2193
    in this case(this part of code is used only for
2306
2194
    'show columns' & 'show statistics' commands).
2307
2195
  */
2308
2196
   table_name= session->make_lex_string(&tmp_lex_string1, show_table_list->alias,
2309
2197
                                    strlen(show_table_list->alias), false);
2310
2198
   db_name= session->make_lex_string(&tmp_lex_string, show_table_list->db,
2311
2199
                                 show_table_list->db_length, false);
2312
 
      
 
2200
 
2313
2201
 
2314
2202
   error= test(schema_table->process_table(session, show_table_list,
2315
2203
                                           table, res, db_name,
2346
2234
  else
2347
2235
  {
2348
2236
    char path[FN_REFLEN];
2349
 
    (void) build_table_filename(path, sizeof(path), db_name->str, 
2350
 
                                table_name->str, reg_ext, 0);
 
2237
    (void) build_table_filename(path, sizeof(path), db_name->str,
 
2238
                                table_name->str, "", 0);
2351
2239
 
2352
2240
      table->field[3]->store(STRING_WITH_LEN("BASE Table"),
2353
2241
                             system_charset_info);
2381
2269
*/
2382
2270
 
2383
2271
static uint32_t get_table_open_method(TableList *tables,
2384
 
                                  ST_SCHEMA_TABLE *schema_table,
2385
 
                                  enum enum_schema_tables)
 
2272
                                      InfoSchemaTable *schema_table,
 
2273
                                      enum enum_schema_tables)
2386
2274
{
2387
2275
  /*
2388
2276
    determine which method will be used for table opening
2393
2281
    int table_open_method= 0, field_indx= 0;
2394
2282
    for (ptr=tables->table->field; (field= *ptr) ; ptr++)
2395
2283
    {
2396
 
      if (bitmap_is_set(tables->table->read_set, field->field_index))
 
2284
      if (field->isReadSet())
2397
2285
        table_open_method|= schema_table->fields_info[field_indx].open_method;
2398
2286
      field_indx++;
2399
2287
    }
2400
2288
    return table_open_method;
2401
2289
  }
2402
2290
  /* I_S tables which use get_all_tables but can not be optimized */
2403
 
  return (uint) OPEN_FULL_TABLE;
 
2291
  return (uint32_t) OPEN_FULL_TABLE;
2404
2292
}
2405
2293
 
2406
2294
 
2422
2310
*/
2423
2311
 
2424
2312
static int fill_schema_table_from_frm(Session *session,TableList *tables,
2425
 
                                      ST_SCHEMA_TABLE *schema_table,
 
2313
                                      InfoSchemaTable *schema_table,
2426
2314
                                      LEX_STRING *db_name,
2427
2315
                                      LEX_STRING *table_name,
2428
2316
                                      enum enum_schema_tables)
2429
2317
{
2430
2318
  Table *table= tables->table;
2431
 
  TABLE_SHARE *share;
 
2319
  TableShare *share;
2432
2320
  Table tbl;
2433
2321
  TableList table_list;
2434
2322
  uint32_t res= 0;
2442
2330
  table_list.table_name= table_name->str;
2443
2331
  table_list.db= db_name->str;
2444
2332
 
2445
 
  key_length= create_table_def_key(session, key, &table_list, 0);
 
2333
  key_length= create_table_def_key(key, &table_list);
2446
2334
  pthread_mutex_lock(&LOCK_open);
2447
2335
  share= get_table_share(session, &table_list, key,
2448
2336
                         key_length, 0, &error);
2492
2380
{
2493
2381
  LEX *lex= session->lex;
2494
2382
  Table *table= tables->table;
2495
 
  SELECT_LEX *old_all_select_lex= lex->all_selects_list;
 
2383
  Select_Lex *old_all_select_lex= lex->all_selects_list;
2496
2384
  enum_sql_command save_sql_command= lex->sql_command;
2497
 
  SELECT_LEX *lsel= tables->schema_select_lex;
2498
 
  ST_SCHEMA_TABLE *schema_table= tables->schema_table;
2499
 
  SELECT_LEX sel;
 
2385
  Select_Lex *lsel= tables->schema_select_lex;
 
2386
  InfoSchemaTable *schema_table= tables->schema_table;
 
2387
  Select_Lex sel;
2500
2388
  LOOKUP_FIELD_VALUES lookup_field_vals;
2501
2389
  LEX_STRING *db_name, *table_name;
2502
2390
  bool with_i_schema;
2504
2392
  List<LEX_STRING> db_names;
2505
2393
  List_iterator_fast<LEX_STRING> it(db_names);
2506
2394
  COND *partial_cond= 0;
2507
 
  uint32_t derived_tables= lex->derived_tables; 
 
2395
  uint32_t derived_tables= lex->derived_tables;
2508
2396
  int error= 1;
2509
2397
  Open_tables_state open_tables_state_backup;
2510
2398
  Query_tables_list query_tables_list_backup;
2511
2399
  uint32_t table_open_method;
2512
2400
  bool old_value= session->no_warnings_for_error;
2513
2401
 
2514
 
  lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
2515
 
 
2516
2402
  /*
2517
2403
    We should not introduce deadlocks even if we already have some
2518
2404
    tables open and locked, since we won't lock tables which we will
2523
2409
  schema_table_idx= get_schema_table_idx(schema_table);
2524
2410
  tables->table_open_method= table_open_method=
2525
2411
    get_table_open_method(tables, schema_table, schema_table_idx);
2526
 
  /* 
 
2412
  /*
2527
2413
    this branch processes SHOW FIELDS, SHOW INDEXES commands.
2528
2414
    see sql_parse.cc, prepare_schema_table() function where
2529
2415
    this values are initialized
2543
2429
 
2544
2430
  if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
2545
2431
  {
2546
 
    /* 
 
2432
    /*
2547
2433
      if lookup value is empty string then
2548
2434
      it's impossible table name or db name
2549
2435
    */
2559
2445
      !lookup_field_vals.wild_db_value)
2560
2446
    tables->has_db_lookup_value= true;
2561
2447
  if (lookup_field_vals.table_value.length &&
2562
 
      !lookup_field_vals.wild_table_value) 
 
2448
      !lookup_field_vals.wild_table_value)
2563
2449
    tables->has_table_lookup_value= true;
2564
2450
 
2565
2451
  if (tables->has_db_lookup_value && tables->has_table_lookup_value)
2593
2479
      List_iterator_fast<LEX_STRING> it_files(table_names);
2594
2480
      while ((table_name= it_files++))
2595
2481
      {
2596
 
        restore_record(table, s->default_values);
 
2482
        table->restoreRecordAsDefault();
2597
2483
        table->field[schema_table->idx_field1]->
2598
2484
          store(db_name->str, db_name->length, system_charset_info);
2599
2485
        table->field[schema_table->idx_field2]->
2603
2489
        {
2604
2490
          /*
2605
2491
            If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN)
2606
 
            we can skip table opening and we don't have lookup value for 
 
2492
            we can skip table opening and we don't have lookup value for
2607
2493
            table name or lookup value is wild string(table name list is
2608
2494
            already created by make_table_name_list() function).
2609
2495
          */
2633
2519
                continue;
2634
2520
            }
2635
2521
 
2636
 
            int res;
2637
2522
            LEX_STRING tmp_lex_string, orig_db_name;
2638
2523
            /*
2639
2524
              Set the parent lex of 'sel' because it is needed by
2643
2528
            sel.parent_lex= lex;
2644
2529
            /* db_name can be changed in make_table_list() func */
2645
2530
            if (!session->make_lex_string(&orig_db_name, db_name->str,
2646
 
                                      db_name->length, false))
 
2531
                                          db_name->length, false))
2647
2532
              goto err;
2648
2533
            if (make_table_list(session, &sel, db_name, table_name))
2649
2534
              goto err;
2657
2542
                                                DRIZZLE_LOCK_IGNORE_FLUSH);
2658
2543
            lex->sql_command= save_sql_command;
2659
2544
            /*
2660
 
              XXX:  show_table_list has a flag i_is_requested,
2661
 
              and when it's set, open_normal_and_derived_tables()
2662
 
              can return an error without setting an error message
2663
 
              in Session, which is a hack. This is why we have to
2664
 
              check for res, then for session->is_error() only then
2665
 
              for session->main_da.sql_errno().
 
2545
XXX:  show_table_list has a flag i_is_requested,
 
2546
and when it's set, open_normal_and_derived_tables()
 
2547
can return an error without setting an error message
 
2548
in Session, which is a hack. This is why we have to
 
2549
check for res, then for session->is_error() only then
 
2550
for session->main_da.sql_errno().
2666
2551
            */
2667
2552
            if (res && session->is_error() &&
2668
2553
                session->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2679
2564
            else
2680
2565
            {
2681
2566
              /*
2682
 
                We should use show_table_list->alias instead of 
 
2567
                We should use show_table_list->alias instead of
2683
2568
                show_table_list->table_name because table_name
2684
2569
                could be changed during opening of I_S tables. It's safe
2685
 
                to use alias because alias contains original table name 
 
2570
                to use alias because alias contains original table name
2686
2571
                in this case.
2687
2572
              */
2688
2573
              session->make_lex_string(&tmp_lex_string, show_table_list->alias,
2689
 
                                   strlen(show_table_list->alias), false);
 
2574
                                       strlen(show_table_list->alias), false);
2690
2575
              res= schema_table->process_table(session, show_table_list, table,
2691
2576
                                               res, &orig_db_name,
2692
2577
                                               &tmp_lex_string);
2709
2594
  error= 0;
2710
2595
err:
2711
2596
  session->restore_backup_open_tables_state(&open_tables_state_backup);
2712
 
  lex->restore_backup_query_tables_list(&query_tables_list_backup);
2713
2597
  lex->derived_tables= derived_tables;
2714
2598
  lex->all_selects_list= old_all_select_lex;
2715
2599
  lex->sql_command= save_sql_command;
2721
2605
bool store_schema_shemata(Session* session, Table *table, LEX_STRING *db_name,
2722
2606
                          const CHARSET_INFO * const cs)
2723
2607
{
2724
 
  restore_record(table, s->default_values);
 
2608
  table->restoreRecordAsDefault();
2725
2609
  table->field[1]->store(db_name->str, db_name->length, system_charset_info);
2726
2610
  table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
2727
2611
  table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
2740
2624
  List<LEX_STRING> db_names;
2741
2625
  LEX_STRING *db_name;
2742
2626
  bool with_i_schema;
2743
 
  HA_CREATE_INFO create;
2744
2627
  Table *table= tables->table;
2745
2628
 
2746
2629
  if (get_lookup_field_values(session, cond, tables, &lookup_field_vals))
2779
2662
      continue;
2780
2663
    }
2781
2664
    {
2782
 
      load_db_opt_by_name(session, db_name->str, &create);
 
2665
      HA_CREATE_INFO create;
 
2666
      load_db_opt_by_name(db_name->str, &create);
 
2667
 
2783
2668
      if (store_schema_shemata(session, table, db_name,
2784
2669
                               create.default_table_charset))
2785
2670
        return(1);
2798
2683
  DRIZZLE_TIME time;
2799
2684
  const CHARSET_INFO * const cs= system_charset_info;
2800
2685
 
2801
 
  restore_record(table, s->default_values);
 
2686
  table->restoreRecordAsDefault();
2802
2687
  table->field[1]->store(db_name->str, db_name->length, cs);
2803
2688
  table->field[2]->store(table_name->str, table_name->length, cs);
2804
2689
  if (res)
2818
2703
  {
2819
2704
    char option_buff[400],*ptr;
2820
2705
    Table *show_table= tables->table;
2821
 
    TABLE_SHARE *share= show_table->s;
 
2706
    TableShare *share= show_table->s;
2822
2707
    handler *file= show_table->file;
2823
 
    handlerton *tmp_db_type= share->db_type();
 
2708
    StorageEngine *tmp_db_type= share->db_type();
2824
2709
    if (share->tmp_table == SYSTEM_TMP_TABLE)
2825
2710
      table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2826
2711
    else if (share->tmp_table)
2834
2719
        continue;
2835
2720
      table->field[i]->set_notnull();
2836
2721
    }
2837
 
    tmp_buff= (char *) ha_resolve_storage_engine_name(tmp_db_type);
2838
 
    table->field[4]->store(tmp_buff, strlen(tmp_buff), cs);
 
2722
    string engine_name= ha_resolve_storage_engine_name(tmp_db_type);
 
2723
    table->field[4]->store(engine_name.c_str(), engine_name.size(), cs);
2839
2724
    table->field[5]->store((int64_t) 0, true);
2840
2725
 
2841
2726
    ptr=option_buff;
2842
2727
    if (share->min_rows)
2843
2728
    {
2844
 
      ptr=my_stpcpy(ptr," min_rows=");
2845
 
      ptr=int64_t10_to_str(share->min_rows,ptr,10);
 
2729
      ptr= strcpy(ptr," min_rows=")+10;
 
2730
      ptr= int64_t10_to_str(share->min_rows,ptr,10);
2846
2731
    }
2847
2732
    if (share->max_rows)
2848
2733
    {
2849
 
      ptr=my_stpcpy(ptr," max_rows=");
2850
 
      ptr=int64_t10_to_str(share->max_rows,ptr,10);
 
2734
      ptr= strcpy(ptr," max_rows=")+10;
 
2735
      ptr= int64_t10_to_str(share->max_rows,ptr,10);
2851
2736
    }
2852
2737
    if (share->avg_row_length)
2853
2738
    {
2854
 
      ptr=my_stpcpy(ptr," avg_row_length=");
2855
 
      ptr=int64_t10_to_str(share->avg_row_length,ptr,10);
 
2739
      ptr= strcpy(ptr," avg_row_length=")+16;
 
2740
      ptr= int64_t10_to_str(share->avg_row_length,ptr,10);
2856
2741
    }
2857
2742
    if (share->db_create_options & HA_OPTION_PACK_KEYS)
2858
 
      ptr=my_stpcpy(ptr," pack_keys=1");
 
2743
      ptr= strcpy(ptr," pack_keys=1")+12;
2859
2744
    if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
2860
 
      ptr=my_stpcpy(ptr," pack_keys=0");
 
2745
      ptr= strcpy(ptr," pack_keys=0")+12;
2861
2746
    /* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
2862
2747
    if (share->db_create_options & HA_OPTION_CHECKSUM)
2863
 
      ptr=my_stpcpy(ptr," checksum=1");
 
2748
      ptr= strcpy(ptr," checksum=1")+11;
2864
2749
    if (share->page_checksum != HA_CHOICE_UNDEF)
2865
 
      ptr= strxmov(ptr, " page_checksum=",
2866
 
                   ha_choice_values[(uint) share->page_checksum], NULL);
 
2750
      ptr+= sprintf(ptr, " page_checksum=%s",
 
2751
                    ha_choice_values[(uint32_t) share->page_checksum]);
2867
2752
    if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
2868
 
      ptr=my_stpcpy(ptr," delay_key_write=1");
 
2753
      ptr= strcpy(ptr," delay_key_write=1")+18;
2869
2754
    if (share->row_type != ROW_TYPE_DEFAULT)
2870
 
      ptr=strxmov(ptr, " row_format=", 
2871
 
                  ha_row_type[(uint) share->row_type],
2872
 
                  NULL);
 
2755
      ptr+= sprintf(ptr, " row_format=%s", ha_row_type[(uint32_t)share->row_type]);
2873
2756
    if (share->block_size)
2874
2757
    {
2875
 
      ptr= my_stpcpy(ptr, " block_size=");
 
2758
      ptr= strcpy(ptr, " block_size=")+12;
2876
2759
      ptr= int64_t10_to_str(share->block_size, ptr, 10);
2877
2760
    }
2878
 
    
2879
 
    if (share->transactional != HA_CHOICE_UNDEF)
2880
 
    {
2881
 
      ptr= strxmov(ptr, " TRANSACTIONAL=",
2882
 
                   (share->transactional == HA_CHOICE_YES ? "1" : "0"),
2883
 
                   NULL);
2884
 
    }
2885
 
    if (share->transactional != HA_CHOICE_UNDEF)
2886
 
      ptr= strxmov(ptr, " transactional=",
2887
 
                   ha_choice_values[(uint) share->transactional], NULL);
 
2761
 
2888
2762
    table->field[19]->store(option_buff+1,
2889
 
                            (ptr == option_buff ? 0 : 
2890
 
                             (uint) (ptr-option_buff)-1), cs);
 
2763
                            (ptr == option_buff ? 0 :
 
2764
                             (uint32_t) (ptr-option_buff)-1), cs);
2891
2765
 
2892
2766
    tmp_buff= (share->table_charset ?
2893
2767
               share->table_charset->name : "default");
2952
2826
      if (file->stats.create_time)
2953
2827
      {
2954
2828
        session->variables.time_zone->gmt_sec_to_TIME(&time,
2955
 
                                                  (my_time_t) file->stats.create_time);
 
2829
                                                  (time_t) file->stats.create_time);
2956
2830
        table->field[14]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2957
2831
        table->field[14]->set_notnull();
2958
2832
      }
2959
2833
      if (file->stats.update_time)
2960
2834
      {
2961
2835
        session->variables.time_zone->gmt_sec_to_TIME(&time,
2962
 
                                                  (my_time_t) file->stats.update_time);
 
2836
                                                  (time_t) file->stats.update_time);
2963
2837
        table->field[15]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2964
2838
        table->field[15]->set_notnull();
2965
2839
      }
2966
2840
      if (file->stats.check_time)
2967
2841
      {
2968
2842
        session->variables.time_zone->gmt_sec_to_TIME(&time,
2969
 
                                                  (my_time_t) file->stats.check_time);
 
2843
                                                  (time_t) file->stats.check_time);
2970
2844
        table->field[16]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2971
2845
        table->field[16]->set_notnull();
2972
2846
      }
2989
2863
  @param[in]      cs                I_S table charset
2990
2864
  @param[in]      offset            offset from beginning of table
2991
2865
                                    to DATE_TYPE column in I_S table
2992
 
                                    
 
2866
 
2993
2867
  @return         void
2994
2868
*/
2995
2869
 
3018
2892
    uint32_t octet_max_length= field->max_display_length();
3019
2893
    if (is_blob && octet_max_length != (uint32_t) 4294967295U)
3020
2894
      octet_max_length /= field->charset()->mbmaxlen;
3021
 
    int64_t char_max_len= is_blob ? 
 
2895
    int64_t char_max_len= is_blob ?
3022
2896
      (int64_t) octet_max_length / field->charset()->mbminlen :
3023
2897
      (int64_t) octet_max_length / field->charset()->mbmaxlen;
3024
2898
    /* CHARACTER_MAXIMUM_LENGTH column*/
3088
2962
  const char *wild= lex->wild ? lex->wild->ptr() : NULL;
3089
2963
  const CHARSET_INFO * const cs= system_charset_info;
3090
2964
  Table *show_table;
3091
 
  TABLE_SHARE *show_table_share;
 
2965
  TableShare *show_table_share;
3092
2966
  Field **ptr, *field, *timestamp_field;
3093
2967
  int count;
3094
2968
 
3099
2973
      /*
3100
2974
        I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
3101
2975
        rather than in SHOW COLUMNS
3102
 
      */ 
 
2976
      */
3103
2977
      if (session->is_error())
3104
2978
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3105
2979
                     session->main_da.sql_errno(), session->main_da.message());
3139
3013
      bitmap_set_all(&show_table->def_read_set);
3140
3014
      show_table->read_set= &show_table->def_read_set;
3141
3015
    }
3142
 
    bitmap_set_all(show_table->read_set);
 
3016
    show_table->setReadSet();
3143
3017
  }
3144
3018
 
3145
3019
  for (; (field= *ptr) ; ptr++)
3159
3033
 
3160
3034
    count++;
3161
3035
    /* Get default row, with all NULL fields set to NULL */
3162
 
    restore_record(table, s->default_values);
 
3036
    table->restoreRecordAsDefault();
3163
3037
 
3164
3038
    table->field[1]->store(db_name->str, db_name->length, cs);
3165
3039
    table->field[2]->store(table_name->str, table_name->length, cs);
3167
3041
                           cs);
3168
3042
    table->field[4]->store((int64_t) count, true);
3169
3043
 
3170
 
    if (get_field_default_value(session, timestamp_field, field, &type, 0))
 
3044
    if (get_field_default_value(timestamp_field, field, &type, 0))
3171
3045
    {
3172
3046
      table->field[5]->store(type.ptr(), type.length(), cs);
3173
3047
      table->field[5]->set_notnull();
3190
3064
        field->unireg_check != Field::TIMESTAMP_DN_FIELD)
3191
3065
      table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
3192
3066
                              cs);
3193
 
    if (field->vcol_info)
3194
 
          table->field[16]->store(STRING_WITH_LEN("VIRTUAL"), cs);
3195
3067
    table->field[18]->store(field->comment.str, field->comment.length, cs);
3196
3068
    {
3197
3069
      enum column_format_type column_format= (enum column_format_type)
3223
3095
  for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
3224
3096
  {
3225
3097
    const CHARSET_INFO * const tmp_cs= cs[0];
3226
 
    if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) && 
 
3098
    if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
3227
3099
        (tmp_cs->state & MY_CS_AVAILABLE) &&
3228
3100
        !(tmp_cs->state & MY_CS_HIDDEN) &&
3229
3101
        !(wild && wild[0] &&
3230
3102
          wild_case_compare(scs, tmp_cs->csname,wild)))
3231
3103
    {
3232
3104
      const char *comment;
3233
 
      restore_record(table, s->default_values);
 
3105
      table->restoreRecordAsDefault();
3234
3106
      table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs);
3235
3107
      table->field[1]->store(tmp_cs->name, strlen(tmp_cs->name), scs);
3236
3108
      comment= tmp_cs->comment ? tmp_cs->comment : "";
3261
3133
    for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3262
3134
    {
3263
3135
      const CHARSET_INFO *tmp_cl= cl[0];
3264
 
      if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) || 
 
3136
      if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3265
3137
          !my_charset_same(tmp_cs, tmp_cl))
3266
3138
        continue;
3267
3139
      if (!(wild && wild[0] &&
3268
3140
          wild_case_compare(scs, tmp_cl->name,wild)))
3269
3141
      {
3270
3142
        const char *tmp_buff;
3271
 
        restore_record(table, s->default_values);
 
3143
        table->restoreRecordAsDefault();
3272
3144
        table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3273
3145
        table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3274
3146
        table->field[2]->store((int64_t) tmp_cl->number, true);
3295
3167
  {
3296
3168
    CHARSET_INFO **cl;
3297
3169
    const CHARSET_INFO *tmp_cs= cs[0];
3298
 
    if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) || 
 
3170
    if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3299
3171
        !(tmp_cs->state & MY_CS_PRIMARY))
3300
3172
      continue;
3301
3173
    for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3302
3174
    {
3303
3175
      const CHARSET_INFO *tmp_cl= cl[0];
3304
 
      if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) || 
 
3176
      if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3305
3177
          !my_charset_same(tmp_cs,tmp_cl))
3306
3178
        continue;
3307
 
      restore_record(table, s->default_values);
 
3179
      table->restoreRecordAsDefault();
3308
3180
      table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3309
3181
      table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3310
3182
      if (schema_table_store_record(session, table))
3351
3223
      const char *str;
3352
3224
      for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
3353
3225
      {
3354
 
        restore_record(table, s->default_values);
 
3226
        table->restoreRecordAsDefault();
3355
3227
        table->field[1]->store(db_name->str, db_name->length, cs);
3356
3228
        table->field[2]->store(table_name->str, table_name->length, cs);
3357
3229
        table->field[3]->store((int64_t) ((key_info->flags &
3393
3265
        uint32_t flags= key_part->field ? key_part->field->flags : 0;
3394
3266
        const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
3395
3267
        table->field[12]->store(pos, strlen(pos), cs);
3396
 
        if (!show_table->s->keys_in_use.is_set(i))
 
3268
        if (!show_table->s->keys_in_use.test(i))
3397
3269
          table->field[14]->store(STRING_WITH_LEN("disabled"), cs);
3398
3270
        else
3399
3271
          table->field[14]->store("", 0, cs);
3400
3272
        table->field[14]->set_notnull();
3401
 
        assert(test(key_info->flags & HA_USES_COMMENT) == 
 
3273
        assert(test(key_info->flags & HA_USES_COMMENT) ==
3402
3274
                   (key_info->comment.length > 0));
3403
3275
        if (key_info->flags & HA_USES_COMMENT)
3404
 
          table->field[15]->store(key_info->comment.str, 
 
3276
          table->field[15]->store(key_info->comment.str,
3405
3277
                                  key_info->comment.length, cs);
3406
3278
        if (schema_table_store_record(session, table))
3407
3279
          return(1);
3417
3289
                       uint32_t key_len, const char *con_type, uint32_t con_len)
3418
3290
{
3419
3291
  const CHARSET_INFO * const cs= system_charset_info;
3420
 
  restore_record(table, s->default_values);
 
3292
  table->restoreRecordAsDefault();
3421
3293
  table->field[1]->store(db_name->str, db_name->length, cs);
3422
3294
  table->field[2]->store(key_name, key_len, cs);
3423
3295
  table->field[3]->store(db_name->str, db_name->length, cs);
3446
3318
    Table *show_table= tables->table;
3447
3319
    KEY *key_info=show_table->key_info;
3448
3320
    uint32_t primary_key= show_table->s->primary_key;
3449
 
    show_table->file->info(HA_STATUS_VARIABLE | 
 
3321
    show_table->file->info(HA_STATUS_VARIABLE |
3450
3322
                           HA_STATUS_NO_LOCK |
3451
3323
                           HA_STATUS_TIME);
3452
3324
    for (uint32_t i=0 ; i < show_table->s->keys ; i++, key_info++)
3475
3347
    List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3476
3348
    while ((f_key_info=it++))
3477
3349
    {
3478
 
      if (store_constraints(session, table, db_name, table_name, 
 
3350
      if (store_constraints(session, table, db_name, table_name,
3479
3351
                            f_key_info->forein_id->str,
3480
3352
                            strlen(f_key_info->forein_id->str),
3481
3353
                            "FOREIGN KEY", 11))
3521
3393
    Table *show_table= tables->table;
3522
3394
    KEY *key_info=show_table->key_info;
3523
3395
    uint32_t primary_key= show_table->s->primary_key;
3524
 
    show_table->file->info(HA_STATUS_VARIABLE | 
 
3396
    show_table->file->info(HA_STATUS_VARIABLE |
3525
3397
                           HA_STATUS_NO_LOCK |
3526
3398
                           HA_STATUS_TIME);
3527
3399
    for (uint32_t i=0 ; i < show_table->s->keys ; i++, key_info++)
3535
3407
        if (key_part->field)
3536
3408
        {
3537
3409
          f_idx++;
3538
 
          restore_record(table, s->default_values);
 
3410
          table->restoreRecordAsDefault();
3539
3411
          store_key_column_usage(table, db_name, table_name,
3540
3412
                                 key_info->name,
3541
 
                                 strlen(key_info->name), 
3542
 
                                 key_part->field->field_name, 
 
3413
                                 strlen(key_info->name),
 
3414
                                 key_part->field->field_name,
3543
3415
                                 strlen(key_part->field->field_name),
3544
3416
                                 (int64_t) f_idx);
3545
3417
          if (schema_table_store_record(session, table))
3562
3434
      {
3563
3435
        r_info= it1++;
3564
3436
        f_idx++;
3565
 
        restore_record(table, s->default_values);
 
3437
        table->restoreRecordAsDefault();
3566
3438
        store_key_column_usage(table, db_name, table_name,
3567
3439
                               f_key_info->forein_id->str,
3568
3440
                               f_key_info->forein_id->length,
3575
3447
                               system_charset_info);
3576
3448
        table->field[9]->set_notnull();
3577
3449
        table->field[10]->store(f_key_info->referenced_table->str,
3578
 
                                f_key_info->referenced_table->length, 
 
3450
                                f_key_info->referenced_table->length,
3579
3451
                                system_charset_info);
3580
3452
        table->field[10]->set_notnull();
3581
3453
        table->field[11]->store(r_info->str, r_info->length,
3596
3468
  Table *table= tables->table;
3597
3469
  const CHARSET_INFO * const cs= system_charset_info;
3598
3470
  OPEN_TableList *open_list;
3599
 
  if (!(open_list=list_open_tables(session,session->lex->select_lex.db, wild))
 
3471
  if (!(open_list=list_open_tables(session->lex->select_lex.db, wild))
3600
3472
            && session->is_fatal_error)
3601
3473
    return(1);
3602
3474
 
3603
3475
  for (; open_list ; open_list=open_list->next)
3604
3476
  {
3605
 
    restore_record(table, s->default_values);
 
3477
    table->restoreRecordAsDefault();
3606
3478
    table->field[0]->store(open_list->db, strlen(open_list->db), cs);
3607
3479
    table->field[1]->store(open_list->table, strlen(open_list->table), cs);
3608
3480
    table->field[2]->store((int64_t) open_list->in_use, true);
3629
3501
      schema_table_idx == SCH_GLOBAL_VARIABLES)
3630
3502
    option_type= OPT_GLOBAL;
3631
3503
 
3632
 
  rw_rdlock(&LOCK_system_variables_hash);
 
3504
  pthread_rwlock_rdlock(&LOCK_system_variables_hash);
3633
3505
  res= show_status_array(session, wild, enumerate_sys_vars(session, sorted_vars),
3634
3506
                         option_type, NULL, "", tables->table, upper_case_names);
3635
 
  rw_unlock(&LOCK_system_variables_hash);
 
3507
  pthread_rwlock_unlock(&LOCK_system_variables_hash);
3636
3508
  return(res);
3637
3509
}
3638
3510
 
3662
3534
    tmp1= &tmp;
3663
3535
  }
3664
3536
  else
3665
 
  { 
 
3537
  {
3666
3538
    option_type= OPT_SESSION;
3667
3539
    tmp1= &session->status_var;
3668
3540
  }
3671
3543
  if (option_type == OPT_GLOBAL)
3672
3544
    calc_sum_of_all_status(&tmp);
3673
3545
  res= show_status_array(session, wild,
3674
 
                         (SHOW_VAR *)all_status_vars.buffer,
 
3546
                         (SHOW_VAR *) all_status_vars.front(),
3675
3547
                         option_type, tmp1, "", tables->table,
3676
3548
                         upper_case_names);
3677
3549
  pthread_mutex_unlock(&LOCK_status);
3716
3588
  {
3717
3589
    List<FOREIGN_KEY_INFO> f_key_list;
3718
3590
    Table *show_table= tables->table;
3719
 
    show_table->file->info(HA_STATUS_VARIABLE | 
 
3591
    show_table->file->info(HA_STATUS_VARIABLE |
3720
3592
                           HA_STATUS_NO_LOCK |
3721
3593
                           HA_STATUS_TIME);
3722
3594
 
3725
3597
    List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3726
3598
    while ((f_key_info= it++))
3727
3599
    {
3728
 
      restore_record(table, s->default_values);
 
3600
      table->restoreRecordAsDefault();
3729
3601
      table->field[1]->store(db_name->str, db_name->length, cs);
3730
3602
      table->field[9]->store(table_name->str, table_name->length, cs);
3731
3603
      table->field[2]->store(f_key_info->forein_id->str,
3732
3604
                             f_key_info->forein_id->length, cs);
3733
 
      table->field[4]->store(f_key_info->referenced_db->str, 
 
3605
      table->field[4]->store(f_key_info->referenced_db->str,
3734
3606
                             f_key_info->referenced_db->length, cs);
3735
 
      table->field[10]->store(f_key_info->referenced_table->str, 
 
3607
      table->field[10]->store(f_key_info->referenced_table->str,
3736
3608
                             f_key_info->referenced_table->length, cs);
3737
3609
      if (f_key_info->referenced_key_name)
3738
3610
      {
3739
 
        table->field[5]->store(f_key_info->referenced_key_name->str, 
 
3611
        table->field[5]->store(f_key_info->referenced_key_name->str,
3740
3612
                               f_key_info->referenced_key_name->length, cs);
3741
3613
        table->field[5]->set_notnull();
3742
3614
      }
3743
3615
      else
3744
3616
        table->field[5]->set_null();
3745
3617
      table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
3746
 
      table->field[7]->store(f_key_info->update_method->str, 
 
3618
      table->field[7]->store(f_key_info->update_method->str,
3747
3619
                             f_key_info->update_method->length, cs);
3748
 
      table->field[8]->store(f_key_info->delete_method->str, 
 
3620
      table->field[8]->store(f_key_info->delete_method->str,
3749
3621
                             f_key_info->delete_method->length, cs);
3750
3622
      if (schema_table_store_record(session, table))
3751
3623
        return(1);
3755
3627
}
3756
3628
 
3757
3629
 
3758
 
struct schema_table_ref 
 
3630
class FindSchemaTableByName : public unary_function<InfoSchemaTable *, bool>
3759
3631
{
3760
3632
  const char *table_name;
3761
 
  ST_SCHEMA_TABLE *schema_table;
 
3633
public:
 
3634
  FindSchemaTableByName(const char *table_name_arg)
 
3635
    : table_name(table_name_arg) {}
 
3636
  result_type operator() (argument_type schema_table)
 
3637
  {
 
3638
    return !my_strcasecmp(system_charset_info,
 
3639
                          schema_table->table_name,
 
3640
                          table_name);
 
3641
  }
3762
3642
};
3763
3643
 
3764
3644
 
3766
3646
  Find schema_tables elment by name
3767
3647
 
3768
3648
  SYNOPSIS
3769
 
    find_schema_table_in_plugin()
3770
 
    session                 thread handler
3771
 
    plugin              plugin
3772
 
    table_name          table name
3773
 
 
3774
 
  RETURN
3775
 
    0   table not found
3776
 
    1   found the schema table
3777
 
*/
3778
 
static bool find_schema_table_in_plugin(Session *, plugin_ref plugin,
3779
 
                                        void* p_table)
3780
 
{
3781
 
  schema_table_ref *p_schema_table= (schema_table_ref *)p_table;
3782
 
  const char* table_name= p_schema_table->table_name;
3783
 
  ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
3784
 
 
3785
 
  if (!my_strcasecmp(system_charset_info,
3786
 
                     schema_table->table_name,
3787
 
                     table_name)) {
3788
 
    p_schema_table->schema_table= schema_table;
3789
 
    return(1);
3790
 
  }
3791
 
 
3792
 
  return(0);
3793
 
}
3794
 
 
3795
 
 
3796
 
/*
3797
 
  Find schema_tables elment by name
3798
 
 
3799
 
  SYNOPSIS
3800
3649
    find_schema_table()
3801
 
    session                 thread handler
3802
3650
    table_name          table name
3803
3651
 
3804
3652
  RETURN
3806
3654
    #   pointer to 'schema_tables' element
3807
3655
*/
3808
3656
 
3809
 
ST_SCHEMA_TABLE *find_schema_table(Session *session, const char* table_name)
 
3657
InfoSchemaTable *find_schema_table(const char* table_name)
3810
3658
{
3811
 
  schema_table_ref schema_table_a;
3812
 
  ST_SCHEMA_TABLE *schema_table= schema_tables;
 
3659
  InfoSchemaTable *schema_table= schema_tables;
3813
3660
 
3814
3661
  for (; schema_table->table_name; schema_table++)
3815
3662
  {
3819
3666
      return(schema_table);
3820
3667
  }
3821
3668
 
3822
 
  schema_table_a.table_name= table_name;
3823
 
  if (plugin_foreach(session, find_schema_table_in_plugin, 
3824
 
                     DRIZZLE_INFORMATION_SCHEMA_PLUGIN, &schema_table_a))
3825
 
    return(schema_table_a.schema_table);
3826
 
 
3827
 
  return(NULL);
 
3669
  vector<InfoSchemaTable *>::iterator iter= 
 
3670
    find_if(all_schema_tables.begin(), all_schema_tables.end(),
 
3671
            FindSchemaTableByName(table_name));
 
3672
  if (iter != all_schema_tables.end())
 
3673
    return *iter;
 
3674
  return NULL;
3828
3675
}
3829
3676
 
3830
3677
 
3831
 
ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
 
3678
InfoSchemaTable *get_schema_table(enum enum_schema_tables schema_table_idx)
3832
3679
{
3833
3680
  return &schema_tables[schema_table_idx];
3834
3681
}
3855
3702
  Item *item;
3856
3703
  Table *table;
3857
3704
  List<Item> field_list;
3858
 
  ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
 
3705
  InfoSchemaTable *schema_table= table_list->schema_table;
3859
3706
  ST_FIELD_INFO *fields_info= schema_table->fields_info;
3860
3707
  const CHARSET_INFO * const cs= system_charset_info;
3861
3708
 
3874
3721
      item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3875
3722
      break;
3876
3723
    case DRIZZLE_TYPE_DATE:
3877
 
    case DRIZZLE_TYPE_TIME:
3878
3724
    case DRIZZLE_TYPE_TIMESTAMP:
3879
3725
    case DRIZZLE_TYPE_DATETIME:
3880
3726
      if (!(item=new Item_return_date_time(fields_info->field_name,
3884
3730
      }
3885
3731
      break;
3886
3732
    case DRIZZLE_TYPE_DOUBLE:
3887
 
      if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC, 
 
3733
      if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
3888
3734
                           fields_info->field_length)) == NULL)
3889
 
        return(NULL);
 
3735
        return NULL;
3890
3736
      break;
3891
3737
    case DRIZZLE_TYPE_NEWDECIMAL:
3892
3738
      if (!(item= new Item_decimal((int64_t) fields_info->value, false)))
3923
3769
    item->maybe_null= (fields_info->field_flags & MY_I_S_MAYBE_NULL);
3924
3770
    field_count++;
3925
3771
  }
3926
 
  TMP_TABLE_PARAM *tmp_table_param =
3927
 
    (TMP_TABLE_PARAM*) (session->alloc(sizeof(TMP_TABLE_PARAM)));
 
3772
  Tmp_Table_Param *tmp_table_param =
 
3773
    (Tmp_Table_Param*) (session->alloc(sizeof(Tmp_Table_Param)));
3928
3774
  tmp_table_param->init();
3929
3775
  tmp_table_param->table_charset= cs;
3930
3776
  tmp_table_param->field_count= field_count;
3931
3777
  tmp_table_param->schema_table= 1;
3932
 
  SELECT_LEX *select_lex= session->lex->current_select;
 
3778
  Select_Lex *select_lex= session->lex->current_select;
3933
3779
  if (!(table= create_tmp_table(session, tmp_table_param,
3934
 
                                field_list, (order_st*) 0, 0, 0, 
 
3780
                                field_list, (order_st*) 0, 0, 0,
3935
3781
                                (select_lex->options | session->options |
3936
3782
                                 TMP_TABLE_ALL_COLUMNS),
3937
3783
                                HA_POS_ERROR, table_list->alias)))
3962
3808
   0    success
3963
3809
*/
3964
3810
 
3965
 
int make_old_format(Session *session, ST_SCHEMA_TABLE *schema_table)
 
3811
int make_old_format(Session *session, InfoSchemaTable *schema_table)
3966
3812
{
3967
3813
  ST_FIELD_INFO *field_info= schema_table->fields_info;
3968
3814
  Name_resolution_context *context= &session->lex->select_lex.context;
3977
3823
        field->set_name(field_info->old_name,
3978
3824
                        strlen(field_info->old_name),
3979
3825
                        system_charset_info);
3980
 
        if (add_item_to_list(session, field))
 
3826
        if (session->add_item_to_list(field))
3981
3827
          return 1;
3982
3828
      }
3983
3829
    }
3986
3832
}
3987
3833
 
3988
3834
 
3989
 
int make_schemata_old_format(Session *session, ST_SCHEMA_TABLE *schema_table)
 
3835
int make_schemata_old_format(Session *session, InfoSchemaTable *schema_table)
3990
3836
{
3991
3837
  char tmp[128];
3992
3838
  LEX *lex= session->lex;
3993
 
  SELECT_LEX *sel= lex->current_select;
 
3839
  Select_Lex *sel= lex->current_select;
3994
3840
  Name_resolution_context *context= &sel->context;
3995
3841
 
3996
3842
  if (!sel->item_list.elements)
3999
3845
    String buffer(tmp,sizeof(tmp), system_charset_info);
4000
3846
    Item_field *field= new Item_field(context,
4001
3847
                                      NULL, NULL, field_info->field_name);
4002
 
    if (!field || add_item_to_list(session, field))
 
3848
    if (!field || session->add_item_to_list(field))
4003
3849
      return 1;
4004
3850
    buffer.length(0);
4005
3851
    buffer.append(field_info->old_name);
4015
3861
}
4016
3862
 
4017
3863
 
4018
 
int make_table_names_old_format(Session *session, ST_SCHEMA_TABLE *schema_table)
 
3864
int make_table_names_old_format(Session *session, InfoSchemaTable *schema_table)
4019
3865
{
4020
3866
  char tmp[128];
4021
3867
  String buffer(tmp,sizeof(tmp), session->charset());
4034
3880
  }
4035
3881
  Item_field *field= new Item_field(context,
4036
3882
                                    NULL, NULL, field_info->field_name);
4037
 
  if (add_item_to_list(session, field))
 
3883
  if (session->add_item_to_list(field))
4038
3884
    return 1;
4039
3885
  field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4040
3886
  if (session->lex->verbose)
4042
3888
    field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4043
3889
    field_info= &schema_table->fields_info[3];
4044
3890
    field= new Item_field(context, NULL, NULL, field_info->field_name);
4045
 
    if (add_item_to_list(session, field))
 
3891
    if (session->add_item_to_list(field))
4046
3892
      return 1;
4047
3893
    field->set_name(field_info->old_name, strlen(field_info->old_name),
4048
3894
                    system_charset_info);
4051
3897
}
4052
3898
 
4053
3899
 
4054
 
int make_columns_old_format(Session *session, ST_SCHEMA_TABLE *schema_table)
 
3900
int make_columns_old_format(Session *session, InfoSchemaTable *schema_table)
4055
3901
{
4056
3902
  int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1};
4057
3903
  int *field_num= fields_arr;
4072
3918
      field->set_name(field_info->old_name,
4073
3919
                      strlen(field_info->old_name),
4074
3920
                      system_charset_info);
4075
 
      if (add_item_to_list(session, field))
 
3921
      if (session->add_item_to_list(field))
4076
3922
        return 1;
4077
3923
    }
4078
3924
  }
4080
3926
}
4081
3927
 
4082
3928
 
4083
 
int make_character_sets_old_format(Session *session, ST_SCHEMA_TABLE *schema_table)
 
3929
int make_character_sets_old_format(Session *session, InfoSchemaTable *schema_table)
4084
3930
{
4085
3931
  int fields_arr[]= {0, 2, 1, 3, -1};
4086
3932
  int *field_num= fields_arr;
4097
3943
      field->set_name(field_info->old_name,
4098
3944
                      strlen(field_info->old_name),
4099
3945
                      system_charset_info);
4100
 
      if (add_item_to_list(session, field))
 
3946
      if (session->add_item_to_list(field))
4101
3947
        return 1;
4102
3948
    }
4103
3949
  }
4119
3965
    1   error
4120
3966
*/
4121
3967
 
4122
 
int mysql_schema_table(Session *session, LEX *lex, TableList *table_list)
 
3968
int mysql_schema_table(Session *session, LEX *, TableList *table_list)
4123
3969
{
4124
3970
  Table *table;
4125
3971
  if (!(table= table_list->schema_table->create_table(session, table_list)))
4143
3989
  session->derived_tables= table;
4144
3990
  table_list->select_lex->options |= OPTION_SCHEMA_TABLE;
4145
3991
 
4146
 
  if (table_list->schema_table_reformed) // show command
4147
 
  {
4148
 
    SELECT_LEX *sel= lex->current_select;
4149
 
    Item *item;
4150
 
    Field_translator *transl, *org_transl;
4151
 
 
4152
 
    if (table_list->field_translation)
4153
 
    {
4154
 
      Field_translator *end= table_list->field_translation_end;
4155
 
      for (transl= table_list->field_translation; transl < end; transl++)
4156
 
      {
4157
 
        if (!transl->item->fixed &&
4158
 
            transl->item->fix_fields(session, &transl->item))
4159
 
          return(1);
4160
 
      }
4161
 
      return(0);
4162
 
    }
4163
 
    List_iterator_fast<Item> it(sel->item_list);
4164
 
    if (!(transl=
4165
 
          (Field_translator*)(session->alloc(sel->item_list.elements *
4166
 
                                    sizeof(Field_translator)))))
4167
 
    {
4168
 
      return(1);
4169
 
    }
4170
 
    for (org_transl= transl; (item= it++); transl++)
4171
 
    {
4172
 
      transl->item= item;
4173
 
      transl->name= item->name;
4174
 
      if (!item->fixed && item->fix_fields(session, &transl->item))
4175
 
      {
4176
 
        return(1);
4177
 
      }
4178
 
    }
4179
 
    table_list->field_translation= org_transl;
4180
 
    table_list->field_translation_end= transl;
4181
 
  }
4182
 
 
4183
3992
  return(0);
4184
3993
}
4185
3994
 
4190
3999
  SYNOPSIS
4191
4000
    make_schema_select()
4192
4001
    session                  thread handler
4193
 
    sel                  pointer to SELECT_LEX
 
4002
    sel                  pointer to Select_Lex
4194
4003
    schema_table_idx     index of 'schema_tables' element
4195
4004
 
4196
4005
  RETURN
4198
4007
    1   error
4199
4008
*/
4200
4009
 
4201
 
int make_schema_select(Session *session, SELECT_LEX *sel,
 
4010
int make_schema_select(Session *session, Select_Lex *sel,
4202
4011
                       enum enum_schema_tables schema_table_idx)
4203
4012
{
4204
 
  ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx);
 
4013
  InfoSchemaTable *schema_table= get_schema_table(schema_table_idx);
4205
4014
  LEX_STRING db, table;
4206
4015
  /*
4207
4016
     We have to make non const db_name & table_name
4333
4142
  {"ROW_FORMAT", 10, DRIZZLE_TYPE_VARCHAR, 0, 1, "Row_format", OPEN_FULL_TABLE},
4334
4143
  {"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4335
4144
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", OPEN_FULL_TABLE},
4336
 
  {"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 
 
4145
  {"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4337
4146
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", OPEN_FULL_TABLE},
4338
 
  {"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 
 
4147
  {"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4339
4148
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE},
4340
4149
  {"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4341
4150
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", OPEN_FULL_TABLE},
4342
 
  {"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 
 
4151
  {"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4343
4152
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE},
4344
4153
  {"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4345
4154
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", OPEN_FULL_TABLE},
4346
 
  {"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG, 0, 
 
4155
  {"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG, 0,
4347
4156
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE},
4348
4157
  {"CREATE_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE},
4349
4158
  {"UPDATE_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE},
4542
4351
 
4543
4352
ST_FIELD_INFO plugin_fields_info[]=
4544
4353
{
4545
 
  {"PLUGIN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Name", 
 
4354
  {"PLUGIN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Name",
4546
4355
   SKIP_OPEN_TABLE},
4547
4356
  {"PLUGIN_VERSION", 20, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4548
4357
  {"PLUGIN_STATUS", 10, DRIZZLE_TYPE_VARCHAR, 0, 0, "Status", SKIP_OPEN_TABLE},
4549
 
  {"PLUGIN_TYPE", 80, DRIZZLE_TYPE_VARCHAR, 0, 0, "Type", SKIP_OPEN_TABLE},
4550
 
  {"PLUGIN_LIBRARY", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Library",
4551
 
   SKIP_OPEN_TABLE},
4552
4358
  {"PLUGIN_AUTHOR", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4553
4359
  {"PLUGIN_DESCRIPTION", 65535, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4554
4360
  {"PLUGIN_LICENSE", 80, DRIZZLE_TYPE_VARCHAR, 0, 1, "License", SKIP_OPEN_TABLE},
4585
4391
 
4586
4392
*/
4587
4393
 
4588
 
ST_SCHEMA_TABLE schema_tables[]=
 
4394
InfoSchemaTable schema_tables[]=
4589
4395
{
4590
 
  {"CHARACTER_SETS", charsets_fields_info, create_schema_table, 
 
4396
  {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
4591
4397
   fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
4592
 
  {"COLLATIONS", collation_fields_info, create_schema_table, 
 
4398
  {"COLLATIONS", collation_fields_info, create_schema_table,
4593
4399
   fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
4594
4400
  {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
4595
4401
   create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0},
4596
 
  {"COLUMNS", columns_fields_info, create_schema_table, 
 
4402
  {"COLUMNS", columns_fields_info, create_schema_table,
4597
4403
   get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0,
4598
4404
   OPTIMIZE_I_S_TABLE},
4599
4405
  {"GLOBAL_STATUS", variables_fields_info, create_schema_table,
4618
4424
   fill_status, make_old_format, 0, -1, -1, 0, 0},
4619
4425
  {"SESSION_VARIABLES", variables_fields_info, create_schema_table,
4620
4426
   fill_variables, make_old_format, 0, -1, -1, 0, 0},
4621
 
  {"STATISTICS", stat_fields_info, create_schema_table, 
 
4427
  {"STATISTICS", stat_fields_info, create_schema_table,
4622
4428
   get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
4623
4429
   OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
4624
 
  {"STATUS", variables_fields_info, create_schema_table, fill_status, 
 
4430
  {"STATUS", variables_fields_info, create_schema_table, fill_status,
4625
4431
   make_old_format, 0, -1, -1, 1, 0},
4626
 
  {"TABLES", tables_fields_info, create_schema_table, 
 
4432
  {"TABLES", tables_fields_info, create_schema_table,
4627
4433
   get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
4628
4434
   OPTIMIZE_I_S_TABLE},
4629
4435
  {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
4635
4441
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
4636
4442
};
4637
4443
 
4638
 
 
4639
 
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
4640
 
template class List_iterator_fast<char>;
4641
 
template class List<char>;
4642
 
#endif
4643
 
 
4644
 
int initialize_schema_table(st_plugin_int *plugin)
4645
 
{
4646
 
  ST_SCHEMA_TABLE *schema_table;
4647
 
 
4648
 
  if (!(schema_table= (ST_SCHEMA_TABLE *)my_malloc(sizeof(ST_SCHEMA_TABLE),
4649
 
                                MYF(MY_WME | MY_ZEROFILL))))
4650
 
      return(1);
4651
 
  /* Historical Requirement */
4652
 
  plugin->data= schema_table; // shortcut for the future
4653
 
  if (plugin->plugin->init)
4654
 
  {
4655
 
    schema_table->create_table= create_schema_table;
4656
 
    schema_table->old_format= make_old_format;
4657
 
    schema_table->idx_field1= -1, 
4658
 
    schema_table->idx_field2= -1; 
4659
 
 
4660
 
    /* Make the name available to the init() function. */
4661
 
    schema_table->table_name= plugin->name.str;
4662
 
 
4663
 
    if (plugin->plugin->init(schema_table))
4664
 
    {
4665
 
      sql_print_error(_("Plugin '%s' init function returned error."),
4666
 
                      plugin->name.str);
4667
 
      goto err;
4668
 
    }
4669
 
    
4670
 
    /* Make sure the plugin name is not set inside the init() function. */
4671
 
    schema_table->table_name= plugin->name.str;
4672
 
  }
4673
 
 
4674
 
  return(0);
4675
 
err:
4676
 
  free(schema_table);
4677
 
  return(1);
4678
 
}
4679
 
 
4680
 
int finalize_schema_table(st_plugin_int *plugin)
4681
 
{
4682
 
  ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
4683
 
 
4684
 
  if (schema_table && plugin->plugin->deinit)
4685
 
    free(schema_table);
4686
 
 
4687
 
  return(0);
4688
 
}