~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2004 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
17
/* Function with list databases, tables or fields */
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
18
#include <drizzled/server_includes.h>
19
#include <drizzled/sql_select.h>
20
#include <drizzled/sql_show.h>
1 by brian
clean slate
21
#include "repl_failsafe.h"
212.5.38 by Monty Taylor
Moved my_dir (and removed references to a lot of places)
22
#include <mysys/my_dir.h>
340 by Monty Taylor
Got everything using sql_print_*.
23
#include <libdrizzle/gettext.h>
1 by brian
clean slate
24
322.2.2 by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter.
25
inline const char *
26
str_or_nil(const char *str)
27
{
28
  return str ? str : "<nil>";
29
}
1 by brian
clean slate
30
31
/* Match the values of enum ha_choice */
32
static const char *ha_choice_values[] = {"", "0", "1"};
33
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
34
static void store_key_options(THD *thd, String *packet, Table *table,
1 by brian
clean slate
35
                              KEY *key_info);
36
37
38
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
39
int wild_case_compare(const CHARSET_INFO * const cs, const char *str,const char *wildstr)
1 by brian
clean slate
40
{
41
  register int flag;
42
  while (*wildstr)
43
  {
44
    while (*wildstr && *wildstr != wild_many && *wildstr != wild_one)
45
    {
46
      if (*wildstr == wild_prefix && wildstr[1])
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
47
        wildstr++;
48
      if (my_toupper(cs, *wildstr++) != my_toupper(cs, *str++))
49
        return(1);
1 by brian
clean slate
50
    }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
51
    if (! *wildstr )
52
      return (*str != 0);
1 by brian
clean slate
53
    if (*wildstr++ == wild_one)
54
    {
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
55
      if (! *str++)
56
        return (1);	/* One char; skip */
1 by brian
clean slate
57
    }
58
    else
59
    {						/* Found '*' */
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
60
      if (!*wildstr)
61
        return(0);		/* '*' as last char: OK */
1 by brian
clean slate
62
      flag=(*wildstr != wild_many && *wildstr != wild_one);
63
      do
64
      {
65
	if (flag)
66
	{
67
	  char cmp;
68
	  if ((cmp= *wildstr) == wild_prefix && wildstr[1])
69
	    cmp=wildstr[1];
70
	  cmp=my_toupper(cs, cmp);
71
	  while (*str && my_toupper(cs, *str) != cmp)
72
	    str++;
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
73
    if (!*str)
74
      return (1);
1 by brian
clean slate
75
	}
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
76
  if (wild_case_compare(cs, str,wildstr) == 0)
77
      return (0);
1 by brian
clean slate
78
      } while (*str++);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
79
      return(1);
1 by brian
clean slate
80
    }
81
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
82
  return (*str != '\0');
1 by brian
clean slate
83
}
84
85
/***************************************************************************
86
** List all table types supported
87
***************************************************************************/
88
149 by Brian Aker
More bool conversion.
89
static bool show_plugins(THD *thd, plugin_ref plugin,
1 by brian
clean slate
90
                            void *arg)
91
{
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
92
  Table *table= (Table*) arg;
1 by brian
clean slate
93
  struct st_mysql_plugin *plug= plugin_decl(plugin);
94
  struct st_plugin_dl *plugin_dl= plugin_dlib(plugin);
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
95
  const CHARSET_INFO * const cs= system_charset_info;
1 by brian
clean slate
96
97
  restore_record(table, s->default_values);
98
99
  table->field[0]->store(plugin_name(plugin)->str,
100
                         plugin_name(plugin)->length, cs);
101
177.4.3 by mark
ripped out more plugin ABI and API version checking, and plugin versions are now strings
102
  if (plug->version)
103
  {
104
    table->field[1]->store(plug->version, strlen(plug->version), cs);
105
    table->field[1]->set_notnull();
106
  }
107
  else
108
    table->field[1]->set_null();
1 by brian
clean slate
109
110
  switch (plugin_state(plugin)) {
111
  /* case PLUGIN_IS_FREED: does not happen */
112
  case PLUGIN_IS_DELETED:
113
    table->field[2]->store(STRING_WITH_LEN("DELETED"), cs);
114
    break;
115
  case PLUGIN_IS_UNINITIALIZED:
116
    table->field[2]->store(STRING_WITH_LEN("INACTIVE"), cs);
117
    break;
118
  case PLUGIN_IS_READY:
119
    table->field[2]->store(STRING_WITH_LEN("ACTIVE"), cs);
120
    break;
121
  default:
51.1.75 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
122
    assert(0);
1 by brian
clean slate
123
  }
124
125
  table->field[3]->store(plugin_type_names[plug->type].str,
126
                         plugin_type_names[plug->type].length,
127
                         cs);
128
129
  if (plugin_dl)
130
  {
177.4.4 by mark
remove now unused columns from SHOW PLUGINS
131
    table->field[4]->store(plugin_dl->dl.str, plugin_dl->dl.length, cs);
132
    table->field[4]->set_notnull();
133
  }
134
  else
135
  {
136
    table->field[4]->set_null();
137
  }
138
139
  if (plug->author)
140
  {
141
    table->field[5]->store(plug->author, strlen(plug->author), cs);
1 by brian
clean slate
142
    table->field[5]->set_notnull();
143
  }
144
  else
145
    table->field[5]->set_null();
146
147
  if (plug->descr)
148
  {
177.4.4 by mark
remove now unused columns from SHOW PLUGINS
149
    table->field[6]->store(plug->descr, strlen(plug->descr), cs);
150
    table->field[6]->set_notnull();
1 by brian
clean slate
151
  }
152
  else
177.4.4 by mark
remove now unused columns from SHOW PLUGINS
153
    table->field[6]->set_null();
1 by brian
clean slate
154
155
  switch (plug->license) {
156
  case PLUGIN_LICENSE_GPL:
177.4.4 by mark
remove now unused columns from SHOW PLUGINS
157
    table->field[7]->store(PLUGIN_LICENSE_GPL_STRING, 
1 by brian
clean slate
158
                           strlen(PLUGIN_LICENSE_GPL_STRING), cs);
159
    break;
160
  case PLUGIN_LICENSE_BSD:
177.4.4 by mark
remove now unused columns from SHOW PLUGINS
161
    table->field[7]->store(PLUGIN_LICENSE_BSD_STRING, 
1 by brian
clean slate
162
                           strlen(PLUGIN_LICENSE_BSD_STRING), cs);
163
    break;
164
  default:
177.4.4 by mark
remove now unused columns from SHOW PLUGINS
165
    table->field[7]->store(PLUGIN_LICENSE_PROPRIETARY_STRING, 
1 by brian
clean slate
166
                           strlen(PLUGIN_LICENSE_PROPRIETARY_STRING), cs);
167
    break;
168
  }
177.4.4 by mark
remove now unused columns from SHOW PLUGINS
169
  table->field[7]->set_notnull();
1 by brian
clean slate
170
171
  return schema_table_store_record(thd, table);
172
}
173
174
327.2.4 by Brian Aker
Refactoring table.h
175
int fill_plugins(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
1 by brian
clean slate
176
{
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
177
  Table *table= tables->table;
1 by brian
clean slate
178
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
179
  if (plugin_foreach_with_mask(thd, show_plugins, DRIZZLE_ANY_PLUGIN,
1 by brian
clean slate
180
                               ~PLUGIN_IS_FREED, table))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
181
    return(1);
1 by brian
clean slate
182
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
183
  return(0);
1 by brian
clean slate
184
}
185
186
187
/*
188
  find_files() - find files in a given directory.
189
190
  SYNOPSIS
191
    find_files()
192
    thd                 thread handler
193
    files               put found files in this list
327.2.4 by Brian Aker
Refactoring table.h
194
    db                  database name to set in TableList structure
1 by brian
clean slate
195
    path                path to database
196
    wild                filter for found files
163 by Brian Aker
Merge Monty's code.
197
    dir                 read databases in path if true, read .frm files in
1 by brian
clean slate
198
                        database otherwise
199
200
  RETURN
201
    FIND_FILES_OK       success
202
    FIND_FILES_OOM      out of memory error
203
    FIND_FILES_DIR      no such directory, or directory can't be read
204
*/
205
206
207
find_files_result
208
find_files(THD *thd, List<LEX_STRING> *files, const char *db,
209
           const char *path, const char *wild, bool dir)
210
{
211
  uint i;
212
  char *ext;
213
  MY_DIR *dirp;
214
  FILEINFO *file;
215
  LEX_STRING *file_name= 0;
216
  uint file_name_len;
327.2.4 by Brian Aker
Refactoring table.h
217
  TableList table_list;
1 by brian
clean slate
218
219
  if (wild && !wild[0])
220
    wild=0;
221
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
222
  memset(&table_list, 0, sizeof(table_list));
1 by brian
clean slate
223
224
  if (!(dirp = my_dir(path,MYF(dir ? MY_WANT_STAT : 0))))
225
  {
226
    if (my_errno == ENOENT)
227
      my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db);
228
    else
229
      my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
230
    return(FIND_FILES_DIR);
1 by brian
clean slate
231
  }
232
233
  for (i=0 ; i < (uint) dirp->number_off_files  ; i++)
234
  {
235
    char uname[NAME_LEN + 1];                   /* Unencoded name */
236
    file=dirp->dir_entry+i;
237
    if (dir)
238
    {                                           /* Return databases */
239
      if ((file->name[0] == '.' && 
240
          ((file->name[1] == '.' && file->name[2] == '\0') ||
241
            file->name[1] == '\0')))
242
        continue;                               /* . or .. */
243
#ifdef USE_SYMDIR
244
      char *ext;
245
      char buff[FN_REFLEN];
246
      if (my_use_symdir && !strcmp(ext=fn_ext(file->name), ".sym"))
247
      {
248
	/* Only show the sym file if it points to a directory */
249
	char *end;
250
        *ext=0;                                 /* Remove extension */
251
	unpack_dirname(buff, file->name);
376 by Brian Aker
strend remove
252
	end= strchr(buff, '\0');
1 by brian
clean slate
253
	if (end != buff && end[-1] == FN_LIBCHAR)
254
	  end[-1]= 0;				// Remove end FN_LIBCHAR
15 by brian
Fix for stat, NETWARE removal
255
        if (stat(buff, file->mystat))
1 by brian
clean slate
256
               continue;
257
       }
258
#endif
212.5.37 by Monty Taylor
Removed my_stat.
259
      if (!S_ISDIR(file->mystat->st_mode))
1 by brian
clean slate
260
        continue;
261
262
      file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
263
      if (wild && wild_compare(uname, wild, 0))
264
        continue;
265
      if (!(file_name= 
163 by Brian Aker
Merge Monty's code.
266
            thd->make_lex_string(file_name, uname, file_name_len, true)))
1 by brian
clean slate
267
      {
268
        my_dirend(dirp);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
269
        return(FIND_FILES_OOM);
1 by brian
clean slate
270
      }
271
    }
272
    else
273
    {
274
        // Return only .frm files which aren't temp files.
275
      if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),reg_ext) ||
276
          is_prefix(file->name, tmp_file_prefix))
277
        continue;
278
      *ext=0;
279
      file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
280
      if (wild)
281
      {
282
	if (lower_case_table_names)
283
	{
284
	  if (wild_case_compare(files_charset_info, uname, wild))
285
	    continue;
286
	}
287
	else if (wild_compare(uname, wild, 0))
288
	  continue;
289
      }
290
    }
291
    if (!(file_name= 
163 by Brian Aker
Merge Monty's code.
292
          thd->make_lex_string(file_name, uname, file_name_len, true)) ||
1 by brian
clean slate
293
        files->push_back(file_name))
294
    {
295
      my_dirend(dirp);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
296
      return(FIND_FILES_OOM);
1 by brian
clean slate
297
    }
298
  }
299
  my_dirend(dirp);
300
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
301
  return(FIND_FILES_OK);
