~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
114
114
#include "ha_prototypes.h"
115
115
#include "ut0mem.h"
116
116
#include "ibuf0ibuf.h"
117
 
#include "mysql_addons.h"
118
117
 
119
118
#include "ha_innodb.h"
120
119
#include "data_dictionary.h"
134
133
#include <google/protobuf/io/coded_stream.h>
135
134
#include <google/protobuf/text_format.h>
136
135
 
 
136
#include <boost/thread/mutex.hpp>
 
137
 
137
138
using namespace std;
138
139
using namespace drizzled;
139
140
 
140
141
/** to protect innobase_open_files */
141
 
static pthread_mutex_t innobase_share_mutex;
 
142
static boost::mutex innobase_share_mutex;
 
143
 
142
144
/** to force correct commit order in binlog */
143
 
static pthread_mutex_t prepare_commit_mutex;
144
145
static ulong commit_threads = 0;
145
 
static pthread_mutex_t commit_threads_m;
146
 
static pthread_cond_t commit_cond;
147
 
static pthread_mutex_t commit_cond_m;
 
146
static boost::condition_variable commit_cond;
 
147
static boost::mutex 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
 
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;
 
163
 
181
164
typedef constrained_check<uint32_t, UINT32_MAX, 10> open_files_constraint;
182
165
static open_files_constraint innobase_open_files;
183
166
typedef constrained_check<uint32_t, 10, 1> mirrored_log_groups_constraint;
350
333
      srv_free_paths_and_sizes();
351
334
      if (internal_innobase_data_file_path)
352
335
        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);
358
336
    }
359
337
    
360
338
    /* These get strdup'd from vm variables */
806
784
ibool
807
785
thd_is_replication_slave_thread(
808
786
/*============================*/
809
 
  void* ) /*!< in: thread handle (Session*) */
 
787
  drizzled::Session* ) /*!< in: thread handle (Session*) */
810
788
{
811
789
  return false;
812
790
}
880
858
ibool
881
859
thd_has_edited_nontrans_tables(
882
860
/*===========================*/
883
 
  void*   session)  /*!< in: thread handle (Session*) */
 
861
  drizzled::Session *session)  /*!< in: thread handle (Session*) */
884
862
{
885
 
  return((ibool)((Session *)session)->transaction.all.hasModifiedNonTransData());
 
863
  return((ibool)session->transaction.all.hasModifiedNonTransData());
886
864
}
887
865
 
888
866
/******************************************************************//**
892
870
ibool
893
871
thd_is_select(
894
872
/*==========*/
895
 
  const void* session)  /*!< in: thread handle (Session*) */
 
873
  const drizzled::Session *session)  /*!< in: thread handle (Session*) */
896
874
{
897
 
  return(session_sql_command((const Session*) session) == SQLCOM_SELECT);
 
875
  return(session_sql_command(session) == SQLCOM_SELECT);
898
876
}
899
877
 
900
878
/******************************************************************//**
905
883
ibool
906
884
thd_supports_xa(
907
885
/*============*/
908
 
  void* )  /*!< in: thread handle (Session*), or NULL to query
 
886
  drizzled::Session* )  /*!< in: thread handle (Session*), or NULL to query
909
887
        the global innodb_supports_xa */
910
888
{
911
889
  /* TODO: Add support here for per-session value */
919
897
ulong
920
898
thd_lock_wait_timeout(
921
899
/*==================*/
922
 
  void*)  /*!< in: thread handle (Session*), or NULL to query
 
900
  drizzled::Session*)  /*!< in: thread handle (Session*), or NULL to query
923
901
      the global innodb_lock_wait_timeout */
924
902
{
925
903
  /* TODO: Add support here for per-session value */
934
912
void
935
913
thd_set_lock_wait_time(
936
914
/*===================*/
937
 
        void*   thd,    /*!< in: thread handle (THD*) */
 
915
        drizzled::Session*      in_session,     /*!< in: thread handle (THD*) */
938
916
        ulint   value)  /*!< in: time waited for the lock */
939
917
{
940
 
        if (thd) {
941
 
          static_cast<Session*>(thd)->utime_after_lock+= value;
942
 
        }
 
918
  if (in_session)
 
919
    in_session->utime_after_lock+= value;
943
920
}
944
921
 
945
922
/********************************************************************//**
1172
1149
innobase_mysql_print_thd(
1173
1150
/*=====================*/
1174
1151
  FILE* f,    /*!< in: output stream */
1175
 
  void * in_session,  /*!< in: pointer to a Drizzle Session object */
 
1152
  drizzled::Session *in_session,  /*!< in: pointer to a Drizzle Session object */
1176
1153
  uint  )   /*!< in: max query length to print, or 0 to
1177
1154
           use the default max length */
1178
1155
{
1179
 
  Session *session= reinterpret_cast<Session *>(in_session);
1180
 
  drizzled::identifier::User::const_shared_ptr user_identifier(session->user());
 
1156
  drizzled::identifier::User::const_shared_ptr user_identifier(in_session->user());
1181
1157
 
1182
1158
  fprintf(f,
1183
1159
          "Drizzle thread %"PRIu64", query id %"PRIu64", %s, %s, %s ",
1184
 
          static_cast<uint64_t>(session->getSessionId()),
1185
 
          static_cast<uint64_t>(session->getQueryId()),
 
1160
          static_cast<uint64_t>(in_session->getSessionId()),
 
1161
          static_cast<uint64_t>(in_session->getQueryId()),
1186
1162
          glob_hostname,
1187
1163
          user_identifier->address().c_str(),
1188
1164
          user_identifier->username().c_str()
1189
1165
  );
1190
 
  fprintf(f, "\n%s", session->getQueryString()->c_str());
 
1166
  fprintf(f, "\n%s", in_session->getQueryString()->c_str());
1191
1167
  putc('\n', f);
1192
1168
}
1193
1169
 
1270
1246
  my_casedn_str(system_charset_info, a);
1271
1247
}
1272
1248
 
