~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2011-02-03 18:12:09 UTC
  • mfrom: (2134.1.9 timestamp)
  • mto: This revision was merged to the branch mainline in revision 2140.
  • Revision ID: brian@tangent.org-20110203181209-xr7i2079pdmu33hd
Merge in table tree.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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/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"
68
68
 
69
69
#include <drizzled/transaction_services.h>
70
 
#include <drizzled/message/statement_transform.h>
 
70
#include "drizzled/message/statement_transform.h"
71
71
 
72
72
#include <boost/algorithm/string.hpp>
73
73
#include <boost/program_options.hpp>
114
114
#include "ha_prototypes.h"
115
115
#include "ut0mem.h"
116
116
#include "ibuf0ibuf.h"
 
117
#include "mysql_addons.h"
117
118
 
118
119
#include "ha_innodb.h"
119
120
#include "data_dictionary.h"
125
126
#include <sstream>
126
127
#include <string>
127
128
 
128
 
#include <plugin/innobase/handler/status_function.h>
129
 
#include <plugin/innobase/handler/replication_log.h>
 
129
#include "plugin/innobase/handler/status_function.h"
 
130
#include "plugin/innobase/handler/replication_log.h"
130
131
 
131
132
#include <google/protobuf/io/zero_copy_stream.h>
132
133
#include <google/protobuf/io/zero_copy_stream_impl.h>
133
134
#include <google/protobuf/io/coded_stream.h>
134
135
#include <google/protobuf/text_format.h>
135
136
 
136
 
#include <boost/thread/mutex.hpp>
137
 
 
138
137
using namespace std;
139
138
using namespace drizzled;
140
139
 
141
140
/** to protect innobase_open_files */
142
 
static boost::mutex innobase_share_mutex;
143
 
 
 
141
static pthread_mutex_t innobase_share_mutex;
144
142
/** to force correct commit order in binlog */
 
143
static pthread_mutex_t prepare_commit_mutex;
145
144
static ulong commit_threads = 0;
146
 
static boost::condition_variable commit_cond;
147
 
static boost::mutex commit_cond_m;
 
145
static pthread_mutex_t commit_threads_m;
 
146
static pthread_cond_t commit_cond;
 
147
static pthread_mutex_t commit_cond_m;
148
148
static bool innodb_inited = 0;
149
149
 
150
150
#define INSIDE_HA_INNOBASE_CC
160
160
#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
161
161
 
162
162
static plugin::XaStorageEngine* innodb_engine_ptr= NULL;
163
 
 
 
163
static plugin::TableFunction* status_table_function_ptr= NULL;
 
164
static plugin::TableFunction* cmp_tool= NULL;
 
165
static plugin::TableFunction* cmp_reset_tool= NULL;
 
166
static plugin::TableFunction* cmp_mem_tool= NULL;
 
167
static plugin::TableFunction* cmp_mem_reset_tool= NULL;
 
168
static plugin::TableFunction* innodb_trx_tool= NULL;
 
169
static plugin::TableFunction* innodb_locks_tool= NULL;
 
170
static plugin::TableFunction* innodb_lock_waits_tool= NULL;
 
171
static plugin::TableFunction* innodb_sys_tables_tool= NULL;
 
172
static plugin::TableFunction* innodb_sys_tablestats_tool= NULL;
 
173
 
 
174
static plugin::TableFunction* innodb_sys_indexes_tool= NULL;
 
175
static plugin::TableFunction* innodb_sys_columns_tool= NULL;
 
176
static plugin::TableFunction* innodb_sys_fields_tool= NULL;
 
177
static plugin::TableFunction* innodb_sys_foreign_tool= NULL;
 
178
static plugin::TableFunction* innodb_sys_foreign_cols_tool= NULL;
 
179
 
 
180
static ReplicationLog *replication_logger= NULL;
164
181
typedef constrained_check<uint32_t, UINT32_MAX, 10> open_files_constraint;
165
182
static open_files_constraint innobase_open_files;
166
183
typedef constrained_check<uint32_t, 10, 1> mirrored_log_groups_constraint;
333
350
      srv_free_paths_and_sizes();
334
351
      if (internal_innobase_data_file_path)
335
352
        free(internal_innobase_data_file_path);
 
353
      pthread_mutex_destroy(&innobase_share_mutex);
 
354
      pthread_mutex_destroy(&prepare_commit_mutex);
 
355
      pthread_mutex_destroy(&commit_threads_m);
 
356
      pthread_mutex_destroy(&commit_cond_m);
 
357
      pthread_cond_destroy(&commit_cond);
336
358
    }
337
359
    
338
360
    /* These get strdup'd from vm variables */
466
488
  UNIV_INTERN int doRenameTable(Session&, const identifier::Table &from, const identifier::Table &to);
467
489
  UNIV_INTERN int doDropTable(Session &session, const identifier::Table &identifier);
468
490
 
469
 
  UNIV_INTERN virtual bool get_error_message(int error, String *buf) const;
 
491
  UNIV_INTERN virtual bool get_error_message(int error, String *buf);
470
492
 
471
493
  UNIV_INTERN uint32_t max_supported_keys() const;
472
494
  UNIV_INTERN uint32_t max_supported_key_length() const;
523
545
{
524
546
  CachedDirectory::Entries entries= directory.getEntries();
525
547
 
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
548
  for (CachedDirectory::Entries::iterator entry_iter= entries.begin(); 
536
549
       entry_iter != entries.end(); ++entry_iter)
537
550
  {
574
587
  if (session.getMessageCache().doesTableMessageExist(identifier))
575
588
    return true;
576
589
 
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
590
  if (access(proto_path.c_str(), F_OK))
584
591
  {
585
592
    return false;
599
606
  if (session.getMessageCache().getTableMessage(identifier, table_proto))
600
607
    return EEXIST;
601
608
 
602
 
  if (read_replication_log_table_message(identifier.getTableName().c_str(), &table_proto) == 0)
603
 
    return EEXIST;
604
 
 
605
609
  if (access(proto_path.c_str(), F_OK))
606
610
  {
607
611
    return errno;
802
806
ibool
803
807
thd_is_replication_slave_thread(
804
808
/*============================*/
805
 
  drizzled::Session* ) /*!< in: thread handle (Session*) */
 
809
  void* ) /*!< in: thread handle (Session*) */
806
810
{
807
811
  return false;
808
812
}
876
880
ibool
877
881
thd_has_edited_nontrans_tables(
878
882
/*===========================*/
879
 
  drizzled::Session *session)  /*!< in: thread handle (Session*) */
 
883
  void*   session)  /*!< in: thread handle (Session*) */
880
884
{
881
 
  return((ibool)session->transaction.all.hasModifiedNonTransData());
 
885
  return((ibool)((Session *)session)->transaction.all.hasModifiedNonTransData());
882
886
}
883
887
 
884
888
/******************************************************************//**
888
892
ibool
889
893
thd_is_select(
890
894
/*==========*/
891
 
  const drizzled::Session *session)  /*!< in: thread handle (Session*) */
 
895
  const void* session)  /*!< in: thread handle (Session*) */