1 by brian
clean slate
302
}
303
304
305
bool
327.2.4 by Brian Aker
Refactoring table.h
306
mysqld_show_create(THD *thd, TableList *table_list)
1 by brian
clean slate
307
{
308
  Protocol *protocol= thd->protocol;
309
  char buff[2048];
310
  String buffer(buff, sizeof(buff), system_charset_info);
311
312
  /* Only one table for now, but VIEW can involve several tables */
313
  if (open_normal_and_derived_tables(thd, table_list, 0))
314
  {
315
    if (thd->is_error() && thd->main_da.sql_errno() != ER_VIEW_INVALID)
163 by Brian Aker
Merge Monty's code.
316
      return(true);
1 by brian
clean slate
317
318
    /*
319
      Clear all messages with 'error' level status and
320
      issue a warning with 'warning' level status in 
321
      case of invalid view and last error is ER_VIEW_INVALID
322
    */
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
323
    drizzle_reset_errors(thd, true);
1 by brian
clean slate
324
    thd->clear_error();
325
  }
326
327
  buffer.length(0);
328
329
  if (store_create_info(thd, table_list, &buffer, NULL))
163 by Brian Aker
Merge Monty's code.
330
    return(true);
1 by brian
clean slate
331
332
  List<Item> field_list;
333
  {
334
    field_list.push_back(new Item_empty_string("Table",NAME_CHAR_LEN));
335
    // 1024 is for not to confuse old clients
336
    field_list.push_back(new Item_empty_string("Create Table",
398.1.4 by Monty Taylor
Renamed max/min.
337
                                               cmax(buffer.length(),(uint32_t)1024)));
1 by brian
clean slate
338
  }
339
340
  if (protocol->send_fields(&field_list,
341
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
163 by Brian Aker
Merge Monty's code.
342
    return(true);
1 by brian
clean slate
343
  protocol->prepare_for_resend();
344
  {
345
    if (table_list->schema_table)
346
      protocol->store(table_list->schema_table->table_name,
347
                      system_charset_info);
348
    else
349
      protocol->store(table_list->table->alias, system_charset_info);
350
  }
351
352
  protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
353
354
  if (protocol->write())
163 by Brian Aker
Merge Monty's code.
355
    return(true);
1 by brian
clean slate
356
357
  my_eof(thd);
163 by Brian Aker
Merge Monty's code.
358
  return(false);
1 by brian
clean slate
359
}
360
361
bool mysqld_show_create_db(THD *thd, char *dbname,
362
                           HA_CREATE_INFO *create_info)
363
{
364
  char buff[2048];
365
  String buffer(buff, sizeof(buff), system_charset_info);
366
  Protocol *protocol=thd->protocol;
367
368
  if (store_db_create_info(thd, dbname, &buffer, create_info))
369
  {
370
    /* 
371
      This assumes that the only reason for which store_db_create_info()
372
      can fail is incorrect database name (which is the case now).
373
    */
374
    my_error(ER_BAD_DB_ERROR, MYF(0), dbname);
163 by Brian Aker
Merge Monty's code.
375
    return(true);    
1 by brian
clean slate
376
  }
377
378
  List<Item> field_list;
379
  field_list.push_back(new Item_empty_string("Database",NAME_CHAR_LEN));
380
  field_list.push_back(new Item_empty_string("Create Database",1024));
381
382
  if (protocol->send_fields(&field_list,
383
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
163 by Brian Aker
Merge Monty's code.
384
    return(true);
1 by brian
clean slate
385
386
  protocol->prepare_for_resend();
387
  protocol->store(dbname, strlen(dbname), system_charset_info);
388
  protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
389
390
  if (protocol->write())
163 by Brian Aker
Merge Monty's code.
391
    return(true);
1 by brian
clean slate
392
  my_eof(thd);
163 by Brian Aker
Merge Monty's code.
393
  return(false);
1 by brian
clean slate
394
}
395
396
397
398
/****************************************************************************
399
  Return only fields for API mysql_list_fields
400
  Use "show table wildcard" in mysql instead of this
401
****************************************************************************/
402
403
void
327.2.4 by Brian Aker
Refactoring table.h
404
mysqld_list_fields(THD *thd, TableList *table_list, const char *wild)
1 by brian
clean slate
405
{
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
406
  Table *table;
1 by brian
clean slate
407
408
  if (open_normal_and_derived_tables(thd, table_list, 0))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
409
    return;
1 by brian
clean slate
410
  table= table_list->table;
411
412
  List<Item> field_list;
413
414
  Field **ptr,*field;
415
  for (ptr=table->field ; (field= *ptr); ptr++)
416
  {
417
    if (!wild || !wild[0] || 
418
        !wild_case_compare(system_charset_info, field->field_name,wild))
419
    {
420
      field_list.push_back(new Item_field(field));
421
    }
422
  }
423
  restore_record(table, s->default_values);              // Get empty record
424
  table->use_all_columns();
425
  if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
426
    return;
1 by brian
clean slate
427
  my_eof(thd);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
428
  return;
1 by brian
clean slate
429
}
430
431
432
/*
433
  Go through all character combinations and ensure that sql_lex.cc can
434
  parse it as an identifier.
435
436
  SYNOPSIS
437
  require_quotes()
438
  name			attribute name
439
  name_length		length of name
440
441
  RETURN
442
    #	Pointer to conflicting character
443
    0	No conflicting character
444
*/
445
446
static const char *require_quotes(const char *name, uint name_length)
447
{
448
  uint length;
163 by Brian Aker
Merge Monty's code.
449
  bool pure_digit= true;
1 by brian
clean slate
450
  const char *end= name + name_length;
451
452
  for (; name < end ; name++)
453
  {
454
    uchar chr= (uchar) *name;
455
    length= my_mbcharlen(system_charset_info, chr);
456
    if (length == 1 && !system_charset_info->ident_map[chr])
457
      return name;
458
    if (length == 1 && (chr < '0' || chr > '9'))
163 by Brian Aker
Merge Monty's code.
459
      pure_digit= false;
1 by brian
clean slate
460
  }
461
  if (pure_digit)
462
    return name;
463
  return 0;
464
}
465
466
467
/*
468
  Quote the given identifier if needed and append it to the target string.
469
  If the given identifier is empty, it will be quoted.
470
471
  SYNOPSIS
472
  append_identifier()
473
  thd                   thread handler
474
  packet                target string
475
  name                  the identifier to be appended
476
  name_length           length of the appending identifier
477
*/
478
479
void
480
append_identifier(THD *thd, String *packet, const char *name, uint length)
481
{
482
  const char *name_end;
483
  char quote_char;
484
  int q= get_quote_char_for_identifier(thd, name, length);
485
486
  if (q == EOF)
487
  {
488
    packet->append(name, length, packet->charset());
489
    return;
490
  }
491
492
  /*
493
    The identifier must be quoted as it includes a quote character or
494
   it's a keyword
495
  */
496
398.1.6 by Monty Taylor
Removed __alpha__ references.
497
  packet->reserve(length*2 + 2);
1 by brian
clean slate
498
  quote_char= (char) q;
499
  packet->append(&quote_char, 1, system_charset_info);
500
501
  for (name_end= name+length ; name < name_end ; name+= length)
502
  {
503
    uchar chr= (uchar) *name;
504
    length= my_mbcharlen(system_charset_info, chr);
505
    /*
506
      my_mbcharlen can return 0 on a wrong multibyte
507
      sequence. It is possible when upgrading from 4.0,
508
      and identifier contains some accented characters.
509
      The manual says it does not work. So we'll just
510
      change length to 1 not to hang in the endless loop.
511
    */
512
    if (!length)
513
      length= 1;
514
    if (length == 1 && chr == (uchar) quote_char)
515
      packet->append(&quote_char, 1, system_charset_info);
516
    packet->append(name, length, system_charset_info);
517
  }
518
  packet->append(&quote_char, 1, system_charset_info);
519
}
520
521
522
/*
523
  Get the quote character for displaying an identifier.
524
525
  SYNOPSIS
526
    get_quote_char_for_identifier()
527
    thd		Thread handler
528
    name	name to quote
529
    length	length of name
530
531
  IMPLEMENTATION
532
    Force quoting in the following cases:
533
      - name is empty (for one, it is possible when we use this function for
534
        quoting user and host names for DEFINER clause);
535
      - name is a keyword;
536
      - name includes a special character;
537
    Otherwise identifier is quoted only if the option OPTION_QUOTE_SHOW_CREATE
538
    is set.
539
540
  RETURN
541
    EOF	  No quote character is needed
542
    #	  Quote character
543
*/
544
545
int get_quote_char_for_identifier(THD *thd, const char *name, uint length)
546
{
547
  if (length &&
548
      !is_keyword(name,length) &&
549
      !require_quotes(name, length) &&
550
      !(thd->options & OPTION_QUOTE_SHOW_CREATE))
551
    return EOF;
352.2.1 by Harrison Fisk
Fix for bugs 259843 and 256482
552
  return '`';
1 by brian
clean slate
553
}
554
555
556
/* Append directory name (if exists) to CREATE INFO */
557
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
558
static void append_directory(THD *thd __attribute__((unused)),
77.1.46 by Monty Taylor
Finished the warnings work!
559
                             String *packet, const char *dir_type,
1 by brian
clean slate
560
			     const char *filename)
561
{
562
  if (filename)
563
  {
564
    uint length= dirname_length(filename);
565
    packet->append(' ');
566
    packet->append(dir_type);
567
    packet->append(STRING_WITH_LEN(" DIRECTORY='"));
568
    packet->append(filename, length);
569
    packet->append('\'');
570
  }
571
}
572
573
574
#define LIST_PROCESS_HOST_LEN 64
575
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
576
static bool get_field_default_value(THD *thd __attribute__((unused)),
77.1.46 by Monty Taylor
Finished the warnings work!
577
                                    Field *timestamp_field,
1 by brian
clean slate
578
                                    Field *field, String *def_value,
579
                                    bool quoted)
580
{
581
  bool has_default;
582
  bool has_now_default;
583
584
  /* 
585
     We are using CURRENT_TIMESTAMP instead of NOW because it is
586
     more standard
587
  */
588
  has_now_default= (timestamp_field == field &&
589
                    field->unireg_check != Field::TIMESTAMP_UN_FIELD);
590
    
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
591
  has_default= (field->type() != DRIZZLE_TYPE_BLOB &&
1 by brian
clean slate
592
                !(field->flags & NO_DEFAULT_VALUE_FLAG) &&
593
                field->unireg_check != Field::NEXT_NUMBER
594
                  && has_now_default);
595
596
  def_value->length(0);
597
  if (has_default)
598
  {
599
    if (has_now_default)
600
      def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
601
    else if (!field->is_null())
602
    {                                             // Not null by default
603
      char tmp[MAX_FIELD_WIDTH];
604
      String type(tmp, sizeof(tmp), field->charset());
605
      field->val_str(&type);
606
      if (type.length())
607
      {
608
        String def_val;
609
        uint dummy_errors;
610
        /* convert to system_charset_info == utf8 */
611
        def_val.copy(type.ptr(), type.length(), field->charset(),
612
                     system_charset_info, &dummy_errors);
613
        if (quoted)
614
          append_unescaped(def_value, def_val.ptr(), def_val.length());
615
        else
616
          def_value->append(def_val.ptr(), def_val.length());
617
      }
618
      else if (quoted)
619
        def_value->append(STRING_WITH_LEN("''"));
620
    }
621
    else if (field->maybe_null() && quoted)
622
      def_value->append(STRING_WITH_LEN("NULL"));    // Null as default
623
    else
624
      return 0;
625
626
  }
627
  return has_default;
628
}
629
630
/*
631
  Build a CREATE TABLE statement for a table.
632
633
  SYNOPSIS
634
    store_create_info()
635
    thd               The thread
636
    table_list        A list containing one table to write statement
637
                      for.
638
    packet            Pointer to a string where statement will be
639
                      written.
640
    create_info_arg   Pointer to create information that can be used
641
                      to tailor the format of the statement.  Can be
642
                      NULL, in which case only SQL_MODE is considered
643
                      when building the statement.
644
  
645
  NOTE
646
    Currently always return 0, but might return error code in the
647
    future.
648
    
649
  RETURN
650
    0       OK
651
 */
652
327.2.4 by Brian Aker
Refactoring table.h
653
int store_create_info(THD *thd, TableList *table_list, String *packet,
1 by brian
clean slate
654
                      HA_CREATE_INFO *create_info_arg)
655
{
656
  List<Item> field_list;
657
  char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], def_value_buf[MAX_FIELD_WIDTH];
658
  const char *alias;
659
  String type(tmp, sizeof(tmp), system_charset_info);
660
  String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
661
  Field **ptr,*field;
662
  uint primary_key;
663
  KEY *key_info;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
664
  Table *table= table_list->table;
1 by brian
clean slate
665
  handler *file= table->file;
666
  TABLE_SHARE *share= table->s;
667
  HA_CREATE_INFO create_info;
163 by Brian Aker
Merge Monty's code.
668
  bool show_table_options= false;
1 by brian
clean slate
669
  my_bitmap_map *old_map;
670
671
  restore_record(table, s->default_values); // Get empty record
672
673
  if (share->tmp_table)
674
    packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
675
  else
676
    packet->append(STRING_WITH_LEN("CREATE TABLE "));
677
  if (create_info_arg &&
678
      (create_info_arg->options & HA_LEX_CREATE_IF_NOT_EXISTS))
679
    packet->append(STRING_WITH_LEN("IF NOT EXISTS "));
680
  if (table_list->schema_table)
681
    alias= table_list->schema_table->table_name;
682
  else
683
  {
684
    if (lower_case_table_names == 2)
685
      alias= table->alias;
686
    else
687
    {
688
      alias= share->table_name.str;
689
    }
690
  }
691
  append_identifier(thd, packet, alias, strlen(alias));
692
  packet->append(STRING_WITH_LEN(" (\n"));
693
  /*
694
    We need this to get default values from the table
695
    We have to restore the read_set if we are called from insert in case
696
    of row based replication.
697
  */
354 by Brian Aker
Refactor of Table methods.
698
  old_map= table->use_all_columns(table->read_set);
1 by brian
clean slate
699
700
  for (ptr=table->field ; (field= *ptr); ptr++)
701
  {
702
    uint flags = field->flags;
703
704
    if (ptr != table->field)
705
      packet->append(STRING_WITH_LEN(",\n"));
706
707
    packet->append(STRING_WITH_LEN("  "));
708
    append_identifier(thd,packet,field->field_name, strlen(field->field_name));
709
    packet->append(' ');
710
    // check for surprises from the previous call to Field::sql_type()
711
    if (type.ptr() != tmp)
712
      type.set(tmp, sizeof(tmp), system_charset_info);
713
    else
714
      type.set_charset(system_charset_info);
715
716
    field->sql_type(type);
717
    packet->append(type.ptr(), type.length(), system_charset_info);
718
719
    if (field->has_charset())
720
    {
721
      if (field->charset() != share->table_charset)
722
      {
723
	packet->append(STRING_WITH_LEN(" CHARACTER SET "));
724
	packet->append(field->charset()->csname);
725
      }
726
      /* 
727
	For string types dump collation name only if 
728
	collation is not primary for the given charset
729
      */
730
      if (!(field->charset()->state & MY_CS_PRIMARY))
731
      {
732
	packet->append(STRING_WITH_LEN(" COLLATE "));
733
	packet->append(field->charset()->name);
734
      }
735
    }
736
737
    if (flags & NOT_NULL_FLAG)
738
      packet->append(STRING_WITH_LEN(" NOT NULL"));
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
739
    else if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
1 by brian
clean slate
740
    {
741
      /*
742
        TIMESTAMP field require explicit NULL flag, because unlike
743
        all other fields they are treated as NOT NULL by default.
744
      */
745
      packet->append(STRING_WITH_LEN(" NULL"));
746
    }
747
    {
748
      /*
749
        Add field flags about FIELD FORMAT (FIXED or DYNAMIC)
750
        and about STORAGE (DISK or MEMORY).
751
      */
752
      enum column_format_type column_format= (enum column_format_type)
753
        ((flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
754
      if (column_format)
755
      {
756
        packet->append(STRING_WITH_LEN(" /*!"));
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
757
        packet->append(STRING_WITH_LEN(DRIZZLE_VERSION_TABLESPACE_IN_FRM_STR));
1 by brian
clean slate
758
        packet->append(STRING_WITH_LEN(" COLUMN_FORMAT"));
759
        if (column_format == COLUMN_FORMAT_TYPE_FIXED)
760
          packet->append(STRING_WITH_LEN(" FIXED */"));
761
        else
762
          packet->append(STRING_WITH_LEN(" DYNAMIC */"));
763
      }
764
    }
765
    if (get_field_default_value(thd, table->timestamp_field,
766
                                field, &def_value, 1))
767
    {
768
      packet->append(STRING_WITH_LEN(" DEFAULT "));
769
      packet->append(def_value.ptr(), def_value.length(), system_charset_info);
770
    }
771
772
    if (table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_DN_FIELD)
773
      packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
774
775
    if (field->unireg_check == Field::NEXT_NUMBER)
776
      packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
777
778
    if (field->comment.length)
779
    {
780
      packet->append(STRING_WITH_LEN(" COMMENT "));
781
      append_unescaped(packet, field->comment.str, field->comment.length);
782
    }
783
  }
784
785
  key_info= table->key_info;
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
786
  memset(&create_info, 0, sizeof(create_info));
1 by brian
clean slate
787
  /* Allow update_create_info to update row type */
788
  create_info.row_type= share->row_type;
789
  file->update_create_info(&create_info);
790
  primary_key= share->primary_key;
791
792
  for (uint i=0 ; i < share->keys ; i++,key_info++)
793
  {
794
    KEY_PART_INFO *key_part= key_info->key_part;
795
    bool found_primary=0;
796
    packet->append(STRING_WITH_LEN(",\n  "));
797
798
    if (i == primary_key && !strcmp(key_info->name, primary_key_name))
799
    {
800
      found_primary=1;
801
      /*
802
        No space at end, because a space will be added after where the
803
        identifier would go, but that is not added for primary key.
804
      */
805
      packet->append(STRING_WITH_LEN("PRIMARY KEY"));
806
    }
807
    else if (key_info->flags & HA_NOSAME)
808
      packet->append(STRING_WITH_LEN("UNIQUE KEY "));
809
    else
810
      packet->append(STRING_WITH_LEN("KEY "));
811
812
    if (!found_primary)
813
     append_identifier(thd, packet, key_info->name, strlen(key_info->name));
814
815
    packet->append(STRING_WITH_LEN(" ("));
816
817
    for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
818
    {
819
      if (j)
820
        packet->append(',');
821
822
      if (key_part->field)
823
        append_identifier(thd,packet,key_part->field->field_name,
824
			  strlen(key_part->field->field_name));
825
      if (key_part->field &&
826
          (key_part->length !=
827
           table->field[key_part->fieldnr-1]->key_length()))
828
      {
829
        char *end;
830
        buff[0] = '(';
831
        end= int10_to_str((long) key_part->length /
832
                          key_part->field->charset()->mbmaxlen,
833
                          buff + 1,10);
834
        *end++ = ')';
835
        packet->append(buff,(uint) (end-buff));
836
      }
837
    }
838
    packet->append(')');
839
    store_key_options(thd, packet, table, key_info);
840
  }
841
842
  /*
843
    Get possible foreign key definitions stored in InnoDB and append them
844
    to the CREATE TABLE statement
845
  */
846
847
  if ((for_str= file->get_foreign_key_create_info()))
848
  {
849
    packet->append(for_str, strlen(for_str));
850
    file->free_foreign_key_create_info(for_str);
851
  }
852
853
  packet->append(STRING_WITH_LEN("\n)"));
854
  {
163 by Brian Aker
Merge Monty's code.
855
    show_table_options= true;
1 by brian
clean slate
856
    /*
857
      Get possible table space definitions and append them
858
      to the CREATE TABLE statement
859
    */
860
861
    /*
862
      IF   check_create_info
863
      THEN add ENGINE only if it was used when creating the table
864
    */
865
    if (!create_info_arg ||
866
        (create_info_arg->used_fields & HA_CREATE_USED_ENGINE))
867
    {
868
      packet->append(STRING_WITH_LEN(" ENGINE="));
869
      packet->append(file->table_type());
870
    }
871
872
    /*
873
      Add AUTO_INCREMENT=... if there is an AUTO_INCREMENT column,
874
      and NEXT_ID > 1 (the default).  We must not print the clause
875
      for engines that do not support this as it would break the
876
      import of dumps, but as of this writing, the test for whether
877
      AUTO_INCREMENT columns are allowed and wether AUTO_INCREMENT=...
878
      is supported is identical, !(file->table_flags() & HA_NO_AUTO_INCREMENT))
879
      Because of that, we do not explicitly test for the feature,
880
      but may extrapolate its existence from that of an AUTO_INCREMENT column.
881
    */
882
883
    if (create_info.auto_increment_value > 1)
884
    {
885
      char *end;
886
      packet->append(STRING_WITH_LEN(" AUTO_INCREMENT="));
152 by Brian Aker
longlong replacement
887
      end= int64_t10_to_str(create_info.auto_increment_value, buff,10);
1 by brian
clean slate
888
      packet->append(buff, (uint) (end - buff));
889
    }
890
891
    if (share->min_rows)
892
    {
893
      char *end;
894
      packet->append(STRING_WITH_LEN(" MIN_ROWS="));
152 by Brian Aker
longlong replacement
895
      end= int64_t10_to_str(share->min_rows, buff, 10);
1 by brian
clean slate
896
      packet->append(buff, (uint) (end- buff));
897
    }
898
899
    if (share->max_rows && !table_list->schema_table)
900
    {
901
      char *end;
902
      packet->append(STRING_WITH_LEN(" MAX_ROWS="));
152 by Brian Aker
longlong replacement
903
      end= int64_t10_to_str(share->max_rows, buff, 10);
1 by brian
clean slate
904
      packet->append(buff, (uint) (end - buff));
905
    }
906
907
    if (share->avg_row_length)
908
    {
909
      char *end;
910
      packet->append(STRING_WITH_LEN(" AVG_ROW_LENGTH="));
152 by Brian Aker
longlong replacement
911
      end= int64_t10_to_str(share->avg_row_length, buff,10);
1 by brian
clean slate
912
      packet->append(buff, (uint) (end - buff));
913
    }
914
915
    if (share->db_create_options & HA_OPTION_PACK_KEYS)
916
      packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
917
    if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
918
      packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
919
    /* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
920
    if (share->db_create_options & HA_OPTION_CHECKSUM)
921
      packet->append(STRING_WITH_LEN(" CHECKSUM=1"));
922
    if (share->page_checksum != HA_CHOICE_UNDEF)
923
    {
924
      packet->append(STRING_WITH_LEN(" PAGE_CHECKSUM="));
925
      packet->append(ha_choice_values[(uint) share->page_checksum], 1);
926
    }
927
    if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
928
      packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
929
    if (create_info.row_type != ROW_TYPE_DEFAULT)
930
    {
931
      packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
932
      packet->append(ha_row_type[(uint) create_info.row_type]);
933
    }
934
    if (share->transactional != HA_CHOICE_UNDEF)
935
    {
936
      packet->append(STRING_WITH_LEN(" TRANSACTIONAL="));
937
      packet->append(ha_choice_values[(uint) share->transactional], 1);
938
    }
939
    if (table->s->key_block_size)
940
    {
941
      char *end;
942
      packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
152 by Brian Aker
longlong replacement
943
      end= int64_t10_to_str(table->s->key_block_size, buff, 10);
1 by brian
clean slate
944
      packet->append(buff, (uint) (end - buff));
945
    }
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
946
    if (share->block_size)
947
    {
948
      char *end;
949
      packet->append(STRING_WITH_LEN(" BLOCK_SIZE="));
950
      end= int64_t10_to_str(share->block_size, buff,10);
951
      packet->append(buff, (uint) (end - buff));
952
    }
1 by brian
clean slate
953
    table->file->append_create_info(packet);
954
    if (share->comment.length)
955
    {
956
      packet->append(STRING_WITH_LEN(" COMMENT="));
957
      append_unescaped(packet, share->comment.str, share->comment.length);
958
    }
959
    if (share->connect_string.length)
960
    {
961
      packet->append(STRING_WITH_LEN(" CONNECTION="));
962
      append_unescaped(packet, share->connect_string.str, share->connect_string.length);
963
    }
964
    append_directory(thd, packet, "DATA",  create_info.data_file_name);
965
    append_directory(thd, packet, "INDEX", create_info.index_file_name);
966
  }
354 by Brian Aker
Refactor of Table methods.
967
  table->restore_column_map(old_map);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
968
  return(0);
1 by brian
clean slate
969
}
970
971
/**
972
  Get a CREATE statement for a given database.
973
974
  The database is identified by its name, passed as @c dbname parameter.
975
  The name should be encoded using the system character set (UTF8 currently).
976
977
  Resulting statement is stored in the string pointed by @c buffer. The string
978
  is emptied first and its character set is set to the system character set.
979
980
  If HA_LEX_CREATE_IF_NOT_EXISTS flag is set in @c create_info->options, then
981
  the resulting CREATE statement contains "IF NOT EXISTS" clause. Other flags
982
  in @c create_options are ignored.
983
984
  @param  thd           The current thread instance.
985
  @param  dbname        The name of the database.
986
  @param  buffer        A String instance where the statement is stored.
987
  @param  create_info   If not NULL, the options member influences the resulting 
988
                        CRATE statement.
989
163 by Brian Aker
Merge Monty's code.
990
  @returns true if errors are detected, false otherwise.
1 by brian
clean slate
991
*/
992
993
bool store_db_create_info(THD *thd, const char *dbname, String *buffer,
994
                          HA_CREATE_INFO *create_info)
995
{
996
  HA_CREATE_INFO create;
997
  uint create_options = create_info ? create_info->options : 0;
998
999
  if (!my_strcasecmp(system_charset_info, dbname,
1000
                     INFORMATION_SCHEMA_NAME.str))
1001
  {
1002
    dbname= INFORMATION_SCHEMA_NAME.str;
1003
    create.default_table_charset= system_charset_info;
1004
  }
1005
  else
1006
  {
1007
    if (check_db_dir_existence(dbname))
163 by Brian Aker
Merge Monty's code.
1008
      return(true);
1 by brian
clean slate
1009
1010
    load_db_opt_by_name(thd, dbname, &create);
1011
  }
1012
1013
  buffer->length(0);
1014
  buffer->free();
1015
  buffer->set_charset(system_charset_info);
1016
  buffer->append(STRING_WITH_LEN("CREATE DATABASE "));
1017
1018
  if (create_options & HA_LEX_CREATE_IF_NOT_EXISTS)
1019
    buffer->append(STRING_WITH_LEN("/*!32312 IF NOT EXISTS*/ "));
1020
1021
  append_identifier(thd, buffer, dbname, strlen(dbname));
1022
1023
  if (create.default_table_charset)
1024
  {
1025
    buffer->append(STRING_WITH_LEN(" /*!40100"));
1026
    buffer->append(STRING_WITH_LEN(" DEFAULT CHARACTER SET "));
1027
    buffer->append(create.default_table_charset->csname);
1028
    if (!(create.default_table_charset->state & MY_CS_PRIMARY))
1029
    {
1030
      buffer->append(STRING_WITH_LEN(" COLLATE "));
1031
      buffer->append(create.default_table_charset->name);
1032
    }
1033
    buffer->append(STRING_WITH_LEN(" */"));
1034
  }
1035
163 by Brian Aker
Merge Monty's code.
1036
  return(false);
1 by brian
clean slate
1037
}
1038
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
1039
static void store_key_options(THD *thd __attribute__((unused)),
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1040
                              String *packet, Table *table,
1 by brian
clean slate
1041
                              KEY *key_info)
1042
{
1043
  char *end, buff[32];
1044
1045
  if (key_info->algorithm == HA_KEY_ALG_BTREE)
1046
    packet->append(STRING_WITH_LEN(" USING BTREE"));
1047
1048
  if (key_info->algorithm == HA_KEY_ALG_HASH)
1049
    packet->append(STRING_WITH_LEN(" USING HASH"));
1050
1051
  if ((key_info->flags & HA_USES_BLOCK_SIZE) &&
1052
      table->s->key_block_size != key_info->block_size)
1053
  {
1054
    packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
152 by Brian Aker
longlong replacement
1055
    end= int64_t10_to_str(key_info->block_size, buff, 10);
1 by brian
clean slate
1056
    packet->append(buff, (uint) (end - buff));
1057
  }
1058
51.1.75 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
1059
  assert(test(key_info->flags & HA_USES_COMMENT) == 
1 by brian
clean slate
1060
              (key_info->comment.length > 0));
1061
  if (key_info->flags & HA_USES_COMMENT)
1062
  {
1063
    packet->append(STRING_WITH_LEN(" COMMENT "));
1064
    append_unescaped(packet, key_info->comment.str, 
1065
                     key_info->comment.length);
1066
  }
1067
}
1068
1069
1070
/****************************************************************************
1071
  Return info about all processes
1072
  returns for each thread: thread id, user, host, db, command, info
1073
****************************************************************************/
1074
1075
class thread_info :public ilink {
1076
public:
1077
  static void *operator new(size_t size)
1078
  {
1079
    return (void*) sql_alloc((uint) size);
1080
  }
1081
  static void operator delete(void *ptr __attribute__((unused)),
1082
                              size_t size __attribute__((unused)))
1083
  { TRASH(ptr, size); }
1084
1085
  ulong thread_id;
1086
  time_t start_time;
1087
  uint   command;
1088
  const char *user,*host,*db,*proc_info,*state_info;
1089
  char *query;
1090
};
1091
1092
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
1093
template class I_List<thread_info>;
1094
#endif
1095
1096
void mysqld_list_processes(THD *thd,const char *user, bool verbose)
1097
{
1098
  Item *field;
1099
  List<Item> field_list;
1100
  I_List<thread_info> thread_infos;
1101
  ulong max_query_length= (verbose ? thd->variables.max_allowed_packet :
1102
			   PROCESS_LIST_WIDTH);
1103
  Protocol *protocol= thd->protocol;
1104
1105
  field_list.push_back(new Item_int("Id", 0, MY_INT32_NUM_DECIMAL_DIGITS));
1106
  field_list.push_back(new Item_empty_string("User",16));
1107
  field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
1108
  field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
1109
  field->maybe_null=1;
1110
  field_list.push_back(new Item_empty_string("Command",16));
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
1111
  field_list.push_back(new Item_return_int("Time",7, DRIZZLE_TYPE_LONG));
1 by brian
clean slate
1112
  field_list.push_back(field=new Item_empty_string("State",30));
1113
  field->maybe_null=1;
1114
  field_list.push_back(field=new Item_empty_string("Info",max_query_length));
1115
  field->maybe_null=1;
1116
  if (protocol->send_fields(&field_list,
1117
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1118
    return;
1 by brian
clean slate
1119
398.1.6 by Monty Taylor
Removed __alpha__ references.
1120
  pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1 by brian
clean slate
1121
  if (!thd->killed)
1122
  {
1123
    I_List_iterator<THD> it(threads);
1124
    THD *tmp;
1125
    while ((tmp=it++))
1126
    {
1127
      Security_context *tmp_sctx= tmp->security_ctx;
1128
      struct st_my_thread_var *mysys_var;
1129
      if ((tmp->vio_ok() || tmp->system_thread) && (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
1130
      {
1131
        thread_info *thd_info= new thread_info;
1132
1133
        thd_info->thread_id=tmp->thread_id;
1134
        thd_info->user= thd->strdup(tmp_sctx->user ? tmp_sctx->user :
1135
                                    (tmp->system_thread ?
1136
                                     "system user" : "unauthenticated user"));
265 by brian
First pass through cleaning up security context.
1137
        thd_info->host= thd->strdup(tmp_sctx->ip);
1 by brian
clean slate
1138
        if ((thd_info->db=tmp->db))             // Safe test
1139
          thd_info->db=thd->strdup(thd_info->db);
1140
        thd_info->command=(int) tmp->command;
1141
        if ((mysys_var= tmp->mysys_var))
1142
          pthread_mutex_lock(&mysys_var->mutex);
1143
        thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
1144
        thd_info->state_info= (char*) (tmp->net.reading_or_writing ?
1145
                                       (tmp->net.reading_or_writing == 2 ?
1146
                                        "Writing to net" :
461 by Monty Taylor
Removed NullS. bu-bye.
1147
                                        thd_info->command == COM_SLEEP ? NULL :
1 by brian
clean slate
1148
                                        "Reading from net") :
322.2.2 by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter.
1149
                                       tmp->get_proc_info() ? tmp->get_proc_info() :
1 by brian
clean slate
1150
                                       tmp->mysys_var &&
1151
                                       tmp->mysys_var->current_cond ?
461 by Monty Taylor
Removed NullS. bu-bye.
1152
                                       "Waiting on cond" : NULL);
1 by brian
clean slate
1153
        if (mysys_var)
1154
          pthread_mutex_unlock(&mysys_var->mutex);
1155
1156
        thd_info->start_time= tmp->start_time;
1157
        thd_info->query=0;
1158
        if (tmp->query)
1159
        {
1160
	  /* 
1161
            query_length is always set to 0 when we set query = NULL; see
1162
	    the comment in sql_class.h why this prevents crashes in possible
1163
            races with query_length
1164
          */
398.1.4 by Monty Taylor
Renamed max/min.
1165
          uint length= cmin((uint32_t)max_query_length, tmp->query_length);
1 by brian
clean slate
1166
          thd_info->query=(char*) thd->strmake(tmp->query,length);
1167
        }
1168
        thread_infos.append(thd_info);
1169
      }
1170
    }
1171
  }
398.1.6 by Monty Taylor
Removed __alpha__ references.
1172
  pthread_mutex_unlock(&LOCK_thread_count);
1 by brian
clean slate
1173
1174
  thread_info *thd_info;
1175
  time_t now= my_time(0);
1176
  while ((thd_info=thread_infos.get()))
1177
  {
1178
    protocol->prepare_for_resend();
151 by Brian Aker
Ulonglong to uint64_t
1179
    protocol->store((uint64_t) thd_info->thread_id);
1 by brian
clean slate
1180
    protocol->store(thd_info->user, system_charset_info);
1181
    protocol->store(thd_info->host, system_charset_info);
1182
    protocol->store(thd_info->db, system_charset_info);
1183
    if (thd_info->proc_info)
1184
      protocol->store(thd_info->proc_info, system_charset_info);
1185
    else
1186
      protocol->store(command_name[thd_info->command].str, system_charset_info);
1187
    if (thd_info->start_time)
205 by Brian Aker
uint32 -> uin32_t
1188
      protocol->store((uint32_t) (now - thd_info->start_time));
1 by brian
clean slate
1189
    else
1190
      protocol->store_null();
1191
    protocol->store(thd_info->state_info, system_charset_info);
1192
    protocol->store(thd_info->query, system_charset_info);
1193
    if (protocol->write())
1194
      break; /* purecov: inspected */
1195
  }
1196
  my_eof(thd);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1197
  return;
1 by brian
clean slate
1198
}
1199
327.2.4 by Brian Aker
Refactoring table.h
1200
int fill_schema_processlist(THD* thd, TableList* tables,
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
1201
                            COND* cond __attribute__((unused)))
1 by brian
clean slate
1202
{
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1203
  Table *table= tables->table;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
1204
  const CHARSET_INFO * const cs= system_charset_info;
1 by brian
clean slate
1205
  char *user;
1206
  time_t now= my_time(0);
1207
461 by Monty Taylor
Removed NullS. bu-bye.
1208
  user= NULL;
1 by brian
clean slate
1209
398.1.6 by Monty Taylor
Removed __alpha__ references.
1210
  pthread_mutex_lock(&LOCK_thread_count);
1 by brian
clean slate
1211
1212
  if (!thd->killed)
1213
  {
1214
    I_List_iterator<THD> it(threads);
1215
    THD* tmp;
1216
1217
    while ((tmp= it++))
1218
    {
1219
      Security_context *tmp_sctx= tmp->security_ctx;
1220
      struct st_my_thread_var *mysys_var;
1221
      const char *val;
1222
1223
      if ((!tmp->vio_ok() && !tmp->system_thread))
1224
        continue;
1225
1226
      restore_record(table, s->default_values);
1227
      /* ID */
163 by Brian Aker
Merge Monty's code.
1228
      table->field[0]->store((int64_t) tmp->thread_id, true);
1 by brian
clean slate
1229
      /* USER */
1230
      val= tmp_sctx->user ? tmp_sctx->user :
1231
            (tmp->system_thread ? "system user" : "unauthenticated user");
1232
      table->field[1]->store(val, strlen(val), cs);
1233
      /* HOST */
265 by brian
First pass through cleaning up security context.
1234
      table->field[2]->store(tmp_sctx->ip, strlen(tmp_sctx->ip), cs);
1 by brian
clean slate
1235
      /* DB */
1236
      if (tmp->db)
1237
      {
1238
        table->field[3]->store(tmp->db, strlen(tmp->db), cs);
1239
        table->field[3]->set_notnull();
1240
      }
1241
1242
      if ((mysys_var= tmp->mysys_var))
1243
        pthread_mutex_lock(&mysys_var->mutex);
1244
      /* COMMAND */
1245
      if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0)))
1246
        table->field[4]->store(val, strlen(val), cs);
1247
      else
1248
        table->field[4]->store(command_name[tmp->command].str,
1249
                               command_name[tmp->command].length, cs);
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
1250
      /* DRIZZLE_TIME */
205 by Brian Aker
uint32 -> uin32_t
1251
      table->field[5]->store((uint32_t)(tmp->start_time ?
163 by Brian Aker
Merge Monty's code.
1252
                                      now - tmp->start_time : 0), true);
1 by brian
clean slate
1253
      /* STATE */
1254
      val= (char*) (tmp->net.reading_or_writing ?
1255
                    (tmp->net.reading_or_writing == 2 ?
1256
                     "Writing to net" :
461 by Monty Taylor
Removed NullS. bu-bye.
1257
                     tmp->command == COM_SLEEP ? NULL :
1 by brian
clean slate
1258
                     "Reading from net") :
322.2.2 by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter.
1259
                    tmp->get_proc_info() ? tmp->get_proc_info() :
1 by brian
clean slate
1260
                    tmp->mysys_var &&
1261
                    tmp->mysys_var->current_cond ?
461 by Monty Taylor
Removed NullS. bu-bye.
1262
                    "Waiting on cond" : NULL);
1 by brian
clean slate
1263
      if (val)
1264
      {
1265
        table->field[6]->store(val, strlen(val), cs);
1266
        table->field[6]->set_notnull();
1267
      }
1268
1269
      if (mysys_var)
1270
        pthread_mutex_unlock(&mysys_var->mutex);
1271
1272
      /* INFO */
1273
      if (tmp->query)
1274
      {
1275
        table->field[7]->store(tmp->query,
398.1.4 by Monty Taylor
Renamed max/min.
1276
                               cmin((uint32_t)PROCESS_LIST_INFO_WIDTH,
1 by brian
clean slate
1277
                                   tmp->query_length), cs);
1278
        table->field[7]->set_notnull();
1279
      }
1280
1281
      if (schema_table_store_record(thd, table))
1282
      {
398.1.6 by Monty Taylor
Removed __alpha__ references.
1283
        pthread_mutex_unlock(&LOCK_thread_count);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1284
        return(1);
1 by brian
clean slate
1285
      }
1286
    }
1287
  }
1288
398.1.6 by Monty Taylor
Removed __alpha__ references.
1289
  pthread_mutex_unlock(&LOCK_thread_count);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1290
  return(0);
1 by brian
clean slate
1291
}
1292
1293
/*****************************************************************************
1294
  Status functions
1295
*****************************************************************************/
1296
1297
static DYNAMIC_ARRAY all_status_vars;
1298
static bool status_vars_inited= 0;
1299
static int show_var_cmp(const void *var1, const void *var2)
1300
{
1301
  return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
1302
}
1303
1304
/*
1305
  deletes all the SHOW_UNDEF elements from the array and calls
1306
  delete_dynamic() if it's completely empty.
1307
*/
1308
static void shrink_var_array(DYNAMIC_ARRAY *array)
1309
{
1310
  uint a,b;
1311
  SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
1312
1313
  for (a= b= 0; b < array->elements; b++)
1314
    if (all[b].type != SHOW_UNDEF)
1315
      all[a++]= all[b];
1316
  if (a)
1317
  {
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
1318
    memset(all+a, 0, sizeof(SHOW_VAR)); // writing NULL-element to the end
1 by brian
clean slate
1319
    array->elements= a;
1320
  }
1321
  else // array is completely empty - delete it
1322
    delete_dynamic(array);
1323
}
1324
1325
/*
1326
  Adds an array of SHOW_VAR entries to the output of SHOW STATUS
1327
1328
  SYNOPSIS
1329
    add_status_vars(SHOW_VAR *list)
1330
    list - an array of SHOW_VAR entries to add to all_status_vars
1331
           the last entry must be {0,0,SHOW_UNDEF}
1332
1333
  NOTE
1334
    The handling of all_status_vars[] is completely internal, it's allocated
1335
    automatically when something is added to it, and deleted completely when
1336
    the last entry is removed.
1337
1338
    As a special optimization, if add_status_vars() is called before
1339
    init_status_vars(), it assumes "startup mode" - neither concurrent access
1340
    to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
1341
1342
    The last entry of the all_status_vars[] should always be {0,0,SHOW_UNDEF}
1343
*/
1344
int add_status_vars(SHOW_VAR *list)
1345
{
1346
  int res= 0;
1347
  if (status_vars_inited)
1348
    pthread_mutex_lock(&LOCK_status);
1349
  if (!all_status_vars.buffer && // array is not allocated yet - do it now
1350
      my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20))
1351
  {
1352
    res= 1;
1353
    goto err;
1354
  }
1355
  while (list->name)
1356
    res|= insert_dynamic(&all_status_vars, (uchar*)list++);
1357
  res|= insert_dynamic(&all_status_vars, (uchar*)list); // appending NULL-element
1358
  all_status_vars.elements--; // but next insert_dynamic should overwite it
1359
  if (status_vars_inited)
1360
    sort_dynamic(&all_status_vars, show_var_cmp);
1361
err:
1362
  if (status_vars_inited)
1363
    pthread_mutex_unlock(&LOCK_status);
1364
  return res;
1365
}
1366
1367
/*
1368
  Make all_status_vars[] usable for SHOW STATUS
1369
1370
  NOTE
1371
    See add_status_vars(). Before init_status_vars() call, add_status_vars()
1372
    works in a special fast "startup" mode. Thus init_status_vars()
1373
    should be called as late as possible but before enabling multi-threading.
1374
*/
1375
void init_status_vars()
1376
{
1377
  status_vars_inited=1;
1378
  sort_dynamic(&all_status_vars, show_var_cmp);
1379
}
1380
1381
void reset_status_vars()
1382
{
1383
  SHOW_VAR *ptr= (SHOW_VAR*) all_status_vars.buffer;
1384
  SHOW_VAR *last= ptr + all_status_vars.elements;
1385
  for (; ptr < last; ptr++)
1386
  {
1387
    /* Note that SHOW_LONG_NOFLUSH variables are not reset */
1388
    if (ptr->type == SHOW_LONG)
1389
      *(ulong*) ptr->value= 0;
1390
  }  
1391
}
1392
1393
/*
1394
  catch-all cleanup function, cleans up everything no matter what
1395
1396
  DESCRIPTION
1397
    This function is not strictly required if all add_to_status/
1398
    remove_status_vars are properly paired, but it's a safety measure that
1399
    deletes everything from the all_status_vars[] even if some
1400
    remove_status_vars were forgotten
1401
*/
1402
void free_status_vars()
1403
{
1404
  delete_dynamic(&all_status_vars);
1405
}
1406
1407
/*
1408
  Removes an array of SHOW_VAR entries from the output of SHOW STATUS
1409
1410
  SYNOPSIS
1411
    remove_status_vars(SHOW_VAR *list)
1412
    list - an array of SHOW_VAR entries to remove to all_status_vars
1413
           the last entry must be {0,0,SHOW_UNDEF}
1414
1415
  NOTE
1416
    there's lots of room for optimizing this, especially in non-sorted mode,
1417
    but nobody cares - it may be called only in case of failed plugin
1418
    initialization in the mysqld startup.
1419
*/
1420
1421
void remove_status_vars(SHOW_VAR *list)
1422
{
1423
  if (status_vars_inited)
1424
  {
1425
    pthread_mutex_lock(&LOCK_status);
1426
    SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
1427
    int a= 0, b= all_status_vars.elements, c= (a+b)/2;
1428
1429
    for (; list->name; list++)
1430
    {
1431
      int res= 0;
1432
      for (a= 0, b= all_status_vars.elements; b-a > 1; c= (a+b)/2)
1433
      {
1434
        res= show_var_cmp(list, all+c);
1435
        if (res < 0)
1436
          b= c;
1437
        else if (res > 0)
1438
          a= c;
1439
        else
1440
          break;
1441
      }
1442
      if (res == 0)
1443
        all[c].type= SHOW_UNDEF;
1444
    }
1445
    shrink_var_array(&all_status_vars);
1446
    pthread_mutex_unlock(&LOCK_status);
1447
  }
1448
  else
1449
  {
1450
    SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
1451
    uint i;
1452
    for (; list->name; list++)
1453
    {
1454
      for (i= 0; i < all_status_vars.elements; i++)
1455
      {
1456
        if (show_var_cmp(list, all+i))
1457
          continue;
1458
        all[i].type= SHOW_UNDEF;
1459
        break;
1460
      }
1461
    }
1462
    shrink_var_array(&all_status_vars);
1463
  }
1464
}
1465
1466
inline void make_upper(char *buf)
1467
{
1468
  for (; *buf; buf++)
1469
    *buf= my_toupper(system_charset_info, *buf);
1470
}
1471
1472
static bool show_status_array(THD *thd, const char *wild,
1473
                              SHOW_VAR *variables,
1474
                              enum enum_var_type value_type,
1475
                              struct system_status_var *status_var,
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1476
                              const char *prefix, Table *table,
1 by brian
clean slate
1477
                              bool ucase_names)
1478
{
1479
  MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, long);
1480
  char * const buff= (char *) &buff_data;
1481
  char *prefix_end;
1482
  /* the variable name should not be longer than 64 characters */
1483
  char name_buffer[64];
1484
  int len;
1485
  LEX_STRING null_lex_str;
1486
  SHOW_VAR tmp, *var;
1487
1488
  null_lex_str.str= 0;				// For sys_var->value_ptr()
1489
  null_lex_str.length= 0;
1490
411.1.1 by Brian Aker
Work on removing GNU specific calls.
1491
  prefix_end=my_stpncpy(name_buffer, prefix, sizeof(name_buffer)-1);
1 by brian
clean slate
1492
  if (*prefix)
1493
    *prefix_end++= '_';
1494
  len=name_buffer + sizeof(name_buffer) - prefix_end;
1495
1496
  for (; variables->name; variables++)
1497
  {
411.1.1 by Brian Aker
Work on removing GNU specific calls.
1498
    my_stpncpy(prefix_end, variables->name, len);
1 by brian
clean slate
1499
    name_buffer[sizeof(name_buffer)-1]=0;       /* Safety */
1500
    if (ucase_names)
1501
      make_upper(name_buffer);
1502
1503
    /*
1504
      if var->type is SHOW_FUNC, call the function.
1505
      Repeat as necessary, if new var is again SHOW_FUNC
1506
    */
1507
    for (var=variables; var->type == SHOW_FUNC; var= &tmp)
77.1.46 by Monty Taylor
Finished the warnings work!
1508
      ((mysql_show_var_func)((st_show_var_func_container *)var->value)->func)(thd, &tmp, buff);
1 by brian
clean slate
1509
1510
    SHOW_TYPE show_type=var->type;
1511
    if (show_type == SHOW_ARRAY)
1512
    {
1513
      show_status_array(thd, wild, (SHOW_VAR *) var->value, value_type,
1514
                        status_var, name_buffer, table, ucase_names);
1515
    }
1516
    else
1517
    {
1518
      if (!(wild && wild[0] && wild_case_compare(system_charset_info,
1519
                                                 name_buffer, wild)))
1520
      {
1521
        char *value=var->value;
1522
        const char *pos, *end;                  // We assign a lot of const's
1523
1524
        pthread_mutex_lock(&LOCK_global_system_variables);
1525
1526
        if (show_type == SHOW_SYS)
1527
        {
1528
          show_type= ((sys_var*) value)->show_type();
1529
          value=     (char*) ((sys_var*) value)->value_ptr(thd, value_type,
1530
                                                           &null_lex_str);
1531
        }
1532
1533
        pos= end= buff;
1534
        /*
1535
          note that value may be == buff. All SHOW_xxx code below
1536
          should still work in this case
1537
        */
1538
        switch (show_type) {
1539
        case SHOW_DOUBLE_STATUS:
1540
          value= ((char *) status_var + (ulong) value);
1541
          /* fall through */
1542
        case SHOW_DOUBLE:
1543
          /* 6 is the default precision for '%f' in sprintf() */
1544
          end= buff + my_fcvt(*(double *) value, 6, buff, NULL);
1545
          break;
1546
        case SHOW_LONG_STATUS:
1547
          value= ((char *) status_var + (ulong) value);
1548
          /* fall through */
1549
        case SHOW_LONG:
1550
        case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
1551
          end= int10_to_str(*(long*) value, buff, 10);
1552
          break;
1553
        case SHOW_LONGLONG_STATUS:
151 by Brian Aker
Ulonglong to uint64_t
1554
          value= ((char *) status_var + (uint64_t) value);
1 by brian
clean slate
1555
          /* fall through */
1556
        case SHOW_LONGLONG:
152 by Brian Aker
longlong replacement
1557
          end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1 by brian
clean slate
1558
          break;
1559
        case SHOW_HA_ROWS:
152 by Brian Aker
longlong replacement
1560
          end= int64_t10_to_str((int64_t) *(ha_rows*) value, buff, 10);
1 by brian
clean slate
1561
          break;
1562
        case SHOW_BOOL:
411.1.1 by Brian Aker
Work on removing GNU specific calls.
1563
          end= my_stpcpy(buff, *(bool*) value ? "ON" : "OFF");
1 by brian
clean slate
1564
          break;
1565
        case SHOW_MY_BOOL:
411.1.1 by Brian Aker
Work on removing GNU specific calls.
1566
          end= my_stpcpy(buff, *(bool*) value ? "ON" : "OFF");
1 by brian
clean slate
1567
          break;
1568
        case SHOW_INT:
205 by Brian Aker
uint32 -> uin32_t
1569
          end= int10_to_str((long) *(uint32_t*) value, buff, 10);
1 by brian
clean slate
1570
          break;
1571
        case SHOW_HAVE:
1572
        {
1573
          SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
1574
          pos= show_comp_option_name[(int) tmp];
376 by Brian Aker
strend remove
1575
          end= strchr(pos, '\0');
1 by brian
clean slate
1576
          break;
1577
        }
1578
        case SHOW_CHAR:
1579
        {
1580
          if (!(pos= value))
1581
            pos= "";
376 by Brian Aker
strend remove
1582
          end= strchr(pos, '\0');
1 by brian
clean slate
1583
          break;
1584
        }
1585
       case SHOW_CHAR_PTR:
1586
        {
1587
          if (!(pos= *(char**) value))
1588
            pos= "";
376 by Brian Aker
strend remove
1589
          end= strchr(pos, '\0');
1 by brian
clean slate
1590
          break;
1591
        }
1592
        case SHOW_KEY_CACHE_LONG:
1593
          value= (char*) dflt_key_cache + (ulong)value;
1594
          end= int10_to_str(*(long*) value, buff, 10);
1595
          break;
1596
        case SHOW_KEY_CACHE_LONGLONG:
1597
          value= (char*) dflt_key_cache + (ulong)value;
152 by Brian Aker
longlong replacement
1598
	  end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1 by brian
clean slate
1599
	  break;
1600
        case SHOW_UNDEF:
1601
          break;                                        // Return empty string
1602
        case SHOW_SYS:                                  // Cannot happen
1603
        default:
51.1.75 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
1604
          assert(0);
1 by brian
clean slate
1605
          break;
1606
        }
1607
        restore_record(table, s->default_values);
1608
        table->field[0]->store(name_buffer, strlen(name_buffer),
1609
                               system_charset_info);
205 by Brian Aker
uint32 -> uin32_t
1610
        table->field[1]->store(pos, (uint32_t) (end - pos), system_charset_info);
1 by brian
clean slate
1611
        table->field[1]->set_notnull();
1612
1613
        pthread_mutex_unlock(&LOCK_global_system_variables);
1614
1615
        if (schema_table_store_record(thd, table))
163 by Brian Aker
Merge Monty's code.
1616
          return(true);
1 by brian
clean slate
1617
      }
1618
    }
1619
  }
1620
163 by Brian Aker
Merge Monty's code.
1621
  return(false);
1 by brian
clean slate
1622
}
1623
1624
1625
/* collect status for all running threads */
1626
1627
void calc_sum_of_all_status(STATUS_VAR *to)
1628
{
1629
1630
  /* Ensure that thread id not killed during loop */
398.1.6 by Monty Taylor
Removed __alpha__ references.
1631
  pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1 by brian
clean slate
1632
1633
  I_List_iterator<THD> it(threads);
1634
  THD *tmp;
1635
  
1636
  /* Get global values as base */
1637
  *to= global_status_var;
1638
  
1639
  /* Add to this status from existing threads */
1640
  while ((tmp= it++))
1641
    add_to_status(to, &tmp->status_var);
1642
  
398.1.6 by Monty Taylor
Removed __alpha__ references.
1643
  pthread_mutex_unlock(&LOCK_thread_count);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1644
  return;
1 by brian
clean slate
1645
}
1646
1647
1648
/* This is only used internally, but we need it here as a forward reference */
1649
extern ST_SCHEMA_TABLE schema_tables[];
1650
1651
typedef struct st_lookup_field_values
1652
{
1653
  LEX_STRING db_value, table_value;
1654
  bool wild_db_value, wild_table_value;
1655
} LOOKUP_FIELD_VALUES;
1656
1657
1658
/*
1659
  Store record to I_S table, convert HEAP table
1660
  to MyISAM if necessary
1661
1662
  SYNOPSIS
1663
    schema_table_store_record()
1664
    thd                   thread handler
1665
    table                 Information schema table to be updated
1666
1667
  RETURN
1668
    0	                  success
1669
    1	                  error
1670
*/
1671
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1672
bool schema_table_store_record(THD *thd, Table *table)
1 by brian
clean slate
1673
{
1674
  int error;
1675
  if ((error= table->file->ha_write_row(table->record[0])))
1676
  {
1677
    TMP_TABLE_PARAM *param= table->pos_in_table_list->schema_table_param;
1678
1679
    if (create_myisam_from_heap(thd, table, param->start_recinfo, 
1680
                                &param->recinfo, error, 0))
1681
      return 1;
1682
  }
1683
  return 0;
1684
}
1685
1686
1687
int make_table_list(THD *thd, SELECT_LEX *sel,
1688
                    LEX_STRING *db_name, LEX_STRING *table_name)
1689
{
1690
  Table_ident *table_ident;
1691
  table_ident= new Table_ident(thd, *db_name, *table_name, 1);
1692
  sel->init_query();
1693
  if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ))
1694
    return 1;
1695
  return 0;
1696
}
1697
1698
1699
/**
1700
  @brief    Get lookup value from the part of 'WHERE' condition 
1701
1702
  @details This function gets lookup value from 
1703
           the part of 'WHERE' condition if it's possible and 
1704
           fill appropriate lookup_field_vals struct field
1705
           with this value.
1706
1707
  @param[in]      thd                   thread handler
1708
  @param[in]      item_func             part of WHERE condition
1709
  @param[in]      table                 I_S table
1710
  @param[in, out] lookup_field_vals     Struct which holds lookup values 
1711
1712
  @return
1713
    0             success
1714
    1             error, there can be no matching records for the condition
1715
*/
1716
1717
bool get_lookup_value(THD *thd, Item_func *item_func,
327.2.4 by Brian Aker
Refactoring table.h
1718
                      TableList *table, 
1 by brian
clean slate
1719
                      LOOKUP_FIELD_VALUES *lookup_field_vals)
1720
{
1721
  ST_SCHEMA_TABLE *schema_table= table->schema_table;
1722
  ST_FIELD_INFO *field_info= schema_table->fields_info;
1723
  const char *field_name1= schema_table->idx_field1 >= 0 ?
1724
    field_info[schema_table->idx_field1].field_name : "";
1725
  const char *field_name2= schema_table->idx_field2 >= 0 ?
1726
    field_info[schema_table->idx_field2].field_name : "";
1727
1728
  if (item_func->functype() == Item_func::EQ_FUNC ||
1729
      item_func->functype() == Item_func::EQUAL_FUNC)
1730
  {
1731
    int idx_field, idx_val;
1732
    char tmp[MAX_FIELD_WIDTH];
1733
    String *tmp_str, str_buff(tmp, sizeof(tmp), system_charset_info);
1734
    Item_field *item_field;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
1735
    const CHARSET_INFO * const cs= system_charset_info;
1 by brian
clean slate
1736
1737
    if (item_func->arguments()[0]->type() == Item::FIELD_ITEM &&
1738
        item_func->arguments()[1]->const_item())
1739
    {
1740
      idx_field= 0;
1741
      idx_val= 1;
1742
    }
1743
    else if (item_func->arguments()[1]->type() == Item::FIELD_ITEM &&
1744
             item_func->arguments()[0]->const_item())
1745
    {
1746
      idx_field= 1;
1747
      idx_val= 0;
1748
    }
1749
    else
1750
      return 0;
1751
1752
    item_field= (Item_field*) item_func->arguments()[idx_field];
1753
    if (table->table != item_field->field->table)
1754
      return 0;
1755
    tmp_str= item_func->arguments()[idx_val]->val_str(&str_buff);
1756
1757
    /* impossible value */
1758
    if (!tmp_str)
1759
      return 1;
1760
1761
    /* Lookup value is database name */
1762
    if (!cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
1763
                               (uchar *) item_field->field_name,
1764
                               strlen(item_field->field_name), 0))
1765
    {
1766
      thd->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(),
163 by Brian Aker
Merge Monty's code.
1767
                           tmp_str->length(), false);
1 by brian
clean slate
1768
    }
1769
    /* Lookup value is table name */
1770
    else if (!cs->coll->strnncollsp(cs, (uchar *) field_name2,
1771
                                    strlen(field_name2),
1772
                                    (uchar *) item_field->field_name,
1773
                                    strlen(item_field->field_name), 0))
1774
    {
1775
      thd->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(),
163 by Brian Aker
Merge Monty's code.
1776
                           tmp_str->length(), false);
1 by brian
clean slate
1777
    }
1778
  }
1779
  return 0;
1780
}
1781
1782
1783
/**
1784
  @brief    Calculates lookup values from 'WHERE' condition 
1785
1786
  @details This function calculates lookup value(database name, table name)
1787
           from 'WHERE' condition if it's possible and 
1788
           fill lookup_field_vals struct fields with these values.
1789
1790
  @param[in]      thd                   thread handler
1791
  @param[in]      cond                  WHERE condition
1792
  @param[in]      table                 I_S table
1793
  @param[in, out] lookup_field_vals     Struct which holds lookup values 
1794
1795
  @return
1796
    0             success
1797
    1             error, there can be no matching records for the condition
1798
*/
1799
327.2.4 by Brian Aker
Refactoring table.h
1800
bool calc_lookup_values_from_cond(THD *thd, COND *cond, TableList *table,
1 by brian
clean slate
1801
                                  LOOKUP_FIELD_VALUES *lookup_field_vals)
1802
{
1803
  if (!cond)
1804
    return 0;
1805
1806
  if (cond->type() == Item::COND_ITEM)
1807
  {
1808
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1809
    {
1810
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1811
      Item *item;
1812
      while ((item= li++))
1813
      {
1814
        if (item->type() == Item::FUNC_ITEM)
1815
        {
1816
          if (get_lookup_value(thd, (Item_func*)item, table, lookup_field_vals))
1817
            return 1;
1818
        }
1819
        else
1820
        {
1821
          if (calc_lookup_values_from_cond(thd, item, table, lookup_field_vals))
1822
            return 1;
1823
        }
1824
      }
1825
    }
1826
    return 0;
1827
  }
1828
  else if (cond->type() == Item::FUNC_ITEM &&
1829
           get_lookup_value(thd, (Item_func*) cond, table, lookup_field_vals))
1830
    return 1;
1831
  return 0;
1832
}
1833
1834
327.2.4 by Brian Aker
Refactoring table.h
1835
bool uses_only_table_name_fields(Item *item, TableList *table)
1 by brian
clean slate
1836
{
1837
  if (item->type() == Item::FUNC_ITEM)
1838
  {
1839
    Item_func *item_func= (Item_func*)item;
1840
    for (uint i=0; i<item_func->argument_count(); i++)
1841
    {
1842
      if (!uses_only_table_name_fields(item_func->arguments()[i], table))
1843
        return 0;
1844
    }
1845
  }
1846
  else if (item->type() == Item::FIELD_ITEM)
1847
  {
1848
    Item_field *item_field= (Item_field*)item;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
1849
    const CHARSET_INFO * const cs= system_charset_info;
1 by brian
clean slate
1850
    ST_SCHEMA_TABLE *schema_table= table->schema_table;
1851
    ST_FIELD_INFO *field_info= schema_table->fields_info;
1852
    const char *field_name1= schema_table->idx_field1 >= 0 ?
1853
      field_info[schema_table->idx_field1].field_name : "";
1854
    const char *field_name2= schema_table->idx_field2 >= 0 ?
1855
      field_info[schema_table->idx_field2].field_name : "";
1856
    if (table->table != item_field->field->table ||
1857
        (cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
1858
                               (uchar *) item_field->field_name,
1859
                               strlen(item_field->field_name), 0) &&
1860
         cs->coll->strnncollsp(cs, (uchar *) field_name2, strlen(field_name2),
1861
                               (uchar *) item_field->field_name,
1862
                               strlen(item_field->field_name), 0)))
1863
      return 0;
1864
  }
1865
  else if (item->type() == Item::REF_ITEM)
1866
    return uses_only_table_name_fields(item->real_item(), table);
1867
1868
  if (item->type() == Item::SUBSELECT_ITEM && !item->const_item())
1869
    return 0;
1870
1871
  return 1;
1872
}
1873
1874
327.2.4 by Brian Aker
Refactoring table.h
1875
static COND * make_cond_for_info_schema(COND *cond, TableList *table)
1 by brian
clean slate
1876
{
1877
  if (!cond)
1878
    return (COND*) 0;
1879
  if (cond->type() == Item::COND_ITEM)
1880
  {
1881
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1882
    {
1883
      /* Create new top level AND item */
1884
      Item_cond_and *new_cond=new Item_cond_and;
1885
      if (!new_cond)
1886
	return (COND*) 0;
1887
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1888
      Item *item;
1889
      while ((item=li++))
1890
      {
1891
	Item *fix= make_cond_for_info_schema(item, table);
1892
	if (fix)
1893
	  new_cond->argument_list()->push_back(fix);
1894
      }
1895
      switch (new_cond->argument_list()->elements) {
1896
      case 0:
1897
	return (COND*) 0;
1898
      case 1:
1899
	return new_cond->argument_list()->head();
1900
      default:
1901
	new_cond->quick_fix_field();
1902
	return new_cond;
1903
      }
1904
    }
1905
    else
1906
    {						// Or list
1907
      Item_cond_or *new_cond=new Item_cond_or;
1908
      if (!new_cond)
1909
	return (COND*) 0;
1910
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1911
      Item *item;
1912
      while ((item=li++))
1913
      {
1914
	Item *fix=make_cond_for_info_schema(item, table);
1915
	if (!fix)
1916
	  return (COND*) 0;
1917
	new_cond->argument_list()->push_back(fix);
1918
      }
1919
      new_cond->quick_fix_field();
1920
      new_cond->top_level_item();
1921
      return new_cond;
1922
    }
1923
  }
1924
1925
  if (!uses_only_table_name_fields(cond, table))
1926
    return (COND*) 0;
1927
  return cond;
1928
}
1929
1930
1931
/**
1932
  @brief   Calculate lookup values(database name, table name)
1933
1934
  @details This function calculates lookup values(database name, table name)
1935
           from 'WHERE' condition or wild values (for 'SHOW' commands only)
1936
           from LEX struct and fill lookup_field_vals struct field
1937
           with these values.
1938
1939
  @param[in]      thd                   thread handler
1940
  @param[in]      cond                  WHERE condition
1941
  @param[in]      tables                I_S table
1942
  @param[in, out] lookup_field_values   Struct which holds lookup values 
1943
1944
  @return
1945
    0             success
1946
    1             error, there can be no matching records for the condition
1947
*/
1948
327.2.4 by Brian Aker
Refactoring table.h
1949
bool get_lookup_field_values(THD *thd, COND *cond, TableList *tables,
1 by brian
clean slate
1950
                             LOOKUP_FIELD_VALUES *lookup_field_values)