1273
 
/**********************************************************************//**
1274
 
Determines the connection character set.
1275
 
@return connection character set */
1276
 
UNIV_INTERN
1277
 
const void*
1278
 
innobase_get_charset(
1279
 
/*=================*/
1280
 
  void* mysql_session)  /*!< in: MySQL thread handle */
1281
 
{
1282
 
  return static_cast<Session*>(mysql_session)->charset();
1283
 
}
1284
 
 
1285
1249
UNIV_INTERN
1286
1250
bool
1287
1251
innobase_isspace(
1291
1255
  return my_isspace(static_cast<const CHARSET_INFO *>(cs), char_to_test);
1292
1256
}
1293
1257
 
1294
 
UNIV_INTERN
1295
 
int
1296
 
innobase_fast_mutex_init(
1297
 
        os_fast_mutex_t*        fast_mutex)
1298
 
{
1299
 
  return pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
1300
 
}
1301
 
 
1302
 
/**********************************************************************//**
1303
 
Determines the current SQL statement.
1304
 
@return        SQL statement string */
1305
 
UNIV_INTERN
1306
 
const char*
1307
 
innobase_get_stmt(
1308
 
/*==============*/
1309
 
       void*   session,        /*!< in: MySQL thread handle */
1310
 
       size_t* length)         /*!< out: length of the SQL statement */
1311
 
{
1312
 
  return static_cast<Session*>(session)->getQueryStringCopy(*length);
1313
 
}
1314
 
 
1315
1258
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1316
1259
/*******************************************************************//**
1317
1260
Map an OS error to an errno value. The OS error number is stored in
1666
1609
  ulint   buflen, /*!< in: length of buf, in bytes */
1667
1610
  const char* id, /*!< in: identifier to convert */
1668
1611
  ulint   idlen,  /*!< in: length of id, in bytes */
1669
 
  void*   session,/*!< in: MySQL connection thread, or NULL */
 
1612
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
1670
1613
  ibool   file_id)/*!< in: TRUE=id is a table or database name;
1671
1614
        FALSE=id is an UTF-8 string */
1672
1615
{
1752
1695
  ulint   buflen, /*!< in: length of buf, in bytes */
1753
1696
  const char* id, /*!< in: identifier to convert */
1754
1697
  ulint   idlen,  /*!< in: length of id, in bytes */
1755
 
  void*   session,/*!< in: MySQL connection thread, or NULL */
 
1698
  drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
1756
1699
  ibool   table_id)/*!< in: TRUE=id is a table or database name;
1757
1700
        FALSE=id is an index name */
1758
1701
{
1806
1749
/*===============*/
1807
1750
  trx_t*  trx)  /*!< in: transaction */
1808
1751
{
1809
 
  return(trx && trx->mysql_thd && static_cast<Session*>(trx->mysql_thd)->getKilled());
 
1752
  return(trx && trx->mysql_thd && trx->mysql_thd->getKilled());
1810
1753
}
1811
1754
 
1812
1755
/**********************************************************************//**
2150
2093
  ret = (bool) srv_parse_data_file_paths_and_sizes(
2151
2094
                                                   internal_innobase_data_file_path);
2152
2095
  if (ret == FALSE) {
2153
 
    errmsg_printf(error::ERROR, 
2154
 
                  "InnoDB: syntax error in innodb_data_file_path");
 
2096
    errmsg_printf(error::ERROR, "InnoDB: syntax error in innodb_data_file_path");
 
2097
 
2155
2098
mem_free_and_error:
2156
2099
    srv_free_paths_and_sizes();
2157
2100
    if (internal_innobase_data_file_path)
2176
2119
    srv_parse_log_group_home_dirs((char *)innobase_log_group_home_dir.c_str());
2177
2120
 
2178
2121
  if (ret == FALSE || innobase_mirrored_log_groups.get() != 1) {
2179
 
    errmsg_printf(error::ERROR,
2180
 
                  _("syntax error in innodb_log_group_home_dir, or a "
2181
 
                  "wrong number of mirrored log groups"));
 
2122
    errmsg_printf(error::ERROR, _("syntax error in innodb_log_group_home_dir, or a "
 
2123
                                  "wrong number of mirrored log groups"));
2182
2124
 
2183
2125
    goto mem_free_and_error;
2184
2126
  }
2221
2163
     srv_max_file_format_at_startup */