892
896
{
893
 
  return(session->getSqlCommand() == SQLCOM_SELECT);
 
897
  return(session_sql_command((const Session*) session) == SQLCOM_SELECT);
894
898
}
895
899
 
896
900
/******************************************************************//**
901
905
ibool
902
906
thd_supports_xa(
903
907
/*============*/
904
 
  drizzled::Session* )  /*!< in: thread handle (Session*), or NULL to query
 
908
  void* )  /*!< in: thread handle (Session*), or NULL to query
905
909
        the global innodb_supports_xa */
906
910
{
907
911
  /* TODO: Add support here for per-session value */
915
919
ulong
916
920
thd_lock_wait_timeout(
917
921
/*==================*/
918
 
  drizzled::Session*)  /*!< in: thread handle (Session*), or NULL to query
 
922
  void*)  /*!< in: thread handle (Session*), or NULL to query
919
923
      the global innodb_lock_wait_timeout */
920
924
{
921
925
  /* TODO: Add support here for per-session value */
930
934
void
931
935
thd_set_lock_wait_time(
932
936
/*===================*/
933
 
        drizzled::Session*      in_session,     /*!< in: thread handle (THD*) */
 
937
        void*   thd,    /*!< in: thread handle (THD*) */
934
938
        ulint   value)  /*!< in: time waited for the lock */
935
939
{
936
 
  if (in_session)
937
 
    in_session->utime_after_lock+= value;
 
940
        if (thd) {
 
941
          static_cast<Session*>(thd)->utime_after_lock+= value;
 
942
        }
938
943
}
939
944
 
940
945
/********************************************************************//**
960
965
  trx_t *trx= session_to_trx(&session);
961
966
 
962
967
  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);
 
968
  ulint error= insert_replication_message(data, message.ByteSize(), trx, trx_id);
969
969
  (void)error;
970
970
 
971
971
  delete[] data;
1076
1076
    tell it also to MySQL so that MySQL knows to empty the
1077
1077
    cached binlog for this transaction */
1078
1078
 
1079
 
    session->markTransactionForRollback(TRUE);
 
1079
    mark_transaction_to_rollback(session, TRUE);
1080
1080
 
1081
1081
    return(HA_ERR_LOCK_DEADLOCK);
1082
1082
 
1085
1085
    latest SQL statement in a lock wait timeout. Previously, we
1086
1086
    rolled back the whole transaction. */
1087
1087
 
1088
 
    session->markTransactionForRollback((bool)row_rollback_on_timeout);
 
1088
    mark_transaction_to_rollback(session, (bool)row_rollback_on_timeout);
1089
1089
 
1090
1090
    return(HA_ERR_LOCK_WAIT_TIMEOUT);
1091
1091
 
1132
1132
    tell it also to MySQL so that MySQL knows to empty the
1133
1133
    cached binlog for this transaction */
1134
1134
 
1135
 
    session->markTransactionForRollback(TRUE);
 
1135
    mark_transaction_to_rollback(session, TRUE);
1136
1136
 
1137
1137
    return(HA_ERR_LOCK_TABLE_FULL);
1138
1138
 
1171
1171
innobase_mysql_print_thd(
1172
1172
/*=====================*/
1173
1173
  FILE* f,    /*!< in: output stream */
1174
 
  drizzled::Session *in_session,  /*!< in: pointer to a Drizzle Session object */
 
1174
  void * in_session,  /*!< in: pointer to a Drizzle Session object */
1175
1175
  uint  )   /*!< in: max query length to print, or 0 to
1176
1176
           use the default max length */
1177
1177
{
1178
 
  drizzled::identifier::User::const_shared_ptr user_identifier(in_session->user());
 
1178
  Session *session= reinterpret_cast<Session *>(in_session);
 
1179
  drizzled::identifier::User::const_shared_ptr user_identifier(session->user());
1179
1180
 
1180
1181
  fprintf(f,
1181
1182
          "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(),
 
1183
          static_cast<uint64_t>(session->getSessionId()),
 
1184
          static_cast<uint64_t>(session->getQueryId()),
 
1185
          glob_hostname,
1185
1186
          user_identifier->address().c_str(),
1186
1187
          user_identifier->username().c_str()
1187
1188
  );
1188
 
  fprintf(f, "\n%s", in_session->getQueryString()->c_str());
 
1189
  fprintf(f, "\n%s", session->getQueryString()->c_str());
1189
1190
  putc('\n', f);
1190
1191
}
1191
1192
 
1268
1269
  my_casedn_str(system_charset_info, a);
1269
1270
}
1270
1271
 
 
1272
/**********************************************************************//**
 
1273
Determines the connection character set.
 
1274
@return connection character set */
 
1275
UNIV_INTERN
 
1276
const void*
 
1277
innobase_get_charset(
 
1278
/*=================*/
 
1279
  void* mysql_session)  /*!< in: MySQL thread handle */
 
1280
{
 
1281
  return static_cast<Session*>(mysql_session)->charset();
 
1282
}
 
1283
 
1271
1284
UNIV_INTERN
1272
1285
bool
1273
1286
innobase_isspace(
1277
1290
  return my_isspace(static_cast<const CHARSET_INFO *>(cs), char_to_test);
1278
1291
}
1279
1292
 
 
1293
UNIV_INTERN
 
1294
int
 
1295
innobase_fast_mutex_init(
 
1296
        os_fast_mutex_t*        fast_mutex)
 
1297
{
 
1298
  return pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
 
1299
}
 
1300
 
 
1301
/**********************************************************************//**
 
1302
Determines the current SQL statement.
 
1303
@return        SQL statement string */
 
1304
UNIV_INTERN
 
1305
const char*
 
1306
innobase_get_stmt(
 
1307
/*==============*/
 
1308
       void*   session,        /*!< in: MySQL thread handle */
 
1309
       size_t* length)         /*!< out: length of the SQL statement */
 
1310
{
 
1311
  return static_cast<Session*>(session)->getQueryStringCopy(*length);
 
1312
}
 
1313
 
1280
1314
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1281
1315
/*******************************************************************//**
1282
1316
Map an OS error to an errno value. The OS error number is stored in
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
{
1717
1751
  ulint   buflen, /*!< in: length of buf, in bytes */
1718
1752
  const char* id, /*!< in: identifier to convert */
1719
1753
  ulint   idlen,  /*!< in: length of id, in bytes */
1720
 
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
 
1754
  void*   session,/*!< in: MySQL connection thread, or NULL */
1721
1755
  ibool   table_id)/*!< in: TRUE=id is a table or database name;
1722
1756
        FALSE=id is an index name */
