~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/handler/ha_innodb.cc

  • Committer: lbieber
  • Date: 2010-09-11 16:33:45 UTC
  • mfrom: (1757.1.2 build)
  • Revision ID: lbieber@orisndriz03-20100911163345-na1t8m18at9thsjl
Merge Vijay - added utf 8 tamil test case suite and test case for creating a database in tamil
Merge Brian - Small set of refactoring (includes one case of memset on a table object).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (C) 2000, 2010, MySQL AB & Innobase Oy. All Rights Reserved.
4
 
Copyright (C) 2008, 2009 Google Inc.
5
 
Copyright (C) 2009, Percona Inc.
 
3
Copyright (c) 2000, 2009, MySQL AB & Innobase Oy. All Rights Reserved.
 
4
Copyright (c) 2008, 2009 Google Inc.
6
5
 
7
6
Portions of this file contain modifications contributed and copyrighted by
8
7
Google, Inc. Those modifications are gratefully acknowledged and are described
10
9
incorporated with their permission, and subject to the conditions contained in
11
10
the file COPYING.Google.
12
11
 
13
 
Portions of this file contain modifications contributed and copyrighted
14
 
by Percona Inc.. Those modifications are
15
 
gratefully acknowledged and are described briefly in the InnoDB
16
 
documentation. The contributions by Percona Inc. are incorporated with
17
 
their permission, and subject to the conditions contained in the file
18
 
COPYING.Percona.
19
 
 
20
12
This program is free software; you can redistribute it and/or modify it under
21
13
the terms of the GNU General Public License as published by the Free Software
22
14
Foundation; version 2 of the License.
26
18
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
27
19
 
28
20
You should have received a copy of the GNU General Public License along with
29
 
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
30
 
St, Fifth Floor, Boston, MA 02110-1301 USA
 
21
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
22
Place, Suite 330, Boston, MA 02111-1307 USA
31
23
 
32
24
*****************************************************************************/
 
25
/***********************************************************************
 
26
 
 
27
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
 
28
Copyright (c) 2009, Percona Inc.
 
29
 
 
30
Portions of this file contain modifications contributed and copyrighted
 
31
by Percona Inc.. Those modifications are
 
32
gratefully acknowledged and are described briefly in the InnoDB
 
33
documentation. The contributions by Percona Inc. are incorporated with
 
34
their permission, and subject to the conditions contained in the file
 
35
COPYING.Percona.
 
36
 
 
37
This program is free software; you can redistribute it and/or modify it
 
38
under the terms of the GNU General Public License as published by the
 
39
Free Software Foundation; version 2 of the License.
 
40
 
 
41
This program is distributed in the hope that it will be useful, but
 
42
WITHOUT ANY WARRANTY; without even the implied warranty of
 
43
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 
44
Public License for more details.
 
45
 
 
46
You should have received a copy of the GNU General Public License along
 
47
with this program; if not, write to the Free Software Foundation, Inc.,
 
48
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
49
 
 
50
***********************************************************************/
33
51
 
34
52
/* TODO list for the InnoDB Cursor in 5.0:
35
53
  - fix savepoint functions to use savepoint storage area
60
78
#include "drizzled/table.h"
61
79
#include "drizzled/field/blob.h"
62
80
#include "drizzled/field/varstring.h"
 
81
#include "drizzled/field/timestamp.h"
63
82
#include "drizzled/plugin/xa_storage_engine.h"
64
83
#include "drizzled/plugin/daemon.h"
65
84
#include "drizzled/memory/multi_malloc.h"
71
90
 
72
91
#include <boost/algorithm/string.hpp>
73
92
#include <boost/program_options.hpp>
74
 
#include <boost/scoped_array.hpp>
75
 
#include <boost/filesystem.hpp>
76
93
#include <drizzled/module/option_map.h>
77
94
#include <iostream>
78
95
 
79
96
namespace po= boost::program_options;
80
 
namespace fs=boost::filesystem;
81
97
using namespace std;
82
98
 
83
99
/** @file ha_innodb.cc */
84
100
 
85
101
/* Include necessary InnoDB headers */
 
102
extern "C" {
86
103
#include "univ.i"
87
 
#include "buf0lru.h"
88
104
#include "btr0sea.h"
89
105
#include "os0file.h"
90
106
#include "os0thread.h"
101
117
#include "log0log.h"
102
118
#include "lock0lock.h"
103
119
#include "dict0crea.h"
104
 
#include "create_replication.h"
105
120
#include "btr0cur.h"
106
121
#include "btr0btr.h"
107
122
#include "fsp0fsp.h"
114
129
#include "ha_prototypes.h"
115
130
#include "ut0mem.h"
116
131
#include "ibuf0ibuf.h"
 
132
#include "mysql_addons.h"
 
133
}
117
134
 
118
135
#include "ha_innodb.h"
119
136
#include "data_dictionary.h"
120
 
#include "replication_dictionary.h"
121
137
#include "internal_dictionary.h"
122
138
#include "handler0vars.h"
123
139
 
126
142
#include <string>
127
143
 
128
144
#include "plugin/innobase/handler/status_function.h"
129
 
#include "plugin/innobase/handler/replication_log.h"
130
 
 
131
 
#include <google/protobuf/io/zero_copy_stream.h>
132
 
#include <google/protobuf/io/zero_copy_stream_impl.h>
133
 
#include <google/protobuf/io/coded_stream.h>
134
 
#include <google/protobuf/text_format.h>
135
 
 
136
 
#include <boost/thread/mutex.hpp>
137
145
 
138
146
using namespace std;
139
147
using namespace drizzled;
140
148
 
 
149
#ifndef DRIZZLE_SERVER
 
150
/* This is needed because of Bug #3596.  Let us hope that pthread_mutex_t
 
151
is defined the same in both builds: the MySQL server and the InnoDB plugin. */
 
152
extern pthread_mutex_t LOCK_thread_count;
 
153
 
 
154
#endif /* DRIZZLE_SERVER */
 
155
 
141
156
/** to protect innobase_open_files */
142
 
static boost::mutex innobase_share_mutex;
143
 
 
 
157
static pthread_mutex_t innobase_share_mutex;
144
158
/** to force correct commit order in binlog */
 
159
static pthread_mutex_t prepare_commit_mutex;
145
160
static ulong commit_threads = 0;
146
 
static boost::condition_variable commit_cond;
147
 
static boost::mutex commit_cond_m;
 
161
static pthread_mutex_t commit_threads_m;
 
162
static pthread_cond_t commit_cond;
 
163
static pthread_mutex_t commit_cond_m;
148
164
static bool innodb_inited = 0;
149
165
 
150
166
#define INSIDE_HA_INNOBASE_CC
160
176
#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
161
177
 
162
178
static plugin::XaStorageEngine* innodb_engine_ptr= NULL;
163
 
 
164
 
typedef constrained_check<uint32_t, UINT32_MAX, 10> open_files_constraint;
165
 
static open_files_constraint innobase_open_files;
166
 
typedef constrained_check<uint32_t, 10, 1> mirrored_log_groups_constraint;
167
 
static mirrored_log_groups_constraint innobase_mirrored_log_groups;
168
 
typedef constrained_check<uint32_t, 100, 2> log_files_in_group_constraint;
169
 
static log_files_in_group_constraint innobase_log_files_in_group;
170
 
typedef constrained_check<uint32_t, 6, 0> force_recovery_constraint;
171
 
force_recovery_constraint innobase_force_recovery;
172
 
typedef constrained_check<size_t, SIZE_MAX, 256*1024, 1024> log_buffer_constraint;
173
 
static log_buffer_constraint innobase_log_buffer_size;
174
 
typedef constrained_check<size_t, SIZE_MAX, 512*1024, 1024> additional_mem_pool_constraint;
175
 
static additional_mem_pool_constraint innobase_additional_mem_pool_size;
176
 
typedef constrained_check<unsigned int, 1000, 1> autoextend_constraint;
177
 
static autoextend_constraint innodb_auto_extend_increment;
178
 
typedef constrained_check<size_t, SIZE_MAX, 5242880, 1048576> buffer_pool_constraint;
179
 
static buffer_pool_constraint innobase_buffer_pool_size;
180
 
typedef constrained_check<uint32_t, MAX_BUFFER_POOLS, 1> buffer_pool_instances_constraint;
181
 
static buffer_pool_instances_constraint innobase_buffer_pool_instances;
182
 
typedef constrained_check<uint32_t, UINT32_MAX, 100> io_capacity_constraint;
183
 
static io_capacity_constraint innodb_io_capacity;
184
 
typedef constrained_check<uint32_t, 5000, 1> purge_batch_constraint;
185
 
static purge_batch_constraint innodb_purge_batch_size;
186
 
typedef constrained_check<uint32_t, 1, 0> purge_threads_constraint;
187
 
static purge_threads_constraint innodb_n_purge_threads;
188
 
typedef constrained_check<uint32_t, 2, 0> trinary_constraint;
189
 
static trinary_constraint innodb_flush_log_at_trx_commit;
190
 
typedef constrained_check<unsigned int, 99, 0> max_dirty_pages_constraint;
191
 
static max_dirty_pages_constraint innodb_max_dirty_pages_pct;
192
 
static uint64_constraint innodb_max_purge_lag;
193
 
static uint64_nonzero_constraint innodb_stats_sample_pages;
194
 
typedef constrained_check<uint32_t, 64, 1> io_threads_constraint;
195
 
static io_threads_constraint innobase_read_io_threads;
196
 
static io_threads_constraint innobase_write_io_threads;
197
 
 
198
 
typedef constrained_check<uint32_t, 1000, 0> concurrency_constraint;
199
 
static concurrency_constraint innobase_commit_concurrency;
200
 
static concurrency_constraint innobase_thread_concurrency;
201
 
static uint32_nonzero_constraint innodb_concurrency_tickets;
202
 
 
203
 
typedef constrained_check<int64_t, INT64_MAX, 1024*1024, 1024*1024> log_file_constraint;
204
 
static log_file_constraint innobase_log_file_size;
205
 
 
206
 
static uint64_constraint innodb_replication_delay;
207
 
 
208
 
/** Percentage of the buffer pool to reserve for 'old' blocks.
209
 
Connected to buf_LRU_old_ratio. */
210
 
typedef constrained_check<uint32_t, 95, 5> old_blocks_constraint;
211
 
static old_blocks_constraint innobase_old_blocks_pct;
212
 
 
213
 
static uint32_constraint innodb_sync_spin_loops;
214
 
static uint32_constraint innodb_spin_wait_delay;
215
 
static uint32_constraint innodb_thread_sleep_delay;
216
 
 
217
 
typedef constrained_check<uint32_t, 64, 0> read_ahead_threshold_constraint;
218
 
static read_ahead_threshold_constraint innodb_read_ahead_threshold;
 
179
static plugin::TableFunction* status_table_function_ptr= NULL;
 
180
static plugin::TableFunction* cmp_tool= NULL;
 
181
static plugin::TableFunction* cmp_reset_tool= NULL;
 
182
static plugin::TableFunction* cmp_mem_tool= NULL;
 
183
static plugin::TableFunction* cmp_mem_reset_tool= NULL;
 
184
static plugin::TableFunction* innodb_trx_tool= NULL;
 
185
static plugin::TableFunction* innodb_locks_tool= NULL;
 
186
static plugin::TableFunction* innodb_lock_waits_tool= NULL;
 
187
 
 
188
static long innobase_mirrored_log_groups, innobase_log_files_in_group,
 
189
  innobase_log_buffer_size,
 
190
  innobase_file_io_threads,
 
191
  innobase_force_recovery, innobase_open_files;
 
192
static long innobase_additional_mem_pool_size= 8*1024*1024L;
 
193
static ulong innobase_commit_concurrency = 0;
 
194
static ulong innobase_read_io_threads;
 
195
static ulong innobase_write_io_threads;
 
196
 
 
197
/**
 
198
 * @TODO: Turn this into size_t as soon as we have a Variable<size_t>
 
199
 */
 
200
static int64_t innobase_buffer_pool_size= 128*1024*1024;
 
201
static int64_t innobase_log_file_size;
219
202
 
220
203
/* The default values for the following char* start-up parameters
221
204
are determined in innobase_init below: */
222
205
 
223
 
std::string innobase_data_home_dir;
224
 
std::string innobase_data_file_path;
225
 
std::string innobase_log_group_home_dir;
226
 
static string innobase_file_format_name;
227
 
static string innobase_change_buffering;
228
 
 
229
 
/* The highest file format being used in the database. The value can be
230
 
set by user, however, it will be adjusted to the newer file format if
231
 
a table of such format is created/opened. */
232
 
static string innobase_file_format_max;
 
206
static char*  innobase_data_home_dir      = NULL;
 
207
static char*  innobase_data_file_path     = NULL;
 
208
static char*  innobase_log_group_home_dir   = NULL;
 
209
static char*  innobase_file_format_name   = NULL;
 
210
static char*  innobase_change_buffering   = NULL;
 
211
 
 
212
/* Note: This variable can be set to on/off and any of the supported
 
213
file formats in the configuration file, but can only be set to any
 
214
of the supported file formats during runtime. */
 
215
static char*  innobase_file_format_check    = NULL;
 
216
 
 
217
/* The following has a misleading name: starting from 4.0.5, this also
 
218
affects Windows: */
 
219
static char*  innobase_unix_file_flush_method   = NULL;
233
220
 
234
221
/* Below we have boolean-valued start-up parameters, and their default
235
222
values */
236
223
 
237
 
typedef constrained_check<uint32_t, 2, 0> trinary_constraint;
238
 
static trinary_constraint innobase_fast_shutdown;
239
 
 
240
 
/* "innobase_file_format_check" decides whether we would continue
241
 
booting the server if the file format stamped on the system
242
 
table space exceeds the maximum file format supported
243
 
by the server. Can be set during server startup at command
244
 
line or configure file, and a read only variable after
245
 
server startup */
246
 
 
247
 
/* If a new file format is introduced, the file format
248
 
name needs to be updated accordingly. Please refer to
249
 
file_format_name_map[] defined in trx0sys.c for the next
250
 
file format name. */
251
 
 
252
 
static my_bool  innobase_file_format_check = TRUE;
 
224
static ulong  innobase_fast_shutdown      = 1;
 
225
#ifdef UNIV_LOG_ARCHIVE
 
226
static my_bool  innobase_log_archive      = FALSE;
 
227
static char*  innobase_log_arch_dir     = NULL;
 
228
#endif /* UNIV_LOG_ARCHIVE */
253
229
static my_bool  innobase_use_doublewrite    = TRUE;
254
230
static my_bool  innobase_use_checksums      = TRUE;
255
231
static my_bool  innobase_rollback_on_timeout    = FALSE;
256
232
static my_bool  innobase_create_status_file   = FALSE;
257
 
static bool innobase_use_replication_log;
258
 
static bool support_xa;
259
 
static bool strict_mode;
260
 
typedef constrained_check<uint32_t, 1024*1024*1024, 1> lock_wait_constraint;
261
 
static lock_wait_constraint lock_wait_timeout;
 
233
static my_bool  innobase_stats_on_metadata    = TRUE;
262
234
 
263
235
static char*  internal_innobase_data_file_path  = NULL;
264
236
 
 
237
static char*  innodb_version_str = (char*) INNODB_VERSION_STR;
 
238
 
265
239
/* The following counter is used to convey information to InnoDB
266
240
about server activity: in selects it is not sensible to call
267
241
srv_active_wake_master_thread after each fetch or search, we only do
279
253
/** Allowed values of innodb_change_buffering */
280
254
static const char* innobase_change_buffering_values[IBUF_USE_COUNT] = {
281
255
  "none",   /* IBUF_USE_NONE */
282
 
  "inserts",    /* IBUF_USE_INSERT */
283
 
  "deletes",    /* IBUF_USE_DELETE_MARK */
284
 
  "changes",    /* IBUF_USE_INSERT_DELETE_MARK */
285
 
  "purges",     /* IBUF_USE_DELETE */
286
 
  "all"         /* IBUF_USE_ALL */
 
256
  "inserts" /* IBUF_USE_INSERT */
287
257
};
288
258
 
289
 
/* "GEN_CLUST_INDEX" is the name reserved for Innodb default
290
 
system primary index. */
291
 
static const char innobase_index_reserve_name[]= "GEN_CLUST_INDEX";
292
 
 
293
259
/********************************************************************
294
260
Gives the file extension of an InnoDB single-table tablespace. */
295
261
static const char* ha_innobase_exts[] = {
333
299
      srv_free_paths_and_sizes();
334
300
      if (internal_innobase_data_file_path)
335
301
        free(internal_innobase_data_file_path);
 
302
      pthread_mutex_destroy(&innobase_share_mutex);
 
303
      pthread_mutex_destroy(&prepare_commit_mutex);
 
304
      pthread_mutex_destroy(&commit_threads_m);
 
305
      pthread_mutex_destroy(&commit_cond_m);
 
306
      pthread_cond_destroy(&commit_cond);
336
307
    }
337
308
    
338
309
    /* These get strdup'd from vm variables */
 
310
    free(innobase_data_home_dir);
339
311
 
340
312
  }
341
313
 
366
338
  {
367
339
    return doRollback(session, all); /* XA rollback just does a SQL ROLLBACK */
368
340
  }
369
 
  virtual uint64_t doGetCurrentTransactionId(Session *session);
370
 
  virtual uint64_t doGetNewTransactionId(Session *session);
371
341
  virtual int doCommit(Session* session, bool all);
372
342
  virtual int doRollback(Session* session, bool all);
373
343
 
411
381
        /* out: 0 or error number */
412
382
    ::drizzled::XID *xid);  /* in: X/Open XA transaction identification */
413
383
 
414
 
  virtual Cursor *create(Table &table)
 
384
  virtual Cursor *create(TableShare &table)
415
385
  {
416
386
    return new ha_innobase(*this, table);
417
387
  }
422
392
  doDropSchema(
423
393
  /*===================*/
424
394
        /* out: error number */
425
 
    const identifier::Schema  &identifier); /* in: database path; inside InnoDB the name
 
395
    const SchemaIdentifier  &identifier); /* in: database path; inside InnoDB the name
426
396
        of the last directory in the path is used as
427
397
        the database name: for example, in 'mysql/data/test'
428
398
        the database name is 'test' */
461
431
 
462
432
  UNIV_INTERN int doCreateTable(Session &session,
463
433
                                Table &form,
464
 
                                const identifier::Table &identifier,
 
434
                                const TableIdentifier &identifier,
465
435
                                message::Table&);
466
 
  UNIV_INTERN int doRenameTable(Session&, const identifier::Table &from, const identifier::Table &to);
467
 
  UNIV_INTERN int doDropTable(Session &session, const identifier::Table &identifier);
 
436
  UNIV_INTERN int doRenameTable(Session&, const TableIdentifier &from, const TableIdentifier &to);
 
437
  UNIV_INTERN int doDropTable(Session &session, const TableIdentifier &identifier);
468
438
 
469
 
  UNIV_INTERN virtual bool get_error_message(int error, String *buf) const;
 
439
  UNIV_INTERN virtual bool get_error_message(int error, String *buf);
470
440
 
471
441
  UNIV_INTERN uint32_t max_supported_keys() const;
472
442
  UNIV_INTERN uint32_t max_supported_key_length() const;
483
453
  }
484
454
 
485
455
  int doGetTableDefinition(drizzled::Session& session,
486
 
                           const identifier::Table &identifier,
 
456
                           const TableIdentifier &identifier,
487
457
                           drizzled::message::Table &table_proto);
488
458
 
489
 
  bool doDoesTableExist(drizzled::Session& session, const identifier::Table &identifier);
 
459
  void doGetTableNames(drizzled::CachedDirectory &directory,
 
460
                       const drizzled::SchemaIdentifier &schema_identifier,
 
461
                       std::set<std::string> &set_of_names);
 
462
 
 
463
  bool doDoesTableExist(drizzled::Session& session, const TableIdentifier &identifier);
490
464
 
491
465
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
492
 
                             const drizzled::identifier::Schema &schema_identifier,
493
 
                             drizzled::identifier::Table::vector &set_of_identifiers);
 
466
                             const drizzled::SchemaIdentifier &schema_identifier,
 
467
                             drizzled::TableIdentifiers &set_of_identifiers);
494
468
  bool validateCreateTableOption(const std::string &key, const std::string &state);
495
469
  void dropTemporarySchema();
496
470
 
518
492
}
519
493
 
520
494
void InnobaseEngine::doGetTableIdentifiers(drizzled::CachedDirectory &directory,
521
 
                                           const drizzled::identifier::Schema &schema_identifier,
522
 
                                           drizzled::identifier::Table::vector &set_of_identifiers)
 
495
                                           const drizzled::SchemaIdentifier &schema_identifier,
 
496
                                           drizzled::TableIdentifiers &set_of_identifiers)
523
497
{
524
498
  CachedDirectory::Entries entries= directory.getEntries();
525
499
 
526
 
  std::string search_string(schema_identifier.getSchemaName());
527
 
 
528
 
  boost::algorithm::to_lower(search_string);
529
 
 
530
 
  if (search_string.compare("data_dictionary") == 0)
531
 
  {
532
 
    set_of_identifiers.push_back(identifier::Table(schema_identifier.getSchemaName(), "SYS_REPLICATION_LOG"));
533
 
  }
534
 
 
535
500
  for (CachedDirectory::Entries::iterator entry_iter= entries.begin(); 
536
501
       entry_iter != entries.end(); ++entry_iter)
537
502
  {
547
512
    { }
548
513
    else
549
514
    {
550
 
      std::string path;
551
 
      path+= directory.getPath();
552
 
      path+= FN_LIBCHAR;
553
 
      path+= entry->filename;
554
 
 
555
 
      message::Table definition;
556
 
      if (StorageEngine::readTableFile(path, definition))
557
 
      {
558
 
        /* 
559
 
           Using schema_identifier here to stop unused warning, could use
560
 
           definition.schema() instead
561
 
        */
562
 
        identifier::Table identifier(schema_identifier.getSchemaName(), definition.name());
563
 
        set_of_identifiers.push_back(identifier);
564
 
      }
 
515
      char uname[NAME_LEN + 1];
 
516
      uint32_t file_name_len;
 
517
 
 
518
      file_name_len= TableIdentifier::filename_to_tablename(filename->c_str(), uname, sizeof(uname));
 
519
      // TODO: Remove need for memory copy here
 
520
      uname[file_name_len - sizeof(DEFAULT_FILE_EXTENSION) + 1]= '\0'; // Subtract ending, place NULL 
 
521
 
 
522
      set_of_identifiers.push_back(TableIdentifier(schema_identifier, uname));
565
523
    }
566
524
  }
567
525
}
568
526
 
569
 
bool InnobaseEngine::doDoesTableExist(Session &session, const identifier::Table &identifier)
 
527
bool InnobaseEngine::doDoesTableExist(Session &session, const TableIdentifier &identifier)
570
528
{
571
529
  string proto_path(identifier.getPath());
572
530
  proto_path.append(DEFAULT_FILE_EXTENSION);
573
531
 
574
 
  if (session.getMessageCache().doesTableMessageExist(identifier))
575
 
    return true;
576
 
 
577
 
  std::string search_string(identifier.getPath());
578
 
  boost::algorithm::to_lower(search_string);
579
 
 
580
 
  if (search_string.compare("data_dictionary/sys_replication_log") == 0)
 
532
  if (session.doesTableMessageExist(identifier))
581
533
    return true;
582
534
 
583
535
  if (access(proto_path.c_str(), F_OK))
589
541
}
590
542
 
591
543
int InnobaseEngine::doGetTableDefinition(Session &session,
592
 
                                         const identifier::Table &identifier,
 
544
                                         const TableIdentifier &identifier,
593
545
                                         message::Table &table_proto)
594
546
{
595
547
  string proto_path(identifier.getPath());
596
548
  proto_path.append(DEFAULT_FILE_EXTENSION);
597
549
 
598
550
  // First we check the temporary tables.
599
 
  if (session.getMessageCache().getTableMessage(identifier, table_proto))
600
 
    return EEXIST;
601
 
 
602
 
  if (read_replication_log_table_message(identifier.getTableName().c_str(), &table_proto) == 0)
 
551
  if (session.getTableMessage(identifier, table_proto))
603
552
    return EEXIST;
604
553
 
605
554
  if (access(proto_path.c_str(), F_OK))
613
562
  return ENOENT;
614
563
}
615
564
 
 
565
void InnobaseEngine::doGetTableNames(CachedDirectory &directory, const SchemaIdentifier&, set<string>& set_of_names)
 
566
{
 
567
  CachedDirectory::Entries entries= directory.getEntries();
 
568
 
 
569
  for (CachedDirectory::Entries::iterator entry_iter= entries.begin(); 
 
570
       entry_iter != entries.end(); ++entry_iter)
 
571
  {
 
572
    CachedDirectory::Entry *entry= *entry_iter;
 
573
    const string *filename= &entry->filename;
 
574
 
 
575
    assert(filename->size());
 
576
 
 
577
    const char *ext= strchr(filename->c_str(), '.');
 
578
 
 
579
    if (ext == NULL || my_strcasecmp(system_charset_info, ext, DEFAULT_FILE_EXTENSION) ||
 
580
        (filename->compare(0, strlen(TMP_FILE_PREFIX), TMP_FILE_PREFIX) == 0))
 
581
    { }
 
582
    else
 
583
    {
 
584
      char uname[NAME_LEN + 1];
 
585
      uint32_t file_name_len;
 
586
 
 
587
      file_name_len= TableIdentifier::filename_to_tablename(filename->c_str(), uname, sizeof(uname));
 
588
      // TODO: Remove need for memory copy here
 
589
      uname[file_name_len - sizeof(DEFAULT_FILE_EXTENSION) + 1]= '\0'; // Subtract ending, place NULL 
 
590
      set_of_names.insert(uname);
 
591
    }
 
592
  }
 
593
}
 
594
 
 
595
/** @brief Initialize the default value of innodb_commit_concurrency.
 
596
 
 
597
Once InnoDB is running, the innodb_commit_concurrency must not change
 
598
from zero to nonzero. (Bug #42101)
 
599
 
 
600
The initial default value is 0, and without this extra initialization,
 
601
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
 
602
to 0, even if it was initially set to nonzero at the command line
 
603
or configuration file. */
 
604
static
 
605
void
 
606
innobase_commit_concurrency_init_default(void);
 
607
/*==========================================*/
616
608
 
617
609
/************************************************************//**
618
610
Validate the file format name and return its corresponding id.
625
617
            name */
626
618
/************************************************************//**
627
619
Validate the file format check config parameters, as a side effect it
628
 
sets the srv_max_file_format_at_startup variable.
629
 
@return the format_id if valid config value, otherwise, return -1 */
630
 
static
631
 
int
632
 
innobase_file_format_validate_and_set(
 
620
sets the srv_check_file_format_at_startup variable.
 
621
@return true if one of  "on" or "off" */
 
622
static
 
623
bool
 
624
innobase_file_format_check_on_off(
 
625
/*==============================*/
 
626
  const char* format_check);    /*!< in: parameter value */
 
627
/************************************************************//**
 
628
Validate the file format check config parameters, as a side effect it
 
629
sets the srv_check_file_format_at_startup variable.
 
630
@return true if valid config value */
 
631
static
 
632
bool
 
633
innobase_file_format_check_validate(
633
634
/*================================*/
634
 
  const char* format_max);    /*!< in: parameter value */
 
635
  const char* format_check);    /*!< in: parameter value */
635
636
 
636
637
static const char innobase_engine_name[]= "InnoDB";
637
638
 
 
639
/*************************************************************//**
 
640
Check for a valid value of innobase_commit_concurrency.
 
641
@return 0 for valid innodb_commit_concurrency */
 
642
static
 
643
int
 
644
innobase_commit_concurrency_validate(
 
645
/*=================================*/
 
646
  Session*      , /*!< in: thread handle */
 
647
  drizzle_sys_var*  , /*!< in: pointer to system
 
648
            variable */
 
649
  void*       save, /*!< out: immediate result
 
650
            for update function */
 
651
  drizzle_value*    value)  /*!< in: incoming string */
 
652
{
 
653
  int64_t   intbuf;
 
654
  ulong   commit_concurrency;
 
655
 
 
656
  if (value->val_int(value, &intbuf)) {
 
657
    /* The value is NULL. That is invalid. */
 
658
    return(1);
 
659
  }
 
660
 
 
661
  *reinterpret_cast<ulong*>(save) = commit_concurrency
 
662
    = static_cast<ulong>(intbuf);
 
663
 
 
664
  /* Allow the value to be updated, as long as it remains zero
 
665
  or nonzero. */
 
666
  return(!(!commit_concurrency == !innobase_commit_concurrency));
 
667
}
 
668
 
 
669
static DRIZZLE_SessionVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG,
 
670
  "Enable InnoDB support for the XA two-phase commit",
 
671
  /* check_func */ NULL, /* update_func */ NULL,
 
672
  /* default */ TRUE);
 
673
 
 
674
static DRIZZLE_SessionVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG,
 
675
  "Enable InnoDB locking in LOCK TABLES",
 
676
  /* check_func */ NULL, /* update_func */ NULL,
 
677
  /* default */ TRUE);
 
678
 
 
679
static DRIZZLE_SessionVAR_BOOL(strict_mode, PLUGIN_VAR_OPCMDARG,
 
680
  "Use strict mode when evaluating create options.",
 
681
  NULL, NULL, FALSE);
 
682
 
 
683
static DRIZZLE_SessionVAR_ULONG(lock_wait_timeout, PLUGIN_VAR_RQCMDARG,
 
684
  "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.",
 
685
  NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
 
686
 
638
687
 
639
688
/*****************************************************************//**
640
689
Commits a transaction in an InnoDB database. */
661
710
  (char*) &export_vars.innodb_buffer_pool_pages_misc,   SHOW_LONG},
662
711
  {"buffer_pool_pages_total",
663
712
  (char*) &export_vars.innodb_buffer_pool_pages_total,    SHOW_LONG},
664
 
  {"buffer_pool_read_ahead",
665
 
  (char*) &export_vars.innodb_buffer_pool_read_ahead, SHOW_LONG},
666
 
  {"buffer_pool_read_ahead_evicted",
667
 
  (char*) &export_vars.innodb_buffer_pool_read_ahead_evicted, SHOW_LONG},
 
713
  {"buffer_pool_read_ahead_rnd",
 
714
  (char*) &export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_LONG},
 
715
  {"buffer_pool_read_ahead_seq",
 
716
  (char*) &export_vars.innodb_buffer_pool_read_ahead_seq, SHOW_LONG},
668
717
  {"buffer_pool_read_requests",
669
718
  (char*) &export_vars.innodb_buffer_pool_read_requests,  SHOW_LONG},
670
719
  {"buffer_pool_reads",
798
847
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
799
848
         in non-Cursor code.
800
849
@return true if session is the replication thread */
801
 
UNIV_INTERN
 
850
extern "C" UNIV_INTERN
802
851
ibool
803
852
thd_is_replication_slave_thread(
804
853
/*============================*/
805
 
  drizzled::Session* ) /*!< in: thread handle (Session*) */
 
854
  void* ) /*!< in: thread handle (Session*) */
806
855
{
807
856
  return false;
808
857
}
872
921
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
873
922
         in non-Cursor code.
874
923
@return true if non-transactional tables have been edited */
875
 
UNIV_INTERN
 
924
extern "C" UNIV_INTERN
876
925
ibool
877
926
thd_has_edited_nontrans_tables(
878
927
/*===========================*/
879
 
  drizzled::Session *session)  /*!< in: thread handle (Session*) */
 
928
  void*   session)  /*!< in: thread handle (Session*) */
880
929
{
881
 
  return((ibool)session->transaction.all.hasModifiedNonTransData());
 
930
  return((ibool)((Session *)session)->transaction.all.hasModifiedNonTransData());
882
931
}
883
932
 
884
933
/******************************************************************//**
885
934
Returns true if the thread is executing a SELECT statement.
886
935
@return true if session is executing SELECT */
887
 
UNIV_INTERN
 
936
extern "C" UNIV_INTERN
888
937
ibool
889
938
thd_is_select(
890
939
/*==========*/
891
 
  const drizzled::Session *session)  /*!< in: thread handle (Session*) */
 
940
  const void* session)  /*!< in: thread handle (Session*) */
892
941
{
893
 
  return(session->getSqlCommand() == SQLCOM_SELECT);
 
942
  return(session_sql_command((const Session*) session) == SQLCOM_SELECT);
894
943
}
895
944
 
896
945
/******************************************************************//**
897
946
Returns true if the thread supports XA,
898
947
global value of innodb_supports_xa if session is NULL.
899
948
@return true if session has XA support */
900
 
UNIV_INTERN
 
949
extern "C" UNIV_INTERN
901
950
ibool
902
951
thd_supports_xa(
903
952
/*============*/
904
 
  drizzled::Session* )  /*!< in: thread handle (Session*), or NULL to query
 
953
  void* session)  /*!< in: thread handle (Session*), or NULL to query
905
954
        the global innodb_supports_xa */
906
955
{
907
 
  /* TODO: Add support here for per-session value */
908
 
  return(support_xa);
 
956
  return(SessionVAR((Session*) session, support_xa));
909
957
}
910
958
 
911
959
/******************************************************************//**
912
960
Returns the lock wait timeout for the current connection.
913
961
@return the lock wait timeout, in seconds */
914
 
UNIV_INTERN
 
962
extern "C" UNIV_INTERN
915
963
ulong
916
964
thd_lock_wait_timeout(
917
965
/*==================*/
918
 
  drizzled::Session*)  /*!< in: thread handle (Session*), or NULL to query
 
966
  void* session)  /*!< in: thread handle (Session*), or NULL to query
919
967
      the global innodb_lock_wait_timeout */
920
968
{
921
 
  /* TODO: Add support here for per-session value */
922
969
  /* According to <drizzle/plugin.h>, passing session == NULL
923
970
  returns the global value of the session variable. */
924
 
  return((ulong)lock_wait_timeout.get());
925
 
}
926
 
 
927
 
/******************************************************************//**
928
 
Set the time waited for the lock for the current query. */
929
 
UNIV_INTERN
930
 
void
931
 
thd_set_lock_wait_time(
932
 
/*===================*/
933
 
        drizzled::Session*      in_session,     /*!< in: thread handle (THD*) */
934
 
        ulint   value)  /*!< in: time waited for the lock */
935
 
{
936
 
  if (in_session)
937
 
    in_session->utime_after_lock+= value;
 
971
  return(SessionVAR((Session*) session, lock_wait_timeout));
938
972
}
939
973
 
940
974
/********************************************************************//**
949
983
  return *(trx_t**) session->getEngineData(innodb_engine_ptr);
950
984
}
951
985
 
952
 
 
953
 
plugin::ReplicationReturnCode ReplicationLog::apply(Session &session,
954
 
                                                    const message::Transaction &message)
955
 
{
956
 
  char *data= new char[message.ByteSize()];
957
 
 
958
 
  message.SerializeToArray(data, message.ByteSize());
959
 
 
960
 
  trx_t *trx= session_to_trx(&session);
961
 
 
962
 
  uint64_t trx_id= message.transaction_context().transaction_id();
963
 
  uint32_t seg_id= message.segment_id();
964
 
  uint64_t end_timestamp= message.transaction_context().end_timestamp();
965
 
  bool is_end_segment= message.end_segment();
966
 
  trx->log_commit_id= TRUE;
967
 
  ulint error= insert_replication_message(data, message.ByteSize(), trx, trx_id,
968
 
               end_timestamp, is_end_segment, seg_id);
969
 
  (void)error;
970
 
 
971
 
  delete[] data;
972
 
 
973
 
  return plugin::SUCCESS;
974
 
}
975
 
 
976
986
/********************************************************************//**
977
987
Call this function when mysqld passes control to the client. That is to
978
988
avoid deadlocks on the adaptive hash S-latch possibly held by session. For more
1022
1032
about a possible transaction rollback inside InnoDB caused by a lock wait
1023
1033
timeout or a deadlock.
1024
1034
@return MySQL error code */
1025
 
UNIV_INTERN
 
1035
extern "C" UNIV_INTERN
1026
1036
int
1027
1037
convert_error_code_to_mysql(
1028
1038
/*========================*/
1034
1044
  case DB_SUCCESS:
1035
1045
    return(0);
1036
1046
 
1037
 
  case DB_INTERRUPTED:
1038
 
    my_error(ER_QUERY_INTERRUPTED, MYF(0));
1039
 
    /* fall through */
1040
 
 
1041
 
  case DB_FOREIGN_EXCEED_MAX_CASCADE:
1042
 
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1043
 
                        HA_ERR_ROW_IS_REFERENCED,
1044
 
                        "InnoDB: Cannot delete/update "
1045
 
                        "rows with cascading foreign key "
1046
 
                        "constraints that exceed max "
1047
 
                        "depth of %d. Please "
1048
 
                        "drop extra constraints and try "
1049
 
                        "again", DICT_FK_MAX_RECURSIVE_LOAD);