2222
2164
  if (innobase_file_format_validate_and_set(innobase_file_format_max.c_str()) < 0)
2223
2165
  {
2224
 
    errmsg_printf(error::ERROR, _("InnoDB: invalid "
2225
 
                    "innodb_file_format_max value: "
2226
 
                    "should be any value up to %s or its "
2227
 
                    "equivalent numeric id"),
2228
 
                    trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
 
2166
    errmsg_printf(error::ERROR, _("InnoDB: invalid innodb_file_format_max value: "
 
2167
                                  "should be any value up to %s or its equivalent numeric id"),
 
2168
                  trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
2229
2169
    goto mem_free_and_error;
2230
2170
  }
2231
2171
 
2244
2184
      }
2245
2185
    }
2246
2186
 
2247
 
    errmsg_printf(error::ERROR,
2248
 
                  "InnoDB: invalid value "
2249
 
                  "innodb_change_buffering=%s",
 
2187
    errmsg_printf(error::ERROR, "InnoDB: invalid value innodb_change_buffering=%s",
2250
2188
                  vm["change-buffering"].as<string>().c_str());
2251
2189
    goto mem_free_and_error;
2252
2190
  }
2324
2262
                                                     TRUE);
2325
2263
 
2326
2264
  innobase_open_tables = hash_create(200);
2327
 
  pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
2328
 
  pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
2329
 
  pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
2330
 
  pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
2331
 
  pthread_cond_init(&commit_cond, NULL);
2332
2265
  innodb_inited= 1;
2333
2266
 
2334
2267
  actuall_engine_ptr->dropTemporarySchema();
2335
2268
 
2336
 
  status_table_function_ptr= new InnodbStatusTool;
 
2269
  context.add(new InnodbStatusTool);
2337
2270
 
2338
2271
  context.add(innodb_engine_ptr);
2339
2272
 
2340
 
  context.add(status_table_function_ptr);
2341
 
 
2342
 
  cmp_tool= new(std::nothrow)CmpTool(false);
2343
 
  context.add(cmp_tool);
2344
 
 
2345
 
  cmp_reset_tool= new(std::nothrow)CmpTool(true);
2346
 
  context.add(cmp_reset_tool);
2347
 
 
2348
 
  cmp_mem_tool= new(std::nothrow)CmpmemTool(false);
2349
 
  context.add(cmp_mem_tool);
2350
 
 
2351
 
  cmp_mem_reset_tool= new(std::nothrow)CmpmemTool(true);
2352
 
  context.add(cmp_mem_reset_tool);
2353
 
 
2354
 
  innodb_trx_tool= new(std::nothrow)InnodbTrxTool("INNODB_TRX");
2355
 
  context.add(innodb_trx_tool);
2356
 
 
2357
 
  innodb_locks_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCKS");
2358
 
  context.add(innodb_locks_tool);
2359
 
 
2360
 
  innodb_lock_waits_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS");
2361
 
  context.add(innodb_lock_waits_tool);
2362
 
 
2363
 
  innodb_sys_tables_tool= new(std::nothrow)InnodbSysTablesTool();
2364
 
  context.add(innodb_sys_tables_tool);
2365
 
 
2366
 
  innodb_sys_tablestats_tool= new(std::nothrow)InnodbSysTableStatsTool();
2367
 
  context.add(innodb_sys_tablestats_tool);
2368
 
 
2369
 
  innodb_sys_indexes_tool= new(std::nothrow)InnodbSysIndexesTool();
2370
 
  context.add(innodb_sys_indexes_tool);
2371
 
 
2372
 
  innodb_sys_columns_tool= new(std::nothrow)InnodbSysColumnsTool();
2373
 
  context.add(innodb_sys_columns_tool);
2374
 
 
2375
 
  innodb_sys_fields_tool= new(std::nothrow)InnodbSysFieldsTool();
2376
 
  context.add(innodb_sys_fields_tool);
2377
 
 
2378
 
  innodb_sys_foreign_tool= new(std::nothrow)InnodbSysForeignTool();
2379
 
  context.add(innodb_sys_foreign_tool);
2380
 
 
2381
 
  innodb_sys_foreign_cols_tool= new(std::nothrow)InnodbSysForeignColsTool();
2382
 
  context.add(innodb_sys_foreign_cols_tool);
 
2273
  context.add(new(std::nothrow)CmpTool(false));
 
2274
 
 
2275
  context.add(new(std::nothrow)CmpTool(true));
 
2276
 
 
2277
  context.add(new(std::nothrow)CmpmemTool(false));
 