1723
1757
{
1771
1805
/*===============*/
1772
1806
  trx_t*  trx)  /*!< in: transaction */
1773
1807
{
1774
 
  return(trx && trx->mysql_thd && trx->mysql_thd->getKilled());
 
1808
  return(trx && trx->mysql_thd && static_cast<Session*>(trx->mysql_thd)->getKilled());
1775
1809
}
1776
1810
 
1777
1811
/**********************************************************************//**
2115
2149
  ret = (bool) srv_parse_data_file_paths_and_sizes(
2116
2150
                                                   internal_innobase_data_file_path);
2117
2151
  if (ret == FALSE) {
2118
 
    errmsg_printf(error::ERROR, "InnoDB: syntax error in innodb_data_file_path");
2119
 
 
 
2152
    errmsg_printf(error::ERROR, 
 
2153
                  "InnoDB: syntax error in innodb_data_file_path");
2120
2154
mem_free_and_error:
2121
2155
    srv_free_paths_and_sizes();
2122
2156
    if (internal_innobase_data_file_path)
2141
2175
    srv_parse_log_group_home_dirs((char *)innobase_log_group_home_dir.c_str());
2142
2176
 
2143
2177
  if (ret == FALSE || innobase_mirrored_log_groups.get() != 1) {
2144
 
    errmsg_printf(error::ERROR, _("syntax error in innodb_log_group_home_dir, or a "
2145
 
                                  "wrong number of mirrored log groups"));
 
2178
    errmsg_printf(error::ERROR,
 
2179
                  _("syntax error in innodb_log_group_home_dir, or a "
 
2180
                  "wrong number of mirrored log groups"));
2146
2181
 
2147
2182
    goto mem_free_and_error;
2148
2183
  }
2185
2220
     srv_max_file_format_at_startup */
2186
2221
  if (innobase_file_format_validate_and_set(innobase_file_format_max.c_str()) < 0)
2187
2222
  {
2188
 
    errmsg_printf(error::ERROR, _("InnoDB: invalid innodb_file_format_max value: "
2189
 
                                  "should be any value up to %s or its equivalent numeric id"),
2190
 
                  trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
 
2223
    errmsg_printf(error::ERROR, _("InnoDB: invalid "
 
2224
                    "innodb_file_format_max value: "
 
2225
                    "should be any value up to %s or its "
 
2226
                    "equivalent numeric id"),
 
2227
                    trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
2191
2228
    goto mem_free_and_error;
2192
2229
  }
2193
2230
 
2206
2243
      }
2207
2244
    }
2208
2245
 
2209
 
    errmsg_printf(error::ERROR, "InnoDB: invalid value innodb_change_buffering=%s",
 
2246
    errmsg_printf(error::ERROR,
 
2247
                  "InnoDB: invalid value "
 
2248
                  "innodb_change_buffering=%s",
2210
2249
                  vm["change-buffering"].as<string>().c_str());
2211
2250
    goto mem_free_and_error;
2212
2251
  }
2284
2323
                                                     TRUE);
2285
2324
 
2286
2325
  innobase_open_tables = hash_create(200);
 
2326
  pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
 
2327
  pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
 
2328
  pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
 
2329
  pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
 
2330
  pthread_cond_init(&commit_cond, NULL);
2287
2331
  innodb_inited= 1;
2288
2332
 
2289
2333
  actuall_engine_ptr->dropTemporarySchema();
2290
2334
 
2291
 
  context.add(new InnodbStatusTool);
 
2335
  status_table_function_ptr= new InnodbStatusTool;
2292
2336
 
2293
2337
  context.add(innodb_engine_ptr);
2294
2338
 
2295
 
  context.add(new(std::nothrow)CmpTool(false));
2296
 
 
2297
 
  context.add(new(std::nothrow)CmpTool(true));
2298
 
 
2299
 
  context.add(new(std::nothrow)CmpmemTool(false));
2300
 
 
2301
 
  context.add(new(std::nothrow)CmpmemTool(true));
2302
 
 
2303
 
  context.add(new(std::nothrow)InnodbTrxTool("INNODB_TRX"));
2304
 
 
2305
 
  context.add(new(std::nothrow)InnodbTrxTool("INNODB_LOCKS"));
