~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

doc modifications

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
38
38
    in Windows?
39
39
*/
40
40
 
41
 
#include <config.h>
 
41
#include "config.h"
42
42
 
43
43
#include <limits.h>
44
44
#include <fcntl.h>
45
45
 
46
 
#include <drizzled/error.h>
47
 
#include <drizzled/errmsg_print.h>
48
 
#include <drizzled/charset_info.h>
49
 
#include <drizzled/internal/m_string.h>
50
 
#include <drizzled/internal/my_sys.h>
51
 
#include <drizzled/my_hash.h>
52
 
#include <drizzled/plugin.h>
53
 
#include <drizzled/show.h>
54
 
#include <drizzled/data_home.h>
55
 
#include <drizzled/error.h>
56
 
#include <drizzled/field.h>
57
 
#include <drizzled/charset.h>
58
 
#include <drizzled/session.h>
59
 
#include <drizzled/current_session.h>
60
 
#include <drizzled/table.h>
61
 
#include <drizzled/field/blob.h>
62
 
#include <drizzled/field/varstring.h>
63
 
#include <drizzled/plugin/xa_storage_engine.h>
64
 
#include <drizzled/plugin/daemon.h>
65
 
#include <drizzled/memory/multi_malloc.h>
66
 
#include <drizzled/pthread_globals.h>
67
 
#include <drizzled/named_savepoint.h>
 
46
#include "drizzled/error.h"
 
47
#include "drizzled/errmsg_print.h"
 
48
#include "drizzled/charset_info.h"
 
49
#include "drizzled/internal/m_string.h"
 
50
#include "drizzled/internal/my_sys.h"
 
51
#include "drizzled/my_hash.h"
 
52
#include "drizzled/plugin.h"
 
53
#include "drizzled/show.h"
 
54
#include "drizzled/data_home.h"
 
55
#include "drizzled/error.h"
 
56
#include "drizzled/field.h"
 
57
#include "drizzled/charset.h"
 
58
#include "drizzled/session.h"
 
59
#include "drizzled/current_session.h"
 
60
#include "drizzled/table.h"
 
61
#include "drizzled/field/blob.h"
 
62
#include "drizzled/field/varstring.h"
 
63
#include "drizzled/field/timestamp.h"
 
64
#include "drizzled/plugin/xa_storage_engine.h"
 
65
#include "drizzled/plugin/daemon.h"
 
66
#include "drizzled/memory/multi_malloc.h"
 
67
#include "drizzled/pthread_globals.h"
 
68
#include "drizzled/named_savepoint.h"
68
69
 
69
70
#include <drizzled/transaction_services.h>
70
 
#include <drizzled/message/statement_transform.h>
 
71
#include "drizzled/message/statement_transform.h"
71
72
 
72
73
#include <boost/algorithm/string.hpp>
73
74
#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" {
86
87
#include "univ.i"
87
88
#include "buf0lru.h"
88
89
#include "btr0sea.h"
114
115
#include "ha_prototypes.h"
115
116
#include "ut0mem.h"
116
117
#include "ibuf0ibuf.h"
 
118
#include "mysql_addons.h"
 
119
}
117
120
 
118
121
#include "ha_innodb.h"
119
122
#include "data_dictionary.h"
125
128
#include <sstream>
126
129
#include <string>
127
130
 
128
 
#include <plugin/innobase/handler/status_function.h>
129
 
#include <plugin/innobase/handler/replication_log.h>
 
131
#include "plugin/innobase/handler/status_function.h"
 
132
#include "plugin/innobase/handler/replication_log.h"
130
133
 
131
134
#include <google/protobuf/io/zero_copy_stream.h>
132
135
#include <google/protobuf/io/zero_copy_stream_impl.h>
133
136
#include <google/protobuf/io/coded_stream.h>
134
137
#include <google/protobuf/text_format.h>
135
138
 
136
 
#include <boost/thread/mutex.hpp>
137
 
 
138
139
using namespace std;
139
140
using namespace drizzled;
140
141
 
141
142
/** to protect innobase_open_files */
142
 
static boost::mutex innobase_share_mutex;
143
 
 
 
143
static pthread_mutex_t innobase_share_mutex;
144
144
/** to force correct commit order in binlog */
 
145
static pthread_mutex_t prepare_commit_mutex;
145
146
static ulong commit_threads = 0;
146
 
static boost::condition_variable commit_cond;
147
 
static boost::mutex commit_cond_m;
 
147
static pthread_mutex_t commit_threads_m;
 
148
static pthread_cond_t commit_cond;
 
149
static pthread_mutex_t commit_cond_m;
148
150
static bool innodb_inited = 0;
149
151
 
150
152
#define INSIDE_HA_INNOBASE_CC
160
162
#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
161
163
 
162
164
static plugin::XaStorageEngine* innodb_engine_ptr= NULL;
163
 
 
 
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;
164
183
typedef constrained_check<uint32_t, UINT32_MAX, 10> open_files_constraint;
165
184
static open_files_constraint innobase_open_files;
166
185
typedef constrained_check<uint32_t, 10, 1> mirrored_log_groups_constraint;
185
204
static purge_batch_constraint innodb_purge_batch_size;
186
205
typedef constrained_check<uint32_t, 1, 0> purge_threads_constraint;
187
206
static purge_threads_constraint innodb_n_purge_threads;
188
 
typedef constrained_check<uint32_t, 2, 0> trinary_constraint;
 
207
typedef constrained_check<uint16_t, 2, 0> trinary_constraint;
189
208
static trinary_constraint innodb_flush_log_at_trx_commit;
190
209
typedef constrained_check<unsigned int, 99, 0> max_dirty_pages_constraint;
191
210
static max_dirty_pages_constraint innodb_max_dirty_pages_pct;
234
253
/* Below we have boolean-valued start-up parameters, and their default
235
254
values */
236
255
 
237
 
typedef constrained_check<uint32_t, 2, 0> trinary_constraint;
 
256
typedef constrained_check<uint16_t, 2, 0> trinary_constraint;
238
257
static trinary_constraint innobase_fast_shutdown;
239
258
 
240
259
/* "innobase_file_format_check" decides whether we would continue
333
352
      srv_free_paths_and_sizes();
334
353
      if (internal_innobase_data_file_path)
335
354
        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);
336
360
    }
337
361
    
338
362
    /* These get strdup'd from vm variables */
422
446
  doDropSchema(
423
447
  /*===================*/
424
448
        /* out: error number */
425
 
    const identifier::Schema  &identifier); /* in: database path; inside InnoDB the name
 
449
    const SchemaIdentifier  &identifier); /* in: database path; inside InnoDB the name
426
450
        of the last directory in the path is used as
427
451
        the database name: for example, in 'mysql/data/test'
428
452
        the database name is 'test' */
461
485
 
462
486
  UNIV_INTERN int doCreateTable(Session &session,
463
487
                                Table &form,
464
 
                                const identifier::Table &identifier,
 
488
                                const TableIdentifier &identifier,
465
489
                                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);
 
490
  UNIV_INTERN int doRenameTable(Session&, const TableIdentifier &from, const TableIdentifier &to);
 
491
  UNIV_INTERN int doDropTable(Session &session, const TableIdentifier &identifier);
468
492
 
469
 
  UNIV_INTERN virtual bool get_error_message(int error, String *buf) const;
 
493
  UNIV_INTERN virtual bool get_error_message(int error, String *buf);
470
494
 
471
495
  UNIV_INTERN uint32_t max_supported_keys() const;
472
496
  UNIV_INTERN uint32_t max_supported_key_length() const;
483
507
  }
484
508
 
485
509
  int doGetTableDefinition(drizzled::Session& session,
486
 
                           const identifier::Table &identifier,
 
510
                           const TableIdentifier &identifier,
487
511
                           drizzled::message::Table &table_proto);
488
512
 
489
 
  bool doDoesTableExist(drizzled::Session& session, const identifier::Table &identifier);
 
513
  bool doDoesTableExist(drizzled::Session& session, const TableIdentifier &identifier);
490
514
 
491
515
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
492
 
                             const drizzled::identifier::Schema &schema_identifier,
493
 
                             drizzled::identifier::Table::vector &set_of_identifiers);
 
516
                             const drizzled::SchemaIdentifier &schema_identifier,
 
517
                             drizzled::TableIdentifier::vector &set_of_identifiers);
494
518
  bool validateCreateTableOption(const std::string &key, const std::string &state);
495
519
  void dropTemporarySchema();
496
520
 
518
542
}
519
543
 
520
544
void InnobaseEngine::doGetTableIdentifiers(drizzled::CachedDirectory &directory,
521
 
                                           const drizzled::identifier::Schema &schema_identifier,
522
 
                                           drizzled::identifier::Table::vector &set_of_identifiers)
 
545
                                           const drizzled::SchemaIdentifier &schema_identifier,
 
546
                                           drizzled::TableIdentifier::vector &set_of_identifiers)
523
547
{
524
548
  CachedDirectory::Entries entries= directory.getEntries();
525
549
 
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
550
  for (CachedDirectory::Entries::iterator entry_iter= entries.begin(); 
536
551
       entry_iter != entries.end(); ++entry_iter)
537
552
  {
559
574
           Using schema_identifier here to stop unused warning, could use
560
575
           definition.schema() instead
561
576
        */
562
 
        identifier::Table identifier(schema_identifier.getSchemaName(), definition.name());
 
577
        TableIdentifier identifier(schema_identifier.getSchemaName(), definition.name());
563
578
        set_of_identifiers.push_back(identifier);
564
579
      }
565
580
    }
566
581
  }
567
582
}
568
583
 
569
 
bool InnobaseEngine::doDoesTableExist(Session &session, const identifier::Table &identifier)
 
