[Groonga-commit] groonga/groonga at 9ebc2f9 [master] grn_table_setoperation(): update score instead of overwriting by GRN_OP_ADJUST

Zurück zum Archiv-Index

Kouhei Sutou null+****@clear*****
Tue Jun 21 19:02:53 JST 2016


Kouhei Sutou	2016-06-21 19:02:53 +0900 (Tue, 21 Jun 2016)

  New Revision: 9ebc2f9c96d3cc876f8670d5d76ad433bb36c7f1
  https://github.com/groonga/groonga/commit/9ebc2f9c96d3cc876f8670d5d76ad433bb36c7f1

  Message:
    grn_table_setoperation(): update score instead of overwriting by GRN_OP_ADJUST
    
    [groonga-dev,04058]
    
    Reported by Naoya Murakami. Thanks!!!

  Modified files:
    lib/db.c
    test/unit/core/test-table.c

  Modified: lib/db.c (+15 -5)
===================================================================
--- lib/db.c    2016-06-20 15:38:54 +0900 (53b2d00)
+++ lib/db.c    2016-06-21 19:02:53 +0900 (02ff9a7)
@@ -4510,11 +4510,21 @@ grn_table_setoperation(grn_ctx *ctx, grn_obj *table1, grn_obj *table2, grn_obj *
     });
     break;
   case GRN_OP_ADJUST :
-    GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, {
-      if (grn_table_get_v(ctx, table1, key, key_size, &value1)) {
-        grn_memcpy(value1, value2, value_size);
-      }
-    });
+    if (have_subrec) {
+      GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, {
+        if (grn_table_get_v(ctx, table1, key, key_size, &value1)) {
+          grn_rset_recinfo *ri1 = value1;
+          grn_rset_recinfo *ri2 = value2;
+          ri1->score += ri2->score;
+        }
+      });
+    } else {
+      GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, {
+        if (grn_table_get_v(ctx, table1, key, key_size, &value1)) {
+          grn_memcpy(value1, value2, value_size);
+        }
+      });
+    }
     break;
   default :
     break;

  Modified: test/unit/core/test-table.c (+124 -1)
