~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Merge with trunk.

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, 2010, MySQL AB & Innobase Oy. All Rights Reserved.
 
4
Copyright (C) 2008, 2009 Google Inc.
 
5
Copyright (C) 2009, Percona Inc.
6
6
 
7
7
Portions of this file contain modifications contributed and copyrighted by
8
8
Google, Inc. Those modifications are gratefully acknowledged and are described
60
60
#include "drizzled/table.h"
61
61
#include "drizzled/field/blob.h"
62
62
#include "drizzled/field/varstring.h"
63
 
#include "drizzled/field/timestamp.h"
64
63
#include "drizzled/plugin/xa_storage_engine.h"
65
64
#include "drizzled/plugin/daemon.h"
66
65
#include "drizzled/memory/multi_malloc.h"
72
71
 
73
72
#include <boost/algorithm/string.hpp>
74
73
#include <boost/program_options.hpp>
 
74
#include <boost/scoped_array.hpp>
75
75
#include <boost/filesystem.hpp>
76
76
#include <drizzled/module/option_map.h>
77
77
#include <iostream>
83
83
/** @file ha_innodb.cc */
84
84
 
85
85
/* Include necessary InnoDB headers */
86
 
extern "C" {
87
86
#include "univ.i"
88
87
#include "buf0lru.h"
89
88
#include "btr0sea.h"
115
114
#include "ha_prototypes.h"
116
115
#include "ut0mem.h"
117
116
#include "ibuf0ibuf.h"
118
 
#include "mysql_addons.h"
119
 
}
120
117
 
121
118
#include "ha_innodb.h"
122
119
#include "data_dictionary.h"
136
133
#include <google/protobuf/io/coded_stream.h>
137
134
#include <google/protobuf/text_format.h>
138
135
 
 
136
#include <boost/thread/mutex.hpp>
 
137
 
139
138
using namespace std;
140
139
using namespace drizzled;
141
140
 
142
141
/** to protect innobase_open_files */
143
 
static pthread_mutex_t innobase_share_mutex;
 
142
static boost::mutex innobase_share_mutex;
 
143
 
144
144
/** to force correct commit order in binlog */
145
 
static pthread_mutex_t prepare_commit_mutex;
146
145
static ulong commit_threads = 0;
147
 
static pthread_mutex_t commit_threads_m;
148
 
static pthread_cond_t commit_cond;
149
 
static pthread_mutex_t commit_cond_m;
 
146
static boost::condition_variable commit_cond;
 
147
static boost::mutex commit_cond_m;
150
148
static bool innodb_inited = 0;
151
149
 
152
150
#define INSIDE_HA_INNOBASE_CC
162
160
#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
163
161
 
164
162
static plugin::XaStorageEngine* innodb_engine_ptr= NULL;
165
 
static plugin::TableFunction* status_table_function_ptr= NULL;
166
 
static plugin::TableFunction* cmp_tool= NULL;
167
 
static plugin::TableFunction* cmp_reset_tool= NULL;
168
 
static plugin::TableFunction* cmp_mem_tool= NULL;
169
 
static plugin::TableFunction* cmp_mem_reset_tool= NULL;
170
 
static plugin::TableFunction* innodb_trx_tool= NULL;
171
 
static plugin::TableFunction* innodb_locks_tool= NULL;
172
 
static plugin::TableFunction* innodb_lock_waits_tool= NULL;
173
 
static plugin::TableFunction* innodb_sys_tables_tool= NULL;
174
 
static plugin::TableFunction* innodb_sys_tablestats_tool= NULL;
175
 
 
176
 
static plugin::TableFunction* innodb_sys_indexes_tool= NULL;
177
 
static plugin::TableFunction* innodb_sys_columns_tool= NULL;
178
 
static plugin::TableFunction* innodb_sys_fields_tool= NULL;
179
 
static plugin::TableFunction* innodb_sys_foreign_tool= NULL;
180
 
static plugin::TableFunction* innodb_sys_foreign_cols_tool= NULL;
181
 
 
182
 
static ReplicationLog *replication_logger= NULL;
 
163
 
183
164
typedef constrained_check<uint32_t, UINT32_MAX, 10> open_files_constraint;
184
165
static open_files_constraint innobase_open_files;
185
166
typedef constrained_check<uint32_t, 10, 1> mirrored_log_groups_constraint;
204
185
static purge_batch_constraint innodb_purge_batch_size;
205
186
typedef constrained_check<uint32_t, 1, 0> purge_threads_constraint;
206
187
static purge_threads_constraint innodb_n_purge_threads;
207
 
typedef constrained_check<uint16_t, 2, 0> trinary_constraint;
 
188
typedef constrained_check<uint32_t, 2, 0> trinary_constraint;
208
189
static trinary_constraint innodb_flush_log_at_trx_commit;
209
190
typedef constrained_check<unsigned int, 99, 0> max_dirty_pages_constraint;
210
191
static max_dirty_pages_constraint innodb_max_dirty_pages_pct;
253
234
/* Below we have boolean-valued start-up parameters, and their default
254
235
values */
255
236
 
256
 
typedef constrained_check<uint16_t, 2, 0> trinary_constraint;
 
237
typedef constrained_check<uint32_t, 2, 0> trinary_constraint;
257
238
static trinary_constraint innobase_fast_shutdown;
258
239
 
259
240
/* "innobase_file_format_check" decides whether we would continue
352
333
      srv_free_paths_and_sizes();
353
334
      if (internal_innobase_data_file_path)
354
335
        free(internal_innobase_data_file_path);
355
 
      pthread_mutex_destroy(&innobase_share_mutex);
356
 
      pthread_mutex_destroy(&prepare_commit_mutex);
357
 
      pthread_mutex_destroy(&commit_threads_m);
358
 
      pthread_mutex_destroy(&commit_cond_m);
359
 
      pthread_cond_destroy(&commit_cond);
360
336
    }
361
337
    
362
338
    /* These get strdup'd from vm variables */
446
422
  doDropSchema(
447
423
  /*===================*/
448
424
        /* out: error number */
449
 
    const SchemaIdentifier  &identifier); /* in: database path; inside InnoDB the name
 
425
    const identifier::Schema  &identifier); /* in: database path; inside InnoDB the name
450
426
        of the last directory in the path is used as
451
427
        the database name: for example, in 'mysql/data/test'
452
428
        the database name is 'test' */
485
461
 
486
462
  UNIV_INTERN int doCreateTable(Session &session,
487
463
                                Table &form,
488
 
                                const TableIdentifier &identifier,
 
464
                                const identifier::Table &identifier,
489
465
                                message::Table&);
490
 
  UNIV_INTERN int doRenameTable(Session&, const TableIdentifier &from, const TableIdentifier &to);
491
 
  UNIV_INTERN int doDropTable(Session &session, const TableIdentifier &identifier);
 
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);
492
468
 
493
 
  UNIV_INTERN virtual bool get_error_message(int error, String *buf);
 
469
  UNIV_INTERN virtual bool get_error_message(int error, String *buf) const;
494
470
 
495
471
  UNIV_INTERN uint32_t max_supported_keys() const;
496
472
  UNIV_INTERN uint32_t max_supported_key_length() const;
507
483
  }
508
484
 
509
485
  int doGetTableDefinition(drizzled::Session& session,
510
 
                           const TableIdentifier &identifier,
 
486
                           const identifier::Table &identifier,
511
487
                           drizzled::message::Table &table_proto);
512
488
 
513
 
  bool doDoesTableExist(drizzled::Session& session, const TableIdentifier &identifier);
 
489
  bool doDoesTableExist(drizzled::Session& session, const identifier::Table &identifier);
514
490
 
515
491
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
516
 
                             const drizzled::SchemaIdentifier &schema_identifier,
517
 
                             drizzled::TableIdentifier::vector &set_of_identifiers);
 
492
                             const drizzled::identifier::Schema &schema_identifier,
 
493
                             drizzled::identifier::Table::vector &set_of_identifiers);
518
494
  bool validateCreateTableOption(const std::string &key, const std::string &state);
519
495
  void dropTemporarySchema();
520
496
 
542
518
}
543
519
 
544
520
void InnobaseEngine::doGetTableIdentifiers(drizzled::CachedDirectory &directory,
545
 
                                           const drizzled::SchemaIdentifier &schema_identifier,
546
 
                                           drizzled::TableIdentifier::vector &set_of_identifiers)
 
521
                                           const drizzled::identifier::Schema &schema_identifier,
 
522
                                           drizzled::identifier::Table::vector &set_of_identifiers)
547
523
{
548
524
  CachedDirectory::Entries entries= directory.getEntries();
549
525
 
 
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
 
550
535
  for (CachedDirectory::Entries::iterator entry_iter= entries.begin(); 
551
536
       entry_iter != entries.end(); ++entry_iter)
552
537
  {
574
559
           Using schema_identifier here to stop unused warning, could use
575
560
           definition.schema() instead
576
561
        */
577
 
        TableIdentifier identifier(schema_identifier.getSchemaName(), definition.name());
 
562
        identifier::Table identifier(schema_identifier.getSchemaName(), definition.name());
578
563
        set_of_identifiers.push_back(identifier);
579
564
      }
580
565
    }
581
566
  }
582
567
}
583
568
 
584
 
bool InnobaseEngine::doDoesTableExist(Session &session, const TableIdentifier &identifier)
 
569
bool InnobaseEngine::doDoesTableExist(Session &session, const identifier::Table &identifier)
585
570
{
586
571
  string proto_path(identifier.getPath());
587
572
  proto_path.append(DEFAULT_FILE_EXTENSION);
589
574
  if (session.getMessageCache().doesTableMessageExist(identifier))
590
575
    return true;
591
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)
 
581
    return true;
 
582
 
592
583
  if (access(proto_path.c_str(), F_OK))
593
584
  {
594
585
    return false;
598
589
}
599
590
 
600
591
int InnobaseEngine::doGetTableDefinition(Session &session,
601
 
                                         const TableIdentifier &identifier,
 
592
                                         const identifier::Table &identifier,
602
593
                                         message::Table &table_proto)
603
594
{
604
595
  string proto_path(identifier.getPath());
608
599
  if (session.getMessageCache().getTableMessage(identifier, table_proto))
609
600
    return EEXIST;
610
601
 
 
602
  if (read_replication_log_table_message(identifier.getTableName().c_str(), &table_proto) == 0)
 
603
    return EEXIST;
 
604
 
611
605
  if (access(proto_path.c_str(), F_OK))
612
606
  {
613
607
    return errno;
804
798
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
805
799
         in non-Cursor code.
806
800
@return true if session is the replication thread */
807
 
extern "C" UNIV_INTERN
 
801
UNIV_INTERN
808
802
ibool
809
803
thd_is_replication_slave_thread(
810
804
/*============================*/
811
 
  void* ) /*!< in: thread handle (Session*) */
 
805
  drizzled::Session* ) /*!< in: thread handle (Session*) */
812
806
{
813
807
  return false;
814
808
}
878
872
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
879
873
         in non-Cursor code.
880
874
@return true if non-transactional tables have been edited */
881
 
extern "C" UNIV_INTERN
 
875
UNIV_INTERN
882
876
ibool
883
877
thd_has_edited_nontrans_tables(
884
878
/*===========================*/
885
 
  void*   session)  /*!< in: thread handle (Session*) */
 
879
  drizzled::Session *session)  /*!< in: thread handle (Session*) */