2278
 
 
2279
  context.add(new(std::nothrow)CmpmemTool(true));
 
2280
 
 
2281
  context.add(new(std::nothrow)InnodbTrxTool("INNODB_TRX"));
 
2282
 
 
2283
  context.add(new(std::nothrow)InnodbTrxTool("INNODB_LOCKS"));
 
2284
 
 
2285
  context.add(new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS"));
 
2286
 
 
2287
  context.add(new(std::nothrow)InnodbSysTablesTool());
 
2288
 
 
2289
  context.add(new(std::nothrow)InnodbSysTableStatsTool());
 
2290
 
 
2291
  context.add(new(std::nothrow)InnodbSysIndexesTool());
 
2292
 
 
2293
  context.add(new(std::nothrow)InnodbSysColumnsTool());
 
2294
 
 
2295
  context.add(new(std::nothrow)InnodbSysFieldsTool());
 
2296
 
 
2297
  context.add(new(std::nothrow)InnodbSysForeignTool());
 
2298
 
 
2299
  context.add(new(std::nothrow)InnodbSysForeignColsTool());
2383
2300
 
2384
2301
  context.add(new(std::nothrow)InnodbInternalTables());
2385
2302
  context.add(new(std::nothrow)InnodbReplicationTable());
2386
2303
 
2387
2304
  if (innobase_use_replication_log)
2388
2305
  {
2389
 
    replication_logger= new(std::nothrow)ReplicationLog();
 
2306
    ReplicationLog *replication_logger= new(std::nothrow)ReplicationLog();
2390
2307
    context.add(replication_logger);
2391
2308
    ReplicationLog::setup(replication_logger);
2392
2309
  }
2477
2394
  btr_search_fully_disabled = (!btr_search_enabled);
2478
2395
 
2479
2396
  return(FALSE);
 
2397
 
2480
2398
error:
2481
2399
  return(TRUE);
2482
2400
}
2581
2499
    /* We need current binlog position for ibbackup to work.
2582
2500
    Note, the position is current because of
2583
2501
    prepare_commit_mutex */
2584
 
retry:
2585
 
    if (innobase_commit_concurrency.get() > 0) {
2586
 
      pthread_mutex_lock(&commit_cond_m);
2587
 
      commit_threads++;
2588
 
 
2589
 
      if (commit_threads > innobase_commit_concurrency.get()) {
 
2502
    const uint32_t commit_concurrency= innobase_commit_concurrency.get();
 
2503
    if (commit_concurrency)
 
2504
    {
 
2505
      do 
 
2506
      {
 
2507
        boost::mutex::scoped_lock scopedLock(commit_cond_m);
 
2508
        commit_threads++;
 
2509
 
 
2510
        if (commit_threads <= commit_concurrency) 
 
2511
          break;
 
2512
 
2590
2513
        commit_threads--;
2591
 
        pthread_cond_wait(&commit_cond,
2592
 
          &commit_cond_m);
2593
 
        pthread_mutex_unlock(&commit_cond_m);
2594
 
        goto retry;
2595
 
      }
2596
 
      else {
2597
 
        pthread_mutex_unlock(&commit_cond_m);
2598
 
      }
 
2514
        commit_cond.wait(scopedLock);
 
2515
      } while (1);
2599
2516
    }
2600
2517
 
2601
2518
    trx->mysql_log_file_name = NULL;
2608
2525
    innobase_commit_low(trx);
2609
2526
    trx->flush_log_later = FALSE;
2610
2527
 
2611
 
    if (innobase_commit_concurrency.get() > 0) {
2612
 
      pthread_mutex_lock(&commit_cond_m);
 
2528
    if (commit_concurrency)
 
2529
    {
 
2530
      boost::mutex::scoped_lock scopedLock(commit_cond_m);
2613
2531
      commit_threads--;
2614
 
      pthread_cond_signal(&commit_cond);
2615
 
      pthread_mutex_unlock(&commit_cond_m);
 
2532
      commit_cond.notify_one();
2616
2533
    }
2617
2534
 
2618
2535
    /* Now do a write + flush of logs. */
2937
2854
  return(true);
2938
2855
}
2939
2856
 
2940
 
/*****************************************************************//**
2941
 
Normalizes a table name string. A normalized name consists of the
2942
 
database name catenated to '/' and table name. An example:
2943
 
test/mytable. On Windows normalization puts both the database name and the
2944
 
table name always to lower case. */
2945
 
static
2946
 
void
2947
 
normalize_table_name(
2948
 
/*=================*/
2949
 
  char*   norm_name,  /*!< out: normalized name as a
2950
 
          null-terminated string */
2951
 
  const char* name)   /*!< in: table name string */
2952
 
{
2953
 
  const char* name_ptr;
2954
 
  const char* db_ptr;
2955
 
  const char* ptr;
2956
 
 
2957
 
  /* Scan name from the end */
2958
 
 
2959
 
  ptr = strchr(name, '\0')-1;
2960
 
 
2961
 
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
2962
 
    ptr--;
2963
 
  }
2964
 
 
2965
 
  name_ptr = ptr + 1;
2966
 
 
2967
 
  assert(ptr > name);
2968
 
 
2969
 
  ptr--;
2970
 
 
2971
 
  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
2972
 
    ptr--;
2973
 
  }
