[Groonga-mysql-commit] mroonga/mroonga [master] Alter table support. refs #1168

Back to archive index

null+****@clear***** null+****@clear*****
2011年 11月 26日 (土) 15:39:01 JST


Kentoku	2011-11-26 06:39:01 +0000 (Sat, 26 Nov 2011)

  New Revision: e85fcebe868c101bfad188b01f457e7482dc575b

  Log:
    Alter table support. refs #1168

  Modified files:
    ha_mroonga.cc
    ha_mroonga.h
    mrn_table.cc
    mrn_table.h

  Modified: ha_mroonga.cc (+86 -51)
===================================================================
--- ha_mroonga.cc    2011-11-25 13:26:52 +0000 (bae05b0)
+++ ha_mroonga.cc    2011-11-26 06:39:01 +0000 (2d73f62)
@@ -83,7 +83,7 @@ const char *grn_obj_get_value_(grn_ctx *ctx, grn_obj *obj, grn_id id, uint32 *si
 /* global variables */
 static pthread_mutex_t mrn_db_mutex;
 static pthread_mutex_t mrn_log_mutex;
-static handlerton *mrn_hton_ptr;
+handlerton *mrn_hton_ptr;
 HASH mrn_open_tables;
 pthread_mutex_t mrn_open_tables_mutex;
 
@@ -137,8 +137,8 @@ static grn_logger_info mrn_logger_info = {
 };
 
 /* global hashes and mutexes */
-static HASH mrn_allocated_thds;
-static pthread_mutex_t mrn_allocated_thds_mutex;
+HASH mrn_allocated_thds;
+pthread_mutex_t mrn_allocated_thds_mutex;
 static uchar *mrn_allocated_thds_get_key(THD *thd,
                                          size_t *length,
                                          my_bool not_used __attribute__ ((unused)))
@@ -336,7 +336,7 @@ my_bool last_insert_grn_id_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
 int last_insert_grn_id(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
 {
   THD *thd = current_thd;
-  st_mrn_slot_data *slot_data = (st_mrn_slot_data*) *thd_ha_data(thd, mrn_hton_ptr);
+  st_mrn_slot_data *slot_data = mrn_get_slot_data(thd, FALSE);
   if (slot_data == NULL) {
     return 0;
   }
@@ -1014,7 +1014,8 @@ static int mrn_deinit(void *p)
     pthread_mutex_lock(&mrn_allocated_thds_mutex);
     while ((tmp_thd = (THD *) my_hash_element(&mrn_allocated_thds, 0)))
     {
-      void *slot_ptr = *thd_ha_data(tmp_thd, mrn_hton_ptr);
+      mrn_clear_alter_share(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;
       my_hash_delete(&mrn_allocated_thds, (uchar *) tmp_thd);
@@ -1487,6 +1488,7 @@ 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);
@@ -2178,14 +2180,6 @@ int ha_mroonga::create(const char *name, TABLE *table, HA_CREATE_INFO *info)
   int i, error = 0;
   MRN_SHARE *tmp_share;
   MRN_DBUG_ENTER_METHOD();
-  uint sql_command = thd_sql_command(ha_thd());
-  if (
-    sql_command == SQLCOM_CREATE_INDEX ||
-    sql_command == SQLCOM_DROP_INDEX ||
-    sql_command == SQLCOM_ALTER_TABLE
-  )
-    DBUG_RETURN(HA_ERR_WRONG_COMMAND);
-
   /* checking data type of virtual columns */
 
   if (!(tmp_share = mrn_get_share(name, table, &error)))
@@ -2245,6 +2239,7 @@ 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();
     error = wrap_handler->ha_open(table, name, mode, test_if_locked);
   } else {
 #ifdef MRN_HANDLER_CLONE_NEED_NAME
@@ -2699,6 +2694,7 @@ int ha_mroonga::wrapper_delete_table(const char *name, MRN_SHARE *tmp_share,
     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)))
@@ -2781,53 +2777,71 @@ int ha_mroonga::storage_delete_table(const char *name, MRN_SHARE *tmp_share,
 int ha_mroonga::delete_table(const char *name)
 {
   int error = 0;
+  THD *thd = ha_thd();
   char db_name[MRN_MAX_PATH_SIZE];
   char tbl_name[MRN_MAX_PATH_SIZE];
   char decode_name[MRN_MAX_PATH_SIZE];
   TABLE_LIST table_list;
-  TABLE_SHARE *tmp_table_share;
+  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();
-  uint sql_command = thd_sql_command(ha_thd());
-  if (
-    sql_command == SQLCOM_CREATE_INDEX ||
-    sql_command == SQLCOM_DROP_INDEX ||
-    sql_command == SQLCOM_ALTER_TABLE
-  )
-    DBUG_RETURN(HA_ERR_WRONG_COMMAND);
   mrn_decode((uchar *) decode_name, (uchar *) decode_name + MRN_MAX_PATH_SIZE,
              (const uchar *) name, (const uchar *) name + strlen(name));
   mrn_db_name_gen(decode_name, db_name);
   mrn_table_name_gen(decode_name, tbl_name);
+  st_mrn_slot_data *slot_data = mrn_get_slot_data(thd, FALSE);
+  if (slot_data && slot_data->first_alter_share)
+  {
+    tmp_alter_share = NULL;
+    alter_share = slot_data->first_alter_share;
+    while (alter_share)
+    {
+      if (!strcmp(alter_share->path, name))
+      {
+        /* found */
+        tmp_table_share = alter_share->alter_share;
+        if (tmp_alter_share)
+          tmp_alter_share->next = alter_share->next;
+        else
+          slot_data->first_alter_share = alter_share->next;
+        free(alter_share);
+        break;
+      }
+      tmp_alter_share = alter_share;
+      alter_share = alter_share->next;
+    }
+  }
+  if (!tmp_table_share)
+  {
 #if MYSQL_VERSION_ID >= 50500
-  table_list.init_one_table(db_name, strlen(db_name),
-                            tbl_name, strlen(tbl_name), tbl_name, TL_WRITE);
+    table_list.init_one_table(db_name, strlen(db_name),
+                              tbl_name, strlen(tbl_name), tbl_name, TL_WRITE);
 #else
-  table_list.init_one_table(db_name, tbl_name, TL_WRITE);
+    table_list.init_one_table(db_name, tbl_name, TL_WRITE);
 #endif
 #if MYSQL_VERSION_ID >= 50500
-  mysql_mutex_lock(&LOCK_open);
+    mysql_mutex_lock(&LOCK_open);
 #endif
-  if (!(tmp_table_share = mrn_get_table_share(&table_list, &error)))
-  {
+    if (!(tmp_table_share = mrn_q_get_table_share(&table_list, name, &error)))
+    {
 #if MYSQL_VERSION_ID >= 50500
-    mysql_mutex_unlock(&LOCK_open);
+      mysql_mutex_unlock(&LOCK_open);
 #endif
-    DBUG_RETURN(error);
-  }
+      DBUG_RETURN(error);
+    }
 #if MYSQL_VERSION_ID >= 50500
-  mysql_mutex_unlock(&LOCK_open);
+    mysql_mutex_unlock(&LOCK_open);
 #endif
-  /* This is previous version */
-  tmp_table_share->version--;
+  }
   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)))
   {
-    mrn_free_table_share(tmp_table_share);
+    mrn_q_free_table_share(tmp_table_share);
     DBUG_RETURN(error);
   }
 
@@ -2842,7 +2856,7 @@ int ha_mroonga::delete_table(const char *name)
 #if MYSQL_VERSION_ID >= 50500
   mysql_mutex_lock(&LOCK_open);
 #endif
-  mrn_free_table_share(tmp_table_share);
+  mrn_q_free_table_share(tmp_table_share);
 #if MYSQL_VERSION_ID >= 50500
   mysql_mutex_unlock(&LOCK_open);
 #endif
@@ -3541,21 +3555,14 @@ int ha_mroonga::storage_write_row(uchar *buf)
   }
 
   // for UDF last_insert_grn_id()