886
880
{
887
 
  return((ibool)((Session *)session)->transaction.all.hasModifiedNonTransData());
 
881
  return((ibool)session->transaction.all.hasModifiedNonTransData());
888
882
}
889
883
 
890
884
/******************************************************************//**
891
885
Returns true if the thread is executing a SELECT statement.
892
886
@return true if session is executing SELECT */
893
 
extern "C" UNIV_INTERN
 
887
UNIV_INTERN
894
888
ibool
895
889
thd_is_select(
896
890
/*==========*/
897
 
  const void* session)  /*!< in: thread handle (Session*) */
 
891
  const drizzled::Session *session)  /*!< in: thread handle (Session*) */
898
892
{
899
 
  return(session_sql_command((const Session*) session) == SQLCOM_SELECT);
 
893
  return(session->getSqlCommand() == SQLCOM_SELECT);
900
894
}
901
895
 
902
896
/******************************************************************//**
903
897
Returns true if the thread supports XA,
904
898
global value of innodb_supports_xa if session is NULL.
905
899
@return true if session has XA support */
906
 
extern "C" UNIV_INTERN
 
900
UNIV_INTERN
907
901
ibool
908
902
thd_supports_xa(
909
903
/*============*/
910
 
  void* )  /*!< in: thread handle (Session*), or NULL to query
 
904
  drizzled::Session* )  /*!< in: thread handle (Session*), or NULL to query
911
905
        the global innodb_supports_xa */