2306
 
 
2307
 
  context.add(new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS"));
2308
 
 
2309
 
  context.add(new(std::nothrow)InnodbSysTablesTool());
2310
 
 
2311
 
  context.add(new(std::nothrow)InnodbSysTableStatsTool());
2312
 
 
2313
 
  context.add(new(std::nothrow)InnodbSysIndexesTool());
2314
 
 
2315
 
  context.add(new(std::nothrow)InnodbSysColumnsTool());
2316
 
 
2317
 
  context.add(new(std::nothrow)InnodbSysFieldsTool());
2318
 
 
2319
 
  context.add(new(std::nothrow)InnodbSysForeignTool());
2320
 
 
2321
 
  context.add(new(std::nothrow)InnodbSysForeignColsTool());
 
2339
  context.add(status_table_function_ptr);
 
2340
 
 
2341
  cmp_tool= new(std::nothrow)CmpTool(false);
 
2342
  context.add(cmp_tool);
 
2343
 
 
2344
  cmp_reset_tool= new(std::nothrow)CmpTool(true);
 
2345
  context.add(cmp_reset_tool);
 
2346
 
 
2347
  cmp_mem_tool= new(std::nothrow)CmpmemTool(false);
 
2348
  context.add(cmp_mem_tool);
 
2349
 
 
2350
  cmp_mem_reset_tool= new(std::nothrow)CmpmemTool(true);
 
2351
  context.add(cmp_mem_reset_tool);
 
2352
 
 
2353
  innodb_trx_tool= new(std::nothrow)InnodbTrxTool("INNODB_TRX");
 
2354
  context.add(innodb_trx_tool);
 
2355
 
 
2356
  innodb_locks_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCKS");
 
2357
  context.add(innodb_locks_tool);
 
2358
 
 
2359
  innodb_lock_waits_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS");
 
2360
  context.add(innodb_lock_waits_tool);
 
2361
 
 
2362
  innodb_sys_tables_tool= new(std::nothrow)InnodbSysTablesTool();
 
2363
  context.add(innodb_sys_tables_tool);
 
2364
 
 
2365
  innodb_sys_tablestats_tool= new(std::nothrow)InnodbSysTableStatsTool();
 
2366
  context.add(innodb_sys_tablestats_tool);
 
2367
 
 
2368
  innodb_sys_indexes_tool= new(std::nothrow)InnodbSysIndexesTool();
 
2369
  context.add(innodb_sys_indexes_tool);
 
2370
 
 
2371
  innodb_sys_columns_tool= new(std::nothrow)InnodbSysColumnsTool();
 
2372
  context.add(innodb_sys_columns_tool);
 
2373
 
 
2374
  innodb_sys_fields_tool= new(std::nothrow)InnodbSysFieldsTool();
 
2375
  context.add(innodb_sys_fields_tool);
 
2376
 
 
2377
  innodb_sys_foreign_tool= new(std::nothrow)InnodbSysForeignTool();
 
2378
  context.add(innodb_sys_foreign_tool);
 
2379
 
 
2380
  innodb_sys_foreign_cols_tool= new(std::nothrow)InnodbSysForeignColsTool();
 
2381
  context.add(innodb_sys_foreign_cols_tool);
2322
2382
 
2323
2383
  context.add(new(std::nothrow)InnodbInternalTables());
2324
2384
  context.add(new(std::nothrow)InnodbReplicationTable());
2325
2385
 
2326
2386
  if (innobase_use_replication_log)
2327
2387
  {
2328
 
    ReplicationLog *replication_logger= new(std::nothrow)ReplicationLog();
 
2388
    replication_logger= new(std::nothrow)ReplicationLog();
2329
2389
    context.add(replication_logger);
2330
2390
    ReplicationLog::setup(replication_logger);
2331
2391
  }
2416
2476
  btr_search_fully_disabled = (!btr_search_enabled);
2417
2477
 
2418
2478
  return(FALSE);
2419
 
 
2420
2479
error:
2421
2480
  return(TRUE);
2422
2481
}
2521
2580
    /* We need current binlog position for ibbackup to work.
2522
2581
    Note, the position is current because of
2523
2582
    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
 
 
 
2583
retry:
 
2584
    if (innobase_commit_concurrency.get() > 0) {
 
2585
      pthread_mutex_lock(&commit_cond_m);
 
2586
      commit_threads++;
 
2587
 
 
2588
      if (commit_threads > innobase_commit_concurrency.get()) {
2535
2589
        commit_threads--;
2536
 
        commit_cond.wait(scopedLock);
2537
 
      } while (1);
 
2590
        pthread_cond_wait(&commit_cond,
 
2591
          &commit_cond_m);
 
2592
        pthread_mutex_unlock(&commit_cond_m);
 
2593
        goto retry;
 
2594
      }
 
2595
      else {
 
2596
        pthread_mutex_unlock(&commit_cond_m);
 
2597
      }
2538
2598
    }
2539
2599
 
2540
2600
    trx->mysql_log_file_name = NULL;
2547
2607
    innobase_commit_low(trx);
2548
2608
    trx->flush_log_later = FALSE;
2549
2609
 
2550
 
    if (commit_concurrency)
2551
 
    {
2552
 
      boost::mutex::scoped_lock scopedLock(commit_cond_m);
 
2610
    if (innobase_commit_concurrency.get() > 0) {
 
2611
      pthread_mutex_lock(&commit_cond_m);
2553
2612
      commit_threads--;
2554
 
      commit_cond.notify_one();
 
2613
      pthread_cond_signal(&commit_cond);
 
2614
      pthread_mutex_unlock(&commit_cond_m);
2555
2615
    }
2556
2616
 
2557
2617
    /* Now do a write + flush of logs. */
2876
2936
  return(true);
2877
2937
}
2878
2938
 
 
2939
/*****************************************************************//**
 
2940
Normalizes a table name string. A normalized name consists of the
 
2941
database name catenated to '/' and table name. An example:
 
2942
test/mytable. On Windows normalization puts both the database name and the
 
2943
table name always to lower case. */
 
2944
static
 
2945
void
 
2946
normalize_table_name(
 
2947
/*=================*/
 
2948
  char*   norm_name,  /*!< out: normalized name as a
 
2949
          null-terminated string */
 
2950
  const char* name)   /*!< in: table name string */
 
2951
{
 
2952
  const char* name_ptr;
 
2953
  const char* db_ptr;
 
2954
  const char* ptr;
 
2955
 
 
2956
  /* Scan name from the end */
 
2957
 
 
2958
  ptr = strchr(name, '\0')-1;
 
2959
 
 
2960
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
 
2961
    ptr--;
 
2962
  }
 
2963
 
 
2964
  name_ptr = ptr + 1;
 
2965
 
 
2966
  assert(ptr > name);
 
2967
 
 
2968
  ptr--;
 
2969
 
 
2970
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
 
2971
    ptr--;
 
2972
  }
 
2973
 
 
2974
  db_ptr = ptr + 1;
 
2975
 
 
2976
  memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
 
