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.cpp1759
1 files changed, 1060 insertions, 699 deletions
diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp
index 83f03fcb272..a94278e19c2 100644
--- a/storage/mroonga/ha_mroonga.cpp
+++ b/storage/mroonga/ha_mroonga.cpp
@@ -27,14 +27,11 @@
#pragma implementation
#endif
-#if MYSQL_VERSION_ID >= 50500
-# include <sql_plugin.h>
-# include <sql_show.h>
-# include <key.h>
-# include <tztime.h>
-# include <sql_base.h>
-#endif
-
+#include <sql_plugin.h>
+#include <sql_show.h>
+#include <key.h>
+#include <tztime.h>
+#include <sql_base.h>
#include <sql_select.h>
#include <item_sum.h>
@@ -102,6 +99,10 @@
# include <sql_table.h>
#endif
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+# include <create_options.h>
+#endif
+
// for debug
#define MRN_CLASS_NAME "ha_mroonga"
@@ -110,7 +111,11 @@
#define MRN_LONG_TEXT_SIZE (1 << 31) // 2Gbytes
#ifdef MRN_HAVE_TDC_LOCK_TABLE_SHARE
-# define mrn_open_mutex(share) &((share)->tdc.LOCK_table_share)
+# ifdef MRN_TABLE_SHARE_TDC_IS_POINTER
+# define mrn_open_mutex(share) &((share)->tdc->LOCK_table_share)
+# else
+# define mrn_open_mutex(share) &((share)->tdc.LOCK_table_share)
+# endif
# define mrn_open_mutex_lock(share) do { \
TABLE_SHARE *share_ = share; \
if (share_ && share_->tmp_table == NO_TMP_TABLE) { \
@@ -156,24 +161,10 @@ static mysql_mutex_t *mrn_LOCK_open;
# define mrn_declare_plugin(NAME) maria_declare_plugin(NAME)
# define mrn_declare_plugin_end maria_declare_plugin_end
# define MRN_PLUGIN_LAST_VALUES MRN_VERSION, MariaDB_PLUGIN_MATURITY_STABLE
-# 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
-# ifdef MRN_PLUGIN_HAVE_FLAGS
-# define MRN_PLUGIN_LAST_VALUES NULL, 0
-# else
-# define MRN_PLUGIN_LAST_VALUES NULL
-# endif
-# if MYSQL_VERSION_ID >= 50706
-# define MRN_ABORT_ON_WARNING(thd) false
-# else
-# define MRN_ABORT_ON_WARNING(thd) thd->abort_on_warning
-# endif
+# define MRN_PLUGIN_LAST_VALUES NULL, 0
#endif
#if MYSQL_VERSION_ID >= 100007 && defined(MRN_MARIADB_P)
@@ -267,9 +258,7 @@ uint grn_atoui(const char *nptr, const char *end, const char **rest);
# 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;
@@ -357,11 +346,6 @@ static const char *mrn_inspect_thr_lock_type(enum thr_lock_type lock_type)
case TL_WRITE_ALLOW_WRITE:
inspected = "TL_WRITE_ALLOW_WRITE";
break;
-#ifdef MRN_HAVE_TL_WRITE_ALLOW_READ
- case TL_WRITE_ALLOW_READ:
- inspected = "TL_WRITE_ALLOW_READ";
- break;
-#endif
#ifdef MRN_HAVE_TL_WRITE_CONCURRENT_DEFAULT
case TL_WRITE_CONCURRENT_DEFAULT:
inspected = "TL_WRITE_CONCURRENT_DEFAULT";
@@ -524,19 +508,15 @@ static const char *mrn_inspect_extra_function(enum ha_extra_function operation)
case HA_EXTRA_PREPARE_FOR_RENAME:
inspected = "HA_EXTRA_PREPARE_FOR_RENAME";
break;
-#ifdef MRN_HAVE_HA_EXTRA_ADD_CHILDREN_LIST
case HA_EXTRA_ADD_CHILDREN_LIST:
inspected = "HA_EXTRA_ADD_CHILDREN_LIST";
break;
-#endif
case HA_EXTRA_ATTACH_CHILDREN:
inspected = "HA_EXTRA_ATTACH_CHILDREN";
break;
-#ifdef MRN_HAVE_HA_EXTRA_IS_ATTACHED_CHILDREN
case HA_EXTRA_IS_ATTACHED_CHILDREN:
inspected = "HA_EXTRA_IS_ATTACHED_CHILDREN";
break;
-#endif
case HA_EXTRA_DETACH_CHILDREN:
inspected = "HA_EXTRA_DETACH_CHILDREN";
break;
@@ -597,7 +577,7 @@ static bool mrn_log_file_opened = false;
static grn_log_level mrn_log_level_default = GRN_LOG_DEFAULT_LEVEL;
static ulong mrn_log_level = mrn_log_level_default;
-char *mrn_default_parser = NULL;
+char *mrn_default_tokenizer = NULL;
char *mrn_default_wrapper_engine = NULL;
static int mrn_lock_timeout = grn_get_lock_timeout();
static char *mrn_libgroonga_version = const_cast<char *>(grn_get_version());
@@ -630,6 +610,11 @@ static TYPELIB mrn_boolean_mode_syntax_flags_typelib = {
NULL
};
#endif
+#ifdef MRN_GROONGA_EMBEDDED
+static my_bool mrn_libgroonga_embedded = TRUE;
+#else
+static my_bool mrn_libgroonga_embedded = FALSE;
+#endif
typedef enum {
MRN_ACTION_ON_ERROR_ERROR,
@@ -836,8 +821,8 @@ static MYSQL_SYSVAR_STR(log_file, mrn_log_file_path,
mrn_log_file_update,
MRN_LOG_FILE_PATH);
-static void mrn_default_parser_update(THD *thd, struct st_mysql_sys_var *var,
- void *var_ptr, const void *save)
+static void mrn_default_tokenizer_update(THD *thd, struct st_mysql_sys_var *var,
+ void *var_ptr, const void *save)
{
MRN_DBUG_ENTER_FUNCTION();
const char *new_value = *((const char **)save);
@@ -848,12 +833,12 @@ static void mrn_default_parser_update(THD *thd, struct st_mysql_sys_var *var,
mrn_change_encoding(&ctx, system_charset_info);
if (strcmp(*old_value_ptr, new_value) == 0) {
GRN_LOG(&ctx, GRN_LOG_NOTICE,
- "default parser isn't changed "
- "because the requested default parser isn't different: <%s>",
+ "default tokenizer for fulltext index isn't changed "
+ "because the requested default tokenizer isn't different: <%s>",
new_value);
} else {
GRN_LOG(&ctx, GRN_LOG_NOTICE,
- "default fulltext parser is changed: <%s> -> <%s>",
+ "default tokenizer for fulltext index is changed: <%s> -> <%s>",
*old_value_ptr, new_value);
}
@@ -869,12 +854,20 @@ static void mrn_default_parser_update(THD *thd, struct st_mysql_sys_var *var,
DBUG_VOID_RETURN;
}
-static MYSQL_SYSVAR_STR(default_parser, mrn_default_parser,
+static MYSQL_SYSVAR_STR(default_parser, mrn_default_tokenizer,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
- "default fulltext parser",
+ "default fulltext parser "
+ "(Deprecated. Use mroonga_default_tokenizer instead.)",
NULL,
- mrn_default_parser_update,
- MRN_PARSER_DEFAULT);
+ mrn_default_tokenizer_update,
+ MRN_DEFAULT_TOKENIZER);
+
+static MYSQL_SYSVAR_STR(default_tokenizer, mrn_default_tokenizer,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
+ "default tokenizer for fulltext index",
+ NULL,
+ mrn_default_tokenizer_update,
+ MRN_DEFAULT_TOKENIZER);
static MYSQL_THDVAR_BOOL(
dry_write, /* name */
@@ -1084,11 +1077,19 @@ static MYSQL_THDVAR_INT(max_n_records_for_estimate,
INT_MAX,
0);
+static MYSQL_SYSVAR_BOOL(libgroonga_embedded, mrn_libgroonga_embedded,
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+ "Whether libgroonga is embedded or not",
+ NULL,
+ NULL,
+ mrn_libgroonga_embedded);
+
static struct st_mysql_sys_var *mrn_system_variables[] =
{
MYSQL_SYSVAR(log_level),
MYSQL_SYSVAR(log_file),
MYSQL_SYSVAR(default_parser),
+ MYSQL_SYSVAR(default_tokenizer),
MYSQL_SYSVAR(dry_write),
MYSQL_SYSVAR(enable_optimization),
MYSQL_SYSVAR(match_escalation_threshold),
@@ -1105,6 +1106,7 @@ static struct st_mysql_sys_var *mrn_system_variables[] =
MYSQL_SYSVAR(boolean_mode_syntax_flags),
#endif
MYSQL_SYSVAR(max_n_records_for_estimate),
+ MYSQL_SYSVAR(libgroonga_embedded),
NULL
};
@@ -1213,7 +1215,7 @@ static int mrn_close_connection(handlerton *hton, THD *thd)
MRN_DBUG_ENTER_FUNCTION();
void *p = *thd_ha_data(thd, mrn_hton_ptr);
if (p) {
- mrn_clear_alter_share(thd);
+ mrn_clear_slot_data(thd);
free(p);
*thd_ha_data(thd, mrn_hton_ptr) = (void *) NULL;
{
@@ -1409,13 +1411,14 @@ static grn_builtin_type mrn_grn_type_from_field(grn_ctx *ctx, Field *field,
return type;
}
-grn_obj_flags mrn_parse_grn_column_create_flags(THD *thd,
- grn_ctx *ctx,
- const char *flag_names,
- uint flag_names_length)
+static bool mrn_parse_grn_column_create_flags(THD *thd,
+ grn_ctx *ctx,
+ const char *flag_names,
+ uint flag_names_length,
+ grn_obj_flags *column_flags)
{
- grn_obj_flags flags = 0;
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;
@@ -1425,14 +1428,17 @@ grn_obj_flags mrn_parse_grn_column_create_flags(THD *thd,
continue;
}
if (rest_length >= 13 && !memcmp(flag_names, "COLUMN_SCALAR", 13)) {
- flags |= GRN_OBJ_COLUMN_SCALAR;
+ *column_flags |= GRN_OBJ_COLUMN_SCALAR;
flag_names += 13;
+ found = true;
} else if (rest_length >= 13 && !memcmp(flag_names, "COLUMN_VECTOR", 13)) {
- flags |= GRN_OBJ_COLUMN_VECTOR;
+ *column_flags |= GRN_OBJ_COLUMN_VECTOR;
flag_names += 13;
+ found = true;
} else if (rest_length >= 13 && !memcmp(flag_names, "COMPRESS_ZLIB", 13)) {
if (mrn_libgroonga_support_zlib) {
- flags |= GRN_OBJ_COMPRESS_ZLIB;
+ *column_flags |= GRN_OBJ_COMPRESS_ZLIB;
+ found = true;
} else {
push_warning_printf(thd, MRN_SEVERITY_WARNING,
ER_MRN_UNSUPPORTED_COLUMN_FLAG_NUM,
@@ -1442,7 +1448,8 @@ grn_obj_flags mrn_parse_grn_column_create_flags(THD *thd,
flag_names += 13;
} else if (rest_length >= 12 && !memcmp(flag_names, "COMPRESS_LZ4", 12)) {
if (mrn_libgroonga_support_lz4) {
- flags |= GRN_OBJ_COMPRESS_LZ4;
+ *column_flags |= GRN_OBJ_COMPRESS_LZ4;
+ found = true;
} else {
push_warning_printf(thd, MRN_SEVERITY_WARNING,
ER_MRN_UNSUPPORTED_COLUMN_FLAG_NUM,
@@ -1459,20 +1466,18 @@ grn_obj_flags mrn_parse_grn_column_create_flags(THD *thd,
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;
+ invalid_flag_name);
break;
}
}
- return flags;
+ return found;
}
-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)
+static 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;
@@ -1588,6 +1593,24 @@ static uint mrn_alter_table_flags(uint flags)
}
#endif
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+static ha_create_table_option mrn_field_options[] =
+{
+ HA_FOPTION_STRING("GROONGA_TYPE", groonga_type),
+ HA_FOPTION_STRING("FLAGS", flags),
+ HA_FOPTION_END
+};
+
+static ha_create_table_option mrn_index_options[] =
+{
+ HA_IOPTION_STRING("TOKENIZER", tokenizer),
+ HA_IOPTION_STRING("NORMALIZER", normalizer),
+ HA_IOPTION_STRING("TOKEN_FILTERS", token_filters),
+ HA_IOPTION_STRING("FLAGS", flags),
+ HA_IOPTION_END
+};
+#endif
+
static int mrn_init(void *p)
{
// init handlerton
@@ -1606,6 +1629,10 @@ static int mrn_init(void *p)
#ifdef MRN_HAVE_HTON_ALTER_TABLE_FLAGS
hton->alter_table_flags = mrn_alter_table_flags;
#endif
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ hton->field_options = mrn_field_options;
+ hton->index_options = mrn_index_options;
+#endif
mrn_hton_ptr = hton;
#ifdef _WIN32
@@ -1629,11 +1656,9 @@ static int mrn_init(void *p)
(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
+ mrn_table_share_lock_ha_data =
+ (PSI_mutex_key *)GetProcAddress(current_module,
+ MRN_TABLE_SHARE_LOCK_HA_DATA_PROC);
# endif
#else
mrn_binlog_filter = binlog_filter;
@@ -1790,7 +1815,7 @@ static int mrn_deinit(void *p)
mrn::Lock lock(&mrn_allocated_thds_mutex);
while ((tmp_thd = (THD *) my_hash_element(&mrn_allocated_thds, 0)))
{
- mrn_clear_alter_share(tmp_thd);
+ mrn_clear_slot_data(tmp_thd);
void *slot_ptr = mrn_get_slot_data(tmp_thd, false);
if (slot_ptr) free(slot_ptr);
*thd_ha_data(tmp_thd, mrn_hton_ptr) = (void *) NULL;
@@ -2367,10 +2392,10 @@ const char *ha_mroonga::table_type() const
const char *ha_mroonga::index_type(uint key_nr)
{
MRN_DBUG_ENTER_METHOD();
- KEY key_info = table->s->key_info[key_nr];
- if (key_info.algorithm == HA_KEY_ALG_FULLTEXT) {
+ KEY *key_info = &(table->s->key_info[key_nr]);
+ if (key_info->algorithm == HA_KEY_ALG_FULLTEXT) {
DBUG_RETURN("FULLTEXT");
- } else if (key_info.algorithm == HA_KEY_ALG_HASH) {
+ } else if (key_info->algorithm == HA_KEY_ALG_HASH) {
DBUG_RETURN("HASH");
} else {
DBUG_RETURN("BTREE");
@@ -2655,9 +2680,10 @@ ulonglong ha_mroonga::table_flags() const
ulong ha_mroonga::wrapper_index_flags(uint idx, uint part, bool all_parts) const
{
ulong index_flags;
- KEY key = table_share->key_info[idx];
+ KEY *key = &(table_share->key_info[idx]);
MRN_DBUG_ENTER_METHOD();
- if (key.algorithm == HA_KEY_ALG_BTREE || key.algorithm == HA_KEY_ALG_UNDEF) {
+ if (key->algorithm == HA_KEY_ALG_BTREE ||
+ key->algorithm == HA_KEY_ALG_UNDEF) {
MRN_SET_WRAP_SHARE_KEY(share, table->s);
MRN_SET_WRAP_TABLE_KEY(this, table);
index_flags = wrap_handler->index_flags(idx, part, all_parts);
@@ -2673,18 +2699,27 @@ ulong ha_mroonga::storage_index_flags(uint idx, uint part, bool all_parts) const
{
MRN_DBUG_ENTER_METHOD();
ulong flags;
- KEY key = table_share->key_info[idx];
- if (key.algorithm == HA_KEY_ALG_BTREE || key.algorithm == HA_KEY_ALG_UNDEF) {
+ KEY *key = &(table_share->key_info[idx]);
+ if (key->algorithm == HA_KEY_ALG_BTREE ||
+ key->algorithm == HA_KEY_ALG_UNDEF) {
flags = HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE;
bool need_normalize_p = false;
- Field *field = &key.key_part[part].field[0];
+ // TODO: MariaDB 10.1 passes key->user_defined_key_parts as part
+ // for ORDER BY DESC. We just it fallback to part = 0. We may use
+ // it for optimization in the future.
+ //
+ // See also: test_if_order_by_key() in sql/sql_select.cc.
+ if (KEY_N_KEY_PARTS(key) == part) {
+ part = 0;
+ }
+ Field *field = &(key->key_part[part].field[0]);
if (field && should_normalize(field)) {
need_normalize_p = true;
}
if (!need_normalize_p) {
flags |= HA_KEYREAD_ONLY;
}
- if (KEY_N_KEY_PARTS(&key) > 1 || !need_normalize_p) {
+ if (KEY_N_KEY_PARTS(key) > 1 || !need_normalize_p) {
flags |= HA_READ_ORDER;
}
} else {
@@ -2697,11 +2732,11 @@ ulong ha_mroonga::index_flags(uint idx, uint part, bool all_parts) const
{
MRN_DBUG_ENTER_METHOD();
- KEY key = table_share->key_info[idx];
- if (key.algorithm == HA_KEY_ALG_FULLTEXT) {
+ KEY *key = &(table_share->key_info[idx]);
+ if (key->algorithm == HA_KEY_ALG_FULLTEXT) {
DBUG_RETURN(HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR);
}
- if (mrn_is_geo_key(&key)) {
+ if (mrn_is_geo_key(key)) {
DBUG_RETURN(HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR);
}
@@ -2833,9 +2868,23 @@ int ha_mroonga::wrapper_create(const char *name, TABLE *table,
share = tmp_share;
MRN_SET_WRAP_SHARE_KEY(tmp_share, table->s);
MRN_SET_WRAP_TABLE_KEY(this, table);
- if (!(hnd =
- tmp_share->hton->create(tmp_share->hton, table->s,
- current_thd->mem_root)))
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ if (parse_engine_table_options(ha_thd(), tmp_share->hton, table->s)) {
+ MRN_SET_BASE_SHARE_KEY(tmp_share, table->s);
+ MRN_SET_BASE_TABLE_KEY(this, table);
+ share = NULL;
+ if (wrap_key_info)
+ {
+ my_free(wrap_key_info);
+ wrap_key_info = NULL;
+ }
+ base_key_info = NULL;
+ error = MRN_GET_ERROR_NUMBER;
+ DBUG_RETURN(error);
+ }
+#endif
+ hnd = get_new_handler(table->s, current_thd->mem_root, tmp_share->hton);
+ if (!hnd)
{
MRN_SET_BASE_SHARE_KEY(tmp_share, table->s);
MRN_SET_BASE_TABLE_KEY(this, table);
@@ -2848,7 +2897,6 @@ int ha_mroonga::wrapper_create(const char *name, TABLE *table,
base_key_info = NULL;
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
- hnd->init();
error = hnd->ha_create(name, table, info);
MRN_SET_BASE_SHARE_KEY(tmp_share, table->s);
MRN_SET_BASE_TABLE_KEY(this, table);
@@ -2856,7 +2904,7 @@ int ha_mroonga::wrapper_create(const char *name, TABLE *table,
delete hnd;
if (error) {
- wrapper_delete_index(name, tmp_share, mapper.table_name());
+ generic_delete_table(name, mapper.table_name());
}
if (wrap_key_info)
@@ -2949,8 +2997,7 @@ int ha_mroonga::wrapper_create_index_fulltext(const char *grn_table_name,
mrn_change_encoding(ctx, system_charset_info);
index_tables[i] = index_table;
- grn_obj *tokenizer = find_tokenizer(tmp_share->key_parser[i],
- tmp_share->key_parser_length[i]);
+ grn_obj *tokenizer = find_tokenizer(key_info, tmp_share, i);
if (tokenizer) {
grn_info_type info_type = GRN_INFO_DEFAULT_TOKENIZER;
grn_obj_set_info(ctx, index_table, info_type, tokenizer);
@@ -3097,14 +3144,14 @@ int ha_mroonga::wrapper_create_index(const char *name, TABLE *table,
for (i = 0; i < n_keys; i++) {
index_tables[i] = NULL;
- KEY key_info = table->s->key_info[i];
- if (key_info.algorithm == HA_KEY_ALG_FULLTEXT) {
+ KEY *key_info = &(table->s->key_info[i]);
+ if (key_info->algorithm == HA_KEY_ALG_FULLTEXT) {
error = wrapper_create_index_fulltext(grn_table_name,
- i, &key_info,
+ i, key_info,
index_tables, NULL, tmp_share);
- } else if (mrn_is_geo_key(&key_info)) {
+ } else if (mrn_is_geo_key(key_info)) {
error = wrapper_create_index_geo(grn_table_name,
- i, &key_info,
+ i, key_info,
index_tables, NULL, tmp_share);
}
}
@@ -3160,12 +3207,12 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
grn_obj *pkey_type;
uint pkey_nr = table->s->primary_key;
if (pkey_nr != MAX_INDEXES) {
- KEY key_info = table->s->key_info[pkey_nr];
+ KEY *key_info = &(table->s->key_info[pkey_nr]);
bool is_id;
- int key_parts = KEY_N_KEY_PARTS(&key_info);
+ int key_parts = KEY_N_KEY_PARTS(key_info);
if (key_parts == 1) {
- Field *pkey_field = key_info.key_part[0].field;
+ Field *pkey_field = key_info->key_part[0].field;
const char *column_name = pkey_field->field_name;
is_id = (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0);
@@ -3177,7 +3224,7 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
}
// default algorithm is BTREE ==> PAT
- if (!is_id && key_info.algorithm == HA_KEY_ALG_HASH) {
+ if (!is_id && key_info->algorithm == HA_KEY_ALG_HASH) {
table_flags |= GRN_OBJ_TABLE_HASH_KEY;
} else if (!is_id) {
table_flags |= GRN_OBJ_TABLE_PAT_KEY;
@@ -3212,8 +3259,8 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
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);
+ 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) {
@@ -3221,9 +3268,9 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
tmp_share->normalizer,
tmp_share->normalizer_length);
} else {
- Field *field = &(key_info.key_part->field[0]);
+ Field *field = &(key_info->key_part->field[0]);
if (should_normalize(field)) {
- normalizer = find_normalizer(&key_info);
+ normalizer = find_normalizer(key_info);
}
}
if (normalizer) {
@@ -3259,7 +3306,6 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
/* create columns */
uint n_columns = table->s->fields;
for (uint i = 0; i < n_columns; i++) {
- grn_obj *col_type;
Field *field = table->s->field[i];
const char *column_name = field->field_name;
int column_name_size = strlen(column_name);
@@ -3280,19 +3326,18 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
#endif
grn_obj_flags col_flags = GRN_OBJ_PERSISTENT;
- if (tmp_share->col_flags[i]) {
- col_flags |= mrn_parse_grn_column_create_flags(ha_thd(),
- ctx,
- tmp_share->col_flags[i],
- tmp_share->col_flags_length[i]);
- } else {
+ if (!find_column_flags(field, tmp_share, i, &col_flags)) {
col_flags |= GRN_OBJ_COLUMN_SCALAR;
}
- grn_builtin_type gtype = mrn_grn_type_from_field(ctx, field, false);
- if (tmp_share->col_type[i]) {
- col_type = grn_ctx_get(ctx, tmp_share->col_type[i], -1);
- } else {
- col_type = grn_ctx_at(ctx, gtype);
+
+ grn_obj *col_type;
+ {
+ int column_type_error_code = ER_CANT_CREATE_TABLE;
+ col_type = find_column_type(field, tmp_share, i, column_type_error_code);
+ if (!col_type) {
+ grn_obj_remove(ctx, table_obj);
+ DBUG_RETURN(column_type_error_code);
+ }
}
char *col_path = NULL; // we don't specify path
@@ -3445,17 +3490,11 @@ bool ha_mroonga::storage_create_foreign_key(TABLE *table,
DBUG_RETURN(false);
}
-#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS
table_list.init_one_table(mapper.db_name(),
strlen(mapper.db_name()),
mapper.mysql_table_name(),
strlen(mapper.mysql_table_name()),
mapper.mysql_table_name(), TL_WRITE);
-#else
- table_list.init_one_table(mapper.db_name(),
- mapper.mysql_table_name(),
- TL_WRITE);
-#endif
mrn_open_mutex_lock(table->s);
tmp_ref_table_share =
mrn_create_tmp_table_share(&table_list, ref_path, &error);
@@ -3572,16 +3611,16 @@ int ha_mroonga::storage_create_validate_index(TABLE *table)
/* checking if index is used for virtual columns */
uint n_keys = table->s->keys;
for (i = 0; i < n_keys; i++) {
- KEY key_info = table->s->key_info[i];
+ KEY *key_info = &(table->s->key_info[i]);
// must be single column key
- int key_parts = KEY_N_KEY_PARTS(&key_info);
+ int key_parts = KEY_N_KEY_PARTS(key_info);
if (key_parts != 1) {
continue;
}
- Field *field = key_info.key_part[0].field;
+ Field *field = key_info->key_part[0].field;
const char *column_name = field->field_name;
if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
- if (key_info.algorithm == HA_KEY_ALG_HASH) {
+ if (key_info->algorithm == HA_KEY_ALG_HASH) {
continue; // hash index is ok
}
GRN_LOG(ctx, GRN_LOG_ERROR, "only hash index can be defined for _id");
@@ -3660,8 +3699,7 @@ int ha_mroonga::storage_create_index_table(TABLE *table,
}
if (key_info->flags & HA_FULLTEXT) {
- grn_obj *tokenizer = find_tokenizer(tmp_share->key_parser[i],
- tmp_share->key_parser_length[i]);
+ grn_obj *tokenizer = find_tokenizer(key_info, tmp_share, i);
if (tokenizer) {
grn_info_type info_type = GRN_INFO_DEFAULT_TOKENIZER;
grn_obj_set_info(ctx, index_table, info_type, tokenizer);
@@ -3909,6 +3947,8 @@ int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
if (error) {
mrn_free_long_term_share(tmp_share->long_term_share);
tmp_share->long_term_share = NULL;
+ } else {
+ error = add_wrap_hton(tmp_share->table_name, tmp_share->hton);
}
mrn_free_share(tmp_share);
DBUG_RETURN(error);
@@ -3956,8 +3996,8 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked)
MRN_SET_WRAP_TABLE_KEY(this, table);
if (!is_clone)
{
- if (!(wrap_handler =
- share->hton->create(share->hton, table->s, &mem_root)))
+ wrap_handler = get_new_handler(table->s, &mem_root, share->hton);
+ if (!wrap_handler)
{
MRN_SET_BASE_SHARE_KEY(share, table->s);
MRN_SET_BASE_TABLE_KEY(this, table);
@@ -3969,19 +4009,13 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked)
base_key_info = NULL;
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
- wrap_handler->init();
#ifdef MRN_HANDLER_HAVE_SET_HA_SHARE_REF
wrap_handler->set_ha_share_ref(&table->s->ha_share);
#endif
error = wrap_handler->ha_open(table, name, mode, test_if_locked);
} else {
-#ifdef MRN_HANDLER_CLONE_NEED_NAME
if (!(wrap_handler = parent_for_clone->wrap_handler->clone(name,
mem_root_for_clone)))
-#else
- if (!(wrap_handler = parent_for_clone->wrap_handler->clone(
- mem_root_for_clone)))
-#endif
{
MRN_SET_BASE_SHARE_KEY(share, table->s);
MRN_SET_BASE_TABLE_KEY(this, table);
@@ -4047,12 +4081,12 @@ int ha_mroonga::wrapper_open_indexes(const char *name)
mrn::PathMapper mapper(name);
uint i = 0;
for (i = 0; i < n_keys; i++) {
- KEY key_info = table->s->key_info[i];
+ KEY *key_info = &(table->s->key_info[i]);
grn_index_tables[i] = NULL;
grn_index_columns[i] = NULL;
- if (!(wrapper_is_target_index(&key_info))) {
+ if (!(wrapper_is_target_index(key_info))) {
continue;
}
@@ -4060,7 +4094,7 @@ int ha_mroonga::wrapper_open_indexes(const char *name)
continue;
}
- mrn::IndexTableName index_table_name(mapper.table_name(), key_info.name);
+ mrn::IndexTableName index_table_name(mapper.table_name(), key_info->name);
grn_index_tables[i] = grn_ctx_get(ctx,
index_table_name.c_str(),
index_table_name.length());
@@ -4077,7 +4111,7 @@ int ha_mroonga::wrapper_open_indexes(const char *name)
strlen(INDEX_COLUMN_NAME));
if (!grn_index_columns[i]) {
/* just for backward compatibility before 1.0. */
- Field *field = key_info.key_part[0].field;
+ Field *field = key_info->key_part[0].field;
grn_index_columns[i] = grn_obj_column(ctx, grn_index_tables[i],
field->field_name,
strlen(field->field_name));
@@ -4337,10 +4371,10 @@ int ha_mroonga::storage_open_indexes(const char *name)
continue;
}
- KEY key_info = table->s->key_info[i];
- if (KEY_N_KEY_PARTS(&key_info) > 1) {
- KEY_PART_INFO *key_part = key_info.key_part;
- for (j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
+ KEY *key_info = &(table->s->key_info[i]);
+ if (KEY_N_KEY_PARTS(key_info) > 1) {
+ KEY_PART_INFO *key_part = key_info->key_part;
+ for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
bitmap_set_bit(&multiple_column_key_bitmap,
key_part[j].field->field_index);
}
@@ -4355,11 +4389,11 @@ int ha_mroonga::storage_open_indexes(const char *name)
if (ctx->rc == GRN_SUCCESS) {
grn_index_columns[i] = grn_obj_column(ctx,
grn_index_tables[i],
- key_info.name,
- strlen(key_info.name));
+ key_info->name,
+ strlen(key_info->name));
}
} else {
- mrn::IndexTableName index_table_name(mapper.table_name(), key_info.name);
+ mrn::IndexTableName index_table_name(mapper.table_name(), key_info->name);
grn_index_tables[i] = grn_ctx_get(ctx,
index_table_name.c_str(),
index_table_name.length());
@@ -4370,7 +4404,7 @@ int ha_mroonga::storage_open_indexes(const char *name)
strlen(INDEX_COLUMN_NAME));
if (!grn_index_columns[i] && ctx->rc == GRN_SUCCESS) {
/* just for backward compatibility before 1.0. */
- Field *field = key_info.key_part[0].field;
+ Field *field = key_info->key_part[0].field;
grn_index_columns[i] = grn_obj_column(ctx, grn_index_tables[i],
field->field_name,
strlen(field->field_name));
@@ -4504,40 +4538,20 @@ int ha_mroonga::close()
error = storage_close();
}
- if (is_temporary_table_name(share->table_name)) {
- TABLE_LIST table_list;
- TABLE_SHARE *tmp_table_share;
- int tmp_error;
- /* no need to decode */
- mrn::PathMapper mapper(share->table_name);
-#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS
- table_list.init_one_table(mapper.db_name(), strlen(mapper.db_name()),
- mapper.mysql_table_name(),
- strlen(mapper.mysql_table_name()),
- mapper.mysql_table_name(),
- TL_WRITE);
-#else
- table_list.init_one_table(mapper.db_name(), mapper.mysql_table_name(),
- TL_WRITE);
-#endif
- mrn_open_mutex_lock(NULL);
- tmp_table_share =
- mrn_create_tmp_table_share(&table_list, share->table_name, &tmp_error);
- mrn_open_mutex_unlock(NULL);
- if (!tmp_table_share) {
- error = tmp_error;
- } else if ((tmp_error = alter_share_add(share->table_name,
- tmp_table_share))) {
- error = tmp_error;
- mrn_open_mutex_lock(NULL);
- mrn_free_tmp_table_share(tmp_table_share);
- mrn_open_mutex_unlock(NULL);
- }
+ if (error != 0)
+ {
+ DBUG_RETURN(error);
}
+
+ error = add_wrap_hton(share->table_name, share->hton);
bitmap_free(&multiple_column_key_bitmap);
+ if (share->use_count == 1) {
+ mrn_free_long_term_share(share->long_term_share);
+ }
mrn_free_share(share);
share = NULL;
is_clone = false;
+
if (
thd &&
thd_sql_command(thd) == SQLCOM_FLUSH
@@ -4554,76 +4568,28 @@ int ha_mroonga::close()
DBUG_RETURN(error);
}
-int ha_mroonga::wrapper_delete_table(const char *name, MRN_SHARE *tmp_share,
+int ha_mroonga::wrapper_delete_table(const char *name,
+ handlerton *wrap_handlerton,
const char *table_name)
{
int error = 0;
- handler *hnd;
MRN_DBUG_ENTER_METHOD();
- MRN_SET_WRAP_SHARE_KEY(tmp_share, tmp_share->table_share);
- if (!(hnd =
- tmp_share->hton->create(tmp_share->hton, tmp_share->table_share,
- current_thd->mem_root)))
- {
- MRN_SET_BASE_SHARE_KEY(tmp_share, tmp_share->table_share);
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- }
- hnd->init();
- MRN_SET_BASE_SHARE_KEY(tmp_share, tmp_share->table_share);
- if ((error = hnd->ha_delete_table(name)))
+ handler *hnd = get_new_handler(NULL, current_thd->mem_root, wrap_handlerton);
+ if (!hnd)
{
- delete hnd;
- DBUG_RETURN(error);
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
- error = wrapper_delete_index(name, tmp_share, table_name);
-
+ error = hnd->ha_delete_table(name);
delete hnd;
- DBUG_RETURN(error);
-}
-
-int ha_mroonga::wrapper_delete_index(const char *name, MRN_SHARE *tmp_share,
- const char *table_name)
-{
- int error = 0;
- MRN_DBUG_ENTER_METHOD();
-
- error = ensure_database_open(name);
- if (error)
- DBUG_RETURN(error);
-
- error = mrn_change_encoding(ctx, system_charset_info);
- if (error)
- DBUG_RETURN(error);
- TABLE_SHARE *tmp_table_share = tmp_share->table_share;
-
- uint i;
- for (i = 0; i < tmp_table_share->keys; i++) {
- error = drop_index(tmp_share, i);
- if (error) {
- DBUG_RETURN(error);
- }
- }
-
- grn_obj *table = grn_ctx_get(ctx, table_name, strlen(table_name));
- if (!ctx->rc) {
- grn_obj_remove(ctx, table);
- }
- if (ctx->rc) {
- error = ER_CANT_OPEN_FILE;
- my_message(error, ctx->errbuf, MYF(0));
- DBUG_RETURN(error);
- }
DBUG_RETURN(error);
}
-int ha_mroonga::storage_delete_table(const char *name, MRN_SHARE *tmp_share,
- const char *table_name)
+int ha_mroonga::generic_delete_table(const char *name, const char *table_name)
{
int error = 0;
- TABLE_SHARE *tmp_table_share = tmp_share->table_share;
MRN_DBUG_ENTER_METHOD();
error = ensure_database_open(name);
@@ -4634,14 +4600,7 @@ int ha_mroonga::storage_delete_table(const char *name, MRN_SHARE *tmp_share,
if (error)
DBUG_RETURN(error);
- uint i;
- for (i = 0; i < tmp_table_share->keys; i++) {
- error = drop_index(tmp_share, i);
- if (error) {
- DBUG_RETURN(error);
- }
- }
-
+ error = drop_indexes(table_name);
grn_obj *table_obj = grn_ctx_get(ctx, table_name, strlen(table_name));
if (!ctx->rc) {
grn_obj_remove(ctx, table_obj);
@@ -4656,86 +4615,50 @@ int ha_mroonga::storage_delete_table(const char *name, MRN_SHARE *tmp_share,
int ha_mroonga::delete_table(const char *name)
{
+ MRN_DBUG_ENTER_METHOD();
+
int error = 0;
THD *thd = ha_thd();
- TABLE_LIST table_list;
- TABLE_SHARE *tmp_table_share = NULL;
- TABLE tmp_table;
- MRN_SHARE *tmp_share;
- st_mrn_alter_share *alter_share, *tmp_alter_share;
- MRN_DBUG_ENTER_METHOD();
+ handlerton *wrap_handlerton = NULL;
mrn::PathMapper mapper(name);
st_mrn_slot_data *slot_data = mrn_get_slot_data(thd, false);
- if (slot_data && slot_data->first_alter_share)
+ if (slot_data && slot_data->first_wrap_hton)
{
- tmp_alter_share = NULL;
- alter_share = slot_data->first_alter_share;
- while (alter_share)
+ st_mrn_wrap_hton *wrap_hton, *tmp_wrap_hton;
+ tmp_wrap_hton = NULL;
+ wrap_hton = slot_data->first_wrap_hton;
+ while (wrap_hton)
{
- if (!strcmp(alter_share->path, name))
+ if (!strcmp(wrap_hton->path, name))
{
/* found */
- tmp_table_share = alter_share->alter_share;
- if (tmp_alter_share)
- tmp_alter_share->next = alter_share->next;
+ wrap_handlerton = wrap_hton->hton;
+ if (tmp_wrap_hton)
+ tmp_wrap_hton->next = wrap_hton->next;
else
- slot_data->first_alter_share = alter_share->next;
- free(alter_share);
+ slot_data->first_wrap_hton = wrap_hton->next;
+ free(wrap_hton);
break;
}
- tmp_alter_share = alter_share;
- alter_share = alter_share->next;
+ tmp_wrap_hton = wrap_hton;
+ wrap_hton = wrap_hton->next;
}
}
- if (!tmp_table_share)
- {
-#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS
- table_list.init_one_table(mapper.db_name(), strlen(mapper.db_name()),
- mapper.mysql_table_name(),
- strlen(mapper.mysql_table_name()),
- mapper.mysql_table_name(),
- TL_WRITE);
-#else
- table_list.init_one_table(mapper.db_name(), mapper.mysql_table_name(),
- TL_WRITE);
-#endif
- mrn_open_mutex_lock(NULL);
- tmp_table_share = mrn_create_tmp_table_share(&table_list, name, &error);
- mrn_open_mutex_unlock(NULL);
- if (!tmp_table_share) {
- DBUG_RETURN(error);
- }
- }
- tmp_table.s = tmp_table_share;
-#ifdef WITH_PARTITION_STORAGE_ENGINE
- tmp_table.part_info = NULL;
-#endif
- if (!(tmp_share = mrn_get_share(name, &tmp_table, &error)))
+
+ if (wrap_handlerton)
{
- mrn_open_mutex_lock(NULL);
- mrn_free_tmp_table_share(tmp_table_share);
- mrn_open_mutex_unlock(NULL);
- DBUG_RETURN(error);
+ error = wrapper_delete_table(name, wrap_handlerton, mapper.table_name());
}
- if (tmp_share->wrapper_mode)
+ if (!error)
{
- error = wrapper_delete_table(name, tmp_share, mapper.table_name());
- } else {
- error = storage_delete_table(name, tmp_share, mapper.table_name());
+ error = generic_delete_table(name, mapper.table_name());
}
- if (!error) {
- mrn_free_long_term_share(tmp_share->long_term_share);
- tmp_share->long_term_share = NULL;
- }
- mrn_free_share(tmp_share);
- mrn_open_mutex_lock(NULL);
- mrn_free_tmp_table_share(tmp_table_share);
- mrn_open_mutex_unlock(NULL);
- if (is_temporary_table_name(name)) {
+ if (!error && is_temporary_table_name(name)) {
mrn_db_manager->drop(name);
}
+
DBUG_RETURN(error);
}
@@ -5331,9 +5254,9 @@ bool ha_mroonga::wrapper_have_target_index()
uint i;
uint n_keys = table->s->keys;
for (i = 0; i < n_keys; i++) {
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
- if (wrapper_is_target_index(&key_info)) {
+ if (wrapper_is_target_index(key_info)) {
have_target_index = true;
break;
}
@@ -5406,9 +5329,9 @@ int ha_mroonga::wrapper_write_row_index(uchar *buf)
uint i;
uint n_keys = table->s->keys;
for (i = 0; i < n_keys; i++) {
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
- if (!(wrapper_is_target_index(&key_info))) {
+ if (!(wrapper_is_target_index(key_info))) {
continue;
}
@@ -5418,8 +5341,8 @@ int ha_mroonga::wrapper_write_row_index(uchar *buf)
}
uint j;
- for (j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
- Field *field = key_info.key_part[j].field;
+ for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
+ Field *field = key_info->key_part[j].field;
if (field->is_null())
continue;
@@ -5481,7 +5404,8 @@ int ha_mroonga::storage_write_row(uchar *buf)
if (strcmp(MRN_COLUMN_NAME_ID, column_name) == 0) {
push_warning_printf(thd, MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, MRN_GET_ERR_MSG(WARN_DATA_TRUNCATED),
+ WARN_DATA_TRUNCATED,
+ MRN_GET_ERR_MSG(WARN_DATA_TRUNCATED),
MRN_COLUMN_NAME_ID,
MRN_GET_CURRENT_ROW_FOR_WARNING(thd));
if (MRN_ABORT_ON_WARNING(thd)) {
@@ -5490,66 +5414,79 @@ int ha_mroonga::storage_write_row(uchar *buf)
}
}
- char *pkey;
- int pkey_size;
- uint pkey_nr;
- pkey_nr = table->s->primary_key;
- GRN_BULK_REWIND(&key_buffer);
- if (pkey_nr == MAX_INDEXES) {
- pkey = NULL;
- pkey_size = 0;
- } else {
- KEY key_info = table->key_info[pkey_nr];
- if (KEY_N_KEY_PARTS(&key_info) == 1) {
- Field *pkey_field = key_info.key_part[0].field;
- error = mrn_change_encoding(ctx, pkey_field->charset());
- if (error) {
- DBUG_RETURN(error);
- }
- generic_store_bulk(pkey_field, &key_buffer);
- pkey = GRN_TEXT_VALUE(&key_buffer);
- pkey_size = GRN_TEXT_LEN(&key_buffer);
- } else {
- mrn_change_encoding(ctx, NULL);
- uchar key[MRN_MAX_KEY_SIZE];
- key_copy(key, buf, &key_info, key_info.key_length);
- grn_bulk_space(ctx, &key_buffer, key_info.key_length);
- pkey = GRN_TEXT_VALUE(&key_buffer);
- storage_encode_multiple_column_key(&key_info,
- key, key_info.key_length,
- (uchar *)pkey, (uint *)&pkey_size);
+ uint pkey_nr = table->s->primary_key;
+
+ int added = 0;
+ {
+ mrn::Lock lock(&(share->record_mutex), have_unique_index());
+ if ((error = storage_write_row_unique_indexes(buf)))
+ {
+ DBUG_RETURN(error);
}
- }
+ unique_indexes_are_processed = true;
- 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);
- }
+ char *pkey;
+ int pkey_size;
+ GRN_BULK_REWIND(&key_buffer);
+ if (pkey_nr == MAX_INDEXES) {
+ pkey = NULL;
+ pkey_size = 0;
+ } else {
+ KEY *key_info = &(table->key_info[pkey_nr]);
+ if (KEY_N_KEY_PARTS(key_info) == 1) {
+ Field *pkey_field = key_info->key_part[0].field;
+ error = mrn_change_encoding(ctx, pkey_field->charset());
+ if (error) {
+ DBUG_RETURN(error);
+ }
+ generic_store_bulk(pkey_field, &key_buffer);
+ pkey = GRN_TEXT_VALUE(&key_buffer);
+ pkey_size = GRN_TEXT_LEN(&key_buffer);
+ } else {
+ mrn_change_encoding(ctx, NULL);
+ uchar key[MRN_MAX_KEY_SIZE];
+ key_copy(key, buf, key_info, key_info->key_length);
+ grn_bulk_reserve(ctx, &key_buffer, MRN_MAX_KEY_SIZE);
+ pkey = GRN_TEXT_VALUE(&key_buffer);
+ storage_encode_multiple_column_key(key_info,
+ key, key_info->key_length,
+ (uchar *)pkey, (uint *)&pkey_size);
+ }
+ }
- int added;
- record_id = grn_table_add(ctx, grn_table, pkey, pkey_size, &added);
- if (ctx->rc) {
- my_message(ER_ERROR_ON_WRITE, ctx->errbuf, MYF(0));
- DBUG_RETURN(ER_ERROR_ON_WRITE);
- }
- if (!added) {
- // duplicated error
- error = HA_ERR_FOUND_DUPP_KEY;
- memcpy(dup_ref, &record_id, sizeof(grn_id));
- dup_key = pkey_nr;
- if (!ignoring_duplicated_key) {
- GRN_LOG(ctx, GRN_LOG_ERROR,
- "duplicated id on insert: update primary key: <%.*s>",
- pkey_size, pkey);
+ 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);
}
- DBUG_RETURN(error);
- }
- if ((error = storage_write_row_unique_indexes(buf)))
- {
- goto err;
+ record_id = grn_table_add(ctx, grn_table, pkey, pkey_size, &added);
+ if (ctx->rc) {
+ my_message(ER_ERROR_ON_WRITE, ctx->errbuf, MYF(0));
+ DBUG_RETURN(ER_ERROR_ON_WRITE);
+ }
+ if (!added) {
+ // duplicated error
+ error = HA_ERR_FOUND_DUPP_KEY;
+ memcpy(dup_ref, &record_id, sizeof(grn_id));
+ dup_key = pkey_nr;
+ if (!ignoring_duplicated_key) {
+ GRN_LOG(ctx, GRN_LOG_ERROR,
+ "duplicated id on insert: update primary key: <%.*s>",
+ pkey_size, pkey);
+ }
+ 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]);
+ }
+ }
+ DBUG_RETURN(error);
+ }
}
- unique_indexes_are_processed = true;
grn_obj colbuf;
GRN_VOID_INIT(&colbuf);
@@ -5673,16 +5610,16 @@ int ha_mroonga::storage_write_row_multiple_column_index(uchar *buf,
key_info,
key_info->key_length);
GRN_BULK_REWIND(&encoded_key_buffer);
- grn_bulk_space(ctx, &encoded_key_buffer, key_info->key_length);
+ grn_bulk_reserve(ctx, &encoded_key_buffer, MRN_MAX_KEY_SIZE);
uint encoded_key_length;
storage_encode_multiple_column_key(key_info,
(uchar *)(GRN_TEXT_VALUE(&key_buffer)),
key_info->key_length,
(uchar *)(GRN_TEXT_VALUE(&encoded_key_buffer)),
&encoded_key_length);
+ grn_bulk_space(ctx, &encoded_key_buffer, encoded_key_length);
DBUG_PRINT("info", ("mroonga: key_length=%u", key_info->key_length));
DBUG_PRINT("info", ("mroonga: encoded_key_length=%u", encoded_key_length));
- DBUG_ASSERT(key_info->key_length >= encoded_key_length);
grn_rc rc;
rc = grn_column_index_update(ctx, index_column, record_id, 1, NULL,
@@ -5709,9 +5646,9 @@ int ha_mroonga::storage_write_row_multiple_column_indexes(uchar *buf,
continue;
}
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
- if (KEY_N_KEY_PARTS(&key_info) == 1 || (key_info.flags & HA_FULLTEXT)) {
+ if (KEY_N_KEY_PARTS(key_info) == 1 || (key_info->flags & HA_FULLTEXT)) {
continue;
}
@@ -5722,7 +5659,7 @@ int ha_mroonga::storage_write_row_multiple_column_indexes(uchar *buf,
if ((error = storage_write_row_multiple_column_index(buf,
record_id,
- &key_info,
+ key_info,
index_column)))
{
goto err;
@@ -5757,7 +5694,7 @@ int ha_mroonga::storage_write_row_unique_index(uchar *buf,
mrn_change_encoding(ctx, NULL);
uchar key[MRN_MAX_KEY_SIZE];
key_copy(key, buf, key_info, key_info->key_length);
- grn_bulk_space(ctx, &key_buffer, key_info->key_length);
+ grn_bulk_reserve(ctx, &key_buffer, MRN_MAX_KEY_SIZE);
ukey = GRN_TEXT_VALUE(&key_buffer);
storage_encode_multiple_column_key(key_info,
key, key_info->key_length,
@@ -5949,11 +5886,11 @@ int ha_mroonga::wrapper_update_row_index(const uchar *old_data, uchar *new_data)
}
mrn_change_encoding(ctx, NULL);
- KEY key_info = table->key_info[table_share->primary_key];
+ KEY *key_info = &(table->key_info[table_share->primary_key]);
GRN_BULK_REWIND(&key_buffer);
key_copy((uchar *)(GRN_TEXT_VALUE(&key_buffer)),
new_data,
- &key_info, key_info.key_length);
+ key_info, key_info->key_length);
int added;
grn_id new_record_id;
new_record_id = grn_table_add(ctx, grn_table,
@@ -5972,15 +5909,15 @@ int ha_mroonga::wrapper_update_row_index(const uchar *old_data, uchar *new_data)
grn_id old_record_id;
my_ptrdiff_t ptr_diff = PTR_BYTE_DIFF(old_data, table->record[0]);
- for (uint j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
- Field *field = key_info.key_part[j].field;
+ for (uint j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
+ Field *field = key_info->key_part[j].field;
field->move_field_offset(ptr_diff);
}
error = wrapper_get_record_id((uchar *)old_data, &old_record_id,
"failed to get old record ID "
"for updating from groonga");
- for (uint j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
- Field *field = key_info.key_part[j].field;
+ for (uint j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
+ Field *field = key_info->key_part[j].field;
field->move_field_offset(-ptr_diff);
}
if (error) {
@@ -5991,9 +5928,9 @@ int ha_mroonga::wrapper_update_row_index(const uchar *old_data, uchar *new_data)
uint i;
uint n_keys = table->s->keys;
for (i = 0; i < n_keys; i++) {
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
- if (!(wrapper_is_target_index(&key_info))) {
+ if (!(wrapper_is_target_index(key_info))) {
continue;
}
@@ -6004,8 +5941,8 @@ int ha_mroonga::wrapper_update_row_index(const uchar *old_data, uchar *new_data)
}
uint j;
- for (j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
- Field *field = key_info.key_part[j].field;
+ for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
+ Field *field = key_info->key_part[j].field;
generic_store_bulk(field, &new_value_buffer);
@@ -6086,6 +6023,7 @@ int ha_mroonga::storage_update_row(const uchar *old_data, uchar *new_data)
KEY *pkey_info = NULL;
storage_store_fields_for_prep_update(old_data, new_data, record_id);
{
+ mrn::Lock lock(&(share->record_mutex), have_unique_index());
mrn::DebugColumnAccess debug_column_access(table, table->read_set);
if ((error = storage_prepare_delete_row_unique_indexes(old_data,
record_id))) {
@@ -6233,9 +6171,9 @@ int ha_mroonga::storage_update_row_index(const uchar *old_data, uchar *new_data)
continue;
}
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
- if (KEY_N_KEY_PARTS(&key_info) == 1 || (key_info.flags & HA_FULLTEXT)) {
+ if (KEY_N_KEY_PARTS(key_info) == 1 || (key_info->flags & HA_FULLTEXT)) {
continue;
}
@@ -6246,42 +6184,44 @@ int ha_mroonga::storage_update_row_index(const uchar *old_data, uchar *new_data)
}
GRN_BULK_REWIND(&old_key);
- grn_bulk_space(ctx, &old_key, key_info.key_length);
- for (uint j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
- Field *field = key_info.key_part[j].field;
+ grn_bulk_space(ctx, &old_key, key_info->key_length);
+ for (uint j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
+ Field *field = key_info->key_part[j].field;
field->move_field_offset(ptr_diff);
}
key_copy((uchar *)(GRN_TEXT_VALUE(&old_key)),
(uchar *)old_data,
- &key_info,
- key_info.key_length);
- for (uint j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
- Field *field = key_info.key_part[j].field;
+ key_info,
+ key_info->key_length);
+ for (uint j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
+ Field *field = key_info->key_part[j].field;
field->move_field_offset(-ptr_diff);
}
GRN_BULK_REWIND(&old_encoded_key);
- grn_bulk_space(ctx, &old_encoded_key, key_info.key_length);
+ grn_bulk_reserve(ctx, &old_encoded_key, MRN_MAX_KEY_SIZE);
uint old_encoded_key_length;
- storage_encode_multiple_column_key(&key_info,
+ storage_encode_multiple_column_key(key_info,
(uchar *)(GRN_TEXT_VALUE(&old_key)),
- key_info.key_length,
+ key_info->key_length,
(uchar *)(GRN_TEXT_VALUE(&old_encoded_key)),
&old_encoded_key_length);
+ grn_bulk_space(ctx, &old_encoded_key, old_encoded_key_length);
GRN_BULK_REWIND(&new_key);
- grn_bulk_space(ctx, &new_key, key_info.key_length);
+ grn_bulk_space(ctx, &new_key, key_info->key_length);
key_copy((uchar *)(GRN_TEXT_VALUE(&new_key)),
(uchar *)new_data,
- &key_info,
- key_info.key_length);
+ key_info,
+ key_info->key_length);
GRN_BULK_REWIND(&new_encoded_key);
- grn_bulk_space(ctx, &new_encoded_key, key_info.key_length);
+ grn_bulk_reserve(ctx, &new_encoded_key, MRN_MAX_KEY_SIZE);
uint new_encoded_key_length;
- storage_encode_multiple_column_key(&key_info,
+ storage_encode_multiple_column_key(key_info,
(uchar *)(GRN_TEXT_VALUE(&new_key)),
- key_info.key_length,
+ key_info->key_length,
(uchar *)(GRN_TEXT_VALUE(&new_encoded_key)),
&new_encoded_key_length);
+ grn_bulk_space(ctx, &new_encoded_key, new_encoded_key_length);
grn_rc rc;
rc = grn_column_index_update(ctx, index_column, record_id, 1,
@@ -6436,9 +6376,9 @@ int ha_mroonga::wrapper_delete_row_index(const uchar *buf)
uint i;
uint n_keys = table->s->keys;
for (i = 0; i < n_keys; i++) {
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
- if (!(wrapper_is_target_index(&key_info))) {
+ if (!(wrapper_is_target_index(key_info))) {
continue;
}
@@ -6449,8 +6389,8 @@ int ha_mroonga::wrapper_delete_row_index(const uchar *buf)
}
uint j;
- for (j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
- Field *field = key_info.key_part[j].field;
+ for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
+ Field *field = key_info->key_part[j].field;
if (field->is_null())
continue;
@@ -6487,20 +6427,23 @@ int ha_mroonga::storage_delete_row(const uchar *buf)
}
storage_store_fields_for_prep_update(buf, NULL, record_id);
- if ((error = storage_prepare_delete_row_unique_indexes(buf, record_id))) {
- DBUG_RETURN(error);
- }
- mrn_change_encoding(ctx, NULL);
- grn_table_delete_by_id(ctx, grn_table, record_id);
- if (ctx->rc) {
- my_message(ER_ERROR_ON_WRITE, ctx->errbuf, MYF(0));
- DBUG_RETURN(ER_ERROR_ON_WRITE);
- }
- if (
- (error = storage_delete_row_index(buf)) ||
- (error = storage_delete_row_unique_indexes())
- ) {
- DBUG_RETURN(error);
+ {
+ mrn::Lock lock(&(share->record_mutex), have_unique_index());
+ if ((error = storage_prepare_delete_row_unique_indexes(buf, record_id))) {
+ DBUG_RETURN(error);
+ }
+ mrn_change_encoding(ctx, NULL);
+ grn_table_delete_by_id(ctx, grn_table, record_id);
+ if (ctx->rc) {
+ my_message(ER_ERROR_ON_WRITE, ctx->errbuf, MYF(0));
+ DBUG_RETURN(ER_ERROR_ON_WRITE);
+ }
+ if (
+ (error = storage_delete_row_index(buf)) ||
+ (error = storage_delete_row_unique_indexes())
+ ) {
+ DBUG_RETURN(error);
+ }
}
grn_db_touch(ctx, grn_ctx_db(ctx));
@@ -6526,9 +6469,9 @@ int ha_mroonga::storage_delete_row_index(const uchar *buf)
continue;
}
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
- if (KEY_N_KEY_PARTS(&key_info) == 1 || (key_info.flags & HA_FULLTEXT)) {
+ if (KEY_N_KEY_PARTS(key_info) == 1 || (key_info->flags & HA_FULLTEXT)) {
continue;
}
@@ -6539,19 +6482,20 @@ int ha_mroonga::storage_delete_row_index(const uchar *buf)
}
GRN_BULK_REWIND(&key);
- grn_bulk_space(ctx, &key, key_info.key_length);
+ grn_bulk_space(ctx, &key, key_info->key_length);
key_copy((uchar *)(GRN_TEXT_VALUE(&key)),
(uchar *)buf,
- &key_info,
- key_info.key_length);
+ key_info,
+ key_info->key_length);
GRN_BULK_REWIND(&encoded_key);
- grn_bulk_space(ctx, &encoded_key, key_info.key_length);
+ grn_bulk_reserve(ctx, &encoded_key, MRN_MAX_KEY_SIZE);
uint encoded_key_length;
- storage_encode_multiple_column_key(&key_info,
+ storage_encode_multiple_column_key(key_info,
(uchar *)(GRN_TEXT_VALUE(&key)),
- key_info.key_length,
+ key_info->key_length,
(uchar *)(GRN_TEXT_VALUE(&encoded_key)),
&encoded_key_length);
+ grn_bulk_space(ctx, &encoded_key, encoded_key_length);
grn_rc rc;
rc = grn_column_index_update(ctx, index_column, record_id, 1,
@@ -6627,7 +6571,7 @@ int ha_mroonga::storage_prepare_delete_row_unique_index(const uchar *buf,
mrn_change_encoding(ctx, NULL);
uchar key[MRN_MAX_KEY_SIZE];
key_copy(key, (uchar *) buf, key_info, key_info->key_length);
- grn_bulk_space(ctx, &key_buffer, key_info->key_length);
+ grn_bulk_reserve(ctx, &key_buffer, MRN_MAX_KEY_SIZE);
ukey = GRN_TEXT_VALUE(&key_buffer);
storage_encode_multiple_column_key(key_info,
key, key_info->key_length,
@@ -6737,8 +6681,8 @@ ha_rows ha_mroonga::wrapper_records_in_range(uint key_nr, key_range *range_min,
{
ha_rows row_count;
MRN_DBUG_ENTER_METHOD();
- KEY key_info = table->s->key_info[key_nr];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->s->key_info[key_nr]);
+ if (mrn_is_geo_key(key_info)) {
row_count = generic_records_in_range_geo(key_nr, range_min, range_max);
} else {
MRN_SET_WRAP_SHARE_KEY(share, table->s);
@@ -6760,8 +6704,8 @@ ha_rows ha_mroonga::storage_records_in_range(uint key_nr, key_range *range_min,
uchar *key_min = NULL, *key_max = NULL;
uchar key_min_entity[MRN_MAX_KEY_SIZE];
uchar key_max_entity[MRN_MAX_KEY_SIZE];
- KEY key_info = table->s->key_info[key_nr];
- bool is_multiple_column_index = KEY_N_KEY_PARTS(&key_info) > 1;
+ KEY *key_info = &(table->s->key_info[key_nr]);
+ bool is_multiple_column_index = KEY_N_KEY_PARTS(key_info) > 1;
if (is_multiple_column_index) {
mrn_change_encoding(ctx, NULL);
@@ -6770,24 +6714,23 @@ ha_rows ha_mroonga::storage_records_in_range(uint key_nr, key_range *range_min,
memcmp(range_min->key, range_max->key, range_min->length) == 0) {
flags |= GRN_CURSOR_PREFIX;
key_min = key_min_entity;
- storage_encode_multiple_column_key(&key_info,
+ storage_encode_multiple_column_key(key_info,
range_min->key, range_min->length,
key_min, &size_min);
} else {
key_min = key_min_entity;
key_max = key_max_entity;
- storage_encode_multiple_column_key_range(&key_info,
+ storage_encode_multiple_column_key_range(key_info,
range_min, range_max,
key_min, &size_min,
key_max, &size_max);
}
- } else if (mrn_is_geo_key(&key_info)) {
- mrn_change_encoding(ctx, key_info.key_part->field->charset());
+ } else if (mrn_is_geo_key(key_info)) {
+ mrn_change_encoding(ctx, key_info->key_part->field->charset());
row_count = generic_records_in_range_geo(key_nr, range_min, range_max);
DBUG_RETURN(row_count);
} else {
- KEY_PART_INFO key_part = key_info.key_part[0];
- Field *field = key_part.field;
+ Field *field = key_info->key_part[0].field;
const char *column_name = field->field_name;
mrn_change_encoding(ctx, field->charset());
@@ -6909,12 +6852,12 @@ ha_rows ha_mroonga::records_in_range(uint key_nr, key_range *range_min, key_rang
int ha_mroonga::wrapper_index_init(uint idx, bool sorted)
{
- int error = 0;
- KEY key_info = table->s->key_info[idx];
MRN_DBUG_ENTER_METHOD();
+ int error = 0;
+ KEY *key_info = &(table->s->key_info[idx]);
MRN_SET_WRAP_SHARE_KEY(share, table->s);
MRN_SET_WRAP_TABLE_KEY(this, table);
- if (!mrn_is_geo_key(&key_info) && key_info.algorithm != HA_KEY_ALG_FULLTEXT)
+ if (!mrn_is_geo_key(key_info) && key_info->algorithm != HA_KEY_ALG_FULLTEXT)
{
error = wrap_handler->ha_index_init(share->wrap_key_nr[idx], sorted);
} else {
@@ -6985,8 +6928,8 @@ int ha_mroonga::wrapper_index_read_map(uchar *buf, const uchar *key,
{
int error = 0;
MRN_DBUG_ENTER_METHOD();
- KEY key_info = table->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
clear_cursor_geo();
error = generic_geo_open_cursor(key, find_flag);
if (!error) {
@@ -7019,7 +6962,7 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
int error = 0;
uint key_nr = active_index;
- KEY key_info = table->key_info[key_nr];
+ KEY *key_info = &(table->key_info[key_nr]);
int flags = 0;
uint size_min = 0, size_max = 0;
uchar *key_min = NULL, *key_max = NULL;
@@ -7030,7 +6973,7 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
clear_cursor_geo();
clear_empty_value_records();
- bool is_multiple_column_index = KEY_N_KEY_PARTS(&key_info) > 1;
+ 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 =
@@ -7039,17 +6982,17 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
("mroonga: multiple column index: "
"search key length=<%u>, "
"multiple column index key length=<%u>",
- key_length, key_info.key_length));
- if (key_length == key_info.key_length) {
+ key_length, key_info->key_length));
+ if (key_length == key_info->key_length) {
if (find_flag == HA_READ_BEFORE_KEY ||
find_flag == HA_READ_PREFIX_LAST_OR_PREV) {
key_max = key_max_entity;
- storage_encode_multiple_column_key(&key_info,
+ storage_encode_multiple_column_key(key_info,
key, key_length,
key_max, &size_max);
} else {
key_min = key_min_entity;
- storage_encode_multiple_column_key(&key_info,
+ storage_encode_multiple_column_key(key_info,
key, key_length,
key_min, &size_min);
if (find_flag == HA_READ_KEY_EXACT) {
@@ -7060,12 +7003,12 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
} else {
flags |= GRN_CURSOR_PREFIX;
key_min = key_min_entity;
- storage_encode_multiple_column_key(&key_info,
+ storage_encode_multiple_column_key(key_info,
key, key_length,
key_min, &size_min);
}
- } else if (mrn_is_geo_key(&key_info)) {
- error = mrn_change_encoding(ctx, key_info.key_part->field->charset());
+ } else if (mrn_is_geo_key(key_info)) {
+ error = mrn_change_encoding(ctx, key_info->key_part->field->charset());
if (error)
DBUG_RETURN(error);
error = generic_geo_open_cursor(key, find_flag);
@@ -7074,8 +7017,7 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
}
DBUG_RETURN(error);
} else {
- KEY_PART_INFO key_part = key_info.key_part[0];
- Field *field = key_part.field;
+ Field *field = key_info->key_part[0].field;
error = mrn_change_encoding(ctx, field->charset());
if (error)
DBUG_RETURN(error);
@@ -7150,7 +7092,7 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
GRN_EXPR_CREATE_FOR_QUERY(ctx, grn_table,
expression, expression_variable);
grn_obj *target_column =
- grn_columns[key_info.key_part->field->field_index];
+ grn_columns[key_info->key_part->field->field_index];
grn_expr_append_const(ctx, expression, target_column, GRN_OP_GET_VALUE, 1);
grn_obj empty_value;
GRN_TEXT_INIT(&empty_value, 0);
@@ -7229,7 +7171,7 @@ int ha_mroonga::storage_index_read_last_map(uchar *buf, const uchar *key,
{
MRN_DBUG_ENTER_METHOD();
uint key_nr = active_index;
- KEY key_info = table->key_info[key_nr];
+ KEY *key_info = &(table->key_info[key_nr]);
int flags = GRN_CURSOR_DESCENDING, error;
uint size_min = 0, size_max = 0;
@@ -7238,19 +7180,18 @@ int ha_mroonga::storage_index_read_last_map(uchar *buf, const uchar *key,
clear_cursor();
- bool is_multiple_column_index = KEY_N_KEY_PARTS(&key_info) > 1;
+ bool is_multiple_column_index = KEY_N_KEY_PARTS(key_info) > 1;
if (is_multiple_column_index) {
mrn_change_encoding(ctx, NULL);
flags |= GRN_CURSOR_PREFIX;
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,
+ storage_encode_multiple_column_key(key_info,
key, key_length,
key_min, &size_min);
} else {
- KEY_PART_INFO key_part = key_info.key_part[0];
- Field *field = key_part.field;
+ Field *field = key_info->key_part[0].field;
error = mrn_change_encoding(ctx, field->charset());
if (error)
DBUG_RETURN(error);
@@ -7308,8 +7249,8 @@ int ha_mroonga::wrapper_index_next(uchar *buf)
{
int error = 0;
MRN_DBUG_ENTER_METHOD();
- KEY key_info = table->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
error = wrapper_get_next_geo_record(buf);
} else {
MRN_SET_WRAP_SHARE_KEY(share, table->s);
@@ -7351,8 +7292,8 @@ int ha_mroonga::wrapper_index_prev(uchar *buf)
{
int error = 0;
MRN_DBUG_ENTER_METHOD();
- KEY key_info = table->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
error = wrapper_get_next_geo_record(buf);
} else {
MRN_SET_WRAP_SHARE_KEY(share, table->s);
@@ -7525,8 +7466,8 @@ int ha_mroonga::wrapper_index_next_same(uchar *buf, const uchar *key,
{
MRN_DBUG_ENTER_METHOD();
int error = 0;
- KEY key_info = table->s->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->s->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
error = wrapper_get_next_geo_record(buf);
} else {
MRN_SET_WRAP_SHARE_KEY(share, table->s);
@@ -7571,8 +7512,8 @@ int ha_mroonga::wrapper_read_range_first(const key_range *start_key,
{
int error = 0;
MRN_DBUG_ENTER_METHOD();
- KEY key_info = table->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
clear_cursor_geo();
error = generic_geo_open_cursor(start_key->key, start_key->flag);
if (!error) {
@@ -7603,11 +7544,11 @@ int ha_mroonga::storage_read_range_first(const key_range *start_key,
uchar *key_min = NULL, *key_max = NULL;
uchar key_min_entity[MRN_MAX_KEY_SIZE];
uchar key_max_entity[MRN_MAX_KEY_SIZE];
- KEY key_info = table->s->key_info[active_index];
+ KEY *key_info = &(table->s->key_info[active_index]);
clear_cursor();
- bool is_multiple_column_index = KEY_N_KEY_PARTS(&key_info) > 1;
+ bool is_multiple_column_index = KEY_N_KEY_PARTS(key_info) > 1;
if (is_multiple_column_index) {
mrn_change_encoding(ctx, NULL);
if (start_key && end_key &&
@@ -7615,13 +7556,13 @@ int ha_mroonga::storage_read_range_first(const key_range *start_key,
memcmp(start_key->key, end_key->key, start_key->length) == 0) {
flags |= GRN_CURSOR_PREFIX;
key_min = key_min_entity;
- storage_encode_multiple_column_key(&key_info,
+ storage_encode_multiple_column_key(key_info,
start_key->key, start_key->length,
key_min, &size_min);
} else {
key_min = key_min_entity;
key_max = key_max_entity;
- storage_encode_multiple_column_key_range(&key_info,
+ storage_encode_multiple_column_key_range(key_info,
start_key, end_key,
key_min, &size_min,
key_max, &size_max);
@@ -7633,8 +7574,7 @@ int ha_mroonga::storage_read_range_first(const key_range *start_key,
}
}
} else {
- KEY_PART_INFO key_part = key_info.key_part[0];
- Field *field = key_part.field;
+ Field *field = key_info->key_part[0].field;
const char *column_name = field->field_name;
error = mrn_change_encoding(ctx, field->charset());
if (error)
@@ -7742,8 +7682,8 @@ int ha_mroonga::wrapper_read_range_next()
{
int error = 0;
MRN_DBUG_ENTER_METHOD();
- KEY key_info = table->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
error = wrapper_get_next_geo_record(table->record[0]);
DBUG_RETURN(error);
}
@@ -8082,7 +8022,7 @@ grn_rc ha_mroonga::generic_ft_init_ext_prepare_expression_in_boolean_mode(
bool parsed = false;
bool done = false;
keyword++;
- keyword_length++;
+ keyword_length--;
while (!done) {
uint consumed_keyword_length = 0;
switch (keyword[0]) {
@@ -8283,12 +8223,11 @@ FT_INFO *ha_mroonga::generic_ft_init_ext(uint flags, uint key_nr, String *key)
check_count_skip(0, 0, true);
mrn_change_encoding(ctx, system_charset_info);
- grn_operator operation = GRN_OP_AND;
+ grn_operator operation = GRN_OP_OR;
if (!matched_record_keys) {
matched_record_keys = grn_table_create(ctx, NULL, 0, NULL,
GRN_OBJ_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC,
grn_table, 0);
- operation = GRN_OP_OR;
}
grn_table_sort_key *sort_keys = NULL;
@@ -8317,6 +8256,24 @@ FT_INFO *ha_mroonga::generic_ft_init_ext(uint flags, uint key_nr, String *key)
matched_record_keys);
grn_table_sort(ctx, matched_record_keys, 0, static_cast<int>(limit),
sorted_result, sort_keys, n_sort_keys);
+ } else if (flags & FT_SORTED) {
+ grn_table_sort_key score_sort_key;
+ score_sort_key.key = grn_obj_column(ctx,
+ matched_record_keys,
+ MRN_COLUMN_NAME_SCORE,
+ strlen(MRN_COLUMN_NAME_SCORE));
+ score_sort_key.offset = 0;
+ score_sort_key.flags = GRN_TABLE_SORT_DESC;
+ if (sorted_result) {
+ grn_obj_unlink(ctx, sorted_result);
+ }
+ sorted_result = grn_table_create(ctx, NULL,
+ 0, NULL,
+ GRN_OBJ_TABLE_NO_KEY, NULL,
+ matched_record_keys);
+ grn_table_sort(ctx, matched_record_keys, 0, -1,
+ sorted_result, &score_sort_key, 1);
+ grn_obj_unlink(ctx, score_sort_key.key);
}
if (sort_keys) {
for (int i = 0; i < n_sort_keys; i++) {
@@ -8586,6 +8543,26 @@ ulonglong ha_mroonga::file_size(const char *path)
}
}
+bool ha_mroonga::have_unique_index()
+{
+ MRN_DBUG_ENTER_METHOD();
+
+ uint n_keys = table->s->keys;
+
+ for (uint i = 0; i < n_keys; i++) {
+ if (i == table->s->primary_key) {
+ continue;
+ }
+
+ KEY *key_info = &(table->key_info[i]);
+ if (key_info->flags & HA_NOSAME) {
+ DBUG_RETURN(true);
+ }
+ }
+
+ DBUG_RETURN(false);
+}
+
void ha_mroonga::push_warning_unsupported_spatial_index_search(enum ha_rkey_function flag)
{
char search_name[MRN_BUFFER_SIZE];
@@ -8712,27 +8689,27 @@ void ha_mroonga::clear_indexes()
DBUG_VOID_RETURN;
}
-int ha_mroonga::alter_share_add(const char *path, TABLE_SHARE *table_share)
+int ha_mroonga::add_wrap_hton(const char *path, handlerton *wrap_handlerton)
{
MRN_DBUG_ENTER_METHOD();
st_mrn_slot_data *slot_data = mrn_get_slot_data(ha_thd(), true);
if (!slot_data)
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- st_mrn_alter_share *alter_share =
- (st_mrn_alter_share *)malloc(sizeof(st_mrn_alter_share));
- if (!alter_share)
+ st_mrn_wrap_hton *wrap_hton =
+ (st_mrn_wrap_hton *)malloc(sizeof(st_mrn_wrap_hton));
+ if (!wrap_hton)
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- alter_share->next = NULL;
- strcpy(alter_share->path, path);
- alter_share->alter_share = table_share;
- if (slot_data->first_alter_share)
+ wrap_hton->next = NULL;
+ strcpy(wrap_hton->path, path);
+ wrap_hton->hton = wrap_handlerton;
+ if (slot_data->first_wrap_hton)
{
- st_mrn_alter_share *tmp_alter_share = slot_data->first_alter_share;
- while (tmp_alter_share->next)
- tmp_alter_share = tmp_alter_share->next;
- tmp_alter_share->next = alter_share;
+ st_mrn_wrap_hton *tmp_wrap_hton = slot_data->first_wrap_hton;
+ while (tmp_wrap_hton->next)
+ tmp_wrap_hton = tmp_wrap_hton->next;
+ tmp_wrap_hton->next = wrap_hton;
} else {
- slot_data->first_alter_share = alter_share;
+ slot_data->first_wrap_hton = wrap_hton;
}
DBUG_RETURN(0);
}
@@ -8848,6 +8825,320 @@ int ha_mroonga::drop_index(MRN_SHARE *target_share, uint key_index)
DBUG_RETURN(error);
}
+int ha_mroonga::drop_indexes_normal(const char *table_name, grn_obj *table)
+{
+ MRN_DBUG_ENTER_METHOD();
+
+ int error = 0;
+
+ grn_hash *columns_raw = grn_hash_create(ctx, NULL, sizeof(grn_id), 0,
+ GRN_OBJ_TABLE_HASH_KEY);
+ mrn::SmartGrnObj columns(ctx, reinterpret_cast<grn_obj *>(columns_raw));
+ if (!columns.get()) {
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "failed to allocate columns buffer: <%s>: <%s>",
+ table_name, ctx->errbuf);
+ error = HA_ERR_OUT_OF_MEM;
+ my_message(ER_ERROR_ON_WRITE, error_message, MYF(0));
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message);
+ DBUG_RETURN(error);
+ }
+
+ grn_table_columns(ctx, table, "", 0, columns.get());
+ grn_table_cursor *cursor = grn_table_cursor_open(ctx,
+ columns.get(),
+ NULL, 0,
+ NULL, 0,
+ 0, -1,
+ 0);
+ if (!cursor) {
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "failed to allocate columns cursor: <%s>: <%s>",
+ table_name, ctx->errbuf);
+ error = HA_ERR_OUT_OF_MEM;
+ my_message(ER_ERROR_ON_WRITE, error_message, MYF(0));
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message);
+ DBUG_RETURN(error);
+ }
+
+ while (grn_table_cursor_next(ctx, cursor) != GRN_ID_NIL) {
+ void *key;
+ grn_table_cursor_get_key(ctx, cursor, &key);
+ grn_id *id = reinterpret_cast<grn_id *>(key);
+ mrn::SmartGrnObj column(ctx, grn_ctx_at(ctx, *id));
+ if (!column.get()) {
+ continue;
+ }
+
+ grn_operator index_operators[] = {
+ GRN_OP_EQUAL,
+ GRN_OP_MATCH,
+ GRN_OP_LESS,
+ GRN_OP_REGEXP
+ };
+ size_t n_index_operators = sizeof(index_operators) / sizeof(grn_operator);
+ for (size_t i = 0; i < n_index_operators; i++) {
+ grn_index_datum index_datum;
+ while (grn_column_find_index_data(ctx,
+ column.get(),
+ index_operators[i],
+ &index_datum,
+ 1) > 0) {
+ grn_id index_table_id = index_datum.index->header.domain;
+ mrn::SmartGrnObj index_table(ctx, grn_ctx_at(ctx, index_table_id));
+ char index_table_name[GRN_TABLE_MAX_KEY_SIZE];
+ int index_table_name_length;
+ index_table_name_length = grn_obj_name(ctx, index_table.get(),
+ index_table_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ if (mrn::IndexTableName::is_custom_name(table_name,
+ strlen(table_name),
+ index_table_name,
+ index_table_name_length)) {
+ char index_column_name[GRN_TABLE_MAX_KEY_SIZE];
+ int index_column_name_length;
+ index_column_name_length = grn_obj_name(ctx,
+ index_datum.index,
+ index_column_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+ grn_rc rc = grn_obj_remove(ctx, index_datum.index);
+ if (rc != GRN_SUCCESS) {
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "failed to drop index column: <%.*s>: <%s>",
+ index_column_name_length, index_column_name,
+ ctx->errbuf);
+ error = ER_ERROR_ON_WRITE;
+ my_message(error, error_message, MYF(0));
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message);
+ }
+ } else {
+ grn_rc rc = grn_obj_remove(ctx, index_table.get());
+ if (rc == GRN_SUCCESS) {
+ index_table.release();
+ } else {
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "failed to drop index table: <%.*s>: <%s>",
+ index_table_name_length, index_table_name,
+ ctx->errbuf);
+ error = ER_ERROR_ON_WRITE;
+ my_message(error, error_message, MYF(0));
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message);
+ }
+ }
+
+ if (error != 0) {
+ break;
+ }
+ }
+
+ if (error != 0) {
+ break;
+ }
+ }
+
+ if (error != 0) {
+ break;
+ }
+ }
+
+ grn_table_cursor_close(ctx, cursor);
+
+ DBUG_RETURN(error);
+}
+
+int ha_mroonga::drop_indexes_multiple(const char *table_name, grn_obj *table)
+{
+ MRN_DBUG_ENTER_METHOD();
+
+ int error = 0;
+
+ char index_table_name_prefix[GRN_TABLE_MAX_KEY_SIZE];
+ snprintf(index_table_name_prefix, GRN_TABLE_MAX_KEY_SIZE,
+ "%s%s", table_name, mrn::IndexTableName::SEPARATOR);
+ grn_table_cursor *cursor =
+ grn_table_cursor_open(ctx,
+ grn_ctx_db(ctx),
+ index_table_name_prefix,
+ strlen(index_table_name_prefix),
+ NULL, 0,
+ 0, -1,
+ GRN_CURSOR_PREFIX);
+ if (!cursor) {
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "failed to allocate index tables cursor: <%s>: <%s>",
+ table_name, ctx->errbuf);
+ error = HA_ERR_OUT_OF_MEM;
+ my_message(ER_ERROR_ON_WRITE, error_message, MYF(0));
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message);
+ DBUG_RETURN(error);
+ }
+
+ grn_id table_id = grn_obj_id(ctx, table);
+ grn_id id;
+ while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) {
+ mrn::SmartGrnObj object(ctx, grn_ctx_at(ctx, id));
+ if (!object.get()) {
+ continue;
+ }
+ if (!grn_obj_is_table(ctx, object.get())) {
+ continue;
+ }
+
+ char multiple_column_index_table_name[GRN_TABLE_MAX_KEY_SIZE];
+ int multiple_column_index_table_name_length;
+ multiple_column_index_table_name_length =
+ grn_obj_name(ctx,
+ object.get(),
+ multiple_column_index_table_name,
+ GRN_TABLE_MAX_KEY_SIZE);
+
+ char multiple_column_index_name[GRN_TABLE_MAX_KEY_SIZE];
+ snprintf(multiple_column_index_name, GRN_TABLE_MAX_KEY_SIZE,
+ "%.*s.%s",
+ multiple_column_index_table_name_length,
+ multiple_column_index_table_name,
+ INDEX_COLUMN_NAME);
+ mrn::SmartGrnObj index_column(ctx, multiple_column_index_name);
+ if (!index_column.get()) {
+ continue;
+ }
+
+ if (grn_obj_get_range(ctx, index_column.get()) != table_id) {
+ continue;
+ }
+
+ grn_rc rc = grn_obj_remove(ctx, object.get());
+ if (rc == GRN_SUCCESS) {
+ object.release();
+ index_column.release();
+ } else {
+ char error_message[MRN_MESSAGE_BUFFER_SIZE];
+ snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
+ "failed to drop multiple column index table: <%.*s>: <%s>",
+ multiple_column_index_table_name_length,
+ multiple_column_index_table_name,
+ ctx->errbuf);
+ error = ER_ERROR_ON_WRITE;
+ my_message(error, error_message, MYF(0));
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message);
+ break;
+ }
+ }
+
+ grn_table_cursor_close(ctx, cursor);
+
+ DBUG_RETURN(error);
+}
+
+int ha_mroonga::drop_indexes(const char *table_name)
+{
+ MRN_DBUG_ENTER_METHOD();
+ int error = 0;
+
+ mrn::SmartGrnObj table(ctx, table_name);
+ if (!table.get()) {
+ DBUG_RETURN(0);
+ }
+
+ error = drop_indexes_normal(table_name, table.get());
+ if (error == 0) {
+ error = drop_indexes_multiple(table_name, table.get());
+ }
+
+ DBUG_RETURN(error);
+}
+
+bool ha_mroonga::find_column_flags(Field *field, MRN_SHARE *mrn_share, int i,
+ grn_obj_flags *column_flags)
+{
+ MRN_DBUG_ENTER_METHOD();
+ bool found = false;
+
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ {
+ const char *names = field->option_struct->flags;
+ if (names) {
+ found = mrn_parse_grn_column_create_flags(ha_thd(),
+ ctx,
+ names,
+ strlen(names),
+ column_flags);
+ DBUG_RETURN(found);
+ }
+ }
+#endif
+
+ if (mrn_share->col_flags[i]) {
+ found = mrn_parse_grn_column_create_flags(ha_thd(),
+ ctx,
+ mrn_share->col_flags[i],
+ mrn_share->col_flags_length[i],
+ column_flags);
+ DBUG_RETURN(found);
+ }
+
+ DBUG_RETURN(found);
+}
+
+grn_obj *ha_mroonga::find_column_type(Field *field, MRN_SHARE *mrn_share, int i,
+ int error_code)
+{
+ MRN_DBUG_ENTER_METHOD();
+
+ const char *grn_type_name = NULL;
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ grn_type_name = field->option_struct->groonga_type;
+#endif
+ if (!grn_type_name) {
+ grn_type_name = mrn_share->col_type[i];
+ }
+
+ grn_obj *type = NULL;
+ if (grn_type_name) {
+ type = grn_ctx_get(ctx, grn_type_name, -1);
+ if (!type) {
+ char error_message[MRN_BUFFER_SIZE];
+ snprintf(error_message, MRN_BUFFER_SIZE,
+ "unknown custom Groonga type name for <%s> column: <%s>",
+ field->field_name, grn_type_name);
+ GRN_LOG(ctx, GRN_LOG_ERROR, "%s", error_message);
+ my_message(error_code, error_message, MYF(0));
+
+ DBUG_RETURN(NULL);
+ }
+ } else {
+ grn_builtin_type grn_type_id = mrn_grn_type_from_field(ctx, field, false);
+ type = grn_ctx_at(ctx, grn_type_id);
+ }
+
+ DBUG_RETURN(type);
+}
+
+grn_obj *ha_mroonga::find_tokenizer(KEY *key, MRN_SHARE *mrn_share, int i)
+{
+ MRN_DBUG_ENTER_METHOD();
+ grn_obj *tokenizer;
+ const char *tokenizer_name = NULL;
+ uint tokenizer_name_length = 0;
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ if (key->option_struct->tokenizer) {
+ tokenizer_name = key->option_struct->tokenizer;
+ tokenizer_name_length = strlen(tokenizer_name);
+ }
+#endif
+ if (!tokenizer_name) {
+ tokenizer_name = mrn_share->key_tokenizer[i];
+ tokenizer_name_length = mrn_share->key_tokenizer_length[i];
+ }
+ tokenizer = find_tokenizer(tokenizer_name, tokenizer_name_length);
+ DBUG_RETURN(tokenizer);
+}
+
grn_obj *ha_mroonga::find_tokenizer(const char *name, int name_length)
{
MRN_DBUG_ENTER_METHOD();
@@ -8862,92 +9153,137 @@ grn_obj *ha_mroonga::find_tokenizer(const char *name, int name_length)
if (!tokenizer) {
char message[MRN_BUFFER_SIZE];
sprintf(message,
- "specified fulltext parser <%.*s> doesn't exist. "
- "default fulltext parser <%s> is used instead.",
+ "specified tokenizer for fulltext index <%.*s> doesn't exist. "
+ "The default tokenizer for fulltext index <%s> is used instead.",
name_length, name,
- MRN_PARSER_DEFAULT);
+ MRN_DEFAULT_TOKENIZER);
push_warning(ha_thd(),
MRN_SEVERITY_WARNING, ER_UNSUPPORTED_EXTENSION,
message);
tokenizer = grn_ctx_get(ctx,
- MRN_PARSER_DEFAULT,
- strlen(MRN_PARSER_DEFAULT));
+ MRN_DEFAULT_TOKENIZER,
+ strlen(MRN_DEFAULT_TOKENIZER));
}
if (!tokenizer) {
push_warning(ha_thd(),
MRN_SEVERITY_WARNING, ER_UNSUPPORTED_EXTENSION,
- "couldn't find fulltext parser. "
- "Bigram fulltext parser is used instead.");
+ "couldn't find tokenizer for fulltext index. "
+ "Bigram tokenizer is used instead.");
tokenizer = grn_ctx_at(ctx, GRN_DB_BIGRAM);
}
DBUG_RETURN(tokenizer);
}
-grn_obj *ha_mroonga::find_normalizer(KEY *key_info)
+grn_obj *ha_mroonga::find_normalizer(KEY *key)
+{
+ MRN_DBUG_ENTER_METHOD();
+
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ if (key->option_struct->normalizer) {
+ grn_obj *normalizer = find_normalizer(key,
+ key->option_struct->normalizer);
+ DBUG_RETURN(normalizer);
+ }
+#endif
+
+ if (key->comment.length > 0) {
+ mrn::ParametersParser parser(key->comment.str,
+ key->comment.length);
+ parser.parse();
+ grn_obj *normalizer = find_normalizer(key, parser["normalizer"]);
+ DBUG_RETURN(normalizer);
+ }
+
+ grn_obj *normalizer = find_normalizer(key, NULL);
+ DBUG_RETURN(normalizer);
+}
+
+grn_obj *ha_mroonga::find_normalizer(KEY *key, const char *name)
{
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,
- key_info->comment.length);
- parser.parse();
- const char *normalizer_name = parser["normalizer"];
- if (normalizer_name) {
- if (strcmp(normalizer_name, "none") == 0) {
- use_normalizer = false;
- } else {
- normalizer = grn_ctx_get(ctx, normalizer_name, -1);
- }
+ if (name) {
+ if (strcmp(name, "none") == 0) {
+ use_normalizer = false;
+ } else {
+ normalizer = grn_ctx_get(ctx, name, -1);
}
}
-#endif
if (use_normalizer && !normalizer) {
- Field *field = key_info->key_part[0].field;
+ Field *field = key->key_part[0].field;
mrn::FieldNormalizer field_normalizer(ctx, ha_thd(), field);
normalizer = field_normalizer.find_grn_normalizer();
}
+
DBUG_RETURN(normalizer);
}
-bool ha_mroonga::find_index_column_flags(KEY *key_info, grn_obj_flags *index_column_flags)
+bool ha_mroonga::find_index_column_flags(KEY *key, 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"];
+
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ {
+ const char *names = key->option_struct->flags;
if (names) {
found = mrn_parse_grn_index_column_flags(ha_thd(),
ctx,
names,
strlen(names),
index_column_flags);
+ DBUG_RETURN(found);
}
}
#endif
+
+ if (key->comment.length > 0) {
+ mrn::ParametersParser parser(key->comment.str,
+ key->comment.length);
+ parser.parse();
+ const char *names = parser["flags"];
+ if (!names) {
+ // Deprecated. It's for backward compatibility.
+ names = parser["index_flags"];
+ }
+ if (names) {
+ found = mrn_parse_grn_index_column_flags(ha_thd(),
+ ctx,
+ names,
+ strlen(names),
+ index_column_flags);
+ }
+ }
+
DBUG_RETURN(found);
}
-bool ha_mroonga::find_token_filters(KEY *key_info, grn_obj *token_filters)
+bool ha_mroonga::find_token_filters(KEY *key, grn_obj *token_filters)
{
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);
+
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ if (key->option_struct->token_filters) {
+ found = find_token_filters_fill(token_filters,
+ key->option_struct->token_filters,
+ strlen(key->option_struct->token_filters));
+ DBUG_RETURN(found);
+ }
+#endif
+
+ if (key->comment.length > 0) {
+ mrn::ParametersParser parser(key->comment.str,
+ key->comment.length);
parser.parse();
const char *names = parser["token_filters"];
if (names) {
found = find_token_filters_fill(token_filters, names, strlen(names));
}
}
-#endif
+
DBUG_RETURN(found);
}
@@ -9356,8 +9692,8 @@ void ha_mroonga::check_count_skip(key_part_map start_key_part_map,
} else {
DBUG_PRINT("info", ("mroonga: count skip: without fulltext"));
uint key_nr = active_index;
- KEY key_info = table->key_info[key_nr];
- KEY_PART_INFO *key_part = key_info.key_part;
+ KEY *key_info = &(table->key_info[key_nr]);
+ KEY_PART_INFO *key_part = key_info->key_part;
for (where = MRN_SELECT_LEX_GET_WHERE_COND(select_lex);
where;
where = where->next) {
@@ -9386,17 +9722,17 @@ void ha_mroonga::check_count_skip(key_part_map start_key_part_map,
if (field->table != table)
break;
uint j;
- for (j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
+ for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
if (key_part[j].field == field)
{
if (!(start_key_part_map >> j) && !(end_key_part_map >> j))
- j = KEY_N_KEY_PARTS(&key_info);
+ j = KEY_N_KEY_PARTS(key_info);
else
i++;
break;
}
}
- if (j >= KEY_N_KEY_PARTS(&key_info))
+ if (j >= KEY_N_KEY_PARTS(key_info))
break;
}
if (i >= select_lex->select_n_where_fields)
@@ -9864,8 +10200,12 @@ 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) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0);
GRN_TIME_SET(ctx, buf, time);
@@ -9896,8 +10236,12 @@ 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) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0);
GRN_TIME_SET(ctx, buf, time);
@@ -9917,8 +10261,12 @@ 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) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0);
GRN_TIME_SET(ctx, buf, time);
@@ -9938,8 +10286,12 @@ 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) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0);
GRN_TIME_SET(ctx, buf, time);
@@ -9959,8 +10311,12 @@ 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) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
grn_obj_reinit(ctx, buf, GRN_DB_TIME, 0);
GRN_TIME_SET(ctx, buf, time);
@@ -10628,8 +10984,8 @@ void ha_mroonga::storage_store_fields(uchar *buf, grn_id record_id)
const char *column_name = field->field_name;
if (ignoring_no_key_columns) {
- KEY key_info = table->s->key_info[active_index];
- if (strcmp(key_info.key_part[0].field->field_name, column_name)) {
+ KEY *key_info = &(table->s->key_info[active_index]);
+ if (strcmp(key_info->key_part[0].field->field_name, column_name)) {
continue;
}
}
@@ -10831,8 +11187,12 @@ 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) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
memcpy(buf, &time, 8);
*size = 8;
@@ -10878,8 +11238,12 @@ 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) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
#else
int mysql_time = (int)sint3korr(key);
@@ -10913,8 +11277,12 @@ 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) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
memcpy(buf, &time, 8);
*size = 8;
@@ -10962,8 +11330,12 @@ int ha_mroonga::storage_encode_key_datetime(Field *field, const uchar *key,
time = time_converter.tm_to_grn_time(&date, usec, &truncated);
}
if (truncated) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
memcpy(buf, &time, 8);
*size = 8;
@@ -10988,8 +11360,12 @@ 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) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
memcpy(buf, &grn_time, 8);
*size = 8;
@@ -11015,8 +11391,12 @@ 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) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
memcpy(buf, &grn_time, 8);
*size = 8;
@@ -11042,8 +11422,12 @@ 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) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
memcpy(buf, &grn_time, 8);
*size = 8;
@@ -11212,8 +11596,12 @@ 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) {
+ if (MRN_ABORT_ON_WARNING(ha_thd())) {
+ error = MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd());
+ }
field->set_warning(MRN_SEVERITY_WARNING,
- WARN_DATA_TRUNCATED, 1);
+ MRN_ERROR_CODE_DATA_TRUNCATE(ha_thd()),
+ 1);
}
memcpy(buf, &time, 8);
*size = 8;
@@ -11381,12 +11769,11 @@ int ha_mroonga::reset()
replacing_ = false;
written_by_row_based_binlog = 0;
mrn_lock_type = F_UNLCK;
- mrn_clear_alter_share(thd);
+ mrn_clear_slot_data(thd);
current_ft_item = NULL;
DBUG_RETURN(error);
}
-#ifdef MRN_HANDLER_CLONE_NEED_NAME
handler *ha_mroonga::wrapper_clone(const char *name, MEM_ROOT *mem_root)
{
handler *cloned_handler;
@@ -11426,47 +11813,6 @@ handler *ha_mroonga::clone(const char *name, MEM_ROOT *mem_root)
}
DBUG_RETURN(cloned_handler);
}
-#else
-handler *ha_mroonga::wrapper_clone(MEM_ROOT *mem_root)
-{
- handler *cloned_handler;
- MRN_DBUG_ENTER_METHOD();
- if (!(cloned_handler = get_new_handler(table->s, mem_root,
- table->s->db_type())))
- DBUG_RETURN(NULL);
- ((ha_mroonga *) cloned_handler)->is_clone = true;
- ((ha_mroonga *) cloned_handler)->parent_for_clone = this;
- ((ha_mroonga *) cloned_handler)->mem_root_for_clone = mem_root;
- if (cloned_handler->ha_open(table, table->s->normalized_path.str,
- table->db_stat, HA_OPEN_IGNORE_IF_LOCKED))
- {
- delete cloned_handler;
- DBUG_RETURN(NULL);
- }
- DBUG_RETURN(cloned_handler);
-}
-
-handler *ha_mroonga::storage_clone(MEM_ROOT *mem_root)
-{
- MRN_DBUG_ENTER_METHOD();
- handler *cloned_handler;
- cloned_handler = handler::clone(mem_root);
- DBUG_RETURN(cloned_handler);
-}
-
-handler *ha_mroonga::clone(MEM_ROOT *mem_root)
-{
- MRN_DBUG_ENTER_METHOD();
- handler *cloned_handler;
- if (share->wrapper_mode)
- {
- cloned_handler = wrapper_clone(mem_root);
- } else {
- cloned_handler = storage_clone(mem_root);
- }
- DBUG_RETURN(cloned_handler);
-}
-#endif
uint8 ha_mroonga::wrapper_table_cache_type()
{
@@ -11511,8 +11857,8 @@ ha_rows ha_mroonga::wrapper_multi_range_read_info_const(uint keyno,
{
MRN_DBUG_ENTER_METHOD();
ha_rows rows;
- KEY key_info = table->key_info[keyno];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[keyno]);
+ if (mrn_is_geo_key(key_info)) {
rows = handler::multi_range_read_info_const(keyno, seq, seq_init_param,
n_ranges, bufsz, flags, cost);
DBUG_RETURN(rows);
@@ -11577,8 +11923,8 @@ ha_rows ha_mroonga::wrapper_multi_range_read_info(uint keyno, uint n_ranges,
{
MRN_DBUG_ENTER_METHOD();
ha_rows rows;
- KEY key_info = table->key_info[keyno];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[keyno]);
+ if (mrn_is_geo_key(key_info)) {
rows = handler::multi_range_read_info(keyno, n_ranges, keys,
#ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS
key_parts,
@@ -11651,8 +11997,8 @@ int ha_mroonga::wrapper_multi_range_read_init(RANGE_SEQ_IF *seq,
{
MRN_DBUG_ENTER_METHOD();
int error = 0;
- KEY key_info = table->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
error = handler::multi_range_read_init(seq, seq_init_param,
n_ranges, mode, buf);
DBUG_RETURN(error);
@@ -11700,8 +12046,8 @@ int ha_mroonga::wrapper_multi_range_read_next(range_id_t *range_info)
{
MRN_DBUG_ENTER_METHOD();
int error = 0;
- KEY key_info = table->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
error = handler::multi_range_read_next(range_info);
DBUG_RETURN(error);
}
@@ -11743,8 +12089,8 @@ int ha_mroonga::wrapper_read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
{
int error = 0;
MRN_DBUG_ENTER_METHOD();
- KEY key_info = table->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
error = handler::read_multi_range_first(found_range_p, ranges,
range_count, sorted, buffer);
DBUG_RETURN(error);
@@ -11795,8 +12141,8 @@ int ha_mroonga::wrapper_read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
{
int error = 0;
MRN_DBUG_ENTER_METHOD();
- KEY key_info = table->key_info[active_index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[active_index]);
+ if (mrn_is_geo_key(key_info)) {
error = handler::read_multi_range_next(found_range_p);
DBUG_RETURN(error);
}
@@ -11970,9 +12316,9 @@ int ha_mroonga::wrapper_delete_all_rows()
uint i;
uint n_keys = table->s->keys;
for (i = 0; i < n_keys; i++) {
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
- if (!(wrapper_is_target_index(&key_info))) {
+ if (!(wrapper_is_target_index(key_info))) {
continue;
}
@@ -12016,7 +12362,6 @@ int ha_mroonga::delete_all_rows()
DBUG_RETURN(error);
}
-#ifdef MRN_HANDLER_HAVE_TRUNCATE
int ha_mroonga::wrapper_truncate()
{
int error = 0;
@@ -12033,7 +12378,6 @@ int ha_mroonga::wrapper_truncate()
DBUG_RETURN(error);
}
-#endif
int ha_mroonga::wrapper_truncate_index()
{
@@ -12055,9 +12399,9 @@ int ha_mroonga::wrapper_truncate_index()
uint i;
uint n_keys = table->s->keys;
for (i = 0; i < n_keys; i++) {
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
- if (!(wrapper_is_target_index(&key_info))) {
+ if (!(wrapper_is_target_index(key_info))) {
continue;
}
@@ -12130,11 +12474,11 @@ int ha_mroonga::storage_truncate_index()
continue;
}
- KEY key_info = table->key_info[i];
+ KEY *key_info = &(table->key_info[i]);
if (
- !(key_info.flags & HA_NOSAME) &&
- (KEY_N_KEY_PARTS(&key_info) == 1 || (key_info.flags & HA_FULLTEXT))
+ !(key_info->flags & HA_NOSAME) &&
+ (KEY_N_KEY_PARTS(key_info) == 1 || (key_info->flags & HA_FULLTEXT))
) {
continue;
}
@@ -12155,7 +12499,6 @@ err:
DBUG_RETURN(error);
}
-#ifdef MRN_HANDLER_HAVE_TRUNCATE
int ha_mroonga::truncate()
{
MRN_DBUG_ENTER_METHOD();
@@ -12168,7 +12511,6 @@ int ha_mroonga::truncate()
}
DBUG_RETURN(error);
}
-#endif
double ha_mroonga::wrapper_scan_time()
{
@@ -12207,8 +12549,8 @@ double ha_mroonga::wrapper_read_time(uint index, uint ranges, ha_rows rows)
double res;
MRN_DBUG_ENTER_METHOD();
if (index < MAX_KEY) {
- KEY key_info = table->key_info[index];
- if (mrn_is_geo_key(&key_info)) {
+ KEY *key_info = &(table->key_info[index]);
+ if (mrn_is_geo_key(key_info)) {
res = handler::read_time(index, ranges, rows);
DBUG_RETURN(res);
}
@@ -12387,16 +12729,14 @@ int ha_mroonga::wrapper_rename_table(const char *from, const char *to,
int error = 0;
handler *hnd;
MRN_DBUG_ENTER_METHOD();
- MRN_SET_WRAP_SHARE_KEY(tmp_share, tmp_share->table_share);
- if (!(hnd =
- tmp_share->hton->create(tmp_share->hton, tmp_share->table_share,
- current_thd->mem_root)))
+
+ hnd = get_new_handler(tmp_share->table_share,
+ current_thd->mem_root,
+ tmp_share->hton);
+ if (!hnd)
{
- MRN_SET_BASE_SHARE_KEY(tmp_share, tmp_share->table_share);
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
- hnd->init();
- MRN_SET_BASE_SHARE_KEY(tmp_share, tmp_share->table_share);
if ((error = hnd->ha_rename_table(from, to)))
{
@@ -12610,17 +12950,11 @@ int ha_mroonga::rename_table(const char *from, const char *to)
if (strcmp(from_mapper.db_name(), to_mapper.db_name()))
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
-#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS
table_list.init_one_table(from_mapper.db_name(),
strlen(from_mapper.db_name()),
from_mapper.mysql_table_name(),
strlen(from_mapper.mysql_table_name()),
from_mapper.mysql_table_name(), TL_WRITE);
-#else
- table_list.init_one_table(from_mapper.db_name(),
- from_mapper.mysql_table_name(),
- TL_WRITE);
-#endif
mrn_open_mutex_lock(NULL);
tmp_table_share = mrn_create_tmp_table_share(&table_list, from, &error);
mrn_open_mutex_unlock(NULL);
@@ -12650,21 +12984,20 @@ int ha_mroonga::rename_table(const char *from, const char *to)
to_mapper.table_name());
}
+ if (!error && to_mapper.table_name()[0] == '#') {
+ error = add_wrap_hton(to, tmp_share->hton);
+ } else if (error && from_mapper.table_name()[0] == '#') {
+ add_wrap_hton(from, tmp_share->hton);
+ }
if (!error) {
mrn_free_long_term_share(tmp_share->long_term_share);
tmp_share->long_term_share = NULL;
}
mrn_free_share(tmp_share);
- if (!error && to_mapper.table_name()[0] == '#') {
- if ((error = alter_share_add(to, tmp_table_share)))
- DBUG_RETURN(error);
- } else if (error && from_mapper.table_name()[0] == '#') {
- alter_share_add(from, tmp_table_share);
- } else {
- mrn_open_mutex_lock(NULL);
- mrn_free_tmp_table_share(tmp_table_share);
- mrn_open_mutex_unlock(NULL);
- }
+ mrn_open_mutex_lock(NULL);
+ mrn_free_tmp_table_share(tmp_table_share);
+ mrn_open_mutex_unlock(NULL);
+
DBUG_RETURN(error);
}
@@ -13669,6 +14002,7 @@ enum_alter_inplace_result ha_mroonga::wrapper_check_if_supported_inplace_alter(
}
memcpy(wrap_altered_table, altered_table, sizeof(TABLE));
memcpy(wrap_altered_table_share, altered_table->s, sizeof(TABLE_SHARE));
+ mrn_init_sql_alloc(ha_thd(), &(wrap_altered_table_share->mem_root));
n_keys = ha_alter_info->index_drop_count;
for (i = 0; i < n_keys; ++i) {
@@ -13785,6 +14119,25 @@ bool ha_mroonga::wrapper_prepare_inplace_alter_table(
if (!alter_handler_flags) {
DBUG_RETURN(false);
}
+
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ int error = 0;
+ MRN_SHARE *tmp_share;
+ tmp_share = mrn_get_share(altered_table->s->table_name.str,
+ altered_table,
+ &error);
+ if (error != 0) {
+ DBUG_RETURN(true);
+ }
+
+ if (parse_engine_table_options(ha_thd(),
+ tmp_share->hton,
+ wrap_altered_table->s)) {
+ mrn_free_share(tmp_share);
+ DBUG_RETURN(true);
+ }
+#endif
+
MRN_SET_WRAP_ALTER_KEY(this, ha_alter_info);
MRN_SET_WRAP_SHARE_KEY(share, table->s);
MRN_SET_WRAP_TABLE_KEY(this, table);
@@ -13793,6 +14146,11 @@ bool ha_mroonga::wrapper_prepare_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);
+
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ mrn_free_share(tmp_share);
+#endif
+
DBUG_RETURN(result);
}
@@ -13857,8 +14215,8 @@ bool ha_mroonga::wrapper_inplace_alter_table(
ha_alter_info->key_count);
MRN_SHARE *tmp_share;
TABLE_SHARE tmp_table_share;
- char **key_parser;
- uint *key_parser_length;
+ char **key_tokenizer;
+ uint *key_tokenizer_length;
KEY *p_key_info = &table->key_info[table_share->primary_key];
bool need_fill_index = false;
memset(index_tables, 0, sizeof(grn_obj *) * ha_alter_info->key_count);
@@ -13868,8 +14226,8 @@ bool ha_mroonga::wrapper_inplace_alter_table(
if (!(tmp_share = (MRN_SHARE *)
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),
+ &key_tokenizer, sizeof(char *) * (tmp_table_share.keys),
+ &key_tokenizer_length, sizeof(uint) * (tmp_table_share.keys),
NullS))
) {
MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables);
@@ -13880,8 +14238,8 @@ bool ha_mroonga::wrapper_inplace_alter_table(
tmp_share->table_share = &tmp_table_share;
tmp_share->index_table = NULL;
tmp_share->index_table_length = NULL;
- tmp_share->key_parser = key_parser;
- tmp_share->key_parser_length = key_parser_length;
+ tmp_share->key_tokenizer = key_tokenizer;
+ tmp_share->key_tokenizer_length = key_tokenizer_length;
bitmap_clear_all(table->read_set);
mrn_set_bitmap_by_key(table->read_set, p_key_info);
n_keys = ha_alter_info->index_add_count;
@@ -13939,14 +14297,32 @@ bool ha_mroonga::wrapper_inplace_alter_table(
bitmap_set_all(table->read_set);
if (!error && alter_handler_flags) {
- MRN_SET_WRAP_ALTER_KEY(this, ha_alter_info);
- MRN_SET_WRAP_SHARE_KEY(share, table->s);
- MRN_SET_WRAP_TABLE_KEY(this, table);
- result = wrap_handler->ha_inplace_alter_table(wrap_altered_table,
- ha_alter_info);
- MRN_SET_BASE_ALTER_KEY(this, ha_alter_info);
- MRN_SET_BASE_SHARE_KEY(share, table->s);
- MRN_SET_BASE_TABLE_KEY(this, table);
+#ifdef MRN_SUPPORT_CUSTOM_OPTIONS
+ {
+ MRN_SHARE *alter_tmp_share;
+ alter_tmp_share = mrn_get_share(altered_table->s->table_name.str,
+ altered_table,
+ &error);
+ if (alter_tmp_share) {
+ if (parse_engine_table_options(ha_thd(),
+ alter_tmp_share->hton,
+ wrap_altered_table->s)) {
+ error = MRN_GET_ERROR_NUMBER;
+ }
+ mrn_free_share(alter_tmp_share);
+ }
+ }
+#endif
+ if (!error) {
+ MRN_SET_WRAP_ALTER_KEY(this, ha_alter_info);
+ MRN_SET_WRAP_SHARE_KEY(share, table->s);
+ MRN_SET_WRAP_TABLE_KEY(this, table);
+ result = wrap_handler->ha_inplace_alter_table(wrap_altered_table,
+ ha_alter_info);
+ MRN_SET_BASE_ALTER_KEY(this, ha_alter_info);
+ MRN_SET_BASE_SHARE_KEY(share, table->s);
+ MRN_SET_BASE_TABLE_KEY(this, table);
+ }
}
if (result || error)
@@ -13954,8 +14330,7 @@ bool ha_mroonga::wrapper_inplace_alter_table(
n_keys = ha_alter_info->index_add_count;
for (i = 0; i < n_keys; ++i) {
uint key_pos = ha_alter_info->index_add_buffer[i];
- KEY *key =
- &altered_table->key_info[key_pos];
+ KEY *key = &altered_table->key_info[key_pos];
if (!(key->flags & HA_FULLTEXT || mrn_is_geo_key(key))) {
continue;
}
@@ -14007,8 +14382,8 @@ bool ha_mroonga::storage_inplace_alter_table_index(
ha_alter_info->key_count);
MRN_SHARE *tmp_share;
TABLE_SHARE tmp_table_share;
- char **index_table, **key_parser, **col_flags, **col_type;
- uint *index_table_length, *key_parser_length, *col_flags_length, *col_type_length;
+ char **index_table, **key_tokenizer, **col_flags, **col_type;
+ uint *index_table_length, *key_tokenizer_length, *col_flags_length, *col_type_length;
bool have_multiple_column_index = false;
memset(index_tables, 0, sizeof(grn_obj *) * ha_alter_info->key_count);
memset(index_columns, 0, sizeof(grn_obj *) * ha_alter_info->key_count);
@@ -14019,8 +14394,8 @@ bool ha_mroonga::storage_inplace_alter_table_index(
&tmp_share, sizeof(*tmp_share),
&index_table, sizeof(char *) * tmp_table_share.keys,
&index_table_length, sizeof(uint) * tmp_table_share.keys,
- &key_parser, sizeof(char *) * tmp_table_share.keys,
- &key_parser_length, sizeof(uint) * tmp_table_share.keys,
+ &key_tokenizer, sizeof(char *) * tmp_table_share.keys,
+ &key_tokenizer_length, sizeof(uint) * tmp_table_share.keys,
&col_flags, sizeof(char *) * tmp_table_share.fields,
&col_flags_length, sizeof(uint) * tmp_table_share.fields,
&col_type, sizeof(char *) * tmp_table_share.fields,
@@ -14035,8 +14410,8 @@ bool ha_mroonga::storage_inplace_alter_table_index(
tmp_share->table_share = &tmp_table_share;
tmp_share->index_table = index_table;
tmp_share->index_table_length = index_table_length;
- tmp_share->key_parser = key_parser;
- tmp_share->key_parser_length = key_parser_length;
+ tmp_share->key_tokenizer = key_tokenizer;
+ tmp_share->key_tokenizer_length = key_tokenizer_length;
tmp_share->col_flags = col_flags;
tmp_share->col_flags_length = col_flags_length;
tmp_share->col_type = col_type;
@@ -14145,8 +14520,8 @@ bool ha_mroonga::storage_inplace_alter_table_add_column(
MRN_SHARE *tmp_share;
TABLE_SHARE tmp_table_share;
- char **index_table, **key_parser, **col_flags, **col_type;
- uint *index_table_length, *key_parser_length, *col_flags_length, *col_type_length;
+ char **index_table, **key_tokenizer, **col_flags, **col_type;
+ uint *index_table_length, *key_tokenizer_length, *col_flags_length, *col_type_length;
tmp_table_share.keys = 0;
tmp_table_share.fields = altered_table->s->fields;
tmp_share = (MRN_SHARE *)mrn_my_multi_malloc(
@@ -14154,8 +14529,8 @@ bool ha_mroonga::storage_inplace_alter_table_add_column(
&tmp_share, sizeof(*tmp_share),
&index_table, sizeof(char *) * tmp_table_share.keys,
&index_table_length, sizeof(uint) * tmp_table_share.keys,
- &key_parser, sizeof(char *) * tmp_table_share.keys,
- &key_parser_length, sizeof(uint) * tmp_table_share.keys,
+ &key_tokenizer, sizeof(char *) * tmp_table_share.keys,
+ &key_tokenizer_length, sizeof(uint) * tmp_table_share.keys,
&col_flags, sizeof(char *) * tmp_table_share.fields,
&col_flags_length, sizeof(uint) * tmp_table_share.fields,
&col_type, sizeof(char *) * tmp_table_share.fields,
@@ -14169,8 +14544,8 @@ bool ha_mroonga::storage_inplace_alter_table_add_column(
tmp_share->table_share = &tmp_table_share;
tmp_share->index_table = index_table;
tmp_share->index_table_length = index_table_length;
- tmp_share->key_parser = key_parser;
- tmp_share->key_parser_length = key_parser_length;
+ tmp_share->key_tokenizer = key_tokenizer;
+ tmp_share->key_tokenizer_length = key_tokenizer_length;
tmp_share->col_flags = col_flags;
tmp_share->col_flags_length = col_flags_length;
tmp_share->col_type = col_type;
@@ -14187,7 +14562,6 @@ bool ha_mroonga::storage_inplace_alter_table_add_column(
continue;
}
- grn_obj *col_type;
Field *field = altered_table->s->field[i];
const char *column_name = field->field_name;
int column_name_size = strlen(column_name);
@@ -14199,20 +14573,19 @@ bool ha_mroonga::storage_inplace_alter_table_add_column(
}
grn_obj_flags col_flags = GRN_OBJ_PERSISTENT;
- if (tmp_share->col_flags[i]) {
- col_flags |= mrn_parse_grn_column_create_flags(ha_thd(),
- ctx,
- tmp_share->col_flags[i],
- tmp_share->col_flags_length[i]);
- } else {
+ if (!find_column_flags(field, tmp_share, i, &col_flags)) {
col_flags |= GRN_OBJ_COLUMN_SCALAR;
}
- grn_builtin_type gtype = mrn_grn_type_from_field(ctx, field, false);
- if (tmp_share->col_type[i]) {
- col_type = grn_ctx_get(ctx, tmp_share->col_type[i], -1);
- } else {
- col_type = grn_ctx_at(ctx, gtype);
+ grn_obj *col_type;
+ {
+ int column_type_error_code = ER_WRONG_FIELD_SPEC;
+ col_type = find_column_type(field, tmp_share, i, column_type_error_code);
+ if (!col_type) {
+ error = column_type_error_code;
+ have_error = true;
+ break;
+ }
}
char *col_path = NULL; // we don't specify path
@@ -14418,6 +14791,7 @@ bool ha_mroonga::wrapper_commit_inplace_alter_table(
bool result;
MRN_DBUG_ENTER_METHOD();
if (!alter_handler_flags) {
+ free_root(&(wrap_altered_table_share->mem_root), MYF(0));
my_free(alter_key_info_buffer);
alter_key_info_buffer = NULL;
DBUG_RETURN(false);
@@ -14431,6 +14805,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);
+ free_root(&(wrap_altered_table_share->mem_root), MYF(0));
my_free(alter_key_info_buffer);
alter_key_info_buffer = NULL;
DBUG_RETURN(result);
@@ -14538,8 +14913,8 @@ int ha_mroonga::wrapper_add_index(TABLE *table_arg, KEY *key_info,
THD *thd = ha_thd();
MRN_SHARE *tmp_share;
TABLE_SHARE tmp_table_share;
- char **key_parser;
- uint *key_parser_length;
+ char **key_tokenizer;
+ uint *key_tokenizer_length;
MRN_DBUG_ENTER_METHOD();
if (!(wrap_alter_key_info = (KEY *) mrn_my_malloc(sizeof(KEY) * num_of_keys,
MYF(MY_WME)))) {
@@ -14553,8 +14928,8 @@ int ha_mroonga::wrapper_add_index(TABLE *table_arg, KEY *key_info,
if (!(tmp_share = (MRN_SHARE *)
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),
+ &key_tokenizer, sizeof(char *) * (n_keys + num_of_keys),
+ &key_tokenizer_length, sizeof(uint) * (n_keys + num_of_keys),
NullS))
) {
MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables);
@@ -14565,8 +14940,8 @@ int ha_mroonga::wrapper_add_index(TABLE *table_arg, KEY *key_info,
tmp_share->table_share = &tmp_table_share;
tmp_share->index_table = NULL;
tmp_share->index_table_length = NULL;
- tmp_share->key_parser = key_parser;
- tmp_share->key_parser_length = key_parser_length;
+ tmp_share->key_tokenizer = key_tokenizer;
+ tmp_share->key_tokenizer_length = key_tokenizer_length;
tmp_share->col_flags = NULL;
tmp_share->col_type = NULL;
#ifdef MRN_HANDLER_HAVE_FINAL_ADD_INDEX
@@ -14677,8 +15052,8 @@ int ha_mroonga::storage_add_index(TABLE *table_arg, KEY *key_info,
MRN_ALLOCATE_VARIABLE_LENGTH_ARRAYS(grn_obj *, index_columns, num_of_keys + n_keys);
MRN_SHARE *tmp_share;
TABLE_SHARE tmp_table_share;
- char **index_table, **key_parser, **col_flags, **col_type;
- uint *index_table_length, *key_parser_length, *col_flags_length, *col_type_length;
+ char **index_table, **key_tokenizer, **col_flags, **col_type;
+ uint *index_table_length, *key_tokenizer_length, *col_flags_length, *col_type_length;
bool have_multiple_column_index = false;
MRN_DBUG_ENTER_METHOD();
@@ -14689,8 +15064,8 @@ int ha_mroonga::storage_add_index(TABLE *table_arg, KEY *key_info,
&tmp_share, sizeof(*tmp_share),
&index_table, sizeof(char*) * tmp_table_share.keys,
&index_table_length, sizeof(uint) * tmp_table_share.keys,
- &key_parser, sizeof(char *) * tmp_table_share.keys,
- &key_parser_length, sizeof(uint) * tmp_table_share.keys,
+ &key_tokenizer, sizeof(char *) * tmp_table_share.keys,
+ &key_tokenizer_length, sizeof(uint) * tmp_table_share.keys,
&col_flags, sizeof(char *) * tmp_table_share.fields,
&col_flags_length, sizeof(uint) * tmp_table_share.fields,
&col_type, sizeof(char *) * tmp_table_share.fields,
@@ -14705,8 +15080,8 @@ int ha_mroonga::storage_add_index(TABLE *table_arg, KEY *key_info,
tmp_share->table_share = &tmp_table_share;
tmp_share->index_table = index_table;
tmp_share->index_table_length = index_table_length;
- tmp_share->key_parser = key_parser;
- tmp_share->key_parser_length = key_parser_length;
+ tmp_share->key_tokenizer = key_tokenizer;
+ tmp_share->key_tokenizer_length = key_tokenizer_length;
tmp_share->col_flags = col_flags;
tmp_share->col_flags_length = col_flags_length;
tmp_share->col_type = col_type;
@@ -15238,11 +15613,11 @@ int ha_mroonga::reset_auto_increment(ulonglong value)
void ha_mroonga::set_pk_bitmap()
{
- KEY key_info = table->key_info[table_share->primary_key];
- uint j;
MRN_DBUG_ENTER_METHOD();
- for (j = 0; j < KEY_N_KEY_PARTS(&key_info); j++) {
- Field *field = key_info.key_part[j].field;
+ KEY *key_info = &(table->key_info[table_share->primary_key]);
+ uint j;
+ for (j = 0; j < KEY_N_KEY_PARTS(key_info); j++) {
+ Field *field = key_info->key_part[j].field;
bitmap_set_bit(table->read_set, field->field_index);
}
DBUG_VOID_RETURN;
@@ -15556,17 +15931,11 @@ char *ha_mroonga::storage_get_foreign_key_create_info()
build_table_filename(ref_path, sizeof(ref_path) - 1,
table_share->db.str, ref_table_buff, "", 0);
DBUG_PRINT("info", ("mroonga: ref_path=%s", ref_path));
-#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS
table_list.init_one_table(table_share->db.str,
table_share->db.length,
ref_table_buff,
ref_table_name_length,
ref_table_buff, TL_WRITE);
-#else
- table_list.init_one_table(table_share->db.str,
- ref_table_buff,
- TL_WRITE);
-#endif
mrn_open_mutex_lock(table_share);
tmp_ref_table_share =
mrn_create_tmp_table_share(&table_list, ref_path, &error);
@@ -15768,17 +16137,11 @@ int ha_mroonga::storage_get_foreign_key_list(THD *thd,
build_table_filename(ref_path, sizeof(ref_path) - 1,
table_share->db.str, ref_table_buff, "", 0);
DBUG_PRINT("info", ("mroonga: ref_path=%s", ref_path));
-#ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS
table_list.init_one_table(table_share->db.str,
table_share->db.length,
ref_table_buff,
ref_table_name_length,
ref_table_buff, TL_WRITE);
-#else
- table_list.init_one_table(table_share->db.str,
- ref_table_buff,
- TL_WRITE);
-#endif
mrn_open_mutex_lock(table_share);
tmp_ref_table_share =
mrn_create_tmp_table_share(&table_list, ref_path, &error);
@@ -15831,7 +16194,6 @@ int ha_mroonga::get_foreign_key_list(THD *thd,
DBUG_RETURN(res);
}
-#ifdef MRN_HANDLER_HAVE_GET_PARENT_FOREIGN_KEY_LIST
int ha_mroonga::wrapper_get_parent_foreign_key_list(THD *thd,
List<FOREIGN_KEY_INFO> *f_key_list)
{
@@ -15866,7 +16228,6 @@ int ha_mroonga::get_parent_foreign_key_list(THD *thd,
}
DBUG_RETURN(res);
}
-#endif
uint ha_mroonga::wrapper_referenced_by_foreign_key()
{