[Groonga-mysql-commit] mroonga/mroonga [master] support fulltext search in sub query.

Back to archive index

null+****@clear***** null+****@clear*****
2012年 2月 4日 (土) 21:47:00 JST


Kouhei Sutou	2012-02-04 21:47:00 +0900 (Sat, 04 Feb 2012)

  New Revision: 32e51cd83ad7e13b4394f70f109859cb95c5af45

  Log:
    support fulltext search in sub query.
    
    This change also fixes
    http://deverock.in/knowledge/1079517145/ERROR%201024%20%28HY000%29%3A%20tc%20is%20null
    
    Reported by @camyuy. Thanks!!!

  Added files:
    test/sql/suite/mroonga_storage/r/sub_query_fulltext.result
    test/sql/suite/mroonga_storage/t/sub_query_fulltext.test
  Modified files:
    ha_mroonga.cc
    ha_mroonga.h

  Modified: ha_mroonga.cc (+34 -30)
===================================================================
--- ha_mroonga.cc    2012-02-03 22:05:02 +0900 (434a0fc)
+++ ha_mroonga.cc    2012-02-04 21:47:00 +0900 (4770807)
@@ -1697,6 +1697,7 @@ ha_mroonga::ha_mroonga(handlerton *hton, TABLE_SHARE *share_arg)
   share = NULL;
   is_clone = FALSE;
   wrap_handler = NULL;
+  sorted_result = NULL;
   matched_record_keys = NULL;
   fulltext_searching = FALSE;
   mrn_lock_type = F_UNLCK;
@@ -3611,7 +3612,7 @@ int ha_mroonga::wrapper_rnd_end()
 int ha_mroonga::storage_rnd_end()
 {
   MRN_DBUG_ENTER_METHOD();
-  clear_search_result();
+  clear_cursor();
   DBUG_RETURN(0);
 }
 
@@ -5044,8 +5045,8 @@ int ha_mroonga::wrapper_index_end()
 int ha_mroonga::storage_index_end()
 {
   MRN_DBUG_ENTER_METHOD();
-  clear_search_result();
-  clear_search_result_geo();
+  clear_cursor();
+  clear_cursor_geo();
   DBUG_RETURN(0);
 }
 
@@ -5108,8 +5109,8 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
   uint size_min = 0, size_max = 0;
   const void *val_min = NULL, *val_max = NULL;
 