2977
 
 
2978
  norm_name[name_ptr - db_ptr - 1] = '/';
 
2979
 
 
2980
#ifdef __WIN__
 
2981
  innobase_casedn_str(norm_name);
 
2982
#endif
 
2983
}
 
2984
 
2879
2985
/********************************************************************//**
2880
2986
Get the upper limit of the MySQL integral and floating-point type.
2881
2987
@return maximum allowed value for the field */
3042
3148
                if (!index_mapping) {
3043
3149
                        /* Report an error if index_mapping continues to be
3044
3150
                        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",
 
3151
                        errmsg_printf(error::ERROR,
 
3152
                                      "InnoDB: fail to allocate memory for "
 
3153
                                        "index translation table. Number of "
 
3154
                                        "Index:%lu, array size:%lu",
3047
3155
                                        mysql_num_index,
3048
3156
                                        share->idx_trans_tbl.array_size);
3049
3157
                        ret = FALSE;
3064
3172
                        ib_table, table->key_info[count].name);
3065
3173
 
3066
3174
                if (!index_mapping[count]) {
3067
 
                        errmsg_printf(error::ERROR, "Cannot find index %s in InnoDB index dictionary.",
3068
 
                                      table->key_info[count].name);
 
3175
                        errmsg_printf(error::ERROR, "Cannot find index %s in InnoDB "
 
3176
                                        "index dictionary.",
 
3177
                                        table->key_info[count].name);
3069
3178
                        ret = FALSE;
3070
3179
                        goto func_exit;
3071
3180
                }
3072
3181
 
3073
3182
                /* Double check fetched index has the same
3074
3183
                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;
 
3184
                if (!innobase_match_index_columns(&table->key_info[count],
 
3185
                                                  index_mapping[count])) {
 
3186
                        errmsg_printf(error::ERROR, "Found index %s whose column info "
 
3187
                                        "does not match that of MySQL.",
 
3188
                                        table->key_info[count].name);
 
3189
                        ret = FALSE;
 
3190
                        goto func_exit;
3080
3191
                }
3081
3192
        }
3082
3193
 
3146
3257
    auto_inc = 0;
3147
3258
 
3148
3259
    ut_print_timestamp(stderr);
3149
 
    errmsg_printf(error::ERROR, "InnoDB: Unable to determine the AUTOINC column name");
 
3260
    fprintf(stderr, "  InnoDB: Unable to determine the AUTOINC "
 
3261
            "column name\n");
3150
3262
  }
3151
3263
 
3152
3264
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
3196
3308
    }
3197
3309
    case DB_RECORD_NOT_FOUND:
3198
3310
      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);
 
3311
      fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
 
3312
              "dictionaries are out of sync.\n"
 
3313
              "InnoDB: Unable to find the AUTOINC column "
 
3314
              "%s in the InnoDB table %s.\n"
 
3315
              "InnoDB: We set the next AUTOINC column "
 
3316
              "value to 0,\n"
 
3317
              "InnoDB: in effect disabling the AUTOINC "
 
3318
              "next value generation.\n"
 
3319
              "InnoDB: You can either set the next "
 
3320
              "AUTOINC value explicitly using ALTER TABLE\n"
 
3321
              "InnoDB: or fix the data dictionary by "
 
3322
              "recreating the table.\n",
 
3323
              col_name, index->table->name);
3206
3324
 
3207
3325
      /* This will disable the AUTOINC generation. */
3208
3326
      auto_inc = 0;
3233
3351
                    uint    test_if_locked) /*!< in: not used */
3234
3352
{
3235
3353
  dict_table_t* ib_table;
 
3354
  char    norm_name[FN_REFLEN];
3236
3355
  Session*    session;
3237
3356
 
3238
3357
  UT_NOT_USED(mode);
3247
3366
    getTransactionalEngine()->releaseTemporaryLatches(session);
3248
3367
  }
3249
3368
 
 
3369
  normalize_table_name(norm_name, identifier.getPath().c_str());
 
3370
 
3250
3371
  user_session = NULL;
3251
3372
 
3252
 
  std::string search_string(identifier.getSchemaName());
3253
 
  boost::algorithm::to_lower(search_string);
 
3373
  if (!(share=get_share(identifier.getPath().c_str()))) {
3254
3374
 
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
 
    }
 
3375
    return(1);
3270
3376
  }
3271
3377
 
3272
3378
  /* Create buffers for packing the fields of a record. Why
3293
3399
  }
3294
3400
 
3295
3401
  /* 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
 
  }
 
3402
  ib_table = dict_table_get(norm_name, TRUE);
3306
3403
  
3307
3404
  if (NULL == ib_table) {
3308
3405
    errmsg_printf(error::ERROR, "Cannot find or open table %s from\n"
3319
3416
        "doesn't support.\n"
3320
3417
        "See " REFMAN "innodb-troubleshooting.html\n"
3321
3418
        "how you can resolve the problem.\n",
3322
 
        identifier.getKeyPath().c_str());
 
3419
        norm_name);
3323
3420
    free_share(share);
3324
3421
    upd_buff.resize(0);
3325
3422
    key_val_buff.resize(0);
3328
3425
    return(HA_ERR_NO_SUCH_TABLE);
3329
3426
  }
3330
3427
 
3331
 
  if (ib_table->ibd_file_missing && ! session->doing_tablespace_operation()) {
 
3428
  if (ib_table->ibd_file_missing && !session_tablespace_op(session)) {
3332
3429
    errmsg_printf(error::ERROR, "MySQL is trying to open a table handle but "
3333
3430
        "the .ibd file for\ntable %s does not exist.\n"
3334
3431
        "Have you deleted the .ibd file from the "
3336
3433
        "or have you used DISCARD TABLESPACE?\n"
3337
3434
        "See " REFMAN "innodb-troubleshooting.html\n"
3338
3435
        "how you can resolve the problem.\n",
3339
 
        identifier.getKeyPath().c_str());
 
3436
        norm_name);
3340
3437
    free_share(share);
3341
3438
    upd_buff.resize(0);
3342
3439
    key_val_buff.resize(0);
3359
3456
 
3360
3457
  if (!innobase_build_index_translation(getTable(), ib_table, share)) {
3361
3458
    errmsg_printf(error::ERROR, "Build InnoDB index translation table for"
3362
 
                    " Table %s failed", identifier.getKeyPath().c_str());
 
3459
                    " Table %s failed", identifier.getPath().c_str());
3363
3460
  }
3364
3461
 
3365
3462
  /* Allocate a buffer for a 'row reference'. A row reference is
4337
4434
    ut_error;
4338
4435
  }
4339
4436
 
4340
 
  sql_command = user_session->getSqlCommand();
 
4437
  sql_command = session_sql_command(user_session);
4341
4438
 
4342
4439
  if ((sql_command == SQLCOM_ALTER_TABLE
4343
4440
       || sql_command == SQLCOM_CREATE_INDEX
4784
4881
  if (error == DB_SUCCESS
4785
4882
      && getTable()->next_number_field
4786
4883
      && new_row == getTable()->getInsertRecord()
4787
 
      && user_session->getSqlCommand() == SQLCOM_INSERT
 
4884
      && session_sql_command(user_session) == SQLCOM_INSERT
4788
4885
      && (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
4789
4886
    == TRX_DUP_IGNORE)  {
4790
4887
 
5723
5820
 
5724
5821
    if (!col_type) {
5725
5822
      push_warning_printf(
5726
 
                          trx->mysql_thd,
 
5823
                          (Session*) trx->mysql_thd,
5727
5824
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
5728
5825
                          ER_CANT_CREATE_TABLE,
5729
5826
                          "Error creating table '%s' with "
5757
5854
        /* in data0type.h we assume that the
5758
5855
        number fits in one byte in prtype */