-  st_mrn_slot_data *slot_data = (st_mrn_slot_data*) *thd_ha_data(thd, mrn_hton_ptr);
+  st_mrn_slot_data *slot_data = mrn_get_slot_data(thd, TRUE);
   if (slot_data == NULL) {
-    slot_data = (st_mrn_slot_data*) malloc(sizeof(st_mrn_slot_data));
-    *thd_ha_data(thd, mrn_hton_ptr) = (void *) slot_data;
-    pthread_mutex_lock(&mrn_allocated_thds_mutex);
-    if (my_hash_insert(&mrn_allocated_thds, (uchar*) thd))
-    {
 #ifndef DBUG_OFF
       dbug_tmp_restore_column_map(table->read_set, tmp_map);
 #endif
       DBUG_RETURN(HA_ERR_OUT_OF_MEM);
-    }
-    pthread_mutex_unlock(&mrn_allocated_thds_mutex);
   }
-  slot_data->last_insert_record_id = record_id;
+  slot_data->last_insert_record_id = (int) record_id;
 
 #ifndef DBUG_OFF
   dbug_tmp_restore_column_map(table->read_set, tmp_map);
@@ -6297,6 +6304,7 @@ int ha_mroonga::storage_reset()
 int ha_mroonga::reset()
 {
   int error = 0;
+  THD *thd = ha_thd();
   MRN_DBUG_ENTER_METHOD();
   DBUG_PRINT("info", ("mroonga: this=%p", this));
   clear_search_result();
@@ -6308,6 +6316,7 @@ int ha_mroonga::reset()
   ignoring_no_key_columns = false;
   ignoring_duplicated_key = false;
   fulltext_searching = false;
+  mrn_clear_alter_share(thd);
   DBUG_RETURN(error);
 }
 