912
906
{
913
907
  /* TODO: Add support here for per-session value */
917
911
/******************************************************************//**
918
912
Returns the lock wait timeout for the current connection.
919
913
@return the lock wait timeout, in seconds */
920
 
extern "C" UNIV_INTERN
 
914
UNIV_INTERN
921
915
ulong
922
916
thd_lock_wait_timeout(
923
917
/*==================*/
924
 
  void*)  /*!< in: thread handle (Session*), or NULL to query
 
918
  drizzled::Session*)  /*!< in: thread handle (Session*), or NULL to query
925
919
      the global innodb_lock_wait_timeout */
926
920
{
927
921
  /* TODO: Add support here for per-session value */
932
926
 
933
927
/******************************************************************//**
934
928
Set the time waited for the lock for the current query. */
935
 
extern "C" UNIV_INTERN
 
929
UNIV_INTERN
936
930
void
937
931
thd_set_lock_wait_time(
938
932
/*===================*/
939
 
        void*   thd,    /*!< in: thread handle (THD*) */
 
933
        drizzled::Session*      in_session,     /*!< in: thread handle (THD*) */
940
934
        ulint   value)  /*!< in: time waited for the lock */
941
935
{
942
 
        if (thd) {
943
 
          static_cast<Session*>(thd)->utime_after_lock+= value;
944
 
        }
 
936
  if (in_session)
 
937
    in_session->utime_after_lock+= value;
945
938
}
946
939
 
947
940
/********************************************************************//**
967
960
  trx_t *trx= session_to_trx(&session);
968
961
 
969
962
  uint64_t trx_id= message.transaction_context().transaction_id();
970
 
  ulint error= insert_replication_message(data, message.ByteSize(), trx, trx_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);
971
969
  (void)error;
972
970
 
973
971
  delete[] data;
1024
1022
about a possible transaction rollback inside InnoDB caused by a lock wait
1025
1023
timeout or a deadlock.
1026
1024
@return MySQL error code */
1027
 
extern "C" UNIV_INTERN
 
1025
UNIV_INTERN
1028
1026
int
1029
1027
convert_error_code_to_mysql(
1030
1028
/*========================*/
1078
1076
    tell it also to MySQL so that MySQL knows to empty the
1079
1077
    cached binlog for this transaction */
1080
1078
 
1081
 
    mark_transaction_to_rollback(session, TRUE);
 
1079
    session->markTransactionForRollback(TRUE);
1082
1080
 
1083
1081
    return(HA_ERR_LOCK_DEADLOCK);
1084
1082
 
1087
1085
    latest SQL statement in a lock wait timeout. Previously, we
1088
1086
    rolled back the whole transaction. */
1089
1087
 
1090
 
    mark_transaction_to_rollback(session, (bool)row_rollback_on_timeout);
 
1088
    session->markTransactionForRollback((bool)row_rollback_on_timeout);
1091
1089
 
1092
1090
    return(HA_ERR_LOCK_WAIT_TIMEOUT);
1093
1091
 
1098
1096
    return(HA_ERR_ROW_IS_REFERENCED);
1099
1097
 
1100
1098
  case DB_CANNOT_ADD_CONSTRAINT:
 
1099
  case DB_CHILD_NO_INDEX:
 
1100
  case DB_PARENT_NO_INDEX:
1101
1101
    return(HA_ERR_CANNOT_ADD_FOREIGN);
1102
1102
 
1103
1103
  case DB_CANNOT_DROP_CONSTRAINT:
1121
1121
 
1122
1122
  case DB_TOO_BIG_RECORD:
1123
1123
    my_error(ER_TOO_BIG_ROWSIZE, MYF(0),
1124
 
       page_get_free_space_of_empty(flags
1125
 
                  & DICT_TF_COMPACT) / 2);
 
1124
             page_get_free_space_of_empty(flags & DICT_TF_COMPACT) / 2);
1126
1125
    return(HA_ERR_TO_BIG_ROW);
1127
1126
 
1128
1127
  case DB_NO_SAVEPOINT:
1133
1132
    tell it also to MySQL so that MySQL knows to empty the
1134
1133
    cached binlog for this transaction */
1135
1134
 
1136
 
    mark_transaction_to_rollback(session, TRUE);
 
1135
    session->markTransactionForRollback(TRUE);
1137
1136
 
1138
1137
    return(HA_ERR_LOCK_TABLE_FULL);
1139
1138
 
1167
1166
 
1168
1167
/*************************************************************//**
1169
1168
Prints info of a Session object (== user session thread) to the given file. */
1170
 
extern "C" UNIV_INTERN
 
1169
UNIV_INTERN
1171
1170
void
1172
1171
innobase_mysql_print_thd(
1173
1172
/*=====================*/
1174
1173
  FILE* f,    /*!< in: output stream */
1175
 
  void * in_session,  /*!< in: pointer to a Drizzle Session object */
 
1174
  drizzled::Session *in_session,  /*!< in: pointer to a Drizzle Session object */
1176
1175
  uint  )   /*!< in: max query length to print, or 0 to
1177
1176
           use the default max length */
1178
1177
{
1179
 
  Session *session= reinterpret_cast<Session *>(in_session);
 
1178
  drizzled::identifier::User::const_shared_ptr user_identifier(in_session->user());
 
1179
 
1180
1180
  fprintf(f,
1181
1181
          "Drizzle thread %"PRIu64", query id %"PRIu64", %s, %s, %s ",
1182
 
          static_cast<uint64_t>(session->getSessionId()),
1183
 
          static_cast<uint64_t>(session->getQueryId()),
 
1182
          static_cast<uint64_t>(in_session->getSessionId()),
 
1183
          static_cast<uint64_t>(in_session->getQueryId()),
1184
1184
          glob_hostname,
1185
 
          session->getSecurityContext().getIp().c_str(),
1186
 
          session->getSecurityContext().getUser().c_str()
 
1185
          user_identifier->address().c_str(),
 
1186
          user_identifier->username().c_str()
1187
1187
  );
1188
 
  fprintf(f, "\n%s", session->getQueryString()->c_str());
 
1188
  fprintf(f, "\n%s", in_session->getQueryString()->c_str());
1189
1189
  putc('\n', f);
1190
1190
}
1191
1191
 
1192
1192
/******************************************************************//**
1193
1193
Get the variable length bounds of the given character set. */
1194
 
extern "C" UNIV_INTERN
 
1194
UNIV_INTERN
1195
1195
void
1196
1196
innobase_get_cset_width(
1197
1197
/*====================*/
1218
1218
 
1219
1219
/******************************************************************//**
1220
1220
Converts an identifier to a table name. */
1221
 
extern "C" UNIV_INTERN
 
1221
UNIV_INTERN
1222
1222
void
1223
1223
innobase_convert_from_table_id(
1224
1224
/*===========================*/
1232
1232
 
1233
1233
/******************************************************************//**
1234
1234
Converts an identifier to UTF-8. */
1235
 
extern "C" UNIV_INTERN
 
1235
UNIV_INTERN
1236
1236
void
1237
1237
innobase_convert_from_id(
1238
1238
/*=====================*/
1247
1247
/******************************************************************//**
1248
1248
Compares NUL-terminated UTF-8 strings case insensitively.
1249
1249
@return 0 if a=b, <0 if a<b, >1 if a>b */
1250
 
extern "C" UNIV_INTERN
 
1250
UNIV_INTERN
1251
1251
int
1252
1252
innobase_strcasecmp(
1253
1253
/*================*/
1259
1259
 
1260
1260
/******************************************************************//**
1261
1261
Makes all characters in a NUL-terminated UTF-8 string lower case. */
1262
 
extern "C" UNIV_INTERN
 
1262
UNIV_INTERN
1263
1263
void
1264
1264
innobase_casedn_str(
1265
1265
/*================*/
1268
1268
  my_casedn_str(system_charset_info, a);
1269
1269
}
1270
1270
 
1271
 
/**********************************************************************//**
1272
 
Determines the connection character set.
1273
 
@return connection character set */
1274
 
extern "C" UNIV_INTERN
1275
 
const void*
1276
 
innobase_get_charset(
1277
 
/*=================*/
1278
 
  void* mysql_session)  /*!< in: MySQL thread handle */
1279
 
{
1280
 
  return static_cast<Session*>(mysql_session)->charset();
1281
 
}
1282
 
 
1283
 
extern "C" UNIV_INTERN
 
1271
UNIV_INTERN
1284
1272
bool
1285
1273
innobase_isspace(
1286
1274
  const void *cs,
1289
1277
  return my_isspace(static_cast<const CHARSET_INFO *>(cs), char_to_test);
1290
1278
}
1291
1279
 
1292
 
UNIV_INTERN
1293
 
int
1294
 
innobase_fast_mutex_init(
1295
 
        os_fast_mutex_t*        fast_mutex)
1296
 
{
1297
 
  return pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
1298
 
}
1299
 
 
1300
 
/**********************************************************************//**
1301
 
Determines the current SQL statement.
1302
 
@return        SQL statement string */
1303
 
extern "C" UNIV_INTERN
1304
 
const char*
1305
 
innobase_get_stmt(
1306
 
/*==============*/
1307
 
       void*   session,        /*!< in: MySQL thread handle */
1308
 
       size_t* length)         /*!< out: length of the SQL statement */
1309
 
{
1310
 
  return static_cast<Session*>(session)->getQueryStringCopy(*length);
1311
 
}
1312
 
 
1313
1280
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1314
1281
/*******************************************************************//**
1315
1282
Map an OS error to an errno value. The OS error number is stored in
1316
1283
_doserrno and the mapped value is stored in errno) */
1317
 
extern "C"
1318
1284
void __cdecl
1319
1285
_dosmaperr(
1320
1286
  unsigned long); /*!< in: OS error value */
1322
1288
/*********************************************************************//**
1323
1289
Creates a temporary file.
1324
1290
@return temporary file descriptor, or < 0 on error */
1325
 
extern "C" UNIV_INTERN
 
1291
UNIV_INTERN
1326
1292
int
1327
1293
innobase_mysql_tmpfile(void)
1328
1294
/*========================*/
1402
1368
/*********************************************************************//**
1403
1369
Creates a temporary file.
1404
1370
@return temporary file descriptor, or < 0 on error */
1405
 
extern "C" UNIV_INTERN
 
1371
UNIV_INTERN
1406
1372
int
1407
1373
innobase_mysql_tmpfile(void)
1408
1374
/*========================*/
1409
1375
{
1410
1376
  int fd2 = -1;
1411
 
  int fd = mysql_tmpfile("ib");
 
1377
  int fd = ::drizzled::tmpfile("ib");
1412
1378
  if (fd >= 0) {
1413
1379
    /* Copy the file descriptor, so that the additional resources
1414
1380
    allocated by create_temp_file() can be freed by invoking
1441
1407
number of bytes that were written to "buf" is returned (including the
1442
1408
terminating NUL).
1443
1409
@return number of bytes that were written */
1444
 
extern "C" UNIV_INTERN
 
1410
UNIV_INTERN
1445
1411
ulint
1446
1412
innobase_raw_format(
1447
1413
/*================*/
1561
1527
/*********************************************************************//**
1562
1528
Allocates an InnoDB transaction for a MySQL Cursor object.
1563
1529
@return InnoDB transaction handle */
1564
 
extern "C" UNIV_INTERN
 
1530
UNIV_INTERN
1565
1531
trx_t*
1566
1532
innobase_trx_allocate(
1567
1533
/*==================*/
1665
1631
  ulint   buflen, /*!< in: length of buf, in bytes */
1666
1632
  const char* id, /*!< in: identifier to convert */
1667
1633
  ulint   idlen,  /*!< in: length of id, in bytes */
1668
 
  void*   session,/*!< in: MySQL connection thread, or NULL */
 
1634
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
1669
1635
  ibool   file_id)/*!< in: TRUE=id is a table or database name;
1670
1636
        FALSE=id is an UTF-8 string */
1671
1637
{
1672
1638
  char nz[NAME_LEN + 1];
1673
 
  char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix];
 
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]);
1674
1641
 
1675
1642
  const char* s = id;
1676
1643
  int   q;
1687
1654
    memcpy(nz, id, idlen);
1688
1655
    nz[idlen] = 0;
1689
1656
 
1690
 
    s = nz2;
1691
 
    idlen = TableIdentifier::filename_to_tablename(nz, nz2, sizeof nz2);
 
1657
    s = nz2.get();
 
1658
    idlen = identifier::Table::filename_to_tablename(nz, nz2.get(), nz2_size);
1692
1659
  }
1693
1660
 
1694
1661
  /* See if the identifier needs to be quoted. */
1742
1709
Convert a table or index name to the MySQL system_charset_info (UTF-8)
1743
1710
and quote it if needed.
1744
1711
@return pointer to the end of buf */
1745
 
extern "C" UNIV_INTERN
 
1712
UNIV_INTERN
1746
1713
char*
1747
1714
innobase_convert_name(
1748
1715
/*==================*/
1750
1717
  ulint   buflen, /*!< in: length of buf, in bytes */
1751
1718
  const char* id, /*!< in: identifier to convert */
1752
1719
  ulint   idlen,  /*!< in: length of id, in bytes */
1753
 
  void*   session,/*!< in: MySQL connection thread, or NULL */
 
1720
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
1754
1721
  ibool   table_id)/*!< in: TRUE=id is a table or database name;
1755
1722
        FALSE=id is an index name */
1756
1723
{
1798
1765
/**********************************************************************//**
1799
1766
Determines if the currently running transaction has been interrupted.
1800
1767
@return TRUE if interrupted */
1801
 
extern "C" UNIV_INTERN
 
1768
UNIV_INTERN
1802
1769
ibool
1803
1770
trx_is_interrupted(
1804
1771
/*===============*/
1805
1772
  trx_t*  trx)  /*!< in: transaction */
1806
1773
{
1807
 
  return(trx && trx->mysql_thd && static_cast<Session*>(trx->mysql_thd)->getKilled());
 
1774
  return(trx && trx->mysql_thd && trx->mysql_thd->getKilled());
1808
1775
}
1809
1776
 
1810
1777
/**********************************************************************//**
1811
1778
Determines if the currently running transaction is in strict mode.
1812
1779
@return TRUE if strict */
1813
 
extern "C" UNIV_INTERN
 
1780
UNIV_INTERN
1814
1781
ibool
1815
1782
trx_is_strict(
1816
1783
/*==========*/
1902
1869
 
1903
1870
static int innodb_commit_concurrency_validate(Session *session, set_var *var)
1904
1871
{
1905
 
   uint32_t new_value= var->save_result.uint32_t_value;
 
1872
   uint64_t new_value= var->getInteger();
1906
1873
 
1907
1874
   if ((innobase_commit_concurrency.get() == 0 && new_value != 0) ||
1908
1875
       (innobase_commit_concurrency.get() != 0 && new_value == 0))
2006
1973
    }
2007
1974
 
2008
1975
    if (format_id >= 0) {
2009
 
      innobase_file_format_max= 
2010
 
        trx_sys_file_format_id_to_name((uint)format_id);
 
1976
      innobase_file_format_max.assign(
 
1977
                             trx_sys_file_format_id_to_name((uint)format_id));
2011
1978
 
2012
1979
      /* Update the max format id in the system tablespace. */
2013
 
      char name_buff[100];
2014
 
      strcpy(name_buff, innobase_file_format_max.c_str());
2015
 
      if (trx_sys_file_format_max_set(format_id, (const char **)&name_buff))
 
1980
      const char *name_buff;
 
1981
 
 
1982
      if (trx_sys_file_format_max_set(format_id, &name_buff))
2016
1983
      {
2017
 
        errmsg_printf(ERRMSG_LVL_WARN,
 
1984
        errmsg_printf(error::WARN,
2018
1985
                      " [Info] InnoDB: the file format in the system "
2019
1986
                      "tablespace is now set to %s.\n", name_buff);
2020
1987
        innobase_file_format_max= name_buff;
2074
2041
  innobase_use_doublewrite= (vm.count("disable-doublewrite")) ? false : true;
2075
2042
  srv_adaptive_flushing= (vm.count("disable-adaptive-flushing")) ? false : true;
2076
2043
  srv_use_sys_malloc= (vm.count("use-internal-malloc")) ? false : true;
 
2044
  srv_use_native_aio= (vm.count("disable-native-aio")) ? false : true;
2077
2045
  support_xa= (vm.count("disable-xa")) ? false : true;
2078
2046
  btr_search_enabled= (vm.count("disable-adaptive-hash-index")) ? false : true;
2079
2047
 
2101
2069
 
2102
2070
#ifdef UNIV_DEBUG
2103
2071
  static const char test_filename[] = "-@";
2104
 
  char      test_tablename[sizeof test_filename
2105
 
    + sizeof srv_mysql50_table_name_prefix];
2106
 
  if ((sizeof test_tablename) - 1
2107
 
      != filename_to_tablename(test_filename, test_tablename,
2108
 
                               sizeof test_tablename)
2109
 
      || strncmp(test_tablename,
2110
 
                 srv_mysql50_table_name_prefix,
2111
 
                 sizeof srv_mysql50_table_name_prefix)
2112
 
      || strcmp(test_tablename
2113
 
                + sizeof srv_mysql50_table_name_prefix,
 
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(),
2114
2083
                test_filename)) {
2115
 
    errmsg_printf(ERRMSG_LVL_ERROR, "tablename encoding has been changed");
 
2084
    errmsg_printf(error::ERROR, "tablename encoding has been changed");
2116
2085
    goto error;
2117
2086
  }
2118
2087
#endif /* UNIV_DEBUG */
2146
2115
  ret = (bool) srv_parse_data_file_paths_and_sizes(
2147
2116
                                                   internal_innobase_data_file_path);
2148
2117
  if (ret == FALSE) {
2149
 
    errmsg_printf(ERRMSG_LVL_ERROR, 
2150
 
                  "InnoDB: syntax error in innodb_data_file_path");
 
2118
    errmsg_printf(error::ERROR, "InnoDB: syntax error in innodb_data_file_path");
 
2119
 
2151
2120
mem_free_and_error:
2152
2121
    srv_free_paths_and_sizes();
2153
2122
    if (internal_innobase_data_file_path)
2172
2141
    srv_parse_log_group_home_dirs((char *)innobase_log_group_home_dir.c_str());
2173
2142
 
2174
2143
  if (ret == FALSE || innobase_mirrored_log_groups.get() != 1) {
2175
 
    errmsg_printf(ERRMSG_LVL_ERROR,
2176
 
                  _("syntax error in innodb_log_group_home_dir, or a "
2177
 
                  "wrong number of mirrored log groups"));
 
2144
    errmsg_printf(error::ERROR, _("syntax error in innodb_log_group_home_dir, or a "
 
2145
                                  "wrong number of mirrored log groups"));
2178
2146
 
2179
2147
    goto mem_free_and_error;
2180
2148
  }
2188
2156
 
2189
2157
    if (format_id > DICT_TF_FORMAT_MAX) {
2190
2158
 
2191
 
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: wrong innodb_file_format.");
 
2159
      errmsg_printf(error::ERROR, "InnoDB: wrong innodb_file_format.");
2192
2160
 
2193
2161
      goto mem_free_and_error;
2194
2162
    }
2217
2185
     srv_max_file_format_at_startup */
2218
2186
  if (innobase_file_format_validate_and_set(innobase_file_format_max.c_str()) < 0)
2219
2187
  {
2220
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("InnoDB: invalid "
2221
 
                    "innodb_file_format_max value: "
2222
 
                    "should be any value up to %s or its "
2223
 
                    "equivalent numeric id"),
2224
 
                    trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
 
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));
2225
2191
    goto mem_free_and_error;
2226
2192
  }
2227
2193
 
2240
2206
      }
2241
2207
    }
2242
2208
 
2243
 
    errmsg_printf(ERRMSG_LVL_ERROR,
2244
 
                  "InnoDB: invalid value "
2245
 
                  "innodb_change_buffering=%s",
 
2209
    errmsg_printf(error::ERROR, "InnoDB: invalid value innodb_change_buffering=%s",
2246
2210
                  vm["change-buffering"].as<string>().c_str());
2247
2211
    goto mem_free_and_error;
2248
2212
  }
2320
2284
                                                     TRUE);
2321
2285
 
2322
2286
  innobase_open_tables = hash_create(200);
2323
 
  pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
2324
 
  pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
2325
 
  pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
2326
 
  pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
2327
 
  pthread_cond_init(&commit_cond, NULL);
2328
2287
  innodb_inited= 1;
2329
2288
 
2330
2289
  actuall_engine_ptr->dropTemporarySchema();
2331
2290
 
2332
 
  status_table_function_ptr= new InnodbStatusTool;
 
2291
  context.add(new InnodbStatusTool);
2333
2292
 
2334
2293
  context.add(innodb_engine_ptr);
2335
2294
 
2336
 
  context.add(status_table_function_ptr);
2337
 
 
2338
 
  cmp_tool= new(std::nothrow)CmpTool(false);
2339
 
  context.add(cmp_tool);
2340
 
 
2341
 
  cmp_reset_tool= new(std::nothrow)CmpTool(true);
2342
 
  context.add(cmp_reset_tool);
2343
 
 
2344
 
  cmp_mem_tool= new(std::nothrow)CmpmemTool(false);
2345
 
  context.add(cmp_mem_tool);
2346
 
 
2347
 
  cmp_mem_reset_tool= new(std::nothrow)CmpmemTool(true);
2348
 
  context.add(cmp_mem_reset_tool);
2349
 
 
2350
 
  innodb_trx_tool= new(std::nothrow)InnodbTrxTool("INNODB_TRX");
2351
 
  context.add(innodb_trx_tool);
2352
 
 
2353
 
  innodb_locks_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCKS");
2354
 
  context.add(innodb_locks_tool);
2355
 
 
2356
 
  innodb_lock_waits_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS");
2357
 
  context.add(innodb_lock_waits_tool);
2358
 
 
2359
 
  innodb_sys_tables_tool= new(std::nothrow)InnodbSysTablesTool();
2360
 
  context.add(innodb_sys_tables_tool);
2361
 
 
2362
 
  innodb_sys_tablestats_tool= new(std::nothrow)InnodbSysTableStatsTool();
2363
 
  context.add(innodb_sys_tablestats_tool);
2364
 
 
2365
 
  innodb_sys_indexes_tool= new(std::nothrow)InnodbSysIndexesTool();
2366
 
  context.add(innodb_sys_indexes_tool);
2367
 
 
2368
 
  innodb_sys_columns_tool= new(std::nothrow)InnodbSysColumnsTool();
2369
 
  context.add(innodb_sys_columns_tool);
2370
 
 
2371
 
  innodb_sys_fields_tool= new(std::nothrow)InnodbSysFieldsTool();
2372
 
  context.add(innodb_sys_fields_tool);
2373
 
 
2374
 
  innodb_sys_foreign_tool= new(std::nothrow)InnodbSysForeignTool();
2375
 
  context.add(innodb_sys_foreign_tool);
2376
 
 
2377
 
  innodb_sys_foreign_cols_tool= new(std::nothrow)InnodbSysForeignColsTool();
2378
 
  context.add(innodb_sys_foreign_cols_tool);
 
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());
2379
2322
 
2380
2323
  context.add(new(std::nothrow)InnodbInternalTables());
2381
2324
  context.add(new(std::nothrow)InnodbReplicationTable());
2382
2325
 
2383
2326
  if (innobase_use_replication_log)
2384
2327
  {
2385
 
    replication_logger= new(std::nothrow)ReplicationLog();
 
2328
    ReplicationLog *replication_logger= new(std::nothrow)ReplicationLog();
2386
2329
    context.add(replication_logger);
2387
2330
    ReplicationLog::setup(replication_logger);
2388
2331
  }
2422
2365
  context.registerVariable(new sys_var_constrained_value<uint32_t>("purge_threads",
2423
2366
                                                                   innodb_n_purge_threads,
2424
2367
                                                                   purge_threads_update));
2425
 
  context.registerVariable(new sys_var_constrained_value<uint16_t>("fast_shutdown", innobase_fast_shutdown));
 
2368
  context.registerVariable(new sys_var_constrained_value<uint32_t>("fast_shutdown", innobase_fast_shutdown));
2426
2369
  context.registerVariable(new sys_var_std_string("file_format",
2427
2370
                                                  innobase_file_format_name,
2428
2371
                                                  innodb_file_format_name_validate));
2434
2377
                                                  innodb_file_format_max_validate));
2435
2378
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("buffer_pool_size", innobase_buffer_pool_size));
2436
2379
  context.registerVariable(new sys_var_constrained_value_readonly<int64_t>("log_file_size", innobase_log_file_size));
2437
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint16_t>("flush_log_at_trx_commit",
 
2380
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("flush_log_at_trx_commit",
2438
2381
                                                  innodb_flush_log_at_trx_commit));
2439
2382
  context.registerVariable(new sys_var_constrained_value_readonly<unsigned int>("max_dirty_pages_pct",
2440
2383
                                                  innodb_max_dirty_pages_pct));
2473
2416
  btr_search_fully_disabled = (!btr_search_enabled);
2474
2417
 
2475
2418
  return(FALSE);
 
2419
 
2476
2420
error:
2477
2421
  return(TRUE);
2478
2422
}
2569
2513
    trx_search_latch_release_if_reserved(trx);
2570
2514
  }
2571
2515
 
2572
 
  if (all
2573
 
    || (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
2574
 
 
 
2516
  if (all)
 
2517
  {
2575
2518
    /* We were instructed to commit the whole transaction, or
2576
2519
    this is an SQL statement end and autocommit is on */
2577
2520
 
2578
2521
    /* We need current binlog position for ibbackup to work.
2579
2522
    Note, the position is current because of
2580
2523
    prepare_commit_mutex */
2581
 
retry:
2582
 
    if (innobase_commit_concurrency.get() > 0) {
2583
 
      pthread_mutex_lock(&commit_cond_m);
2584
 
      commit_threads++;
2585
 
 
2586
 
      if (commit_threads > innobase_commit_concurrency.get()) {
 
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
 
2587
2535
        commit_threads--;
2588
 
        pthread_cond_wait(&commit_cond,
2589
 
          &commit_cond_m);
2590
 
        pthread_mutex_unlock(&commit_cond_m);
2591
 
        goto retry;
2592
 
      }
2593
 
      else {
2594
 
        pthread_mutex_unlock(&commit_cond_m);
2595
 
      }
 
2536
        commit_cond.wait(scopedLock);
 
2537
      } while (1);
2596
2538
    }
2597
2539
 
2598
 
                /* Store transaction point for binlog
2599
 
    Later logic tests that this is set to _something_. We need
2600
 
    that logic to fire, even though we do not have a real name. */
2601
 
    trx->mysql_log_file_name = "UNUSED";
 
2540
    trx->mysql_log_file_name = NULL;
2602
2541
    trx->mysql_log_offset = 0;
2603
2542
 
2604
2543
    /* Don't do write + flush right now. For group commit
2608
2547
    innobase_commit_low(trx);
2609
2548
    trx->flush_log_later = FALSE;
2610
2549
 
2611
 
    if (innobase_commit_concurrency.get() > 0) {
2612
 
      pthread_mutex_lock(&commit_cond_m);
 
2550
    if (commit_concurrency)
 
2551
    {
 
2552
      boost::mutex::scoped_lock scopedLock(commit_cond_m);
2613
2553
      commit_threads--;
2614
 
      pthread_cond_signal(&commit_cond);
2615
 
      pthread_mutex_unlock(&commit_cond_m);
 
2554
      commit_cond.notify_one();
2616
2555
    }
2617
2556
 
2618
2557
    /* Now do a write + flush of logs. */
2697
2636
 
2698
2637
  row_unlock_table_autoinc_for_mysql(trx);
2699
2638
 
2700
 
  if (all
2701
 
    || !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
2702
 
 
 
2639
  if (all)
 
2640
  {
2703
2641
    error = trx_rollback_for_mysql(trx);
2704
2642
  } else {
2705
2643
    error = trx_rollback_last_sql_stat_for_mysql(trx);
2858
2796
      trx->undo_no > 0 &&
2859
2797
      global_system_variables.log_warnings)
2860
2798
  {
2861
 
      errmsg_printf(ERRMSG_LVL_WARN,
 
2799
      errmsg_printf(error::WARN,
2862
2800
      "Drizzle is closing a connection during a KILL operation\n"
2863
2801
      "that has an active InnoDB transaction.  %llu row modifications will "
2864
2802
      "roll back.\n",
2938
2876
  return(true);
2939
2877
}
2940
2878
 
2941
 
/*****************************************************************//**
2942
 
Normalizes a table name string. A normalized name consists of the
2943
 
database name catenated to '/' and table name. An example:
2944
 
test/mytable. On Windows normalization puts both the database name and the
2945
 
table name always to lower case. */
2946
 
static
2947
 
void
2948
 
normalize_table_name(
2949
 
/*=================*/
2950
 
  char*   norm_name,  /*!< out: normalized name as a
2951
 
          null-terminated string */
2952
 
  const char* name)   /*!< in: table name string */
2953
 
{
2954
 
  const char* name_ptr;
2955
 
  const char* db_ptr;
2956
 
  const char* ptr;
2957
 
 
2958
 
  /* Scan name from the end */
2959
 
 
2960
 
  ptr = strchr(name, '\0')-1;
2961
 
 
2962
 
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
2963
 
    ptr--;
2964
 
  }
2965
 
 
2966
 
  name_ptr = ptr + 1;
2967
 
 
2968
 
  assert(ptr > name);
2969
 
 
2970
 
  ptr--;
2971
 
 
2972
 
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
2973
 
    ptr--;
2974
 
  }
2975
 
 
2976
 
  db_ptr = ptr + 1;
2977
 
 
2978
 
  memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
2979
 
 
2980
 
  norm_name[name_ptr - db_ptr - 1] = '/';
2981
 
 
2982
 
#ifdef __WIN__
2983
 
  innobase_casedn_str(norm_name);
2984
 
#endif
2985
 
}
2986
 
 
2987
2879
/********************************************************************//**
2988
2880
Get the upper limit of the MySQL integral and floating-point type.
2989
2881
@return maximum allowed value for the field */
3150
3042
                if (!index_mapping) {
3151
3043
                        /* Report an error if index_mapping continues to be
3152
3044
                        NULL and mysql_num_index is a non-zero value */
3153
 
                        errmsg_printf(ERRMSG_LVL_ERROR,
3154
 
                                      "InnoDB: fail to allocate memory for "
3155
 
                                        "index translation table. Number of "
3156
 
                                        "Index:%lu, array size:%lu",
 
3045
                        errmsg_printf(error::ERROR, "InnoDB: fail to allocate memory for "
 
3046
                                      "index translation table. Number of Index:%lu, array size:%lu",
3157
3047
                                        mysql_num_index,
3158
3048
                                        share->idx_trans_tbl.array_size);
3159
3049
                        ret = FALSE;
3174
3064
                        ib_table, table->key_info[count].name);
3175
3065
 
3176
3066
                if (!index_mapping[count]) {
3177
 
                        errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find index %s in InnoDB "
3178
 
                                        "index dictionary.",
3179
 
                                        table->key_info[count].name);
 
3067
                        errmsg_printf(error::ERROR, "Cannot find index %s in InnoDB index dictionary.",
 
3068
                                      table->key_info[count].name);
3180
3069
                        ret = FALSE;
3181
3070
                        goto func_exit;
3182
3071
                }
3183
3072
 
3184
3073
                /* Double check fetched index has the same
3185
3074
                column info as those in mysql key_info. */
3186
 
                if (!innobase_match_index_columns(&table->key_info[count],
3187
 
                                                  index_mapping[count])) {
3188
 
                        errmsg_printf(ERRMSG_LVL_ERROR, "Found index %s whose column info "
3189
 
                                        "does not match that of MySQL.",
3190
 
                                        table->key_info[count].name);
3191
 
                        ret = FALSE;
3192
 
                        goto func_exit;
 
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;
3193
3080
                }
3194
3081
        }
3195
3082
 
3259
3146
    auto_inc = 0;
3260
3147
 
3261
3148
    ut_print_timestamp(stderr);
3262
 
    fprintf(stderr, "  InnoDB: Unable to determine the AUTOINC "
3263
 
            "column name\n");
 
3149
    errmsg_printf(error::ERROR, "InnoDB: Unable to determine the AUTOINC column name");
3264
3150
  }
3265
3151
 
3266
3152
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
3310
3196
    }
3311
3197
    case DB_RECORD_NOT_FOUND:
3312
3198
      ut_print_timestamp(stderr);
3313
 
      fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
3314
 
              "dictionaries are out of sync.\n"
3315
 
              "InnoDB: Unable to find the AUTOINC column "
3316
 
              "%s in the InnoDB table %s.\n"
3317
 
              "InnoDB: We set the next AUTOINC column "
3318
 
              "value to 0,\n"
3319
 
              "InnoDB: in effect disabling the AUTOINC "
3320
 
              "next value generation.\n"
3321
 
              "InnoDB: You can either set the next "
3322
 
              "AUTOINC value explicitly using ALTER TABLE\n"
3323
 
              "InnoDB: or fix the data dictionary by "
3324
 
              "recreating the table.\n",
3325
 
              col_name, index->table->name);
 
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);
3326
3206
 
