summaryrefslogtreecommitdiff
path: root/storage/mroonga/ha_mroonga.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'storage/mroonga/ha_mroonga.cpp')
-rw-r--r--storage/mroonga/ha_mroonga.cpp876
1 files changed, 632 insertions, 244 deletions
diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp
index dbc2f0ca6e3..83f03fcb272 100644
--- a/storage/mroonga/ha_mroonga.cpp
+++ b/storage/mroonga/ha_mroonga.cpp
@@ -21,6 +21,7 @@
*/
#include "mrn_mysql.h"
+#include "mrn_mysql_compat.h"
#ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation
@@ -35,6 +36,11 @@
#endif
#include <sql_select.h>
+#include <item_sum.h>
+
+#ifdef MRN_HAVE_BINLOG_H
+# include <binlog.h>
+#endif
#ifdef MRN_HAVE_SQL_OPTIMIZER_H
# include <sql_optimizer.h>
@@ -49,9 +55,6 @@
#ifdef WIN32
# include <math.h>
# include <direct.h>
-# define MRN_ALLOCATE_VARIABLE_LENGTH_ARRAYS(type, variable_name, variable_size) \
- type *variable_name = (type *)_malloca(sizeof(type) * (variable_size))
-# define MRN_FREE_VARIABLE_LENGTH_ARRAYS(variable_name) _freea(variable_name)
# define MRN_TABLE_SHARE_LOCK_SHARE_PROC "?key_TABLE_SHARE_LOCK_share@@3IA"
# define MRN_TABLE_SHARE_LOCK_HA_DATA_PROC "?key_TABLE_SHARE_LOCK_ha_data@@3IA"
# ifdef _WIN64
@@ -64,11 +67,14 @@
#else
# include <dirent.h>
# include <unistd.h>
-# define MRN_ALLOCATE_VARIABLE_LENGTH_ARRAYS(type, variable_name, variable_size) \
- type variable_name[variable_size]
-# define MRN_FREE_VARIABLE_LENGTH_ARRAYS(variable_name)
#endif
+#define MRN_ALLOCATE_VARIABLE_LENGTH_ARRAYS(type, variable_name, variable_size) \
+ type *variable_name = \
+ (type *)mrn_my_malloc(sizeof(type) * (variable_size), MYF(MY_WME))
+#define MRN_FREE_VARIABLE_LENGTH_ARRAYS(variable_name) \
+ my_free(variable_name)
+
#include "mrn_err.h"
#include "mrn_table.hpp"
#include "ha_mroonga.hpp"
@@ -89,6 +95,8 @@
#include <mrn_smart_grn_obj.hpp>
#include <mrn_database_manager.hpp>
#include <mrn_grn.hpp>
+#include <mrn_value_decoder.hpp>
+#include <mrn_database_repairer.hpp>
#ifdef MRN_SUPPORT_FOREIGN_KEYS
# include <sql_table.h>
@@ -148,7 +156,11 @@ static mysql_mutex_t *mrn_LOCK_open;
# define mrn_declare_plugin(NAME) maria_declare_plugin(NAME)
# define mrn_declare_plugin_end maria_declare_plugin_end
# define MRN_PLUGIN_LAST_VALUES MRN_VERSION, MariaDB_PLUGIN_MATURITY_STABLE
-# define MRN_ABORT_ON_WARNING(thd) thd_kill_level(thd)
+# if MYSQL_VERSION_ID >= 100000
+# define MRN_ABORT_ON_WARNING(thd) thd_kill_level(thd)
+# else
+# define MRN_ABORT_ON_WARNING(thd) thd->abort_on_warning
+# endif
#else
# define mrn_declare_plugin(NAME) mysql_declare_plugin(NAME)
# define mrn_declare_plugin_end mysql_declare_plugin_end
@@ -157,7 +169,11 @@ static mysql_mutex_t *mrn_LOCK_open;
# else
# define MRN_PLUGIN_LAST_VALUES NULL
# endif
-# define MRN_ABORT_ON_WARNING(thd) thd->abort_on_warning
+# if MYSQL_VERSION_ID >= 50706
+# define MRN_ABORT_ON_WARNING(thd) false
+# else
+# define MRN_ABORT_ON_WARNING(thd) thd->abort_on_warning
+# endif
#endif
#if MYSQL_VERSION_ID >= 100007 && defined(MRN_MARIADB_P)
@@ -172,12 +188,69 @@ static mysql_mutex_t *mrn_LOCK_open;
# define MRN_GET_ERR_MSG(code) ER(code)
#endif
+#if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P)
+# define MRN_LEX_GET_TABLE_LIST(lex) (lex)->select_lex->table_list.first
+#else
+# define MRN_LEX_GET_TABLE_LIST(lex) (lex)->select_lex.table_list.first
+#endif
+
+#if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P)
+# define MRN_KEYTYPE_FOREIGN KEYTYPE_FOREIGN
+#else
+# define MRN_KEYTYPE_FOREIGN Key::FOREIGN_KEY
+#endif
+
+#if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P)
+# define mrn_calculate_key_len(table, key_index, buffer, keypart_map) \
+ calculate_key_len(table, key_index, keypart_map)
+#else
+# define mrn_calculate_key_len(table, key_index, buffer, keypart_map) \
+ calculate_key_len(table, key_index, buffer, keypart_map)
+#endif
+
+#if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P)
+# define MRN_SELECT_LEX_GET_WHERE_COND(select_lex) \
+ ((select_lex)->where_cond())
+# define MRN_SELECT_LEX_GET_HAVING_COND(select_lex) \
+ ((select_lex)->having_cond())
+# define MRN_SELECT_LEX_GET_ACTIVE_OPTIONS(select_lex) \
+ ((select_lex)->active_options())
+#else
+# define MRN_SELECT_LEX_GET_WHERE_COND(select_lex) \
+ ((select_lex)->where)
+# define MRN_SELECT_LEX_GET_HAVING_COND(select_lex) \
+ ((select_lex)->having)
+# define MRN_SELECT_LEX_GET_ACTIVE_OPTIONS(select_lex) \
+ ((select_lex)->options)
+#endif
+
+#if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P)
+# define MRN_TABLE_LIST_GET_DERIVED(table_list) NULL
+#else
+# define MRN_TABLE_LIST_GET_DERIVED(table_list) (table_list)->derived
+#endif
+
+#if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P)
+# define MRN_GEOMETRY_FREE(geometry)
+#else
+# define MRN_GEOMETRY_FREE(geometry) delete (geometry)
+#endif
+
Rpl_filter *mrn_binlog_filter;
Time_zone *mrn_my_tz_UTC;
#ifdef MRN_HAVE_TABLE_DEF_CACHE
HASH *mrn_table_def_cache;
#endif
+#ifdef MRN_HAVE_PSI_MEMORY_KEY
+PSI_memory_key mrn_memory_key;
+
+static PSI_memory_info mrn_all_memory_keys[]=
+{
+ {&mrn_memory_key, "Mroonga", 0}
+};
+#endif
+
static const char *INDEX_COLUMN_NAME = "index";
static const char *MRN_PLUGIN_AUTHOR = "The Mroonga project";
@@ -189,31 +262,22 @@ extern "C" {
int grn_atoi(const char *nptr, const char *end, const char **rest);
uint grn_atoui(const char *nptr, const char *end, const char **rest);
-/* global variables */
-handlerton *mrn_hton_ptr;
-HASH mrn_open_tables;
-mysql_mutex_t mrn_open_tables_mutex;
-HASH mrn_long_term_share;
-mysql_mutex_t mrn_long_term_share_mutex;
-
-HASH mrn_allocated_thds;
-mysql_mutex_t mrn_allocated_thds_mutex;
-/* internal variables */
-static grn_ctx mrn_ctx;
-static mysql_mutex_t mrn_log_mutex;
-static grn_obj *mrn_db;
-static grn_ctx mrn_db_manager_ctx;
-static mysql_mutex_t mrn_db_manager_mutex;
-mrn::DatabaseManager *mrn_db_manager = NULL;
-
#ifdef HAVE_PSI_INTERFACE
-PSI_mutex_key mrn_allocated_thds_mutex_key;
+# ifdef WIN32
+# ifdef MRN_TABLE_SHARE_HAVE_LOCK_SHARE
+PSI_mutex_key *mrn_table_share_lock_share;
+# endif
+# ifdef MRN_TABLE_SHARE_HAVE_LOCK_HA_DATA
+PSI_mutex_key *mrn_table_share_lock_ha_data;
+# endif
+# endif
static PSI_mutex_key mrn_open_tables_mutex_key;
static PSI_mutex_key mrn_long_term_share_mutex_key;
+static PSI_mutex_key mrn_allocated_thds_mutex_key;
PSI_mutex_key mrn_share_mutex_key;
PSI_mutex_key mrn_long_term_share_auto_inc_mutex_key;
-static PSI_mutex_key mrn_db_manager_mutex_key;
static PSI_mutex_key mrn_log_mutex_key;
+static PSI_mutex_key mrn_db_manager_mutex_key;
static PSI_mutex_info mrn_mutexes[] =
{
@@ -226,20 +290,25 @@ static PSI_mutex_info mrn_mutexes[] =
{&mrn_log_mutex_key, "log", PSI_FLAG_GLOBAL},
{&mrn_db_manager_mutex_key, "DatabaseManager", PSI_FLAG_GLOBAL}
};
-
-#ifdef WIN32
-# ifdef MRN_TABLE_SHARE_HAVE_LOCK_SHARE
- PSI_mutex_key *mrn_table_share_lock_share;
-# endif
-# ifdef MRN_TABLE_SHARE_HAVE_LOCK_HA_DATA
- PSI_mutex_key *mrn_table_share_lock_ha_data;
-# endif
#endif
-#else
-#undef MRN_TABLE_SHARE_HAVE_LOCK_SHARE
-#undef MRN_TABLE_SHARE_HAVE_LOCK_HA_DATA
-#endif
+/* global variables */
+handlerton *mrn_hton_ptr;
+HASH mrn_open_tables;
+mysql_mutex_t mrn_open_tables_mutex;
+HASH mrn_long_term_share;
+mysql_mutex_t mrn_long_term_share_mutex;
+
+HASH mrn_allocated_thds;
+mysql_mutex_t mrn_allocated_thds_mutex;
+
+/* internal variables */
+static grn_ctx mrn_ctx;
+static mysql_mutex_t mrn_log_mutex;
+static grn_obj *mrn_db;
+static grn_ctx mrn_db_manager_ctx;
+static mysql_mutex_t mrn_db_manager_mutex;
+mrn::DatabaseManager *mrn_db_manager = NULL;
#ifdef WIN32
@@ -293,12 +362,19 @@ static const char *mrn_inspect_thr_lock_type(enum thr_lock_type lock_type)
inspected = "TL_WRITE_ALLOW_READ";
break;
#endif
+#ifdef MRN_HAVE_TL_WRITE_CONCURRENT_DEFAULT
+ case TL_WRITE_CONCURRENT_DEFAULT:
+ inspected = "TL_WRITE_CONCURRENT_DEFAULT";
+ break;
+#endif
case TL_WRITE_CONCURRENT_INSERT:
inspected = "TL_WRITE_CONCURRENT_INSERT";
break;
+#ifdef MRN_HAVE_TL_WRITE_DELAYED
case TL_WRITE_DELAYED:
inspected = "TL_WRITE_DELAYED";
break;
+#endif
case TL_WRITE_DEFAULT:
inspected = "TL_WRITE_DEFAULT";
break;
@@ -537,6 +613,7 @@ typedef enum {
MRN_BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_UPDATE = (1 << 4),
MRN_BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_LEADING_NOT = (1 << 5)
} mrn_boolean_mode_syntax_flag;
+#ifdef MRN_SUPPORT_THDVAR_SET
static const char *mrn_boolean_mode_sytnax_flag_names[] = {
"DEFAULT",
"SYNTAX_QUERY",
@@ -552,6 +629,7 @@ static TYPELIB mrn_boolean_mode_syntax_flags_typelib = {
mrn_boolean_mode_sytnax_flag_names,
NULL
};
+#endif
typedef enum {
MRN_ACTION_ON_ERROR_ERROR,
@@ -612,13 +690,25 @@ static uchar *mrn_allocated_thds_get_key(const uchar *record,
static struct st_mysql_storage_engine storage_engine_structure =
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
+#if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P)
+# define MRN_STATUS_VARIABLE_ENTRY(name, value, type, scope) \
+ {name, value, type, scope}
+#else
+# define MRN_STATUS_VARIABLE_ENTRY(name, value, type, scope) \
+ {name, value, type}
+#endif
+
static struct st_mysql_show_var mrn_status_variables[] =
{
- {MRN_STATUS_VARIABLE_NAME_PREFIX_STRING "_count_skip",
- (char *)&mrn_count_skip, SHOW_LONG},
- {MRN_STATUS_VARIABLE_NAME_PREFIX_STRING "_fast_order_limit",
- (char *)&mrn_fast_order_limit, SHOW_LONG},
- {NullS, NullS, SHOW_LONG}
+ MRN_STATUS_VARIABLE_ENTRY(MRN_STATUS_VARIABLE_NAME_PREFIX_STRING "_count_skip",
+ (char *)&mrn_count_skip,
+ SHOW_LONG,
+ SHOW_SCOPE_GLOBAL),
+ MRN_STATUS_VARIABLE_ENTRY(MRN_STATUS_VARIABLE_NAME_PREFIX_STRING "_fast_order_limit",
+ (char *)&mrn_fast_order_limit,
+ SHOW_LONG,
+ SHOW_SCOPE_GLOBAL),
+ MRN_STATUS_VARIABLE_ENTRY(NullS, NullS, SHOW_LONG, SHOW_SCOPE_GLOBAL)
};
static const char *mrn_log_level_type_names[] = {
@@ -728,10 +818,10 @@ static void mrn_log_file_update(THD *thd, struct st_mysql_sys_var *var,
#ifdef MRN_NEED_FREE_STRING_MEMALLOC_PLUGIN_VAR
char *old_log_file_name = *old_value_ptr;
- *old_value_ptr = my_strdup(new_log_file_name, MYF(MY_WME));
+ *old_value_ptr = mrn_my_strdup(new_log_file_name, MYF(MY_WME));
my_free(old_log_file_name);
#else
- *old_value_ptr = my_strdup(new_log_file_name, MYF(MY_WME));
+ *old_value_ptr = mrn_my_strdup(new_log_file_name, MYF(MY_WME));
#endif
grn_ctx_fin(&ctx);
@@ -769,7 +859,7 @@ static void mrn_default_parser_update(THD *thd, struct st_mysql_sys_var *var,
#ifdef MRN_NEED_FREE_STRING_MEMALLOC_PLUGIN_VAR
my_free(*old_value_ptr);
- *old_value_ptr = my_strdup(new_value, MYF(MY_WME));
+ *old_value_ptr = mrn_my_strdup(new_value, MYF(MY_WME));
#else
*old_value_ptr = (char *)new_value;
#endif
@@ -811,7 +901,7 @@ static MYSQL_THDVAR_LONGLONG(match_escalation_threshold,
NULL,
grn_get_default_match_escalation_threshold(),
-1,
- LONGLONG_MAX,
+ INT_MAX64,
0);
static void mrn_vector_column_delimiter_update(THD *thd, struct st_mysql_sys_var *var,
@@ -823,7 +913,7 @@ static void mrn_vector_column_delimiter_update(THD *thd, struct st_mysql_sys_var
#ifdef MRN_NEED_FREE_STRING_MEMALLOC_PLUGIN_VAR
my_free(*old_value_ptr);
- *old_value_ptr = my_strdup(new_value, MYF(MY_WME));
+ *old_value_ptr = mrn_my_strdup(new_value, MYF(MY_WME));
#else
*old_value_ptr = (char *)new_value;
#endif
@@ -849,7 +939,7 @@ static void mrn_database_path_prefix_update(THD *thd,
if (*old_value_ptr)
my_free(*old_value_ptr);
if (new_value)
- *old_value_ptr = my_strdup(new_value, MYF(MY_WME));
+ *old_value_ptr = mrn_my_strdup(new_value, MYF(MY_WME));
else
*old_value_ptr = NULL;
#else
@@ -967,6 +1057,7 @@ static MYSQL_SYSVAR_BOOL(libgroonga_support_lz4, mrn_libgroonga_support_lz4,
NULL,
grn_check_lz4_support());
+#ifdef MRN_SUPPORT_THDVAR_SET
static MYSQL_THDVAR_SET(boolean_mode_syntax_flags,
PLUGIN_VAR_RQCMDARG,
"The flags to custom syntax in BOOLEAN MODE. "
@@ -978,6 +1069,20 @@ static MYSQL_THDVAR_SET(boolean_mode_syntax_flags,
NULL,
MRN_BOOLEAN_MODE_SYNTAX_FLAG_DEFAULT,
&mrn_boolean_mode_syntax_flags_typelib);
+#endif
+
+static const int MRN_MAX_N_RECORDS_FOR_ESTIMATE_DEFAULT = 1000;
+
+static MYSQL_THDVAR_INT(max_n_records_for_estimate,
+ PLUGIN_VAR_RQCMDARG,
+ "The max number of records to "
+ "estimate the number of matched records",
+ NULL,
+ NULL,
+ MRN_MAX_N_RECORDS_FOR_ESTIMATE_DEFAULT,
+ -1,
+ INT_MAX,
+ 0);
static struct st_mysql_sys_var *mrn_system_variables[] =
{
@@ -996,7 +1101,10 @@ static struct st_mysql_sys_var *mrn_system_variables[] =
MYSQL_SYSVAR(vector_column_delimiter),
MYSQL_SYSVAR(libgroonga_support_zlib),
MYSQL_SYSVAR(libgroonga_support_lz4),
+#ifdef MRN_SUPPORT_THDVAR_SET
MYSQL_SYSVAR(boolean_mode_syntax_flags),
+#endif
+ MYSQL_SYSVAR(max_n_records_for_estimate),
NULL
};
@@ -1116,7 +1224,11 @@ static int mrn_close_connection(handlerton *hton, THD *thd)
DBUG_RETURN(0);
}
+#ifdef MRN_FLUSH_LOGS_HAVE_BINLOG_GROUP_FLUSH
+static bool mrn_flush_logs(handlerton *hton, bool binlog_group_flush)
+#else
static bool mrn_flush_logs(handlerton *hton)
+#endif
{
MRN_DBUG_ENTER_FUNCTION();
bool result = 0;
@@ -1322,7 +1434,7 @@ grn_obj_flags mrn_parse_grn_column_create_flags(THD *thd,
if (mrn_libgroonga_support_zlib) {
flags |= GRN_OBJ_COMPRESS_ZLIB;
} else {
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ push_warning_printf(thd, MRN_SEVERITY_WARNING,
ER_MRN_UNSUPPORTED_COLUMN_FLAG_NUM,
ER_MRN_UNSUPPORTED_COLUMN_FLAG_STR,
"COMPRESS_ZLIB");
@@ -1332,7 +1444,7 @@ grn_obj_flags mrn_parse_grn_column_create_flags(THD *thd,
if (mrn_libgroonga_support_lz4) {
flags |= GRN_OBJ_COMPRESS_LZ4;
} else {
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ push_warning_printf(thd, MRN_SEVERITY_WARNING,
ER_MRN_UNSUPPORTED_COLUMN_FLAG_NUM,
ER_MRN_UNSUPPORTED_COLUMN_FLAG_STR,
"COMPRESS_LZ4");
@@ -1344,7 +1456,7 @@ grn_obj_flags mrn_parse_grn_column_create_flags(THD *thd,
"%.*s",
static_cast<int>(rest_length),
flag_names);
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ push_warning_printf(thd, MRN_SEVERITY_WARNING,
ER_MRN_INVALID_COLUMN_FLAG_NUM,
ER_MRN_INVALID_COLUMN_FLAG_STR,
invalid_flag_name,
@@ -1356,7 +1468,53 @@ grn_obj_flags mrn_parse_grn_column_create_flags(THD *thd,
return flags;
}
-#ifdef HAVE_SPATIAL
+bool mrn_parse_grn_index_column_flags(THD *thd,
+ grn_ctx *ctx,
+ const char *flag_names,
+ uint flag_names_length,
+ grn_obj_flags *index_column_flags)
+{
+ const char *flag_names_end = flag_names + flag_names_length;
+ bool found = false;
+
+ while (flag_names < flag_names_end) {
+ uint rest_length = flag_names_end - flag_names;
+
+ if (*flag_names == '|' || *flag_names == ' ') {
+ flag_names += 1;
+ continue;
+ }
+ if (rest_length >= 4 && !memcmp(flag_names, "NONE", 4)) {
+ flag_names += 4;
+ found = true;
+ } else if (rest_length >= 13 && !memcmp(flag_names, "WITH_POSITION", 13)) {
+ *index_column_flags |= GRN_OBJ_WITH_POSITION;
+ flag_names += 13;
+ found = true;
+ } else if (rest_length >= 12 && !memcmp(flag_names, "WITH_SECTION", 12)) {
+ *index_column_flags |= GRN_OBJ_WITH_SECTION;
+ flag_names += 12;
+ found = true;
+ } else if (rest_length >= 11 && !memcmp(flag_names, "WITH_WEIGHT", 11)) {
+ *index_column_flags |= GRN_OBJ_WITH_WEIGHT;
+ flag_names += 11;
+ found = true;
+ } else {
+ char invalid_flag_name[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(invalid_flag_name, MRN_MESSAGE_BUFFER_SIZE,
+ "%.*s",
+ static_cast<int>(rest_length),
+ flag_names);
+ push_warning_printf(thd, MRN_SEVERITY_WARNING,
+ ER_MRN_INVALID_INDEX_FLAG_NUM,
+ ER_MRN_INVALID_INDEX_FLAG_STR,
+ invalid_flag_name);
+ }
+ }
+ return found;
+}
+
+#ifdef MRN_HAVE_SPATIAL
static int mrn_set_geometry(grn_ctx *ctx, grn_obj *buf,
const char *wkb, uint wkb_size)
{
@@ -1393,12 +1551,13 @@ static int mrn_set_geometry(grn_ctx *ctx, grn_obj *buf,
error = ER_MRN_GEOMETRY_NOT_SUPPORT_NUM;
break;
}
- delete geometry;
+ MRN_GEOMETRY_FREE(geometry);
return error;
}
#endif
+#ifdef MRN_HAVE_HTON_ALTER_TABLE_FLAGS
static uint mrn_alter_table_flags(uint flags)
{
uint alter_flags = 0;
@@ -1419,18 +1578,15 @@ static uint mrn_alter_table_flags(uint flags)
HA_INPLACE_DROP_INDEX_NO_READ_WRITE |
HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE |
HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE |
- HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE |
- HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE |
HA_INPLACE_ADD_INDEX_NO_WRITE |
HA_INPLACE_DROP_INDEX_NO_WRITE |
HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE |
- HA_INPLACE_DROP_UNIQUE_INDEX_NO_WRITE |
- HA_INPLACE_ADD_PK_INDEX_NO_WRITE |
- HA_INPLACE_DROP_PK_INDEX_NO_WRITE;
+ HA_INPLACE_DROP_UNIQUE_INDEX_NO_WRITE;
}
#endif
return alter_flags;
}
+#endif
static int mrn_init(void *p)
{
@@ -1440,11 +1596,16 @@ static int mrn_init(void *p)
hton = (handlerton *)p;
hton->state = SHOW_OPTION_YES;
hton->create = mrn_handler_create;
- hton->flags = 0;
+ hton->flags = HTON_NO_FLAGS;
+#ifndef MRN_SUPPORT_PARTITION
+ hton->flags |= HTON_NO_PARTITION;
+#endif
hton->drop_database = mrn_drop_database;
hton->close_connection = mrn_close_connection;
hton->flush_logs = mrn_flush_logs;
+#ifdef MRN_HAVE_HTON_ALTER_TABLE_FLAGS
hton->alter_table_flags = mrn_alter_table_flags;
+#endif
mrn_hton_ptr = hton;
#ifdef _WIN32
@@ -1462,13 +1623,17 @@ static int mrn_init(void *p)
(mysql_mutex_t *)GetProcAddress(current_module,
"?LOCK_open@@3Ust_mysql_mutex@@A");
# endif
-# ifdef MRN_TABLE_SHARE_HAVE_LOCK_SHARE
- mrn_table_share_lock_share =
- (PSI_mutex_key *)GetProcAddress(current_module, MRN_TABLE_SHARE_LOCK_SHARE_PROC);
-# endif
-# ifdef MRN_TABLE_SHARE_HAVE_LOCK_HA_DATA
- mrn_table_share_lock_ha_data =
- (PSI_mutex_key *)GetProcAddress(current_module, MRN_TABLE_SHARE_LOCK_HA_DATA_PROC);
+# ifdef HAVE_PSI_INTERFACE
+# ifdef MRN_TABLE_SHARE_HAVE_LOCK_SHARE
+ mrn_table_share_lock_share =
+ (PSI_mutex_key *)GetProcAddress(current_module,
+ MRN_TABLE_SHARE_LOCK_SHARE_PROC);
+# endif
+# ifdef MRN_TABLE_SHARE_HAVE_LOCK_HA_DATA
+ mrn_table_share_lock_ha_data =
+ (PSI_mutex_key *)GetProcAddress(current_module,
+ MRN_TABLE_SHARE_LOCK_HA_DATA_PROC);
+# endif
# endif
#else
mrn_binlog_filter = binlog_filter;
@@ -1502,6 +1667,14 @@ static int mrn_init(void *p)
if (mrn_change_encoding(ctx, system_charset_info))
goto err_mrn_change_encoding;
+#ifdef MRN_HAVE_PSI_MEMORY_KEY
+ {
+ const char *category = "ha_mroonga";
+ int n_keys = array_elements(mrn_all_memory_keys);
+ mysql_memory_register(category, mrn_all_memory_keys, n_keys);
+ }
+#endif
+
if (mysql_mutex_init(mrn_log_mutex_key,
&mrn_log_mutex,
MY_MUTEX_INIT_FAST) != 0) {
@@ -2164,6 +2337,9 @@ ha_mroonga::~ha_mroonga()
if (share_for_create.wrapper_mode) {
plugin_unlock(NULL, share_for_create.plugin);
}
+ if (share_for_create.table_name) {
+ my_free(share_for_create.table_name);
+ }
mrn_free_share_alloc(&share_for_create);
free_root(&mem_root_for_create, MYF(0));
}
@@ -2545,7 +2721,7 @@ int ha_mroonga::create_share_for_create() const
THD *thd = ha_thd();
LEX *lex = thd->lex;
HA_CREATE_INFO *create_info = &lex->create_info;
- TABLE_LIST *table_list = lex->select_lex.table_list.first;
+ TABLE_LIST *table_list = MRN_LEX_GET_TABLE_LIST(lex);
MRN_DBUG_ENTER_METHOD();
wrap_handler_for_create = NULL;
memset(&table_for_create, 0, sizeof(TABLE));
@@ -2589,10 +2765,12 @@ int ha_mroonga::create_share_for_create() const
}
}
}
- init_alloc_root(&mem_root_for_create, 1024, 0, MYF(0));
+ mrn_init_alloc_root(&mem_root_for_create, 1024, 0, MYF(0));
analyzed_for_create = true;
if (table_list) {
- share_for_create.table_name = table_list->table_name;
+ share_for_create.table_name = mrn_my_strndup(table_list->table_name,
+ table_list->table_name_length,
+ MYF(MY_WME));
share_for_create.table_name_length = table_list->table_name_length;
}
share_for_create.table_share = &table_share_for_create;
@@ -2741,10 +2919,13 @@ int ha_mroonga::wrapper_create_index_fulltext(const char *grn_table_name,
GRN_OBJ_PERSISTENT;
grn_obj *index_table;
- grn_obj_flags index_column_flags =
- GRN_OBJ_COLUMN_INDEX | GRN_OBJ_WITH_POSITION | GRN_OBJ_PERSISTENT;
- if (KEY_N_KEY_PARTS(key_info) > 1) {
- index_column_flags |= GRN_OBJ_WITH_SECTION;
+ grn_obj_flags index_column_flags = GRN_OBJ_COLUMN_INDEX | GRN_OBJ_PERSISTENT;
+
+ if (!find_index_column_flags(key_info, &index_column_flags)) {
+ index_column_flags |= GRN_OBJ_WITH_POSITION;
+ if (KEY_N_KEY_PARTS(key_info) > 1) {
+ index_column_flags |= GRN_OBJ_WITH_SECTION;
+ }
}
mrn::SmartGrnObj lexicon_key_type(ctx, GRN_DB_SHORT_TEXT);
@@ -3029,7 +3210,8 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
DBUG_RETURN(error);
}
- if (table_flags == (GRN_OBJ_PERSISTENT | GRN_OBJ_TABLE_PAT_KEY)) {
+ if (table_flags == (GRN_OBJ_PERSISTENT | GRN_OBJ_TABLE_PAT_KEY) ||
+ table_flags == (GRN_OBJ_PERSISTENT | GRN_OBJ_TABLE_HASH_KEY)) {
KEY key_info = table->s->key_info[pkey_nr];
int key_parts = KEY_N_KEY_PARTS(&key_info);
if (key_parts == 1) {
@@ -3182,7 +3364,7 @@ bool ha_mroonga::storage_create_foreign_key(TABLE *table,
char ref_db_buff[NAME_LEN + 1], ref_table_buff[NAME_LEN + 1];
while ((key = key_iterator++))
{
- if (key->type != Key::FOREIGN_KEY)
+ if (key->type != MRN_KEYTYPE_FOREIGN)
{
continue;
}
@@ -3207,7 +3389,11 @@ bool ha_mroonga::storage_create_foreign_key(TABLE *table,
Key_part_spec *key_part_ref_col = key_part_ref_col_iterator++;
LEX_STRING ref_field_name = key_part_ref_col->field_name;
DBUG_PRINT("info", ("mroonga: ref_field_name=%s", ref_field_name.str));
+#ifdef MRN_FOREIGN_KEY_USE_CONST_STRING
+ LEX_CSTRING ref_db_name = fk->ref_db;
+#else
LEX_STRING ref_db_name = fk->ref_db;
+#endif
DBUG_PRINT("info", ("mroonga: ref_db_name=%s", ref_db_name.str));
if (ref_db_name.str && lower_case_table_names) {
strmake(ref_db_buff, ref_db_name.str, sizeof(ref_db_buff) - 1);
@@ -3215,7 +3401,11 @@ bool ha_mroonga::storage_create_foreign_key(TABLE *table,
ref_db_name.str = ref_db_buff;
DBUG_PRINT("info", ("mroonga: casedn ref_db_name=%s", ref_db_name.str));
}
+#ifdef MRN_FOREIGN_KEY_USE_CONST_STRING
+ LEX_CSTRING ref_table_name = fk->ref_table;
+#else
LEX_STRING ref_table_name = fk->ref_table;
+#endif
DBUG_PRINT("info", ("mroonga: ref_table_name=%s", ref_table_name.str));
if (ref_table_name.str && lower_case_table_names) {
strmake(ref_table_buff, ref_table_name.str, sizeof(ref_table_buff) - 1);
@@ -3545,10 +3735,13 @@ int ha_mroonga::storage_create_index(TABLE *table, const char *grn_table_name,
if (error)
DBUG_RETURN(error);
- grn_obj_flags index_column_flags =
- GRN_OBJ_COLUMN_INDEX | GRN_OBJ_WITH_POSITION | GRN_OBJ_PERSISTENT;
- if (is_multiple_column_index) {
- index_column_flags |= GRN_OBJ_WITH_SECTION;
+ grn_obj_flags index_column_flags = GRN_OBJ_COLUMN_INDEX | GRN_OBJ_PERSISTENT;
+
+ if (!find_index_column_flags(key_info, &index_column_flags)) {
+ index_column_flags |= GRN_OBJ_WITH_POSITION;
+ if (is_multiple_column_index) {
+ index_column_flags |= GRN_OBJ_WITH_SECTION;
+ }
}
index_table = index_tables[i];
@@ -3753,7 +3946,7 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked)
}
}
- init_alloc_root(&mem_root, 1024, 0, MYF(0));
+ mrn_init_alloc_root(&mem_root, 1024, 0, MYF(0));
wrap_key_info = mrn_create_key_info_for_table(share, table, &error);
if (error)
DBUG_RETURN(error);
@@ -3988,15 +4181,17 @@ int ha_mroonga::storage_open(const char *name, int mode, uint test_if_locked)
DBUG_RETURN(error);
}
- error = storage_open_indexes(name);
- if (error) {
- // TODO: free grn_columns and set NULL;
- grn_obj_unlink(ctx, grn_table);
- grn_table = NULL;
- DBUG_RETURN(error);
- }
+ if (!(ha_thd()->open_options & HA_OPEN_FOR_REPAIR)) {
+ error = storage_open_indexes(name);
+ if (error) {
+ // TODO: free grn_columns and set NULL;
+ grn_obj_unlink(ctx, grn_table);
+ grn_table = NULL;
+ DBUG_RETURN(error);
+ }
- storage_set_keys_in_use();
+ storage_set_keys_in_use();
+ }
ref_length = sizeof(grn_id);
DBUG_RETURN(0);
@@ -4043,6 +4238,11 @@ int ha_mroonga::storage_open_columns(void)
int n_columns = table->s->fields;
grn_columns = (grn_obj **)malloc(sizeof(grn_obj *) * n_columns);
grn_column_ranges = (grn_obj **)malloc(sizeof(grn_obj *) * n_columns);
+ for (int i = 0; i < n_columns; i++) {
+ grn_columns[i] = NULL;
+ grn_column_ranges[i] = NULL;
+ }
+
if (table_share->blob_fields)
{
if (blob_buffers)
@@ -4055,8 +4255,7 @@ int ha_mroonga::storage_open_columns(void)
}
}
- int i;
- for (i = 0; i < n_columns; i++) {
+ for (int i = 0; i < n_columns; i++) {
Field *field = table->field[i];
const char *column_name = field->field_name;
int column_name_size = strlen(column_name);
@@ -4065,24 +4264,46 @@ int ha_mroonga::storage_open_columns(void)
blob_buffers[i].set_charset(field->charset());
}
if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
- grn_columns[i] = NULL;
- grn_column_ranges[i] = NULL;
continue;
}
grn_columns[i] = grn_obj_column(ctx, grn_table,
column_name, column_name_size);
+ if (!grn_columns[i]) {
+ error = ER_CANT_OPEN_FILE;
+ my_message(error, ctx->errbuf, MYF(0));
+ break;
+ }
+
grn_id range_id = grn_obj_get_range(ctx, grn_columns[i]);
grn_column_ranges[i] = grn_ctx_at(ctx, range_id);
- if (ctx->rc) {
- // TODO: free grn_columns and set NULL;
- int error = ER_CANT_OPEN_FILE;
+ if (!grn_column_ranges[i]) {
+ error = ER_CANT_OPEN_FILE;
my_message(error, ctx->errbuf, MYF(0));
- DBUG_RETURN(error);
+ break;
}
}
- DBUG_RETURN(0);
+ if (error != 0) {
+ for (int i = 0; i < n_columns; i++) {
+ grn_obj *column = grn_columns[i];
+ if (column) {
+ grn_obj_unlink(ctx, column);
+ }
+
+ grn_obj *range = grn_column_ranges[i];
+ if (range) {
+ grn_obj_unlink(ctx, range);
+ }
+ }
+
+ free(grn_columns);
+ grn_columns = NULL;
+ free(grn_column_ranges);
+ grn_column_ranges = NULL;
+ }
+
+ DBUG_RETURN(error);
}
int ha_mroonga::storage_open_indexes(const char *name)
@@ -4147,7 +4368,7 @@ int ha_mroonga::storage_open_indexes(const char *name)
grn_index_tables[i],
INDEX_COLUMN_NAME,
strlen(INDEX_COLUMN_NAME));
- if (!grn_index_columns[i]) {
+ if (!grn_index_columns[i] && ctx->rc == GRN_SUCCESS) {
/* just for backward compatibility before 1.0. */
Field *field = key_info.key_part[0].field;
grn_index_columns[i] = grn_obj_column(ctx, grn_index_tables[i],
@@ -5176,7 +5397,7 @@ int ha_mroonga::wrapper_write_row_index(uchar *buf)
(int)GRN_TEXT_LEN(&key_buffer),
GRN_TEXT_VALUE(&key_buffer));
error = ER_ERROR_ON_WRITE;
- push_warning(ha_thd(), Sql_condition::WARN_LEVEL_WARN, error,
+ push_warning(ha_thd(), MRN_SEVERITY_WARNING, error,
error_message);
DBUG_RETURN(0);
}
@@ -5259,7 +5480,7 @@ int ha_mroonga::storage_write_row(uchar *buf)
if (field->is_null()) continue;
if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ push_warning_printf(thd, MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, MRN_GET_ERR_MSG(WARN_DATA_TRUNCATED),
MRN_COLUMN_NAME_ID,
MRN_GET_CURRENT_ROW_FOR_WARNING(thd));
@@ -5339,7 +5560,7 @@ int ha_mroonga::storage_write_row(uchar *buf)
if (field->is_null())
continue;
-#ifdef HAVE_SPATIAL
+#ifdef MRN_HAVE_SPATIAL
bool is_null_geometry_value =
field->real_type() == MYSQL_TYPE_GEOMETRY &&
static_cast<Field_geom *>(field)->get_length() == 0;
@@ -5687,7 +5908,7 @@ int ha_mroonga::wrapper_get_record_id(uchar *data, grn_id *record_id,
"%s: key=<%.*s>",
context, (int)GRN_TEXT_LEN(&key), GRN_TEXT_VALUE(&key));
error = ER_ERROR_ON_WRITE;
- push_warning(ha_thd(), Sql_condition::WARN_LEVEL_WARN, error,
+ push_warning(ha_thd(), MRN_SEVERITY_WARNING, error,
error_message);
}
grn_obj_unlink(ctx, &key);
@@ -5851,7 +6072,7 @@ int ha_mroonga::storage_update_row(const uchar *old_data, uchar *new_data)
if (bitmap_is_set(table->write_set, field->field_index)) {
if (field->is_null()) continue;
if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ push_warning_printf(thd, MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, MRN_GET_ERR_MSG(WARN_DATA_TRUNCATED),
MRN_COLUMN_NAME_ID,
MRN_GET_CURRENT_ROW_FOR_WARNING(thd));
@@ -5909,7 +6130,7 @@ int ha_mroonga::storage_update_row(const uchar *old_data, uchar *new_data)
snprintf(message, MRN_BUFFER_SIZE,
"data truncated for primary key column: <%s>",
column_name);
- push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
+ push_warning(thd, MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, message);
}
have_pkey = true;
@@ -6489,6 +6710,7 @@ uint ha_mroonga::storage_max_supported_key_parts() const
uint ha_mroonga::max_supported_key_parts() const
{
MRN_DBUG_ENTER_METHOD();
+
uint parts;
if (!share && !analyzed_for_create &&
(
@@ -6506,6 +6728,7 @@ uint ha_mroonga::max_supported_key_parts() const
} else {
parts = storage_max_supported_key_parts();
}
+
DBUG_RETURN(parts);
}
@@ -6601,6 +6824,7 @@ ha_rows ha_mroonga::storage_records_in_range(uint key_nr, key_range *range_min,
}
}
+ int cursor_limit = THDVAR(ha_thd(), max_n_records_for_estimate);
uint pkey_nr = table->s->primary_key;
if (key_nr == pkey_nr) {
DBUG_PRINT("info", ("mroonga: use primary key"));
@@ -6608,7 +6832,7 @@ ha_rows ha_mroonga::storage_records_in_range(uint key_nr, key_range *range_min,
cursor = grn_table_cursor_open(ctx, grn_table,
key_min, size_min,
key_max, size_max,
- 0, -1, flags);
+ 0, cursor_limit, flags);
while (grn_table_cursor_next(ctx, cursor) != GRN_ID_NIL) {
row_count++;
}
@@ -6621,18 +6845,13 @@ ha_rows ha_mroonga::storage_records_in_range(uint key_nr, key_range *range_min,
}
grn_table_cursor *cursor;
- grn_table_cursor *index_cursor;
cursor = grn_table_cursor_open(ctx, grn_index_tables[key_nr],
key_min, size_min,
key_max, size_max,
- 0, -1, flags);
- index_cursor = grn_index_cursor_open(ctx, cursor,
- grn_index_columns[key_nr],
- 0, GRN_ID_MAX, 0);
- while (grn_table_cursor_next(ctx, index_cursor) != GRN_ID_NIL) {
- row_count++;
- }
- grn_obj_unlink(ctx, index_cursor);
+ 0, cursor_limit, flags);
+ grn_obj *index_column = grn_index_columns[key_nr];
+ grn_ii *ii = reinterpret_cast<grn_ii *>(index_column);
+ row_count = grn_ii_estimate_size_for_lexicon_cursor(ctx, ii, cursor);
grn_table_cursor_close(ctx, cursor);
}
DBUG_RETURN(row_count);
@@ -6814,7 +7033,8 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
bool is_multiple_column_index = KEY_N_KEY_PARTS(&key_info) > 1;
if (is_multiple_column_index) {
mrn_change_encoding(ctx, NULL);
- uint key_length = calculate_key_len(table, active_index, key, keypart_map);
+ uint key_length =
+ mrn_calculate_key_len(table, active_index, key, keypart_map);
DBUG_PRINT("info",
("mroonga: multiple column index: "
"search key length=<%u>, "
@@ -6832,6 +7052,10 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
storage_encode_multiple_column_key(&key_info,
key, key_length,
key_min, &size_min);
+ if (find_flag == HA_READ_KEY_EXACT) {
+ key_max = key_min;
+ size_max = size_min;
+ }
}
} else {
flags |= GRN_CURSOR_PREFIX;
@@ -7018,7 +7242,8 @@ int ha_mroonga::storage_index_read_last_map(uchar *buf, const uchar *key,
if (is_multiple_column_index) {
mrn_change_encoding(ctx, NULL);
flags |= GRN_CURSOR_PREFIX;
- uint key_length = calculate_key_len(table, active_index, key, keypart_map);
+ uint key_length =
+ mrn_calculate_key_len(table, active_index, key, keypart_map);
key_min = key_min_entity;
storage_encode_multiple_column_key(&key_info,
key, key_length,
@@ -7630,7 +7855,8 @@ void ha_mroonga::generic_ft_init_ext_add_conditions_fast_order_limit(
{
MRN_DBUG_ENTER_METHOD();
- Item *where = table->pos_in_table_list->select_lex->where;
+ Item *where =
+ MRN_SELECT_LEX_GET_WHERE_COND(table->pos_in_table_list->select_lex);
bool is_storage_mode = !(share->wrapper_mode);
mrn::ConditionConverter converter(info->ctx, grn_table, is_storage_mode);
@@ -7806,7 +8032,10 @@ grn_expr_flags ha_mroonga::expr_flags_in_boolean_mode()
{
MRN_DBUG_ENTER_METHOD();
- ulonglong syntax_flags = THDVAR(ha_thd(), boolean_mode_syntax_flags);
+ ulonglong syntax_flags = MRN_BOOLEAN_MODE_SYNTAX_FLAG_DEFAULT;
+#ifdef MRN_SUPPORT_THDVAR_SET
+ syntax_flags = THDVAR(ha_thd(), boolean_mode_syntax_flags);
+#endif
grn_expr_flags expression_flags = 0;
if (syntax_flags == MRN_BOOLEAN_MODE_SYNTAX_FLAG_DEFAULT) {
expression_flags = GRN_EXPR_SYNTAX_QUERY | GRN_EXPR_ALLOW_LEADING_NOT;
@@ -8093,7 +8322,7 @@ FT_INFO *ha_mroonga::generic_ft_init_ext(uint flags, uint key_nr, String *key)
for (int i = 0; i < n_sort_keys; i++) {
grn_obj_unlink(info->ctx, sort_keys[i].key);
}
- free(sort_keys);
+ my_free(sort_keys);
}
DBUG_RETURN((FT_INFO *)info);
@@ -8372,7 +8601,7 @@ void ha_mroonga::push_warning_unsupported_spatial_index_search(enum ha_rkey_func
sprintf(search_name, "unknown: %d", flag);
}
push_warning_printf(ha_thd(),
- Sql_condition::WARN_LEVEL_WARN,
+ MRN_SEVERITY_WARNING,
ER_UNSUPPORTED_EXTENSION,
"spatial index search "
"except MBRContains aren't supported: <%s>",
@@ -8638,7 +8867,7 @@ grn_obj *ha_mroonga::find_tokenizer(const char *name, int name_length)
name_length, name,
MRN_PARSER_DEFAULT);
push_warning(ha_thd(),
- Sql_condition::WARN_LEVEL_WARN, ER_UNSUPPORTED_EXTENSION,
+ MRN_SEVERITY_WARNING, ER_UNSUPPORTED_EXTENSION,
message);
tokenizer = grn_ctx_get(ctx,
MRN_PARSER_DEFAULT,
@@ -8646,7 +8875,7 @@ grn_obj *ha_mroonga::find_tokenizer(const char *name, int name_length)
}
if (!tokenizer) {
push_warning(ha_thd(),
- Sql_condition::WARN_LEVEL_WARN, ER_UNSUPPORTED_EXTENSION,
+ MRN_SEVERITY_WARNING, ER_UNSUPPORTED_EXTENSION,
"couldn't find fulltext parser. "
"Bigram fulltext parser is used instead.");
tokenizer = grn_ctx_at(ctx, GRN_DB_BIGRAM);
@@ -8682,6 +8911,28 @@ grn_obj *ha_mroonga::find_normalizer(KEY *key_info)
DBUG_RETURN(normalizer);
}
+bool ha_mroonga::find_index_column_flags(KEY *key_info, grn_obj_flags *index_column_flags)
+{
+ MRN_DBUG_ENTER_METHOD();
+ bool found = false;
+#if MYSQL_VERSION_ID >= 50500
+ if (key_info->comment.length > 0) {
+ mrn::ParametersParser parser(key_info->comment.str,
+ key_info->comment.length);
+ parser.parse();
+ const char *names = parser["index_flags"];
+ if (names) {
+ found = mrn_parse_grn_index_column_flags(ha_thd(),
+ ctx,
+ names,
+ strlen(names),
+ index_column_flags);
+ }
+ }
+#endif
+ DBUG_RETURN(found);
+}
+
bool ha_mroonga::find_token_filters(KEY *key_info, grn_obj *token_filters)
{
MRN_DBUG_ENTER_METHOD();
@@ -8718,7 +8969,7 @@ bool ha_mroonga::find_token_filters_put(grn_obj *token_filters,
"nonexistent token filter: <%.*s>",
token_filter_name_length, token_filter_name);
push_warning(ha_thd(),
- Sql_condition::WARN_LEVEL_WARN, ER_UNSUPPORTED_EXTENSION,
+ MRN_SEVERITY_WARNING, ER_UNSUPPORTED_EXTENSION,
message);
return false;
}
@@ -8778,7 +9029,7 @@ break_loop:
(int)(current - last_name_end), last_name_end,
(int)(end - current), current);
push_warning(ha_thd(),
- Sql_condition::WARN_LEVEL_WARN, ER_UNSUPPORTED_EXTENSION,
+ MRN_SEVERITY_WARNING, ER_UNSUPPORTED_EXTENSION,
message);
return false;
}
@@ -9050,9 +9301,9 @@ void ha_mroonga::check_count_skip(key_part_map start_key_part_map,
if (
thd_sql_command(ha_thd()) == SQLCOM_SELECT &&
- !select_lex->non_agg_fields.elements &&
+ select_lex->item_list.elements == 1 &&
!select_lex->group_list.elements &&
- !select_lex->having &&
+ !MRN_SELECT_LEX_GET_HAVING_COND(select_lex) &&
select_lex->table_list.elements == 1
) {
Item *info = (Item *) select_lex->item_list.first_node()->info;
@@ -9073,7 +9324,7 @@ void ha_mroonga::check_count_skip(key_part_map start_key_part_map,
Item *where;
if (fulltext) {
DBUG_PRINT("info", ("mroonga: count skip: fulltext"));
- where = select_lex->where;
+ where = MRN_SELECT_LEX_GET_WHERE_COND(select_lex);
if (!where ||
where->type() != Item::FUNC_ITEM ||
((Item_func *)where)->functype() != Item_func::FT_FUNC) {
@@ -9081,20 +9332,10 @@ void ha_mroonga::check_count_skip(key_part_map start_key_part_map,
count_skip = false;
DBUG_VOID_RETURN;
}
- where = where->next;
- if (!where ||
- where->type() != Item::STRING_ITEM) {
- DBUG_PRINT("info", ("mroonga: count skip: string item is not match"));
- count_skip = false;
- DBUG_VOID_RETURN;
- }
- for (where = where->next; where; where = where->next) {
- if (where->type() != Item::FIELD_ITEM)
- break;
- DBUG_PRINT("info", ("mroonga: count skip: FIELD_ITEM=%p", where));
- }
- if (where != info) {
- DBUG_PRINT("info", ("mroonga: count skip: where clause is not match"));
+ if (select_lex->select_n_where_fields != 1) {
+ DBUG_PRINT("info",
+ ("mroonga: count skip: "
+ "where clause is not fulltext search only"));
count_skip = false;
DBUG_VOID_RETURN;
}
@@ -9117,10 +9358,29 @@ void ha_mroonga::check_count_skip(key_part_map start_key_part_map,
uint key_nr = active_index;
KEY key_info = table->key_info[key_nr];
KEY_PART_INFO *key_part = key_info.key_part;
- for (where = select_lex->where; where; where = where->next) {
- if (where->type() == Item::FIELD_ITEM)
+ for (where = MRN_SELECT_LEX_GET_WHERE_COND(select_lex);
+ where;
+ where = where->next) {
+ Item *target = where;
+
+ if (where->type() == Item::FUNC_ITEM) {
+ Item_func *func_item = static_cast<Item_func *>(where);
+ if (func_item->arg_count == 0) {
+ break;
+ }
+ target = func_item->key_item();
+ where = where->next;
+ if (func_item->arguments()[0] == where) {
+ uint n_args = func_item->arg_count;
+ for (; n_args > 0; --n_args) {
+ where = where->next;
+ }
+ }
+ }
+
+ if (target->type() == Item::FIELD_ITEM)
{
- Field *field = ((Item_field *)where)->field;
+ Field *field = ((Item_field *)target)->field;
if (!field)
break;
if (field->table != table)
@@ -9174,6 +9434,27 @@ bool ha_mroonga::is_grn_zero_column_value(grn_obj *column, grn_obj *value)
DBUG_RETURN(true);
}
+bool ha_mroonga::is_primary_key_field(Field *field) const
+{
+ MRN_DBUG_ENTER_METHOD();
+
+ if (table->s->primary_key == MAX_INDEXES) {
+ DBUG_RETURN(false);
+ }
+
+ KEY *key_info = &(table->s->key_info[table->s->primary_key]);
+ if (KEY_N_KEY_PARTS(key_info) != 1) {
+ DBUG_RETURN(false);
+ }
+
+ if (strcmp(field->field_name,
+ key_info->key_part[0].field->field_name) == 0) {
+ DBUG_RETURN(true);
+ } else {
+ DBUG_RETURN(false);
+ }
+}
+
void ha_mroonga::check_fast_order_limit(grn_table_sort_key **sort_keys,
int *n_sort_keys,
longlong *limit)
@@ -9188,7 +9469,7 @@ void ha_mroonga::check_fast_order_limit(grn_table_sort_key **sort_keys,
TABLE_LIST *table_list = table->pos_in_table_list;
st_select_lex *select_lex = table_list->select_lex;
- SELECT_LEX_UNIT *unit = table_list->derived;
+ SELECT_LEX_UNIT *unit = MRN_TABLE_LIST_GET_DERIVED(table_list);
st_select_lex *first_select_lex;
if (unit)
{
@@ -9198,13 +9479,13 @@ void ha_mroonga::check_fast_order_limit(grn_table_sort_key **sort_keys,
}
DBUG_PRINT("info",
("mroonga: first_select_lex->options=%llu",
- first_select_lex ? first_select_lex->options : 0));
+ first_select_lex ? MRN_SELECT_LEX_GET_ACTIVE_OPTIONS(first_select_lex) : 0));
if (
thd_sql_command(ha_thd()) == SQLCOM_SELECT &&
!select_lex->with_sum_func &&
!select_lex->group_list.elements &&
- !select_lex->having &&
+ !MRN_SELECT_LEX_GET_HAVING_COND(select_lex) &&
select_lex->table_list.elements == 1 &&
select_lex->order_list.elements &&
select_lex->explicit_limit &&
@@ -9225,17 +9506,18 @@ void ha_mroonga::check_fast_order_limit(grn_table_sort_key **sort_keys,
fast_order_limit = false;
DBUG_VOID_RETURN;
}
- if (first_select_lex && (first_select_lex->options & OPTION_FOUND_ROWS)) {
+ if (first_select_lex &&
+ (MRN_SELECT_LEX_GET_ACTIVE_OPTIONS(first_select_lex) & OPTION_FOUND_ROWS)) {
DBUG_PRINT("info",
("mroonga: fast_order_limit = false: "
"SQL_CALC_FOUND_ROWS is specified"));
fast_order_limit = false;
DBUG_VOID_RETURN;
}
- Item *where = select_lex->where;
+ bool is_storage_mode = !(share->wrapper_mode);
+ Item *where = MRN_SELECT_LEX_GET_WHERE_COND(select_lex);
const Item_func *match_against = NULL;
if (where) {
- bool is_storage_mode = !(share->wrapper_mode);
mrn::ConditionConverter converter(ctx, grn_table, is_storage_mode);
if (!converter.is_convertable(where)) {
DBUG_PRINT("info",
@@ -9253,18 +9535,22 @@ void ha_mroonga::check_fast_order_limit(grn_table_sort_key **sort_keys,
DBUG_VOID_RETURN;
}
}
- *n_sort_keys = select_lex->order_list.elements;
- *sort_keys = (grn_table_sort_key *)malloc(sizeof(grn_table_sort_key) *
- *n_sort_keys);
+ int n_max_sort_keys = select_lex->order_list.elements;
+ *n_sort_keys = 0;
+ size_t sort_keys_size = sizeof(grn_table_sort_key) * n_max_sort_keys;
+ *sort_keys = (grn_table_sort_key *)mrn_my_malloc(sort_keys_size,
+ MYF(MY_WME));
+ memset(*sort_keys, 0, sort_keys_size);
ORDER *order;
int i;
mrn_change_encoding(ctx, system_charset_info);
- for (order = (ORDER *) select_lex->order_list.first, i = 0; order;
+ for (order = (ORDER *) select_lex->order_list.first, i = 0;
+ order;
order = order->next, i++) {
Item *item = *order->item;
- if (grn_columns && item->type() == Item::FIELD_ITEM)
+ if (item->type() == Item::FIELD_ITEM)
{
- Field *field = ((Item_field *) (*order->item))->field;
+ Field *field = static_cast<Item_field *>(item)->field;
const char *column_name = field->field_name;
int column_name_size = strlen(column_name);
@@ -9273,14 +9559,31 @@ void ha_mroonga::check_fast_order_limit(grn_table_sort_key **sort_keys,
DBUG_PRINT("info", ("mroonga: fast_order_limit = false: "
"sort by collated value isn't supported yet."));
fast_order_limit = false;
- free(*sort_keys);
+ my_free(*sort_keys);
*sort_keys = NULL;
*n_sort_keys = 0;
DBUG_VOID_RETURN;
}
- (*sort_keys)[i].key = grn_obj_column(ctx, matched_record_keys,
- column_name, column_name_size);
+ if (is_storage_mode) {
+ (*sort_keys)[i].key = grn_obj_column(ctx, matched_record_keys,
+ column_name, column_name_size);
+ } else {
+ if (is_primary_key_field(field)) {
+ (*sort_keys)[i].key = grn_obj_column(ctx, matched_record_keys,
+ MRN_COLUMN_NAME_KEY,
+ strlen(MRN_COLUMN_NAME_KEY));
+ } else {
+ DBUG_PRINT("info", ("mroonga: fast_order_limit = false: "
+ "sort by not primary key value "
+ "isn't supported in wrapper mode."));
+ fast_order_limit = false;
+ my_free(*sort_keys);
+ *sort_keys = NULL;
+ *n_sort_keys = 0;
+ DBUG_VOID_RETURN;
+ }
+ }
} else if (!match_against || match_against->eq(item, true)) {
(*sort_keys)[i].key = grn_obj_column(ctx, matched_record_keys,
MRN_COLUMN_NAME_SCORE,
@@ -9289,7 +9592,7 @@ void ha_mroonga::check_fast_order_limit(grn_table_sort_key **sort_keys,
DBUG_PRINT("info", ("mroonga: fast_order_limit = false: "
"sort by computed value isn't supported."));
fast_order_limit = false;
- free(*sort_keys);
+ my_free(*sort_keys);
*sort_keys = NULL;
*n_sort_keys = 0;
DBUG_VOID_RETURN;
@@ -9301,6 +9604,7 @@ void ha_mroonga::check_fast_order_limit(grn_table_sort_key **sort_keys,
} else {
(*sort_keys)[i].flags = GRN_TABLE_SORT_DESC;
}
+ (*n_sort_keys)++;
}
DBUG_PRINT("info", ("mroonga: fast_order_limit = true"));
fast_order_limit = true;
@@ -9329,7 +9633,8 @@ int ha_mroonga::generic_store_bulk_variable_size_string(Field *field,
String value;
field->val_str(NULL, &value);
grn_obj_reinit(ctx, buf, GRN_DB_SHORT_TEXT, 0);
- DBUG_PRINT("info", ("mroonga: length=%u", value.length()));
+ DBUG_PRINT("info", ("mroonga: length=%" MRN_FORMAT_STRING_LENGTH,
+ value.length()));
DBUG_PRINT("info", ("mroonga: value=%s", value.c_ptr_safe()));
GRN_TEXT_SET(ctx, buf, value.ptr(), value.length());
DBUG_RETURN(error);
@@ -9392,7 +9697,7 @@ int ha_mroonga::generic_store_bulk_integer(Field *field, grn_obj *buf)
"unknown integer value size: <%u>: "
"available sizes: [1, 2, 3, 4, 8]",
size);
- push_warning(ha_thd(), Sql_condition::WARN_LEVEL_WARN,
+ push_warning(ha_thd(), MRN_SEVERITY_WARNING,
error, error_message);
break;
}
@@ -9432,7 +9737,7 @@ int ha_mroonga::generic_store_bulk_unsigned_integer(Field *field, grn_obj *buf)
"unknown unsigned integer value size: <%u>: "
"available sizes: [1, 2, 3, 4, 8]",
size);
- push_warning(ha_thd(), Sql_condition::WARN_LEVEL_WARN,
+ push_warning(ha_thd(), MRN_SEVERITY_WARNING,
error, error_message);
break;
}
@@ -9459,7 +9764,7 @@ int ha_mroonga::generic_store_bulk_float(Field *field, grn_obj *buf)
"unknown float value size: <%u>: "
"available sizes: [4, 8]",
size);
- push_warning(ha_thd(), Sql_condition::WARN_LEVEL_WARN,
+ push_warning(ha_thd(), MRN_SEVERITY_WARNING,
error, error_message);
break;
}
@@ -9519,7 +9824,7 @@ int ha_mroonga::generic_store_bulk_date(Field *field, grn_obj *buf)
mrn::TimeConverter time_converter;
long long int time = time_converter.tm_to_grn_time(&date, usec, &truncated);
if (truncated) {
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
+ field->set_warning(MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, 1);
}
grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0);
@@ -9539,7 +9844,7 @@ int ha_mroonga::generic_store_bulk_time(Field *field, grn_obj *buf)
long long int time = time_converter.mysql_time_to_grn_time(&mysql_time,
&truncated);
if (truncated) {
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
+ field->set_warning(MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, 1);
}
grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0);
@@ -9559,7 +9864,7 @@ int ha_mroonga::generic_store_bulk_datetime(Field *field, grn_obj *buf)
long long int time = time_converter.mysql_time_to_grn_time(&mysql_time,
&truncated);
if (truncated) {
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
+ field->set_warning(MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, 1);
}
grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0);
@@ -9591,7 +9896,7 @@ int ha_mroonga::generic_store_bulk_year(Field *field, grn_obj *buf)
mrn::TimeConverter time_converter;
long long int time = time_converter.tm_to_grn_time(&date, usec, &truncated);
if (truncated) {
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
+ field->set_warning(MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, 1);
}
grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0);
@@ -9612,7 +9917,7 @@ int ha_mroonga::generic_store_bulk_datetime2(Field *field, grn_obj *buf)
long long int time = time_converter.mysql_time_to_grn_time(&mysql_time,
&truncated);
if (truncated) {
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
+ field->set_warning(MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, 1);
}
grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0);
@@ -9633,7 +9938,7 @@ int ha_mroonga::generic_store_bulk_time2(Field *field, grn_obj *buf)
long long int time = time_converter.mysql_time_to_grn_time(&mysql_time,
&truncated);
if (truncated) {
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
+ field->set_warning(MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, 1);
}
grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0);
@@ -9654,7 +9959,7 @@ int ha_mroonga::generic_store_bulk_new_date(Field *field, grn_obj *buf)
long long int time = time_converter.mysql_time_to_grn_time(&mysql_date,
&truncated);
if (truncated) {
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
+ field->set_warning(MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, 1);
}
grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0);
@@ -9690,7 +9995,7 @@ int ha_mroonga::generic_store_bulk_geometry(Field *field, grn_obj *buf)
{
MRN_DBUG_ENTER_METHOD();
int error = 0;
-#ifdef HAVE_SPATIAL
+#ifdef MRN_HAVE_SPATIAL
String buffer;
Field_geom *geometry = (Field_geom *)field;
String *value = geometry->val_str(0, &buffer);
@@ -9876,7 +10181,7 @@ void ha_mroonga::storage_store_field_integer(Field *field,
"unknown integer value size: <%d>: "
"available sizes: [1, 2, 4, 8]",
value_length);
- push_warning(ha_thd(), Sql_condition::WARN_LEVEL_WARN,
+ push_warning(ha_thd(), MRN_SEVERITY_WARNING,
HA_ERR_UNSUPPORTED, error_message);
storage_store_field_string(field, value, value_length);
break;
@@ -9928,7 +10233,7 @@ void ha_mroonga::storage_store_field_unsigned_integer(Field *field,
"unknown integer value size: <%d>: "
"available sizes: [1, 2, 4, 8]",
value_length);
- push_warning(ha_thd(), Sql_condition::WARN_LEVEL_WARN,
+ push_warning(ha_thd(), MRN_SEVERITY_WARNING,
HA_ERR_UNSUPPORTED, error_message);
storage_store_field_string(field, value, value_length);
break;
@@ -10121,7 +10426,7 @@ void ha_mroonga::storage_store_field_geometry(Field *field,
uint value_length)
{
MRN_DBUG_ENTER_METHOD();
-#ifdef HAVE_SPATIAL
+#ifdef MRN_HAVE_SPATIAL
uchar wkb[SRID_SIZE + WKB_HEADER_SIZE + POINT_DATA_SIZE];
grn_geo_point *field_value = (grn_geo_point *)value;
int latitude, longitude;
@@ -10526,7 +10831,7 @@ int ha_mroonga::storage_encode_key_timestamp(Field *field, const uchar *key,
mrn::TimeConverter time_converter;
time = time_converter.mysql_time_to_grn_time(&mysql_time, &truncated);
if (truncated) {
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
+ field->set_warning(MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, 1);
}
memcpy(buf, &time, 8);
@@ -10573,7 +10878,7 @@ int ha_mroonga::storage_encode_key_time(Field *field, const uchar *key,
mrn::TimeConverter time_converter;
time = time_converter.mysql_time_to_grn_time(&mysql_time, &truncated);
if (truncated) {
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
+ field->set_warning(MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, 1);
}
#else
@@ -10608,7 +10913,7 @@ int ha_mroonga::storage_encode_key_year(Field *field, const uchar *key,
long long int time = time_converter.tm_to_grn_time(&datetime, usec,
&truncated);
if (truncated) {
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
+ field->set_warning(MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, 1);
}
memcpy(buf, &time, 8);
@@ -10657,7 +10962,7 @@ int ha_mroonga::storage_encode_key_datetime(Field *field, const uchar *key,
time = time_converter.tm_to_grn_time(&date, usec, &truncated);
}
if (truncated) {
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
+ field->set_warning(MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, 1);
}
memcpy(buf, &time, 8);
@@ -10683,7 +10988,7 @@ int ha_mroonga::storage_encode_key_timestamp2(Field *field, const uchar *key,
long long int grn_time = time_converter.mysql_time_to_grn_time(&mysql_time,
&truncated);
if (truncated) {
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
+ field->set_warning(MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, 1);
}
memcpy(buf, &grn_time, 8);
@@ -10710,7 +11015,7 @@ int ha_mroonga::storage_encode_key_datetime2(Field *field, const uchar *key,
long long int grn_time = time_converter.mysql_time_to_grn_time(&mysql_time,
&truncated);
if (truncated) {
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
+ field->set_warning(MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, 1);
}
memcpy(buf, &grn_time, 8);
@@ -10737,7 +11042,7 @@ int ha_mroonga::storage_encode_key_time2(Field *field, const uchar *key,
long long int grn_time = time_converter.mysql_time_to_grn_time(&mysql_time,
&truncated);
if (truncated) {
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
+ field->set_warning(MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, 1);
}
memcpy(buf, &grn_time, 8);
@@ -10759,7 +11064,7 @@ int ha_mroonga::storage_encode_key_enum(Field *field, const uchar *key,
memcpy(buf, &value, *size);
} else {
uint16 value;
- shortget(value, key);
+ mrn::value_decoder::decode(&value, key);
*size = 2;
memcpy(buf, &value, *size);
}
@@ -10871,7 +11176,7 @@ int ha_mroonga::storage_encode_key(Field *field, const uchar *key,
{
float float_value;
double double_value;
- float4get(float_value, ptr);
+ mrn::value_decoder::decode(&float_value, ptr);
double_value = float_value;
memcpy(buf, &double_value, 8);
*size = 8;
@@ -10880,7 +11185,7 @@ int ha_mroonga::storage_encode_key(Field *field, const uchar *key,
case MYSQL_TYPE_DOUBLE:
{
double val;
- float8get(val, ptr);
+ mrn::value_decoder::decode(&val, ptr);
memcpy(buf, &val, 8);
*size = 8;
break;
@@ -10907,7 +11212,7 @@ int ha_mroonga::storage_encode_key(Field *field, const uchar *key,
long long int time = time_converter.tm_to_grn_time(&date, usec,
&truncated);
if (truncated) {
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
+ field->set_warning(MRN_SEVERITY_WARNING,
WARN_DATA_TRUNCATED, 1);
}
memcpy(buf, &time, 8);
@@ -10994,16 +11299,29 @@ int ha_mroonga::generic_reset()
{
MRN_DBUG_ENTER_METHOD();
int error = 0;
- if (thd_sql_command(ha_thd()) == SQLCOM_SELECT) {
- st_select_lex *select_lex = table->pos_in_table_list->select_lex;
- List_iterator<Item_func_match> iterator(*(select_lex->ftfunc_list));
- Item_func_match *item;
- while ((item = iterator++)) {
- if (item->ft_handler) {
- mrn_generic_ft_clear(item->ft_handler);
- }
+
+ if (thd_sql_command(ha_thd()) != SQLCOM_SELECT) {
+ DBUG_RETURN(error);
+ }
+
+ TABLE_LIST *table_list = table->pos_in_table_list;
+ if (!table_list) {
+ DBUG_RETURN(error);
+ }
+
+ st_select_lex *select_lex = table_list->select_lex;
+ if (!select_lex) {
+ DBUG_RETURN(error);
+ }
+
+ List_iterator<Item_func_match> iterator(*(select_lex->ftfunc_list));
+ Item_func_match *item;
+ while ((item = iterator++)) {
+ if (item->ft_handler) {
+ mrn_generic_ft_clear(item->ft_handler);
}
}
+
DBUG_RETURN(error);
}
@@ -12040,9 +12358,9 @@ void ha_mroonga::update_create_info(HA_CREATE_INFO* create_info)
}
if (create_info->connect_string.str) {
slot_data->alter_connect_string =
- my_strndup(create_info->connect_string.str,
- create_info->connect_string.length,
- MYF(MY_WME));
+ mrn_my_strndup(create_info->connect_string.str,
+ create_info->connect_string.length,
+ MYF(MY_WME));
}
if (slot_data->alter_comment) {
my_free(slot_data->alter_comment);
@@ -12050,9 +12368,9 @@ void ha_mroonga::update_create_info(HA_CREATE_INFO* create_info)
}
if (create_info->comment.str) {
slot_data->alter_comment =
- my_strndup(create_info->comment.str,
- create_info->comment.length,
- MYF(MY_WME));
+ mrn_my_strndup(create_info->comment.str,
+ create_info->comment.length,
+ MYF(MY_WME));
}
if (share && share->disable_keys) {
slot_data->disable_keys_create_info = create_info;
@@ -12365,14 +12683,15 @@ bool ha_mroonga::wrapper_is_crashed() const
bool ha_mroonga::storage_is_crashed() const
{
MRN_DBUG_ENTER_METHOD();
- bool crashed = handler::is_crashed();
+ mrn::DatabaseRepairer repairer(ctx, ha_thd());
+ bool crashed = repairer.is_crashed();
DBUG_RETURN(crashed);
}
bool ha_mroonga::is_crashed() const
{
MRN_DBUG_ENTER_METHOD();
- int crashed;
+ bool crashed;
if (share->wrapper_mode)
{
crashed = wrapper_is_crashed();
@@ -12384,52 +12703,52 @@ bool ha_mroonga::is_crashed() const
bool ha_mroonga::wrapper_auto_repair(int error) const
{
- bool crashed;
+ bool repaired;
MRN_DBUG_ENTER_METHOD();
MRN_SET_WRAP_SHARE_KEY(share, table->s);
MRN_SET_WRAP_TABLE_KEY(this, table);
#ifdef MRN_HANDLER_AUTO_REPAIR_HAVE_ERROR
- crashed = wrap_handler->auto_repair(error);
+ repaired = wrap_handler->auto_repair(error);
#else
- crashed = wrap_handler->auto_repair();
+ repaired = wrap_handler->auto_repair();
#endif
MRN_SET_BASE_SHARE_KEY(share, table->s);
MRN_SET_BASE_TABLE_KEY(this, table);
- DBUG_RETURN(crashed);
+ DBUG_RETURN(repaired);
}
bool ha_mroonga::storage_auto_repair(int error) const
{
MRN_DBUG_ENTER_METHOD();
- bool crashed;
+ bool repaired;
#ifdef MRN_HANDLER_AUTO_REPAIR_HAVE_ERROR
- crashed = handler::auto_repair(error);
+ repaired = handler::auto_repair(error);
#else
- crashed = handler::auto_repair();
+ repaired = handler::auto_repair();
#endif
- DBUG_RETURN(crashed);
+ DBUG_RETURN(repaired);
}
bool ha_mroonga::auto_repair(int error) const
{
MRN_DBUG_ENTER_METHOD();
- bool crashed;
+ bool repaired;
// TODO: We should consider about creating share for error =
// ER_CANT_OPEN_FILE. The following code just ignores the error.
if (share && share->wrapper_mode)
{
- crashed = wrapper_auto_repair(error);
+ repaired = wrapper_auto_repair(error);
} else {
- crashed = storage_auto_repair(error);
+ repaired = storage_auto_repair(error);
}
- DBUG_RETURN(crashed);
+ DBUG_RETURN(repaired);
}
bool ha_mroonga::auto_repair() const
{
MRN_DBUG_ENTER_METHOD();
- bool crashed = auto_repair(HA_ERR_CRASHED_ON_USAGE);
- DBUG_RETURN(crashed);
+ bool repaired = auto_repair(HA_ERR_CRASHED_ON_USAGE);
+ DBUG_RETURN(repaired);
}
int ha_mroonga::generic_disable_index(int i, KEY *key_info)
@@ -12760,7 +13079,12 @@ int ha_mroonga::wrapper_check(THD* thd, HA_CHECK_OPT* check_opt)
int ha_mroonga::storage_check(THD* thd, HA_CHECK_OPT* check_opt)
{
MRN_DBUG_ENTER_METHOD();
- DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED);
+ mrn::DatabaseRepairer repairer(ctx, thd);
+ if (repairer.repair()) {
+ DBUG_RETURN(HA_ADMIN_OK);
+ } else {
+ DBUG_RETURN(HA_ADMIN_CORRUPT);
+ }
}
int ha_mroonga::check(THD* thd, HA_CHECK_OPT* check_opt)
@@ -12929,6 +13253,58 @@ int ha_mroonga::wrapper_recreate_indexes(THD *thd)
DBUG_RETURN(error);
}
+int ha_mroonga::storage_recreate_indexes(THD *thd)
+{
+ MRN_DBUG_ENTER_METHOD();
+
+ if (share->disable_keys)
+ DBUG_RETURN(HA_ADMIN_OK);
+
+ clear_indexes();
+
+ int n_columns = table->s->fields;
+ for (int i = 0; i < n_columns; i++) {
+ grn_obj *column = grn_columns[i];
+
+ if (!column)
+ continue;
+
+ int n_hooks = grn_obj_get_nhooks(ctx, column, GRN_HOOK_SET);
+ for (int j = 0; j < n_hooks; j++) {
+ grn_obj_delete_hook(ctx, column, GRN_HOOK_SET, j);
+ }
+ }
+
+ uint n_keys = table_share->keys;
+ mrn::PathMapper mapper(table_share->normalized_path.str);
+ for (uint i = 0; i < n_keys; i++) {
+ if (share->index_table && share->index_table[i])
+ continue;
+
+ if (i == table_share->primary_key)
+ continue;
+
+ mrn::IndexTableName index_table_name(mapper.table_name(),
+ table_share->key_info[i].name);
+ char index_column_full_name[MRN_MAX_PATH_SIZE];
+ snprintf(index_column_full_name, MRN_MAX_PATH_SIZE,
+ "%s.%s", index_table_name.c_str(), INDEX_COLUMN_NAME);
+ remove_grn_obj_force(index_column_full_name);
+ remove_grn_obj_force(index_table_name.c_str());
+ }
+
+ int error;
+ error = storage_create_indexes(table, mapper.table_name(), grn_table, share);
+ if (error)
+ DBUG_RETURN(HA_ADMIN_FAILED);
+
+ error = storage_open_indexes(table_share->normalized_path.str);
+ if (error)
+ DBUG_RETURN(HA_ADMIN_FAILED);
+
+ DBUG_RETURN(HA_ADMIN_OK);
+}
+
int ha_mroonga::wrapper_repair(THD* thd, HA_CHECK_OPT* check_opt)
{
int error;
@@ -12947,7 +13323,8 @@ int ha_mroonga::wrapper_repair(THD* thd, HA_CHECK_OPT* check_opt)
int ha_mroonga::storage_repair(THD* thd, HA_CHECK_OPT* check_opt)
{
MRN_DBUG_ENTER_METHOD();
- DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED);
+ int error = storage_recreate_indexes(thd);
+ DBUG_RETURN(error);
}
int ha_mroonga::repair(THD* thd, HA_CHECK_OPT* check_opt)
@@ -12966,35 +13343,36 @@ int ha_mroonga::repair(THD* thd, HA_CHECK_OPT* check_opt)
bool ha_mroonga::wrapper_check_and_repair(THD *thd)
{
- // XXX: success is valid variable name?
- bool success;
+ bool is_error_or_not_supported;
MRN_DBUG_ENTER_METHOD();
MRN_SET_WRAP_SHARE_KEY(share, table->s);
MRN_SET_WRAP_TABLE_KEY(this, table);
- success = wrap_handler->ha_check_and_repair(thd);
+ is_error_or_not_supported = wrap_handler->ha_check_and_repair(thd);
MRN_SET_BASE_SHARE_KEY(share, table->s);
MRN_SET_BASE_TABLE_KEY(this, table);
- DBUG_RETURN(success);
+ DBUG_RETURN(is_error_or_not_supported);
}
bool ha_mroonga::storage_check_and_repair(THD *thd)
{
MRN_DBUG_ENTER_METHOD();
- DBUG_RETURN(true);
+ bool is_error = false;
+ mrn::DatabaseRepairer repairer(ctx, thd);
+ is_error = !repairer.repair();
+ DBUG_RETURN(is_error);
}
bool ha_mroonga::check_and_repair(THD *thd)
{
MRN_DBUG_ENTER_METHOD();
- // XXX: success is valid variable name?
- bool success;
+ bool is_error_or_not_supported;
if (share->wrapper_mode)
{
- success = wrapper_check_and_repair(thd);
+ is_error_or_not_supported = wrapper_check_and_repair(thd);
} else {
- success = storage_check_and_repair(thd);
+ is_error_or_not_supported = storage_check_and_repair(thd);
}
- DBUG_RETURN(success);
+ DBUG_RETURN(is_error_or_not_supported);
}
int ha_mroonga::wrapper_analyze(THD* thd, HA_CHECK_OPT* check_opt)
@@ -13059,7 +13437,11 @@ bool ha_mroonga::wrapper_is_fatal_error(int error_num, uint flags)
MRN_DBUG_ENTER_METHOD();
MRN_SET_WRAP_SHARE_KEY(share, table->s);
MRN_SET_WRAP_TABLE_KEY(this, table);
+#ifdef MRN_HANDLER_IS_FATAL_ERROR_HAVE_FLAGS
res = wrap_handler->is_fatal_error(error_num, flags);
+#else
+ res = wrap_handler->is_fatal_error(error_num);
+#endif
MRN_SET_BASE_SHARE_KEY(share, table->s);
MRN_SET_BASE_TABLE_KEY(this, table);
DBUG_RETURN(res);
@@ -13068,7 +13450,11 @@ bool ha_mroonga::wrapper_is_fatal_error(int error_num, uint flags)
bool ha_mroonga::storage_is_fatal_error(int error_num, uint flags)
{
MRN_DBUG_ENTER_METHOD();
+#ifdef MRN_HANDLER_IS_FATAL_ERROR_HAVE_FLAGS
bool is_fatal_error = handler::is_fatal_error(error_num, flags);
+#else
+ bool is_fatal_error = handler::is_fatal_error(error_num);
+#endif
DBUG_RETURN(is_fatal_error);
}
@@ -13234,7 +13620,9 @@ enum_alter_inplace_result ha_mroonga::wrapper_check_if_supported_inplace_alter(
uint n_keys;
uint i;
enum_alter_inplace_result result_mroonga = HA_ALTER_INPLACE_NO_LOCK;
- DBUG_PRINT("info", ("mroonga: handler_flags=%lu", ha_alter_info->handler_flags));
+ DBUG_PRINT("info",
+ ("mroonga: handler_flags=%lu",
+ static_cast<ulong>(ha_alter_info->handler_flags)));
if (wrapper_is_comment_changed(table, altered_table)) {
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
@@ -13267,7 +13655,7 @@ enum_alter_inplace_result ha_mroonga::wrapper_check_if_supported_inplace_alter(
alter_index_add_count = 0;
alter_handler_flags = ha_alter_info->handler_flags;
if (!(alter_key_info_buffer = (KEY *)
- my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
+ mrn_my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
&alter_key_info_buffer, sizeof(KEY) * ha_alter_info->key_count,
&alter_index_drop_buffer, sizeof(KEY) * ha_alter_info->index_drop_count,
&alter_index_add_buffer, sizeof(uint) * ha_alter_info->index_add_count,
@@ -13362,8 +13750,6 @@ enum_alter_inplace_result ha_mroonga::storage_check_if_supported_inplace_alter(
Alter_inplace_info::DROP_INDEX |
Alter_inplace_info::ADD_UNIQUE_INDEX |
Alter_inplace_info::DROP_UNIQUE_INDEX |
- Alter_inplace_info::ADD_PK_INDEX |
- Alter_inplace_info::DROP_PK_INDEX |
Alter_inplace_info::ADD_COLUMN |
Alter_inplace_info::DROP_COLUMN |
Alter_inplace_info::ALTER_COLUMN_NAME;
@@ -13480,7 +13866,7 @@ bool ha_mroonga::wrapper_inplace_alter_table(
tmp_table_share.keys = ha_alter_info->key_count;
tmp_table_share.fields = 0;
if (!(tmp_share = (MRN_SHARE *)
- my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
+ mrn_my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
&tmp_share, sizeof(*tmp_share),
&key_parser, sizeof(char *) * (tmp_table_share.keys),
&key_parser_length, sizeof(uint) * (tmp_table_share.keys),
@@ -13629,7 +14015,7 @@ bool ha_mroonga::storage_inplace_alter_table_index(
tmp_table_share.keys = ha_alter_info->key_count;
tmp_table_share.fields = 0;
if (!(tmp_share = (MRN_SHARE *)
- my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
+ mrn_my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
&tmp_share, sizeof(*tmp_share),
&index_table, sizeof(char *) * tmp_table_share.keys,
&index_table_length, sizeof(uint) * tmp_table_share.keys,
@@ -13763,7 +14149,7 @@ bool ha_mroonga::storage_inplace_alter_table_add_column(
uint *index_table_length, *key_parser_length, *col_flags_length, *col_type_length;
tmp_table_share.keys = 0;
tmp_table_share.fields = altered_table->s->fields;
- tmp_share = (MRN_SHARE *)my_multi_malloc(
+ tmp_share = (MRN_SHARE *)mrn_my_multi_malloc(
MYF(MY_WME | MY_ZEROFILL),
&tmp_share, sizeof(*tmp_share),
&index_table, sizeof(char *) * tmp_table_share.keys,
@@ -14155,8 +14541,8 @@ int ha_mroonga::wrapper_add_index(TABLE *table_arg, KEY *key_info,
char **key_parser;
uint *key_parser_length;
MRN_DBUG_ENTER_METHOD();
- if (!(wrap_alter_key_info = (KEY *) my_malloc(sizeof(KEY) * num_of_keys,
- MYF(MY_WME)))) {
+ if (!(wrap_alter_key_info = (KEY *) mrn_my_malloc(sizeof(KEY) * num_of_keys,
+ MYF(MY_WME)))) {
MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables);
MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_columns);
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
@@ -14165,7 +14551,7 @@ int ha_mroonga::wrapper_add_index(TABLE *table_arg, KEY *key_info,
tmp_table_share.keys = n_keys + num_of_keys;
tmp_table_share.fields = 0;
if (!(tmp_share = (MRN_SHARE *)
- my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
+ mrn_my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
&tmp_share, sizeof(*tmp_share),
&key_parser, sizeof(char *) * (n_keys + num_of_keys),
&key_parser_length, sizeof(uint) * (n_keys + num_of_keys),
@@ -14299,7 +14685,7 @@ int ha_mroonga::storage_add_index(TABLE *table_arg, KEY *key_info,
tmp_table_share.keys = n_keys + num_of_keys;
tmp_table_share.fields = 0;
if (!(tmp_share = (MRN_SHARE *)
- my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
+ mrn_my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
&tmp_share, sizeof(*tmp_share),
&index_table, sizeof(char*) * tmp_table_share.keys,
&index_table_length, sizeof(uint) * tmp_table_share.keys,
@@ -14663,7 +15049,7 @@ void ha_mroonga::storage_get_auto_increment(ulonglong offset,
*first_value = long_term_share->auto_inc_value;
DBUG_PRINT("info", ("mroonga: *first_value(auto_inc_value)=%llu",
*first_value));
- *nb_reserved_values = ULONGLONG_MAX;
+ *nb_reserved_values = UINT_MAX64;
} else {
handler::get_auto_increment(offset, increment, nb_desired_values,
first_value, nb_reserved_values);
@@ -14811,6 +15197,7 @@ int ha_mroonga::check_for_upgrade(HA_CHECK_OPT *check_opt)
DBUG_RETURN(error);
}
+#ifdef MRN_HANDLER_HAVE_RESET_AUTO_INCREMENT
int ha_mroonga::wrapper_reset_auto_increment(ulonglong value)
{
int res;
@@ -14847,6 +15234,7 @@ int ha_mroonga::reset_auto_increment(ulonglong value)
}
DBUG_RETURN(res);
}
+#endif
void ha_mroonga::set_pk_bitmap()
{
@@ -15199,8 +15587,8 @@ char *ha_mroonga::storage_get_foreign_key_create_info()
}
create_info_str.q_append(") ON DELETE RESTRICT ON UPDATE RESTRICT", 39);
}
- if (!(create_info = (char *) my_malloc(create_info_str.length() + 1,
- MYF(MY_WME)))) {
+ if (!(create_info = (char *) mrn_my_malloc(create_info_str.length() + 1,
+ MYF(MY_WME)))) {
DBUG_RETURN(NULL);
}
memcpy(create_info, create_info_str.ptr(), create_info_str.length());