[Groonga-mysql-commit] mroonga/mroonga [master] [storage] support creating multicolumn index but it's not used yet.

Back to archive index

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




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