5759
5856
        push_warning_printf(
5760
 
          trx->mysql_thd,
 
5857
          (Session*) trx->mysql_thd,
5761
5858
          DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5762
5859
          ER_CANT_CREATE_TABLE,
5763
5860
          "In InnoDB, charset-collation codes"
6032
6129
  trx_t*    trx;
6033
6130
  int   primary_key_no;
6034
6131
  uint    i;
 
6132
  char    name2[FN_REFLEN];
 
6133
  char    norm_name[FN_REFLEN];
6035
6134
  ib_int64_t  auto_inc_value;
6036
6135
  ulint   iflags;
6037
6136
  /* Cache the value of innodb_file_format, in case it is
6041
6140
  const char* stmt;
6042
6141
  size_t stmt_len;
6043
6142
 
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
 
  }
 
6143
  const char *table_name= identifier.getPath().c_str();
6051
6144
 
6052
6145
  if (form.getShare()->sizeFields() > 1000) {
6053
6146
    /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
6070
6163
 
6071
6164
  srv_lower_case_table_names = TRUE;
6072
6165
 
 
6166
  strcpy(name2, table_name);
 
6167
 
 
6168
  normalize_table_name(norm_name, name2);
 
6169
 
6073
6170
  /* Latch the InnoDB data dictionary exclusively so that no deadlocks
6074
6171
    or lock waits can happen in it during a table create operation.
6075
6172
    Drop table etc. do this latching in row0mysql.c. */
6177
6274
  if (lex_identified_temp_table)
6178
6275
    iflags |= DICT_TF2_TEMPORARY << DICT_TF2_SHIFT;
6179
6276
 
6180
 
  error= create_table_def(trx, &form, identifier.getKeyPath().c_str(),
6181
 
                          lex_identified_temp_table ? identifier.getKeyPath().c_str() : NULL,
 
6277
  error= create_table_def(trx, &form, norm_name,
 
6278
                          lex_identified_temp_table ? name2 : NULL,
6182
6279
                          iflags);
6183
6280
 
6184
6281
  session.setXaId(trx->id);
6194
6291
      order the rows by their row id which is internally generated
6195
6292
      by InnoDB */
6196
6293
 
6197
 
    error = create_clustered_index_when_no_primary(trx, iflags, identifier.getKeyPath().c_str());
 
6294
    error = create_clustered_index_when_no_primary(trx, iflags, norm_name);
6198
6295
    if (error) {
6199
6296
      goto cleanup;
6200
6297
    }
6202
6299
 
6203
6300
  if (primary_key_no != -1) {
6204
6301
    /* In InnoDB the clustered index must always be created first */
6205
 
    if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
 
6302
    if ((error = create_index(trx, &form, iflags, norm_name,
6206
6303
                              (uint) primary_key_no))) {
6207
6304
      goto cleanup;
6208
6305
    }
6211
6308
  for (i = 0; i < form.getShare()->sizeKeys(); i++) {
6212
6309
    if (i != (uint) primary_key_no) {
6213
6310
 
6214
 
      if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
 
6311
      if ((error = create_index(trx, &form, iflags, norm_name,
6215
6312
                                i))) {
6216
6313
        goto cleanup;
6217
6314
      }
6218
6315
    }
6219
6316
  }
6220
6317
 
6221
 
  stmt= session.getQueryStringCopy(stmt_len);
 
6318
  stmt = innobase_get_stmt(&session, &stmt_len);
6222
6319
 
6223
6320
  if (stmt) {
6224
6321
    string generated_create_table;
6225
6322
    const char *query= stmt;
6226
6323
 
6227
 
    if (session.getSqlCommand() == SQLCOM_CREATE_TABLE)
 
6324
    if (session_sql_command(&session) == SQLCOM_CREATE_TABLE)
6228
6325
    {
6229
6326
      message::transformTableDefinitionToSql(create_proto,
6230
6327
                                             generated_create_table,
6234
6331
 
6235
6332
    error = row_table_add_foreign_constraints(trx,
6236
6333
                                              query, strlen(query),
6237
 
                                              identifier.getKeyPath().c_str(),
 
6334
                                              norm_name,
6238
6335
                                              lex_identified_temp_table);
6239
6336
    switch (error) {
6240
6337
 
6245
6342
                          "Create table '%s' with foreign key constraint"
6246
6343
                          " failed. There is no index in the referenced"
6247
6344
                          " table where the referenced columns appear"
6248
 
                          " as the first columns.\n", identifier.getKeyPath().c_str());
 
6345
                          " as the first columns.\n", norm_name);
6249
6346
      break;
6250
6347
 
6251
6348
    case DB_CHILD_NO_INDEX:
6255
6352
                          "Create table '%s' with foreign key constraint"
6256
6353
                          " failed. There is no index in the referencing"
6257
6354
                          " table where referencing columns appear"
6258
 
                          " as the first columns.\n", identifier.getKeyPath().c_str());
 
6355
                          " as the first columns.\n", norm_name);
6259
6356
      break;
6260
6357
    }
6261
6358
 
6276
6373
 
6277
6374
  log_buffer_flush_to_disk();
6278
6375
 
6279
 
  innobase_table = dict_table_get(identifier.getKeyPath().c_str(), FALSE);
 
6376
  innobase_table = dict_table_get(norm_name, FALSE);
6280
6377
 
6281
6378
  assert(innobase_table != 0);
6282
6379
 
6299
6396
    does a table copy too. */
6300
6397
 
6301
6398
  if ((create_proto.options().has_auto_increment_value()
6302
 
       || session.getSqlCommand() == SQLCOM_ALTER_TABLE
6303
 
       || session.getSqlCommand() == SQLCOM_CREATE_INDEX)
 
6399
       || session_sql_command(&session) == SQLCOM_ALTER_TABLE
 
6400
       || session_sql_command(&session) == SQLCOM_CREATE_INDEX)
6304
6401
      && create_proto.options().auto_increment_value() != 0) {
6305
6402
 
6306
6403
    /* Query was one of :
6393
6490
 
6394
6491
  update_session(getTable()->in_use);
6395
6492
 
6396
 
  if (user_session->getSqlCommand() != SQLCOM_TRUNCATE) {
 
6493
  if (session_sql_command(user_session) != SQLCOM_TRUNCATE) {
6397
6494
  fallback:
6398
6495
    /* We only handle TRUNCATE TABLE t as a special case.
6399
6496
    DELETE FROM t will have to use ha_innobase::doDeleteRecord(),
6432
6529
  int error;
6433
6530
  trx_t*  parent_trx;
6434
6531
  trx_t*  trx;
 
6532
  char  norm_name[1000];
6435
6533
 
6436
6534
  ut_a(identifier.getPath().length() < 1000);
6437
6535
 
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
 
  }
 
6536
  /* Strangely, MySQL passes the table name without the '.frm'
 
6537
    extension, in contrast to ::create */
 
6538
  normalize_table_name(norm_name, identifier.getPath().c_str());
6445
6539
 
6446
6540
  /* Get the transaction associated with the current session, or create one
6447
6541
    if not yet created */
6459
6553
 
6460
6554
  /* Drop the table in InnoDB */
6461
6555
 
6462
 
  error = row_drop_table_for_mysql(identifier.getKeyPath().c_str(), trx,
6463
 
                                   session.getSqlCommand()
 
6556
  error = row_drop_table_for_mysql(norm_name, trx,
 
6557
                                   session_sql_command(&session)
6464
6558
                                   == SQLCOM_DROP_DB);
6465
6559
 
6466
6560
  session.setXaId(trx->id);
6488
6582
    if (identifier.getType() == message::Table::TEMPORARY)
6489
6583
    {
6490
6584
      session.getMessageCache().removeTableMessage(identifier);
6491
 
      ulint sql_command = session.getSqlCommand();
 
6585
      ulint sql_command = session_sql_command(&session);
6492
6586
 
6493
6587
      // If this was the final removal to an alter table then we will need
6494
6588
      // to remove the .dfe that was left behind.
6608
6702
innobase_rename_table(
6609
6703
/*==================*/
6610
6704
  trx_t*    trx,  /*!< in: transaction */
6611
 
  const identifier::Table &from,
6612
 
  const identifier::Table &to,
 
6705
  const char* from, /*!< in: old name of the table */
 
6706
  const char* to, /*!< in: new name of the table */
6613
6707
  ibool   lock_and_commit)
6614
6708
        /*!< in: TRUE=lock data dictionary and commit */
6615
6709
{
6616
6710
  int error;
 
6711
  char norm_to[FN_REFLEN];
 
6712
  char norm_from[FN_REFLEN];
6617
6713
 
6618
6714
  srv_lower_case_table_names = TRUE;
6619
6715
 
 
6716
  normalize_table_name(norm_to, to);
 
6717
  normalize_table_name(norm_from, from);
 
6718
 
6620
6719
  /* Serialize data dictionary operations with dictionary mutex:
6621
6720
  no deadlocks can occur then in these operations */
6622
6721
 
6624
6723
    row_mysql_lock_data_dictionary(trx);
6625
6724
  }
6626
6725
 
6627
 
  error = row_rename_table_for_mysql(from.getKeyPath().c_str(), to.getKeyPath().c_str(), trx, lock_and_commit);
 
6726
  error = row_rename_table_for_mysql(
 
6727
    norm_from, norm_to, trx, lock_and_commit);
6628
6728
 
6629
6729
  if (error != DB_SUCCESS) {
6630
6730
    FILE* ef = dict_foreign_err_file;
6631
6731
 
6632
6732
    fputs("InnoDB: Renaming table ", ef);
6633
 
    ut_print_name(ef, trx, TRUE, from.getKeyPath().c_str());
 
6733
    ut_print_name(ef, trx, TRUE, norm_from);
6634
6734
    fputs(" to ", ef);
6635
 
    ut_print_name(ef, trx, TRUE, to.getKeyPath().c_str());
 
6735
    ut_print_name(ef, trx, TRUE, norm_to);
6636
6736
    fputs(" failed!\n", ef);
6637
6737
  }
6638
6738
 
6677
6777
 
6678
6778
  trx = innobase_trx_allocate(&session);
6679
6779
 
6680
 
  error = innobase_rename_table(trx, from, to, TRUE);
 
6780
  error = innobase_rename_table(trx, from.getPath().c_str(), to.getPath().c_str(), TRUE);
6681
6781
 
6682
6782
  session.setXaId(trx->id);
6683
6783
 
6702
6802
     is the one we are trying to rename to) and return the generic
6703
6803
     error code. */
6704
6804
  if (error == (int) DB_DUPLICATE_KEY) {
6705
 
    my_error(ER_TABLE_EXISTS_ERROR, to);
 
6805
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to.getPath().c_str());
6706
6806
    error = DB_ERROR;
6707
6807
  }
6708
6808
 
7131
7231
    n_rows can not be 0 unless the table is empty, set to 1
7132
7232
    instead. The original problem of bug#29507 is actually
7133
7233
    fixed in the server code. */
7134
 
    if (user_session->getSqlCommand() == SQLCOM_TRUNCATE) {
 
7234
    if (session_sql_command(user_session) == SQLCOM_TRUNCATE) {
7135
7235
 
7136
7236
      n_rows = 1;
7137
7237
 
7759
7859
                              tmp_foreign_fields, tmp_referenced_fields);
7760
7860
 
7761
7861
    ForeignKeyInfo *pf_key_info = (ForeignKeyInfo *)
7762
 
      session->getMemRoot()->duplicate(&f_key_info, sizeof(ForeignKeyInfo));
 
7862
      session->memdup(&f_key_info, sizeof(ForeignKeyInfo));
7763
7863
    f_key_list->push_back(pf_key_info);
7764
7864
    foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
7765
7865
  }
8289
8389
static INNOBASE_SHARE* get_share(const char* table_name)
8290
8390
{
8291
8391
  INNOBASE_SHARE *share;
8292
 
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
 
8392
  pthread_mutex_lock(&innobase_share_mutex);
8293
8393
 
8294
8394
  ulint fold = ut_fold_string(table_name);
8295
8395
 
8316
8416
  }
8317
8417
 
8318
8418
  share->use_count++;
 
8419
  pthread_mutex_unlock(&innobase_share_mutex);
8319
8420
 
8320
8421
  return(share);
8321
8422
}
8322
8423
 
8323
8424
static void free_share(INNOBASE_SHARE* share)
8324
8425
{
8325
 
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
 
8426
  pthread_mutex_lock(&innobase_share_mutex);
8326
8427
 
8327
8428
#ifdef UNIV_DEBUG
8328
8429
  INNOBASE_SHARE* share2;
8351
8452
    /* TODO: invoke HASH_MIGRATE if innobase_open_tables
8352
8453
    shrinks too much */
8353
8454
  }
 
8455
 
 
8456
  pthread_mutex_unlock(&innobase_share_mutex);
8354
8457
}
8355
8458
 