2974
 
 
2975
 
  db_ptr = ptr + 1;
2976
 
 
2977
 
  memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
2978
 
 
2979
 
  norm_name[name_ptr - db_ptr - 1] = '/';
2980
 
 
2981
 
#ifdef __WIN__
2982
 
  innobase_casedn_str(norm_name);
2983
 
#endif
2984
 
}
2985
 
 
2986
2857
/********************************************************************//**
2987
2858
Get the upper limit of the MySQL integral and floating-point type.
2988
2859
@return maximum allowed value for the field */
3149
3020
                if (!index_mapping) {
3150
3021
                        /* Report an error if index_mapping continues to be
3151
3022
                        NULL and mysql_num_index is a non-zero value */
3152
 
                        errmsg_printf(error::ERROR,
3153
 
                                      "InnoDB: fail to allocate memory for "
3154
 
                                        "index translation table. Number of "
3155
 
                                        "Index:%lu, array size:%lu",
 
3023
                        errmsg_printf(error::ERROR, "InnoDB: fail to allocate memory for "
 
3024
                                      "index translation table. Number of Index:%lu, array size:%lu",
3156
3025
                                        mysql_num_index,
3157
3026
                                        share->idx_trans_tbl.array_size);
3158
3027
                        ret = FALSE;
3173
3042
                        ib_table, table->key_info[count].name);
3174
3043
 
3175
3044
                if (!index_mapping[count]) {
3176
 
                        errmsg_printf(error::ERROR, "Cannot find index %s in InnoDB "
3177
 
                                        "index dictionary.",
3178
 
                                        table->key_info[count].name);
 
3045
                        errmsg_printf(error::ERROR, "Cannot find index %s in InnoDB index dictionary.",
 
3046
                                      table->key_info[count].name);
3179
3047
                        ret = FALSE;
3180
3048
                        goto func_exit;
3181
3049
                }
3182
3050
 
3183
3051
                /* Double check fetched index has the same
3184
3052
                column info as those in mysql key_info. */
3185
 
                if (!innobase_match_index_columns(&table->key_info[count],
3186
 
                                                  index_mapping[count])) {
3187
 
                        errmsg_printf(error::ERROR, "Found index %s whose column info "
3188
 
                                        "does not match that of MySQL.",
3189
 
                                        table->key_info[count].name);
3190
 
                        ret = FALSE;
3191
 
                        goto func_exit;
 
3053
                if (!innobase_match_index_columns(&table->key_info[count], index_mapping[count])) {
 
3054
                  errmsg_printf(error::ERROR, "Found index %s whose column info does not match that of MySQL.",
 
3055
                                table->key_info[count].name);
 
3056
                  ret = FALSE;
 
3057
                  goto func_exit;
3192
3058
                }
3193
3059
        }
3194
3060
 
3258
3124
    auto_inc = 0;
3259
3125
 
3260
3126
    ut_print_timestamp(stderr);
3261
 
    fprintf(stderr, "  InnoDB: Unable to determine the AUTOINC "
3262
 
            "column name\n");
 
3127
    errmsg_printf(error::ERROR, "InnoDB: Unable to determine the AUTOINC column name");
3263
3128
  }
3264
3129
 
3265
3130
  if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
3309
3174
    }
3310
3175
    case DB_RECORD_NOT_FOUND:
3311
3176
      ut_print_timestamp(stderr);
3312
 
      fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
3313
 
              "dictionaries are out of sync.\n"
3314
 
              "InnoDB: Unable to find the AUTOINC column "
3315
 
              "%s in the InnoDB table %s.\n"
3316
 
              "InnoDB: We set the next AUTOINC column "
3317
 
              "value to 0,\n"
3318
 
              "InnoDB: in effect disabling the AUTOINC "
3319
 
              "next value generation.\n"
3320
 
              "InnoDB: You can either set the next "
3321
 
              "AUTOINC value explicitly using ALTER TABLE\n"
3322
 
              "InnoDB: or fix the data dictionary by "
3323
 
              "recreating the table.\n",
3324
 
              col_name, index->table->name);
 
3177
      errmsg_printf(error::ERROR, "InnoDB: MySQL and InnoDB data dictionaries are out of sync.\n"
 
3178
                    "InnoDB: Unable to find the AUTOINC column %s in the InnoDB table %s.\n"
 
3179
                    "InnoDB: We set the next AUTOINC column value to 0,\n"
 
3180
                    "InnoDB: in effect disabling the AUTOINC next value generation.\n"
 
3181
                    "InnoDB: You can either set the next AUTOINC value explicitly using ALTER TABLE\n"
 
3182
                    "InnoDB: or fix the data dictionary by recreating the table.\n",
 
3183
                    col_name, index->table->name);