1951
{
1952
  LEX *lex= thd->lex;
461 by Monty Taylor
Removed NullS. bu-bye.
1953
  const char *wild= lex->wild ? lex->wild->ptr() : NULL;
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
1954
  memset(lookup_field_values, 0, sizeof(LOOKUP_FIELD_VALUES));
1 by brian
clean slate
1955
  switch (lex->sql_command) {
1956
  case SQLCOM_SHOW_DATABASES:
1957
    if (wild)
1958
    {
1959
      lookup_field_values->db_value.str= (char*) wild;
1960
      lookup_field_values->db_value.length= strlen(wild);
1961
      lookup_field_values->wild_db_value= 1;
1962
    }
1963
    return 0;
1964
  case SQLCOM_SHOW_TABLES:
1965
  case SQLCOM_SHOW_TABLE_STATUS:
1966
    lookup_field_values->db_value.str= lex->select_lex.db;
1967
    lookup_field_values->db_value.length=strlen(lex->select_lex.db);
1968
    if (wild)
1969
    {
1970
      lookup_field_values->table_value.str= (char*)wild;
1971
      lookup_field_values->table_value.length= strlen(wild);
1972
      lookup_field_values->wild_table_value= 1;
1973
    }
1974
    return 0;
1975
  default:
1976
    /*
1977
      The "default" is for queries over I_S.
1978
      All previous cases handle SHOW commands.
1979
    */
1980
    return calc_lookup_values_from_cond(thd, cond, tables, lookup_field_values);
1981
  }
1982
}
1983
1984
1985
enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
1986
{
1987
  return (enum enum_schema_tables) (schema_table - &schema_tables[0]);
1988
}
1989
1990
1991
/*
1992
  Create db names list. Information schema name always is first in list
1993
1994
  SYNOPSIS
1995
    make_db_list()
1996
    thd                   thread handler
1997
    files                 list of db names
1998
    wild                  wild string
1999
    idx_field_vals        idx_field_vals->db_name contains db name or
2000
                          wild string
2001
    with_i_schema         returns 1 if we added 'IS' name to list
2002
                          otherwise returns 0 
2003
2004
  RETURN
2005
    zero                  success
2006
    non-zero              error
2007
*/
2008
2009
int make_db_list(THD *thd, List<LEX_STRING> *files,
2010
                 LOOKUP_FIELD_VALUES *lookup_field_vals,
2011
                 bool *with_i_schema)