3327
3207
      /* This will disable the AUTOINC generation. */
3328
3208
      auto_inc = 0;
3348
3228
@return 1 if error, 0 if success */
3349
3229
UNIV_INTERN
3350
3230
int
3351
 
ha_innobase::doOpen(const TableIdentifier &identifier,
 
3231
ha_innobase::doOpen(const identifier::Table &identifier,
3352
3232
                    int   mode,   /*!< in: not used */
3353
3233
                    uint    test_if_locked) /*!< in: not used */
3354
3234
{
3355
3235
  dict_table_t* ib_table;
3356
 
  char    norm_name[FN_REFLEN];
3357
3236
  Session*    session;
3358
3237
 
3359
3238
  UT_NOT_USED(mode);
3368
3247
    getTransactionalEngine()->releaseTemporaryLatches(session);
3369
3248
  }
3370
3249
 
3371
 
  normalize_table_name(norm_name, identifier.getPath().c_str());
3372
 
 
3373
3250
  user_session = NULL;
3374
3251
 
3375
 
  if (!(share=get_share(identifier.getPath().c_str()))) {
 
3252
  std::string search_string(identifier.getSchemaName());
 
3253
  boost::algorithm::to_lower(search_string);
3376
3254
 
3377
 
    return(1);
 
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
    }
3378
3270
  }