3325
3184
 
3326
3185
      /* This will disable the AUTOINC generation. */
3327
3186
      auto_inc = 0;
3352
3211
                    uint    test_if_locked) /*!< in: not used */
3353
3212
{
3354
3213
  dict_table_t* ib_table;
3355
 
  char    norm_name[FN_REFLEN];
3356
3214
  Session*    session;
3357
3215
 
3358
3216
  UT_NOT_USED(mode);
3367
3225
    getTransactionalEngine()->releaseTemporaryLatches(session);
3368
3226
  }
3369
3227
 
3370
 
  normalize_table_name(norm_name, identifier.getPath().c_str());
3371
 
 
3372
3228
  user_session = NULL;
3373
3229
 
3374
 
  if (!(share=get_share(identifier.getPath().c_str()))) {
 
3230
  if (!(share=get_share(identifier.getKeyPath().c_str()))) {
3375
3231
 
3376
3232
    return(1);
3377
3233
  }
3400
3256
  }
3401
3257
 
3402
3258
  /* Get pointer to a table object in InnoDB dictionary cache */
3403
 
  ib_table = dict_table_get(norm_name, TRUE);
 
3259
  ib_table = dict_table_get(identifier.getKeyPath().c_str(), TRUE);
3404
3260
  
3405
3261
  if (NULL == ib_table) {
3406
3262
    errmsg_printf(error::ERROR, "Cannot find or open table %s from\n"
3417
3273
        "doesn't support.\n"
3418
3274
        "See " REFMAN "innodb-troubleshooting.html\n"
3419
3275
        "how you can resolve the problem.\n",
3420
 
        norm_name);
 
3276
        identifier.getKeyPath().c_str());
3421
3277
    free_share(share);
3422
3278
    upd_buff.resize(0);
3423
3279
    key_val_buff.resize(0);
3434
3290
        "or have you used DISCARD TABLESPACE?\n"
3435
3291
        "See " REFMAN "innodb-troubleshooting.html\n"
3436
3292
        "how you can resolve the problem.\n",
3437
 
        norm_name);
 
3293
        identifier.getKeyPath().c_str());
3438
3294
    free_share(share);
3439
3295
    upd_buff.resize(0);
3440
3296
    key_val_buff.resize(0);
3457
3313
 
3458
3314
  if (!innobase_build_index_translation(getTable(), ib_table, share)) {
3459
3315
    errmsg_printf(error::ERROR, "Build InnoDB index translation table for"
3460
 
                    " Table %s failed", identifier.getPath().c_str());
 
3316
                    " Table %s failed", identifier.getKeyPath().c_str());
3461
3317
  }
3462
3318
 
3463
3319
  /* Allocate a buffer for a 'row reference'. A row reference is
5821
5677
 
5822
5678
    if (!col_type) {
5823
5679
      push_warning_printf(
5824
 
                          (Session*) trx->mysql_thd,
 
5680
                          trx->mysql_thd,
5825
5681
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
5826
5682
                          ER_CANT_CREATE_TABLE,
5827
5683
                          "Error creating table '%s' with "
5855
5711
        /* in data0type.h we assume that the
5856
5712
        number fits in one byte in prtype */