2012
{
2013
  LEX_STRING *i_s_name_copy= 0;
2014
  i_s_name_copy= thd->make_lex_string(i_s_name_copy,
2015
                                      INFORMATION_SCHEMA_NAME.str,
163 by Brian Aker
Merge Monty's code.
2016
                                      INFORMATION_SCHEMA_NAME.length, true);
1 by brian
clean slate
2017
  *with_i_schema= 0;
2018
  if (lookup_field_vals->wild_db_value)
2019
  {
2020
    /*
2021
      This part of code is only for SHOW DATABASES command.
2022
      idx_field_vals->db_value can be 0 when we don't use
2023
      LIKE clause (see also get_index_field_values() function)
2024
    */
2025
    if (!lookup_field_vals->db_value.str ||
2026
        !wild_case_compare(system_charset_info, 
2027
                           INFORMATION_SCHEMA_NAME.str,
2028
                           lookup_field_vals->db_value.str))
2029
    {
2030
      *with_i_schema= 1;
2031
      if (files->push_back(i_s_name_copy))
2032
        return 1;
2033
    }
461 by Monty Taylor
Removed NullS. bu-bye.
2034
    return (find_files(thd, files, NULL, mysql_data_home,
1 by brian
clean slate
2035
                       lookup_field_vals->db_value.str, 1) != FIND_FILES_OK);
2036
  }
2037
2038
2039
  /*
2040
    If we have db lookup vaule we just add it to list and
2041
    exit from the function
2042
  */
2043
  if (lookup_field_vals->db_value.str)
2044
  {
2045
    if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str,
2046
                       lookup_field_vals->db_value.str))
2047
    {
2048
      *with_i_schema= 1;
2049
      if (files->push_back(i_s_name_copy))
2050
        return 1;
2051
      return 0;
2052
    }
2053
    if (files->push_back(&lookup_field_vals->db_value))
2054
      return 1;
2055
    return 0;
2056
  }
2057
2058
  /*
2059
    Create list of existing databases. It is used in case
2060
    of select from information schema table
2061
  */
2062
  if (files->push_back(i_s_name_copy))
2063
    return 1;
2064
  *with_i_schema= 1;
461 by Monty Taylor
Removed NullS. bu-bye.
2065
  return (find_files(thd, files, NULL,
2066
                     mysql_data_home, NULL, 1) != FIND_FILES_OK);
1 by brian
clean slate
2067
}
2068
2069
2070
struct st_add_schema_table 
2071
{
2072
  List<LEX_STRING> *files;
2073
  const char *wild;
2074
};
2075
2076
149 by Brian Aker
More bool conversion.
2077
static bool add_schema_table(THD *thd, plugin_ref plugin,
1 by brian
clean slate
2078
                                void* p_data)
2079
{
2080
  LEX_STRING *file_name= 0;
2081
  st_add_schema_table *data= (st_add_schema_table *)p_data;
2082
  List<LEX_STRING> *file_list= data->files;
2083
  const char *wild= data->wild;
2084
  ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
2085
2086
  if (schema_table->hidden)
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2087
      return(0);
1 by brian
clean slate
2088
  if (wild)
2089
  {
2090
    if (lower_case_table_names)
2091
    {
2092
      if (wild_case_compare(files_charset_info,
2093
                            schema_table->table_name,
2094
                            wild))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2095
        return(0);
1 by brian
clean slate
2096
    }
2097
    else if (wild_compare(schema_table->table_name, wild, 0))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2098
      return(0);
1 by brian
clean slate
2099
  }
2100
2101
  if ((file_name= thd->make_lex_string(file_name, schema_table->table_name,
2102
                                       strlen(schema_table->table_name),
163 by Brian Aker
Merge Monty's code.
2103
                                       true)) &&
1 by brian
clean slate
2104
      !file_list->push_back(file_name))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2105
    return(0);
2106
  return(1);
1 by brian
clean slate
2107
}
2108
2109
2110
int schema_tables_add(THD *thd, List<LEX_STRING> *files, const char *wild)
2111
{
2112
  LEX_STRING *file_name= 0;
2113
  ST_SCHEMA_TABLE *tmp_schema_table= schema_tables;
2114
  st_add_schema_table add_data;
2115
2116
  for (; tmp_schema_table->table_name; tmp_schema_table++)
2117
  {
2118
    if (tmp_schema_table->hidden)
2119
      continue;
2120
    if (wild)
2121
    {
2122
      if (lower_case_table_names)
2123
      {
2124
        if (wild_case_compare(files_charset_info,
2125
                              tmp_schema_table->table_name,
2126
                              wild))
2127
          continue;
2128
      }
2129
      else if (wild_compare(tmp_schema_table->table_name, wild, 0))
2130
        continue;
2131
    }
2132
    if ((file_name= 
2133
         thd->make_lex_string(file_name, tmp_schema_table->table_name,
163 by Brian Aker
Merge Monty's code.
2134
                              strlen(tmp_schema_table->table_name), true)) &&
1 by brian
clean slate
2135
        !files->push_back(file_name))
2136
      continue;
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2137
    return(1);
1 by brian
clean slate
2138
  }
2139
2140
  add_data.files= files;
2141
  add_data.wild= wild;
2142
  if (plugin_foreach(thd, add_schema_table,
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
2143
                     DRIZZLE_INFORMATION_SCHEMA_PLUGIN, &add_data))
259 by Brian Aker
First pass on PAM auth
2144
    return(1);
1 by brian
clean slate
2145
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2146
  return(0);
1 by brian
clean slate
2147
}
2148
2149
2150
/**
2151
  @brief          Create table names list
2152
2153
  @details        The function creates the list of table names in
2154
                  database
2155
2156
  @param[in]      thd                   thread handler
2157
  @param[in]      table_names           List of table names in database
2158
  @param[in]      lex                   pointer to LEX struct
2159
  @param[in]      lookup_field_vals     pointer to LOOKUP_FIELD_VALUE struct
163 by Brian Aker
Merge Monty's code.
2160
  @param[in]      with_i_schema         true means that we add I_S tables to list
1 by brian
clean slate
2161
  @param[in]      db_name               database name
2162
2163
  @return         Operation status
2164
    @retval       0           ok
2165
    @retval       1           fatal error
2166
    @retval       2           Not fatal error; Safe to ignore this file list
2167
*/
2168
2169
static int
2170
make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
2171
                     LOOKUP_FIELD_VALUES *lookup_field_vals,
2172
                     bool with_i_schema, LEX_STRING *db_name)
2173
{
2174
  char path[FN_REFLEN];
2175
  build_table_filename(path, sizeof(path), db_name->str, "", "", 0);
2176
  if (!lookup_field_vals->wild_table_value &&
2177
      lookup_field_vals->table_value.str)
2178
  {
2179
    if (with_i_schema)
2180
    {
2181
      if (find_schema_table(thd, lookup_field_vals->table_value.str))
2182
      {
2183
        if (table_names->push_back(&lookup_field_vals->table_value))
2184
          return 1;
2185
      }
2186
    }
2187
    else
2188
    {    
2189
      if (table_names->push_back(&lookup_field_vals->table_value))
2190
        return 1;
2191
    }
2192
    return 0;
2193
  }
2194
2195
  /*
2196
    This call will add all matching the wildcards (if specified) IS tables
2197
    to the list
2198
  */
2199
  if (with_i_schema)
2200
    return (schema_tables_add(thd, table_names,
2201
                              lookup_field_vals->table_value.str));
2202
2203
  find_files_result res= find_files(thd, table_names, db_name->str, path,
2204
                                    lookup_field_vals->table_value.str, 0);
2205
  if (res != FIND_FILES_OK)
2206
  {
2207
    /*
2208
      Downgrade errors about problems with database directory to
2209
      warnings if this is not a 'SHOW' command.  Another thread
2210
      may have dropped database, and we may still have a name
2211
      for that directory.
2212
    */
2213
    if (res == FIND_FILES_DIR)
2214
    {
2215
      if (lex->sql_command != SQLCOM_SELECT)
2216
        return 1;
2217
      thd->clear_error();
2218
      return 2;
2219
    }
2220
    return 1;
2221
  }
2222
  return 0;
2223
}
2224
2225
2226
/**
2227
  @brief          Fill I_S table for SHOW COLUMNS|INDEX commands
2228
2229
  @param[in]      thd                      thread handler
327.2.4 by Brian Aker
Refactoring table.h
2230
  @param[in]      tables                   TableList for I_S table
1 by brian
clean slate
2231
  @param[in]      schema_table             pointer to I_S structure
2232
  @param[in]      open_tables_state_backup pointer to Open_tables_state object
2233
                                           which is used to save|restore original
2234
                                           status of variables related to
2235
                                           open tables state
2236
2237
  @return         Operation status
2238
    @retval       0           success
2239
    @retval       1           error
2240
*/
2241
2242
static int 
327.2.4 by Brian Aker
Refactoring table.h
2243
fill_schema_show_cols_or_idxs(THD *thd, TableList *tables,
1 by brian
clean slate
2244
                              ST_SCHEMA_TABLE *schema_table,
2245
                              Open_tables_state *open_tables_state_backup)
2246
{
2247
  LEX *lex= thd->lex;
2248
  bool res;
2249
  LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name;
2250
  enum_sql_command save_sql_command= lex->sql_command;
327.2.4 by Brian Aker
Refactoring table.h
2251
  TableList *show_table_list= (TableList*) tables->schema_select_lex->
1 by brian
clean slate
2252
    table_list.first;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2253
  Table *table= tables->table;
1 by brian
clean slate
2254
  int error= 1;
2255
2256
  lex->all_selects_list= tables->schema_select_lex;
2257
  /*
2258
    Restore thd->temporary_tables to be able to process
2259
    temporary tables(only for 'show index' & 'show columns').
2260
    This should be changed when processing of temporary tables for
2261
    I_S tables will be done.
2262
  */
2263
  thd->temporary_tables= open_tables_state_backup->temporary_tables;
2264
  /*
2265
    Let us set fake sql_command so views won't try to merge
2266
    themselves into main statement. If we don't do this,
2267
    SELECT * from information_schema.xxxx will cause problems.
2268
    SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()' 
2269
  */
2270
  lex->sql_command= SQLCOM_SHOW_FIELDS;
2271
  res= open_normal_and_derived_tables(thd, show_table_list,
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
2272
                                      DRIZZLE_LOCK_IGNORE_FLUSH);
1 by brian
clean slate
2273
  lex->sql_command= save_sql_command;
2274
  /*
2275
    get_all_tables() returns 1 on failure and 0 on success thus
2276
    return only these and not the result code of ::process_table()
2277
2278
    We should use show_table_list->alias instead of 
2279
    show_table_list->table_name because table_name
2280
    could be changed during opening of I_S tables. It's safe
2281
    to use alias because alias contains original table name 
2282
    in this case(this part of code is used only for 
2283
    'show columns' & 'show statistics' commands).
2284
  */
2285
   table_name= thd->make_lex_string(&tmp_lex_string1, show_table_list->alias,
163 by Brian Aker
Merge Monty's code.
2286
                                    strlen(show_table_list->alias), false);
1 by brian
clean slate
2287
   db_name= thd->make_lex_string(&tmp_lex_string, show_table_list->db,
163 by Brian Aker
Merge Monty's code.
2288
                                 show_table_list->db_length, false);
1 by brian
clean slate
2289
      
2290
2291
   error= test(schema_table->process_table(thd, show_table_list,
2292
                                           table, res, db_name,
2293
                                           table_name));
2294
   thd->temporary_tables= 0;
2295
   close_tables_for_reopen(thd, &show_table_list);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2296
   return(error);
1 by brian
clean slate
2297
}
2298
2299
2300
/**
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2301
  @brief          Fill I_S table for SHOW Table NAMES commands
1 by brian
clean slate
2302
2303
  @param[in]      thd                      thread handler
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2304
  @param[in]      table                    Table struct for I_S table
1 by brian
clean slate
2305
  @param[in]      db_name                  database name
2306
  @param[in]      table_name               table name
163 by Brian Aker
Merge Monty's code.
2307
  @param[in]      with_i_schema            I_S table if true
1 by brian
clean slate
2308
2309
  @return         Operation status
2310
    @retval       0           success
2311
    @retval       1           error
2312
*/
2313
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2314
static int fill_schema_table_names(THD *thd, Table *table,
1 by brian
clean slate
2315
                                   LEX_STRING *db_name, LEX_STRING *table_name,
2316
                                   bool with_i_schema)
2317
{
2318
  if (with_i_schema)
2319
  {
2320
    table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
2321
                           system_charset_info);
2322
  }
2323
  else
2324
  {
2325
    enum legacy_db_type not_used;
2326
    char path[FN_REFLEN];
2327
    (void) build_table_filename(path, sizeof(path), db_name->str, 
2328
                                table_name->str, reg_ext, 0);
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2329
    if (mysql_frm_type(thd, path, &not_used)) 
2330
    {
2331
      table->field[3]->store(STRING_WITH_LEN("BASE Table"),
2332
                             system_charset_info);
2333
    }
2334
    else
2335
    {
1 by brian
clean slate
2336
      table->field[3]->store(STRING_WITH_LEN("ERROR"),
2337
                             system_charset_info);
2338
    }
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2339
1 by brian
clean slate
2340
    if (thd->is_error() && thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2341
    {
2342
      thd->clear_error();
2343
      return 0;
2344
    }
2345
  }
2346
  if (schema_table_store_record(thd, table))
2347
    return 1;
2348
  return 0;
2349
}
2350
2351
2352
/**
2353
  @brief          Get open table method
2354
2355
  @details        The function calculates the method which will be used
2356
                  for table opening:
2357
                  SKIP_OPEN_TABLE - do not open table
2358
                  OPEN_FRM_ONLY   - open FRM file only
2359
                  OPEN_FULL_TABLE - open FRM, data, index files
2360
  @param[in]      tables               I_S table table_list
2361
  @param[in]      schema_table         I_S table struct
2362
  @param[in]      schema_table_idx     I_S table index
2363
2364
  @return         return a set of flags
2365
    @retval       SKIP_OPEN_TABLE | OPEN_FRM_ONLY | OPEN_FULL_TABLE
2366
*/
2367
327.2.4 by Brian Aker
Refactoring table.h
2368
static uint get_table_open_method(TableList *tables,
1 by brian
clean slate
2369
                                  ST_SCHEMA_TABLE *schema_table,
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
2370
                                  enum enum_schema_tables schema_table_idx __attribute__((unused)))