8356
8459
/*****************************************************************//**
8385
8488
  trx = check_trx_exists(session);
8386
8489
 
8387
8490
  assert(EQ_CURRENT_SESSION(session));
8388
 
  const uint32_t sql_command = session->getSqlCommand();
 
8491
  const uint32_t sql_command = session_sql_command(session);
8389
8492
 
8390
8493
  if (sql_command == SQLCOM_DROP_TABLE) {
8391
8494
 
8471
8574
 
8472
8575
    if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
8473
8576
         && lock_type <= TL_WRITE)
8474
 
        && ! session->doing_tablespace_operation()
 
8577
        && !session_tablespace_op(session)
8475
8578
        && sql_command != SQLCOM_TRUNCATE
8476
8579
        && sql_command != SQLCOM_CREATE_TABLE) {
8477
8580
 
8548
8651
 
8549
8652
  if (auto_inc == 0) {
8550
8653
    ut_print_timestamp(stderr);
8551
 
    errmsg_printf(error::ERROR, "  InnoDB: AUTOINC next value generation is disabled for '%s'\n", innodb_table->name);
 
8654
    fprintf(stderr, "  InnoDB: AUTOINC next value generation "
 
8655
            "is disabled for '%s'\n", innodb_table->name);
8552
8656
  }
8553
8657
 
8554
8658
  dict_table_autoinc_unlock(innodb_table);
8703
8807
/* See comment in Cursor.cc */
8704
8808
UNIV_INTERN
8705
8809
bool
8706
 
