~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/show.cc

  • Committer: Brian Aker
  • Date: 2009-05-11 17:50:22 UTC
  • Revision ID: brian@gaz-20090511175022-y35q9ky6uh9ldcjt
Replacing Sun employee copyright headers (aka... anything done by a Sun
employee is copyright by Sun).

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"
 
24
#include <drizzled/show.h>
22
25
#include <mysys/my_dir.h>
23
 
#include <libdrizzle/gettext.h>
 
26
#include <drizzled/gettext.h>
 
27
#include <drizzled/util/convert.h>
 
28
#include <drizzled/error.h>
 
29
#include <drizzled/tztime.h>
 
30
#include <drizzled/data_home.h>
 
31
#include <drizzled/item/blob.h>
 
32
#include <drizzled/item/cmpfunc.h>
 
33
#include <drizzled/item/return_int.h>
 
34
#include <drizzled/item/empty_string.h>
 
35
#include <drizzled/item/return_date_time.h>
 
36
#include <drizzled/sql_base.h>
 
37
#include <drizzled/db.h>
 
38
#include <drizzled/field/timestamp.h>
 
39
#include <drizzled/field/decimal.h>
 
40
#include <drizzled/lock.h>
 
41
#include <drizzled/item/return_date_time.h>
 
42
#include <drizzled/item/empty_string.h>
 
43
#include "drizzled/plugin_registry.h"
 
44
 
 
45
#include <string>
 
46
#include <iostream>
 
47
#include <sstream>
 
48
#include <vector>
 
49
#include <algorithm>
 
50
 
 
51
using namespace std;
 
52
 
 
53
extern "C"
 
54
int show_var_cmp(const void *var1, const void *var2);
24
55
 
25
56
inline const char *
26
57
str_or_nil(const char *str)
31
62
/* Match the values of enum ha_choice */
32
63
static const char *ha_choice_values[] = {"", "0", "1"};
33
64
 
34
 
static void store_key_options(THD *thd, String *packet, Table *table,
 
65
static void store_key_options(Session *session, String *packet, Table *table,
35
66
                              KEY *key_info);
36
67
 
 
68
static vector<InfoSchemaTable *> all_schema_tables;
 
69
 
 
70
Table *create_schema_table(Session *session, TableList *table_list);
 
71
int make_old_format(Session *session, InfoSchemaTable *schema_table);
 
72
 
 
73
void add_infoschema_table(InfoSchemaTable *schema_table)
 
74
{
 
75
  if (schema_table->create_table == NULL)
 
76
    schema_table->create_table= create_schema_table;
 
77
  if (schema_table->old_format == NULL)
 
78
    schema_table->old_format= make_old_format;
 
79
  if (schema_table->idx_field1 == 0)
 
80
    schema_table->idx_field1= -1;
 
81
  if (schema_table->idx_field2)
 
82
   schema_table->idx_field2= -1;
 
83
 
 
84
  all_schema_tables.push_back(schema_table);
 
85
}
 
86
 
 
87
void remove_infoschema_table(InfoSchemaTable *table)
 
88
{
 
89
  all_schema_tables.erase(remove_if(all_schema_tables.begin(),
 
90
                                    all_schema_tables.end(),
 
91
                                    bind2nd(equal_to<InfoSchemaTable *>(),
 
92
                                            table)),
 
93
                          all_schema_tables.end());
 
94
}
37
95
 
38
96
 
39
97
int wild_case_compare(const CHARSET_INFO * const cs, const char *str,const char *wildstr)
86
144
** List all table types supported
87
145
***************************************************************************/
88
146
 
89
 
static bool show_plugins(THD *thd, plugin_ref plugin,
90
 
                            void *arg)
 
147
class ShowPlugins : public unary_function<st_plugin_int *, bool>
91
148
{
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);
 
149
  Session *session;
 
150
  Table *table;
 
151
public:
 
152
  ShowPlugins(Session *session_arg, Table *table_arg)
 
153
    : session(session_arg), table(table_arg) {}
 
154
 
 
155
  result_type operator() (argument_type plugin)
 
156
  {
 
157
    struct drizzled_plugin_manifest *plug= plugin_decl(plugin);
 
158
    const CHARSET_INFO * const cs= system_charset_info;
 
159
  
 
160
    table->restoreRecordAsDefault();
 
161
  
 
162
    table->field[0]->store(plugin_name(plugin)->str,
 
163
                           plugin_name(plugin)->length, cs);
 
164
  
 
165
    if (plug->version)
 
166
    {
 
167
      table->field[1]->store(plug->version, strlen(plug->version), cs);
 
168
      table->field[1]->set_notnull();
 
169
    }
 
170
    else
 
171
      table->field[1]->set_null();
 
172
  
 
173
    if (plugin->isInited)
 
174
      table->field[2]->store(STRING_WITH_LEN("ACTIVE"), cs);
 
175
    else
 
176
      table->field[2]->store(STRING_WITH_LEN("INACTIVE"), cs);
 
177
  
 
178
    if (plug->author)
 
179
    {
 
180
      table->field[3]->store(plug->author, strlen(plug->author), cs);
 
181
      table->field[3]->set_notnull();
 
182
    }
 
183
    else
 
184
      table->field[3]->set_null();
 
185
  
 
186
    if (plug->descr)
 
187
    {
 
188
      table->field[4]->store(plug->descr, strlen(plug->descr), cs);
 
189
      table->field[4]->set_notnull();
 
190
    }
 
191
    else
 
192
      table->field[4]->set_null();
 
193
  
 
194
    switch (plug->license) {
 
195
    case PLUGIN_LICENSE_GPL:
 
196
      table->field[5]->store(PLUGIN_LICENSE_GPL_STRING,
 
197
                             strlen(PLUGIN_LICENSE_GPL_STRING), cs);
 
198
      break;
 
199
    case PLUGIN_LICENSE_BSD:
 
200
      table->field[5]->store(PLUGIN_LICENSE_BSD_STRING,
 
201
                             strlen(PLUGIN_LICENSE_BSD_STRING), cs);
 
202
      break;
 
203
    case PLUGIN_LICENSE_LGPL:
 
204
      table->field[5]->store(PLUGIN_LICENSE_LGPL_STRING,
 
205
                             strlen(PLUGIN_LICENSE_LGPL_STRING), cs);
 
206
      break;
 
207
    default:
 
208
      table->field[5]->store(PLUGIN_LICENSE_PROPRIETARY_STRING,
 
209
                             strlen(PLUGIN_LICENSE_PROPRIETARY_STRING), cs);
 
210
      break;
 
211
    }
142
212
    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)))
 
213
  
 
214
    return schema_table_store_record(session, table);
 
215
  }
 
216
};
 
217
 
 
218
 
 
219
int fill_plugins(Session *session, TableList *tables, COND *)
176
220
{
177
221
  Table *table= tables->table;
178
222
 
179
 
  if (plugin_foreach_with_mask(thd, show_plugins, DRIZZLE_ANY_PLUGIN,
180
 
                               ~PLUGIN_IS_FREED, table))
181
 
    return(1);
182
 
 
 
223
  PluginRegistry &registry= PluginRegistry::getPluginRegistry();
 
224
  vector<st_plugin_int *> plugins= registry.get_list(true);
 
225
  vector<st_plugin_int *>::iterator iter=
 
226
    find_if(plugins.begin(), plugins.end(), ShowPlugins(session, table));
 
227
  if (iter != plugins.end())
 
228
    return 1;
183
229
  return(0);
184
230
}
185
231
 
189
235
 
190
236
  SYNOPSIS
191
237
    find_files()
192
 
    thd                 thread handler
 
238
    session                 thread handler
193
239
    files               put found files in this list
194
240
    db                  database name to set in TableList structure
195
241
    path                path to database
205
251
 
206
252
 
207
253
find_files_result
208
 
find_files(THD *thd, List<LEX_STRING> *files, const char *db,
 
254
find_files(Session *session, List<LEX_STRING> *files, const char *db,
209
255
           const char *path, const char *wild, bool dir)
210
256
{
211
257
  uint32_t i;
230
276
    return(FIND_FILES_DIR);
231
277
  }
232
278
 
233
 
  for (i=0 ; i < (uint) dirp->number_off_files  ; i++)
 
279
  for (i=0 ; i < (uint32_t) dirp->number_off_files  ; i++)
234
280
  {
235
281
    char uname[NAME_LEN + 1];                   /* Unencoded name */
236
282
    file=dirp->dir_entry+i;
237
283
    if (dir)
238
284
    {                                           /* Return databases */
239
 
      if ((file->name[0] == '.' && 
 
285
      if ((file->name[0] == '.' &&
240
286
          ((file->name[1] == '.' && file->name[2] == '\0') ||
241
287
            file->name[1] == '\0')))
242
288
        continue;                               /* . or .. */
262
308
      file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
263
309
      if (wild && wild_compare(uname, wild, 0))
264
310
        continue;
265
 
      if (!(file_name= 
266
 
            thd->make_lex_string(file_name, uname, file_name_len, true)))
 
311
      if (!(file_name=
 
312
            session->make_lex_string(file_name, uname, file_name_len, true)))
267
313
      {
268
314
        my_dirend(dirp);
269
315
        return(FIND_FILES_OOM);
271
317
    }
272
318
    else
273
319
    {
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))
 
320
      // Return only .frm files which aren't temp files.
 
321
      if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),".dfe") ||
 
322
          is_prefix(file->name, TMP_FILE_PREFIX))
277
323
        continue;
278
324
      *ext=0;
279
325
      file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
280
326
      if (wild)
281
327
      {
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;
 
328
        if (lower_case_table_names)
 
329
        {
 
330
          if (wild_case_compare(files_charset_info, uname, wild))
 
331
            continue;
 
332
        }
 
333
        else if (wild_compare(uname, wild, 0))
 
334
          continue;
289
335
      }
290
336
    }
291
 
    if (!(file_name= 
292
 
          thd->make_lex_string(file_name, uname, file_name_len, true)) ||
 
337
    if (!(file_name=
 
338
          session->make_lex_string(file_name, uname, file_name_len, true)) ||
293
339
        files->push_back(file_name))
294
340
    {
295
341
      my_dirend(dirp);
302
348
}
303
349
 
304
350
 
305
 
bool
306
 
mysqld_show_create(THD *thd, TableList *table_list)
 
351
bool drizzled_show_create(Session *session, TableList *table_list)
307
352
{
308
 
  Protocol *protocol= thd->protocol;
 
353
  Protocol *protocol= session->protocol;
309
354
  char buff[2048];
310
355
  String buffer(buff, sizeof(buff), system_charset_info);
311
356
 
312
357
  /* Only one table for now, but VIEW can involve several tables */
313
 
  if (open_normal_and_derived_tables(thd, table_list, 0))
 
358
  if (open_normal_and_derived_tables(session, table_list, 0))
314
359
  {
315
 
    if (thd->is_error() && thd->main_da.sql_errno() != ER_VIEW_INVALID)
 
360
    if (session->is_error())
316
361
      return(true);
317
362
 
318
363
    /*
319
364
      Clear all messages with 'error' level status and
320
 
      issue a warning with 'warning' level status in 
 
365
      issue a warning with 'warning' level status in
321
366
      case of invalid view and last error is ER_VIEW_INVALID
322
367
    */
323
 
    drizzle_reset_errors(thd, true);
324
 
    thd->clear_error();
 
368
    drizzle_reset_errors(session, true);
 
369
    session->clear_error();
325
370
  }
326
371
 
327
372
  buffer.length(0);
328
373
 
329
 
  if (store_create_info(thd, table_list, &buffer, NULL))
 
374
  if (store_create_info(session, table_list, &buffer, NULL))
330
375
    return(true);
331
376
 
332
377
  List<Item> field_list;
337
382
                                               cmax(buffer.length(),(uint32_t)1024)));
338
383
  }
339
384
 