1050
 
    /* fall through */
1051
 
 
1052
1047
  case DB_ERROR:
1053
1048
  default:
1054
1049
    return(-1); /* unspecified error */
1055
1050
 
1056
1051
  case DB_DUPLICATE_KEY:
1057
 
    /* Be cautious with returning this error, since
1058
 
       mysql could re-enter the storage layer to get
1059
 
       duplicated key info, the operation requires a
1060
 
       valid table handle and/or transaction information,
1061
 
       which might not always be available in the error
1062
 
       handling stage. */
1063
1052
    return(HA_ERR_FOUND_DUPP_KEY);
1064
1053
 
1065
1054
  case DB_FOREIGN_DUPLICATE_KEY:
1076
1065
    tell it also to MySQL so that MySQL knows to empty the
1077
1066
    cached binlog for this transaction */
1078
1067
 
1079
 
    session->markTransactionForRollback(TRUE);
 
1068
    mark_transaction_to_rollback(session, TRUE);
1080
1069
 
1081
1070
    return(HA_ERR_LOCK_DEADLOCK);
1082
1071
 
1085
1074
    latest SQL statement in a lock wait timeout. Previously, we
1086
1075
    rolled back the whole transaction. */
1087
1076
 
1088
 
    session->markTransactionForRollback((bool)row_rollback_on_timeout);
 
1077
    mark_transaction_to_rollback(session, (bool)row_rollback_on_timeout);
1089
1078
 
1090
1079
    return(HA_ERR_LOCK_WAIT_TIMEOUT);
1091
1080
 
1096
1085
    return(HA_ERR_ROW_IS_REFERENCED);
1097
1086
 
1098
1087
  case DB_CANNOT_ADD_CONSTRAINT:
1099
 
  case DB_CHILD_NO_INDEX:
1100
 
  case DB_PARENT_NO_INDEX:
1101
1088
    return(HA_ERR_CANNOT_ADD_FOREIGN);
1102
1089
 
1103
1090
  case DB_CANNOT_DROP_CONSTRAINT:
1121
1108
 
1122
1109
  case DB_TOO_BIG_RECORD:
1123
1110
    my_error(ER_TOO_BIG_ROWSIZE, MYF(0),
1124
 
             page_get_free_space_of_empty(flags & DICT_TF_COMPACT) / 2);
 
1111
       page_get_free_space_of_empty(flags
 
1112
                  & DICT_TF_COMPACT) / 2);
1125
1113
    return(HA_ERR_TO_BIG_ROW);
1126
1114
 
1127
1115
  case DB_NO_SAVEPOINT:
1132
1120
    tell it also to MySQL so that MySQL knows to empty the
1133
1121
    cached binlog for this transaction */
1134
1122
 
1135
 
    session->markTransactionForRollback(TRUE);
 
1123
    mark_transaction_to_rollback(session, TRUE);
1136
1124
 
1137
1125
    return(HA_ERR_LOCK_TABLE_FULL);
1138
1126
 
1147
1135
    and the actual error code name could very well be different.
1148
1136
    This will require some monitoring, ie. the status
1149
1137
    of this request on our part.*/
1150
 
 
1151
 
    /* New error code HA_ERR_TOO_MANY_CONCURRENT_TRXS is only
1152
 
       available in 5.1.38 and later, but the plugin should still
1153
 
       work with previous versions of MySQL.
1154
 
       In Drizzle we seem to not have this yet.
1155
 
    */
1156
 
#ifdef HA_ERR_TOO_MANY_CONCURRENT_TRXS
1157
 
    return(HA_ERR_TOO_MANY_CONCURRENT_TRXS);
1158
 
#else /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
 
1138
#ifdef ER_TOO_MANY_CONCURRENT_TRXS
 
1139
    return(ER_TOO_MANY_CONCURRENT_TRXS);
 
1140
#else
1159
1141
    return(HA_ERR_RECORD_FILE_FULL);
1160
 
#endif /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
 
1142
#endif
1161
1143
  case DB_UNSUPPORTED:
1162
1144
    return(HA_ERR_UNSUPPORTED);
1163
1145
  }
1164
1146
}
1165
1147
 
1166
1148
 
 
1149
 
 
1150
/*************************************************************//**
 
1151
If you want to print a session that is not associated with the current thread,
 
1152
you must call this function before reserving the InnoDB kernel_mutex, to
 
1153
protect Drizzle from setting session->query NULL. If you print a session of the
 
1154
current thread, we know that Drizzle cannot modify sesion->query, and it is
 
1155
not necessary to call this. Call innobase_mysql_end_print_arbitrary_thd()
 
1156
after you release the kernel_mutex.
 
1157
 
 
1158
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
 
1159
         in non-Cursor code.
 
1160
 */
 
1161
extern "C" UNIV_INTERN
 
1162
void
 
1163
innobase_mysql_prepare_print_arbitrary_thd(void)
 
1164
/*============================================*/
 
1165
{
 
1166
  ut_ad(!mutex_own(&kernel_mutex));
 
1167
  LOCK_thread_count.lock();
 
1168
}
 
1169
 
 
1170
/*************************************************************//**
 
1171
Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
 
1172
In the InnoDB latching order, the mutex sits right above the
 
1173
kernel_mutex.  In debug builds, we assert that the kernel_mutex is
 
1174
released before this function is invoked. 
 
1175
 
 
1176
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
 
1177
         in non-Cursor code.
 
1178
*/
 
1179
extern "C" UNIV_INTERN
 
1180
void
 
1181
innobase_mysql_end_print_arbitrary_thd(void)
 
1182
/*========================================*/
 
1183
{
 
1184
  ut_ad(!mutex_own(&kernel_mutex));
 
1185
  LOCK_thread_count.unlock();
 
1186
}
 
1187
 
1167
1188
/*************************************************************//**
1168
1189
Prints info of a Session object (== user session thread) to the given file. */
1169
 
UNIV_INTERN
 
1190
extern "C" UNIV_INTERN
1170
1191
void
1171
1192
innobase_mysql_print_thd(
1172
1193
/*=====================*/
1173
1194
  FILE* f,    /*!< in: output stream */
1174
 
  drizzled::Session *in_session,  /*!< in: pointer to a Drizzle Session object */
 
1195
  void * in_session,  /*!< in: pointer to a Drizzle Session object */
1175
1196
  uint  )   /*!< in: max query length to print, or 0 to
1176
1197
           use the default max length */
1177
1198
{
1178
 
  drizzled::identifier::User::const_shared_ptr user_identifier(in_session->user());
1179
 
 
 
1199
  Session *session= reinterpret_cast<Session *>(in_session);
1180
1200
  fprintf(f,
1181
1201
          "Drizzle thread %"PRIu64", query id %"PRIu64", %s, %s, %s ",
1182
 
          static_cast<uint64_t>(in_session->getSessionId()),
1183
 
          static_cast<uint64_t>(in_session->getQueryId()),
 
1202
          static_cast<uint64_t>(session->getSessionId()),
 
1203
          static_cast<uint64_t>(session->getQueryId()),
1184
1204
          glob_hostname,
1185
 
          user_identifier->address().c_str(),
1186
 
          user_identifier->username().c_str()
1187
 
  );
1188
 
  fprintf(f, "\n%s", in_session->getQueryString()->c_str());
 
1205
          session->getSecurityContext().getIp().c_str(),
 
1206
          session->getSecurityContext().getUser().c_str()
 
1207
  );
 
1208
  fprintf(f,
 
1209
          "\n%s", session->getQueryString().c_str()
 
1210
  );
1189
1211
  putc('\n', f);
1190
1212
}
1191
1213
 
1192
1214
/******************************************************************//**
1193
1215
Get the variable length bounds of the given character set. */
1194
 
UNIV_INTERN
 
