~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Added code necessary for building plugins dynamically.
Merged in changes from lifeless to allow autoreconf to work.
Touching plugin.ini files now triggers a rebuid - so config/autorun.sh is no
longer required to be run after touching those.
Removed the duplicate plugin names - also removed the issue that getting them
different would silently fail weirdly later.

Show diffs side-by-side

added added

removed removed

Lines of Context:
50
50
***********************************************************************/
51
51
 
52
52
/* TODO list for the InnoDB Cursor in 5.0:
 
53
  - Remove the flag trx->active_trans and look at trx->conc_state
53
54
  - fix savepoint functions to use savepoint storage area
54
55
  - Find out what kind of problems the OS X case-insensitivity causes to
55
56
    table and database names; should we 'normalize' the names like we do
56
57
    in Windows?
57
58
*/
58
59
 
59
 
#include "config.h"
60
 
 
61
 
#include <limits.h>
62
 
#include <fcntl.h>
63
 
 
 
60
#include "drizzled/server_includes.h"
64
61
#include "drizzled/error.h"
65
62
#include "drizzled/errmsg_print.h"
66
 
#include "drizzled/charset_info.h"
67
 
#include "drizzled/internal/m_string.h"
68
 
#include "drizzled/internal/my_sys.h"
69
 
#include "drizzled/my_hash.h"
 
63
#include "mystrings/m_ctype.h"
 
64
#include "mysys/my_sys.h"
 
65
#include "mysys/hash.h"
 
66
#include "mysys/mysys_err.h"
70
67
#include "drizzled/plugin.h"
71
68
#include "drizzled/show.h"
72
69
#include "drizzled/data_home.h"
73
70
#include "drizzled/error.h"
74
71
#include "drizzled/field.h"
75
 
#include "drizzled/charset.h"
76
72
#include "drizzled/session.h"
77
73
#include "drizzled/current_session.h"
78
74
#include "drizzled/table.h"
79
75
#include "drizzled/field/blob.h"
80
76
#include "drizzled/field/varstring.h"
81
77
#include "drizzled/field/timestamp.h"
82
 
#include "drizzled/plugin/xa_storage_engine.h"
83
 
#include "drizzled/plugin/daemon.h"
 
78
#include "drizzled/plugin/storage_engine.h"
 
79
#include "drizzled/plugin/info_schema_table.h"
84
80
#include "drizzled/memory/multi_malloc.h"
85
 
#include "drizzled/pthread_globals.h"
86
 
#include "drizzled/named_savepoint.h"
87
 
 
88
 
#include <drizzled/transaction_services.h>
89
81
 
90
82
/** @file ha_innodb.cc */
91
83
 
123
115
}
124
116
 
125
117
#include "ha_innodb.h"
126
 
#include "data_dictionary.h"
 
118
#include "i_s.h"
127
119
#include "handler0vars.h"
128
120
 
129
 
#include <iostream>
130
 
#include <sstream>
131
121
#include <string>
132
122
 
133
 
#include "plugin/innobase/handler/status_function.h"
134
 
 
135
123
using namespace std;
136
 
using namespace drizzled;
 
124
 
137
125
 
138
126
#ifndef DRIZZLE_SERVER
139
127
/* This is needed because of Bug #3596.  Let us hope that pthread_mutex_t
164
152
# define EQ_CURRENT_SESSION(session) ((session) == current_session)
165
153
#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
166
154
 
167
 
static plugin::XaStorageEngine* innodb_engine_ptr= NULL;
168
 
static plugin::TableFunction* status_table_function_ptr= NULL;
169
 
static plugin::TableFunction* cmp_tool= NULL;
170
 
static plugin::TableFunction* cmp_reset_tool= NULL;
171
 
static plugin::TableFunction* cmp_mem_tool= NULL;
172
 
static plugin::TableFunction* cmp_mem_reset_tool= NULL;
173
 
static plugin::TableFunction* innodb_trx_tool= NULL;
174
 
static plugin::TableFunction* innodb_locks_tool= NULL;
175
 
static plugin::TableFunction* innodb_lock_waits_tool= NULL;
 
155
static drizzled::plugin::StorageEngine* innodb_engine_ptr= NULL;
176
156
 
177
157
static const long AUTOINC_OLD_STYLE_LOCKING = 0;
178
158
static const long AUTOINC_NEW_STYLE_LOCKING = 1;
220
200
#endif /* UNIV_LOG_ARCHIVE */
221
201
static my_bool  innobase_use_doublewrite                = TRUE;
222
202
static my_bool  innobase_use_checksums                  = TRUE;
 
203
static my_bool  innobase_locks_unsafe_for_binlog        = TRUE;
223
204
static my_bool  innobase_rollback_on_timeout            = FALSE;
224
205
static my_bool  innobase_create_status_file             = FALSE;
225
206
static my_bool  innobase_stats_on_metadata              = TRUE;
258
239
static INNOBASE_SHARE *get_share(const char *table_name);
259
240
static void free_share(INNOBASE_SHARE *share);
260
241
 
261
 
class InnobaseEngine : public plugin::XaStorageEngine
 
242
class InnobaseEngine : public drizzled::plugin::StorageEngine
262
243
{
263
244
public:
264
 
  explicit InnobaseEngine(string name_arg) :
265
 
    plugin::XaStorageEngine(name_arg,
266
 
                            HTON_NULL_IN_KEY |
267
 
                            HTON_CAN_INDEX_BLOBS |
268
 
                            HTON_PRIMARY_KEY_REQUIRED_FOR_POSITION |
269
 
                            HTON_PRIMARY_KEY_IN_READ_INDEX |
270
 
                            HTON_PARTIAL_COLUMN_READ |
271
 
                            HTON_TABLE_SCAN_ON_INDEX |
272
 
                            HTON_HAS_DOES_TRANSACTIONS)
 
245
  InnobaseEngine(string name_arg)
 
246
   : drizzled::plugin::StorageEngine(name_arg,
 
247
                                     HTON_HAS_DOES_TRANSACTIONS, sizeof(trx_named_savept_t))
273
248
  {
274
 
    table_definition_ext= plugin::DEFAULT_DEFINITION_FILE_EXT;
 
249
    table_definition_ext= drizzled::plugin::DEFAULT_DEFINITION_FILE_EXT;
275
250
    addAlias("INNOBASE");
276
251
  }
277
252
 
278
 
  virtual ~InnobaseEngine()
279
 
  {
280
 
    int err= 0;
281
 
    if (innodb_inited) {
282
 
 
283
 
      srv_fast_shutdown = (ulint) innobase_fast_shutdown;
284
 
      innodb_inited = 0;
285
 
      hash_table_free(innobase_open_tables);
286
 
      innobase_open_tables = NULL;
287
 
      if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
288
 
        err = 1;
289
 
      }
290
 
      srv_free_paths_and_sizes();
291
 
      if (internal_innobase_data_file_path)
292
 
        free(internal_innobase_data_file_path);
293
 
      pthread_mutex_destroy(&innobase_share_mutex);
294
 
      pthread_mutex_destroy(&prepare_commit_mutex);
295
 
      pthread_mutex_destroy(&commit_threads_m);
296
 
      pthread_mutex_destroy(&commit_cond_m);
297
 
      pthread_cond_destroy(&commit_cond);
298
 
    }
299
 
  }
300
 
 
301
 
private:
302
 
  virtual int doStartTransaction(Session *session, start_transaction_option_t options);
303
 
  virtual void doStartStatement(Session *session);
304
 
  virtual void doEndStatement(Session *session);
305
 
public:
306
253
  virtual
307
254
  int
308
255
  close_connection(
311
258
        Session*        session);       /* in: handle to the MySQL thread of the user
312
259
                        whose resources should be free'd */
313
260
 
314
 
  virtual int doSetSavepoint(Session* session,
315
 
                                 drizzled::NamedSavepoint &savepoint);
316
 
  virtual int doRollbackToSavepoint(Session* session,
317
 
                                     drizzled::NamedSavepoint &savepoint);
318
 
  virtual int doReleaseSavepoint(Session* session,
319
 
                                     drizzled::NamedSavepoint &savepoint);
320
 
  virtual int doXaCommit(Session* session, bool all)
321
 
  {
322
 
    return doCommit(session, all); /* XA commit just does a SQL COMMIT */
323
 
  }
324
 
  virtual int doXaRollback(Session *session, bool all)
325
 
  {
326
 
    return doRollback(session, all); /* XA rollback just does a SQL ROLLBACK */
327
 
  }
328
 
  virtual int doCommit(Session* session, bool all);
329
 
  virtual int doRollback(Session* session, bool all);
 
261
  virtual int savepoint_set_hook(Session* session,
 
262
                                 void *savepoint);
 
263
  virtual int savepoint_rollback_hook(Session* session, 
 
264
                                      void *savepoint);
 
265
  virtual int savepoint_release_hook(Session* session, 
 
266
                                     void *savepoint);
 
267
  virtual int commit(Session* session, bool all);
 
268
  virtual int rollback(Session* session, bool all);
330
269
 
331
270
  /***********************************************************************
332
271
  This function is used to prepare X/Open XA distributed transaction   */
333
272
  virtual
334
273
  int
335
 
  doXaPrepare(
 
274
  prepare(
336
275
  /*================*/
337
276
                        /* out: 0 or error number */
338
277
        Session*        session,        /* in: handle to the MySQL thread of the user
343
282
  This function is used to recover X/Open XA distributed transactions   */
344
283
  virtual
345
284
  int
346
 
  doXaRecover(
 
285
  recover(
347
286
  /*================*/
348
287
                                /* out: number of prepared transactions
349
288
                                stored in xid_list */
350
 
        ::drizzled::XID*        xid_list,       /* in/out: prepared transactions */
351
 
        size_t len);            /* in: number of slots in xid_list */
 
289
        XID*    xid_list,       /* in/out: prepared transactions */
 
290
        uint    len);           /* in: number of slots in xid_list */
352
291
  /***********************************************************************
353
292
  This function is used to commit one X/Open XA distributed transaction
354
293
  which is in the prepared state */
355
294
  virtual
356
295
  int
357
 
  doXaCommitXid(
 
296
  commit_by_xid(
358
297
  /*===================*/
359
298
                        /* out: 0 or error number */
360
 
        ::drizzled::XID*        xid);   /* in: X/Open XA transaction identification */
 
299
        XID*    xid);   /* in: X/Open XA transaction identification */
361
300
  /***********************************************************************
362
301
  This function is used to rollback one X/Open XA distributed transaction
363
302
  which is in the prepared state */
364
303
  virtual
365
304
  int
366
 
  doXaRollbackXid(
 
305
  rollback_by_xid(
367
306
  /*=====================*/
368
307
                        /* out: 0 or error number */
369
 
        ::drizzled::XID *xid);  /* in: X/Open XA transaction identification */
 
308
        XID     *xid);  /* in: X/Open XA transaction identification */
370
309
 
371
 
  virtual Cursor *create(TableShare &table,
372
 
                         memory::Root *mem_root)
 
310
  virtual Cursor *create(TableShare *table,
 
311
                          MEM_ROOT *mem_root)
373
312
  {
374
 
    return new (mem_root) ha_innobase(*this, table);
 
313
    return new (mem_root) ha_innobase(this, table);
375
314
  }
376
315
 
377
316
  /*********************************************************************
378
317
  Removes all tables in the named database inside InnoDB. */
379
 
  bool
380
 
  doDropSchema(
 
318
  virtual
 
319
  void
 
320
  drop_database(
381
321
  /*===================*/
382
322
                        /* out: error number */
383
 
        const std::string       &schema_name);  /* in: database path; inside InnoDB the name
 
323
        char*   path);  /* in: database path; inside InnoDB the name
384
324
                        of the last directory in the path is used as
385
325
                        the database name: for example, in 'mysql/data/test'
386
326
                        the database name is 'test' */
387
327
 
 
328
  /*********************************************************************
 
329
  Creates an InnoDB transaction struct for the session if it does not yet have one.
 
330
  Starts a new InnoDB transaction if a transaction is not yet started. And
 
331
  assigns a new snapshot for a consistent read if the transaction does not yet
 
332
  have one. */
 
333
  virtual
 
334
  int
 
335
  start_consistent_snapshot(
 
336
  /*====================================*/
 
337
                        /* out: 0 */
 
338
        Session*        session);       /* in: MySQL thread handle of the user for whom
 
339
                        the transaction should be committed */
388
340
  /********************************************************************
389
341
  Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
390
342
  the logs, and the name of this function should be innobase_checkpoint. */
407
359
 
408
360
  virtual
409
361
  int
410
 
  doReleaseTemporaryLatches(
 
362
  release_temporary_latches(
411
363
  /*===============================*/
412
364
                                /* out: 0 */
413
365
        Session*                session);       /* in: MySQL thread */
417
369
        return(ha_innobase_exts);
418
370
  }
419
371
 
420
 
  UNIV_INTERN int doCreateTable(Session *session,
 
372
  UNIV_INTERN int doCreateTable(Session *session, 
 
373
                                const char *table_name,
421
374
                                Table& form,
422
 
                                drizzled::TableIdentifier &identifier,
423
 
                                message::Table&);
 
375
                                HA_CREATE_INFO& create_info,
 
376
                                drizzled::message::Table&);
424
377
  UNIV_INTERN int doRenameTable(Session* session,
425
 
                                const char* from,
 
378
                                const char* from, 
426
379
                                const char* to);
427
 
  UNIV_INTERN int doDropTable(Session& session, TableIdentifier &identifier);
428
 
 
429
 
  UNIV_INTERN virtual bool get_error_message(int error, String *buf);
430
 
 
431
 
  UNIV_INTERN uint32_t max_supported_keys() const;
432
 
  UNIV_INTERN uint32_t max_supported_key_length() const;
433
 
  UNIV_INTERN uint32_t max_supported_key_part_length() const;
434
 
 
435
 
 
436
 
  UNIV_INTERN uint32_t index_flags(enum  ha_key_alg) const
437
 
  {
438
 
    return (HA_READ_NEXT |
439
 
            HA_READ_PREV |
440
 
            HA_READ_ORDER |
441
 
            HA_READ_RANGE |
442
 
            HA_KEYREAD_ONLY);
443
 
  }
 
380
  UNIV_INTERN int doDropTable(Session& session, const string table_path);
444
381
};
445
382
 
446
383
/** @brief Initialize the default value of innodb_commit_concurrency.
495
432
innobase_commit_concurrency_validate(
496
433
/*=================================*/
497
434
        Session*                        ,       /*!< in: thread handle */
498
 
        drizzle_sys_var*        ,       /*!< in: pointer to system
 
435
        struct st_mysql_sys_var*        ,       /*!< in: pointer to system
499
436
                                                variable */
500
437
        void*                           save,   /*!< out: immediate result
501
438
                                                for update function */
502
 
        drizzle_value*          value)  /*!< in: incoming string */
 
439
        struct st_mysql_value*          value)  /*!< in: incoming string */