3379
3271
 
3380
3272
  /* Create buffers for packing the fields of a record. Why
3383
3275
  stored the string length as the first byte. */
3384
3276
 
3385
3277
  upd_and_key_val_buff_len =
3386
 
        getTable()->getShare()->stored_rec_length
 
3278
        getTable()->getShare()->sizeStoredRecord()
3387
3279
        + getTable()->getShare()->max_key_length
3388
3280
        + MAX_REF_PARTS * 3;
3389
3281
 
3401
3293
  }
3402
3294
 
3403
3295
  /* Get pointer to a table object in InnoDB dictionary cache */
3404
 
  ib_table = dict_table_get(norm_name, TRUE);
 
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
  }
3405
3306
  
3406
3307
  if (NULL == ib_table) {
3407
 
    errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find or open table %s from\n"
 
3308
    errmsg_printf(error::ERROR, "Cannot find or open table %s from\n"
3408
3309
        "the internal data dictionary of InnoDB "
3409
3310
        "though the .frm file for the\n"
3410
3311
        "table exists. Maybe you have deleted and "
3418
3319
        "doesn't support.\n"
3419
3320
        "See " REFMAN "innodb-troubleshooting.html\n"
3420
3321
        "how you can resolve the problem.\n",
3421
 
        norm_name);
 
3322
        identifier.getKeyPath().c_str());
3422
3323
    free_share(share);
3423
3324
    upd_buff.resize(0);
3424
3325
    key_val_buff.resize(0);
3427
3328
    return(HA_ERR_NO_SUCH_TABLE);
3428
3329
  }
3429
3330
 
3430
 
  if (ib_table->ibd_file_missing && !session_tablespace_op(session)) {
3431
 
    errmsg_printf(ERRMSG_LVL_ERROR, "MySQL is trying to open a table handle but "
 
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 "
3432
3333
        "the .ibd file for\ntable %s does not exist.\n"
3433
3334
        "Have you deleted the .ibd file from the "
3434
3335
        "database directory under\nthe MySQL datadir, "
3435
3336
        "or have you used DISCARD TABLESPACE?\n"
3436
3337
        "See " REFMAN "innodb-troubleshooting.html\n"
3437
3338
        "how you can resolve the problem.\n",
3438
 
        norm_name);
 
3339
        identifier.getKeyPath().c_str());
3439
3340
    free_share(share);
3440
3341
    upd_buff.resize(0);
3441
3342
    key_val_buff.resize(0);
3447
3348
 
3448
3349
  prebuilt = row_create_prebuilt(ib_table);
3449
3350
 
3450
 
  prebuilt->mysql_row_len = getTable()->getShare()->stored_rec_length;
 
3351
  prebuilt->mysql_row_len = getTable()->getShare()->sizeStoredRecord();
3451
3352
  prebuilt->default_rec = getTable()->getDefaultValues();
3452
3353
  ut_ad(prebuilt->default_rec);
3453
3354
 
3457
3358
  key_used_on_scan = primary_key;
3458
3359
 
3459
3360
  if (!innobase_build_index_translation(getTable(), ib_table, share)) {
3460
 
    errmsg_printf(ERRMSG_LVL_ERROR, "Build InnoDB index translation table for"
3461
 
                    " Table %s failed", identifier.getPath().c_str());
 
3361
    errmsg_printf(error::ERROR, "Build InnoDB index translation table for"
 
3362
                    " Table %s failed", identifier.getKeyPath().c_str());
3462
3363
  }
3463
3364
 
3464
3365
  /* Allocate a buffer for a 'row reference'. A row reference is
3472
3373
    prebuilt->clust_index_was_generated = FALSE;
3473
3374
 
3474
3375
    if (UNIV_UNLIKELY(primary_key >= MAX_KEY)) {
3475
 
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has a primary key in "
 
3376
      errmsg_printf(error::ERROR, "Table %s has a primary key in "
3476
3377
                    "InnoDB data dictionary, but not "
3477
3378
                    "in MySQL!", identifier.getTableName().c_str());
3478
3379
 
3527
3428
    }
3528
3429
  } else {
3529
3430
    if (primary_key != MAX_KEY) {
3530
 
      errmsg_printf(ERRMSG_LVL_ERROR,
 
3431
      errmsg_printf(error::ERROR,
3531
3432
                    "Table %s has no primary key in InnoDB data "
3532
3433
                    "dictionary, but has one in MySQL! If you "
3533
3434
                    "created the table with a MySQL version < "
3563
3464
    and it will never be updated anyway. */
3564
3465
 
