[Groonga-commit] groonga/groonga at 49fe82b [master] in_records: add

Back to archive index

Kouhei Sutou null+****@clear*****
Wed Apr 19 11:48:01 JST 2017


Kouhei Sutou	2017-04-19 11:48:01 +0900 (Wed, 19 Apr 2017)

  New Revision: 49fe82b6d9c122fdea2fb386c7db7532d1b05a70
  https://github.com/groonga/groonga/commit/49fe82b6d9c122fdea2fb386c7db7532d1b05a70

  Message:
    in_records: add

  Added files:
    lib/proc/proc_in_records.c
    test/command/suite/select/function/in_records/multiple.expected
    test/command/suite/select/function/in_records/multiple.test
    test/command/suite/select/function/in_records/one.expected
    test/command/suite/select/function/in_records/one.test
  Modified files:
    lib/grn_proc.h
    lib/proc.c
    lib/proc/sources.am

  Modified: lib/grn_proc.h (+2 -1)
===================================================================
--- lib/grn_proc.h    2017-04-19 11:06:49 +0900 (302fea4)
+++ lib/grn_proc.h    2017-04-19 11:48:01 +0900 (9792938)
@@ -1,6 +1,6 @@
 /* -*- c-basic-offset: 2 -*- */
 /*
-  Copyright(C) 2009-2016 Brazil
+  Copyright(C) 2009-2017 Brazil
 
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
@@ -52,6 +52,7 @@ void grn_proc_init_fuzzy_search(grn_ctx *ctx);
 void grn_proc_init_highlight(grn_ctx *ctx);
 void grn_proc_init_highlight_full(grn_ctx *ctx);
 void grn_proc_init_highlight_html(grn_ctx *ctx);
+void grn_proc_init_in_records(grn_ctx *ctx);
 void grn_proc_init_lock_acquire(grn_ctx *ctx);
 void grn_proc_init_lock_clear(grn_ctx *ctx);
 void grn_proc_init_lock_release(grn_ctx *ctx);

  Modified: lib/proc.c (+2 -0)
===================================================================
--- lib/proc.c    2017-04-19 11:06:49 +0900 (6cbdbb8)
+++ lib/proc.c    2017-04-19 11:48:01 +0900 (f253c77)
@@ -3972,4 +3972,6 @@ grn_db_init_builtin_commands(grn_ctx *ctx)
   grn_proc_init_object_list(ctx);
 
   grn_proc_init_table_copy(ctx);
+
+  grn_proc_init_in_records(ctx);
 }

  Added: lib/proc/proc_in_records.c (+170 -0) 100644
===================================================================
--- /dev/null
+++ lib/proc/proc_in_records.c    2017-04-19 11:48:01 +0900 (4ab3201)
@@ -0,0 +1,170 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+  Copyright(C) 2017 Brazil
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License version 2.1 as published by the Free Software Foundation.
+
+  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include "../grn_proc.h"
+
+#include <groonga/plugin.h>
+
+static grn_obj *
+func_in_records(grn_ctx *ctx,
+                int n_args,
+                grn_obj **args,
+                grn_user_data *user_data)
+{
+  grn_obj *found;
+  grn_obj *table;
+  grn_obj columns;
+  int i;
+
+  found = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_BOOL, 0);
+  if (!found) {
+    return NULL;
+  }
+  GRN_BOOL_SET(ctx, found, GRN_FALSE);
+
+  if (n_args < 3) {
+    GRN_PLUGIN_ERROR(ctx,
+                     GRN_INVALID_ARGUMENT,
+                     "in_records(): wrong number of arguments (%d for 3..)",
+                     n_args);
+    return found;
+  }
+
+  if ((n_args % 2) != 1) {
+    GRN_PLUGIN_ERROR(ctx,
+                     GRN_INVALID_ARGUMENT,
+                     "in_records(): the number of arguments must be odd (%d)",
+                     n_args);
+    return found;
+  }
+
+  table = args[0];
+  if (!grn_obj_is_table(ctx, table)) {
+    grn_obj inspected;
+    GRN_TEXT_INIT(&inspected, 0);
+    grn_inspect(ctx, &inspected, table);
+    GRN_PLUGIN_ERROR(ctx,
+                     GRN_INVALID_ARGUMENT,
+                     "in_records(): the first argument must be a table: <%.*s>",
+                     (int)GRN_TEXT_LEN(&inspected),
+                     GRN_TEXT_VALUE(&inspected));
+    GRN_OBJ_FIN(ctx, &inspected);
+    return found;
+  }
+
+  GRN_PTR_INIT(&columns, GRN_OBJ_VECTOR, GRN_ID_NIL);
+  for (i = 1; i < n_args; i += 2) {
+    grn_obj *column_name = args[i + 1];
+    grn_obj *column;
+
+    if (!grn_obj_is_text_family_bulk(ctx, column_name)) {
+      grn_obj inspected;
+      GRN_TEXT_INIT(&inspected, 0);
+      grn_inspect(ctx, &inspected, table);
+      GRN_PLUGIN_ERROR(ctx,
+                       GRN_INVALID_ARGUMENT,
+                       "in_records(): "
+                       "the %dth argument must be column name as string: "
+                       "<%.*s>",
+                       i + 1,
+                       (int)GRN_TEXT_LEN(&inspected),
+                       GRN_TEXT_VALUE(&inspected));
+      GRN_OBJ_FIN(ctx, &inspected);
+      goto exit;
+    }
+
+    column = grn_obj_column(ctx, table,
+                            GRN_TEXT_VALUE(column_name),
+                            GRN_TEXT_LEN(column_name));
+    if (!column) {
+      grn_obj inspected;
+      GRN_TEXT_INIT(&inspected, 0);
+      grn_inspect(ctx, &inspected, table);
+      GRN_PLUGIN_ERROR(ctx,
+                       GRN_INVALID_ARGUMENT,
+                       "in_records(): "
+                       "the %dth argument must be existing column name: "
+                       "<%.*s>",
+                       i + 1,
+                       (int)GRN_TEXT_LEN(&inspected),
+                       GRN_TEXT_VALUE(&inspected));
+      GRN_OBJ_FIN(ctx, &inspected);
+      goto exit;
+    }
+    GRN_PTR_PUT(ctx, &columns, column);
+  }
+
+  {
+    grn_obj column_value;
+
+    GRN_VOID_INIT(&column_value);
+    GRN_TABLE_EACH_BEGIN(ctx, table, cursor, id) {
+      grn_bool found_record = GRN_TRUE;
+
+      for (i = 1; i < n_args; i += 2) {
+        grn_obj *value = args[i];
+        grn_obj *column = GRN_PTR_VALUE_AT(&columns, (i - 1) / 2);
+
+        if (grn_obj_is_data_column(ctx, column)) {
+          grn_bool found_value = GRN_FALSE;
+
+          GRN_BULK_REWIND(&column_value);
+          grn_obj_get_value(ctx, column, id, &column_value);
+
+          found_value = grn_operator_exec_equal(ctx, value, &column_value);
+          if (ctx->rc != GRN_SUCCESS) {
+            found_record = GRN_FALSE;
+            break;
+          }
+
+          if (!found_value) {
+            found_record = GRN_FALSE;
+            break;
+          }
+        } else {
+          found_record = GRN_FALSE;
+          break;
+        }
+      }
+
+      if (found_record) {
+        GRN_BOOL_SET(ctx, found, GRN_TRUE);
+        break;
+      }
+    } GRN_TABLE_EACH_END(ctx, cursor);
+    GRN_OBJ_FIN(ctx, &column_value);
+  }
+
+exit :
+  for (i = 1; i < n_args; i += 2) {
+    grn_obj *column = GRN_PTR_VALUE_AT(&columns, (i - 1) / 2);
+    if (column->header.type == GRN_ACCESSOR) {
+      grn_obj_unlink(ctx, column);
+    }
+  }
+  GRN_OBJ_FIN(ctx, &columns);
+
+  return found;
+}
+
+void
+grn_proc_init_in_records(grn_ctx *ctx)
+{
+  grn_proc_create(ctx, "in_records", -1, GRN_PROC_FUNCTION,
+                  func_in_records, NULL, NULL, 0, NULL);
+}

  Modified: lib/proc/sources.am (+2 -1)
===================================================================
--- lib/proc/sources.am    2017-04-19 11:06:49 +0900 (e84cf7f)
+++ lib/proc/sources.am    2017-04-19 11:48:01 +0900 (3113901)
@@ -3,6 +3,8 @@ libgrnproc_la_SOURCES =				\
 	proc_config.c				\
 	proc_dump.c				\
 	proc_fuzzy_search.c			\
+	proc_highlight.c			\
+	proc_in_records.c			\
 	proc_lock.c				\
 	proc_object.c				\
 	proc_object_inspect.c			\
@@ -11,6 +13,5 @@ libgrnproc_la_SOURCES =				\
 	proc_schema.c				\
 	proc_select.c				\
 	proc_snippet.c				\
-	proc_highlight.c			\
 	proc_table.c				\
 	proc_tokenize.c

  Added: test/command/suite/select/function/in_records/multiple.expected (+84 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/in_records/multiple.expected    2017-04-19 11:48:01 +0900 (ea0c26e)
@@ -0,0 +1,84 @@
+plugin_register functions/time
+[[0,0.0,0.0],true]
+table_create Users TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Tags TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Reports TABLE_NO_KEY
+[[0,0.0,0.0],true]
+column_create Reports user COLUMN_SCALAR Users
+[[0,0.0,0.0],true]
+column_create Reports tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+column_create Reports day COLUMN_SCALAR Time
+[[0,0.0,0.0],true]
+table_create Logs TABLE_NO_KEY
+[[0,0.0,0.0],true]
+column_create Logs user COLUMN_SCALAR Users
+[[0,0.0,0.0],true]
+column_create Logs tag COLUMN_SCALAR Tags
+[[0,0.0,0.0],true]
+column_create Logs time COLUMN_SCALAR Time
+[[0,0.0,0.0],true]
+load --table Reports
+[
+{"user": "alice", "tag": "tag1", "day": "2017-04-18 00:00:00"},
+{"user": "alice", "tag": "tag1", "day": "2017-04-19 00:00:00"},
+{"user": "david", "tag": "tag2", "day": "2017-04-20 00:00:00"},
+{"user": "david", "tag": "tag3", "day": "2017-04-21 00:00:00"}
+]
+[[0,0.0,0.0],4]
+load --table Logs
+[
+{"user": "alice", "tag": "tag1", "time": "2017-04-18 11:22:33"},
+{"user": "alice", "tag": "tag1", "time": "2017-04-20 11:22:33"},
+{"user": "bob",   "tag": "tag1", "time": "2017-04-19 11:22:33"},
+{"user": "david", "tag": "tag1", "time": "2017-04-19 11:22:33"},
+{"user": "david", "tag": "tag2", "time": "2017-04-20 11:22:33"}
+]
+[[0,0.0,0.0],5]
+select Logs   --filter 'in_records(Reports,                        user, "user",                        tag, "tag",                        time_classify_day(time), "day")'
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        2
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "tag",
+          "Tags"
+        ],
+        [
+          "time",
+          "Time"
+        ],
+        [
+          "user",
+          "Users"
+        ]
+      ],
+      [
+        1,
+        "tag1",
+        1492482153.0,
+        "alice"
+      ],
+      [
+        5,
+        "tag2",
+        1492654953.0,
+        "david"
+      ]
+    ]
+  ]
+]

  Added: test/command/suite/select/function/in_records/multiple.test (+37 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/in_records/multiple.test    2017-04-19 11:48:01 +0900 (6c04630)
@@ -0,0 +1,37 @@
+plugin_register functions/time
+
+table_create Users TABLE_HASH_KEY ShortText
+table_create Tags TABLE_HASH_KEY ShortText
+
+table_create Reports TABLE_NO_KEY
+column_create Reports user COLUMN_SCALAR Users
+column_create Reports tag COLUMN_SCALAR Tags
+column_create Reports day COLUMN_SCALAR Time
+
+table_create Logs TABLE_NO_KEY
+column_create Logs user COLUMN_SCALAR Users
+column_create Logs tag COLUMN_SCALAR Tags
+column_create Logs time COLUMN_SCALAR Time
+
+load --table Reports
+[
+{"user": "alice", "tag": "tag1", "day": "2017-04-18 00:00:00"},
+{"user": "alice", "tag": "tag1", "day": "2017-04-19 00:00:00"},
+{"user": "david", "tag": "tag2", "day": "2017-04-20 00:00:00"},
+{"user": "david", "tag": "tag3", "day": "2017-04-21 00:00:00"}
+]
+
+load --table Logs
+[
+{"user": "alice", "tag": "tag1", "time": "2017-04-18 11:22:33"},
+{"user": "alice", "tag": "tag1", "time": "2017-04-20 11:22:33"},
+{"user": "bob",   "tag": "tag1", "time": "2017-04-19 11:22:33"},
+{"user": "david", "tag": "tag1", "time": "2017-04-19 11:22:33"},
+{"user": "david", "tag": "tag2", "time": "2017-04-20 11:22:33"}
+]
+
+select Logs \
+  --filter 'in_records(Reports, \
+                       user, "user", \
+                       tag, "tag", \
+                       time_classify_day(time), "day")'

  Added: test/command/suite/select/function/in_records/one.expected (+57 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/in_records/one.expected    2017-04-19 11:48:01 +0900 (22ac7e1)
@@ -0,0 +1,57 @@
+table_create Users TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Reports TABLE_NO_KEY
+[[0,0.0,0.0],true]
+column_create Reports user COLUMN_SCALAR Users
+[[0,0.0,0.0],true]
+table_create Logs TABLE_NO_KEY
+[[0,0.0,0.0],true]
+column_create Logs user COLUMN_SCALAR Users
+[[0,0.0,0.0],true]
+load --table Reports
+[
+{"user": "alice"},
+{"user": "david"}
+]
+[[0,0.0,0.0],2]
+load --table Logs
+[
+{"user": "alice"},
+{"user": "bob"},
+{"user": "chris"},
+{"user": "david"}
+]
+[[0,0.0,0.0],4]
+select Logs   --filter 'in_records(Reports, user, "user")'
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        2
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "user",
+          "Users"
+        ]
+      ],
+      [
+        1,
+        "alice"
+      ],
+      [
+        4,
+        "david"
+      ]
+    ]
+  ]
+]

  Added: test/command/suite/select/function/in_records/one.test (+24 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/in_records/one.test    2017-04-19 11:48:01 +0900 (9e7163c)
@@ -0,0 +1,24 @@
+table_create Users TABLE_HASH_KEY ShortText
+
+table_create Reports TABLE_NO_KEY
+column_create Reports user COLUMN_SCALAR Users
+
+table_create Logs TABLE_NO_KEY
+column_create Logs user COLUMN_SCALAR Users
+
+load --table Reports
+[
+{"user": "alice"},
+{"user": "david"}
+]
+
+load --table Logs
+[
+{"user": "alice"},
+{"user": "bob"},
+{"user": "chris"},
+{"user": "david"}
+]
+
+select Logs \
+  --filter 'in_records(Reports, user, "user")'
-------------- next part --------------
HTML����������������������������...
下载 



More information about the Groonga-commit mailing list
Back to archive index