[Groonga-mysql-commit] mroonga/mroonga [master] Add wrapper "create table" and "drop table" prototype.

Zurück zum Archiv-Index

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 */




Groonga-mysql-commit メーリングリストの案内
Zurück zum Archiv-Index