~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2010-12-25 00:28:49 UTC
  • mto: This revision was merged to the branch mainline in revision 2031.
  • Revision ID: brian@tangent.org-20101225002849-g73mg6ihulajis0o
First pass in refactoring of the name of my_decimal.

Show diffs side-by-side

added added

removed removed

Lines of Context:
71
71
 
72
72
#include <boost/algorithm/string.hpp>
73
73
#include <boost/program_options.hpp>
74
 
#include <boost/scoped_array.hpp>
75
74
#include <boost/filesystem.hpp>
76
75
#include <drizzled/module/option_map.h>
77
76
#include <iostream>
83
82
/** @file ha_innodb.cc */
84
83
 
85
84
/* Include necessary InnoDB headers */
 
85
extern "C" {
86
86
#include "univ.i"
87
87
#include "buf0lru.h"
88
88
#include "btr0sea.h"
114
114
#include "ha_prototypes.h"
115
115
#include "ut0mem.h"
116
116
#include "ibuf0ibuf.h"
 
117
#include "mysql_addons.h"
 
118
}
117
119
 
118
120
#include "ha_innodb.h"
119
121
#include "data_dictionary.h"
133
135
#include <google/protobuf/io/coded_stream.h>
134
136
#include <google/protobuf/text_format.h>
135
137
 
136
 
#include <boost/thread/mutex.hpp>
137
 
 
138
138
using namespace std;
139
139
using namespace drizzled;
140
140
 
141
141
/** to protect innobase_open_files */
142
 
static boost::mutex innobase_share_mutex;
143
 
 
 
142
static pthread_mutex_t innobase_share_mutex;
144
143
/** to force correct commit order in binlog */
 
144
static pthread_mutex_t prepare_commit_mutex;
145
145
static ulong commit_threads = 0;
146
 
static boost::condition_variable commit_cond;
147
 
static boost::mutex commit_cond_m;
 
146
static pthread_mutex_t commit_threads_m;
 
147
static pthread_cond_t commit_cond;
 
148
static pthread_mutex_t commit_cond_m;
148
149
static bool innodb_inited = 0;
149
150
 
150
151
#define INSIDE_HA_INNOBASE_CC
160
161
#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
161
162
 
162
163
static plugin::XaStorageEngine* innodb_engine_ptr= NULL;
163
 
 
 
164
static plugin::TableFunction* status_table_function_ptr= NULL;
 
165
static plugin::TableFunction* cmp_tool= NULL;
 
166
static plugin::TableFunction* cmp_reset_tool= NULL;
 
167
static plugin::TableFunction* cmp_mem_tool= NULL;
 
168
static plugin::TableFunction* cmp_mem_reset_tool= NULL;
 
169
static plugin::TableFunction* innodb_trx_tool= NULL;
 
170
static plugin::TableFunction* innodb_locks_tool= NULL;
 
171
static plugin::TableFunction* innodb_lock_waits_tool= NULL;
 
172
static plugin::TableFunction* innodb_sys_tables_tool= NULL;
 
173
static plugin::TableFunction* innodb_sys_tablestats_tool= NULL;
 
174
 
 
175
static plugin::TableFunction* innodb_sys_indexes_tool= NULL;
 
176
static plugin::TableFunction* innodb_sys_columns_tool= NULL;
 
177
static plugin::TableFunction* innodb_sys_fields_tool= NULL;
 
178
static plugin::TableFunction* innodb_sys_foreign_tool= NULL;
 
179
static plugin::TableFunction* innodb_sys_foreign_cols_tool= NULL;
 
180
 
 
181
static ReplicationLog *replication_logger= NULL;
164
182
typedef constrained_check<uint32_t, UINT32_MAX, 10> open_files_constraint;
165
183
static open_files_constraint innobase_open_files;
166
184
typedef constrained_check<uint32_t, 10, 1> mirrored_log_groups_constraint;
185
203
static purge_batch_constraint innodb_purge_batch_size;
186
204
typedef constrained_check<uint32_t, 1, 0> purge_threads_constraint;
187
205
static purge_threads_constraint innodb_n_purge_threads;
188
 
typedef constrained_check<uint32_t, 2, 0> trinary_constraint;
 
206
typedef constrained_check<uint16_t, 2, 0> trinary_constraint;
189
207
static trinary_constraint innodb_flush_log_at_trx_commit;
190
208
typedef constrained_check<unsigned int, 99, 0> max_dirty_pages_constraint;
191
209
static max_dirty_pages_constraint innodb_max_dirty_pages_pct;
234
252
/* Below we have boolean-valued start-up parameters, and their default
235
253
values */
236
254
 
237
 
typedef constrained_check<uint32_t, 2, 0> trinary_constraint;
 
255
typedef constrained_check<uint16_t, 2, 0> trinary_constraint;
238
256
static trinary_constraint innobase_fast_shutdown;
239
257
 
240
258
/* "innobase_file_format_check" decides whether we would continue
333
351
      srv_free_paths_and_sizes();
334
352
      if (internal_innobase_data_file_path)
335
353
        free(internal_innobase_data_file_path);
 
354
      pthread_mutex_destroy(&innobase_share_mutex);
 
355
      pthread_mutex_destroy(&prepare_commit_mutex);
 
356
      pthread_mutex_destroy(&commit_threads_m);
 
357
      pthread_mutex_destroy(&commit_cond_m);
 
358
      pthread_cond_destroy(&commit_cond);
336
359
    }
337
360
    
338
361
    /* These get strdup'd from vm variables */
422
445
  doDropSchema(
423
446
  /*===================*/
424
447
        /* out: error number */
425
 
    const identifier::Schema  &identifier); /* in: database path; inside InnoDB the name
 
448
    const SchemaIdentifier  &identifier); /* in: database path; inside InnoDB the name
426
449
        of the last directory in the path is used as
427
450
        the database name: for example, in 'mysql/data/test'
428
451
        the database name is 'test' */
461
484
 
462
485
  UNIV_INTERN int doCreateTable(Session &session,
463
486
                                Table &form,
464
 
                                const identifier::Table &identifier,
 
487
                                const TableIdentifier &identifier,
465
488
                                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);
 
489
  UNIV_INTERN int doRenameTable(Session&, const TableIdentifier &from, const TableIdentifier &to);
 
490
  UNIV_INTERN int doDropTable(Session &session, const TableIdentifier &identifier);
468
491
 
469
 
  UNIV_INTERN virtual bool get_error_message(int error, String *buf) const;
 
492
  UNIV_INTERN virtual bool get_error_message(int error, String *buf);
470
493
 
471
494
  UNIV_INTERN uint32_t max_supported_keys() const;
472
495
  UNIV_INTERN uint32_t max_supported_key_length() const;
483
506
  }
484
507
 
485
508
  int doGetTableDefinition(drizzled::Session& session,
486
 
                           const identifier::Table &identifier,
 
509
                           const TableIdentifier &identifier,
487
510
                           drizzled::message::Table &table_proto);
488
511
 
489
 
  bool doDoesTableExist(drizzled::Session& session, const identifier::Table &identifier);
 
512
  bool doDoesTableExist(drizzled::Session& session, const TableIdentifier &identifier);
490
513
 
491
514
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
492
 
                             const drizzled::identifier::Schema &schema_identifier,
493
 
                             drizzled::identifier::Table::vector &set_of_identifiers);
 
515
                             const drizzled::SchemaIdentifier &schema_identifier,
 
516
                             drizzled::TableIdentifier::vector &set_of_identifiers);
494
517
  bool validateCreateTableOption(const std::string &key, const std::string &state);
495
518
  void dropTemporarySchema();
496
519
 
518
541
}
519
542
 
520
543
void InnobaseEngine::doGetTableIdentifiers(drizzled::CachedDirectory &directory,
521
 
                                           const drizzled::identifier::Schema &schema_identifier,
522
 
                                           drizzled::identifier::Table::vector &set_of_identifiers)
 
544
                                           const drizzled::SchemaIdentifier &schema_identifier,
 
545
                                           drizzled::TableIdentifier::vector &set_of_identifiers)
523
546
{
524
547
  CachedDirectory::Entries entries= directory.getEntries();
525
548
 
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
549
  for (CachedDirectory::Entries::iterator entry_iter= entries.begin(); 
536
550
       entry_iter != entries.end(); ++entry_iter)
537
551
  {
559
573
           Using schema_identifier here to stop unused warning, could use
560
574
           definition.schema() instead
561
575
        */
562
 
        identifier::Table identifier(schema_identifier.getSchemaName(), definition.name());
 
576
        TableIdentifier identifier(schema_identifier.getSchemaName(), definition.name());
563
577
        set_of_identifiers.push_back(identifier);
564
578
      }
565
579
    }
566
580
  }
567
581
}
568
582
 
569
 
bool InnobaseEngine::doDoesTableExist(Session &session, const identifier::Table &identifier)
 