503
440
{
504
441
        int64_t         intbuf;
505
442
        ulong           commit_concurrency;
536
473
  NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
537
474
 
538
475
 
 
476
/***********************************************************************
 
477
Closes an InnoDB database. */
 
478
static
 
479
int
 
480
innobase_deinit(drizzled::plugin::Registry &registry);
 
481
 
539
482
/*****************************************************************//**
540
483
Commits a transaction in an InnoDB database. */
541
484
static
544
487
/*================*/
545
488
        trx_t*  trx);   /*!< in: transaction handle */
546
489
 
547
 
static drizzle_show_var innodb_status_variables[]= {
 
490
static SHOW_VAR innodb_status_variables[]= {
548
491
  {"buffer_pool_pages_data",
549
492
  (char*) &export_vars.innodb_buffer_pool_pages_data,     SHOW_LONG},
550
493
  {"buffer_pool_pages_dirty",
638
581
  {NULL, NULL, SHOW_LONG}
639
582
};
640
583
 
641
 
InnodbStatusTool::Generator::Generator(drizzled::Field **fields) :
642
 
  plugin::TableFunction::Generator(fields)
643
 
644
 
  srv_export_innodb_status();
645
 
  status_var_ptr= innodb_status_variables;
646
 
}
647
 
 
648
 
bool InnodbStatusTool::Generator::populate()
649
 
{
650
 
  if (status_var_ptr->name)
651
 
  {
652
 
    std::ostringstream oss;
653
 
    string return_value;
654
 
    const char *value= status_var_ptr->value;
655
 
 
656
 
    /* VARIABLE_NAME */
657
 
    push(status_var_ptr->name);
658
 
 
659
 
    switch (status_var_ptr->type)
660
 
    {
661
 
    case SHOW_LONG:
662
 
      oss << *(int64_t*) value;
663
 
      return_value= oss.str();
664
 
      break;
665
 
    case SHOW_LONGLONG:
666
 
      oss << *(int64_t*) value;
667
 
      return_value= oss.str();
668
 
      break;
669
 
    case SHOW_BOOL:
670
 
      return_value= *(bool*) value ? "ON" : "OFF";
671
 
      break;
672
 
    default:
673
 
      assert(0);
674
 
    }
675
 
 
676
 
    /* VARIABLE_VALUE */
677
 
    if (return_value.length())
678
 
      push(return_value);
679
 
    else 
680
 
      push(" ");
681
 
 
682
 
    status_var_ptr++;
683
 
 
684
 
    return true;
685
 
  }
686
 
  return false;
687
 
}
688
 
 
689
584
/* General functions */
690
585
 
691
586
/******************************************************************//**
831
726
/*=======*/
832
727
        Session*        session)        /*!< in: Drizzle Session */
833
728
{
834
 
        return *(trx_t**) session->getEngineData(innodb_engine_ptr);
 
729
        return(*(trx_t**) session_ha_data(session, innodb_engine_ptr));
835
730
}
836
731
 
837
732
/********************************************************************//**
840
735
documentation, see Cursor.cc.
841
736
@return 0 */
842
737
int
843
 
InnobaseEngine::doReleaseTemporaryLatches(
 
738
InnobaseEngine::release_temporary_latches(
844
739
/*===============================*/
845
740
        Session*                session)        /*!< in: MySQL thread */
846
741
{
1052
947
          static_cast<uint64_t>(session_get_thread_id( session)),
1053
948
          static_cast<uint64_t>(session->getQueryId()),
1054
949
          glob_hostname,
1055
 
          session->getSecurityContext().getIp().c_str(),
1056
 
          session->getSecurityContext().getUser().c_str()
 
950
          session->security_ctx.ip.c_str(),
 
951
          session->security_ctx.user.c_str()
1057
952
  );
1058
953
  fprintf(f,
1059
 
          "\n%s", session->getQueryString().c_str()
 
954
          "\n%s", session->getQueryString()
1060
955
  );
1061
956
        putc('\n', f);
1062
957
}
1092
987
void
1093
988
innobase_convert_from_table_id(
1094
989
/*===========================*/
1095
 
        const void*,                    /*!< in: the 'from' character set */
 
990
        const struct charset_info_st*,  /*!< in: the 'from' character set */
1096
991
        char*                   to,     /*!< out: converted identifier */
1097
992
        const char*             from,   /*!< in: identifier to convert */
1098
993
        ulint                   len)    /*!< in: length of 'to', in bytes */
1106
1001
void
1107
1002
innobase_convert_from_id(
1108
1003
/*=====================*/
1109
 
        const void*,                    /*!< in: the 'from' character set */
 
1004
        const struct charset_info_st*,  /*!< in: the 'from' character set */
1110
1005
        char*                   to,     /*!< out: converted identifier */
1111
1006
        const char*             from,   /*!< in: identifier to convert */
1112
1007
        ulint                   len)    /*!< in: length of 'to', in bytes */
1142
1037
Determines the connection character set.
1143
1038
@return connection character set */
1144
1039
extern "C" UNIV_INTERN
1145
 
const void*
 
1040
const charset_info_st*
1146
1041
innobase_get_charset(
1147
1042
/*=================*/
1148
1043
        void*   mysql_session)  /*!< in: MySQL thread handle */
1149
1044
{
1150
 
        return session_charset(static_cast<Session*>(mysql_session));
1151
 
}
1152
 
 
1153
 
extern "C" UNIV_INTERN
1154
 
bool
1155
 
innobase_isspace(
1156
 
        const void *cs,
1157
 
        char char_to_test)
1158
 
{
1159
 
        return my_isspace(static_cast<const CHARSET_INFO *>(cs), char_to_test);
1160
 
}
1161
 
 
1162
 
UNIV_INTERN
1163
 
int
1164
 
innobase_fast_mutex_init(
1165
 
        os_fast_mutex_t*        fast_mutex)
1166
 
{
1167
 
        return pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
 
1045
        return(session_charset(static_cast<Session*>(mysql_session)));
1168
1046
}
1169
1047
 
1170
1048
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1265
1143
/*========================*/
1266
1144
{
1267
1145
        int     fd2 = -1;
1268
 
        int     fd = mysql_tmpfile("ib");
 
1146
        File    fd = mysql_tmpfile("ib");
1269
1147
        if (fd >= 0) {
1270
1148
                /* Copy the file descriptor, so that the additional resources
1271
1149
                allocated by create_temp_file() can be freed by invoking
1272
 
                internal::my_close().
 
1150
                my_close().
1273
1151
 
1274
1152
                Because the file descriptor returned by this function
1275
1153
                will be passed to fdopen(), it will be closed by invoking
1276
1154
                fclose(), which in turn will invoke close() instead of
1277
 
                internal::my_close(). */
 
1155
                my_close(). */
1278
1156
                fd2 = dup(fd);
1279
1157
                if (fd2 < 0) {
1280
 
                        errno=errno;
 
1158
                        my_errno=errno;
1281
1159
                        my_error(EE_OUT_OF_FILERESOURCES,
1282
1160
                                 MYF(ME_BELL+ME_WAITTANG),
1283
 
                                 "ib*", errno);
 
1161
                                 "ib*", my_errno);
1284
1162
                }
1285
 
                internal::my_close(fd, MYF(MY_WME));
 
1163
                my_close(fd, MYF(MY_WME));
1286
1164
        }
1287
1165
        return(fd2);
1288
1166
}
1433
1311
        trx = trx_allocate_for_mysql();
1434
1312
 
1435
1313
        trx->mysql_thd = session;
1436
 
        trx->mysql_query_str = session->query.c_str();
 
1314
        trx->mysql_query_str = session_query(session);
1437
1315
 
1438
1316
        innobase_trx_init(session, trx);
1439
1317
 
1471
1349
/*********************************************************************//**
1472
1350
Construct ha_innobase Cursor. */
1473
1351
UNIV_INTERN
1474
 
ha_innobase::ha_innobase(plugin::StorageEngine &engine_arg,
1475
 
                         TableShare &table_arg)
 
1352
ha_innobase::ha_innobase(drizzled::plugin::StorageEngine *engine_arg,
 
1353
                         TableShare *table_arg)
1476
1354
  :Cursor(engine_arg, table_arg),
 
1355
  int_table_flags(HA_REC_NOT_IN_SEQ |
 
1356
                  HA_NULL_IN_KEY |
 
1357
                  HA_CAN_INDEX_BLOBS |
 
1358
                  HA_PRIMARY_KEY_REQUIRED_FOR_POSITION |
 
1359
                  HA_PRIMARY_KEY_IN_READ_INDEX |
 
1360
                  HA_PARTIAL_COLUMN_READ |
 
1361
                  HA_TABLE_SCAN_ON_INDEX | 
 
1362
                  HA_MRR_CANT_SORT),
1477
1363
  primary_key(0), /* needs initialization because index_flags() may be called 
1478
1364
                     before this is set to the real value. It's ok to have any 
1479
1365
                     value here because it doesn't matter if we return the
1525
1411
        update_session(session);
1526
1412
}
1527
1413
 
 
1414
/*********************************************************************//**
 
1415
Registers that InnoDB takes part in an SQL statement, so that MySQL knows to
 
1416
roll back the statement if the statement results in an error. This MUST be
 
1417
called for every SQL statement that may be rolled back by MySQL. Calling this
 
1418
several times to register the same statement is allowed, too. */
 
1419
static inline
 
1420
void
 
1421
innobase_register_stmt(
 
1422
/*===================*/
 
1423
        drizzled::plugin::StorageEngine*        engine, /*!< in: Innobase hton */
 
1424
        Session*        session)        /*!< in: MySQL thd (connection) object */
 
1425
{
 
1426
        assert(engine == innodb_engine_ptr);
 
1427
        /* Register the statement */
 
1428
        trans_register_ha(session, FALSE, engine);
 
1429
}
 
1430
 
 
1431
/*********************************************************************//**
 
1432
Registers an InnoDB transaction in MySQL, so that the MySQL XA code knows
 
1433
to call the InnoDB prepare and commit, or rollback for the transaction. This
 
1434
MUST be called for every transaction for which the user may call commit or
 
1435
rollback. Calling this several times to register the same transaction is
 
1436
allowed, too.
 
1437
This function also registers the current SQL statement. */
 
1438
static inline
 
1439
void
 
1440
innobase_register_trx_and_stmt(
 
1441
/*===========================*/
 
1442
        drizzled::plugin::StorageEngine *engine, /*!< in: Innobase StorageEngine */
 
1443
        Session*        session)        /*!< in: MySQL thd (connection) object */
 
1444
{
 
1445
        /* NOTE that actually innobase_register_stmt() registers also
 
1446
        the transaction in the AUTOCOMMIT=1 mode. */
 
1447
 
 
1448
        innobase_register_stmt(engine, session);
 
1449
 
 
1450
        if (session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
 
1451
 
 
1452
                /* No autocommit mode, register for a transaction */
 
1453
                trans_register_ha(session, TRUE, engine);
 
1454
        }
 
1455
}
 
