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