583
bool InnobaseEngine::doDoesTableExist(Session &session, const TableIdentifier &identifier)
570
584
{
571
585
  string proto_path(identifier.getPath());
572
586
  proto_path.append(DEFAULT_FILE_EXTENSION);
574
588
  if (session.getMessageCache().doesTableMessageExist(identifier))
575
589
    return true;
576
590
 
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
 
 
583
591
  if (access(proto_path.c_str(), F_OK))
584
592
  {
585
593
    return false;
589
597
}
590
598
 
591
599
int InnobaseEngine::doGetTableDefinition(Session &session,
592
 
                                         const identifier::Table &identifier,
 
600
                                         const TableIdentifier &identifier,
593
601
                                         message::Table &table_proto)
594
602
{
595
603
  string proto_path(identifier.getPath());
599
607
  if (session.getMessageCache().getTableMessage(identifier, table_proto))
600
608
    return EEXIST;
601
609
 
602
 
  if (read_replication_log_table_message(identifier.getTableName().c_str(), &table_proto) == 0)
603
 
    return EEXIST;
604
 
 
605
610
  if (access(proto_path.c_str(), F_OK))
606
611
  {
607
612
    return errno;
798
803
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
799
804
         in non-Cursor code.
800
805
@return true if session is the replication thread */
801
 
UNIV_INTERN
 
806
extern "C" UNIV_INTERN
802
807
ibool
803
808
thd_is_replication_slave_thread(
804
809
/*============================*/
805
 
  drizzled::Session* ) /*!< in: thread handle (Session*) */
 
810
  void* ) /*!< in: thread handle (Session*) */
806
811
{
807
812
  return false;
808
813
}
872
877
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
873
878
         in non-Cursor code.
874
879
@return true if non-transactional tables have been edited */
875
 
UNIV_INTERN
 
880
extern "C" UNIV_INTERN
876
881
ibool
877
882
thd_has_edited_nontrans_tables(
878
883
/*===========================*/
879
 
  drizzled::Session *session)  /*!< in: thread handle (Session*) */
 
884
  void*   session)  /*!< in: thread handle (Session*) */
880
885
{
881
 
  return((ibool)session->transaction.all.hasModifiedNonTransData());
 
886
  return((ibool)((Session *)session)->transaction.all.hasModifiedNonTransData());
882
887
}
883
888
 
884
889
/******************************************************************//**
885
890
Returns true if the thread is executing a SELECT statement.
886
891
@return true if session is executing SELECT */
887
 
UNIV_INTERN
 
892
extern "C" UNIV_INTERN
888
893
ibool
889
894
thd_is_select(
890
895
/*==========*/
891
 
  const drizzled::Session *session)  /*!< in: thread handle (Session*) */
 
896
  const void* session)  /*!< in: thread handle (Session*) */
892
897
{
893
 
  return(session->getSqlCommand() == SQLCOM_SELECT);
 
898
  return(session_sql_command((const Session*) session) == SQLCOM_SELECT);
894
899
}
895
900
 
896
901
/******************************************************************//**
897
902
Returns true if the thread supports XA,
898
903
global value of innodb_supports_xa if session is NULL.
899
904
@return true if session has XA support */
900
 
UNIV_INTERN
 
905
extern "C" UNIV_INTERN
901
906
ibool
902
907
thd_supports_xa(
903
908
/*============*/
904
 
  drizzled::Session* )  /*!< in: thread handle (Session*), or NULL to query
 
909
  void* )  /*!< in: thread handle (Session*), or NULL to query
905
910
        the global innodb_supports_xa */