-  clear_search_result();
-  clear_search_result_geo();
+  clear_cursor();
+  clear_cursor_geo();
 
   bool is_multiple_column_index = key_info.key_parts > 1;
   if (is_multiple_column_index) {
@@ -5252,7 +5253,7 @@ int ha_mroonga::storage_index_read_last_map(uchar *buf, const uchar *key,
   uint size_min = 0, size_max = 0;
   const void *val_min = NULL, *val_max = NULL;
 
-  clear_search_result();
+  clear_cursor();
 
   bool is_multiple_column_index = key_info.key_parts > 1;
   if (is_multiple_column_index) {
@@ -5426,7 +5427,7 @@ int ha_mroonga::wrapper_index_first(uchar *buf)
 int ha_mroonga::storage_index_first(uchar *buf)
 {
   MRN_DBUG_ENTER_METHOD();
-  clear_search_result();
+  clear_cursor();
   int flags = GRN_CURSOR_ASCENDING;
   uint pkey_nr = table->s->primary_key;
   mrn_change_encoding(ctx, NULL);
@@ -5491,7 +5492,7 @@ int ha_mroonga::wrapper_index_last(uchar *buf)
 int ha_mroonga::storage_index_last(uchar *buf)
 {
   MRN_DBUG_ENTER_METHOD();
-  clear_search_result();
+  clear_cursor();
   int flags = GRN_CURSOR_DESCENDING;
   uint pkey_nr = table->s->primary_key;
   mrn_change_encoding(ctx, NULL);
@@ -5619,7 +5620,7 @@ int ha_mroonga::storage_read_range_first(const key_range *start_key,
   const void *val_min = NULL, *val_max = NULL;
   KEY key_info = table->s->key_info[active_index];
 
-  clear_search_result();
+  clear_cursor();
 
   bool is_multiple_column_index = key_info.key_parts > 1;
   if (is_multiple_column_index) {
@@ -5788,13 +5789,28 @@ int ha_mroonga::generic_ft_init()
   MRN_DBUG_ENTER_METHOD();
   int error = 0;
   mrn_change_encoding(ctx, NULL);
-  if (!cursor) {
+  if (sorted_result) {
+    cursor = grn_table_cursor_open(ctx, sorted_result,
+                                   NULL, 0, NULL, 0,
+                                   0, -1, 0);
+  } else {
     cursor = grn_table_cursor_open(ctx, matched_record_keys, NULL, 0, NULL, 0, 0,
                                    -1, 0);
-    if (ctx->rc)
-    {
-      error = ER_ERROR_ON_READ;
-      my_message(error, ctx->errbuf, MYF(0));
+  }
+  if (ctx->rc) {
+    error = ER_ERROR_ON_READ;
+    my_message(error, ctx->errbuf, MYF(0));
+  } else {
+    if (sorted_result) {
+      if (grn_table->header.type == GRN_TABLE_NO_KEY) {
+        id_accessor = grn_obj_column(ctx, sorted_result,
+                                     MRN_COLUMN_NAME_ID,
+                                     strlen(MRN_COLUMN_NAME_ID));
+      } else {
+        key_accessor = grn_obj_column(ctx, sorted_result,
+                                      MRN_COLUMN_NAME_KEY,
+                                      strlen(MRN_COLUMN_NAME_KEY));
+      }
     } else {
       key_accessor = grn_obj_column(ctx, matched_record_keys,
                                     MRN_COLUMN_NAME_KEY,
@@ -6075,18 +6091,7 @@ FT_INFO *ha_mroonga::generic_ft_init_ext(uint flags, uint key_nr, String *key)
                                            info->result);
     grn_table_sort(ctx, info->result, 0, limit, info->sorted_result,
                    sort_keys, n_sort_keys);
-    cursor = grn_table_cursor_open(ctx, info->sorted_result,
-                                   NULL, 0, NULL, 0,
-                                   0, -1, 0);
-    if (grn_table->header.type == GRN_TABLE_NO_KEY) {
-      id_accessor = grn_obj_column(ctx, info->sorted_result,
-                                   MRN_COLUMN_NAME_ID,
-                                   strlen(MRN_COLUMN_NAME_ID));
-    } else {
-      key_accessor = grn_obj_column(ctx, info->sorted_result,
-                                    MRN_COLUMN_NAME_KEY,
-                                    strlen(MRN_COLUMN_NAME_KEY));
-    }
+    sorted_result = info->sorted_result;
   } else {
     merge_matched_record_keys(info->result);
   }
@@ -6156,7 +6161,6 @@ int ha_mroonga::storage_ft_read(uchar *buf)
   found_record_id = grn_table_cursor_next(ctx, cursor);
   if (ctx->rc) {
     my_message(ER_ERROR_ON_READ, ctx->errbuf, MYF(0));
-    clear_search_result();
     DBUG_RETURN(ER_ERROR_ON_READ);
   }
 
@@ -6187,7 +6191,6 @@ int ha_mroonga::storage_ft_read(uchar *buf)
     if (ctx->rc) {
       record_id = GRN_ID_NIL;
       my_message(ER_ERROR_ON_READ, ctx->errbuf, MYF(0));
-      clear_search_result();
       DBUG_RETURN(ER_ERROR_ON_READ);
     } else {
       record_id = *((grn_id *)key);
@@ -6364,6 +6367,9 @@ void ha_mroonga::clear_search_result()
 {
   MRN_DBUG_ENTER_METHOD();
   clear_cursor();
+  if (sorted_result) {
+    sorted_result = NULL;
+  }
   if (matched_record_keys) {
     grn_obj_unlink(ctx, matched_record_keys);
     matched_record_keys = NULL;
@@ -6592,8 +6598,6 @@ int ha_mroonga::storage_get_next_record(uchar *buf)
   if (ctx->rc) {
     int error = ER_ERROR_ON_READ;
     my_message(error, ctx->errbuf, MYF(0));
-    clear_search_result();
-    clear_search_result_geo();
     DBUG_RETURN(error);
   }
   if (record_id == GRN_ID_NIL) {

  Modified: ha_mroonga.h (+1 -0)
===================================================================
--- ha_mroonga.h    2012-02-03 22:05:02 +0900 (8d8855d)
+++ ha_mroonga.h    2012-02-04 21:47:00 +0900 (1b78e81)
@@ -184,6 +184,7 @@ private:
   grn_obj *id_accessor;
   grn_obj *key_accessor;
 
+  grn_obj *sorted_result;
   grn_obj *matched_record_keys;
 
   uchar **key_min;

  Added: test/sql/suite/mroonga_storage/r/sub_query_fulltext.result (+44 -0) 100644
===================================================================
--- /dev/null
+++ test/sql/suite/mroonga_storage/r/sub_query_fulltext.result    2012-02-04 21:47:00 +0900 (659e776)
@@ -0,0 +1,44 @@
+DROP TABLE IF EXISTS diaries, users;
+CREATE TABLE users (
+id INT PRIMARY KEY AUTO_INCREMENT,
+name TEXT
+) DEFAULT CHARSET UTF8;
+CREATE TABLE diaries (
+id INT PRIMARY KEY AUTO_INCREMENT,
+user_id INT UNSIGNED NOT NULL,
+title TEXT,
+FULLTEXT INDEX (title)
+) DEFAULT CHARSET UTF8;
+SHOW CREATE TABLE diaries;
+Table	Create Table
+diaries	CREATE TABLE `diaries` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `user_id` int(10) unsigned NOT NULL,
+  `title` text,
+  PRIMARY KEY (`id`),
+  FULLTEXT KEY `title` (`title`)
+) ENGINE=mroonga DEFAULT CHARSET=utf8
+INSERT INTO users (name) VALUES ("alice");
+INSERT INTO users (name) VALUES ("bob");
+INSERT INTO users (name) VALUES ("carlos");
+SELECT * FROM users;
+id	name
+1	alice
+2	bob
+3	carlos
+INSERT INTO diaries (user_id, title) VALUES (1, "Hello!");
+INSERT INTO diaries (user_id, title) VALUES (2, "my name is bob");
+INSERT INTO diaries (user_id, title) VALUES (3, "my name is carlos");
+SELECT * FROM diaries;
+id	user_id	title
+1	1	Hello!
+2	2	my name is bob
+3	3	my name is carlos
+SELECT * FROM users
+WHERE id IN (SELECT user_id FROM diaries
+WHERE MATCH(title) AGAINST("name"))
+ORDER BY id DESC;
+id	name
+3	carlos
+2	bob
+DROP TABLE diaries, users;

  Added: test/sql/suite/mroonga_storage/t/sub_query_fulltext.test (+55 -0) 100644
===================================================================
--- /dev/null
+++ test/sql/suite/mroonga_storage/t/sub_query_fulltext.test    2012-02-04 21:47:00 +0900 (35f1dd7)
@@ -0,0 +1,55 @@
+# Copyright(C) 2012 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 include/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS diaries, users;
+--enable_warnings
+
+CREATE TABLE users (
+  id INT PRIMARY KEY AUTO_INCREMENT,
+  name TEXT
+) DEFAULT CHARSET UTF8;
+
+CREATE TABLE diaries (
+  id INT PRIMARY KEY AUTO_INCREMENT,
+  user_id INT UNSIGNED NOT NULL,
+  title TEXT,
+  FULLTEXT INDEX (title)
+) DEFAULT CHARSET UTF8;
+SHOW CREATE TABLE diaries;
+
+INSERT INTO users (name) VALUES ("alice");
+INSERT INTO users (name) VALUES ("bob");
+INSERT INTO users (name) VALUES ("carlos");
+
+SELECT * FROM users;
+
+INSERT INTO diaries (user_id, title) VALUES (1, "Hello!");
+INSERT INTO diaries (user_id, title) VALUES (2, "my name is bob");
+INSERT INTO diaries (user_id, title) VALUES (3, "my name is carlos");
+
+SELECT * FROM diaries;
+
+SELECT * FROM users
+         WHERE id IN (SELECT user_id FROM diaries
+                                     WHERE MATCH(title) AGAINST("name"))
+         ORDER BY id DESC;
+
+DROP TABLE diaries, users;
+
+--source include/have_mroonga_deinit.inc




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