1 by brian
clean slate
2371
{
2372
  /*
2373
    determine which method will be used for table opening
2374
  */
2375
  if (schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
2376
  {
2377
    Field **ptr, *field;
2378
    int table_open_method= 0, field_indx= 0;
2379
    for (ptr=tables->table->field; (field= *ptr) ; ptr++)
2380
    {
2381
      if (bitmap_is_set(tables->table->read_set, field->field_index))
2382
        table_open_method|= schema_table->fields_info[field_indx].open_method;
2383
      field_indx++;
2384
    }
2385
    return table_open_method;
2386
  }
2387
  /* I_S tables which use get_all_tables but can not be optimized */
2388
  return (uint) OPEN_FULL_TABLE;
2389
}
2390
2391
2392
/**
2393
  @brief          Fill I_S table with data from FRM file only
2394
2395
  @param[in]      thd                      thread handler
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2396
  @param[in]      table                    Table struct for I_S table
1 by brian
clean slate
2397
  @param[in]      schema_table             I_S table struct
2398
  @param[in]      db_name                  database name
2399
  @param[in]      table_name               table name
2400
  @param[in]      schema_table_idx         I_S table index
2401
2402
  @return         Operation status
2403
    @retval       0           Table is processed and we can continue
2404
                              with new table
2405
    @retval       1           It's view and we have to use
2406
                              open_tables function for this table
2407
*/
2408
327.2.4 by Brian Aker
Refactoring table.h
2409
static int fill_schema_table_from_frm(THD *thd,TableList *tables,
77.1.46 by Monty Taylor
Finished the warnings work!
2410
                                      ST_SCHEMA_TABLE *schema_table,
1 by brian
clean slate
2411
                                      LEX_STRING *db_name,
2412
                                      LEX_STRING *table_name,
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
2413
                                      enum enum_schema_tables schema_table_idx __attribute__((unused)))
1 by brian
clean slate
2414
{
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2415
  Table *table= tables->table;
1 by brian
clean slate
2416
  TABLE_SHARE *share;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2417
  Table tbl;
327.2.4 by Brian Aker
Refactoring table.h
2418
  TableList table_list;
1 by brian
clean slate
2419
  uint res= 0;
2420
  int error;
2421
  char key[MAX_DBKEY_LENGTH];
2422
  uint key_length;
2423
327.2.4 by Brian Aker
Refactoring table.h
2424
  memset(&table_list, 0, sizeof(TableList));
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2425
  memset(&tbl, 0, sizeof(Table));
1 by brian
clean slate
2426
2427
  table_list.table_name= table_name->str;
2428
  table_list.db= db_name->str;
2429
2430
  key_length= create_table_def_key(thd, key, &table_list, 0);
2431
  pthread_mutex_lock(&LOCK_open);
2432
  share= get_table_share(thd, &table_list, key,
357 by Brian Aker
flag cleanup
2433
                         key_length, 0, &error);
1 by brian
clean slate
2434
  if (!share)
2435
  {
2436
    res= 0;
2437
    goto err;
2438
  }
2439
2440
  {
2441
    tbl.s= share;
2442
    table_list.table= &tbl;
2443
    res= schema_table->process_table(thd, &table_list, table,
2444
                                     res, db_name, table_name);
2445
  }
2446
2447
  release_table_share(share, RELEASE_NORMAL);
2448
2449
err:
2450
  pthread_mutex_unlock(&LOCK_open);
2451
  thd->clear_error();
2452
  return res;
2453
}
2454
2455
2456
2457
/**
2458
  @brief          Fill I_S tables whose data are retrieved
2459
                  from frm files and storage engine
2460
2461
  @details        The information schema tables are internally represented as
2462
                  temporary tables that are filled at query execution time.
2463
                  Those I_S tables whose data are retrieved
2464
                  from frm files and storage engine are filled by the function
2465
                  get_all_tables().
2466
2467
  @param[in]      thd                      thread handler
2468
  @param[in]      tables                   I_S table
2469
  @param[in]      cond                     'WHERE' condition
2470
2471
  @return         Operation status
2472
    @retval       0                        success
2473
    @retval       1                        error
2474
*/
2475
327.2.4 by Brian Aker
Refactoring table.h
2476
int get_all_tables(THD *thd, TableList *tables, COND *cond)
1 by brian
clean slate
2477
{
2478
  LEX *lex= thd->lex;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2479
  Table *table= tables->table;
1 by brian
clean slate
2480
  SELECT_LEX *old_all_select_lex= lex->all_selects_list;
2481
  enum_sql_command save_sql_command= lex->sql_command;
2482
  SELECT_LEX *lsel= tables->schema_select_lex;
2483
  ST_SCHEMA_TABLE *schema_table= tables->schema_table;
2484
  SELECT_LEX sel;
2485
  LOOKUP_FIELD_VALUES lookup_field_vals;
2486
  LEX_STRING *db_name, *table_name;
2487
  bool with_i_schema;
2488
  enum enum_schema_tables schema_table_idx;
2489
  List<LEX_STRING> db_names;
2490
  List_iterator_fast<LEX_STRING> it(db_names);
2491
  COND *partial_cond= 0;
2492
  uint derived_tables= lex->derived_tables; 
2493
  int error= 1;
2494
  Open_tables_state open_tables_state_backup;
2495
  Query_tables_list query_tables_list_backup;
2496
  uint table_open_method;
2497
  bool old_value= thd->no_warnings_for_error;
2498
2499
  lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
2500
2501
  /*
2502
    We should not introduce deadlocks even if we already have some
2503
    tables open and locked, since we won't lock tables which we will
2504
    open and will ignore possible name-locks for these tables.
2505
  */
2506
  thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
2507
2508
  schema_table_idx= get_schema_table_idx(schema_table);
2509
  tables->table_open_method= table_open_method=
2510
    get_table_open_method(tables, schema_table, schema_table_idx);
2511
  /* 
2512
    this branch processes SHOW FIELDS, SHOW INDEXES commands.
2513
    see sql_parse.cc, prepare_schema_table() function where
2514
    this values are initialized
2515
  */
2516
  if (lsel && lsel->table_list.first)
2517
  {
2518
    error= fill_schema_show_cols_or_idxs(thd, tables, schema_table,
2519
                                         &open_tables_state_backup);
2520
    goto err;
2521
  }
2522
2523
  if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
2524
  {
2525
    error= 0;
2526
    goto err;
2527
  }
2528
2529
  if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
2530
  {
2531
    /* 
2532
      if lookup value is empty string then
2533
      it's impossible table name or db name
2534
    */
140 by Brian Aker
Remove dead class, clean up warning.
2535
    if ((lookup_field_vals.db_value.str && !lookup_field_vals.db_value.str[0]) ||
2536
        (lookup_field_vals.table_value.str && !lookup_field_vals.table_value.str[0]))
1 by brian
clean slate
2537
    {
2538
      error= 0;
2539
      goto err;
2540
    }
2541
  }
2542
2543
  if (lookup_field_vals.db_value.length &&
2544
      !lookup_field_vals.wild_db_value)
163 by Brian Aker
Merge Monty's code.
2545
    tables->has_db_lookup_value= true;
1 by brian
clean slate
2546
  if (lookup_field_vals.table_value.length &&
2547
      !lookup_field_vals.wild_table_value) 
163 by Brian Aker
Merge Monty's code.
2548
    tables->has_table_lookup_value= true;
1 by brian
clean slate
2549
2550
  if (tables->has_db_lookup_value && tables->has_table_lookup_value)
2551
    partial_cond= 0;
2552
  else
2553
    partial_cond= make_cond_for_info_schema(cond, tables);
2554
2555
  if (lex->describe)
2556
  {
2557
    /* EXPLAIN SELECT */
2558
    error= 0;
2559
    goto err;
2560
  }
2561
2562
  if (make_db_list(thd, &db_names, &lookup_field_vals, &with_i_schema))
2563
    goto err;
2564
  it.rewind(); /* To get access to new elements in basis list */
2565
  while ((db_name= it++))
2566
  {
2567
    {
2568
      thd->no_warnings_for_error= 1;
2569
      List<LEX_STRING> table_names;
2570
      int res= make_table_name_list(thd, &table_names, lex,
2571
                                    &lookup_field_vals,
2572
                                    with_i_schema, db_name);
2573
      if (res == 2)   /* Not fatal error, continue */
2574
        continue;
2575
      if (res)
2576
        goto err;
2577
2578
      List_iterator_fast<LEX_STRING> it_files(table_names);
2579
      while ((table_name= it_files++))
2580
      {
2581
	restore_record(table, s->default_values);
2582
        table->field[schema_table->idx_field1]->
2583
          store(db_name->str, db_name->length, system_charset_info);
2584
        table->field[schema_table->idx_field2]->
2585
          store(table_name->str, table_name->length, system_charset_info);
2586
2587
        if (!partial_cond || partial_cond->val_int())
2588
        {
2589
          /*
2590
            If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN)
2591
            we can skip table opening and we don't have lookup value for 
2592
            table name or lookup value is wild string(table name list is
2593
            already created by make_table_name_list() function).
2594
          */
2595
          if (!table_open_method && schema_table_idx == SCH_TABLES &&
2596
              (!lookup_field_vals.table_value.length ||
2597
               lookup_field_vals.wild_table_value))
2598
          {
2599
            if (schema_table_store_record(thd, table))
2600
              goto err;      /* Out of space in temporary table */
2601
            continue;
2602
          }
2603
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2604
          /* SHOW Table NAMES command */
1 by brian
clean slate
2605
          if (schema_table_idx == SCH_TABLE_NAMES)
2606
          {
2607
            if (fill_schema_table_names(thd, tables->table, db_name,
2608
                                        table_name, with_i_schema))
2609
              continue;
2610
          }
2611
          else
2612
          {
2613
            if (!(table_open_method & ~OPEN_FRM_ONLY) &&
2614
                !with_i_schema)
2615
            {
2616
              if (!fill_schema_table_from_frm(thd, tables, schema_table, db_name,
2617
                                              table_name, schema_table_idx))
2618
                continue;
2619
            }
2620
2621
            int res;
2622
            LEX_STRING tmp_lex_string, orig_db_name;
2623
            /*
2624
              Set the parent lex of 'sel' because it is needed by
2625
              sel.init_query() which is called inside make_table_list.
2626
            */
2627
            thd->no_warnings_for_error= 1;
2628
            sel.parent_lex= lex;
2629
            /* db_name can be changed in make_table_list() func */
2630
            if (!thd->make_lex_string(&orig_db_name, db_name->str,
163 by Brian Aker
Merge Monty's code.
2631
                                      db_name->length, false))
1 by brian
clean slate
2632
              goto err;
2633
            if (make_table_list(thd, &sel, db_name, table_name))
2634
              goto err;
327.2.4 by Brian Aker
Refactoring table.h
2635
            TableList *show_table_list= (TableList*) sel.table_list.first;
1 by brian
clean slate
2636
            lex->all_selects_list= &sel;
2637
            lex->derived_tables= 0;
2638
            lex->sql_command= SQLCOM_SHOW_FIELDS;
2639
            show_table_list->i_s_requested_object=
2640
              schema_table->i_s_requested_object;
2641
            res= open_normal_and_derived_tables(thd, show_table_list,
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
2642
                                                DRIZZLE_LOCK_IGNORE_FLUSH);
1 by brian
clean slate
2643
            lex->sql_command= save_sql_command;
2644
            /*
2645
              XXX:  show_table_list has a flag i_is_requested,
2646
              and when it's set, open_normal_and_derived_tables()
2647
              can return an error without setting an error message
2648
              in THD, which is a hack. This is why we have to
2649
              check for res, then for thd->is_error() only then
2650
              for thd->main_da.sql_errno().
2651
            */
2652
            if (res && thd->is_error() &&
2653
                thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2654
            {
2655
              /*
2656
                Hide error for not existing table.
2657
                This error can occur for example when we use
2658
                where condition with db name and table name and this
2659
                table does not exist.
2660
              */
2661
              res= 0;
2662
              thd->clear_error();
2663
            }
2664
            else
2665
            {
2666
              /*
2667
                We should use show_table_list->alias instead of 
2668
                show_table_list->table_name because table_name
2669
                could be changed during opening of I_S tables. It's safe
2670
                to use alias because alias contains original table name 
2671
                in this case.
2672
              */
2673
              thd->make_lex_string(&tmp_lex_string, show_table_list->alias,
163 by Brian Aker
Merge Monty's code.
2674
                                   strlen(show_table_list->alias), false);
1 by brian
clean slate
2675
              res= schema_table->process_table(thd, show_table_list, table,
2676
                                               res, &orig_db_name,
2677
                                               &tmp_lex_string);
2678
              close_tables_for_reopen(thd, &show_table_list);
2679
            }
51.1.75 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
2680
            assert(!lex->query_tables_own_last);
1 by brian
clean slate
2681
            if (res)
2682
              goto err;
2683
          }
2684
        }
2685
      }
2686
      /*
2687
        If we have information schema its always the first table and only
2688
        the first table. Reset for other tables.
2689
      */
2690
      with_i_schema= 0;
2691
    }
2692
  }
2693
2694
  error= 0;
2695
err:
2696
  thd->restore_backup_open_tables_state(&open_tables_state_backup);
2697
  lex->restore_backup_query_tables_list(&query_tables_list_backup);
2698
  lex->derived_tables= derived_tables;
2699
  lex->all_selects_list= old_all_select_lex;
2700
  lex->sql_command= save_sql_command;
2701
  thd->no_warnings_for_error= old_value;
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2702
  return(error);
1 by brian
clean slate
2703
}
2704
2705
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2706
bool store_schema_shemata(THD* thd, Table *table, LEX_STRING *db_name,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
2707
                          const CHARSET_INFO * const cs)
1 by brian
clean slate
2708
{
2709
  restore_record(table, s->default_values);
2710
  table->field[1]->store(db_name->str, db_name->length, system_charset_info);
2711
  table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
2712
  table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
2713
  return schema_table_store_record(thd, table);
2714
}
2715
2716
327.2.4 by Brian Aker
Refactoring table.h
2717
int fill_schema_schemata(THD *thd, TableList *tables, COND *cond)
1 by brian
clean slate
2718
{
2719
  /*
2720
    TODO: fill_schema_shemata() is called when new client is connected.
2721
    Returning error status in this case leads to client hangup.
2722
  */
2723
2724
  LOOKUP_FIELD_VALUES lookup_field_vals;
2725
  List<LEX_STRING> db_names;
2726
  LEX_STRING *db_name;
2727
  bool with_i_schema;
2728
  HA_CREATE_INFO create;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2729
  Table *table= tables->table;
1 by brian
clean slate
2730
2731
  if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2732
    return(0);
1 by brian
clean slate
2733
  if (make_db_list(thd, &db_names, &lookup_field_vals,
2734
                   &with_i_schema))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2735
    return(1);
1 by brian
clean slate
2736
2737
  /*
2738
    If we have lookup db value we should check that the database exists
2739
  */
2740
  if(lookup_field_vals.db_value.str && !lookup_field_vals.wild_db_value &&
2741
     !with_i_schema)
2742
  {
2743
    char path[FN_REFLEN+16];
2744
    uint path_len;
15 by brian
Fix for stat, NETWARE removal
2745
    struct stat stat_info;
1 by brian
clean slate
2746
    if (!lookup_field_vals.db_value.str[0])
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2747
      return(0);
1 by brian
clean slate
2748
    path_len= build_table_filename(path, sizeof(path),
2749
                                   lookup_field_vals.db_value.str, "", "", 0);
2750
    path[path_len-1]= 0;
15 by brian
Fix for stat, NETWARE removal
2751
    if (stat(path,&stat_info))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2752
      return(0);
1 by brian
clean slate
2753
  }
2754
2755
  List_iterator_fast<LEX_STRING> it(db_names);
2756
  while ((db_name=it++))
2757
  {
2758
    if (with_i_schema)       // information schema name is always first in list
2759
    {
2760
      if (store_schema_shemata(thd, table, db_name,
2761
                               system_charset_info))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2762
        return(1);
1 by brian
clean slate
2763
      with_i_schema= 0;
2764
      continue;
2765
    }
2766
    {
2767
      load_db_opt_by_name(thd, db_name->str, &create);
2768
      if (store_schema_shemata(thd, table, db_name,
2769
                               create.default_table_charset))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2770
        return(1);
1 by brian
clean slate
2771
    }
2772
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2773
  return(0);
1 by brian
clean slate
2774
}
2775
2776
327.2.4 by Brian Aker
Refactoring table.h
2777
static int get_schema_tables_record(THD *thd, TableList *tables,
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2778
				    Table *table, bool res,
1 by brian
clean slate
2779
				    LEX_STRING *db_name,
2780
				    LEX_STRING *table_name)
2781
{
2782
  const char *tmp_buff;
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
2783
  DRIZZLE_TIME time;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
2784
  const CHARSET_INFO * const cs= system_charset_info;
1 by brian
clean slate
2785
2786
  restore_record(table, s->default_values);
2787
  table->field[1]->store(db_name->str, db_name->length, cs);
2788
  table->field[2]->store(table_name->str, table_name->length, cs);
2789
  if (res)
2790
  {
2791
    /*
2792
      there was errors during opening tables
2793
    */
2794
    const char *error= thd->is_error() ? thd->main_da.message() : "";
2795
    if (tables->schema_table)
2796
      table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2797
    else
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2798
      table->field[3]->store(STRING_WITH_LEN("BASE Table"), cs);
1 by brian
clean slate
2799
    table->field[20]->store(error, strlen(error), cs);
2800
    thd->clear_error();
2801
  }
2802
  else
2803
  {
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
2804
    char option_buff[400],*ptr;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2805
    Table *show_table= tables->table;
1 by brian
clean slate
2806
    TABLE_SHARE *share= show_table->s;
2807
    handler *file= show_table->file;
2808
    handlerton *tmp_db_type= share->db_type();
2809
    if (share->tmp_table == SYSTEM_TMP_TABLE)
2810
      table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2811
    else if (share->tmp_table)
2812
      table->field[3]->store(STRING_WITH_LEN("LOCAL TEMPORARY"), cs);
2813
    else
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2814
      table->field[3]->store(STRING_WITH_LEN("BASE Table"), cs);
1 by brian
clean slate
2815
2816
    for (int i= 4; i < 20; i++)
2817
    {
2818
      if (i == 7 || (i > 12 && i < 17) || i == 18)
2819
        continue;
2820
      table->field[i]->set_notnull();
2821
    }
2822
    tmp_buff= (char *) ha_resolve_storage_engine_name(tmp_db_type);
2823
    table->field[4]->store(tmp_buff, strlen(tmp_buff), cs);
163 by Brian Aker
Merge Monty's code.
2824
    table->field[5]->store((int64_t) share->frm_version, true);
1 by brian
clean slate
2825
2826
    ptr=option_buff;
2827
    if (share->min_rows)
2828
    {
411.1.1 by Brian Aker
Work on removing GNU specific calls.
2829
      ptr=my_stpcpy(ptr," min_rows=");
152 by Brian Aker
longlong replacement
2830
      ptr=int64_t10_to_str(share->min_rows,ptr,10);
1 by brian
clean slate
2831
    }
2832
    if (share->max_rows)
2833
    {
411.1.1 by Brian Aker
Work on removing GNU specific calls.
2834
      ptr=my_stpcpy(ptr," max_rows=");
152 by Brian Aker
longlong replacement
2835
      ptr=int64_t10_to_str(share->max_rows,ptr,10);
1 by brian
clean slate
2836
    }
2837
    if (share->avg_row_length)
2838
    {
411.1.1 by Brian Aker
Work on removing GNU specific calls.
2839
      ptr=my_stpcpy(ptr," avg_row_length=");
152 by Brian Aker
longlong replacement
2840
      ptr=int64_t10_to_str(share->avg_row_length,ptr,10);
1 by brian
clean slate
2841
    }
2842
    if (share->db_create_options & HA_OPTION_PACK_KEYS)
411.1.1 by Brian Aker
Work on removing GNU specific calls.
2843
      ptr=my_stpcpy(ptr," pack_keys=1");
1 by brian
clean slate
2844
    if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
411.1.1 by Brian Aker
Work on removing GNU specific calls.
2845
      ptr=my_stpcpy(ptr," pack_keys=0");
1 by brian
clean slate
2846
    /* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
2847
    if (share->db_create_options & HA_OPTION_CHECKSUM)
411.1.1 by Brian Aker
Work on removing GNU specific calls.
2848
      ptr=my_stpcpy(ptr," checksum=1");
1 by brian
clean slate
2849
    if (share->page_checksum != HA_CHOICE_UNDEF)
2850
      ptr= strxmov(ptr, " page_checksum=",
461 by Monty Taylor
Removed NullS. bu-bye.
2851
                   ha_choice_values[(uint) share->page_checksum], NULL);
1 by brian
clean slate
2852
    if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
411.1.1 by Brian Aker
Work on removing GNU specific calls.
2853
      ptr=my_stpcpy(ptr," delay_key_write=1");
1 by brian
clean slate
2854
    if (share->row_type != ROW_TYPE_DEFAULT)
2855
      ptr=strxmov(ptr, " row_format=", 
2856
                  ha_row_type[(uint) share->row_type],
461 by Monty Taylor
Removed NullS. bu-bye.
2857
                  NULL);
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
2858
    if (share->block_size)
2859
    {
411.1.1 by Brian Aker
Work on removing GNU specific calls.
2860
      ptr= my_stpcpy(ptr, " block_size=");
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
2861
      ptr= int64_t10_to_str(share->block_size, ptr, 10);
2862
    }
2863
    
1 by brian
clean slate
2864
    if (share->transactional != HA_CHOICE_UNDEF)
2865
    {
2866
      ptr= strxmov(ptr, " TRANSACTIONAL=",
2867
                   (share->transactional == HA_CHOICE_YES ? "1" : "0"),
461 by Monty Taylor
Removed NullS. bu-bye.
2868
                   NULL);
1 by brian
clean slate
2869
    }
2870
    if (share->transactional != HA_CHOICE_UNDEF)
2871
      ptr= strxmov(ptr, " transactional=",
461 by Monty Taylor
Removed NullS. bu-bye.
2872
                   ha_choice_values[(uint) share->transactional], NULL);
1 by brian
clean slate
2873
    table->field[19]->store(option_buff+1,
2874
                            (ptr == option_buff ? 0 : 
2875
                             (uint) (ptr-option_buff)-1), cs);
2876
2877
    tmp_buff= (share->table_charset ?
2878
               share->table_charset->name : "default");
2879
    table->field[17]->store(tmp_buff, strlen(tmp_buff), cs);
2880
2881
    if (share->comment.str)
2882
      table->field[20]->store(share->comment.str, share->comment.length, cs);
2883
2884
    if(file)
2885
    {
2886
      file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO |
2887
                 HA_STATUS_NO_LOCK);
2888
      enum row_type row_type = file->get_row_type();
2889
      switch (row_type) {
2890
      case ROW_TYPE_NOT_USED:
2891
      case ROW_TYPE_DEFAULT:
2892
        tmp_buff= ((share->db_options_in_use &
2893
                    HA_OPTION_COMPRESS_RECORD) ? "Compressed" :
2894
                   (share->db_options_in_use & HA_OPTION_PACK_RECORD) ?
2895
                   "Dynamic" : "Fixed");
2896
        break;
2897
      case ROW_TYPE_FIXED:
2898
        tmp_buff= "Fixed";
2899
        break;
2900
      case ROW_TYPE_DYNAMIC:
2901
        tmp_buff= "Dynamic";
2902
        break;
2903
      case ROW_TYPE_COMPRESSED:
2904
        tmp_buff= "Compressed";
2905
        break;
2906
      case ROW_TYPE_REDUNDANT:
2907
        tmp_buff= "Redundant";
2908
        break;
2909
      case ROW_TYPE_COMPACT:
2910
        tmp_buff= "Compact";
2911
        break;
2912
      case ROW_TYPE_PAGE:
2913
        tmp_buff= "Paged";
2914
        break;
2915
      }
2916
      table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
2917
      if (!tables->schema_table)
2918
      {
163 by Brian Aker
Merge Monty's code.
2919
        table->field[7]->store((int64_t) file->stats.records, true);
1 by brian
clean slate
2920
        table->field[7]->set_notnull();
2921
      }
163 by Brian Aker
Merge Monty's code.
2922
      table->field[8]->store((int64_t) file->stats.mean_rec_length, true);
2923
      table->field[9]->store((int64_t) file->stats.data_file_length, true);
1 by brian
clean slate
2924
      if (file->stats.max_data_file_length)
2925
      {
152 by Brian Aker
longlong replacement
2926
        table->field[10]->store((int64_t) file->stats.max_data_file_length,
163 by Brian Aker
Merge Monty's code.
2927
                                true);
1 by brian
clean slate
2928
      }
163 by Brian Aker
Merge Monty's code.
2929
      table->field[11]->store((int64_t) file->stats.index_file_length, true);
2930
      table->field[12]->store((int64_t) file->stats.delete_length, true);
1 by brian
clean slate
2931
      if (show_table->found_next_number_field)
2932
      {
152 by Brian Aker
longlong replacement
2933
        table->field[13]->store((int64_t) file->stats.auto_increment_value,
163 by Brian Aker
Merge Monty's code.
2934
                                true);
1 by brian
clean slate
2935
        table->field[13]->set_notnull();
2936
      }
2937
      if (file->stats.create_time)
2938
      {
2939
        thd->variables.time_zone->gmt_sec_to_TIME(&time,
2940
                                                  (my_time_t) file->stats.create_time);
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
2941
        table->field[14]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
1 by brian
clean slate
2942
        table->field[14]->set_notnull();
2943
      }
2944
      if (file->stats.update_time)
2945
      {
2946
        thd->variables.time_zone->gmt_sec_to_TIME(&time,
2947
                                                  (my_time_t) file->stats.update_time);
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
2948
        table->field[15]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
1 by brian
clean slate
2949
        table->field[15]->set_notnull();
2950
      }
2951
      if (file->stats.check_time)
2952
      {
2953
        thd->variables.time_zone->gmt_sec_to_TIME(&time,
2954
                                                  (my_time_t) file->stats.check_time);
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
2955
        table->field[16]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
1 by brian
clean slate
2956
        table->field[16]->set_notnull();
2957
      }
2958
      if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
2959
      {
163 by Brian Aker
Merge Monty's code.
2960
        table->field[18]->store((int64_t) file->checksum(), true);
1 by brian
clean slate
2961
        table->field[18]->set_notnull();
2962
      }
2963
    }
2964
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2965
  return(schema_table_store_record(thd, table));
1 by brian
clean slate
2966
}
2967
2968
2969
/**
2970
  @brief    Store field characteristics into appropriate I_S table columns
2971
2972
  @param[in]      table             I_S table
2973
  @param[in]      field             processed field
2974
  @param[in]      cs                I_S table charset
2975
  @param[in]      offset            offset from beginning of table
2976
                                    to DATE_TYPE column in I_S table
2977
                                    
2978
  @return         void
2979
*/
2980
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2981
void store_column_type(Table *table, Field *field, const CHARSET_INFO * const cs,
1 by brian
clean slate
2982
                       uint offset)
2983
{
2984
  bool is_blob;
2985
  int decimals, field_length;
2986
  const char *tmp_buff;
2987
  char column_type_buff[MAX_FIELD_WIDTH];
2988
  String column_type(column_type_buff, sizeof(column_type_buff), cs);
2989
2990
  field->sql_type(column_type);
2991
  /* DTD_IDENTIFIER column */
2992
  table->field[offset + 7]->store(column_type.ptr(), column_type.length(), cs);
2993
  table->field[offset + 7]->set_notnull();
2994
  tmp_buff= strchr(column_type.ptr(), '(');
2995
  /* DATA_TYPE column */
2996
  table->field[offset]->store(column_type.ptr(),
2997
                         (tmp_buff ? tmp_buff - column_type.ptr() :
2998
                          column_type.length()), cs);
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
2999
  is_blob= (field->type() == DRIZZLE_TYPE_BLOB);
1 by brian
clean slate
3000
  if (field->has_charset() || is_blob ||
238 by Brian Aker
Pass through sql_show to remove type to be removed.
3001
      field->real_type() == DRIZZLE_TYPE_VARCHAR)  // For varbinary type
1 by brian
clean slate
3002
  {
205 by Brian Aker
uint32 -> uin32_t
3003
    uint32_t octet_max_length= field->max_display_length();
3004
    if (is_blob && octet_max_length != (uint32_t) 4294967295U)
1 by brian
clean slate
3005
      octet_max_length /= field->charset()->mbmaxlen;
152 by Brian Aker
longlong replacement
3006
    int64_t char_max_len= is_blob ? 
3007
      (int64_t) octet_max_length / field->charset()->mbminlen :
3008
      (int64_t) octet_max_length / field->charset()->mbmaxlen;
1 by brian
clean slate
3009
    /* CHARACTER_MAXIMUM_LENGTH column*/
163 by Brian Aker
Merge Monty's code.
3010
    table->field[offset + 1]->store(char_max_len, true);
1 by brian
clean slate
3011
    table->field[offset + 1]->set_notnull();
3012
    /* CHARACTER_OCTET_LENGTH column */
163 by Brian Aker
Merge Monty's code.
3013
    table->field[offset + 2]->store((int64_t) octet_max_length, true);
1 by brian
clean slate
3014
    table->field[offset + 2]->set_notnull();
3015
  }
3016
3017
  /*
3018
    Calculate field_length and decimals.
3019
    They are set to -1 if they should not be set (we should return NULL)
3020
  */
3021
3022
  decimals= field->decimals();
3023
  switch (field->type()) {
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
3024
  case DRIZZLE_TYPE_NEWDECIMAL:
1 by brian
clean slate
3025
    field_length= ((Field_new_decimal*) field)->precision;
3026
    break;
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
3027
  case DRIZZLE_TYPE_TINY:
3028
  case DRIZZLE_TYPE_LONG:
3029
  case DRIZZLE_TYPE_LONGLONG:
1 by brian
clean slate
3030
    field_length= field->max_display_length() - 1;
3031
    break;
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
3032
  case DRIZZLE_TYPE_DOUBLE:
1 by brian
clean slate
3033
    field_length= field->field_length;
3034
    if (decimals == NOT_FIXED_DEC)
3035
      decimals= -1;                           // return NULL
3036
    break;
3037
  default:
3038
    field_length= decimals= -1;
3039
    break;
3040
  }
3041
3042
  /* NUMERIC_PRECISION column */
3043
  if (field_length >= 0)
3044
  {
163 by Brian Aker
Merge Monty's code.
3045
    table->field[offset + 3]->store((int64_t) field_length, true);
1 by brian
clean slate
3046
    table->field[offset + 3]->set_notnull();
3047
  }
3048
  /* NUMERIC_SCALE column */
3049
  if (decimals >= 0)
3050
  {
163 by Brian Aker
Merge Monty's code.
3051
    table->field[offset + 4]->store((int64_t) decimals, true);
1 by brian
clean slate
3052
    table->field[offset + 4]->set_notnull();
3053
  }
3054
  if (field->has_charset())
3055
  {
3056
    /* CHARACTER_SET_NAME column*/
3057
    tmp_buff= field->charset()->csname;
3058
    table->field[offset + 5]->store(tmp_buff, strlen(tmp_buff), cs);
3059
    table->field[offset + 5]->set_notnull();
3060
    /* COLLATION_NAME column */
3061
    tmp_buff= field->charset()->name;
3062
    table->field[offset + 6]->store(tmp_buff, strlen(tmp_buff), cs);
3063
    table->field[offset + 6]->set_notnull();
3064
  }
3065
}
3066
3067
327.2.4 by Brian Aker
Refactoring table.h
3068
static int get_schema_column_record(THD *thd, TableList *tables,
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3069
				    Table *table, bool res,
1 by brian
clean slate
3070
				    LEX_STRING *db_name,
3071
				    LEX_STRING *table_name)
3072
{
3073
  LEX *lex= thd->lex;
461 by Monty Taylor
Removed NullS. bu-bye.
3074
  const char *wild= lex->wild ? lex->wild->ptr() : NULL;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3075
  const CHARSET_INFO * const cs= system_charset_info;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3076
  Table *show_table;
1 by brian
clean slate
3077
  TABLE_SHARE *show_table_share;
3078
  Field **ptr, *field, *timestamp_field;
3079
  int count;
3080
3081
  if (res)
3082
  {
3083
    if (lex->sql_command != SQLCOM_SHOW_FIELDS)
3084
    {
3085
      /*
3086
        I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
3087
        rather than in SHOW COLUMNS
3088
      */ 
3089
      if (thd->is_error())
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
3090
        push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1 by brian
clean slate
3091
                     thd->main_da.sql_errno(), thd->main_da.message());
3092
      thd->clear_error();
3093
      res= 0;
3094
    }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3095
    return(res);
1 by brian
clean slate
3096
  }
3097
3098
  show_table= tables->table;
3099
  show_table_share= show_table->s;
3100
  count= 0;
3101
3102
  if (tables->schema_table)
3103
  {
3104
    ptr= show_table->field;
3105
    timestamp_field= show_table->timestamp_field;
3106
    show_table->use_all_columns();               // Required for default
3107
  }
3108
  else
3109
  {
3110
    ptr= show_table_share->field;
3111
    timestamp_field= show_table_share->timestamp_field;
3112
    /*
3113
      read_set may be inited in case of
3114
      temporary table
3115
    */
3116
    if (!show_table->read_set)
3117
    {
3118
      /* to satisfy 'field->val_str' ASSERTs */
3119
      uchar *bitmaps;
3120
      uint bitmap_size= show_table_share->column_bitmap_size;
3121
      if (!(bitmaps= (uchar*) alloc_root(thd->mem_root, bitmap_size)))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3122
        return(0);
1 by brian
clean slate
3123
      bitmap_init(&show_table->def_read_set,
163 by Brian Aker
Merge Monty's code.
3124
                  (my_bitmap_map*) bitmaps, show_table_share->fields, false);
1 by brian
clean slate
3125
      bitmap_set_all(&show_table->def_read_set);
3126
      show_table->read_set= &show_table->def_read_set;
3127
    }
3128
    bitmap_set_all(show_table->read_set);
3129
  }
3130
3131
  for (; (field= *ptr) ; ptr++)
3132
  {
3133
    uchar *pos;
3134
    char tmp[MAX_FIELD_WIDTH];
3135
    String type(tmp,sizeof(tmp), system_charset_info);
3136
    char *end;
3137
3138
    /* to satisfy 'field->val_str' ASSERTs */
3139
    field->table= show_table;
3140
    show_table->in_use= thd;
3141
3142
    if (wild && wild[0] &&
3143
        wild_case_compare(system_charset_info, field->field_name,wild))
3144
      continue;
3145
3146
    count++;
3147
    /* Get default row, with all NULL fields set to NULL */
3148
    restore_record(table, s->default_values);
3149
3150
    table->field[1]->store(db_name->str, db_name->length, cs);
3151
    table->field[2]->store(table_name->str, table_name->length, cs);
3152
    table->field[3]->store(field->field_name, strlen(field->field_name),
3153
                           cs);
163 by Brian Aker
Merge Monty's code.
3154
    table->field[4]->store((int64_t) count, true);
1 by brian
clean slate
3155
3156
    if (get_field_default_value(thd, timestamp_field, field, &type, 0))
3157
    {
3158
      table->field[5]->store(type.ptr(), type.length(), cs);
3159
      table->field[5]->set_notnull();
3160
    }
3161
    pos=(uchar*) ((field->flags & NOT_NULL_FLAG) ?  "NO" : "YES");
3162
    table->field[6]->store((const char*) pos,
3163
                           strlen((const char*) pos), cs);
3164
    store_column_type(table, field, cs, 7);
3165
3166
    pos=(uchar*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
3167
                 (field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
3168
                 (field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
3169
    table->field[15]->store((const char*) pos,
3170
                            strlen((const char*) pos), cs);
3171
3172
    end= tmp;
3173
    if (field->unireg_check == Field::NEXT_NUMBER)
3174
      table->field[16]->store(STRING_WITH_LEN("auto_increment"), cs);
3175
    if (timestamp_field == field &&
3176
        field->unireg_check != Field::TIMESTAMP_DN_FIELD)
3177
      table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
3178
                              cs);
3179
3180
    table->field[18]->store(field->comment.str, field->comment.length, cs);
3181
    {
3182
      enum column_format_type column_format= (enum column_format_type)
3183
        ((field->flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
100 by Brian Aker
First pass through refactor to remove STORAGE TYPE from Yacc (and eventually
3184
      pos=(uchar*)"Default";
1 by brian
clean slate
3185
      table->field[19]->store((const char*) pos,
3186
                              strlen((const char*) pos), cs);
3187
      pos=(uchar*)(column_format == COLUMN_FORMAT_TYPE_DEFAULT ? "Default" :
3188
                   column_format == COLUMN_FORMAT_TYPE_FIXED ? "Fixed" :
3189
                                                             "Dynamic");
3190
      table->field[20]->store((const char*) pos,
3191
                              strlen((const char*) pos), cs);
3192
    }
3193
    if (schema_table_store_record(thd, table))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3194
      return(1);
1 by brian
clean slate
3195
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3196
  return(0);
1 by brian
clean slate
3197
}
3198
3199
3200
327.2.4 by Brian Aker
Refactoring table.h
3201
int fill_schema_charsets(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
1 by brian
clean slate
3202
{
3203
  CHARSET_INFO **cs;
461 by Monty Taylor
Removed NullS. bu-bye.
3204
  const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NULL;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3205
  Table *table= tables->table;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3206
  const CHARSET_INFO * const scs= system_charset_info;
1 by brian
clean slate
3207
3208
  for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
3209
  {
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3210
    const CHARSET_INFO * const tmp_cs= cs[0];
1 by brian
clean slate
3211
    if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) && 
3212
        (tmp_cs->state & MY_CS_AVAILABLE) &&
3213
        !(tmp_cs->state & MY_CS_HIDDEN) &&
3214
        !(wild && wild[0] &&
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3215
          wild_case_compare(scs, tmp_cs->csname,wild)))
1 by brian
clean slate
3216
    {
3217
      const char *comment;
3218
      restore_record(table, s->default_values);
3219
      table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs);
3220
      table->field[1]->store(tmp_cs->name, strlen(tmp_cs->name), scs);
3221
      comment= tmp_cs->comment ? tmp_cs->comment : "";
3222
      table->field[2]->store(comment, strlen(comment), scs);
163 by Brian Aker
Merge Monty's code.
3223
      table->field[3]->store((int64_t) tmp_cs->mbmaxlen, true);
1 by brian
clean slate
3224
      if (schema_table_store_record(thd, table))
3225
        return 1;
3226
    }
3227
  }
3228
  return 0;
3229
}
3230
3231
327.2.4 by Brian Aker
Refactoring table.h
3232
int fill_schema_collation(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
1 by brian
clean slate
3233
{
3234
  CHARSET_INFO **cs;
461 by Monty Taylor
Removed NullS. bu-bye.
3235
  const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NULL;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3236
  Table *table= tables->table;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3237
  const CHARSET_INFO * const scs= system_charset_info;
1 by brian
clean slate
3238
  for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3239
  {
3240
    CHARSET_INFO **cl;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3241
    const CHARSET_INFO *tmp_cs= cs[0];
1 by brian
clean slate
3242
    if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3243
         (tmp_cs->state & MY_CS_HIDDEN) ||
3244
        !(tmp_cs->state & MY_CS_PRIMARY))
3245
      continue;
3246
    for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3247
    {
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3248
      const CHARSET_INFO *tmp_cl= cl[0];
1 by brian
clean slate
3249
      if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) || 
3250
          !my_charset_same(tmp_cs, tmp_cl))
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3251
        continue;
1 by brian
clean slate
3252
      if (!(wild && wild[0] &&
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3253
          wild_case_compare(scs, tmp_cl->name,wild)))
1 by brian
clean slate
3254
      {
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3255
        const char *tmp_buff;
3256
        restore_record(table, s->default_values);
3257
        table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
1 by brian
clean slate
3258
        table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
163 by Brian Aker
Merge Monty's code.
3259
        table->field[2]->store((int64_t) tmp_cl->number, true);
1 by brian
clean slate
3260
        tmp_buff= (tmp_cl->state & MY_CS_PRIMARY) ? "Yes" : "";
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3261
        table->field[3]->store(tmp_buff, strlen(tmp_buff), scs);
1 by brian
clean slate
3262
        tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : "";
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3263
        table->field[4]->store(tmp_buff, strlen(tmp_buff), scs);
163 by Brian Aker
Merge Monty's code.
3264
        table->field[5]->store((int64_t) tmp_cl->strxfrm_multiply, true);
1 by brian
clean slate
3265
        if (schema_table_store_record(thd, table))
3266
          return 1;
3267
      }
3268
    }
3269
  }
3270
  return 0;
3271
}
3272
3273
327.2.4 by Brian Aker
Refactoring table.h
3274
int fill_schema_coll_charset_app(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
1 by brian
clean slate
3275
{
3276
  CHARSET_INFO **cs;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3277
  Table *table= tables->table;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3278
  const CHARSET_INFO * const scs= system_charset_info;
1 by brian
clean slate
3279
  for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3280
  {
3281
    CHARSET_INFO **cl;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3282
    const CHARSET_INFO *tmp_cs= cs[0];
1 by brian
clean slate
3283
    if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) || 
3284
        !(tmp_cs->state & MY_CS_PRIMARY))
3285
      continue;
3286
    for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3287
    {
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3288
      const CHARSET_INFO *tmp_cl= cl[0];
1 by brian
clean slate
3289
      if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) || 
3290
          !my_charset_same(tmp_cs,tmp_cl))
3291
	continue;
3292
      restore_record(table, s->default_values);
3293
      table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3294
      table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3295
      if (schema_table_store_record(thd, table))
3296
        return 1;
3297
    }
3298
  }
3299
  return 0;
3300
}
3301
3302
327.2.4 by Brian Aker
Refactoring table.h
3303
static int get_schema_stat_record(THD *thd, TableList *tables,
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3304
				  Table *table, bool res,
1 by brian
clean slate
3305
				  LEX_STRING *db_name,
3306
				  LEX_STRING *table_name)
3307
{
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3308
  const CHARSET_INFO * const cs= system_charset_info;
1 by brian
clean slate
3309
  if (res)
3310
  {
3311
    if (thd->lex->sql_command != SQLCOM_SHOW_KEYS)
3312
    {
3313
      /*
3314
        I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
3315
        rather than in SHOW KEYS
3316
      */
3317
      if (thd->is_error())
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
3318
        push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1 by brian
clean slate
3319
                     thd->main_da.sql_errno(), thd->main_da.message());
3320
      thd->clear_error();
3321
      res= 0;
3322
    }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3323
    return(res);
1 by brian
clean slate
3324
  }
3325
  else
3326
  {
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3327
    Table *show_table= tables->table;
1 by brian
clean slate
3328
    KEY *key_info=show_table->s->key_info;
3329
    if (show_table->file)
3330
      show_table->file->info(HA_STATUS_VARIABLE |
3331
                             HA_STATUS_NO_LOCK |
3332
                             HA_STATUS_TIME);
3333
    for (uint i=0 ; i < show_table->s->keys ; i++,key_info++)
3334
    {
3335
      KEY_PART_INFO *key_part= key_info->key_part;
3336
      const char *str;
3337
      for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
3338
      {
3339
        restore_record(table, s->default_values);
3340
        table->field[1]->store(db_name->str, db_name->length, cs);
3341
        table->field[2]->store(table_name->str, table_name->length, cs);
152 by Brian Aker
longlong replacement
3342
        table->field[3]->store((int64_t) ((key_info->flags &
163 by Brian Aker
Merge Monty's code.
3343
                                            HA_NOSAME) ? 0 : 1), true);
1 by brian
clean slate
3344
        table->field[4]->store(db_name->str, db_name->length, cs);
3345
        table->field[5]->store(key_info->name, strlen(key_info->name), cs);
163 by Brian Aker
Merge Monty's code.
3346
        table->field[6]->store((int64_t) (j+1), true);
1 by brian
clean slate
3347
        str=(key_part->field ? key_part->field->field_name :
3348
             "?unknown field?");
3349
        table->field[7]->store(str, strlen(str), cs);
3350
        if (show_table->file)
3351
        {
3352
          if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER)
3353
          {
3354
            table->field[8]->store(((key_part->key_part_flag &
3355
                                     HA_REVERSE_SORT) ?
3356
                                    "D" : "A"), 1, cs);
3357
            table->field[8]->set_notnull();
3358
          }
3359
          KEY *key=show_table->key_info+i;
3360
          if (key->rec_per_key[j])
3361
          {
3362
            ha_rows records=(show_table->file->stats.records /
3363
                             key->rec_per_key[j]);
163 by Brian Aker
Merge Monty's code.
3364
            table->field[9]->store((int64_t) records, true);
1 by brian
clean slate
3365
            table->field[9]->set_notnull();
3366
          }
3367
          str= show_table->file->index_type(i);
3368
          table->field[13]->store(str, strlen(str), cs);
3369
        }
3370
        if ((key_part->field &&
3371
             key_part->length !=
3372
             show_table->s->field[key_part->fieldnr-1]->key_length()))
3373
        {
152 by Brian Aker
longlong replacement
3374
          table->field[10]->store((int64_t) key_part->length /
163 by Brian Aker
Merge Monty's code.
3375
                                  key_part->field->charset()->mbmaxlen, true);
1 by brian
clean slate
3376
          table->field[10]->set_notnull();
3377
        }
3378
        uint flags= key_part->field ? key_part->field->flags : 0;
3379
        const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
3380
        table->field[12]->store(pos, strlen(pos), cs);
3381
        if (!show_table->s->keys_in_use.is_set(i))
3382
          table->field[14]->store(STRING_WITH_LEN("disabled"), cs);
3383
        else
3384
          table->field[14]->store("", 0, cs);
3385
        table->field[14]->set_notnull();
51.1.75 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
3386
        assert(test(key_info->flags & HA_USES_COMMENT) == 
1 by brian
clean slate
3387
                   (key_info->comment.length > 0));
3388
        if (key_info->flags & HA_USES_COMMENT)
3389
          table->field[15]->store(key_info->comment.str, 
3390
                                  key_info->comment.length, cs);
3391
        if (schema_table_store_record(thd, table))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3392
          return(1);
1 by brian
clean slate
3393
      }
3394
    }
3395
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3396
  return(res);
1 by brian
clean slate
3397
}
3398
3399
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3400
bool store_constraints(THD *thd, Table *table, LEX_STRING *db_name,
1 by brian
clean slate
3401
                       LEX_STRING *table_name, const char *key_name,
3402
                       uint key_len, const char *con_type, uint con_len)
3403
{
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3404
  const CHARSET_INFO * const cs= system_charset_info;
1 by brian
clean slate
3405
  restore_record(table, s->default_values);
3406
  table->field[1]->store(db_name->str, db_name->length, cs);
3407
  table->field[2]->store(key_name, key_len, cs);
3408
  table->field[3]->store(db_name->str, db_name->length, cs);
3409
  table->field[4]->store(table_name->str, table_name->length, cs);
3410
  table->field[5]->store(con_type, con_len, cs);
3411
  return schema_table_store_record(thd, table);
3412
}
3413
3414
327.2.4 by Brian Aker
Refactoring table.h
3415
static int get_schema_constraints_record(THD *thd, TableList *tables,
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3416
					 Table *table, bool res,
1 by brian
clean slate
3417
					 LEX_STRING *db_name,
3418
					 LEX_STRING *table_name)
3419
{
3420
  if (res)
3421
  {
3422
    if (thd->is_error())
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
3423
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1 by brian
clean slate
3424
                   thd->main_da.sql_errno(), thd->main_da.message());
3425
    thd->clear_error();
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3426
    return(0);
1 by brian
clean slate
3427
  }
3428
  else
3429
  {
3430
    List<FOREIGN_KEY_INFO> f_key_list;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3431
    Table *show_table= tables->table;
1 by brian
clean slate
3432
    KEY *key_info=show_table->key_info;
3433
    uint primary_key= show_table->s->primary_key;
3434
    show_table->file->info(HA_STATUS_VARIABLE | 
3435
                           HA_STATUS_NO_LOCK |
3436
                           HA_STATUS_TIME);
3437
    for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
3438
    {
3439
      if (i != primary_key && !(key_info->flags & HA_NOSAME))
3440
        continue;
3441
3442
      if (i == primary_key && !strcmp(key_info->name, primary_key_name))
3443
      {
3444
        if (store_constraints(thd, table, db_name, table_name, key_info->name,
3445
                              strlen(key_info->name),
3446
                              STRING_WITH_LEN("PRIMARY KEY")))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3447
          return(1);
1 by brian
clean slate
3448
      }
3449
      else if (key_info->flags & HA_NOSAME)
3450
      {
3451
        if (store_constraints(thd, table, db_name, table_name, key_info->name,
3452
                              strlen(key_info->name),
3453
                              STRING_WITH_LEN("UNIQUE")))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3454
          return(1);
1 by brian
clean slate
3455
      }
3456
    }
3457
3458
    show_table->file->get_foreign_key_list(thd, &f_key_list);
3459
    FOREIGN_KEY_INFO *f_key_info;
3460
    List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3461
    while ((f_key_info=it++))
3462
    {
3463
      if (store_constraints(thd, table, db_name, table_name, 
3464
                            f_key_info->forein_id->str,
3465
                            strlen(f_key_info->forein_id->str),
3466
                            "FOREIGN KEY", 11))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3467
        return(1);
1 by brian
clean slate
3468
    }
3469
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3470
  return(res);
1 by brian
clean slate
3471
}
3472
3473
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3474
void store_key_column_usage(Table *table, LEX_STRING *db_name,
1 by brian
clean slate
3475
                            LEX_STRING *table_name, const char *key_name,
3476
                            uint key_len, const char *con_type, uint con_len,
152 by Brian Aker
longlong replacement
3477
                            int64_t idx)
1 by brian
clean slate
3478
{
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3479
  const CHARSET_INFO * const cs= system_charset_info;
1 by brian
clean slate
3480
  table->field[1]->store(db_name->str, db_name->length, cs);
3481
  table->field[2]->store(key_name, key_len, cs);
3482
  table->field[4]->store(db_name->str, db_name->length, cs);
3483
  table->field[5]->store(table_name->str, table_name->length, cs);
3484
  table->field[6]->store(con_type, con_len, cs);
163 by Brian Aker
Merge Monty's code.
3485
  table->field[7]->store((int64_t) idx, true);
1 by brian
clean slate
3486
}
3487
3488
3489
static int get_schema_key_column_usage_record(THD *thd,
327.2.4 by Brian Aker
Refactoring table.h
3490
					      TableList *tables,
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3491
					      Table *table, bool res,
1 by brian
clean slate
3492
					      LEX_STRING *db_name,
3493
					      LEX_STRING *table_name)
3494
{
3495
  if (res)
3496
  {
3497
    if (thd->is_error())
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
3498
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1 by brian
clean slate
3499
                   thd->main_da.sql_errno(), thd->main_da.message());
3500
    thd->clear_error();
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3501
    return(0);
1 by brian
clean slate
3502
  }
3503
  else
3504
  {
3505
    List<FOREIGN_KEY_INFO> f_key_list;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3506
    Table *show_table= tables->table;
1 by brian
clean slate
3507
    KEY *key_info=show_table->key_info;
3508
    uint primary_key= show_table->s->primary_key;
3509
    show_table->file->info(HA_STATUS_VARIABLE | 
3510
                           HA_STATUS_NO_LOCK |
3511
                           HA_STATUS_TIME);
3512
    for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
3513
    {
3514
      if (i != primary_key && !(key_info->flags & HA_NOSAME))
3515
        continue;
3516
      uint f_idx= 0;
3517
      KEY_PART_INFO *key_part= key_info->key_part;
3518
      for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
3519
      {
3520
        if (key_part->field)
3521
        {
3522
          f_idx++;
3523
          restore_record(table, s->default_values);
3524
          store_key_column_usage(table, db_name, table_name,
3525
                                 key_info->name,
3526
                                 strlen(key_info->name), 
3527
                                 key_part->field->field_name, 
3528
                                 strlen(key_part->field->field_name),
152 by Brian Aker
longlong replacement
3529
                                 (int64_t) f_idx);
1 by brian
clean slate
3530
          if (schema_table_store_record(thd, table))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3531
            return(1);
1 by brian
clean slate
3532
        }
3533
      }
3534
    }
3535
3536
    show_table->file->get_foreign_key_list(thd, &f_key_list);
3537
    FOREIGN_KEY_INFO *f_key_info;
3538
    List_iterator_fast<FOREIGN_KEY_INFO> fkey_it(f_key_list);
3539
    while ((f_key_info= fkey_it++))
3540
    {
3541
      LEX_STRING *f_info;
3542
      LEX_STRING *r_info;
3543
      List_iterator_fast<LEX_STRING> it(f_key_info->foreign_fields),
3544
        it1(f_key_info->referenced_fields);
3545
      uint f_idx= 0;
3546
      while ((f_info= it++))
3547
      {
3548
        r_info= it1++;
3549
        f_idx++;
3550
        restore_record(table, s->default_values);
3551
        store_key_column_usage(table, db_name, table_name,
3552
                               f_key_info->forein_id->str,
3553
                               f_key_info->forein_id->length,
3554
                               f_info->str, f_info->length,
152 by Brian Aker
longlong replacement
3555
                               (int64_t) f_idx);
163 by Brian Aker
Merge Monty's code.
3556
        table->field[8]->store((int64_t) f_idx, true);
1 by brian
clean slate
3557
        table->field[8]->set_notnull();
3558
        table->field[9]->store(f_key_info->referenced_db->str,
3559
                               f_key_info->referenced_db->length,
3560
                               system_charset_info);
3561
        table->field[9]->set_notnull();
3562
        table->field[10]->store(f_key_info->referenced_table->str,
3563
                                f_key_info->referenced_table->length, 
3564
                                system_charset_info);
3565
        table->field[10]->set_notnull();
3566
        table->field[11]->store(r_info->str, r_info->length,
3567
                                system_charset_info);
3568
        table->field[11]->set_notnull();
3569
        if (schema_table_store_record(thd, table))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3570
          return(1);
1 by brian
clean slate
3571
      }
3572
    }
3573
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3574
  return(res);
1 by brian
clean slate
3575
}
3576
3577
327.2.4 by Brian Aker
Refactoring table.h
3578
int fill_open_tables(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
1 by brian
clean slate
3579
{
461 by Monty Taylor
Removed NullS. bu-bye.
3580
  const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NULL;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3581
  Table *table= tables->table;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3582
  const CHARSET_INFO * const cs= system_charset_info;
327.2.4 by Brian Aker
Refactoring table.h
3583
  OPEN_TableList *open_list;
1 by brian
clean slate
3584
  if (!(open_list=list_open_tables(thd,thd->lex->select_lex.db, wild))
3585
            && thd->is_fatal_error)
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3586
    return(1);
1 by brian
clean slate
3587
3588
  for (; open_list ; open_list=open_list->next)
3589
  {
3590
    restore_record(table, s->default_values);
3591
    table->field[0]->store(open_list->db, strlen(open_list->db), cs);
3592
    table->field[1]->store(open_list->table, strlen(open_list->table), cs);
163 by Brian Aker
Merge Monty's code.
3593
    table->field[2]->store((int64_t) open_list->in_use, true);
3594
    table->field[3]->store((int64_t) open_list->locked, true);
1 by brian
clean slate
3595
    if (schema_table_store_record(thd, table))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3596
      return(1);
1 by brian
clean slate
3597
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3598
  return(0);
1 by brian
clean slate
3599
}
3600
3601
327.2.4 by Brian Aker
Refactoring table.h
3602
int fill_variables(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
1 by brian
clean slate
3603
{
3604
  int res= 0;
3605
  LEX *lex= thd->lex;
461 by Monty Taylor
Removed NullS. bu-bye.
3606
  const char *wild= lex->wild ? lex->wild->ptr() : NULL;
1 by brian
clean slate
3607
  enum enum_schema_tables schema_table_idx=
3608
    get_schema_table_idx(tables->schema_table);
3609
  enum enum_var_type option_type= OPT_SESSION;
3610
  bool upper_case_names= (schema_table_idx != SCH_VARIABLES);
3611
  bool sorted_vars= (schema_table_idx == SCH_VARIABLES);
3612
3613
  if (lex->option_type == OPT_GLOBAL ||
3614
      schema_table_idx == SCH_GLOBAL_VARIABLES)
3615
    option_type= OPT_GLOBAL;
3616
3617
  rw_rdlock(&LOCK_system_variables_hash);
3618
  res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars),
3619
                         option_type, NULL, "", tables->table, upper_case_names);
3620
  rw_unlock(&LOCK_system_variables_hash);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3621
  return(res);
1 by brian
clean slate
3622
}
3623
3624
327.2.4 by Brian Aker
Refactoring table.h
3625
int fill_status(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
1 by brian
clean slate
3626
{
3627
  LEX *lex= thd->lex;
461 by Monty Taylor
Removed NullS. bu-bye.
3628
  const char *wild= lex->wild ? lex->wild->ptr() : NULL;
1 by brian
clean slate
3629
  int res= 0;
3630
  STATUS_VAR *tmp1, tmp;
3631
  enum enum_schema_tables schema_table_idx=
3632
    get_schema_table_idx(tables->schema_table);
3633
  enum enum_var_type option_type;
3634
  bool upper_case_names= (schema_table_idx != SCH_STATUS);
3635
3636
  if (schema_table_idx == SCH_STATUS)
3637
  {
3638
    option_type= lex->option_type;
3639
    if (option_type == OPT_GLOBAL)
3640
      tmp1= &tmp;
3641
    else
3642
      tmp1= thd->initial_status_var;
3643
  }
3644
  else if (schema_table_idx == SCH_GLOBAL_STATUS)
3645
  {
3646
    option_type= OPT_GLOBAL;
3647
    tmp1= &tmp;
3648
  }
3649
  else
3650
  { 
3651
    option_type= OPT_SESSION;
3652
    tmp1= &thd->status_var;
3653
  }
3654
3655
  pthread_mutex_lock(&LOCK_status);
3656
  if (option_type == OPT_GLOBAL)
3657
    calc_sum_of_all_status(&tmp);
3658
  res= show_status_array(thd, wild,
3659
                         (SHOW_VAR *)all_status_vars.buffer,
3660
                         option_type, tmp1, "", tables->table,
3661
                         upper_case_names);
3662
  pthread_mutex_unlock(&LOCK_status);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3663
  return(res);
1 by brian
clean slate
3664
}
3665
3666
3667
/*
3668
  Fill and store records into I_S.referential_constraints table
3669
3670
  SYNOPSIS
3671
    get_referential_constraints_record()
3672
    thd                 thread handle
3673
    tables              table list struct(processed table)
3674
    table               I_S table
3675
    res                 1 means the error during opening of the processed table
3676
                        0 means processed table is opened without error
3677
    base_name           db name
3678
    file_name           table name
3679
3680
  RETURN
3681
    0	ok
3682
    #   error
3683
*/
3684
3685
static int
327.2.4 by Brian Aker
Refactoring table.h
3686
get_referential_constraints_record(THD *thd, TableList *tables,
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3687
                                   Table *table, bool res,
1 by brian
clean slate
3688
                                   LEX_STRING *db_name, LEX_STRING *table_name)
3689
{
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3690
  const CHARSET_INFO * const cs= system_charset_info;
1 by brian
clean slate
3691
3692
  if (res)
3693
  {
3694
    if (thd->is_error())
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
3695
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1 by brian
clean slate
3696
                   thd->main_da.sql_errno(), thd->main_da.message());
3697
    thd->clear_error();
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3698
    return(0);
1 by brian
clean slate
3699
  }
3700
3701
  {
3702
    List<FOREIGN_KEY_INFO> f_key_list;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3703
    Table *show_table= tables->table;
1 by brian
clean slate
3704
    show_table->file->info(HA_STATUS_VARIABLE | 
3705
                           HA_STATUS_NO_LOCK |
3706
                           HA_STATUS_TIME);
3707
3708
    show_table->file->get_foreign_key_list(thd, &f_key_list);
3709
    FOREIGN_KEY_INFO *f_key_info;
3710
    List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3711
    while ((f_key_info= it++))
3712
    {
3713
      restore_record(table, s->default_values);
3714
      table->field[1]->store(db_name->str, db_name->length, cs);
3715
      table->field[9]->store(table_name->str, table_name->length, cs);
3716
      table->field[2]->store(f_key_info->forein_id->str,
3717
                             f_key_info->forein_id->length, cs);
3718
      table->field[4]->store(f_key_info->referenced_db->str, 
3719
                             f_key_info->referenced_db->length, cs);
3720
      table->field[10]->store(f_key_info->referenced_table->str, 
3721
                             f_key_info->referenced_table->length, cs);
3722
      if (f_key_info->referenced_key_name)
3723
      {
3724
        table->field[5]->store(f_key_info->referenced_key_name->str, 
3725
                               f_key_info->referenced_key_name->length, cs);
3726
        table->field[5]->set_notnull();
3727
      }
3728
      else
3729
        table->field[5]->set_null();
3730
      table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
3731
      table->field[7]->store(f_key_info->update_method->str, 
3732
                             f_key_info->update_method->length, cs);
3733
      table->field[8]->store(f_key_info->delete_method->str, 
3734
                             f_key_info->delete_method->length, cs);
3735
      if (schema_table_store_record(thd, table))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3736
        return(1);
1 by brian
clean slate
3737
    }
3738
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3739
  return(0);
1 by brian
clean slate
3740
}
3741
3742
3743
struct schema_table_ref 
3744
{
3745
  const char *table_name;
3746
  ST_SCHEMA_TABLE *schema_table;
3747
};
3748
3749
3750
/*
3751
  Find schema_tables elment by name
3752
3753
  SYNOPSIS
3754
    find_schema_table_in_plugin()
3755
    thd                 thread handler
3756
    plugin              plugin
3757
    table_name          table name
3758
3759
  RETURN
3760
    0	table not found
3761
    1   found the schema table
3762
*/
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
3763
static bool find_schema_table_in_plugin(THD *thd __attribute__((unused)),
77.1.46 by Monty Taylor
Finished the warnings work!
3764
                                           plugin_ref plugin,
1 by brian
clean slate
3765
                                           void* p_table)
3766
{
3767
  schema_table_ref *p_schema_table= (schema_table_ref *)p_table;
3768
  const char* table_name= p_schema_table->table_name;
3769
  ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
3770
3771
  if (!my_strcasecmp(system_charset_info,
3772
                     schema_table->table_name,
3773
                     table_name)) {
3774
    p_schema_table->schema_table= schema_table;
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3775
    return(1);
1 by brian
clean slate
3776
  }
3777
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3778
  return(0);
1 by brian
clean slate
3779
}
3780
3781
3782
/*
3783
  Find schema_tables elment by name
3784
3785
  SYNOPSIS
3786
    find_schema_table()
3787
    thd                 thread handler
3788
    table_name          table name
3789
3790
  RETURN
3791
    0	table not found
3792
    #   pointer to 'schema_tables' element
3793
*/
3794
3795
ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name)
3796
{
3797
  schema_table_ref schema_table_a;
3798
  ST_SCHEMA_TABLE *schema_table= schema_tables;
3799
3800
  for (; schema_table->table_name; schema_table++)
3801
  {
3802
    if (!my_strcasecmp(system_charset_info,
3803
                       schema_table->table_name,
3804
                       table_name))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3805
      return(schema_table);
1 by brian
clean slate
3806
  }
3807
3808
  schema_table_a.table_name= table_name;
3809
  if (plugin_foreach(thd, find_schema_table_in_plugin, 
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
3810
                     DRIZZLE_INFORMATION_SCHEMA_PLUGIN, &schema_table_a))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3811
    return(schema_table_a.schema_table);
1 by brian
clean slate
3812
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3813
  return(NULL);
1 by brian
clean slate
3814
}
3815
3816
3817
ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
3818
{
3819
  return &schema_tables[schema_table_idx];
3820
}
3821
3822
3823
/**
3824
  Create information_schema table using schema_table data.
3825
3826
  @note
3827
3828
  @param
3829
    thd	       	          thread handler
3830
3831
  @param table_list Used to pass I_S table information(fields info, tables
3832
  parameters etc) and table name.
3833
3834
  @retval  \#             Pointer to created table
3835
  @retval  NULL           Can't create table
3836
*/
3837
327.2.4 by Brian Aker
Refactoring table.h
3838
Table *create_schema_table(THD *thd, TableList *table_list)
1 by brian
clean slate
3839
{
3840
  int field_count= 0;
3841
  Item *item;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3842
  Table *table;
1 by brian
clean slate
3843
  List<Item> field_list;
3844
  ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
3845
  ST_FIELD_INFO *fields_info= schema_table->fields_info;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
3846
  const CHARSET_INFO * const cs= system_charset_info;
1 by brian
clean slate
3847
3848
  for (; fields_info->field_name; fields_info++)
3849
  {
3850
    switch (fields_info->field_type) {
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
3851
    case DRIZZLE_TYPE_TINY:
3852
    case DRIZZLE_TYPE_LONG:
3853
    case DRIZZLE_TYPE_LONGLONG:
1 by brian
clean slate
3854
      if (!(item= new Item_return_int(fields_info->field_name,
3855
                                      fields_info->field_length,
3856
                                      fields_info->field_type,
3857
                                      fields_info->value)))
3858
      {
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3859
        return(0);
1 by brian
clean slate
3860
      }
3861
      item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3862
      break;
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
3863
    case DRIZZLE_TYPE_NEWDATE:
3864
    case DRIZZLE_TYPE_TIME:
3865
    case DRIZZLE_TYPE_TIMESTAMP:
3866
    case DRIZZLE_TYPE_DATETIME:
1 by brian
clean slate
3867
      if (!(item=new Item_return_date_time(fields_info->field_name,
3868
                                           fields_info->field_type)))
3869
      {
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3870
        return(0);
1 by brian
clean slate
3871
      }
3872
      break;
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
3873
    case DRIZZLE_TYPE_DOUBLE:
1 by brian
clean slate
3874
      if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC, 
3875
                           fields_info->field_length)) == NULL)
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3876
        return(NULL);
1 by brian
clean slate
3877
      break;
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
3878
    case DRIZZLE_TYPE_NEWDECIMAL:
152 by Brian Aker
longlong replacement
3879
      if (!(item= new Item_decimal((int64_t) fields_info->value, false)))
1 by brian
clean slate
3880
      {
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3881
        return(0);
1 by brian
clean slate
3882
      }
3883
      item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3884
      item->decimals= fields_info->field_length%10;
3885
      item->max_length= (fields_info->field_length/100)%100;
3886
      if (item->unsigned_flag == 0)
3887
        item->max_length+= 1;
3888
      if (item->decimals > 0)
3889
        item->max_length+= 1;
3890
      item->set_name(fields_info->field_name,
3891
                     strlen(fields_info->field_name), cs);
3892
      break;
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
3893
    case DRIZZLE_TYPE_BLOB:
1 by brian
clean slate
3894
      if (!(item= new Item_blob(fields_info->field_name,
3895
                                fields_info->field_length)))
3896
      {
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3897
        return(0);
1 by brian
clean slate
3898
      }
3899
      break;
3900
    default:
3901
      if (!(item= new Item_empty_string("", fields_info->field_length, cs)))
3902
      {
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3903
        return(0);
1 by brian
clean slate
3904
      }
3905
      item->set_name(fields_info->field_name,
3906
                     strlen(fields_info->field_name), cs);
3907
      break;
3908
    }
3909
    field_list.push_back(item);
3910
    item->maybe_null= (fields_info->field_flags & MY_I_S_MAYBE_NULL);
3911
    field_count++;
3912
  }
3913
  TMP_TABLE_PARAM *tmp_table_param =
3914
    (TMP_TABLE_PARAM*) (thd->alloc(sizeof(TMP_TABLE_PARAM)));
3915
  tmp_table_param->init();
3916
  tmp_table_param->table_charset= cs;
3917
  tmp_table_param->field_count= field_count;
3918
  tmp_table_param->schema_table= 1;
3919
  SELECT_LEX *select_lex= thd->lex->current_select;
3920
  if (!(table= create_tmp_table(thd, tmp_table_param,
327.2.3 by Brian Aker
Refactoring of class Table
3921
                                field_list, (order_st*) 0, 0, 0, 
1 by brian
clean slate
3922
                                (select_lex->options | thd->options |
3923
                                 TMP_TABLE_ALL_COLUMNS),
3924
                                HA_POS_ERROR, table_list->alias)))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3925
    return(0);
1 by brian
clean slate
3926
  my_bitmap_map* bitmaps=
3927
    (my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count));