906
911
{
907
912
  /* TODO: Add support here for per-session value */
911
916
/******************************************************************//**
912
917
Returns the lock wait timeout for the current connection.
913
918
@return the lock wait timeout, in seconds */
914
 
UNIV_INTERN
 
919
extern "C" UNIV_INTERN
915
920
ulong
916
921
thd_lock_wait_timeout(
917
922
/*==================*/
918
 
  drizzled::Session*)  /*!< in: thread handle (Session*), or NULL to query
 
923
  void*)  /*!< in: thread handle (Session*), or NULL to query
919
924
      the global innodb_lock_wait_timeout */
920
925
{
921
926
  /* TODO: Add support here for per-session value */
926
931
 
927
932
/******************************************************************//**
928
933
Set the time waited for the lock for the current query. */
929
 
UNIV_INTERN
 
934
extern "C" UNIV_INTERN
930
935
void
931
936
thd_set_lock_wait_time(
932
937
/*===================*/
933
 
        drizzled::Session*      in_session,     /*!< in: thread handle (THD*) */
 
938
        void*   thd,    /*!< in: thread handle (THD*) */
934
939
        ulint   value)  /*!< in: time waited for the lock */
935
940
{
936
 
  if (in_session)
937
 
    in_session->utime_after_lock+= value;
 
941
        if (thd) {
 
942
          static_cast<Session*>(thd)->utime_after_lock+= value;
 
943
        }
938
944
}
939
945
 
940
946
/********************************************************************//**
960
966
  trx_t *trx= session_to_trx(&session);
961
967
 
962
968
  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
  ulint error= insert_replication_message(data, message.ByteSize(), trx, trx_id);
969
970
  (void)error;
970
971
 
971
972
  delete[] data;
1022
1023
about a possible transaction rollback inside InnoDB caused by a lock wait
1023
1024
timeout or a deadlock.
1024
1025
@return MySQL error code */
1025
 
UNIV_INTERN
 
1026
extern "C" UNIV_INTERN
1026
1027
int
1027
1028
convert_error_code_to_mysql(
1028
1029
/*========================*/
1076
1077
    tell it also to MySQL so that MySQL knows to empty the
1077
1078
    cached binlog for this transaction */
1078
1079
 
1079
 
    session->markTransactionForRollback(TRUE);
 
1080
    mark_transaction_to_rollback(session, TRUE);
1080
1081
 
1081
1082
    return(HA_ERR_LOCK_DEADLOCK);
1082
1083
 
1085
1086
    latest SQL statement in a lock wait timeout. Previously, we
1086
1087
    rolled back the whole transaction. */
1087
1088
 
1088
 
    session->markTransactionForRollback((bool)row_rollback_on_timeout);
 
1089
    mark_transaction_to_rollback(session, (bool)row_rollback_on_timeout);
1089
1090
 
1090
1091
    return(HA_ERR_LOCK_WAIT_TIMEOUT);
1091
1092
 
1121
1122
 
1122
1123
  case DB_TOO_BIG_RECORD:
1123
1124
    my_error(ER_TOO_BIG_ROWSIZE, MYF(0),
1124
 
             page_get_free_space_of_empty(flags & DICT_TF_COMPACT) / 2);
 
1125
       page_get_free_space_of_empty(flags
 
1126
                  & DICT_TF_COMPACT) / 2);
1125
1127
    return(HA_ERR_TO_BIG_ROW);
1126
1128
 
1127
1129
  case DB_NO_SAVEPOINT:
1132
1134
    tell it also to MySQL so that MySQL knows to empty the
1133
1135
    cached binlog for this transaction */
1134
1136
 
1135
 
    session->markTransactionForRollback(TRUE);
 
1137
    mark_transaction_to_rollback(session, TRUE);
1136
1138
 
1137
1139
    return(HA_ERR_LOCK_TABLE_FULL);
1138
1140
 
1166
1168
 
1167
1169
/*************************************************************//**
1168
1170
Prints info of a Session object (== user session thread) to the given file. */
1169
 
UNIV_INTERN
 
1171
extern "C" UNIV_INTERN
1170
1172
void
1171
1173
innobase_mysql_print_thd(
1172
1174
/*=====================*/
1173
1175
  FILE* f,    /*!< in: output stream */
1174
 
  drizzled::Session *in_session,  /*!< in: pointer to a Drizzle Session object */
 
1176
  void * in_session,  /*!< in: pointer to a Drizzle Session object */
1175
1177
  uint  )   /*!< in: max query length to print, or 0 to
1176
1178
           use the default max length */
1177
1179
{
1178
 
  drizzled::identifier::User::const_shared_ptr user_identifier(in_session->user());
 
1180
  Session *session= reinterpret_cast<Session *>(in_session);
 
1181
  drizzled::identifier::User::const_shared_ptr user_identifier(session->user());
1179
1182
 
1180
1183
  fprintf(f,
1181
1184
          "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()),
 
1185
          static_cast<uint64_t>(session->getSessionId()),
 
1186
          static_cast<uint64_t>(session->getQueryId()),
1184
1187
          glob_hostname,
1185
1188
          user_identifier->address().c_str(),
1186
1189
          user_identifier->username().c_str()
1187
1190
  );
1188
 
  fprintf(f, "\n%s", in_session->getQueryString()->c_str());
 
1191
  fprintf(f, "\n%s", session->getQueryString()->c_str());
1189
1192
  putc('\n', f);
1190
1193
}
1191
1194
 
1192
1195
/******************************************************************//**
1193
1196
Get the variable length bounds of the given character set. */
1194
 
UNIV_INTERN
 
1197
extern "C" UNIV_INTERN
1195
1198
void
1196
1199
innobase_get_cset_width(
1197
1200
/*====================*/
1218
1221
 
1219
1222
/******************************************************************//**
1220
1223
Converts an identifier to a table name. */
1221
 
UNIV_INTERN
 
1224
extern "C" UNIV_INTERN
1222
1225
void
1223
1226
innobase_convert_from_table_id(
1224
1227
/*===========================*/
1232
1235
 
1233
1236
/******************************************************************//**
1234
1237
Converts an identifier to UTF-8. */
1235
 
UNIV_INTERN
 
1238
extern "C" UNIV_INTERN
1236
1239
void
1237
1240
innobase_convert_from_id(
1238
1241
/*=====================*/
1247
1250
/******************************************************************//**
1248
1251
Compares NUL-terminated UTF-8 strings case insensitively.
1249
1252
@return 0 if a=b, <0 if a<b, >1 if a>b */
1250
 
UNIV_INTERN
 
1253
extern "C" UNIV_INTERN
1251
1254
int
1252
1255
innobase_strcasecmp(
1253
1256
/*================*/
1259
1262
 
1260
1263
/******************************************************************//**
1261
1264
Makes all characters in a NUL-terminated UTF-8 string lower case. */
1262
 
UNIV_INTERN
 
1265
extern "C" UNIV_INTERN
1263
1266
void
1264
1267
innobase_casedn_str(
1265
1268
/*================*/
1268
1271
  my_casedn_str(system_charset_info, a);
1269
1272
}
1270
1273
 
1271
 
UNIV_INTERN
 
1274
/**********************************************************************//**
 
1275
Determines the connection character set.
 
1276
@return connection character set */
 
1277
extern "C" UNIV_INTERN
 
1278
const void*
 
1279
innobase_get_charset(
 
1280
/*=================*/
 
1281
  void* mysql_session)  /*!< in: MySQL thread handle */
 
1282
{
 
1283
  return static_cast<Session*>(mysql_session)->charset();
 
1284
}
 
1285
 
 
1286
extern "C" UNIV_INTERN
1272
1287
bool
1273
1288
innobase_isspace(
1274
1289
  const void *cs,
1277
1292
  return my_isspace(static_cast<const CHARSET_INFO *>(cs), char_to_test);
1278
1293
}
1279
1294
 
 
1295
UNIV_INTERN
 
1296
int
 
1297
innobase_fast_mutex_init(
 
1298
        os_fast_mutex_t*        fast_mutex)
 
1299
{
 
1300
  return pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
 
1301
}
 
1302
 
 
1303
/**********************************************************************//**
 
1304
Determines the current SQL statement.
 
1305
@return        SQL statement string */
 
1306
extern "C" UNIV_INTERN
 
1307
const char*
 
1308
innobase_get_stmt(
 
1309
/*==============*/
 
1310
       void*   session,        /*!< in: MySQL thread handle */
 
1311
       size_t* length)         /*!< out: length of the SQL statement */
 
1312
{
 
1313
  return static_cast<Session*>(session)->getQueryStringCopy(*length);
 
1314
}
 
1315
 
1280
1316
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1281
1317
/*******************************************************************//**
1282
1318
Map an OS error to an errno value. The OS error number is stored in
1283
1319
_doserrno and the mapped value is stored in errno) */
 
1320
extern "C"
1284
1321
void __cdecl
1285
1322
_dosmaperr(
1286
1323
  unsigned long); /*!< in: OS error value */
1288
1325
/*********************************************************************//**
1289
1326
Creates a temporary file.
1290
1327
@return temporary file descriptor, or < 0 on error */
1291
 
UNIV_INTERN
 
1328
extern "C" UNIV_INTERN
1292
1329
int
1293
1330
innobase_mysql_tmpfile(void)
1294
1331
/*========================*/
1368
1405
/*********************************************************************//**
1369
1406
Creates a temporary file.
1370
1407
@return temporary file descriptor, or < 0 on error */
1371
 
UNIV_INTERN
 
1408
extern "C" UNIV_INTERN
1372
1409
int
1373
1410
innobase_mysql_tmpfile(void)
1374
1411
/*========================*/
1407
1444
number of bytes that were written to "buf" is returned (including the
1408
1445
terminating NUL).
1409
1446
@return number of bytes that were written */
1410
 
UNIV_INTERN
 
1447
extern "C" UNIV_INTERN
1411
1448
ulint
1412
1449
innobase_raw_format(
1413
1450
/*================*/
1527
1564
/*********************************************************************//**
1528
1565
Allocates an InnoDB transaction for a MySQL Cursor object.
1529
1566
@return InnoDB transaction handle */
1530
 
UNIV_INTERN
 
1567
extern "C" UNIV_INTERN
1531
1568
trx_t*
1532
1569
innobase_trx_allocate(
1533
1570
/*==================*/
1631
1668
  ulint   buflen, /*!< in: length of buf, in bytes */
1632
1669
  const char* id, /*!< in: identifier to convert */
1633
1670
  ulint   idlen,  /*!< in: length of id, in bytes */
1634
 
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
 
1671
  void*   session,/*!< in: MySQL connection thread, or NULL */
1635
1672
  ibool   file_id)/*!< in: TRUE=id is a table or database name;
1636
1673
        FALSE=id is an UTF-8 string */
1637
1674
{
1638
1675
  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]);
 
1676
  char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix];
1641
1677
 
1642
1678
  const char* s = id;
1643
1679
  int   q;
1654
1690
    memcpy(nz, id, idlen);
1655
1691
    nz[idlen] = 0;
1656
1692
 
1657
 
    s = nz2.get();
1658
 
    idlen = identifier::Table::filename_to_tablename(nz, nz2.get(), nz2_size);
 
1693
    s = nz2;
 
1694
    idlen = TableIdentifier::filename_to_tablename(nz, nz2, sizeof nz2);
1659
1695
  }
1660
1696
 
1661
1697
  /* See if the identifier needs to be quoted. */
1709
1745
Convert a table or index name to the MySQL system_charset_info (UTF-8)
1710
1746
and quote it if needed.
1711
1747
@return pointer to the end of buf */
1712
 
UNIV_INTERN
 
1748
extern "C" UNIV_INTERN
1713
1749
char*
1714
1750
innobase_convert_name(
1715
1751
/*==================*/
1717
1753
  ulint   buflen, /*!< in: length of buf, in bytes */
1718
1754
  const char* id, /*!< in: identifier to convert */
1719
1755
  ulint   idlen,  /*!< in: length of id, in bytes */
1720
 
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
 
1756
  void*   session,/*!< in: MySQL connection thread, or NULL */
1721
1757
  ibool   table_id)/*!< in: TRUE=id is a table or database name;
1722
1758
        FALSE=id is an index name */
1723
1759
{
1765
1801
/**********************************************************************//**
1766
1802
Determines if the currently running transaction has been interrupted.
1767
1803
@return TRUE if interrupted */
1768
 
UNIV_INTERN
 
1804
extern "C" UNIV_INTERN
1769
1805
ibool
1770
1806
trx_is_interrupted(
1771
1807
/*===============*/
1772
1808
  trx_t*  trx)  /*!< in: transaction */
1773
1809
{
1774
 
  return(trx && trx->mysql_thd && trx->mysql_thd->getKilled());
 
1810
  return(trx && trx->mysql_thd && static_cast<Session*>(trx->mysql_thd)->getKilled());
1775
1811
}
1776
1812
 
1777
1813
/**********************************************************************//**
1778
1814
Determines if the currently running transaction is in strict mode.
1779
1815
@return TRUE if strict */
1780
 
UNIV_INTERN
 
1816
extern "C" UNIV_INTERN
1781
1817
ibool
1782
1818
trx_is_strict(
1783
1819
/*==========*/
1869
1905
 
1870
1906
static int innodb_commit_concurrency_validate(Session *session, set_var *var)
1871
1907
{
1872
 
   uint64_t new_value= var->getInteger();
 
1908
   uint32_t new_value= var->save_result.uint32_t_value;
1873
1909
 
1874
1910
   if ((innobase_commit_concurrency.get() == 0 && new_value != 0) ||
1875
1911
       (innobase_commit_concurrency.get() != 0 && new_value == 0))
1973
2009
    }
1974
2010
 
1975
2011
    if (format_id >= 0) {
1976
 
      innobase_file_format_max.assign(
1977
 
                             trx_sys_file_format_id_to_name((uint)format_id));
 
2012
      innobase_file_format_max= 
 
2013
        trx_sys_file_format_id_to_name((uint)format_id);
1978
2014
 
1979
2015
      /* 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))
 
2016
      char name_buff[100];
 
2017
      strcpy(name_buff, innobase_file_format_max.c_str());
 
2018
      if (trx_sys_file_format_max_set(format_id, (const char **)&name_buff))
1983
2019
      {
1984
 
        errmsg_printf(error::WARN,
 
2020
        errmsg_printf(ERRMSG_LVL_WARN,
1985
2021
                      " [Info] InnoDB: the file format in the system "
1986
2022
                      "tablespace is now set to %s.\n", name_buff);
1987
2023
        innobase_file_format_max= name_buff;
2041
2077
  innobase_use_doublewrite= (vm.count("disable-doublewrite")) ? false : true;
2042
2078
  srv_adaptive_flushing= (vm.count("disable-adaptive-flushing")) ? false : true;
2043
2079
  srv_use_sys_malloc= (vm.count("use-internal-malloc")) ? false : true;
2044
 
  srv_use_native_aio= (vm.count("disable-native-aio")) ? false : true;
2045
2080
  support_xa= (vm.count("disable-xa")) ? false : true;
2046
2081
  btr_search_enabled= (vm.count("disable-adaptive-hash-index")) ? false : true;
2047
2082
 
2069
2104
 
2070
2105
#ifdef UNIV_DEBUG
2071
2106
  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(),
 
2107
  char      test_tablename[sizeof test_filename
 
2108
    + sizeof srv_mysql50_table_name_prefix];
 
2109
  if ((sizeof test_tablename) - 1
 
2110
      != filename_to_tablename(test_filename, test_tablename,
 
2111
                               sizeof test_tablename)
 
2112
      || strncmp(test_tablename,
 
2113
                 srv_mysql50_table_name_prefix,
 
2114
                 sizeof srv_mysql50_table_name_prefix)
 
2115
      || strcmp(test_tablename
 
2116
                + sizeof srv_mysql50_table_name_prefix,
2083
2117
                test_filename)) {
2084
 
    errmsg_printf(error::ERROR, "tablename encoding has been changed");
 
2118
    errmsg_printf(ERRMSG_LVL_ERROR, "tablename encoding has been changed");
2085
2119
    goto error;
2086
2120
  }
2087
2121
#endif /* UNIV_DEBUG */
2115
2149
  ret = (bool) srv_parse_data_file_paths_and_sizes(
2116
2150
                                                   internal_innobase_data_file_path);
2117
2151
  if (ret == FALSE) {
2118
 
    errmsg_printf(error::ERROR, "InnoDB: syntax error in innodb_data_file_path");
2119
 
 
 
2152
    errmsg_printf(ERRMSG_LVL_ERROR, 
 
2153
                  "InnoDB: syntax error in innodb_data_file_path");
2120
2154
mem_free_and_error:
2121
2155
    srv_free_paths_and_sizes();
2122
2156
    if (internal_innobase_data_file_path)
2141
2175
    srv_parse_log_group_home_dirs((char *)innobase_log_group_home_dir.c_str());
2142
2176
 
2143
2177
  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"));
 
2178
    errmsg_printf(ERRMSG_LVL_ERROR,
 
2179
                  _("syntax error in innodb_log_group_home_dir, or a "
 
2180
                  "wrong number of mirrored log groups"));
2146
2181
 
2147
2182
    goto mem_free_and_error;
2148
2183
  }
2156
2191
 
2157
2192
    if (format_id > DICT_TF_FORMAT_MAX) {
2158
2193
 
2159
 
      errmsg_printf(error::ERROR, "InnoDB: wrong innodb_file_format.");
 
2194
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: wrong innodb_file_format.");
2160
2195
 
2161
2196
      goto mem_free_and_error;
2162
2197
    }
2185
2220
     srv_max_file_format_at_startup */
2186
2221
  if (innobase_file_format_validate_and_set(innobase_file_format_max.c_str()) < 0)
2187
2222
  {
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));
 
2223
    errmsg_printf(ERRMSG_LVL_ERROR, _("InnoDB: invalid "
 
2224
                    "innodb_file_format_max value: "
 
2225
                    "should be any value up to %s or its "
 
2226
                    "equivalent numeric id"),
 
2227
                    trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
2191
2228
    goto mem_free_and_error;
2192
2229
  }
2193
2230
 
2206
2243
      }
2207
2244
    }
2208
2245
 
2209
 
    errmsg_printf(error::ERROR, "InnoDB: invalid value innodb_change_buffering=%s",
 
2246
    errmsg_printf(ERRMSG_LVL_ERROR,
 
2247
                  "InnoDB: invalid value "
 
2248
                  "innodb_change_buffering=%s",
2210
2249
                  vm["change-buffering"].as<string>().c_str());
2211
2250
    goto mem_free_and_error;
2212
2251
  }
2284
2323
                                                     TRUE);
2285
2324
 
2286
2325
  innobase_open_tables = hash_create(200);
 
2326
  pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
 
2327
  pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
 
2328
  pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
 
2329
  pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
 
2330
  pthread_cond_init(&commit_cond, NULL);
2287
2331
  innodb_inited= 1;
2288
2332
 
2289
2333
  actuall_engine_ptr->dropTemporarySchema();
2290
2334
 
2291
 
  context.add(new InnodbStatusTool);
 
2335
  status_table_function_ptr= new InnodbStatusTool;
2292
2336
 
2293
2337
  context.add(innodb_engine_ptr);
2294
2338
 
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());
 
2339
  context.add(status_table_function_ptr);
 
2340
 
 
2341
  cmp_tool= new(std::nothrow)CmpTool(false);
 
2342
  context.add(cmp_tool);
 
2343
 
 
2344
  cmp_reset_tool= new(std::nothrow)CmpTool(true);
 
2345
  context.add(cmp_reset_tool);
 
2346
 
 
2347
  cmp_mem_tool= new(std::nothrow)CmpmemTool(false);
 
2348
  context.add(cmp_mem_tool);
 
2349
 
 
2350
  cmp_mem_reset_tool= new(std::nothrow)CmpmemTool(true);
 
2351
  context.add(cmp_mem_reset_tool);
 
2352
 
 
2353
  innodb_trx_tool= new(std::nothrow)InnodbTrxTool("INNODB_TRX");
 
2354
  context.add(innodb_trx_tool);
 
2355
 
 
2356
  innodb_locks_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCKS");
 
2357
  context.add(innodb_locks_tool);
 
2358
 
 
2359
  innodb_lock_waits_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS");
 
2360
  context.add(innodb_lock_waits_tool);
 
2361
 
 
2362
  innodb_sys_tables_tool= new(std::nothrow)InnodbSysTablesTool();
 
2363
  context.add(innodb_sys_tables_tool);
 
2364
 
 
2365
  innodb_sys_tablestats_tool= new(std::nothrow)InnodbSysTableStatsTool();
 
2366
  context.add(innodb_sys_tablestats_tool);
 
2367
 
 
2368
  innodb_sys_indexes_tool= new(std::nothrow)InnodbSysIndexesTool();
 
2369
  context.add(innodb_sys_indexes_tool);
 
2370
 
 
2371
  innodb_sys_columns_tool= new(std::nothrow)InnodbSysColumnsTool();
 
2372
  context.add(innodb_sys_columns_tool);
 
2373
 
 
2374
  innodb_sys_fields_tool= new(std::nothrow)InnodbSysFieldsTool();
 
2375
  context.add(innodb_sys_fields_tool);
 
2376
 
 
2377
  innodb_sys_foreign_tool= new(std::nothrow)InnodbSysForeignTool();
 
2378
  context.add(innodb_sys_foreign_tool);
 
2379
 
 
2380
  innodb_sys_foreign_cols_tool= new(std::nothrow)InnodbSysForeignColsTool();
 
2381
  context.add(innodb_sys_foreign_cols_tool);
2322
2382
 
2323
2383
  context.add(new(std::nothrow)InnodbInternalTables());
2324
2384
  context.add(new(std::nothrow)InnodbReplicationTable());
2325
2385
 
2326
2386
  if (innobase_use_replication_log)
2327
2387
  {
2328
 
    ReplicationLog *replication_logger= new(std::nothrow)ReplicationLog();
 
2388
    replication_logger= new(std::nothrow)ReplicationLog();
2329
2389
    context.add(replication_logger);
2330
2390
    ReplicationLog::setup(replication_logger);
2331
2391
  }
2365
2425
  context.registerVariable(new sys_var_constrained_value<uint32_t>("purge_threads",
2366
2426
                                                                   innodb_n_purge_threads,
2367
2427
                                                                   purge_threads_update));
2368
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("fast_shutdown", innobase_fast_shutdown));
 
2428
  context.registerVariable(new sys_var_constrained_value<uint16_t>("fast_shutdown", innobase_fast_shutdown));
2369
2429
  context.registerVariable(new sys_var_std_string("file_format",
2370
2430
                                                  innobase_file_format_name,
2371
2431
                                                  innodb_file_format_name_validate));
2377
2437
                                                  innodb_file_format_max_validate));