1216
extern "C" UNIV_INTERN
1195
1217
void
1196
1218
innobase_get_cset_width(
1197
1219
/*====================*/
1208
1230
  if (cs) {
1209
1231
    *mbminlen = cs->mbminlen;
1210
1232
    *mbmaxlen = cs->mbmaxlen;
1211
 
    ut_ad(*mbminlen < DATA_MBMAX);
1212
 
    ut_ad(*mbmaxlen < DATA_MBMAX);
1213
1233
  } else {
1214
1234
    ut_a(cset == 0);
1215
1235
    *mbminlen = *mbmaxlen = 0;
1218
1238
 
1219
1239
/******************************************************************//**
1220
1240
Converts an identifier to a table name. */
1221
 
UNIV_INTERN
 
1241
extern "C" UNIV_INTERN
1222
1242
void
1223
1243
innobase_convert_from_table_id(
1224
1244
/*===========================*/
1232
1252
 
1233
1253
/******************************************************************//**
1234
1254
Converts an identifier to UTF-8. */
1235
 
UNIV_INTERN
 
1255
extern "C" UNIV_INTERN
1236
1256
void
1237
1257
innobase_convert_from_id(
1238
1258
/*=====================*/
1247
1267
/******************************************************************//**
1248
1268
Compares NUL-terminated UTF-8 strings case insensitively.
1249
1269
@return 0 if a=b, <0 if a<b, >1 if a>b */
1250
 
UNIV_INTERN
 
1270
extern "C" UNIV_INTERN
1251
1271
int
1252
1272
innobase_strcasecmp(
1253
1273
/*================*/
1259
1279
 
1260
1280
/******************************************************************//**
1261
1281
Makes all characters in a NUL-terminated UTF-8 string lower case. */
1262
 
UNIV_INTERN
 
1282
extern "C" UNIV_INTERN
1263
1283
void
1264
1284
innobase_casedn_str(
1265
1285
/*================*/
1268
1288
  my_casedn_str(system_charset_info, a);
1269
1289
}
1270
1290
 
1271
 
UNIV_INTERN
 
1291
/**********************************************************************//**
 
1292
Determines the connection character set.
 
1293
@return connection character set */
 
1294
extern "C" UNIV_INTERN
 
1295
const void*
 
1296
innobase_get_charset(
 
1297
/*=================*/
 
1298
  void* mysql_session)  /*!< in: MySQL thread handle */
 
1299
{
 
1300
  return session_charset(static_cast<Session*>(mysql_session));
 
1301
}
 
1302
 
 
1303
extern "C" UNIV_INTERN
1272
1304
bool
1273
1305
innobase_isspace(
1274
1306
  const void *cs,
1277
1309
  return my_isspace(static_cast<const CHARSET_INFO *>(cs), char_to_test);
1278
1310
}
1279
1311
 
 
1312
UNIV_INTERN
 
1313
int
 
1314
innobase_fast_mutex_init(
 
1315
        os_fast_mutex_t*        fast_mutex)
 
1316
{
 
1317
  return pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
 
1318
}
 
1319
 
1280
1320
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1281
1321
/*******************************************************************//**
1282
1322
Map an OS error to an errno value. The OS error number is stored in
1283
1323
_doserrno and the mapped value is stored in errno) */
 
1324
extern "C"
1284
1325
void __cdecl
1285
1326
_dosmaperr(
1286
1327
  unsigned long); /*!< in: OS error value */
1288
1329
/*********************************************************************//**
1289
1330
Creates a temporary file.
1290
1331
@return temporary file descriptor, or < 0 on error */
1291
 
UNIV_INTERN
 
1332
extern "C" UNIV_INTERN
1292
1333
int
1293
1334
innobase_mysql_tmpfile(void)
1294
1335
/*========================*/
1368
1409
/*********************************************************************//**
1369
1410
Creates a temporary file.
1370
1411
@return temporary file descriptor, or < 0 on error */
1371
 
UNIV_INTERN
 
1412
extern "C" UNIV_INTERN
1372
1413
int
1373
1414
innobase_mysql_tmpfile(void)
1374
1415
/*========================*/
1375
1416
{
1376
1417
  int fd2 = -1;
1377
 
  int fd = ::drizzled::tmpfile("ib");
 
1418
  int fd = mysql_tmpfile("ib");
1378
1419
  if (fd >= 0) {
1379
1420
    /* Copy the file descriptor, so that the additional resources
1380
1421
    allocated by create_temp_file() can be freed by invoking
1407
1448
number of bytes that were written to "buf" is returned (including the
1408
1449
terminating NUL).
1409
1450
@return number of bytes that were written */
1410
 
UNIV_INTERN
 
1451
extern "C" UNIV_INTERN
1411
1452
ulint
1412
1453
innobase_raw_format(
1413
1454
/*================*/
1527
1568
/*********************************************************************//**
1528
1569
Allocates an InnoDB transaction for a MySQL Cursor object.
1529
1570
@return InnoDB transaction handle */
1530
 
UNIV_INTERN
 
1571
extern "C" UNIV_INTERN
1531
1572
trx_t*
1532
1573
innobase_trx_allocate(
1533
1574
/*==================*/
1541
1582
  trx = trx_allocate_for_mysql();
1542
1583
 
1543
1584
  trx->mysql_thd = session;
 
1585
  trx->mysql_query_str = session->query.c_str();
1544
1586
 
1545
1587
  innobase_trx_init(session, trx);
1546
1588
 
1579
1621
Construct ha_innobase Cursor. */
1580
1622
UNIV_INTERN
1581
1623
ha_innobase::ha_innobase(plugin::StorageEngine &engine_arg,
1582
 
                         Table &table_arg)
 
1624
                         TableShare &table_arg)
1583
1625
  :Cursor(engine_arg, table_arg),
1584
1626
  primary_key(0), /* needs initialization because index_flags() may be called 
1585
1627
                     before this is set to the real value. It's ok to have any 
1631
1673
  ulint   buflen, /*!< in: length of buf, in bytes */
1632
1674
  const char* id, /*!< in: identifier to convert */
1633
1675
  ulint   idlen,  /*!< in: length of id, in bytes */
1634
 
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
 
1676
  void*   session,/*!< in: MySQL connection thread, or NULL */
1635
1677
  ibool   file_id)/*!< in: TRUE=id is a table or database name;
1636
1678
        FALSE=id is an UTF-8 string */
1637
1679
{
1638
1680
  char nz[NAME_LEN + 1];
1639
 
  const size_t nz2_size= NAME_LEN + 1 + srv_mysql50_table_name_prefix.size();
1640
 
  boost::scoped_array<char> nz2(new char[nz2_size]);
 
1681
  char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix];
1641
1682
 
1642
1683
  const char* s = id;
1643
1684
  int   q;
1654
1695
    memcpy(nz, id, idlen);
1655
1696
    nz[idlen] = 0;
1656
1697
 
1657
 
    s = nz2.get();
1658
 
    idlen = identifier::Table::filename_to_tablename(nz, nz2.get(), nz2_size);
 
1698
    s = nz2;
 
1699
    idlen = TableIdentifier::filename_to_tablename(nz, nz2, sizeof nz2);
1659
1700
  }
1660
1701
 
1661
1702
  /* See if the identifier needs to be quoted. */
1709
1750
Convert a table or index name to the MySQL system_charset_info (UTF-8)
1710
1751
and quote it if needed.
1711
1752
@return pointer to the end of buf */
1712
 
UNIV_INTERN
 
1753
extern "C" UNIV_INTERN
1713
1754
char*
1714
1755
innobase_convert_name(
1715
1756
/*==================*/
1717
1758
  ulint   buflen, /*!< in: length of buf, in bytes */
1718
1759
  const char* id, /*!< in: identifier to convert */
1719
1760
  ulint   idlen,  /*!< in: length of id, in bytes */
1720
 
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
 
1761
  void*   session,/*!< in: MySQL connection thread, or NULL */
1721
1762
  ibool   table_id)/*!< in: TRUE=id is a table or database name;
1722
1763
        FALSE=id is an index name */
1723
1764
{
1765
1806
/**********************************************************************//**
1766
1807
Determines if the currently running transaction has been interrupted.
1767
1808
@return TRUE if interrupted */
1768
 
UNIV_INTERN
 
1809
extern "C" UNIV_INTERN
1769
1810
ibool
1770
1811
trx_is_interrupted(
1771
1812
/*===============*/
1772
1813
  trx_t*  trx)  /*!< in: transaction */
1773
1814
{
1774
 
  return(trx && trx->mysql_thd && trx->mysql_thd->getKilled());
1775
 
}
1776
 
 
1777
 
/**********************************************************************//**
1778
 
Determines if the currently running transaction is in strict mode.
1779
 
@return TRUE if strict */
1780
 
UNIV_INTERN
1781
 
ibool
1782
 
trx_is_strict(
1783
 
/*==========*/
1784
 
        trx_t*  trx)    /*!< in: transaction */
1785
 
{
1786
 
        return(trx && trx->mysql_thd
1787
 
               && true);
 
1815
  return(trx && trx->mysql_thd && session_killed((Session*) trx->mysql_thd));
1788
1816
}
1789
1817
 
1790
1818
/**************************************************************//**
1806
1834
  value= value - (value % align_val);
1807
1835
}
1808
1836
 
1809
 
static void auto_extend_update(Session *, sql_var_t)
1810
 
{
1811
 
  srv_auto_extend_increment= innodb_auto_extend_increment.get();
1812
 
}
1813
 
 
1814
 
static void io_capacity_update(Session *, sql_var_t)
1815
 
{
1816
 
  srv_io_capacity= innodb_io_capacity.get();
1817
 
}
1818
 
 
1819
 
static void purge_batch_update(Session *, sql_var_t)
1820
 
{
1821
 
  srv_purge_batch_size= innodb_purge_batch_size.get();
1822
 
}
1823
 
 
1824
 
static void purge_threads_update(Session *, sql_var_t)
1825
 
{
1826
 
  srv_n_purge_threads= innodb_n_purge_threads.get();
1827
 
}
1828
 
 
1829
 
static void innodb_adaptive_hash_index_update(Session *, sql_var_t)
1830
 
{
1831
 
  if (btr_search_enabled)
1832
 
  {
1833
 
    btr_search_enable();
1834
 
  } else {
1835
 
    btr_search_disable();
1836
 
  }
1837
 
}
1838
 
 
1839
 
static void innodb_old_blocks_pct_update(Session *, sql_var_t)
1840
 
{
1841
 
  innobase_old_blocks_pct= buf_LRU_old_ratio_update(innobase_old_blocks_pct.get(), TRUE);
1842
 
}
1843
 
 
1844
 
static void innodb_thread_concurrency_update(Session *, sql_var_t)
1845
 
{
1846
 
  srv_thread_concurrency= innobase_thread_concurrency.get();
1847
 
}
1848
 
 
1849
 
static void innodb_sync_spin_loops_update(Session *, sql_var_t)
1850
 
{
1851
 
  srv_n_spin_wait_rounds= innodb_sync_spin_loops.get();
1852
 
}
1853
 
 
1854
 
static void innodb_spin_wait_delay_update(Session *, sql_var_t)
1855
 
{
1856
 
  srv_spin_wait_delay= innodb_spin_wait_delay.get();
1857
 
}
1858
 
 
1859
 
static void innodb_thread_sleep_delay_update(Session *, sql_var_t)
1860
 
{
1861
 
  srv_thread_sleep_delay= innodb_thread_sleep_delay.get();
1862
 
}
1863
 
 
1864
 
static void innodb_read_ahead_threshold_update(Session *, sql_var_t)
1865
 
{
1866
 
  srv_read_ahead_threshold= innodb_read_ahead_threshold.get();
1867
 
}
1868
 
 
1869
 
 
1870
 
static int innodb_commit_concurrency_validate(Session *session, set_var *var)
1871
 
{
1872
 
   uint64_t new_value= var->getInteger();
1873
 
 
1874
 
   if ((innobase_commit_concurrency.get() == 0 && new_value != 0) ||
1875
 
       (innobase_commit_concurrency.get() != 0 && new_value == 0))
1876
 
   {
1877
 
     push_warning_printf(session,
1878
 
                         DRIZZLE_ERROR::WARN_LEVEL_WARN,
1879
 
                         ER_WRONG_ARGUMENTS,
1880
 
                         _("Once InnoDB is running, innodb_commit_concurrency "
1881
 
                           "must not change between zero and nonzero."));
1882
 
     return 1;
1883
 
   }
1884
 
   return 0;
1885
 
}
1886
 
 
1887
 
/*************************************************************//**
1888
 
Check if it is a valid file format. This function is registered as
1889
 
a callback with MySQL.
1890
 
@return 0 for valid file format */
1891
 
static
1892
 
int
1893
 
innodb_file_format_name_validate(
1894
 
/*=============================*/
1895
 
  Session*      , /*!< in: thread handle */
1896
 
  set_var *var)
1897
 
{
1898
 
  const char *file_format_input = var->value->str_value.ptr();
1899
 
  if (file_format_input == NULL)
1900
 
    return 1;
1901
 
 
1902
 
  if (file_format_input != NULL) {
1903
 
    uint  format_id;
1904
 
 
1905
 
    format_id = innobase_file_format_name_lookup(
1906
 
      file_format_input);
1907
 
 
1908
 
    if (format_id <= DICT_TF_FORMAT_MAX) {
1909
 
      innobase_file_format_name =
1910
 
        trx_sys_file_format_id_to_name(format_id);
1911
 
 
1912
 
      return(0);
1913
 
    }
1914
 
  }
1915
 
 
1916
 
  return(1);
1917
 
}
1918
 
 
1919
 
/*************************************************************//**
1920
 
Check if it is a valid value of innodb_change_buffering. This function is
1921
 
registered as a callback with MySQL.
1922
 
@return 0 for valid innodb_change_buffering */
1923
 
static
1924
 
int
1925
 
innodb_change_buffering_validate(
1926
 
/*=============================*/
1927
 
  Session*      , /*!< in: thread handle */
1928
 
  set_var *var)
1929
 
{
1930
 
  const char *change_buffering_input = var->value->str_value.ptr();
1931
 
 
1932
 
  if (change_buffering_input == NULL)
1933
 
    return 1;
1934
 
 
1935
 
  ulint use;
1936
 
 
1937
 
  for (use = 0;
1938
 
       use < UT_ARR_SIZE(innobase_change_buffering_values);
1939
 
       ++use) {
1940
 
    if (!innobase_strcasecmp(change_buffering_input,
1941
 
                             innobase_change_buffering_values[use]))
1942
 
    {
1943
 
      ibuf_use= static_cast<ibuf_use_t>(use); 
1944
 
      return 0;
1945
 
    }
1946
 
  }
1947
 
 
1948
 
  return 1;
1949
 
}
1950
 
 
1951
 
 
1952
 
/*************************************************************//**
1953
 
Check if valid argument to innodb_file_format_max. This function
1954
 
is registered as a callback with MySQL.
1955
 
@return 0 for valid file format */
1956
 
static
1957
 
int
1958
 
innodb_file_format_max_validate(
1959
 
/*==============================*/
1960
 
  Session*   session, /*!< in: thread handle */
1961
 
  set_var *var)
1962
 
{
1963
 
  const char *file_format_input = var->value->str_value.ptr();
1964
 
  if (file_format_input == NULL)
1965
 
    return 1;
1966
 
 
1967
 
  if (file_format_input != NULL) {
1968
 
    int format_id = innobase_file_format_validate_and_set(file_format_input);
1969
 
 
1970
 
    if (format_id > DICT_TF_FORMAT_MAX) {
1971
 
      /* DEFAULT is "on", which is invalid at runtime. */
1972
 
      return 1;
1973
 
    }
1974
 
 
1975
 
    if (format_id >= 0) {
1976
 
      innobase_file_format_max.assign(
1977
 
                             trx_sys_file_format_id_to_name((uint)format_id));
1978
 
 
1979
 
      /* Update the max format id in the system tablespace. */
1980
 
      const char *name_buff;
1981
 
 
1982
 
      if (trx_sys_file_format_max_set(format_id, &name_buff))
1983
 
      {
1984
 
        errmsg_printf(error::WARN,
1985
 
                      " [Info] InnoDB: the file format in the system "
1986
 
                      "tablespace is now set to %s.\n", name_buff);
1987
 
        innobase_file_format_max= name_buff;
1988
 
      }
1989
 
      return(0);
1990
 
 
1991
 
    } else {
1992
 
      push_warning_printf(session,
1993
 
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
1994
 
                          ER_WRONG_ARGUMENTS,
1995
 
                          "InnoDB: invalid innodb_file_format_max "
1996
 
                          "value; can be any format up to %s "
1997
 
                          "or equivalent id of %d",
1998
 
                          trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX),
1999
 
                          DICT_TF_FORMAT_MAX);
2000
 
    }
2001
 
  }
2002
 
 
2003
 
  return(1);
2004
 
}
2005
 
 
2006
 
 
2007
1837
/*********************************************************************//**
2008
1838
Opens an InnoDB database.
2009
1839
@return 0 on success, error code on failure */
2013
1843
/*==========*/
2014
1844
  module::Context &context) /*!< in: Drizzle Plugin Context */
2015
1845
{
 
1846
  static char current_dir[3];   /*!< Set if using current lib */
2016
1847
  int   err;
2017
1848
  bool    ret;
 
1849
  char    *default_path;
2018
1850
  uint    format_id;
2019
1851
  InnobaseEngine *actuall_engine_ptr;
2020
1852
  const module::option_map &vm= context.getOptions();
2021
1853
 
2022
 
  srv_auto_extend_increment= innodb_auto_extend_increment.get();
2023
 
  srv_io_capacity= innodb_io_capacity.get();
2024
 
  srv_purge_batch_size= innodb_purge_batch_size.get();
2025
 
  srv_n_purge_threads= innodb_n_purge_threads.get();
2026
 
  srv_flush_log_at_trx_commit= innodb_flush_log_at_trx_commit.get();
2027
 
  srv_max_buf_pool_modified_pct= innodb_max_dirty_pages_pct.get();
2028
 
  srv_max_purge_lag= innodb_max_purge_lag.get();
2029
 
  srv_stats_sample_pages= innodb_stats_sample_pages.get();
2030
 
  srv_n_free_tickets_to_enter= innodb_concurrency_tickets.get();
2031
 
  srv_replication_delay= innodb_replication_delay.get();
2032
 
  srv_thread_concurrency= innobase_thread_concurrency.get();
2033
 
  srv_n_spin_wait_rounds= innodb_sync_spin_loops.get();
2034
 
  srv_spin_wait_delay= innodb_spin_wait_delay.get();
2035
 
  srv_thread_sleep_delay= innodb_thread_sleep_delay.get();
2036
 
  srv_read_ahead_threshold= innodb_read_ahead_threshold.get();
2037
 
 
2038
 
  /* Inverted Booleans */
2039
 
 
2040
 
  innobase_use_checksums= (vm.count("disable-checksums")) ? false : true;
2041
 
  innobase_use_doublewrite= (vm.count("disable-doublewrite")) ? false : true;
2042
 
  srv_adaptive_flushing= (vm.count("disable-adaptive-flushing")) ? false : true;
2043
 
  srv_use_sys_malloc= (vm.count("use-internal-malloc")) ? false : true;
2044
 
  srv_use_native_aio= (vm.count("disable-native-aio")) ? false : true;
2045
 
  support_xa= (vm.count("disable-xa")) ? false : true;
2046
 
  btr_search_enabled= (vm.count("disable-adaptive-hash-index")) ? false : true;
2047
 
 
2048
 
 
2049
 
  /* Hafta do this here because we need to late-bind the default value */
 
1854
  if (vm.count("io-capacity"))
 
1855
  {
 
1856
    if (srv_io_capacity < 100)
 
1857
    {
 
1858
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for io-capacity\n"));
 
1859
      exit(-1);
 
1860
    }
 
1861
  }
 
1862
 
2050
1863
  if (vm.count("data-home-dir"))
2051
1864
  {
2052
 
    innobase_data_home_dir= vm["data-home-dir"].as<string>();
2053
 
  }
2054
 
  else
2055
 
  {
2056
 
    innobase_data_home_dir= getDataHome().file_string();
2057
 
  }
2058
 
 
 
1865
    innobase_data_home_dir= strdup(vm["data-home-dir"].as<string>().c_str());
 
1866
  }
 
1867
 
 
1868
  else
 
1869
  {
 
1870
    innobase_data_home_dir= NULL;
 
1871
  }
 
1872
 
 
1873
  if (vm.count("fast-shutdown"))
 
1874
  {
 
1875
    if (innobase_fast_shutdown > 2)
 
1876
    {
 
1877
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for fast-shutdown\n"));
 
1878
      exit(-1);
 
1879
    }
 
1880
  }
 
1881
 
 
1882
  if (vm.count("file-format-check"))
 
1883
  {
 
1884
    innobase_file_format_check= const_cast<char *>(vm["file-format-check"].as<string>().c_str());
 
1885
  }
 
1886
 
 
1887
  if (vm.count("flush-log-at-trx-commit"))
 
1888
  {
 
1889
    if (srv_flush_log_at_trx_commit > 2)
 
1890
    {
 
1891
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for flush-log-at-trx-commit\n"));
 
1892
      exit(-1);
 
1893
    }
 
1894
  }
 
1895
 
 
1896
  if (vm.count("flush-method"))
 
1897
  {
 
1898
    innobase_unix_file_flush_method= const_cast<char *>(vm["flush-method"].as<string>().c_str());
 
1899
  }
 
1900
  else
 
1901
  {
 
1902
    innobase_unix_file_flush_method= NULL;
 
1903
  }
 
1904
 
 
1905
#ifdef UNIV_LOG_ARCHIVE
 
1906
  if (vm.count("log-arch-dir"))
 
1907
  {
 
1908
    innobase_log_arch_dir= const_cast<char *>(vm["log-arch-dir"].as<string>().c_str());
 
1909
  }
 
1910
 
 
1911
  else
 
1912
  {
 
1913
    innobase_log_arch_dir= NULL;
 
1914
  }
 
1915
#endif /* UNIV_LOG_ARCHIVE */
 
1916
 
 
1917
  if (vm.count("max-dirty-pages-pct"))
 
1918
  {
 
1919
    if (srv_max_buf_pool_modified_pct > 99)
 
1920
    {
 
1921
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for max-dirty-pages-pct\n"));
 
1922
      exit(-1);
 
1923
    }
 
1924
  }
 
1925
 
 
1926
  if (vm.count("stats-sample-pages"))
 
1927
  {
 
1928
    if (srv_stats_sample_pages < 8)
 
1929
    {
 
1930
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for stats-sample-pages\n"));
 
1931
      exit(-1);
 
1932
    }
 
1933
  }
 
1934
 
 
1935
  if (vm.count("additional-mem-pool-size"))
 
1936
  {
 
1937
    align_value(innobase_additional_mem_pool_size);
 
1938
 
 
1939
    if (innobase_additional_mem_pool_size < 512*1024L)
 
1940
    {
 
1941
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for additional-mem-pool-size\n"));
 
1942
      exit(-1);
 
1943
    }
 
1944
 
 
1945
  }
 
1946
 
 
1947
  if (vm.count("autoextend-increment"))
 
1948
  {
 
1949
    if (srv_auto_extend_increment < 1 || srv_auto_extend_increment > 1000)
 
1950
    {
 
1951
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for autoextend-increment\n"));
 
1952
      exit(-1);
 
1953
    }
 
1954
  }
 
1955
 
 
1956
  if (vm.count("buffer-pool-size"))
 
1957
  {
 
1958
    align_value(innobase_buffer_pool_size, 1024*1024);
 
1959
    if (innobase_buffer_pool_size < 5*1024*1024)
 
1960
    {
 
1961
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for buffer-pool-size\n"));
 
1962
      exit(-1);
 
1963
    }
 
1964
    
 
1965
  }
 
1966
 
 
1967
  if (vm.count("commit-concurrency"))
 
1968
  {
 
1969
    if (srv_replication_delay > 1000)
 
1970
    {
 
1971
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for commit-concurrency\n"));
 
1972
      exit(-1);
 
1973
    }
 
1974
  }
 
1975
 
 
1976
  if (vm.count("concurrency-tickets"))
 
1977
  {
 
1978
    if (srv_n_free_tickets_to_enter < 1)
 
1979
    {
 
1980
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for concurrency-tickets\n"));
 
1981
      exit(-1);
 
1982
    }
 
1983
  }
 
1984
 
 
1985
  if (vm.count("file-io-threads"))
 
1986
  {
 
1987
    if (innobase_file_io_threads < 4 || innobase_file_io_threads > 64)
 
1988
    {
 
1989
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for file-io-threads\n"));
 
1990
      exit(-1);
 
1991
    }
 
1992
  }
 
1993
 
 
1994
  if (vm.count("read-io-threads"))
 
1995
  {
 
1996
    if (innobase_read_io_threads < 1 || innobase_read_io_threads > 64)
 
1997
    {
 
1998
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-io-threads\n"));
 
1999
      exit(-1);
 
2000
    }
 
2001
  }
 
2002
 
 
2003
  if (vm.count("write-io-threads"))
 
2004
  {
 
2005
    if (innobase_write_io_threads < 1 || innobase_write_io_threads > 64)
 
2006
    {
 
2007
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for write-io-threads\n"));
 
2008
      exit(-1);
 
2009
    }
 
2010
  }
 
2011
 
 
2012
  if (vm.count("force-recovery"))
 
2013
  {
 
2014
    if (innobase_force_recovery > 6)
 
2015
    {
 
2016
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for force-recovery\n"));
 
2017
      exit(-1);
 
2018
    }
 
2019
  }
 
2020
 
 
2021
  if (vm.count("log-buffer-size"))
 
2022
  {
 
2023
    align_value(innobase_log_buffer_size);
 
2024
    if (innobase_log_buffer_size < 256*1024L)
 
2025
    {
 
2026
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
 
2027
      exit(-1);
 
2028
    }
 
2029
  }
 
2030
 
 
2031
  if (vm.count("log-file-size"))
 
2032
  {
 
2033
    align_value(innobase_log_file_size, 1024*1024);
 
2034
    if (innobase_log_file_size < 1*1024*1024L)
 
2035
    {
 
2036
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-file-size\n"));
 
2037
      exit(-1);
 
2038
    }
 
2039
  }
 
2040
 
 
2041
  if (vm.count("log-files-in-group"))
 
2042
  {
 
2043
    if (innobase_log_files_in_group < 2 || innobase_log_files_in_group > 100)
 
2044
    {
 
2045
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for log-files-in-group\n"));
 
2046
      exit(-1);
 
2047
    }
 
2048
  }
 
2049
 
 
2050
  if (vm.count("mirrored-log-groups"))
 
2051
  {
 
2052
    if (innobase_mirrored_log_groups < 1 || innobase_mirrored_log_groups > 10)
 
2053
    {
 
2054
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for mirrored-log-groups\n"));
 
2055
      exit(-1);
 
2056
    }
 
2057
  }
 
2058
 
 
2059
  if (vm.count("open-files"))
 
2060
  {
 
2061
    if (innobase_open_files < 10)
 
2062
    {
 
2063
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for open-files\n"));
 
2064
      exit(-1);
 
2065
    }
 
2066
  }
 
2067
 
 
2068
  if (vm.count("thread-concurrency"))
 
2069
  {
 
2070
    if (srv_thread_concurrency > 1000)
 
2071
    {
 
2072
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for thread-concurrency\n"));
 
2073
      exit(-1);
 
2074
    }
 
2075
  }
2059
2076
 
2060
2077
  if (vm.count("data-file-path"))
2061
2078
  {
2062
 
    innobase_data_file_path= vm["data-file-path"].as<string>();
2063
 
  }
2064
 
 
 
2079
    innobase_data_file_path= const_cast<char *>(vm["data-file-path"].as<string>().c_str());
 
2080
  }
 
2081
  else
 
2082
  {
 
2083
    innobase_data_file_path= NULL;
 
2084
  }
 
2085
 
 
2086
  if (vm.count("version"))
 
2087
  {
 
2088
    innodb_version_str= const_cast<char *>(vm["version"].as<string>().c_str());
 
2089
  }
 
2090
 
 
2091
  if (vm.count("read-ahead-threshold"))
 
2092
  {
 
2093
    if (srv_read_ahead_threshold > 64)
 
2094
    {
 
2095
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read-ahead-threshold\n"));
 
2096
      exit(-1);
 
2097
    }
 
2098
  }
 
2099
 
 
2100
  if (vm.count("support-xa"))
 
2101
  {
 
2102
    (SessionVAR(NULL,support_xa))= vm["support-xa"].as<bool>();
 
2103
  }
 
2104
 
 
2105
  if (vm.count("table-locks"))
 
2106
  {
 
2107
    (SessionVAR(NULL,table_locks))= vm["table-locks"].as<bool>();
 
2108
  }
 
2109
 
 
2110
  if (vm.count("strict-mode"))
 
2111
  {
 
2112
    (SessionVAR(NULL,strict_mode))= vm["strict-mode"].as<bool>();
 
2113
  }
 
2114
 
 
2115
  if (vm.count("lock-wait-timeout"))
 
2116
  {
 
2117
    if (vm["lock-wait-timeout"].as<unsigned long>() < 1 || vm["lock-wait-timeout"].as<unsigned long>() > 1024*1024*1024)
 
2118
    {
 
2119
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for lock-wait-timeout\n"));
 
2120
      exit(-1);
 
2121
    }
 
2122
 
 
2123
    (SessionVAR(NULL,lock_wait_timeout))= vm["lock-wait-timeout"].as<unsigned long>();
 
2124
  }
2065
2125
 
2066
2126
  innodb_engine_ptr= actuall_engine_ptr= new InnobaseEngine(innobase_engine_name);
2067
2127
 
2069
2129
 
2070
2130
#ifdef UNIV_DEBUG
2071
2131
  static const char test_filename[] = "-@";
2072
 
  const size_t test_tablename_size= sizeof test_filename
2073
 
    + srv_mysql50_table_name_prefix.size();
2074
 
  boost::scoped_array test_tablename(new char[test_tablename_size]);
2075
 
  if ((test_tablename_size) - 1
2076
 
      != filename_to_tablename(test_filename, test_tablename.get(),
2077
 
                               test_tablename_size)
2078
 
      || strncmp(test_tablename.get(),
2079
 
                 srv_mysql50_table_name_prefix.c_str(),
2080
 
                 srv_mysql50_table_name_prefix.size())
2081
 
      || strcmp(test_tablename.get()
2082
 
                + srv_mysql50_table_name_prefix.size(),
 
2132
  char      test_tablename[sizeof test_filename
 
2133
    + sizeof srv_mysql50_table_name_prefix];
 
2134
  if ((sizeof test_tablename) - 1
 
2135
      != filename_to_tablename(test_filename, test_tablename,
 
2136
                               sizeof test_tablename)
 
2137
      || strncmp(test_tablename,
 
2138
                 srv_mysql50_table_name_prefix,
 
2139
                 sizeof srv_mysql50_table_name_prefix)
 
2140
      || strcmp(test_tablename
 
2141
                + sizeof srv_mysql50_table_name_prefix,
2083
2142
                test_filename)) {
2084
 
    errmsg_printf(error::ERROR, "tablename encoding has been changed");
 
2143
    errmsg_printf(ERRMSG_LVL_ERROR, "tablename encoding has been changed");
2085
2144
    goto error;
2086
2145
  }
2087
2146
#endif /* UNIV_DEBUG */
2088
2147
 
 
2148
  /* Check that values don't overflow on 32-bit systems. */
 
2149
  if (sizeof(ulint) == 4) {
 
2150
    if (innobase_buffer_pool_size > UINT32_MAX) {
 
2151
      errmsg_printf(ERRMSG_LVL_ERROR, 
 
2152
                    "innobase_buffer_pool_size can't be over 4GB"
 
2153
                    " on 32-bit systems");
 
2154
 
 
2155
      goto error;
 
2156
    }
 
2157
 
 
2158
    if (innobase_log_file_size > UINT32_MAX) {
 
2159
      errmsg_printf(ERRMSG_LVL_ERROR, 
 
2160
                    "innobase_log_file_size can't be over 4GB"
 
2161
                    " on 32-bit systems");
 
2162
 
 
2163
      goto error;
 
2164
    }
 
2165
  }
 
2166
 
2089
2167
  os_innodb_umask = (ulint)internal::my_umask;
2090
2168
 
 
2169
  /* First calculate the default path for innodb_data_home_dir etc.,
 
2170
    in case the user has not given any value.
 
2171
 
 
2172
    Note that when using the embedded server, the datadirectory is not
 
2173
    necessarily the current directory of this program. */
 
2174
 
 
2175
  /* It's better to use current lib, to keep paths short */
 
2176
  current_dir[0] = FN_CURLIB;
 
2177
  current_dir[1] = FN_LIBCHAR;
 
2178
  current_dir[2] = 0;
 
2179
  default_path = current_dir;
 
2180
 
 
2181
  ut_a(default_path);
 
2182
 
 
2183
  srv_set_thread_priorities = TRUE;
 
2184
  srv_query_thread_priority = QUERY_PRIOR;
2091
2185
 
2092
2186
  /* Set InnoDB initialization parameters according to the values
2093
2187
    read from MySQL .cnf file */
2096
2190
 
2097
2191
  /* The default dir for data files is the datadir of MySQL */
2098
2192
 
2099
 
  srv_data_home = (char *)innobase_data_home_dir.c_str();
 
2193
  srv_data_home = (innobase_data_home_dir ? innobase_data_home_dir :
 
2194
                   default_path);
2100
2195
 
2101
2196
  /* Set default InnoDB data file size to 10 MB and let it be
2102
2197
    auto-extending. Thus users can use InnoDB in >= 4.0 without having
2103
2198
    to specify any startup options. */
2104
2199
 
2105
 
  if (innobase_data_file_path.empty()) 
2106
 
  {
2107
 
    innobase_data_file_path= std::string("ibdata1:10M:autoextend");
 
2200
  if (!innobase_data_file_path) {
 
2201
    innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
2108
2202
  }
2109
2203
 
2110
2204
  /* Since InnoDB edits the argument in the next call, we make another
2111
2205
    copy of it: */
2112
2206
 
2113
 
  internal_innobase_data_file_path = strdup(innobase_data_file_path.c_str());
 
2207
  internal_innobase_data_file_path = strdup(innobase_data_file_path);
2114
2208
 
2115
2209
  ret = (bool) srv_parse_data_file_paths_and_sizes(
2116
2210
                                                   internal_innobase_data_file_path);
2117
2211
  if (ret == FALSE) {
2118
 
    errmsg_printf(error::ERROR, "InnoDB: syntax error in innodb_data_file_path");
2119
 
 
 
2212
    errmsg_printf(ERRMSG_LVL_ERROR, 
 
2213
                  "InnoDB: syntax error in innodb_data_file_path");
2120
2214
mem_free_and_error:
2121
2215
    srv_free_paths_and_sizes();
2122
2216
    if (internal_innobase_data_file_path)
2130
2224
 
2131
2225
  if (vm.count("log-group-home-dir"))
2132
2226
  {
2133
 
    innobase_log_group_home_dir= vm["log-group-home-dir"].as<string>();
 
2227
    innobase_log_group_home_dir= const_cast<char *>(vm["log-group-home-dir"].as<string>().c_str());
2134
2228
  }
2135
2229
  else
2136
2230
  {
2137
 
    innobase_log_group_home_dir= getDataHome().file_string();
 
2231
    innobase_log_group_home_dir = default_path;
2138
2232
  }
2139
2233
 
 
2234
#ifdef UNIV_LOG_ARCHIVE
 
2235
  /* Since innodb_log_arch_dir has no relevance under MySQL,
 
2236
    starting from 4.0.6 we always set it the same as
 
2237
innodb_log_group_home_dir: */
 
2238
 
 
2239
  innobase_log_arch_dir = innobase_log_group_home_dir;
 
2240
 
 
2241
  srv_arch_dir = innobase_log_arch_dir;
 
2242
#endif /* UNIG_LOG_ARCHIVE */
 
2243
 
2140
2244
  ret = (bool)
2141
 
    srv_parse_log_group_home_dirs((char *)innobase_log_group_home_dir.c_str());
 
2245
    srv_parse_log_group_home_dirs(innobase_log_group_home_dir);
2142
2246
 
2143
 
  if (ret == FALSE || innobase_mirrored_log_groups.get() != 1) {
2144
 
    errmsg_printf(error::ERROR, _("syntax error in innodb_log_group_home_dir, or a "
2145
 
                                  "wrong number of mirrored log groups"));
 
2247
  if (ret == FALSE || innobase_mirrored_log_groups != 1) {
 
2248
    errmsg_printf(ERRMSG_LVL_ERROR, "syntax error in innodb_log_group_home_dir, or a "
 
2249
                  "wrong number of mirrored log groups");
2146
2250
 
2147
2251
    goto mem_free_and_error;
2148
2252
  }
2156
2260
 
2157
2261
    if (format_id > DICT_TF_FORMAT_MAX) {
2158
2262
 
2159
 
      errmsg_printf(error::ERROR, "InnoDB: wrong innodb_file_format.");
 
2263
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: wrong innodb_file_format.");
2160
2264
 
2161
2265
      goto mem_free_and_error;
2162
2266
    }
2167
2271
 
2168
2272
  srv_file_format = format_id;
2169
2273
 
2170
 
  innobase_file_format_name =
2171
 
    trx_sys_file_format_id_to_name(format_id);
2172
 
 
2173
 
  /* Check innobase_file_format_check variable */
2174
 
  if (!innobase_file_format_check)
2175
 
  {
2176
 
    /* Set the value to disable checking. */
2177
 
    srv_max_file_format_at_startup = DICT_TF_FORMAT_MAX + 1;
2178
 
  } else {
2179
 
    /* Set the value to the lowest supported format. */
2180
 
    srv_max_file_format_at_startup = DICT_TF_FORMAT_MIN;
2181
 
  }
2182
 
 
2183
 
  /* Did the user specify a format name that we support?
2184
 
     As a side effect it will update the variable
2185
 
     srv_max_file_format_at_startup */
2186
 
  if (innobase_file_format_validate_and_set(innobase_file_format_max.c_str()) < 0)
2187
 
  {
2188
 
    errmsg_printf(error::ERROR, _("InnoDB: invalid innodb_file_format_max value: "
2189
 
                                  "should be any value up to %s or its equivalent numeric id"),
2190
 
                  trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
2191
 
    goto mem_free_and_error;
 
2274
  /* Given the type of innobase_file_format_name we have little
 
2275
    choice but to cast away the constness from the returned name.
 
2276
    innobase_file_format_name is used in the MySQL set variable
 
2277
    interface and so can't be const. */
 
2278
 
 
2279
  innobase_file_format_name = 
 
2280
    (char*) trx_sys_file_format_id_to_name(format_id);
 
2281
 
 
2282
  /* Process innobase_file_format_check variable */
 
2283
  ut_a(innobase_file_format_check != NULL);
 
2284
 
 
2285
  /* As a side effect it will set srv_check_file_format_at_startup
 
2286
    on valid input. First we check for "on"/"off". */
 
2287
  if (!innobase_file_format_check_on_off(innobase_file_format_check)) {
 
2288
 
 
2289
    /* Did the user specify a format name that we support ?
 
2290
      As a side effect it will update the variable
 
2291
      srv_check_file_format_at_startup */
 
2292
    if (!innobase_file_format_check_validate(
 
2293
                                             innobase_file_format_check)) {
 
2294
 
 
2295
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: invalid "
 
2296
                    "innodb_file_format_check value: "
 
2297
                    "should be either 'on' or 'off' or "
 
2298
                    "any value up to %s or its "
 
2299
                    "equivalent numeric id",
 
2300
                    trx_sys_file_format_id_to_name(
 
2301
                                                   DICT_TF_FORMAT_MAX));
 
2302
 
 
2303
      goto mem_free_and_error;
 
2304
    }
2192
2305
  }
2193
2306
 
2194
2307
  if (vm.count("change-buffering"))
2199
2312
         use < UT_ARR_SIZE(innobase_change_buffering_values);
2200
2313
         use++) {
2201
2314
      if (!innobase_strcasecmp(
2202
 
                               innobase_change_buffering.c_str(),
 
2315
                               vm["change-buffering"].as<string>().c_str(),
2203
2316
                               innobase_change_buffering_values[use])) {
2204
 
        ibuf_use = static_cast<ibuf_use_t>(use);
 
2317
        ibuf_use = (ibuf_use_t) use;
2205
2318
        goto innobase_change_buffering_inited_ok;
2206
2319
      }
2207
2320
    }
2208
2321
 
2209
 
    errmsg_printf(error::ERROR, "InnoDB: invalid value innodb_change_buffering=%s",
 
2322
    errmsg_printf(ERRMSG_LVL_ERROR,
 
2323
                  "InnoDB: invalid value "
 
2324
                  "innodb_file_format_check=%s",
2210
2325
                  vm["change-buffering"].as<string>().c_str());
2211
2326
    goto mem_free_and_error;
2212
2327
  }
2213
2328
 
2214
2329
innobase_change_buffering_inited_ok:
2215
2330
  ut_a((ulint) ibuf_use < UT_ARR_SIZE(innobase_change_buffering_values));
2216
 
  innobase_change_buffering = innobase_change_buffering_values[ibuf_use];
 
2331
  innobase_change_buffering = (char*)
 
2332
    innobase_change_buffering_values[ibuf_use];
2217
2333
 
2218
2334
  /* --------------------------------------------------*/
2219
2335
 
2220
 
  if (vm.count("flush-method") != 0)
2221
 
  {
2222
 
    srv_file_flush_method_str = (char *)vm["flush-method"].as<string>().c_str();
2223
 
  }
 
2336
  srv_file_flush_method_str = innobase_unix_file_flush_method;
2224
2337
 
2225
2338
  srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
2226
2339
  srv_n_log_files = (ulint) innobase_log_files_in_group;
2227
2340
  srv_log_file_size = (ulint) innobase_log_file_size;
2228
2341
 
 
2342
#ifdef UNIV_LOG_ARCHIVE
 
2343
  srv_log_archive_on = (ulint) innobase_log_archive;
 
2344
#endif /* UNIV_LOG_ARCHIVE */
2229
2345
  srv_log_buffer_size = (ulint) innobase_log_buffer_size;
2230
2346
 
2231
2347
  srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
2232
 
  srv_buf_pool_instances = (ulint) innobase_buffer_pool_instances;
2233
2348
 
2234
2349
  srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
2235
2350
 
 
2351
  srv_n_file_io_threads = (ulint) innobase_file_io_threads;
2236
2352
  srv_n_read_io_threads = (ulint) innobase_read_io_threads;
2237
2353
  srv_n_write_io_threads = (ulint) innobase_write_io_threads;
2238
2354
 
2260
2376
 
2261
2377
  data_mysql_default_charset_coll = (ulint)default_charset_info->number;
2262
2378
 
 
2379
 
 
2380
  innobase_commit_concurrency_init_default();
 
2381
 
2263
2382
  /* Since we in this module access directly the fields of a trx
2264
2383
    struct, and due to different headers and flags it might happen that
2265
2384
    mutex_t has a different size in this module and in InnoDB
2268
2387
 
2269
2388
  err = innobase_start_or_create_for_mysql();
2270
2389
 
2271
 
  if (err != DB_SUCCESS)
2272
 
  {
2273
 
    goto mem_free_and_error;
2274
 
  }
2275
 
 
2276
 
  err = dict_create_sys_replication_log();
2277
 
 
2278
2390
  if (err != DB_SUCCESS) {
2279
2391
    goto mem_free_and_error;
2280
2392
  }
2281
2393
 
2282
 
 
2283
 
  innobase_old_blocks_pct = buf_LRU_old_ratio_update(innobase_old_blocks_pct.get(),
2284
 
                                                     TRUE);
2285
 
 
2286
2394
  innobase_open_tables = hash_create(200);
 
2395
  pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
 
2396
  pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
 
2397
  pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
 
2398
  pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
 
2399
  pthread_cond_init(&commit_cond, NULL);
2287
2400
  innodb_inited= 1;
2288
2401
 
2289
2402
  actuall_engine_ptr->dropTemporarySchema();
2290
2403
 
2291
 
  context.add(new InnodbStatusTool);
 
2404
  status_table_function_ptr= new InnodbStatusTool;
2292
2405
 
2293
2406
  context.add(innodb_engine_ptr);
2294
2407
 
2295
 
  context.add(new(std::nothrow)CmpTool(false));
2296
 
 
2297
 
  context.add(new(std::nothrow)CmpTool(true));
2298
 
 
2299
 
  context.add(new(std::nothrow)CmpmemTool(false));
2300
 
 
2301
 
  context.add(new(std::nothrow)CmpmemTool(true));
2302
 
 
2303
 
  context.add(new(std::nothrow)InnodbTrxTool("INNODB_TRX"));
2304
 
 
2305
 
  context.add(new(std::nothrow)InnodbTrxTool("INNODB_LOCKS"));
2306
 
 
2307
 
  context.add(new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS"));
2308
 
 
2309
 
  context.add(new(std::nothrow)InnodbSysTablesTool());
2310
 
 
2311
 
  context.add(new(std::nothrow)InnodbSysTableStatsTool());
2312
 
 
2313
 
  context.add(new(std::nothrow)InnodbSysIndexesTool());
2314
 
 
2315
 
  context.add(new(std::nothrow)InnodbSysColumnsTool());
2316
 
 
2317
 
  context.add(new(std::nothrow)InnodbSysFieldsTool());
2318
 
 
2319
 
  context.add(new(std::nothrow)InnodbSysForeignTool());
2320
 
 
2321
 
  context.add(new(std::nothrow)InnodbSysForeignColsTool());
 
2408
  context.add(status_table_function_ptr);
 
2409
 
 
2410
  cmp_tool= new(std::nothrow)CmpTool(false);
 
2411
  context.add(cmp_tool);
 
2412
 
 
2413
  cmp_reset_tool= new(std::nothrow)CmpTool(true);
 
2414
  context.add(cmp_reset_tool);
 
2415
 
 
2416
  cmp_mem_tool= new(std::nothrow)CmpmemTool(false);
 
2417
  context.add(cmp_mem_tool);
 
2418
 
 
2419
  cmp_mem_reset_tool= new(std::nothrow)CmpmemTool(true);
 
2420
  context.add(cmp_mem_reset_tool);
 
2421
 
 
2422
  innodb_trx_tool= new(std::nothrow)InnodbTrxTool("INNODB_TRX");
 
2423
  context.add(innodb_trx_tool);
 
2424
 
 
2425
  innodb_locks_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCKS");
 
2426
  context.add(innodb_locks_tool);
 
2427
 
 
2428
  innodb_lock_waits_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS");
 
2429
  context.add(innodb_lock_waits_tool);
2322
2430
 
2323
2431
  context.add(new(std::nothrow)InnodbInternalTables());
2324
 
  context.add(new(std::nothrow)InnodbReplicationTable());
2325
 
 
2326
 
  if (innobase_use_replication_log)
2327
 
  {
2328
 
    ReplicationLog *replication_logger= new(std::nothrow)ReplicationLog();
2329
 
    context.add(replication_logger);
2330
 
    ReplicationLog::setup(replication_logger);
2331
 
  }
2332
 
 
2333
 
  context.registerVariable(new sys_var_const_string_val("data-home-dir", innobase_data_home_dir));
2334
 
  context.registerVariable(new sys_var_const_string_val("flush-method", 
2335
 
                                                        vm.count("flush-method") ?  vm["flush-method"].as<string>() : ""));
2336
 
  context.registerVariable(new sys_var_const_string_val("log-group-home-dir", innobase_log_group_home_dir));
2337
 
  context.registerVariable(new sys_var_const_string_val("data-file-path", innobase_data_file_path));
2338
 
  context.registerVariable(new sys_var_const_string_val("version", vm["version"].as<string>()));
2339
 
 
2340
 
 
2341
 
  context.registerVariable(new sys_var_bool_ptr_readonly("replication_log", &innobase_use_replication_log));
2342
 
  context.registerVariable(new sys_var_bool_ptr_readonly("checksums", &innobase_use_checksums));
2343
 
  context.registerVariable(new sys_var_bool_ptr_readonly("doublewrite", &innobase_use_doublewrite));
2344
 
  context.registerVariable(new sys_var_bool_ptr("file-per-table", &srv_file_per_table));
2345
 
  context.registerVariable(new sys_var_bool_ptr_readonly("file-format-check", &innobase_file_format_check));
2346
 
  context.registerVariable(new sys_var_bool_ptr("adaptive-flushing", &srv_adaptive_flushing));
2347
 
  context.registerVariable(new sys_var_bool_ptr("status-file", &innobase_create_status_file));
2348
 
  context.registerVariable(new sys_var_bool_ptr_readonly("use-sys-malloc", &srv_use_sys_malloc));
2349
 
  context.registerVariable(new sys_var_bool_ptr_readonly("use-native-aio", &srv_use_native_aio));
2350
 
 
2351
 
  context.registerVariable(new sys_var_bool_ptr("support-xa", &support_xa));
2352
 
  context.registerVariable(new sys_var_bool_ptr("strict_mode", &strict_mode));
2353
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("lock_wait_timeout", lock_wait_timeout));
2354
 
 
2355
 
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("additional_mem_pool_size",innobase_additional_mem_pool_size));
2356
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("autoextend_increment",
2357
 
                                                                   innodb_auto_extend_increment,
2358
 
                                                                   auto_extend_update));
2359
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("io_capacity",
2360
 
                                                                   innodb_io_capacity,
2361
 
                                                                   io_capacity_update));
2362
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("purge_batch_size",
2363
 
                                                                   innodb_purge_batch_size,
2364
 
                                                                   purge_batch_update));
2365
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("purge_threads",
2366
 
                                                                   innodb_n_purge_threads,
2367
 
                                                                   purge_threads_update));
2368
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("fast_shutdown", innobase_fast_shutdown));
2369
 
  context.registerVariable(new sys_var_std_string("file_format",
2370
 
                                                  innobase_file_format_name,
2371
 
                                                  innodb_file_format_name_validate));
2372
 
  context.registerVariable(new sys_var_std_string("change_buffering",
2373
 
                                                  innobase_change_buffering,
2374
 
                                                  innodb_change_buffering_validate));
2375
 
  context.registerVariable(new sys_var_std_string("file_format_max",
2376
 
                                                  innobase_file_format_max,
2377
 
                                                  innodb_file_format_max_validate));
2378
 
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("buffer_pool_size", innobase_buffer_pool_size));
2379
 
  context.registerVariable(new sys_var_constrained_value_readonly<int64_t>("log_file_size", innobase_log_file_size));
2380
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("flush_log_at_trx_commit",
2381
 
                                                  innodb_flush_log_at_trx_commit));
2382
 
  context.registerVariable(new sys_var_constrained_value_readonly<unsigned int>("max_dirty_pages_pct",
2383
 
                                                  innodb_max_dirty_pages_pct));
2384
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("max_purge_lag", innodb_max_purge_lag));
2385
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("stats_sample_pages", innodb_stats_sample_pages));
2386
 
  context.registerVariable(new sys_var_bool_ptr("adaptive_hash_index", &btr_search_enabled, innodb_adaptive_hash_index_update));
2387
 
 
2388
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("commit_concurrency",
2389
 
                                                                   innobase_commit_concurrency,
2390
 
                                                                   innodb_commit_concurrency_validate));
2391
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("concurrency_tickets",
2392
 
                                                                   innodb_concurrency_tickets));
2393
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("read_io_threads", innobase_read_io_threads));
2394
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("write_io_threads", innobase_write_io_threads));
2395
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("replication_delay", innodb_replication_delay));
2396
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("force_recovery", innobase_force_recovery));
2397
 
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("log_buffer_size", innobase_log_buffer_size));
2398
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("log_files_in_group", innobase_log_files_in_group));
2399
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("mirrored_log_groups", innobase_mirrored_log_groups));
2400
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("open_files", innobase_open_files));
2401
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("old_blocks_pct",
2402
 
                                                                   innobase_old_blocks_pct,
2403
 
                                                                   innodb_old_blocks_pct_update));
2404
 
  context.registerVariable(new sys_var_uint32_t_ptr("old_blocks_time", &buf_LRU_old_threshold_ms));
2405
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("sync_spin_loops", innodb_sync_spin_loops, innodb_sync_spin_loops_update));
2406
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("spin_wait_delay", innodb_spin_wait_delay, innodb_spin_wait_delay_update));
2407
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("thread_sleep_delay", innodb_thread_sleep_delay, innodb_thread_sleep_delay_update));
2408
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("thread_concurrency",
2409
 
                                                                   innobase_thread_concurrency,
2410
 
                                                                   innodb_thread_concurrency_update));
2411
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("read_ahead_threshold",
2412
 
                                                                   innodb_read_ahead_threshold,
2413
 
                                                                   innodb_read_ahead_threshold_update));
 
2432
 
2414
2433
  /* Get the current high water mark format. */
2415
 
  innobase_file_format_max = trx_sys_file_format_max_get();
2416
 
  btr_search_fully_disabled = (!btr_search_enabled);
 
2434
  innobase_file_format_check = (char*) trx_sys_file_format_max_get();
2417
2435
 
2418
2436
  return(FALSE);
2419
 
 
2420
2437
error:
2421
2438
  return(TRUE);
2422
2439
}
2513
2530
    trx_search_latch_release_if_reserved(trx);
2514
2531
  }
2515
2532
 
2516
 
  if (all)
2517
 
  {
 
2533
  if (all
 
2534
    || (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
 
2535
 
2518
2536
    /* We were instructed to commit the whole transaction, or
2519
2537
    this is an SQL statement end and autocommit is on */
2520
2538
 
2521
2539
    /* We need current binlog position for ibbackup to work.
2522
2540
    Note, the position is current because of
2523
2541
    prepare_commit_mutex */
2524
 
    const uint32_t commit_concurrency= innobase_commit_concurrency.get();
2525
 
    if (commit_concurrency)
2526
 
    {
2527
 
      do 
2528
 
      {
2529
 
        boost::mutex::scoped_lock scopedLock(commit_cond_m);
2530
 
        commit_threads++;
2531
 
 
2532
 
        if (commit_threads <= commit_concurrency) 
2533
 
          break;
2534
 
 
 
2542
retry:
 
2543
    if (innobase_commit_concurrency > 0) {
 
2544
      pthread_mutex_lock(&commit_cond_m);
 
2545
      commit_threads++;
 
2546
 
 
2547
      if (commit_threads > innobase_commit_concurrency) {
2535
2548
        commit_threads--;
2536
 
        commit_cond.wait(scopedLock);
2537
 
      } while (1);
 
2549
        pthread_cond_wait(&commit_cond,
 
2550
          &commit_cond_m);
 
2551
        pthread_mutex_unlock(&commit_cond_m);
 
2552
        goto retry;
 
2553
      }
 
2554
      else {
 
2555
        pthread_mutex_unlock(&commit_cond_m);
 
2556
      }
2538
2557
    }
2539
2558
 
2540
 
    trx->mysql_log_file_name = NULL;
 
2559
                /* Store transaction point for binlog
 
2560
    Later logic tests that this is set to _something_. We need
 
2561
    that logic to fire, even though we do not have a real name. */
 
2562
    trx->mysql_log_file_name = "UNUSED";
2541
2563
    trx->mysql_log_offset = 0;
2542
2564
 
2543
2565
    /* Don't do write + flush right now. For group commit
2547
2569
    innobase_commit_low(trx);
2548
2570
    trx->flush_log_later = FALSE;
2549
2571
 
2550
 
    if (commit_concurrency)
2551
 
    {
2552
 
      boost::mutex::scoped_lock scopedLock(commit_cond_m);
 
2572
    if (innobase_commit_concurrency > 0) {
 
2573
      pthread_mutex_lock(&commit_cond_m);
2553
2574
      commit_threads--;
2554
 
      commit_cond.notify_one();
 
2575
      pthread_cond_signal(&commit_cond);
 
2576
      pthread_mutex_unlock(&commit_cond_m);
2555
2577
    }
2556
2578
 
2557
2579
    /* Now do a write + flush of logs. */
2571
2593
    SQL statement */
2572
2594
 
2573
2595
    trx_mark_sql_stat_end(trx);
2574
 
 
2575
 
    if (! session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
2576
 
    {
2577
 
      if (trx->conc_state != TRX_NOT_STARTED)
2578
 
      {
2579
 
        commit(session, TRUE);
2580
 
      }
2581
 
    }
2582
2596
  }
2583
2597
 
2584
2598
  trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */
2593
2607
  threads: */
2594
2608
  srv_active_wake_master_thread();
2595
2609
 
2596
 
  if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
2597
 
      trx->global_read_view)
2598
 
  {
2599
 
    /* At low transaction isolation levels we let
2600
 
       each consistent read set its own snapshot */
2601
 
    read_view_close_for_mysql(trx);
2602
 
  }
2603
 
 
2604
2610
  return(0);
2605
2611
}
2606
2612
 
2628
2634
 
2629
2635
  innobase_release_stat_resources(trx);
2630
2636
 
2631
 
  trx->n_autoinc_rows = 0;
2632
 
 
2633
2637
  /* If we had reserved the auto-inc lock for some table (if
2634
2638
  we come here to roll back the latest SQL statement) we
2635
2639
  release it now before a possibly lengthy rollback */
2636
2640
 
2637
2641
  row_unlock_table_autoinc_for_mysql(trx);
2638
2642
 
2639
 
  if (all)
2640
 
  {
 
2643
  if (all
 
2644
    || !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
 
2645
 
2641
2646
    error = trx_rollback_for_mysql(trx);
2642
2647
  } else {
2643
2648
    error = trx_rollback_last_sql_stat_for_mysql(trx);
2644
2649
  }
2645
2650
 
2646
 
  if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
2647
 
      trx->global_read_view)
2648
 
  {
2649
 
    /* At low transaction isolation levels we let
2650
 
       each consistent read set its own snapshot */
2651
 
    read_view_close_for_mysql(trx);
2652
 
  }
2653
 
 
2654
2651
  return(convert_error_code_to_mysql(error, 0, NULL));
2655
2652
}
2656
2653
 
2787
2784
 
2788
2785
  ut_a(trx);
2789
2786
 
2790
 
  assert(session->getKilled() != Session::NOT_KILLED ||
 
2787
  assert(session->killed != Session::NOT_KILLED ||
2791
2788
         trx->conc_state == TRX_NOT_STARTED);
2792
2789
 
2793
2790
  /* Warn if rolling back some things... */
2794
 
  if (session->getKilled() != Session::NOT_KILLED &&
 
2791
  if (session->killed != Session::NOT_KILLED &&
2795
2792
      trx->conc_state != TRX_NOT_STARTED &&
2796
 
      trx->undo_no > 0 &&
 
2793
      trx->undo_no.low > 0 &&
2797
2794
      global_system_variables.log_warnings)
2798
2795
  {
2799
 
      errmsg_printf(error::WARN,
 
2796
      errmsg_printf(ERRMSG_LVL_WARN, 
2800
2797
      "Drizzle is closing a connection during a KILL operation\n"
2801
 
      "that has an active InnoDB transaction.  %llu row modifications will "
 
2798
      "that has an active InnoDB transaction.  %lu row modifications will "
2802
2799
      "roll back.\n",
2803
 
      (ullint) trx->undo_no);
 
2800
      (ulong) trx->undo_no.low);
2804
2801
  }
2805
2802
 
2806
2803
  innobase_rollback_trx(trx);
2876
2873
  return(true);
2877
2874
}
2878
2875
 
2879
 
/********************************************************************//**
2880
 
Get the upper limit of the MySQL integral and floating-point type.
2881
 
@return maximum allowed value for the field */
2882
 
static
2883
 
uint64_t
2884
 
innobase_get_int_col_max_value(
2885
 
/*===========================*/
2886
 
        const Field*    field)  /*!< in: MySQL field */
2887
 
{
2888
 
        uint64_t        max_value = 0;
2889
 
 
2890
 
        switch(field->key_type()) {
2891
 
        /* TINY */
2892
 
        case HA_KEYTYPE_BINARY:
2893
 
                max_value = 0xFFULL;
2894
 
                break;
2895
 
        /* LONG */
2896
 
        case HA_KEYTYPE_ULONG_INT:
2897
 
                max_value = 0xFFFFFFFFULL;
2898
 
                break;
2899
 
        case HA_KEYTYPE_LONG_INT:
2900
 
                max_value = 0x7FFFFFFFULL;
2901
 
                break;
2902
 
        /* BIG */
2903
 
        case HA_KEYTYPE_ULONGLONG:
2904
 
                max_value = 0xFFFFFFFFFFFFFFFFULL;
2905
 
                break;
2906
 
        case HA_KEYTYPE_LONGLONG:
2907
 
                max_value = 0x7FFFFFFFFFFFFFFFULL;
2908
 
                break;
2909
 
        case HA_KEYTYPE_DOUBLE:
2910
 
                /* We use the maximum as per IEEE754-2008 standard, 2^53 */
2911
 
                max_value = 0x20000000000000ULL;
2912
 
                break;
2913
 
        default:
2914
 
                ut_error;
2915
 
        }
2916
 
 
2917
 
        return(max_value);
2918
 
}
2919
 
 
2920
 
/*******************************************************************//**
2921
 
This function checks whether the index column information
2922
 
is consistent between KEY info from mysql and that from innodb index.
2923
 
@return TRUE if all column types match. */
2924
 
static
2925
 
ibool
2926
 
innobase_match_index_columns(
2927
 
/*=========================*/
2928
 
        const KeyInfo*          key_info,       /*!< in: Index info
2929
 
                                                from mysql */
2930
 
        const dict_index_t*     index_info)     /*!< in: Index info
2931
 
                                                from Innodb */
2932
 
{
2933
 
        const KeyPartInfo*      key_part;
2934
 
        const KeyPartInfo*      key_end;
2935
 
        const dict_field_t*     innodb_idx_fld;
2936
 
        const dict_field_t*     innodb_idx_fld_end;
2937
 
 
2938
 
        /* Check whether user defined index column count matches */
2939
 
        if (key_info->key_parts != index_info->n_user_defined_cols) {
2940
 
                return(FALSE);
2941
 
        }
2942
 
 
2943
 
        key_part = key_info->key_part;
2944
 
        key_end = key_part + key_info->key_parts;
2945
 
        innodb_idx_fld = index_info->fields;
2946
 
        innodb_idx_fld_end = index_info->fields + index_info->n_fields;
2947
 
 
2948
 
        /* Check each index column's datatype. We do not check
2949
 
        column name because there exists case that index
2950
 
        column name got modified in mysql but such change does not
2951
 
        propagate to InnoDB.
2952
 
        One hidden assumption here is that the index column sequences
2953
 
        are matched up between those in mysql and Innodb. */
2954
 
        for (; key_part != key_end; ++key_part) {
2955
 
                ulint   col_type;
2956
 
                ibool   is_unsigned;
2957
 
                ulint   mtype = innodb_idx_fld->col->mtype;
2958
 
 
2959
 
                /* Need to translate to InnoDB column type before
2960
 
                comparison. */
2961
 
                col_type = get_innobase_type_from_mysql_type(&is_unsigned,
2962
 
                                                             key_part->field);
2963
 
 
2964
 
                /* Ignore Innodb specific system columns. */
2965
 
                while (mtype == DATA_SYS) {
2966
 
                        innodb_idx_fld++;
2967
 
 
2968
 
                        if (innodb_idx_fld >= innodb_idx_fld_end) {
2969
 
                                return(FALSE);
2970
 
                        }
2971
 
                }
2972
 
 
2973
 
                if (col_type != mtype) {
2974
 
                        /* Column Type mismatches */
2975
 
                        return(FALSE);
2976
 
                }
2977
 
 
2978
 
                innodb_idx_fld++;
2979
 
        }
2980
 
 
2981
 
        return(TRUE);
2982
 
}
2983
 
 
2984
 
/*******************************************************************//**
2985
 
This function builds a translation table in INNOBASE_SHARE
2986
 
structure for fast index location with mysql array number from its
2987
 
table->key_info structure. This also provides the necessary translation
2988
 
between the key order in mysql key_info and Innodb ib_table->indexes if
2989
 
they are not fully matched with each other.
2990
 
Note we do not have any mutex protecting the translation table
2991
 
building based on the assumption that there is no concurrent
2992
 
index creation/drop and DMLs that requires index lookup. All table
2993
 
handle will be closed before the index creation/drop.
2994
 
@return TRUE if index translation table built successfully */
2995
 
static
2996
 
ibool
2997
 
innobase_build_index_translation(
2998
 
/*=============================*/
2999
 
        const Table*            table,    /*!< in: table in MySQL data
3000
 
                                          dictionary */
3001
 
        dict_table_t*           ib_table, /*!< in: table in Innodb data
3002
 
                                          dictionary */
3003
 
        INNOBASE_SHARE*         share)    /*!< in/out: share structure
3004
 
                                          where index translation table
3005
 
                                          will be constructed in. */
3006
 
{
3007
 
        ulint           mysql_num_index;
3008
 
        ulint           ib_num_index;
3009
 
        dict_index_t**  index_mapping;
3010
 
        ibool           ret = TRUE;
3011
 
 
3012
 
        mutex_enter(&dict_sys->mutex);
3013
 
 
3014
 
        mysql_num_index = table->getShare()->keys;
3015
 
        ib_num_index = UT_LIST_GET_LEN(ib_table->indexes);
3016
 
 
3017
 
        index_mapping = share->idx_trans_tbl.index_mapping;
3018
 
 
3019
 
        /* If there exists inconsistency between MySQL and InnoDB dictionary
3020
 
        (metadata) information, the number of index defined in MySQL
3021
 
        could exceed that in InnoDB, do not build index translation
3022
 
        table in such case */
3023
 
        if (UNIV_UNLIKELY(ib_num_index < mysql_num_index)) {
3024
 
                ret = FALSE;
3025
 
                goto func_exit;
3026
 
        }
3027
 
 
3028
 
        /* If index entry count is non-zero, nothing has
3029
 
        changed since last update, directly return TRUE */
3030
 
        if (share->idx_trans_tbl.index_count) {
3031
 
                /* Index entry count should still match mysql_num_index */
3032
 
                ut_a(share->idx_trans_tbl.index_count == mysql_num_index);
3033
 
                goto func_exit;
3034
 
        }
3035
 
 
3036
 
        /* The number of index increased, rebuild the mapping table */
3037
 
        if (mysql_num_index > share->idx_trans_tbl.array_size) {
3038
 
                index_mapping = (dict_index_t**) realloc(index_mapping,
3039
 
                                                        mysql_num_index *
3040
 
                                                         sizeof(*index_mapping));
3041
 
 
3042
 
                if (!index_mapping) {
3043
 
                        /* Report an error if index_mapping continues to be
3044
 
                        NULL and mysql_num_index is a non-zero value */
3045
 
                        errmsg_printf(error::ERROR, "InnoDB: fail to allocate memory for "
3046
 
                                      "index translation table. Number of Index:%lu, array size:%lu",
3047
 
                                        mysql_num_index,
3048
 
                                        share->idx_trans_tbl.array_size);
3049
 
                        ret = FALSE;
3050
 
                        goto func_exit;
3051
 
                }
3052
 
 
3053
 
                share->idx_trans_tbl.array_size = mysql_num_index;
3054
 
        }
3055
 
 
3056
 
        /* For each index in the mysql key_info array, fetch its
3057
 
        corresponding InnoDB index pointer into index_mapping
3058
 
        array. */
3059
 
        for (ulint count = 0; count < mysql_num_index; count++) {
3060
 
 
3061
 
                /* Fetch index pointers into index_mapping according to mysql
3062
 
                index sequence */
3063
 
                index_mapping[count] = dict_table_get_index_on_name(
3064
 
                        ib_table, table->key_info[count].name);
3065
 
 
3066
 
                if (!index_mapping[count]) {
3067
 
                        errmsg_printf(error::ERROR, "Cannot find index %s in InnoDB index dictionary.",
3068
 
                                      table->key_info[count].name);
3069
 
                        ret = FALSE;
3070
 
                        goto func_exit;
3071
 
                }
3072
 
 
3073
 
                /* Double check fetched index has the same
3074
 
                column info as those in mysql key_info. */
3075
 
                if (!innobase_match_index_columns(&table->key_info[count], index_mapping[count])) {
3076
 
                  errmsg_printf(error::ERROR, "Found index %s whose column info does not match that of MySQL.",
3077
 
                                table->key_info[count].name);
3078
 
                  ret = FALSE;
3079
 
                  goto func_exit;
3080
 
                }
3081
 
        }
3082
 
 
3083
 
        /* Successfully built the translation table */
3084
 
        share->idx_trans_tbl.index_count = mysql_num_index;
3085
 
 
3086
 
func_exit:
3087
 
        if (!ret) {
3088
 
                /* Build translation table failed. */
3089
 
                free(index_mapping);
3090
 
 
3091
 
                share->idx_trans_tbl.array_size = 0;
3092
 
                share->idx_trans_tbl.index_count = 0;
3093
 
                index_mapping = NULL;
3094
 
        }
3095
 
 
3096
 
        share->idx_trans_tbl.index_mapping = index_mapping;
3097
 
 
3098
 
        mutex_exit(&dict_sys->mutex);
3099
 
 
3100
 
        return(ret);
3101
 
}
3102
 
 
3103
 
/*******************************************************************//**
3104
 
This function uses index translation table to quickly locate the
3105
 
requested index structure.
3106
 
Note we do not have mutex protection for the index translatoin table
3107
 
access, it is based on the assumption that there is no concurrent
3108
 
translation table rebuild (fter create/drop index) and DMLs that
3109
 
require index lookup.
3110
 
@return dict_index_t structure for requested index. NULL if
3111
 
fail to locate the index structure. */
3112
 
static
3113
 
dict_index_t*
3114
 
innobase_index_lookup(
3115
 
/*==================*/
3116
 
        INNOBASE_SHARE* share,  /*!< in: share structure for index
3117
 
                                translation table. */
3118
 
        uint            keynr)  /*!< in: index number for the requested
3119
 
                                index */
3120
 
{
3121
 
        if (!share->idx_trans_tbl.index_mapping
3122
 
            || keynr >= share->idx_trans_tbl.index_count) {
3123
 
                return(NULL);
3124
 
        }
3125
 
 
3126
 
        return(share->idx_trans_tbl.index_mapping[keynr]);
 
2876
/*****************************************************************//**
 
2877
Normalizes a table name string. A normalized name consists of the
 
2878
database name catenated to '/' and table name. An example:
 
2879
test/mytable. On Windows normalization puts both the database name and the
 
2880
table name always to lower case. */
 
2881
static
 
2882
void
 
2883
normalize_table_name(
 
2884
/*=================*/
 
2885
  char*   norm_name,  /*!< out: normalized name as a
 
2886
          null-terminated string */
 
2887
  const char* name)   /*!< in: table name string */
 
2888
{
 
2889
  const char* name_ptr;
 
2890
  const char* db_ptr;
 
2891
  const char* ptr;
 
2892
 
 
2893
  /* Scan name from the end */
 
2894
 
 
2895
  ptr = strchr(name, '\0')-1;
 
2896
 
 
2897
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
 
2898
    ptr--;
 
2899
  }
 
2900
 
 
2901
  name_ptr = ptr + 1;
 
2902
 
 
2903
  assert(ptr > name);
 
2904
 
 
2905
  ptr--;
 
2906
 
 
2907
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
 
2908
    ptr--;
 
2909
  }
 
2910
 
 
2911
  db_ptr = ptr + 1;
 
2912
 
 
2913
  memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
 
2914
 
 
2915
  norm_name[name_ptr - db_ptr - 1] = '/';
 
2916
 
 
2917
#ifdef __WIN__
 
2918
  innobase_casedn_str(norm_name);
 
2919
#endif
3127
2920
}
3128
2921
 
3129
2922
/********************************************************************//**
3130
2923
Set the autoinc column max value. This should only be called once from
3131
 
ha_innobase::open(). Therefore there's no need for a covering lock. */
 
2924
ha_innobase::open(). Therefore there's no need for a covering lock.
 
2925
@return DB_SUCCESS or error code */
3132
2926
UNIV_INTERN
3133
 
void
 
2927
ulint
3134
2928
ha_innobase::innobase_initialize_autoinc()
3135
2929
/*======================================*/
3136
2930
{
 
2931
  dict_index_t* index;
3137
2932
  uint64_t  auto_inc;
3138
 
  const Field*  field = getTable()->found_next_number_field;
3139
 
 
3140
 
  if (field != NULL) {
3141
 
    auto_inc = innobase_get_int_col_max_value(field);
3142
 
  } else {
3143
 
    /* We have no idea what's been passed in to us as the
3144
 
       autoinc column. We set it to the 0, effectively disabling
3145
 
       updates to the table. */
3146
 
    auto_inc = 0;
3147
 
 
 
2933
  const char* col_name;
 
2934
  ulint   error;
 
2935
 
 
2936
  col_name = table->found_next_number_field->field_name;
 
2937
  index = innobase_get_index(table->getShare()->next_number_index);
 
2938
 
 
2939
  /* Execute SELECT MAX(col_name) FROM TABLE; */
 
2940
  error = row_search_max_autoinc(index, col_name, &auto_inc);
 
2941
 
 
2942
  switch (error) {
 
2943
  case DB_SUCCESS:
 
2944
 
 
2945
    /* At the this stage we don't know the increment
 
2946
    or the offset, so use default inrement of 1. */
 
2947
    ++auto_inc;
 
2948
    break;
 
2949
 
 
2950
  case DB_RECORD_NOT_FOUND:
3148
2951
    ut_print_timestamp(stderr);
3149
 
    errmsg_printf(error::ERROR, "InnoDB: Unable to determine the AUTOINC column name");
3150
 
  }
3151
 
 
3152
 
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
3153
 
    /* If the recovery level is set so high that writes
3154
 
       are disabled we force the AUTOINC counter to 0
3155
 
       value effectively disabling writes to the table.
3156
 
       Secondly, we avoid reading the table in case the read
3157
 
       results in failure due to a corrupted table/index.
3158
 
 
3159
 
       We will not return an error to the client, so that the
3160
 
       tables can be dumped with minimal hassle.  If an error
3161
 
       were returned in this case, the first attempt to read
3162
 
       the table would fail and subsequent SELECTs would succeed. */
3163
 
    auto_inc = 0;
3164
 
  } else if (field == NULL) {
3165
 
    /* This is a far more serious error, best to avoid
3166
 
       opening the table and return failure. */
3167
 
    my_error(ER_AUTOINC_READ_FAILED, MYF(0));
3168
 
  } else {
3169
 
    dict_index_t*       index;
3170
 
    const char* col_name;
3171
 
    uint64_t    read_auto_inc;
3172
 
    ulint               err;
3173
 
 
3174
 
    update_session(getTable()->in_use);
3175
 
    col_name = field->field_name;
3176
 
 
3177
 
    ut_a(prebuilt->trx == session_to_trx(user_session));
3178
 
 
3179
 
    index = innobase_get_index(getTable()->getShare()->next_number_index);
3180
 
 
3181
 
    /* Execute SELECT MAX(col_name) FROM TABLE; */
3182
 
    err = row_search_max_autoinc(index, col_name, &read_auto_inc);
3183
 
 
3184
 
    switch (err) {
3185
 
    case DB_SUCCESS: {
3186
 
      uint64_t col_max_value;
3187
 
 
3188
 
      col_max_value = innobase_get_int_col_max_value(field);
3189
 
 
3190
 
      /* At the this stage we do not know the increment
3191
 
         nor the offset, so use a default increment of 1. */
3192
 
 
3193
 
      auto_inc = innobase_next_autoinc(read_auto_inc, 1, 1, col_max_value);
3194
 
 
3195
 
      break;
3196
 
    }
3197
 
    case DB_RECORD_NOT_FOUND:
3198
 
      ut_print_timestamp(stderr);
3199
 
      errmsg_printf(error::ERROR, "InnoDB: MySQL and InnoDB data dictionaries are out of sync.\n"
3200
 
                    "InnoDB: Unable to find the AUTOINC column %s in the InnoDB table %s.\n"
3201
 
                    "InnoDB: We set the next AUTOINC column value to 0,\n"
3202
 
                    "InnoDB: in effect disabling the AUTOINC next value generation.\n"
3203
 
                    "InnoDB: You can either set the next AUTOINC value explicitly using ALTER TABLE\n"
3204
 
                    "InnoDB: or fix the data dictionary by recreating the table.\n",
3205
 
                    col_name, index->table->name);
3206
 
 
3207
 
      /* This will disable the AUTOINC generation. */
3208
 
      auto_inc = 0;
3209
 
 
3210
 
      /* We want the open to succeed, so that the user can
3211
 
         take corrective action. ie. reads should succeed but
3212
 
         updates should fail. */
3213
 
      err = DB_SUCCESS;
3214
 
      break;
3215
 
    default:
3216
 
      /* row_search_max_autoinc() should only return
3217
 
         one of DB_SUCCESS or DB_RECORD_NOT_FOUND. */
3218
 
      ut_error;
3219
 
    }
 
2952
    fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
 
2953
      "dictionaries are out of sync.\n"
 
2954
      "InnoDB: Unable to find the AUTOINC column %s in the "
 
2955
      "InnoDB table %s.\n"
 
2956
      "InnoDB: We set the next AUTOINC column value to the "
 
2957
      "maximum possible value,\n"
 
2958
      "InnoDB: in effect disabling the AUTOINC next value "
 
2959
      "generation.\n"
 
2960
      "InnoDB: You can either set the next AUTOINC value "
 
2961
      "explicitly using ALTER TABLE\n"
 
2962
      "InnoDB: or fix the data dictionary by recreating "
 
2963
      "the table.\n",
 
2964
      col_name, index->table->name);
 
2965
 
 
2966
    auto_inc = 0xFFFFFFFFFFFFFFFFULL;
 
2967
    break;
 
2968
 
 
2969
  default:
 
2970
    return(error);
3220
2971
  }
3221
2972
 
3222
2973
  dict_table_autoinc_initialize(prebuilt->table, auto_inc);
 
2974
 
 
2975
  return(DB_SUCCESS);
3223
2976
}
3224
2977
 
3225
2978
/*****************************************************************//**
3228
2981
@return 1 if error, 0 if success */
3229
2982
UNIV_INTERN
3230
2983
int
3231
 
ha_innobase::doOpen(const identifier::Table &identifier,
 
2984
ha_innobase::doOpen(const TableIdentifier &identifier,
3232
2985
                    int   mode,   /*!< in: not used */
3233
2986
                    uint    test_if_locked) /*!< in: not used */
3234
2987
{
3235
2988
  dict_table_t* ib_table;
 
2989
  char    norm_name[FN_REFLEN];
3236
2990
  Session*    session;
3237
2991
 
3238
2992
  UT_NOT_USED(mode);
3239
2993
  UT_NOT_USED(test_if_locked);
3240
2994
 
3241
 
  session= getTable()->in_use;
 
2995
  session= table->in_use;
3242
2996
 
3243
2997
  /* Under some cases Drizzle seems to call this function while
3244
2998
  holding btr_search_latch. This breaks the latching order as
3247
3001
    getTransactionalEngine()->releaseTemporaryLatches(session);
3248
3002
  }
3249
3003
 
 
3004
  normalize_table_name(norm_name, identifier.getPath().c_str());
 
3005
 
3250
3006
  user_session = NULL;
3251
3007
 
3252
 
  std::string search_string(identifier.getSchemaName());
3253
 
  boost::algorithm::to_lower(search_string);
 
3008
  if (!(share=get_share(identifier.getPath().c_str()))) {
3254
3009
 
3255
 
  if (search_string.compare("data_dictionary") == 0)
3256
 
  {
3257
 
    std::string table_name(identifier.getTableName());
3258
 
    boost::algorithm::to_upper(table_name);
3259
 
    if (!(share=get_share(table_name.c_str())))
3260
 
    {
3261
 
      return 1;
3262
 
    }
3263
 
  }
3264
 
  else
3265
 
  {
3266
 
    if (!(share=get_share(identifier.getKeyPath().c_str())))
3267
 
    {
3268
 
      return(1);
3269
 
    }
 
3010
    return(1);
3270
3011
  }
3271
3012
 
3272
3013
  /* Create buffers for packing the fields of a record. Why
3275
3016
  stored the string length as the first byte. */
3276
3017
 
3277
3018
  upd_and_key_val_buff_len =
3278
 
        getTable()->getShare()->sizeStoredRecord()
3279
 
        + getTable()->getShare()->max_key_length
 
3019
        table->getShare()->stored_rec_length
 
3020
        + table->getShare()->max_key_length
3280
3021
        + MAX_REF_PARTS * 3;
3281
3022
 
3282
3023
  upd_buff.resize(upd_and_key_val_buff_len);
3293
3034
  }
3294
3035
 
3295
3036
  /* Get pointer to a table object in InnoDB dictionary cache */
3296
 
  if (search_string.compare("data_dictionary") == 0)
3297
 
  {
3298
 
    std::string table_name(identifier.getTableName());
3299
 
    boost::algorithm::to_upper(table_name);
3300
 
    ib_table = dict_table_get(table_name.c_str(), TRUE);
3301
 
  }
3302
 
  else
3303
 
  {
3304
 
    ib_table = dict_table_get(identifier.getKeyPath().c_str(), TRUE);
3305
 
  }
 
3037
  ib_table = dict_table_get(norm_name, TRUE);
3306
3038
  
3307
3039
  if (NULL == ib_table) {
3308
 
    errmsg_printf(error::ERROR, "Cannot find or open table %s from\n"
 
3040
    errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find or open table %s from\n"
3309
3041
        "the internal data dictionary of InnoDB "
3310
3042
        "though the .frm file for the\n"
3311
3043
        "table exists. Maybe you have deleted and "
3319
3051
        "doesn't support.\n"
3320
3052
        "See " REFMAN "innodb-troubleshooting.html\n"
3321
3053
        "how you can resolve the problem.\n",
3322
 
        identifier.getKeyPath().c_str());
 
3054
        norm_name);
3323
3055
    free_share(share);
3324
3056
    upd_buff.resize(0);
3325
3057
    key_val_buff.resize(0);
3328
3060
    return(HA_ERR_NO_SUCH_TABLE);
3329
3061
  }
3330
3062
 
3331
 
  if (ib_table->ibd_file_missing && ! session->doing_tablespace_operation()) {
3332
 
    errmsg_printf(error::ERROR, "MySQL is trying to open a table handle but "
 
3063
  if (ib_table->ibd_file_missing && !session_tablespace_op(session)) {
 
3064
    errmsg_printf(ERRMSG_LVL_ERROR, "MySQL is trying to open a table handle but "
3333
3065
        "the .ibd file for\ntable %s does not exist.\n"
3334
3066
        "Have you deleted the .ibd file from the "
3335
3067
        "database directory under\nthe MySQL datadir, "
3336
3068
        "or have you used DISCARD TABLESPACE?\n"
3337
3069
        "See " REFMAN "innodb-troubleshooting.html\n"
3338
3070
        "how you can resolve the problem.\n",
3339
 
        identifier.getKeyPath().c_str());
 
3071
        norm_name);
3340
3072
    free_share(share);
3341
3073
    upd_buff.resize(0);
3342
3074
    key_val_buff.resize(0);
3348
3080
 
3349
3081
  prebuilt = row_create_prebuilt(ib_table);
3350
3082
 
3351
 
  prebuilt->mysql_row_len = getTable()->getShare()->sizeStoredRecord();
3352
 
  prebuilt->default_rec = getTable()->getDefaultValues();
 
3083
  prebuilt->mysql_row_len = table->getShare()->stored_rec_length;
 
3084
  prebuilt->default_rec = table->getDefaultValues();
3353
3085
  ut_ad(prebuilt->default_rec);
3354
3086
 
3355
3087
  /* Looks like MySQL-3.23 sometimes has primary key number != 0 */
3356
3088
 
3357
 
  primary_key = getTable()->getShare()->getPrimaryKey();
 
3089
  primary_key = table->getShare()->getPrimaryKey();
3358
3090
  key_used_on_scan = primary_key;
3359
3091
 
3360
 
  if (!innobase_build_index_translation(getTable(), ib_table, share)) {
3361
 
    errmsg_printf(error::ERROR, "Build InnoDB index translation table for"
3362
 
                    " Table %s failed", identifier.getKeyPath().c_str());
3363
 
  }
3364
 
 
3365
3092
  /* Allocate a buffer for a 'row reference'. A row reference is
3366
3093
  a string of bytes of length ref_length which uniquely specifies
3367
3094
  a row in our table. Note that MySQL may also compare two row
3369
3096
  of length ref_length! */
3370
3097
 
3371
3098
  if (!row_table_got_default_clust_index(ib_table)) {
 
3099
    if (primary_key >= MAX_KEY) {
 
3100
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has a primary key in InnoDB data "
 
3101
          "dictionary, but not in MySQL!", identifier.getTableName().c_str());
 
3102
    }
3372
3103
 
3373
3104
    prebuilt->clust_index_was_generated = FALSE;
3374
3105
 
3375
 
    if (UNIV_UNLIKELY(primary_key >= MAX_KEY)) {
3376
 
      errmsg_printf(error::ERROR, "Table %s has a primary key in "
3377
 
                    "InnoDB data dictionary, but not "
3378
 
                    "in MySQL!", identifier.getTableName().c_str());
3379
 
 
3380
 
      /* This mismatch could cause further problems
3381
 
         if not attended, bring this to the user's attention
3382
 
         by printing a warning in addition to log a message
3383
 
         in the errorlog */
3384
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3385
 
                          ER_NO_SUCH_INDEX,
3386
 
                          "InnoDB: Table %s has a "
3387
 
                          "primary key in InnoDB data "
3388
 
                          "dictionary, but not in "
3389
 
                          "MySQL!", identifier.getTableName().c_str());
3390
 
 
3391
 
      /* If primary_key >= MAX_KEY, its (primary_key)
3392
 
         value could be out of bound if continue to index
3393
 
         into key_info[] array. Find InnoDB primary index,
3394
 
         and assign its key_length to ref_length.
3395
 
         In addition, since MySQL indexes are sorted starting
3396
 
         with primary index, unique index etc., initialize
3397
 
         ref_length to the first index key length in
3398
 
         case we fail to find InnoDB cluster index.
3399
 
 
3400
 
         Please note, this will not resolve the primary
3401
 
         index mismatch problem, other side effects are
3402
 
         possible if users continue to use the table.
3403
 
         However, we allow this table to be opened so
3404
 
         that user can adopt necessary measures for the
3405
 
         mismatch while still being accessible to the table
3406
 
         date. */
3407
 
      ref_length = getTable()->key_info[0].key_length;
3408
 
 
3409
 
      /* Find correspoinding cluster index
3410
 
         key length in MySQL's key_info[] array */
3411
 
      for (ulint i = 0; i < getTable()->getShare()->keys; i++) {
3412
 
        dict_index_t*   index;
3413
 
        index = innobase_get_index(i);
3414
 
        if (dict_index_is_clust(index)) {
3415
 
          ref_length =
3416
 
            getTable()->key_info[i].key_length;
3417
 
        }
3418
 
      }
3419
 
    } else {
3420
 
      /* MySQL allocates the buffer for ref.
3421
 
         key_info->key_length includes space for all key
3422
 
         columns + one byte for each column that may be
3423
 
         NULL. ref_length must be as exact as possible to
3424
 
         save space, because all row reference buffers are
3425
 
         allocated based on ref_length. */
3426
 
 
3427
 
      ref_length = getTable()->key_info[primary_key].key_length;
3428
 
    }
 
3106
    /* MySQL allocates the buffer for ref. key_info->key_length
 
3107
    includes space for all key columns + one byte for each column
 
3108
    that may be NULL. ref_length must be as exact as possible to
 
3109
    save space, because all row reference buffers are allocated
 
3110
    based on ref_length. */
 
3111
 
 
3112
    ref_length = table->key_info[primary_key].key_length;
3429
3113
  } else {
3430
3114
    if (primary_key != MAX_KEY) {
3431
 
      errmsg_printf(error::ERROR,
3432
 
                    "Table %s has no primary key in InnoDB data "
3433
 
                    "dictionary, but has one in MySQL! If you "
3434
 
                    "created the table with a MySQL version < "
3435
 
                    "3.23.54 and did not define a primary key, "
3436
 
                    "but defined a unique key with all non-NULL "
3437
 
                    "columns, then MySQL internally treats that "
3438
 
                    "key as the primary key. You can fix this "
3439
 
                    "error by dump + DROP + CREATE + reimport "
3440
 
                    "of the table.", identifier.getTableName().c_str());
3441
 
 
3442
 
      /* This mismatch could cause further problems
3443
 
         if not attended, bring this to the user attention
3444
 
         by printing a warning in addition to log a message
3445
 
         in the errorlog */
3446
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3447
 
                          ER_NO_SUCH_INDEX,
3448
 
                          "InnoDB: Table %s has no "
3449
 
                          "primary key in InnoDB data "
3450
 
                          "dictionary, but has one in "
3451
 
                          "MySQL!", identifier.getTableName().c_str());
 
3115
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has no primary key in InnoDB data "
 
3116
          "dictionary, but has one in MySQL! If you "
 
3117
          "created the table with a MySQL version < "
 
3118
          "3.23.54 and did not define a primary key, "
 
3119
          "but defined a unique key with all non-NULL "
 
3120
          "columns, then MySQL internally treats that "
 
3121
          "key as the primary key. You can fix this "
 
3122
          "error by dump + DROP + CREATE + reimport "
 
3123
          "of the table.", identifier.getTableName().c_str());
3452
3124
    }
3453
3125
 
3454
3126
    prebuilt->clust_index_was_generated = TRUE;
3464
3136
    and it will never be updated anyway. */
3465
3137
 
3466
3138
    if (key_used_on_scan != MAX_KEY) {
3467
 
      errmsg_printf(error::WARN, 
 
3139
      errmsg_printf(ERRMSG_LVL_WARN, 
3468
3140
        "Table %s key_used_on_scan is %lu even "
3469
3141
        "though there is no primary key inside "
3470
3142
        "InnoDB.", identifier.getTableName().c_str(), (ulong) key_used_on_scan);
3481
3153
    /* We update the highest file format in the system table
3482
3154
    space, if this table has higher file format setting. */
3483
3155
 
3484
 
    char changed_file_format_max[100];
3485
 
    strcpy(changed_file_format_max, innobase_file_format_max.c_str());
3486
 
    trx_sys_file_format_max_upgrade((const char **)&changed_file_format_max,
 
3156
    trx_sys_file_format_max_upgrade(
 
3157
      (const char**) &innobase_file_format_check,
3487
3158
      dict_table_get_format(prebuilt->table));
3488
 
    innobase_file_format_max= changed_file_format_max;
3489
3159
  }
3490
3160
 
 
3161
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
 
3162
 
3491
3163
  /* Only if the table has an AUTOINC column. */
3492
 
  if (prebuilt->table != NULL && getTable()->found_next_number_field != NULL) {
 
3164
  if (prebuilt->table != NULL && table->found_next_number_field != NULL) {
 
3165
    ulint error;
3493
3166
 
3494
3167
    dict_table_autoinc_lock(prebuilt->table);
3495
3168
 
3499
3172
    autoinc value from a previous Drizzle open. */
3500
3173
    if (dict_table_autoinc_read(prebuilt->table) == 0) {
3501
3174
 
3502
 
      innobase_initialize_autoinc();
 
3175
      error = innobase_initialize_autoinc();
 
3176
      ut_a(error == DB_SUCCESS);
3503
3177
    }
3504
3178
 
3505
3179
    dict_table_autoinc_unlock(prebuilt->table);
3506
3180
  }
3507
3181
 
3508
 
  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
3509
 
 
3510
3182
  return(0);
3511
3183
}
3512
3184
 
3527
3199
{
3528
3200
  Session*  session;
3529
3201
 
3530
 
  session= getTable()->in_use;
 
3202
  session= table->in_use;
3531
3203
  if (session != NULL) {
3532
3204
    getTransactionalEngine()->releaseTemporaryLatches(session);
3533
3205
  }
3616
3288
of this function is in rem0cmp.c in InnoDB source code! If you change this
3617
3289
function, remember to update the prototype there!
3618
3290
@return 1, 0, -1, if a is greater, equal, less than b, respectively */
3619
 
UNIV_INTERN int
 
3291
extern "C" UNIV_INTERN
 
3292
int
3620
3293
innobase_mysql_cmp(
3621
3294
/*===============*/
3622
3295
  int   mysql_type, /*!< in: MySQL type */
3663
3336
      charset = get_charset(charset_number);
3664
3337
 
3665
3338
      if (charset == NULL) {
3666
 
        errmsg_printf(error::ERROR, "InnoDB needs charset %lu for doing "
 
3339
        errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB needs charset %lu for doing "
3667
3340
                      "a comparison, but MySQL cannot "
3668
3341
                      "find that charset.",
3669
3342
                      (ulong) charset_number);
3698
3371
the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1
3699
3372
VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'.
3700
3373
@return DATA_BINARY, DATA_VARCHAR, ... */
3701
 
UNIV_INTERN
 
3374
extern "C" UNIV_INTERN
3702
3375
ulint
3703
3376
get_innobase_type_from_mysql_type(
3704
3377
/*==============================*/
3747
3420
      return(DATA_VARMYSQL);
3748
3421
    }
3749
3422
  case DRIZZLE_TYPE_DECIMAL:
3750
 
  case DRIZZLE_TYPE_MICROTIME:
3751
3423
    return(DATA_FIXBINARY);
3752
3424
  case DRIZZLE_TYPE_LONG:
3753
3425
  case DRIZZLE_TYPE_LONGLONG:
3754
3426
  case DRIZZLE_TYPE_DATETIME:
3755
 
  case DRIZZLE_TYPE_TIME:
3756
3427
  case DRIZZLE_TYPE_DATE:
3757
3428
  case DRIZZLE_TYPE_TIMESTAMP:
3758
 
  case DRIZZLE_TYPE_ENUM:
3759
3429
    return(DATA_INT);
3760
3430
  case DRIZZLE_TYPE_DOUBLE:
3761
3431
    return(DATA_DOUBLE);
3762
3432
  case DRIZZLE_TYPE_BLOB:
3763
 
    return(DATA_BLOB);
3764
 
  case DRIZZLE_TYPE_BOOLEAN:
3765
 
  case DRIZZLE_TYPE_UUID:
3766
 
    return(DATA_FIXBINARY);
3767
 
  case DRIZZLE_TYPE_NULL:
 
3433
                return(DATA_BLOB);
 
3434
  default:
3768
3435
    ut_error;
3769
3436
  }
3770
3437
 
3813
3480
  uint    buff_len,/*!< in: buffer length */
3814
3481
  const unsigned char*  record)/*!< in: row in MySQL format */
3815
3482
{
3816
 
  KeyInfo*    key_info  = &getTable()->key_info[keynr];
 
3483
  KeyInfo*    key_info  = &table->key_info[keynr];
3817
3484
  KeyPartInfo*  key_part  = key_info->key_part;
3818
3485
  KeyPartInfo*  end   = key_part + key_info->key_parts;
3819
3486
  char*   buff_start  = buff;
3885
3552
      cs = field->charset();
3886
3553
 
3887
3554
      lenlen = (ulint)
3888
 
        (((Field_varstring*)field)->pack_length_no_ptr());
 
3555
        (((Field_varstring*)field)->length_bytes);
3889
3556
 
3890
3557
      data = row_mysql_read_true_varchar(&len,
3891
3558
        (byte*) (record
3892
 
        + (ulint)get_field_offset(getTable(), field)),
 
3559
        + (ulint)get_field_offset(table, field)),
3893
3560
        lenlen);
3894
3561
 
3895
3562
      true_len = len;
3952
3619
 
3953
3620
      blob_data = row_mysql_read_blob_ref(&blob_len,
3954
3621
        (byte*) (record
3955
 
        + (ulint)get_field_offset(getTable(), field)),
 
3622
        + (ulint)get_field_offset(table, field)),
3956
3623
          (ulint) field->pack_length());
3957
3624
 
3958
3625
      true_len = blob_len;
3959
3626
 
3960
 
      ut_a(get_field_offset(getTable(), field)
 
3627
      ut_a(get_field_offset(table, field)
3961
3628
        == key_part->offset);
3962
3629
 
3963
3630
      /* For multi byte character sets we need to calculate
4004
3671
      ulint     key_len;
4005
3672
      const unsigned char*    src_start;
4006
3673
      enum_field_types  real_type;
4007
 
      const CHARSET_INFO* cs= field->charset();
4008
3674
 
4009
3675
      key_len = key_part->length;
4010
3676
 
4026
3692
      memcpy(buff, src_start, true_len);
4027
3693
      buff += true_len;
4028
3694
 
4029
 
      /* Pad the unused space with spaces. */
 
3695
      /* Pad the unused space with spaces. Note that no
 
3696
      padding is ever needed for UCS-2 because in MySQL,
 
3697
      all UCS2 characters are 2 bytes, as MySQL does not
 
3698
      support surrogate pairs, which are needed to represent
 
3699
      characters in the range U+10000 to U+10FFFF. */
4030
3700
 
4031
3701
      if (true_len < key_len) {
4032
 
        ulint   pad_len = key_len - true_len;
4033
 
        ut_a(!(pad_len % cs->mbminlen));
4034
 
 
4035
 
        cs->cset->fill(cs, buff, pad_len,
4036
 
                       0x20 /* space */);
 
3702
        ulint pad_len = key_len - true_len;
 
3703
        memset(buff, ' ', pad_len);
4037
3704
        buff += pad_len;
4038
3705
      }
4039
3706
    }
4141
3808
 
4142
3809
  /* Note that in InnoDB, i is the column number. MySQL calls columns
4143
3810
  'fields'. */
4144
 
  for (i = 0; i < n_fields; i++)
 
3811
  for (i = 0; i < n_fields; i++) 
4145
3812
  {
4146
 
    const dict_col_t *col= &index->table->cols[i];
4147
3813
    templ = prebuilt->mysql_template + n_requested_fields;
4148
3814
    field = table->getField(i);
4149
3815
 
4189
3855
    n_requested_fields++;
4190
3856
 
4191
3857
    templ->col_no = i;
4192
 
    templ->clust_rec_field_no = dict_col_get_clust_pos(col, clust_index);
4193
 
    ut_ad(templ->clust_rec_field_no != ULINT_UNDEFINED);
4194
3858
 
4195
3859
    if (index == clust_index) {
4196
 
      templ->rec_field_no = templ->clust_rec_field_no;
 
3860
      templ->rec_field_no = dict_col_get_clust_pos(
 
3861
        &index->table->cols[i], index);
4197
3862
    } else {
4198
3863
      templ->rec_field_no = dict_index_get_nth_col_pos(
4199
3864
                index, i);
4200
 
      if (templ->rec_field_no == ULINT_UNDEFINED) {
4201
 
        prebuilt->need_to_access_clustered = TRUE;
4202
 
      }
 
3865
    }
 
3866
 
 
3867
    if (templ->rec_field_no == ULINT_UNDEFINED) {
 
3868
      prebuilt->need_to_access_clustered = TRUE;
4203
3869
    }
4204
3870
 
4205
3871
    if (field->null_ptr) {
4221
3887
      mysql_prefix_len = templ->mysql_col_offset
4222
3888
        + templ->mysql_col_len;
4223
3889
    }
4224
 
    templ->type = col->mtype;
 
3890
    templ->type = index->table->cols[i].mtype;
4225
3891
    templ->mysql_type = (ulint)field->type();
4226
3892
 
4227
3893
    if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
4228
3894
      templ->mysql_length_bytes = (ulint)
4229
 
        (((Field_varstring*)field)->pack_length_no_ptr());
 
3895
        (((Field_varstring*)field)->length_bytes);
4230
3896
    }
4231
3897
 
4232
 
    templ->charset = dtype_get_charset_coll(col->prtype);
4233
 
    templ->mbminlen = dict_col_get_mbminlen(col);
4234
 
    templ->mbmaxlen = dict_col_get_mbmaxlen(col);
4235
 
    templ->is_unsigned = col->prtype & DATA_UNSIGNED;
 
3898
    templ->charset = dtype_get_charset_coll(
 
3899
      index->table->cols[i].prtype);
 
3900
    templ->mbminlen = index->table->cols[i].mbminlen;
 
3901
    templ->mbmaxlen = index->table->cols[i].mbmaxlen;
 
3902
    templ->is_unsigned = index->table->cols[i].prtype
 
3903
              & DATA_UNSIGNED;
4236
3904
    if (templ->type == DATA_BLOB) {
4237
3905
      prebuilt->templ_contains_blob = TRUE;
4238
3906
    }
4249
3917
    for (i = 0; i < n_requested_fields; i++) {
4250
3918
      templ = prebuilt->mysql_template + i;
4251
3919
 
4252
 
      templ->rec_field_no = templ->clust_rec_field_no;
 
3920
      templ->rec_field_no = dict_col_get_clust_pos(
 
3921
        &index->table->cols[templ->col_no],
 
3922
        clust_index);
4253
3923
    }
4254
3924
  }
4255
3925
}
4256
3926
 
4257
3927
/********************************************************************//**
 
3928
Get the upper limit of the MySQL integral and floating-point type. */
 
3929
UNIV_INTERN
 
3930
uint64_t
 
3931
ha_innobase::innobase_get_int_col_max_value(
 
3932
/*========================================*/
 
3933
  const Field*  field)
 
3934
{
 
3935
  uint64_t  max_value = 0;
 
3936
 
 
3937
  switch(field->key_type()) {
 
3938
  /* TINY */
 
3939
  case HA_KEYTYPE_BINARY:
 
3940
    max_value = 0xFFULL;
 
3941
    break;
 
3942
  /* MEDIUM */
 
3943
  case HA_KEYTYPE_UINT24:
 
3944
    max_value = 0xFFFFFFULL;
 
3945
    break;
 
3946
  /* LONG */
 
3947
  case HA_KEYTYPE_ULONG_INT:
 
3948
    max_value = 0xFFFFFFFFULL;
 
3949
    break;
 
3950
  case HA_KEYTYPE_LONG_INT:
 
3951
    max_value = 0x7FFFFFFFULL;
 
3952
    break;
 
3953
  /* BIG */
 
3954
  case HA_KEYTYPE_ULONGLONG:
 
3955
    max_value = 0xFFFFFFFFFFFFFFFFULL;
 
3956
    break;
 
3957
  case HA_KEYTYPE_LONGLONG:
 
3958
    max_value = 0x7FFFFFFFFFFFFFFFULL;
 
3959
    break;
 
3960
  case HA_KEYTYPE_DOUBLE:
 
3961
    /* We use the maximum as per IEEE754-2008 standard, 2^53 */
 
3962
    max_value = 0x20000000000000ULL;
 
3963
    break;
 
3964
  default:
 
3965
    ut_error;
 
3966
  }
 
3967
 
 
3968
  return(max_value);
 
3969
}
 
3970
 
 
3971
/********************************************************************//**
4258
3972
This special handling is really to overcome the limitations of MySQL's
4259
3973
binlogging. We need to eliminate the non-determinism that will arise in
4260
3974
INSERT ... SELECT type of statements, since MySQL binlog only stores the
4323
4037
  trx_t*    trx = session_to_trx(user_session);
4324
4038
 
4325
4039
  if (prebuilt->trx != trx) {
4326
 
    errmsg_printf(error::ERROR, "The transaction object for the table handle is at "
 
4040
    errmsg_printf(ERRMSG_LVL_ERROR, "The transaction object for the table handle is at "
4327
4041
        "%p, but for the current thread it is at %p",
4328
4042
        (const void*) prebuilt->trx, (const void*) trx);
4329
4043
 
4337
4051
    ut_error;
4338
4052
  }
4339
4053
 
4340
 
  sql_command = user_session->getSqlCommand();
 
4054
  sql_command = session_sql_command(user_session);
4341
4055
 
4342
4056
  if ((sql_command == SQLCOM_ALTER_TABLE
4343
4057
       || sql_command == SQLCOM_CREATE_INDEX
4405
4119
  num_write_row++;
4406
4120
 
4407
4121
  /* This is the case where the table has an auto-increment column */
4408
 
  if (getTable()->next_number_field && record == getTable()->getInsertRecord()) {
 
4122
  if (table->next_number_field && record == table->getInsertRecord()) {
4409
4123
 
4410
4124
    /* Reset the error code before calling
4411
4125
    innobase_get_auto_increment(). */
4412
4126
    prebuilt->autoinc_error = DB_SUCCESS;
4413
4127
 
4414
4128
    if ((error = update_auto_increment())) {
 
4129
 
4415
4130
      /* We don't want to mask autoinc overflow errors. */
4416
 
 
4417
 
      /* Handle the case where the AUTOINC sub-system
4418
 
         failed during initialization. */
4419
 
      if (prebuilt->autoinc_error == DB_UNSUPPORTED) {
4420
 
        error_result = ER_AUTOINC_READ_FAILED;
4421
 
        /* Set the error message to report too. */
4422
 
        my_error(ER_AUTOINC_READ_FAILED, MYF(0));
4423
 
        goto func_exit;
4424
 
      } else if (prebuilt->autoinc_error != DB_SUCCESS) {
 
4131
      if (prebuilt->autoinc_error != DB_SUCCESS) {
4425
4132
        error = (int) prebuilt->autoinc_error;
4426
4133
 
4427
4134
        goto report_error;
4441
4148
    /* Build the template used in converting quickly between
4442
4149
    the two database formats */
4443
4150
 
4444
 
    build_template(prebuilt, NULL, getTable(), ROW_MYSQL_WHOLE_ROW);
 
4151
    build_template(prebuilt, NULL, table,
 
4152
             ROW_MYSQL_WHOLE_ROW);
4445
4153
  }
4446
4154
 
4447
4155
  innodb_srv_conc_enter_innodb(prebuilt->trx);
4448
4156
 
4449
4157
  error = row_insert_for_mysql((byte*) record, prebuilt);
4450
4158
 
4451
 
  user_session->setXaId(trx->id);
4452
 
 
4453
4159
  /* Handle duplicate key errors */
4454
4160
  if (auto_inc_used) {
4455
4161
    ulint   err;
4467
4173
    /* We need the upper limit of the col type to check for
4468
4174
    whether we update the table autoinc counter or not. */
4469
4175
    col_max_value = innobase_get_int_col_max_value(
4470
 
      getTable()->next_number_field); 
 
4176
      table->next_number_field);
 
4177
 
4471
4178
    /* Get the value that MySQL attempted to store in the table.*/
4472
 
    auto_inc = getTable()->next_number_field->val_int();
 
4179
    auto_inc = table->next_number_field->val_int();
4473
4180
 
4474
4181
    switch (error) {
4475
4182
    case DB_DUPLICATE_KEY:
4505
4212
      update the table upper limit. Note: last_value
4506
4213
      will be 0 if get_auto_increment() was not called.*/
4507
4214
 
4508
 
      if (auto_inc >= prebuilt->autoinc_last_value) {
 
4215
      if (auto_inc <= col_max_value
 
4216
          && auto_inc >= prebuilt->autoinc_last_value) {
4509
4217
set_max_autoinc:
4510
 
        /* This should filter out the negative
4511
 
           values set explicitly by the user. */
4512
 
        if (auto_inc <= col_max_value) {
4513
 
          ut_a(prebuilt->autoinc_increment > 0);
4514
 
 
4515
 
          uint64_t      need;
4516
 
          uint64_t      offset;
4517
 
 
4518
 
          offset = prebuilt->autoinc_offset;
4519
 
          need = prebuilt->autoinc_increment;
4520
 
 
4521
 
          auto_inc = innobase_next_autoinc(
4522
 
                                           auto_inc,
4523
 
                                           need, offset, col_max_value);
4524
 
 
4525
 
          err = innobase_set_max_autoinc(
4526
 
                                         auto_inc);
4527
 
 
4528
 
          if (err != DB_SUCCESS) {
4529
 
            error = err;
4530
 
          }
 
4218
        ut_a(prebuilt->autoinc_increment > 0);
 
4219
 
 
4220
        uint64_t  need;
 
4221
        uint64_t  offset;
 
4222
 
 
4223
        offset = prebuilt->autoinc_offset;
 
4224
        need = prebuilt->autoinc_increment;
 
4225
 
 
4226
        auto_inc = innobase_next_autoinc(
 
4227
          auto_inc, need, offset, col_max_value);
 
4228
 
 
4229
        err = innobase_set_max_autoinc(auto_inc);
 
4230
 
 
4231
        if (err != DB_SUCCESS) {
 
4232
          error = err;
4531
4233
        }
4532
4234
      }
4533
4235
      break;
4628
4330
        o_ptr = row_mysql_read_true_varchar(
4629
4331
          &o_len, o_ptr,
4630
4332
          (ulint)
4631
 
          (((Field_varstring*)field)->pack_length_no_ptr()));
 
4333
          (((Field_varstring*)field)->length_bytes));
4632
4334
 
4633
4335
        n_ptr = row_mysql_read_true_varchar(
4634
4336
          &n_len, n_ptr,
4635
4337
          (ulint)
4636
 
          (((Field_varstring*)field)->pack_length_no_ptr()));
 
4338
          (((Field_varstring*)field)->length_bytes));
4637
4339
      }
4638
4340
 
4639
4341
      break;
4724
4426
  /* Build an update vector from the modified fields in the rows
4725
4427
  (uses upd_buff of the handle) */
4726
4428
 
4727
 
  calc_row_difference(uvect, (unsigned char*) old_row, new_row, getTable(),
 
4429
  calc_row_difference(uvect, (unsigned char*) old_row, new_row, table,
4728
4430
      &upd_buff[0], (ulint)upd_and_key_val_buff_len,
4729
4431
      prebuilt, user_session);
4730
4432
 
4733
4435
 
4734
4436
  ut_a(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
4735
4437
 
4736
 
  if (getTable()->found_next_number_field)
 
4438
  if (table->found_next_number_field)
4737
4439
  {
4738
4440
    uint64_t  auto_inc;
4739
4441
    uint64_t  col_max_value;
4740
4442
 
4741
 
    auto_inc = getTable()->found_next_number_field->val_int();
 
4443
    auto_inc = table->found_next_number_field->val_int();
4742
4444
 
4743
4445
    /* We need the upper limit of the col type to check for
4744
4446
    whether we update the table autoinc counter or not. */
4745
4447
    col_max_value = innobase_get_int_col_max_value(
4746
 
      getTable()->found_next_number_field);
 
4448
      table->found_next_number_field);
4747
4449
 
4748
4450
    uint64_t current_autoinc;
4749
4451
    ulint autoinc_error= innobase_get_autoinc(&current_autoinc);
4771
4473
 
4772
4474
  error = row_update_for_mysql((byte*) old_row, prebuilt);
4773
4475
 
4774
 
  user_session->setXaId(trx->id);
4775
 
 
4776
4476
  /* We need to do some special AUTOINC handling for the following case:
4777
4477
 
4778
4478
  INSERT INTO t (c1,c2) VALUES(x,y) ON DUPLICATE KEY UPDATE ...
4782
4482
  value used in the INSERT statement.*/
4783
4483
 
4784
4484
  if (error == DB_SUCCESS
4785
 
      && getTable()->next_number_field
4786
 
      && new_row == getTable()->getInsertRecord()
4787
 
      && user_session->getSqlCommand() == SQLCOM_INSERT
 
4485
      && table->next_number_field
 
4486
      && new_row == table->getInsertRecord()
 
4487
      && session_sql_command(user_session) == SQLCOM_INSERT
4788
4488
      && (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
4789
4489
    == TRX_DUP_IGNORE)  {
4790
4490
 
4791
4491
    uint64_t  auto_inc;
4792
4492
    uint64_t  col_max_value;
4793
4493
 
4794
 
    auto_inc = getTable()->next_number_field->val_int();
 
4494
    auto_inc = table->next_number_field->val_int();
4795
4495
 
4796
4496
    /* We need the upper limit of the col type to check for
4797
4497
    whether we update the table autoinc counter or not. */
4798
4498
    col_max_value = innobase_get_int_col_max_value(
4799
 
      getTable()->next_number_field);
 
4499
      table->next_number_field);
4800
4500
 
4801
4501
    if (auto_inc <= col_max_value && auto_inc != 0) {
4802
4502
 
4863
4563
 
4864
4564
  error = row_update_for_mysql((byte*) record, prebuilt);
4865
4565
 
4866
 
  user_session->setXaId(trx->id);
4867
 
 
4868
4566
  innodb_srv_conc_exit_innodb(trx);
4869
4567
 
4870
4568
  error = convert_error_code_to_mysql(
4898
4596
  case ROW_READ_WITH_LOCKS:
4899
4597
    if (!srv_locks_unsafe_for_binlog
4900
4598
        && prebuilt->trx->isolation_level
4901
 
        > TRX_ISO_READ_COMMITTED) {
 
4599
        != TRX_ISO_READ_COMMITTED) {
4902
4600
      break;
4903
4601
    }
4904
4602
    /* fall through */
4928
4626
ha_innobase::try_semi_consistent_read(bool yes)
4929
4627
/*===========================================*/
4930
4628
{
4931
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
4629
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
4932
4630
 
4933
4631
  /* Row read type is set to semi consistent read if this was
4934
4632
  requested by the MySQL and either innodb_locks_unsafe_for_binlog
4937
4635
 
4938
4636
  if (yes
4939
4637
      && (srv_locks_unsafe_for_binlog
4940
 
    || prebuilt->trx->isolation_level <= TRX_ISO_READ_COMMITTED)) {
 
4638
    || prebuilt->trx->isolation_level == TRX_ISO_READ_COMMITTED)) {
4941
4639
    prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
4942
4640
  } else {
4943
4641
    prebuilt->row_read_type = ROW_READ_WITH_LOCKS;
5118
4816
 
5119
4817
  index = prebuilt->index;
5120
4818
 
5121
 
  if (UNIV_UNLIKELY(index == NULL)) {
5122
 
    prebuilt->index_usable = FALSE;
5123
 
    return(HA_ERR_CRASHED);
5124
 
  }
5125
 
 
5126
 
  if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
5127
 
    return(HA_ERR_TABLE_DEF_CHANGED);
5128
 
  }
5129
 
 
5130
4819
  /* Note that if the index for which the search template is built is not
5131
4820
  necessarily prebuilt->index, but can also be the clustered index */
5132
4821
 
5133
4822
  if (prebuilt->sql_stat_start) {
5134
 
    build_template(prebuilt, user_session, getTable(),
 
4823
    build_template(prebuilt, user_session, table,
5135
4824
             ROW_MYSQL_REC_FIELDS);
5136
4825
  }
5137
4826
 
5186
4875
  switch (ret) {
5187
4876
  case DB_SUCCESS:
5188
4877
    error = 0;
5189
 
    getTable()->status = 0;
 
4878
    table->status = 0;
5190
4879
    break;
5191
4880
  case DB_RECORD_NOT_FOUND:
5192
4881
    error = HA_ERR_KEY_NOT_FOUND;
5193
 
    getTable()->status = STATUS_NOT_FOUND;
 
4882
    table->status = STATUS_NOT_FOUND;
5194
4883
    break;
5195
4884
  case DB_END_OF_INDEX:
5196
4885
    error = HA_ERR_KEY_NOT_FOUND;
5197
 
    getTable()->status = STATUS_NOT_FOUND;
 
4886
    table->status = STATUS_NOT_FOUND;
5198
4887
    break;
5199
4888
  default:
5200
4889
    error = convert_error_code_to_mysql((int) ret,
5201
4890
                prebuilt->table->flags,
5202
4891
                user_session);
5203
 
    getTable()->status = STATUS_NOT_FOUND;
 
4892
    table->status = STATUS_NOT_FOUND;
5204
4893
    break;
5205
4894
  }
5206
4895
 
5239
4928
 
5240
4929
  ha_statistic_increment(&system_status_var::ha_read_key_count);
5241
4930
 
5242
 
  if (keynr != MAX_KEY && getTable()->getShare()->sizeKeys() > 0) 
 
4931
  ut_ad(user_session == table->in_use);
 
4932
  ut_a(prebuilt->trx == session_to_trx(user_session));
 
4933
 
 
4934
  if (keynr != MAX_KEY && table->getShare()->sizeKeys() > 0) 
5243
4935
  {
5244
 
    KeyInfo *key = getTable()->key_info + keynr;
5245
 
    index = innobase_index_lookup(share, keynr);
5246
 
 
5247
 
    if (index) {
5248
 
      ut_a(ut_strcmp(index->name, key->name) == 0);
5249
 
    } else {
5250
 
      /* Can't find index with keynr in the translation
5251
 
         table. Only print message if the index translation
5252
 
         table exists */
5253
 
      if (share->idx_trans_tbl.index_mapping) {
5254
 
        errmsg_printf(error::ERROR,
5255
 
                      "InnoDB could not find "
5256
 
                      "index %s key no %u for "
5257
 
                      "table %s through its "
5258
 
                      "index translation table",
5259
 
                      key ? key->name : "NULL",
5260
 
                      keynr,
5261
 
                      prebuilt->table->name);
5262
 
      }
5263
 
 
5264
 
      index = dict_table_get_index_on_name(prebuilt->table,
5265
 
                                           key->name);
5266
 
    }
 
4936
    index = dict_table_get_index_on_name(prebuilt->table,
 
4937
                                         table->getShare()->getTableProto()->indexes(keynr).name().c_str());
5267
4938
  } else {
5268
4939
    index = dict_table_get_first_index(prebuilt->table);
5269
4940
  }
5270
4941
 
5271
4942
  if (!index) {
5272
 
    errmsg_printf(error::ERROR, 
 
4943
    errmsg_printf(ERRMSG_LVL_ERROR, 
5273
4944
      "Innodb could not find key n:o %u with name %s "
5274
4945
      "from dict cache for table %s",
5275
 
      keynr, getTable()->getShare()->getTableMessage()->indexes(keynr).name().c_str(),
 
4946
      keynr, table->getShare()->getTableProto()->indexes(keynr).name().c_str(),
5276
4947
      prebuilt->table->name);
5277
4948
  }
5278
4949
 
5298
4969
  prebuilt->index = innobase_get_index(keynr);
5299
4970
 
5300
4971
  if (UNIV_UNLIKELY(!prebuilt->index)) {
5301
 
    errmsg_printf(error::WARN, "InnoDB: change_active_index(%u) failed",
 
4972
    errmsg_printf(ERRMSG_LVL_WARN, "InnoDB: change_active_index(%u) failed",
5302
4973
          keynr);
5303
 
    prebuilt->index_usable = FALSE;
5304
4974
    return(1);
5305
4975
  }
5306
4976
 
5308
4978
                 prebuilt->index);
5309
4979
 
5310
4980
  if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
5311
 
    push_warning_printf(user_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
5312
 
                        HA_ERR_TABLE_DEF_CHANGED,
5313
 
                        "InnoDB: insufficient history for index %u",
5314
 
                        keynr);
 
4981
    errmsg_printf(ERRMSG_LVL_WARN,
 
4982
         "InnoDB: insufficient history for index %u",
 
4983
          keynr);
5315
4984
    /* The caller seems to ignore this.  Thus, we must check
5316
4985
    this again in row_search_for_mysql(). */
5317
4986
    return(2);
5330
4999
  the flag ROW_MYSQL_WHOLE_ROW below, but that caused unnecessary
5331
5000
  copying. Starting from MySQL-4.1 we use a more efficient flag here. */
5332
5001
 
5333
 
  build_template(prebuilt, user_session, getTable(), ROW_MYSQL_REC_FIELDS);
 
5002
  build_template(prebuilt, user_session, table, ROW_MYSQL_REC_FIELDS);
5334
5003
 
5335
5004
  return(0);
5336
5005
}
5390
5059
  switch (ret) {
5391
5060
  case DB_SUCCESS:
5392
5061
    error = 0;
5393
 
    getTable()->status = 0;
 
5062
    table->status = 0;
5394
5063
    break;
5395
5064
  case DB_RECORD_NOT_FOUND:
5396
5065
    error = HA_ERR_END_OF_FILE;
5397
 
    getTable()->status = STATUS_NOT_FOUND;
 
5066
    table->status = STATUS_NOT_FOUND;
5398
5067
    break;
5399
5068
  case DB_END_OF_INDEX:
5400
5069
    error = HA_ERR_END_OF_FILE;
5401
 
    getTable()->status = STATUS_NOT_FOUND;
 
5070
    table->status = STATUS_NOT_FOUND;
5402
5071
    break;
5403
5072
  default:
5404
5073
    error = convert_error_code_to_mysql(
5405
5074
      (int) ret, prebuilt->table->flags, user_session);
5406
 
    getTable()->status = STATUS_NOT_FOUND;
 
5075
    table->status = STATUS_NOT_FOUND;
5407
5076
    break;
5408
5077
  }
5409
5078
 
5598
5267
 
5599
5268
  ha_statistic_increment(&system_status_var::ha_read_rnd_count);
5600
5269
 
5601
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
5270
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
5602
5271
 
5603
5272
  if (prebuilt->clust_index_was_generated) {
5604
5273
    /* No primary key was defined for the table and we
5644
5313
{
5645
5314
  uint    len;
5646
5315
 
5647
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
5316
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
5648
5317
 
5649
5318
  if (prebuilt->clust_index_was_generated) {
5650
5319
    /* No primary key was defined for the table and we
5664
5333
  table. */
5665
5334
 
5666
5335
  if (len != ref_length) {
5667
 
    errmsg_printf(error::ERROR, "Stored ref len is %lu, but table ref len is %lu",
 
5336
    errmsg_printf(ERRMSG_LVL_ERROR, "Stored ref len is %lu, but table ref len is %lu",
5668
5337
        (ulong) len, (ulong) ref_length);
5669
5338
  }
5670
5339
}
5720
5389
 
5721
5390
    col_type = get_innobase_type_from_mysql_type(&unsigned_type,
5722
5391
                  field);
5723
 
 
5724
 
    if (!col_type) {
5725
 
      push_warning_printf(
5726
 
                          trx->mysql_thd,
5727
 
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
5728
 
                          ER_CANT_CREATE_TABLE,
5729
 
                          "Error creating table '%s' with "
5730
 
                          "column '%s'. Please check its "
5731
 
                          "column type and try to re-create "
5732
 
                          "the table with an appropriate "
5733
 
                          "column type.",
5734
 
                          table->name, (char*) field->field_name);
5735
 
      goto err_col;
5736
 
    }
5737
 
 
5738
5392
    if (field->null_ptr) {
5739
5393
      nulls_allowed = 0;
5740
5394
    } else {
5757
5411
        /* in data0type.h we assume that the
5758
5412
        number fits in one byte in prtype */
5759
5413
        push_warning_printf(
5760
 
          trx->mysql_thd,
 
5414
          (Session*) trx->mysql_thd,
5761
5415
          DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5762
5416
          ER_CANT_CREATE_TABLE,
5763
5417
          "In InnoDB, charset-collation codes"
5780
5434
    long_true_varchar = 0;
5781
5435
 
5782
5436
    if (field->type() == DRIZZLE_TYPE_VARCHAR) {
5783
 
      col_len -= ((Field_varstring*)field)->pack_length_no_ptr();
 
5437
      col_len -= ((Field_varstring*)field)->length_bytes;
5784
5438
 
5785
 
      if (((Field_varstring*)field)->pack_length_no_ptr() == 2) {
 
5439
      if (((Field_varstring*)field)->length_bytes == 2) {
5786
5440
        long_true_varchar = DATA_LONG_TRUE_VARCHAR;
5787
5441
      }
5788
5442
    }
5789
5443
 
5790
 
    /* First check whether the column to be added has a
5791
 
       system reserved name. */
5792
 
    if (dict_col_name_is_reserved(field->field_name)){
5793
 
      my_error(ER_WRONG_COLUMN_NAME, MYF(0), field->field_name);
5794
 
 
5795
 
  err_col:
5796
 
      dict_mem_table_free(table);
5797
 
      trx_commit_for_mysql(trx);
5798
 
 
5799
 
      error = DB_ERROR;
5800
 
      goto error_ret;
5801
 
    }
5802
 
 
5803
5444
    dict_mem_table_add_col(table, table->heap,
5804
5445
      (char*) field->field_name,
5805
5446
      col_type,
5813
5454
 
5814
5455
  error = row_create_table_for_mysql(table, trx);
5815
5456
 
5816
 
        if (error == DB_DUPLICATE_KEY) {
5817
 
                char buf[100];
5818
 
                char* buf_end = innobase_convert_identifier(
5819
 
                        buf, sizeof buf - 1, table_name, strlen(table_name),
5820
 
                        trx->mysql_thd, TRUE);
5821
 
 
5822
 
                *buf_end = '\0';
5823
 
                my_error(ER_TABLE_EXISTS_ERROR, MYF(0), buf);
5824
 
        }
5825
 
 
5826
 
error_ret:
5827
5457
  error = convert_error_code_to_mysql(error, flags, NULL);
5828
5458
 
5829
5459
  return(error);
5860
5490
 
5861
5491
  n_fields = key->key_parts;
5862
5492
 
5863
 
  /* Assert that "GEN_CLUST_INDEX" cannot be used as non-primary index */
5864
 
  ut_a(innobase_strcasecmp(key->name, innobase_index_reserve_name) != 0);
5865
 
 
5866
5493
  ind_type = 0;
5867
5494
 
5868
5495
  if (key_num == form->getShare()->getPrimaryKey()) {
5915
5542
        && field->type() != DRIZZLE_TYPE_VARCHAR)
5916
5543
      || (field->type() == DRIZZLE_TYPE_VARCHAR
5917
5544
        && key_part->length < field->pack_length()
5918
 
        - ((Field_varstring*)field)->pack_length_no_ptr())) {
 
5545
        - ((Field_varstring*)field)->length_bytes)) {
5919
5546
 
5920
5547
      prefix_len = key_part->length;
5921
5548
 
5923
5550
        || col_type == DATA_FLOAT
5924
5551
        || col_type == DATA_DOUBLE
5925
5552
        || col_type == DATA_DECIMAL) {
5926
 
        errmsg_printf(error::ERROR, 
 
5553
        errmsg_printf(ERRMSG_LVL_ERROR, 
5927
5554
          "MySQL is trying to create a column "
5928
5555
          "prefix index field, on an "
5929
5556
          "inappropriate data type. Table "
5972
5599
  /* We pass 0 as the space id, and determine at a lower level the space
5973
5600
  id where to store the table */
5974
5601
 
5975
 
  index = dict_mem_index_create(table_name,
5976
 
                                innobase_index_reserve_name,
5977
 
                                0, DICT_CLUSTERED, 0);
 
5602
  index = dict_mem_index_create(table_name, "GEN_CLUST_INDEX",
 
5603
              0, DICT_CLUSTERED, 0);
5978
5604
 
5979
5605
  error = row_create_index_for_mysql(index, trx, NULL);
5980
5606
 
6023
5649
/*================*/
6024
5650
  Session         &session, /*!< in: Session */
6025
5651
  Table&    form,   /*!< in: information on table columns and indexes */
6026
 
        const identifier::Table &identifier,
 
5652
        const TableIdentifier &identifier,
6027
5653
        message::Table& create_proto)
6028
5654
{
6029
5655
  int   error;
6032
5658
  trx_t*    trx;
6033
5659
  int   primary_key_no;
6034
5660
  uint    i;
 
5661
  char    name2[FN_REFLEN];
 
5662
  char    norm_name[FN_REFLEN];
6035
5663
  ib_int64_t  auto_inc_value;
6036
5664
  ulint   iflags;
6037
5665
  /* Cache the value of innodb_file_format, in case it is
6038
5666
    modified by another thread while the table is being created. */
6039
5667
  const ulint file_format = srv_file_format;
6040
5668
  bool lex_identified_temp_table= (create_proto.type() == message::Table::TEMPORARY);
6041
 
  const char* stmt;
6042
 
  size_t stmt_len;
6043
 
 
6044
 
  std::string search_string(identifier.getSchemaName());
6045
 
  boost::algorithm::to_lower(search_string);
6046
 
 
6047
 
  if (search_string.compare("data_dictionary") == 0)
6048
 
  {
6049
 
    return HA_WRONG_CREATE_OPTION;
6050
 
  }
 
5669
 
 
5670
  const char *table_name= identifier.getPath().c_str();
6051
5671
 
6052
5672
  if (form.getShare()->sizeFields() > 1000) {
6053
5673
    /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
6070
5690
 
6071
5691
  srv_lower_case_table_names = TRUE;
6072
5692
 
 
5693
  strcpy(name2, table_name);
 
5694
 
 
5695
  normalize_table_name(norm_name, name2);
 
5696
 
6073
5697
  /* Latch the InnoDB data dictionary exclusively so that no deadlocks
6074
5698
    or lock waits can happen in it during a table create operation.
6075
5699
    Drop table etc. do this latching in row0mysql.c. */
6134
5758
# error "DICT_TF_ZSSIZE_MAX < 1"
6135
5759
#endif
6136
5760
 
6137
 
    if (strict_mode)
 
5761
    if (SessionVAR(&session, strict_mode))
6138
5762
    {
6139
5763
      if (! srv_file_per_table)
6140
5764
      {
6153
5777
                            "InnoDB: ROW_FORMAT=compressed requires innodb_file_format > Antelope.");
6154
5778
      }
6155
5779
    }
 
5780
 
 
5781
    error= create_table_def(trx, &form, norm_name,
 
5782
                            lex_identified_temp_table ? name2 : NULL,
 
5783
                            iflags);
 
5784
  }
 
5785
 
 
5786
  if (error) {
 
5787
    goto cleanup;
6156
5788
  }
6157
5789
 
6158
5790
  /* Look for a primary key */
6161
5793
                   (int) form.getShare()->getPrimaryKey() :
6162
5794
                   -1);
6163
5795
 
6164
 
  /* Our function innobase_get_mysql_key_number_for_index assumes
 
5796
  /* Our function row_get_mysql_key_number_for_index assumes
6165
5797
    the primary key is always number 0, if it exists */
6166
5798
 
6167
5799
  assert(primary_key_no == -1 || primary_key_no == 0);
6168
5800
 
6169
 
  /* Check for name conflicts (with reserved name) for
6170
 
     any user indices to be created. */
6171
 
  if (innobase_index_name_is_reserved(trx, form.key_info,
6172
 
                                      form.getShare()->keys)) {
6173
 
    error = -1;
6174
 
    goto cleanup;
6175
 
  }
6176
 
 
6177
 
  if (lex_identified_temp_table)
6178
 
    iflags |= DICT_TF2_TEMPORARY << DICT_TF2_SHIFT;
6179
 
 
6180
 
  error= create_table_def(trx, &form, identifier.getKeyPath().c_str(),
6181
 
                          lex_identified_temp_table ? identifier.getKeyPath().c_str() : NULL,
6182
 
                          iflags);
6183
 
 
6184
 
  session.setXaId(trx->id);
6185
 
 
6186
 
  if (error) {
6187
 
    goto cleanup;
6188
 
  }
6189
 
 
6190
5801
  /* Create the keys */
6191
5802
 
6192
5803
  if (form.getShare()->sizeKeys() == 0 || primary_key_no == -1) {
6194
5805
      order the rows by their row id which is internally generated
6195
5806
      by InnoDB */
6196
5807
 
6197
 
    error = create_clustered_index_when_no_primary(trx, iflags, identifier.getKeyPath().c_str());
 
5808
    error = create_clustered_index_when_no_primary(trx, iflags, norm_name);
6198
5809
    if (error) {
6199
5810
      goto cleanup;
6200
5811
    }
6202
5813
 
6203
5814
  if (primary_key_no != -1) {
6204
5815
    /* In InnoDB the clustered index must always be created first */
6205
 
    if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
 
5816
    if ((error = create_index(trx, &form, iflags, norm_name,
6206
5817
                              (uint) primary_key_no))) {
6207
5818
      goto cleanup;
6208
5819
    }
6211
5822
  for (i = 0; i < form.getShare()->sizeKeys(); i++) {
6212
5823
    if (i != (uint) primary_key_no) {
6213
5824
 
6214
 
      if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
 
5825
      if ((error = create_index(trx, &form, iflags, norm_name,
6215
5826
                                i))) {
6216
5827
        goto cleanup;
6217
5828
      }
6218
5829
    }
6219
5830
  }
6220
5831
 
6221
 
  stmt= session.getQueryStringCopy(stmt_len);
6222
 
 
6223
 
  if (stmt) {
 
5832
  if (trx->mysql_query_str) {
6224
5833
    string generated_create_table;
6225
 
    const char *query= stmt;
 
5834
    const char *query= trx->mysql_query_str;
6226
5835
 
6227
 
    if (session.getSqlCommand() == SQLCOM_CREATE_TABLE)
 
5836
    if (session_sql_command(&session) == SQLCOM_CREATE_TABLE)
6228
5837
    {
6229
5838
      message::transformTableDefinitionToSql(create_proto,
6230
5839
                                             generated_create_table,
6233
5842
    }
6234
5843
 
6235
5844
    error = row_table_add_foreign_constraints(trx,
6236
 
                                              query, strlen(query),
6237
 
                                              identifier.getKeyPath().c_str(),
 
5845
                                              query,
 
5846
                                              norm_name,
6238
5847
                                              lex_identified_temp_table);
6239
 
    switch (error) {
6240
 
 
6241
 
    case DB_PARENT_NO_INDEX:
6242
 
      push_warning_printf(
6243
 
                          &session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6244
 
                          HA_ERR_CANNOT_ADD_FOREIGN,
6245
 
                          "Create table '%s' with foreign key constraint"
6246
 
                          " failed. There is no index in the referenced"
6247
 
                          " table where the referenced columns appear"
6248
 
                          " as the first columns.\n", identifier.getKeyPath().c_str());
6249
 
      break;
6250
 
 
6251
 
    case DB_CHILD_NO_INDEX:
6252
 
      push_warning_printf(
6253
 
                          &session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6254
 
                          HA_ERR_CANNOT_ADD_FOREIGN,
6255
 
                          "Create table '%s' with foreign key constraint"
6256
 
                          " failed. There is no index in the referencing"
6257
 
                          " table where referencing columns appear"
6258
 
                          " as the first columns.\n", identifier.getKeyPath().c_str());
6259
 
      break;
6260
 
    }
6261
5848
 
6262
5849
    error = convert_error_code_to_mysql(error, iflags, NULL);
6263
5850
 
6276
5863
 
6277
5864
  log_buffer_flush_to_disk();
6278
5865
 
6279
 
  innobase_table = dict_table_get(identifier.getKeyPath().c_str(), FALSE);
 
5866
  innobase_table = dict_table_get(norm_name, FALSE);
6280
5867
 
6281
5868
  assert(innobase_table != 0);
6282
5869
 
6284
5871
    /* We update the highest file format in the system table
6285
5872
      space, if this table has higher file format setting. */
6286
5873
 
6287
 
    char changed_file_format_max[100];
6288
 
    strcpy(changed_file_format_max, innobase_file_format_max.c_str());
6289
 
    trx_sys_file_format_max_upgrade((const char **)&changed_file_format_max,
6290
 
      dict_table_get_format(innobase_table));
6291
 
    innobase_file_format_max= changed_file_format_max;
 
5874
    trx_sys_file_format_max_upgrade((const char**) &innobase_file_format_check,
 
5875
                                    dict_table_get_format(innobase_table));
6292
5876
  }
6293
5877
 
6294
5878
  /* Note: We can't call update_session() as prebuilt will not be
6295
5879
    setup at this stage and so we use session. */
6296
5880
 
6297
5881
  /* We need to copy the AUTOINC value from the old table if
6298
 
    this is an ALTER TABLE or CREATE INDEX because CREATE INDEX
6299
 
    does a table copy too. */
 
5882
    this is an ALTER TABLE. */
6300
5883
 
6301
5884
  if ((create_proto.options().has_auto_increment_value()
6302
 
       || session.getSqlCommand() == SQLCOM_ALTER_TABLE
6303
 
       || session.getSqlCommand() == SQLCOM_CREATE_INDEX)
 
5885
       || session_sql_command(&session) == SQLCOM_ALTER_TABLE)
6304
5886
      && create_proto.options().auto_increment_value() != 0) {
6305
5887
 
6306
 
    /* Query was one of :
6307
 
       CREATE TABLE ...AUTO_INCREMENT = x; or
6308
 
       ALTER TABLE...AUTO_INCREMENT = x;   or
6309
 
       CREATE INDEX x on t(...);
6310
 
       Find out a table definition from the dictionary and get
6311
 
       the current value of the auto increment field. Set a new
6312
 
       value to the auto increment field if the value is greater
6313
 
       than the maximum value in the column. */
 
5888
    /* Query was ALTER TABLE...AUTO_INCREMENT = x; or
 
5889
      CREATE TABLE ...AUTO_INCREMENT = x; Find out a table
 
5890
      definition from the dictionary and get the current value
 
5891
      of the auto increment field. Set a new value to the
 
5892
      auto increment field if the value is greater than the
 
5893
      maximum value in the column. */
6314
5894
 
6315
5895
    auto_inc_value = create_proto.options().auto_increment_value();
6316
5896
 
6328
5908
 
6329
5909
  if (lex_identified_temp_table)
6330
5910
  {
6331
 
    session.getMessageCache().storeTableMessage(identifier, create_proto);
 
5911
    session.storeTableMessage(identifier, create_proto);
6332
5912
  }
6333
5913
  else
6334
5914
  {
6362
5942
 
6363
5943
  ut_a(prebuilt->trx);
6364
5944
  ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
6365
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
5945
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
6366
5946
 
6367
5947
  dict_table = prebuilt->table;
6368
5948
  trx = prebuilt->trx;
6391
5971
  /* Get the transaction associated with the current session, or create one
6392
5972
  if not yet created, and update prebuilt->trx */
6393
5973
 
6394
 
  update_session(getTable()->in_use);
 
5974
  update_session(table->in_use);
6395
5975
 
6396
 
  if (user_session->getSqlCommand() != SQLCOM_TRUNCATE) {
 
5976
  if (session_sql_command(user_session) != SQLCOM_TRUNCATE) {
6397
5977
  fallback:
6398
5978
    /* We only handle TRUNCATE TABLE t as a special case.
6399
5979
    DELETE FROM t will have to use ha_innobase::doDeleteRecord(),
6427
6007
InnobaseEngine::doDropTable(
6428
6008
/*======================*/
6429
6009
        Session &session,
6430
 
        const identifier::Table &identifier)
 
6010
        const TableIdentifier &identifier)
6431
6011
{
6432
6012
  int error;
6433
6013
  trx_t*  parent_trx;
6434
6014
  trx_t*  trx;
 
6015
  char  norm_name[1000];
6435
6016
 
6436
6017
  ut_a(identifier.getPath().length() < 1000);
6437
6018
 
6438
 
  std::string search_string(identifier.getSchemaName());
6439
 
  boost::algorithm::to_lower(search_string);
6440
 
 
6441
 
  if (search_string.compare("data_dictionary") == 0)
6442
 
  {
6443
 
    return HA_ERR_TABLE_READONLY;
6444
 
  }
 
6019
  /* Strangely, MySQL passes the table name without the '.frm'
 
6020
    extension, in contrast to ::create */
 
6021
  normalize_table_name(norm_name, identifier.getPath().c_str());
6445
6022
 
6446
6023
  /* Get the transaction associated with the current session, or create one
6447
6024
    if not yet created */
6459
6036
 
6460
6037
  /* Drop the table in InnoDB */
6461
6038
 
6462
 
  error = row_drop_table_for_mysql(identifier.getKeyPath().c_str(), trx,
6463
 
                                   session.getSqlCommand()
 
6039
  error = row_drop_table_for_mysql(norm_name, trx,
 
6040
                                   session_sql_command(&session)
6464
6041
                                   == SQLCOM_DROP_DB);
6465
6042
 
6466
 
  session.setXaId(trx->id);
6467
 
 
6468
6043
  /* Flush the log to reduce probability that the .frm files and
6469
6044
    the InnoDB data dictionary get out-of-sync if the user runs
6470
6045
    with innodb_flush_log_at_trx_commit = 0 */
6487
6062
  {
6488
6063
    if (identifier.getType() == message::Table::TEMPORARY)
6489
6064
    {
6490
 
      session.getMessageCache().removeTableMessage(identifier);
6491
 
      ulint sql_command = session.getSqlCommand();
 
6065
      session.removeTableMessage(identifier);
 
6066
      ulint sql_command = session_sql_command(&session);
6492
6067
 
6493
6068
      // If this was the final removal to an alter table then we will need
6494
6069
      // to remove the .dfe that was left behind.
6521
6096
bool
6522
6097
InnobaseEngine::doDropSchema(
6523
6098
/*===================*/
6524
 
                             const identifier::Schema &identifier)
 
6099
                             const SchemaIdentifier &identifier)
6525
6100
    /*!< in: database path; inside InnoDB the name
6526
6101
      of the last directory in the path is used as
6527
6102
      the database name: for example, in 'mysql/data/test'
6571
6146
 
6572
6147
void InnobaseEngine::dropTemporarySchema()
6573
6148
{
6574
 
  identifier::Schema schema_identifier(GLOBAL_TEMPORARY_EXT);
 
6149
  SchemaIdentifier schema_identifier(GLOBAL_TEMPORARY_EXT);
6575
6150
  trx_t*  trx= NULL;
6576
6151
  string schema_path(GLOBAL_TEMPORARY_EXT);
6577
6152
 
6580
6155
  trx = trx_allocate_for_mysql();
6581
6156
 
6582
6157
  trx->mysql_thd = NULL;
 
6158
  trx->mysql_query_str = NULL;
6583
6159
 
6584
6160
  trx->check_foreigns = false;
6585
6161
  trx->check_unique_secondary = false;
6608
6184
innobase_rename_table(
6609
6185
/*==================*/
6610
6186
  trx_t*    trx,  /*!< in: transaction */
6611
 
  const identifier::Table &from,
6612
 
  const identifier::Table &to,
 
6187
  const char* from, /*!< in: old name of the table */
 
6188
  const char* to, /*!< in: new name of the table */
6613
6189
  ibool   lock_and_commit)
6614
6190
        /*!< in: TRUE=lock data dictionary and commit */
6615
6191
{
6616
6192
  int error;
 
6193
  char norm_to[FN_REFLEN];
 
6194
  char norm_from[FN_REFLEN];
6617
6195
 
6618
6196
  srv_lower_case_table_names = TRUE;
6619
6197
 
 
6198
  normalize_table_name(norm_to, to);
 
6199
  normalize_table_name(norm_from, from);
 
6200
 
6620
6201
  /* Serialize data dictionary operations with dictionary mutex:
6621
6202
  no deadlocks can occur then in these operations */
6622
6203
 
6624
6205
    row_mysql_lock_data_dictionary(trx);
6625
6206
  }
6626
6207
 
6627
 
  error = row_rename_table_for_mysql(from.getKeyPath().c_str(), to.getKeyPath().c_str(), trx, lock_and_commit);
 
6208
  error = row_rename_table_for_mysql(
 
6209
    norm_from, norm_to, trx, lock_and_commit);
6628
6210
 
6629
6211
  if (error != DB_SUCCESS) {
6630
6212
    FILE* ef = dict_foreign_err_file;
6631
6213
 
6632
6214
    fputs("InnoDB: Renaming table ", ef);
6633
 
    ut_print_name(ef, trx, TRUE, from.getKeyPath().c_str());
 
6215
    ut_print_name(ef, trx, TRUE, norm_from);
6634
6216
    fputs(" to ", ef);
6635
 
    ut_print_name(ef, trx, TRUE, to.getKeyPath().c_str());
 
6217
    ut_print_name(ef, trx, TRUE, norm_to);
6636
6218
    fputs(" failed!\n", ef);
6637
6219
  }
6638
6220
 
6651
6233
/*********************************************************************//**
6652
6234
Renames an InnoDB table.
6653
6235
@return 0 or error code */
6654
 
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, const identifier::Table &from, const identifier::Table &to)
 
6236
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
6655
6237
{
6656
6238
  // A temp table alter table/rename is a shallow rename and only the
6657
6239
  // definition needs to be updated.
6658
6240
  if (to.getType() == message::Table::TEMPORARY && from.getType() == message::Table::TEMPORARY)
6659
6241
  {
6660
 
    session.getMessageCache().renameTableMessage(from, to);
 
6242
    session.renameTableMessage(from, to);
6661
6243
    return 0;
6662
6244
  }
6663
6245
 
6677
6259
 
6678
6260
  trx = innobase_trx_allocate(&session);
6679
6261
 
6680
 
  error = innobase_rename_table(trx, from, to, TRUE);
6681
 
 
6682
 
  session.setXaId(trx->id);
 
6262
  error = innobase_rename_table(trx, from.getPath().c_str(), to.getPath().c_str(), TRUE);
6683
6263
 
6684
6264
  /* Tell the InnoDB server that there might be work for
6685
6265
    utility threads: */
6689
6269
  innobase_commit_low(trx);
6690
6270
  trx_free_for_mysql(trx);
6691
6271
 
6692
 
  /* Add a special case to handle the Duplicated Key error
6693
 
     and return DB_ERROR instead.
6694
 
     This is to avoid a possible SIGSEGV error from mysql error
6695
 
     handling code. Currently, mysql handles the Duplicated Key
6696
 
     error by re-entering the storage layer and getting dup key
6697
 
     info by calling get_dup_key(). This operation requires a valid
6698
 
     table handle ('row_prebuilt_t' structure) which could no
6699
 
     longer be available in the error handling stage. The suggested
6700
 
     solution is to report a 'table exists' error message (since
6701
 
     the dup key error here is due to an existing table whose name
6702
 
     is the one we are trying to rename to) and return the generic
6703
 
     error code. */
6704
 
  if (error == (int) DB_DUPLICATE_KEY) {
6705
 
    my_error(ER_TABLE_EXISTS_ERROR, to);
6706
 
    error = DB_ERROR;
6707
 
  }
6708
 
 
6709
6272
  error = convert_error_code_to_mysql(error, 0, NULL);
6710
6273
 
6711
6274
  if (not error)
6733
6296
  KeyInfo*    key;
6734
6297
  dict_index_t* index;
6735
6298
  unsigned char*    key_val_buff2 = (unsigned char*) malloc(
6736
 
              getTable()->getShare()->sizeStoredRecord()
6737
 
          + getTable()->getShare()->max_key_length + 100);
6738
 
  ulint   buff2_len = getTable()->getShare()->sizeStoredRecord()
6739
 
          + getTable()->getShare()->max_key_length + 100;
 
6299
              table->getShare()->stored_rec_length
 
6300
          + table->getShare()->max_key_length + 100);
 
6301
  ulint   buff2_len = table->getShare()->stored_rec_length
 
6302
          + table->getShare()->max_key_length + 100;
6740
6303
  dtuple_t* range_start;
6741
6304
  dtuple_t* range_end;
6742
6305
  ib_int64_t  n_rows;
6744
6307
  ulint   mode2;
6745
6308
  mem_heap_t* heap;
6746
6309
 
6747
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
6310
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
6748
6311
 
6749
6312
  prebuilt->trx->op_info = (char*)"estimating records in index range";
6750
6313
 
6755
6318
 
6756
6319
  active_index = keynr;
6757
6320
 
6758
 
  key = &getTable()->key_info[active_index];
6759
 
 
6760
 
  index = innobase_get_index(keynr);
6761
 
 
6762
 
  /* There exists possibility of not being able to find requested
6763
 
     index due to inconsistency between MySQL and InoDB dictionary info.
6764
 
     Necessary message should have been printed in innobase_get_index() */
6765
 
  if (UNIV_UNLIKELY(!index)) {
6766
 
    n_rows = HA_POS_ERROR;
6767
 
    goto func_exit;
6768
 
  }
6769
 
 
6770
 
  if (UNIV_UNLIKELY(!row_merge_is_index_usable(prebuilt->trx, index))) {
6771
 
    n_rows = HA_ERR_TABLE_DEF_CHANGED;
6772
 
    goto func_exit;
6773
 
  }
 
6321
  key = &table->key_info[active_index];
 
6322
 
 
6323
  index = dict_table_get_index_on_name(prebuilt->table, table->getShare()->getTableProto()->indexes(active_index).name().c_str());
 
6324
 
 
6325
  /* MySQL knows about this index and so we must be able to find it.*/
 
6326
  ut_a(index);
6774
6327
 
6775
6328
  heap = mem_heap_create(2 * (key->key_parts * sizeof(dfield_t)
6776
6329
            + sizeof(dtuple_t)));
6815
6368
 
6816
6369
  mem_heap_free(heap);
6817
6370
 
6818
 
func_exit:
6819
6371
  free(key_val_buff2);
6820
6372
 
6821
6373
  prebuilt->trx->op_info = (char*)"";
6845
6397
  dict_index_t* index;
6846
6398
  uint64_t  estimate;
6847
6399
  uint64_t  local_data_file_length;
6848
 
  ulint stat_n_leaf_pages;
6849
6400
 
6850
6401
  /* We do not know if MySQL can call this function before calling
6851
6402
  external_lock(). To be safe, update the session of the current table
6852
6403
  handle. */
6853
6404
 
6854
 
  update_session(getTable()->in_use);
 
6405
  update_session(table->in_use);
6855
6406
 
6856
6407
  prebuilt->trx->op_info = (char*)
6857
6408
         "calculating upper bound for table rows";
6863
6414
 
6864
6415
  index = dict_table_get_first_index(prebuilt->table);
6865
6416
 
6866
 
  stat_n_leaf_pages = index->stat_n_leaf_pages;
6867
 
 
6868
 
  ut_a(stat_n_leaf_pages > 0);
 
6417
  ut_a(index->stat_n_leaf_pages > 0);
6869
6418
 
6870
6419
  local_data_file_length =
6871
 
    ((uint64_t) stat_n_leaf_pages) * UNIV_PAGE_SIZE;
 
6420
    ((uint64_t) index->stat_n_leaf_pages) * UNIV_PAGE_SIZE;
6872
6421
 
6873
6422
 
6874
6423
  /* Calculate a minimum length for a clustered index record and from
6917
6466
  ha_rows total_rows;
6918
6467
  double  time_for_scan;
6919
6468
 
6920
 
  if (index != getTable()->getShare()->getPrimaryKey()) {
 
6469
  if (index != table->getShare()->getPrimaryKey()) {
6921
6470
    /* Not clustered */
6922
6471
    return(Cursor::read_time(index, ranges, rows));
6923
6472
  }
6941
6490
}
6942
6491
 
6943
6492
/*********************************************************************//**
6944
 
Calculates the key number used inside MySQL for an Innobase index. We will
6945
 
first check the "index translation table" for a match of the index to get
6946
 
the index number. If there does not exist an "index translation table",
6947
 
or not able to find the index in the translation table, then we will fall back
6948
 
to the traditional way of looping through dict_index_t list to find a
6949
 
match. In this case, we have to take into account if we generated a
6950
 
default clustered index for the table
6951
 
@return the key number used inside MySQL */
6952
 
static
6953
 
unsigned int
6954
 
innobase_get_mysql_key_number_for_index(
6955
 
/*====================================*/
6956
 
        INNOBASE_SHARE*         share,  /*!< in: share structure for index
6957
 
                                        translation table. */
6958
 
        const drizzled::Table*  table,  /*!< in: table in MySQL data
6959
 
                                        dictionary */
6960
 
        dict_table_t*           ib_table,/*!< in: table in Innodb data
6961
 
                                        dictionary */
6962
 
        const dict_index_t*     index)  /*!< in: index */
6963
 
{
6964
 
        const dict_index_t*     ind;
6965
 
        unsigned int            i;
6966
 
 
6967
 
        ut_ad(index);
6968
 
        ut_ad(ib_table);
6969
 
        ut_ad(table);
6970
 
        ut_ad(share);
6971
 
 
6972
 
        /* If index does not belong to the table of share structure. Search
6973
 
        index->table instead */
6974
 
        if (index->table != ib_table) {
6975
 
                i = 0;
6976
 
                ind = dict_table_get_first_index(index->table);
6977
 
 
6978
 
                while (index != ind) {
6979
 
                        ind = dict_table_get_next_index(ind);
6980
 
                        i++;
6981
 
                }
6982
 
 
6983
 
                if (row_table_got_default_clust_index(index->table)) {
6984
 
                        ut_a(i > 0);
6985
 
                        i--;
6986
 
                }
6987
 
 
6988
 
                return(i);
6989
 
        }
6990
 
 
6991
 
        /* If index does not belong to the table of share structure. Search
6992
 
        index->table instead */
6993
 
        if (index->table != ib_table) {
6994
 
                i = 0;
6995
 
                ind = dict_table_get_first_index(index->table);
6996
 
 
6997
 
                while (index != ind) {
6998
 
                        ind = dict_table_get_next_index(ind);
6999
 
                        i++;
7000
 
                }
7001
 
 
7002
 
                if (row_table_got_default_clust_index(index->table)) {
7003
 
                        ut_a(i > 0);
7004
 
                        i--;
7005
 
                }
7006
 
 
7007
 
                return(i);
7008
 
        }
7009
 
 
7010
 
        /* If index translation table exists, we will first check
7011
 
        the index through index translation table for a match. */
7012
 
        if (share->idx_trans_tbl.index_mapping) {
7013
 
                for (i = 0; i < share->idx_trans_tbl.index_count; i++) {
7014
 
                        if (share->idx_trans_tbl.index_mapping[i] == index) {
7015
 
                                return(i);
7016
 
                        }
7017
 
                }
7018
 
 
7019
 
                /* Print an error message if we cannot find the index
7020
 
                ** in the "index translation table". */
7021
 
                errmsg_printf(error::ERROR,
7022
 
                              "Cannot find index %s in InnoDB index "
7023
 
                                "translation table.", index->name);
7024
 
        }
7025
 
 
7026
 
        /* If we do not have an "index translation table", or not able
7027
 
        to find the index in the translation table, we'll directly find
7028
 
        matching index in the dict_index_t list */
7029
 
        for (i = 0; i < table->getShare()->keys; i++) {
7030
 
                ind = dict_table_get_index_on_name(
7031
 
                        ib_table, table->key_info[i].name);
7032
 
 
7033
 
                if (index == ind) {
7034
 
                        return(i);
7035
 
                }
7036
 
        }
7037
 
 
7038
 
                errmsg_printf(error::ERROR,
7039
 
                              "Cannot find matching index number for index %s "
7040
 
                              "in InnoDB index list.", index->name);
7041
 
 
7042
 
        return(0);
7043
 
}
7044
 
/*********************************************************************//**
7045
6493
Returns statistics information of the table to the MySQL interpreter,
7046
6494
in various fields of the handle object. */
7047
6495
UNIV_INTERN
7054
6502
  dict_index_t* index;
7055
6503
  ha_rows   rec_per_key;
7056
6504
  ib_int64_t  n_rows;
 
6505
  ulong   j;
 
6506
  ulong   i;
 
6507
  char    path[FN_REFLEN];
7057
6508
  os_file_stat_t  stat_info;
7058
6509
 
7059
6510
  /* If we are forcing recovery at a high level, we will suppress
7060
6511
  statistics calculation on tables, because that may crash the
7061
6512
  server if an index is badly corrupted. */
7062
6513
 
 
6514
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
 
6515
 
 
6516
    /* We return success (0) instead of HA_ERR_CRASHED,
 
6517
    because we want MySQL to process this query and not
 
6518
    stop, like it would do if it received the error code
 
6519
    HA_ERR_CRASHED. */
 
6520
 
 
6521
    return(0);
 
6522
  }
 
6523
 
7063
6524
  /* We do not know if MySQL can call this function before calling
7064
6525
  external_lock(). To be safe, update the session of the current table
7065
6526
  handle. */
7066
6527
 
7067
 
  update_session(getTable()->in_use);
 
6528
  update_session(table->in_use);
7068
6529
 
7069
6530
  /* In case MySQL calls this in the middle of a SELECT query, release
7070
6531
  possible adaptive hash latch to avoid deadlocks of threads */
7076
6537
  ib_table = prebuilt->table;
7077
6538
 
7078
6539
  if (flag & HA_STATUS_TIME) {
7079
 
    /* In Analyze we call with this flag: update
7080
 
       then statistics so that they are up-to-date */
7081
 
 
7082
 
    prebuilt->trx->op_info = "updating table statistics";
7083
 
 
7084
 
    dict_update_statistics(ib_table,
7085
 
                           FALSE /* update even if stats
7086
 
                                    are initialized */);
7087
 
 
7088
 
 
7089
 
    prebuilt->trx->op_info = "returning various info to MySQL";
7090
 
 
7091
 
    fs::path get_status_path(getDataHomeCatalog());
7092
 
    get_status_path /= ib_table->name;
7093
 
    fs::change_extension(get_status_path, "dfe");
 
6540
    if (innobase_stats_on_metadata) {
 
6541
      /* In sql_show we call with this flag: update
 
6542
      then statistics so that they are up-to-date */
 
6543
 
 
6544
      prebuilt->trx->op_info = "updating table statistics";
 
6545
 
 
6546
      dict_update_statistics(ib_table);
 
6547
 
 
6548
      prebuilt->trx->op_info = "returning various info to MySQL";
 
6549
    }
 
6550
 
 
6551
    snprintf(path, sizeof(path), "%s/%s%s",
 
6552
             data_home, ib_table->name, ".dfe");
 
6553
 
 
6554
    internal::unpack_filename(path,path);
7094
6555
 
7095
6556
    /* Note that we do not know the access time of the table,
7096
6557
    nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
7097
6558
 
7098
 
    if (os_file_get_status(get_status_path.file_string().c_str(), &stat_info)) {
 
6559
    if (os_file_get_status(path,&stat_info)) {
7099
6560
      stats.create_time = (ulong) stat_info.ctime;
7100
6561
    }
7101
6562
  }
7102
6563
 
7103
6564
  if (flag & HA_STATUS_VARIABLE) {
7104
 
 
7105
 
    dict_table_stats_lock(ib_table, RW_S_LATCH);
7106
 
 
7107
6565
    n_rows = ib_table->stat_n_rows;
7108
6566
 
7109
6567
    /* Because we do not protect stat_n_rows by any mutex in a
7131
6589
    n_rows can not be 0 unless the table is empty, set to 1
7132
6590
    instead. The original problem of bug#29507 is actually
7133
6591
    fixed in the server code. */
7134
 
    if (user_session->getSqlCommand() == SQLCOM_TRUNCATE) {
 
6592
    if (session_sql_command(user_session) == SQLCOM_TRUNCATE) {
7135
6593
 
7136
6594
      n_rows = 1;
7137
6595
 
7153
6611
        ib_table->stat_sum_of_other_index_sizes)
7154
6612
          * UNIV_PAGE_SIZE;
7155
6613
 
7156
 
    dict_table_stats_unlock(ib_table, RW_S_LATCH);
7157
 
 
7158
6614
    /* Since fsp_get_available_space_in_free_extents() is
7159
6615
    acquiring latches inside InnoDB, we do not call it if we
7160
6616
    are asked by MySQL to avoid locking. Another reason to
7161
6617
    avoid the call is that it uses quite a lot of CPU.
7162
 
    See Bug#38185. */
7163
 
    if (flag & HA_STATUS_NO_LOCK) {
7164
 
      /* We do not update delete_length if no
7165
 
         locking is requested so the "old" value can
7166
 
         remain. delete_length is initialized to 0 in
7167
 
         the ha_statistics' constructor. */
7168
 
    } else if (UNIV_UNLIKELY
7169
 
               (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE)) {
7170
 
      /* Avoid accessing the tablespace if
7171
 
         innodb_crash_recovery is set to a high value. */
7172
 
      stats.delete_length = 0;
7173
 
    } else {
7174
 
      ullint    avail_space;
7175
 
 
7176
 
      avail_space = fsp_get_available_space_in_free_extents(ib_table->space);
7177
 
 
7178
 
      if (avail_space == ULLINT_UNDEFINED) {
 
6618
    See Bug#38185.
 
6619
    We do not update delete_length if no locking is requested
 
6620
    so the "old" value can remain. delete_length is initialized
 
6621
    to 0 in the ha_statistics' constructor. */
 
6622
    if (!(flag & HA_STATUS_NO_LOCK)) {
 
6623
 
 
6624
      /* lock the data dictionary to avoid races with
 
6625
      ibd_file_missing and tablespace_discarded */
 
6626
      row_mysql_lock_data_dictionary(prebuilt->trx);
 
6627
 
 
6628
      /* ib_table->space must be an existent tablespace */
 
6629
      if (!ib_table->ibd_file_missing
 
6630
          && !ib_table->tablespace_discarded) {
 
6631
 
 
6632
        stats.delete_length =
 
6633
          fsp_get_available_space_in_free_extents(
 
6634
            ib_table->space) * 1024;
 
6635
      } else {
 
6636
 
7179
6637
        Session*  session;
7180
6638
 
7181
 
        session= getTable()->in_use;
 
6639
        session= table->in_use;
7182
6640
        assert(session);
7183
6641
 
7184
6642
        push_warning_printf(
7193
6651
          ib_table->name);
7194
6652
 
7195
6653
        stats.delete_length = 0;
7196
 
      } else {
7197
 
        stats.delete_length = avail_space * 1024;
7198
6654
      }
 
6655
 
 
6656
      row_mysql_unlock_data_dictionary(prebuilt->trx);
7199
6657
    }
7200
6658
 
7201
6659
    stats.check_time = 0;
7208
6666
  }
7209
6667
 
7210
6668
  if (flag & HA_STATUS_CONST) {
7211
 
    ulong i;
7212
 
    /* Verify the number of index in InnoDB and MySQL
7213
 
       matches up. If prebuilt->clust_index_was_generated
7214
 
       holds, InnoDB defines GEN_CLUST_INDEX internally */
7215
 
    ulint       num_innodb_index = UT_LIST_GET_LEN(ib_table->indexes) - prebuilt->clust_index_was_generated;
 
6669
    index = dict_table_get_first_index(ib_table);
7216
6670
 
7217
 
    if (getTable()->getShare()->keys != num_innodb_index) {
7218
 
      errmsg_printf(error::ERROR, "Table %s contains %lu "
7219
 
                      "indexes inside InnoDB, which "
7220
 
                      "is different from the number of "
7221
 
                      "indexes %u defined in the MySQL ",
7222
 
                      ib_table->name, num_innodb_index,
7223
 
                      getTable()->getShare()->keys);
 
6671
    if (prebuilt->clust_index_was_generated) {
 
6672
      index = dict_table_get_next_index(index);
7224
6673
    }
7225
6674
 
7226
 
    dict_table_stats_lock(ib_table, RW_S_LATCH);
7227
 
 
7228
 
    for (i = 0; i < getTable()->getShare()->sizeKeys(); i++) {
7229
 
      ulong j;
7230
 
      /* We could get index quickly through internal
7231
 
         index mapping with the index translation table.
7232
 
         The identity of index (match up index name with
7233
 
         that of table->key_info[i]) is already verified in
7234
 
         innobase_get_index().  */
7235
 
      index = innobase_get_index(i);
7236
 
 
 
6675
    for (i = 0; i < table->getShare()->sizeKeys(); i++) {
7237
6676
      if (index == NULL) {
7238
 
        errmsg_printf(error::ERROR, "Table %s contains fewer "
 
6677
        errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains fewer "
7239
6678
            "indexes inside InnoDB than "
7240
6679
            "are defined in the MySQL "
7241
6680
            ".frm file. Have you mixed up "
7247
6686
        break;
7248
6687
      }
7249
6688
 
7250
 
      for (j = 0; j < getTable()->key_info[i].key_parts; j++) {
 
6689
      for (j = 0; j < table->key_info[i].key_parts; j++) {
7251
6690
 
7252
6691
        if (j + 1 > index->n_uniq) {
7253
 
          errmsg_printf(error::ERROR, 
 
6692
          errmsg_printf(ERRMSG_LVL_ERROR, 
7254
6693
"Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking "
7255
6694
"statistics for %lu columns. Have you mixed up .frm files from different "
7256
6695
"installations? "
7281
6720
          rec_per_key = 1;
7282
6721
        }
7283
6722
 
7284
 
        getTable()->key_info[i].rec_per_key[j]=
 
6723
        table->key_info[i].rec_per_key[j]=
7285
6724
          rec_per_key >= ~(ulong) 0 ? ~(ulong) 0 :
7286
6725
          (ulong) rec_per_key;
7287
6726
      }
 
6727
 
 
6728
      index = dict_table_get_next_index(index);
7288
6729
    }
7289
 
 
7290
 
    dict_table_stats_unlock(ib_table, RW_S_LATCH);
7291
 
  }
7292
 
 
7293
 
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
7294
 
    goto func_exit;
7295
6730
  }
7296
6731
 
7297
6732
  if (flag & HA_STATUS_ERRKEY) {
7304
6739
 
7305
6740
    if (err_index) {
7306
6741
      errkey = (unsigned int)
7307
 
        innobase_get_mysql_key_number_for_index(share, getTable(), ib_table,
7308
 
                                                err_index);
 
6742
        row_get_mysql_key_number_for_index(err_index);
7309
6743
    } else {
7310
6744
      errkey = (unsigned int) prebuilt->trx->error_key_num;
7311
6745
    }
7312
6746
  }
7313
6747
 
7314
 
  if ((flag & HA_STATUS_AUTO) && getTable()->found_next_number_field) {
 
6748
  if ((flag & HA_STATUS_AUTO) && table->found_next_number_field) {
7315
6749
    stats.auto_increment_value = innobase_peek_autoinc();
7316
6750
  }
7317
6751
 
7318
 
func_exit:
7319
6752
  prebuilt->trx->op_info = (char*)"";
7320
6753
 
7321
6754
  return(0);
7348
6781
/*===============*/
7349
6782
  Session*  session)  /*!< in: user thread handle */
7350
6783
{
7351
 
  dict_index_t* index;
7352
 
  ulint         n_rows;
7353
 
  ulint         n_rows_in_table = ULINT_UNDEFINED;
7354
 
  ibool         is_ok           = TRUE;
7355
 
  ulint         old_isolation_level;
 
6784
  ulint   ret;
7356
6785
 
7357
 
  assert(session == getTable()->in_use);
 
6786
  assert(session == table->in_use);
7358
6787
  ut_a(prebuilt->trx);
7359
6788
  ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
7360
6789
  ut_a(prebuilt->trx == session_to_trx(session));
7363
6792
    /* Build the template; we will use a dummy template
7364
6793
    in index scans done in checking */
7365
6794
 
7366
 
    build_template(prebuilt, NULL, getTable(), ROW_MYSQL_WHOLE_ROW);
7367
 
  }
7368
 
 
7369
 
  if (prebuilt->table->ibd_file_missing) {
7370
 
        errmsg_printf(error::ERROR, "InnoDB: Error:\n"
7371
 
                    "InnoDB: MySQL is trying to use a table handle"
7372
 
                    " but the .ibd file for\n"
7373
 
                    "InnoDB: table %s does not exist.\n"
7374
 
                    "InnoDB: Have you deleted the .ibd file"
7375
 
                    " from the database directory under\n"
7376
 
                    "InnoDB: the MySQL datadir, or have you"
7377
 
                    " used DISCARD TABLESPACE?\n"
7378
 
                    "InnoDB: Please refer to\n"
7379
 
                    "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
7380
 
                    "InnoDB: how you can resolve the problem.\n",
7381
 
                    prebuilt->table->name);
7382
 
    return(HA_ADMIN_CORRUPT);
7383
 
  }
7384
 
 
7385
 
  prebuilt->trx->op_info = "checking table";
7386
 
 
7387
 
  old_isolation_level = prebuilt->trx->isolation_level;
7388
 
 
7389
 
  /* We must run the index record counts at an isolation level
7390
 
     >= READ COMMITTED, because a dirty read can see a wrong number
7391
 
     of records in some index; to play safe, we use always
7392
 
     REPEATABLE READ here */
7393
 
 
7394
 
  prebuilt->trx->isolation_level = TRX_ISO_REPEATABLE_READ;
7395
 
 
7396
 
  /* Enlarge the fatal lock wait timeout during CHECK TABLE. */
7397
 
  mutex_enter(&kernel_mutex);
7398
 
  srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */
7399
 
  mutex_exit(&kernel_mutex);
7400
 
 
7401
 
  for (index = dict_table_get_first_index(prebuilt->table);
7402
 
       index != NULL;
7403
 
       index = dict_table_get_next_index(index)) {
7404
 
#if 0
7405
 
    fputs("Validating index ", stderr);
7406
 
    ut_print_name(stderr, trx, FALSE, index->name);
7407
 
    putc('\n', stderr);
7408
 
#endif
7409
 
 
7410
 
    if (!btr_validate_index(index, prebuilt->trx)) {
7411
 
      is_ok = FALSE;
7412
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7413
 
                          ER_NOT_KEYFILE,
7414
 
                          "InnoDB: The B-tree of"
7415
 
                          " index '%-.200s' is corrupted.",
7416
 
                          index->name);
7417
 
      continue;
7418
 
    }
7419
 
 
7420
 
    /* Instead of invoking change_active_index(), set up
7421
 
       a dummy template for non-locking reads, disabling
7422
 
       access to the clustered index. */
7423
 
    prebuilt->index = index;
7424
 
 
7425
 
    prebuilt->index_usable = row_merge_is_index_usable(
7426
 
                        prebuilt->trx, prebuilt->index);
7427
 
 
7428
 
    if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
7429
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7430
 
                          HA_ERR_TABLE_DEF_CHANGED,
7431
 
                          "InnoDB: Insufficient history for"
7432
 
                          " index '%-.200s'",
7433
 
                          index->name);
7434
 
      continue;
7435
 
    }
7436
 
 
7437
 
    prebuilt->sql_stat_start = TRUE;
7438
 
    prebuilt->template_type = ROW_MYSQL_DUMMY_TEMPLATE;
7439
 
    prebuilt->n_template = 0;
7440
 
    prebuilt->need_to_access_clustered = FALSE;
7441
 
 
7442
 
    dtuple_set_n_fields(prebuilt->search_tuple, 0);
7443
 
 
7444
 
    prebuilt->select_lock_type = LOCK_NONE;
7445
 
 
7446
 
    if (!row_check_index_for_mysql(prebuilt, index, &n_rows)) {
7447
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7448
 
                          ER_NOT_KEYFILE,
7449
 
                          "InnoDB: The B-tree of"
7450
 
                          " index '%-.200s' is corrupted.",
7451
 
                          index->name);
7452
 
      is_ok = FALSE;
7453
 
    }
7454
 
 
7455
 
    if (user_session->getKilled()) {
7456
 
      break;
7457
 
    }
7458
 
 
7459
 
#if 0
7460
 
    fprintf(stderr, "%lu entries in index %s\n", n_rows,
7461
 
            index->name);
7462
 
#endif
7463
 
 
7464
 
    if (index == dict_table_get_first_index(prebuilt->table)) {
7465
 
      n_rows_in_table = n_rows;
7466
 
    } else if (n_rows != n_rows_in_table) {
7467
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7468
 
                          ER_NOT_KEYFILE,
7469
 
                          "InnoDB: Index '%-.200s'"
7470
 
                          " contains %lu entries,"
7471
 
                          " should be %lu.",
7472
 
                          index->name,
7473
 
                          (ulong) n_rows,
7474
 
                          (ulong) n_rows_in_table);
7475
 
      is_ok = FALSE;
7476
 
    }
7477
 
  }
7478
 
 
7479
 
  /* Restore the original isolation level */
7480
 
  prebuilt->trx->isolation_level = old_isolation_level;
7481
 
 
7482
 
  /* We validate also the whole adaptive hash index for all tables
7483
 
     at every CHECK TABLE */
7484
 
 
7485
 
  if (!btr_search_validate()) {
7486
 
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7487
 
                 ER_NOT_KEYFILE,
7488
 
                 "InnoDB: The adaptive hash index is corrupted.");
7489
 
    is_ok = FALSE;
7490
 
  }
7491
 
 
7492
 
  /* Restore the fatal lock wait timeout after CHECK TABLE. */
7493
 
  mutex_enter(&kernel_mutex);
7494
 
  srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */
7495
 
  mutex_exit(&kernel_mutex);
7496
 
 
7497
 
  prebuilt->trx->op_info = "";
7498
 
  if (user_session->getKilled()) {
7499
 
    my_error(ER_QUERY_INTERRUPTED, MYF(0));
7500
 
  }
7501
 
 
7502
 
  return(is_ok ? HA_ADMIN_OK : HA_ADMIN_CORRUPT);
 
6795
    build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
 
6796
  }
 
6797
 
 
6798
  ret = row_check_table_for_mysql(prebuilt);
 
6799
 
 
6800
  if (ret == DB_SUCCESS) {
 
6801
    return(HA_ADMIN_OK);
 
6802
  }
 
6803
 
 
6804
  return(HA_ADMIN_CORRUPT);
7503
6805
}
7504
6806
 
7505
6807
/*************************************************************//**
7525
6827
    return((char*)comment); /* string too long */
7526
6828
  }
7527
6829
 
7528
 
  update_session(getTable()->in_use);
 
6830
  update_session(table->in_use);
7529
6831
 
7530
6832
  prebuilt->trx->op_info = (char*)"returning table comment";
7531
6833
 
7596
6898
  external_lock(). To be safe, update the session of the current table
7597
6899
  handle. */
7598
6900
 
7599
 
  update_session(getTable()->in_use);
 
6901
  update_session(table->in_use);
7600
6902
 
7601
6903
  prebuilt->trx->op_info = (char*)"getting info on foreign keys";
7602
6904
 
7617
6919
  flen = ftell(srv_dict_tmpfile);
7618
6920
  if (flen < 0) {
7619
6921
    flen = 0;
 
6922
  } else if (flen > 64000 - 1) {
 
6923
    flen = 64000 - 1;
7620
6924
  }
7621
6925
 
7622
6926
  /* allocate buffer for the string, and
7643
6947
  dict_foreign_t* foreign;
7644
6948
 
7645
6949
  ut_a(prebuilt != NULL);
7646
 
  update_session(getTable()->in_use);
 
6950
  update_session(table->in_use);
7647
6951
  prebuilt->trx->op_info = (char*)"getting list of foreign keys";
7648
6952
  trx_search_latch_release_if_reserved(prebuilt->trx);
7649
6953
  mutex_enter(&(dict_sys->mutex));
7676
6980
      i++;
7677
6981
    }
7678
6982
    db_name[i] = 0;
7679
 
    ulen= identifier::Table::filename_to_tablename(db_name, uname, sizeof(uname));
 
6983
    ulen= TableIdentifier::filename_to_tablename(db_name, uname, sizeof(uname));
7680
6984
    LEX_STRING *tmp_referenced_db = session->make_lex_string(NULL, uname, ulen, true);
7681
6985
 
7682
6986
    /* Table name */
7683
6987
    tmp_buff += i + 1;
7684
 
    ulen= identifier::Table::filename_to_tablename(tmp_buff, uname, sizeof(uname));
 
6988
    ulen= TableIdentifier::filename_to_tablename(tmp_buff, uname, sizeof(uname));
7685
6989
    LEX_STRING *tmp_referenced_table = session->make_lex_string(NULL, uname, ulen, true);
7686
6990
 
7687
6991
    /** Foreign Fields **/
7759
7063
                              tmp_foreign_fields, tmp_referenced_fields);
7760
7064
 
7761
7065
    ForeignKeyInfo *pf_key_info = (ForeignKeyInfo *)
7762
 
      session->getMemRoot()->duplicate(&f_key_info, sizeof(ForeignKeyInfo));
 
7066
      session->memdup(&f_key_info, sizeof(ForeignKeyInfo));
7763
7067
    f_key_list->push_back(pf_key_info);
7764
7068
    foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
7765
7069
  }
7781
7085
{
7782
7086
  bool  can_switch;
7783
7087
 
7784
 
  ut_a(prebuilt->trx == session_to_trx(getTable()->in_use));
 
7088
  ut_a(prebuilt->trx == session_to_trx(table->in_use));
7785
7089
 
7786
7090
  prebuilt->trx->op_info =
7787
7091
      "determining if there are foreign key constraints";
7869
7173
      either, because the calling threads may change.
7870
7174
      CAREFUL HERE, OR MEMORY CORRUPTION MAY OCCUR! */
7871
7175
    case HA_EXTRA_IGNORE_DUP_KEY:
7872
 
      session_to_trx(getTable()->in_use)->duplicates |= TRX_DUP_IGNORE;
 
7176
      session_to_trx(table->in_use)->duplicates |= TRX_DUP_IGNORE;
7873
7177
      break;
7874
7178
    case HA_EXTRA_WRITE_CAN_REPLACE:
7875
 
      session_to_trx(getTable()->in_use)->duplicates |= TRX_DUP_REPLACE;
 
7179
      session_to_trx(table->in_use)->duplicates |= TRX_DUP_REPLACE;
7876
7180
      break;
7877
7181
    case HA_EXTRA_WRITE_CANNOT_REPLACE:
7878
 
      session_to_trx(getTable()->in_use)->duplicates &= ~TRX_DUP_REPLACE;
 
7182
      session_to_trx(table->in_use)->duplicates &= ~TRX_DUP_REPLACE;
7879
7183
      break;
7880
7184
    case HA_EXTRA_NO_IGNORE_DUP_KEY:
7881
 
      session_to_trx(getTable()->in_use)->duplicates &=
 
7185
      session_to_trx(table->in_use)->duplicates &=
7882
7186
        ~(TRX_DUP_IGNORE | TRX_DUP_REPLACE);
7883
7187
      break;
7884
7188
    default:/* Do nothing */
8014
7318
{
8015
7319
  trx_t*      trx;
8016
7320
  static const char truncated_msg[] = "... truncated...\n";
8017
 
  const long    MAX_STATUS_SIZE = 1048576;
 
7321
  const long    MAX_STATUS_SIZE = 64000;
8018
7322
  ulint     trx_list_start = ULINT_UNDEFINED;
8019
7323
  ulint     trx_list_end = ULINT_UNDEFINED;
8020
7324
 
8032
7336
 
8033
7337
  mutex_enter(&srv_monitor_file_mutex);
8034
7338
  rewind(srv_monitor_file);
8035
 
  srv_printf_innodb_monitor(srv_monitor_file, FALSE,
 
7339
  srv_printf_innodb_monitor(srv_monitor_file,
8036
7340
        &trx_list_start, &trx_list_end);
8037
7341
  flen = ftell(srv_monitor_file);
8038
7342
  os_file_set_eof(srv_monitor_file);
8043
7347
 
8044
7348
  if (flen > MAX_STATUS_SIZE) {
8045
7349
    usable_len = MAX_STATUS_SIZE;
8046
 
    srv_truncated_status_writes++;
8047
7350
  } else {
8048
7351
    usable_len = flen;
8049
7352
  }
8079
7382
 
8080
7383
  mutex_exit(&srv_monitor_file_mutex);
8081
7384
 
8082
 
  stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
8083
 
             STRING_WITH_LEN(""), str, flen);
 
7385
  bool result = FALSE;
8084
7386
 
 
7387
  if (stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
 
7388
      STRING_WITH_LEN(""), str, flen)) {
 
7389
    result= TRUE;
 
7390
  }
8085
7391
  free(str);
8086
7392
 
8087
7393
  return(FALSE);
8088
7394
}
8089
7395
 
8090
7396
/************************************************************************//**
8091
 
Implements the SHOW MUTEX STATUS command.
8092
 
@return true on failure false on success*/
 
7397
Implements the SHOW MUTEX STATUS command. . */
8093
7398
static
8094
7399
bool
8095
7400
innodb_mutex_show_status(
8097
7402
  plugin::StorageEngine*  engine,   /*!< in: the innodb StorageEngine */
8098
7403
  Session*  session,  /*!< in: the MySQL query thread of the
8099
7404
          caller */
8100
 
  stat_print_fn*  stat_print)   /*!< in: function for printing
8101
 
                                        statistics */
 
7405
  stat_print_fn*  stat_print)
8102
7406
{
8103
7407
  char buf1[IO_SIZE], buf2[IO_SIZE];
8104
7408
  mutex_t*  mutex;
8105
7409
  rw_lock_t*  lock;
8106
 
  ulint         block_mutex_oswait_count = 0;
8107
 
  ulint         block_lock_oswait_count = 0;
8108
 
  mutex_t*      block_mutex = NULL;
8109
 
  rw_lock_t*    block_lock = NULL;
8110
7410
#ifdef UNIV_DEBUG
8111
7411
  ulint   rw_lock_count= 0;
8112
7412
  ulint   rw_lock_count_spin_loop= 0;
8120
7420
 
8121
7421
  mutex_enter(&mutex_list_mutex);
8122
7422
 
8123
 
  for (mutex = UT_LIST_GET_FIRST(mutex_list); mutex != NULL;
8124
 
       mutex = UT_LIST_GET_NEXT(list, mutex)) {
8125
 
    if (mutex->count_os_wait == 0) {
8126
 
      continue;
8127
 
    }
8128
 
 
8129
 
 
8130
 
    if (buf_pool_is_block_mutex(mutex)) {
8131
 
      block_mutex = mutex;
8132
 
      block_mutex_oswait_count += mutex->count_os_wait;
8133
 
      continue;
 
7423
  mutex = UT_LIST_GET_FIRST(mutex_list);
 
7424
 
 
7425
  while (mutex != NULL) {
 
7426
    if (mutex->count_os_wait == 0
 
7427
        || buf_pool_is_block_mutex(mutex)) {
 
7428
      goto next_mutex;
8134
7429
    }
8135
7430
#ifdef UNIV_DEBUG
8136
7431
    if (mutex->mutex_type != 1) {
8157
7452
          return(1);
8158
7453
        }
8159
7454
      }
8160
 
    } else {
 
7455
    }
 
7456
    else {
8161
7457
      rw_lock_count += mutex->count_using;
8162
7458
      rw_lock_count_spin_loop += mutex->count_spin_loop;
8163
7459
      rw_lock_count_spin_rounds += mutex->count_spin_rounds;
8169
7465
    buf1len= snprintf(buf1, sizeof(buf1), "%s:%lu",
8170
7466
          mutex->cfile_name, (ulong) mutex->cline);
8171
7467
    buf2len= snprintf(buf2, sizeof(buf2), "os_waits=%lu",
8172
 
                      (ulong) mutex->count_os_wait);
 
7468
          mutex->count_os_wait);
8173
7469
 
8174
7470
    if (stat_print(session, innobase_engine_name,
8175
7471
             engine_name_len, buf1, buf1len,
8178
7474
      return(1);
8179
7475
    }
8180
7476
#endif /* UNIV_DEBUG */
8181
 
  }
8182
 
 
8183
 
  if (block_mutex) {
8184
 
    buf1len = snprintf(buf1, sizeof buf1,
8185
 
                       "combined %s:%lu",
8186
 
                       block_mutex->cfile_name,
8187
 
                       (ulong) block_mutex->cline);
8188
 
    buf2len = snprintf(buf2, sizeof buf2,
8189
 
                       "os_waits=%lu",
8190
 
                       (ulong) block_mutex_oswait_count);
8191
 
 
8192
 
    if (stat_print(session, innobase_engine_name,
8193
 
                   strlen(innobase_engine_name), buf1, buf1len,
8194
 
                   buf2, buf2len)) {
8195
 
      mutex_exit(&mutex_list_mutex);
8196
 
      return(1);
8197
 
    }
 
7477
 
 
7478
next_mutex:
 
7479
    mutex = UT_LIST_GET_NEXT(list, mutex);
8198
7480
  }
8199
7481
 
8200
7482
  mutex_exit(&mutex_list_mutex);
8201
7483
 
8202
7484
  mutex_enter(&rw_lock_list_mutex);
8203
7485
 
8204
 
  for (lock = UT_LIST_GET_FIRST(rw_lock_list); lock != NULL;
8205
 
       lock = UT_LIST_GET_NEXT(list, lock)) {
8206
 
    if (lock->count_os_wait == 0) {
8207
 
      continue;
8208
 
    }
8209
 
 
8210
 
    if (buf_pool_is_block_lock(lock)) {
8211
 
      block_lock = lock;
8212
 
      block_lock_oswait_count += lock->count_os_wait;
8213
 
      continue;
8214
 
    }
8215
 
 
8216
 
    buf1len = snprintf(buf1, sizeof buf1, "%s:%lu",
8217
 
                       lock->cfile_name, (ulong) lock->cline);
8218
 
    buf2len = snprintf(buf2, sizeof buf2, "os_waits=%lu",
8219
 
                       (ulong) lock->count_os_wait);
8220
 
 
8221
 
    if (stat_print(session, innobase_engine_name,
8222
 
                   strlen(innobase_engine_name), buf1, buf1len,
8223
 
                   buf2, buf2len)) {
8224
 
      mutex_exit(&rw_lock_list_mutex);
8225
 
      return(1);
8226
 
    }
8227
 
  }
8228
 
 
8229
 
  if (block_lock) {
8230
 
    buf1len = snprintf(buf1, sizeof buf1,
8231
 
                       "combined %s:%lu",
8232
 
                       block_lock->cfile_name,
8233
 
                       (ulong) block_lock->cline);
8234
 
    buf2len = snprintf(buf2, sizeof buf2,
8235
 
                       "os_waits=%lu",
8236
 
                       (ulong) block_lock_oswait_count);
8237
 
 
8238
 
    if (stat_print(session, innobase_engine_name,
8239
 
                   strlen(innobase_engine_name), buf1, buf1len,
8240
 
                   buf2, buf2len)) {
8241
 
      mutex_exit(&rw_lock_list_mutex);
8242
 
      return(1);
8243
 
    }
 
7486
  lock = UT_LIST_GET_FIRST(rw_lock_list);
 
7487
 
 
7488
  while (lock != NULL) {
 
7489
    if (lock->count_os_wait
 
7490
                    && !buf_pool_is_block_lock(lock)) {
 
7491
      buf1len= snprintf(buf1, sizeof(buf1), "%s:%lu",
 
7492
                                    lock->cfile_name, (unsigned long) lock->cline);
 
7493
      buf2len= snprintf(buf2, sizeof(buf2),
 
7494
                                    "os_waits=%lu", lock->count_os_wait);
 
7495
 
 
7496
      if (stat_print(session, innobase_engine_name,
 
7497
               engine_name_len, buf1, buf1len,
 
7498
               buf2, buf2len)) {
 
7499
        mutex_exit(&rw_lock_list_mutex);
 
7500
        return(1);
 
7501
      }
 
7502
    }
 
7503
    lock = UT_LIST_GET_NEXT(list, lock);
8244
7504
  }
8245
7505
 
8246
7506
  mutex_exit(&rw_lock_list_mutex);
8247
7507
 
8248
7508
#ifdef UNIV_DEBUG
8249
 
  buf2len = snprintf(buf2, sizeof buf2,
8250
 
                     "count=%lu, spin_waits=%lu, spin_rounds=%lu, "
8251
 
                     "os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
8252
 
                     (ulong) rw_lock_count,
8253
 
                     (ulong) rw_lock_count_spin_loop,
8254
 
                     (ulong) rw_lock_count_spin_rounds,
8255
 
                     (ulong) rw_lock_count_os_wait,
8256
 
                     (ulong) rw_lock_count_os_yield,
8257
 
                     (ulong) (rw_lock_wait_time / 1000));
 
7509
  buf2len= my_snprintf(buf2, sizeof(buf2),
 
7510
    "count=%lu, spin_waits=%lu, spin_rounds=%lu, "
 
7511
    "os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
 
7512
    rw_lock_count, rw_lock_count_spin_loop,
 
7513
    rw_lock_count_spin_rounds,
 
7514
    rw_lock_count_os_wait, rw_lock_count_os_yield,
 
7515
    (ulong) (rw_lock_wait_time/1000));
8258
7516
 
8259
7517
  if (stat_print(session, innobase_engine_name, engine_name_len,
8260
7518
      STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
8289
7547
static INNOBASE_SHARE* get_share(const char* table_name)
8290
7548
{
8291
7549
  INNOBASE_SHARE *share;
8292
 
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
 
7550
  pthread_mutex_lock(&innobase_share_mutex);
8293
7551
 
8294
7552
  ulint fold = ut_fold_string(table_name);
8295
7553
 
8299
7557
        !strcmp(share->table_name, table_name));
8300
7558
 
8301
7559
  if (!share) {
 
7560
 
 
7561
    uint length = (uint) strlen(table_name);
 
7562
 
8302
7563
    /* TODO: invoke HASH_MIGRATE if innobase_open_tables
8303
7564
    grows too big */
8304
7565
 
8305
 
    share= new INNOBASE_SHARE(table_name);
 
7566
    share = (INNOBASE_SHARE *) malloc(sizeof(*share)+length+1);
 
7567
                memset(share, 0, sizeof(*share)+length+1);
 
7568
 
 
7569
    share->table_name = (char*) memcpy(share + 1,
 
7570
               table_name, length + 1);
8306
7571
 
8307
7572
    HASH_INSERT(INNOBASE_SHARE, table_name_hash,
8308
7573
          innobase_open_tables, fold, share);
8309
7574
 
8310
7575
    thr_lock_init(&share->lock);
8311
 
 
8312
 
    /* Index translation table initialization */
8313
 
    share->idx_trans_tbl.index_mapping = NULL;
8314
 
    share->idx_trans_tbl.index_count = 0;
8315
 
    share->idx_trans_tbl.array_size = 0;
8316
7576
  }
8317
7577
 
8318
7578
  share->use_count++;
 
7579
  pthread_mutex_unlock(&innobase_share_mutex);
8319
7580
 
8320
7581
  return(share);
8321
7582
}
8322
7583
 
8323
7584
static void free_share(INNOBASE_SHARE* share)
8324
7585
{
8325
 
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
 
7586
  pthread_mutex_lock(&innobase_share_mutex);
8326
7587
 
8327
7588
#ifdef UNIV_DEBUG
8328
7589
  INNOBASE_SHARE* share2;
8342
7603
    HASH_DELETE(INNOBASE_SHARE, table_name_hash,
8343
7604
          innobase_open_tables, fold, share);
8344
7605
    share->lock.deinit();
8345
 
 
8346
 
    /* Free any memory from index translation table */
8347
 
    free(share->idx_trans_tbl.index_mapping);
8348
 
 
8349
 
    delete share;
 
7606
    free(share);
8350
7607
 
8351
7608
    /* TODO: invoke HASH_MIGRATE if innobase_open_tables
8352
7609
    shrinks too much */
8353
7610
  }
 
7611
 
 
7612
  pthread_mutex_unlock(&innobase_share_mutex);
8354
7613
}
8355
7614
 
8356
7615
/*****************************************************************//**
8385
7644
  trx = check_trx_exists(session);
8386
7645
 
8387
7646
  assert(EQ_CURRENT_SESSION(session));
8388
 
  const uint32_t sql_command = session->getSqlCommand();
 
7647
  const uint32_t sql_command = session_sql_command(session);
8389
7648
 
8390
7649
  if (sql_command == SQLCOM_DROP_TABLE) {
8391
7650
 
8421
7680
    isolation_level = trx->isolation_level;
8422
7681
 
8423
7682
    if ((srv_locks_unsafe_for_binlog
8424
 
         || isolation_level <= TRX_ISO_READ_COMMITTED)
 
7683
         || isolation_level == TRX_ISO_READ_COMMITTED)
8425
7684
        && isolation_level != TRX_ISO_SERIALIZABLE
8426
7685
        && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
8427
7686
        && (sql_command == SQLCOM_INSERT_SELECT
8428
 
            || sql_command == SQLCOM_REPLACE_SELECT
8429
 
            || sql_command == SQLCOM_UPDATE
8430
 
            || sql_command == SQLCOM_CREATE_TABLE
8431
 
            || sql_command == SQLCOM_SET_OPTION)) {
 
7687
      || sql_command == SQLCOM_UPDATE
 
7688
      || sql_command == SQLCOM_CREATE_TABLE)) {
8432
7689
 
8433
7690
      /* If we either have innobase_locks_unsafe_for_binlog
8434
7691
      option set or this session is using READ COMMITTED
8435
7692
      isolation level and isolation level of the transaction
8436
7693
      is not set to serializable and MySQL is doing
8437
 
      INSERT INTO...SELECT or REPLACE INTO...SELECT
8438
 
      or UPDATE ... = (SELECT ...) or CREATE  ...
8439
 
      SELECT... or SET ... = (SELECT ...) without
8440
 
      FOR UPDATE or IN SHARE MODE in select,
8441
 
      then we use consistent read for select. */
 
7694
      INSERT INTO...SELECT or UPDATE ... = (SELECT ...) or
 
7695
      CREATE  ... SELECT... without FOR UPDATE or
 
7696
      IN SHARE MODE in select, then we use consistent
 
7697
      read for select. */
8442
7698
 
8443
7699
      prebuilt->select_lock_type = LOCK_NONE;
8444
7700
      prebuilt->stored_select_lock_type = LOCK_NONE;
8471
7727
 
8472
7728
    if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
8473
7729
         && lock_type <= TL_WRITE)
8474
 
        && ! session->doing_tablespace_operation()
 
7730
        && !session_tablespace_op(session)
8475
7731
        && sql_command != SQLCOM_TRUNCATE
8476
7732
        && sql_command != SQLCOM_CREATE_TABLE) {
8477
7733
 
8517
7773
  *value = dict_table_autoinc_read(prebuilt->table);
8518
7774
 
8519
7775
  /* It should have been initialized during open. */
8520
 
  if (*value == 0) {
8521
 
    prebuilt->autoinc_error = DB_UNSUPPORTED;
8522
 
    dict_table_autoinc_unlock(prebuilt->table);
8523
 
  }
 
7776
  ut_a(*value != 0);
8524
7777
 
8525
7778
  return(DB_SUCCESS);
8526
7779
}
8527
7780
 
8528
7781
/*******************************************************************//**
8529
 
This function reads the global auto-inc counter. It doesn't use the
 
7782
This function reads the global auto-inc counter. It doesn't use the 
8530
7783
AUTOINC lock even if the lock mode is set to TRADITIONAL.
8531
7784
@return the autoinc value */
8532
7785
UNIV_INTERN
8546
7799
 
8547
7800
  auto_inc = dict_table_autoinc_read(innodb_table);
8548
7801
 
8549
 
  if (auto_inc == 0) {
8550
 
    ut_print_timestamp(stderr);
8551
 
    errmsg_printf(error::ERROR, "  InnoDB: AUTOINC next value generation is disabled for '%s'\n", innodb_table->name);
8552
 
  }
 
7802
  ut_a(auto_inc > 0);
8553
7803
 
8554
7804
  dict_table_autoinc_unlock(innodb_table);
8555
7805
 
8578
7828
  uint64_t  autoinc = 0;
8579
7829
 
8580
7830
  /* Prepare prebuilt->trx in the table handle */
8581
 
  update_session(getTable()->in_use);
 
7831
  update_session(table->in_use);
8582
7832
 
8583
7833
  error = innobase_get_autoinc(&autoinc);
8584
7834
 
8602
7852
  invoking this method. So we are not sure if it's guaranteed to
8603
7853
  be 0 or not. */
8604
7854
 
8605
 
  /* We need the upper limit of the col type to check for
8606
 
     whether we update the table autoinc counter or not. */
8607
 
  uint64_t col_max_value = innobase_get_int_col_max_value(getTable()->next_number_field);
8608
 
 
8609
7855
  /* Called for the first time ? */
8610
7856
  if (trx->n_autoinc_rows == 0) {
8611
7857
 
8622
7868
  /* Not in the middle of a mult-row INSERT. */
8623
7869
  } else if (prebuilt->autoinc_last_value == 0) {
8624
7870
    set_if_bigger(*first_value, autoinc);
8625
 
    /* Check for -ve values. */
8626
 
  } else if (*first_value > col_max_value && trx->n_autoinc_rows > 0) {
8627
 
    /* Set to next logical value. */
8628
 
    ut_a(autoinc > trx->n_autoinc_rows);
8629
 
    *first_value = (autoinc - trx->n_autoinc_rows) - 1;
8630
7871
  }
8631
7872
 
8632
7873
  *nb_reserved_values = trx->n_autoinc_rows;
8634
7875
  /* This all current style autoinc. */
8635
7876
  {
8636
7877
    uint64_t  need;
8637
 
    uint64_t  current;
8638
7878
    uint64_t  next_value;
8639
 
 
8640
 
    current = *first_value > col_max_value ? autoinc : *first_value;
 
7879
    uint64_t  col_max_value;
 
7880
 
 
7881
    /* We need the upper limit of the col type to check for
 
7882
    whether we update the table autoinc counter or not. */
 
7883
    col_max_value = innobase_get_int_col_max_value(
 
7884
      table->next_number_field);
 
7885
 
8641
7886
    need = *nb_reserved_values * increment;
8642
7887
 
8643
7888
    /* Compute the last value in the interval */
8644
 
    next_value = innobase_next_autoinc(current, need, offset, col_max_value);
 
7889
    next_value = innobase_next_autoinc(
 
7890
      *first_value, need, offset, col_max_value);
8645
7891
 
8646
7892
    prebuilt->autoinc_last_value = next_value;
8647
7893
 
8678
7924
{
8679
7925
  int error;
8680
7926
 
8681
 
  update_session(getTable()->in_use);
 
7927
  update_session(table->in_use);
8682
7928
 
8683
7929
  error = row_lock_table_autoinc_for_mysql(prebuilt);
8684
7930
 
8703
7949
/* See comment in Cursor.cc */
8704
7950
UNIV_INTERN
8705
7951
bool
8706
 
InnobaseEngine::get_error_message(int, String *buf) const
 
7952
InnobaseEngine::get_error_message(int, String *buf)
8707
7953
{
8708
7954
  trx_t*  trx = check_trx_exists(current_session);
8709
7955
 
8744
7990
  /* Do a type-aware comparison of primary key fields. PK fields
8745
7991
  are always NOT NULL, so no checks for NULL are performed. */
8746
7992
 
8747
 
  key_part = getTable()->key_info[getTable()->getShare()->getPrimaryKey()].key_part;
 
7993
  key_part = table->key_info[table->getShare()->getPrimaryKey()].key_part;
8748
7994
 
8749
7995
  key_part_end = key_part
8750
 
      + getTable()->key_info[getTable()->getShare()->getPrimaryKey()].key_parts;
 
7996
      + table->key_info[table->getShare()->getPrimaryKey()].key_parts;
8751
7997
 
8752
7998
  for (; key_part != key_part_end; ++key_part) {
8753
7999
    field = key_part->field;
8787
8033
finds charset information and returns length of prefix_len characters in the
8788
8034
index field in bytes.
8789
8035
@return number of bytes occupied by the first n characters */
8790
 
UNIV_INTERN
 
8036
extern "C" UNIV_INTERN
8791
8037
ulint
8792
8038
innobase_get_at_most_n_mbchars(
8793
8039
/*===========================*/
8880
8126
  trx->detailed_error[0]= '\0';
8881
8127
 
8882
8128
  /* Set the isolation level of the transaction. */
8883
 
  trx->isolation_level= innobase_map_isolation_level(session->getTxIsolation());
 
8129
  trx->isolation_level= innobase_map_isolation_level(session_tx_isolation(session));
8884
8130
}
8885
8131
 
8886
8132
void
8895
8141
 
8896
8142
  innobase_release_stat_resources(trx);
8897
8143
 
 
8144
  if (! session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
 
8145
  {
 
8146
    if (trx->conc_state != TRX_NOT_STARTED)
 
8147
    {
 
8148
      commit(session, TRUE);
 
8149
    }
 
8150
  }
 
8151
  else
 
8152
  {
 
8153
    if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
 
8154
        trx->global_read_view)
 
8155
    {
 
8156
      /* At low transaction isolation levels we let
 
8157
      each consistent read set its own snapshot */
 
8158
      read_view_close_for_mysql(trx);
 
8159
    }
 
8160
  }
8898
8161
}
8899
8162
 
8900
8163
/*******************************************************************//**
8964
8227
  return(error);
8965
8228
}
8966
8229
 
8967
 
uint64_t InnobaseEngine::doGetCurrentTransactionId(Session *session)
8968
 
{
8969
 
  trx_t *trx= session_to_trx(session);
8970
 
  return (trx->id);
8971
 
}
8972
 
 
8973
 
uint64_t InnobaseEngine::doGetNewTransactionId(Session *session)
8974
 
{
8975
 
  trx_t*& trx = session_to_trx(session);
8976
 
 
8977
 
  if (trx == NULL)
8978
 
  {
8979
 
    trx = innobase_trx_allocate(session);
8980
 
 
8981
 
    innobase_trx_init(session, trx);
8982
 
  }
8983
 
 
8984
 
  mutex_enter(&kernel_mutex);
8985
 
  trx->id= trx_sys_get_new_trx_id();
8986
 
  mutex_exit(&kernel_mutex);
8987
 
 
8988
 
  uint64_t transaction_id= trx->id;
8989
 
 
8990
 
  return transaction_id;
8991
 
}
8992
 
 
8993
8230
/*******************************************************************//**
8994
8231
This function is used to recover X/Open XA distributed transactions.
8995
8232
@return number of prepared transactions stored in xid_list */
9101
8338
}
9102
8339
 
9103
8340
/************************************************************//**
 
8341
Validate the file format check value, is it one of "on" or "off",
 
8342
as a side effect it sets the srv_check_file_format_at_startup variable.
 
8343
@return true if config value one of "on" or  "off" */
 
8344
static
 
8345
bool
 
8346
innobase_file_format_check_on_off(
 
8347
/*==============================*/
 
8348
  const char* format_check) /*!< in: parameter value */
 
8349
{
 
8350
  bool    ret = true;
 
8351
 
 
8352
  if (!innobase_strcasecmp(format_check, "off")) {
 
8353
 
 
8354
    /* Set the value to disable checking. */
 
8355
    srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX + 1;
 
8356
 
 
8357
  } else if (!innobase_strcasecmp(format_check, "on")) {
 
8358
 
 
8359
    /* Set the value to the lowest supported format. */
 
8360
    srv_check_file_format_at_startup = DICT_TF_FORMAT_51;
 
8361
  } else {
 
8362
    ret = FALSE;
 
8363
  }
 
8364
 
 
8365
  return(ret);
 
8366
}
 
8367
 
 
8368
/************************************************************//**
9104
8369
Validate the file format check config parameters, as a side effect it
9105
 
sets the srv_max_file_format_at_startup variable.
9106
 
@return the format_id if valid config value, otherwise, return -1 */
 
8370
sets the srv_check_file_format_at_startup variable.
 
8371
@return true if valid config value */
9107
8372
static
9108
 
int
9109
 
innobase_file_format_validate_and_set(
 
8373
bool
 
8374
innobase_file_format_check_validate(
9110
8375
/*================================*/
9111
 
  const char* format_max) /*!< in: parameter value */
 
8376
  const char* format_check) /*!< in: parameter value */
9112
8377
{
9113
8378
  uint    format_id;
 
8379
  bool    ret = true;
9114
8380
 
9115
 
  format_id = innobase_file_format_name_lookup(format_max);
 
8381
  format_id = innobase_file_format_name_lookup(format_check);
9116
8382
 
9117
8383
  if (format_id < DICT_TF_FORMAT_MAX + 1) {
9118
 
    srv_max_file_format_at_startup = format_id;
9119
 
    return((int) format_id);
9120
 
  } else {
9121
 
    return(-1);
9122
 
  }
9123
 
}
9124
 
 
9125
 
 
 
8384
    srv_check_file_format_at_startup = format_id;
 
8385
  } else {
 
8386
    ret = false;
 
8387
  }
 
8388
 
 
8389
  return(ret);
 
8390
}
 
8391
 
 
8392
/*************************************************************//**
 
8393
Check if it is a valid file format. This function is registered as
 
8394
a callback with MySQL.
 
8395
@return 0 for valid file format */
 
8396
static
 
8397
int
 
8398
innodb_file_format_name_validate(
 
8399
/*=============================*/
 
8400
  Session*      , /*!< in: thread handle */
 
8401
  drizzle_sys_var*  , /*!< in: pointer to system
 
8402
            variable */
 
8403
  void*       save, /*!< out: immediate result
 
8404
            for update function */
 
8405
  drizzle_value*    value)  /*!< in: incoming string */
 
8406
{
 
8407
  const char* file_format_input;
 
8408
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8409
  int   len = sizeof(buff);
 
8410
 
 
8411
  ut_a(save != NULL);
 
8412
  ut_a(value != NULL);
 
8413
 
 
8414
  file_format_input = value->val_str(value, buff, &len);
 
8415
 
 
8416
  if (file_format_input != NULL) {
 
8417
    uint  format_id;
 
8418
 
 
8419
    format_id = innobase_file_format_name_lookup(
 
8420
      file_format_input);
 
8421
 
 
8422
    if (format_id <= DICT_TF_FORMAT_MAX) {
 
8423
 
 
8424
      *static_cast<const char**>(save) = file_format_input;
 
8425
      return(0);
 
8426
    }
 
8427
  }
 
8428
 
 
8429
  *static_cast<const char**>(save) = NULL;
 
8430
  return(1);
 
8431
}
 
8432
 
 
8433
/****************************************************************//**
 
8434
Update the system variable innodb_file_format using the "saved"
 
8435
value. This function is registered as a callback with MySQL. */
 
8436
static
 
8437
void
 
8438
innodb_file_format_name_update(
 
8439
/*===========================*/
 
8440
  Session*      ,   /*!< in: thread handle */
 
8441
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8442
              system variable */
 
8443
  void*       var_ptr,  /*!< out: where the
 
8444
              formal string goes */
 
8445
  const void*     save)   /*!< in: immediate result
 
8446
              from check function */
 
8447
{
 
8448
  const char* format_name;
 
8449
 
 
8450
  ut_a(var_ptr != NULL);
 
8451
  ut_a(save != NULL);
 
8452
 
 
8453
  format_name = *static_cast<const char*const*>(save);
 
8454
 
 
8455
  if (format_name) {
 
8456
    uint  format_id;
 
8457
 
 
8458
    format_id = innobase_file_format_name_lookup(format_name);
 
8459
 
 
8460
    if (format_id <= DICT_TF_FORMAT_MAX) {
 
8461
      srv_file_format = format_id;
 
8462
    }
 
8463
  }
 
8464
 
 
8465
  *static_cast<const char**>(var_ptr)
 
8466
    = trx_sys_file_format_id_to_name(srv_file_format);
 
8467
}
 
8468
 
 
8469
/*************************************************************//**
 
8470
Check if valid argument to innodb_file_format_check. This
 
8471
function is registered as a callback with MySQL.
 
8472
@return 0 for valid file format */
 
8473
static
 
8474
int
 
8475
innodb_file_format_check_validate(
 
8476
/*==============================*/
 
8477
  Session*      , /*!< in: thread handle */
 
8478
  drizzle_sys_var*  , /*!< in: pointer to system
 
8479
            variable */
 
8480
  void*       save, /*!< out: immediate result
 
8481
            for update function */
 
8482
  drizzle_value*    value)  /*!< in: incoming string */
 
8483
{
 
8484
  const char* file_format_input;
 
8485
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8486
  int   len = sizeof(buff);
 
8487
 
 
8488
  ut_a(save != NULL);
 
8489
  ut_a(value != NULL);
 
8490
 
 
8491
  file_format_input = value->val_str(value, buff, &len);
 
8492
 
 
8493
  if (file_format_input != NULL) {
 
8494
 
 
8495
    /* Check if user set on/off, we want to print a suitable
 
8496
    message if they did so. */
 
8497
 
 
8498
    if (innobase_file_format_check_on_off(file_format_input)) {
 
8499
      errmsg_printf(ERRMSG_LVL_WARN, 
 
8500
        "InnoDB: invalid innodb_file_format_check "
 
8501
        "value; on/off can only be set at startup or "
 
8502
        "in the configuration file");
 
8503
    } else if (innobase_file_format_check_validate(
 
8504
        file_format_input)) {
 
8505
 
 
8506
      *static_cast<const char**>(save) = file_format_input;
 
8507
 
 
8508
      return(0);
 
8509
 
 
8510
    } else {
 
8511
      errmsg_printf(ERRMSG_LVL_WARN, 
 
8512
        "InnoDB: invalid innodb_file_format_check "
 
8513
        "value; can be any format up to %s "
 
8514
        "or its equivalent numeric id",
 
8515
        trx_sys_file_format_id_to_name(
 
8516
          DICT_TF_FORMAT_MAX));
 
8517
    }
 
8518
  }
 
8519
 
 
8520
  *static_cast<const char**>(save) = NULL;
 
8521
  return(1);
 
8522
}
 
8523
 
 
8524
/****************************************************************//**
 
8525
Update the system variable innodb_file_format_check using the "saved"
 
8526
value. This function is registered as a callback with MySQL. */
 
8527
static
 
8528
void
 
8529
innodb_file_format_check_update(
 
8530
/*============================*/
 
8531
  Session*      session,  /*!< in: thread handle */
 
8532
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8533
              system variable */
 
8534
  void*       var_ptr,  /*!< out: where the
 
8535
              formal string goes */
 
8536
  const void*     save)   /*!< in: immediate result
 
8537
              from check function */
 
8538
{
 
8539
  const char* format_name_in;
 
8540
  const char**  format_name_out;
 
8541
  uint    format_id;
 
8542
 
 
8543
  ut_a(save != NULL);
 
8544
  ut_a(var_ptr != NULL);
 
8545
 
 
8546
  format_name_in = *static_cast<const char*const*>(save);
 
8547
 
 
8548
  if (!format_name_in) {
 
8549
 
 
8550
    return;
 
8551
  }
 
8552
 
 
8553
  format_id = innobase_file_format_name_lookup(format_name_in);
 
8554
 
 
8555
  if (format_id > DICT_TF_FORMAT_MAX) {
 
8556
    /* DEFAULT is "on", which is invalid at runtime. */
 
8557
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
8558
            ER_WRONG_ARGUMENTS,
 
8559
            "Ignoring SET innodb_file_format=%s",
 
8560
            format_name_in);
 
8561
    return;
 
8562
  }
 
8563
 
 
8564
  format_name_out = static_cast<const char**>(var_ptr);
 
8565
 
 
8566
  /* Update the max format id in the system tablespace. */
 
8567
  if (trx_sys_file_format_max_set(format_id, format_name_out)) {
 
8568
    ut_print_timestamp(stderr);
 
8569
    fprintf(stderr,
 
8570
      " [Info] InnoDB: the file format in the system "
 
8571
      "tablespace is now set to %s.\n", *format_name_out);
 
8572
  }
 
8573
}
 
8574
 
 
8575
/****************************************************************//**
 
8576
Update the system variable innodb_adaptive_hash_index using the "saved"
 
8577
value. This function is registered as a callback with MySQL. */
 
8578
static
 
8579
void
 
8580
innodb_adaptive_hash_index_update(
 
8581
/*==============================*/
 
8582
  Session*      ,   /*!< in: thread handle */
 
8583
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8584
              system variable */
 
8585
  void*       , /*!< out: where the
 
8586
              formal string goes */
 
8587
  const void*     save)   /*!< in: immediate result
 
8588
              from check function */
 
8589
{
 
8590
  if (*(bool*) save) {
 
8591
    btr_search_enable();
 
8592
  } else {
 
8593
    btr_search_disable();
 
8594
  }
 
8595
}
 
8596
 
 
8597
/*************************************************************//**
 
8598
Check if it is a valid value of innodb_change_buffering.  This function is
 
8599
registered as a callback with MySQL.
 
8600
@return 0 for valid innodb_change_buffering */
 
8601
static
 
8602
int
 
8603
innodb_change_buffering_validate(
 
8604
/*=============================*/
 
8605
  Session*      , /*!< in: thread handle */
 
8606
  drizzle_sys_var*  , /*!< in: pointer to system
 
8607
            variable */
 
8608
  void*       save, /*!< out: immediate result
 
8609
            for update function */
 
8610
  drizzle_value*    value)  /*!< in: incoming string */
 
8611
{
 
8612
  const char* change_buffering_input;
 
8613
  char    buff[STRING_BUFFER_USUAL_SIZE];
 
8614
  int   len = sizeof(buff);
 
8615
 
 
8616
  ut_a(save != NULL);
 
8617
  ut_a(value != NULL);
 
8618
 
 
8619
  change_buffering_input = value->val_str(value, buff, &len);
 
8620
 
 
8621
  if (change_buffering_input != NULL) {
 
8622
    ulint use;
 
8623
 
 
8624
    for (use = 0; use < UT_ARR_SIZE(innobase_change_buffering_values);
 
8625
         use++) {
 
8626
      if (!innobase_strcasecmp(
 
8627
            change_buffering_input,
 
8628
            innobase_change_buffering_values[use])) {
 
8629
        *(ibuf_use_t*) save = (ibuf_use_t) use;
 
8630
        return(0);
 
8631
      }
 
8632
    }
 
8633
  }
 
8634
 
 
8635
  return(1);
 
8636
}
 
8637
 
 
8638
/****************************************************************//**
 
8639
Update the system variable innodb_change_buffering using the "saved"
 
8640
value. This function is registered as a callback with MySQL. */
 
8641
static
 
8642
void
 
8643
innodb_change_buffering_update(
 
8644
/*===========================*/
 
8645
  Session*      ,   /*!< in: thread handle */
 
8646
  drizzle_sys_var*  ,   /*!< in: pointer to
 
8647
              system variable */
 
8648
  void*       var_ptr,  /*!< out: where the
 
8649
              formal string goes */
 
8650
  const void*     save)   /*!< in: immediate result
 
8651
              from check function */
 
8652
{
 
8653
  ut_a(var_ptr != NULL);
 
8654
  ut_a(save != NULL);
 
8655
  ut_a((*(ibuf_use_t*) save) < IBUF_USE_COUNT);
 
8656
 
 
8657
  ibuf_use = *(const ibuf_use_t*) save;
 
8658
 
 
8659
  *(const char**) var_ptr = innobase_change_buffering_values[ibuf_use];
 
8660
}
 
8661
 
 
8662
/* plugin options */
 
8663
static DRIZZLE_SYSVAR_BOOL(checksums, innobase_use_checksums,
 
8664
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8665
  "Enable InnoDB checksums validation (enabled by default). ",
 
8666
  NULL, NULL, TRUE);
 
8667
 
 
8668
static DRIZZLE_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
 
8669
  PLUGIN_VAR_READONLY,
 
8670
  "The common part for InnoDB table spaces.",
 
8671
  NULL, NULL, NULL);
 
8672
 
 
8673
static DRIZZLE_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
 
8674
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8675
  "Enable InnoDB doublewrite buffer (enabled by default). ",
 
8676
  NULL, NULL, TRUE);
 
8677
 
 
8678
static DRIZZLE_SYSVAR_ULONG(io_capacity, srv_io_capacity,
 
8679
  PLUGIN_VAR_RQCMDARG,
 
8680
  "Number of IOPs the server can do. Tunes the background IO rate",
 
8681
  NULL, NULL, 200, 100, ~0L, 0);
 
8682
 
 
8683
static DRIZZLE_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
 
8684
  PLUGIN_VAR_OPCMDARG,
 
8685
  "Speeds up the shutdown process of the InnoDB storage engine. Possible "
 
8686
  "values are 0, 1 (faster)"
 
8687
  " or 2 (fastest - crash-like)"
 
8688
  ".",
 
8689
  NULL, NULL, 1, 0, 2, 0);
 
8690
 
 
8691
static DRIZZLE_SYSVAR_BOOL(file_per_table, srv_file_per_table,
 
8692
  PLUGIN_VAR_NOCMDARG,
 
8693
  "Stores each InnoDB table to an .ibd file in the database dir.",
 
8694
  NULL, NULL, FALSE);
 
8695
 
 
8696
static DRIZZLE_SYSVAR_STR(file_format, innobase_file_format_name,
 
8697
  PLUGIN_VAR_RQCMDARG,
 
8698
  "File format to use for new tables in .ibd files.",
 
8699
  innodb_file_format_name_validate,
 
8700
  innodb_file_format_name_update, "Antelope");
 
8701
 
 
8702
static DRIZZLE_SYSVAR_STR(file_format_check, innobase_file_format_check,
 
8703
  PLUGIN_VAR_OPCMDARG,
 
8704
  "The highest file format in the tablespace.",
 
8705
  innodb_file_format_check_validate,
 
8706
  innodb_file_format_check_update,
 
8707
  "on");
 
8708
 
 
8709
static DRIZZLE_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
 
8710
  PLUGIN_VAR_OPCMDARG,
 
8711
  "Set to 0 (write and flush once per second),"
 
8712
  " 1 (write and flush at each commit)"
 
8713
  " or 2 (write at commit, flush once per second).",
 
8714
  NULL, NULL, 1, 0, 2, 0);
 
8715
 
 
8716
static DRIZZLE_SYSVAR_STR(flush_method, innobase_unix_file_flush_method,
 
8717
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8718
  "With which method to flush data.", NULL, NULL, NULL);
 
8719
 
 
8720
#ifdef UNIV_LOG_ARCHIVE
 
8721
static DRIZZLE_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
 
8722
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8723
  "Where full logs should be archived.", NULL, NULL, NULL);
 
8724
 
 
8725
static DRIZZLE_SYSVAR_BOOL(log_archive, innobase_log_archive,
 
8726
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
 
8727
  "Set to 1 if you want to have logs archived.", NULL, NULL, FALSE);
 
8728
#endif /* UNIV_LOG_ARCHIVE */
 
8729
 
 
8730
static DRIZZLE_SYSVAR_STR(log_group_home_dir, innobase_log_group_home_dir,
 
8731
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8732
  "Path to InnoDB log files.", NULL, NULL, NULL);
 
8733
 
 
8734
static DRIZZLE_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
 
8735
  PLUGIN_VAR_RQCMDARG,
 
8736
  "Percentage of dirty pages allowed in bufferpool.",
 
8737
  NULL, NULL, 75, 0, 99, 0);
 
8738
 
 
8739
static DRIZZLE_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
 
8740
  PLUGIN_VAR_NOCMDARG,
 
8741
  "Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
 
8742
  NULL, NULL, TRUE);
 
8743
 
 
8744
static DRIZZLE_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
 
8745
  PLUGIN_VAR_RQCMDARG,
 
8746
  "Desired maximum length of the purge queue (0 = no limit)",
 
8747
  NULL, NULL, 0, 0, ~0L, 0);
 
8748
 
 
8749
static DRIZZLE_SYSVAR_BOOL(status_file, innobase_create_status_file,
 
8750
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_NOSYSVAR,
 
8751
  "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file",
 
8752
  NULL, NULL, FALSE);
 
8753
 
 
8754
static DRIZZLE_SYSVAR_BOOL(stats_on_metadata, innobase_stats_on_metadata,
 
8755
  PLUGIN_VAR_OPCMDARG,
 
8756
  "Enable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)",
 
8757
  NULL, NULL, TRUE);
 
8758
 
 
8759
static DRIZZLE_SYSVAR_ULONGLONG(stats_sample_pages, srv_stats_sample_pages,
 
8760
  PLUGIN_VAR_RQCMDARG,
 
8761
  "The number of index pages to sample when calculating statistics (default 8)",
 
8762
  NULL, NULL, 8, 1, ~0ULL, 0);
 
8763
 
 
8764
static DRIZZLE_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
 
8765
  PLUGIN_VAR_OPCMDARG,
 
8766
  "Enable InnoDB adaptive hash index (enabled by default).",
 
8767
  NULL, innodb_adaptive_hash_index_update, TRUE);
 
8768
 
 
8769
static DRIZZLE_SYSVAR_ULONG(replication_delay, srv_replication_delay,
 
8770
  PLUGIN_VAR_RQCMDARG,
 
8771
  "Replication thread delay (ms) on the slave server if "
 
8772
  "innodb_thread_concurrency is reached (0 by default)",
 
8773
  NULL, NULL, 0, 0, ~0UL, 0);
 
8774
 
 
8775
static DRIZZLE_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
 
8776
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8777
  "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
 
8778
  NULL, NULL, 8*1024*1024L, 512*1024L, LONG_MAX, 1024);
 
8779
 
 
8780
static DRIZZLE_SYSVAR_UINT(autoextend_increment, srv_auto_extend_increment,
 
8781
  PLUGIN_VAR_RQCMDARG,
 
8782
  "Data file autoextend increment in megabytes",
 
8783
  NULL, NULL, 8L, 1L, 1000L, 0);
 
8784
 
 
8785
static DRIZZLE_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
 
8786
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8787
  "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
 
8788
  NULL, NULL, 128*1024*1024L, 5*1024*1024L, INT64_MAX, 1024*1024L);
 
8789
 
 
8790
static DRIZZLE_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
 
8791
  PLUGIN_VAR_RQCMDARG,
 
8792
  "Helps in performance tuning in heavily concurrent environments.",
 
8793
  innobase_commit_concurrency_validate, NULL, 0, 0, 1000, 0);
 
8794
 
 
8795
static DRIZZLE_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
 
8796
  PLUGIN_VAR_RQCMDARG,
 
8797
  "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket",
 
8798
  NULL, NULL, 500L, 1L, ~0L, 0);
 
8799
 
 
8800
static DRIZZLE_SYSVAR_LONG(file_io_threads, innobase_file_io_threads,
 
8801
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8802
  "Number of file I/O threads in InnoDB.",
 
8803
  NULL, NULL, 4, 4, 64, 0);
 
8804
 
 
8805
static DRIZZLE_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads,
 
8806
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8807
  "Number of background read I/O threads in InnoDB.",
 
8808
  NULL, NULL, 4, 1, 64, 0);
 
8809
 
 
8810
static DRIZZLE_SYSVAR_ULONG(write_io_threads, innobase_write_io_threads,
 
8811
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8812
  "Number of background write I/O threads in InnoDB.",
 
8813
  NULL, NULL, 4, 1, 64, 0);
 
8814
 
 
8815
static DRIZZLE_SYSVAR_LONG(force_recovery, innobase_force_recovery,
 
8816
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8817
  "Helps to save your data in case the disk image of the database becomes corrupt.",
 
8818
  NULL, NULL, 0, 0, 6, 0);
 
8819
 
 
8820
static DRIZZLE_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size,
 
8821
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8822
  "The size of the buffer which InnoDB uses to write log to the log files on disk.",
 
8823
  NULL, NULL, 8*1024*1024L, 256*1024L, LONG_MAX, 1024);
 
8824
 
 
8825
static DRIZZLE_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size,
 
8826
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8827
  "Size of each log file in a log group.",
 
8828
  NULL, NULL, 20*1024*1024L, 1*1024*1024L, INT64_MAX, 1024*1024L);
 
8829
 
 
8830
static DRIZZLE_SYSVAR_LONG(log_files_in_group, innobase_log_files_in_group,
 
8831
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8832
  "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.",
 
8833
  NULL, NULL, 2, 2, 100, 0);
 
8834
 
 
8835
static DRIZZLE_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups,
 
8836
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8837
  "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
 
8838
  NULL, NULL, 1, 1, 10, 0);
 
8839
 
 
8840
static DRIZZLE_SYSVAR_LONG(open_files, innobase_open_files,
 
8841
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8842
  "How many files at the maximum InnoDB keeps open at the same time.",
 
8843
  NULL, NULL, 300L, 10L, LONG_MAX, 0);
 
8844
 
 
8845
static DRIZZLE_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
 
8846
  PLUGIN_VAR_RQCMDARG,
 
8847
  "Count of spin-loop rounds in InnoDB mutexes (30 by default)",
 
8848
  NULL, NULL, 30L, 0L, ~0L, 0);
 
8849
 
 
8850
static DRIZZLE_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay,
 
8851
  PLUGIN_VAR_OPCMDARG,
 
8852
  "Maximum delay between polling for a spin lock (6 by default)",
 
8853
  NULL, NULL, 6L, 0L, ~0L, 0);
 
8854
 
 
8855
static DRIZZLE_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
 
8856
  PLUGIN_VAR_RQCMDARG,
 
8857
  "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.",
 
8858
  NULL, NULL, 0, 0, 1000, 0);
 