584
bool InnobaseEngine::doDoesTableExist(Session &session, const TableIdentifier &identifier)
570
585
{
571
586
  string proto_path(identifier.getPath());
572
587
  proto_path.append(DEFAULT_FILE_EXTENSION);
574
589
  if (session.getMessageCache().doesTableMessageExist(identifier))
575
590
    return true;
576
591
 
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
592
  if (access(proto_path.c_str(), F_OK))
584
593
  {
585
594
    return false;
589
598
}
590
599
 
591
600
int InnobaseEngine::doGetTableDefinition(Session &session,
592
 
                                         const identifier::Table &identifier,
 
601
                                         const TableIdentifier &identifier,
593
602
                                         message::Table &table_proto)
594
603
{
595
604
  string proto_path(identifier.getPath());
599
608
  if (session.getMessageCache().getTableMessage(identifier, table_proto))
600
609
    return EEXIST;
601
610
 
602
 
  if (read_replication_log_table_message(identifier.getTableName().c_str(), &table_proto) == 0)
603
 
    return EEXIST;
604
 
 
605
611
  if (access(proto_path.c_str(), F_OK))
606
612
  {
607
613
    return errno;
798
804
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
799
805
         in non-Cursor code.
800
806
@return true if session is the replication thread */
801
 
UNIV_INTERN
 
807
extern "C" UNIV_INTERN
802
808
ibool
803
809
thd_is_replication_slave_thread(
804
810
/*============================*/
805
 
  drizzled::Session* ) /*!< in: thread handle (Session*) */
 
811
  void* ) /*!< in: thread handle (Session*) */
806
812
{
807
813
  return false;
808
814
}
872
878
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
873
879
         in non-Cursor code.
874
880
@return true if non-transactional tables have been edited */
875
 
UNIV_INTERN
 
881
extern "C" UNIV_INTERN
876
882
ibool
877
883
thd_has_edited_nontrans_tables(
878
884
/*===========================*/
879
 
  drizzled::Session *session)  /*!< in: thread handle (Session*) */
 
885
  void*   session)  /*!< in: thread handle (Session*) */
880
886
{
881
 
  return((ibool)session->transaction.all.hasModifiedNonTransData());
 
887
  return((ibool)((Session *)session)->transaction.all.hasModifiedNonTransData());
882
888
}
883
889
 
884
890
/******************************************************************//**
885
891
Returns true if the thread is executing a SELECT statement.
886
892
@return true if session is executing SELECT */
887
 
UNIV_INTERN
 
893
extern "C" UNIV_INTERN
888
894
ibool
889
895
thd_is_select(
890
896
/*==========*/
891
 
  const drizzled::Session *session)  /*!< in: thread handle (Session*) */
 
897
  const void* session)  /*!< in: thread handle (Session*) */
892
898
{
893
 
  return(session->getSqlCommand() == SQLCOM_SELECT);
 
899
  return(session_sql_command((const Session*) session) == SQLCOM_SELECT);
894
900
}
895
901
 
896
902
/******************************************************************//**
897
903
Returns true if the thread supports XA,
898
904
global value of innodb_supports_xa if session is NULL.
899
905
@return true if session has XA support */
900
 
UNIV_INTERN
 
906
extern "C" UNIV_INTERN
901
907
ibool
902
908
thd_supports_xa(
903
909
/*============*/
904
 
  drizzled::Session* )  /*!< in: thread handle (Session*), or NULL to query
 
910
  void* )  /*!< in: thread handle (Session*), or NULL to query
905
911
        the global innodb_supports_xa */
906
912
{
907
913
  /* TODO: Add support here for per-session value */
911
917
/******************************************************************//**
912
918
Returns the lock wait timeout for the current connection.
913
919
@return the lock wait timeout, in seconds */
914
 
UNIV_INTERN
 
920
extern "C" UNIV_INTERN
915
921
ulong
916
922
thd_lock_wait_timeout(
917
923
/*==================*/
918
 
  drizzled::Session*)  /*!< in: thread handle (Session*), or NULL to query
 
924
  void*)  /*!< in: thread handle (Session*), or NULL to query
919
925
      the global innodb_lock_wait_timeout */
920
926
{
921
927
  /* TODO: Add support here for per-session value */
926
932
 
927
933
/******************************************************************//**
928
934
Set the time waited for the lock for the current query. */
929
 
UNIV_INTERN
 
935
extern "C" UNIV_INTERN
930
936
void
931
937
thd_set_lock_wait_time(
932
938
/*===================*/
933
 
        drizzled::Session*      in_session,     /*!< in: thread handle (THD*) */
 
939
        void*   thd,    /*!< in: thread handle (THD*) */
934
940
        ulint   value)  /*!< in: time waited for the lock */
935
941
{
936
 
  if (in_session)
937
 
    in_session->utime_after_lock+= value;
 
942
        if (thd) {
 
943
          static_cast<Session*>(thd)->utime_after_lock+= value;
 
944
        }
938
945
}
939
946
 
940
947
/********************************************************************//**
960
967
  trx_t *trx= session_to_trx(&session);
961
968
 
962
969
  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);
 
970
  ulint error= insert_replication_message(data, message.ByteSize(), trx, trx_id);
969
971
  (void)error;
970
972
 
971
973
  delete[] data;
1022
1024
about a possible transaction rollback inside InnoDB caused by a lock wait
1023
1025
timeout or a deadlock.
1024
1026
@return MySQL error code */
1025
 
UNIV_INTERN
 
1027
extern "C" UNIV_INTERN
1026
1028
int
1027
1029
convert_error_code_to_mysql(
1028
1030
/*========================*/
1076
1078
    tell it also to MySQL so that MySQL knows to empty the
1077
1079
    cached binlog for this transaction */
1078
1080
 
1079
 
    session->markTransactionForRollback(TRUE);
 
1081
    mark_transaction_to_rollback(session, TRUE);
1080
1082
 
1081
1083
    return(HA_ERR_LOCK_DEADLOCK);
1082
1084
 
1085
1087
    latest SQL statement in a lock wait timeout. Previously, we
1086
1088
    rolled back the whole transaction. */
1087
1089
 
1088
 
    session->markTransactionForRollback((bool)row_rollback_on_timeout);
 
1090
    mark_transaction_to_rollback(session, (bool)row_rollback_on_timeout);
1089
1091
 
1090
1092
    return(HA_ERR_LOCK_WAIT_TIMEOUT);
1091
1093
 
1096
1098
    return(HA_ERR_ROW_IS_REFERENCED);
1097
1099
 
1098
1100
  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 & DICT_TF_COMPACT) / 2);
 
1124
       page_get_free_space_of_empty(flags
 
1125
                  & DICT_TF_COMPACT) / 2);
1125
1126
    return(HA_ERR_TO_BIG_ROW);
1126
1127
 
1127
1128
  case DB_NO_SAVEPOINT:
1132
1133
    tell it also to MySQL so that MySQL knows to empty the
1133
1134
    cached binlog for this transaction */
1134
1135
 
1135
 
    session->markTransactionForRollback(TRUE);
 
1136
    mark_transaction_to_rollback(session, TRUE);
1136
1137
 
1137
1138
    return(HA_ERR_LOCK_TABLE_FULL);
1138
1139
 
1166
1167
 
1167
1168
/*************************************************************//**
1168
1169
Prints info of a Session object (== user session thread) to the given file. */
1169
 
UNIV_INTERN
 
1170
extern "C" UNIV_INTERN
1170
1171
void
1171
1172
innobase_mysql_print_thd(
1172
1173
/*=====================*/
1173
1174
  FILE* f,    /*!< in: output stream */
1174
 
  drizzled::Session *in_session,  /*!< in: pointer to a Drizzle Session object */
 
1175
  void * in_session,  /*!< in: pointer to a Drizzle Session object */
1175
1176
  uint  )   /*!< in: max query length to print, or 0 to
1176
1177
           use the default max length */