340
 
  if (protocol->send_fields(&field_list,
341
 
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
 
385
  if (protocol->sendFields(&field_list,
 
386
                           Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
 
387
  {
342
388
    return(true);
343
 
  protocol->prepare_for_resend();
 
389
  }
 
390
  protocol->prepareForResend();
344
391
  {
345
392
    if (table_list->schema_table)
346
393
      protocol->store(table_list->schema_table->table_name,
354
401
  if (protocol->write())
355
402
    return(true);
356
403
 
357
 
  my_eof(thd);
 
404
  session->my_eof();
358
405
  return(false);
359
406
}
360
407
 
361
 
bool mysqld_show_create_db(THD *thd, char *dbname,
 
408
bool mysqld_show_create_db(Session *session, char *dbname,
362
409
                           HA_CREATE_INFO *create_info)
363
410
{
364
411
  char buff[2048];
365
412
  String buffer(buff, sizeof(buff), system_charset_info);
366
 
  Protocol *protocol=thd->protocol;
 
413
  Protocol *protocol=session->protocol;
367
414
 
368
 
  if (store_db_create_info(thd, dbname, &buffer, create_info))
 
415
  if (store_db_create_info(session, dbname, &buffer, create_info))
369
416
  {
370
 
    /* 
 
417
    /*
371
418
      This assumes that the only reason for which store_db_create_info()
372
419
      can fail is incorrect database name (which is the case now).
373
420
    */
374
421
    my_error(ER_BAD_DB_ERROR, MYF(0), dbname);
375
 
    return(true);    
 
422
    return(true);
376
423
  }
377
424
 
378
425
  List<Item> field_list;
379
426
  field_list.push_back(new Item_empty_string("Database",NAME_CHAR_LEN));
380
427
  field_list.push_back(new Item_empty_string("Create Database",1024));
381
428
 
382
 
  if (protocol->send_fields(&field_list,
383
 
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
 
429
  if (protocol->sendFields(&field_list,
 
430
                           Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
384
431
    return(true);
385
432
 
386
 
  protocol->prepare_for_resend();
 
433
  protocol->prepareForResend();
387
434
  protocol->store(dbname, strlen(dbname), system_charset_info);
388
435
  protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
389
436
 
390
437
  if (protocol->write())
391
438
    return(true);
392
 
  my_eof(thd);
 
439
  session->my_eof();
393
440
  return(false);
394
441
}
395
442
 
401
448
****************************************************************************/
402
449
 
403
450
void
404
 
mysqld_list_fields(THD *thd, TableList *table_list, const char *wild)
 
451
mysqld_list_fields(Session *session, TableList *table_list, const char *wild)
405
452
{
406
453
  Table *table;
407
454
 
408
 
  if (open_normal_and_derived_tables(thd, table_list, 0))
 
455
  if (open_normal_and_derived_tables(session, table_list, 0))
409
456
    return;
410
457
  table= table_list->table;
411
458
 
414
461
  Field **ptr,*field;
415
462
  for (ptr=table->field ; (field= *ptr); ptr++)
416
463
  {
417
 
    if (!wild || !wild[0] || 
 
464
    if (!wild || !wild[0] ||
418
465
        !wild_case_compare(system_charset_info, field->field_name,wild))
419
466
    {
420
467
      field_list.push_back(new Item_field(field));
421
468
    }
422
469
  }
423
 
  restore_record(table, s->default_values);              // Get empty record
 
470
  table->restoreRecordAsDefault();              // Get empty record
424
471
  table->use_all_columns();
425
 
  if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS))
 
472
  if (session->protocol->sendFields(&field_list, Protocol::SEND_DEFAULTS))
426
473
    return;
427
 
  my_eof(thd);
 
474
  session->my_eof();
428
475
  return;
429
476
}
430
477
 
431
478
 
432
479
/*
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
 
 
521
 
 
522
 
/*
523
480
  Get the quote character for displaying an identifier.
524
481
 
525
482
  SYNOPSIS
526
483
    get_quote_char_for_identifier()
527
 
    thd         Thread handler
 
484
    session             Thread handler
528
485
    name        name to quote
529
486
    length      length of name
530
487
 
542
499
    #     Quote character
543
500
*/
544
501
 
545
 
int get_quote_char_for_identifier(THD *thd, const char *name, uint32_t length)
 
502
int get_quote_char_for_identifier(Session *, const char *, uint32_t)
546
503
{
547
 
  if (length &&
548
 
      !is_keyword(name,length) &&
549
 
      !require_quotes(name, length) &&
550
 
      !(thd->options & OPTION_QUOTE_SHOW_CREATE))
551
 
    return EOF;
552
504
  return '`';
553
505
}
554
506
 
555
507
 
556
508
/* Append directory name (if exists) to CREATE INFO */
557
509
 
558
 
static void append_directory(THD *thd __attribute__((unused)),
 
510
static void append_directory(Session *,
559
511
                             String *packet, const char *dir_type,
560
 
                             const char *filename)
 
512
                             const char *filename)
561
513
{
562
514
  if (filename)
563
515
  {
573
525
 
574
526
#define LIST_PROCESS_HOST_LEN 64
575
527
 
576
 
static bool get_field_default_value(THD *thd __attribute__((unused)),
 
528
static bool get_field_default_value(Session *,
577
529
                                    Field *timestamp_field,
578
530
                                    Field *field, String *def_value,
579
531
                                    bool quoted)
581
533
  bool has_default;
582
534
  bool has_now_default;
583
535
 
584
 
  /* 
 
536
  /*
585
537
     We are using CURRENT_TIMESTAMP instead of NOW because it is
586
538
     more standard
587
539
  */
588
540
  has_now_default= (timestamp_field == field &&
589
541
                    field->unireg_check != Field::TIMESTAMP_UN_FIELD);
590
 
    
 
542
 
591
543
  has_default= (field->type() != DRIZZLE_TYPE_BLOB &&
592
544
                !(field->flags & NO_DEFAULT_VALUE_FLAG) &&
593
 
                field->unireg_check != Field::NEXT_NUMBER
594
 
                  && has_now_default);
 
545
                field->unireg_check != Field::NEXT_NUMBER);
595
546
 
596
547
  def_value->length(0);
597
548
  if (has_default)
622
573
      def_value->append(STRING_WITH_LEN("NULL"));    // Null as default
623
574
    else
624
575
      return 0;
625
 
 
626
576
  }
627
577
  return has_default;
628
578
}
632
582
 
633
583
  SYNOPSIS
634
584
    store_create_info()
635
 
    thd               The thread
 
585
    session               The thread
636
586
    table_list        A list containing one table to write statement
637
587
                      for.
638
588
    packet            Pointer to a string where statement will be
641
591
                      to tailor the format of the statement.  Can be
642
592
                      NULL, in which case only SQL_MODE is considered
643
593
                      when building the statement.
644
 
  
 
594
 
645
595
  NOTE
646
596
    Currently always return 0, but might return error code in the
647
597
    future.
648
 
    
 
598
 
649
599
  RETURN
650
600
    0       OK
651
601
 */
652
602
 
653
 
int store_create_info(THD *thd, TableList *table_list, String *packet,
 
603
int store_create_info(Session *session, TableList *table_list, String *packet,
654
604
                      HA_CREATE_INFO *create_info_arg)
655
605
{
656
606
  List<Item> field_list;
657
 
  char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], def_value_buf[MAX_FIELD_WIDTH];
 
607
  char tmp[MAX_FIELD_WIDTH], *for_str, def_value_buf[MAX_FIELD_WIDTH];
658
608
  const char *alias;
 
609
  string buff;
659
610
  String type(tmp, sizeof(tmp), system_charset_info);
660
611
  String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
661
612
  Field **ptr,*field;
663
614
  KEY *key_info;
664
615
  Table *table= table_list->table;
665
616
  handler *file= table->file;
666
 
  TABLE_SHARE *share= table->s;
 
617
  TableShare *share= table->s;
667
618
  HA_CREATE_INFO create_info;
668
619
  bool show_table_options= false;
669
620
  my_bitmap_map *old_map;
670
621
 
671
 
  restore_record(table, s->default_values); // Get empty record
 
622
  table->restoreRecordAsDefault(); // Get empty record
672
623
 
673
624
  if (share->tmp_table)
674
625
    packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
684
635
    if (lower_case_table_names == 2)
685
636
      alias= table->alias;
686
637
    else
687
 
    {
688
638
      alias= share->table_name.str;
689
 
    }
690
639
  }
691
 
  append_identifier(thd, packet, alias, strlen(alias));
 
640
  packet->append_identifier(alias, strlen(alias));
692
641
  packet->append(STRING_WITH_LEN(" (\n"));
693
642
  /*
694
643
    We need this to get default values from the table
705
654
      packet->append(STRING_WITH_LEN(",\n"));
706
655
 
707
656
    packet->append(STRING_WITH_LEN("  "));
708
 
    append_identifier(thd,packet,field->field_name, strlen(field->field_name));
 
657
    packet->append_identifier(field->field_name, strlen(field->field_name));
709
658
    packet->append(' ');
710
659
    // check for surprises from the previous call to Field::sql_type()
711
660
    if (type.ptr() != tmp)
720
669
    {
721
670
      if (field->charset() != share->table_charset)
722
671
      {
723
 
        packet->append(STRING_WITH_LEN(" CHARACTER SET "));
724
 
        packet->append(field->charset()->csname);
 
672
        packet->append(STRING_WITH_LEN(" CHARACTER SET "));
 
673
        packet->append(field->charset()->csname);
725
674
      }
726
 
      /* 
727
 
        For string types dump collation name only if 
728
 
        collation is not primary for the given charset
 
675
 
 
676
      /*
 
677
        For string types dump collation name only if
 
678
        collation is not primary for the given charset
729
679
      */
730
680
      if (!(field->charset()->state & MY_CS_PRIMARY))
731
681
      {
732
 
        packet->append(STRING_WITH_LEN(" COLLATE "));
733
 
        packet->append(field->charset()->name);
 
682
        packet->append(STRING_WITH_LEN(" COLLATE "));
 
683
        packet->append(field->charset()->name);
734
684
      }
735
685
    }
736
686
 
754
704
      if (column_format)
755
705
      {
756
706
        packet->append(STRING_WITH_LEN(" /*!"));
757
 
        packet->append(STRING_WITH_LEN(DRIZZLE_VERSION_TABLESPACE_IN_FRM_STR));
758
707
        packet->append(STRING_WITH_LEN(" COLUMN_FORMAT"));
759
708
        if (column_format == COLUMN_FORMAT_TYPE_FIXED)
760
709
          packet->append(STRING_WITH_LEN(" FIXED */"));
762
711
          packet->append(STRING_WITH_LEN(" DYNAMIC */"));
763
712
      }
764
713
    }
765
 
    if (get_field_default_value(thd, table->timestamp_field,
 
714
    if (get_field_default_value(session, table->timestamp_field,
766
715
                                field, &def_value, 1))
767
716
    {
768
717
      packet->append(STRING_WITH_LEN(" DEFAULT "));
795
744
    bool found_primary=0;
796
745
    packet->append(STRING_WITH_LEN(",\n  "));
797
746
 
798
 
    if (i == primary_key && !strcmp(key_info->name, primary_key_name))
 
747
    if (i == primary_key && is_primary_key(key_info))
799
748
    {
800
749
      found_primary=1;
801
750
      /*
810
759
      packet->append(STRING_WITH_LEN("KEY "));
811
760
 
812
761
    if (!found_primary)
813
 
     append_identifier(thd, packet, key_info->name, strlen(key_info->name));
 
762
     packet->append_identifier(key_info->name, strlen(key_info->name));
814
763
 
815
764
    packet->append(STRING_WITH_LEN(" ("));
816
765
 
820
769
        packet->append(',');
821
770
 
822
771
      if (key_part->field)
823
 
        append_identifier(thd,packet,key_part->field->field_name,
824
 
                          strlen(key_part->field->field_name));
 
772
        packet->append_identifier(key_part->field->field_name,
 
773
                                  strlen(key_part->field->field_name));
825
774
      if (key_part->field &&
826
775
          (key_part->length !=
827
776
           table->field[key_part->fieldnr-1]->key_length()))
828
777
      {
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));
 
778
        buff= "(";
 
779
        buff= to_string(buff, (int32_t) key_part->length /
 
780
                              key_part->field->charset()->mbmaxlen);
 
781
        buff += ")";
 
782
        packet->append(buff.c_str(), buff.length());
836
783
      }
837
784
    }
838
785
    packet->append(')');
839
 
    store_key_options(thd, packet, table, key_info);
 
786
    store_key_options(session, packet, table, key_info);
840
787
  }
841
788
 
842
789
  /*
882
829
 
883
830
    if (create_info.auto_increment_value > 1)
884
831
    {
885
 
      char *end;
886
832
      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));
 
833
      buff= to_string(create_info.auto_increment_value);
 
834
      packet->append(buff.c_str(), buff.length());
889
835
    }
890
836
 
891
837
    if (share->min_rows)
892
838
    {
893
 
      char *end;
894
839
      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));
 
840
      buff= to_string(share->min_rows);
 
841
      packet->append(buff.c_str(), buff.length());
897
842
    }
898
843
 
899
844
    if (share->max_rows && !table_list->schema_table)
900
845
    {
901
 
      char *end;
902
846
      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));
 
847
      buff= to_string(share->max_rows);
 
848
      packet->append(buff.c_str(), buff.length());
905
849
    }
906
850
 
907
851
    if (share->avg_row_length)
908
852
    {
909
 
      char *end;
910
853
      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));
 
854
      buff= to_string(share->avg_row_length);
 
855
      packet->append(buff.c_str(), buff.length());
913
856
    }
914
857
 
915
858
    if (share->db_create_options & HA_OPTION_PACK_KEYS)
922
865
    if (share->page_checksum != HA_CHOICE_UNDEF)
923
866
    {
924
867
      packet->append(STRING_WITH_LEN(" PAGE_CHECKSUM="));
925
 
      packet->append(ha_choice_values[(uint) share->page_checksum], 1);
 
868
      packet->append(ha_choice_values[(uint32_t) share->page_checksum], 1);
926
869
    }
927
870
    if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
928
871
      packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
929
872
    if (create_info.row_type != ROW_TYPE_DEFAULT)
930
873
    {
931
874
      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);
 
875
      packet->append(ha_row_type[(uint32_t) create_info.row_type]);
938
876
    }
939
877
    if (table->s->key_block_size)
940
878
    {
941
 
      char *end;
942
879
      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));
 
880
      buff= to_string(table->s->key_block_size);
 
881
      packet->append(buff.c_str(), buff.length());
945
882
    }
946
883
    if (share->block_size)
947
884
    {
948
 
      char *end;
949
885
      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));
 
886
      buff= to_string(share->block_size);
 
887
      packet->append(buff.c_str(), buff.length());
952
888
    }
953
889
    table->file->append_create_info(packet);
954
890
    if (share->comment.length)
961
897
      packet->append(STRING_WITH_LEN(" CONNECTION="));
962
898
      append_unescaped(packet, share->connect_string.str, share->connect_string.length);
963
899
    }
964
 
    append_directory(thd, packet, "DATA",  create_info.data_file_name);
965
 
    append_directory(thd, packet, "INDEX", create_info.index_file_name);
 
900
    append_directory(session, packet, "DATA",  create_info.data_file_name);
 
901
    append_directory(session, packet, "INDEX", create_info.index_file_name);
966
902
  }
967
903
  table->restore_column_map(old_map);
968
904
  return(0);
981
917
  the resulting CREATE statement contains "IF NOT EXISTS" clause. Other flags
982
918
  in @c create_options are ignored.
983
919
 
984
 
  @param  thd           The current thread instance.
 
920
  @param  session           The current thread instance.
985
921
  @param  dbname        The name of the database.
986
922
  @param  buffer        A String instance where the statement is stored.
987
 
  @param  create_info   If not NULL, the options member influences the resulting 
 
923
  @param  create_info   If not NULL, the options member influences the resulting
988
924
                        CRATE statement.
989
925
 
990
926
  @returns true if errors are detected, false otherwise.
991
927
*/
992
928
 
993
 
bool store_db_create_info(THD *thd, const char *dbname, String *buffer,
 
929
bool store_db_create_info(Session *session, const char *dbname, String *buffer,
994
930
                          HA_CREATE_INFO *create_info)
995
931
{
996
932
  HA_CREATE_INFO create;
997
933
  uint32_t create_options = create_info ? create_info->options : 0;
998
934
 
999
935
  if (!my_strcasecmp(system_charset_info, dbname,
1000
 
                     INFORMATION_SCHEMA_NAME.str))
 
936
                     INFORMATION_SCHEMA_NAME.c_str()))
1001
937
  {
1002
 
    dbname= INFORMATION_SCHEMA_NAME.str;
 
938
    dbname= INFORMATION_SCHEMA_NAME.c_str();
1003
939
    create.default_table_charset= system_charset_info;
1004
940
  }
1005
941
  else
1007
943
    if (check_db_dir_existence(dbname))
1008
944
      return(true);
1009
945
 
1010
 
    load_db_opt_by_name(thd, dbname, &create);
 
946
    load_db_opt_by_name(session, dbname, &create);
1011
947
  }
1012
948
 
1013
949
  buffer->length(0);
1016
952
  buffer->append(STRING_WITH_LEN("CREATE DATABASE "));
1017
953
 
1018
954
  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
 
  }
 
955
    buffer->append(STRING_WITH_LEN("IF NOT EXISTS "));
 
956
 
 
957
  buffer->append_identifier(dbname, strlen(dbname));
1035
958
 
1036
959
  return(false);
1037
960
}
1038
961
 
1039
 
static void store_key_options(THD *thd __attribute__((unused)),
 
962
static void store_key_options(Session *,
1040
963
                              String *packet, Table *table,
1041
964
                              KEY *key_info)
1042
965
{
1053
976
  {
1054
977
    packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
1055
978
    end= int64_t10_to_str(key_info->block_size, buff, 10);
1056
 
    packet->append(buff, (uint) (end - buff));
 
979
    packet->append(buff, (uint32_t) (end - buff));
1057
980
  }
1058
981
 
1059
 
  assert(test(key_info->flags & HA_USES_COMMENT) == 
 
982
  assert(test(key_info->flags & HA_USES_COMMENT) ==
1060
983
              (key_info->comment.length > 0));
1061
984
  if (key_info->flags & HA_USES_COMMENT)
1062
985
  {
1063
986
    packet->append(STRING_WITH_LEN(" COMMENT "));
1064
 
    append_unescaped(packet, key_info->comment.str, 
 
987
    append_unescaped(packet, key_info->comment.str,
1065
988
                     key_info->comment.length);
1066
989
  }
1067
990
}
1076
999
public:
1077
1000
  static void *operator new(size_t size)
1078
1001
  {
1079
 
    return (void*) sql_alloc((uint) size);
 
1002
    return (void*) sql_alloc((uint32_t) size);
1080
1003
  }
1081
 
  static void operator delete(void *ptr __attribute__((unused)),
1082
 
                              size_t size __attribute__((unused)))
 
1004
  static void operator delete(void *, size_t)
1083
1005
  { TRASH(ptr, size); }
1084
1006
 
1085
 
  ulong thread_id;
 
1007
  my_thread_id thread_id;
1086
1008
  time_t start_time;
1087
1009
  uint32_t   command;
1088
1010
  const char *user,*host,*db,*proc_info,*state_info;
1093
1015
template class I_List<thread_info>;
1094
1016
#endif
1095
1017
 
1096
 
void mysqld_list_processes(THD *thd,const char *user, bool verbose)
 
1018
void mysqld_list_processes(Session *session,const char *user, bool)
1097
1019
{
1098
1020
  Item *field;
1099
1021
  List<Item> field_list;
1100
1022
  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;
 
1023
  Protocol *protocol= session->protocol;
1104
1024
 
1105
1025
  field_list.push_back(new Item_int("Id", 0, MY_INT32_NUM_DECIMAL_DIGITS));
1106
1026
  field_list.push_back(new Item_empty_string("User",16));
1107
1027
  field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
1108
1028
  field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
1109
 
  field->maybe_null=1;
 
1029
  field->maybe_null= true;
1110
1030
  field_list.push_back(new Item_empty_string("Command",16));
1111
1031
  field_list.push_back(new Item_return_int("Time",7, DRIZZLE_TYPE_LONG));
1112
1032
  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))
 
1033
  field->maybe_null= true;
 
1034
  field_list.push_back(field=new Item_empty_string("Info", PROCESS_LIST_WIDTH));
 
1035
  field->maybe_null= true;
 
1036
  if (protocol->sendFields(&field_list,
 
1037
                           Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
1118
1038
    return;
1119
1039
 
1120
1040
  pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1121
 
  if (!thd->killed)
 
1041
  if (!session->killed)
1122
1042
  {
1123
 
    I_List_iterator<THD> it(threads);
1124
 
    THD *tmp;
1125
 
    while ((tmp=it++))
 
1043
    I_List_iterator<Session> it(session_list);
 
1044
    Session *tmp;
 
1045
    while ((tmp= it++))
1126
1046
    {
1127
 
      Security_context *tmp_sctx= tmp->security_ctx;
 
1047
      Security_context *tmp_sctx= &tmp->security_ctx;
1128
1048
      struct st_my_thread_var *mysys_var;
1129
 
      if ((tmp->vio_ok() || tmp->system_thread) && (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
 
1049
      if (tmp->protocol->isConnected() && (!user || (tmp_sctx->user.c_str() && !strcmp(tmp_sctx->user.c_str(), user))))
1130
1050
      {
1131
 
        thread_info *thd_info= new thread_info;
 
1051
        thread_info *session_info= new thread_info;
1132
1052
 
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;
 
1053
        session_info->thread_id=tmp->thread_id;
 
1054
        session_info->user= session->strdup(tmp_sctx->user.c_str() ? tmp_sctx->user.c_str() : "unauthenticated user");
 
1055
        session_info->host= session->strdup(tmp_sctx->ip.c_str());
 
1056
        if ((session_info->db=tmp->db))             // Safe test
 
1057
          session_info->db=session->strdup(session_info->db);
 
1058
        session_info->command=(int) tmp->command;
1141
1059
        if ((mysys_var= tmp->mysys_var))
1142
1060
          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") :
 
1061
 
 
1062
        if (tmp->killed == Session::KILL_CONNECTION)
 
1063
          session_info->proc_info= (char*) "Killed";
 
1064
        else
 
1065
          session_info->proc_info= command_name[session_info->command].str;
 
1066
 
 
1067
        session_info->state_info= (char*) (tmp->protocol->isWriting() ?
 
1068
                                           "Writing to net" :
 
1069
                                           tmp->protocol->isReading() ?
 
1070
                                           (session_info->command == COM_SLEEP ?
 
1071
                                            NULL : "Reading from net") :
1149
1072
                                       tmp->get_proc_info() ? tmp->get_proc_info() :
1150
1073
                                       tmp->mysys_var &&
1151
1074
                                       tmp->mysys_var->current_cond ?
1153
1076
        if (mysys_var)
1154
1077
          pthread_mutex_unlock(&mysys_var->mutex);
1155
1078
 
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);
 
1079
        session_info->start_time= tmp->start_time;
 
1080
        session_info->query= NULL;
 
1081
        if (tmp->process_list_info[0])
 
1082
          session_info->query= session->strdup(tmp->process_list_info);
 
1083
        thread_infos.append(session_info);
1169
1084
      }
1170
1085
    }
1171
1086
  }
1172
1087
  pthread_mutex_unlock(&LOCK_thread_count);
1173
1088
 
1174
 
  thread_info *thd_info;
1175
 
  time_t now= my_time(0);
1176
 
  while ((thd_info=thread_infos.get()))
 
1089
  thread_info *session_info;
 
1090
  time_t now= time(NULL);
 
1091
  while ((session_info=thread_infos.get()))
1177
1092
  {
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);
 
1093
    protocol->prepareForResend();
 
1094
    protocol->store((uint64_t) session_info->thread_id);
 
1095
    protocol->store(session_info->user, system_charset_info);
 
1096
    protocol->store(session_info->host, system_charset_info);
 
1097
    protocol->store(session_info->db, system_charset_info);
 
1098
    protocol->store(session_info->proc_info, system_charset_info);
 
1099
 
 
1100
    if (session_info->start_time)
 
1101
      protocol->store((uint32_t) (now - session_info->start_time));
 
1102
    else
 
1103
      protocol->store();
 
1104
 
 
1105
    protocol->store(session_info->state_info, system_charset_info);
 
1106
    protocol->store(session_info->query, system_charset_info);
 
1107
 
1193
1108
    if (protocol->write())
1194
1109
      break; /* purecov: inspected */
1195
1110
  }
1196
 
  my_eof(thd);
 
1111
  session->my_eof();
1197
1112
  return;
1198
1113
}
1199
1114
 
1200
 
int fill_schema_processlist(THD* thd, TableList* tables,
1201
 
                            COND* cond __attribute__((unused)))
 
1115
int fill_schema_processlist(Session* session, TableList* tables, COND*)
1202
1116
{
1203
1117
  Table *table= tables->table;
1204
1118
  const CHARSET_INFO * const cs= system_charset_info;
1205
1119
  char *user;
1206
 
  time_t now= my_time(0);
 
1120
  time_t now= time(NULL);
 
1121
  size_t length;
 
1122
 
 
1123
  if (now == (time_t)-1)
 
1124
    return 1;
1207
1125
 
1208
1126
  user= NULL;
1209
1127
 
1210
1128
  pthread_mutex_lock(&LOCK_thread_count);
1211
1129
 
1212
 
  if (!thd->killed)
 
1130
  if (!session->killed)
1213
1131
  {
1214
 
    I_List_iterator<THD> it(threads);
1215
 
    THD* tmp;
 
1132
    I_List_iterator<Session> it(session_list);
 
1133
    Session* tmp;
1216
1134
 
1217
1135
    while ((tmp= it++))
1218
1136
    {
1219
 
      Security_context *tmp_sctx= tmp->security_ctx;
 
1137
      Security_context *tmp_sctx= &tmp->security_ctx;
1220
1138
      struct st_my_thread_var *mysys_var;
1221
1139
      const char *val;
1222
1140
 
1223
 
      if ((!tmp->vio_ok() && !tmp->system_thread))
 
1141
      if (! tmp->protocol->isConnected())
1224
1142
        continue;
1225
1143
 
1226
 
      restore_record(table, s->default_values);
 
1144
      table->restoreRecordAsDefault();
1227
1145
      /* ID */
1228
1146
      table->field[0]->store((int64_t) tmp->thread_id, true);
1229
1147
      /* USER */
1230
 
      val= tmp_sctx->user ? tmp_sctx->user :
1231
 
            (tmp->system_thread ? "system user" : "unauthenticated user");
 
1148
      val= tmp_sctx->user.c_str() ? tmp_sctx->user.c_str() : "unauthenticated user";
1232
1149
      table->field[1]->store(val, strlen(val), cs);
1233
1150
      /* HOST */
1234
 
      table->field[2]->store(tmp_sctx->ip, strlen(tmp_sctx->ip), cs);
 
1151
      table->field[2]->store(tmp_sctx->ip.c_str(), strlen(tmp_sctx->ip.c_str()), cs);
1235
1152
      /* DB */
1236
1153
      if (tmp->db)
1237
1154
      {
1242
1159
      if ((mysys_var= tmp->mysys_var))
1243
1160
        pthread_mutex_lock(&mysys_var->mutex);
1244
1161
      /* COMMAND */
1245
 
      if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0)))
 
1162
      if ((val= (char *) (tmp->killed == Session::KILL_CONNECTION? "Killed" : 0)))
1246
1163
        table->field[4]->store(val, strlen(val), cs);
1247
1164
      else
1248
1165
        table->field[4]->store(command_name[tmp->command].str,
1251
1168
      table->field[5]->store((uint32_t)(tmp->start_time ?
1252
1169
                                      now - tmp->start_time : 0), true);
1253
1170
      /* 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") :
 
1171
      val= (char*) (tmp->protocol->isWriting() ?
 
1172
                    "Writing to net" :
 
1173
                    tmp->protocol->isReading() ?
 
1174
                    (tmp->command == COM_SLEEP ?
 
1175
                     NULL : "Reading from net") :
1259
1176
                    tmp->get_proc_info() ? tmp->get_proc_info() :
1260
1177
                    tmp->mysys_var &&
1261
1178
                    tmp->mysys_var->current_cond ?
1269
1186
      if (mysys_var)
1270
1187
        pthread_mutex_unlock(&mysys_var->mutex);
1271
1188
 
1272
 
      /* INFO */
1273
 
      if (tmp->query)
 
1189
      length= strlen(tmp->process_list_info);
 
1190
 
 
1191
      if (length)
1274
1192
      {
1275
 
        table->field[7]->store(tmp->query,
1276
 
                               cmin((uint32_t)PROCESS_LIST_INFO_WIDTH,
1277
 
                                   tmp->query_length), cs);
 
1193
        table->field[7]->store(tmp->process_list_info, length, cs);
1278
1194
        table->field[7]->set_notnull();
1279
1195
      }
1280
1196
 
1281
 
      if (schema_table_store_record(thd, table))
 
1197
      if (schema_table_store_record(session, table))
1282
1198
      {
1283
1199
        pthread_mutex_unlock(&LOCK_thread_count);
1284
1200
        return(1);
1294
1210
  Status functions
1295
1211
*****************************************************************************/
1296
1212
 
1297
 
static DYNAMIC_ARRAY all_status_vars;
 
1213
static vector<SHOW_VAR *> all_status_vars;
1298
1214
static bool status_vars_inited= 0;
1299
 
static int show_var_cmp(const void *var1, const void *var2)
 
1215
int show_var_cmp(const void *var1, const void *var2)
1300
1216
{
1301
1217
  return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
1302
1218
}
1303
1219
 
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)
 
1220
class show_var_cmp_functor
1309
1221
{
1310
 
  uint32_t a,b;
1311
 
  SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
 
1222
  public:
 
1223
  show_var_cmp_functor() { }
 
1224
  inline bool operator()(const SHOW_VAR *var1, const SHOW_VAR *var2) const
 
1225
  {
 
1226
    int val= strcmp(var1->name, var2->name);
 
1227
    return (val < 0);
 
1228
  }
 
1229
};
1312
1230
 
1313
 
  for (a= b= 0; b < array->elements; b++)
1314
 
    if (all[b].type != SHOW_UNDEF)
1315
 
      all[a++]= all[b];
1316
 
  if (a)
 
1231
class show_var_remove_if
 
1232
{
 
1233
  public:
 
1234
  show_var_remove_if() { }
 
1235
  inline bool operator()(const SHOW_VAR *curr) const
1317
1236
  {
1318
 
    memset(all+a, 0, sizeof(SHOW_VAR)); // writing NULL-element to the end
1319
 
    array->elements= a;
 
1237
    return (curr->type == SHOW_UNDEF);
1320
1238
  }
1321
 
  else // array is completely empty - delete it
1322
 
    delete_dynamic(array);
1323
 
}
 
1239
};
1324
1240
 
1325
1241
/*
1326
1242
  Adds an array of SHOW_VAR entries to the output of SHOW STATUS
1338
1254
    As a special optimization, if add_status_vars() is called before
1339
1255
    init_status_vars(), it assumes "startup mode" - neither concurrent access
1340
1256
    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
1257
*/
1344
1258
int add_status_vars(SHOW_VAR *list)
1345
1259
{
1346
1260
  int res= 0;
1347
1261
  if (status_vars_inited)
1348
1262
    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
1263
  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
 
1264
    all_status_vars.insert(all_status_vars.begin(), list++);
1359
1265
  if (status_vars_inited)
1360
 
    sort_dynamic(&all_status_vars, show_var_cmp);
1361
 
err:
 
1266
    sort(all_status_vars.begin(), all_status_vars.end(),
 
1267
         show_var_cmp_functor());
1362
1268
  if (status_vars_inited)
1363
1269
    pthread_mutex_unlock(&LOCK_status);
1364
1270
  return res;
1374
1280
*/
1375
1281
void init_status_vars()
1376
1282
{
1377
 
  status_vars_inited=1;
1378
 
  sort_dynamic(&all_status_vars, show_var_cmp);
 
1283
  status_vars_inited= 1;
 
1284
  sort(all_status_vars.begin(), all_status_vars.end(),
 
1285
       show_var_cmp_functor());
1379
1286
}
1380
1287
 
1381
1288
void reset_status_vars()
1382
1289
{
1383
 
  SHOW_VAR *ptr= (SHOW_VAR*) all_status_vars.buffer;
1384
 
  SHOW_VAR *last= ptr + all_status_vars.elements;
1385
 
  for (; ptr < last; ptr++)
 
1290
  vector<SHOW_VAR *>::iterator p= all_status_vars.begin();
 
1291
  while (p != all_status_vars.end())
1386
1292
  {
1387
1293
    /* Note that SHOW_LONG_NOFLUSH variables are not reset */
1388
 
    if (ptr->type == SHOW_LONG)
1389
 
      *(ulong*) ptr->value= 0;
1390
 
  }  
 
1294
    if ((*p)->type == SHOW_LONG)
 
1295
      (*p)->value= 0;
 
1296
    ++p;
 
1297
  }
1391
1298
}
1392
1299
 
1393
1300
/*
1396
1303
  DESCRIPTION
1397
1304
    This function is not strictly required if all add_to_status/
1398
1305
    remove_status_vars are properly paired, but it's a safety measure that
1399
 
    deletes everything from the all_status_vars[] even if some
 
1306
    deletes everything from the all_status_vars vector even if some
1400
1307
    remove_status_vars were forgotten
1401
1308
*/
1402
1309
void free_status_vars()
1403
1310
{
1404
 
  delete_dynamic(&all_status_vars);
 
1311
  all_status_vars.clear();
1405
1312
}
1406
1313
 
1407
1314
/*
1423
1330
  if (status_vars_inited)
1424
1331
  {
1425
1332
    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;
 
1333
    SHOW_VAR *all= all_status_vars.front();
 
1334
    int a= 0, b= all_status_vars.size(), c= (a+b)/2;
1428
1335
 
1429
1336
    for (; list->name; list++)
1430
1337
    {
1431
1338
      int res= 0;
1432
 
      for (a= 0, b= all_status_vars.elements; b-a > 1; c= (a+b)/2)
 
1339
      for (a= 0, b= all_status_vars.size(); b-a > 1; c= (a+b)/2)
1433
1340
      {
1434
1341
        res= show_var_cmp(list, all+c);
1435
1342
        if (res < 0)
1442
1349
      if (res == 0)
1443
1350
        all[c].type= SHOW_UNDEF;
1444
1351
    }
1445
 
    shrink_var_array(&all_status_vars);
 
1352
    /* removes all the SHOW_UNDEF elements from the vector */
 
1353
    all_status_vars.erase(std::remove_if(all_status_vars.begin(),
 
1354
                            all_status_vars.end(),show_var_remove_if()),
 
1355
                            all_status_vars.end());
1446
1356
    pthread_mutex_unlock(&LOCK_status);
1447
1357
  }
1448
1358
  else
1449
1359
  {
1450
 
    SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
 
1360
    SHOW_VAR *all= all_status_vars.front();
1451
1361
    uint32_t i;
1452
1362
    for (; list->name; list++)
1453
1363
    {
1454
 
      for (i= 0; i < all_status_vars.elements; i++)
 
1364
      for (i= 0; i < all_status_vars.size(); i++)
1455
1365
      {
1456
1366
        if (show_var_cmp(list, all+i))
1457
1367
          continue;
1459
1369
        break;
1460
1370
      }
1461
1371
    }
1462
 
    shrink_var_array(&all_status_vars);
 
1372
    /* removes all the SHOW_UNDEF elements from the vector */
 
1373
    all_status_vars.erase(std::remove_if(all_status_vars.begin(),
 
1374
                            all_status_vars.end(),show_var_remove_if()),
 
1375
                            all_status_vars.end());
1463
1376
  }
1464
1377
}
1465
1378
 
1469
1382
    *buf= my_toupper(system_charset_info, *buf);
1470
1383
}
1471
1384
 
1472
 
static bool show_status_array(THD *thd, const char *wild,
 
1385
static bool show_status_array(Session *session, const char *wild,
1473
1386
                              SHOW_VAR *variables,
1474
1387
                              enum enum_var_type value_type,
1475
1388
                              struct system_status_var *status_var,
1476
1389
                              const char *prefix, Table *table,
1477
1390
                              bool ucase_names)
1478
1391
{
1479
 
  MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, long);
 
1392
  MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, int64_t);
1480
1393
  char * const buff= (char *) &buff_data;
1481
1394
  char *prefix_end;
1482
1395
  /* the variable name should not be longer than 64 characters */
1483
1396
  char name_buffer[64];
1484
1397
  int len;
1485
 
  LEX_STRING null_lex_str;
1486
1398
  SHOW_VAR tmp, *var;
1487
1399
 
1488
 
  null_lex_str.str= 0;                          // For sys_var->value_ptr()
1489
 
  null_lex_str.length= 0;
 
1400
  prefix_end= strncpy(name_buffer, prefix, sizeof(name_buffer)-1);
 
1401
  prefix_end+= strlen(prefix);
1490
1402
 
1491
 
  prefix_end=my_stpncpy(name_buffer, prefix, sizeof(name_buffer)-1);
1492
1403
  if (*prefix)
1493
1404
    *prefix_end++= '_';
1494
1405
  len=name_buffer + sizeof(name_buffer) - prefix_end;
1495
1406
 
1496
1407
  for (; variables->name; variables++)
1497
1408
  {
1498
 
    my_stpncpy(prefix_end, variables->name, len);
 
1409
    strncpy(prefix_end, variables->name, len);
1499
1410
    name_buffer[sizeof(name_buffer)-1]=0;       /* Safety */
1500
1411
    if (ucase_names)
1501
1412
      make_upper(name_buffer);
1505
1416
      Repeat as necessary, if new var is again SHOW_FUNC
1506
1417
    */
1507
1418
    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);
 
1419
      ((mysql_show_var_func)((st_show_var_func_container *)var->value)->func)(session, &tmp, buff);
1509
1420
 
1510
1421
    SHOW_TYPE show_type=var->type;
1511
1422
    if (show_type == SHOW_ARRAY)
1512
1423
    {
1513
 
      show_status_array(thd, wild, (SHOW_VAR *) var->value, value_type,
 
1424
      show_status_array(session, wild, (SHOW_VAR *) var->value, value_type,
1514
1425
                        status_var, name_buffer, table, ucase_names);
1515
1426
    }
1516
1427
    else
1520
1431
      {
1521
1432
        char *value=var->value;
1522
1433
        const char *pos, *end;                  // We assign a lot of const's
1523
 
 
1524
1434
        pthread_mutex_lock(&LOCK_global_system_variables);
1525
1435
 
1526
1436
        if (show_type == SHOW_SYS)
1527
1437
        {
1528
1438
          show_type= ((sys_var*) value)->show_type();
1529
 
          value=     (char*) ((sys_var*) value)->value_ptr(thd, value_type,
1530
 
                                                           &null_lex_str);
 
1439
          value= (char*) ((sys_var*) value)->value_ptr(session, value_type,
 
1440
                                                       &null_lex_str);
1531
1441
        }
1532
1442
 
1533
1443
        pos= end= buff;
1547
1457
          value= ((char *) status_var + (ulong) value);
1548
1458
          /* fall through */
1549
1459
        case SHOW_LONG:
1550
 
        case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
1551
1460
          end= int10_to_str(*(long*) value, buff, 10);
1552
1461
          break;
1553
1462
        case SHOW_LONGLONG_STATUS:
1556
1465
        case SHOW_LONGLONG:
1557
1466
          end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1558
1467
          break;
 
1468
        case SHOW_SIZE:
 
1469
          {
 
1470
            stringstream ss (stringstream::in);
 
1471
            ss << *(size_t*) value;
 
1472
 
 
1473
            string str= ss.str();
 
1474
            strncpy(buff, str.c_str(), str.length());
 
1475
            end= buff+ str.length();
 
1476
          }
 
1477
          break;
1559
1478
        case SHOW_HA_ROWS:
1560
1479
          end= int64_t10_to_str((int64_t) *(ha_rows*) value, buff, 10);
1561
1480
          break;
1562
1481
        case SHOW_BOOL:
1563
 
          end= my_stpcpy(buff, *(bool*) value ? "ON" : "OFF");
 
1482
          end+= sprintf(buff,"%s", *(bool*) value ? "ON" : "OFF");
1564
1483
          break;
1565
1484
        case SHOW_MY_BOOL:
1566
 
          end= my_stpcpy(buff, *(bool*) value ? "ON" : "OFF");
 
1485
          end+= sprintf(buff,"%s", *(bool*) value ? "ON" : "OFF");
1567
1486
          break;
1568
1487
        case SHOW_INT:
 
1488
        case SHOW_INT_NOFLUSH: // the difference lies in refresh_status()
1569
1489
          end= int10_to_str((long) *(uint32_t*) value, buff, 10);
1570
1490
          break;
1571
1491
        case SHOW_HAVE:
1572
1492
        {
1573
 
          SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
1574
 
          pos= show_comp_option_name[(int) tmp];
 
1493
          SHOW_COMP_OPTION tmp_option= *(SHOW_COMP_OPTION *)value;
 
1494
          pos= show_comp_option_name[(int) tmp_option];
1575
1495
          end= strchr(pos, '\0');
1576
1496
          break;
1577
1497
        }
1604
1524
          assert(0);
1605
1525
          break;
1606
1526
        }
1607
 
        restore_record(table, s->default_values);
 
1527
        table->restoreRecordAsDefault();
1608
1528
        table->field[0]->store(name_buffer, strlen(name_buffer),
1609
1529
                               system_charset_info);
1610
1530
        table->field[1]->store(pos, (uint32_t) (end - pos), system_charset_info);
1612
1532
 
1613
1533
        pthread_mutex_unlock(&LOCK_global_system_variables);
1614
1534
 
1615
 
        if (schema_table_store_record(thd, table))
 
1535
        if (schema_table_store_record(session, table))
1616
1536
          return(true);
1617
1537
      }
1618
1538
    }
1630
1550
  /* Ensure that thread id not killed during loop */
1631
1551
  pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1632
1552
 
1633
 
  I_List_iterator<THD> it(threads);
1634
 
  THD *tmp;
1635
 
  
 
1553
  I_List_iterator<Session> it(session_list);
 
1554
  Session *tmp;
 
1555
 
1636
1556
  /* Get global values as base */
1637
1557
  *to= global_status_var;
1638
 
  
 
1558
 
1639
1559
  /* Add to this status from existing threads */
1640
1560
  while ((tmp= it++))
1641
1561
    add_to_status(to, &tmp->status_var);
1642
 
  
 
1562
 
1643
1563
  pthread_mutex_unlock(&LOCK_thread_count);
1644
1564
  return;
1645
1565
}
1646
1566
 
1647
1567
 
1648
1568
/* This is only used internally, but we need it here as a forward reference */
1649
 
extern ST_SCHEMA_TABLE schema_tables[];
 
1569
extern InfoSchemaTable schema_tables[];
1650
1570
 
1651
1571
typedef struct st_lookup_field_values
1652
1572
{
1661
1581
 
1662
1582
  SYNOPSIS
1663
1583
    schema_table_store_record()
1664
 
    thd                   thread handler
 
1584
    session                   thread handler
1665
1585
    table                 Information schema table to be updated
1666
1586
 
1667
1587
  RETURN
1669
1589
    1                     error
1670
1590
*/
1671
1591
 
1672
 
bool schema_table_store_record(THD *thd, Table *table)
 
1592
bool schema_table_store_record(Session *session, Table *table)
1673
1593
{
1674
1594
  int error;
1675
1595
  if ((error= table->file->ha_write_row(table->record[0])))
1676
1596
  {
1677
 
    TMP_TABLE_PARAM *param= table->pos_in_table_list->schema_table_param;
 
1597
    Tmp_Table_Param *param= table->pos_in_table_list->schema_table_param;
1678
1598
 
1679
 
    if (create_myisam_from_heap(thd, table, param->start_recinfo, 
 
1599
    if (create_myisam_from_heap(session, table, param->start_recinfo,
1680
1600
                                &param->recinfo, error, 0))
1681
1601
      return 1;
1682
1602
  }
1684
1604
}
1685
1605
 
1686
1606
 
1687
 
int make_table_list(THD *thd, SELECT_LEX *sel,
 
1607
int make_table_list(Session *session, Select_Lex *sel,
1688
1608
                    LEX_STRING *db_name, LEX_STRING *table_name)
1689
1609
{
1690
1610
  Table_ident *table_ident;
1691
 
  table_ident= new Table_ident(thd, *db_name, *table_name, 1);
 
1611
  table_ident= new Table_ident(session, *db_name, *table_name, 1);
1692
1612
  sel->init_query();
1693
 
  if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ))
 
1613
  if (!sel->add_table_to_list(session, table_ident, 0, 0, TL_READ))
1694
1614
    return 1;
1695
1615
  return 0;
1696
1616
}
1697
1617
 
1698
1618
 
1699
1619
/**
1700
 
  @brief    Get lookup value from the part of 'WHERE' condition 
 
1620
  @brief    Get lookup value from the part of 'WHERE' condition
1701
1621
 
1702
 
  @details This function gets lookup value from 
1703
 
           the part of 'WHERE' condition if it's possible and 
 
1622
  @details This function gets lookup value from
 
1623
           the part of 'WHERE' condition if it's possible and
1704
1624
           fill appropriate lookup_field_vals struct field
1705
1625
           with this value.
1706
1626
 
1707
 
  @param[in]      thd                   thread handler
 
1627
  @param[in]      session                   thread handler
1708
1628
  @param[in]      item_func             part of WHERE condition
1709
1629
  @param[in]      table                 I_S table
1710
 
  @param[in, out] lookup_field_vals     Struct which holds lookup values 
 
1630
  @param[in, out] lookup_field_vals     Struct which holds lookup values
1711
1631
 
1712
1632
  @return
1713
1633
    0             success
1714
1634
    1             error, there can be no matching records for the condition
1715
1635
*/
1716
1636
 
1717
 
bool get_lookup_value(THD *thd, Item_func *item_func,
1718
 
                      TableList *table, 
 
1637
bool get_lookup_value(Session *session, Item_func *item_func,
 
1638
                      TableList *table,
1719
1639
                      LOOKUP_FIELD_VALUES *lookup_field_vals)
1720
1640
{
1721
 
  ST_SCHEMA_TABLE *schema_table= table->schema_table;
 
1641
  InfoSchemaTable *schema_table= table->schema_table;
1722
1642
  ST_FIELD_INFO *field_info= schema_table->fields_info;
1723
1643
  const char *field_name1= schema_table->idx_field1 >= 0 ?
1724
1644
    field_info[schema_table->idx_field1].field_name : "";
1763
1683
                               (unsigned char *) item_field->field_name,
1764
1684
                               strlen(item_field->field_name), 0))
1765
1685
    {
1766
 
      thd->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(),
 
1686
      session->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(),
1767
1687
                           tmp_str->length(), false);
1768
1688
    }
1769
1689
    /* Lookup value is table name */
1772
1692
                                    (unsigned char *) item_field->field_name,
1773
1693
                                    strlen(item_field->field_name), 0))
1774
1694
    {
1775
 
      thd->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(),
 
1695
      session->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(),
1776
1696
                           tmp_str->length(), false);
1777
1697
    }
1778
1698
  }
1781
1701
 
1782
1702
 
1783
1703
/**
1784
 
  @brief    Calculates lookup values from 'WHERE' condition 
 
1704
  @brief    Calculates lookup values from 'WHERE' condition
1785
1705
 
1786
1706
  @details This function calculates lookup value(database name, table name)
1787
 
           from 'WHERE' condition if it's possible and 
 
1707
           from 'WHERE' condition if it's possible and
1788
1708
           fill lookup_field_vals struct fields with these values.
1789
1709
 
1790
 
  @param[in]      thd                   thread handler
 
1710
  @param[in]      session                   thread handler
1791
1711
  @param[in]      cond                  WHERE condition
1792
1712
  @param[in]      table                 I_S table
1793
 
  @param[in, out] lookup_field_vals     Struct which holds lookup values 
 
1713
  @param[in, out] lookup_field_vals     Struct which holds lookup values
1794
1714
 
1795
1715
  @return
1796
1716
    0             success
1797
1717
    1             error, there can be no matching records for the condition
1798
1718
*/
1799
1719
 
1800
 
bool calc_lookup_values_from_cond(THD *thd, COND *cond, TableList *table,
 
1720
bool calc_lookup_values_from_cond(Session *session, COND *cond, TableList *table,
1801
1721
                                  LOOKUP_FIELD_VALUES *lookup_field_vals)
1802
1722
{
1803
1723
  if (!cond)
1813
1733
      {
1814
1734
        if (item->type() == Item::FUNC_ITEM)
1815
1735
        {
1816
 
          if (get_lookup_value(thd, (Item_func*)item, table, lookup_field_vals))
 
1736
          if (get_lookup_value(session, (Item_func*)item, table, lookup_field_vals))
1817
1737
            return 1;
1818
1738
        }
1819
1739
        else
1820
1740
        {
1821
 
          if (calc_lookup_values_from_cond(thd, item, table, lookup_field_vals))
 
1741
          if (calc_lookup_values_from_cond(session, item, table, lookup_field_vals))
1822
1742
            return 1;
1823
1743
        }
1824
1744
      }
1826
1746
    return 0;
1827
1747
  }
1828
1748
  else if (cond->type() == Item::FUNC_ITEM &&
1829
 
           get_lookup_value(thd, (Item_func*) cond, table, lookup_field_vals))
 
1749
           get_lookup_value(session, (Item_func*) cond, table, lookup_field_vals))
1830
1750
    return 1;
1831
1751
  return 0;
1832
1752
}
1847
1767
  {
1848
1768
    Item_field *item_field= (Item_field*)item;
1849
1769
    const CHARSET_INFO * const cs= system_charset_info;
1850
 
    ST_SCHEMA_TABLE *schema_table= table->schema_table;
 
1770
    InfoSchemaTable *schema_table= table->schema_table;
1851
1771
    ST_FIELD_INFO *field_info= schema_table->fields_info;
1852
1772
    const char *field_name1= schema_table->idx_field1 >= 0 ?
1853
1773
      field_info[schema_table->idx_field1].field_name : "";
1936
1856
           from LEX struct and fill lookup_field_vals struct field
1937
1857
           with these values.
1938
1858
 
1939
 
  @param[in]      thd                   thread handler
 
1859
  @param[in]      session                   thread handler
1940
1860
  @param[in]      cond                  WHERE condition
1941
1861
  @param[in]      tables                I_S table
1942
 
  @param[in, out] lookup_field_values   Struct which holds lookup values 
 
1862
  @param[in, out] lookup_field_values   Struct which holds lookup values
1943
1863
 
1944
1864
  @return
1945
1865
    0             success
1946
1866
    1             error, there can be no matching records for the condition
1947
1867
*/
1948
1868
 
1949
 
bool get_lookup_field_values(THD *thd, COND *cond, TableList *tables,
 
1869
bool get_lookup_field_values(Session *session, COND *cond, TableList *tables,
1950
1870
                             LOOKUP_FIELD_VALUES *lookup_field_values)
1951
1871
{
1952
 
  LEX *lex= thd->lex;
 
1872
  LEX *lex= session->lex;
1953
1873
  const char *wild= lex->wild ? lex->wild->ptr() : NULL;
1954
1874
  memset(lookup_field_values, 0, sizeof(LOOKUP_FIELD_VALUES));
1955
1875
  switch (lex->sql_command) {
1977
1897
      The "default" is for queries over I_S.
1978
1898
      All previous cases handle SHOW commands.
1979
1899
    */
1980
 
    return calc_lookup_values_from_cond(thd, cond, tables, lookup_field_values);
 
1900
    return calc_lookup_values_from_cond(session, cond, tables, lookup_field_values);
1981
1901
  }
1982
1902
}
1983
1903
 
1984
1904
 
1985
 
enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
 
1905
enum enum_schema_tables get_schema_table_idx(InfoSchemaTable *schema_table)
1986
1906
{
1987
1907
  return (enum enum_schema_tables) (schema_table - &schema_tables[0]);
1988
1908
}
1993
1913
 
1994
1914
  SYNOPSIS
1995
1915
    make_db_list()
1996
 
    thd                   thread handler
 
1916
    session                   thread handler
1997
1917
    files                 list of db names
1998
1918
    wild                  wild string
1999
1919
    idx_field_vals        idx_field_vals->db_name contains db name or
2000
1920
                          wild string
2001
1921
    with_i_schema         returns 1 if we added 'IS' name to list
2002
 
                          otherwise returns 0 
 
1922
                          otherwise returns 0
2003
1923
 
2004
1924
  RETURN
2005
1925
    zero                  success
2006
1926
    non-zero              error
2007
1927
*/
2008
1928
 
2009
 
int make_db_list(THD *thd, List<LEX_STRING> *files,
 
1929
int make_db_list(Session *session, List<LEX_STRING> *files,
2010
1930
                 LOOKUP_FIELD_VALUES *lookup_field_vals,
2011
1931
                 bool *with_i_schema)
2012
1932
{
2013
1933
  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);
 
1934
  i_s_name_copy= session->make_lex_string(i_s_name_copy,
 
1935
                                      INFORMATION_SCHEMA_NAME.c_str(),
 
1936
                                      INFORMATION_SCHEMA_NAME.length(), true);
2017
1937
  *with_i_schema= 0;
2018
1938
  if (lookup_field_vals->wild_db_value)
2019
1939
  {
2023
1943
      LIKE clause (see also get_index_field_values() function)
2024
1944
    */
2025
1945
    if (!lookup_field_vals->db_value.str ||
2026
 
        !wild_case_compare(system_charset_info, 
2027
 
                           INFORMATION_SCHEMA_NAME.str,
 
1946
        !wild_case_compare(system_charset_info,
 
1947
                           INFORMATION_SCHEMA_NAME.c_str(),
2028
1948
                           lookup_field_vals->db_value.str))
2029
1949
    {
2030
1950
      *with_i_schema= 1;
2031
1951
      if (files->push_back(i_s_name_copy))
2032
1952
        return 1;
2033
1953
    }
2034
 
    return (find_files(thd, files, NULL, mysql_data_home,
 
1954
    return (find_files(session, files, NULL, drizzle_data_home,
2035
1955
                       lookup_field_vals->db_value.str, 1) != FIND_FILES_OK);
2036
1956
  }
2037
1957
 
2042
1962
  */
2043
1963
  if (lookup_field_vals->db_value.str)
2044
1964
  {
2045
 
    if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str,
 
1965
    if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.c_str(),
2046
1966
                       lookup_field_vals->db_value.str))
2047
1967
    {
2048
1968
      *with_i_schema= 1;
2062
1982
  if (files->push_back(i_s_name_copy))
2063
1983
    return 1;
2064
1984
  *with_i_schema= 1;
2065
 
  return (find_files(thd, files, NULL,
2066
 
                     mysql_data_home, NULL, 1) != FIND_FILES_OK);
 
1985
  return (find_files(session, files, NULL,
 
1986
                     drizzle_data_home, NULL, 1) != FIND_FILES_OK);
2067
1987
}
2068
1988
 
2069
1989
 
2070
 
struct st_add_schema_table 
 
1990
struct st_add_schema_table
2071
1991
{
2072
1992
  List<LEX_STRING> *files;
2073
1993
  const char *wild;
2074
1994
};
2075
1995
 
2076
1996
 
2077
 
static bool add_schema_table(THD *thd, plugin_ref plugin,
2078
 
                                void* p_data)
 
1997
class AddSchemaTable : public unary_function<InfoSchemaTable *, bool>
2079
1998
{
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)
 
1999
  Session *session;
 
2000
  st_add_schema_table *data;
 
2001
public:
 
2002
  AddSchemaTable(Session *session_arg, st_add_schema_table *data_arg)
 
2003
    : session(session_arg), data(data_arg) {}
 
2004
  result_type operator() (argument_type schema_table)
2089
2005
  {
2090
 
    if (lower_case_table_names)
 
2006
    LEX_STRING *file_name= 0;
 
2007
    List<LEX_STRING> *file_list= data->files;
 
2008
    const char *wild= data->wild;
 
2009
  
 
2010
    if (schema_table->hidden)
 
2011
        return(0);
 
2012
    if (wild)
2091
2013
    {
2092
 
      if (wild_case_compare(files_charset_info,
2093
 
                            schema_table->table_name,
2094
 
                            wild))
 
2014
      if (lower_case_table_names)
 
2015
      {
 
2016
        if (wild_case_compare(files_charset_info,
 
2017
                              schema_table->table_name,
 
2018
                              wild))
 
2019
          return(0);
 
2020
      }
 
2021
      else if (wild_compare(schema_table->table_name, wild, 0))
2095
2022
        return(0);
2096
2023
    }
2097
 
    else if (wild_compare(schema_table->table_name, wild, 0))
 
2024
  
 
2025
    if ((file_name= session->make_lex_string(file_name, schema_table->table_name,
 
2026
                                         strlen(schema_table->table_name),
 
2027
                                         true)) &&
 
2028
        !file_list->push_back(file_name))
2098
2029
      return(0);
 
2030
    return(1);
2099
2031
  }
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)
 
2032
};
 
2033
 
 
2034
 
 
2035
int schema_tables_add(Session *session, List<LEX_STRING> *files, const char *wild)
2111
2036
{
2112
2037
  LEX_STRING *file_name= 0;
2113
 
  ST_SCHEMA_TABLE *tmp_schema_table= schema_tables;
 
2038
  InfoSchemaTable *tmp_schema_table= schema_tables;
2114
2039
  st_add_schema_table add_data;
2115
2040
 
2116
2041
  for (; tmp_schema_table->table_name; tmp_schema_table++)
2129
2054
      else if (wild_compare(tmp_schema_table->table_name, wild, 0))
2130
2055
        continue;
2131
2056
    }
2132
 
    if ((file_name= 
2133
 
         thd->make_lex_string(file_name, tmp_schema_table->table_name,
 
2057
    if ((file_name=
 
2058
         session->make_lex_string(file_name, tmp_schema_table->table_name,
2134
2059
                              strlen(tmp_schema_table->table_name), true)) &&
2135
2060
        !files->push_back(file_name))
2136
2061
      continue;
2139
2064
 
2140
2065
  add_data.files= files;
2141
2066
  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);
 
2067
  vector<InfoSchemaTable *>::iterator iter=
 
2068
    find_if(all_schema_tables.begin(), all_schema_tables.end(),
 
2069
           AddSchemaTable(session, &add_data));
 
2070
  if (iter != all_schema_tables.end())
 
2071
    return 1;
 
2072
  return 0 ;
2147
2073
}
2148
2074
 
2149
2075
 
2153
2079
  @details        The function creates the list of table names in
2154
2080
                  database
2155
2081
 
2156
 
  @param[in]      thd                   thread handler
 
2082
  @param[in]      session                   thread handler
2157
2083
  @param[in]      table_names           List of table names in database
2158
2084
  @param[in]      lex                   pointer to LEX struct
2159
2085
  @param[in]      lookup_field_vals     pointer to LOOKUP_FIELD_VALUE struct
2167
2093
*/
2168
2094
 
2169
2095
static int
2170
 
make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
 
2096
make_table_name_list(Session *session, List<LEX_STRING> *table_names, LEX *lex,
2171
2097
                     LOOKUP_FIELD_VALUES *lookup_field_vals,
2172
2098
                     bool with_i_schema, LEX_STRING *db_name)
2173
2099
{
2178
2104
  {
2179
2105
    if (with_i_schema)
2180
2106
    {
2181
 
      if (find_schema_table(thd, lookup_field_vals->table_value.str))
 
2107
      if (find_schema_table(session, lookup_field_vals->table_value.str))
2182
2108
      {
2183
2109
        if (table_names->push_back(&lookup_field_vals->table_value))
2184
2110
          return 1;
2185
2111
      }
2186
2112
    }
2187
2113
    else
2188
 
    {    
 
2114
    {
2189
2115
      if (table_names->push_back(&lookup_field_vals->table_value))
2190
2116
        return 1;
2191
2117
    }
2197
2123
    to the list
2198
2124
  */
2199
2125
  if (with_i_schema)
2200
 
    return (schema_tables_add(thd, table_names,
 
2126
    return (schema_tables_add(session, table_names,
2201
2127
                              lookup_field_vals->table_value.str));
2202
2128
 
2203
 
  find_files_result res= find_files(thd, table_names, db_name->str, path,
 
2129
  find_files_result res= find_files(session, table_names, db_name->str, path,
2204
2130
                                    lookup_field_vals->table_value.str, 0);
2205
2131
  if (res != FIND_FILES_OK)
2206
2132
  {
2214
2140
    {
2215
2141
      if (lex->sql_command != SQLCOM_SELECT)
2216
2142
        return 1;
2217
 
      thd->clear_error();
 
2143
      session->clear_error();
2218
2144
      return 2;
2219
2145
    }
2220
2146
    return 1;
2226
2152
/**
2227
2153
  @brief          Fill I_S table for SHOW COLUMNS|INDEX commands
2228
2154
 
2229
 
  @param[in]      thd                      thread handler
 
2155
  @param[in]      session                      thread handler
2230
2156
  @param[in]      tables                   TableList for I_S table
2231
2157
  @param[in]      schema_table             pointer to I_S structure
2232
2158
  @param[in]      open_tables_state_backup pointer to Open_tables_state object
2239
2165
    @retval       1           error
2240
2166
*/
2241
2167
 
2242
 
static int 
2243
 
fill_schema_show_cols_or_idxs(THD *thd, TableList *tables,
2244
 
                              ST_SCHEMA_TABLE *schema_table,
 
2168
static int
 
2169
fill_schema_show_cols_or_idxs(Session *session, TableList *tables,
 
2170
                              InfoSchemaTable *schema_table,
2245
2171
                              Open_tables_state *open_tables_state_backup)
2246
2172
{
2247
 
  LEX *lex= thd->lex;
 
2173
  LEX *lex= session->lex;
2248
2174
  bool res;
2249
2175
  LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name;
2250
2176
  enum_sql_command save_sql_command= lex->sql_command;
2255
2181
 
2256
2182
  lex->all_selects_list= tables->schema_select_lex;
2257
2183
  /*
2258
 
    Restore thd->temporary_tables to be able to process
 
2184
    Restore session->temporary_tables to be able to process
2259
2185
    temporary tables(only for 'show index' & 'show columns').
2260
2186
    This should be changed when processing of temporary tables for
2261
2187
    I_S tables will be done.
2262
2188
  */
2263
 
  thd->temporary_tables= open_tables_state_backup->temporary_tables;
 
2189
  session->temporary_tables= open_tables_state_backup->temporary_tables;
2264
2190
  /*
2265
2191
    Let us set fake sql_command so views won't try to merge
2266
2192
    themselves into main statement. If we don't do this,
2267
2193
    SELECT * from information_schema.xxxx will cause problems.
2268
 
    SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()' 
 
2194
    SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
2269
2195
  */
2270
2196
  lex->sql_command= SQLCOM_SHOW_FIELDS;
2271
 
  res= open_normal_and_derived_tables(thd, show_table_list,
 
2197
  res= open_normal_and_derived_tables(session, show_table_list,
2272
2198
                                      DRIZZLE_LOCK_IGNORE_FLUSH);
2273
2199
  lex->sql_command= save_sql_command;
2274
2200
  /*
2275
2201
    get_all_tables() returns 1 on failure and 0 on success thus
2276
2202
    return only these and not the result code of ::process_table()
2277
2203
 
2278
 
    We should use show_table_list->alias instead of 
 
2204
    We should use show_table_list->alias instead of
2279
2205
    show_table_list->table_name because table_name
2280
2206
    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 
 
2207
    to use alias because alias contains original table name
 
2208
    in this case(this part of code is used only for
2283
2209
    'show columns' & 'show statistics' commands).
2284
2210
  */
2285
 
   table_name= thd->make_lex_string(&tmp_lex_string1, show_table_list->alias,
 
2211
   table_name= session->make_lex_string(&tmp_lex_string1, show_table_list->alias,
2286
2212
                                    strlen(show_table_list->alias), false);
2287
 
   db_name= thd->make_lex_string(&tmp_lex_string, show_table_list->db,
 
2213
   db_name= session->make_lex_string(&tmp_lex_string, show_table_list->db,
2288
2214
                                 show_table_list->db_length, false);
2289
 
      
2290
 
 
2291
 
   error= test(schema_table->process_table(thd, show_table_list,
 
2215
 
 
2216
 
 
2217
   error= test(schema_table->process_table(session, show_table_list,
2292
2218
                                           table, res, db_name,
2293
2219
                                           table_name));
2294
 
   thd->temporary_tables= 0;
2295
 
   close_tables_for_reopen(thd, &show_table_list);
 
2220
   session->temporary_tables= 0;
 
2221
   close_tables_for_reopen(session, &show_table_list);
2296
2222
   return(error);
2297
2223
}
2298
2224
 
2300
2226
/**
2301
2227
  @brief          Fill I_S table for SHOW Table NAMES commands
2302
2228
 
2303
 
  @param[in]      thd                      thread handler
 
2229
  @param[in]      session                      thread handler
2304
2230
  @param[in]      table                    Table struct for I_S table
2305
2231
  @param[in]      db_name                  database name
2306
2232
  @param[in]      table_name               table name
2311
2237
    @retval       1           error
2312
2238
*/
2313
2239
 
2314
 
static int fill_schema_table_names(THD *thd, Table *table,
 
2240
static int fill_schema_table_names(Session *session, Table *table,
2315
2241
                                   LEX_STRING *db_name, LEX_STRING *table_name,
2316
2242
                                   bool with_i_schema)
2317
2243
{
2322
2248
  }
2323
2249
  else
2324
2250
  {
2325
 
    enum legacy_db_type not_used;
2326
2251
    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
 
    {
 
2252
    (void) build_table_filename(path, sizeof(path), db_name->str,
 
2253
                                table_name->str, "", 0);
 
2254
 
2331
2255
      table->field[3]->store(STRING_WITH_LEN("BASE Table"),
2332
2256
                             system_charset_info);
2333
 
    }
2334
 
    else
2335
 
    {
2336
 
      table->field[3]->store(STRING_WITH_LEN("ERROR"),
2337
 
                             system_charset_info);
2338
 
    }
2339
2257
 
2340
 
    if (thd->is_error() && thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
 
2258
    if (session->is_error() && session->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2341
2259
    {
2342
 
      thd->clear_error();
 
2260
      session->clear_error();
2343
2261
      return 0;
2344
2262
    }
2345
2263
  }
2346
 
  if (schema_table_store_record(thd, table))
 
2264
  if (schema_table_store_record(session, table))
2347
2265
    return 1;
2348
2266
  return 0;
2349
2267
}
2366
2284
*/
2367
2285
 
2368
2286
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)))
 
2287
                                      InfoSchemaTable *schema_table,
 
2288
                                      enum enum_schema_tables)
2371
2289
{
2372
2290
  /*
2373
2291
    determine which method will be used for table opening
2378
2296
    int table_open_method= 0, field_indx= 0;
2379
2297
    for (ptr=tables->table->field; (field= *ptr) ; ptr++)
2380
2298
    {
2381
 
      if (bitmap_is_set(tables->table->read_set, field->field_index))
 
2299
      if (field->isReadSet())
2382
2300
        table_open_method|= schema_table->fields_info[field_indx].open_method;
2383
2301
      field_indx++;
2384
2302
    }
2385
2303
    return table_open_method;
2386
2304
  }
2387
2305
  /* I_S tables which use get_all_tables but can not be optimized */
2388
 
  return (uint) OPEN_FULL_TABLE;
 
2306
  return (uint32_t) OPEN_FULL_TABLE;
2389
2307
}
2390
2308
 
2391
2309
 
2392
2310
/**
2393
2311
  @brief          Fill I_S table with data from FRM file only
2394
2312
 
2395
 
  @param[in]      thd                      thread handler
 
2313
  @param[in]      session                      thread handler
2396
2314
  @param[in]      table                    Table struct for I_S table
2397
2315
  @param[in]      schema_table             I_S table struct
2398
2316
  @param[in]      db_name                  database name
2406
2324
                              open_tables function for this table
2407
2325
*/
2408
2326
 
2409
 
static int fill_schema_table_from_frm(THD *thd,TableList *tables,
2410
 
                                      ST_SCHEMA_TABLE *schema_table,
 
2327
static int fill_schema_table_from_frm(Session *session,TableList *tables,
 
2328
                                      InfoSchemaTable *schema_table,
2411
2329
                                      LEX_STRING *db_name,
2412
2330
                                      LEX_STRING *table_name,
2413
 
                                      enum enum_schema_tables schema_table_idx __attribute__((unused)))
 
2331
                                      enum enum_schema_tables)
2414
2332
{
2415
2333
  Table *table= tables->table;
2416
 
  TABLE_SHARE *share;
 
2334
  TableShare *share;
2417
2335
  Table tbl;
2418
2336
  TableList table_list;
2419
2337
  uint32_t res= 0;
2427
2345
  table_list.table_name= table_name->str;
2428
2346
  table_list.db= db_name->str;
2429
2347
 
2430
 
  key_length= create_table_def_key(thd, key, &table_list, 0);
 
2348
  key_length= create_table_def_key(session, key, &table_list, 0);
2431
2349
  pthread_mutex_lock(&LOCK_open);
2432
 
  share= get_table_share(thd, &table_list, key,
 
2350
  share= get_table_share(session, &table_list, key,
2433
2351
                         key_length, 0, &error);
2434
2352
  if (!share)
2435
2353
  {
2440
2358
  {
2441
2359
    tbl.s= share;
2442
2360
    table_list.table= &tbl;
2443
 
    res= schema_table->process_table(thd, &table_list, table,
 
2361
    res= schema_table->process_table(session, &table_list, table,
2444
2362
                                     res, db_name, table_name);
2445
2363
  }
2446
2364
 
2448
2366
 
2449
2367
err:
2450
2368
  pthread_mutex_unlock(&LOCK_open);
2451
 
  thd->clear_error();
 
2369
  session->clear_error();
2452
2370
  return res;
2453
2371
}
2454
2372
 
2464
2382
                  from frm files and storage engine are filled by the function
2465
2383
                  get_all_tables().
2466
2384
 
2467
 
  @param[in]      thd                      thread handler
 
2385
  @param[in]      session                      thread handler
2468
2386
  @param[in]      tables                   I_S table
2469
2387
  @param[in]      cond                     'WHERE' condition
2470
2388
 
2473
2391
    @retval       1                        error
2474
2392
*/
2475
2393
 
2476
 
int get_all_tables(THD *thd, TableList *tables, COND *cond)
 
2394
int get_all_tables(Session *session, TableList *tables, COND *cond)
2477
2395
{
2478
 
  LEX *lex= thd->lex;
 
2396
  LEX *lex= session->lex;
2479
2397
  Table *table= tables->table;
2480
 
  SELECT_LEX *old_all_select_lex= lex->all_selects_list;
 
2398
  Select_Lex *old_all_select_lex= lex->all_selects_list;
2481
2399
  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;
 
2400
  Select_Lex *lsel= tables->schema_select_lex;
 
2401
  InfoSchemaTable *schema_table= tables->schema_table;
 
2402
  Select_Lex sel;
2485
2403
  LOOKUP_FIELD_VALUES lookup_field_vals;
2486
2404
  LEX_STRING *db_name, *table_name;
2487
2405
  bool with_i_schema;
2489
2407
  List<LEX_STRING> db_names;
2490
2408
  List_iterator_fast<LEX_STRING> it(db_names);
2491
2409
  COND *partial_cond= 0;
2492
 
  uint32_t derived_tables= lex->derived_tables; 
 
2410
  uint32_t derived_tables= lex->derived_tables;
2493
2411
  int error= 1;
2494
2412
  Open_tables_state open_tables_state_backup;
2495
2413
  Query_tables_list query_tables_list_backup;
2496
2414
  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);
 
2415
  bool old_value= session->no_warnings_for_error;
2500
2416
 
2501
2417
  /*
2502
2418
    We should not introduce deadlocks even if we already have some
2503
2419
    tables open and locked, since we won't lock tables which we will
2504
2420
    open and will ignore possible name-locks for these tables.
2505
2421
  */
2506
 
  thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
 
2422
  session->reset_n_backup_open_tables_state(&open_tables_state_backup);
2507
2423
 
2508
2424
  schema_table_idx= get_schema_table_idx(schema_table);
2509
2425
  tables->table_open_method= table_open_method=
2510
2426
    get_table_open_method(tables, schema_table, schema_table_idx);
2511
 
  /* 
 
2427
  /*
2512
2428
    this branch processes SHOW FIELDS, SHOW INDEXES commands.
2513
2429
    see sql_parse.cc, prepare_schema_table() function where
2514
2430
    this values are initialized
2515
2431
  */
2516
2432
  if (lsel && lsel->table_list.first)
2517
2433
  {
2518
 
    error= fill_schema_show_cols_or_idxs(thd, tables, schema_table,
 
2434
    error= fill_schema_show_cols_or_idxs(session, tables, schema_table,
2519
2435
                                         &open_tables_state_backup);
2520
2436
    goto err;
2521
2437
  }
2522
2438
 
2523
 
  if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
 
2439
  if (get_lookup_field_values(session, cond, tables, &lookup_field_vals))
2524
2440
  {
2525
2441
    error= 0;
2526
2442
    goto err;
2528
2444
 
2529
2445
  if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
2530
2446
  {
2531
 
    /* 
 
2447
    /*
2532
2448
      if lookup value is empty string then
2533
2449
      it's impossible table name or db name
2534
2450
    */
2544
2460
      !lookup_field_vals.wild_db_value)
2545
2461
    tables->has_db_lookup_value= true;
2546
2462
  if (lookup_field_vals.table_value.length &&
2547
 
      !lookup_field_vals.wild_table_value) 
 
2463
      !lookup_field_vals.wild_table_value)
2548
2464
    tables->has_table_lookup_value= true;
2549
2465
 
2550
2466
  if (tables->has_db_lookup_value && tables->has_table_lookup_value)
2559
2475
    goto err;
2560
2476
  }
2561
2477
 
2562
 
  if (make_db_list(thd, &db_names, &lookup_field_vals, &with_i_schema))
 
2478
  if (make_db_list(session, &db_names, &lookup_field_vals, &with_i_schema))
2563
2479
    goto err;
2564
2480
  it.rewind(); /* To get access to new elements in basis list */
2565
2481
  while ((db_name= it++))
2566
2482
  {
2567
2483
    {
2568
 
      thd->no_warnings_for_error= 1;
 
2484
      session->no_warnings_for_error= 1;
2569
2485
      List<LEX_STRING> table_names;
2570
 
      int res= make_table_name_list(thd, &table_names, lex,
 
2486
      int res= make_table_name_list(session, &table_names, lex,
2571
2487
                                    &lookup_field_vals,
2572
2488
                                    with_i_schema, db_name);
2573
2489
      if (res == 2)   /* Not fatal error, continue */
2578
2494
      List_iterator_fast<LEX_STRING> it_files(table_names);
2579
2495
      while ((table_name= it_files++))
2580
2496
      {
2581
 
        restore_record(table, s->default_values);
 
2497
        table->restoreRecordAsDefault();
2582
2498
        table->field[schema_table->idx_field1]->
2583
2499
          store(db_name->str, db_name->length, system_charset_info);
2584
2500
        table->field[schema_table->idx_field2]->
2588
2504
        {
2589
2505
          /*
2590
2506
            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 
 
2507
            we can skip table opening and we don't have lookup value for
2592
2508
            table name or lookup value is wild string(table name list is
2593
2509
            already created by make_table_name_list() function).
2594
2510
          */
2596
2512
              (!lookup_field_vals.table_value.length ||
2597
2513
               lookup_field_vals.wild_table_value))
2598
2514
          {
2599
 
            if (schema_table_store_record(thd, table))
 
2515
            if (schema_table_store_record(session, table))
2600
2516
              goto err;      /* Out of space in temporary table */
2601
2517
            continue;
2602
2518
          }
2604
2520
          /* SHOW Table NAMES command */
2605
2521
          if (schema_table_idx == SCH_TABLE_NAMES)
2606
2522
          {
2607
 
            if (fill_schema_table_names(thd, tables->table, db_name,
 
2523
            if (fill_schema_table_names(session, tables->table, db_name,
2608
2524
                                        table_name, with_i_schema))
2609
2525
              continue;
2610
2526
          }
2613
2529
            if (!(table_open_method & ~OPEN_FRM_ONLY) &&
2614
2530
                !with_i_schema)
2615
2531
            {
2616
 
              if (!fill_schema_table_from_frm(thd, tables, schema_table, db_name,
 
2532
              if (!fill_schema_table_from_frm(session, tables, schema_table, db_name,
2617
2533
                                              table_name, schema_table_idx))
2618
2534
                continue;
2619
2535
            }
2620
2536
 
2621
 
            int res;
2622
2537
            LEX_STRING tmp_lex_string, orig_db_name;
2623
2538
            /*
2624
2539
              Set the parent lex of 'sel' because it is needed by
2625
2540
              sel.init_query() which is called inside make_table_list.
2626
2541
            */
2627
 
            thd->no_warnings_for_error= 1;
 
2542
            session->no_warnings_for_error= 1;
2628
2543
            sel.parent_lex= lex;
2629
2544
            /* 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))
 
2545
            if (!session->make_lex_string(&orig_db_name, db_name->str,
 
2546
                                          db_name->length, false))
2632
2547
              goto err;
2633
 
            if (make_table_list(thd, &sel, db_name, table_name))
 
2548
            if (make_table_list(session, &sel, db_name, table_name))
2634
2549
              goto err;
2635
2550
            TableList *show_table_list= (TableList*) sel.table_list.first;
2636
2551
            lex->all_selects_list= &sel;
2638
2553
            lex->sql_command= SQLCOM_SHOW_FIELDS;
2639
2554
            show_table_list->i_s_requested_object=
2640
2555
              schema_table->i_s_requested_object;
2641
 
            res= open_normal_and_derived_tables(thd, show_table_list,
 
2556
            res= open_normal_and_derived_tables(session, show_table_list,
2642
2557
                                                DRIZZLE_LOCK_IGNORE_FLUSH);
2643
2558
            lex->sql_command= save_sql_command;
2644
2559
            /*
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().
 
2560
XXX:  show_table_list has a flag i_is_requested,
 
2561
and when it's set, open_normal_and_derived_tables()
 
2562
can return an error without setting an error message
 
2563
in Session, which is a hack. This is why we have to
 
2564
check for res, then for session->is_error() only then
 
2565
for session->main_da.sql_errno().
2651
2566
            */
2652
 
            if (res && thd->is_error() &&
2653
 
                thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
 
2567
            if (res && session->is_error() &&
 
2568
                session->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2654
2569
            {
2655
2570
              /*
2656
2571
                Hide error for not existing table.
2659
2574
                table does not exist.
2660
2575
              */
2661
2576
              res= 0;
2662
 
              thd->clear_error();
 
2577
              session->clear_error();
2663
2578
            }
2664
2579
            else
2665
2580
            {
2666
2581
              /*
2667
 
                We should use show_table_list->alias instead of 
 
2582
                We should use show_table_list->alias instead of
2668
2583
                show_table_list->table_name because table_name
2669
2584
                could be changed during opening of I_S tables. It's safe
2670
 
                to use alias because alias contains original table name 
 
2585
                to use alias because alias contains original table name
2671
2586
                in this case.
2672
2587
              */
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,
 
2588
              session->make_lex_string(&tmp_lex_string, show_table_list->alias,
 
2589
                                       strlen(show_table_list->alias), false);
 
2590
              res= schema_table->process_table(session, show_table_list, table,
2676
2591
                                               res, &orig_db_name,
2677
2592
                                               &tmp_lex_string);
2678
 
              close_tables_for_reopen(thd, &show_table_list);
 
2593
              close_tables_for_reopen(session, &show_table_list);
2679
2594
            }
2680
2595
            assert(!lex->query_tables_own_last);
2681
2596
            if (res)
2693
2608
 
2694
2609
  error= 0;
2695
2610
err:
2696
 
  thd->restore_backup_open_tables_state(&open_tables_state_backup);
2697
 
  lex->restore_backup_query_tables_list(&query_tables_list_backup);
 
2611
  session->restore_backup_open_tables_state(&open_tables_state_backup);
2698
2612
  lex->derived_tables= derived_tables;
2699
2613
  lex->all_selects_list= old_all_select_lex;
2700
2614
  lex->sql_command= save_sql_command;
2701
 
  thd->no_warnings_for_error= old_value;
 
2615
  session->no_warnings_for_error= old_value;
2702
2616
  return(error);
2703
2617
}
2704
2618
 
2705
2619
 
2706
 
bool store_schema_shemata(THD* thd, Table *table, LEX_STRING *db_name,
 
2620
bool store_schema_shemata(Session* session, Table *table, LEX_STRING *db_name,
2707
2621
                          const CHARSET_INFO * const cs)
2708
2622
{
2709
 
  restore_record(table, s->default_values);
 
2623
  table->restoreRecordAsDefault();
2710
2624
  table->field[1]->store(db_name->str, db_name->length, system_charset_info);
2711
2625
  table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
2712
2626
  table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
2713
 
  return schema_table_store_record(thd, table);
 
2627
  return schema_table_store_record(session, table);
2714
2628
}
2715
2629
 
2716
2630
 
2717
 
int fill_schema_schemata(THD *thd, TableList *tables, COND *cond)
 
2631
int fill_schema_schemata(Session *session, TableList *tables, COND *cond)
2718
2632
{
2719
2633
  /*
2720
2634
    TODO: fill_schema_shemata() is called when new client is connected.
2725
2639
  List<LEX_STRING> db_names;
2726
2640
  LEX_STRING *db_name;
2727
2641
  bool with_i_schema;
2728
 
  HA_CREATE_INFO create;
2729
2642
  Table *table= tables->table;
2730
2643
 
2731
 
  if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
 
2644
  if (get_lookup_field_values(session, cond, tables, &lookup_field_vals))
2732
2645
    return(0);
2733
 
  if (make_db_list(thd, &db_names, &lookup_field_vals,
 
2646
  if (make_db_list(session, &db_names, &lookup_field_vals,
2734
2647
                   &with_i_schema))
2735
2648
    return(1);
2736
2649
 
2757
2670
  {
2758
2671
    if (with_i_schema)       // information schema name is always first in list
2759
2672
    {
2760
 
      if (store_schema_shemata(thd, table, db_name,
 
2673
      if (store_schema_shemata(session, table, db_name,
2761
2674
                               system_charset_info))
2762
2675
        return(1);
2763
2676
      with_i_schema= 0;
2764
2677
      continue;
2765
2678
    }
2766
2679
    {
2767
 
      load_db_opt_by_name(thd, db_name->str, &create);
2768
 
      if (store_schema_shemata(thd, table, db_name,
 
2680
      HA_CREATE_INFO create;
 
2681
      load_db_opt_by_name(session, db_name->str, &create);
 
2682
 
 
2683
      if (store_schema_shemata(session, table, db_name,
2769
2684
                               create.default_table_charset))
2770
2685
        return(1);
2771
2686
    }
2774
2689
}
2775
2690
 
2776
2691
 
2777
 
static int get_schema_tables_record(THD *thd, TableList *tables,
 
2692
static int get_schema_tables_record(Session *session, TableList *tables,
2778
2693
                                    Table *table, bool res,
2779
2694
                                    LEX_STRING *db_name,
2780
2695
                                    LEX_STRING *table_name)
2783
2698
  DRIZZLE_TIME time;
2784
2699
  const CHARSET_INFO * const cs= system_charset_info;
2785
2700
 
2786
 
  restore_record(table, s->default_values);
 
2701
  table->restoreRecordAsDefault();
2787
2702
  table->field[1]->store(db_name->str, db_name->length, cs);
2788
2703
  table->field[2]->store(table_name->str, table_name->length, cs);
2789
2704
  if (res)
2791
2706
    /*
2792
2707
      there was errors during opening tables
2793
2708
    */
2794
 
    const char *error= thd->is_error() ? thd->main_da.message() : "";
 
2709
    const char *error= session->is_error() ? session->main_da.message() : "";
2795
2710
    if (tables->schema_table)
2796
2711
      table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2797
2712
    else
2798
2713
      table->field[3]->store(STRING_WITH_LEN("BASE Table"), cs);
2799
2714
    table->field[20]->store(error, strlen(error), cs);
2800
 
    thd->clear_error();
 
2715
    session->clear_error();
2801
2716
  }
2802
2717
  else
2803
2718
  {
2804
2719
    char option_buff[400],*ptr;
2805
2720
    Table *show_table= tables->table;
2806
 
    TABLE_SHARE *share= show_table->s;
 
2721
    TableShare *share= show_table->s;
2807
2722
    handler *file= show_table->file;
2808
 
    handlerton *tmp_db_type= share->db_type();
 
2723
    StorageEngine *tmp_db_type= share->db_type();
2809
2724
    if (share->tmp_table == SYSTEM_TMP_TABLE)
2810
2725
      table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2811
2726
    else if (share->tmp_table)
2819
2734
        continue;
2820
2735
      table->field[i]->set_notnull();
2821
2736
    }
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);
 
2737
    string engine_name= ha_resolve_storage_engine_name(tmp_db_type);
 
2738
    table->field[4]->store(engine_name.c_str(), engine_name.size(), cs);
 
2739
    table->field[5]->store((int64_t) 0, true);
2825
2740
 
2826
2741
    ptr=option_buff;
2827
2742
    if (share->min_rows)
2828
2743
    {
2829
 
      ptr=my_stpcpy(ptr," min_rows=");
2830
 
      ptr=int64_t10_to_str(share->min_rows,ptr,10);
 
2744
      ptr= strcpy(ptr," min_rows=")+10;
 
2745
      ptr= int64_t10_to_str(share->min_rows,ptr,10);
2831
2746
    }
2832
2747
    if (share->max_rows)
2833
2748
    {
2834
 
      ptr=my_stpcpy(ptr," max_rows=");
2835
 
      ptr=int64_t10_to_str(share->max_rows,ptr,10);
 
2749
      ptr= strcpy(ptr," max_rows=")+10;
 
2750
      ptr= int64_t10_to_str(share->max_rows,ptr,10);
2836
2751
    }
2837
2752
    if (share->avg_row_length)
2838
2753
    {
2839
 
      ptr=my_stpcpy(ptr," avg_row_length=");
2840
 
      ptr=int64_t10_to_str(share->avg_row_length,ptr,10);
 
2754
      ptr= strcpy(ptr," avg_row_length=")+16;
 
2755
      ptr= int64_t10_to_str(share->avg_row_length,ptr,10);
2841
2756
    }
2842
2757
    if (share->db_create_options & HA_OPTION_PACK_KEYS)
2843
 
      ptr=my_stpcpy(ptr," pack_keys=1");
 
2758
      ptr= strcpy(ptr," pack_keys=1")+12;
2844
2759
    if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
2845
 
      ptr=my_stpcpy(ptr," pack_keys=0");
 
2760
      ptr= strcpy(ptr," pack_keys=0")+12;
2846
2761
    /* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
2847
2762
    if (share->db_create_options & HA_OPTION_CHECKSUM)
2848
 
      ptr=my_stpcpy(ptr," checksum=1");
 
2763
      ptr= strcpy(ptr," checksum=1")+11;
2849
2764
    if (share->page_checksum != HA_CHOICE_UNDEF)
2850
 
      ptr= strxmov(ptr, " page_checksum=",
2851
 
                   ha_choice_values[(uint) share->page_checksum], NULL);
 
2765
      ptr+= sprintf(ptr, " page_checksum=%s",
 
2766
                    ha_choice_values[(uint32_t) share->page_checksum]);
2852
2767
    if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
2853
 
      ptr=my_stpcpy(ptr," delay_key_write=1");
 
2768
      ptr= strcpy(ptr," delay_key_write=1")+18;
2854
2769
    if (share->row_type != ROW_TYPE_DEFAULT)
2855
 
      ptr=strxmov(ptr, " row_format=", 
2856
 
                  ha_row_type[(uint) share->row_type],
2857
 
                  NULL);
 
2770
      ptr+= sprintf(ptr, " row_format=%s", ha_row_type[(uint32_t)share->row_type]);
2858
2771
    if (share->block_size)
2859
2772
    {
2860
 
      ptr= my_stpcpy(ptr, " block_size=");
 
2773
      ptr= strcpy(ptr, " block_size=")+12;
2861
2774
      ptr= int64_t10_to_str(share->block_size, ptr, 10);
2862
2775
    }
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);
 
2776
 
2873
2777
    table->field[19]->store(option_buff+1,
2874
 
                            (ptr == option_buff ? 0 : 
2875
 
                             (uint) (ptr-option_buff)-1), cs);
 
2778
                            (ptr == option_buff ? 0 :
 
2779
                             (uint32_t) (ptr-option_buff)-1), cs);
2876
2780
 
2877
2781
    tmp_buff= (share->table_charset ?
2878
2782
               share->table_charset->name : "default");
2936
2840
      }
2937
2841
      if (file->stats.create_time)
2938
2842
      {
2939
 
        thd->variables.time_zone->gmt_sec_to_TIME(&time,
2940
 
                                                  (my_time_t) file->stats.create_time);
 
2843
        session->variables.time_zone->gmt_sec_to_TIME(&time,
 
2844
                                                  (time_t) file->stats.create_time);
2941
2845
        table->field[14]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2942
2846
        table->field[14]->set_notnull();
2943
2847
      }
2944
2848
      if (file->stats.update_time)
2945
2849
      {
2946
 
        thd->variables.time_zone->gmt_sec_to_TIME(&time,
2947
 
                                                  (my_time_t) file->stats.update_time);
 
2850
        session->variables.time_zone->gmt_sec_to_TIME(&time,
 
2851
                                                  (time_t) file->stats.update_time);
2948
2852
        table->field[15]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2949
2853
        table->field[15]->set_notnull();
2950
2854
      }
2951
2855
      if (file->stats.check_time)
2952
2856
      {
2953
 
        thd->variables.time_zone->gmt_sec_to_TIME(&time,
2954
 
                                                  (my_time_t) file->stats.check_time);
 
2857
        session->variables.time_zone->gmt_sec_to_TIME(&time,
 
2858
                                                  (time_t) file->stats.check_time);
2955
2859
        table->field[16]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2956
2860
        table->field[16]->set_notnull();
2957
2861
      }
2962
2866
      }
2963
2867
    }
2964
2868
  }
2965
 
  return(schema_table_store_record(thd, table));
 
2869
  return(schema_table_store_record(session, table));
2966
2870
}
2967
2871
 
2968
2872
 
2974
2878
  @param[in]      cs                I_S table charset
2975
2879
  @param[in]      offset            offset from beginning of table
2976
2880
                                    to DATE_TYPE column in I_S table
2977
 
                                    
 
2881
 
2978
2882
  @return         void
2979
2883
*/
2980
2884
 
3003
2907
    uint32_t octet_max_length= field->max_display_length();
3004
2908
    if (is_blob && octet_max_length != (uint32_t) 4294967295U)
3005
2909
      octet_max_length /= field->charset()->mbmaxlen;
3006
 
    int64_t char_max_len= is_blob ? 
 
2910
    int64_t char_max_len= is_blob ?
3007
2911
      (int64_t) octet_max_length / field->charset()->mbminlen :
3008
2912
      (int64_t) octet_max_length / field->charset()->mbmaxlen;
3009
2913
    /* CHARACTER_MAXIMUM_LENGTH column*/
3024
2928
  case DRIZZLE_TYPE_NEWDECIMAL:
3025
2929
    field_length= ((Field_new_decimal*) field)->precision;
3026
2930
    break;
3027
 
  case DRIZZLE_TYPE_TINY:
3028
2931
  case DRIZZLE_TYPE_LONG:
3029
2932
  case DRIZZLE_TYPE_LONGLONG:
3030
2933
    field_length= field->max_display_length() - 1;
3065
2968
}
3066
2969
 
3067
2970
 
3068
 
static int get_schema_column_record(THD *thd, TableList *tables,
 
2971
static int get_schema_column_record(Session *session, TableList *tables,
3069
2972
                                    Table *table, bool res,
3070
2973
                                    LEX_STRING *db_name,
3071
2974
                                    LEX_STRING *table_name)
3072
2975
{
3073
 
  LEX *lex= thd->lex;
 
2976
  LEX *lex= session->lex;
3074
2977
  const char *wild= lex->wild ? lex->wild->ptr() : NULL;
3075
2978
  const CHARSET_INFO * const cs= system_charset_info;
3076
2979
  Table *show_table;
3077
 
  TABLE_SHARE *show_table_share;
 
2980
  TableShare *show_table_share;
3078
2981
  Field **ptr, *field, *timestamp_field;
3079
2982
  int count;
3080
2983
 
3085
2988
      /*
3086
2989
        I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
3087
2990
        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();
 
2991
      */
 
2992
      if (session->is_error())
 
2993
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2994
                     session->main_da.sql_errno(), session->main_da.message());
 
2995
      session->clear_error();
3093
2996
      res= 0;
3094
2997
    }
3095
2998
    return(res);
3118
3021
      /* to satisfy 'field->val_str' ASSERTs */
3119
3022
      unsigned char *bitmaps;
3120
3023
      uint32_t bitmap_size= show_table_share->column_bitmap_size;
3121
 
      if (!(bitmaps= (unsigned char*) alloc_root(thd->mem_root, bitmap_size)))
 
3024
      if (!(bitmaps= (unsigned char*) alloc_root(session->mem_root, bitmap_size)))
3122
3025
        return(0);
3123
3026
      bitmap_init(&show_table->def_read_set,
3124
3027
                  (my_bitmap_map*) bitmaps, show_table_share->fields, false);
3125
3028
      bitmap_set_all(&show_table->def_read_set);
3126
3029
      show_table->read_set= &show_table->def_read_set;
3127
3030
    }
3128
 
    bitmap_set_all(show_table->read_set);
 
3031
    show_table->setReadSet();
3129
3032
  }
3130
3033
 
3131
3034
  for (; (field= *ptr) ; ptr++)
3137
3040
 
3138
3041
    /* to satisfy 'field->val_str' ASSERTs */
3139
3042
    field->table= show_table;
3140
 
    show_table->in_use= thd;
 
3043
    show_table->in_use= session;
3141
3044
 
3142
3045
    if (wild && wild[0] &&
3143
3046
        wild_case_compare(system_charset_info, field->field_name,wild))
3145
3048
 
3146
3049
    count++;
3147
3050
    /* Get default row, with all NULL fields set to NULL */
3148
 
    restore_record(table, s->default_values);
 
3051
    table->restoreRecordAsDefault();
3149
3052
 
3150
3053
    table->field[1]->store(db_name->str, db_name->length, cs);
3151
3054
    table->field[2]->store(table_name->str, table_name->length, cs);
3153
3056
                           cs);
3154
3057
    table->field[4]->store((int64_t) count, true);
3155
3058
 
3156
 
    if (get_field_default_value(thd, timestamp_field, field, &type, 0))
 
3059
    if (get_field_default_value(session, timestamp_field, field, &type, 0))
3157
3060
    {
3158
3061
      table->field[5]->store(type.ptr(), type.length(), cs);
3159
3062
      table->field[5]->set_notnull();
3176
3079
        field->unireg_check != Field::TIMESTAMP_DN_FIELD)
3177
3080
      table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
3178
3081
                              cs);
3179
 
 
3180
3082
    table->field[18]->store(field->comment.str, field->comment.length, cs);
3181
3083
    {
3182
3084
      enum column_format_type column_format= (enum column_format_type)
3190
3092
      table->field[20]->store((const char*) pos,
3191
3093
                              strlen((const char*) pos), cs);
3192
3094
    }
3193
 
    if (schema_table_store_record(thd, table))
 
3095
    if (schema_table_store_record(session, table))
3194
3096
      return(1);
3195
3097
  }
3196
3098
  return(0);
3198
3100
 
3199
3101
 
3200
3102
 
3201
 
int fill_schema_charsets(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
 
3103
int fill_schema_charsets(Session *session, TableList *tables, COND *)
3202
3104
{
3203
3105
  CHARSET_INFO **cs;
3204
 
  const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NULL;
 
3106
  const char *wild= session->lex->wild ? session->lex->wild->ptr() : NULL;
3205
3107
  Table *table= tables->table;
3206
3108
  const CHARSET_INFO * const scs= system_charset_info;
3207
3109
 
3208
3110
  for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
3209
3111
  {
3210
3112
    const CHARSET_INFO * const tmp_cs= cs[0];
3211
 
    if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) && 
 
3113
    if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
3212
3114
        (tmp_cs->state & MY_CS_AVAILABLE) &&
3213
3115
        !(tmp_cs->state & MY_CS_HIDDEN) &&
3214
3116
        !(wild && wild[0] &&
3215
3117
          wild_case_compare(scs, tmp_cs->csname,wild)))
3216
3118
    {
3217
3119
      const char *comment;
3218
 
      restore_record(table, s->default_values);
 
3120
      table->restoreRecordAsDefault();
3219
3121
      table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs);
3220
3122
      table->field[1]->store(tmp_cs->name, strlen(tmp_cs->name), scs);
3221
3123
      comment= tmp_cs->comment ? tmp_cs->comment : "";
3222
3124
      table->field[2]->store(comment, strlen(comment), scs);
3223
3125
      table->field[3]->store((int64_t) tmp_cs->mbmaxlen, true);
3224
 
      if (schema_table_store_record(thd, table))
 
3126
      if (schema_table_store_record(session, table))
3225
3127
        return 1;
3226
3128
    }
3227
3129
  }
3229
3131
}
3230
3132
 
3231
3133
 
3232
 
int fill_schema_collation(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
 
3134
int fill_schema_collation(Session *session, TableList *tables, COND *)
3233
3135
{
3234
3136
  CHARSET_INFO **cs;
3235
 
  const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NULL;
 
3137
  const char *wild= session->lex->wild ? session->lex->wild->ptr() : NULL;
3236
3138
  Table *table= tables->table;
3237
3139
  const CHARSET_INFO * const scs= system_charset_info;
3238
3140
  for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3246
3148
    for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3247
3149
    {
3248
3150
      const CHARSET_INFO *tmp_cl= cl[0];
3249
 
      if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) || 
 
3151
      if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3250
3152
          !my_charset_same(tmp_cs, tmp_cl))
3251
3153
        continue;
3252
3154
      if (!(wild && wild[0] &&
3253
3155
          wild_case_compare(scs, tmp_cl->name,wild)))
3254
3156
      {
3255
3157
        const char *tmp_buff;
3256
 
        restore_record(table, s->default_values);
 
3158
        table->restoreRecordAsDefault();
3257
3159
        table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3258
3160
        table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3259
3161
        table->field[2]->store((int64_t) tmp_cl->number, true);
3262
3164
        tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : "";
3263
3165
        table->field[4]->store(tmp_buff, strlen(tmp_buff), scs);
3264
3166
        table->field[5]->store((int64_t) tmp_cl->strxfrm_multiply, true);
3265
 
        if (schema_table_store_record(thd, table))
 
3167
        if (schema_table_store_record(session, table))
3266
3168
          return 1;
3267
3169
      }
3268
3170
    }
3271
3173
}
3272
3174
 
3273
3175
 
3274
 
int fill_schema_coll_charset_app(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
 
3176
int fill_schema_coll_charset_app(Session *session, TableList *tables, COND *)
3275
3177
{
3276
3178
  CHARSET_INFO **cs;
3277
3179
  Table *table= tables->table;
3280
3182
  {
3281
3183
    CHARSET_INFO **cl;
3282
3184
    const CHARSET_INFO *tmp_cs= cs[0];
3283
 
    if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) || 
 
3185
    if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3284
3186
        !(tmp_cs->state & MY_CS_PRIMARY))
3285
3187
      continue;
3286
3188
    for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3287
3189
    {
3288
3190
      const CHARSET_INFO *tmp_cl= cl[0];
3289
 
      if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) || 
 
3191
      if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3290
3192
          !my_charset_same(tmp_cs,tmp_cl))
3291
3193
        continue;
3292
 
      restore_record(table, s->default_values);
 
3194
      table->restoreRecordAsDefault();
3293
3195
      table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3294
3196
      table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3295
 
      if (schema_table_store_record(thd, table))
 
3197
      if (schema_table_store_record(session, table))
3296
3198
        return 1;
3297
3199
    }
3298
3200
  }
3300
3202
}
3301
3203
 
3302
3204
 
3303
 
static int get_schema_stat_record(THD *thd, TableList *tables,
 
3205
static int get_schema_stat_record(Session *session, TableList *tables,
3304
3206
                                  Table *table, bool res,
3305
3207
                                  LEX_STRING *db_name,
3306
3208
                                  LEX_STRING *table_name)
3308
3210
  const CHARSET_INFO * const cs= system_charset_info;
3309
3211
  if (res)
3310
3212
  {
3311
 
    if (thd->lex->sql_command != SQLCOM_SHOW_KEYS)
 
3213
    if (session->lex->sql_command != SQLCOM_SHOW_KEYS)
3312
3214
    {
3313
3215
      /*
3314
3216
        I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
3315
3217
        rather than in SHOW KEYS
3316
3218
      */
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();
 
3219
      if (session->is_error())
 
3220
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
3221
                     session->main_da.sql_errno(), session->main_da.message());
 
3222
      session->clear_error();
3321
3223
      res= 0;
3322
3224
    }
3323
3225
    return(res);
3336
3238
      const char *str;
3337
3239
      for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
3338
3240
      {
3339
 
        restore_record(table, s->default_values);
 
3241
        table->restoreRecordAsDefault();
3340
3242
        table->field[1]->store(db_name->str, db_name->length, cs);
3341
3243
        table->field[2]->store(table_name->str, table_name->length, cs);
3342
3244
        table->field[3]->store((int64_t) ((key_info->flags &
3378
3280
        uint32_t flags= key_part->field ? key_part->field->flags : 0;
3379
3281
        const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
3380
3282
        table->field[12]->store(pos, strlen(pos), cs);
3381
 
        if (!show_table->s->keys_in_use.is_set(i))
 
3283
        if (!show_table->s->keys_in_use.test(i))
3382
3284
          table->field[14]->store(STRING_WITH_LEN("disabled"), cs);
3383
3285
        else
3384
3286
          table->field[14]->store("", 0, cs);
3385
3287
        table->field[14]->set_notnull();
3386
 
        assert(test(key_info->flags & HA_USES_COMMENT) == 
 
3288
        assert(test(key_info->flags & HA_USES_COMMENT) ==
3387
3289
                   (key_info->comment.length > 0));
3388
3290
        if (key_info->flags & HA_USES_COMMENT)
3389
 
          table->field[15]->store(key_info->comment.str, 
 
3291
          table->field[15]->store(key_info->comment.str,
3390
3292
                                  key_info->comment.length, cs);
3391
 
        if (schema_table_store_record(thd, table))
 
3293
        if (schema_table_store_record(session, table))
3392
3294
          return(1);
3393
3295
      }
3394
3296
    }
3397
3299
}
3398
3300
 
3399
3301
 
3400
 
bool store_constraints(THD *thd, Table *table, LEX_STRING *db_name,
 
3302
bool store_constraints(Session *session, Table *table, LEX_STRING *db_name,
3401
3303
                       LEX_STRING *table_name, const char *key_name,
3402
3304
                       uint32_t key_len, const char *con_type, uint32_t con_len)
3403
3305
{
3404
3306
  const CHARSET_INFO * const cs= system_charset_info;
3405
 
  restore_record(table, s->default_values);
 
3307
  table->restoreRecordAsDefault();
3406
3308
  table->field[1]->store(db_name->str, db_name->length, cs);
3407
3309
  table->field[2]->store(key_name, key_len, cs);
3408
3310
  table->field[3]->store(db_name->str, db_name->length, cs);
3409
3311
  table->field[4]->store(table_name->str, table_name->length, cs);
3410
3312
  table->field[5]->store(con_type, con_len, cs);
3411
 
  return schema_table_store_record(thd, table);
 
3313
  return schema_table_store_record(session, table);
3412
3314
}
3413
3315
 
3414
3316
 
3415
 
static int get_schema_constraints_record(THD *thd, TableList *tables,
 
3317
static int get_schema_constraints_record(Session *session, TableList *tables,
3416
3318
                                         Table *table, bool res,
3417
3319
                                         LEX_STRING *db_name,
3418
3320
                                         LEX_STRING *table_name)
3419
3321
{
3420
3322
  if (res)
3421
3323
  {
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();
 
3324
    if (session->is_error())
 
3325
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
3326
                   session->main_da.sql_errno(), session->main_da.message());
 
3327
    session->clear_error();
3426
3328
    return(0);
3427
3329
  }
3428
3330
  else
3431
3333
    Table *show_table= tables->table;
3432
3334
    KEY *key_info=show_table->key_info;
3433
3335
    uint32_t primary_key= show_table->s->primary_key;
3434
 
    show_table->file->info(HA_STATUS_VARIABLE | 
 
3336
    show_table->file->info(HA_STATUS_VARIABLE |
3435
3337
                           HA_STATUS_NO_LOCK |
3436
3338
                           HA_STATUS_TIME);
3437
3339
    for (uint32_t i=0 ; i < show_table->s->keys ; i++, key_info++)
3439
3341
      if (i != primary_key && !(key_info->flags & HA_NOSAME))
3440
3342
        continue;
3441
3343
 
3442
 
      if (i == primary_key && !strcmp(key_info->name, primary_key_name))
 
3344
      if (i == primary_key && is_primary_key(key_info))
3443
3345
      {
3444
 
        if (store_constraints(thd, table, db_name, table_name, key_info->name,
 
3346
        if (store_constraints(session, table, db_name, table_name, key_info->name,
3445
3347
                              strlen(key_info->name),
3446
3348
                              STRING_WITH_LEN("PRIMARY KEY")))
3447
3349
          return(1);
3448
3350
      }
3449
3351
      else if (key_info->flags & HA_NOSAME)
3450
3352
      {
3451
 
        if (store_constraints(thd, table, db_name, table_name, key_info->name,
 
3353
        if (store_constraints(session, table, db_name, table_name, key_info->name,
3452
3354
                              strlen(key_info->name),
3453
3355
                              STRING_WITH_LEN("UNIQUE")))
3454
3356
          return(1);
3455
3357
      }
3456
3358
    }
3457
3359
 
3458
 
    show_table->file->get_foreign_key_list(thd, &f_key_list);
 
3360
    show_table->file->get_foreign_key_list(session, &f_key_list);
3459
3361
    FOREIGN_KEY_INFO *f_key_info;
3460
3362
    List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3461
3363
    while ((f_key_info=it++))
3462
3364
    {
3463
 
      if (store_constraints(thd, table, db_name, table_name, 
 
3365
      if (store_constraints(session, table, db_name, table_name,
3464
3366
                            f_key_info->forein_id->str,
3465
3367
                            strlen(f_key_info->forein_id->str),
3466
3368
                            "FOREIGN KEY", 11))
3486
3388
}
3487
3389
 
3488
3390
 
3489
 
static int get_schema_key_column_usage_record(THD *thd,
 
3391
static int get_schema_key_column_usage_record(Session *session,
3490
3392
                                              TableList *tables,
3491
3393
                                              Table *table, bool res,
3492
3394
                                              LEX_STRING *db_name,
3494
3396
{
3495
3397
  if (res)
3496
3398
  {
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();
 
3399
    if (session->is_error())
 
3400
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
3401
                   session->main_da.sql_errno(), session->main_da.message());
 
3402
    session->clear_error();
3501
3403
    return(0);
3502
3404
  }
3503
3405
  else
3506
3408
    Table *show_table= tables->table;
3507
3409
    KEY *key_info=show_table->key_info;
3508
3410
    uint32_t primary_key= show_table->s->primary_key;
3509
 
    show_table->file->info(HA_STATUS_VARIABLE | 
 
3411
    show_table->file->info(HA_STATUS_VARIABLE |
3510
3412
                           HA_STATUS_NO_LOCK |
3511
3413
                           HA_STATUS_TIME);
3512
3414
    for (uint32_t i=0 ; i < show_table->s->keys ; i++, key_info++)
3520
3422
        if (key_part->field)
3521
3423
        {
3522
3424
          f_idx++;
3523
 
          restore_record(table, s->default_values);
 
3425
          table->restoreRecordAsDefault();
3524
3426
          store_key_column_usage(table, db_name, table_name,
3525
3427
                                 key_info->name,
3526
 
                                 strlen(key_info->name), 
3527
 
                                 key_part->field->field_name, 
 
3428
                                 strlen(key_info->name),
 
3429
                                 key_part->field->field_name,
3528
3430
                                 strlen(key_part->field->field_name),
3529
3431
                                 (int64_t) f_idx);
3530
 
          if (schema_table_store_record(thd, table))
 
3432
          if (schema_table_store_record(session, table))
3531
3433
            return(1);
3532
3434
        }
3533
3435
      }
3534
3436
    }
3535
3437
 
3536
 
    show_table->file->get_foreign_key_list(thd, &f_key_list);
 
3438
    show_table->file->get_foreign_key_list(session, &f_key_list);
3537
3439
    FOREIGN_KEY_INFO *f_key_info;
3538
3440
    List_iterator_fast<FOREIGN_KEY_INFO> fkey_it(f_key_list);
3539
3441
    while ((f_key_info= fkey_it++))
3547
3449
      {
3548
3450
        r_info= it1++;
3549
3451
        f_idx++;
3550
 
        restore_record(table, s->default_values);
 
3452
        table->restoreRecordAsDefault();
3551
3453
        store_key_column_usage(table, db_name, table_name,
3552
3454
                               f_key_info->forein_id->str,
3553
3455
                               f_key_info->forein_id->length,
3560
3462
                               system_charset_info);
3561
3463
        table->field[9]->set_notnull();
3562
3464
        table->field[10]->store(f_key_info->referenced_table->str,
3563
 
                                f_key_info->referenced_table->length, 
 
3465
                                f_key_info->referenced_table->length,
3564
3466
                                system_charset_info);
3565
3467
        table->field[10]->set_notnull();
3566
3468
        table->field[11]->store(r_info->str, r_info->length,
3567
3469
                                system_charset_info);
3568
3470
        table->field[11]->set_notnull();
3569
 
        if (schema_table_store_record(thd, table))
 
3471
        if (schema_table_store_record(session, table))
3570
3472
          return(1);
3571
3473
      }
3572
3474
    }
3575
3477
}
3576
3478
 
3577
3479
 
3578
 
int fill_open_tables(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
 
3480
int fill_open_tables(Session *session, TableList *tables, COND *)
3579
3481
{
3580
 
  const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NULL;
 
3482
  const char *wild= session->lex->wild ? session->lex->wild->ptr() : NULL;
3581
3483
  Table *table= tables->table;
3582
3484
  const CHARSET_INFO * const cs= system_charset_info;
3583
3485
  OPEN_TableList *open_list;
3584
 
  if (!(open_list=list_open_tables(thd,thd->lex->select_lex.db, wild))
3585
 
            && thd->is_fatal_error)
 
3486
  if (!(open_list=list_open_tables(session->lex->select_lex.db, wild))
 
3487
            && session->is_fatal_error)
3586
3488
    return(1);
3587
3489
 
3588
3490
  for (; open_list ; open_list=open_list->next)
3589
3491
  {
3590
 
    restore_record(table, s->default_values);
 
3492
    table->restoreRecordAsDefault();
3591
3493
    table->field[0]->store(open_list->db, strlen(open_list->db), cs);
3592
3494
    table->field[1]->store(open_list->table, strlen(open_list->table), cs);
3593
3495
    table->field[2]->store((int64_t) open_list->in_use, true);
3594
3496
    table->field[3]->store((int64_t) open_list->locked, true);
3595
 
    if (schema_table_store_record(thd, table))
 
3497
    if (schema_table_store_record(session, table))
3596
3498
      return(1);
3597
3499
  }
3598
3500
  return(0);
3599
3501
}
3600
3502
 
3601
3503
 
3602
 
int fill_variables(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
 
3504
int fill_variables(Session *session, TableList *tables, COND *)
3603
3505
{
3604
3506
  int res= 0;
3605
 
  LEX *lex= thd->lex;
 
3507
  LEX *lex= session->lex;
3606
3508
  const char *wild= lex->wild ? lex->wild->ptr() : NULL;
3607
3509
  enum enum_schema_tables schema_table_idx=
3608
3510
    get_schema_table_idx(tables->schema_table);
3614
3516
      schema_table_idx == SCH_GLOBAL_VARIABLES)
3615
3517
    option_type= OPT_GLOBAL;
3616
3518
 
3617
 
  rw_rdlock(&LOCK_system_variables_hash);
3618
 
  res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars),
 
3519
  pthread_rwlock_rdlock(&LOCK_system_variables_hash);
 
3520
  res= show_status_array(session, wild, enumerate_sys_vars(session, sorted_vars),
3619
3521
                         option_type, NULL, "", tables->table, upper_case_names);
3620
 
  rw_unlock(&LOCK_system_variables_hash);
 
3522
  pthread_rwlock_unlock(&LOCK_system_variables_hash);
3621
3523
  return(res);
3622
3524
}
3623
3525
 
3624
3526
 
3625
 
int fill_status(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
 
3527
int fill_status(Session *session, TableList *tables, COND *)
3626
3528
{
3627
 
  LEX *lex= thd->lex;
 
3529
  LEX *lex= session->lex;
3628
3530
  const char *wild= lex->wild ? lex->wild->ptr() : NULL;
3629
3531
  int res= 0;
3630
3532
  STATUS_VAR *tmp1, tmp;
3639
3541
    if (option_type == OPT_GLOBAL)
3640
3542
      tmp1= &tmp;
3641
3543
    else
3642
 
      tmp1= thd->initial_status_var;
 
3544
      tmp1= session->initial_status_var;
3643
3545
  }
3644
3546
  else if (schema_table_idx == SCH_GLOBAL_STATUS)
3645
3547
  {
3647
3549
    tmp1= &tmp;
3648
3550
  }
3649
3551
  else
3650
 
  { 
 
3552
  {
3651
3553
    option_type= OPT_SESSION;
3652
 
    tmp1= &thd->status_var;
 
3554
    tmp1= &session->status_var;
3653
3555
  }
3654
3556
 
3655
3557
  pthread_mutex_lock(&LOCK_status);
3656
3558
  if (option_type == OPT_GLOBAL)
3657
3559
    calc_sum_of_all_status(&tmp);
3658
 
  res= show_status_array(thd, wild,
3659
 
                         (SHOW_VAR *)all_status_vars.buffer,
 
3560
  res= show_status_array(session, wild,
 
3561
                         (SHOW_VAR *) all_status_vars.front(),
3660
3562
                         option_type, tmp1, "", tables->table,
3661
3563
                         upper_case_names);
3662
3564
  pthread_mutex_unlock(&LOCK_status);
3669
3571
 
3670
3572
  SYNOPSIS
3671
3573
    get_referential_constraints_record()
3672
 
    thd                 thread handle
 
3574
    session                 thread handle
3673
3575
    tables              table list struct(processed table)
3674
3576
    table               I_S table
3675
3577
    res                 1 means the error during opening of the processed table
3683
3585
*/
3684
3586
 
3685
3587
static int
3686
 
get_referential_constraints_record(THD *thd, TableList *tables,
 
3588
get_referential_constraints_record(Session *session, TableList *tables,
3687
3589
                                   Table *table, bool res,
3688
3590
                                   LEX_STRING *db_name, LEX_STRING *table_name)
3689
3591
{
3691
3593
 
3692
3594
  if (res)
3693
3595
  {
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();
 
3596
    if (session->is_error())
 
3597
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
3598
                   session->main_da.sql_errno(), session->main_da.message());
 
3599
    session->clear_error();
3698
3600
    return(0);
3699
3601
  }
3700
3602
 
3701
3603
  {
3702
3604
    List<FOREIGN_KEY_INFO> f_key_list;
3703
3605
    Table *show_table= tables->table;
3704
 
    show_table->file->info(HA_STATUS_VARIABLE | 
 
3606
    show_table->file->info(HA_STATUS_VARIABLE |
3705
3607
                           HA_STATUS_NO_LOCK |
3706
3608
                           HA_STATUS_TIME);
3707
3609
 
3708
 
    show_table->file->get_foreign_key_list(thd, &f_key_list);
 
3610
    show_table->file->get_foreign_key_list(session, &f_key_list);
3709
3611
    FOREIGN_KEY_INFO *f_key_info;
3710
3612
    List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3711
3613
    while ((f_key_info= it++))
3712
3614
    {
3713
 
      restore_record(table, s->default_values);
 
3615
      table->restoreRecordAsDefault();
3714
3616
      table->field[1]->store(db_name->str, db_name->length, cs);
3715
3617
      table->field[9]->store(table_name->str, table_name->length, cs);
3716
3618
      table->field[2]->store(f_key_info->forein_id->str,
3717
3619
                             f_key_info->forein_id->length, cs);
3718
 
      table->field[4]->store(f_key_info->referenced_db->str, 
 
3620
      table->field[4]->store(f_key_info->referenced_db->str,
3719
3621
                             f_key_info->referenced_db->length, cs);
3720
 
      table->field[10]->store(f_key_info->referenced_table->str, 
 
3622
      table->field[10]->store(f_key_info->referenced_table->str,
3721
3623
                             f_key_info->referenced_table->length, cs);
3722
3624
      if (f_key_info->referenced_key_name)
3723
3625
      {
3724
 
        table->field[5]->store(f_key_info->referenced_key_name->str, 
 
3626
        table->field[5]->store(f_key_info->referenced_key_name->str,
3725
3627
                               f_key_info->referenced_key_name->length, cs);
3726
3628
        table->field[5]->set_notnull();
3727
3629
      }
3728
3630
      else
3729
3631
        table->field[5]->set_null();
3730
3632
      table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
3731
 
      table->field[7]->store(f_key_info->update_method->str, 
 
3633
      table->field[7]->store(f_key_info->update_method->str,
3732
3634
                             f_key_info->update_method->length, cs);
3733
 
      table->field[8]->store(f_key_info->delete_method->str, 
 
3635
      table->field[8]->store(f_key_info->delete_method->str,
3734
3636
                             f_key_info->delete_method->length, cs);
3735
 
      if (schema_table_store_record(thd, table))
 
3637
      if (schema_table_store_record(session, table))
3736
3638
        return(1);
3737
3639
    }
3738
3640
  }
3740
3642
}
3741
3643
 
3742
3644
 
3743
 
struct schema_table_ref 
 
3645
class FindSchemaTableByName : public unary_function<InfoSchemaTable *, bool>
3744
3646
{
3745
3647
  const char *table_name;
3746
 
  ST_SCHEMA_TABLE *schema_table;
 
3648
public:
 
3649
  FindSchemaTableByName(const char *table_name_arg)
 
3650
    : table_name(table_name_arg) {}
 
3651
  result_type operator() (argument_type schema_table)
 
3652
  {
 
3653
    return !my_strcasecmp(system_charset_info,
 
3654
                          schema_table->table_name,
 
3655
                          table_name);
 
3656
  }
3747
3657
};
3748
3658
 
3749
3659
 
3751
3661
  Find schema_tables elment by name
3752
3662
 
3753
3663
  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
3664
    find_schema_table()
3787
 
    thd                 thread handler
 
3665
    session                 thread handler
3788
3666
    table_name          table name
3789
3667
 
3790
3668
  RETURN
3792
3670
    #   pointer to 'schema_tables' element
3793
3671
*/
3794
3672
 
3795
 
ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name)
 
3673
InfoSchemaTable *find_schema_table(Session *, const char* table_name)
3796
3674
{
3797
 
  schema_table_ref schema_table_a;
3798
 
  ST_SCHEMA_TABLE *schema_table= schema_tables;
 
3675
  InfoSchemaTable *schema_table= schema_tables;
3799
3676
 
3800
3677
  for (; schema_table->table_name; schema_table++)
3801
3678
  {
3805
3682
      return(schema_table);
3806
3683
  }
3807
3684
 
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
 
 
 
3685
  vector<InfoSchemaTable *>::iterator iter= 
 
3686
    find_if(all_schema_tables.begin(), all_schema_tables.end(),
 
3687
            FindSchemaTableByName(table_name));
 
3688
  if (iter != all_schema_tables.end())
 
3689
    return *iter;
3813
3690
  return(NULL);
3814
3691
}
3815
3692
 
3816
3693
 
3817
 
ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
 
3694
InfoSchemaTable *get_schema_table(enum enum_schema_tables schema_table_idx)
3818
3695
{
3819
3696
  return &schema_tables[schema_table_idx];
3820
3697
}
3826
3703
  @note
3827
3704
 
3828
3705
  @param
3829
 
    thd                   thread handler
 
3706
    session                       thread handler
3830
3707
 
3831
3708
  @param table_list Used to pass I_S table information(fields info, tables
3832
3709
  parameters etc) and table name.
3835
3712
  @retval  NULL           Can't create table
3836
3713
*/
3837
3714
 
3838
 
Table *create_schema_table(THD *thd, TableList *table_list)
 
3715
Table *create_schema_table(Session *session, TableList *table_list)
3839
3716
{
3840
3717
  int field_count= 0;
3841
3718
  Item *item;
3842
3719
  Table *table;
3843
3720
  List<Item> field_list;
3844
 
  ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
 
3721
  InfoSchemaTable *schema_table= table_list->schema_table;
3845
3722
  ST_FIELD_INFO *fields_info= schema_table->fields_info;
3846
3723
  const CHARSET_INFO * const cs= system_charset_info;
3847
3724
 
3848
3725
  for (; fields_info->field_name; fields_info++)
3849
3726
  {
3850
3727
    switch (fields_info->field_type) {
3851
 
    case DRIZZLE_TYPE_TINY:
3852
3728
    case DRIZZLE_TYPE_LONG:
3853
3729
    case DRIZZLE_TYPE_LONGLONG:
3854
3730
      if (!(item= new Item_return_int(fields_info->field_name,
3860
3736
      }
3861
3737
      item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3862
3738
      break;
3863
 
    case DRIZZLE_TYPE_NEWDATE:
3864
 
    case DRIZZLE_TYPE_TIME:
 
3739
    case DRIZZLE_TYPE_DATE:
3865
3740
    case DRIZZLE_TYPE_TIMESTAMP:
3866
3741
    case DRIZZLE_TYPE_DATETIME:
3867
3742
      if (!(item=new Item_return_date_time(fields_info->field_name,
3871
3746
      }
3872
3747
      break;
3873
3748
    case DRIZZLE_TYPE_DOUBLE:
3874
 
      if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC, 
 
3749
      if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
3875
3750
                           fields_info->field_length)) == NULL)
3876
3751
        return(NULL);
3877
3752
      break;
3910
3785
    item->maybe_null= (fields_info->field_flags & MY_I_S_MAYBE_NULL);
3911
3786
    field_count++;
3912
3787
  }
3913
 
  TMP_TABLE_PARAM *tmp_table_param =
3914
 
    (TMP_TABLE_PARAM*) (thd->alloc(sizeof(TMP_TABLE_PARAM)));
 
3788
  Tmp_Table_Param *tmp_table_param =
 
3789
    (Tmp_Table_Param*) (session->alloc(sizeof(Tmp_Table_Param)));
3915
3790
  tmp_table_param->init();
3916
3791
  tmp_table_param->table_charset= cs;
3917
3792
  tmp_table_param->field_count= field_count;
3918
3793
  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 |
 
3794
  Select_Lex *select_lex= session->lex->current_select;
 
3795
  if (!(table= create_tmp_table(session, tmp_table_param,
 
3796
                                field_list, (order_st*) 0, 0, 0,
 
3797
                                (select_lex->options | session->options |
3923
3798
                                 TMP_TABLE_ALL_COLUMNS),
3924
3799
                                HA_POS_ERROR, table_list->alias)))
3925
3800
    return(0);
3926
3801
  my_bitmap_map* bitmaps=
3927
 
    (my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count));
 
3802
    (my_bitmap_map*) session->alloc(bitmap_buffer_size(field_count));
3928
3803
  bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
3929
3804
              false);
3930
3805
  table->read_set= &table->def_read_set;
3941
3816
 
3942
3817
  SYNOPSIS
3943
3818
    make_old_format()
3944
 
    thd                 thread handler
 
3819
    session                     thread handler
3945
3820
    schema_table        pointer to 'schema_tables' element
3946
3821
 
3947
3822
  RETURN
3949
3824
   0    success
3950
3825
*/
3951
3826
 
3952
 
int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
 
3827
int make_old_format(Session *session, InfoSchemaTable *schema_table)
3953
3828
{
3954
3829
  ST_FIELD_INFO *field_info= schema_table->fields_info;
3955
 
  Name_resolution_context *context= &thd->lex->select_lex.context;
 
3830
  Name_resolution_context *context= &session->lex->select_lex.context;
3956
3831
  for (; field_info->field_name; field_info++)
3957
3832
  {
3958
3833
    if (field_info->old_name)
3964
3839
        field->set_name(field_info->old_name,
3965
3840
                        strlen(field_info->old_name),
3966
3841
                        system_charset_info);
3967
 
        if (add_item_to_list(thd, field))
 
3842
        if (session->add_item_to_list(field))
3968
3843
          return 1;
3969
3844
      }
3970
3845
    }
3973
3848
}
3974
3849
 
3975
3850
 
3976
 
int make_schemata_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
 
3851
int make_schemata_old_format(Session *session, InfoSchemaTable *schema_table)
3977
3852
{
3978
3853
  char tmp[128];
3979
 
  LEX *lex= thd->lex;
3980
 
  SELECT_LEX *sel= lex->current_select;
 
3854
  LEX *lex= session->lex;
 
3855
  Select_Lex *sel= lex->current_select;
3981
3856
  Name_resolution_context *context= &sel->context;
3982
3857
 
3983
3858
  if (!sel->item_list.elements)
3986
3861
    String buffer(tmp,sizeof(tmp), system_charset_info);
3987
3862
    Item_field *field= new Item_field(context,
3988
3863
                                      NULL, NULL, field_info->field_name);
3989
 
    if (!field || add_item_to_list(thd, field))
 
3864
    if (!field || session->add_item_to_list(field))
3990
3865
      return 1;
3991
3866
    buffer.length(0);
3992
3867
    buffer.append(field_info->old_name);
4002
3877
}
4003
3878
 
4004
3879
 
4005
 
int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
 
3880
int make_table_names_old_format(Session *session, InfoSchemaTable *schema_table)
4006
3881
{
4007
3882
  char tmp[128];
4008
 
  String buffer(tmp,sizeof(tmp), thd->charset());
4009
 
  LEX *lex= thd->lex;
 
3883
  String buffer(tmp,sizeof(tmp), session->charset());
 
3884
  LEX *lex= session->lex;
4010
3885
  Name_resolution_context *context= &lex->select_lex.context;
4011
3886
 
4012
3887
  ST_FIELD_INFO *field_info= &schema_table->fields_info[2];
4021
3896
  }
4022
3897
  Item_field *field= new Item_field(context,
4023
3898
                                    NULL, NULL, field_info->field_name);
4024
 
  if (add_item_to_list(thd, field))
 
3899
  if (session->add_item_to_list(field))
4025
3900
    return 1;
4026
3901
  field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4027
 
  if (thd->lex->verbose)
 
3902
  if (session->lex->verbose)
4028
3903
  {
4029
3904
    field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4030
3905
    field_info= &schema_table->fields_info[3];
4031
3906
    field= new Item_field(context, NULL, NULL, field_info->field_name);
4032
 
    if (add_item_to_list(thd, field))
 
3907
    if (session->add_item_to_list(field))
4033
3908
      return 1;
4034
3909
    field->set_name(field_info->old_name, strlen(field_info->old_name),
4035
3910
                    system_charset_info);
4038
3913
}
4039
3914
 
4040
3915
 
4041
 
int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
 
3916
int make_columns_old_format(Session *session, InfoSchemaTable *schema_table)
4042
3917
{
4043
3918
  int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1};
4044
3919
  int *field_num= fields_arr;
4045
3920
  ST_FIELD_INFO *field_info;
4046
 
  Name_resolution_context *context= &thd->lex->select_lex.context;
 
3921
  Name_resolution_context *context= &session->lex->select_lex.context;
4047
3922
 
4048
3923
  for (; *field_num >= 0; field_num++)
4049
3924
  {
4050
3925
    field_info= &schema_table->fields_info[*field_num];
4051
 
    if (!thd->lex->verbose && (*field_num == 13 ||
 
3926
    if (!session->lex->verbose && (*field_num == 13 ||
4052
3927
                               *field_num == 17 ||
4053
3928
                               *field_num == 18))
4054
3929
      continue;
4059
3934
      field->set_name(field_info->old_name,
4060
3935
                      strlen(field_info->old_name),
4061
3936
                      system_charset_info);
4062
 
      if (add_item_to_list(thd, field))
 
3937
      if (session->add_item_to_list(field))
4063
3938
        return 1;
4064
3939
    }
4065
3940
  }
4067
3942
}
4068
3943
 
4069
3944
 
4070
 
int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
 
3945
int make_character_sets_old_format(Session *session, InfoSchemaTable *schema_table)
4071
3946
{
4072
3947
  int fields_arr[]= {0, 2, 1, 3, -1};
4073
3948
  int *field_num= fields_arr;
4074
3949
  ST_FIELD_INFO *field_info;
4075
 
  Name_resolution_context *context= &thd->lex->select_lex.context;
 
3950
  Name_resolution_context *context= &session->lex->select_lex.context;
4076
3951
 
4077
3952
  for (; *field_num >= 0; field_num++)
4078
3953
  {
4084
3959
      field->set_name(field_info->old_name,
4085
3960
                      strlen(field_info->old_name),
4086
3961
                      system_charset_info);
4087
 
      if (add_item_to_list(thd, field))
 
3962
      if (session->add_item_to_list(field))
4088
3963
        return 1;
4089
3964
    }
4090
3965
  }
4097
3972
 
4098
3973
  SYNOPSIS
4099
3974
  mysql_schema_table()
4100
 
    thd                thread handler
 
3975
    session                thread handler
4101
3976
    lex                pointer to LEX
4102
3977
    table_list         pointer to table_list
4103
3978
 
4106
3981
    1   error
4107
3982
*/
4108
3983
 
4109
 
int mysql_schema_table(THD *thd, LEX *lex, TableList *table_list)
 
3984
int mysql_schema_table(Session *session, LEX *, TableList *table_list)
4110
3985
{
4111
3986
  Table *table;
4112
 
  if (!(table= table_list->schema_table->create_table(thd, table_list)))
 
3987
  if (!(table= table_list->schema_table->create_table(session, table_list)))
4113
3988
    return(1);
4114
3989
  table->s->tmp_table= SYSTEM_TMP_TABLE;
4115
3990
  /*
4126
4001
  table_list->table_name= table->s->table_name.str;
4127
4002
  table_list->table_name_length= table->s->table_name.length;
4128
4003
  table_list->table= table;
4129
 
  table->next= thd->derived_tables;
4130
 
  thd->derived_tables= table;
 
4004
  table->next= session->derived_tables;
 
4005
  session->derived_tables= table;
4131
4006
  table_list->select_lex->options |= OPTION_SCHEMA_TABLE;
4132
4007
 
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
4008
  return(0);
4171
4009
}
4172
4010
 
4176
4014
 
4177
4015
  SYNOPSIS
4178
4016
    make_schema_select()
4179
 
    thd                  thread handler
4180
 
    sel                  pointer to SELECT_LEX
 
4017
    session                  thread handler
 
4018
    sel                  pointer to Select_Lex
4181
4019
    schema_table_idx     index of 'schema_tables' element
4182
4020
 
4183
4021
  RETURN
4185
4023
    1   error
4186
4024
*/
4187
4025
 
4188
 
int make_schema_select(THD *thd, SELECT_LEX *sel,
 
4026
int make_schema_select(Session *session, Select_Lex *sel,
4189
4027
                       enum enum_schema_tables schema_table_idx)
4190
4028
{
4191
 
  ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx);
 
4029
  InfoSchemaTable *schema_table= get_schema_table(schema_table_idx);
4192
4030
  LEX_STRING db, table;
4193
4031
  /*
4194
4032
     We have to make non const db_name & table_name
4195
4033
     because of lower_case_table_names
4196
4034
  */
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,
 
4035
  session->make_lex_string(&db, INFORMATION_SCHEMA_NAME.c_str(),
 
4036
                       INFORMATION_SCHEMA_NAME.length(), 0);
 
4037
  session->make_lex_string(&table, schema_table->table_name,
4200
4038
                       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),
 
4039
  if (schema_table->old_format(session, schema_table) ||   /* Handle old syntax */
 
4040
      !sel->add_table_to_list(session, new Table_ident(session, db, table, 0),
4203
4041
                              0, 0, TL_READ))
4204
4042
  {
4205
4043
    return(1);
4225
4063
                              enum enum_schema_table_state executed_place)
4226
4064
{
4227
4065
  JOIN_TAB *tmp_join_tab= join->join_tab+join->tables;
4228
 
  THD *thd= join->thd;
4229
 
  LEX *lex= thd->lex;
 
4066
  Session *session= join->session;
 
4067
  LEX *lex= session->lex;
4230
4068
  bool result= 0;
4231
4069
 
4232
 
  thd->no_warnings_for_error= 1;
 
4070
  session->no_warnings_for_error= 1;
4233
4071
  for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
4234
4072
  {
4235
4073
    if (!tab->table || !tab->table->pos_in_table_list)
4243
4081
 
4244
4082
 
4245
4083
      /* skip I_S optimizations specific to get_all_tables */
4246
 
      if (thd->lex->describe &&
 
4084
      if (session->lex->describe &&
4247
4085
          (table_list->schema_table->fill_table != get_all_tables))
4248
4086
        continue;
4249
4087
 
4277
4115
      else
4278
4116
        table_list->table->file->stats.records= 0;
4279
4117
 
4280
 
      if (table_list->schema_table->fill_table(thd, table_list,
 
4118
      if (table_list->schema_table->fill_table(session, table_list,
4281
4119
                                               tab->select_cond))
4282
4120
      {
4283
4121
        result= 1;
4290
4128
      table_list->schema_table_state= executed_place;
4291
4129
    }
4292
4130
  }
4293
 
  thd->no_warnings_for_error= 0;
 
4131
  session->no_warnings_for_error= 0;
4294
4132
  return(result);
4295
4133
}
4296
4134
 
4320
4158
  {"ROW_FORMAT", 10, DRIZZLE_TYPE_VARCHAR, 0, 1, "Row_format", OPEN_FULL_TABLE},
4321
4159
  {"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4322
4160
   (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, 
 
4161
  {"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4324
4162
   (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, 
 
4163
  {"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4326
4164
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE},
4327
4165
  {"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4328
4166
   (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, 
 
4167
  {"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4330
4168
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE},
4331
4169
  {"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4332
4170
   (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, 
 
4171
  {"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG, 0,
4334
4172
   (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE},
4335
4173
  {"CREATE_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE},
4336
4174
  {"UPDATE_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE},
4529
4367
 
4530
4368
ST_FIELD_INFO plugin_fields_info[]=
4531
4369
{
4532
 
  {"PLUGIN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Name", 
 
4370
  {"PLUGIN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Name",
4533
4371
   SKIP_OPEN_TABLE},
4534
4372
  {"PLUGIN_VERSION", 20, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4535
4373
  {"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
4374
  {"PLUGIN_AUTHOR", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4540
4375
  {"PLUGIN_DESCRIPTION", 65535, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4541
4376
  {"PLUGIN_LICENSE", 80, DRIZZLE_TYPE_VARCHAR, 0, 1, "License", SKIP_OPEN_TABLE},
4572
4407
 
4573
4408
*/
4574
4409
 
4575
 
ST_SCHEMA_TABLE schema_tables[]=
 
4410
InfoSchemaTable schema_tables[]=
4576
4411
{
4577
 
  {"CHARACTER_SETS", charsets_fields_info, create_schema_table, 
 
4412
  {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
4578
4413
   fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
4579
 
  {"COLLATIONS", collation_fields_info, create_schema_table, 
 
4414
  {"COLLATIONS", collation_fields_info, create_schema_table,
4580
4415
   fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
4581
4416
  {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
4582
4417
   create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0},
4583
 
  {"COLUMNS", columns_fields_info, create_schema_table, 
 
4418
  {"COLUMNS", columns_fields_info, create_schema_table,
4584
4419
   get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0,
4585
4420
   OPTIMIZE_I_S_TABLE},
4586
4421
  {"GLOBAL_STATUS", variables_fields_info, create_schema_table,
4605
4440
   fill_status, make_old_format, 0, -1, -1, 0, 0},
4606
4441
  {"SESSION_VARIABLES", variables_fields_info, create_schema_table,
4607
4442
   fill_variables, make_old_format, 0, -1, -1, 0, 0},
4608
 
  {"STATISTICS", stat_fields_info, create_schema_table, 
 
4443
  {"STATISTICS", stat_fields_info, create_schema_table,
4609
4444
   get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
4610
4445
   OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
4611
 
  {"STATUS", variables_fields_info, create_schema_table, fill_status, 
 
4446
  {"STATUS", variables_fields_info, create_schema_table, fill_status,
4612
4447
   make_old_format, 0, -1, -1, 1, 0},
4613
 
  {"TABLES", tables_fields_info, create_schema_table, 
 
4448
  {"TABLES", tables_fields_info, create_schema_table,
4614
4449
   get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
4615
4450
   OPTIMIZE_I_S_TABLE},
4616
4451
  {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
4622
4457
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
4623
4458
};
4624
4459
 
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
 
}