1456
 
1528
1457
/*****************************************************************//**
1529
1458
Convert an SQL identifier to the MySQL system_charset_info (UTF-8)
1530
1459
and quote it if needed.
1692
1621
        prebuilt->read_just_key = 0;
1693
1622
}
1694
1623
 
 
1624
/*****************************************************************//**
 
1625
Call this when you have opened a new table handle in HANDLER, before you
 
1626
call index_read_idx() etc. Actually, we can let the cursor stay open even
 
1627
over a transaction commit! Then you should call this before every operation,
 
1628
fetch next etc. This function inits the necessary things even after a
 
1629
transaction commit. */
 
1630
UNIV_INTERN
 
1631
void
 
1632
ha_innobase::init_table_handle_for_HANDLER(void)
 
1633
/*============================================*/
 
1634
{
 
1635
        /* If current session does not yet have a trx struct, create one.
 
1636
        If the current handle does not yet have a prebuilt struct, create
 
1637
        one. Update the trx pointers in the prebuilt struct. Normally
 
1638
        this operation is done in external_lock. */
 
1639
 
 
1640
        update_session(ha_session());
 
1641
 
 
1642
        /* Initialize the prebuilt struct much like it would be inited in
 
1643
        external_lock */
 
1644
 
 
1645
        innobase_release_stat_resources(prebuilt->trx);
 
1646
 
 
1647
        /* If the transaction is not started yet, start it */
 
1648
 
 
1649
        trx_start_if_not_started(prebuilt->trx);
 
1650
 
 
1651
        /* Assign a read view if the transaction does not have it yet */
 
1652
 
 
1653
        trx_assign_read_view(prebuilt->trx);
 
1654
 
 
1655
        /* Set the MySQL flag to mark that there is an active transaction */
 
1656
 
 
1657
        if (prebuilt->trx->active_trans == 0) {
 
1658
 
 
1659
                innobase_register_trx_and_stmt(engine, user_session);
 
1660
 
 
1661
                prebuilt->trx->active_trans = 1;
 
1662
        }
 
1663
 
 
1664
        /* We did the necessary inits in this function, no need to repeat them
 
1665
        in row_search_for_mysql */
 
1666
 
 
1667
        prebuilt->sql_stat_start = FALSE;
 
1668
 
 
1669
        /* We let HANDLER always to do the reads as consistent reads, even
 
1670
        if the trx isolation level would have been specified as SERIALIZABLE */
 
1671
 
 
1672
        prebuilt->select_lock_type = LOCK_NONE;
 
1673
        prebuilt->stored_select_lock_type = LOCK_NONE;
 
1674
 
 
1675
        /* Always fetch all columns in the index record */
 
1676
 
 
1677
        prebuilt->hint_need_to_fetch_extra_cols = ROW_RETRIEVE_ALL_COLS;
 
1678
 
 
1679
        /* We want always to fetch all columns in the whole row? Or do
 
1680
        we???? */
 
1681
 
 
1682
        prebuilt->used_in_HANDLER = TRUE;
 
1683
        reset_template(prebuilt);
 
1684
}
 
1685
 
1695
1686
/*********************************************************************//**
1696
1687
Opens an InnoDB database.
1697
1688
@return 0 on success, error code on failure */
1699
1690
int
1700
1691
innobase_init(
1701
1692
/*==========*/
1702
 
        plugin::Context &context)       /*!< in: Drizzle Plugin Context */
 
1693
        drizzled::plugin::Registry      &registry)      /*!< in: Drizzle Plugin Registry */
1703
1694
{
1704
1695
        static char     current_dir[3];         /*!< Set if using current lib */
1705
1696
        int             err;
1709
1700
 
1710
1701
        innodb_engine_ptr= new InnobaseEngine(innobase_engine_name);
1711
1702
 
 
1703
 
1712
1704
        ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)DRIZZLE_TYPE_VARCHAR);
1713
1705
 
1714
1706
#ifdef UNIV_DEBUG
1748
1740
                }
1749
1741
        }
1750
1742
 
1751
 
        os_innodb_umask = (ulint)internal::my_umask;
 
1743
        os_innodb_umask = (ulint)my_umask;
1752
1744
 
1753
1745
        /* First calculate the default path for innodb_data_home_dir etc.,
1754
1746
        in case the user has not given any value.
1942
1934
 
1943
1935
        row_rollback_on_timeout = (ibool) innobase_rollback_on_timeout;
1944
1936
 
1945
 
        srv_locks_unsafe_for_binlog = (ibool) TRUE;
 
1937
        srv_locks_unsafe_for_binlog = (ibool) innobase_locks_unsafe_for_binlog;
1946
1938
 
1947
1939
        srv_max_n_open_files = (ulint) innobase_open_files;
1948
1940
        srv_innodb_status = (ibool) innobase_create_status_file;
1977
1969
        pthread_cond_init(&commit_cond, NULL);
1978
1970
        innodb_inited= 1;
1979
1971
 
1980
 
        status_table_function_ptr= new InnodbStatusTool;
1981
 
 
1982
 
        context.add(innodb_engine_ptr);
1983
 
 
1984
 
        context.add(status_table_function_ptr);
1985
 
 
1986
 
        cmp_tool= new(std::nothrow)CmpTool(false);
1987
 
        context.add(cmp_tool);
1988
 
 
1989
 
        cmp_reset_tool= new(std::nothrow)CmpTool(true);
1990
 
        context.add(cmp_reset_tool);
1991
 
 
1992
 
        cmp_mem_tool= new(std::nothrow)CmpmemTool(false);
1993
 
        context.add(cmp_mem_tool);
1994
 
 
1995
 
        cmp_mem_reset_tool= new(std::nothrow)CmpmemTool(true);
1996
 
        context.add(cmp_mem_reset_tool);
1997
 
 
1998
 
        innodb_trx_tool= new(std::nothrow)InnodbTrxTool("INNODB_TRX");
1999
 
        context.add(innodb_trx_tool);
2000
 
 
2001
 
        innodb_locks_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCKS");
2002
 
        context.add(innodb_locks_tool);
2003
 
 
2004
 
        innodb_lock_waits_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS");
2005
 
        context.add(innodb_lock_waits_tool);
 
1972
        if (innodb_locks_init() ||
 
1973
                innodb_trx_init() ||
 
1974
                innodb_lock_waits_init() ||
 
1975
                i_s_cmp_init() ||
 
1976
                i_s_cmp_reset_init() ||
 
1977
                i_s_cmpmem_init() ||
 
1978
                i_s_cmpmem_reset_init())
 
1979
                goto error;
 
1980
 
 
1981
        registry.add(innodb_engine_ptr);
 
1982
 
 
1983
        registry.add(innodb_trx_schema_table);
 
1984
        registry.add(innodb_locks_schema_table);
 
1985
        registry.add(innodb_lock_waits_schema_table);   
 
1986
        registry.add(innodb_cmp_schema_table);
 
1987
        registry.add(innodb_cmp_reset_schema_table);
 
1988
        registry.add(innodb_cmpmem_schema_table);
 
1989
        registry.add(innodb_cmpmem_reset_schema_table);
2006
1990
 
2007
1991
        /* Get the current high water mark format. */
2008
1992
        innobase_file_format_check = (char*) trx_sys_file_format_max_get();
2012
1996
        return(TRUE);
2013
1997
}
2014
1998
 
 
1999
/*******************************************************************//**
 
2000
Closes an InnoDB database.
 
2001
@return TRUE if error */
 
2002
static
 
2003
int
 
2004
innobase_deinit(drizzled::plugin::Registry &registry)
 
2005
{
 
2006
        int     err= 0;
 
2007
        i_s_common_deinit(registry);
 
2008
        registry.remove(innodb_engine_ptr);
 
2009
        delete innodb_engine_ptr;
 
2010
 
 
2011
        if (innodb_inited) {
 
2012
 
 
2013
                srv_fast_shutdown = (ulint) innobase_fast_shutdown;
 
2014
                innodb_inited = 0;
 
2015
                hash_table_free(innobase_open_tables);
 
2016
                innobase_open_tables = NULL;
 
2017
                if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
 
2018
                        err = 1;
 
2019
                }
 
2020
                srv_free_paths_and_sizes();
 
2021
                if (internal_innobase_data_file_path)
 
2022
                  free(internal_innobase_data_file_path);
 
2023
                pthread_mutex_destroy(&innobase_share_mutex);
 
2024
                pthread_mutex_destroy(&prepare_commit_mutex);
 
2025
                pthread_mutex_destroy(&commit_threads_m);
 
2026
                pthread_mutex_destroy(&commit_cond_m);
 
2027
                pthread_cond_destroy(&commit_cond);
 
2028
        }
 
2029
 
 
2030
        return(err);
 
2031
}
2015
2032
 
2016
2033
/****************************************************************//**
2017
2034
Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
2053
2070
have one.
2054
2071
@return 0 */
2055
2072
int
2056
 
InnobaseEngine::doStartTransaction(
 
2073
InnobaseEngine::start_consistent_snapshot(
2057
2074
/*====================================*/
2058
 
        Session*        session,        /*!< in: MySQL thread handle of the user for whom
2059
 
                                                 the transaction should be committed */
2060
 
  start_transaction_option_t options)
 
2075
        Session*        session)        /*!< in: MySQL thread handle of the user for whom
 
2076
                        the transaction should be committed */
2061
2077
{
 
2078
        trx_t*  trx;
 
2079
 
2062
2080
        assert(this == innodb_engine_ptr);
2063
2081
 
2064
2082
        /* Create a new trx struct for session, if it does not yet have one */
2065
 
        trx_t *trx = check_trx_exists(session);
 
2083
 
 
2084
        trx = check_trx_exists(session);
2066
2085
 
2067
2086
        /* This is just to play safe: release a possible FIFO ticket and
2068
2087
        search latch. Since we will reserve the kernel mutex, we have to
2069
2088
        release the search system latch first to obey the latching order. */
 
2089
 
2070
2090
        innobase_release_stat_resources(trx);
2071
2091
 
2072
2092
        /* If the transaction is not started yet, start it */
 
2093
 
2073
2094
        trx_start_if_not_started(trx);
2074
2095
 
2075
2096
        /* Assign a read view if the transaction does not have it yet */
2076
 
  if (options == START_TRANS_OPT_WITH_CONS_SNAPSHOT)
2077
 
          trx_assign_read_view(trx);
2078
 
 
2079
 
        return 0;
 
2097
 
 
2098
        trx_assign_read_view(trx);
 
2099
 
 
2100
        /* Set the MySQL flag to mark that there is an active transaction */
 
2101
 
 
2102
        if (trx->active_trans == 0) {
 
2103
                innobase_register_trx_and_stmt(this, current_session);
 
2104
                trx->active_trans = 1;
 
2105
        }
 
2106
 
 
2107
        return(0);
2080
2108
}
2081
2109
 
2082
2110
/*****************************************************************//**
2084
2112
ended.
2085
2113
@return 0 */
2086
2114
int
2087
 