8859
 
 
8860
static DRIZZLE_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay,
 
8861
  PLUGIN_VAR_RQCMDARG,
 
8862
  "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep",
 
8863
  NULL, NULL, 10000L, 0L, ~0L, 0);
 
8864
 
 
8865
static DRIZZLE_SYSVAR_STR(data_file_path, innobase_data_file_path,
 
8866
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
 
8867
  "Path to individual files and their sizes.",
 
8868
  NULL, NULL, NULL);
 
8869
 
 
8870
static DRIZZLE_SYSVAR_STR(version, innodb_version_str,
 
8871
  PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
 
8872
  "InnoDB version", NULL, NULL, INNODB_VERSION_STR);
 
8873
 
 
8874
static DRIZZLE_SYSVAR_BOOL(use_sys_malloc, srv_use_sys_malloc,
 
8875
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8876
  "Use OS memory allocator instead of InnoDB's internal memory allocator",
 
8877
  NULL, NULL, TRUE);
 
8878
 
 
8879
static DRIZZLE_SYSVAR_STR(change_buffering, innobase_change_buffering,
 
8880
  PLUGIN_VAR_RQCMDARG,
 
8881
  "Buffer changes to reduce random access: "
 
8882
  "OFF, ON, inserting, deleting, changing, or purging.",
 
8883
  innodb_change_buffering_validate,
 
8884
  innodb_change_buffering_update, NULL);
 