1177
1178
{
1178
 
  drizzled::identifier::User::const_shared_ptr user_identifier(in_session->user());
1179
 
 
 
1179
  Session *session= reinterpret_cast<Session *>(in_session);
1180
1180
  fprintf(f,
1181
1181
          "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()),
1184
 
          getServerHostname().c_str(),
1185
 
          user_identifier->address().c_str(),
1186
 
          user_identifier->username().c_str()
 
1182
          static_cast<uint64_t>(session->getSessionId()),
 
1183
          static_cast<uint64_t>(session->getQueryId()),
 
1184
          glob_hostname,
 
1185
          session->getSecurityContext().getIp().c_str(),
 
1186
          session->getSecurityContext().getUser().c_str()
1187
1187
  );
1188
 
  fprintf(f, "\n%s", in_session->getQueryString()->c_str());
 
1188
  fprintf(f, "\n%s", 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
 
UNIV_INTERN
 
1194
extern "C" 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
 
UNIV_INTERN
 
1221
extern "C" 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
 
UNIV_INTERN
 
1235
extern "C" 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
 
UNIV_INTERN
 
1250
extern "C" 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
 
UNIV_INTERN
 
1262
extern "C" 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
 
UNIV_INTERN
 
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
1272
1284
bool
1273
1285
innobase_isspace(
1274
1286
  const void *cs,
1277
1289
  return my_isspace(static_cast<const CHARSET_INFO *>(cs), char_to_test);
1278
1290
}
1279
1291
 
 
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
 
1280
1313
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1281
1314
/*******************************************************************//**
1282
1315
Map an OS error to an errno value. The OS error number is stored in
1283
1316
_doserrno and the mapped value is stored in errno) */
 
1317
extern "C"
1284
1318
void __cdecl
1285
1319
_dosmaperr(
1286
1320
  unsigned long); /*!< in: OS error value */
1288
1322
/*********************************************************************//**
1289
1323
Creates a temporary file.
1290
1324
@return temporary file descriptor, or < 0 on error */
1291
 
UNIV_INTERN
 
1325
extern "C" UNIV_INTERN
1292
1326
int
1293
1327
innobase_mysql_tmpfile(void)
1294
1328
/*========================*/
1368
1402
/*********************************************************************//**
1369
1403
Creates a temporary file.
1370
1404
@return temporary file descriptor, or < 0 on error */
1371
 
UNIV_INTERN
 
1405
extern "C" UNIV_INTERN
1372
1406
int
1373
1407
innobase_mysql_tmpfile(void)
1374
1408
/*========================*/
1375
1409
{
1376
1410
  int fd2 = -1;
1377
 
  int fd = ::drizzled::tmpfile("ib");
 
1411
  int fd = mysql_tmpfile("ib");
1378
1412
  if (fd >= 0) {
1379
1413
    /* Copy the file descriptor, so that the additional resources
1380
1414
    allocated by create_temp_file() can be freed by invoking
1407
1441
number of bytes that were written to "buf" is returned (including the
1408
1442
terminating NUL).
1409
1443
@return number of bytes that were written */
1410
 
UNIV_INTERN
 
1444
extern "C" UNIV_INTERN
1411
1445
ulint
1412
1446
innobase_raw_format(
1413
1447
/*================*/
1527
1561
/*********************************************************************//**
1528
1562
Allocates an InnoDB transaction for a MySQL Cursor object.
1529
1563
@return InnoDB transaction handle */
1530
 
UNIV_INTERN
 
1564
extern "C" UNIV_INTERN
1531
1565
trx_t*
1532
1566
innobase_trx_allocate(
1533
1567
/*==================*/
1631
1665
  ulint   buflen, /*!< in: length of buf, in bytes */
1632
1666
  const char* id, /*!< in: identifier to convert */
1633
1667
  ulint   idlen,  /*!< in: length of id, in bytes */
1634
 
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
 
1668
  void*   session,/*!< in: MySQL connection thread, or NULL */
1635
1669
  ibool   file_id)/*!< in: TRUE=id is a table or database name;
1636
1670
        FALSE=id is an UTF-8 string */
1637
1671
{
1638
1672
  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]);
 
1673
  char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix];
1641
1674
 
1642
1675
  const char* s = id;
1643
1676
  int   q;
1654
1687
    memcpy(nz, id, idlen);
1655
1688
    nz[idlen] = 0;
1656
1689
 
1657
 
    s = nz2.get();
1658
 
    idlen = identifier::Table::filename_to_tablename(nz, nz2.get(), nz2_size);
 
1690
    s = nz2;
 
1691
    idlen = TableIdentifier::filename_to_tablename(nz, nz2, sizeof nz2);
1659
1692
  }
1660
1693
 
1661
1694
  /* See if the identifier needs to be quoted. */
1709
1742
Convert a table or index name to the MySQL system_charset_info (UTF-8)
1710
1743
and quote it if needed.
1711
1744
@return pointer to the end of buf */
1712
 
UNIV_INTERN
 
1745
extern "C" UNIV_INTERN
1713
1746
char*
1714
1747
innobase_convert_name(
1715
1748
/*==================*/
1717
1750
  ulint   buflen, /*!< in: length of buf, in bytes */
1718
1751
  const char* id, /*!< in: identifier to convert */
1719
1752
  ulint   idlen,  /*!< in: length of id, in bytes */
1720
 
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
 
1753
  void*   session,/*!< in: MySQL connection thread, or NULL */
1721
1754
  ibool   table_id)/*!< in: TRUE=id is a table or database name;
1722
1755
        FALSE=id is an index name */
1723
1756
{
1765
1798
/**********************************************************************//**
1766
1799
Determines if the currently running transaction has been interrupted.
1767
1800
@return TRUE if interrupted */
1768
 
UNIV_INTERN
 
1801
extern "C" UNIV_INTERN
1769
1802
ibool
1770
1803
trx_is_interrupted(
1771
1804
/*===============*/
1772
1805
  trx_t*  trx)  /*!< in: transaction */
1773
1806
{
1774
 
  return(trx && trx->mysql_thd && trx->mysql_thd->getKilled());
 
1807
  return(trx && trx->mysql_thd && static_cast<Session*>(trx->mysql_thd)->getKilled());
1775
1808
}
1776
1809
 
1777
1810
/**********************************************************************//**
1778
1811
Determines if the currently running transaction is in strict mode.
1779
1812
@return TRUE if strict */
1780
 
UNIV_INTERN
 
1813
extern "C" UNIV_INTERN
1781
1814
ibool
1782
1815
trx_is_strict(
1783
1816
/*==========*/
1869
1902
 
1870
1903
static int innodb_commit_concurrency_validate(Session *session, set_var *var)
1871
1904
{
1872
 
   uint64_t new_value= var->getInteger();
 
1905
   uint32_t new_value= var->save_result.uint32_t_value;
1873
1906
 
1874
1907
   if ((innobase_commit_concurrency.get() == 0 && new_value != 0) ||
1875
1908
       (innobase_commit_concurrency.get() != 0 && new_value == 0))
1973
2006
    }
1974
2007
 
1975
2008
    if (format_id >= 0) {
1976
 
      innobase_file_format_max.assign(
1977
 
                             trx_sys_file_format_id_to_name((uint)format_id));
 
2009
      innobase_file_format_max= 
 
2010
        trx_sys_file_format_id_to_name((uint)format_id);
1978
2011
 
1979
2012
      /* 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))
 
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))
1983
2016
      {
1984
 
        errmsg_printf(error::WARN,
 
2017
        errmsg_printf(ERRMSG_LVL_WARN,
1985
2018
                      " [Info] InnoDB: the file format in the system "
1986
2019
                      "tablespace is now set to %s.\n", name_buff);
1987
2020
        innobase_file_format_max= name_buff;
2041
2074
  innobase_use_doublewrite= (vm.count("disable-doublewrite")) ? false : true;
2042
2075
  srv_adaptive_flushing= (vm.count("disable-adaptive-flushing")) ? false : true;
2043
2076
  srv_use_sys_malloc= (vm.count("use-internal-malloc")) ? false : true;
2044
 
  srv_use_native_aio= (vm.count("disable-native-aio")) ? false : true;
2045
2077
  support_xa= (vm.count("disable-xa")) ? false : true;
2046
2078
  btr_search_enabled= (vm.count("disable-adaptive-hash-index")) ? false : true;
2047
2079
 
2069
2101
 
2070
2102
#ifdef UNIV_DEBUG
2071
2103
  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(),
 
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,
2083
2114
                test_filename)) {
2084
 
    errmsg_printf(error::ERROR, "tablename encoding has been changed");
 
2115
    errmsg_printf(ERRMSG_LVL_ERROR, "tablename encoding has been changed");
2085
2116
    goto error;
2086
2117
  }
2087
2118
#endif /* UNIV_DEBUG */
2115
2146
  ret = (bool) srv_parse_data_file_paths_and_sizes(
2116
2147
                                                   internal_innobase_data_file_path);
2117
2148
  if (ret == FALSE) {
2118
 
    errmsg_printf(error::ERROR, "InnoDB: syntax error in innodb_data_file_path");
2119
 
 
 
2149
    errmsg_printf(ERRMSG_LVL_ERROR, 
 
2150
                  "InnoDB: syntax error in innodb_data_file_path");
2120
2151
mem_free_and_error:
2121
2152
    srv_free_paths_and_sizes();
2122
2153
    if (internal_innobase_data_file_path)
2141
2172
    srv_parse_log_group_home_dirs((char *)innobase_log_group_home_dir.c_str());
2142
2173
 
2143
2174
  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"));
 
2175
    errmsg_printf(ERRMSG_LVL_ERROR,
 
2176
                  _("syntax error in innodb_log_group_home_dir, or a "
 
2177
                  "wrong number of mirrored log groups"));
2146
2178
 
2147
2179
    goto mem_free_and_error;
2148
2180
  }
2156
2188
 
2157
2189
    if (format_id > DICT_TF_FORMAT_MAX) {
2158
2190
 
2159
 
      errmsg_printf(error::ERROR, "InnoDB: wrong innodb_file_format.");
 
2191
      errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: wrong innodb_file_format.");
2160
2192
 
2161
2193
      goto mem_free_and_error;
2162
2194
    }
2185
2217
     srv_max_file_format_at_startup */
2186
2218
  if (innobase_file_format_validate_and_set(innobase_file_format_max.c_str()) < 0)
2187
2219
  {
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));
 
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));
2191
2225
    goto mem_free_and_error;
2192
2226
  }
2193
2227
 
2206
2240
      }
2207
2241
    }
2208
2242
 
2209
 
    errmsg_printf(error::ERROR, "InnoDB: invalid value innodb_change_buffering=%s",
 
2243
    errmsg_printf(ERRMSG_LVL_ERROR,
 
2244
                  "InnoDB: invalid value "
 
2245
                  "innodb_change_buffering=%s",
2210
2246
                  vm["change-buffering"].as<string>().c_str());
2211
2247
    goto mem_free_and_error;
2212
2248
  }
2284
2320
                                                     TRUE);
2285
2321
 
2286
2322
  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);
2287
2328
  innodb_inited= 1;
2288
2329
 
2289
2330
  actuall_engine_ptr->dropTemporarySchema();
2290
2331
 
2291
 
  context.add(new InnodbStatusTool);
 
2332
  status_table_function_ptr= new InnodbStatusTool;
2292
2333
 
2293
2334
  context.add(innodb_engine_ptr);
2294
2335
 
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());
 
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);
2322
2379
 
2323
2380
  context.add(new(std::nothrow)InnodbInternalTables());
2324
2381
  context.add(new(std::nothrow)InnodbReplicationTable());
2325
2382
 
2326
2383
  if (innobase_use_replication_log)
2327
2384
  {
2328
 
    ReplicationLog *replication_logger= new(std::nothrow)ReplicationLog();
 
2385
    replication_logger= new(std::nothrow)ReplicationLog();
2329
2386
    context.add(replication_logger);
2330
2387
    ReplicationLog::setup(replication_logger);
2331
2388
  }
2365
2422
  context.registerVariable(new sys_var_constrained_value<uint32_t>("purge_threads",
2366
2423
                                                                   innodb_n_purge_threads,
2367
2424
                                                                   purge_threads_update));
2368
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("fast_shutdown", innobase_fast_shutdown));
 
2425
  context.registerVariable(new sys_var_constrained_value<uint16_t>("fast_shutdown", innobase_fast_shutdown));
2369
2426
  context.registerVariable(new sys_var_std_string("file_format",
2370
2427
                                                  innobase_file_format_name,
2371
2428
                                                  innodb_file_format_name_validate));
2377
2434
                                                  innodb_file_format_max_validate));
2378
2435
  context.registerVariable(new sys_var_constrained_value_readonly<size_t>("buffer_pool_size", innobase_buffer_pool_size));