InnobaseEngine::doCommit(
 
2115
InnobaseEngine::commit(
2088
2116
/*============*/
2089
2117
        Session*        session,        /*!< in: MySQL thread handle of the user for whom
2090
2118
                        the transaction should be committed */
2104
2132
                trx_search_latch_release_if_reserved(trx);
2105
2133
        }
2106
2134
 
 
2135
        /* The flag trx->active_trans is set to 1 in
 
2136
 
 
2137
        1. ::external_lock(),
 
2138
        2. ::start_stmt(),
 
2139
        3. innobase_query_caching_of_table_permitted(),
 
2140
        4. InnobaseEngine::savepoint_set(),
 
2141
        5. ::init_table_handle_for_HANDLER(),
 
2142
        6. InnobaseEngine::start_consistent_snapshot(),
 
2143
 
 
2144
        and it is only set to 0 in a commit or a rollback. If it is 0 we know
 
2145
        there cannot be resources to be freed and we could return immediately.
 
2146
        For the time being, we play safe and do the cleanup though there should
 
2147
        be nothing to clean up. */
 
2148
 
 
2149
        if (trx->active_trans == 0
 
2150
                && trx->conc_state != TRX_NOT_STARTED) {
 
2151
 
 
2152
                errmsg_printf(ERRMSG_LVL_ERROR, "trx->active_trans == 0, but"
 
2153
                        " trx->conc_state != TRX_NOT_STARTED");
 
2154
        }
2107
2155
        if (all
2108
2156
                || (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
2109
2157
 
2150
2198
                        pthread_mutex_unlock(&commit_cond_m);
2151
2199
                }
2152
2200
 
2153
 
                if (trx->conc_state == TRX_PREPARED) {
 
2201
                if (trx->active_trans == 2) {
2154
2202
 
2155
2203
                        pthread_mutex_unlock(&prepare_commit_mutex);
2156
2204
                }
2157
2205
 
2158
2206
                /* Now do a write + flush of logs. */
2159
2207
                trx_commit_complete_for_mysql(trx);
 
2208
                trx->active_trans = 0;
2160
2209
 
2161
2210
        } else {
2162
2211
                /* We just mark the SQL statement ended and do not do a
2193
2242
Rolls back a transaction or the latest SQL statement.
2194
2243
@return 0 or error number */
2195
2244
int
2196
 
InnobaseEngine::doRollback(
 
2245
InnobaseEngine::rollback(
2197
2246
/*==============*/
2198
2247
        Session*        session,/*!< in: handle to the MySQL thread of the user
2199
2248
                        whose transaction should be rolled back */
2223
2272
                || !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
2224
2273
 
2225
2274
                error = trx_rollback_for_mysql(trx);
 
2275
                trx->active_trans = 0;
2226
2276
        } else {
2227
2277
                error = trx_rollback_last_sql_stat_for_mysql(trx);
2228
2278
        }
2263
2313
@return 0 if success, HA_ERR_NO_SAVEPOINT if no savepoint with the
2264
2314
given name */
2265
2315
int
2266
 
InnobaseEngine::doRollbackToSavepoint(
 
2316
InnobaseEngine::savepoint_rollback_hook(
2267
2317
/*===========================*/
2268
2318
        Session*        session,                /*!< in: handle to the MySQL thread of the user
2269
2319
                                whose transaction should be rolled back */
2270
 
        drizzled::NamedSavepoint &named_savepoint)      /*!< in: savepoint data */
 
2320
        void*   savepoint)      /*!< in: savepoint data */
2271
2321
{
2272
2322
        ib_int64_t      mysql_binlog_cache_pos;
2273
2323
        int             error = 0;
2274
2324
        trx_t*          trx;
 
2325
        char            sp_name[64];
2275
2326
 
2276
2327
        assert(this == innodb_engine_ptr);
2277
2328
 
2283
2334
 
2284
2335
        innobase_release_stat_resources(trx);
2285
2336
 
2286
 
        error= (int)trx_rollback_to_savepoint_for_mysql(trx, named_savepoint.getName().c_str(),
2287
 
                                                        &mysql_binlog_cache_pos);
 
2337
        /* TODO: use provided savepoint data area to store savepoint data */
 
2338
 
 
2339
        int64_t2str((ulint)savepoint, sp_name, 36);
 
2340
 
 
2341
        error = (int) trx_rollback_to_savepoint_for_mysql(trx, sp_name,
 
2342
                                                &mysql_binlog_cache_pos);
2288
2343
        return(convert_error_code_to_mysql(error, 0, NULL));
2289
2344
}
2290
2345
 
2293
2348
@return 0 if success, HA_ERR_NO_SAVEPOINT if no savepoint with the
2294
2349
given name */
2295
2350
int
2296
 
InnobaseEngine::doReleaseSavepoint(
 
2351
InnobaseEngine::savepoint_release_hook(
2297
2352
/*=======================*/
2298
2353
        Session*        session,                /*!< in: handle to the MySQL thread of the user
2299
2354
                                whose transaction should be rolled back */
2300
 
        drizzled::NamedSavepoint &named_savepoint)      /*!< in: savepoint data */
 
2355
        void*   savepoint)      /*!< in: savepoint data */
2301
2356
{
2302
2357
        int             error = 0;
2303
2358
        trx_t*          trx;
 
2359
        char            sp_name[64];
2304
2360
 
2305
2361
        assert(this == innodb_engine_ptr);
2306
2362
 
2307
2363
        trx = check_trx_exists(session);
2308
2364
 
2309
 
        error = (int) trx_release_savepoint_for_mysql(trx, named_savepoint.getName().c_str());
 
2365
        /* TODO: use provided savepoint data area to store savepoint data */
 
2366
 
 
2367
        int64_t2str((ulint)savepoint, sp_name, 36);
 
2368
 
 
2369
        error = (int) trx_release_savepoint_for_mysql(trx, sp_name);
2310
2370
 
2311
2371
        return(convert_error_code_to_mysql(error, 0, NULL));
2312
2372
}
2315
2375
Sets a transaction savepoint.
2316
2376
@return always 0, that is, always succeeds */
2317
2377
int
2318
 
InnobaseEngine::doSetSavepoint(
 
2378
InnobaseEngine::savepoint_set_hook(
2319
2379
/*===============*/
2320
2380
        Session*        session,/*!< in: handle to the MySQL thread */
2321
 
        drizzled::NamedSavepoint &named_savepoint)      /*!< in: savepoint data */
 
2381
        void*   savepoint)      /*!< in: savepoint data */
2322
2382
{
2323
2383
        int     error = 0;
2324
2384
        trx_t*  trx;
2340
2400
        innobase_release_stat_resources(trx);
2341
2401
 
2342
2402
        /* cannot happen outside of transaction */
2343
 
        assert(trx->conc_state != TRX_NOT_STARTED);
2344
 
 
2345
 
        error = (int) trx_savepoint_for_mysql(trx, named_savepoint.getName().c_str(), (ib_int64_t)0);
 
2403
        assert(trx->active_trans);
 
2404
 
 
2405
        /* TODO: use provided savepoint data area to store savepoint data */
 
2406
        char sp_name[64];
 
2407
        int64_t2str((ulint)savepoint,sp_name,36);
 
2408
 
 
2409
        error = (int) trx_savepoint_for_mysql(trx, sp_name, (ib_int64_t)0);
2346
2410
 
2347
2411
        return(convert_error_code_to_mysql(error, 0, NULL));
2348
2412
}
2363
2427
 
2364
2428
        ut_a(trx);
2365
2429
 
2366
 
  assert(session->killed != Session::NOT_KILLED ||
2367
 
         trx->conc_state == TRX_NOT_STARTED);
2368
 
 
2369
 
  /* Warn if rolling back some things... */
2370
 
        if (session->killed != Session::NOT_KILLED &&
2371
 
      trx->conc_state != TRX_NOT_STARTED &&
2372
 
      trx->undo_no.low > 0 &&
2373
 
      global_system_variables.log_warnings)
2374
 
  {
2375
 
      errmsg_printf(ERRMSG_LVL_WARN, 
2376
 
      "Drizzle is closing a connection during a KILL operation\n"
2377
 
      "that has an active InnoDB transaction.  %lu row modifications will "
2378
 
      "roll back.\n",
2379
 
      (ulong) trx->undo_no.low);
2380
 
  }
 
2430
        if (trx->active_trans == 0
 
2431
                && trx->conc_state != TRX_NOT_STARTED) {
 
2432
 
 
2433
                errmsg_printf(ERRMSG_LVL_ERROR, "trx->active_trans == 0, but"
 
2434
                        " trx->conc_state != TRX_NOT_STARTED");
 
2435
        }
 
2436
 
 
2437
 
 
2438
        if (trx->conc_state != TRX_NOT_STARTED &&
 
2439
                global_system_variables.log_warnings) {
 
2440
                errmsg_printf(ERRMSG_LVL_WARN, 
 
2441
                        "MySQL is closing a connection that has an active "
 
2442
                        "InnoDB transaction.  %lu row modifications will "
 
2443
                        "roll back.",
 
2444
                        (ulong) trx->undo_no.low);
 
2445
        }
2381
2446
 
2382
2447
        innobase_rollback_trx(trx);
2383
2448
 
2429
2494
}
2430
2495
 
2431
2496
 
 
2497
 
 
2498
/****************************************************************//**
 
2499
Get the table flags to use for the statement.
 
2500
@return table flags */
 
2501
UNIV_INTERN
 
2502
Cursor::Table_flags
 
2503
ha_innobase::table_flags() const
 
2504
/*============================*/
 
2505
{
 
2506
        return int_table_flags;
 
2507
}
 
2508
 
2432
2509
/****************************************************************//**
2433
2510
Returns the index type. */
2434
2511
UNIV_INTERN
2441
2518
        return("BTREE");
2442
2519
}
2443
2520
 
 
2521
 
 
2522
/****************************************************************//**
 
2523
Returns the operations supported for indexes.
 
2524
@return flags of supported operations */
 
2525
UNIV_INTERN
 
2526
uint32_t
 
2527
ha_innobase::index_flags(
 
2528
/*=====================*/
 
2529
        uint,
 
2530
        uint,
 
2531
        bool)
 
2532
const
 
2533
{
 
2534
        return(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER
 
2535
               | HA_READ_RANGE | HA_KEYREAD_ONLY);
 
2536
}
 
2537
 
2444
2538
/****************************************************************//**
2445
2539
Returns the maximum number of keys.
2446
2540
@return MAX_KEY */
2447
2541
UNIV_INTERN
2448
2542
uint
2449
 
InnobaseEngine::max_supported_keys() const
 
2543
ha_innobase::max_supported_keys() const
2450
2544
/*===================================*/
2451
2545
{
2452
2546
        return(MAX_KEY);
2457
2551
@return maximum supported key length, in bytes */
2458
2552
UNIV_INTERN
2459
2553
uint32_t
2460
 
InnobaseEngine::max_supported_key_length() const
 
2554
ha_innobase::max_supported_key_length() const
2461
2555
/*=========================================*/
2462
2556
{
2463
2557
        /* An InnoDB page must store >= 2 keys; a secondary key record
2618
2712
        holding btr_search_latch. This breaks the latching order as
2619
2713
        we acquire dict_sys->mutex below and leads to a deadlock. */
2620
2714
        if (session != NULL) {
2621
 
                getTransactionalEngine()->releaseTemporaryLatches(session);
 
2715
                engine->release_temporary_latches(session);
2622
2716
        }
2623
2717
 
2624
2718
        normalize_table_name(norm_name, name);
2639
2733
                                table->s->stored_rec_length
2640
2734
                                + table->s->max_key_length
2641
2735
                                + MAX_REF_PARTS * 3;
2642
 
        if (!(unsigned char*) memory::multi_malloc(false,
 
2736
        if (!(unsigned char*) drizzled::memory::multi_malloc(false,
2643
2737
                        &upd_buff, upd_and_key_val_buff_len,
2644
2738
                        &key_val_buff, upd_and_key_val_buff_len,
2645
2739
                        NULL)) {
2688
2782
                                norm_name);
2689
2783
                free_share(share);
2690
2784
                free(upd_buff);
2691
 
                errno = ENOENT;
 
2785
                my_errno = ENOENT;
2692
2786
 
2693
2787
                return(HA_ERR_NO_SUCH_TABLE);
2694
2788
        }
2704
2798
                                norm_name);
2705
2799
                free_share(share);
2706
2800
                free(upd_buff);
2707
 
                errno = ENOENT;
 
2801
                my_errno = ENOENT;
2708
2802
 
2709
2803
                dict_table_decrement_handle_count(ib_table, FALSE);
2710
2804
                return(HA_ERR_NO_SUCH_TABLE);
2816
2910
 
2817
2911
UNIV_INTERN
2818
2912
uint32_t
2819
 
InnobaseEngine::max_supported_key_part_length() const
 
2913
ha_innobase::max_supported_key_part_length() const
2820
2914
{
2821
2915
        return(DICT_MAX_INDEX_COL_LEN - 1);
2822
2916
}
2833
2927
 
2834
2928
        session = ha_session();
2835
2929
        if (session != NULL) {
2836
 
                getTransactionalEngine()->releaseTemporaryLatches(session);
 
2930
                engine->release_temporary_latches(session);
2837
2931
        }
2838
2932
 
2839
2933
        row_prebuilt_free(prebuilt, FALSE);
3053
3147
                } else {
3054
3148
                        return(DATA_VARMYSQL);
3055
3149
                }
3056
 
        case DRIZZLE_TYPE_DECIMAL:
 
3150
        case DRIZZLE_TYPE_NEWDECIMAL:
3057
3151
                return(DATA_FIXBINARY);
3058
3152
        case DRIZZLE_TYPE_LONG:
3059
3153
        case DRIZZLE_TYPE_LONGLONG:
3739
3833
                ut_error;
3740
3834
        }
3741
3835
 
3742
 
        ha_statistic_increment(&system_status_var::ha_write_count);
 
3836
        ha_statistic_increment(&SSV::ha_write_count);
3743
3837
 
3744
3838
        sql_command = session_sql_command(user_session);
3745
3839
 
3746
3840
        if ((sql_command == SQLCOM_ALTER_TABLE
 
3841
             || sql_command == SQLCOM_OPTIMIZE
3747
3842
             || sql_command == SQLCOM_CREATE_INDEX
3748
3843
             || sql_command == SQLCOM_DROP_INDEX)
3749
3844
            && num_write_row >= 10000) {
3784
3879
                        no need to re-acquire locks on it. */
3785
3880
 
3786
3881
                        /* Altering to InnoDB format */
3787
 
                        getTransactionalEngine()->commit(user_session, 1);
 
3882
                        engine->commit(user_session, 1);
 
3883
                        /* Note that this transaction is still active. */
 
3884
                        prebuilt->trx->active_trans = 1;
3788
3885
                        /* We will need an IX lock on the destination table. */
3789
3886
                        prebuilt->sql_stat_start = TRUE;
3790
3887
                } else {
3798
3895
 
3799
3896
                        /* Commit the transaction.  This will release the table
3800
3897
                        locks, so they have to be acquired again. */
3801
 
                        getTransactionalEngine()->commit(user_session, 1);
 
3898
                        engine->commit(user_session, 1);
 
3899
                        /* Note that this transaction is still active. */
 
3900
                        prebuilt->trx->active_trans = 1;
3802
3901
                        /* Re-acquire the table lock on the source table. */
3803
3902
                        row_lock_table_for_mysql(prebuilt, src_table, mode);
3804
3903
                        /* We will need an IX lock on the destination table. */
4108
4207
 
4109
4208
        ut_a(prebuilt->trx == trx);
4110
4209
 
4111
 
        ha_statistic_increment(&system_status_var::ha_update_count);
 
4210
        ha_statistic_increment(&SSV::ha_update_count);
4112
4211
 
4113
4212
        if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
4114
4213
                table->timestamp_field->set_time();
4213
4312
 
4214
4313
        ut_a(prebuilt->trx == trx);
4215
4314
 
4216
 
        ha_statistic_increment(&system_status_var::ha_delete_count);
 
4315
        ha_statistic_increment(&SSV::ha_delete_count);
4217
4316
 
4218
4317
        if (!prebuilt->upd_node) {
4219
4318
                row_get_prebuilt_update_vector(prebuilt);
4401
4500
 
4402
4501
  A) if the user has not explicitly set any MySQL table level locks:
4403
4502
 
4404
 
  1) Drizzle calls StorageEngine::doStartStatement(), indicating to
4405
 
     InnoDB that a new SQL statement has begun.
4406
 
 
4407
 
  2a) For each InnoDB-managed table in the SELECT, Drizzle calls ::external_lock
4408
 
     to set an 'intention' table level lock on the table of the Cursor instance.
4409
 
     There we set prebuilt->sql_stat_start = TRUE. The flag sql_stat_start should 
4410
 
     be set true if we are taking this table handle instance to use in a new SQL
4411
 
     statement issued by the user.
4412
 
 
4413
 
  2b) If prebuilt->sql_stat_start == TRUE we 'pre-compile' the MySQL search
 