5857
5713
        push_warning_printf(
5858
 
          (Session*) trx->mysql_thd,
 
5714
          trx->mysql_thd,
5859
5715
          DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5860
5716
          ER_CANT_CREATE_TABLE,
5861
5717
          "In InnoDB, charset-collation codes"
6130
5986
  trx_t*    trx;
6131
5987
  int   primary_key_no;
6132
5988
  uint    i;
6133
 
  char    name2[FN_REFLEN];
6134
 
  char    norm_name[FN_REFLEN];
6135
5989
  ib_int64_t  auto_inc_value;
6136
5990
  ulint   iflags;
6137
5991
  /* Cache the value of innodb_file_format, in case it is
6141
5995
  const char* stmt;
6142
5996
  size_t stmt_len;
6143
5997
 
6144
 
  const char *table_name= identifier.getPath().c_str();
6145
 
 
6146
5998
  if (form.getShare()->sizeFields() > 1000) {
6147
5999
    /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
6148
6000
      but we play safe here */
6164
6016
 
6165
6017
  srv_lower_case_table_names = TRUE;
6166
6018
 
6167
 
  strcpy(name2, table_name);
6168
 
 
6169
 
  normalize_table_name(norm_name, name2);
6170
 
 
6171
6019
  /* Latch the InnoDB data dictionary exclusively so that no deadlocks
6172
6020
    or lock waits can happen in it during a table create operation.
6173
6021
    Drop table etc. do this latching in row0mysql.c. */
6275
6123
  if (lex_identified_temp_table)
6276
6124
    iflags |= DICT_TF2_TEMPORARY << DICT_TF2_SHIFT;
6277
6125
 
6278
 
  error= create_table_def(trx, &form, norm_name,
6279
 
                          lex_identified_temp_table ? name2 : NULL,
 
6126
  error= create_table_def(trx, &form, identifier.getKeyPath().c_str(),
 
6127
                          lex_identified_temp_table ? identifier.getKeyPath().c_str() : NULL,
6280
6128
                          iflags);
6281
6129
 
6282
6130
  session.setXaId(trx->id);
6292
6140
      order the rows by their row id which is internally generated
6293
6141
      by InnoDB */
6294
6142
 
6295
 
    error = create_clustered_index_when_no_primary(trx, iflags, norm_name);
 
6143
    error = create_clustered_index_when_no_primary(trx, iflags, identifier.getKeyPath().c_str());
6296
6144
    if (error) {
6297
6145
      goto cleanup;
6298
6146
    }
6300
6148
 
6301
6149
  if (primary_key_no != -1) {
6302
6150
    /* In InnoDB the clustered index must always be created first */
6303
 
    if ((error = create_index(trx, &form, iflags, norm_name,
 
6151
    if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
6304
6152
                              (uint) primary_key_no))) {
6305
6153
      goto cleanup;
6306
6154
    }
6309
6157
  for (i = 0; i < form.getShare()->sizeKeys(); i++) {
6310
6158
    if (i != (uint) primary_key_no) {
6311
6159
 
6312
 
      if ((error = create_index(trx, &form, iflags, norm_name,
 
6160
      if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
6313
6161
                                i))) {
6314
6162
        goto cleanup;
6315
6163
      }
6316
6164
    }
6317
6165
  }
6318
6166
 
6319
 
  stmt = innobase_get_stmt(&session, &stmt_len);
 
6167
  stmt= session.getQueryStringCopy(stmt_len);
6320
6168
 
6321
6169
  if (stmt) {
6322
6170
    string generated_create_table;
6332
6180
 
6333
6181
    error = row_table_add_foreign_constraints(trx,
6334
6182
                                              query, strlen(query),
6335
 
                                              norm_name,
 
6183
                                              identifier.getKeyPath().c_str(),
6336
6184
                                              lex_identified_temp_table);
6337
6185
    switch (error) {
6338
6186
 
6343
6191
                          "Create table '%s' with foreign key constraint"
6344
6192
                          " failed. There is no index in the referenced"
6345
6193
                          " table where the referenced columns appear"
6346
 
                          " as the first columns.\n", norm_name);
 
6194
                          " as the first columns.\n", identifier.getKeyPath().c_str());
6347
6195
      break;
6348
6196
 
6349
6197
    case DB_CHILD_NO_INDEX:
6353
6201
                          "Create table '%s' with foreign key constraint"
6354
6202
                          " failed. There is no index in the referencing"
6355
6203
                          " table where referencing columns appear"
6356
 
                          " as the first columns.\n", norm_name);
 
6204
                          " as the first columns.\n", identifier.getKeyPath().c_str());
6357
6205
      break;
6358
6206
    }
6359
6207
 
6374
6222
 
6375
6223
  log_buffer_flush_to_disk();
6376
6224
 
6377
 
  innobase_table = dict_table_get(norm_name, FALSE);
 
6225
  innobase_table = dict_table_get(identifier.getKeyPath().c_str(), FALSE);
6378
6226
 
6379
6227
  assert(innobase_table != 0);
6380
6228
 
6530
6378
  int error;
6531
6379
  trx_t*  parent_trx;
6532
6380
  trx_t*  trx;
6533
 
  char  norm_name[1000];
6534
6381
 
6535
6382
  ut_a(identifier.getPath().length() < 1000);
6536
6383
 
6537
 
  /* Strangely, MySQL passes the table name without the '.frm'
6538
 
    extension, in contrast to ::create */
6539
 
  normalize_table_name(norm_name, identifier.getPath().c_str());
6540
 
 
6541
6384
  /* Get the transaction associated with the current session, or create one
6542
6385
    if not yet created */
6543
6386
 
6554
6397
 
6555
6398
  /* Drop the table in InnoDB */
6556
6399
 
