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.cpp1520
1 files changed, 1094 insertions, 426 deletions
diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp
index 8b9a08b59dc..83f03fcb272 100644
--- a/storage/mroonga/ha_mroonga.cpp
+++ b/storage/mroonga/ha_mroonga.cpp
@@ -2,7 +2,7 @@
/*
Copyright(C) 2010 Tetsuro IKEDA
Copyright(C) 2010-2013 Kentoku SHIBA
- Copyright(C) 2011-2014 Kouhei Sutou <kou@clear-code.com>
+ Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
Copyright(C) 2013 Kenji Maruyama <mmmaru777@gmail.com>
This library is free software; you can redistribute it and/or
@@ -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>
@@ -116,23 +124,14 @@
} \
} while (0)
#else
-# if MYSQL_VERSION_ID >= 50500
-# ifdef DBUG_OFF
-# ifndef _WIN32
-extern mysql_mutex_t LOCK_open;
-# endif
-# endif
-static mysql_mutex_t *mrn_LOCK_open;
-# define mrn_open_mutex_lock(share) mysql_mutex_lock(mrn_LOCK_open)
-# define mrn_open_mutex_unlock(share) mysql_mutex_unlock(mrn_LOCK_open)
-# else
+# ifdef DBUG_OFF
# ifndef _WIN32
-extern pthread_mutex_t LOCK_open;
+extern mysql_mutex_t LOCK_open;
# endif
-static pthread_mutex_t *mrn_LOCK_open;
-# define mrn_open_mutex_lock(share)
-# define mrn_open_mutex_unlock(share)
# endif
+static mysql_mutex_t *mrn_LOCK_open;
+# define mrn_open_mutex_lock(share) mysql_mutex_lock(mrn_LOCK_open)
+# define mrn_open_mutex_unlock(share) mysql_mutex_unlock(mrn_LOCK_open)
#endif
#if MYSQL_VERSION_ID >= 50600
@@ -157,7 +156,11 @@ static pthread_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
@@ -166,15 +169,10 @@ static pthread_mutex_t *mrn_LOCK_open;
# else
# define MRN_PLUGIN_LAST_VALUES NULL
# endif
-# define MRN_ABORT_ON_WARNING(thd) thd->abort_on_warning
-#endif
-
-#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;
+# 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
@@ -190,12 +188,69 @@ static pthread_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";
@@ -207,20 +262,55 @@ 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);
+#ifdef HAVE_PSI_INTERFACE
+# 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_log_mutex_key;
+static PSI_mutex_key mrn_db_manager_mutex_key;
+
+static PSI_mutex_info mrn_mutexes[] =
+{
+ {&mrn_open_tables_mutex_key, "open_tables", PSI_FLAG_GLOBAL},
+ {&mrn_long_term_share_mutex_key, "long_term_share", PSI_FLAG_GLOBAL},
+ {&mrn_allocated_thds_mutex_key, "allocated_thds", PSI_FLAG_GLOBAL},
+ {&mrn_share_mutex_key, "share", 0},
+ {&mrn_long_term_share_auto_inc_mutex_key,
+ "long_term_share::auto_inc", 0},
+ {&mrn_log_mutex_key, "log", PSI_FLAG_GLOBAL},
+ {&mrn_db_manager_mutex_key, "DatabaseManager", PSI_FLAG_GLOBAL}
+};
+#endif
+
/* global variables */
-static pthread_mutex_t mrn_log_mutex;
handlerton *mrn_hton_ptr;
HASH mrn_open_tables;
-pthread_mutex_t mrn_open_tables_mutex;
+mysql_mutex_t mrn_open_tables_mutex;
HASH mrn_long_term_share;
-pthread_mutex_t mrn_long_term_share_mutex;
+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
static inline double round(double x)
{
@@ -272,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;
@@ -506,6 +603,33 @@ static int mrn_lock_timeout = grn_get_lock_timeout();
static char *mrn_libgroonga_version = const_cast<char *>(grn_get_version());
static char *mrn_version = const_cast<char *>(MRN_VERSION);
static char *mrn_vector_column_delimiter = NULL;
+static my_bool mrn_libgroonga_support_zlib = FALSE;
+static my_bool mrn_libgroonga_support_lz4 = FALSE;
+typedef enum {
+ MRN_BOOLEAN_MODE_SYNTAX_FLAG_DEFAULT = (1 << 0),
+ MRN_BOOLEAN_MODE_SYNTAX_FLAG_SYNTAX_QUERY = (1 << 1),
+ MRN_BOOLEAN_MODE_SYNTAX_FLAG_SYNTAX_SCRIPT = (1 << 2),
+ MRN_BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_COLUMN = (1 << 3),
+ 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",
+ "SYNTAX_SCRIPT",
+ "ALLOW_COLUMN",
+ "ALLOW_UPDATE",
+ "ALLOW_LEADING_NOT",
+ NullS
+};
+static TYPELIB mrn_boolean_mode_syntax_flags_typelib = {
+ array_elements(mrn_boolean_mode_sytnax_flag_names) - 1,
+ "",
+ mrn_boolean_mode_sytnax_flag_names,
+ NULL
+};
+#endif
typedef enum {
MRN_ACTION_ON_ERROR_ERROR,
@@ -552,9 +676,6 @@ static grn_logger mrn_logger = {
NULL
};
-/* global hashes and mutexes */
-HASH mrn_allocated_thds;
-pthread_mutex_t mrn_allocated_thds_mutex;
static uchar *mrn_allocated_thds_get_key(const uchar *record,
size_t *length,
my_bool not_used __attribute__ ((unused)))
@@ -569,22 +690,42 @@ 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[] = { "NONE", "EMERG", "ALERT",
- "CRIT", "ERROR", "WARNING",
- "NOTICE", "INFO", "DEBUG",
- "DUMP", NullS };
-static TYPELIB mrn_log_level_typelib =
-{
- array_elements(mrn_log_level_type_names)-1,
+static const char *mrn_log_level_type_names[] = {
+ "NONE",
+ "EMERG",
+ "ALERT",
+ "CRIT",
+ "ERROR",
+ "WARNING",
+ "NOTICE",
+ "INFO",
+ "DEBUG",
+ "DUMP",
+ NullS
+};
+static TYPELIB mrn_log_level_typelib = {
+ array_elements(mrn_log_level_type_names) - 1,
"mrn_log_level_typelib",
mrn_log_level_type_names,
NULL
@@ -677,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));
- my_free(old_log_file_name, MYF(0));
+ *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);
@@ -717,8 +858,8 @@ 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, MYF(0));
- *old_value_ptr = my_strdup(new_value, MYF(MY_WME));
+ my_free(*old_value_ptr);
+ *old_value_ptr = mrn_my_strdup(new_value, MYF(MY_WME));
#else
*old_value_ptr = (char *)new_value;
#endif
@@ -760,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,
@@ -771,8 +912,8 @@ static void mrn_vector_column_delimiter_update(THD *thd, struct st_mysql_sys_var
char **old_value_ptr = (char **)var_ptr;
#ifdef MRN_NEED_FREE_STRING_MEMALLOC_PLUGIN_VAR
- my_free(*old_value_ptr, MYF(0));
- *old_value_ptr = my_strdup(new_value, MYF(MY_WME));
+ my_free(*old_value_ptr);
+ *old_value_ptr = mrn_my_strdup(new_value, MYF(MY_WME));
#else
*old_value_ptr = (char *)new_value;
#endif
@@ -796,9 +937,9 @@ static void mrn_database_path_prefix_update(THD *thd,
char **old_value_ptr = (char **)var_ptr;
#ifdef MRN_NEED_FREE_STRING_MEMALLOC_PLUGIN_VAR
if (*old_value_ptr)
- my_free(*old_value_ptr, MYF(0));
+ 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
@@ -876,6 +1017,73 @@ static MYSQL_SYSVAR_STR(version, mrn_version,
NULL,
MRN_VERSION);
+static my_bool grn_check_zlib_support()
+{
+ bool is_zlib_support = false;
+ grn_obj grn_support_p;
+
+ GRN_BOOL_INIT(&grn_support_p, 0);
+ grn_obj_get_info(&mrn_ctx, NULL, GRN_INFO_SUPPORT_ZLIB, &grn_support_p);
+ is_zlib_support = (GRN_BOOL_VALUE(&grn_support_p));
+ grn_obj_unlink(&mrn_ctx, &grn_support_p);
+
+ return is_zlib_support;
+}
+
+static my_bool grn_check_lz4_support()
+{
+ bool is_lz4_support = false;
+ grn_obj grn_support_p;
+
+ GRN_BOOL_INIT(&grn_support_p, 0);
+ grn_obj_get_info(&mrn_ctx, NULL, GRN_INFO_SUPPORT_LZ4, &grn_support_p);
+ is_lz4_support = (GRN_BOOL_VALUE(&grn_support_p));
+ grn_obj_unlink(&mrn_ctx, &grn_support_p);
+
+ return is_lz4_support;
+}
+
+static MYSQL_SYSVAR_BOOL(libgroonga_support_zlib, mrn_libgroonga_support_zlib,
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+ "The status of libgroonga supports zlib",
+ NULL,
+ NULL,
+ grn_check_zlib_support());
+
+static MYSQL_SYSVAR_BOOL(libgroonga_support_lz4, mrn_libgroonga_support_lz4,
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+ "The status of libgroonga supports LZ4",
+ NULL,
+ 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. "
+ "Available flags: "
+ "DEFAULT(=SYNTAX_QUERY,ALLOW_LEADING_NOT), "
+ "SYNTAX_QUERY, SYNTAX_SCRIPT, "
+ "ALLOW_COLUMN, ALLOW_UPDATE and ALLOW_LEADING_NOT",
+ NULL,
+ 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[] =
{
MYSQL_SYSVAR(log_level),
@@ -891,6 +1099,12 @@ static struct st_mysql_sys_var *mrn_system_variables[] =
MYSQL_SYSVAR(libgroonga_version),
MYSQL_SYSVAR(version),
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
};
@@ -917,7 +1131,7 @@ static ST_FIELD_INFO i_s_mrn_stats_fields_info[] =
MYSQL_TYPE_LONG,
0,
0,
- "Rows written to groonga",
+ "Rows written to Groonga",
SKIP_OPEN_TABLE
},
{
@@ -926,7 +1140,7 @@ static ST_FIELD_INFO i_s_mrn_stats_fields_info[] =
MYSQL_TYPE_LONG,
0,
0,
- "Rows read from groonga",
+ "Rows read from Groonga",
SKIP_OPEN_TABLE
}
};
@@ -1010,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;
@@ -1191,7 +1409,112 @@ static grn_builtin_type mrn_grn_type_from_field(grn_ctx *ctx, Field *field,
return type;
}
-#ifdef HAVE_SPATIAL
+grn_obj_flags mrn_parse_grn_column_create_flags(THD *thd,
+ grn_ctx *ctx,
+ const char *flag_names,
+ uint flag_names_length)
+{
+ grn_obj_flags flags = 0;
+ const char *flag_names_end = flag_names + flag_names_length;
+
+ 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 >= 13 && !memcmp(flag_names, "COLUMN_SCALAR", 13)) {
+ flags |= GRN_OBJ_COLUMN_SCALAR;
+ flag_names += 13;
+ } else if (rest_length >= 13 && !memcmp(flag_names, "COLUMN_VECTOR", 13)) {
+ flags |= GRN_OBJ_COLUMN_VECTOR;
+ flag_names += 13;
+ } else if (rest_length >= 13 && !memcmp(flag_names, "COMPRESS_ZLIB", 13)) {
+ if (mrn_libgroonga_support_zlib) {
+ flags |= GRN_OBJ_COMPRESS_ZLIB;
+ } else {
+ push_warning_printf(thd, MRN_SEVERITY_WARNING,
+ ER_MRN_UNSUPPORTED_COLUMN_FLAG_NUM,
+ ER_MRN_UNSUPPORTED_COLUMN_FLAG_STR,
+ "COMPRESS_ZLIB");
+ }
+ flag_names += 13;
+ } else if (rest_length >= 12 && !memcmp(flag_names, "COMPRESS_LZ4", 12)) {
+ if (mrn_libgroonga_support_lz4) {
+ flags |= GRN_OBJ_COMPRESS_LZ4;
+ } else {
+ push_warning_printf(thd, MRN_SEVERITY_WARNING,
+ ER_MRN_UNSUPPORTED_COLUMN_FLAG_NUM,
+ ER_MRN_UNSUPPORTED_COLUMN_FLAG_STR,
+ "COMPRESS_LZ4");
+ }
+ flag_names += 12;
+ } 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_COLUMN_FLAG_NUM,
+ ER_MRN_INVALID_COLUMN_FLAG_STR,
+ invalid_flag_name,
+ "COLUMN_SCALAR");
+ flags |= GRN_OBJ_COLUMN_SCALAR;
+ break;
+ }
+ }
+ return flags;
+}
+
+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)
{
@@ -1228,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;
@@ -1254,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)
{
@@ -1275,11 +1596,16 @@ static int mrn_init(void *p)
hton = (handlerton *)p;
hton->state = SHOW_OPTION_YES;
hton->create = mrn_handler_create;
- hton->flags = HTON_NO_PARTITION;
+ 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
@@ -1294,21 +1620,20 @@ static int mrn_init(void *p)
# endif
# ifndef MRN_HAVE_TDC_LOCK_TABLE_SHARE
mrn_LOCK_open =
-# if MYSQL_VERSION_ID >= 50500
(mysql_mutex_t *)GetProcAddress(current_module,
"?LOCK_open@@3Ust_mysql_mutex@@A");
-# else
- (pthread_mutex_t *)GetProcAddress(current_module,
- "?LOCK_open@@3U_RTL_CRITICAL_SECTION@@A");
-# endif
# 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;
@@ -1321,7 +1646,14 @@ static int mrn_init(void *p)
# endif
#endif
- // init groonga
+#ifdef HAVE_PSI_INTERFACE
+ if (PSI_server) {
+ const char *category = "mroonga";
+ int n_mutexes = array_elements(mrn_mutexes);
+ PSI_server->register_mutex(category, mrn_mutexes, n_mutexes);
+ }
+#endif
+
if (grn_init() != GRN_SUCCESS) {
goto err_grn_init;
}
@@ -1335,7 +1667,17 @@ static int mrn_init(void *p)
if (mrn_change_encoding(ctx, system_charset_info))
goto err_mrn_change_encoding;
- if (pthread_mutex_init(&mrn_log_mutex, NULL) != 0) {
+#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) {
goto err_log_mutex_init;
}
@@ -1358,25 +1700,39 @@ static int mrn_init(void *p)
grn_ctx_init(&mrn_db_manager_ctx, 0);
grn_logger_set(&mrn_db_manager_ctx, &mrn_logger);
- mrn_db_manager = new mrn::DatabaseManager(&mrn_db_manager_ctx);
+ if (mysql_mutex_init(mrn_db_manager_mutex_key,
+ &mrn_db_manager_mutex,
+ MY_MUTEX_INIT_FAST) != 0) {
+ GRN_LOG(&mrn_db_manager_ctx, GRN_LOG_ERROR,
+ "failed to initialize mutex for database manager");
+ goto err_db_manager_mutex_init;
+ }
+ mrn_db_manager = new mrn::DatabaseManager(&mrn_db_manager_ctx,
+ &mrn_db_manager_mutex);
if (!mrn_db_manager->init()) {
goto err_db_manager_init;
}
- if ((pthread_mutex_init(&mrn_allocated_thds_mutex, NULL) != 0)) {
+ if ((mysql_mutex_init(mrn_allocated_thds_mutex_key,
+ &mrn_allocated_thds_mutex,
+ MY_MUTEX_INIT_FAST) != 0)) {
goto err_allocated_thds_mutex_init;
}
if (my_hash_init(&mrn_allocated_thds, system_charset_info, 32, 0, 0,
mrn_allocated_thds_get_key, 0, 0)) {
goto error_allocated_thds_hash_init;
}
- if ((pthread_mutex_init(&mrn_open_tables_mutex, NULL) != 0)) {
+ if ((mysql_mutex_init(mrn_open_tables_mutex_key,
+ &mrn_open_tables_mutex,
+ MY_MUTEX_INIT_FAST) != 0)) {
goto err_allocated_open_tables_mutex_init;
}
if (my_hash_init(&mrn_open_tables, system_charset_info, 32, 0, 0,
mrn_open_tables_get_key, 0, 0)) {
goto error_allocated_open_tables_hash_init;
}
- if ((pthread_mutex_init(&mrn_long_term_share_mutex, NULL) != 0)) {
+ if ((mysql_mutex_init(mrn_long_term_share_mutex_key,
+ &mrn_long_term_share_mutex,
+ MY_MUTEX_INIT_FAST) != 0)) {
goto error_allocated_long_term_share_mutex_init;
}
if (my_hash_init(&mrn_long_term_share, system_charset_info, 32, 0, 0,
@@ -1391,18 +1747,20 @@ static int mrn_init(void *p)
return 0;
error_allocated_long_term_share_hash_init:
- pthread_mutex_destroy(&mrn_long_term_share_mutex);
+ mysql_mutex_destroy(&mrn_long_term_share_mutex);
error_allocated_long_term_share_mutex_init:
my_hash_free(&mrn_open_tables);
error_allocated_open_tables_hash_init:
- pthread_mutex_destroy(&mrn_open_tables_mutex);
+ mysql_mutex_destroy(&mrn_open_tables_mutex);
err_allocated_open_tables_mutex_init:
my_hash_free(&mrn_allocated_thds);
error_allocated_thds_hash_init:
- pthread_mutex_destroy(&mrn_allocated_thds_mutex);
+ mysql_mutex_destroy(&mrn_allocated_thds_mutex);
err_allocated_thds_mutex_init:
err_db_manager_init:
delete mrn_db_manager;
+ mysql_mutex_destroy(&mrn_db_manager_mutex);
+err_db_manager_mutex_init:
grn_ctx_fin(&mrn_db_manager_ctx);
grn_obj_unlink(ctx, mrn_db);
err_db_create:
@@ -1411,7 +1769,7 @@ err_db_create:
mrn_log_file_opened = false;
}
err_log_file_open:
- pthread_mutex_destroy(&mrn_log_mutex);
+ mysql_mutex_destroy(&mrn_log_mutex);
err_log_mutex_init:
err_mrn_change_encoding:
grn_ctx_fin(ctx);
@@ -1450,12 +1808,13 @@ static int mrn_deinit(void *p)
}
my_hash_free(&mrn_long_term_share);
- pthread_mutex_destroy(&mrn_long_term_share_mutex);
+ mysql_mutex_destroy(&mrn_long_term_share_mutex);
my_hash_free(&mrn_open_tables);
- pthread_mutex_destroy(&mrn_open_tables_mutex);
+ mysql_mutex_destroy(&mrn_open_tables_mutex);
my_hash_free(&mrn_allocated_thds);
- pthread_mutex_destroy(&mrn_allocated_thds_mutex);
+ mysql_mutex_destroy(&mrn_allocated_thds_mutex);
delete mrn_db_manager;
+ mysql_mutex_destroy(&mrn_db_manager_mutex);
grn_ctx_fin(&mrn_db_manager_ctx);
grn_obj_unlink(ctx, mrn_db);
@@ -1466,7 +1825,7 @@ static int mrn_deinit(void *p)
fclose(mrn_log_file);
mrn_log_file_opened = false;
}
- pthread_mutex_destroy(&mrn_log_mutex);
+ mysql_mutex_destroy(&mrn_log_mutex);
return 0;
}
@@ -1489,6 +1848,18 @@ mrn_declare_plugin(MRN_PLUGIN_NAME)
i_s_mrn_stats
mrn_declare_plugin_end;
+static double mrn_get_score_value(grn_obj *score)
+{
+ MRN_DBUG_ENTER_FUNCTION();
+ double score_value;
+ if (score->header.domain == GRN_DB_FLOAT) {
+ score_value = GRN_FLOAT_VALUE(score);
+ } else {
+ score_value = (double)GRN_INT32_VALUE(score);
+ }
+ DBUG_RETURN(score_value);
+}
+
static void mrn_generic_ft_clear(FT_INFO *handler)
{
MRN_DBUG_ENTER_FUNCTION();
@@ -1555,7 +1926,7 @@ static float mrn_wrapper_ft_find_relevance(FT_INFO *handler, uchar *record,
GRN_BULK_REWIND(&(info->score));
grn_obj_get_value(info->ctx, info->score_column,
result_record_id, &(info->score));
- score = (float)GRN_INT32_VALUE(&(info->score));
+ score = mrn_get_score_value(&(info->score));
}
}
@@ -1593,7 +1964,7 @@ static float mrn_wrapper_ft_get_relevance(FT_INFO *handler)
GRN_BULK_REWIND(&(info->score));
grn_obj_get_value(info->ctx, info->score_column,
result_record_id, &(info->score));
- score = (float)GRN_INT32_VALUE(&(info->score));
+ score = mrn_get_score_value(&(info->score));
}
}
@@ -1640,7 +2011,7 @@ static float mrn_storage_ft_find_relevance(FT_INFO *handler, uchar *record,
GRN_BULK_REWIND(&(info->score));
grn_obj_get_value(info->ctx, info->score_column,
result_record_id, &(info->score));
- score = (float)GRN_INT32_VALUE(&(info->score));
+ score = mrn_get_score_value(&(info->score));
}
}
DBUG_PRINT("info", ("mroonga: record_id=%d score=%g",
@@ -1672,7 +2043,7 @@ static float mrn_storage_ft_get_relevance(FT_INFO *handler)
GRN_BULK_REWIND(&(info->score));
grn_obj_get_value(info->ctx, info->score_column,
result_record_id, &(info->score));
- score = (float)GRN_INT32_VALUE(&(info->score));
+ score = mrn_get_score_value(&(info->score));
}
}
DBUG_PRINT("info",
@@ -1916,7 +2287,6 @@ ha_mroonga::ha_mroonga(handlerton *hton, TABLE_SHARE *share_arg)
grn_column_ranges(NULL),
grn_index_tables(NULL),
grn_index_columns(NULL),
- grn_table_is_referenced(false),
grn_source_column_geo(NULL),
cursor_geo(NULL),
@@ -1967,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));
}
@@ -2126,7 +2499,7 @@ uint ha_mroonga::wrapper_max_supported_key_length() const
uint ha_mroonga::storage_max_supported_key_length() const
{
MRN_DBUG_ENTER_METHOD();
- DBUG_RETURN(HA_MAX_REC_LENGTH);
+ DBUG_RETURN(GRN_TABLE_MAX_KEY_SIZE);
}
uint ha_mroonga::max_supported_key_length() const
@@ -2173,7 +2546,7 @@ uint ha_mroonga::wrapper_max_supported_key_part_length() const
uint ha_mroonga::storage_max_supported_key_part_length() const
{
MRN_DBUG_ENTER_METHOD();
- DBUG_RETURN(HA_MAX_REC_LENGTH);
+ DBUG_RETURN(GRN_TABLE_MAX_KEY_SIZE);
}
uint ha_mroonga::max_supported_key_part_length() const
@@ -2348,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));
@@ -2392,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;
@@ -2467,7 +2842,7 @@ int ha_mroonga::wrapper_create(const char *name, TABLE *table,
share = NULL;
if (wrap_key_info)
{
- my_free(wrap_key_info, MYF(0));
+ my_free(wrap_key_info);
wrap_key_info = NULL;
}
base_key_info = NULL;
@@ -2486,7 +2861,7 @@ int ha_mroonga::wrapper_create(const char *name, TABLE *table,
if (wrap_key_info)
{
- my_free(wrap_key_info, MYF(0));
+ my_free(wrap_key_info);
wrap_key_info = NULL;
}
base_key_info = NULL;
@@ -2544,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);
@@ -2832,15 +3210,16 @@ 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) {
grn_obj *normalizer = NULL;
if (tmp_share->normalizer) {
- normalizer = grn_ctx_get(ctx,
- tmp_share->normalizer,
- tmp_share->normalizer_length);
+ normalizer = grn_ctx_get(ctx,
+ tmp_share->normalizer,
+ tmp_share->normalizer_length);
} else {
Field *field = &(key_info.key_part->field[0]);
if (should_normalize(field)) {
@@ -2902,12 +3281,10 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
grn_obj_flags col_flags = GRN_OBJ_PERSISTENT;
if (tmp_share->col_flags[i]) {
- // TODO: parse flags
- if (strcmp(tmp_share->col_flags[i], "COLUMN_VECTOR") == 0) {
- col_flags |= GRN_OBJ_COLUMN_VECTOR;
- } else {
- col_flags |= GRN_OBJ_COLUMN_SCALAR;
- }
+ col_flags |= mrn_parse_grn_column_create_flags(ha_thd(),
+ ctx,
+ tmp_share->col_flags[i],
+ tmp_share->col_flags_length[i]);
} else {
col_flags |= GRN_OBJ_COLUMN_SCALAR;
}
@@ -2987,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;
}
@@ -3012,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);
@@ -3020,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);
@@ -3350,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];
@@ -3448,7 +3836,8 @@ int ha_mroonga::storage_create_indexes(TABLE *table, const char *grn_table_name,
}
if (error) {
while (true) {
- if (index_tables[i]) {
+ if (index_tables[i] &&
+ !(tmp_share->index_table && tmp_share->index_table[i])) {
grn_obj_remove(ctx, index_tables[i]);
}
if (!i)
@@ -3557,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);
@@ -3574,7 +3963,7 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked)
MRN_SET_BASE_TABLE_KEY(this, table);
if (wrap_key_info)
{
- my_free(wrap_key_info, MYF(0));
+ my_free(wrap_key_info);
wrap_key_info = NULL;
}
base_key_info = NULL;
@@ -3598,7 +3987,7 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked)
MRN_SET_BASE_TABLE_KEY(this, table);
if (wrap_key_info)
{
- my_free(wrap_key_info, MYF(0));
+ my_free(wrap_key_info);
wrap_key_info = NULL;
}
base_key_info = NULL;
@@ -3626,7 +4015,7 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked)
wrap_handler = NULL;
if (wrap_key_info)
{
- my_free(wrap_key_info, MYF(0));
+ my_free(wrap_key_info);
wrap_key_info = NULL;
}
base_key_info = NULL;
@@ -3792,67 +4181,20 @@ 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);
- }
-
- storage_set_keys_in_use();
-
- ref_length = sizeof(grn_id);
- DBUG_RETURN(0);
-}
-
-void ha_mroonga::update_grn_table_is_referenced()
-{
- MRN_DBUG_ENTER_METHOD();
-
- grn_table_is_referenced = false;
-
- grn_table_cursor *cursor;
- int flags = GRN_CURSOR_BY_ID | GRN_CURSOR_ASCENDING;;
- cursor = grn_table_cursor_open(ctx, grn_ctx_db(ctx),
- NULL, 0,
- NULL, 0,
- 0, -1, flags);
- if (cursor) {
- grn_id id;
- grn_id grn_table_id;
-
- grn_table_id = grn_obj_id(ctx, grn_table);
- while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
- grn_obj *object;
- grn_id range = GRN_ID_NIL;
-
- object = grn_ctx_at(ctx, id);
- if (!object) {
- ctx->rc = GRN_SUCCESS;
- continue;
- }
-
- switch (object->header.type) {
- case GRN_COLUMN_FIX_SIZE:
- case GRN_COLUMN_VAR_SIZE:
- range = grn_obj_get_range(ctx, object);
- break;
- default:
- break;
- }
- grn_obj_unlink(ctx, object);
-
- if (range == grn_table_id) {
- grn_table_is_referenced = true;
- break;
- }
+ 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);
}
- grn_table_cursor_close(ctx, cursor);
+ storage_set_keys_in_use();
}
- DBUG_VOID_RETURN;
+ ref_length = sizeof(grn_id);
+ DBUG_RETURN(0);
}
int ha_mroonga::open_table(const char *name)
@@ -3881,8 +4223,6 @@ int ha_mroonga::open_table(const char *name)
DBUG_RETURN(error);
}
- update_grn_table_is_referenced();
-
DBUG_RETURN(0);
}
@@ -3898,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)
@@ -3910,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);
@@ -3920,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)
@@ -4002,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],
@@ -4104,7 +4470,7 @@ int ha_mroonga::wrapper_close()
wrap_handler = NULL;
if (wrap_key_info)
{
- my_free(wrap_key_info, MYF(0));
+ my_free(wrap_key_info);
wrap_key_info = NULL;
}
base_key_info = NULL;
@@ -4323,7 +4689,6 @@ int ha_mroonga::delete_table(const char *name)
}
if (!tmp_table_share)
{
- mrn::PathMapper mapper(name);
#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS
table_list.init_one_table(mapper.db_name(), strlen(mapper.db_name()),
mapper.mysql_table_name(),
@@ -5032,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);
}
@@ -5090,6 +5455,7 @@ int ha_mroonga::storage_write_row(uchar *buf)
{
MRN_DBUG_ENTER_METHOD();
int error = 0;
+ bool unique_indexes_are_processed = false;
if (is_dry_write()) {
DBUG_PRINT("info", ("mroonga: dry write: ha_mroonga::%s", __FUNCTION__));
@@ -5098,7 +5464,6 @@ int ha_mroonga::storage_write_row(uchar *buf)
THD *thd = ha_thd();
int i;
- uint j;
int n_columns = table->s->fields;
if (table->next_number_field && buf == table->record[0])
@@ -5115,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));
@@ -5156,6 +5521,11 @@ int ha_mroonga::storage_write_row(uchar *buf)
}
}
+ if (grn_table->header.type != GRN_TABLE_NO_KEY && pkey_size == 0) {
+ my_message(ER_ERROR_ON_WRITE, "primary key is empty", MYF(0));
+ DBUG_RETURN(ER_ERROR_ON_WRITE);
+ }
+
int added;
record_id = grn_table_add(ctx, grn_table, pkey, pkey_size, &added);
if (ctx->rc) {
@@ -5179,6 +5549,7 @@ int ha_mroonga::storage_write_row(uchar *buf)
{
goto err;
}
+ unique_indexes_are_processed = true;
grn_obj colbuf;
GRN_VOID_INIT(&colbuf);
@@ -5189,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;
@@ -5270,13 +5641,16 @@ int ha_mroonga::storage_write_row(uchar *buf)
DBUG_RETURN(0);
err:
- for (j = 0; j < table->s->keys; j++) {
- if (j == pkey_nr) {
- continue;
- }
- KEY *key_info = &table->key_info[j];
- if (key_info->flags & HA_NOSAME) {
- grn_table_delete_by_id(ctx, grn_index_tables[j], key_id[j]);
+ if (unique_indexes_are_processed) {
+ uint j;
+ for (j = 0; j < table->s->keys; j++) {
+ if (j == pkey_nr) {
+ continue;
+ }
+ KEY *key_info = &table->key_info[j];
+ if (key_info->flags & HA_NOSAME) {
+ grn_table_delete_by_id(ctx, grn_index_tables[j], key_id[j]);
+ }
}
}
grn_table_delete_by_id(ctx, grn_table, record_id);
@@ -5363,6 +5737,7 @@ err:
int ha_mroonga::storage_write_row_unique_index(uchar *buf,
KEY *key_info,
grn_obj *index_table,
+ grn_obj *index_column,
grn_id *key_id)
{
char *ukey = NULL;
@@ -5398,7 +5773,29 @@ int ha_mroonga::storage_write_row_unique_index(uchar *buf,
if (!added) {
// duplicated error
error = HA_ERR_FOUND_DUPP_KEY;
- memcpy(dup_ref, key_id, sizeof(grn_id));
+ grn_id duplicated_record_id = GRN_ID_NIL;
+ {
+ grn_table_cursor *table_cursor;
+ table_cursor = grn_table_cursor_open(ctx, index_table,
+ ukey, ukey_size,
+ ukey, ukey_size,
+ 0, -1, 0);
+ if (table_cursor) {
+ grn_obj *index_cursor;
+ index_cursor = grn_index_cursor_open(ctx, table_cursor, index_column,
+ GRN_ID_NIL, GRN_ID_MAX, 0);
+ if (index_cursor) {
+ grn_posting *posting;
+ posting = grn_index_cursor_next(ctx, index_cursor, NULL);
+ if (posting) {
+ duplicated_record_id = posting->rid;
+ }
+ }
+ grn_obj_unlink(ctx, index_cursor);
+ }
+ grn_table_cursor_close(ctx, table_cursor);
+ }
+ memcpy(dup_ref, &duplicated_record_id, sizeof(grn_id));
if (!ignoring_duplicated_key) {
GRN_LOG(ctx, GRN_LOG_ERROR,
"duplicated id on insert: update unique index: <%.*s>",
@@ -5431,9 +5828,14 @@ int ha_mroonga::storage_write_row_unique_indexes(uchar *buf)
if (!index_table) {
continue;
}
+ grn_obj *index_column = grn_index_columns[i];
+ if (!index_column) {
+ continue;
+ }
if ((error = storage_write_row_unique_index(buf, key_info,
- index_table, &key_id[i])))
+ index_table, index_column,
+ &key_id[i])))
{
if (error == HA_ERR_FOUND_DUPP_KEY)
{
@@ -5449,7 +5851,16 @@ err:
mrn_change_encoding(ctx, NULL);
do {
i--;
+
+ if (i == table->s->primary_key) {
+ continue;
+ }
+
KEY *key_info = &table->key_info[i];
+ if (!(key_info->flags & HA_NOSAME)) {
+ continue;
+ }
+
if (key_info->flags & HA_NOSAME) {
grn_table_delete_by_id(ctx, grn_index_tables[i], key_id[i]);
}
@@ -5497,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);
@@ -5661,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));
@@ -5719,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;
@@ -5914,6 +6325,13 @@ int ha_mroonga::storage_update_row_unique_indexes(uchar *new_data)
continue;
}
+ grn_obj *index_column = grn_index_columns[i];
+ if (!index_column) {
+ key_id[i] = GRN_ID_NIL;
+ del_key_id[i] = GRN_ID_NIL;
+ continue;
+ }
+
if (
KEY_N_KEY_PARTS(key_info) == 1 &&
!bitmap_is_set(table->write_set,
@@ -5926,7 +6344,8 @@ int ha_mroonga::storage_update_row_unique_indexes(uchar *new_data)
}
if ((error = storage_write_row_unique_index(new_data, key_info,
- index_table, &key_id[i])))
+ index_table, index_column,
+ &key_id[i])))
{
if (error == HA_ERR_FOUND_DUPP_KEY)
{
@@ -6276,28 +6695,40 @@ int ha_mroonga::delete_row(const uchar *buf)
DBUG_RETURN(error);
}
-uint ha_mroonga::wrapper_max_supported_key_parts()
+uint ha_mroonga::wrapper_max_supported_key_parts() const
{
MRN_DBUG_ENTER_METHOD();
DBUG_RETURN(MAX_REF_PARTS);
}
-uint ha_mroonga::storage_max_supported_key_parts()
+uint ha_mroonga::storage_max_supported_key_parts() const
{
MRN_DBUG_ENTER_METHOD();
- DBUG_RETURN(1);
+ DBUG_RETURN(MAX_REF_PARTS);
}
-uint ha_mroonga::max_supported_key_parts()
+uint ha_mroonga::max_supported_key_parts() const
{
MRN_DBUG_ENTER_METHOD();
+
uint parts;
- if (share->wrapper_mode)
- {
+ if (!share && !analyzed_for_create &&
+ (
+ thd_sql_command(ha_thd()) == SQLCOM_CREATE_TABLE ||
+ thd_sql_command(ha_thd()) == SQLCOM_CREATE_INDEX ||
+ thd_sql_command(ha_thd()) == SQLCOM_ALTER_TABLE
+ )
+ ) {
+ create_share_for_create();
+ }
+ if (analyzed_for_create && share_for_create.wrapper_mode) {
+ parts = wrapper_max_supported_key_parts();
+ } else if (wrap_handler && share && share->wrapper_mode) {
parts = wrapper_max_supported_key_parts();
} else {
parts = storage_max_supported_key_parts();
}
+
DBUG_RETURN(parts);
}
@@ -6393,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"));
@@ -6400,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++;
}
@@ -6413,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);
@@ -6606,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>, "
@@ -6624,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;
@@ -6810,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,
@@ -7422,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);
@@ -7594,6 +8028,37 @@ bool ha_mroonga::generic_ft_init_ext_parse_pragma_w(struct st_mrn_ft_info *info,
DBUG_RETURN(n_weights > 0);
}
+grn_expr_flags ha_mroonga::expr_flags_in_boolean_mode()
+{
+ MRN_DBUG_ENTER_METHOD();
+
+ 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;
+ } else {
+ if (syntax_flags & MRN_BOOLEAN_MODE_SYNTAX_FLAG_SYNTAX_SCRIPT) {
+ expression_flags |= GRN_EXPR_SYNTAX_SCRIPT;
+ } else {
+ expression_flags |= GRN_EXPR_SYNTAX_QUERY;
+ }
+ if (syntax_flags & MRN_BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_COLUMN) {
+ expression_flags |= GRN_EXPR_ALLOW_COLUMN;
+ }
+ if (syntax_flags & MRN_BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_UPDATE) {
+ expression_flags |= GRN_EXPR_ALLOW_UPDATE;
+ }
+ if (syntax_flags & MRN_BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_LEADING_NOT) {
+ expression_flags |= GRN_EXPR_ALLOW_LEADING_NOT;
+ }
+ }
+
+ DBUG_RETURN(expression_flags);
+}
+
grn_rc ha_mroonga::generic_ft_init_ext_prepare_expression_in_boolean_mode(
struct st_mrn_ft_info *info,
String *key,
@@ -7674,12 +8139,10 @@ grn_rc ha_mroonga::generic_ft_init_ext_prepare_expression_in_boolean_mode(
if (!weight_specified) {
grn_expr_append_obj(info->ctx, match_columns, index_column, GRN_OP_PUSH, 1);
}
- grn_expr_flags expression_flags =
- GRN_EXPR_SYNTAX_QUERY | GRN_EXPR_ALLOW_LEADING_NOT;
rc = grn_expr_parse(info->ctx, expression,
keyword, keyword_length,
match_columns, GRN_OP_MATCH, default_operator,
- expression_flags);
+ expr_flags_in_boolean_mode());
if (rc) {
char error_message[MRN_MESSAGE_BUFFER_SIZE];
snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
@@ -7859,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);
@@ -8138,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>",
@@ -8351,7 +8814,8 @@ int ha_mroonga::drop_index(MRN_SHARE *target_share, uint key_index)
const char *table_name = target_share->index_table[key_index];
snprintf(target_name, GRN_TABLE_MAX_KEY_SIZE,
"%s.%s", table_name, key_info[key_index].name);
- grn_obj *index_column = grn_ctx_get(ctx, target_name, strlen(target_name));
+ target_name_length = strlen(target_name);
+ grn_obj *index_column = grn_ctx_get(ctx, target_name, target_name_length);
if (index_column) {
rc = grn_obj_remove(ctx, index_column);
}
@@ -8366,6 +8830,8 @@ int ha_mroonga::drop_index(MRN_SHARE *target_share, uint key_index)
target_name_length = grn_obj_name(ctx, index_table,
target_name, GRN_TABLE_MAX_KEY_SIZE);
rc = grn_obj_remove(ctx, index_table);
+ } else {
+ target_name_length = 0;
}
}
@@ -8401,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,
@@ -8409,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);
@@ -8421,6 +8887,7 @@ grn_obj *ha_mroonga::find_normalizer(KEY *key_info)
{
MRN_DBUG_ENTER_METHOD();
grn_obj *normalizer = NULL;
+ bool use_normalizer = true;
#if MYSQL_VERSION_ID >= 50500
if (key_info->comment.length > 0) {
mrn::ParametersParser parser(key_info->comment.str,
@@ -8428,11 +8895,15 @@ grn_obj *ha_mroonga::find_normalizer(KEY *key_info)
parser.parse();
const char *normalizer_name = parser["normalizer"];
if (normalizer_name) {
- normalizer = grn_ctx_get(ctx, normalizer_name, -1);
+ if (strcmp(normalizer_name, "none") == 0) {
+ use_normalizer = false;
+ } else {
+ normalizer = grn_ctx_get(ctx, normalizer_name, -1);
+ }
}
}
#endif
- if (!normalizer) {
+ if (use_normalizer && !normalizer) {
Field *field = key_info->key_part[0].field;
mrn::FieldNormalizer field_normalizer(ctx, ha_thd(), field);
normalizer = field_normalizer.find_grn_normalizer();
@@ -8440,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();
@@ -8476,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;
}
@@ -8536,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;
}
@@ -8808,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;
@@ -8831,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) {
@@ -8839,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;
}
@@ -8875,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)
@@ -8932,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)
@@ -8946,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)
{
@@ -8956,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 &&
@@ -8983,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",
@@ -9011,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);
@@ -9031,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,
@@ -9047,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;
@@ -9059,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;
@@ -9087,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);
@@ -9150,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;
}
@@ -9190,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;
}
@@ -9217,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;
}
@@ -9277,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);
@@ -9297,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);
@@ -9317,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);
@@ -9349,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);
@@ -9370,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);
@@ -9391,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);
@@ -9412,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);
@@ -9438,9 +9985,9 @@ int ha_mroonga::generic_store_bulk_blob(Field *field, grn_obj *buf)
int error = 0;
String buffer;
Field_blob *blob = (Field_blob *)field;
- const char *value = blob->val_str(0, &buffer)->ptr();
+ String *value = blob->val_str(0, &buffer);
grn_obj_reinit(ctx, buf, GRN_DB_TEXT, 0);
- GRN_TEXT_SET(ctx, buf, value, blob->get_length());
+ GRN_TEXT_SET(ctx, buf, value->ptr(), value->length());
DBUG_RETURN(error);
}
@@ -9448,11 +9995,12 @@ 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;
- const char *wkb = geometry->val_str(0, &buffer)->ptr();
- int len = geometry->get_length();
+ String *value = geometry->val_str(0, &buffer);
+ const char *wkb = value->ptr();
+ int len = value->length();
error = mrn_set_geometry(ctx, buf, wkb, len);
#endif
DBUG_RETURN(error);
@@ -9633,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;
@@ -9685,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;
@@ -9878,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;
@@ -9994,7 +10542,7 @@ void ha_mroonga::storage_store_field(Field *field,
}
}
-void ha_mroonga::storage_store_field_column(Field *field,
+void ha_mroonga::storage_store_field_column(Field *field, bool is_primary_key,
int nth_column, grn_id record_id)
{
MRN_DBUG_ENTER_METHOD();
@@ -10009,7 +10557,6 @@ void ha_mroonga::storage_store_field_column(Field *field,
grn_obj_reinit(ctx, value, range_id, GRN_OBJ_VECTOR);
grn_obj_get_value(ctx, column, record_id, value);
- // TODO: Check whether reference type or not
grn_obj unvectored_value;
GRN_TEXT_INIT(&unvectored_value, 0);
int n_ids = GRN_BULK_VSIZE(value) / sizeof(grn_id);
@@ -10042,7 +10589,15 @@ void ha_mroonga::storage_store_field_column(Field *field,
} else {
grn_obj_reinit(ctx, value, range_id, 0);
grn_obj_get_value(ctx, column, record_id, value);
- storage_store_field(field, GRN_BULK_HEAD(value), GRN_BULK_VSIZE(value));
+ if (is_primary_key && GRN_BULK_VSIZE(value) == 0) {
+ char key[GRN_TABLE_MAX_KEY_SIZE];
+ int key_length;
+ key_length = grn_table_get_key(ctx, grn_table, record_id,
+ &key, GRN_TABLE_MAX_KEY_SIZE);
+ storage_store_field(field, key, key_length);
+ } else {
+ storage_store_field(field, GRN_BULK_HEAD(value), GRN_BULK_VSIZE(value));
+ }
}
DBUG_VOID_RETURN;
@@ -10056,9 +10611,11 @@ void ha_mroonga::storage_store_fields(uchar *buf, grn_id record_id)
my_ptrdiff_t ptr_diff = PTR_BYTE_DIFF(buf, table->record[0]);
Field *primary_key_field = NULL;
- if (grn_table_is_referenced && table->s->primary_key != MAX_INDEXES) {
+ if (table->s->primary_key != MAX_INDEXES) {
KEY *key_info = &(table->s->key_info[table->s->primary_key]);
- primary_key_field = key_info->key_part[0].field;
+ if (KEY_N_KEY_PARTS(key_info) == 1) {
+ primary_key_field = key_info->key_part[0].field;
+ }
}
int i;
@@ -10087,13 +10644,9 @@ void ha_mroonga::storage_store_fields(uchar *buf, grn_id record_id)
} else if (primary_key_field &&
strcmp(primary_key_field->field_name, column_name) == 0) {
// for primary key column
- char key[GRN_TABLE_MAX_KEY_SIZE];
- int key_length;
- key_length = grn_table_get_key(ctx, grn_table, record_id,
- &key, GRN_TABLE_MAX_KEY_SIZE);
- storage_store_field(field, key, key_length);
+ storage_store_field_column(field, true, i, record_id);
} else {
- storage_store_field_column(field, i ,record_id);
+ storage_store_field_column(field, false, i, record_id);
}
field->move_field_offset(-ptr_diff);
}
@@ -10278,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);
@@ -10325,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
@@ -10360,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);
@@ -10409,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);
@@ -10435,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);
@@ -10462,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);
@@ -10489,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);
@@ -10511,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);
}
@@ -10623,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;
@@ -10632,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;
@@ -10659,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);
@@ -10746,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);
}
@@ -10770,12 +11336,12 @@ int ha_mroonga::wrapper_reset()
MRN_SET_BASE_TABLE_KEY(this, table);
#ifdef MRN_HANDLER_HAVE_CHECK_IF_SUPPORTED_INPLACE_ALTER
if (alter_key_info_buffer) {
- my_free(alter_key_info_buffer, MYF(0));
+ my_free(alter_key_info_buffer);
alter_key_info_buffer = NULL;
}
#else
if (wrap_alter_key_info) {
- my_free(wrap_alter_key_info, MYF(0));
+ my_free(wrap_alter_key_info);
wrap_alter_key_info = NULL;
}
#endif
@@ -11787,24 +12353,24 @@ void ha_mroonga::update_create_info(HA_CREATE_INFO* create_info)
if (slot_data) {
slot_data->alter_create_info = create_info;
if (slot_data->alter_connect_string) {
- my_free(slot_data->alter_connect_string, MYF(0));
+ my_free(slot_data->alter_connect_string);
slot_data->alter_connect_string = NULL;
}
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, MYF(0));
+ my_free(slot_data->alter_comment);
slot_data->alter_comment = NULL;
}
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;
@@ -12117,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();
@@ -12136,52 +12703,90 @@ 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)
+{
+ MRN_DBUG_ENTER_METHOD();
+
+ int error = 0;
+ if (share->index_table[i]) {
+ char index_column_name[GRN_TABLE_MAX_KEY_SIZE];
+ snprintf(index_column_name, GRN_TABLE_MAX_KEY_SIZE - 1,
+ "%s.%s", share->index_table[i], key_info[i].name);
+ grn_obj *index_column = grn_ctx_get(ctx,
+ index_column_name,
+ strlen(index_column_name));
+ if (index_column) {
+ grn_obj_remove(ctx, index_column);
+ }
+ } else {
+ mrn::PathMapper mapper(share->table_name);
+ mrn::IndexTableName index_table_name(mapper.table_name(),
+ key_info[i].name);
+ grn_obj *index_table = grn_ctx_get(ctx,
+ index_table_name.c_str(),
+ index_table_name.length());
+ if (index_table) {
+ grn_obj_remove(ctx, index_table);
+ }
+ }
+ if (ctx->rc == GRN_SUCCESS) {
+ grn_index_tables[i] = NULL;
+ grn_index_columns[i] = NULL;
+ } else {
+ // TODO: Implement ctx->rc to error converter and use it.
+ error = ER_ERROR_ON_WRITE;
+ my_message(error, ctx->errbuf, MYF(0));
+ }
+
+ DBUG_RETURN(error);
}
int ha_mroonga::wrapper_disable_indexes(uint mode)
@@ -12212,23 +12817,16 @@ int ha_mroonga::wrapper_disable_indexes(uint mode)
}
}
KEY *key_info = table_share->key_info;
- mrn::PathMapper mapper(share->table_name);
for (i = 0; i < table_share->keys; i++) {
if (!(key_info[i].flags & HA_FULLTEXT) &&
!mrn_is_geo_key(&key_info[i])) {
continue;
}
- mrn::IndexTableName index_table_name(mapper.table_name(),
- key_info[i].name);
- grn_obj *index_table = grn_ctx_get(ctx,
- index_table_name.c_str(),
- index_table_name.length());
- if (index_table) {
- grn_obj_remove(ctx, index_table);
+ int sub_error = generic_disable_index(i, key_info);
+ if (error != 0 && sub_error != 0) {
+ error = sub_error;
}
- grn_index_tables[i] = NULL;
- grn_index_columns[i] = NULL;
}
} else {
error = HA_ERR_WRONG_COMMAND;
@@ -12239,6 +12837,7 @@ int ha_mroonga::wrapper_disable_indexes(uint mode)
int ha_mroonga::storage_disable_indexes(uint mode)
{
+ int error = 0;
MRN_DBUG_ENTER_METHOD();
if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE || mode == HA_KEY_SWITCH_ALL) {
uint i;
@@ -12252,7 +12851,6 @@ int ha_mroonga::storage_disable_indexes(uint mode)
}
}
KEY *key_info = table_share->key_info;
- mrn::PathMapper mapper(share->table_name);
for (i = 0; i < table_share->keys; i++) {
if (i == table->s->primary_key) {
continue;
@@ -12262,21 +12860,15 @@ int ha_mroonga::storage_disable_indexes(uint mode)
continue;
}
- mrn::IndexTableName index_table_name(mapper.table_name(),
- key_info[i].name);
- grn_obj *index_table = grn_ctx_get(ctx,
- index_table_name.c_str(),
- index_table_name.length());
- if (index_table) {
- grn_obj_remove(ctx, index_table);
+ int sub_error = generic_disable_index(i, key_info);
+ if (error != 0 && sub_error != 0) {
+ error = sub_error;
}
- grn_index_tables[i] = NULL;
- grn_index_columns[i] = NULL;
}
} else {
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
}
int ha_mroonga::disable_indexes(uint mode)
@@ -12305,7 +12897,7 @@ int ha_mroonga::wrapper_enable_indexes(uint mode)
if (share->wrap_key_nr[i] < MAX_KEY) {
continue;
}
- if (!grn_index_tables[i]) {
+ if (!grn_index_columns[i]) {
break;
}
}
@@ -12334,7 +12926,7 @@ int ha_mroonga::wrapper_enable_indexes(uint mode)
}
index_tables[i] = NULL;
index_columns[i] = NULL;
- if (!grn_index_tables[i]) {
+ if (!grn_index_columns[i]) {
if (
(key_info[i].flags & HA_FULLTEXT) &&
(error = wrapper_create_index_fulltext(mapper.table_name(),
@@ -12394,7 +12986,7 @@ int ha_mroonga::storage_enable_indexes(uint mode)
if (i == table->s->primary_key) {
continue;
}
- if (!grn_index_tables[i]) {
+ if (!grn_index_columns[i]) {
break;
}
}
@@ -12420,7 +13012,7 @@ int ha_mroonga::storage_enable_indexes(uint mode)
break;
}
index_tables[i] = NULL;
- if (!grn_index_tables[i]) {
+ if (!grn_index_columns[i]) {
if ((error = storage_create_index(table, mapper.table_name(), grn_table,
share, &key_info[i], index_tables,
index_columns, i)))
@@ -12434,6 +13026,8 @@ int ha_mroonga::storage_enable_indexes(uint mode)
mrn_set_bitmap_by_key(table->read_set, &key_info[i]);
have_multiple_column_index = true;
}
+ grn_index_tables[i] = index_tables[i];
+ grn_index_columns[i] = index_columns[i];
} else {
index_columns[i] = NULL;
}
@@ -12485,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)
@@ -12654,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;
@@ -12672,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)
@@ -12691,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)
@@ -12784,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);
@@ -12793,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);
}
@@ -12902,6 +13563,7 @@ int ha_mroonga::storage_add_index_multiple_columns(KEY *key_info,
if ((error = storage_write_row_unique_index(table->record[0],
current_key_info,
index_tables[i],
+ index_columns[i],
&key_id)))
{
if (error == HA_ERR_FOUND_DUPP_KEY)
@@ -12958,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);
@@ -12991,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,
@@ -13086,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;
@@ -13204,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),
@@ -13308,7 +13970,7 @@ bool ha_mroonga::wrapper_inplace_alter_table(
result = true;
}
mrn_free_share_alloc(tmp_share);
- my_free(tmp_share, MYF(0));
+ my_free(tmp_share);
MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables);
MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_columns);
DBUG_RETURN(result);
@@ -13353,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,
@@ -13434,6 +14096,12 @@ bool ha_mroonga::storage_inplace_alter_table_index(
ha_alter_info->key_count,
index_tables,
index_columns, false);
+ if (error == HA_ERR_FOUND_DUPP_UNIQUE) {
+ my_printf_error(ER_DUP_UNIQUE, ER(ER_DUP_UNIQUE), MYF(0),
+ table_share->table_name);
+ } else if (error) {
+ my_message(error, "failed to create multiple column index", MYF(0));
+ }
for (i = 0; i < n_columns; ++i) {
Field *field = altered_table->field[i];
field->move_field_offset(-ptr_diff);
@@ -13460,7 +14128,7 @@ bool ha_mroonga::storage_inplace_alter_table_index(
have_error = true;
}
mrn_free_share_alloc(tmp_share);
- my_free(tmp_share, MYF(0));
+ my_free(tmp_share);
MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables);
MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_columns);
@@ -13481,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,
@@ -13532,12 +14200,10 @@ bool ha_mroonga::storage_inplace_alter_table_add_column(
grn_obj_flags col_flags = GRN_OBJ_PERSISTENT;
if (tmp_share->col_flags[i]) {
- // TODO: parse flags
- if (strcmp(tmp_share->col_flags[i], "COLUMN_VECTOR") == 0) {
- col_flags |= GRN_OBJ_COLUMN_VECTOR;
- } else {
- col_flags |= GRN_OBJ_COLUMN_SCALAR;
- }
+ col_flags |= mrn_parse_grn_column_create_flags(ha_thd(),
+ ctx,
+ tmp_share->col_flags[i],
+ tmp_share->col_flags_length[i]);
} else {
col_flags |= GRN_OBJ_COLUMN_SCALAR;
}
@@ -13570,7 +14236,7 @@ bool ha_mroonga::storage_inplace_alter_table_add_column(
grn_obj_unlink(ctx, table_obj);
mrn_free_share_alloc(tmp_share);
- my_free(tmp_share, MYF(0));
+ my_free(tmp_share);
DBUG_RETURN(have_error);
}
@@ -13752,7 +14418,7 @@ bool ha_mroonga::wrapper_commit_inplace_alter_table(
bool result;
MRN_DBUG_ENTER_METHOD();
if (!alter_handler_flags) {
- my_free(alter_key_info_buffer, MYF(0));
+ my_free(alter_key_info_buffer);
alter_key_info_buffer = NULL;
DBUG_RETURN(false);
}
@@ -13765,7 +14431,7 @@ bool ha_mroonga::wrapper_commit_inplace_alter_table(
MRN_SET_BASE_ALTER_KEY(this, ha_alter_info);
MRN_SET_BASE_SHARE_KEY(share, table->s);
MRN_SET_BASE_TABLE_KEY(this, table);
- my_free(alter_key_info_buffer, MYF(0));
+ my_free(alter_key_info_buffer);
alter_key_info_buffer = NULL;
DBUG_RETURN(result);
}
@@ -13875,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);
@@ -13885,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),
@@ -13990,7 +14656,7 @@ int ha_mroonga::wrapper_add_index(TABLE *table_arg, KEY *key_info,
}
#endif
mrn_free_share_alloc(tmp_share);
- my_free(tmp_share, MYF(0));
+ my_free(tmp_share);
MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables);
MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_columns);
DBUG_RETURN(error);
@@ -14019,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,
@@ -14104,7 +14770,7 @@ int ha_mroonga::storage_add_index(TABLE *table_arg, KEY *key_info,
}
#endif
mrn_free_share_alloc(tmp_share);
- my_free(tmp_share, MYF(0));
+ my_free(tmp_share);
MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables);
MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_columns);
DBUG_RETURN(error);
@@ -14383,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);
@@ -14531,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;
@@ -14567,6 +15234,7 @@ int ha_mroonga::reset_auto_increment(ulonglong value)
}
DBUG_RETURN(res);
}
+#endif
void ha_mroonga::set_pk_bitmap()
{
@@ -14919,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());
@@ -15277,7 +15945,7 @@ void ha_mroonga::wrapper_free_foreign_key_create_info(char* str)
void ha_mroonga::storage_free_foreign_key_create_info(char* str)
{
MRN_DBUG_ENTER_METHOD();
- my_free(str, MYF(0));
+ my_free(str);
DBUG_VOID_RETURN;
}
#else