4503
  1) MySQL calls ::external_lock to set an 'intention' table level lock on
 
4504
the table of the handle instance. There we set
 
4505
prebuilt->sql_stat_start = TRUE. The flag sql_stat_start should be set
 
4506
true if we are taking this table handle instance to use in a new SQL
 
4507
statement issued by the user. We also increment trx->n_mysql_tables_in_use.
 
4508
 
 
4509
  2) If prebuilt->sql_stat_start == TRUE we 'pre-compile' the MySQL search
4414
4510
instructions to prebuilt->template of the table handle instance in
4415
4511
::index_read. The template is used to save CPU time in large joins.
4416
4512
 
4422
4518
  4) We do the SELECT. MySQL may repeatedly call ::index_read for the
4423
4519
same table handle instance, if it is a join.
4424
4520
 
4425
 
5) When the SELECT ends, the Drizzle kernel calls doEndStatement()
4426
 
 
4427
 
 (a) we execute a COMMIT there if the autocommit is on. The Drizzle interpreter 
4428
 
     does NOT execute autocommit for pure read transactions, though it should.
4429
 
     That is why we must execute the COMMIT in ::doEndStatement().
 
4521
  5) When the SELECT ends, MySQL removes its intention table level locks
 
4522
in ::external_lock. When trx->n_mysql_tables_in_use drops to zero,
 
4523
 (a) we execute a COMMIT there if the autocommit is on,
4430
4524
 (b) we also release possible 'SQL statement level resources' InnoDB may
4431
 
     have for this SQL statement.
4432
 
 
4433
 
  @todo
4434
 
 
4435
 
  Remove need for InnoDB to call autocommit for read-only trx
4436
 
 
4437
 
  @todo Check the below is still valid (I don't think it is...)
 
4525
have for this SQL statement. The MySQL interpreter does NOT execute
 
4526
autocommit for pure read transactions, though it should. That is why the
 
4527
table Cursor in that case has to execute the COMMIT in ::external_lock.
4438
4528
 
4439
4529
  B) If the user has explicitly set MySQL table level locks, then MySQL
4440
4530
does NOT call ::external_lock at the start of the statement. To determine
4476
4566
 
4477
4567
        ut_a(prebuilt->trx == session_to_trx(user_session));
4478
4568
 
4479
 
        ha_statistic_increment(&system_status_var::ha_read_key_count);
 
4569
        ha_statistic_increment(&SSV::ha_read_key_count);
4480
4570
 
4481
4571
        index = prebuilt->index;
4482
4572
 
4591
4681
        KEY*            key = 0;
4592
4682
        dict_index_t*   index = 0;
4593
4683
 
4594
 
        ha_statistic_increment(&system_status_var::ha_read_key_count);
 
4684
        ha_statistic_increment(&SSV::ha_read_key_count);
4595
4685
 
4596
4686
        ut_ad(user_session == ha_session());
4597
4687
        ut_a(prebuilt->trx == session_to_trx(user_session));
4756
4846
        unsigned char*  buf)    /*!< in/out: buffer for next row in MySQL
4757
4847
                                format */
4758
4848
{
4759
 
        ha_statistic_increment(&system_status_var::ha_read_next_count);
 
4849
        ha_statistic_increment(&SSV::ha_read_next_count);
4760
4850
 
4761
4851
        return(general_fetch(buf, ROW_SEL_NEXT, 0));
4762
4852
}
4772
4862
        const unsigned char*    ,       /*!< in: key value */
4773
4863
        uint            )       /*!< in: key value length */
4774
4864
{
4775
 
        ha_statistic_increment(&system_status_var::ha_read_next_count);
 
4865
        ha_statistic_increment(&SSV::ha_read_next_count);
4776
4866
 
4777
4867
        return(general_fetch(buf, ROW_SEL_NEXT, last_match_mode));
4778
4868
}
4787
4877
/*====================*/
4788
4878
        unsigned char*  buf)    /*!< in/out: buffer for previous row in MySQL format */