6557
 
  error = row_drop_table_for_mysql(norm_name, trx,
 
6400
  error = row_drop_table_for_mysql(identifier.getKeyPath().c_str(), trx,
6558
6401
                                   session_sql_command(&session)
6559
6402
                                   == SQLCOM_DROP_DB);
6560
6403
 
6703
6546
innobase_rename_table(
6704
6547
/*==================*/
6705
6548
  trx_t*    trx,  /*!< in: transaction */
6706
 
  const char* from, /*!< in: old name of the table */
6707
 
  const char* to, /*!< in: new name of the table */
 
6549
  const identifier::Table &from,
 
6550
  const identifier::Table &to,
6708
6551
  ibool   lock_and_commit)
6709
6552
        /*!< in: TRUE=lock data dictionary and commit */
6710
6553
{
6711
6554
  int error;
6712
 
  char norm_to[FN_REFLEN];
6713
 
  char norm_from[FN_REFLEN];
6714
6555
 
6715
6556
  srv_lower_case_table_names = TRUE;
6716
6557
 
6717
 
  normalize_table_name(norm_to, to);
6718
 
  normalize_table_name(norm_from, from);
6719
 
 
6720
6558
  /* Serialize data dictionary operations with dictionary mutex:
6721
6559
  no deadlocks can occur then in these operations */
6722
6560
 
6724
6562
    row_mysql_lock_data_dictionary(trx);
6725
6563
  }
6726
6564
 
6727
 
  error = row_rename_table_for_mysql(
6728
 
    norm_from, norm_to, trx, lock_and_commit);
 
6565
  error = row_rename_table_for_mysql(from.getKeyPath().c_str(), to.getKeyPath().c_str(), trx, lock_and_commit);
6729
6566
 
6730
6567
  if (error != DB_SUCCESS) {
6731
6568
    FILE* ef = dict_foreign_err_file;
6732
6569
 
6733
6570
    fputs("InnoDB: Renaming table ", ef);
6734
 
    ut_print_name(ef, trx, TRUE, norm_from);
 
6571
    ut_print_name(ef, trx, TRUE, from.getKeyPath().c_str());
6735
6572
    fputs(" to ", ef);
6736
 
    ut_print_name(ef, trx, TRUE, norm_to);
 
6573
    ut_print_name(ef, trx, TRUE, to.getKeyPath().c_str());
6737
6574
    fputs(" failed!\n", ef);
6738
6575
  }
6739
6576
 
6778
6615
 
6779
6616
  trx = innobase_trx_allocate(&session);
6780
6617
 
6781
 
  error = innobase_rename_table(trx, from.getPath().c_str(), to.getPath().c_str(), TRUE);
 
6618
  error = innobase_rename_table(trx, from, to, TRUE);
6782
6619
 
6783
6620
  session.setXaId(trx->id);
6784
6621
 
6803
6640
     is the one we are trying to rename to) and return the generic
6804
6641
     error code. */
6805
6642
  if (error == (int) DB_DUPLICATE_KEY) {
6806
 
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to.getPath().c_str());
 
6643
    my_error(ER_TABLE_EXISTS_ERROR, to);
6807
6644
    error = DB_ERROR;
6808
6645
  }
6809
6646
 
8390
8227
static INNOBASE_SHARE* get_share(const char* table_name)
8391
8228
{
8392
8229
  INNOBASE_SHARE *share;
8393
 
  pthread_mutex_lock(&innobase_share_mutex);
 
8230
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
8394
8231
 
8395
8232
  ulint fold = ut_fold_string(table_name);
8396
8233
 
8417
8254
  }
8418
8255
 
8419
8256
  share->use_count++;
8420
 
  pthread_mutex_unlock(&innobase_share_mutex);
8421
8257
 
8422
8258
  return(share);
8423
8259
}
8424
8260
 
8425
8261
static void free_share(INNOBASE_SHARE* share)
8426
8262
{
8427
 
  pthread_mutex_lock(&innobase_share_mutex);
 
8263
  boost::mutex::scoped_lock scopedLock(innobase_share_mutex);
8428
8264
 
8429
8265
#ifdef UNIV_DEBUG
8430
8266
  INNOBASE_SHARE* share2;
8453
8289
    /* TODO: invoke HASH_MIGRATE if innobase_open_tables
8454
8290
    shrinks too much */
8455
8291
  }
8456
 
 
8457
 
  pthread_mutex_unlock(&innobase_share_mutex);
8458
8292
}
8459
8293
 
8460
8294
/*****************************************************************//**
8652
8486
 
8653
8487
  if (auto_inc == 0) {
8654
8488
    ut_print_timestamp(stderr);
8655
 
    fprintf(stderr, "  InnoDB: AUTOINC next value generation "
8656
 
            "is disabled for '%s'\n", innodb_table->name);
 
8489
    errmsg_printf(error::ERROR, "  InnoDB: AUTOINC next value generation is disabled for '%s'\n", innodb_table->name);
8657
8490
  }
8658
8491
 
8659
8492
  dict_table_autoinc_unlock(innodb_table);
9450
9283
    if (innobase_strcasecmp(key->name,
9451
9284
                            innobase_index_reserve_name) == 0) {
9452
9285
      /* Push warning to drizzle */
9453
 
      push_warning_printf((Session*)trx->mysql_thd,
 
9286
      push_warning_printf(trx->mysql_thd,
9454
9287
                          DRIZZLE_ERROR::WARN_LEVEL_WARN,
9455
9288
                          ER_WRONG_NAME_FOR_INDEX,
9456
9289
                          "Cannot Create Index with name "
9476
9309
  ulint   buflen;
9477
9310
  const char* id;
9478
9311
  ulint   idlen;
9479
 
  void*   session;
 
9312
  drizzled::Session *session;
9480
9313
  ibool   file_id;
9481
9314
 
9482
9315
  const char* expected;