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