4789
4879
{
4790
 
        ha_statistic_increment(&system_status_var::ha_read_prev_count);
 
4880
        ha_statistic_increment(&SSV::ha_read_prev_count);
4791
4881
 
4792
4882
        return(general_fetch(buf, ROW_SEL_PREV, 0));
4793
4883
}
4804
4894
{
4805
4895
        int     error;
4806
4896
 
4807
 
        ha_statistic_increment(&system_status_var::ha_read_first_count);
 
4897
        ha_statistic_increment(&SSV::ha_read_first_count);
4808
4898
 
4809
4899
        error = index_read(buf, NULL, 0, HA_READ_AFTER_KEY);
4810
4900
 
4829
4919
{
4830
4920
        int     error;
4831
4921
 
4832
 
        ha_statistic_increment(&system_status_var::ha_read_last_count);
 
4922
        ha_statistic_increment(&SSV::ha_read_last_count);
4833
4923
 
4834
4924
        error = index_read(buf, NULL, 0, HA_READ_BEFORE_KEY);
4835
4925
 
4898
4988
{
4899
4989
        int     error;
4900
4990
 
4901
 
        ha_statistic_increment(&system_status_var::ha_read_rnd_next_count);
 
4991
        ha_statistic_increment(&SSV::ha_read_rnd_next_count);
4902
4992
 
4903
4993
        if (start_of_scan) {
4904
4994
                error = index_first(buf);
4931
5021
        int             error;
4932
5022
        uint            keynr   = active_index;
4933
5023
 
4934
 
        ha_statistic_increment(&system_status_var::ha_read_rnd_count);
 
5024
        ha_statistic_increment(&SSV::ha_read_rnd_count);
4935
5025
 
4936
5026
        ut_a(prebuilt->trx == session_to_trx(ha_session()));
4937
5027
 
5287
5377
        Session*        session,        /*!< in: connection thread. */
5288
5378
        Table&          form,           /*!< in: information on table
5289
5379
                                        columns and indexes */
5290
 
        message::Table& create_proto)
 
5380
        HA_CREATE_INFO& create_info,
 
5381
        drizzled::message::Table& create_proto)
5291
5382
{
5292
5383
        ibool   kbs_specified   = FALSE;
5293
5384
        ibool   ret             = TRUE;
5344
5435
        }
5345
5436
 
5346
5437
        /* Now check for ROW_FORMAT specifier. */
5347
 
        if (create_proto.options().has_row_type()) {
 
5438
        if (create_info.used_fields & HA_CREATE_USED_ROW_FORMAT) {
5348
5439
                switch (form.s->row_type) {
5349
5440
                        const char* row_format_name;
5350
5441
                case ROW_TYPE_COMPRESSED:
5443
5534
InnobaseEngine::doCreateTable(
5444
5535
/*================*/
5445
5536
        Session*        session,        /*!< in: Session */
5446
 
        Table&          form,           /*!< in: information on table columns and indexes */
5447
 
        drizzled::TableIdentifier &identifier,
5448
 
        message::Table& create_proto)
 
5537
        const char*     table_name,     /*!< in: table name */
 
5538
        Table&          form,           /*!< in: information on table
 
5539
                                        columns and indexes */
 
5540
        HA_CREATE_INFO& create_info,    /*!< in: more information of the
 
5541
                                        created table, contains also the
 
5542
                                        create statement string */
 
5543
        drizzled::message::Table& create_proto)
5449
5544
{
5450
5545
        int             error;
5451
5546
        dict_table_t*   innobase_table;
5460
5555
        /* Cache the value of innodb_file_format, in case it is
5461
5556
        modified by another thread while the table is being created. */
5462
5557
        const ulint     file_format = srv_file_format;
5463
 
        bool lex_identified_temp_table= (create_proto.type() == message::Table::TEMPORARY);
5464
 
 
5465
 
        const char *table_name= identifier.getPath().c_str();
5466
5558
 
5467
5559
        assert(session != NULL);
5468
5560
 
5478
5570
        table. Currently InnoDB does not support symbolic link on Windows. */
5479
5571
 
5480
5572
        if (srv_file_per_table
5481
 
            && (! lex_identified_temp_table)) {
 
5573
            && (!create_info.options & HA_LEX_CREATE_TMP_TABLE)) {
5482
5574
 
5483
5575
                if ((table_name[1] == ':')
5484
5576
                    || (table_name[0] == '\\' && table_name[1] == '\\')) {
5524
5616
        iflags = 0;
5525
5617
 
5526
5618
        /* Validate create options if innodb_strict_mode is set. */
5527
 
        if (! create_options_are_valid(session, form, create_proto)) {
 
5619
        if (!create_options_are_valid(session, form, create_info, create_proto)) {
5528
5620
                error = ER_ILLEGAL_HA_CREATE_OPTION;
5529
5621
                goto cleanup;
5530
5622
        }
5573
5665
                }
5574
5666
        }
5575
5667
 
5576
 
        if (create_proto.options().has_row_type()) {
 
5668
        if (create_info.used_fields & HA_CREATE_USED_ROW_FORMAT) {
5577
5669
                if (iflags) {
5578
5670
                        /* KEY_BLOCK_SIZE was specified. */
5579
5671
                        if (form.s->row_type != ROW_TYPE_COMPRESSED) {
5648
5740
                case ROW_TYPE_NOT_USED:
5649
5741
                case ROW_TYPE_FIXED:
5650
5742
                default:
5651
 
                        error = ER_ILLEGAL_HA_CREATE_OPTION;
5652
 
                        goto cleanup;
 
5743
                        push_warning(session,
 
5744
                                     DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
5745
                                     ER_ILLEGAL_HA_CREATE_OPTION,
 
5746
                                     "InnoDB: assuming ROW_FORMAT=COMPACT.");
5653
5747
                case ROW_TYPE_DEFAULT:
5654
5748
                case ROW_TYPE_COMPACT:
5655
5749
                        iflags = DICT_TF_COMPACT;
5662
5756
        }
5663
5757
 
5664
5758
        error = create_table_def(trx, &form, norm_name,
5665
 
                lex_identified_temp_table ? name2 : NULL,
 
5759
                create_info.options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
5666
5760
                iflags);
5667
5761
 
5668
5762
        if (error) {
5714
5808
                }
5715
5809
        }
5716
5810
 
5717
 
        if (trx->mysql_query_str) {
 
5811
        if (*trx->mysql_query_str) {
5718
5812
                error = row_table_add_foreign_constraints(trx,
5719
 
                        trx->mysql_query_str, norm_name,
5720
 
                        lex_identified_temp_table);
 
5813
                        *trx->mysql_query_str, norm_name,
 
5814
                        create_info.options & HA_LEX_CREATE_TMP_TABLE);
5721
5815
 
5722
5816
                error = convert_error_code_to_mysql(error, iflags, NULL);
5723
5817
 
5755
5849
        /* We need to copy the AUTOINC value from the old table if
5756
5850
        this is an ALTER TABLE. */
5757
5851
 
5758
 
        if ((create_proto.options().has_auto_increment_value()
 
5852
        if (((create_info.used_fields & HA_CREATE_USED_AUTO)
5759
5853
            || session_sql_command(session) == SQLCOM_ALTER_TABLE)
5760
 
            && create_proto.options().auto_increment_value() != 0) {
 
5854
            && create_info.auto_increment_value != 0) {
5761
5855
 
5762
5856
                /* Query was ALTER TABLE...AUTO_INCREMENT = x; or
5763
5857
                CREATE TABLE ...AUTO_INCREMENT = x; Find out a table
5766
5860
                auto increment field if the value is greater than the
5767
5861
                maximum value in the column. */
5768
5862
 
5769
 
                auto_inc_value = create_proto.options().auto_increment_value();
 
5863
                auto_inc_value = create_info.auto_increment_value;
5770
5864
 
5771
5865
                dict_table_autoinc_lock(innobase_table);
5772
5866
                dict_table_autoinc_initialize(innobase_table, auto_inc_value);
5843
5937
                /* We only handle TRUNCATE TABLE t as a special case.
5844
5938
                DELETE FROM t will have to use ha_innobase::delete_row(),
5845
5939
                because DELETE is transactional while TRUNCATE is not. */
5846
 
                return(errno=HA_ERR_WRONG_COMMAND);
 
5940
                return(my_errno=HA_ERR_WRONG_COMMAND);
5847
5941
        }
5848
5942
 
5849
5943
        /* Truncate the table in InnoDB */
5871
5965
int
5872
5966
InnobaseEngine::doDropTable(
5873
5967
/*======================*/
5874
 
        Session &session,
5875
 
        TableIdentifier &identifier)
 
5968
        Session& session,
 
5969
        const string table_path)        /* in: table name */
5876
5970
{
5877
5971
        int     error;
5878
5972
        trx_t*  parent_trx;
5879
5973
        trx_t*  trx;
5880
5974
        char    norm_name[1000];
5881
5975
 
5882
 
        ut_a(identifier.getPath().length() < 1000);
 
5976
        ut_a(table_path.length() < 1000);
5883
5977
 
5884
5978
        /* Strangely, MySQL passes the table name without the '.frm'
5885
5979
        extension, in contrast to ::create */
5886
 
        normalize_table_name(norm_name, identifier.getPath().c_str());
 
5980
        normalize_table_name(norm_name, table_path.c_str());
5887
5981
 
5888
5982
        /* Get the transaction associated with the current session, or create one
5889
5983
        if not yet created */
5928
6022
 
5929
6023
/*****************************************************************//**
5930
6024
Removes all tables in the named database inside InnoDB. */
5931
 
bool
5932
 
InnobaseEngine::doDropSchema(
 
6025
void
 
6026
InnobaseEngine::drop_database(
5933
6027
/*===================*/
5934
 
                             const std::string &schema_name)
5935
 
                /*!< in: database path; inside InnoDB the name
 
6028
        char*   path)   /*!< in: database path; inside InnoDB the name
5936
6029
                        of the last directory in the path is used as
5937
6030
                        the database name: for example, in 'mysql/data/test'
5938
6031
                        the database name is 'test' */
5939
6032
{
 
6033
        ulint   len             = 0;
5940
6034
        trx_t*  trx;
 
6035
        char*   ptr;
5941
6036
        int     error;
5942
 
        string schema_path(schema_name);
 
6037
        char*   namebuf;
5943
6038
        Session*        session         = current_session;
5944
6039
 
5945
6040
        /* Get the transaction associated with the current session, or create one
5958
6053
                trx_search_latch_release_if_reserved(parent_trx);
5959
6054
        }
5960
6055
 
5961
 
        schema_path.append("/");
 
6056
        ptr = strchr(path, '\0') - 2;
 
6057
 
 
6058
        while (ptr >= path && *ptr != '\\' && *ptr != '/') {
 
6059
                ptr--;
 
6060
                len++;
 
6061
        }
 
6062
 
 
6063
        ptr++;
 
6064
        namebuf = (char*) malloc((uint) len + 2);
 
6065
 
 
6066
        memcpy(namebuf, ptr, len);
 
6067
        namebuf[len] = '/';
 
6068
        namebuf[len + 1] = '\0';
 
6069
#ifdef  __WIN__
 
6070
        innobase_casedn_str(namebuf);
 
6071
#endif
 
6072
#if defined __WIN__ && !defined MYSQL_SERVER
 
6073
        /* In the Windows plugin, thd = current_thd is always NULL */
 
6074
        trx = trx_allocate_for_mysql();
 
6075
        trx->mysql_thd = NULL;
 
6076
        trx->mysql_query_str = NULL;
 
6077
#else
5962
6078
        trx = innobase_trx_allocate(session);
5963
 
        error = row_drop_database_for_mysql(schema_path.c_str(), trx);
 
6079
#endif
 
6080
        error = row_drop_database_for_mysql(namebuf, trx);
 
6081
        free(namebuf);
5964
6082
 
5965
6083
        /* Flush the log to reduce probability that the .frm files and
5966
6084
        the InnoDB data dictionary get out-of-sync if the user runs
5975
6093
 
5976
6094
        innobase_commit_low(trx);
5977
6095
        trx_free_for_mysql(trx);
5978
 
 
5979
 
        return false; // We are just a listener since we lack control over DDL, so we give no positive acknowledgement. 
5980
6096
}
5981
6097
/*********************************************************************//**
5982
6098
Renames an InnoDB table.
6352
6468
                snprintf(path, sizeof(path), "%s/%s%s",
6353
6469
                               drizzle_data_home, ib_table->name, ".dfe");
6354
6470
 
6355
 
                internal::unpack_filename(path,path);
 
6471
                unpack_filename(path,path);
6356
6472
 
6357
6473
                /* Note that we do not know the access time of the table,
6358
6474
                nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
6562
6678
int
6563
6679
ha_innobase::analyze(
6564
6680
/*=================*/
6565
 
        Session*)               /*!< in: connection thread handle */
 
6681
        Session*        ,               /*!< in: connection thread handle */
 
6682
        HA_CHECK_OPT*   )       /*!< in: currently ignored */
6566
6683
{
6567
6684
        /* Simply call ::info() with all the flags */
6568
6685
        info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
6570
6687
        return(0);
6571
6688
}
6572
6689
 
 
6690
/**********************************************************************//**
 
6691
This is mapped to "ALTER TABLE tablename ENGINE=InnoDB", which rebuilds
 
6692
the table in MySQL. */
 
6693
UNIV_INTERN
 
6694
int
 
6695
ha_innobase::optimize(
 
6696
/*==================*/
 
6697
        Session*        ,       /*!< in: connection thread handle */
 
6698
        HA_CHECK_OPT*   )       /*!< in: currently ignored */
 
6699
{
 
6700
        return(HA_ADMIN_TRY_ALTER);
 
6701
}
 
6702
 
6573
6703
/*******************************************************************//**
6574
6704
Tries to check that an InnoDB table is not corrupted. If corruption is
6575
6705
noticed, prints to stderr information about it. In case of corruption
6579
6709
int
6580
6710
ha_innobase::check(
6581
6711
/*===============*/
6582
 
        Session*        session)        /*!< in: user thread handle */
 
6712
        Session*        session,        /*!< in: user thread handle */
 
6713
        HA_CHECK_OPT*   )               /*!< in: check options, currently
 
6714
                                        ignored */
6583
6715
{
6584
6716
        ulint           ret;
6585
6717
 
6767
6899
          while (tmp_buff[i] != '/')
6768
6900
                  i++;
6769
6901
          tmp_buff+= i + 1;
6770
 
          f_key_info.forein_id = session->make_lex_string(NULL, tmp_buff, strlen(tmp_buff), true);
 
6902
          f_key_info.forein_id = session_make_lex_string(session, 0,
 
6903
                  tmp_buff, (uint) strlen(tmp_buff), 1);
6771
6904
          tmp_buff= foreign->referenced_table_name;
6772
6905
 
6773
6906
          /* Database name */
6779
6912
          }
6780
6913
          db_name[i]= 0;
6781
6914
          ulen= filename_to_tablename(db_name, uname, sizeof(uname));
6782
 
          f_key_info.referenced_db = session->make_lex_string(NULL, uname, ulen, true);
 
6915
          f_key_info.referenced_db = session_make_lex_string(session, 0,
 
6916
                  uname, ulen, 1);
6783
6917
 
6784
6918
          /* Table name */
6785
6919
          tmp_buff+= i + 1;
6786
6920
          ulen= filename_to_tablename(tmp_buff, uname, sizeof(uname));
6787
 
          f_key_info.referenced_table = session->make_lex_string(NULL, uname, ulen, true);
 
6921
          f_key_info.referenced_table = session_make_lex_string(session, 0,
 
6922
                  uname, ulen, 1);
6788
6923
 
6789
6924
          for (i= 0;;) {
6790
6925
                  tmp_buff= foreign->foreign_col_names[i];
6791
 
                  name = session->make_lex_string(name, tmp_buff, strlen(tmp_buff), true);
 
6926
                  name = session_make_lex_string(session, name,
 
6927
                          tmp_buff, (uint) strlen(tmp_buff), 1);
6792
6928
                  f_key_info.foreign_fields.push_back(name);
6793
6929
                  tmp_buff= foreign->referenced_col_names[i];
6794
 
                  name = session->make_lex_string(name, tmp_buff, strlen(tmp_buff), true);
 
6930
                  name = session_make_lex_string(session, name,
 
6931
                        tmp_buff, (uint) strlen(tmp_buff), 1);
6795
6932
                  f_key_info.referenced_fields.push_back(name);
6796
6933
                  if (++i >= foreign->n_fields)
6797
6934
                          break;
6818
6955
            length=8;
6819
6956
            tmp_buff= "RESTRICT";
6820
6957
          }
6821
 
          f_key_info.delete_method = session->make_lex_string(
6822
 
                  f_key_info.delete_method, tmp_buff, length, true);
 
6958
          f_key_info.delete_method = session_make_lex_string(
 
6959
                  session, f_key_info.delete_method, tmp_buff, length, 1);
6823
6960
 
6824
6961
 
6825
6962
          if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE)
6842
6979
            length=8;
6843
6980
            tmp_buff= "RESTRICT";
6844
6981
          }
6845
 
          f_key_info.update_method = session->make_lex_string(
6846
 
                  f_key_info.update_method, tmp_buff, length, true);
 
6982
          f_key_info.update_method = session_make_lex_string(
 
6983
                  session, f_key_info.update_method, tmp_buff, length, 1);
6847
6984
          if (foreign->referenced_index &&
6848
6985
              foreign->referenced_index->name)
6849
6986
          {
6850
 
            f_key_info.referenced_key_name = session->make_lex_string(
6851
 
                    f_key_info.referenced_key_name,
 
6987
            f_key_info.referenced_key_name = session_make_lex_string(
 
6988
                    session, f_key_info.referenced_key_name,
6852
6989
                    foreign->referenced_index->name,
6853
 
                    strlen(foreign->referenced_index->name), true);
 
6990
                    (uint) strlen(foreign->referenced_index->name), 1);
6854
6991
          }
6855
6992
          else
6856
6993
            f_key_info.referenced_key_name= 0;
7005
7142
}
7006
7143
 
7007
7144
/******************************************************************//**
 
7145
MySQL calls this function at the start of each SQL statement inside LOCK
 
7146
TABLES. Inside LOCK TABLES the ::external_lock method does not work to
 
7147
mark SQL statement borders. Note also a special case: if a temporary table
 
7148
is created inside LOCK TABLES, MySQL has not called external_lock() at all
 
7149
on that table.
 
7150
MySQL-5.0 also calls this before each statement in an execution of a stored
 
7151
procedure. To make the execution more deterministic for binlogging, MySQL-5.0
 
7152
locks all tables involved in a stored procedure with full explicit table
 
7153
locks (session_in_lock_tables(session) holds in store_lock()) before executing
 
7154
the procedure.
 
7155
@return 0 or error code */
 
7156
UNIV_INTERN
 
7157
int
 
7158
ha_innobase::start_stmt(
 
7159
/*====================*/
 
7160
        Session*        session,        /*!< in: handle to the user thread */
 
7161
        thr_lock_type   lock_type)
 
7162
{
 
7163
        trx_t*          trx;
 
7164
 
 
7165
        update_session(session);
 
7166
 
 
7167
        trx = prebuilt->trx;
 
7168
 
 
7169
        /* Here we release the search latch and the InnoDB thread FIFO ticket
 
7170
        if they were reserved. They should have been released already at the
 
7171
        end of the previous statement, but because inside LOCK TABLES the
 
7172
        lock count method does not work to mark the end of a SELECT statement,
 
7173
        that may not be the case. We MUST release the search latch before an
 
7174
        INSERT, for example. */
 
7175
 
 
7176
        innobase_release_stat_resources(trx);
 
7177
 
 
7178
        /* Reset the AUTOINC statement level counter for multi-row INSERTs. */
 
7179
        trx->n_autoinc_rows = 0;
 
7180
 
 
7181
        prebuilt->sql_stat_start = TRUE;
 
7182
        prebuilt->hint_need_to_fetch_extra_cols = 0;
 
7183
        reset_template(prebuilt);
 
7184
 
 
7185
        if (!prebuilt->mysql_has_locked) {
 
7186
                /* This handle is for a temporary table created inside
 
7187
                this same LOCK TABLES; since MySQL does NOT call external_lock
 
7188
                in this case, we must use x-row locks inside InnoDB to be
 
7189
                prepared for an update of a row */
 
7190
 
 
7191
                prebuilt->select_lock_type = LOCK_X;
 
7192
        } else {
 
7193
                if (trx->isolation_level != TRX_ISO_SERIALIZABLE
 
7194
                        && session_sql_command(session) == SQLCOM_SELECT
 
7195
                        && lock_type == TL_READ) {
 
7196
 
 
7197
                        /* For other than temporary tables, we obtain
 
7198
                        no lock for consistent read (plain SELECT). */
 
7199
 
 
7200
                        prebuilt->select_lock_type = LOCK_NONE;
 
7201
                } else {
 
7202
                        /* Not a consistent read: restore the
 
7203
                        select_lock_type value. The value of
 
7204
                        stored_select_lock_type was decided in:
 
7205
                        1) ::store_lock(),
 
7206
                        2) ::external_lock(),
 
7207
                        3) ::init_table_handle_for_HANDLER(), and
 
7208
                      */
 
7209
 
 
7210
                        prebuilt->select_lock_type =
 
7211
                                prebuilt->stored_select_lock_type;
 
7212
                }
 
7213
        }
 
7214
 
 
7215
        trx->detailed_error[0] = '\0';
 
7216
 
 
7217
        /* Set the MySQL flag to mark that there is an active transaction */
 
7218
        if (trx->active_trans == 0) {
 
7219
 
 
7220
                innobase_register_trx_and_stmt(engine, session);
 
7221
                trx->active_trans = 1;
 
7222
        } else {
 
7223
                innobase_register_stmt(engine, session);
 
7224
        }
 
7225
 
 
7226
        return(0);
 
7227
}
 
7228
 
 
7229
/******************************************************************//**
7008
7230
Maps a MySQL trx isolation level code to the InnoDB isolation level code
7009
7231
@return InnoDB isolation level */
7010
7232
static inline
7024
7246
 
7025
7247
/******************************************************************//**
7026
7248
As MySQL will execute an external lock for every new table it uses when it
7027
 
starts to process an SQL statement.  We can use this function to store the pointer to
7028
 
the Session in the handle.
 
7249
starts to process an SQL statement (an exception is when MySQL calls
 
7250
start_stmt for the handle) we can use this function to store the pointer to
 
7251
the Session in the handle. We will also use this function to communicate
 
7252
to InnoDB that a new SQL statement has started and that we must store a
 
7253
savepoint to our transaction handle, so that we are able to roll back
 
7254
the SQL statement in case of an error.
7029
7255
@return 0 */
7030
7256
UNIV_INTERN
7031
7257
int
7034
7260
        Session*        session,        /*!< in: handle to the user thread */
7035
7261
        int     lock_type)      /*!< in: lock type */
7036
7262
{
 
7263
        trx_t*          trx;
 
7264
 
 
7265
 
7037
7266
        update_session(session);
7038
7267
 
7039
 
  trx_t *trx= prebuilt->trx;
 
7268
        trx = prebuilt->trx;
7040
7269
 
7041
7270
        prebuilt->sql_stat_start = TRUE;
7042
7271
        prebuilt->hint_need_to_fetch_extra_cols = 0;
7054
7283
        if (lock_type != F_UNLCK) {
7055
7284
                /* MySQL is setting a new table lock */
7056
7285
 
 
7286
                trx->detailed_error[0] = '\0';
 
7287
 
 
7288
                /* Set the MySQL flag to mark that there is an active
 
7289
                transaction */
 
7290
                if (trx->active_trans == 0) {
 
7291
 
 
7292
                        innobase_register_trx_and_stmt(engine, session);
 
7293
                        trx->active_trans = 1;
 
7294
                } else if (trx->n_mysql_tables_in_use == 0) {
 
7295
                        innobase_register_stmt(engine, session);
 
7296
                }
 
7297
 
7057
7298
                if (trx->isolation_level == TRX_ISO_SERIALIZABLE
7058
7299
                        && prebuilt->select_lock_type == LOCK_NONE
7059
7300
                        && session_test_options(session,
7086
7327
                        trx->mysql_n_tables_locked++;
7087
7328
                }
7088
7329
 
 
7330
                trx->n_mysql_tables_in_use++;
7089
7331
                prebuilt->mysql_has_locked = TRUE;
7090
7332
 
7091
7333
                return(0);
7092
7334
        }
7093
7335
 
7094
7336
        /* MySQL is releasing a table lock */
 
7337
 
 
7338
        trx->n_mysql_tables_in_use--;
7095
7339
        prebuilt->mysql_has_locked = FALSE;
7096
 
        trx->mysql_n_tables_locked= 0;
 
7340
 
 
7341
        /* Release a possible FIFO ticket and search latch. Since we
 
7342
        may reserve the kernel mutex, we have to release the search
 
7343
        system latch first to obey the latching order. */
 
7344
 
 
7345
        innobase_release_stat_resources(trx);
 
7346
 
 
7347
        /* If the MySQL lock count drops to zero we know that the current SQL
 
7348
        statement has ended */
 
7349
 
 
7350
        if (trx->n_mysql_tables_in_use == 0) {
 
7351
 
 
7352
                trx->mysql_n_tables_locked = 0;
 
7353
                prebuilt->used_in_HANDLER = FALSE;
 
7354
 
 
7355
                if (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
 
7356
                        if (trx->active_trans != 0) {
 
7357
                                engine->commit(session, TRUE);
 
7358
                        }
 
7359
                } else {
 
7360
                        if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
 
7361
                                                && trx->global_read_view) {
 
7362
 
 
7363
                                /* At low transaction isolation levels we let
 
7364
                                each consistent read set its own snapshot */
 
7365
 
 
7366
                                read_view_close_for_mysql(trx);
 
7367
                        }
 
7368
                }
 
7369
        }
7097
7370
 
7098
7371
        return(0);
7099
7372
}
7100
7373
 
7101
7374
/************************************************************************//**
 
7375
Here we export InnoDB status variables to MySQL. */
 
7376
static
 
7377
void
 
7378
innodb_export_status(void)
 
7379
/*======================*/
 
7380
{
 
7381
        if (innodb_inited) {
 
7382
                srv_export_innodb_status();
 
7383
        }
 
7384
}
 
7385
 
 
7386
/************************************************************************//**
7102
7387
Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB
7103
7388
Monitor to the client. */
7104
7389
static
7105
7390
bool
7106
7391
innodb_show_status(
7107
7392
/*===============*/
7108
 
        plugin::StorageEngine*  engine, /*!< in: the innodb StorageEngine */
 
7393
        drizzled::plugin::StorageEngine*        engine, /*!< in: the innodb StorageEngine */
7109
7394
        Session*        session,/*!< in: the MySQL query thread of the caller */
7110
7395
        stat_print_fn *stat_print)
7111
7396
{
7192
7477
bool
7193
7478
innodb_mutex_show_status(
7194
7479
/*=====================*/
7195
 
        plugin::StorageEngine*  engine,         /*!< in: the innodb StorageEngine */
 
7480
        drizzled::plugin::StorageEngine*        engine,         /*!< in: the innodb StorageEngine */
7196
7481
        Session*        session,        /*!< in: the MySQL query thread of the
7197
7482
                                        caller */
7198
7483
        stat_print_fn*  stat_print)
7436
7721
 
7437
7722
        trx = check_trx_exists(session);
7438
7723
 
 
7724
        /* NOTE: MySQL can call this function with lock 'type' TL_IGNORE!
 
7725
        Be careful to ignore TL_IGNORE if we are going to do something with
 
7726
        only 'real' locks! */
 
7727
 
 
7728
        /* If no MySQL table is in use, we need to set the isolation level
 
7729
        of the transaction. */
 
7730
 
 
7731
        if (lock_type != TL_IGNORE
 
7732
            && trx->n_mysql_tables_in_use == 0) {
 
7733
                trx->isolation_level = innobase_map_isolation_level(
 
7734
                        (enum_tx_isolation) session_tx_isolation(session));
 
7735
 
 
7736
                if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
 
7737
                    && trx->global_read_view) {
 
7738
 
 
7739
                        /* At low transaction isolation levels we let
 
7740
                        each consistent read set its own snapshot */
 
7741
 
 
7742
                        read_view_close_for_mysql(trx);
 
7743
                }
 
7744
        }
 
7745
 
7439
7746
        assert(EQ_CURRENT_SESSION(session));
7440
7747
        const uint32_t sql_command = session_sql_command(session);
7441
7748
 
7516
7823
                TABLESPACE or TRUNCATE TABLE then allow multiple
7517
7824
                writers. Note that ALTER TABLE uses a TL_WRITE_ALLOW_READ
7518
7825
                < TL_WRITE_CONCURRENT_INSERT.
7519
 
                */
 
7826
 
 
7827
                We especially allow multiple writers if MySQL is at the
 
7828
                start of a stored procedure call (SQLCOM_CALL) or a
 
7829
                stored function call (MySQL does have in_lock_tables
 
7830
                TRUE there). */
7520
7831
 
7521
7832
                if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
7522
7833
                     && lock_type <= TL_WRITE)
7523
7834
                    && !session_tablespace_op(session)
7524
7835
                    && sql_command != SQLCOM_TRUNCATE
 
7836
                    && sql_command != SQLCOM_OPTIMIZE
7525
7837
                    && sql_command != SQLCOM_CREATE_TABLE) {
7526
7838
 
7527
7839
                        lock_type = TL_WRITE_ALLOW_WRITE;
7532
7844
                would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts
7533
7845
                to t2. Convert the lock to a normal read lock to allow
7534
7846
                concurrent inserts to t2.
7535
 
    */
 
7847
 
 
7848
                We especially allow concurrent inserts if MySQL is at the
 
7849
                start of a stored procedure call (SQLCOM_CALL)
 
7850
                (MySQL does have session_in_lock_tables() TRUE there). */
7536
7851
 
7537
7852
                if (lock_type == TL_READ_NO_INSERT) {
7538
7853
 
7744
8059
 
7745
8060
        innobase_reset_autoinc(value);
7746
8061
 
7747
 
        return 0;
 
8062
        return(0);
7748
8063
}
7749
8064
 
7750
8065
/* See comment in Cursor.cc */
7751
8066
UNIV_INTERN
7752
8067
bool
7753
 
InnobaseEngine::get_error_message(int, String *buf)
 
8068
ha_innobase::get_error_message(int, String *buf)
7754
8069
{
7755
 
        trx_t*  trx = check_trx_exists(current_session);
 
8070
        trx_t*  trx = check_trx_exists(ha_session());
7756
8071
 
7757
8072
        buf->copy(trx->detailed_error, (uint) strlen(trx->detailed_error),
7758
8073
                system_charset_info);
7907
8222
 
7908
8223
        return(char_length);
7909
8224
}
7910
 
/**
7911
 
 * We will also use this function to communicate
7912
 
 * to InnoDB that a new SQL statement has started and that we must store a
7913
 
 * savepoint to our transaction handle, so that we are able to roll back
7914
 
 * the SQL statement in case of an error.
7915
 
 */
7916
 
void
7917
 
InnobaseEngine::doStartStatement(
7918
 
        Session *session) /*!< in: handle to the Drizzle session */
7919
 
{
7920
 
  /* 
7921
 
   * Create the InnoDB transaction structure
7922
 
   * for the session
7923
 
   */
7924
 
        trx_t *trx= check_trx_exists(session);
7925
 
 
7926
 
  /* "reset" the error message for the transaction */
7927
 
  trx->detailed_error[0]= '\0';
7928
 
 
7929
 
        /* Set the isolation level of the transaction. */
7930
 
  trx->isolation_level= innobase_map_isolation_level((enum_tx_isolation) session_tx_isolation(session));
7931
 
}
7932
 
 
7933
 
void
7934
 
InnobaseEngine::doEndStatement(
7935
 
  Session *session)
7936
 
{
7937
 
  trx_t *trx= check_trx_exists(session);
7938
 
 
7939
 
  /* Release a possible FIFO ticket and search latch. Since we
7940
 
  may reserve the kernel mutex, we have to release the search
7941
 
  system latch first to obey the latching order. */
7942
 
 
7943
 
  innobase_release_stat_resources(trx);
7944
 
 
7945
 
  if (! session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
7946
 
  {
7947
 
    if (trx->conc_state != TRX_NOT_STARTED)
7948
 
    {
7949
 
      commit(session, TRUE);
7950
 
    }
7951
 
  }
7952
 
  else
7953
 
  {
7954
 
    if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
7955
 
        trx->global_read_view)
7956
 
    {
7957
 
      /* At low transaction isolation levels we let
7958
 
      each consistent read set its own snapshot */
7959
 
      read_view_close_for_mysql(trx);
7960
 
    }
7961
 
  }
7962
 
}
7963
8225
 
7964
8226
/*******************************************************************//**
7965
8227
This function is used to prepare an X/Open XA distributed transaction.
7966
8228
@return 0 or error number */
7967
8229
int
7968
 
InnobaseEngine::doXaPrepare(
 
8230
InnobaseEngine::prepare(
7969
8231
/*================*/
7970
8232
        Session*        session,/*!< in: handle to the MySQL thread of
7971
8233
                                the user whose XA transaction should
7995
8257
 
7996
8258
        innobase_release_stat_resources(trx);
7997
8259
 
 
8260
        if (trx->active_trans == 0 && trx->conc_state != TRX_NOT_STARTED) {
 
8261
 
 
8262
          errmsg_printf(ERRMSG_LVL_ERROR,
 
8263
                        "trx->active_trans == 0, but trx->conc_state != "
 
8264
                        "TRX_NOT_STARTED");
 
8265
        }
 
8266
 
7998
8267
        if (all
7999
8268
                || (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
8000
8269
 
8001
8270
                /* We were instructed to prepare the whole transaction, or
8002
8271
                this is an SQL statement end and autocommit is on */
8003
8272
 
8004
 
                ut_ad(trx->conc_state != TRX_NOT_STARTED);
 
8273
                ut_ad(trx->active_trans);
8005
8274
 
8006
8275
                error = (int) trx_prepare_for_mysql(trx);
8007
8276
        } else {
8048
8317
                to block for undefined period of time.
8049
8318
                */
8050
8319
                pthread_mutex_lock(&prepare_commit_mutex);
8051
 
                trx->conc_state = TRX_PREPARED;
 
8320
                trx->active_trans = 2;
8052
8321
        }
8053
8322
        return(error);
8054
8323
}
8057
8326
This function is used to recover X/Open XA distributed transactions.
8058
8327
@return number of prepared transactions stored in xid_list */
8059
8328
int
8060
 
InnobaseEngine::doXaRecover(
 
8329
InnobaseEngine::recover(
8061
8330
/*================*/
8062
 
        ::drizzled::XID*        xid_list,/*!< in/out: prepared transactions */
8063
 
        size_t len)     /*!< in: number of slots in xid_list */
 
8331
        XID*            xid_list,/*!< in/out: prepared transactions */
 
8332
        uint            len)    /*!< in: number of slots in xid_list */
8064
8333
{
8065
8334
        assert(this == innodb_engine_ptr);
8066
8335
 
8069
8338
                return(0);
8070
8339
        }
8071
8340
 
8072
 
        return(trx_recover_for_mysql((::XID *)xid_list, len));
 
8341
        return(trx_recover_for_mysql(xid_list, len));
8073
8342
}
8074
8343
 
8075
8344
/*******************************************************************//**
8077
8346
which is in the prepared state
8078
8347
@return 0 or error number */
8079
8348
int
8080
 
InnobaseEngine::doXaCommitXid(
 
8349
InnobaseEngine::commit_by_xid(
8081
8350
/*===================*/
8082
 
        ::drizzled::XID*        xid)    /*!< in: X/Open XA transaction identification */
 
8351
        XID*    xid)    /*!< in: X/Open XA transaction identification */
8083
8352
{
8084
8353
        trx_t*  trx;
8085
8354
 
8086
8355
        assert(this == innodb_engine_ptr);
8087
8356
 
8088
 
        trx = trx_get_trx_by_xid((::XID *)xid);
 
8357
        trx = trx_get_trx_by_xid(xid);
8089
8358
 
8090
8359
        if (trx) {
8091
8360
                innobase_commit_low(trx);
8101
8370
which is in the prepared state
8102
8371
@return 0 or error number */
8103
8372
int
8104
 
InnobaseEngine::doXaRollbackXid(
 
8373
InnobaseEngine::rollback_by_xid(
8105
8374
/*=====================*/
8106
 
        ::drizzled::XID*                xid)    /*!< in: X/Open XA transaction
 
8375
        XID*            xid)    /*!< in: X/Open XA transaction
8107
8376
                                identification */
8108
8377
{
8109
8378
        trx_t*  trx;
8110
8379
 
8111
8380
        assert(this == innodb_engine_ptr);
8112
8381
 
8113
 
        trx = trx_get_trx_by_xid((::XID *)xid);
 
8382
        trx = trx_get_trx_by_xid(xid);
8114
8383
 
8115
8384
        if (trx) {
8116
8385
                return(innobase_rollback_trx(trx));
8224
8493
innodb_file_format_name_validate(
8225
8494
/*=============================*/
8226
8495
        Session*                        ,       /*!< in: thread handle */
8227
 
        drizzle_sys_var*        ,       /*!< in: pointer to system
 
8496
        struct st_mysql_sys_var*        ,       /*!< in: pointer to system
8228
8497
                                                variable */
8229
8498
        void*                           save,   /*!< out: immediate result
8230
8499
                                                for update function */
8231
 
        drizzle_value*          value)  /*!< in: incoming string */
 
8500
        struct st_mysql_value*          value)  /*!< in: incoming string */
8232
8501
{
8233
8502
        const char*     file_format_input;
8234
8503
        char            buff[STRING_BUFFER_USUAL_SIZE];
8264
8533
innodb_file_format_name_update(
8265
8534
/*===========================*/
8266
8535
        Session*                        ,               /*!< in: thread handle */
8267
 
        drizzle_sys_var*        ,               /*!< in: pointer to
 
8536
        struct st_mysql_sys_var*        ,               /*!< in: pointer to
8268
8537
                                                        system variable */
8269
8538
        void*                           var_ptr,        /*!< out: where the
8270
8539
                                                        formal string goes */
8301
8570
innodb_file_format_check_validate(
8302
8571
/*==============================*/
8303
8572
        Session*                        ,       /*!< in: thread handle */
8304
 
        drizzle_sys_var*        ,       /*!< in: pointer to system
 
8573
        struct st_mysql_sys_var*        ,       /*!< in: pointer to system
8305
8574
                                                variable */
8306
8575
        void*                           save,   /*!< out: immediate result
8307
8576
                                                for update function */
8308
 
        drizzle_value*          value)  /*!< in: incoming string */
 
8577
        struct st_mysql_value*          value)  /*!< in: incoming string */
8309
8578
{
8310
8579
        const char*     file_format_input;
8311
8580
        char            buff[STRING_BUFFER_USUAL_SIZE];
8355
8624
innodb_file_format_check_update(
8356
8625
/*============================*/
8357
8626
        Session*                        session,        /*!< in: thread handle */
8358
 
        drizzle_sys_var*        ,               /*!< in: pointer to
 
8627
        struct st_mysql_sys_var*        ,               /*!< in: pointer to
8359
8628
                                                        system variable */
8360
8629
        void*                           var_ptr,        /*!< out: where the
8361
8630
                                                        formal string goes */
8406
8675
innodb_adaptive_hash_index_update(
8407
8676
/*==============================*/
8408
8677
        Session*                        ,               /*!< in: thread handle */
8409
 
        drizzle_sys_var*        ,               /*!< in: pointer to
 
8678
        struct st_mysql_sys_var*        ,               /*!< in: pointer to
8410
8679
                                                        system variable */
8411
8680
        void*                           ,       /*!< out: where the
8412
8681
                                                        formal string goes */
8429
8698
innodb_change_buffering_validate(
8430
8699
/*=============================*/
8431
8700
        Session*                        ,       /*!< in: thread handle */
8432
 
        drizzle_sys_var*        ,       /*!< in: pointer to system
 
8701
        struct st_mysql_sys_var*        ,       /*!< in: pointer to system
8433
8702
                                                variable */
8434
8703
        void*                           save,   /*!< out: immediate result
8435
8704
                                                for update function */
8436
 
        drizzle_value*          value)  /*!< in: incoming string */
 
8705
        struct st_mysql_value*          value)  /*!< in: incoming string */
8437
8706
{
8438
8707
        const char*     change_buffering_input;
8439
8708
        char            buff[STRING_BUFFER_USUAL_SIZE];
8469
8738
innodb_change_buffering_update(
8470
8739
/*===========================*/
8471
8740
        Session*                        ,               /*!< in: thread handle */
8472
 
        drizzle_sys_var*        ,               /*!< in: pointer to
 
8741
        struct st_mysql_sys_var*        ,               /*!< in: pointer to
8473
8742
                                                        system variable */
8474
8743
        void*                           var_ptr,        /*!< out: where the
8475
8744
                                                        formal string goes */
8485
8754
        *(const char**) var_ptr = innobase_change_buffering_values[ibuf_use];
8486
8755
}
8487
8756
 
 
8757
static int show_innodb_vars(SHOW_VAR *var, char *)
 
8758
{
 
8759
  innodb_export_status();
 
8760
  var->type= SHOW_ARRAY;
 
8761
  var->value= (char *) &innodb_status_variables;
 
8762
  return 0;
 
8763
}
 
8764
 
 
8765
static st_show_var_func_container
 
8766
show_innodb_vars_cont = { &show_innodb_vars };
 
8767
 
 
8768
static SHOW_VAR innodb_status_variables_export[]= {
 
8769
  {"Innodb",                   (char*) &show_innodb_vars_cont, SHOW_FUNC},
 
8770
  {NULL, NULL, SHOW_LONG}
 
8771
};
 
8772
 
 
8773
 
8488
8774
/* plugin options */
8489
8775
static DRIZZLE_SYSVAR_BOOL(checksums, innobase_use_checksums,
8490
8776
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
8545
8831
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8546
8832
  "With which method to flush data.", NULL, NULL, NULL);
8547
8833
 
 
8834
static DRIZZLE_SYSVAR_BOOL(locks_unsafe_for_binlog, innobase_locks_unsafe_for_binlog,
 
8835
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
 
8836
  "Force InnoDB to not use next-key locking, to use only row-level locking.",
 
8837
  NULL, NULL, TRUE);
 
8838
 
8548
8839
#ifdef UNIV_LOG_ARCHIVE
8549
8840
static DRIZZLE_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
8550
8841
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8735
9026
  "trigger a readahead.",
8736
9027
  NULL, NULL, 56, 0, 64, 0);
8737
9028
 
8738
 
static drizzle_sys_var* innobase_system_variables[]= {
 
9029
static struct st_mysql_sys_var* innobase_system_variables[]= {
8739
9030
  DRIZZLE_SYSVAR(additional_mem_pool_size),
8740
9031
  DRIZZLE_SYSVAR(autoextend_increment),
8741
9032
  DRIZZLE_SYSVAR(buffer_pool_size),
8755
9046
  DRIZZLE_SYSVAR(flush_log_at_trx_commit),
8756
9047
  DRIZZLE_SYSVAR(flush_method),
8757
9048
  DRIZZLE_SYSVAR(force_recovery),
 
9049
  DRIZZLE_SYSVAR(locks_unsafe_for_binlog),
8758
9050
  DRIZZLE_SYSVAR(lock_wait_timeout),
8759
9051
#ifdef UNIV_LOG_ARCHIVE
8760
9052
  DRIZZLE_SYSVAR(log_arch_dir),
8791
9083
  NULL
8792
9084
};
8793
9085
 
8794
 
DRIZZLE_DECLARE_PLUGIN
 
9086
drizzle_declare_plugin
8795
9087
{
8796
 
  DRIZZLE_VERSION_ID,
8797
9088
  innobase_engine_name,
8798
9089
  INNODB_VERSION_STR,
8799
9090
  "Innobase Oy",
8800
9091
  "Supports transactions, row-level locking, and foreign keys",
8801
9092
  PLUGIN_LICENSE_GPL,
8802
9093
  innobase_init, /* Plugin Init */
 
9094
  innobase_deinit, /* Plugin Deinit */
 
9095
  innodb_status_variables_export,/* status variables             */
8803
9096
  innobase_system_variables, /* system variables */
8804
9097
  NULL /* reserved */
8805
9098
}
8806
 
DRIZZLE_DECLARE_PLUGIN_END;
 
9099
drizzle_declare_plugin_end;
8807
9100
 
8808
9101
int ha_innobase::read_range_first(const key_range *start_key,
8809
9102
                                  const key_range *end_key,