[Groonga-mysql-commit] mroonga/mroonga [master] [storage] support multiple colum index update.

Zurück zum Archiv-Index

null+****@clear***** null+****@clear*****
2011年 9月 23日 (金) 23:22:39 JST


Kouhei Sutou	2011-09-23 14:22:39 +0000 (Fri, 23 Sep 2011)

  New Revision: b268ab84df2ed5ab09572ad95d5547c4fa4a61c5

  Log:
    [storage] support multiple colum index update.
    
    refs #455

  Added files:
    test/sql/groonga_storage/r/multiple_column_index_update.result
    test/sql/groonga_storage/t/multiple_column_index_update.test
  Modified files:
    ha_mroonga.cc
    ha_mroonga.h

  Modified: ha_mroonga.cc (+91 -1)
===================================================================
--- ha_mroonga.cc    2011-09-23 14:21:03 +0000 (87c14e3)
+++ ha_mroonga.cc    2011-09-23 14:22:39 +0000 (bde7274)
@@ -3415,6 +3415,8 @@ err:
 int ha_mroonga::storage_update_row(const uchar *old_data, uchar *new_data)
 {
   MRN_DBUG_ENTER_METHOD();
+  int error;
+
   grn_obj colbuf;
   int i, col_size;
   int n_columns = table->s->fields;
@@ -3487,7 +3489,95 @@ int ha_mroonga::storage_update_row(const uchar *old_data, uchar *new_data)
     }
   }
   grn_obj_unlink(ctx, &colbuf);
-  DBUG_RETURN(0);
+
+  error = storage_update_row_index(old_data, new_data);
+
+  DBUG_RETURN(error);
+}
+
+int ha_mroonga::storage_update_row_index(const uchar *old_data, uchar *new_data)
+{
+  MRN_DBUG_ENTER_METHOD();
+  int error;
+
+  grn_obj old_key, old_encoded_key, new_key, new_encoded_key;
+  GRN_TEXT_INIT(&old_key, 0);
+  GRN_TEXT_INIT(&old_encoded_key, 0);
+  GRN_TEXT_INIT(&new_key, 0);
+  GRN_TEXT_INIT(&new_encoded_key, 0);
+
+  my_ptrdiff_t ptr_diff = PTR_BYTE_DIFF(old_data, table->record[0]);
+
+#ifndef DBUG_OFF
+  my_bitmap_map *tmp_map = dbug_tmp_use_all_columns(table, table->read_set);
+#endif
+  uint i;
+  uint n_keys = table->s->keys;
+  for (i = 0; i < n_keys; i++) {
+    KEY key_info = table->key_info[i];
+
+    if (key_info.key_parts == 1) {
+      continue;
+    }
+
+    GRN_BULK_REWIND(&old_key);
+    grn_bulk_space(ctx, &old_key, key_info.key_length);
+    for (int j = 0; j < key_info.key_parts; 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 (int j = 0; j < key_info.key_parts; 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);
+    uint old_encoded_key_length;
+    mrn_multiple_column_key_encode(&key_info,
+                                   (uchar *)(GRN_TEXT_VALUE(&old_key)),
+                                   key_info.key_length,
+                                   (uchar *)(GRN_TEXT_VALUE(&old_encoded_key)),
+                                   &old_encoded_key_length);
+
+    GRN_BULK_REWIND(&new_key);
+    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);
+    GRN_BULK_REWIND(&new_encoded_key);
+    grn_bulk_space(ctx, &new_encoded_key, key_info.key_length);
+    uint new_encoded_key_length;
+    mrn_multiple_column_key_encode(&key_info,
+                                   (uchar *)(GRN_TEXT_VALUE(&new_key)),
+                                   key_info.key_length,
+                                   (uchar *)(GRN_TEXT_VALUE(&new_encoded_key)),
+                                   &new_encoded_key_length);
+
+    grn_obj *index_column = grn_index_columns[i];
+    grn_rc rc;
+    rc = grn_column_index_update(ctx, index_column, record_id, 1,
+                                 &old_encoded_key, &new_encoded_key);
+    if (rc) {
+      error = ER_ERROR_ON_WRITE;
+      my_message(error, ctx->errbuf, MYF(0));
+      goto err;
+    }
+  }
+err:
+#ifndef DBUG_OFF
+  dbug_tmp_restore_column_map(table->read_set, tmp_map);
+#endif
+  grn_obj_unlink(ctx, &old_key);
+  grn_obj_unlink(ctx, &old_encoded_key);
+  grn_obj_unlink(ctx, &new_key);
+  grn_obj_unlink(ctx, &new_encoded_key);
+
+  DBUG_RETURN(error);
 }
 
 int ha_mroonga::update_row(const uchar *old_data, uchar *new_data)

  Modified: ha_mroonga.h (+1 -0)
