null+****@clear*****
null+****@clear*****
2011年 10月 3日 (月) 20:04:33 JST
Kouhei Sutou 2011-10-03 11:04:33 +0000 (Mon, 03 Oct 2011) New Revision: 706c5dab126a1caa1931bed21bd610871c48691e Log: [wrapper] support apatial index. But update isn't supported yet. Added files: test/sql/groonga_wrapper/r/geometry_contains.result test/sql/groonga_wrapper/t/geometry_contains.test Modified files: ha_mroonga.cc ha_mroonga.h Modified: ha_mroonga.cc (+107 -71) =================================================================== --- ha_mroonga.cc 2011-10-03 10:24:47 +0000 (3eb160b) +++ ha_mroonga.cc 2011-10-03 11:04:33 +0000 (7f5f7db) @@ -4229,13 +4229,23 @@ int ha_mroonga::wrapper_index_read_map(uchar * buf, const uchar * key, { int error = 0; MRN_DBUG_ENTER_METHOD(); - MRN_SET_WRAP_SHARE_KEY(share, table->s); - MRN_SET_WRAP_TABLE_KEY(this, table); - if (fulltext_searching) - set_pk_bitmap(); - error = wrap_handler->index_read_map(buf, key, keypart_map, find_flag); - MRN_SET_BASE_SHARE_KEY(share, table->s); - MRN_SET_BASE_TABLE_KEY(this, table); + KEY key_info = table->key_info[active_index]; + if (mrn_is_geo_key(&key_info)) { + clear_search_result(); + error = generic_geo_open_cursor(key, find_flag); + if (!error) { + error = wrapper_get_next_record(buf); + } + DBUG_RETURN(error); + } else { + MRN_SET_WRAP_SHARE_KEY(share, table->s); + MRN_SET_WRAP_TABLE_KEY(this, table); + if (fulltext_searching) + set_pk_bitmap(); + error = wrap_handler->index_read_map(buf, key, keypart_map, find_flag); + MRN_SET_BASE_SHARE_KEY(share, table->s); + MRN_SET_BASE_TABLE_KEY(this, table); + } DBUG_RETURN(error); } @@ -4264,7 +4274,10 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key, key, key_length, key_min[active_index], &size_min); } else if (mrn_is_geo_key(&key_info)) { - error = storage_index_read_map_geo(buf, key, find_flag); + error = generic_geo_open_cursor(key, find_flag); + if (!error) { + error = storage_get_next_record(buf); + } DBUG_RETURN(error); } else { KEY_PART_INFO key_part = key_info.key_part[0]; @@ -4343,31 +4356,6 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key, DBUG_RETURN(error); } -int ha_mroonga::storage_index_read_map_geo(uchar *buf, const uchar *key, - enum ha_rkey_function find_flag) -{ - MRN_DBUG_ENTER_METHOD(); - int error = 0; - int flags = 0; - if (find_flag & HA_READ_MBR_CONTAIN) { - result_geo = generic_geo_select_in_rectangle(grn_index_columns[active_index], - key); - // TODO: check result - cursor = grn_table_cursor_open(ctx, result_geo, NULL, 0, NULL, 0, - 0, -1, flags); - } else { - push_warning_unsupported_spatial_index_search(find_flag); - cursor = grn_table_cursor_open(ctx, grn_table, NULL, 0, NULL, 0, - 0, -1, flags); - } - if (ctx->rc) { - my_message(ER_ERROR_ON_READ, ctx->errbuf, MYF(0)); - DBUG_RETURN(ER_ERROR_ON_READ); - } - error = storage_get_next_record(buf); - DBUG_RETURN(error); -} - int ha_mroonga::index_read_map(uchar * buf, const uchar * key, key_part_map keypart_map, enum ha_rkey_function find_flag) @@ -4677,19 +4665,29 @@ int ha_mroonga::index_last(uchar *buf) int ha_mroonga::wrapper_index_next_same(uchar *buf, const uchar *key, uint keylen) { - int error = 0; MRN_DBUG_ENTER_METHOD(); - MRN_SET_WRAP_SHARE_KEY(share, table->s); - MRN_SET_WRAP_TABLE_KEY(this, table); - if (fulltext_searching) - set_pk_bitmap(); + int error = 0; + KEY key_info = table->s->key_info[active_index]; + if (mrn_is_geo_key(&key_info)) { + if (cursor) { + error = wrapper_get_next_record(buf); + } else { + table->status = STATUS_NOT_FOUND; + error = HA_ERR_END_OF_FILE; + } + } else { + MRN_SET_WRAP_SHARE_KEY(share, table->s); + MRN_SET_WRAP_TABLE_KEY(this, table); + if (fulltext_searching) + set_pk_bitmap(); #ifdef MRN_HANDLER_HAVE_HA_INDEX_NEXT_SAME - error = wrap_handler->ha_index_next_same(buf, key, keylen); + error = wrap_handler->ha_index_next_same(buf, key, keylen); #else - error = wrap_handler->index_next_same(buf, key, keylen); + error = wrap_handler->index_next_same(buf, key, keylen); #endif - MRN_SET_BASE_SHARE_KEY(share, table->s); - MRN_SET_BASE_TABLE_KEY(this, table); + MRN_SET_BASE_SHARE_KEY(share, table->s); + MRN_SET_BASE_TABLE_KEY(this, table); + } DBUG_RETURN(error); } @@ -5129,35 +5127,7 @@ FT_INFO *ha_mroonga::ft_init_ext(uint flags, uint key_nr, String *key) int ha_mroonga::wrapper_ft_read(uchar *buf) { MRN_DBUG_ENTER_METHOD(); - int error = 0; - do { - grn_id found_record_id = grn_table_cursor_next(ctx, cursor); - if (found_record_id == GRN_ID_NIL) { - error = HA_ERR_END_OF_FILE; - clear_cursor(); - break; - } else { - GRN_BULK_REWIND(&key_buffer); - grn_obj_get_value(ctx, key_accessor, found_record_id, &key_buffer); - MRN_SET_WRAP_SHARE_KEY(share, table->s); - MRN_SET_WRAP_TABLE_KEY(this, table); -#ifdef MRN_HANDLER_HAVE_HA_INDEX_READ_IDX_MAP - error = wrap_handler->ha_index_read_idx_map(buf, - share->wrap_primary_key, - (uchar *)GRN_TEXT_VALUE(&key_buffer), - pk_keypart_map, - HA_READ_KEY_EXACT); -#else - error = wrap_handler->index_read_idx_map(buf, - share->wrap_primary_key, - (uchar *)GRN_TEXT_VALUE(&key_buffer), - pk_keypart_map, - HA_READ_KEY_EXACT); -#endif - MRN_SET_BASE_SHARE_KEY(share, table->s); - MRN_SET_BASE_TABLE_KEY(this, table); - } - } while (error == HA_ERR_END_OF_FILE); + int error = wrapper_get_next_record(buf); DBUG_RETURN(error); } @@ -5381,6 +5351,48 @@ grn_obj *ha_mroonga::find_tokenizer(const char *name, int name_length) DBUG_RETURN(tokenizer); } +int ha_mroonga::wrapper_get_next_record(uchar *buf) +{ + MRN_DBUG_ENTER_METHOD(); + int error = 0; + do { + grn_id found_record_id = grn_table_cursor_next(ctx, cursor); + if (found_record_id == GRN_ID_NIL) { + error = HA_ERR_END_OF_FILE; + clear_cursor(); + break; + } else { + GRN_BULK_REWIND(&key_buffer); + if (key_accessor) { + grn_obj_get_value(ctx, key_accessor, found_record_id, &key_buffer); + } else { + void *key; + int key_length; + key_length = grn_table_cursor_get_key(ctx, cursor, &key); + GRN_TEXT_SET(ctx, &key_buffer, key, key_length); + } + MRN_SET_WRAP_SHARE_KEY(share, table->s); + MRN_SET_WRAP_TABLE_KEY(this, table); +#ifdef MRN_HANDLER_HAVE_HA_INDEX_READ_IDX_MAP + error = wrap_handler->ha_index_read_idx_map(buf, + share->wrap_primary_key, + (uchar *)GRN_TEXT_VALUE(&key_buffer), + pk_keypart_map, + HA_READ_KEY_EXACT); +#else + error = wrap_handler->index_read_idx_map(buf, + share->wrap_primary_key, + (uchar *)GRN_TEXT_VALUE(&key_buffer), + pk_keypart_map, + HA_READ_KEY_EXACT); +#endif + MRN_SET_BASE_SHARE_KEY(share, table->s); + MRN_SET_BASE_TABLE_KEY(this, table); + } + } while (error == HA_ERR_END_OF_FILE); + DBUG_RETURN(error); +} + int ha_mroonga::storage_get_next_record(uchar *buf) { MRN_DBUG_ENTER_METHOD(); @@ -5452,6 +5464,30 @@ grn_obj *ha_mroonga::generic_geo_select_in_rectangle(grn_obj *index_column, return result; } +int ha_mroonga::generic_geo_open_cursor(const uchar *key, + enum ha_rkey_function find_flag) +{ + MRN_DBUG_ENTER_METHOD(); + int error = 0; + int flags = 0; + if (find_flag & HA_READ_MBR_CONTAIN) { + result_geo = generic_geo_select_in_rectangle(grn_index_columns[active_index], + key); + // TODO: check result + cursor = grn_table_cursor_open(ctx, result_geo, NULL, 0, NULL, 0, + 0, -1, flags); + } else { + push_warning_unsupported_spatial_index_search(find_flag); + cursor = grn_table_cursor_open(ctx, grn_table, NULL, 0, NULL, 0, + 0, -1, flags); + } + if (ctx->rc) { + error = ER_ERROR_ON_READ; + my_message(error, ctx->errbuf, MYF(0)); + } + DBUG_RETURN(error); +} + void ha_mroonga::check_count_skip(key_part_map start_key_part_map, key_part_map end_key_part_map, bool fulltext) { Modified: ha_mroonga.h (+2 -2) =================================================================== --- ha_mroonga.h 2011-10-03 10:24:47 +0000 (5118290) +++ ha_mroonga.h 2011-10-03 11:04:33 +0000 (ccd53a6) @@ -332,9 +332,11 @@ private: void clear_cursor(); void clear_search_result(); grn_obj *find_tokenizer(const char *name, int name_length); + int wrapper_get_next_record(uchar *buf); int storage_get_next_record(uchar *buf); grn_obj *generic_geo_select_in_rectangle(grn_obj *index_column, const uchar *rectangle); + int generic_geo_open_cursor(const uchar *key, enum ha_rkey_function find_flag); #ifdef MRN_HANDLER_HAVE_HA_CLOSE int close(); @@ -451,8 +453,6 @@ private: int storage_index_read_map(uchar *buf, const uchar *key, key_part_map keypart_map, enum ha_rkey_function find_flag); - int storage_index_read_map_geo(uchar *buf, const uchar *key, - enum ha_rkey_function find_flag); int wrapper_index_read_last_map(uchar *buf, const uchar *key, key_part_map keypart_map); int storage_index_read_last_map(uchar *buf, const uchar *key, Added: test/sql/groonga_wrapper/r/geometry_contains.result (+169 -0) 100644 =================================================================== --- /dev/null +++ test/sql/groonga_wrapper/r/geometry_contains.result 2011-10-03 11:04:33 +0000 (dfc4ac4) @@ -0,0 +1,169 @@ +drop table if exists diaries; +create table shops ( +id int primary key auto_increment, +name text, +location geometry NOT NULL, +spatial key location_index (location) +) comment = 'engine "innodb"'; +show create table shops; +Table Create Table +shops CREATE TABLE `shops` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` text, + `location` geometry NOT NULL, + PRIMARY KEY (`id`), + SPATIAL KEY `location_index` (`location`) +) ENGINE=groonga DEFAULT CHARSET=latin1 COMMENT='engine "innodb"' +insert into shops (name, location) +values ('nezu-no-taiyaki', +GeomFromText('POINT(139.762573 35.720253)')); +insert into shops (name, location) +values ('taiyaki-kataoka', +GeomFromText('POINT(139.715591 35.712521)')); +insert into shops (name, location) +values ('soba-taiyaki-ku', +GeomFromText('POINT(139.659088 35.683712)')); +insert into shops (name, location) +values ('kuruma', +GeomFromText('POINT(139.706207 35.721516)')); +insert into shops (name, location) +values ('hirose-ya', +GeomFromText('POINT(139.685608 35.714844)')); +insert into shops (name, location) +values ('sazare', +GeomFromText('POINT(139.685043 35.714653)')); +insert into shops (name, location) +values ('omede-taiyaki', +GeomFromText('POINT(139.817154 35.700516)')); +insert into shops (name, location) +values ('onaga-ya', +GeomFromText('POINT(139.81105 35.698254)')); +insert into shops (name, location) +values ('shiro-ya', +GeomFromText('POINT(139.638611 35.705517)')); +insert into shops (name, location) +values ('fuji-ya', +GeomFromText('POINT(139.637115 35.703938)')); +insert into shops (name, location) +values ('miyoshi', +GeomFromText('POINT(139.537323 35.644539)')); +insert into shops (name, location) +values ('juju-ya', +GeomFromText('POINT(139.695755 35.628922)')); +insert into shops (name, location) +values ('tatsumi-ya', +GeomFromText('POINT(139.638657 35.665501)')); +insert into shops (name, location) +values ('tetsuji', +GeomFromText('POINT(139.76857 35.680912)')); +insert into shops (name, location) +values ('gazuma-ya', +GeomFromText('POINT(139.647598 35.700817)')); +insert into shops (name, location) +values ('honma-mon', +GeomFromText('POINT(139.652573 35.722736)')); +insert into shops (name, location) +values ('naniwa-ya', +GeomFromText('POINT(139.796234 35.730061)')); +insert into shops (name, location) +values ('kuro-dai', +GeomFromText('POINT(139.704834 35.650345)')); +insert into shops (name, location) +values ('daruma', +GeomFromText('POINT(139.770599 35.681461)')); +insert into shops (name, location) +values ('yanagi-ya', +GeomFromText('POINT(139.783981 35.685341)')); +insert into shops (name, location) +values ('sharaku', +GeomFromText('POINT(139.794846 35.716969)')); +insert into shops (name, location) +values ('takane', +GeomFromText('POINT(139.560913 35.698601)')); +insert into shops (name, location) +values ('chiyoda', +GeomFromText('POINT(139.652817 35.642601)')); +insert into shops (name, location) +values ('da-ka-po', +GeomFromText('POINT(139.727356 35.627346)')); +insert into shops (name, location) +values ('matsushima-ya', +GeomFromText('POINT(139.737381 35.640556)')); +insert into shops (name, location) +values ('kazuya', +GeomFromText('POINT(139.760895 35.673508)')); +insert into shops (name, location) +values ('furuya-kogane-an', +GeomFromText('POINT(139.676071 35.680603)')); +insert into shops (name, location) +values ('hachi-no-ie', +GeomFromText('POINT(139.668106 35.608021)')); +insert into shops (name, location) +values ('azuki-chan', +GeomFromText('POINT(139.673203 35.64151)')); +insert into shops (name, location) +values ('kuriko-an', +GeomFromText('POINT(139.796829 35.712013)')); +insert into shops (name, location) +values ('yume-no-aru-machi-no-taiyaki-ya-san', +GeomFromText('POINT(139.712524 35.616199)')); +insert into shops (name, location) +values ('naze-ya', +GeomFromText('POINT(139.665833 35.609039)')); +insert into shops (name, location) +values ('sanoki-ya', +GeomFromText('POINT(139.770721 35.66592)')); +insert into shops (name, location) +values ('shigeta', +GeomFromText('POINT(139.780273 35.672626)')); +insert into shops (name, location) +values ('nishimi-ya', +GeomFromText('POINT(139.774628 35.671825)')); +insert into shops (name, location) +values ('hiiragi', +GeomFromText('POINT(139.711517 35.647701)')); +select id, name, AsText(location) as location_text from shops; +id name location_text +1 nezu-no-taiyaki POINT(139.762573 35.720253) +2 taiyaki-kataoka POINT(139.715591 35.712521) +3 soba-taiyaki-ku POINT(139.659088 35.683712) +4 kuruma POINT(139.706207 35.721516) +5 hirose-ya POINT(139.685608 35.714844) +6 sazare POINT(139.685043 35.714653) +7 omede-taiyaki POINT(139.817154 35.700516) +8 onaga-ya POINT(139.81105 35.698254) +9 shiro-ya POINT(139.638611 35.705517) +10 fuji-ya POINT(139.637115 35.703938) +11 miyoshi POINT(139.537323 35.644539) +12 juju-ya POINT(139.695755 35.628922) +13 tatsumi-ya POINT(139.638657 35.665501) +14 tetsuji POINT(139.76857 35.680912) +15 gazuma-ya POINT(139.647598 35.700817) +16 honma-mon POINT(139.652573 35.722736) +17 naniwa-ya POINT(139.796234 35.730061) +18 kuro-dai POINT(139.704834 35.650345) +19 daruma POINT(139.770599 35.681461) +20 yanagi-ya POINT(139.783981 35.685341) +21 sharaku POINT(139.794846 35.716969) +22 takane POINT(139.560913 35.698601) +23 chiyoda POINT(139.652817 35.642601) +24 da-ka-po POINT(139.727356 35.627346) +25 matsushima-ya POINT(139.737381 35.640556) +26 kazuya POINT(139.760895 35.673508) +27 furuya-kogane-an POINT(139.676071 35.680603) +28 hachi-no-ie POINT(139.668106 35.608021) +29 azuki-chan POINT(139.673203 35.64151) +30 kuriko-an POINT(139.796829 35.712013) +31 yume-no-aru-machi-no-taiyaki-ya-san POINT(139.712524 35.616199) +32 naze-ya POINT(139.665833 35.609039) +33 sanoki-ya POINT(139.770721 35.66592) +34 shigeta POINT(139.780273 35.672626) +35 nishimi-ya POINT(139.774628 35.671825) +36 hiiragi POINT(139.711517 35.647701) +select id, name, AsText(location) as location_text from shops +where MBRContains(GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location); +id name location_text +26 kazuya POINT(139.760895 35.673508) +14 tetsuji POINT(139.76857 35.680912) +19 daruma POINT(139.770599 35.681461) +drop table shops; Added: test/sql/groonga_wrapper/t/geometry_contains.test (+143 -0) 100644 =================================================================== --- /dev/null +++ test/sql/groonga_wrapper/t/geometry_contains.test 2011-10-03 11:04:33 +0000 (75ea56f) @@ -0,0 +1,143 @@ +# 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 diaries; +--enable_warnings + +create table shops ( + id int primary key auto_increment, + name text, + location geometry NOT NULL, + spatial key location_index (location) +) comment = 'engine "innodb"'; +show create table shops; +insert into shops (name, location) + values ('nezu-no-taiyaki', + GeomFromText('POINT(139.762573 35.720253)')); +insert into shops (name, location) + values ('taiyaki-kataoka', + GeomFromText('POINT(139.715591 35.712521)')); +insert into shops (name, location) + values ('soba-taiyaki-ku', + GeomFromText('POINT(139.659088 35.683712)')); +insert into shops (name, location) + values ('kuruma', + GeomFromText('POINT(139.706207 35.721516)')); +insert into shops (name, location) + values ('hirose-ya', + GeomFromText('POINT(139.685608 35.714844)')); +insert into shops (name, location) + values ('sazare', + GeomFromText('POINT(139.685043 35.714653)')); +insert into shops (name, location) + values ('omede-taiyaki', + GeomFromText('POINT(139.817154 35.700516)')); +insert into shops (name, location) + values ('onaga-ya', + GeomFromText('POINT(139.81105 35.698254)')); +insert into shops (name, location) + values ('shiro-ya', + GeomFromText('POINT(139.638611 35.705517)')); +insert into shops (name, location) + values ('fuji-ya', + GeomFromText('POINT(139.637115 35.703938)')); +insert into shops (name, location) + values ('miyoshi', + GeomFromText('POINT(139.537323 35.644539)')); +insert into shops (name, location) + values ('juju-ya', + GeomFromText('POINT(139.695755 35.628922)')); +insert into shops (name, location) + values ('tatsumi-ya', + GeomFromText('POINT(139.638657 35.665501)')); +insert into shops (name, location) + values ('tetsuji', + GeomFromText('POINT(139.76857 35.680912)')); +insert into shops (name, location) + values ('gazuma-ya', + GeomFromText('POINT(139.647598 35.700817)')); +insert into shops (name, location) + values ('honma-mon', + GeomFromText('POINT(139.652573 35.722736)')); +insert into shops (name, location) + values ('naniwa-ya', + GeomFromText('POINT(139.796234 35.730061)')); +insert into shops (name, location) + values ('kuro-dai', + GeomFromText('POINT(139.704834 35.650345)')); +insert into shops (name, location) + values ('daruma', + GeomFromText('POINT(139.770599 35.681461)')); +insert into shops (name, location) + values ('yanagi-ya', + GeomFromText('POINT(139.783981 35.685341)')); +insert into shops (name, location) + values ('sharaku', + GeomFromText('POINT(139.794846 35.716969)')); +insert into shops (name, location) + values ('takane', + GeomFromText('POINT(139.560913 35.698601)')); +insert into shops (name, location) + values ('chiyoda', + GeomFromText('POINT(139.652817 35.642601)')); +insert into shops (name, location) + values ('da-ka-po', + GeomFromText('POINT(139.727356 35.627346)')); +insert into shops (name, location) + values ('matsushima-ya', + GeomFromText('POINT(139.737381 35.640556)')); +insert into shops (name, location) + values ('kazuya', + GeomFromText('POINT(139.760895 35.673508)')); +insert into shops (name, location) + values ('furuya-kogane-an', + GeomFromText('POINT(139.676071 35.680603)')); +insert into shops (name, location) + values ('hachi-no-ie', + GeomFromText('POINT(139.668106 35.608021)')); +insert into shops (name, location) + values ('azuki-chan', + GeomFromText('POINT(139.673203 35.64151)')); +insert into shops (name, location) + values ('kuriko-an', + GeomFromText('POINT(139.796829 35.712013)')); +insert into shops (name, location) + values ('yume-no-aru-machi-no-taiyaki-ya-san', + GeomFromText('POINT(139.712524 35.616199)')); +insert into shops (name, location) + values ('naze-ya', + GeomFromText('POINT(139.665833 35.609039)')); +insert into shops (name, location) + values ('sanoki-ya', + GeomFromText('POINT(139.770721 35.66592)')); +insert into shops (name, location) + values ('shigeta', + GeomFromText('POINT(139.780273 35.672626)')); +insert into shops (name, location) + values ('nishimi-ya', + GeomFromText('POINT(139.774628 35.671825)')); +insert into shops (name, location) + values ('hiiragi', + GeomFromText('POINT(139.711517 35.647701)')); +select id, name, AsText(location) as location_text from shops; +select id, name, AsText(location) as location_text from shops + where MBRContains(GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location); +drop table shops; + +--source suite/groonga_include/groonga_deinit.inc