8885
 
 
8886
static DRIZZLE_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
 
8887
  PLUGIN_VAR_RQCMDARG,
 
8888
  "Number of pages that must be accessed sequentially for InnoDB to"
 
8889
  "trigger a readahead.",
 
8890
  NULL, NULL, 56, 0, 64, 0);
9126
8891
 
9127
8892
static void init_options(drizzled::module::option_context &context)
9128
8893
{
9129
 
  context("disable-checksums",
9130
 
          "Disable InnoDB checksums validation.");
 
8894
  context("checksums",
 
8895
          po::value<bool>(&innobase_use_checksums)->default_value(true)->zero_tokens(),
 
8896
          "Enable InnoDB checksums validation.");
9131
8897
  context("data-home-dir",
9132
8898
          po::value<string>(),
9133
8899
          "The common part for InnoDB table spaces.");
9134
 
  context("disable-doublewrite",
9135
 
          "Disable InnoDB doublewrite buffer.");
 
8900
  context("doublewrite",
 
8901
          po::value<bool>(&innobase_use_doublewrite)->default_value(true)->zero_tokens(),
 
8902
          "Enable InnoDB doublewrite buffer.");
9136
8903
  context("io-capacity",
9137
 
          po::value<io_capacity_constraint>(&innodb_io_capacity)->default_value(200),
 
8904
          po::value<unsigned long>(&srv_io_capacity)->default_value(200),
9138
8905
          "Number of IOPs the server can do. Tunes the background IO rate");
9139
8906
  context("fast-shutdown",
9140
 
          po::value<trinary_constraint>(&innobase_fast_shutdown)->default_value(1), 
 
8907
          po::value<unsigned long>(&innobase_fast_shutdown)->default_value(1), 
9141
8908
          "Speeds up the shutdown process of the InnoDB storage engine. Possible values are 0, 1 (faster) or 2 (fastest - crash-like).");
9142
 
  context("purge-batch-size",
9143
 
          po::value<purge_batch_constraint>(&innodb_purge_batch_size)->default_value(20),
9144
 
          "Number of UNDO logs to purge in one batch from the history list. "
9145
 
          "Default is 20.");
9146
 
  context("purge-threads",
9147
 
          po::value<purge_threads_constraint>(&innodb_n_purge_threads)->default_value(0),
9148
 
          "Purge threads can be either 0 or 1. Defalut is 0.");
9149
8909
  context("file-per-table",
9150
8910
          po::value<bool>(&srv_file_per_table)->default_value(false)->zero_tokens(),
9151
 
           "Stores each InnoDB table to an .ibd file in the database dir.");
9152
 
  context("file-format-max",
9153
 
          po::value<string>(&innobase_file_format_max)->default_value("Antelope"),
9154
 
          "The highest file format in the tablespace.");
9155
 
  context("file-format-check",
9156
 
          po::value<bool>(&innobase_file_format_check)->default_value(true)->zero_tokens(),
9157
 
          "Whether to perform system file format check.");
 
8911
          "Stores each InnoDB table to an .ibd file in the database dir.");