3928
  bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
163 by Brian Aker
Merge Monty's code.
3929
              false);
1 by brian
clean slate
3930
  table->read_set= &table->def_read_set;
3931
  bitmap_clear_all(table->read_set);
3932
  table_list->schema_table_param= tmp_table_param;
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3933
  return(table);
1 by brian
clean slate
3934
}
3935
3936
3937
/*
3938
  For old SHOW compatibility. It is used when
3939
  old SHOW doesn't have generated column names
3940
  Make list of fields for SHOW
3941
3942
  SYNOPSIS
3943
    make_old_format()
3944
    thd			thread handler
3945
    schema_table        pointer to 'schema_tables' element
3946
3947
  RETURN
3948
   1	error
3949
   0	success
3950
*/
3951
3952
int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
3953
{
3954
  ST_FIELD_INFO *field_info= schema_table->fields_info;
3955
  Name_resolution_context *context= &thd->lex->select_lex.context;
3956
  for (; field_info->field_name; field_info++)
3957
  {
3958
    if (field_info->old_name)
3959
    {
3960
      Item_field *field= new Item_field(context,
461 by Monty Taylor
Removed NullS. bu-bye.
3961
                                        NULL, NULL, field_info->field_name);
1 by brian
clean slate
3962
      if (field)
3963
      {
3964
        field->set_name(field_info->old_name,
3965
                        strlen(field_info->old_name),
3966
                        system_charset_info);
3967
        if (add_item_to_list(thd, field))
3968
          return 1;
3969
      }
3970
    }
3971
  }
3972
  return 0;
3973
}
3974
3975
3976
int make_schemata_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
3977
{
3978
  char tmp[128];
3979
  LEX *lex= thd->lex;
3980
  SELECT_LEX *sel= lex->current_select;
3981
  Name_resolution_context *context= &sel->context;
3982
3983
  if (!sel->item_list.elements)
3984
  {
3985
    ST_FIELD_INFO *field_info= &schema_table->fields_info[1];
3986
    String buffer(tmp,sizeof(tmp), system_charset_info);
3987
    Item_field *field= new Item_field(context,
461 by Monty Taylor
Removed NullS. bu-bye.
3988
                                      NULL, NULL, field_info->field_name);
1 by brian
clean slate
3989
    if (!field || add_item_to_list(thd, field))
3990
      return 1;
3991
    buffer.length(0);
3992
    buffer.append(field_info->old_name);
3993
    if (lex->wild && lex->wild->ptr())
3994
    {
3995
      buffer.append(STRING_WITH_LEN(" ("));
3996
      buffer.append(lex->wild->ptr());
3997
      buffer.append(')');
3998
    }
3999
    field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4000
  }
4001
  return 0;
4002
}
4003
4004
4005
int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4006
{
4007
  char tmp[128];
4008
  String buffer(tmp,sizeof(tmp), thd->charset());
4009
  LEX *lex= thd->lex;
4010
  Name_resolution_context *context= &lex->select_lex.context;
4011
4012
  ST_FIELD_INFO *field_info= &schema_table->fields_info[2];
4013
  buffer.length(0);
4014
  buffer.append(field_info->old_name);
4015
  buffer.append(lex->select_lex.db);
4016
  if (lex->wild && lex->wild->ptr())
4017
  {
4018
    buffer.append(STRING_WITH_LEN(" ("));
4019
    buffer.append(lex->wild->ptr());
4020
    buffer.append(')');
4021
  }
4022
  Item_field *field= new Item_field(context,
461 by Monty Taylor
Removed NullS. bu-bye.
4023
                                    NULL, NULL, field_info->field_name);
1 by brian
clean slate
4024
  if (add_item_to_list(thd, field))
4025
    return 1;
4026
  field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4027
  if (thd->lex->verbose)
4028
  {
4029
    field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4030
    field_info= &schema_table->fields_info[3];
461 by Monty Taylor
Removed NullS. bu-bye.
4031
    field= new Item_field(context, NULL, NULL, field_info->field_name);
1 by brian
clean slate
4032
    if (add_item_to_list(thd, field))
4033
      return 1;
4034
    field->set_name(field_info->old_name, strlen(field_info->old_name),
4035
                    system_charset_info);
4036
  }
4037
  return 0;
4038
}
4039
4040
4041
int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4042
{
4043
  int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1};
