[Groonga-mysql-commit] mroonga/mroonga [master] [storage] support read_range_first for multipul column index.

Back to archive index

null+****@clear***** null+****@clear*****
2011年 9月 22日 (木) 19:44:51 JST


Kouhei Sutou	2011-09-22 10:44:51 +0000 (Thu, 22 Sep 2011)

  New Revision: b01c01844c3978c85d1ab2c387442962e0bf670d

  Log:
    [storage] support read_range_first for multipul column index.
    
    refs #455

  Modified files:
    ha_mroonga.cc
    test/sql/groonga_storage/r/multiple_column_index.result

  Modified: ha_mroonga.cc (+70 -36)
===================================================================
--- ha_mroonga.cc    2011-09-22 10:31:13 +0000 (4caa555)
+++ ha_mroonga.cc    2011-09-22 10:44:51 +0000 (3a98a92)
@@ -4052,8 +4052,14 @@ int ha_mroonga::storage_index_first(uchar *buf)
     grn_table_cursor_close(ctx, cur0);
     cur0 = NULL;
   }
+  bool is_multiple_column_index = table->key_info[active_index].key_parts > 1;
   uint pkey_nr = table->s->primary_key;
-  if (active_index == pkey_nr) { // primary index
+  if (is_multiple_column_index) { // primary index
+    DBUG_PRINT("info", ("mroonga use multiple column key"));
+    cur = grn_table_cursor_open(ctx, grn_index_tables[active_index],
+                                NULL, 0, NULL, 0,
+                                0, -1, 0);
+  } else if (active_index == pkey_nr) { // primary index
     DBUG_PRINT("info", ("mroonga use primary key"));
     cur =
       grn_table_cursor_open(ctx, grn_table, NULL, 0, NULL, 0,
@@ -4270,12 +4276,8 @@ int ha_mroonga::storage_read_range_first(const key_range *start_key,
                    end_key ? end_key->keypart_map : 0, FALSE);
   int flags = 0;
   uint size_min = 0, size_max = 0;
-  void *val_min = NULL, *val_max = NULL;
+  const void *val_min = NULL, *val_max = NULL;
   KEY key_info = table->s->key_info[active_index];
-  KEY_PART_INFO key_part = key_info.key_part[0];
-  Field *field = key_part.field;
-  const char *col_name = field->field_name;
-  int col_name_size = strlen(col_name);
 
   if (cur) {
     grn_table_cursor_close(ctx, cur);
@@ -4286,43 +4288,75 @@ int ha_mroonga::storage_read_range_first(const key_range *start_key,
     cur0 = NULL;
   }
 
-  if (start_key != NULL) {
-    mrn_set_key_buf(ctx, field, start_key->key, key_min[active_index],
-                    &size_min);
-    val_min = key_min[active_index];
-    if (start_key->flag == HA_READ_AFTER_KEY) {
-      flags |= GRN_CURSOR_GT;
-    } else if (start_key->flag == HA_READ_KEY_EXACT) {
-      // for _id
-      if (strncmp(MRN_ID_COL_NAME, col_name, col_name_size) == 0) {
-        grn_id found_record_id = *(grn_id *)key_min[active_index];
-        if (grn_table_at(ctx, grn_table, found_record_id) != GRN_ID_NIL) { // found
-          store_fields_from_primary_table(table->record[0], found_record_id);
-          table->status = 0;
-          cur = NULL;
-          record_id = found_record_id;
-          DBUG_RETURN(0);
+  bool is_multiple_column_index = key_info.key_parts > 1;
+  if (is_multiple_column_index) {
+    if (start_key && end_key &&
+        start_key->length == end_key->length &&
+        memcmp(start_key->key, end_key->key, start_key->length) == 0) {
+      flags |= GRN_CURSOR_PREFIX;
+      val_min = start_key->key;
+      size_min = start_key->length;
+    } else {
+      if (start_key) {
+        val_min = start_key->key;
+        size_min = start_key->length;
+      }
+      if (end_key) {
+        val_max = end_key->key;
+        size_max = end_key->length;
+      }
+    }
+  } else {
+    KEY_PART_INFO key_part = key_info.key_part[0];
+    Field *field = key_part.field;
+    const char *col_name = field->field_name;
+    int col_name_size = strlen(col_name);
+    if (start_key) {
+      if (start_key->flag == HA_READ_KEY_EXACT) {
+        // for _id
+        if (strncmp(MRN_ID_COL_NAME, col_name, col_name_size) == 0) {
+          grn_id found_record_id = *(grn_id *)key_min[active_index];
+          if (grn_table_at(ctx, grn_table, found_record_id) != GRN_ID_NIL) { // found
+            store_fields_from_primary_table(table->record[0], found_record_id);
+            table->status = 0;
+            cur = NULL;
+            record_id = found_record_id;
+            DBUG_RETURN(0);
+          } else {
+            table->status = STATUS_NOT_FOUND;
+            cur = NULL;
+            record_id = GRN_ID_NIL;
+            DBUG_RETURN(HA_ERR_END_OF_FILE);
+          }
         } else {
-          table->status = STATUS_NOT_FOUND;
-          cur = NULL;
-          record_id = GRN_ID_NIL;
-          DBUG_RETURN(HA_ERR_END_OF_FILE);
+          mrn_set_key_buf(ctx, field, start_key->key, key_min[active_index],
+                          &size_min);
+          val_min = key_min[active_index];
         }
       }
-
     }
-  }
-  if (end_key != NULL) {
-    mrn_set_key_buf(ctx, field, end_key->key, key_max[active_index],
-      &size_max);
-    val_max = key_max[active_index];
-    if (end_key->flag == HA_READ_BEFORE_KEY) {
-      flags |= GRN_CURSOR_LT;
+    if (end_key) {
+      mrn_set_key_buf(ctx, field, end_key->key, key_max[active_index],
+                      &size_max);
+      val_max = key_max[active_index];
     }
   }
-  uint pkey_nr = table->s->primary_key;
 
-  if (active_index == pkey_nr) { // primary index
+  if (start_key && start_key->flag == HA_READ_AFTER_KEY) {
+    flags |= GRN_CURSOR_GT;
+  }
+  if (end_key && end_key->flag == HA_READ_BEFORE_KEY) {
+    flags |= GRN_CURSOR_LT;
+  }
+
+  uint pkey_nr = table->s->primary_key;
+  if (is_multiple_column_index) { // multiple column index
+    DBUG_PRINT("info", ("mroonga use multiple column key"));
+    cur = grn_table_cursor_open(ctx, grn_index_tables[active_index],
+                                val_min, size_min,
+                                val_max, size_max,
+                                0, -1, flags);
+  } else if (active_index == pkey_nr) { // primary index
     DBUG_PRINT("info", ("mroonga use primary key"));
     cur =
       grn_table_cursor_open(ctx, grn_table, val_min, size_min, val_max, size_max,

  Modified: test/sql/groonga_storage/r/multiple_column_index.result (+1 -1)
===================================================================
--- test/sql/groonga_storage/r/multiple_column_index.result    2011-09-22 10:31:13 +0000 (25d06ba)
+++ test/sql/groonga_storage/r/multiple_column_index.result    2011-09-22 10:44:51 +0000 (2584c6d)
@@ -27,9 +27,9 @@ id	last_name	first_name
 4	Taro	Tanaka
 select * from listing where last_name = "Taro";
 id	last_name	first_name
-1	Taro	Yamada
 2	Taro	Suzuki
 4	Taro	Tanaka
+1	Taro	Yamada
 select * from listing where last_name = "Taro" and first_name = "Suzuki";
 id	last_name	first_name
 2	Taro	Suzuki




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