9158
8912
  context("file-format",
9159
 
          po::value<string>(&innobase_file_format_name)->default_value("Antelope"),
 
8913
          po::value<string>()->default_value("Antelope"),
9160
8914
          "File format to use for new tables in .ibd files.");
 
8915
  context("file-format-check",
 
8916
          po::value<string>()->default_value("on"),
 
8917
          "The highest file format in the tablespace.");
9161
8918
  context("flush-log-at-trx-commit",
9162
 
          po::value<trinary_constraint>(&innodb_flush_log_at_trx_commit)->default_value(1),
 
8919
          po::value<unsigned long>(&srv_flush_log_at_trx_commit)->default_value(1),
9163
8920
          "Set to 0 (write and flush once per second), 1 (write and flush at each commit) or 2 (write at commit, flush once per second).");
9164
8921
  context("flush-method",
9165
8922
          po::value<string>(),
9166
8923
          "With which method to flush data.");
 
8924
#ifdef UNIV_LOG_ARCHIVE
 
8925
  context("log-arch-dir",
 
8926
          po::value<string>(),
 
8927
          "Where full logs should be archived.");
 
8928
  context("log-archive",
 
8929
          po::value<bool>(&innobase_log_archive)->default_value(false)->zero_tokens(),
 
8930
          "Set to 1 if you want to have logs archived.");
 
