~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/show.cc

  • Committer: Brian Aker
  • Date: 2009-08-21 18:46:31 UTC
  • mto: This revision was merged to the branch mainline in revision 1123.
  • Revision ID: brian@gaz-20090821184631-e11gja79070fvhk4
Cleanup around page checksum removal

Show diffs side-by-side

added added

removed removed

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