InnobaseEngine::get_error_message(int, String *buf) const
 
8810
InnobaseEngine::get_error_message(int, String *buf)
8707
8811
{
8708
8812
  trx_t*  trx = check_trx_exists(current_session);
8709
8813
 
8787
8891
finds charset information and returns length of prefix_len characters in the
8788
8892
index field in bytes.
8789
8893
@return number of bytes occupied by the first n characters */
 
8894
UNIV_INTERN
 
8895
ulint
 
8896
innobase_get_at_most_n_mbchars(
 
8897
/*===========================*/
 
8898
  ulint charset_id, /*!< in: character set id */
 
8899
  ulint prefix_len, /*!< in: prefix length in bytes of the index
 
8900
        (this has to be divided by mbmaxlen to get the
 
8901
        number of CHARACTERS n in the prefix) */
 
8902
  ulint data_len,   /*!< in: length of the string in bytes */
 
8903
  const char* str); /*!< in: character string */
8790
8904
 
8791
8905
ulint
8792
8906
innobase_get_at_most_n_mbchars(
8870
8984
  trx->detailed_error[0]= '\0';
8871
8985
 
8872
8986
  /* Set the isolation level of the transaction. */
8873
 
  trx->isolation_level= innobase_map_isolation_level(session->getTxIsolation());
 
8987
  trx->isolation_level= innobase_map_isolation_level(session_tx_isolation(session));
8874
8988
}
8875
8989
 
8876
8990
void
8913
9027
    return(0);
8914
9028
  }
8915
9029
 
8916
 
  session->get_xid(reinterpret_cast<DrizzleXid*>(&trx->xid));
 
9030
  session->get_xid(reinterpret_cast<DRIZZLE_XID*>(&trx->xid));
8917
9031
 
8918
9032
  /* Release a possible FIFO ticket and search latch. Since we will
8919
9033
  reserve the kernel mutex, we have to release the search system latch
9335
9449
    if (innobase_strcasecmp(key->name,
9336
9450
                            innobase_index_reserve_name) == 0) {
9337
9451
      /* Push warning to drizzle */
9338
 
      push_warning_printf(trx->mysql_thd,
 
9452
      push_warning_printf((Session*)trx->mysql_thd,
9339
9453
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
9340
9454
                          ER_WRONG_NAME_FOR_INDEX,
9341
9455
                          "Cannot Create Index with name "
9361
9475
  ulint   buflen;
9362
9476
  const char* id;
9363
9477
  ulint   idlen;
9364
 
  drizzled::Session *session;
 
9478
  void*   session;
9365
9479
  ibool   file_id;
9366
9480
 
9367
9481
  const char* expected;