8931
#endif /* UNIV_LOG_ARCHIVE */
9167
8932
  context("log-group-home-dir",
9168
8933
          po::value<string>(),
9169
8934
          "Path to InnoDB log files.");
9170
8935
  context("max-dirty-pages-pct",
9171
 
          po::value<max_dirty_pages_constraint>(&innodb_max_dirty_pages_pct)->default_value(75),
 
8936
          po::value<unsigned long>(&srv_max_buf_pool_modified_pct)->default_value(75),
9172
8937
          "Percentage of dirty pages allowed in bufferpool.");
9173
 
  context("disable-adaptive-flushing",
9174
 
          "Do not attempt flushing dirty pages to avoid IO bursts at checkpoints.");
 
8938
  context("adaptive-flushing",
 
8939
          po::value<bool>(&srv_adaptive_flushing)->default_value(true)->zero_tokens(),
 
8940
          "Attempt flushing dirty pages to avoid IO bursts at checkpoints.");
9175
8941
  context("max-purge-lag",
9176
 
          po::value<uint64_constraint>(&innodb_max_purge_lag)->default_value(0),
 
8942
          po::value<unsigned long>(&srv_max_purge_lag)->default_value(0),
9177
8943
          "Desired maximum length of the purge queue (0 = no limit)");
9178
8944
  context("status-file",
9179
8945
          po::value<bool>(&innobase_create_status_file)->default_value(false)->zero_tokens(),
9180
8946
          "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file");
