null+****@clear*****
null+****@clear*****
2011年 6月 6日 (月) 18:55:34 JST
Kentoku 2011-06-06 09:55:34 +0000 (Mon, 06 Jun 2011)
New Revision: 7889e0344f9f3386a04495012de608e19b57e246
Log:
Add wrapper "create table" and "drop table" prototype.
Added files:
mrn_err.h
mrn_table.cc
mrn_table.h
Modified files:
Makefile.am
ha_mroonga.cc
ha_mroonga.h
Modified: Makefile.am (+3 -3)
===================================================================
--- Makefile.am 2011-05-29 13:12:18 +0000 (fb8d4e2)
+++ Makefile.am 2011-06-06 09:55:34 +0000 (528f505)
@@ -3,19 +3,19 @@ AUTOMAKE_OPTIONS = 1.9.7
AM_CPPFLAGS = $(MYSQL_INC) $(GROONGA_CFLAGS) $(MECAB_INCLUDES) $(MYSQL_VERSION_CFLAGS)
ACLOCAL_AMFLAGS = $$ACLOCAL_ARGS
-noinst_HEADERS = mrnsys.h ha_mroonga.h
+noinst_HEADERS = mrnsys.h ha_mroonga.h mrn_table.h mrn_err.h
plugin_LTLIBRARIES = ha_groonga.la
ha_groonga_la_LDFLAGS = -module $(GROONGA_LIBS) $(MECAB_LIBS)
ha_groonga_la_CXXFLAGS = $(AM_CFLAGS) $(MYSQL_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
ha_groonga_la_CFLAGS = $(AM_CFLAGS) $(MYSQL_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
-ha_groonga_la_SOURCES = ha_mroonga.cc mrnsys.c
+ha_groonga_la_SOURCES = ha_mroonga.cc mrnsys.c mrn_table.cc
plugin_LIBRARIES = libgroonga_storage_engine.a
libgroonga_storage_engine_a_LDFLANGS = $(GROONGA_LIBS) $(MECAB_LIBS)
libgroonga_storage_engine_a_CXXFLAGS = $(AM_CFLAGS) $(MYSQL_CFLAGS)
libgroonga_storage_engine_a_CFLAGS = $(AM_CFLAGS) $(MYSQL_CFLAGS)
-libgroonga_storage_engine_a_SOURCES = ha_mroonga.cc mrnsys.c
+libgroonga_storage_engine_a_SOURCES = ha_mroonga.cc mrnsys.c mrn_table.cc
SUBDIRS = test apt rpm yum doc
Modified: ha_mroonga.cc (+217 -44)
===================================================================
--- ha_mroonga.cc 2011-05-29 13:12:18 +0000 (2aacbdc)
+++ ha_mroonga.cc 2011-06-06 09:55:34 +0000 (93e924e)
@@ -36,6 +36,7 @@
#endif
#define MYSQL_SERVER 1
+#include "mysql_version.h"
#ifdef MYSQL51
#include <mysql_priv.h>
@@ -46,6 +47,7 @@
#include <probes_mysql.h>
#include <sql_plugin.h>
#include <sql_show.h>
+#include "sql_partition.h"
#endif
#include <sql_select.h>
#include <ft_global.h>
@@ -54,12 +56,20 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include "mrn_err.h"
+#include "mrn_table.h"
#include "ha_mroonga.h"
#ifdef __cplusplus
extern "C" {
#endif
+#if MYSQL_VERSION_ID >= 50500
+extern mysql_mutex_t LOCK_open;
+#else
+extern pthread_mutex_t LOCK_open;
+#endif
+
/* global variables */
grn_obj *mrn_db;
grn_hash *mrn_hash;
@@ -73,6 +83,17 @@ _ft_vft mrn_ft_vft = {
NULL // mrn_ft_reinit_search
};
handlerton *mrn_hton_ptr;
+HASH mrn_open_tables;
+pthread_mutex_t mrn_open_tables_mutex;
+uchar *grn_open_tables_get_key(
+ MRN_SHARE *share,
+ size_t *length,
+ my_bool not_used __attribute__ ((unused))
+) {
+ DBUG_ENTER("grn_open_tables_get_key");
+ *length = share->table_name_length;
+ DBUG_RETURN((uchar*) share->table_name);
+}
/* status */
st_mrn_statuses mrn_status_vals;
@@ -387,10 +408,21 @@ int mrn_init(void *p)
(my_hash_get_key) mrn_allocated_thds_get_key, 0, 0)) {
goto error_allocated_thds_hash_init;
}
+ if ((pthread_mutex_init(&mrn_open_tables_mutex, NULL) != 0)) {
+ goto err_allocated_open_tables_mutex_init;
+ }
+ if (my_hash_init(&mrn_open_tables, system_charset_info, 32, 0, 0,
+ (my_hash_get_key) grn_open_tables_get_key, 0, 0)) {
+ goto error_allocated_open_tables_hash_init;
+ }
grn_ctx_fin(ctx);
return 0;
+error_allocated_open_tables_hash_init:
+ pthread_mutex_destroy(&mrn_open_tables_mutex);
+err_allocated_open_tables_mutex_init:
+ my_hash_free(&mrn_allocated_thds);
error_allocated_thds_hash_init:
pthread_mutex_destroy(&mrn_allocated_thds_mutex);
err_allocated_thds_mutex_init:
@@ -424,6 +456,8 @@ int mrn_deinit(void *p)
pthread_mutex_unlock(&mrn_allocated_thds_mutex);
}
+ my_hash_free(&mrn_open_tables);
+ pthread_mutex_destroy(&mrn_open_tables_mutex);
my_hash_free(&mrn_allocated_thds);
pthread_mutex_destroy(&mrn_allocated_thds_mutex);
pthread_mutex_destroy(&mrn_log_mutex);
@@ -898,11 +932,28 @@ ulong ha_mroonga::index_flags(uint idx, uint part, bool all_parts) const
}
}
-int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
+int ha_mroonga::wrapper_create(const char *name, TABLE *table,
+ HA_CREATE_INFO *info, MRN_SHARE *tmp_share)
{
- DBUG_ENTER("ha_mroonga::create");
- /* checking data type of virtual columns */
- int i;
+ int error;
+ handler *hnd;
+ DBUG_ENTER("ha_mroonga::wrapper_create");
+ /* TODO: create groonga index */
+
+ if (!(hnd =
+ tmp_share->hton->create(tmp_share->hton, table->s,
+ current_thd->mem_root)))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ error = hnd->ha_create(name, table, info);
+ delete hnd;
+ DBUG_RETURN(error);
+}
+
+int ha_mroonga::default_create(const char *name, TABLE *table,
+ HA_CREATE_INFO *info, MRN_SHARE *tmp_share)
+{
+ int error, i;
+ DBUG_ENTER("ha_mroonga::default_create");
uint n_columns = table->s->fields;
for (i = 0; i < n_columns; i++) {
Field *field = table->s->field[i];
@@ -918,9 +969,10 @@ int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
break;
default:
GRN_LOG(ctx, GRN_LOG_ERROR, "_id must be numeric data type");
- my_message(ER_CANT_CREATE_TABLE, "_id must be numeric data type", MYF(0));
- DBUG_RETURN(ER_CANT_CREATE_TABLE);
- }
+ error = ER_CANT_CREATE_TABLE;
+ my_message(error, "_id must be numeric data type", MYF(0));
+ DBUG_RETURN(error);
+ }
}
if (strncmp(MRN_SCORE_COL_NAME, col_name, col_name_size) == 0) {
switch (field->type()) {
@@ -929,9 +981,10 @@ int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
break;
default:
GRN_LOG(ctx, GRN_LOG_ERROR, "_score must be float or double");
- my_message(ER_CANT_CREATE_TABLE, "_score must be float or double", MYF(0));
- DBUG_RETURN(ER_CANT_CREATE_TABLE);
- }
+ error = ER_CANT_CREATE_TABLE;
+ my_message(error, "_score must be float or double", MYF(0));
+ DBUG_RETURN(error);
+ }
}
}
@@ -943,8 +996,9 @@ int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
int key_parts = key_info.key_parts;
if (key_parts != 1) {
GRN_LOG(ctx, GRN_LOG_ERROR, "complex key is not supported yet");
- my_message(ER_NOT_SUPPORTED_YET, "complex key is not supported yet.", MYF(0));
- DBUG_RETURN(ER_NOT_SUPPORTED_YET);
+ error = ER_NOT_SUPPORTED_YET;
+ my_message(error, "complex key is not supported yet.", MYF(0));
+ DBUG_RETURN(error);
}
Field *field = key_info.key_part[0].field;
const char *col_name = field->field_name;
@@ -954,13 +1008,15 @@ int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
continue; // hash index is ok
}
GRN_LOG(ctx, GRN_LOG_ERROR, "only hash index can be defined for _id");
- my_message(ER_CANT_CREATE_TABLE, "only hash index can be defined for _id", MYF(0));
- DBUG_RETURN(ER_CANT_CREATE_TABLE);
+ error = ER_CANT_CREATE_TABLE;
+ my_message(error, "only hash index can be defined for _id", MYF(0));
+ DBUG_RETURN(error);
}
if (strncmp(MRN_SCORE_COL_NAME, col_name, col_name_size) == 0) {
GRN_LOG(ctx, GRN_LOG_ERROR, "_score cannot be used for index");
- my_message(ER_CANT_CREATE_TABLE, "_score cannot be used for index", MYF(0));
- DBUG_RETURN(ER_CANT_CREATE_TABLE);
+ error = ER_CANT_CREATE_TABLE;
+ my_message(error, "_score cannot be used for index", MYF(0));
+ DBUG_RETURN(error);
}
}
@@ -980,16 +1036,18 @@ int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
db_obj = grn_db_create(ctx, db_path, NULL);
if (ctx->rc) {
pthread_mutex_unlock(&db_mutex);
- my_message(ER_CANT_CREATE_FILE, ctx->errbuf, MYF(0));
- DBUG_RETURN(ER_CANT_CREATE_FILE);
+ error = ER_CANT_CREATE_TABLE;
+ my_message(error, ctx->errbuf, MYF(0));
+ DBUG_RETURN(error);
}
} else {
// opening existing database
db_obj = grn_db_open(ctx, db_path);
if (ctx->rc) {
pthread_mutex_unlock(&db_mutex);
- my_message(ER_CANT_OPEN_FILE, ctx->errbuf, MYF(0));
- DBUG_RETURN(ER_CANT_OPEN_FILE);
+ error = ER_CANT_OPEN_FILE;
+ my_message(error, ctx->errbuf, MYF(0));
+ DBUG_RETURN(error);
}
}
mrn_hash_put(ctx, mrn_hash, db_name, db_obj);
@@ -1009,8 +1067,9 @@ int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
int key_parts = key_info.key_parts;
if (key_parts != 1) {
GRN_LOG(ctx, GRN_LOG_ERROR, "complex key is not supported yet");
- my_message(ER_NOT_SUPPORTED_YET, "complex key is not supported yet", MYF(0));
- DBUG_RETURN(ER_NOT_SUPPORTED_YET);
+ error = ER_NOT_SUPPORTED_YET;
+ my_message(error, "complex key is not supported yet", MYF(0));
+ DBUG_RETURN(error);
}
Field *pkey_field = key_info.key_part[0].field;
const char *col_name = pkey_field->field_name;
@@ -1050,8 +1109,9 @@ int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
tbl_obj = grn_table_create(ctx, tbl_name, tbl_name_len, tbl_path,
tbl_flags, pkey_type, pkey_value_type);
if (ctx->rc) {
- my_message(ER_CANT_CREATE_TABLE, ctx->errbuf, MYF(0));
- DBUG_RETURN(ER_CANT_CREATE_TABLE);
+ error = ER_CANT_CREATE_TABLE;
+ my_message(error, ctx->errbuf, MYF(0));
+ DBUG_RETURN(error);
}
/* create columns */
@@ -1074,8 +1134,9 @@ int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
col_path, col_flags, col_type);
if (ctx->rc) {
grn_obj_remove(ctx, tbl_obj);
- my_message(ER_CANT_CREATE_TABLE, ctx->errbuf, MYF(0));
- DBUG_RETURN(ER_CANT_CREATE_TABLE);
+ error = ER_CANT_CREATE_TABLE;
+ my_message(error, ctx->errbuf, MYF(0));
+ DBUG_RETURN(error);
}
}
@@ -1094,8 +1155,9 @@ int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
int key_parts = key_info.key_parts;
if (key_parts != 1) {
GRN_LOG(ctx, GRN_LOG_ERROR, "complex key is not supported yet");
- my_message(ER_NOT_SUPPORTED_YET, "complex key is not supported yet.", MYF(0));
- DBUG_RETURN(ER_NOT_SUPPORTED_YET);
+ error = ER_NOT_SUPPORTED_YET;
+ my_message(error, "complex key is not supported yet.", MYF(0));
+ DBUG_RETURN(error);
}
mrn_index_name_gen(tbl_name, i, idx_name);
@@ -1130,8 +1192,9 @@ int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
idx_tbl_flags, col_type, 0);
if (ctx->rc) {
grn_obj_remove(ctx, tbl_obj);
+ error = ER_CANT_CREATE_TABLE;
my_message(ER_CANT_CREATE_TABLE, ctx->errbuf, MYF(0));
- DBUG_RETURN(ER_CANT_CREATE_TABLE);
+ DBUG_RETURN(error);
}
if (key_alg == HA_KEY_ALG_FULLTEXT) {
@@ -1146,8 +1209,9 @@ int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
if (ctx->rc) {
grn_obj_remove(ctx, idx_tbl_obj);
grn_obj_remove(ctx, tbl_obj);
- my_message(ER_CANT_CREATE_TABLE, ctx->errbuf, MYF(0));
- DBUG_RETURN(ER_CANT_CREATE_TABLE);
+ error = ER_CANT_CREATE_TABLE;
+ my_message(error, ctx->errbuf, MYF(0));
+ DBUG_RETURN(error);
}
grn_id gid = grn_obj_id(ctx, col_obj);
@@ -1159,10 +1223,31 @@ int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
/* clean up */
grn_obj_unlink(ctx, tbl_obj);
-
DBUG_RETURN(0);
}
+int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
+{
+ int i, error = 0;
+ MRN_SHARE *tmp_share;
+ DBUG_ENTER("ha_mroonga::create");
+ /* checking data type of virtual columns */
+
+ if (!(tmp_share = mrn_get_share(name, table, &error)))
+ DBUG_RETURN(error);
+
+ if (tmp_share->wrapper_mode)
+ {
+ /* create wrapped table */
+ error = wrapper_create(name, table, info, tmp_share);
+ } else {
+ error = default_create(name, table, info, tmp_share);
+ }
+
+ mrn_free_share(tmp_share);
+ DBUG_RETURN(error);
+}
+
int ha_mroonga::open(const char *name, int mode, uint test_if_locked)
{
DBUG_ENTER("ha_mroonga::open");
@@ -1301,27 +1386,49 @@ int ha_mroonga::close()
DBUG_RETURN(0);
}
-int ha_mroonga::delete_table(const char *name)
+int ha_mroonga::wrapper_delete_table(const char *name, MRN_SHARE *tmp_share)
{
- DBUG_ENTER("ha_mroonga::delete_table");
+ int error;
+ handler *hnd;
+ DBUG_ENTER("ha_mroonga::wrapper_delete_table");
+ if (!(hnd =
+ tmp_share->hton->create(tmp_share->hton, table->s,
+ current_thd->mem_root)))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+
+ if ((error = hnd->ha_delete_table(name)))
+ {
+ delete hnd;
+ DBUG_RETURN(error);
+ }
+
+ /* TODO: create groonga index */
+
+ delete hnd;
+ DBUG_RETURN(0);
+}
+
+int ha_mroonga::default_delete_table(const char *name, MRN_SHARE *tmp_share,
+ const char *tbl_name)
+{
+ int error;
+ TABLE_SHARE *tmp_table_share = tmp_share->table_share;
+ DBUG_ENTER("ha_mroonga::default_delete_table");
char db_path[MRN_MAX_PATH_SIZE];
- char tbl_name[MRN_MAX_PATH_SIZE];
char idx_name[MRN_MAX_PATH_SIZE];
grn_obj *db_obj, *tbl_obj, *lex_obj, *hash_obj, *pat_obj;
mrn_db_path_gen(name, db_path);
db_obj = grn_db_open(ctx, db_path);
if (ctx->rc) {
- my_message(ER_CANT_OPEN_FILE, ctx->errbuf, MYF(0));
- DBUG_RETURN(ER_CANT_OPEN_FILE);
+ error = ER_CANT_OPEN_FILE;
+ my_message(error, ctx->errbuf, MYF(0));
+ DBUG_RETURN(error);
}
grn_ctx_use(ctx, db_obj);
- mrn_table_name_gen(name, tbl_name);
-
- /* FIXME: remove const 100 */
int i;
- for (i = 0; i < 100; i++) { // 100 is enough
+ for (i = 0; i < tmp_table_share->keys; i++) {
mrn_index_name_gen(tbl_name, i, idx_name);
grn_obj *idx_tbl_obj = grn_ctx_get(ctx, idx_name, strlen(idx_name));
if (idx_tbl_obj != NULL) {
@@ -1331,10 +1438,76 @@ int ha_mroonga::delete_table(const char *name)
tbl_obj = grn_ctx_get(ctx, tbl_name, strlen(tbl_name));
if (ctx->rc) {
- my_message(ER_CANT_OPEN_FILE, ctx->errbuf, MYF(0));
- DBUG_RETURN(ER_CANT_OPEN_FILE);
+ error = ER_CANT_OPEN_FILE;
+ my_message(error, ctx->errbuf, MYF(0));
+ DBUG_RETURN(error);
}
- DBUG_RETURN(grn_obj_remove(ctx, tbl_obj));
+ error = grn_obj_remove(ctx, tbl_obj);
+ DBUG_RETURN(error);
+}
+
+int ha_mroonga::delete_table(const char *name)
+{
+ int error = 0;
+ char db_name[MRN_MAX_PATH_SIZE];
+ char tbl_name[MRN_MAX_PATH_SIZE];
+ TABLE_LIST table_list;
+ TABLE_SHARE *tmp_table_share;
+ TABLE tmp_table;
+ MRN_SHARE *tmp_share;
+ DBUG_ENTER("ha_mroonga::delete_table");
+ mrn_db_name_gen(name, db_name);
+ mrn_table_name_gen(name, tbl_name);
+#if MYSQL_VERSION_ID >= 50500
+ table_list.init_one_table(db_name, strlen(db_name),
+ tbl_name, strlen(tbl_name), tbl_name, TL_WRITE);
+ mysql_mutex_lock(&LOCK_open);
+#else
+ table_list.init_one_table(db_name, tbl_name, TL_WRITE);
+ pthread_mutex_lock(&LOCK_open);
+#endif
+ if (!(tmp_table_share = mrn_get_table_share(&table_list, &error)))
+ {
+#if MYSQL_VERSION_ID >= 50500
+ mysql_mutex_unlock(&LOCK_open);
+#else
+ pthread_mutex_unlock(&LOCK_open);
+#endif
+ DBUG_RETURN(error);
+ }
+#if MYSQL_VERSION_ID >= 50500
+ mysql_mutex_unlock(&LOCK_open);
+#else
+ pthread_mutex_unlock(&LOCK_open);
+#endif
+ tmp_table.s = tmp_table_share;
+ tmp_table.part_info = NULL;
+ if (!(tmp_share = mrn_get_share(name, &tmp_table, &error)))
+ {
+ mrn_free_table_share(tmp_table_share);
+ DBUG_RETURN(error);
+ }
+
+ if (tmp_share->wrapper_mode)
+ {
+ error = wrapper_delete_table(name, tmp_share);
+ } else {
+ error = default_delete_table(name, tmp_share, tbl_name);
+ }
+
+ mrn_free_share(tmp_share);
+#if MYSQL_VERSION_ID >= 50500
+ mysql_mutex_lock(&LOCK_open);
+#else
+ pthread_mutex_lock(&LOCK_open);
+#endif
+ mrn_free_table_share(tmp_table_share);
+#if MYSQL_VERSION_ID >= 50500
+ mysql_mutex_unlock(&LOCK_open);
+#else
+ pthread_mutex_unlock(&LOCK_open);
+#endif
+ DBUG_RETURN(error);
}
int ha_mroonga::info(uint flag)
Modified: ha_mroonga.h (+7 -0)
===================================================================
--- ha_mroonga.h 2011-05-29 13:12:18 +0000 (11ff31a)
+++ ha_mroonga.h 2011-06-06 09:55:34 +0000 (9601ead)
@@ -203,6 +203,13 @@ private:
key_part_map end_key_part_map, bool fulltext);
void check_fast_order_limit();
void store_fields_from_primary_table(uchar *buf, grn_id rid);
+ int wrapper_create(const char *name, TABLE *table,
+ HA_CREATE_INFO *info, MRN_SHARE *tmp_share);
+ int default_create(const char *name, TABLE *table,
+ HA_CREATE_INFO *info, MRN_SHARE *tmp_share);
+ int wrapper_delete_table(const char *name, MRN_SHARE *tmp_share);
+ int default_delete_table(const char *name, MRN_SHARE *tmp_share,
+ const char *tbl_name);
};
#ifdef __cplusplus
Added: mrn_err.h (+24 -0) 100644
===================================================================
--- /dev/null
+++ mrn_err.h 2011-06-06 09:55:34 +0000 (9a79001)
@@ -0,0 +1,24 @@
+/* Copyright(C) 2011 Kentoku SHIBA
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _mrn_err_h
+#define _mrn_err_h
+
+#define ER_MRN_INVALID_TABLE_PARAM_NUM 16501
+#define ER_MRN_INVALID_TABLE_PARAM_STR "The table parameter '%-.64s' is invalid"
+
+#endif /* _mrn_err_h */
Added: mrn_table.cc (+542 -0) 100644
===================================================================
--- /dev/null
+++ mrn_table.cc 2011-06-06 09:55:34 +0000 (91c4dff)
@@ -0,0 +1,542 @@
+/* Copyright(C) 2011 Kentoku SHIBA
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#define MYSQL_SERVER 1
+#include "mysql_version.h"
+#if MYSQL_VERSION_ID < 50500
+#include "mysql_priv.h"
+#include <mysql/plugin.h>
+#else
+#include "sql_priv.h"
+#include "probes_mysql.h"
+#include "sql_class.h"
+#include "sql_partition.h"
+#include "sql_servers.h"
+#include "sql_base.h"
+#endif
+#include "mrn_err.h"
+#include "mrnsys.h"
+#include "mrn_table.h"
+
+#define MRN_DEFAULT_STR "DEFAULT"
+#define MRN_DEFAULT_LEN (sizeof(MRN_DEFAULT_STR) - 1)
+#define MRN_GROONGA_STR "GROONGA"
+#define MRN_GROONGA_LEN (sizeof(MRN_GROONGA_STR) - 1)
+
+extern HASH mrn_open_tables;
+extern pthread_mutex_t mrn_open_tables_mutex;
+
+char *mrn_create_string(const char *str, uint length)
+{
+ char *res;
+ DBUG_ENTER("mrn_create_string");
+ if (!(res = (char*) my_malloc(length + 1, MYF(MY_WME))))
+ DBUG_RETURN(NULL);
+ memcpy(res, str, length);
+ res[length] = '\0';
+ DBUG_RETURN(res);
+}
+
+char *mrn_get_string_between_quote(char *ptr, bool alloc)
+{
+ char *start_ptr, *end_ptr, *tmp_ptr, *esc_ptr;
+ bool find_flg = FALSE, esc_flg = FALSE;
+ DBUG_ENTER("mrn_get_string_between_quote");
+
+ start_ptr = strchr(ptr, '\'');
+ end_ptr = strchr(ptr, '"');
+ if (start_ptr && (!end_ptr || start_ptr < end_ptr))
+ {
+ tmp_ptr = ++start_ptr;
+ while (!find_flg)
+ {
+ if (!(end_ptr = strchr(tmp_ptr, '\'')))
+ DBUG_RETURN(NULL);
+ esc_ptr = tmp_ptr;
+ while (!find_flg)
+ {
+ esc_ptr = strchr(esc_ptr, '\\');
+ if (!esc_ptr || esc_ptr > end_ptr)
+ find_flg = TRUE;
+ else if (esc_ptr == end_ptr - 1)
+ {
+ esc_flg = TRUE;
+ tmp_ptr = end_ptr + 1;
+ break;
+ } else {
+ esc_flg = TRUE;
+ esc_ptr += 2;
+ }
+ }
+ }
+ } else if (end_ptr)
+ {
+ start_ptr = end_ptr;
+ tmp_ptr = ++start_ptr;
+ while (!find_flg)
+ {
+ if (!(end_ptr = strchr(tmp_ptr, '"')))
+ DBUG_RETURN(NULL);
+ esc_ptr = tmp_ptr;
+ while (!find_flg)
+ {
+ esc_ptr = strchr(esc_ptr, '\\');
+ if (!esc_ptr || esc_ptr > end_ptr)
+ find_flg = TRUE;
+ else if (esc_ptr == end_ptr - 1)
+ {
+ esc_flg = TRUE;
+ tmp_ptr = end_ptr + 1;
+ break;
+ } else {
+ esc_flg = TRUE;
+ esc_ptr += 2;
+ }
+ }
+ }
+ } else
+ DBUG_RETURN(NULL);
+
+ *end_ptr = '\0';
+ if (esc_flg)
+ {
+ esc_ptr = start_ptr;
+ while (TRUE)
+ {
+ esc_ptr = strchr(esc_ptr, '\\');
+ if (!esc_ptr)
+ break;
+ switch(*(esc_ptr + 1))
+ {
+ case 'b':
+ *esc_ptr = '\b';
+ break;
+ case 'n':
+ *esc_ptr = '\n';
+ break;
+ case 'r':
+ *esc_ptr = '\r';
+ break;
+ case 't':
+ *esc_ptr = '\t';
+ break;
+ default:
+ *esc_ptr = *(esc_ptr + 1);
+ break;
+ }
+ esc_ptr++;
+ strcpy(esc_ptr, esc_ptr + 1);
+ }
+ }
+ if (alloc)
+ {
+ DBUG_RETURN(
+ mrn_create_string(
+ start_ptr,
+ strlen(start_ptr))
+ );
+ } else {
+ DBUG_RETURN(start_ptr);
+ }
+}
+
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+void mrn_get_partition_info(const char *table_name, uint table_name_length,
+ const TABLE *table, partition_element **part_elem,
+ partition_element **sub_elem)
+{
+ char tmp_name[FN_LEN];
+ partition_info *part_info = table->part_info;
+ partition_element *tmp_part_elem = NULL, *tmp_sub_elem = NULL;
+ bool tmp_flg = FALSE, tmp_find_flg = FALSE;
+ DBUG_ENTER("mrn_get_partition_info");
+ *part_elem = NULL;
+ *sub_elem = NULL;
+ if (!part_info)
+ DBUG_VOID_RETURN;
+
+ if (!memcmp(table_name + table_name_length - 5, "#TMP#", 5))
+ tmp_flg = TRUE;
+
+ DBUG_PRINT("info",("mroonga table_name=%s", table_name));
+ List_iterator<partition_element> part_it(part_info->partitions);
+ while ((*part_elem = part_it++))
+ {
+ if ((*part_elem)->subpartitions.elements)
+ {
+ List_iterator<partition_element> sub_it((*part_elem)->subpartitions);
+ while ((*sub_elem = sub_it++))
+ {
+ create_subpartition_name(tmp_name, table->s->path.str,
+ (*part_elem)->partition_name, (*sub_elem)->partition_name,
+ NORMAL_PART_NAME);
+ DBUG_PRINT("info",("mroonga tmp_name=%s", tmp_name));
+ if (!memcmp(table_name, tmp_name, table_name_length + 1))
+ DBUG_VOID_RETURN;
+ if (
+ tmp_flg &&
+ *(tmp_name + table_name_length - 5) == '\0' &&
+ !memcmp(table_name, tmp_name, table_name_length - 5)
+ ) {
+ tmp_part_elem = *part_elem;
+ tmp_sub_elem = *sub_elem;
+ tmp_flg = FALSE;
+ tmp_find_flg = TRUE;
+ }
+ }
+ } else {
+ create_partition_name(tmp_name, table->s->path.str,
+ (*part_elem)->partition_name, NORMAL_PART_NAME, TRUE);
+ DBUG_PRINT("info",("mroonga tmp_name=%s", tmp_name));
+ if (!memcmp(table_name, tmp_name, table_name_length + 1))
+ DBUG_VOID_RETURN;
+ if (
+ tmp_flg &&
+ *(tmp_name + table_name_length - 5) == '\0' &&
+ !memcmp(table_name, tmp_name, table_name_length - 5)
+ ) {
+ tmp_part_elem = *part_elem;
+ tmp_flg = FALSE;
+ tmp_find_flg = TRUE;
+ }
+ }
+ }
+ if (tmp_find_flg)
+ {
+ *part_elem = tmp_part_elem;
+ *sub_elem = tmp_sub_elem;
+ DBUG_PRINT("info",("mroonga tmp find"));
+ DBUG_VOID_RETURN;
+ }
+ *part_elem = NULL;
+ *sub_elem = NULL;
+ DBUG_PRINT("info",("mroonga no hit"));
+ DBUG_VOID_RETURN;
+}
+#endif
+
+#define MRN_PARAM_STR_LEN(name) name ## _length
+#define MRN_PARAM_STR(title_name, param_name) \
+ if (!strncasecmp(tmp_ptr, title_name, title_length)) \
+ { \
+ DBUG_PRINT("info",("mroonga "title_name" start")); \
+ if (!share->param_name) \
+ { \
+ if ((share->param_name = mrn_get_string_between_quote( \
+ start_ptr, TRUE))) \
+ share->MRN_PARAM_STR_LEN(param_name) = strlen(share->param_name); \
+ else { \
+ error = ER_MRN_INVALID_TABLE_PARAM_NUM; \
+ my_printf_error(error, ER_MRN_INVALID_TABLE_PARAM_STR, \
+ MYF(0), tmp_ptr); \
+ goto error; \
+ } \
+ DBUG_PRINT("info",("mroonga "title_name"=%s", share->param_name)); \
+ } \
+ break; \
+ }
+
+int mrn_parse_table_param(MRN_SHARE *share, TABLE *table)
+{
+ int i, error;
+ int title_length;
+ char *param_string = NULL;
+ char *sprit_ptr[2];
+ char *tmp_ptr, *tmp_ptr2, *start_ptr;
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ partition_element *part_elem;
+ partition_element *sub_elem;
+#endif
+ DBUG_ENTER("mrn_parse_table_param");
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ mrn_get_partition_info(share->table_name, share->table_name_length, table,
+ &part_elem, &sub_elem);
+#endif
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ for (i = 4; i > 0; i--)
+#else
+ for (i = 2; i > 0; i--)
+#endif
+ {
+ if (param_string)
+ {
+ my_free(param_string, MYF(0));
+ param_string = NULL;
+ }
+ switch (i)
+ {
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ case 4:
+ if (!sub_elem || !sub_elem->part_comment)
+ continue;
+ DBUG_PRINT("info",("mroonga create sub comment string"));
+ if (
+ !(param_string = mrn_create_string(
+ sub_elem->part_comment,
+ strlen(sub_elem->part_comment)))
+ ) {
+ error = HA_ERR_OUT_OF_MEM;
+ goto error_alloc_param_string;
+ }
+ DBUG_PRINT("info",("mroonga sub comment string=%s", param_string));
+ break;
+ case 3:
+ if (!part_elem || !part_elem->part_comment)
+ continue;
+ DBUG_PRINT("info",("mroonga create part comment string"));
+ if (
+ !(param_string = mrn_create_string(
+ part_elem->part_comment,
+ strlen(part_elem->part_comment)))
+ ) {
+ error = HA_ERR_OUT_OF_MEM;
+ goto error_alloc_param_string;
+ }
+ DBUG_PRINT("info",("mroonga part comment string=%s", param_string));
+ break;
+#endif
+ case 2:
+ if (table->s->comment.length == 0)
+ continue;
+ DBUG_PRINT("info",("mroonga create comment string"));
+ if (
+ !(param_string = mrn_create_string(
+ table->s->comment.str,
+ table->s->comment.length))
+ ) {
+ error = HA_ERR_OUT_OF_MEM;
+ goto error_alloc_param_string;
+ }
+ DBUG_PRINT("info",("mroonga comment string=%s", param_string));
+ break;
+ default:
+ if (table->s->connect_string.length == 0)
+ continue;
+ DBUG_PRINT("info",("mroonga create connect_string string"));
+ if (
+ !(param_string = mrn_create_string(
+ table->s->connect_string.str,
+ table->s->connect_string.length))
+ ) {
+ error = HA_ERR_OUT_OF_MEM;
+ goto error_alloc_param_string;
+ }
+ DBUG_PRINT("info",("mroonga connect_string=%s", param_string));
+ break;
+ }
+
+ sprit_ptr[0] = param_string;
+ while (sprit_ptr[0])
+ {
+ if ((sprit_ptr[1] = strchr(sprit_ptr[0], ',')))
+ {
+ *sprit_ptr[1] = '\0';
+ sprit_ptr[1]++;
+ }
+ tmp_ptr = sprit_ptr[0];
+ sprit_ptr[0] = sprit_ptr[1];
+ while (*tmp_ptr == ' ' || *tmp_ptr == '\r' ||
+ *tmp_ptr == '\n' || *tmp_ptr == '\t')
+ tmp_ptr++;
+
+ if (*tmp_ptr == '\0')
+ continue;
+
+ title_length = 0;
+ start_ptr = tmp_ptr;
+ while (*start_ptr != ' ' && *start_ptr != '\'' &&
+ *start_ptr != '"' && *start_ptr != '\0' &&
+ *start_ptr != '\r' && *start_ptr != '\n' &&
+ *start_ptr != '\t')
+ {
+ title_length++;
+ start_ptr++;
+ }
+
+ switch (title_length)
+ {
+ case 0:
+ continue;
+ case 6:
+ MRN_PARAM_STR("engine", engine);
+ error = ER_MRN_INVALID_TABLE_PARAM_NUM;
+ my_printf_error(error, ER_MRN_INVALID_TABLE_PARAM_STR,
+ MYF(0), tmp_ptr);
+ goto error;
+ default:
+ error = ER_MRN_INVALID_TABLE_PARAM_NUM;
+ my_printf_error(error, ER_MRN_INVALID_TABLE_PARAM_STR,
+ MYF(0), tmp_ptr);
+ goto error;
+ }
+ }
+ }
+
+ if (share->engine)
+ {
+ LEX_STRING engine_name;
+ if (
+ (
+ share->engine_length == MRN_DEFAULT_LEN &&
+ !strncasecmp(share->engine, MRN_DEFAULT_STR, MRN_DEFAULT_LEN)
+ ) ||
+ (
+ share->engine_length == MRN_GROONGA_LEN &&
+ !strncasecmp(share->engine, MRN_GROONGA_STR, MRN_GROONGA_LEN)
+ )
+ ) {
+ my_free(share->engine, MYF(0));
+ share->engine = NULL;
+ share->engine_length = 0;
+ } else {
+ engine_name.str = share->engine;
+ engine_name.length = share->engine_length;
+ if (!(share->plugin = ha_resolve_by_name(NULL, &engine_name)))
+ {
+ my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), share->engine);
+ error = ER_UNKNOWN_STORAGE_ENGINE;
+ goto error;
+ }
+ share->hton = plugin_data(share->plugin, handlerton *);
+ share->wrapper_mode = TRUE;
+ }
+ }
+
+ if (param_string)
+ my_free(param_string, MYF(0));
+ DBUG_RETURN(0);
+
+error:
+ if (param_string)
+ my_free(param_string, MYF(0));
+error_alloc_param_string:
+ DBUG_RETURN(error);
+}
+
+int mrn_free_share_alloc(
+ MRN_SHARE *share
+) {
+ DBUG_ENTER("mrn_free_share_alloc");
+ if (share->engine)
+ my_free(share->engine, MYF(0));
+ DBUG_RETURN(0);
+}
+
+MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error)
+{
+ MRN_SHARE *share;
+ char *tmp_name;
+ uint length;
+ DBUG_ENTER("mrn_get_share");
+ length = (uint) strlen(table_name);
+ pthread_mutex_lock(&mrn_open_tables_mutex);
+ if (!(share = (MRN_SHARE*) my_hash_search(&mrn_open_tables,
+ (uchar*) table_name, length)))
+ {
+ if (!(share = (MRN_SHARE *)
+ my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
+ &share, sizeof(*share),
+ &tmp_name, length + 1,
+ NullS))
+ ) {
+ *error = HA_ERR_OUT_OF_MEM;
+ goto error_alloc_share;
+ }
+ share->use_count = 0;
+ share->table_name_length = length;
+ share->table_name = tmp_name;
+ strmov(share->table_name, table_name);
+ share->table_share = table->s;
+
+ if ((*error = mrn_parse_table_param(share, table)))
+ goto error_parse_table_param;
+ if (pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST))
+ {
+ *error = HA_ERR_OUT_OF_MEM;
+ goto error_init_mutex;
+ }
+ thr_lock_init(&share->lock);
+ if (my_hash_insert(&mrn_open_tables, (uchar*) share))
+ {
+ *error = HA_ERR_OUT_OF_MEM;
+ goto error_hash_insert;
+ }
+ }
+ share->use_count++;
+ pthread_mutex_unlock(&mrn_open_tables_mutex);
+ DBUG_RETURN(share);
+
+error_hash_insert:
+ pthread_mutex_destroy(&share->mutex);
+error_init_mutex:
+error_parse_table_param:
+ mrn_free_share_alloc(share);
+ my_free(share, MYF(0));
+error_alloc_share:
+ pthread_mutex_unlock(&mrn_open_tables_mutex);
+ DBUG_RETURN(NULL);
+}
+
+int mrn_free_share(MRN_SHARE *share)
+{
+ DBUG_ENTER("mrn_free_share");
+ pthread_mutex_lock(&mrn_open_tables_mutex);
+ if (!--share->use_count)
+ {
+ my_hash_delete(&mrn_open_tables, (uchar*) share);
+ if (share->wrapper_mode)
+ plugin_unlock(NULL, share->plugin);
+ mrn_free_share_alloc(share);
+ thr_lock_delete(&share->lock);
+ pthread_mutex_destroy(&share->mutex);
+ my_free(share, MYF(0));
+ }
+ pthread_mutex_unlock(&mrn_open_tables_mutex);
+ DBUG_RETURN(0);
+}
+
+TABLE_SHARE *mrn_get_table_share(TABLE_LIST *table_list, int *error)
+{
+ char key[MAX_DBKEY_LENGTH];
+ uint key_length;
+ TABLE_SHARE *share;
+#if MYSQL_VERSION_ID >= 50500
+ my_hash_value_type hash_value;
+#endif
+ THD *thd = current_thd;
+ DBUG_ENTER("mrn_get_table_share");
+ key_length = create_table_def_key(thd, key, table_list, FALSE);
+#if MYSQL_VERSION_ID >= 50500
+ hash_value = my_calc_hash(&table_def_cache, (uchar*) key, key_length);
+ share = get_table_share(thd, table_list, key, key_length, 0, error,
+ hash_value);
+#else
+ share = get_table_share(thd, table_list, key, key_length, 0, error);
+#endif
+ DBUG_RETURN(share);
+}
+
+void mrn_free_table_share(TABLE_SHARE *share)
+{
+ DBUG_ENTER("mrn_free_table_share");
+#if MYSQL_VERSION_ID >= 50500
+ release_table_share(share);
+#else
+ release_table_share(share, RELEASE_NORMAL);
+#endif
+ DBUG_VOID_RETURN;
+}
Added: mrn_table.h (+54 -0) 100644
===================================================================
--- /dev/null
+++ mrn_table.h 2011-06-06 09:55:34 +0000 (d668246)
@@ -0,0 +1,54 @@
+/* Copyright(C) 2011 Kentoku SHIBA
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _mrn_table_h
+#define _mrn_table_h
+
+#if MYSQL_VERSION_ID >= 50500
+#define my_free(A,B) my_free(A)
+#endif
+
+typedef struct st_mroonga_share
+{
+ char *table_name;
+ uint table_name_length;
+ uint use_count;
+ pthread_mutex_t mutex;
+ THR_LOCK lock;
+ TABLE_SHARE *table_share;
+
+ char *engine;
+ int engine_length;
+ plugin_ref plugin;
+ handlerton *hton;
+ bool wrapper_mode;
+} MRN_SHARE;
+
+char *mrn_create_string(const char *str, uint length);
+char *mrn_get_string_between_quote(char *ptr, bool alloc);
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+void mrn_get_partition_info(const char *table_name, uint table_name_length,
+ const TABLE *table, partition_element **part_elem,
+ partition_element **sub_elem);
+#endif
+int mrn_parse_table_param(MRN_SHARE *share, TABLE *table);
+MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error);
+int mrn_free_share(MRN_SHARE *share);
+TABLE_SHARE *mrn_get_table_share(TABLE_LIST *table_list, int *error);
+void mrn_free_table_share(TABLE_SHARE *share);
+
+#endif /* _mrn_table_h */