4044
  int *field_num= fields_arr;
4045
  ST_FIELD_INFO *field_info;
4046
  Name_resolution_context *context= &thd->lex->select_lex.context;
4047
4048
  for (; *field_num >= 0; field_num++)
4049
  {
4050
    field_info= &schema_table->fields_info[*field_num];
4051
    if (!thd->lex->verbose && (*field_num == 13 ||
4052
                               *field_num == 17 ||
4053
                               *field_num == 18))
4054
      continue;
4055
    Item_field *field= new Item_field(context,
461 by Monty Taylor
Removed NullS. bu-bye.
4056
                                      NULL, NULL, field_info->field_name);
1 by brian
clean slate
4057
    if (field)
4058
    {
4059
      field->set_name(field_info->old_name,
4060
                      strlen(field_info->old_name),
4061
                      system_charset_info);
4062
      if (add_item_to_list(thd, field))
4063
        return 1;
4064
    }
4065
  }
4066
  return 0;
4067
}
4068
4069
4070
int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4071
{
4072
  int fields_arr[]= {0, 2, 1, 3, -1};
4073
  int *field_num= fields_arr;
4074
  ST_FIELD_INFO *field_info;
4075
  Name_resolution_context *context= &thd->lex->select_lex.context;
4076
4077
  for (; *field_num >= 0; field_num++)
4078
  {
4079
    field_info= &schema_table->fields_info[*field_num];
4080
    Item_field *field= new Item_field(context,
461 by Monty Taylor
Removed NullS. bu-bye.
4081
                                      NULL, NULL, field_info->field_name);
1 by brian
clean slate
4082
    if (field)
4083
    {
4084
      field->set_name(field_info->old_name,
4085
                      strlen(field_info->old_name),
4086
                      system_charset_info);
4087
      if (add_item_to_list(thd, field))
4088
        return 1;
4089
    }
4090
  }
4091
  return 0;
4092
}
4093
4094
4095
/*
4096
  Create information_schema table
4097
4098
  SYNOPSIS
4099
  mysql_schema_table()
4100
    thd                thread handler
4101
    lex                pointer to LEX
4102
    table_list         pointer to table_list
4103
4104
  RETURN
4105
    0	success
4106
    1   error
4107
*/
4108
327.2.4 by Brian Aker
Refactoring table.h
4109
int mysql_schema_table(THD *thd, LEX *lex, TableList *table_list)
1 by brian
clean slate
4110
{
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
4111
  Table *table;
1 by brian
clean slate
4112
  if (!(table= table_list->schema_table->create_table(thd, table_list)))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
4113
    return(1);
1 by brian
clean slate
4114
  table->s->tmp_table= SYSTEM_TMP_TABLE;
4115
  /*
4116
    This test is necessary to make
4117
    case insensitive file systems +
4118
    upper case table names(information schema tables) +
4119
    views
4120
    working correctly
4121
  */
4122
  if (table_list->schema_table_name)
4123
    table->alias_name_used= my_strcasecmp(table_alias_charset,
4124
                                          table_list->schema_table_name,
4125
                                          table_list->alias);
4126
  table_list->table_name= table->s->table_name.str;
4127
  table_list->table_name_length= table->s->table_name.length;
4128
  table_list->table= table;
4129
  table->next= thd->derived_tables;
4130
  thd->derived_tables= table;
4131
  table_list->select_lex->options |= OPTION_SCHEMA_TABLE;
4132
4133
  if (table_list->schema_table_reformed) // show command
4134
  {
4135
    SELECT_LEX *sel= lex->current_select;
4136
    Item *item;
4137
    Field_translator *transl, *org_transl;
4138
4139
    if (table_list->field_translation)
4140
    {
4141
      Field_translator *end= table_list->field_translation_end;
4142
      for (transl= table_list->field_translation; transl < end; transl++)
4143
      {
4144
        if (!transl->item->fixed &&
4145
            transl->item->fix_fields(thd, &transl->item))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
4146
          return(1);
1 by brian
clean slate
4147
      }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
4148
      return(0);
1 by brian
clean slate
4149
    }
4150
    List_iterator_fast<Item> it(sel->item_list);
4151
    if (!(transl=
401 by Brian Aker
Partial Query_arena removal
4152
          (Field_translator*)(thd->alloc(sel->item_list.elements *
1 by brian
clean slate
4153
                                    sizeof(Field_translator)))))
4154
    {
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
4155
      return(1);
1 by brian
clean slate
4156
    }
4157
    for (org_transl= transl; (item= it++); transl++)
4158
    {
4159
      transl->item= item;
4160
      transl->name= item->name;
4161
      if (!item->fixed && item->fix_fields(thd, &transl->item))
4162
      {
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
4163
        return(1);
1 by brian
clean slate
4164
      }
4165
    }
4166
    table_list->field_translation= org_transl;
4167
    table_list->field_translation_end= transl;
4168
  }
4169
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
4170
  return(0);
1 by brian
clean slate
4171
}
4172
4173
4174
/*
4175
  Generate select from information_schema table
4176
4177
  SYNOPSIS
4178
    make_schema_select()
4179
    thd                  thread handler
4180
    sel                  pointer to SELECT_LEX
4181
    schema_table_idx     index of 'schema_tables' element
4182
4183
  RETURN
4184
    0	success
4185
    1   error
4186
*/
4187
4188
int make_schema_select(THD *thd, SELECT_LEX *sel,
4189
		       enum enum_schema_tables schema_table_idx)