2379
2436
  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",
 
2437
  context.registerVariable(new sys_var_constrained_value_readonly<uint16_t>("flush_log_at_trx_commit",
2381
2438
                                                  innodb_flush_log_at_trx_commit));
2382
2439
  context.registerVariable(new sys_var_constrained_value_readonly<unsigned int>("max_dirty_pages_pct",
2383
2440
                                                  innodb_max_dirty_pages_pct));
2416
2473
  btr_search_fully_disabled = (!btr_search_enabled);
2417
2474
 
2418
2475
  return(FALSE);
2419
 
 
2420
2476
error:
2421
2477
  return(TRUE);
2422
2478
}
2513
2569
    trx_search_latch_release_if_reserved(trx);
2514
2570
  }
2515
2571
 
2516
 
  if (all)
2517
 
  {
 
2572
  if (all
 
2573
    || (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
 
2574
 
2518
2575
    /* We were instructed to commit the whole transaction, or
2519
2576
    this is an SQL statement end and autocommit is on */
2520
2577
 
2521
2578
    /* We need current binlog position for ibbackup to work.
2522
2579
    Note, the position is current because of
2523
2580
    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
 
 
 
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()) {
2535
2587
        commit_threads--;
2536
 
        commit_cond.wait(scopedLock);
2537
 
      } while (1);
 
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
      }
2538
2596
    }
2539
2597
 
2540
 
    trx->mysql_log_file_name = NULL;
 
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";
2541
2602
    trx->mysql_log_offset = 0;
2542
2603
 
2543
2604
    /* Don't do write + flush right now. For group commit
2547
2608
    innobase_commit_low(trx);
2548
2609
    trx->flush_log_later = FALSE;
2549
2610
 
2550
 
    if (commit_concurrency)
2551
 
    {
2552
 
      boost::mutex::scoped_lock scopedLock(commit_cond_m);
 
2611
    if (innobase_commit_concurrency.get() > 0) {
 
2612
      pthread_mutex_lock(&commit_cond_m);
2553
2613
      commit_threads--;
2554
 
      commit_cond.notify_one();
 
2614
      pthread_cond_signal(&commit_cond);
 
2615
      pthread_mutex_unlock(&commit_cond_m);
2555
2616
    }
2556
2617
 
2557
2618
    /* Now do a write + flush of logs. */
2636
2697
 
2637
2698
  row_unlock_table_autoinc_for_mysql(trx);
2638
2699
 
2639
 
  if (all)
2640
 
  {
 
2700
  if (all
 
2701
    || !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
 
2702
 
2641
2703
    error = trx_rollback_for_mysql(trx);
2642
2704
  } else {
2643
2705
    error = trx_rollback_last_sql_stat_for_mysql(trx);
2796
2858
      trx->undo_no > 0 &&
2797
2859
      global_system_variables.log_warnings)
2798
2860
  {
2799
 
      errmsg_printf(error::WARN,
 
2861
      errmsg_printf(ERRMSG_LVL_WARN,
2800
2862
      "Drizzle is closing a connection during a KILL operation\n"
2801
2863
      "that has an active InnoDB transaction.  %llu row modifications will "
2802
2864
      "roll back.\n",
2876
2938
  return(true);
2877
2939
}
2878
2940
 
 
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
 
2879
2987
/********************************************************************//**
2880
2988
Get the upper limit of the MySQL integral and floating-point type.
2881
2989
@return maximum allowed value for the field */
3042
3150
                if (!index_mapping) {
3043
3151
                        /* Report an error if index_mapping continues to be
3044
3152
                        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",
 
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",
3047
3157
                                        mysql_num_index,
3048
3158
                                        share->idx_trans_tbl.array_size);
3049
3159
                        ret = FALSE;
3064
3174
                        ib_table, table->key_info[count].name);
3065
3175
 
3066
3176
                if (!index_mapping[count]) {
3067
 
                        errmsg_printf(error::ERROR, "Cannot find index %s in InnoDB index dictionary.",
3068
 
                                      table->key_info[count].name);
 
3177
                        errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find index %s in InnoDB "
 
3178
                                        "index dictionary.",
 
3179
                                        table->key_info[count].name);
3069
3180
                        ret = FALSE;
3070
3181
                        goto func_exit;
3071
3182
                }
3072
3183
 
3073
3184
                /* Double check fetched index has the same
3074
3185
                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;
 
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;
3080
3193
                }
3081
3194
        }
3082
3195
 
3146
3259
    auto_inc = 0;
3147
3260
 
3148
3261
    ut_print_timestamp(stderr);
3149
 
    errmsg_printf(error::ERROR, "InnoDB: Unable to determine the AUTOINC column name");
 
3262
    fprintf(stderr, "  InnoDB: Unable to determine the AUTOINC "
 
3263
            "column name\n");
3150
3264
  }
3151
3265
 
3152
3266
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
3196
3310
    }
3197
3311
    case DB_RECORD_NOT_FOUND:
3198
3312
      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);
 
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);
3206
3326
 
3207
3327
      /* This will disable the AUTOINC generation. */
3208
3328
      auto_inc = 0;
3228
3348
@return 1 if error, 0 if success */
3229
3349
UNIV_INTERN
3230
3350
int
3231
 
ha_innobase::doOpen(const identifier::Table &identifier,
 
3351
ha_innobase::doOpen(const TableIdentifier &identifier,
3232
3352
                    int   mode,   /*!< in: not used */
3233
3353
                    uint    test_if_locked) /*!< in: not used */
3234
3354
{
3235
3355
  dict_table_t* ib_table;
 
3356
  char    norm_name[FN_REFLEN];
3236
3357
  Session*    session;
3237
3358
 
3238
3359
  UT_NOT_USED(mode);
3247
3368
    getTransactionalEngine()->releaseTemporaryLatches(session);
3248
3369
  }
3249
3370
 
 
3371
  normalize_table_name(norm_name, identifier.getPath().c_str());
 
3372
 
3250
3373
  user_session = NULL;
3251
3374
 
3252
 
  std::string search_string(identifier.getSchemaName());
3253
 
  boost::algorithm::to_lower(search_string);
 
3375
  if (!(share=get_share(identifier.getPath().c_str()))) {
3254
3376
 
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
 
    }
 
3377
    return(1);
3270
3378
  }
3271
3379
 
3272
3380
  /* Create buffers for packing the fields of a record. Why
3275
3383
  stored the string length as the first byte. */
3276
3384
 
3277
3385
  upd_and_key_val_buff_len =
3278
 
        getTable()->getShare()->sizeStoredRecord()
 
3386
        getTable()->getShare()->stored_rec_length
3279
3387
        + getTable()->getShare()->max_key_length
3280
3388
        + MAX_REF_PARTS * 3;
3281
3389
 
3293
3401
  }
3294
3402
 
3295
3403
  /* 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
 
  }
 
3404
  ib_table = dict_table_get(norm_name, TRUE);
3306
3405
  
3307
3406
  if (NULL == ib_table) {
3308
 
    errmsg_printf(error::ERROR, "Cannot find or open table %s from\n"
 
3407
    errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find or open table %s from\n"
3309
3408
        "the internal data dictionary of InnoDB "
3310
3409
        "though the .frm file for the\n"
3311
3410
        "table exists. Maybe you have deleted and "
3319
3418
        "doesn't support.\n"
3320
3419
        "See " REFMAN "innodb-troubleshooting.html\n"
3321
3420
        "how you can resolve the problem.\n",
3322
 
        identifier.getKeyPath().c_str());
 
3421
        norm_name);
3323
3422
    free_share(share);
3324
3423
    upd_buff.resize(0);
3325
3424
    key_val_buff.resize(0);
3328
3427
    return(HA_ERR_NO_SUCH_TABLE);
3329
3428
  }
3330
3429
 
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 "
 
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 "
3333
3432
        "the .ibd file for\ntable %s does not exist.\n"
3334
3433
        "Have you deleted the .ibd file from the "
3335
3434
        "database directory under\nthe MySQL datadir, "
3336
3435
        "or have you used DISCARD TABLESPACE?\n"
3337
3436
        "See " REFMAN "innodb-troubleshooting.html\n"
3338
3437
        "how you can resolve the problem.\n",
3339
 
        identifier.getKeyPath().c_str());
 
3438
        norm_name);
3340
3439
    free_share(share);
3341
3440
    upd_buff.resize(0);
3342
3441
    key_val_buff.resize(0);
3348
3447
 
3349
3448
  prebuilt = row_create_prebuilt(ib_table);
3350
3449
 
3351
 
  prebuilt->mysql_row_len = getTable()->getShare()->sizeStoredRecord();
 
3450
  prebuilt->mysql_row_len = getTable()->getShare()->stored_rec_length;
3352
3451
  prebuilt->default_rec = getTable()->getDefaultValues();
3353
3452
  ut_ad(prebuilt->default_rec);
3354
3453
 
3358
3457
  key_used_on_scan = primary_key;
3359
3458
 
3360
3459
  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());
 
3460
    errmsg_printf(ERRMSG_LVL_ERROR, "Build InnoDB index translation table for"
 
3461
                    " Table %s failed", identifier.getPath().c_str());
3363
3462
  }
3364
3463
 
3365
3464
  /* Allocate a buffer for a 'row reference'. A row reference is
3373
3472
    prebuilt->clust_index_was_generated = FALSE;
3374
3473
 
3375
3474
    if (UNIV_UNLIKELY(primary_key >= MAX_KEY)) {
3376
 
      errmsg_printf(error::ERROR, "Table %s has a primary key in "
 
3475
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has a primary key in "
3377
3476
                    "InnoDB data dictionary, but not "
3378
3477
                    "in MySQL!", identifier.getTableName().c_str());
3379
3478
 
3428
3527
    }
3429
3528
  } else {
3430
3529
    if (primary_key != MAX_KEY) {
3431
 
      errmsg_printf(error::ERROR,
 
3530
      errmsg_printf(ERRMSG_LVL_ERROR,
3432
3531
                    "Table %s has no primary key in InnoDB data "
3433
3532
                    "dictionary, but has one in MySQL! If you "
3434
3533
                    "created the table with a MySQL version < "
3464
3563
    and it will never be updated anyway. */
3465
3564
 
3466
3565
    if (key_used_on_scan != MAX_KEY) {
3467
 
      errmsg_printf(error::WARN, 
 
3566
      errmsg_printf(ERRMSG_LVL_WARN, 
3468
3567
        "Table %s key_used_on_scan is %lu even "
3469
3568
        "though there is no primary key inside "
3470
3569
        "InnoDB.", identifier.getTableName().c_str(), (ulong) key_used_on_scan);
3616
3715
of this function is in rem0cmp.c in InnoDB source code! If you change this
3617
3716
function, remember to update the prototype there!
3618
3717
@return 1, 0, -1, if a is greater, equal, less than b, respectively */
3619
 
UNIV_INTERN int
 
3718
extern "C" UNIV_INTERN
 
3719
int
3620
3720
innobase_mysql_cmp(
3621
3721
/*===============*/
3622
3722
  int   mysql_type, /*!< in: MySQL type */
3663
3763
      charset = get_charset(charset_number);
3664
3764
 
3665
3765
      if (charset == NULL) {
3666
 
        errmsg_printf(error::ERROR, "InnoDB needs charset %lu for doing "
 
3766
        errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB needs charset %lu for doing "
3667
3767
                      "a comparison, but MySQL cannot "
3668
3768
                      "find that charset.",
3669
3769
                      (ulong) charset_number);
3698
3798
the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1
3699
3799
VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'.
3700
3800
@return DATA_BINARY, DATA_VARCHAR, ... */
3701
 
UNIV_INTERN
 
3801
extern "C" UNIV_INTERN
3702
3802
ulint
3703
3803
get_innobase_type_from_mysql_type(
3704
3804
/*==============================*/
3747
3847
      return(DATA_VARMYSQL);
3748
3848
    }
3749
3849
  case DRIZZLE_TYPE_DECIMAL:
3750
 
  case DRIZZLE_TYPE_MICROTIME:
3751
3850
    return(DATA_FIXBINARY);
3752
3851
  case DRIZZLE_TYPE_LONG:
3753
3852
  case DRIZZLE_TYPE_LONGLONG:
3754
3853
  case DRIZZLE_TYPE_DATETIME:
3755
 
  case DRIZZLE_TYPE_TIME:
3756
3854
  case DRIZZLE_TYPE_DATE:
3757
3855
  case DRIZZLE_TYPE_TIMESTAMP:
3758
 
  case DRIZZLE_TYPE_ENUM:
3759
3856
    return(DATA_INT);
3760
3857
  case DRIZZLE_TYPE_DOUBLE:
3761
3858
    return(DATA_DOUBLE);
3762
3859
  case DRIZZLE_TYPE_BLOB:
3763
3860
    return(DATA_BLOB);
3764
 
  case DRIZZLE_TYPE_BOOLEAN:
3765
 
  case DRIZZLE_TYPE_UUID:
3766
 
    return(DATA_FIXBINARY);
3767
 
  case DRIZZLE_TYPE_NULL:
 
3861
  default:
3768
3862
    ut_error;
3769
3863
  }
3770
3864
 
4189
4283
    n_requested_fields++;
4190
4284
 
4191
4285
    templ->col_no = i;
4192
 
    templ->clust_rec_field_no = dict_col_get_clust_pos(col, clust_index);
4193
 
    ut_ad(templ->clust_rec_field_no != ULINT_UNDEFINED);
4194
4286
 
4195
4287
    if (index == clust_index) {
4196
 
      templ->rec_field_no = templ->clust_rec_field_no;
 
4288
      templ->rec_field_no = dict_col_get_clust_pos(col, index);
4197
4289
    } else {
4198
4290
      templ->rec_field_no = dict_index_get_nth_col_pos(
4199
4291
                index, i);
4200
 
      if (templ->rec_field_no == ULINT_UNDEFINED) {
4201
 
        prebuilt->need_to_access_clustered = TRUE;
4202
 
      }
 
4292
    }
 
4293
 
 
4294
    if (templ->rec_field_no == ULINT_UNDEFINED) {
 
4295
      prebuilt->need_to_access_clustered = TRUE;
4203
4296
    }
4204
4297
 
4205
4298
    if (field->null_ptr) {
4249
4342
    for (i = 0; i < n_requested_fields; i++) {
4250
4343
      templ = prebuilt->mysql_template + i;
4251
4344
 
4252
 
      templ->rec_field_no = templ->clust_rec_field_no;
 
4345
      templ->rec_field_no = dict_col_get_clust_pos(
 
4346
        &index->table->cols[templ->col_no],
 
4347
        clust_index);
4253
4348
    }
4254
4349
  }
4255
4350
}
4323
4418
  trx_t*    trx = session_to_trx(user_session);
4324
4419
 
4325
4420
  if (prebuilt->trx != trx) {
4326
 
    errmsg_printf(error::ERROR, "The transaction object for the table handle is at "
 
4421
    errmsg_printf(ERRMSG_LVL_ERROR, "The transaction object for the table handle is at "
4327
4422
        "%p, but for the current thread it is at %p",
4328
4423
        (const void*) prebuilt->trx, (const void*) trx);
4329
4424
 
4337
4432
    ut_error;
4338
4433
  }
4339
4434
 
4340
 
  sql_command = user_session->getSqlCommand();
 
4435
  sql_command = session_sql_command(user_session);
4341
4436
 
4342
4437
  if ((sql_command == SQLCOM_ALTER_TABLE
4343
4438
       || sql_command == SQLCOM_CREATE_INDEX
4784
4879
  if (error == DB_SUCCESS
4785
4880
      && getTable()->next_number_field
4786
4881
      && new_row == getTable()->getInsertRecord()
4787
 
      && user_session->getSqlCommand() == SQLCOM_INSERT
 
4882
      && session_sql_command(user_session) == SQLCOM_INSERT
4788
4883
      && (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
4789
4884
    == TRX_DUP_IGNORE)  {
4790
4885
 
5251
5346
         table. Only print message if the index translation
5252
5347
         table exists */
5253
5348
      if (share->idx_trans_tbl.index_mapping) {
5254
 
        errmsg_printf(error::ERROR,
 
5349
        errmsg_printf(ERRMSG_LVL_ERROR,
5255
5350
                      "InnoDB could not find "
5256
5351
                      "index %s key no %u for "
5257
5352
                      "table %s through its "
5269
5364
  }
5270
5365
 
5271
5366
  if (!index) {
5272
 
    errmsg_printf(error::ERROR, 
 
5367
    errmsg_printf(ERRMSG_LVL_ERROR, 
5273
5368
      "Innodb could not find key n:o %u with name %s "
5274
5369
      "from dict cache for table %s",
5275
 
      keynr, getTable()->getShare()->getTableMessage()->indexes(keynr).name().c_str(),
 
5370
      keynr, getTable()->getShare()->getTableProto()->indexes(keynr).name().c_str(),
5276
5371
      prebuilt->table->name);
5277
5372
  }
5278
5373
 
5298
5393
  prebuilt->index = innobase_get_index(keynr);
5299
5394
 
5300
5395
  if (UNIV_UNLIKELY(!prebuilt->index)) {
5301
 
    errmsg_printf(error::WARN, "InnoDB: change_active_index(%u) failed",
 
5396
    errmsg_printf(ERRMSG_LVL_WARN, "InnoDB: change_active_index(%u) failed",
5302
5397
          keynr);
5303
5398
    prebuilt->index_usable = FALSE;
5304
5399
    return(1);
5664
5759
  table. */
5665
5760
 
5666
5761
  if (len != ref_length) {
5667
 
    errmsg_printf(error::ERROR, "Stored ref len is %lu, but table ref len is %lu",
 
5762
    errmsg_printf(ERRMSG_LVL_ERROR, "Stored ref len is %lu, but table ref len is %lu",
5668
5763
        (ulong) len, (ulong) ref_length);
5669
5764
  }
5670
5765
}
5723
5818
 
5724
5819
    if (!col_type) {
5725
5820
      push_warning_printf(
5726
 
                          trx->mysql_thd,
 
5821
                          (Session*) trx->mysql_thd,
5727
5822
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
5728
5823
                          ER_CANT_CREATE_TABLE,
5729
5824
                          "Error creating table '%s' with "
5757
5852
        /* in data0type.h we assume that the
5758
5853
        number fits in one byte in prtype */
5759
5854
        push_warning_printf(
5760
 
          trx->mysql_thd,
 
5855
          (Session*) trx->mysql_thd,
5761
5856
          DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5762
5857
          ER_CANT_CREATE_TABLE,
5763
5858
          "In InnoDB, charset-collation codes"
5923
6018
        || col_type == DATA_FLOAT
5924
6019
        || col_type == DATA_DOUBLE
5925
6020
        || col_type == DATA_DECIMAL) {
5926
 
        errmsg_printf(error::ERROR, 
 
6021
        errmsg_printf(ERRMSG_LVL_ERROR, 
5927
6022
          "MySQL is trying to create a column "
5928
6023
          "prefix index field, on an "
5929
6024
          "inappropriate data type. Table "
6023
6118
/*================*/
6024
6119
  Session         &session, /*!< in: Session */
6025
6120
  Table&    form,   /*!< in: information on table columns and indexes */
6026
 
        const identifier::Table &identifier,
 
6121
        const TableIdentifier &identifier,
6027
6122
        message::Table& create_proto)
6028
6123
{
6029
6124
  int   error;
6032
6127
  trx_t*    trx;
6033
6128
  int   primary_key_no;
6034
6129
  uint    i;
 
6130
  char    name2[FN_REFLEN];
 
6131
  char    norm_name[FN_REFLEN];
6035
6132
  ib_int64_t  auto_inc_value;
6036
6133
  ulint   iflags;
6037
6134
  /* Cache the value of innodb_file_format, in case it is
6041
6138
  const char* stmt;
6042
6139
  size_t stmt_len;
6043
6140
 
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
 
  }
 
6141
  const char *table_name= identifier.getPath().c_str();
6051
6142
 
6052
6143
  if (form.getShare()->sizeFields() > 1000) {
6053
6144
    /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
6070
6161
 
6071
6162
  srv_lower_case_table_names = TRUE;
6072
6163
 
 
6164
  strcpy(name2, table_name);
 
6165
 
 
6166
  normalize_table_name(norm_name, name2);
 
6167
 
6073
6168
  /* Latch the InnoDB data dictionary exclusively so that no deadlocks
6074
6169
    or lock waits can happen in it during a table create operation.
6075
6170
    Drop table etc. do this latching in row0mysql.c. */
6177
6272
  if (lex_identified_temp_table)
6178
6273
    iflags |= DICT_TF2_TEMPORARY << DICT_TF2_SHIFT;
6179
6274
 
6180
 
  error= create_table_def(trx, &form, identifier.getKeyPath().c_str(),
6181
 
                          lex_identified_temp_table ? identifier.getKeyPath().c_str() : NULL,
 
6275
  error= create_table_def(trx, &form, norm_name,
 
6276
                          lex_identified_temp_table ? name2 : NULL,
6182
6277
                          iflags);
6183
6278
 
6184
6279
  session.setXaId(trx->id);
6194
6289
      order the rows by their row id which is internally generated
6195
6290
      by InnoDB */
6196
6291
 
6197
 
    error = create_clustered_index_when_no_primary(trx, iflags, identifier.getKeyPath().c_str());
 
6292
    error = create_clustered_index_when_no_primary(trx, iflags, norm_name);
6198
6293
    if (error) {
6199
6294
      goto cleanup;
6200
6295
    }
6202
6297
 
6203
6298
  if (primary_key_no != -1) {
6204
6299
    /* In InnoDB the clustered index must always be created first */
6205
 
    if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
 
6300
    if ((error = create_index(trx, &form, iflags, norm_name,
6206
6301
                              (uint) primary_key_no))) {
6207
6302
      goto cleanup;
6208
6303
    }
6211
6306
  for (i = 0; i < form.getShare()->sizeKeys(); i++) {
6212
6307
    if (i != (uint) primary_key_no) {
6213
6308
 
6214
 
      if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
 
6309
      if ((error = create_index(trx, &form, iflags, norm_name,
6215
6310
                                i))) {
6216
6311
        goto cleanup;
6217
6312
      }
6218
6313
    }
6219
6314
  }
6220
6315
 
6221
 
  stmt= session.getQueryStringCopy(stmt_len);
 
6316
  stmt = innobase_get_stmt(&session, &stmt_len);
6222
6317
 
6223
6318
  if (stmt) {
6224
6319
    string generated_create_table;
6225
6320
    const char *query= stmt;
6226
6321
 
6227
 
    if (session.getSqlCommand() == SQLCOM_CREATE_TABLE)
 
6322
    if (session_sql_command(&session) == SQLCOM_CREATE_TABLE)
6228
6323
    {
6229
6324
      message::transformTableDefinitionToSql(create_proto,
6230
6325
                                             generated_create_table,
6234
6329
 
6235
6330
    error = row_table_add_foreign_constraints(trx,
6236
6331
                                              query, strlen(query),
6237
 
                                              identifier.getKeyPath().c_str(),
 
6332
                                              norm_name,
6238
6333
                                              lex_identified_temp_table);
6239
 
    switch (error) {
6240
 
 
6241
 
    case DB_PARENT_NO_INDEX:
6242
 
      push_warning_printf(
6243
 
                          &session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6244
 
                          HA_ERR_CANNOT_ADD_FOREIGN,
6245
 
                          "Create table '%s' with foreign key constraint"
6246
 
                          " failed. There is no index in the referenced"
6247
 
                          " table where the referenced columns appear"
6248
 
                          " as the first columns.\n", identifier.getKeyPath().c_str());
6249
 
      break;
6250
 
 
6251
 
    case DB_CHILD_NO_INDEX:
6252
 
      push_warning_printf(
6253
 
                          &session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6254
 
                          HA_ERR_CANNOT_ADD_FOREIGN,
6255
 
                          "Create table '%s' with foreign key constraint"
6256
 
                          " failed. There is no index in the referencing"
6257
 
                          " table where referencing columns appear"
6258
 
                          " as the first columns.\n", identifier.getKeyPath().c_str());
6259
 
      break;
6260
 
    }
6261
6334
 
6262
6335
    error = convert_error_code_to_mysql(error, iflags, NULL);
6263
6336
 
6276
6349
 
6277
6350
  log_buffer_flush_to_disk();
6278
6351
 
6279
 
  innobase_table = dict_table_get(identifier.getKeyPath().c_str(), FALSE);
 
6352
  innobase_table = dict_table_get(norm_name, FALSE);
6280
6353
 
6281
6354
  assert(innobase_table != 0);
6282
6355
 
6299
6372
    does a table copy too. */
6300
6373
 
6301
6374
  if ((create_proto.options().has_auto_increment_value()
6302
 
       || session.getSqlCommand() == SQLCOM_ALTER_TABLE
6303
 
       || session.getSqlCommand() == SQLCOM_CREATE_INDEX)
 
6375
       || session_sql_command(&session) == SQLCOM_ALTER_TABLE
 
6376
       || session_sql_command(&session) == SQLCOM_CREATE_INDEX)
6304
6377
      && create_proto.options().auto_increment_value() != 0) {
6305
6378
 
6306
6379
    /* Query was one of :
6393
6466
 
6394
6467
  update_session(getTable()->in_use);
6395
6468
 
6396
 
  if (user_session->getSqlCommand() != SQLCOM_TRUNCATE) {
 
6469
  if (session_sql_command(user_session) != SQLCOM_TRUNCATE) {
6397
6470
  fallback:
6398
6471
    /* We only handle TRUNCATE TABLE t as a special case.
6399
6472
    DELETE FROM t will have to use ha_innobase::doDeleteRecord(),
6427
6500
InnobaseEngine::doDropTable(
6428
6501
/*======================*/
6429
6502
        Session &session,
6430
 
        const identifier::Table &identifier)
 
6503
        const TableIdentifier &identifier)
6431
6504
{
6432
6505
  int error;
6433
6506
  trx_t*  parent_trx;
6434
6507
  trx_t*  trx;
 
6508
  char  norm_name[1000];
6435
6509
 
6436
6510
  ut_a(identifier.getPath().length() < 1000);
6437
6511
 
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
 
  }
 
6512
  /* Strangely, MySQL passes the table name without the '.frm'
 
6513
    extension, in contrast to ::create */
 
6514
  normalize_table_name(norm_name, identifier.getPath().c_str());
6445
6515
 
6446
6516
  /* Get the transaction associated with the current session, or create one
6447
6517
    if not yet created */
6459
6529
 
6460
6530
  /* Drop the table in InnoDB */
6461
6531
 
6462
 
  error = row_drop_table_for_mysql(identifier.getKeyPath().c_str(), trx,
6463
 
                                   session.getSqlCommand()
 
6532
  error = row_drop_table_for_mysql(norm_name, trx,
 
6533
                                   session_sql_command(&session)
6464
6534
                                   == SQLCOM_DROP_DB);
6465
6535
 
6466
6536
  session.setXaId(trx->id);
6488
6558
    if (identifier.getType() == message::Table::TEMPORARY)
6489
6559
    {
6490
6560
      session.getMessageCache().removeTableMessage(identifier);
6491
 
      ulint sql_command = session.getSqlCommand();
 
6561
      ulint sql_command = session_sql_command(&session);
6492
6562
 
6493
6563
      // If this was the final removal to an alter table then we will need
6494
6564
      // to remove the .dfe that was left behind.
6521
6591
bool
6522
6592
InnobaseEngine::doDropSchema(
6523
6593
/*===================*/
6524
 
                             const identifier::Schema &identifier)
 
6594
                             const SchemaIdentifier &identifier)
6525
6595
    /*!< in: database path; inside InnoDB the name
6526
6596
      of the last directory in the path is used as
6527
6597
      the database name: for example, in 'mysql/data/test'
6571
6641
 
6572
6642
void InnobaseEngine::dropTemporarySchema()
6573
6643
{
6574
 
  identifier::Schema schema_identifier(GLOBAL_TEMPORARY_EXT);
 
6644
  SchemaIdentifier schema_identifier(GLOBAL_TEMPORARY_EXT);
6575
6645
  trx_t*  trx= NULL;
6576
6646
  string schema_path(GLOBAL_TEMPORARY_EXT);
6577
6647
 
6608
6678
innobase_rename_table(
6609
6679
/*==================*/
6610
6680
  trx_t*    trx,  /*!< in: transaction */
6611
 
  const identifier::Table &from,
6612
 
  const identifier::Table &to,
 
6681
  const char* from, /*!< in: old name of the table */
 
6682
  const char* to, /*!< in: new name of the table */
6613
6683
  ibool   lock_and_commit)
6614
6684
        /*!< in: TRUE=lock data dictionary and commit */
6615
6685
{
6616
6686
  int error;
 
6687
  char norm_to[FN_REFLEN];
 
6688
  char norm_from[FN_REFLEN];
6617
6689
 
6618
6690
  srv_lower_case_table_names = TRUE;
6619
6691
 
 
6692
  normalize_table_name(norm_to, to);
 
6693
  normalize_table_name(norm_from, from);
 
6694
 
6620
6695
  /* Serialize data dictionary operations with dictionary mutex:
6621
6696
  no deadlocks can occur then in these operations */
6622
6697
 
6624
6699
    row_mysql_lock_data_dictionary(trx);
6625
6700
  }
6626
6701
 
6627
 
  error = row_rename_table_for_mysql(from.getKeyPath().c_str(), to.getKeyPath().c_str(), trx, lock_and_commit);
 
6702
  error = row_rename_table_for_mysql(
 
6703
    norm_from, norm_to, trx, lock_and_commit);
6628
6704
 
6629
6705
  if (error != DB_SUCCESS) {
6630
6706
    FILE* ef = dict_foreign_err_file;
6631
6707
 
6632
6708
    fputs("InnoDB: Renaming table ", ef);
6633
 
    ut_print_name(ef, trx, TRUE, from.getKeyPath().c_str());
 
6709
    ut_print_name(ef, trx, TRUE, norm_from);
6634
6710
    fputs(" to ", ef);
6635
 
    ut_print_name(ef, trx, TRUE, to.getKeyPath().c_str());
 
6711
    ut_print_name(ef, trx, TRUE, norm_to);
6636
6712
    fputs(" failed!\n", ef);
6637
6713
  }
6638
6714
 
6651
6727
/*********************************************************************//**
6652
6728
Renames an InnoDB table.
6653
6729
@return 0 or error code */
6654
 
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, const identifier::Table &from, const identifier::Table &to)
 
6730
UNIV_INTERN int InnobaseEngine::doRenameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
6655
6731
{
6656
6732
  // A temp table alter table/rename is a shallow rename and only the
6657
6733
  // definition needs to be updated.
6677
6753
 
6678
6754
  trx = innobase_trx_allocate(&session);
6679
6755
 
6680
 
  error = innobase_rename_table(trx, from, to, TRUE);
 
6756
  error = innobase_rename_table(trx, from.getPath().c_str(), to.getPath().c_str(), TRUE);
6681
6757
 
6682
6758
  session.setXaId(trx->id);
6683
6759
 
6702
6778
     is the one we are trying to rename to) and return the generic
6703
6779
     error code. */
6704
6780
  if (error == (int) DB_DUPLICATE_KEY) {
6705
 
    my_error(ER_TABLE_EXISTS_ERROR, to);
 
6781
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to.getPath().c_str());
6706
6782
    error = DB_ERROR;
6707
6783
  }
6708
6784
 
6733
6809
  KeyInfo*    key;
6734
6810
  dict_index_t* index;
6735
6811
  unsigned char*    key_val_buff2 = (unsigned char*) malloc(
6736
 
              getTable()->getShare()->sizeStoredRecord()
 
6812
              getTable()->getShare()->stored_rec_length
6737
6813
          + getTable()->getShare()->max_key_length + 100);
6738
 
  ulint   buff2_len = getTable()->getShare()->sizeStoredRecord()
 
6814
  ulint   buff2_len = getTable()->getShare()->stored_rec_length
6739
6815
          + getTable()->getShare()->max_key_length + 100;
6740
6816
  dtuple_t* range_start;
6741
6817
  dtuple_t* range_end;
6845
6921
  dict_index_t* index;
6846
6922
  uint64_t  estimate;
6847
6923
  uint64_t  local_data_file_length;
6848
 
  ulint stat_n_leaf_pages;
6849
6924
 
6850
6925
  /* We do not know if MySQL can call this function before calling
6851
6926
  external_lock(). To be safe, update the session of the current table
6863
6938
 
6864
6939
  index = dict_table_get_first_index(prebuilt->table);
6865
6940
 
6866
 
  stat_n_leaf_pages = index->stat_n_leaf_pages;
6867
 
 
6868
 
  ut_a(stat_n_leaf_pages > 0);
 
6941
  ut_a(index->stat_n_leaf_pages > 0);
6869
6942
 
6870
6943
  local_data_file_length =
6871
 
    ((uint64_t) stat_n_leaf_pages) * UNIV_PAGE_SIZE;
 
6944
    ((uint64_t) index->stat_n_leaf_pages) * UNIV_PAGE_SIZE;
6872
6945
 
6873
6946
 
6874
6947
  /* Calculate a minimum length for a clustered index record and from
7018
7091
 
7019
7092
                /* Print an error message if we cannot find the index
7020
7093
                ** in the "index translation table". */
7021
 
                errmsg_printf(error::ERROR,
 
7094
                errmsg_printf(ERRMSG_LVL_ERROR,
7022
7095
                              "Cannot find index %s in InnoDB index "
7023
7096
                                "translation table.", index->name);
7024
7097
        }
7035
7108
                }
7036
7109
        }
7037
7110
 
7038
 
                errmsg_printf(error::ERROR,
 
7111
                errmsg_printf(ERRMSG_LVL_ERROR,
7039
7112
                              "Cannot find matching index number for index %s "
7040
7113
                              "in InnoDB index list.", index->name);
7041
7114
 
7081
7154
 
7082
7155
    prebuilt->trx->op_info = "updating table statistics";
7083
7156
 
7084
 
    dict_update_statistics(ib_table,
7085
 
                           FALSE /* update even if stats
7086
 
                                    are initialized */);
7087
 
 
 
7157
    dict_update_statistics(ib_table);
7088
7158
 
7089
7159
    prebuilt->trx->op_info = "returning various info to MySQL";
7090
7160
 
7101
7171
  }
7102
7172
 
7103
7173
  if (flag & HA_STATUS_VARIABLE) {
7104
 
 
7105
 
    dict_table_stats_lock(ib_table, RW_S_LATCH);
7106
 
 
7107
7174
    n_rows = ib_table->stat_n_rows;
7108
7175
 
7109
7176
    /* Because we do not protect stat_n_rows by any mutex in a
7131
7198
    n_rows can not be 0 unless the table is empty, set to 1
7132
7199
    instead. The original problem of bug#29507 is actually
7133
7200
    fixed in the server code. */
7134
 
    if (user_session->getSqlCommand() == SQLCOM_TRUNCATE) {
 
7201
    if (session_sql_command(user_session) == SQLCOM_TRUNCATE) {
7135
7202
 
7136
7203
      n_rows = 1;
7137
7204
 
7153
7220
        ib_table->stat_sum_of_other_index_sizes)
7154
7221
          * UNIV_PAGE_SIZE;
7155
7222
 
7156
 
    dict_table_stats_unlock(ib_table, RW_S_LATCH);
7157
 
 
7158
7223
    /* Since fsp_get_available_space_in_free_extents() is
7159
7224
    acquiring latches inside InnoDB, we do not call it if we
7160
7225
    are asked by MySQL to avoid locking. Another reason to
7171
7236
         innodb_crash_recovery is set to a high value. */
7172
7237
      stats.delete_length = 0;
7173
7238
    } else {
7174
 
      ullint    avail_space;
7175
 
 
7176
 
      avail_space = fsp_get_available_space_in_free_extents(ib_table->space);
7177
 
 
7178
 
      if (avail_space == ULLINT_UNDEFINED) {
 
7239
      /* lock the data dictionary to avoid races with
 
7240
      ibd_file_missing and tablespace_discarded */
 
7241
      row_mysql_lock_data_dictionary(prebuilt->trx);
 
7242
 
 
7243
      /* ib_table->space must be an existent tablespace */
 
7244
      if (!ib_table->ibd_file_missing
 
7245
          && !ib_table->tablespace_discarded) {
 
7246
 
 
7247
        stats.delete_length =
 
7248
          fsp_get_available_space_in_free_extents(
 
7249
            ib_table->space) * 1024;
 
7250
      } else {
 
7251
 
7179
7252
        Session*  session;
7180
7253
 
7181
7254
        session= getTable()->in_use;
7193
7266
          ib_table->name);
7194
7267
 
7195
7268
        stats.delete_length = 0;
7196
 
      } else {
7197
 
        stats.delete_length = avail_space * 1024;
7198
7269
      }
 
7270
 
 
7271
      row_mysql_unlock_data_dictionary(prebuilt->trx);
7199
7272
    }
7200
7273
 
7201
7274
    stats.check_time = 0;
7215
7288
    ulint       num_innodb_index = UT_LIST_GET_LEN(ib_table->indexes) - prebuilt->clust_index_was_generated;
7216
7289
 
7217
7290
    if (getTable()->getShare()->keys != num_innodb_index) {
7218
 
      errmsg_printf(error::ERROR, "Table %s contains %lu "
 
7291
      errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains %lu "
7219
7292
                      "indexes inside InnoDB, which "
7220
7293
                      "is different from the number of "
7221
7294
                      "indexes %u defined in the MySQL ",
7223
7296
                      getTable()->getShare()->keys);
7224
7297
    }
7225
7298
 
7226
 
    dict_table_stats_lock(ib_table, RW_S_LATCH);
7227
 
 
7228
7299
    for (i = 0; i < getTable()->getShare()->sizeKeys(); i++) {
7229
7300
      ulong j;
7230
7301
      /* We could get index quickly through internal
7235
7306
      index = innobase_get_index(i);
7236
7307
 
7237
7308
      if (index == NULL) {
7238
 
        errmsg_printf(error::ERROR, "Table %s contains fewer "
 
7309
        errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains fewer "
7239
7310
            "indexes inside InnoDB than "
7240
7311
            "are defined in the MySQL "
7241
7312
            ".frm file. Have you mixed up "
7250
7321
      for (j = 0; j < getTable()->key_info[i].key_parts; j++) {
7251
7322
 
7252
7323
        if (j + 1 > index->n_uniq) {
7253
 
          errmsg_printf(error::ERROR, 
 
7324
          errmsg_printf(ERRMSG_LVL_ERROR, 
7254
7325
"Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking "
7255
7326
"statistics for %lu columns. Have you mixed up .frm files from different "
7256
7327
"installations? "
7262
7333
          break;
7263
7334
        }
7264
7335
 
 
7336
        dict_index_stat_mutex_enter(index);
 
7337
 
7265
7338
        if (index->stat_n_diff_key_vals[j + 1] == 0) {
7266
7339
 
7267
7340
          rec_per_key = stats.records;
7270
7343
           index->stat_n_diff_key_vals[j + 1]);
7271
7344
        }
7272
7345
 
 
7346
        dict_index_stat_mutex_exit(index);
 
7347
 
7273
7348
        /* Since MySQL seems to favor table scans
7274
7349
        too much over index searches, we pretend
7275
7350
        index selectivity is 2 times better than
7286
7361
          (ulong) rec_per_key;
7287
7362
      }
7288
7363
    }
7289
 
 
7290
 
    dict_table_stats_unlock(ib_table, RW_S_LATCH);
7291
7364
  }
7292
7365
 
7293
7366
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
7367
7440
  }
7368
7441
 
7369
7442
  if (prebuilt->table->ibd_file_missing) {
7370
 
        errmsg_printf(error::ERROR, "InnoDB: Error:\n"
 
7443
        errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: Error:\n"
7371
7444
                    "InnoDB: MySQL is trying to use a table handle"
7372
7445
                    " but the .ibd file for\n"
7373
7446
                    "InnoDB: table %s does not exist.\n"
7617
7690
  flen = ftell(srv_dict_tmpfile);
7618
7691
  if (flen < 0) {
7619
7692
    flen = 0;
 
7693
  } else if (flen > 64000 - 1) {
 
7694
    flen = 64000 - 1;
7620
7695
  }
7621
7696
 
7622
7697
  /* allocate buffer for the string, and
7676
7751
      i++;
7677
7752
    }
7678
7753
    db_name[i] = 0;
7679
 
    ulen= identifier::Table::filename_to_tablename(db_name, uname, sizeof(uname));
 
7754
    ulen= TableIdentifier::filename_to_tablename(db_name, uname, sizeof(uname));
7680
7755
    LEX_STRING *tmp_referenced_db = session->make_lex_string(NULL, uname, ulen, true);
7681
7756
 
7682
7757
    /* Table name */
7683
7758
    tmp_buff += i + 1;
7684
 
    ulen= identifier::Table::filename_to_tablename(tmp_buff, uname, sizeof(uname));
 
7759
    ulen= TableIdentifier::filename_to_tablename(tmp_buff, uname, sizeof(uname));
7685
7760
    LEX_STRING *tmp_referenced_table = session->make_lex_string(NULL, uname, ulen, true);
7686
7761
 
7687
7762
    /** Foreign Fields **/
7759
7834
                              tmp_foreign_fields, tmp_referenced_fields);
7760
7835
 
7761
7836
    ForeignKeyInfo *pf_key_info = (ForeignKeyInfo *)
7762
 
      session->getMemRoot()->duplicate(&f_key_info, sizeof(ForeignKeyInfo));
 
7837
      session->memdup(&f_key_info, sizeof(ForeignKeyInfo));
7763
7838
    f_key_list->push_back(pf_key_info);
7764
7839
    foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
7765
7840
  }
8289
8364
static INNOBASE_SHARE* get_share(const char* table_name)
8290
8365
{
8291
8366
  INNOBASE_SHARE *share;
8292
 
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
 
8367
  pthread_mutex_lock(&innobase_share_mutex);
8293
8368
 
8294
8369
  ulint fold = ut_fold_string(table_name);
8295
8370
 
8316
8391
  }
8317
8392
 
8318
8393
  share->use_count++;
 
8394
  pthread_mutex_unlock(&innobase_share_mutex);
8319
8395
 
8320
8396
  return(share);
8321
8397
}
8322
8398
 
8323
8399
static void free_share(INNOBASE_SHARE* share)
8324
8400
{
8325
 
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
 
8401
  pthread_mutex_lock(&innobase_share_mutex);
8326
8402
 
8327
8403
#ifdef UNIV_DEBUG
8328
8404
  INNOBASE_SHARE* share2;
8351
8427
    /* TODO: invoke HASH_MIGRATE if innobase_open_tables
8352
8428
    shrinks too much */
8353
8429
  }
 
8430
 
 
8431
  pthread_mutex_unlock(&innobase_share_mutex);
8354
8432
}
8355
8433
 
8356
8434
/*****************************************************************//**
8385
8463
  trx = check_trx_exists(session);
8386
8464
 
8387
8465
  assert(EQ_CURRENT_SESSION(session));
8388
 
  const uint32_t sql_command = session->getSqlCommand();
 
8466
  const uint32_t sql_command = session_sql_command(session);
8389
8467
 
8390
8468
  if (sql_command == SQLCOM_DROP_TABLE) {
8391
8469
 
8471
8549
 
8472
8550
    if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
8473
8551
         && lock_type <= TL_WRITE)
8474
 
        && ! session->doing_tablespace_operation()
 
8552
        && !session_tablespace_op(session)
8475
8553
        && sql_command != SQLCOM_TRUNCATE
8476
8554
        && sql_command != SQLCOM_CREATE_TABLE) {
8477
8555
 
8548
8626
 
8549
8627
  if (auto_inc == 0) {
8550
8628
    ut_print_timestamp(stderr);
8551
 
    errmsg_printf(error::ERROR, "  InnoDB: AUTOINC next value generation is disabled for '%s'\n", innodb_table->name);
 
8629
    fprintf(stderr, "  InnoDB: AUTOINC next value generation "
 
8630
            "is disabled for '%s'\n", innodb_table->name);
8552
8631
  }
8553
8632
 
8554
8633
  dict_table_autoinc_unlock(innodb_table);
8703
8782
/* See comment in Cursor.cc */
8704
8783
UNIV_INTERN
8705
8784
bool
8706
 
InnobaseEngine::get_error_message(int, String *buf) const
 
8785
InnobaseEngine::get_error_message(int, String *buf)
8707
8786
{
8708
8787
  trx_t*  trx = check_trx_exists(current_session);
8709
8788
 
8787
8866
finds charset information and returns length of prefix_len characters in the
8788
8867
index field in bytes.
8789
8868
@return number of bytes occupied by the first n characters */
 
8869
extern "C" UNIV_INTERN
 
8870
ulint
 
8871
innobase_get_at_most_n_mbchars(
 
8872
/*===========================*/
 
8873
  ulint charset_id, /*!< in: character set id */
 
8874
  ulint prefix_len, /*!< in: prefix length in bytes of the index
 
8875
        (this has to be divided by mbmaxlen to get the
 
8876
        number of CHARACTERS n in the prefix) */
 
8877
  ulint data_len,   /*!< in: length of the string in bytes */
 
8878
  const char* str); /*!< in: character string */
8790
8879
 
8791
8880
ulint
8792
8881
innobase_get_at_most_n_mbchars(
8870
8959
  trx->detailed_error[0]= '\0';
8871
8960
 
8872
8961
  /* Set the isolation level of the transaction. */
8873
 
  trx->isolation_level= innobase_map_isolation_level(session->getTxIsolation());
 
8962
  trx->isolation_level= innobase_map_isolation_level(session_tx_isolation(session));
8874
8963
}
8875
8964
 
8876
8965
void
8913
9002
    return(0);
8914
9003
  }
8915
9004
 
8916
 
  session->get_xid(reinterpret_cast<DrizzleXid*>(&trx->xid));
 
9005
  session->get_xid(reinterpret_cast<DRIZZLE_XID*>(&trx->xid));
8917
9006
 
8918
9007
  /* Release a possible FIFO ticket and search latch. Since we will
8919
9008
  reserve the kernel mutex, we have to release the search system latch
9138
9227
          "Purge threads can be either 0 or 1. Defalut is 0.");
9139
9228
  context("file-per-table",
9140
9229
          po::value<bool>(&srv_file_per_table)->default_value(false)->zero_tokens(),
9141
 
           "Stores each InnoDB table to an .ibd file in the database dir.");
 
9230
          "Stores each InnoDB table to an .ibd file in the database dir.");
 
9231
  context("file-format",
 
9232
          po::value<string>(&innobase_file_format_name)->default_value("Antelope"),
 
9233
          "File format to use for new tables in .ibd files.");
9142
9234
  context("file-format-max",
9143
9235
          po::value<string>(&innobase_file_format_max)->default_value("Antelope"),
9144
9236
          "The highest file format in the tablespace.");
9145
9237
  context("file-format-check",
9146
9238
          po::value<bool>(&innobase_file_format_check)->default_value(true)->zero_tokens(),
9147
9239
          "Whether to perform system file format check.");
9148
 
  context("file-format",
9149
 
          po::value<string>(&innobase_file_format_name)->default_value("Antelope"),
9150
 
          "File format to use for new tables in .ibd files.");
9151
9240
  context("flush-log-at-trx-commit",
9152
9241
          po::value<trinary_constraint>(&innodb_flush_log_at_trx_commit)->default_value(1),
9153
9242
          "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).");
9182
9271
          po::value<additional_mem_pool_constraint>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
9183
9272
          "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.");
9184
9273
  context("autoextend-increment",
9185
 
          po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(64L),
 
9274
          po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(8L),
9186
9275
          "Data file autoextend increment in megabytes");
9187
9276
  context("buffer-pool-size",
9188
9277
          po::value<buffer_pool_constraint>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
9241
9330
          "InnoDB version");
9242
9331
  context("use-internal-malloc",
9243
9332
          "Use InnoDB's internal memory allocator instal of the OS memory allocator.");
9244
 
  context("disable-native-aio",
9245
 
          _("Do not use Native AIO library for IO, even if available"));
9246
9333
  context("change-buffering",
9247
9334
          po::value<string>(&innobase_change_buffering),
9248
9335
          "Buffer changes to reduce random access: OFF, ON, inserting, deleting, changing, or purging.");
9283
9370
  "Supports transactions, row-level locking, and foreign keys",
9284
9371
  PLUGIN_LICENSE_GPL,
9285
9372
  innobase_init, /* Plugin Init */
9286
 
  NULL, /* depends */
 
9373
  NULL, /* system variables */
9287
9374
  init_options /* reserved */
9288
9375
}
9289
9376
DRIZZLE_DECLARE_PLUGIN_END;
9315
9402
This function checks each index name for a table against reserved
9316
9403
system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
9317
9404
this function pushes an warning message to the client, and returns true. */
9318
 
UNIV_INTERN
 
9405
extern "C" UNIV_INTERN
9319
9406
bool
9320
9407
innobase_index_name_is_reserved(
9321
9408
/*============================*/
9335
9422
    if (innobase_strcasecmp(key->name,
9336
9423
                            innobase_index_reserve_name) == 0) {
9337
9424
      /* Push warning to drizzle */
9338
 
      push_warning_printf(trx->mysql_thd,
 
9425
      push_warning_printf((Session*)trx->mysql_thd,
9339
9426
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
9340
9427
                          ER_WRONG_NAME_FOR_INDEX,
9341
9428
                          "Cannot Create Index with name "
9361
9448
  ulint   buflen;
9362
9449
  const char* id;
9363
9450
  ulint   idlen;
9364
 
  drizzled::Session *session;
 
9451
  void*   session;
9365
9452
  ibool   file_id;
9366
9453
 
9367
9454
  const char* expected;