9181
 
  context("disable-stats-on-metadata",
9182
 
          "Disable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)");
 
8947
  context("stats-on-metadata",
 
8948
          po::value<bool>(&innobase_stats_on_metadata)->default_value(true)->zero_tokens(),
 
8949
          "Enable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)");
9183
8950
  context("stats-sample-pages",
9184
 
          po::value<uint64_nonzero_constraint>(&innodb_stats_sample_pages)->default_value(8),
 
8951
          po::value<uint64_t>(&srv_stats_sample_pages)->default_value(8),
9185
8952
          "The number of index pages to sample when calculating statistics (default 8)");
9186
 
  context("disable-adaptive-hash-index",
 
8953
  context("adaptive-hash-index",
 
8954
          po::value<bool>(&btr_search_enabled)->default_value(true)->zero_tokens(),
9187
8955
          "Enable InnoDB adaptive hash index (enabled by default)");
9188
8956
  context("replication-delay",
9189
 
          po::value<uint64_constraint>(&innodb_replication_delay)->default_value(0),
 
8957
          po::value<unsigned long>(&srv_replication_delay)->default_value(0),
9190
8958
          "Replication thread delay (ms) on the slave server if innodb_thread_concurrency is reached (0 by default)");
9191
8959
  context("additional-mem-pool-size",
9192
 
          po::value<additional_mem_pool_constraint>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
 
8960
          po::value<long>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
9193
8961
          "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.");
9194
8962
  context("autoextend-increment",
9195
 
          po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(64L),
 
8963
          po::value<uint32_t>(&srv_auto_extend_increment)->default_value(8L),
9196
8964
          "Data file autoextend increment in megabytes");
9197
8965
  context("buffer-pool-size",
9198
 
          po::value<buffer_pool_constraint>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
 
8966
          po::value<int64_t>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
9199
8967
          "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.");
9200
 
  context("buffer-pool-instances",
9201
 
          po::value<buffer_pool_instances_constraint>(&innobase_buffer_pool_instances)->default_value(1),
9202
 
          "Number of buffer pool instances, set to higher value on high-end machines to increase scalability");
9203
 
 
9204
8968
  context("commit-concurrency",
9205
 
          po::value<concurrency_constraint>(&innobase_commit_concurrency)->default_value(0),
 
8969
          po::value<unsigned long>(&innobase_commit_concurrency)->default_value(0),
9206
8970
          "Helps in performance tuning in heavily concurrent environments.");
9207
8971
  context("concurrency-tickets",
9208
 
          po::value<uint32_nonzero_constraint>(&innodb_concurrency_tickets)->default_value(500L),
 
8972
          po::value<unsigned long>(&srv_n_free_tickets_to_enter)->default_value(500L),
9209
8973
          "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket");
 
8974
  context("file-io-threads",
 
8975
          po::value<long>(&innobase_file_io_threads)->default_value(4),
 
8976
          "Number of file I/O threads in InnoDB.");
9210
8977
  context("read-io-threads",
9211
 
          po::value<io_threads_constraint>(&innobase_read_io_threads)->default_value(4),
 
8978
          po::value<unsigned long>(&innobase_read_io_threads)->default_value(4),
9212
8979
          "Number of background read I/O threads in InnoDB.");
9213
8980
  context("write-io-threads",
9214
 
          po::value<io_threads_constraint>(&innobase_write_io_threads)->default_value(4),
 
8981
          po::value<unsigned long>(&innobase_write_io_threads)->default_value(4),
9215
8982
          "Number of background write I/O threads in InnoDB.");
9216
8983
  context("force-recovery",
9217
 
          po::value<force_recovery_constraint>(&innobase_force_recovery)->default_value(0),
 
8984
          po::value<long>(&innobase_force_recovery)->default_value(0),
9218
8985
          "Helps to save your data in case the disk image of the database becomes corrupt.");
9219
8986
  context("log-buffer-size",
9220
 
          po::value<log_buffer_constraint>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
 
8987
          po::value<long>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
9221
8988
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9222
8989
  context("log-file-size",
9223
 
          po::value<log_file_constraint>(&innobase_log_file_size)->default_value(20*1024*1024L),
 
8990
          po::value<int64_t>(&innobase_log_file_size)->default_value(20*1024*1024L),
9224
8991
          "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9225
8992
  context("log-files-in-group",
9226
 
          po::value<log_files_in_group_constraint>(&innobase_log_files_in_group)->default_value(2),
 
8993
          po::value<long>(&innobase_log_files_in_group)->default_value(2),
9227
8994
          "Number of log files in the log group. InnoDB writes to the files in a circular fashion.");
9228
8995
  context("mirrored-log-groups",
9229
 
          po::value<mirrored_log_groups_constraint>(&innobase_mirrored_log_groups)->default_value(1),
 
8996
          po::value<long>(&innobase_mirrored_log_groups)->default_value(1),
9230
8997
          "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.");
9231
8998
  context("open-files",
9232
 
          po::value<open_files_constraint>(&innobase_open_files)->default_value(300L),
 
8999
          po::value<long>(&innobase_open_files)->default_value(300L),
9233
9000
          "How many files at the maximum InnoDB keeps open at the same time.");
9234
9001
  context("sync-spin-loops",
9235
 
          po::value<uint32_constraint>(&innodb_sync_spin_loops)->default_value(30L),
 
9002
          po::value<unsigned long>(&srv_n_spin_wait_rounds)->default_value(30L),
9236
9003
          "Count of spin-loop rounds in InnoDB mutexes (30 by default)");
9237
9004
  context("spin-wait-delay",
9238
 
          po::value<uint32_constraint>(&innodb_spin_wait_delay)->default_value(6L),
 
9005
          po::value<unsigned long>(&srv_spin_wait_delay)->default_value(6L),
9239
9006
          "Maximum delay between polling for a spin lock (6 by default)");
9240
9007
  context("thread-concurrency",
9241
 
          po::value<concurrency_constraint>(&innobase_thread_concurrency)->default_value(0),
 
9008
          po::value<unsigned long>(&srv_thread_concurrency)->default_value(0),
9242
9009
          "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.");
9243
9010
  context("thread-sleep-delay",
9244
 
          po::value<uint32_constraint>(&innodb_thread_sleep_delay)->default_value(10000L),
 
9011
          po::value<unsigned long>(&srv_thread_sleep_delay)->default_value(10000L),
9245
9012
          "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep");
9246
9013
  context("data-file-path",
9247
9014
          po::value<string>(),
9249
9016
  context("version",
9250
9017
          po::value<string>()->default_value(INNODB_VERSION_STR),
9251
9018
          "InnoDB version");
9252
 
  context("use-internal-malloc",
9253
 
          "Use InnoDB's internal memory allocator instal of the OS memory allocator.");
9254
 
  context("disable-native-aio",
9255
 
          _("Do not use Native AIO library for IO, even if available"));
 
9019
  context("use-sys-malloc",
 
9020
          po::value<bool>(&srv_use_sys_malloc)->default_value(true)->zero_tokens(),
 
9021
          "Use OS memory allocator instead of InnoDB's internal memory allocator");
9256
9022
  context("change-buffering",
9257
 
          po::value<string>(&innobase_change_buffering),
 
9023
          po::value<string>(),
9258
9024
          "Buffer changes to reduce random access: OFF, ON, inserting, deleting, changing, or purging.");
9259
9025
  context("read-ahead-threshold",
9260
 
          po::value<read_ahead_threshold_constraint>(&innodb_read_ahead_threshold)->default_value(56),
 
9026
          po::value<unsigned long>(&srv_read_ahead_threshold)->default_value(56),
9261
9027
          "Number of pages that must be accessed sequentially for InnoDB to trigger a readahead.");
9262
 
  context("disable-xa",
9263
 
          "Disable InnoDB support for the XA two-phase commit");
9264
 
  context("disable-table-locks",
9265
 
          "Disable InnoDB locking in LOCK TABLES");
 
9028
  context("support-xa",
 
9029
          po::value<bool>()->default_value(true)->zero_tokens(),
 
9030
          "Enable InnoDB support for the XA two-phase commit");
 
9031
  context("table-locks",
 
9032
          po::value<bool>()->default_value(true)->zero_tokens(),
 
9033
          "Enable InnoDB locking in LOCK TABLES");
9266
9034
  context("strict-mode",
9267
 
          po::value<bool>(&strict_mode)->default_value(false)->zero_tokens(),
 
9035
          po::value<bool>()->default_value(false)->zero_tokens(),
9268
9036
          "Use strict mode when evaluating create options.");
9269
 
  context("replication-log",
9270
 
          po::value<bool>(&innobase_use_replication_log)->default_value(false),
9271
 
          _("Enable internal replication log."));
9272
9037
  context("lock-wait-timeout",
9273
 
          po::value<lock_wait_constraint>(&lock_wait_timeout)->default_value(50),
9274
 
          _("Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout."));
9275
 
  context("old-blocks-pct",
9276
 
          po::value<old_blocks_constraint>(&innobase_old_blocks_pct)->default_value(100 * 3 / 8),
9277
 
          _("Percentage of the buffer pool to reserve for 'old' blocks."));
9278
 
  context("old-blocks-time",
9279
 
          po::value<uint32_t>(&buf_LRU_old_threshold_ms)->default_value(0),
9280
 
          _("ove blocks to the 'new' end of the buffer pool if the first access"
9281
 
            " was at least this many milliseconds ago."
9282
 
            " The timeout is disabled if 0 (the default)."));
 
9038
          po::value<unsigned long>()->default_value(50),
 
9039
          "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.");
9283
9040
}
9284
9041
 
9285
 
 
 
9042
static drizzle_sys_var* innobase_system_variables[]= {
 
9043
  DRIZZLE_SYSVAR(additional_mem_pool_size),
 
9044
  DRIZZLE_SYSVAR(autoextend_increment),
 
9045
  DRIZZLE_SYSVAR(buffer_pool_size),
 
9046
  DRIZZLE_SYSVAR(checksums),
 
9047
  DRIZZLE_SYSVAR(commit_concurrency),
 
9048
  DRIZZLE_SYSVAR(concurrency_tickets),
 
9049
  DRIZZLE_SYSVAR(data_file_path),
 
9050
  DRIZZLE_SYSVAR(data_home_dir),
 
9051
  DRIZZLE_SYSVAR(doublewrite),
 
9052
  DRIZZLE_SYSVAR(fast_shutdown),
 
9053
  DRIZZLE_SYSVAR(file_io_threads),
 
9054
  DRIZZLE_SYSVAR(read_io_threads),
 
9055
  DRIZZLE_SYSVAR(write_io_threads),
 
9056
  DRIZZLE_SYSVAR(file_per_table),
 
9057
  DRIZZLE_SYSVAR(file_format),
 
9058
  DRIZZLE_SYSVAR(file_format_check),
 
9059
  DRIZZLE_SYSVAR(flush_log_at_trx_commit),
 
9060
  DRIZZLE_SYSVAR(flush_method),
 
9061
  DRIZZLE_SYSVAR(force_recovery),
 
9062
  DRIZZLE_SYSVAR(lock_wait_timeout),
 
9063
#ifdef UNIV_LOG_ARCHIVE
 
9064
  DRIZZLE_SYSVAR(log_arch_dir),
 
9065
  DRIZZLE_SYSVAR(log_archive),
 
9066
#endif /* UNIV_LOG_ARCHIVE */
 
9067
  DRIZZLE_SYSVAR(log_buffer_size),
 
9068
  DRIZZLE_SYSVAR(log_file_size),
 
9069
  DRIZZLE_SYSVAR(log_files_in_group),
 
9070
  DRIZZLE_SYSVAR(log_group_home_dir),
 
9071
  DRIZZLE_SYSVAR(max_dirty_pages_pct),
 
9072
  DRIZZLE_SYSVAR(max_purge_lag),
 
9073
  DRIZZLE_SYSVAR(adaptive_flushing),
 
9074
  DRIZZLE_SYSVAR(mirrored_log_groups),
 
9075
  DRIZZLE_SYSVAR(open_files),
 
9076
  DRIZZLE_SYSVAR(stats_on_metadata),
 
9077
  DRIZZLE_SYSVAR(stats_sample_pages),
 
9078
  DRIZZLE_SYSVAR(adaptive_hash_index),
 
9079
  DRIZZLE_SYSVAR(replication_delay),
 
9080
  DRIZZLE_SYSVAR(status_file),
 
9081
  DRIZZLE_SYSVAR(strict_mode),
 
9082
  DRIZZLE_SYSVAR(support_xa),
 
9083
  DRIZZLE_SYSVAR(sync_spin_loops),
 
9084
  DRIZZLE_SYSVAR(spin_wait_delay),
 
9085
  DRIZZLE_SYSVAR(table_locks),
 
9086
  DRIZZLE_SYSVAR(thread_concurrency),
 
9087
  DRIZZLE_SYSVAR(thread_sleep_delay),
 
9088
  DRIZZLE_SYSVAR(version),
 
9089
  DRIZZLE_SYSVAR(use_sys_malloc),
 
9090
  DRIZZLE_SYSVAR(change_buffering),
 
9091
  DRIZZLE_SYSVAR(read_ahead_threshold),
 
9092
  DRIZZLE_SYSVAR(io_capacity),
 
9093
  NULL
 
9094
};
9286
9095
 
9287
9096
DRIZZLE_DECLARE_PLUGIN
9288
9097
{
9293
9102
  "Supports transactions, row-level locking, and foreign keys",
9294
9103
  PLUGIN_LICENSE_GPL,
9295
9104
  innobase_init, /* Plugin Init */
9296
 
  NULL, /* depends */
 
9105
  innobase_system_variables, /* system variables */
9297
9106
  init_options /* reserved */
9298
9107
}
9299
9108
DRIZZLE_DECLARE_PLUGIN_END;
9321
9130
  return res;
9322
9131
}
9323
9132
 
9324
 
/***********************************************************************
9325
 
This function checks each index name for a table against reserved
9326
 
system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
9327
 
this function pushes an warning message to the client, and returns true. */
9328
 
UNIV_INTERN
9329
 
bool
9330
 
innobase_index_name_is_reserved(
9331
 
/*============================*/
9332
 
                                        /* out: true if an index name
9333
 
                                        matches the reserved name */
9334
 
        const trx_t*    trx,            /* in: InnoDB transaction handle */
9335
 
        const KeyInfo*  key_info,       /* in: Indexes to be created */
9336
 
        ulint           num_of_keys)    /* in: Number of indexes to
9337
 
                                        be created. */
 
9133
/** @brief Initialize the default value of innodb_commit_concurrency.
 
9134
 
 
9135
Once InnoDB is running, the innodb_commit_concurrency must not change
 
9136
from zero to nonzero. (Bug #42101)
 
9137
 
 
9138
The initial default value is 0, and without this extra initialization,
 
9139
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
 
9140
to 0, even if it was initially set to nonzero at the command line
 
9141
or configuration file. */
 
9142
static
 
9143
void
 
9144
innobase_commit_concurrency_init_default(void)
 
9145
/*==========================================*/
9338
9146
{
9339
 
  const KeyInfo*        key;
9340
 
  uint          key_num;        /* index number */
9341
 
 
9342
 
  for (key_num = 0; key_num < num_of_keys; key_num++) {
9343
 
    key = &key_info[key_num];
9344
 
 
9345
 
    if (innobase_strcasecmp(key->name,
9346
 
                            innobase_index_reserve_name) == 0) {
9347
 
      /* Push warning to drizzle */
9348
 
      push_warning_printf(trx->mysql_thd,
9349
 
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
9350
 
                          ER_WRONG_NAME_FOR_INDEX,
9351
 
                          "Cannot Create Index with name "
9352
 
                          "'%s'. The name is reserved "
9353
 
                          "for the system default primary "
9354
 
                          "index.",
9355
 
                          innobase_index_reserve_name);
9356
 
 
9357
 
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
9358
 
               innobase_index_reserve_name);
9359
 
 
9360
 
      return(true);
9361
 
    }
9362
 
  }
9363
 
 
9364
 
  return(false);
 
9147
  DRIZZLE_SYSVAR_NAME(commit_concurrency).def_val
 
9148
    = innobase_commit_concurrency;
9365
9149
}
9366
9150
 
9367
9151
#ifdef UNIV_COMPILE_TEST_FUNCS
9371
9155
  ulint   buflen;
9372
9156
  const char* id;
9373
9157
  ulint   idlen;
9374
 
  drizzled::Session *session;
 
9158
  void*   session;
9375
9159
  ibool   file_id;
9376
9160
 
9377
9161
  const char* expected;