===================================================================
--- test/unit/core/test-table.c    2016-06-20 15:38:54 +0900 (1703305)
+++ test/unit/core/test-table.c    2016-06-21 19:02:53 +0900 (18692d2)
@@ -1,6 +1,6 @@
 /* -*- c-basic-offset: 2; coding: utf-8 -*- */
 /*
-  Copyright (C) 2009-2012  Kouhei Sutou <kou �� clear-code.com>
+  Copyright (C) 2009-2016  Kouhei Sutou <kou �� clear-code.com>
 
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
@@ -41,6 +41,8 @@ void data_truncate_anonymous(void);
 void test_truncate_anonymous(gconstpointer data);
 void data_truncate_named(void);
 void test_truncate_named(gconstpointer data);
+void data_setoperation(void);
+void test_setoperation(gconstpointer data);
 
 static gchar *tmp_directory;
 
@@ -609,3 +611,124 @@ test_truncate_named(gconstpointer data)
   cut_assert_equal_string("", GRN_TEXT_VALUE(&buffer));
   cut_assert_equal_uint(0, grn_table_size(context, table));
 }
+
+void
+data_setoperation(void)
+{
+#define ADD_DATA(operator, records)                     \
+  gcut_add_datum(#operator,                             \
+                 "operator", G_TYPE_INT, operator,	\
+                 "records", G_TYPE_STRING, records,	\
+                 NULL)
+
+  ADD_DATA(GRN_OP_OR,
+           "[[a, 1.0], [b, 2.0], [c, 1.0]]");
+  ADD_DATA(GRN_OP_AND,
+           "[[b, 2.0]]");
+  ADD_DATA(GRN_OP_AND_NOT,
+           "[[a, 1.0]]");
+  ADD_DATA(GRN_OP_ADJUST,
+           "[[a, 1.0], [b, 2.0]]");
+
+#undef ADD_DATA
+}
+
+void
+test_setoperation(gconstpointer data)
+{
+  grn_operator operator;
+  grn_obj *entries;
+  grn_obj *result1;
+  grn_obj *result2;
+  const char *dump;
+
+  operator = gcut_data_get_int(data, "operator");
+
+  assert_send_command("table_create Entries TABLE_HASH_KEY ShortText");
+  send_command(
+    "load "
+    "--table Entries "
+    "--values '[{\"_key\": \"a\"}, {\"_key\": \"b\"}, {\"_key\": \"c\"}]'");
+
+  entries = grn_ctx_get(context, "Entries", -1);
+  {
+    const char *condition = "_id < 3";
+    grn_obj *expr;
+    grn_obj *variable;
+
+    GRN_EXPR_CREATE_FOR_QUERY(context, entries, expr, variable);
+    grn_expr_parse(context, expr,
+                   condition, strlen(condition),
+                   NULL, GRN_OP_AND, GRN_OP_MATCH, GRN_EXPR_SYNTAX_SCRIPT);
+    result1 = grn_table_select(context, entries, expr, NULL, GRN_OP_OR);
+    grn_obj_unlink(context, expr);
+  }
+  {
+    const char *condition = "_id > 1";
+    grn_obj *expr;
+    grn_obj *variable;
+
+    GRN_EXPR_CREATE_FOR_QUERY(context, entries, expr, variable);
+    grn_expr_parse(context, expr,
+                   condition, strlen(condition),
+                   NULL, GRN_OP_AND, GRN_OP_MATCH, GRN_EXPR_SYNTAX_SCRIPT);
+    result2 = grn_table_select(context, entries, expr, NULL, GRN_OP_OR);
+    grn_obj_unlink(context, expr);
+  }
+
+  grn_table_setoperation(context, result1, result2, result1, operator);
+
+  {
+    grn_bool first_record = GRN_TRUE;
+    grn_obj buffer;
+    grn_obj *score_accessor;
+    grn_obj score;
+
+    GRN_TEXT_INIT(&buffer, 0);
+    GRN_TEXT_PUTS(context, &buffer, "[");
+    score_accessor = grn_obj_column(context, result1,
+                                    GRN_COLUMN_NAME_SCORE,
+                                    GRN_COLUMN_NAME_SCORE_LEN);
+    GRN_FLOAT_INIT(&score, 0);
+    GRN_TABLE_EACH_BEGIN(context, result1, cursor, id) {
+      void *result_key;
+      grn_id entry_id;
+      char entry_key[GRN_TABLE_MAX_KEY_SIZE];
+      int entry_key_size;
+
+      if (first_record) {
+        first_record = GRN_FALSE;
+      } else {
+        GRN_TEXT_PUTS(context, &buffer, ", ");
+      }
+
+      GRN_TEXT_PUTS(context, &buffer, "[");
+
+      grn_table_cursor_get_key(context, cursor, &result_key);
+      entry_id = *((grn_id *)result_key);
+      entry_key_size = grn_table_get_key(context,
+                                         entries,
+                                         entry_id,
+                                         entry_key,
+                                         GRN_TABLE_MAX_KEY_SIZE);
+      GRN_TEXT_PUT(context, &buffer, entry_key, entry_key_size);
+
+      GRN_TEXT_PUTS(context, &buffer, ", ");
+
+      GRN_BULK_REWIND(&score);
+      grn_obj_get_value(context, score_accessor, id, &score);
+      grn_text_printf(context, &buffer, "%.1f", GRN_FLOAT_VALUE(&score));
+
+      GRN_TEXT_PUTS(context, &buffer, "]");
+    } GRN_TABLE_EACH_END(context, cursor);
+    GRN_OBJ_FIN(context, &score);
+    grn_obj_unlink(context, score_accessor);
+    GRN_TEXT_PUTS(context, &buffer, "]");
+
+    dump = cut_take_strndup(GRN_TEXT_VALUE(&buffer), GRN_TEXT_LEN(&buffer));
+    GRN_OBJ_FIN(context, &buffer);
+  }
+
+  cut_assert_equal_string(gcut_data_get_string(data, "records"),
+                          dump);
+}
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Zurück zum Archiv-Index