[Groonga-mysql-commit] mroonga/mroonga [master] storage: support index search for 0 value

Back to archive index

null+****@clear***** null+****@clear*****
2012年 3月 27日 (火) 17:06:49 JST


Kouhei Sutou	2012-03-27 17:06:49 +0900 (Tue, 27 Mar 2012)

  New Revision: 8d0c97d062b12c35104b867dc2bdf1d89048ad78

  Log:
    storage: support index search for 0 value
    
    It's just a workaround. If groonga supports null value, we should use
    it and drop this workaround.
    
    Reported by @104yuki_n. Thanks!!!

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

  Modified: ha_mroonga.cc (+29 -0)
===================================================================
--- ha_mroonga.cc    2012-03-27 14:44:11 +0900 (1ddb8af)
+++ ha_mroonga.cc    2012-03-27 17:06:49 +0900 (2ea6ef9)
@@ -4465,6 +4465,16 @@ int ha_mroonga::storage_write_row(uchar *buf)
       goto err2;
     }
     generic_store_bulk(field, &colbuf);
+    if (added && is_grn_zero_column_value(grn_columns[i], &colbuf)) {
+      // WORKAROUND: groonga can't index newly added '0' value for
+      // fix size column. So we add non-'0' value first then add
+      // real '0' value again. It will be removed when groonga
+      // supports 'null' value.
+      char *bytes = GRN_BULK_HEAD(&colbuf);
+      bytes[0] = '\1';
+      grn_obj_set_value(ctx, grn_columns[i], record_id, &colbuf, GRN_OBJ_SET);
+      bytes[0] = '\0';
+    }
     grn_obj_set_value(ctx, grn_columns[i], record_id, &colbuf, GRN_OBJ_SET);
     if (ctx->rc) {
 #ifndef DBUG_OFF
@@ -7681,6 +7691,25 @@ bool ha_mroonga::is_fulltext_search_item(const Item *item)
   DBUG_RETURN(true);
 }
 
+bool ha_mroonga::is_grn_zero_column_value(grn_obj *column, grn_obj *value)
+{
+  MRN_DBUG_ENTER_METHOD();
+
+  if (column->header.type != GRN_COLUMN_FIX_SIZE) {
+    DBUG_RETURN(false);
+  }
+
+  char *bytes = GRN_BULK_HEAD(value);
+  unsigned int size = GRN_BULK_VSIZE(value);
+  for (unsigned int i = 0; i < size; ++i) {
+    if (bytes[i] != '\0') {
+      DBUG_RETURN(false);
+    }
+  }
+
+  DBUG_RETURN(true);
+}
+
 void ha_mroonga::check_fast_order_limit(grn_table_sort_key **sort_keys,
                                         int *n_sort_keys,
                                         longlong *limit,

  Modified: ha_mroonga.h (+1 -0)
===================================================================
--- ha_mroonga.h    2012-03-27 14:44:11 +0900 (f9efe52)
+++ ha_mroonga.h    2012-03-27 17:06:49 +0900 (01bbabe)
@@ -460,6 +460,7 @@ private:
   bool is_groonga_layer_condition(const Item *item,
                                   const Item_func **match_against=NULL);
   bool is_fulltext_search_item(const Item *item);
+  bool is_grn_zero_column_value(grn_obj *column, grn_obj *value);
   void check_fast_order_limit(grn_table_sort_key **sort_keys, int *n_sort_keys,
                               longlong *limit,
                               grn_obj *target_table, grn_obj *score_column);

  Added: test/sql/suite/mroonga_storage/r/column_int_with_index_zero_value.result (+21 -0) 100644
===================================================================
--- /dev/null
+++ test/sql/suite/mroonga_storage/r/column_int_with_index_zero_value.result    2012-03-27 17:06:49 +0900 (6ee5800)
@@ -0,0 +1,21 @@
+DROP TABLE IF EXISTS items;
+CREATE TABLE items (
+name VARCHAR(255),
+price INT KEY
+) ENGINE=mroonga DEFAULT CHARSET=utf8;
+INSERT INTO items VALUES ("hamburger", 200);
+INSERT INTO items VALUES ("smile", 0);
+INSERT INTO items VALUES ("coke", 100);
+SELECT * FROM items;
+name	price
+smile	0
+coke	100
+hamburger	200
+SELECT * FROM items WHERE price = 0;
+name	price
+smile	0
+SELECT * FROM items WHERE price <= 100;
+name	price
+smile	0
+coke	100
+DROP TABLE items;

  Added: test/sql/suite/mroonga_storage/t/column_int_with_index_zero_value.test (+40 -0) 100644
===================================================================
--- /dev/null
+++ test/sql/suite/mroonga_storage/t/column_int_with_index_zero_value.test    2012-03-27 17:06:49 +0900 (06eb1d4)
@@ -0,0 +1,40 @@
+# 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 include/have_mroonga.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS items;
+--enable_warnings
+
+CREATE TABLE items (
+  name VARCHAR(255),
+  price INT KEY
+) ENGINE=mroonga DEFAULT CHARSET=utf8;
+
+INSERT INTO items VALUES ("hamburger", 200);
+INSERT INTO items VALUES ("smile", 0);
+INSERT INTO items VALUES ("coke", 100);
+
+SELECT * FROM items;
+
+SELECT * FROM items WHERE price = 0;
+
+SELECT * FROM items WHERE price <= 100;
+
+DROP TABLE items;
+
+--source include/have_mroonga_deinit.inc




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