@@ -7152,6 +7161,7 @@ int ha_mroonga::wrapper_rename_table(const char *from, const char *to,
     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)))
@@ -7275,6 +7285,7 @@ int ha_mroonga::storage_rename_table(const char *from, const char *to,
 int ha_mroonga::rename_table(const char *from, const char *to)
 {
   int error = 0;
+  THD *thd = ha_thd();
   char from_db_name[MRN_MAX_PATH_SIZE];
   char to_db_name[MRN_MAX_PATH_SIZE];
   char from_tbl_name[MRN_MAX_PATH_SIZE];
@@ -7306,7 +7317,7 @@ int ha_mroonga::rename_table(const char *from, const char *to)
 #if MYSQL_VERSION_ID >= 50500
   mysql_mutex_lock(&LOCK_open);
 #endif
-  if (!(tmp_table_share = mrn_get_table_share(&table_list, &error)))
+  if (!(tmp_table_share = mrn_q_get_table_share(&table_list, from, &error)))
   {
 #if MYSQL_VERSION_ID >= 50500
     mysql_mutex_unlock(&LOCK_open);
@@ -7316,18 +7327,39 @@ int ha_mroonga::rename_table(const char *from, const char *to)
 #if MYSQL_VERSION_ID >= 50500
   mysql_mutex_unlock(&LOCK_open);
 #endif
-  /* This is previous version */
-  tmp_table_share->version--;
   tmp_table.s = tmp_table_share;
 #ifdef WITH_PARTITION_STORAGE_ENGINE
   tmp_table.part_info = NULL;
 #endif
   if (!(tmp_share = mrn_get_share(from, &tmp_table, &error)))
   {
-    mrn_free_table_share(tmp_table_share);
+    mrn_q_free_table_share(tmp_table_share);
     DBUG_RETURN(error);
   }
 
+  if (to_tbl_name[0] == '#')
+  {
+    st_mrn_slot_data *slot_data = mrn_get_slot_data(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)
+      DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+    alter_share->next = NULL;
+    strcpy(alter_share->path, to);
+    alter_share->alter_share = tmp_table_share;
+    if (slot_data->first_alter_share)
+    {
+      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;
+    } else {
+      slot_data->first_alter_share = alter_share;
+    }
+  }
+
   if (tmp_share->wrapper_mode)
   {
     error = wrapper_rename_table(from, to, tmp_share,
@@ -7338,13 +7370,16 @@ int ha_mroonga::rename_table(const char *from, const char *to)
   }
 
   mrn_free_share(tmp_share);
+  if (to_tbl_name[0] != '#')
+  {
 #if MYSQL_VERSION_ID >= 50500
-  mysql_mutex_lock(&LOCK_open);
+    mysql_mutex_lock(&LOCK_open);
 #endif
-  mrn_free_table_share(tmp_table_share);
+    mrn_q_free_table_share(tmp_table_share);
 #if MYSQL_VERSION_ID >= 50500
-  mysql_mutex_unlock(&LOCK_open);
+    mysql_mutex_unlock(&LOCK_open);
 #endif
+  }
   DBUG_RETURN(error);
 }
 

  Modified: ha_mroonga.h (+0 -5)
===================================================================
--- ha_mroonga.h    2011-11-25 13:26:52 +0000 (415a0e0)
+++ ha_mroonga.h    2011-11-26 06:39:01 +0000 (a6ad1d6)
@@ -113,11 +113,6 @@ struct st_mrn_ft_info
   ha_mroonga *mroonga;
 };
 
-struct st_mrn_slot_data
-{
-  grn_id last_insert_record_id;
-};
-
 /* handler class */
 class ha_mroonga: public handler
 {

  Modified: mrn_table.cc (+86 -0)
===================================================================
--- mrn_table.cc    2011-11-25 13:26:52 +0000 (9241622)
+++ mrn_table.cc    2011-11-26 06:39:01 +0000 (47b2517)
@@ -42,6 +42,9 @@
 extern HASH mrn_open_tables;
 extern pthread_mutex_t mrn_open_tables_mutex;
 extern char *mrn_default_parser;
+extern handlerton *mrn_hton_ptr;
+extern HASH mrn_allocated_thds;
+extern pthread_mutex_t mrn_allocated_thds_mutex;
 
 char *mrn_create_string(const char *str, uint length)
 {
@@ -755,6 +758,48 @@ void mrn_free_table_share(TABLE_SHARE *share)
   DBUG_VOID_RETURN;
 }
 
+TABLE_SHARE *mrn_q_get_table_share(TABLE_LIST *table_list, const char *path,
+                                   int *error)
+{
+  uint key_length;
+  TABLE_SHARE *share;
+  THD *thd = current_thd;
+  DBUG_ENTER("mrn_q_get_table_share");
+#if MYSQL_VERSION_ID >= 50603
+  const char *key;
+  key_length = get_table_def_key(table_list, &key);
+#else
+  char key[MAX_DBKEY_LENGTH];
+  key_length = create_table_def_key(thd, key, table_list, FALSE);
+#endif
+#if MYSQL_VERSION_ID >= 50500
+  if (!(share = alloc_table_share(table_list, key, key_length)))
+  {
+    *error = ER_CANT_OPEN_FILE;
+    DBUG_RETURN(NULL);
+  }
+  share->path.str = (char *) path;
+  share->path.length = strlen(path);
+  share->normalized_path.str = share->path.str;
+  share->normalized_path.length = share->path.length;
+  if (open_table_def(thd, share, 0))
+  {
+    *error = ER_CANT_OPEN_FILE;
+    DBUG_RETURN(NULL);
+  }
+#else
+  share = get_table_share(thd, table_list, key, key_length, 0, error);
+#endif
+  DBUG_RETURN(share);
+}
+
+void mrn_q_free_table_share(TABLE_SHARE *share)
+{
+  DBUG_ENTER("mrn_q_free_table_share");
+  share->destroy();
+  DBUG_VOID_RETURN;
+}
+
 KEY *mrn_create_key_info_for_table(MRN_SHARE *share, TABLE *table, int *error)
 {
   uint *wrap_key_nr = share->wrap_key_nr, i, j;
@@ -825,3 +870,44 @@ uint mrn_decode(uchar *buf_st, uchar *buf_ed, const uchar *st, const uchar *ed)
   DBUG_PRINT("info", ("mroonga: out=%s", buf_st));
   DBUG_RETURN(buf - buf_st);
 }
+
+st_mrn_slot_data *mrn_get_slot_data(THD *thd, bool can_create)
+{
+  DBUG_ENTER("mrn_get_slot_data");
+  st_mrn_slot_data *slot_data =
+    (st_mrn_slot_data*) *thd_ha_data(thd, mrn_hton_ptr);
+  if (slot_data == NULL) {
+    slot_data = (st_mrn_slot_data*) malloc(sizeof(st_mrn_slot_data));
+    slot_data->first_alter_share = NULL;
+    *thd_ha_data(thd, mrn_hton_ptr) = (void *) slot_data;
+    pthread_mutex_lock(&mrn_allocated_thds_mutex);
+    if (my_hash_insert(&mrn_allocated_thds, (uchar*) thd))
+    {
+      pthread_mutex_unlock(&mrn_allocated_thds_mutex);
+      free(slot_data);
+      DBUG_RETURN(NULL);
+    }
+    pthread_mutex_unlock(&mrn_allocated_thds_mutex);
+  }
+  DBUG_RETURN(slot_data);
+}
+
+void mrn_clear_alter_share(THD *thd)
+{
+  DBUG_ENTER("mrn_clear_alter_share");
+  st_mrn_slot_data *slot_data = mrn_get_slot_data(thd, FALSE);
+  if (slot_data && slot_data->first_alter_share)
+  {
+    st_mrn_alter_share *tmp_alter_share;
+    st_mrn_alter_share *alter_share = slot_data->first_alter_share;
+    while (alter_share)
+    {
+      tmp_alter_share = alter_share->next;
+      mrn_q_free_table_share(alter_share->alter_share);
+      free(alter_share);
+      alter_share = tmp_alter_share;
+    }
+    slot_data->first_alter_share = NULL;
+  }
+  DBUG_VOID_RETURN;
+}

  Modified: mrn_table.h (+18 -0)
===================================================================
--- mrn_table.h    2011-11-25 13:26:52 +0000 (40d1812)
+++ mrn_table.h    2011-11-26 06:39:01 +0000 (a0509a1)
@@ -51,6 +51,19 @@ typedef struct st_mroonga_share
   bool               wrapper_mode;
 } MRN_SHARE;
 
+struct st_mrn_alter_share
+{
+  char path[FN_REFLEN + 1];
+  TABLE_SHARE *alter_share;
+  st_mrn_alter_share *next;
+};
+
+struct st_mrn_slot_data
+{
+  int last_insert_record_id;
+  st_mrn_alter_share *first_alter_share;
+};
+
 #define MRN_SET_WRAP_SHARE_KEY(share, table_share)
 /*
   table_share->keys = share->wrap_keys; \
@@ -88,9 +101,14 @@ int mrn_free_share_alloc(MRN_SHARE *share);
 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);
+TABLE_SHARE *mrn_q_get_table_share(TABLE_LIST *table_list, const char *path,
+                                   int *error);
+void mrn_q_free_table_share(TABLE_SHARE *share);
 KEY *mrn_create_key_info_for_table(MRN_SHARE *share, TABLE *table, int *error);
 void mrn_set_bitmap_by_key(MY_BITMAP *map, KEY *key_info);
 uint mrn_decode(uchar *buf_st, uchar *buf_ed,
                 const uchar *st, const uchar *ed);
+st_mrn_slot_data *mrn_get_slot_data(THD *thd, bool can_create);
+void mrn_clear_alter_share(THD *thd);
 
 #endif /* _mrn_table_h */




Groonga-mysql-commit メーリングリストの案内
Back to archive index