4190
{
4191
  ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx);
4192
  LEX_STRING db, table;
4193
  /*
4194
     We have to make non const db_name & table_name
4195
     because of lower_case_table_names
4196
  */
4197
  thd->make_lex_string(&db, INFORMATION_SCHEMA_NAME.str,
4198
                       INFORMATION_SCHEMA_NAME.length, 0);
4199
  thd->make_lex_string(&table, schema_table->table_name,
4200
                       strlen(schema_table->table_name), 0);
4201
  if (schema_table->old_format(thd, schema_table) ||   /* Handle old syntax */
4202
      !sel->add_table_to_list(thd, new Table_ident(thd, db, table, 0),
4203
                              0, 0, TL_READ))
4204
  {
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
4205
    return(1);
1 by brian
clean slate
4206
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
4207
  return(0);
1 by brian
clean slate
4208
}
4209
4210
4211
/*
4212
  Fill temporary schema tables before SELECT
4213
4214
  SYNOPSIS
4215
    get_schema_tables_result()
4216
    join  join which use schema tables
4217
    executed_place place where I_S table processed
4218
4219
  RETURN
163 by Brian Aker
Merge Monty's code.
4220
    false success
4221
    true  error
1 by brian
clean slate
4222
*/
4223
4224
bool get_schema_tables_result(JOIN *join,
4225
                              enum enum_schema_table_state executed_place)
4226
{
4227
  JOIN_TAB *tmp_join_tab= join->join_tab+join->tables;
4228
  THD *thd= join->thd;
4229
  LEX *lex= thd->lex;
4230
  bool result= 0;
4231
4232
  thd->no_warnings_for_error= 1;
4233
  for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
4234
  {
4235
    if (!tab->table || !tab->table->pos_in_table_list)
4236
      break;
4237
327.2.4 by Brian Aker
Refactoring table.h
4238
    TableList *table_list= tab->table->pos_in_table_list;
1 by brian
clean slate
4239
    if (table_list->schema_table)
4240
    {
4241
      bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
4242
                          lex->current_select->master_unit()->item);
4243
4244
4245
      /* skip I_S optimizations specific to get_all_tables */
4246
      if (thd->lex->describe &&
4247
          (table_list->schema_table->fill_table != get_all_tables))
4248
        continue;
4249
4250
      /*
4251
        If schema table is already processed and
4252
        the statement is not a subselect then
4253
        we don't need to fill this table again.
4254
        If schema table is already processed and
4255
        schema_table_state != executed_place then
4256
        table is already processed and
4257
        we should skip second data processing.
4258
      */
4259
      if (table_list->schema_table_state &&
4260
          (!is_subselect || table_list->schema_table_state != executed_place))
4261
        continue;
4262
4263
      /*
4264
        if table is used in a subselect and
4265
        table has been processed earlier with the same
4266
        'executed_place' value then we should refresh the table.
4267
      */
4268
      if (table_list->schema_table_state && is_subselect)
4269
      {
4270
        table_list->table->file->extra(HA_EXTRA_NO_CACHE);
4271
        table_list->table->file->extra(HA_EXTRA_RESET_STATE);
4272
        table_list->table->file->ha_delete_all_rows();
4273
        free_io_cache(table_list->table);
4274
        filesort_free_buffers(table_list->table,1);
4275
        table_list->table->null_row= 0;
4276
      }
4277
      else
4278
        table_list->table->file->stats.records= 0;
4279
4280
      if (table_list->schema_table->fill_table(thd, table_list,
4281
                                               tab->select_cond))
4282
      {
4283
        result= 1;
4284
        join->error= 1;
4285
        tab->read_record.file= table_list->table->file;
4286
        table_list->schema_table_state= executed_place;
4287
        break;
4288
      }
4289
      tab->read_record.file= table_list->table->file;
4290
      table_list->schema_table_state= executed_place;
4291
    }
4292
  }
4293
  thd->no_warnings_for_error= 0;
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
4294
  return(result);
1 by brian
clean slate
4295
}
4296
4297
ST_FIELD_INFO schema_fields_info[]=
4298
{
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4299
  {"CATALOG_NAME", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4300
  {"SCHEMA_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Database",
4301
   SKIP_OPEN_TABLE},
4302
  {"DEFAULT_CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4303
   SKIP_OPEN_TABLE},
4304
  {"DEFAULT_COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4305
  {"SQL_PATH", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4306
  {0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
1 by brian
clean slate
4307
};
4308
4309
4310
ST_FIELD_INFO tables_fields_info[]=
4311
{
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4312
  {"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4313
  {"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4314
  {"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Name",
1 by brian
clean slate
4315
   SKIP_OPEN_TABLE},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4316
  {"TABLE_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4317
  {"ENGINE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Engine", OPEN_FRM_ONLY},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4318
  {"VERSION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
1 by brian
clean slate
4319
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", OPEN_FRM_ONLY},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4320
  {"ROW_FORMAT", 10, DRIZZLE_TYPE_VARCHAR, 0, 1, "Row_format", OPEN_FULL_TABLE},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4321
  {"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
1 by brian
clean slate
4322
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", OPEN_FULL_TABLE},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4323
  {"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 
1 by brian
clean slate
4324
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", OPEN_FULL_TABLE},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4325
  {"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 
1 by brian
clean slate
4326
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4327
  {"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
1 by brian
clean slate
4328
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", OPEN_FULL_TABLE},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4329
  {"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 
1 by brian
clean slate
4330
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4331
  {"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
1 by brian
clean slate
4332
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", OPEN_FULL_TABLE},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4333
  {"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG, 0, 
1 by brian
clean slate
4334
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4335
  {"CREATE_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE},
4336
  {"UPDATE_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE},
4337
  {"CHECK_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Check_time", OPEN_FULL_TABLE},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4338
  {"TABLE_COLLATION", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4339
  {"CHECKSUM", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
1 by brian
clean slate
4340
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", OPEN_FULL_TABLE},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4341
  {"CREATE_OPTIONS", 255, DRIZZLE_TYPE_VARCHAR, 0, 1, "Create_options",
1 by brian
clean slate
4342
   OPEN_FRM_ONLY},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4343
  {"TABLE_COMMENT", TABLE_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Comment", OPEN_FRM_ONLY},
4344
  {0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
1 by brian
clean slate
4345
};
4346
4347
4348
ST_FIELD_INFO columns_fields_info[]=
4349
{
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4350
  {"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4351
  {"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4352
  {"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4353
  {"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Field",
1 by brian
clean slate
4354
   OPEN_FRM_ONLY},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4355
  {"ORDINAL_POSITION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
1 by brian
clean slate
4356
   MY_I_S_UNSIGNED, 0, OPEN_FRM_ONLY},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4357
  {"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, DRIZZLE_TYPE_VARCHAR, 0,
1 by brian
clean slate
4358
   1, "Default", OPEN_FRM_ONLY},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4359
  {"IS_NULLABLE", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Null", OPEN_FRM_ONLY},
4360
  {"DATA_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4361
  {"CHARACTER_MAXIMUM_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG,
4362
   0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4363
  {"CHARACTER_OCTET_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG,
4364
   0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4365
  {"NUMERIC_PRECISION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG,
4366
   0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4367
  {"NUMERIC_SCALE", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG,
4368
   0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4369
  {"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4370
  {"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4371
  {"COLUMN_TYPE", 65535, DRIZZLE_TYPE_VARCHAR, 0, 0, "Type", OPEN_FRM_ONLY},
4372
  {"COLUMN_KEY", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Key", OPEN_FRM_ONLY},
4373
  {"EXTRA", 27, DRIZZLE_TYPE_VARCHAR, 0, 0, "Extra", OPEN_FRM_ONLY},
4374
  {"PRIVILEGES", 80, DRIZZLE_TYPE_VARCHAR, 0, 0, "Privileges", OPEN_FRM_ONLY},
4375
  {"COLUMN_COMMENT", COLUMN_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Comment", OPEN_FRM_ONLY},
4376
  {"STORAGE", 8, DRIZZLE_TYPE_VARCHAR, 0, 0, "Storage", OPEN_FRM_ONLY},
4377
  {"FORMAT", 8, DRIZZLE_TYPE_VARCHAR, 0, 0, "Format", OPEN_FRM_ONLY},
4378
  {0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
1 by brian
clean slate
4379
};
4380
4381
4382
ST_FIELD_INFO charsets_fields_info[]=
4383
{
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4384
  {"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Charset",
4385
   SKIP_OPEN_TABLE},
4386
  {"DEFAULT_COLLATE_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Default collation",
4387
   SKIP_OPEN_TABLE},
4388
  {"DESCRIPTION", 60, DRIZZLE_TYPE_VARCHAR, 0, 0, "Description",
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4389
   SKIP_OPEN_TABLE},
4390
  {"MAXLEN", 3, DRIZZLE_TYPE_LONGLONG, 0, 0, "Maxlen", SKIP_OPEN_TABLE},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4391
  {0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
1 by brian
clean slate
4392
};
4393
4394
4395
ST_FIELD_INFO collation_fields_info[]=
4396
{
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4397
  {"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Collation", SKIP_OPEN_TABLE},
4398
  {"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Charset",
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4399
   SKIP_OPEN_TABLE},
4400
  {"ID", MY_INT32_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 0, "Id",
4401
   SKIP_OPEN_TABLE},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4402
  {"IS_DEFAULT", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Default", SKIP_OPEN_TABLE},
4403
  {"IS_COMPILED", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Compiled", SKIP_OPEN_TABLE},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4404
  {"SORTLEN", 3, DRIZZLE_TYPE_LONGLONG, 0, 0, "Sortlen", SKIP_OPEN_TABLE},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4405
  {0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
1 by brian
clean slate
4406
};
4407
4408
4409
4410
ST_FIELD_INFO coll_charset_app_fields_info[]=
4411
{
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4412
  {"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4413
  {"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4414
  {0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
1 by brian
clean slate
4415
};
4416
4417
4418
ST_FIELD_INFO stat_fields_info[]=
4419
{
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4420
  {"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4421
  {"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4422
  {"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table", OPEN_FRM_ONLY},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4423
  {"NON_UNIQUE", 1, DRIZZLE_TYPE_LONGLONG, 0, 0, "Non_unique", OPEN_FRM_ONLY},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4424
  {"INDEX_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4425
  {"INDEX_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Key_name",
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4426
   OPEN_FRM_ONLY},
4427
  {"SEQ_IN_INDEX", 2, DRIZZLE_TYPE_LONGLONG, 0, 0, "Seq_in_index", OPEN_FRM_ONLY},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4428
  {"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Column_name",
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4429
   OPEN_FRM_ONLY},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4430
  {"COLLATION", 1, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4431
  {"CARDINALITY", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 1,
1 by brian
clean slate
4432
   "Cardinality", OPEN_FULL_TABLE},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4433
  {"SUB_PART", 3, DRIZZLE_TYPE_LONGLONG, 0, 1, "Sub_part", OPEN_FRM_ONLY},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4434
  {"PACKED", 10, DRIZZLE_TYPE_VARCHAR, 0, 1, "Packed", OPEN_FRM_ONLY},
4435
  {"NULLABLE", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Null", OPEN_FRM_ONLY},
4436
  {"INDEX_TYPE", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "Index_type", OPEN_FULL_TABLE},
4437
  {"COMMENT", 16, DRIZZLE_TYPE_VARCHAR, 0, 1, "Comment", OPEN_FRM_ONLY},
4438
  {"INDEX_COMMENT", INDEX_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Index_Comment", OPEN_FRM_ONLY},
4439
  {0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
1 by brian
clean slate
4440
};
4441
4442
4443
ST_FIELD_INFO table_constraints_fields_info[]=
4444
{
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4445
  {"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4446
  {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4447
   OPEN_FULL_TABLE},
4448
  {"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4449
   OPEN_FULL_TABLE},
4450
  {"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4451
  {"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4452
  {"CONSTRAINT_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4453
   OPEN_FULL_TABLE},
4454
  {0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
1 by brian
clean slate
4455
};
4456
4457
4458
ST_FIELD_INFO key_column_usage_fields_info[]=
4459
{
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4460
  {"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4461
  {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4462
   OPEN_FULL_TABLE},
4463
  {"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4464
   OPEN_FULL_TABLE},
4465
  {"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4466
  {"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4467
  {"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4468
  {"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4469
  {"ORDINAL_POSITION", 10 ,DRIZZLE_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE},
4470
  {"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,DRIZZLE_TYPE_LONGLONG, 0, 1, 0,
4471
   OPEN_FULL_TABLE},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4472
  {"REFERENCED_TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4473
   OPEN_FULL_TABLE},
4474
  {"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4475
   OPEN_FULL_TABLE},
4476
  {"REFERENCED_COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4477
   OPEN_FULL_TABLE},
4478
  {0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
1 by brian
clean slate
4479
};
4480
4481
4482
ST_FIELD_INFO table_names_fields_info[]=
4483
{
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4484
  {"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4485
  {"TABLE_SCHEMA",NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4486
  {"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Tables_in_",
1 by brian
clean slate
4487
   SKIP_OPEN_TABLE},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4488
  {"TABLE_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table_type",
1 by brian
clean slate
4489
   OPEN_FRM_ONLY},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4490
  {0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
1 by brian
clean slate
4491
};
4492
4493
4494
ST_FIELD_INFO open_tables_fields_info[]=
4495
{
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4496
  {"Database", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Database",
1 by brian
clean slate
4497
   SKIP_OPEN_TABLE},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4498
  {"Table",NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table", SKIP_OPEN_TABLE},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4499
  {"In_use", 1, DRIZZLE_TYPE_LONGLONG, 0, 0, "In_use", SKIP_OPEN_TABLE},
4500
  {"Name_locked", 4, DRIZZLE_TYPE_LONGLONG, 0, 0, "Name_locked", SKIP_OPEN_TABLE},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4501
  {0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
1 by brian
clean slate
4502
};
4503
4504
4505
ST_FIELD_INFO variables_fields_info[]=
4506
{
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4507
  {"VARIABLE_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Variable_name",
1 by brian
clean slate
4508
   SKIP_OPEN_TABLE},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4509
  {"VARIABLE_VALUE", 16300, DRIZZLE_TYPE_VARCHAR, 0, 1, "Value", SKIP_OPEN_TABLE},
4510
  {0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
1 by brian
clean slate
4511
};
4512
4513
4514
ST_FIELD_INFO processlist_fields_info[]=
4515
{
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4516
  {"ID", 4, DRIZZLE_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4517
  {"USER", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "User", SKIP_OPEN_TABLE},
4518
  {"HOST", LIST_PROCESS_HOST_LEN,  DRIZZLE_TYPE_VARCHAR, 0, 0, "Host",
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4519
   SKIP_OPEN_TABLE},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4520
  {"DB", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Db", SKIP_OPEN_TABLE},
4521
  {"COMMAND", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "Command", SKIP_OPEN_TABLE},
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4522
  {"TIME", 7, DRIZZLE_TYPE_LONGLONG, 0, 0, "Time", SKIP_OPEN_TABLE},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4523
  {"STATE", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "State", SKIP_OPEN_TABLE},
4524
  {"INFO", PROCESS_LIST_INFO_WIDTH, DRIZZLE_TYPE_VARCHAR, 0, 1, "Info",
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
4525
   SKIP_OPEN_TABLE},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4526
  {0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
1 by brian
clean slate
4527
};
4528
4529
4530
ST_FIELD_INFO plugin_fields_info[]=
4531
{
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4532
  {"PLUGIN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Name", 
4533
   SKIP_OPEN_TABLE},
4534
  {"PLUGIN_VERSION", 20, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4535
  {"PLUGIN_STATUS", 10, DRIZZLE_TYPE_VARCHAR, 0, 0, "Status", SKIP_OPEN_TABLE},
4536
  {"PLUGIN_TYPE", 80, DRIZZLE_TYPE_VARCHAR, 0, 0, "Type", SKIP_OPEN_TABLE},
4537
  {"PLUGIN_LIBRARY", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Library",
4538
   SKIP_OPEN_TABLE},
4539
  {"PLUGIN_AUTHOR", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4540
  {"PLUGIN_DESCRIPTION", 65535, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4541
  {"PLUGIN_LICENSE", 80, DRIZZLE_TYPE_VARCHAR, 0, 1, "License", SKIP_OPEN_TABLE},
4542
  {0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
1 by brian
clean slate
4543
};
4544
4545
ST_FIELD_INFO referential_constraints_fields_info[]=
4546
{
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4547
  {"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4548
  {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4549
   OPEN_FULL_TABLE},
4550
  {"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4551
   OPEN_FULL_TABLE},
4552
  {"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4553
   OPEN_FULL_TABLE},
4554
  {"UNIQUE_CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4555
   OPEN_FULL_TABLE},
4556
  {"UNIQUE_CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0,
1 by brian
clean slate
4557
   MY_I_S_MAYBE_NULL, 0, OPEN_FULL_TABLE},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4558
  {"MATCH_OPTION", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4559
  {"UPDATE_RULE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4560
  {"DELETE_RULE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4561
  {"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4562
  {"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
1 by brian
clean slate
4563
   OPEN_FULL_TABLE},
238 by Brian Aker
Pass through sql_show to remove type to be removed.
4564
  {0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
1 by brian
clean slate
4565
};
4566
4567
4568
/*
4569
  Description of ST_FIELD_INFO in table.h
4570
4571
  Make sure that the order of schema_tables and enum_schema_tables are the same.
4572
4573
*/
4574
4575
ST_SCHEMA_TABLE schema_tables[]=
4576
{
4577
  {"CHARACTER_SETS", charsets_fields_info, create_schema_table, 
4578
   fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
4579
  {"COLLATIONS", collation_fields_info, create_schema_table, 
4580
   fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
4581
  {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
4582
   create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0},
4583
  {"COLUMNS", columns_fields_info, create_schema_table, 
4584
   get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0,
357 by Brian Aker
flag cleanup
4585
   OPTIMIZE_I_S_TABLE},
1 by brian
clean slate
4586
  {"GLOBAL_STATUS", variables_fields_info, create_schema_table,
4587
   fill_status, make_old_format, 0, -1, -1, 0, 0},
4588
  {"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
4589
   fill_variables, make_old_format, 0, -1, -1, 0, 0},
4590
  {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
4591
   get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
4592
   OPEN_TABLE_ONLY},
4593
  {"OPEN_TABLES", open_tables_fields_info, create_schema_table,
4594
   fill_open_tables, make_old_format, 0, -1, -1, 1, 0},
4595
  {"PLUGINS", plugin_fields_info, create_schema_table,
4596
   fill_plugins, make_old_format, 0, -1, -1, 0, 0},
4597
  {"PROCESSLIST", processlist_fields_info, create_schema_table,
4598
   fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0},
4599
  {"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
4600
   create_schema_table, get_all_tables, 0, get_referential_constraints_record,
4601
   1, 9, 0, OPEN_TABLE_ONLY},
4602
  {"SCHEMATA", schema_fields_info, create_schema_table,
4603
   fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
4604
  {"SESSION_STATUS", variables_fields_info, create_schema_table,
4605
   fill_status, make_old_format, 0, -1, -1, 0, 0},
4606
  {"SESSION_VARIABLES", variables_fields_info, create_schema_table,
4607
   fill_variables, make_old_format, 0, -1, -1, 0, 0},
4608
  {"STATISTICS", stat_fields_info, create_schema_table, 
4609
   get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
4610
   OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
4611
  {"STATUS", variables_fields_info, create_schema_table, fill_status, 
4612
   make_old_format, 0, -1, -1, 1, 0},
4613
  {"TABLES", tables_fields_info, create_schema_table, 
4614
   get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
4615
   OPTIMIZE_I_S_TABLE},
4616
  {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
4617
   get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, OPEN_TABLE_ONLY},
4618
  {"TABLE_NAMES", table_names_fields_info, create_schema_table,
4619
   get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
4620
  {"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
4621
   make_old_format, 0, -1, -1, 1, 0},
4622
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
4623
};
4624
4625
4626
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
4627
template class List_iterator_fast<char>;
4628
template class List<char>;
4629
#endif
4630
4631
int initialize_schema_table(st_plugin_int *plugin)
4632
{
4633
  ST_SCHEMA_TABLE *schema_table;
4634
4635
  if (!(schema_table= (ST_SCHEMA_TABLE *)my_malloc(sizeof(ST_SCHEMA_TABLE),
4636
                                MYF(MY_WME | MY_ZEROFILL))))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
4637
      return(1);
1 by brian
clean slate
4638
  /* Historical Requirement */
4639
  plugin->data= schema_table; // shortcut for the future
4640
  if (plugin->plugin->init)
4641
  {
4642
    schema_table->create_table= create_schema_table;
4643
    schema_table->old_format= make_old_format;
4644
    schema_table->idx_field1= -1, 
4645
    schema_table->idx_field2= -1; 
4646
4647
    /* Make the name available to the init() function. */
4648
    schema_table->table_name= plugin->name.str;
4649
4650
    if (plugin->plugin->init(schema_table))
4651
    {
340 by Monty Taylor
Got everything using sql_print_*.
4652
      sql_print_error(_("Plugin '%s' init function returned error."),
1 by brian
clean slate
4653
                      plugin->name.str);
4654
      goto err;
4655
    }
4656
    
4657
    /* Make sure the plugin name is not set inside the init() function. */
4658
    schema_table->table_name= plugin->name.str;
4659
  }
4660
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
4661
  return(0);
1 by brian
clean slate
4662
err:
4663
  my_free(schema_table, MYF(0));
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
4664
  return(1);
1 by brian
clean slate
4665
}
4666
4667
int finalize_schema_table(st_plugin_int *plugin)
4668
{
4669
  ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
4670
4671
  if (schema_table && plugin->plugin->deinit)
4672
    my_free(schema_table, MYF(0));
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
4673
4674
  return(0);
1 by brian
clean slate
4675
}