3565
3466
    if (key_used_on_scan != MAX_KEY) {
3566
 
      errmsg_printf(ERRMSG_LVL_WARN, 
 
3467
      errmsg_printf(error::WARN, 
3567
3468
        "Table %s key_used_on_scan is %lu even "
3568
3469
        "though there is no primary key inside "
3569
3470
        "InnoDB.", identifier.getTableName().c_str(), (ulong) key_used_on_scan);
3715
3616
of this function is in rem0cmp.c in InnoDB source code! If you change this
3716
3617
function, remember to update the prototype there!
3717
3618
@return 1, 0, -1, if a is greater, equal, less than b, respectively */
3718
 
extern "C" UNIV_INTERN
3719
 
int
 
3619
UNIV_INTERN int
3720
3620
innobase_mysql_cmp(
3721
3621
/*===============*/
3722
3622
  int   mysql_type, /*!< in: MySQL type */
3763
3663
      charset = get_charset(charset_number);
3764
3664
 
3765
3665
      if (charset == NULL) {
3766
 
        errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB needs charset %lu for doing "
 
3666
        errmsg_printf(error::ERROR, "InnoDB needs charset %lu for doing "
3767
3667
                      "a comparison, but MySQL cannot "
3768
3668
                      "find that charset.",
3769
3669
                      (ulong) charset_number);
3798
3698
the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1
3799
3699
VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'.
3800
3700
@return DATA_BINARY, DATA_VARCHAR, ... */
3801
 
extern "C" UNIV_INTERN
 
3701
UNIV_INTERN
3802
3702
ulint
3803
3703
get_innobase_type_from_mysql_type(
3804
3704
/*==============================*/
3847
3747
      return(DATA_VARMYSQL);
3848
3748
    }
3849
3749
  case DRIZZLE_TYPE_DECIMAL:
 
3750
  case DRIZZLE_TYPE_MICROTIME:
3850
3751
    return(DATA_FIXBINARY);
3851
3752
  case DRIZZLE_TYPE_LONG:
3852
3753
  case DRIZZLE_TYPE_LONGLONG:
3853
3754
  case DRIZZLE_TYPE_DATETIME:
 
3755
  case DRIZZLE_TYPE_TIME:
3854
3756
  case DRIZZLE_TYPE_DATE:
3855
3757
  case DRIZZLE_TYPE_TIMESTAMP:
3856
3758
  case DRIZZLE_TYPE_ENUM:
3859
3761
    return(DATA_DOUBLE);
3860
3762
  case DRIZZLE_TYPE_BLOB:
3861
3763
    return(DATA_BLOB);
 
3764
  case DRIZZLE_TYPE_BOOLEAN:
3862
3765
  case DRIZZLE_TYPE_UUID:
3863
3766
    return(DATA_FIXBINARY);
3864
3767
  case DRIZZLE_TYPE_NULL:
4286
4189
    n_requested_fields++;
4287
4190
 
4288
4191
    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);
4289
4194
 
4290
4195
    if (index == clust_index) {
4291
 
      templ->rec_field_no = dict_col_get_clust_pos(col, index);
 
4196
      templ->rec_field_no = templ->clust_rec_field_no;
4292
4197
    } else {
4293
4198
      templ->rec_field_no = dict_index_get_nth_col_pos(
4294
4199
                index, i);
4295
 
    }
4296
 
 
4297
 
    if (templ->rec_field_no == ULINT_UNDEFINED) {
4298
 
      prebuilt->need_to_access_clustered = TRUE;
 
4200
      if (templ->rec_field_no == ULINT_UNDEFINED) {
 
4201
        prebuilt->need_to_access_clustered = TRUE;
 
4202
      }
4299
4203
    }
4300
4204
 
4301
4205
    if (field->null_ptr) {
4345
4249
    for (i = 0; i < n_requested_fields; i++) {
4346
4250
      templ = prebuilt->mysql_template + i;
4347
4251
 
4348
 
      templ->rec_field_no = dict_col_get_clust_pos(
4349
 
        &index->table->cols[templ->col_no],
4350
 
        clust_index);
 
4252
      templ->rec_field_no = templ->clust_rec_field_no;
4351
4253
    }
4352
4254
  }
4353
4255
}
4421
4323
  trx_t*    trx = session_to_trx(user_session);
4422
4324
 
4423
4325
  if (prebuilt->trx != trx) {
4424
 
    errmsg_printf(ERRMSG_LVL_ERROR, "The transaction object for the table handle is at "
 
4326
    errmsg_printf(error::ERROR, "The transaction object for the table handle is at "
4425
4327
        "%p, but for the current thread it is at %p",
4426
4328
        (const void*) prebuilt->trx, (const void*) trx);
4427
4329
 
4435
4337
    ut_error;
4436
4338
  }
4437
4339
 
4438
 
  sql_command = session_sql_command(user_session);
 
4340
  sql_command = user_session->getSqlCommand();
4439
4341
 
4440
4342
  if ((sql_command == SQLCOM_ALTER_TABLE
4441
4343
       || sql_command == SQLCOM_CREATE_INDEX
4882
4784
  if (error == DB_SUCCESS
4883
4785
      && getTable()->next_number_field
4884
4786
      && new_row == getTable()->getInsertRecord()
4885
 
      && session_sql_command(user_session) == SQLCOM_INSERT
 
4787
      && user_session->getSqlCommand() == SQLCOM_INSERT
4886
4788
      && (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
4887
4789
    == TRX_DUP_IGNORE)  {
4888
4790
 
5349
5251
         table. Only print message if the index translation
5350
5252
         table exists */
5351
5253
      if (share->idx_trans_tbl.index_mapping) {
5352
 
        errmsg_printf(ERRMSG_LVL_ERROR,
 
5254
        errmsg_printf(error::ERROR,
5353
5255
                      "InnoDB could not find "
5354
5256
                      "index %s key no %u for "
5355
5257
                      "table %s through its "
5367
5269
  }
5368
5270
 
5369
5271
  if (!index) {
5370
 
    errmsg_printf(ERRMSG_LVL_ERROR, 
 
5272
    errmsg_printf(error::ERROR, 
5371
5273
      "Innodb could not find key n:o %u with name %s "
5372
5274
      "from dict cache for table %s",
5373
 
      keynr, getTable()->getShare()->getTableProto()->indexes(keynr).name().c_str(),
 
5275
      keynr, getTable()->getShare()->getTableMessage()->indexes(keynr).name().c_str(),
5374
5276
      prebuilt->table->name);
5375
5277
  }
5376
5278
 
5396
5298
  prebuilt->index = innobase_get_index(keynr);
5397
5299
 
5398
5300
  if (UNIV_UNLIKELY(!prebuilt->index)) {
5399
 
    errmsg_printf(ERRMSG_LVL_WARN, "InnoDB: change_active_index(%u) failed",
 
5301
    errmsg_printf(error::WARN, "InnoDB: change_active_index(%u) failed",
5400
5302
          keynr);
5401
5303
    prebuilt->index_usable = FALSE;
5402
5304
    return(1);
5762
5664
  table. */
5763
5665
 
5764
5666
  if (len != ref_length) {
5765
 
    errmsg_printf(ERRMSG_LVL_ERROR, "Stored ref len is %lu, but table ref len is %lu",
 
5667
    errmsg_printf(error::ERROR, "Stored ref len is %lu, but table ref len is %lu",
5766
5668
        (ulong) len, (ulong) ref_length);
5767
5669
  }
5768
5670
}
5821
5723
 
5822
5724
    if (!col_type) {
5823
5725
      push_warning_printf(
5824
 
                          (Session*) trx->mysql_thd,
 
5726
                          trx->mysql_thd,
5825
5727
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
5826
5728
                          ER_CANT_CREATE_TABLE,
5827
5729
                          "Error creating table '%s' with "
5855
5757
        /* in data0type.h we assume that the
5856
5758
        number fits in one byte in prtype */
5857
5759
        push_warning_printf(
5858
 
          (Session*) trx->mysql_thd,
 
5760
          trx->mysql_thd,
5859
5761
          DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5860
5762
          ER_CANT_CREATE_TABLE,
5861
5763
          "In InnoDB, charset-collation codes"
6021
5923
        || col_type == DATA_FLOAT
6022
5924
        || col_type == DATA_DOUBLE
6023
5925
        || col_type == DATA_DECIMAL) {
6024
 
        errmsg_printf(ERRMSG_LVL_ERROR, 
 
5926
        errmsg_printf(error::ERROR, 
6025
5927
          "MySQL is trying to create a column "
6026
5928
          "prefix index field, on an "
6027
5929
          "inappropriate data type. Table "
6121
6023
/*================*/
6122
6024
  Session         &session, /*!< in: Session */
6123
6025
  Table&    form,   /*!< in: information on table columns and indexes */
6124
 
        const TableIdentifier &identifier,
 
6026
        const identifier::Table &identifier,
6125
6027
        message::Table& create_proto)
6126
6028
{
6127
6029
  int   error;
6130
6032
  trx_t*    trx;
6131
6033
  int   primary_key_no;
6132
6034
  uint    i;
6133
 
  char    name2[FN_REFLEN];
6134
 
  char    norm_name[FN_REFLEN];
6135
6035
  ib_int64_t  auto_inc_value;
6136
6036
  ulint   iflags;
6137
6037
  /* Cache the value of innodb_file_format, in case it is
6141
6041
  const char* stmt;
6142
6042
  size_t stmt_len;
6143
6043
 
6144
 
  const char *table_name= identifier.getPath().c_str();
 
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
  }
6145
6051
 
6146
6052
  if (form.getShare()->sizeFields() > 1000) {
6147
6053
    /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
6164
6070
 
6165
6071
  srv_lower_case_table_names = TRUE;
6166
6072
 
6167
 
  strcpy(name2, table_name);
6168
 
 
6169
 
  normalize_table_name(norm_name, name2);
6170
 
 
6171
6073
  /* Latch the InnoDB data dictionary exclusively so that no deadlocks
6172
6074
    or lock waits can happen in it during a table create operation.
6173
6075
    Drop table etc. do this latching in row0mysql.c. */
6275
6177
  if (lex_identified_temp_table)
6276
6178
    iflags |= DICT_TF2_TEMPORARY << DICT_TF2_SHIFT;
6277
6179
 
6278
 
  error= create_table_def(trx, &form, norm_name,
6279
 
                          lex_identified_temp_table ? name2 : NULL,
 
6180
  error= create_table_def(trx, &form, identifier.getKeyPath().c_str(),
 
6181
                          lex_identified_temp_table ? identifier.getKeyPath().c_str() : NULL,
6280
6182
                          iflags);
6281
6183
 
6282
6184
  session.setXaId(trx->id);
6292
6194
      order the rows by their row id which is internally generated
6293
6195
      by InnoDB */
6294
6196
 
6295
 
    error = create_clustered_index_when_no_primary(trx, iflags, norm_name);
 
6197
    error = create_clustered_index_when_no_primary(trx, iflags, identifier.getKeyPath().c_str());
6296
6198
    if (error) {
6297
6199
      goto cleanup;
6298
6200
    }
6300
6202
 
6301
6203
  if (primary_key_no != -1) {
6302
6204
    /* In InnoDB the clustered index must always be created first */
6303
 
    if ((error = create_index(trx, &form, iflags, norm_name,
 
6205
    if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
6304
6206
                              (uint) primary_key_no))) {
6305
6207
      goto cleanup;
6306
6208
    }
6309
6211
  for (i = 0; i < form.getShare()->sizeKeys(); i++) {
6310
6212
    if (i != (uint) primary_key_no) {
6311
6213
 
6312
 
      if ((error = create_index(trx, &form, iflags, norm_name,
 
6214
      if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
6313
6215
                                i))) {
6314
6216
        goto cleanup;
6315
6217
      }
6316
6218
    }
6317
6219
  }
6318
6220
 
6319
 
  stmt = innobase_get_stmt(&session, &stmt_len);
 
6221
  stmt= session.getQueryStringCopy(stmt_len);
6320
6222
 
6321
6223
  if (stmt) {
6322
6224
    string generated_create_table;
6323
6225
    const char *query= stmt;
6324
6226
 
6325
 
    if (session_sql_command(&session) == SQLCOM_CREATE_TABLE)
 
6227
    if (session.getSqlCommand() == SQLCOM_CREATE_TABLE)
6326
6228
    {
6327
6229
      message::transformTableDefinitionToSql(create_proto,
6328
6230
                                             generated_create_table,
6332
6234
 
6333
6235
    error = row_table_add_foreign_constraints(trx,
6334
6236
                                              query, strlen(query),
6335
 
                                              norm_name,
 
6237
                                              identifier.getKeyPath().c_str(),
6336
6238
                                              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
    }
6337
6261
 
6338
6262
    error = convert_error_code_to_mysql(error, iflags, NULL);
6339
6263
 
6352
6276
 
6353
6277
  log_buffer_flush_to_disk();
6354
6278
 
6355
 
  innobase_table = dict_table_get(norm_name, FALSE);
 
6279
  innobase_table = dict_table_get(identifier.getKeyPath().c_str(), FALSE);
6356
6280
 
6357
6281
  assert(innobase_table != 0);
6358
6282
 
6375
6299
    does a table copy too. */
6376
6300
 
6377
6301
  if ((create_proto.options().has_auto_increment_value()
6378
 
       || session_sql_command(&session) == SQLCOM_ALTER_TABLE
6379
 
       || session_sql_command(&session) == SQLCOM_CREATE_INDEX)
 
6302
       || session.getSqlCommand() == SQLCOM_ALTER_TABLE
 
6303
       || session.getSqlCommand() == SQLCOM_CREATE_INDEX)
6380
6304
      && create_proto.options().auto_increment_value() != 0) {
6381
6305
 
6382
6306
    /* Query was one of :
6469
6393
 
6470
6394
  update_session(getTable()->in_use);
6471
6395
 
6472
 
  if (session_sql_command(user_session) != SQLCOM_TRUNCATE) {
 
6396
  if (user_session->getSqlCommand() != SQLCOM_TRUNCATE) {
6473
6397
  fallback:
6474
6398
    /* We only handle TRUNCATE TABLE t as a special case.
6475
6399
    DELETE FROM t will have to use ha_innobase::doDeleteRecord(),
6503
6427
InnobaseEngine::doDropTable(
6504
6428
/*======================*/
6505
6429
        Session &session,
6506
 
        const TableIdentifier &identifier)
 
6430
        const identifier::Table &identifier)
6507
6431
{
6508
6432
  int error;
6509
6433
  trx_t*  parent_trx;
6510
6434
  trx_t*  trx;
6511
 
  char  norm_name[1000];
6512
6435
 
6513
6436
  ut_a(identifier.getPath().length() < 1000);
6514
6437
 
6515
 
  /* Strangely, MySQL passes the table name without the '.frm'
6516
 
    extension, in contrast to ::create */
6517
 
  normalize_table_name(norm_name, identifier.getPath().c_str());
 
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
  }
6518
6445
 
6519
6446
  /* Get the transaction associated with the current session, or create one
6520
6447
    if not yet created */
6532
6459
 
6533
6460
  /* Drop the table in InnoDB */
6534
6461
 
6535
 
  error = row_drop_table_for_mysql(norm_name, trx,
6536
 
                                   session_sql_command(&session)
 
6462
  error = row_drop_table_for_mysql(identifier.getKeyPath().c_str(), trx,
 
6463
                                   session.getSqlCommand()
6537
6464
                                   == SQLCOM_DROP_DB);
6538
6465
 
6539
6466
  session.setXaId(trx->id);
6561
6488
    if (identifier.getType() == message::Table::TEMPORARY)
6562
6489
    {
6563
6490
      session.getMessageCache().removeTableMessage(identifier);
6564
 
      ulint sql_command = session_sql_command(&session);
 
6491
      ulint sql_command = session.getSqlCommand();
6565
6492
 
6566
6493
      // If this was the final removal to an alter table then we will need
6567
6494
      // to remove the .dfe that was left behind.
6594
6521
bool
6595
6522
InnobaseEngine::doDropSchema(
6596
6523
/*===================*/
6597
 
                             const SchemaIdentifier &identifier)
 
6524
                             const identifier::Schema &identifier)
6598
6525
    /*!< in: database path; inside InnoDB the name
6599
6526
      of the last directory in the path is used as
6600
6527
      the database name: for example, in 'mysql/data/test'
6644
6571
 
6645
6572
void InnobaseEngine::dropTemporarySchema()
6646
6573
{
6647
 
  SchemaIdentifier schema_identifier(GLOBAL_TEMPORARY_EXT);
 
6574
  identifier::Schema schema_identifier(GLOBAL_TEMPORARY_EXT);
6648
6575
  trx_t*  trx= NULL;
6649
6576
  string schema_path(GLOBAL_TEMPORARY_EXT);
6650
6577
 
6681
6608
innobase_rename_table(
6682
6609
/*==================*/
6683
6610
  trx_t*    trx,  /*!< in: transaction */
6684
 
  const char* from, /*!< in: old name of the table */
6685
 
  const char* to, /*!< in: new name of the table */
 
6611
  const identifier::Table &from,
 
6612
  const identifier::Table &to,
6686
6613
  ibool   lock_and_commit)
6687
6614
        /*!< in: TRUE=lock data dictionary and commit */
6688
6615
{
6689
6616
  int error;
6690
 
  char norm_to[FN_REFLEN];
6691
 
  char norm_from[FN_REFLEN];
6692
6617
 
6693
6618
  srv_lower_case_table_names = TRUE;
6694
6619
 
6695
 
  normalize_table_name(norm_to, to);
6696
 
  normalize_table_name(norm_from, from);
6697
 
 
6698
6620
  /* Serialize data dictionary operations with dictionary mutex:
6699
6621
  no deadlocks can occur then in these operations */
6700
6622
 
6702
6624
    row_mysql_lock_data_dictionary(trx);
6703
6625
  }
6704
6626
 
6705
 
  error = row_rename_table_for_mysql(
6706
 
    norm_from, norm_to, trx, lock_and_commit);
 
6627
  error = row_rename_table_for_mysql(from.getKeyPath().c_str(), to.getKeyPath().c_str(), trx, lock_and_commit);
6707
6628
 
6708
6629
  if (error != DB_SUCCESS) {
6709
6630
    FILE* ef = dict_foreign_err_file;
6710
6631
 
6711
6632
    fputs("InnoDB: Renaming table ", ef);
6712
 
    ut_print_name(ef, trx, TRUE, norm_from);
 
6633
    ut_print_name(ef, trx, TRUE, from.getKeyPath().c_str());
6713
6634
    fputs(" to ", ef);
6714
 
    ut_print_name(ef, trx, TRUE, norm_to);
 
6635
    ut_print_name(ef, trx, TRUE, to.getKeyPath().c_str());
6715
6636
    fputs(" failed!\n", ef);
6716
6637
  }
6717
6638
 
6730
6651
/*********************************************************************//**
6731
6652
Renames an InnoDB table.
6732
6653
@return 0 or error code */
6733
 
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
 
6654
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, const identifier::Table &from, const identifier::Table &to)
6734
6655
{
6735
6656
  // A temp table alter table/rename is a shallow rename and only the
6736
6657
  // definition needs to be updated.
6756
6677
 
6757
6678
  trx = innobase_trx_allocate(&session);
6758
6679
 
6759
 
  error = innobase_rename_table(trx, from.getPath().c_str(), to.getPath().c_str(), TRUE);
 
6680
  error = innobase_rename_table(trx, from, to, TRUE);
6760
6681
 
6761
6682
  session.setXaId(trx->id);
6762
6683
 
6781
6702
     is the one we are trying to rename to) and return the generic
6782
6703
     error code. */
6783
6704
  if (error == (int) DB_DUPLICATE_KEY) {
6784
 
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to.getPath().c_str());
 
6705
    my_error(ER_TABLE_EXISTS_ERROR, to);
6785
6706
    error = DB_ERROR;
6786
6707
  }
6787
6708
 
6812
6733
  KeyInfo*    key;
6813
6734
  dict_index_t* index;
6814
6735
  unsigned char*    key_val_buff2 = (unsigned char*) malloc(
6815
 
              getTable()->getShare()->stored_rec_length
 
6736
              getTable()->getShare()->sizeStoredRecord()
6816
6737
          + getTable()->getShare()->max_key_length + 100);
6817
 
  ulint   buff2_len = getTable()->getShare()->stored_rec_length
 
6738
  ulint   buff2_len = getTable()->getShare()->sizeStoredRecord()
6818
6739
          + getTable()->getShare()->max_key_length + 100;
6819
6740
  dtuple_t* range_start;
6820
6741
  dtuple_t* range_end;
6924
6845
  dict_index_t* index;
6925
6846
  uint64_t  estimate;
6926
6847
  uint64_t  local_data_file_length;
 
6848
  ulint stat_n_leaf_pages;
6927
6849
 
6928
6850
  /* We do not know if MySQL can call this function before calling
6929
6851
  external_lock(). To be safe, update the session of the current table
6941
6863
 
6942
6864
  index = dict_table_get_first_index(prebuilt->table);
6943
6865
 
6944
 
  ut_a(index->stat_n_leaf_pages > 0);
 
6866
  stat_n_leaf_pages = index->stat_n_leaf_pages;
 
6867
 
 
6868
  ut_a(stat_n_leaf_pages > 0);
6945
6869
 
6946
6870
  local_data_file_length =
6947
 
    ((uint64_t) index->stat_n_leaf_pages) * UNIV_PAGE_SIZE;
 
6871
    ((uint64_t) stat_n_leaf_pages) * UNIV_PAGE_SIZE;
6948
6872
 
6949
6873
 
6950
6874
  /* Calculate a minimum length for a clustered index record and from
7094
7018
 
7095
7019
                /* Print an error message if we cannot find the index
7096
7020
                ** in the "index translation table". */
7097
 
                errmsg_printf(ERRMSG_LVL_ERROR,
 
7021
                errmsg_printf(error::ERROR,
7098
7022
                              "Cannot find index %s in InnoDB index "
7099
7023
                                "translation table.", index->name);
7100
7024
        }
7111
7035
                }
7112
7036
        }
7113
7037
 
7114
 
                errmsg_printf(ERRMSG_LVL_ERROR,
 
7038
                errmsg_printf(error::ERROR,
7115
7039
                              "Cannot find matching index number for index %s "
7116
7040
                              "in InnoDB index list.", index->name);
7117
7041
 
7157
7081
 
7158
7082
    prebuilt->trx->op_info = "updating table statistics";
7159
7083
 
7160
 
    dict_update_statistics(ib_table);
 
7084
    dict_update_statistics(ib_table,
 
7085
                           FALSE /* update even if stats
 
7086
                                    are initialized */);
 
7087
 
7161
7088
 
7162
7089
    prebuilt->trx->op_info = "returning various info to MySQL";
7163
7090
 
7174
7101
  }
7175
7102
 
7176
7103
  if (flag & HA_STATUS_VARIABLE) {
 
7104
 
 
7105
    dict_table_stats_lock(ib_table, RW_S_LATCH);
 
7106
 
7177
7107
    n_rows = ib_table->stat_n_rows;
7178
7108
 
7179
7109
    /* Because we do not protect stat_n_rows by any mutex in a
7201
7131
    n_rows can not be 0 unless the table is empty, set to 1
7202
7132
    instead. The original problem of bug#29507 is actually
7203
7133
    fixed in the server code. */
7204
 
    if (session_sql_command(user_session) == SQLCOM_TRUNCATE) {
 
7134
    if (user_session->getSqlCommand() == SQLCOM_TRUNCATE) {
7205
7135
 
7206
7136
      n_rows = 1;
7207
7137
 
7223
7153
        ib_table->stat_sum_of_other_index_sizes)
7224
7154
          * UNIV_PAGE_SIZE;
7225
7155
 
 
7156
    dict_table_stats_unlock(ib_table, RW_S_LATCH);
 
7157
 
7226
7158
    /* Since fsp_get_available_space_in_free_extents() is
7227
7159
    acquiring latches inside InnoDB, we do not call it if we
7228
7160
    are asked by MySQL to avoid locking. Another reason to
7239
7171
         innodb_crash_recovery is set to a high value. */
7240
7172
      stats.delete_length = 0;
7241
7173
    } else {
7242
 
      /* lock the data dictionary to avoid races with
7243
 
      ibd_file_missing and tablespace_discarded */
7244
 
      row_mysql_lock_data_dictionary(prebuilt->trx);
7245
 
 
7246
 
      /* ib_table->space must be an existent tablespace */
7247
 
      if (!ib_table->ibd_file_missing
7248
 
          && !ib_table->tablespace_discarded) {
7249
 
 
7250
 
        stats.delete_length =
7251
 
          fsp_get_available_space_in_free_extents(
7252
 
            ib_table->space) * 1024;
7253
 
      } else {
7254
 
 
 
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) {
7255
7179
        Session*  session;
7256
7180
 
7257
7181
        session= getTable()->in_use;
7269
7193
          ib_table->name);
7270
7194
 
7271
7195
        stats.delete_length = 0;
 
7196
      } else {
 
7197
        stats.delete_length = avail_space * 1024;
7272
7198
      }
7273
 
 
7274
 
      row_mysql_unlock_data_dictionary(prebuilt->trx);
7275
7199
    }
7276
7200
 
7277
7201
    stats.check_time = 0;
7291
7215
    ulint       num_innodb_index = UT_LIST_GET_LEN(ib_table->indexes) - prebuilt->clust_index_was_generated;
7292
7216
 
7293
7217
    if (getTable()->getShare()->keys != num_innodb_index) {
7294
 
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains %lu "
 
7218
      errmsg_printf(error::ERROR, "Table %s contains %lu "
7295
7219
                      "indexes inside InnoDB, which "
7296
7220
                      "is different from the number of "
7297
7221
                      "indexes %u defined in the MySQL ",
7299
7223
                      getTable()->getShare()->keys);
7300
7224
    }
7301
7225
 
 
7226
    dict_table_stats_lock(ib_table, RW_S_LATCH);
 
7227
 
7302
7228
    for (i = 0; i < getTable()->getShare()->sizeKeys(); i++) {
7303
7229
      ulong j;
7304
7230
      /* We could get index quickly through internal
7309
7235
      index = innobase_get_index(i);
7310
7236
 
7311
7237
      if (index == NULL) {
7312
 
        errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains fewer "
 
7238
        errmsg_printf(error::ERROR, "Table %s contains fewer "
7313
7239
            "indexes inside InnoDB than "
7314
7240
            "are defined in the MySQL "
7315
7241
            ".frm file. Have you mixed up "
7324
7250
      for (j = 0; j < getTable()->key_info[i].key_parts; j++) {
7325
7251
 
7326
7252
        if (j + 1 > index->n_uniq) {
7327
 
          errmsg_printf(ERRMSG_LVL_ERROR, 
 
7253
          errmsg_printf(error::ERROR, 
7328
7254
"Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking "
7329
7255
"statistics for %lu columns. Have you mixed up .frm files from different "
7330
7256
"installations? "
7336
7262
          break;
7337
7263
        }
7338
7264
 
7339
 
        dict_index_stat_mutex_enter(index);
7340
 
 
7341
7265
        if (index->stat_n_diff_key_vals[j + 1] == 0) {
7342
7266
 
7343
7267
          rec_per_key = stats.records;
7346
7270
           index->stat_n_diff_key_vals[j + 1]);
7347
7271
        }
7348
7272
 
7349
 
        dict_index_stat_mutex_exit(index);
7350
 
 
7351
7273
        /* Since MySQL seems to favor table scans
7352
7274
        too much over index searches, we pretend
7353
7275
        index selectivity is 2 times better than
7364
7286
          (ulong) rec_per_key;
7365
7287
      }
7366
7288
    }
 
7289
 
 
7290
    dict_table_stats_unlock(ib_table, RW_S_LATCH);
7367
7291
  }
7368
7292
 
7369
7293
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
7443
7367
  }
7444
7368
 
7445
7369
  if (prebuilt->table->ibd_file_missing) {
7446
 
        errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: Error:\n"
 
7370
        errmsg_printf(error::ERROR, "InnoDB: Error:\n"
7447
7371
                    "InnoDB: MySQL is trying to use a table handle"
7448
7372
                    " but the .ibd file for\n"
7449
7373
                    "InnoDB: table %s does not exist.\n"
7693
7617
  flen = ftell(srv_dict_tmpfile);
7694
7618
  if (flen < 0) {
7695
7619
    flen = 0;
7696
 
  } else if (flen > 64000 - 1) {
7697
 
    flen = 64000 - 1;
7698
7620
  }
7699
7621
 
7700
7622
  /* allocate buffer for the string, and
7754
7676
      i++;
7755
7677
    }
7756
7678
    db_name[i] = 0;
7757
 
    ulen= TableIdentifier::filename_to_tablename(db_name, uname, sizeof(uname));
 
7679
    ulen= identifier::Table::filename_to_tablename(db_name, uname, sizeof(uname));
7758
7680
    LEX_STRING *tmp_referenced_db = session->make_lex_string(NULL, uname, ulen, true);
7759
7681
 
7760
7682
    /* Table name */
7761
7683
    tmp_buff += i + 1;
7762
 
    ulen= TableIdentifier::filename_to_tablename(tmp_buff, uname, sizeof(uname));
 
7684
    ulen= identifier::Table::filename_to_tablename(tmp_buff, uname, sizeof(uname));
7763
7685
    LEX_STRING *tmp_referenced_table = session->make_lex_string(NULL, uname, ulen, true);
7764
7686
 
7765
7687
    /** Foreign Fields **/
7837
7759
                              tmp_foreign_fields, tmp_referenced_fields);
7838
7760
 
7839
7761
    ForeignKeyInfo *pf_key_info = (ForeignKeyInfo *)
7840
 
      session->memdup(&f_key_info, sizeof(ForeignKeyInfo));
 
7762
      session->getMemRoot()->duplicate(&f_key_info, sizeof(ForeignKeyInfo));
7841
7763
    f_key_list->push_back(pf_key_info);
7842
7764
    foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
7843
7765
  }
8367
8289
static INNOBASE_SHARE* get_share(const char* table_name)
8368
8290
{
8369
8291
  INNOBASE_SHARE *share;
8370
 
  pthread_mutex_lock(&innobase_share_mutex);
 
8292
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
8371
8293
 
8372
8294
  ulint fold = ut_fold_string(table_name);
8373
8295
 
8394
8316
  }
8395
8317
 
8396
8318
  share->use_count++;
8397
 
  pthread_mutex_unlock(&innobase_share_mutex);
8398
8319
 
8399
8320
  return(share);
8400
8321
}
8401
8322
 
8402
8323
static void free_share(INNOBASE_SHARE* share)
8403
8324
{
8404
 
  pthread_mutex_lock(&innobase_share_mutex);
 
8325
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
8405
8326
 
8406
8327
#ifdef UNIV_DEBUG
8407
8328
  INNOBASE_SHARE* share2;
8430
8351
    /* TODO: invoke HASH_MIGRATE if innobase_open_tables
8431
8352
    shrinks too much */
8432
8353
  }
8433
 
 
8434
 
  pthread_mutex_unlock(&innobase_share_mutex);
8435
8354
}
8436
8355
 
8437
8356
/*****************************************************************//**
8466
8385
  trx = check_trx_exists(session);
8467
8386
 
8468
8387
  assert(EQ_CURRENT_SESSION(session));
8469
 
  const uint32_t sql_command = session_sql_command(session);
 
8388
  const uint32_t sql_command = session->getSqlCommand();
8470
8389
 
8471
8390
  if (sql_command == SQLCOM_DROP_TABLE) {
8472
8391
 
8552
8471
 
8553
8472
    if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
8554
8473
         && lock_type <= TL_WRITE)
8555
 
        && !session_tablespace_op(session)
 
8474
        && ! session->doing_tablespace_operation()
8556
8475
        && sql_command != SQLCOM_TRUNCATE
8557
8476
        && sql_command != SQLCOM_CREATE_TABLE) {
8558
8477
 
8629
8548
 
8630
8549
  if (auto_inc == 0) {
8631
8550
    ut_print_timestamp(stderr);
8632
 
    fprintf(stderr, "  InnoDB: AUTOINC next value generation "
8633
 
            "is disabled for '%s'\n", innodb_table->name);
 
8551
    errmsg_printf(error::ERROR, "  InnoDB: AUTOINC next value generation is disabled for '%s'\n", innodb_table->name);
8634
8552
  }
8635
8553
 
8636
8554
  dict_table_autoinc_unlock(innodb_table);
8785
8703
/* See comment in Cursor.cc */
8786
8704
UNIV_INTERN
8787
8705
bool
8788
 
InnobaseEngine::get_error_message(int, String *buf)
 
8706
InnobaseEngine::get_error_message(int, String *buf) const
8789
8707
{
8790
8708
  trx_t*  trx = check_trx_exists(current_session);
8791
8709
 
8869
8787
finds charset information and returns length of prefix_len characters in the
8870
8788
index field in bytes.
8871
8789
@return number of bytes occupied by the first n characters */
8872
 
extern "C" UNIV_INTERN
 
8790
UNIV_INTERN
8873
8791
ulint
8874
8792
innobase_get_at_most_n_mbchars(
8875
8793
/*===========================*/
8962
8880
  trx->detailed_error[0]= '\0';
8963
8881
 
8964
8882
  /* Set the isolation level of the transaction. */
8965
 
  trx->isolation_level= innobase_map_isolation_level(session_tx_isolation(session));
 
8883
  trx->isolation_level= innobase_map_isolation_level(session->getTxIsolation());
8966
8884
}
8967
8885
 
8968
8886
void
9005
8923
    return(0);
9006
8924
  }
9007
8925
 
9008
 
  session->get_xid(reinterpret_cast<DRIZZLE_XID*>(&trx->xid));
 
8926
  session->get_xid(reinterpret_cast<DrizzleXid*>(&trx->xid));
9009
8927
 
9010
8928
  /* Release a possible FIFO ticket and search latch. Since we will
9011
8929
  reserve the kernel mutex, we have to release the search system latch
9230
9148
          "Purge threads can be either 0 or 1. Defalut is 0.");
9231
9149
  context("file-per-table",
9232
9150
          po::value<bool>(&srv_file_per_table)->default_value(false)->zero_tokens(),
9233
 
          "Stores each InnoDB table to an .ibd file in the database dir.");
9234
 
  context("file-format",
9235
 
          po::value<string>(&innobase_file_format_name)->default_value("Antelope"),
9236
 
          "File format to use for new tables in .ibd files.");
 
9151
           "Stores each InnoDB table to an .ibd file in the database dir.");
9237
9152
  context("file-format-max",
9238
9153
          po::value<string>(&innobase_file_format_max)->default_value("Antelope"),
9239
9154
          "The highest file format in the tablespace.");
9240
9155
  context("file-format-check",
9241
9156
          po::value<bool>(&innobase_file_format_check)->default_value(true)->zero_tokens(),
9242
9157
          "Whether to perform system file format check.");
 
9158
  context("file-format",
 
9159
          po::value<string>(&innobase_file_format_name)->default_value("Antelope"),
 
9160
          "File format to use for new tables in .ibd files.");
9243
9161
  context("flush-log-at-trx-commit",
9244
9162
          po::value<trinary_constraint>(&innodb_flush_log_at_trx_commit)->default_value(1),
9245
9163
          "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).");
9274
9192
          po::value<additional_mem_pool_constraint>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
9275
9193
          "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.");
9276
9194
  context("autoextend-increment",
9277
 
          po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(8L),
 
9195
          po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(64L),
9278
9196
          "Data file autoextend increment in megabytes");
9279
9197
  context("buffer-pool-size",
9280
9198
          po::value<buffer_pool_constraint>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
9333
9251
          "InnoDB version");
9334
9252
  context("use-internal-malloc",
9335
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"));
9336
9256
  context("change-buffering",
9337
9257
          po::value<string>(&innobase_change_buffering),
9338
9258
          "Buffer changes to reduce random access: OFF, ON, inserting, deleting, changing, or purging.");
9373
9293
  "Supports transactions, row-level locking, and foreign keys",
9374
9294
  PLUGIN_LICENSE_GPL,
9375
9295
  innobase_init, /* Plugin Init */
9376
 
  NULL, /* system variables */
 
9296
  NULL, /* depends */
9377
9297
  init_options /* reserved */
9378
9298
}
9379
9299
DRIZZLE_DECLARE_PLUGIN_END;
9405
9325
This function checks each index name for a table against reserved
9406
9326
system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
9407
9327
this function pushes an warning message to the client, and returns true. */
9408
 
extern "C" UNIV_INTERN
 
9328
UNIV_INTERN
9409
9329
bool
9410
9330
innobase_index_name_is_reserved(
9411
9331
/*============================*/
9425
9345
    if (innobase_strcasecmp(key->name,
9426
9346
                            innobase_index_reserve_name) == 0) {
9427
9347
      /* Push warning to drizzle */
9428
 
      push_warning_printf((Session*)trx->mysql_thd,
 
9348
      push_warning_printf(trx->mysql_thd,
9429
9349
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
9430
9350
                          ER_WRONG_NAME_FOR_INDEX,
9431
9351
                          "Cannot Create Index with name "
9451
9371
  ulint   buflen;
9452
9372
  const char* id;
9453
9373
  ulint   idlen;
9454
 
  void*   session;
 
9374
  drizzled::Session *session;
9455
9375
  ibool   file_id;
9456
9376
 
9457
9377
  const char* expected;