2378
2438
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("buffer_pool_size", innobase_buffer_pool_size));
2379
2439
  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",
 
2440
  context.registerVariable(new sys_var_constrained_value_readonly<uint16_t>("flush_log_at_trx_commit",
2381
2441
                                                  innodb_flush_log_at_trx_commit));
2382
2442
  context.registerVariable(new sys_var_constrained_value_readonly<unsigned int>("max_dirty_pages_pct",
2383
2443
                                                  innodb_max_dirty_pages_pct));
2416
2476
  btr_search_fully_disabled = (!btr_search_enabled);
2417
2477
 
2418
2478
  return(FALSE);
2419
 
 
2420
2479
error:
2421
2480
  return(TRUE);
2422
2481
}
2513
2572
    trx_search_latch_release_if_reserved(trx);
2514
2573
  }
2515
2574
 
2516
 
  if (all)
2517
 
  {
 
2575
  if (all
 
2576
    || (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
 
2577
 
2518
2578
    /* We were instructed to commit the whole transaction, or
2519
2579
    this is an SQL statement end and autocommit is on */
2520
2580
 
2521
2581
    /* We need current binlog position for ibbackup to work.
2522
2582
    Note, the position is current because of
2523
2583
    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
 
 
 
2584
retry:
 
2585
    if (innobase_commit_concurrency.get() > 0) {
 
2586
      pthread_mutex_lock(&commit_cond_m);
 
2587
      commit_threads++;
 
2588
 
 
2589
      if (commit_threads > innobase_commit_concurrency.get()) {
2535
2590
        commit_threads--;
2536
 
        commit_cond.wait(scopedLock);
2537
 
      } while (1);
 
2591
        pthread_cond_wait(&commit_cond,
 
2592
          &commit_cond_m);
 
2593
        pthread_mutex_unlock(&commit_cond_m);
 
2594
        goto retry;
 
2595
      }
 
2596
      else {
 
2597
        pthread_mutex_unlock(&commit_cond_m);
 
2598
      }
2538
2599
    }
2539
2600
 
2540
 
    trx->mysql_log_file_name = NULL;
 
2601
                /* Store transaction point for binlog
 
2602
    Later logic tests that this is set to _something_. We need
 
2603
    that logic to fire, even though we do not have a real name. */
 
2604
    trx->mysql_log_file_name = "UNUSED";
2541
2605
    trx->mysql_log_offset = 0;
2542
2606
 
2543
2607
    /* Don't do write + flush right now. For group commit
2547
2611
    innobase_commit_low(trx);
2548
2612
    trx->flush_log_later = FALSE;
2549
2613
 
2550
 
    if (commit_concurrency)
2551
 
    {
2552
 
      boost::mutex::scoped_lock scopedLock(commit_cond_m);
 
2614
    if (innobase_commit_concurrency.get() > 0) {
 
2615
      pthread_mutex_lock(&commit_cond_m);
2553
2616
      commit_threads--;
2554
 
      commit_cond.notify_one();
 
2617
      pthread_cond_signal(&commit_cond);
 
2618
      pthread_mutex_unlock(&commit_cond_m);
2555
2619
    }
2556
2620
 
2557
2621
    /* Now do a write + flush of logs. */
2636
2700
 
2637
2701
  row_unlock_table_autoinc_for_mysql(trx);
2638
2702
 
2639
 
  if (all)
2640
 
  {
 
2703
  if (all
 
2704
    || !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
 
2705
 
2641
2706
    error = trx_rollback_for_mysql(trx);
2642
2707
  } else {
2643
2708
    error = trx_rollback_last_sql_stat_for_mysql(trx);
2796
2861
      trx->undo_no > 0 &&
2797
2862
      global_system_variables.log_warnings)
2798
2863
  {
2799
 
      errmsg_printf(error::WARN,
 
2864
      errmsg_printf(ERRMSG_LVL_WARN,
2800
2865
      "Drizzle is closing a connection during a KILL operation\n"
2801
2866
      "that has an active InnoDB transaction.  %llu row modifications will "
2802
2867
      "roll back.\n",
2876
2941
  return(true);
2877
2942
}
2878
2943
 
 
2944
/*****************************************************************//**
 
2945
Normalizes a table name string. A normalized name consists of the
 
2946
database name catenated to '/' and table name. An example:
 
2947
test/mytable. On Windows normalization puts both the database name and the
 
2948
table name always to lower case. */
 
2949
static
 
2950
void
 
2951
normalize_table_name(
 
2952
/*=================*/
 
2953
  char*   norm_name,  /*!< out: normalized name as a
 
2954
          null-terminated string */
 
2955
  const char* name)   /*!< in: table name string */
 
2956
{
 
2957
  const char* name_ptr;
 
2958
  const char* db_ptr;
 
2959
  const char* ptr;
 
2960
 
 
2961
  /* Scan name from the end */
 
2962
 
 
2963
  ptr = strchr(name, '\0')-1;
 
2964
 
 
2965
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
 
2966
    ptr--;
 
2967
  }
 
2968
 
 
2969
  name_ptr = ptr + 1;
 
2970
 
 
2971
  assert(ptr > name);
 
2972
 
 
2973
  ptr--;
 
2974
 
 
2975
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
 
2976
    ptr--;
 
2977
  }
 
2978
 
 
2979
  db_ptr = ptr + 1;
 
2980
 
 
2981
  memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
 
2982
 
 
2983
  norm_name[name_ptr - db_ptr - 1] = '/';
 
2984
 
 
2985
#ifdef __WIN__
 
2986
  innobase_casedn_str(norm_name);
 
2987
#endif
 
2988
}
 
2989
 
2879
2990
/********************************************************************//**
2880
2991
Get the upper limit of the MySQL integral and floating-point type.
2881
2992
@return maximum allowed value for the field */
3042
3153
                if (!index_mapping) {
3043
3154
                        /* Report an error if index_mapping continues to be
3044
3155
                        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",
 
3156
                        errmsg_printf(ERRMSG_LVL_ERROR,
 
3157
                                      "InnoDB: fail to allocate memory for "
 
3158
                                        "index translation table. Number of "
 
3159
                                        "Index:%lu, array size:%lu",
3047
3160
                                        mysql_num_index,
3048
3161
                                        share->idx_trans_tbl.array_size);
3049
3162
                        ret = FALSE;
3064
3177
                        ib_table, table->key_info[count].name);
3065
3178
 
3066
3179
                if (!index_mapping[count]) {
3067
 
                        errmsg_printf(error::ERROR, "Cannot find index %s in InnoDB index dictionary.",
3068
 
                                      table->key_info[count].name);
 
3180
                        errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find index %s in InnoDB "
 
3181
                                        "index dictionary.",
 
3182
                                        table->key_info[count].name);
3069
3183
                        ret = FALSE;
3070
3184
                        goto func_exit;
3071
3185
                }
3072
3186
 
3073
3187
                /* Double check fetched index has the same
3074
3188
                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;
 
3189
                if (!innobase_match_index_columns(&table->key_info[count],
 
3190
                                                  index_mapping[count])) {
 
3191
                        errmsg_printf(ERRMSG_LVL_ERROR, "Found index %s whose column info "
 
3192
                                        "does not match that of MySQL.",
 
3193
                                        table->key_info[count].name);
 
3194
                        ret = FALSE;
 
3195
                        goto func_exit;
3080
3196
                }
3081
3197
        }
3082
3198
 
3146
3262
    auto_inc = 0;
3147
3263
 
3148
3264
    ut_print_timestamp(stderr);
3149
 
    errmsg_printf(error::ERROR, "InnoDB: Unable to determine the AUTOINC column name");
 
3265
    fprintf(stderr, "  InnoDB: Unable to determine the AUTOINC "
 
3266
            "column name\n");
3150
3267
  }
3151
3268
 
3152
3269
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
3196
3313
    }
3197
3314
    case DB_RECORD_NOT_FOUND:
3198
3315
      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);
 
3316
      fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
 
3317
              "dictionaries are out of sync.\n"
 
3318
              "InnoDB: Unable to find the AUTOINC column "
 
3319
              "%s in the InnoDB table %s.\n"
 
3320
              "InnoDB: We set the next AUTOINC column "
 
3321
              "value to 0,\n"
 
3322
              "InnoDB: in effect disabling the AUTOINC "
 
3323
              "next value generation.\n"
 
3324
              "InnoDB: You can either set the next "
 
3325
              "AUTOINC value explicitly using ALTER TABLE\n"
 
3326
              "InnoDB: or fix the data dictionary by "
 
3327
              "recreating the table.\n",
 
3328
              col_name, index->table->name);
3206
3329
 
3207
3330
      /* This will disable the AUTOINC generation. */
3208
3331
      auto_inc = 0;
3228
3351
@return 1 if error, 0 if success */
3229
3352
UNIV_INTERN
3230
3353
int
3231
 
ha_innobase::doOpen(const identifier::Table &identifier,
 
3354
ha_innobase::doOpen(const TableIdentifier &identifier,
3232
3355
                    int   mode,   /*!< in: not used */
3233
3356
                    uint    test_if_locked) /*!< in: not used */
3234
3357
{
3235
3358
  dict_table_t* ib_table;
 
3359
  char    norm_name[FN_REFLEN];
3236
3360
  Session*    session;
3237
3361
 
3238
3362
  UT_NOT_USED(mode);
3247
3371
    getTransactionalEngine()->releaseTemporaryLatches(session);
3248
3372
  }
3249
3373
 
 
3374
  normalize_table_name(norm_name, identifier.getPath().c_str());
 
3375
 
3250
3376
  user_session = NULL;
3251
3377
 
3252
 
  std::string search_string(identifier.getSchemaName());
3253
 
  boost::algorithm::to_lower(search_string);
 
3378
  if (!(share=get_share(identifier.getPath().c_str()))) {
3254
3379
 
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
 
    }
 
3380
    return(1);
3270
3381
  }
3271
3382
 
3272
3383
  /* Create buffers for packing the fields of a record. Why
3275
3386
  stored the string length as the first byte. */
3276
3387
 
3277
3388
  upd_and_key_val_buff_len =
3278
 
        getTable()->getShare()->sizeStoredRecord()
 
3389
        getTable()->getShare()->stored_rec_length
3279
3390
        + getTable()->getShare()->max_key_length
3280
3391
        + MAX_REF_PARTS * 3;
3281
3392
 
3293
3404
  }
3294
3405
 
3295
3406
  /* 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
 
  }
 
3407
  ib_table = dict_table_get(norm_name, TRUE);
3306
3408
  
3307
3409
  if (NULL == ib_table) {
3308
 
    errmsg_printf(error::ERROR, "Cannot find or open table %s from\n"
 
3410
    errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find or open table %s from\n"
3309
3411
        "the internal data dictionary of InnoDB "
3310
3412
        "though the .frm file for the\n"
3311
3413
        "table exists. Maybe you have deleted and "
3319
3421
        "doesn't support.\n"
3320
3422
        "See " REFMAN "innodb-troubleshooting.html\n"
3321
3423
        "how you can resolve the problem.\n",
3322
 
        identifier.getKeyPath().c_str());
 
3424
        norm_name);
3323
3425
    free_share(share);
3324
3426
    upd_buff.resize(0);
3325
3427
    key_val_buff.resize(0);
3328
3430
    return(HA_ERR_NO_SUCH_TABLE);
3329
3431
  }
3330
3432
 
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 "
 
3433
  if (ib_table->ibd_file_missing && !session_tablespace_op(session)) {
 
3434
    errmsg_printf(ERRMSG_LVL_ERROR, "MySQL is trying to open a table handle but "
3333
3435
        "the .ibd file for\ntable %s does not exist.\n"
3334
3436
        "Have you deleted the .ibd file from the "
3335
3437
        "database directory under\nthe MySQL datadir, "
3336
3438
        "or have you used DISCARD TABLESPACE?\n"
3337
3439
        "See " REFMAN "innodb-troubleshooting.html\n"
3338
3440
        "how you can resolve the problem.\n",
3339
 
        identifier.getKeyPath().c_str());
 
3441
        norm_name);
3340
3442
    free_share(share);
3341
3443
    upd_buff.resize(0);
3342
3444
    key_val_buff.resize(0);
3348
3450
 
3349
3451
  prebuilt = row_create_prebuilt(ib_table);
3350
3452
 
3351
 
  prebuilt->mysql_row_len = getTable()->getShare()->sizeStoredRecord();
 
3453
  prebuilt->mysql_row_len = getTable()->getShare()->stored_rec_length;
3352
3454
  prebuilt->default_rec = getTable()->getDefaultValues();
3353
3455
  ut_ad(prebuilt->default_rec);
3354
3456
 
3358
3460
  key_used_on_scan = primary_key;
3359
3461
 
3360
3462
  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());
 
3463
    errmsg_printf(ERRMSG_LVL_ERROR, "Build InnoDB index translation table for"
 
3464
                    " Table %s failed", identifier.getPath().c_str());
3363
3465
  }
3364
3466
 
3365
3467
  /* Allocate a buffer for a 'row reference'. A row reference is
3373
3475
    prebuilt->clust_index_was_generated = FALSE;
3374
3476
 
3375
3477
    if (UNIV_UNLIKELY(primary_key >= MAX_KEY)) {
3376
 
      errmsg_printf(error::ERROR, "Table %s has a primary key in "
 
3478
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has a primary key in "
3377
3479
                    "InnoDB data dictionary, but not "
3378
3480
                    "in MySQL!", identifier.getTableName().c_str());
3379
3481
 
3428
3530
    }
3429
3531
  } else {
3430
3532
    if (primary_key != MAX_KEY) {
3431
 
      errmsg_printf(error::ERROR,
 
3533
      errmsg_printf(ERRMSG_LVL_ERROR,
3432
3534
                    "Table %s has no primary key in InnoDB data "
3433
3535
                    "dictionary, but has one in MySQL! If you "
3434
3536
                    "created the table with a MySQL version < "
3464
3566
    and it will never be updated anyway. */
3465
3567
 
3466
3568
    if (key_used_on_scan != MAX_KEY) {
3467
 
      errmsg_printf(error::WARN, 
 
3569
      errmsg_printf(ERRMSG_LVL_WARN, 
3468
3570
        "Table %s key_used_on_scan is %lu even "
3469
3571
        "though there is no primary key inside "
3470
3572
        "InnoDB.", identifier.getTableName().c_str(), (ulong) key_used_on_scan);
3616
3718
of this function is in rem0cmp.c in InnoDB source code! If you change this
3617
3719
function, remember to update the prototype there!
3618
3720
@return 1, 0, -1, if a is greater, equal, less than b, respectively */
3619
 
UNIV_INTERN int
 
3721
extern "C" UNIV_INTERN
 
3722
int
3620
3723
innobase_mysql_cmp(
3621
3724
/*===============*/
3622
3725
  int   mysql_type, /*!< in: MySQL type */
3663
3766
      charset = get_charset(charset_number);
3664
3767
 
3665
3768
      if (charset == NULL) {
3666
 
        errmsg_printf(error::ERROR, "InnoDB needs charset %lu for doing "
 
3769
        errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB needs charset %lu for doing "
3667
3770
                      "a comparison, but MySQL cannot "
3668
3771
                      "find that charset.",
3669
3772
                      (ulong) charset_number);
3698
3801
the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1
3699
3802
VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'.
3700
3803
@return DATA_BINARY, DATA_VARCHAR, ... */
3701
 
UNIV_INTERN
 
3804
extern "C" UNIV_INTERN
3702
3805
ulint
3703
3806
get_innobase_type_from_mysql_type(
3704
3807
/*==============================*/
3747
3850
      return(DATA_VARMYSQL);
3748
3851
    }
3749
3852
  case DRIZZLE_TYPE_DECIMAL:
3750
 
  case DRIZZLE_TYPE_MICROTIME:
3751
3853
    return(DATA_FIXBINARY);
3752
3854
  case DRIZZLE_TYPE_LONG:
3753
3855
  case DRIZZLE_TYPE_LONGLONG:
4323
4425
  trx_t*    trx = session_to_trx(user_session);
4324
4426
 
4325
4427
  if (prebuilt->trx != trx) {
4326
 
    errmsg_printf(error::ERROR, "The transaction object for the table handle is at "
 
4428
    errmsg_printf(ERRMSG_LVL_ERROR, "The transaction object for the table handle is at "
4327
4429
        "%p, but for the current thread it is at %p",
4328
4430
        (const void*) prebuilt->trx, (const void*) trx);
4329
4431
 
4337
4439
    ut_error;
4338
4440
  }
4339
4441
 
4340
 
  sql_command = user_session->getSqlCommand();
 
4442
  sql_command = session_sql_command(user_session);
4341
4443
 
4342
4444
  if ((sql_command == SQLCOM_ALTER_TABLE
4343
4445
       || sql_command == SQLCOM_CREATE_INDEX
4784
4886
  if (error == DB_SUCCESS
4785
4887
      && getTable()->next_number_field
4786
4888
      && new_row == getTable()->getInsertRecord()
4787
 
      && user_session->getSqlCommand() == SQLCOM_INSERT
 
4889
      && session_sql_command(user_session) == SQLCOM_INSERT
4788
4890
      && (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
4789
4891
    == TRX_DUP_IGNORE)  {
4790
4892
 
5251
5353
         table. Only print message if the index translation
5252
5354
         table exists */
5253
5355
      if (share->idx_trans_tbl.index_mapping) {
5254
 
        errmsg_printf(error::ERROR,
 
5356
        errmsg_printf(ERRMSG_LVL_ERROR,
5255
5357
                      "InnoDB could not find "
5256
5358
                      "index %s key no %u for "
5257
5359
                      "table %s through its "
5269
5371
  }
5270
5372
 
5271
5373
  if (!index) {
5272
 
    errmsg_printf(error::ERROR, 
 
5374
    errmsg_printf(ERRMSG_LVL_ERROR, 
5273
5375
      "Innodb could not find key n:o %u with name %s "
5274
5376
      "from dict cache for table %s",
5275
 
      keynr, getTable()->getShare()->getTableMessage()->indexes(keynr).name().c_str(),
 
5377
      keynr, getTable()->getShare()->getTableProto()->indexes(keynr).name().c_str(),
5276
5378
      prebuilt->table->name);
5277
5379
  }
5278
5380
 
5298
5400
  prebuilt->index = innobase_get_index(keynr);
5299
5401
 
5300
5402
  if (UNIV_UNLIKELY(!prebuilt->index)) {
5301
 
    errmsg_printf(error::WARN, "InnoDB: change_active_index(%u) failed",
 
5403
    errmsg_printf(ERRMSG_LVL_WARN, "InnoDB: change_active_index(%u) failed",
5302
5404
          keynr);
5303
5405
    prebuilt->index_usable = FALSE;
5304
5406
    return(1);
5664
5766
  table. */
5665
5767
 
5666
5768
  if (len != ref_length) {
5667
 
    errmsg_printf(error::ERROR, "Stored ref len is %lu, but table ref len is %lu",
 
5769
    errmsg_printf(ERRMSG_LVL_ERROR, "Stored ref len is %lu, but table ref len is %lu",
5668
5770
        (ulong) len, (ulong) ref_length);
5669
5771
  }
5670
5772
}
5723
5825
 
5724
5826
    if (!col_type) {
5725
5827
      push_warning_printf(
5726
 
                          trx->mysql_thd,
 
5828
                          (Session*) trx->mysql_thd,
5727
5829
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
5728
5830
                          ER_CANT_CREATE_TABLE,
5729
5831
                          "Error creating table '%s' with "
5757
5859
        /* in data0type.h we assume that the
5758
5860
        number fits in one byte in prtype */
5759
5861
        push_warning_printf(
5760
 
          trx->mysql_thd,
 
5862
          (Session*) trx->mysql_thd,
5761
5863
          DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5762
5864
          ER_CANT_CREATE_TABLE,
5763
5865
          "In InnoDB, charset-collation codes"
5923
6025
        || col_type == DATA_FLOAT
5924
6026
        || col_type == DATA_DOUBLE
5925
6027
        || col_type == DATA_DECIMAL) {
5926
 
        errmsg_printf(error::ERROR, 
 
6028
        errmsg_printf(ERRMSG_LVL_ERROR, 
5927
6029
          "MySQL is trying to create a column "
5928
6030
          "prefix index field, on an "
5929
6031
          "inappropriate data type. Table "
6023
6125
/*================*/
6024
6126
  Session         &session, /*!< in: Session */
6025
6127
  Table&    form,   /*!< in: information on table columns and indexes */
6026
 
        const identifier::Table &identifier,
 
6128
        const TableIdentifier &identifier,
6027
6129
        message::Table& create_proto)
6028
6130
{
6029
6131
  int   error;
6032
6134
  trx_t*    trx;
6033
6135
  int   primary_key_no;
6034
6136
  uint    i;
 
6137
  char    name2[FN_REFLEN];
 
6138
  char    norm_name[FN_REFLEN];
6035
6139
  ib_int64_t  auto_inc_value;
6036
6140
  ulint   iflags;
6037
6141
  /* Cache the value of innodb_file_format, in case it is
6041
6145
  const char* stmt;
6042
6146
  size_t stmt_len;
6043
6147
 
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
 
  }
 
6148
  const char *table_name= identifier.getPath().c_str();
6051
6149
 
6052
6150
  if (form.getShare()->sizeFields() > 1000) {
6053
6151
    /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
6070
6168
 
6071
6169
  srv_lower_case_table_names = TRUE;
6072
6170
 
 
6171
  strcpy(name2, table_name);
 
6172
 
 
6173
  normalize_table_name(norm_name, name2);
 
6174
 
6073
6175
  /* Latch the InnoDB data dictionary exclusively so that no deadlocks
6074
6176
    or lock waits can happen in it during a table create operation.
6075
6177
    Drop table etc. do this latching in row0mysql.c. */
6177
6279
  if (lex_identified_temp_table)
6178
6280
    iflags |= DICT_TF2_TEMPORARY << DICT_TF2_SHIFT;
6179
6281
 
6180
 
  error= create_table_def(trx, &form, identifier.getKeyPath().c_str(),
6181
 
                          lex_identified_temp_table ? identifier.getKeyPath().c_str() : NULL,
 
6282
  error= create_table_def(trx, &form, norm_name,
 
6283
                          lex_identified_temp_table ? name2 : NULL,
6182
6284
                          iflags);
6183
6285
 
6184
6286
  session.setXaId(trx->id);
6194
6296
      order the rows by their row id which is internally generated
6195
6297
      by InnoDB */
6196
6298
 
6197
 
    error = create_clustered_index_when_no_primary(trx, iflags, identifier.getKeyPath().c_str());
 
6299
    error = create_clustered_index_when_no_primary(trx, iflags, norm_name);
6198
6300
    if (error) {
6199
6301
      goto cleanup;
6200
6302
    }
6202
6304
 
6203
6305
  if (primary_key_no != -1) {
6204
6306
    /* In InnoDB the clustered index must always be created first */
6205
 
    if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
 
6307
    if ((error = create_index(trx, &form, iflags, norm_name,
6206
6308
                              (uint) primary_key_no))) {
6207
6309
      goto cleanup;
6208
6310
    }
6211
6313
  for (i = 0; i < form.getShare()->sizeKeys(); i++) {
6212
6314
    if (i != (uint) primary_key_no) {
6213
6315
 
6214
 
      if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
 
6316
      if ((error = create_index(trx, &form, iflags, norm_name,
6215
6317
                                i))) {
6216
6318
        goto cleanup;
6217
6319
      }
6218
6320
    }
6219
6321
  }
6220
6322
 
6221
 
  stmt= session.getQueryStringCopy(stmt_len);
 
6323
  stmt = innobase_get_stmt(&session, &stmt_len);
6222
6324
 
6223
6325
  if (stmt) {
6224
6326
    string generated_create_table;
6225
6327
    const char *query= stmt;
6226
6328
 
6227
 
    if (session.getSqlCommand() == SQLCOM_CREATE_TABLE)
 
6329
    if (session_sql_command(&session) == SQLCOM_CREATE_TABLE)
6228
6330
    {
6229
6331
      message::transformTableDefinitionToSql(create_proto,
6230
6332
                                             generated_create_table,
6234
6336
 
6235
6337
    error = row_table_add_foreign_constraints(trx,
6236
6338
                                              query, strlen(query),
6237
 
                                              identifier.getKeyPath().c_str(),
 
6339
                                              norm_name,
6238
6340
                                              lex_identified_temp_table);
6239
6341
    switch (error) {
6240
6342
 
6245
6347
                          "Create table '%s' with foreign key constraint"
6246
6348
                          " failed. There is no index in the referenced"
6247
6349
                          " table where the referenced columns appear"
6248
 
                          " as the first columns.\n", identifier.getKeyPath().c_str());
 
6350
                          " as the first columns.\n", norm_name);
6249
6351
      break;
6250
6352
 
6251
6353
    case DB_CHILD_NO_INDEX:
6255
6357
                          "Create table '%s' with foreign key constraint"
6256
6358
                          " failed. There is no index in the referencing"
6257
6359
                          " table where referencing columns appear"
6258
 
                          " as the first columns.\n", identifier.getKeyPath().c_str());
 
6360
                          " as the first columns.\n", norm_name);
6259
6361
      break;
6260
6362
    }
6261
6363
 
6276
6378
 
6277
6379
  log_buffer_flush_to_disk();
6278
6380
 
6279
 
  innobase_table = dict_table_get(identifier.getKeyPath().c_str(), FALSE);
 
6381
  innobase_table = dict_table_get(norm_name, FALSE);
6280
6382
 
6281
6383
  assert(innobase_table != 0);
6282
6384
 
6299
6401
    does a table copy too. */
6300
6402
 
6301
6403
  if ((create_proto.options().has_auto_increment_value()
6302
 
       || session.getSqlCommand() == SQLCOM_ALTER_TABLE
6303
 
       || session.getSqlCommand() == SQLCOM_CREATE_INDEX)
 
6404
       || session_sql_command(&session) == SQLCOM_ALTER_TABLE
 
6405
       || session_sql_command(&session) == SQLCOM_CREATE_INDEX)
6304
6406
      && create_proto.options().auto_increment_value() != 0) {
6305
6407
 
6306
6408
    /* Query was one of :
6393
6495
 
6394
6496
  update_session(getTable()->in_use);
6395
6497
 
6396
 
  if (user_session->getSqlCommand() != SQLCOM_TRUNCATE) {
 
6498
  if (session_sql_command(user_session) != SQLCOM_TRUNCATE) {
6397
6499
  fallback:
6398
6500
    /* We only handle TRUNCATE TABLE t as a special case.
6399
6501
    DELETE FROM t will have to use ha_innobase::doDeleteRecord(),
6427
6529
InnobaseEngine::doDropTable(
6428
6530
/*======================*/
6429
6531
        Session &session,
6430
 
        const identifier::Table &identifier)
 
6532
        const TableIdentifier &identifier)
6431
6533
{
6432
6534
  int error;
6433
6535
  trx_t*  parent_trx;
6434
6536
  trx_t*  trx;
 
6537
  char  norm_name[1000];
6435
6538
 
6436
6539
  ut_a(identifier.getPath().length() < 1000);
6437
6540
 
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
 
  }
 
6541
  /* Strangely, MySQL passes the table name without the '.frm'
 
6542
    extension, in contrast to ::create */
 
6543
  normalize_table_name(norm_name, identifier.getPath().c_str());
6445
6544
 
6446
6545
  /* Get the transaction associated with the current session, or create one
6447
6546
    if not yet created */
6459
6558
 
6460
6559
  /* Drop the table in InnoDB */
6461
6560
 
6462
 
  error = row_drop_table_for_mysql(identifier.getKeyPath().c_str(), trx,
6463
 
                                   session.getSqlCommand()
 
6561
  error = row_drop_table_for_mysql(norm_name, trx,
 
6562
                                   session_sql_command(&session)
6464
6563
                                   == SQLCOM_DROP_DB);
6465
6564
 
6466
6565
  session.setXaId(trx->id);
6488
6587
    if (identifier.getType() == message::Table::TEMPORARY)
6489
6588
    {
6490
6589
      session.getMessageCache().removeTableMessage(identifier);
6491
 
      ulint sql_command = session.getSqlCommand();
 
6590
      ulint sql_command = session_sql_command(&session);
6492
6591
 
6493
6592
      // If this was the final removal to an alter table then we will need
6494
6593
      // to remove the .dfe that was left behind.
6521
6620
bool
6522
6621
InnobaseEngine::doDropSchema(
6523
6622
/*===================*/
6524
 
                             const identifier::Schema &identifier)
 
6623
                             const SchemaIdentifier &identifier)
6525
6624
    /*!< in: database path; inside InnoDB the name
6526
6625
      of the last directory in the path is used as
6527
6626
      the database name: for example, in 'mysql/data/test'
6571
6670
 
6572
6671
void InnobaseEngine::dropTemporarySchema()
6573
6672
{
6574
 
  identifier::Schema schema_identifier(GLOBAL_TEMPORARY_EXT);
 
6673
  SchemaIdentifier schema_identifier(GLOBAL_TEMPORARY_EXT);
6575
6674
  trx_t*  trx= NULL;
6576
6675
  string schema_path(GLOBAL_TEMPORARY_EXT);
6577
6676
 
6608
6707
innobase_rename_table(
6609
6708
/*==================*/
6610
6709
  trx_t*    trx,  /*!< in: transaction */
6611
 
  const identifier::Table &from,
6612
 
  const identifier::Table &to,
 
6710
  const char* from, /*!< in: old name of the table */
 
6711
  const char* to, /*!< in: new name of the table */
6613
6712
  ibool   lock_and_commit)
6614
6713
        /*!< in: TRUE=lock data dictionary and commit */
6615
6714
{
6616
6715
  int error;
 
6716
  char norm_to[FN_REFLEN];
 
6717
  char norm_from[FN_REFLEN];
6617
6718
 
6618
6719
  srv_lower_case_table_names = TRUE;
6619
6720
 
 
6721
  normalize_table_name(norm_to, to);
 
6722
  normalize_table_name(norm_from, from);
 
6723
 
6620
6724
  /* Serialize data dictionary operations with dictionary mutex:
6621
6725
  no deadlocks can occur then in these operations */
6622
6726
 
6624
6728
    row_mysql_lock_data_dictionary(trx);
6625
6729
  }
6626
6730
 
6627
 
  error = row_rename_table_for_mysql(from.getKeyPath().c_str(), to.getKeyPath().c_str(), trx, lock_and_commit);
 
6731
  error = row_rename_table_for_mysql(
 
6732
    norm_from, norm_to, trx, lock_and_commit);
6628
6733
 
6629
6734
  if (error != DB_SUCCESS) {
6630
6735
    FILE* ef = dict_foreign_err_file;
6631
6736
 
6632
6737
    fputs("InnoDB: Renaming table ", ef);
6633
 
    ut_print_name(ef, trx, TRUE, from.getKeyPath().c_str());
 
6738
    ut_print_name(ef, trx, TRUE, norm_from);
6634
6739
    fputs(" to ", ef);
6635
 
    ut_print_name(ef, trx, TRUE, to.getKeyPath().c_str());
 
6740
    ut_print_name(ef, trx, TRUE, norm_to);
6636
6741
    fputs(" failed!\n", ef);
6637
6742
  }
6638
6743
 
6651
6756
/*********************************************************************//**
6652
6757
Renames an InnoDB table.
6653
6758
@return 0 or error code */
6654
 
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, const identifier::Table &from, const identifier::Table &to)
 
6759
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
6655
6760
{
6656
6761
  // A temp table alter table/rename is a shallow rename and only the
6657
6762
  // definition needs to be updated.
6677
6782
 
6678
6783
  trx = innobase_trx_allocate(&session);
6679
6784
 
6680
 
  error = innobase_rename_table(trx, from, to, TRUE);
 
6785
  error = innobase_rename_table(trx, from.getPath().c_str(), to.getPath().c_str(), TRUE);
6681
6786
 
6682
6787
  session.setXaId(trx->id);
6683
6788
 
6702
6807
     is the one we are trying to rename to) and return the generic
6703
6808
     error code. */
6704
6809
  if (error == (int) DB_DUPLICATE_KEY) {
6705
 
    my_error(ER_TABLE_EXISTS_ERROR, to);
 
6810
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to.getPath().c_str());
6706
6811
    error = DB_ERROR;
6707
6812
  }
6708
6813
 
6733
6838
  KeyInfo*    key;
6734
6839
  dict_index_t* index;
6735
6840
  unsigned char*    key_val_buff2 = (unsigned char*) malloc(
6736
 
              getTable()->getShare()->sizeStoredRecord()
 
6841
              getTable()->getShare()->stored_rec_length
6737
6842
          + getTable()->getShare()->max_key_length + 100);
6738
 
  ulint   buff2_len = getTable()->getShare()->sizeStoredRecord()
 
6843
  ulint   buff2_len = getTable()->getShare()->stored_rec_length
6739
6844
          + getTable()->getShare()->max_key_length + 100;
6740
6845
  dtuple_t* range_start;
6741
6846
  dtuple_t* range_end;
7018
7123
 
7019
7124
                /* Print an error message if we cannot find the index
7020
7125
                ** in the "index translation table". */
7021
 
                errmsg_printf(error::ERROR,
 
7126
                errmsg_printf(ERRMSG_LVL_ERROR,
7022
7127
                              "Cannot find index %s in InnoDB index "
7023
7128
                                "translation table.", index->name);
7024
7129
        }
7035
7140
                }
7036
7141
        }
7037
7142
 
7038
 
                errmsg_printf(error::ERROR,
 
7143
                errmsg_printf(ERRMSG_LVL_ERROR,
7039
7144
                              "Cannot find matching index number for index %s "
7040
7145
                              "in InnoDB index list.", index->name);
7041
7146
 
7131
7236
    n_rows can not be 0 unless the table is empty, set to 1
7132
7237
    instead. The original problem of bug#29507 is actually
7133
7238
    fixed in the server code. */
7134
 
    if (user_session->getSqlCommand() == SQLCOM_TRUNCATE) {
 
7239
    if (session_sql_command(user_session) == SQLCOM_TRUNCATE) {
7135
7240
 
7136
7241
      n_rows = 1;
7137
7242
 
7215
7320
    ulint       num_innodb_index = UT_LIST_GET_LEN(ib_table->indexes) - prebuilt->clust_index_was_generated;
7216
7321
 
7217
7322
    if (getTable()->getShare()->keys != num_innodb_index) {
7218
 
      errmsg_printf(error::ERROR, "Table %s contains %lu "
 
7323
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains %lu "
7219
7324
                      "indexes inside InnoDB, which "
7220
7325
                      "is different from the number of "
7221
7326
                      "indexes %u defined in the MySQL ",
7235
7340
      index = innobase_get_index(i);
7236
7341
 
7237
7342
      if (index == NULL) {
7238
 
        errmsg_printf(error::ERROR, "Table %s contains fewer "
 
7343
        errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains fewer "
7239
7344
            "indexes inside InnoDB than "
7240
7345
            "are defined in the MySQL "
7241
7346
            ".frm file. Have you mixed up "
7250
7355
      for (j = 0; j < getTable()->key_info[i].key_parts; j++) {
7251
7356
 
7252
7357
        if (j + 1 > index->n_uniq) {
7253
 
          errmsg_printf(error::ERROR, 
 
7358
          errmsg_printf(ERRMSG_LVL_ERROR, 
7254
7359
"Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking "
7255
7360
"statistics for %lu columns. Have you mixed up .frm files from different "
7256
7361
"installations? "
7367
7472
  }
7368
7473
 
7369
7474
  if (prebuilt->table->ibd_file_missing) {
7370
 
        errmsg_printf(error::ERROR, "InnoDB: Error:\n"
 
7475
        errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: Error:\n"
7371
7476
                    "InnoDB: MySQL is trying to use a table handle"
7372
7477
                    " but the .ibd file for\n"
7373
7478
                    "InnoDB: table %s does not exist.\n"
7676
7781
      i++;
7677
7782
    }
7678
7783
    db_name[i] = 0;
7679
 
    ulen= identifier::Table::filename_to_tablename(db_name, uname, sizeof(uname));
 
7784
    ulen= TableIdentifier::filename_to_tablename(db_name, uname, sizeof(uname));
7680
7785
    LEX_STRING *tmp_referenced_db = session->make_lex_string(NULL, uname, ulen, true);
7681
7786
 
7682
7787
    /* Table name */
7683
7788
    tmp_buff += i + 1;
7684
 
    ulen= identifier::Table::filename_to_tablename(tmp_buff, uname, sizeof(uname));
 
7789
    ulen= TableIdentifier::filename_to_tablename(tmp_buff, uname, sizeof(uname));
7685
7790
    LEX_STRING *tmp_referenced_table = session->make_lex_string(NULL, uname, ulen, true);
7686
7791
 
7687
7792
    /** Foreign Fields **/
7759
7864
                              tmp_foreign_fields, tmp_referenced_fields);
7760
7865
 
7761
7866
    ForeignKeyInfo *pf_key_info = (ForeignKeyInfo *)
7762
 
      session->getMemRoot()->duplicate(&f_key_info, sizeof(ForeignKeyInfo));
 
7867
      session->memdup(&f_key_info, sizeof(ForeignKeyInfo));
7763
7868
    f_key_list->push_back(pf_key_info);
7764
7869
    foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
7765
7870
  }
8289
8394
static INNOBASE_SHARE* get_share(const char* table_name)
8290
8395
{
8291
8396
  INNOBASE_SHARE *share;
8292
 
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
 
8397
  pthread_mutex_lock(&innobase_share_mutex);
8293
8398
 
8294
8399
  ulint fold = ut_fold_string(table_name);
8295
8400
 
8316
8421
  }
8317
8422
 
8318
8423
  share->use_count++;
 
8424
  pthread_mutex_unlock(&innobase_share_mutex);
8319
8425
 
8320
8426
  return(share);
8321
8427
}
8322
8428
 
8323
8429
static void free_share(INNOBASE_SHARE* share)
8324
8430
{
8325
 
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
 
8431
  pthread_mutex_lock(&innobase_share_mutex);
8326
8432
 
8327
8433
#ifdef UNIV_DEBUG
8328
8434
  INNOBASE_SHARE* share2;
8351
8457
    /* TODO: invoke HASH_MIGRATE if innobase_open_tables
8352
8458
    shrinks too much */
8353
8459
  }
 
8460
 
 
8461
  pthread_mutex_unlock(&innobase_share_mutex);
8354
8462
}
8355
8463
 
8356
8464
/*****************************************************************//**
8385
8493
  trx = check_trx_exists(session);
8386
8494
 
8387
8495
  assert(EQ_CURRENT_SESSION(session));
8388
 
  const uint32_t sql_command = session->getSqlCommand();
 
8496
  const uint32_t sql_command = session_sql_command(session);
8389
8497
 
8390
8498
  if (sql_command == SQLCOM_DROP_TABLE) {
8391
8499
 
8471
8579
 
8472
8580
    if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
8473
8581
         && lock_type <= TL_WRITE)
8474
 
        && ! session->doing_tablespace_operation()
 
8582
        && !session_tablespace_op(session)
8475
8583
        && sql_command != SQLCOM_TRUNCATE
8476
8584
        && sql_command != SQLCOM_CREATE_TABLE) {
8477
8585
 
8548
8656
 
8549
8657
  if (auto_inc == 0) {
8550
8658
    ut_print_timestamp(stderr);
8551
 
    errmsg_printf(error::ERROR, "  InnoDB: AUTOINC next value generation is disabled for '%s'\n", innodb_table->name);
 
8659
    fprintf(stderr, "  InnoDB: AUTOINC next value generation "
 
8660
            "is disabled for '%s'\n", innodb_table->name);
8552
8661
  }
8553
8662
 
8554
8663
  dict_table_autoinc_unlock(innodb_table);
8703
8812
/* See comment in Cursor.cc */
8704
8813
UNIV_INTERN
8705
8814
bool
8706
 
InnobaseEngine::get_error_message(int, String *buf) const
 
8815
InnobaseEngine::get_error_message(int, String *buf)
8707
8816
{
8708
8817
  trx_t*  trx = check_trx_exists(current_session);
8709
8818
 
8787
8896
finds charset information and returns length of prefix_len characters in the
8788
8897
index field in bytes.
8789
8898
@return number of bytes occupied by the first n characters */
8790
 
UNIV_INTERN
 
8899
extern "C" UNIV_INTERN
8791
8900
ulint
8792
8901
innobase_get_at_most_n_mbchars(
8793
8902
/*===========================*/
8880
8989
  trx->detailed_error[0]= '\0';
8881
8990
 
8882
8991
  /* Set the isolation level of the transaction. */
8883
 
  trx->isolation_level= innobase_map_isolation_level(session->getTxIsolation());
 
8992
  trx->isolation_level= innobase_map_isolation_level(session_tx_isolation(session));
8884
8993
}
8885
8994
 
8886
8995
void
9148
9257
          "Purge threads can be either 0 or 1. Defalut is 0.");
9149
9258
  context("file-per-table",
9150
9259
          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.");
 
9260
          "Stores each InnoDB table to an .ibd file in the database dir.");
 
9261
  context("file-format",
 
9262
          po::value<string>(&innobase_file_format_name)->default_value("Antelope"),
 
9263
          "File format to use for new tables in .ibd files.");
9152
9264
  context("file-format-max",
9153
9265
          po::value<string>(&innobase_file_format_max)->default_value("Antelope"),
9154
9266
          "The highest file format in the tablespace.");
9155
9267
  context("file-format-check",
9156
9268
          po::value<bool>(&innobase_file_format_check)->default_value(true)->zero_tokens(),
9157
9269
          "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.");
9161
9270
  context("flush-log-at-trx-commit",
9162
9271
          po::value<trinary_constraint>(&innodb_flush_log_at_trx_commit)->default_value(1),
9163
9272
          "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).");
9192
9301
          po::value<additional_mem_pool_constraint>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
9193
9302
          "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.");
9194
9303
  context("autoextend-increment",
9195
 
          po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(64L),
 
9304
          po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(8L),
9196
9305
          "Data file autoextend increment in megabytes");
9197
9306
  context("buffer-pool-size",
9198
9307
          po::value<buffer_pool_constraint>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
9251
9360
          "InnoDB version");
9252
9361
  context("use-internal-malloc",
9253
9362
          "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"));
9256
9363
  context("change-buffering",
9257
9364
          po::value<string>(&innobase_change_buffering),
9258
9365
          "Buffer changes to reduce random access: OFF, ON, inserting, deleting, changing, or purging.");
9293
9400
  "Supports transactions, row-level locking, and foreign keys",
9294
9401
  PLUGIN_LICENSE_GPL,
9295
9402
  innobase_init, /* Plugin Init */
9296
 
  NULL, /* depends */
 
9403
  NULL, /* system variables */
9297
9404
  init_options /* reserved */
9298
9405
}
9299
9406
DRIZZLE_DECLARE_PLUGIN_END;
9325
9432
This function checks each index name for a table against reserved
9326
9433
system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
9327
9434
this function pushes an warning message to the client, and returns true. */
9328
 
UNIV_INTERN
 
9435
extern "C" UNIV_INTERN
9329
9436
bool
9330
9437
innobase_index_name_is_reserved(
9331
9438
/*============================*/
9345
9452
    if (innobase_strcasecmp(key->name,
9346
9453
                            innobase_index_reserve_name) == 0) {
9347
9454
      /* Push warning to drizzle */
9348
 
      push_warning_printf(trx->mysql_thd,
 
9455
      push_warning_printf((Session*)trx->mysql_thd,
9349
9456
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
9350
9457
                          ER_WRONG_NAME_FOR_INDEX,
9351
9458
                          "Cannot Create Index with name "
9371
9478
  ulint   buflen;
9372
9479
  const char* id;
9373
9480
  ulint   idlen;
9374
 
  drizzled::Session *session;
 
9481
  void*   session;
9375
9482
  ibool   file_id;
9376
9483
 
9377
9484
  const char* expected;