===================================================================
--- ha_mroonga.h    2011-09-23 14:21:03 +0000 (ba8dcff)
+++ ha_mroonga.h    2011-09-23 14:22:39 +0000 (0d7420a)
@@ -391,6 +391,7 @@ private:
   int wrapper_update_row(const uchar *old_data, uchar *new_data);
   int wrapper_update_row_index(const uchar *old_data, uchar *new_data);
   int storage_update_row(const uchar *old_data, uchar *new_data);
+  int storage_update_row_index(const uchar *old_data, uchar *new_data);
   int wrapper_delete_row(const uchar *buf);
   int wrapper_delete_row_index(const uchar *buf);
   int storage_delete_row(const uchar *buf);

  Added: test/sql/groonga_storage/r/multiple_column_index_update.result (+34 -0) 100644
===================================================================
--- /dev/null
+++ test/sql/groonga_storage/r/multiple_column_index_update.result    2011-09-23 14:22:39 +0000 (fc43237)
@@ -0,0 +1,34 @@
+drop table if exists listing;
+set names utf8;
+create table scores (
+id int primary key auto_increment not null,
+name char(30) not null,
+score int not null,
+index property (name, score)
+) default charset utf8;
+show create table scores;
+Table	Create Table
+scores	CREATE TABLE `scores` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `name` char(30) NOT NULL,
+  `score` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `property` (`name`,`score`)
+) ENGINE=groonga DEFAULT CHARSET=utf8
+insert into scores (name, score) values("Taro Yamada", 29);
+insert into scores (name, score) values("Taro Yamada", -12);
+insert into scores (name, score) values("Jiro Yamada", 27);
+insert into scores (name, score) values("Taro Yamada", 10);
+select * from scores;
+id	name	score
+1	Taro Yamada	29
+2	Taro Yamada	-12
+3	Jiro Yamada	27
+4	Taro Yamada	10
+update scores set name = "Taro Yamada" where name = "Jiro Yamada" and score = 27;
+select * from scores where name = "Taro Yamada" and (score >= -12 and score < 29);
+id	name	score
+2	Taro Yamada	-12
+4	Taro Yamada	10
+3	Taro Yamada	27
+drop table scores;

  Added: test/sql/groonga_storage/t/multiple_column_index_update.test (+40 -0) 100644
===================================================================
--- /dev/null
+++ test/sql/groonga_storage/t/multiple_column_index_update.test    2011-09-23 14:22:39 +0000 (02ee4e3)
@@ -0,0 +1,40 @@
+# Copyright(C) 2011 Kouhei Sutou <kou****@clear*****>
+#
+# 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
+
+--source suite/groonga_include/groonga_init.inc
+
+--disable_warnings
+drop table if exists listing;
+--enable_warnings
+
+set names utf8;
+create table scores (
+  id int primary key auto_increment not null,
+  name char(30) not null,
+  score int not null,
+  index property (name, score)
+) default charset utf8;
+show create table scores;
+insert into scores (name, score) values("Taro Yamada", 29);
+insert into scores (name, score) values("Taro Yamada", -12);
+insert into scores (name, score) values("Jiro Yamada", 27);
+insert into scores (name, score) values("Taro Yamada", 10);
+select * from scores;
+update scores set name = "Taro Yamada" where name = "Jiro Yamada" and score = 27;
+select * from scores where name = "Taro Yamada" and (score >= -12 and score < 29);
+drop table scores;
+
+--source suite/groonga_include/groonga_deinit.inc




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