null+****@clear*****
null+****@clear*****
2011年 9月 22日 (木) 12:49:04 JST
Kouhei Sutou 2011-09-22 03:49:04 +0000 (Thu, 22 Sep 2011)
New Revision: c1bf2895ae85744390e8c5ad8ea75538c8ac1691
Log:
[storage] support creating multicolumn index but it's not used yet.
refs #455
Added files:
test/sql/groonga_storage/r/multiple_column_index.result
test/sql/groonga_storage/t/multiple_column_index.test
Modified files:
ha_mroonga.cc
Modified: ha_mroonga.cc (+42 -44)
===================================================================
--- ha_mroonga.cc 2011-09-22 02:29:19 +0000 (c4b5ebe)
+++ ha_mroonga.cc 2011-09-22 03:49:04 +0000 (357ea5c)
@@ -1423,23 +1423,22 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
uint pkey_nr = table->s->primary_key;
if (pkey_nr != MAX_INDEXES) {
KEY key_info = table->s->key_info[pkey_nr];
+ bool is_id;
- // surpose simgle column key
int key_parts = key_info.key_parts;
- if (key_parts != 1) {
- GRN_LOG(ctx, GRN_LOG_ERROR, "complex key is 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;
- int col_name_size = strlen(col_name);
- bool is_id = (strncmp(MRN_ID_COL_NAME, col_name, col_name_size) == 0);
+ if (key_parts == 1) {
+ Field *pkey_field = key_info.key_part[0].field;
+ const char *col_name = pkey_field->field_name;
+ int col_name_size = strlen(col_name);
+ is_id = (strncmp(MRN_ID_COL_NAME, col_name, col_name_size) == 0);
- int mysql_field_type = pkey_field->type();
- grn_builtin_type gtype = mrn_get_type(ctx, mysql_field_type);
- pkey_type = grn_ctx_at(ctx, gtype);
+ int mysql_field_type = pkey_field->type();
+ grn_builtin_type gtype = mrn_get_type(ctx, mysql_field_type);
+ pkey_type = grn_ctx_at(ctx, gtype);
+ } else {
+ is_id = false;
+ pkey_type = grn_ctx_at(ctx, GRN_DB_SHORT_TEXT);
+ }
// default algorithm is BTREE ==> PAT
if (!is_id && key_info.algorithm == HA_KEY_ALG_HASH) {
@@ -1511,33 +1510,32 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
continue; // pkey is already handled
}
- grn_obj *idx_tbl_obj, *idx_col_obj, *col_obj, *col_type, buf;
+ grn_obj *idx_tbl_obj, *idx_col_obj;
+ grn_obj *column = NULL;
+ grn_obj *index_type = NULL;
KEY key_info = table->s->key_info[i];
- // must be single column key
int key_parts = key_info.key_parts;
- if (key_parts != 1) {
- GRN_LOG(ctx, GRN_LOG_ERROR, "complex key is not supported yet");
- error = ER_NOT_SUPPORTED_YET;
- my_message(error, "complex key is not supported yet.", MYF(0));
- DBUG_RETURN(error);
- }
-
- mrn_index_table_name_gen(tbl_name, key_info.name, idx_name);
+ if (key_parts == 1) {
+ Field *field = key_info.key_part[0].field;
+ const char *column_name = field->field_name;
+ int column_name_size = strlen(column_name);
- Field *field = key_info.key_part[0].field;
- const char *col_name = field->field_name;
- int col_name_size = strlen(col_name);
+ if (strncmp(MRN_ID_COL_NAME, column_name, column_name_size) == 0) {
+ // skipping _id virtual column
+ continue;
+ }
- if (strncmp(MRN_ID_COL_NAME, col_name, col_name_size) == 0) {
- // skipping _id virtual column
- continue;
+ column = grn_obj_column(ctx, tbl_obj, column_name, column_name_size);
+ int mysql_field_type = field->type();
+ grn_builtin_type groonga_type = mrn_get_type(ctx, mysql_field_type);
+ index_type = grn_ctx_at(ctx, groonga_type);
+ } else {
+ index_type = grn_ctx_at(ctx, GRN_DB_TEXT);
}
- col_obj = grn_obj_column(ctx, tbl_obj, col_name, col_name_size);
- int mysql_field_type = field->type();
- grn_builtin_type gtype = mrn_get_type(ctx, mysql_field_type);
- col_type = grn_ctx_at(ctx, gtype);
+ mrn_index_table_name_gen(tbl_name, key_info.name, idx_name);
+
grn_obj_flags idx_col_flags =
GRN_OBJ_COLUMN_INDEX | GRN_OBJ_WITH_POSITION | GRN_OBJ_PERSISTENT;
@@ -1552,7 +1550,7 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
}
idx_tbl_obj = grn_table_create(ctx, idx_name, strlen(idx_name), NULL,
- idx_tbl_flags, col_type, 0);
+ idx_tbl_flags, index_type, 0);
if (ctx->rc) {
grn_obj_remove(ctx, tbl_obj);
error = ER_CANT_CREATE_TABLE;
@@ -1582,11 +1580,14 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
DBUG_RETURN(error);
}
- grn_id gid = grn_obj_id(ctx, col_obj);
- GRN_TEXT_INIT(&buf, 0);
- GRN_TEXT_SET(ctx, &buf, (char*) &gid, sizeof(grn_id));
- grn_obj_set_info(ctx, idx_col_obj, GRN_INFO_SOURCE, &buf);
- grn_obj_unlink(ctx, &buf);
+ if (column) {
+ grn_obj source_ids;
+ grn_id source_id = grn_obj_id(ctx, column);
+ GRN_UINT32_INIT(&source_ids, GRN_OBJ_VECTOR);
+ GRN_UINT32_PUT(ctx, &source_ids, source_id);
+ grn_obj_set_info(ctx, idx_col_obj, GRN_INFO_SOURCE, &source_ids);
+ grn_obj_unlink(ctx, &source_ids);
+ }
}
/* clean up */
@@ -1649,10 +1650,7 @@ int ha_mroonga::storage_create_validate_index(TABLE *table)
// must be single column key
int key_parts = key_info.key_parts;
if (key_parts != 1) {
- GRN_LOG(ctx, GRN_LOG_ERROR, "complex key is not supported yet");
- error = ER_NOT_SUPPORTED_YET;
- my_message(error, "complex key is not supported yet.", MYF(0));
- DBUG_RETURN(error);
+ continue;
}
Field *field = key_info.key_part[0].field;
const char *col_name = field->field_name;
Added: test/sql/groonga_storage/r/multiple_column_index.result (+40 -0) 100644
===================================================================
--- /dev/null
+++ test/sql/groonga_storage/r/multiple_column_index.result 2011-09-22 03:49:04 +0000 (25d06ba)
@@ -0,0 +1,40 @@
+drop table if exists listing;
+set names utf8;
+create table listing (
+id int primary key auto_increment not null,
+last_name char(30) not null,
+first_name char(30) not null,
+index name (last_name, first_name)
+) default charset utf8;
+show create table listing;
+Table Create Table
+listing CREATE TABLE `listing` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `last_name` char(30) NOT NULL,
+ `first_name` char(30) NOT NULL,
+ PRIMARY KEY (`id`),
+ KEY `name` (`last_name`,`first_name`)
+) ENGINE=groonga DEFAULT CHARSET=utf8
+insert into listing (last_name, first_name) values("Taro", "Yamada");
+insert into listing (last_name, first_name) values("Taro", "Suzuki");
+insert into listing (last_name, first_name) values("Jiro", "Yamada");
+insert into listing (last_name, first_name) values("Taro", "Tanaka");
+select * from listing;
+id last_name first_name
+1 Taro Yamada
+2 Taro Suzuki
+3 Jiro Yamada
+4 Taro Tanaka
+select * from listing where last_name = "Taro";
+id last_name first_name
+1 Taro Yamada
+2 Taro Suzuki
+4 Taro Tanaka
+select * from listing where last_name = "Taro" and first_name = "Suzuki";
+id last_name first_name
+2 Taro Suzuki
+select * from listing where last_name = "Taro" and (first_name >= "S" and first_name <= "Y");
+id last_name first_name
+2 Taro Suzuki
+4 Taro Tanaka
+drop table listing;
Added: test/sql/groonga_storage/t/multiple_column_index.test (+41 -0) 100644
===================================================================
--- /dev/null
+++ test/sql/groonga_storage/t/multiple_column_index.test 2011-09-22 03:49:04 +0000 (b9f7d03)
@@ -0,0 +1,41 @@
+# 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 listing (
+ id int primary key auto_increment not null,
+ last_name char(30) not null,
+ first_name char(30) not null,
+ index name (last_name, first_name)
+) default charset utf8;
+show create table listing;
+insert into listing (last_name, first_name) values("Taro", "Yamada");
+insert into listing (last_name, first_name) values("Taro", "Suzuki");
+insert into listing (last_name, first_name) values("Jiro", "Yamada");
+insert into listing (last_name, first_name) values("Taro", "Tanaka");
+select * from listing;
+select * from listing where last_name = "Taro";
+select * from listing where last_name = "Taro" and first_name = "Suzuki";
+select * from listing where last_name = "Taro" and (first_name >= "S" and first_name <= "Y");
+drop table listing;
+
+--source suite/groonga_include/groonga_deinit.inc