[Groonga-commit] groonga/groonga [master] table: add filter command.

Back to archive index

null+****@clear***** null+****@clear*****
2012年 6月 26日 (火) 14:50:36 JST


Daijiro MORI	2012-06-26 14:50:36 +0900 (Tue, 26 Jun 2012)

  New Revision: b2a7fb3eb5be1a999fe75fe5a859a257bb29f128
  https://github.com/groonga/groonga/commit/b2a7fb3eb5be1a999fe75fe5a859a257bb29f128

  Log:
    table: add filter command.

  Added files:
    test/function/suite/table/filter.expected
    test/function/suite/table/filter.test
  Modified files:
    lib/db.h
    lib/expr.c
    plugins/table/table.c

  Modified: lib/db.h (+7 -1)
===================================================================
--- lib/db.h    2012-06-26 14:38:25 +0900 (6054433)
+++ lib/db.h    2012-06-26 14:50:36 +0900 (b973242)
@@ -442,7 +442,13 @@ GRN_API void grn_load_(grn_ctx *ctx, grn_content_type input_type,
 
 GRN_API grn_rc grn_table_group_with_range_gap(grn_ctx *ctx, grn_obj *table,
                                               grn_table_sort_key *group_key,
-                                              grn_obj *result_set, uint32_t range_gap);
+                                              grn_obj *result_set,
+                                              uint32_t range_gap);
+
+GRN_API grn_rc grn_column_filter(grn_ctx *ctx, grn_obj *column,
+                                 grn_operator op,
+                                 grn_obj *value, grn_obj *result_set,
+                                 grn_operator set_op);
 
 #ifdef __cplusplus
 }

  Modified: lib/expr.c (+29 -0)
===================================================================
--- lib/expr.c    2012-06-26 14:38:25 +0900 (5e5a7b3)
+++ lib/expr.c    2012-06-26 14:50:36 +0900 (afb5660)
@@ -5758,3 +5758,32 @@ grn_expr_snip(grn_ctx *ctx, grn_obj *expr, int flags,
   }
   GRN_API_RETURN(res);
 }
+
+/*
+  So far, grn_column_filter() is nothing but a very rough prototype.
+  Although GRN_COLUMN_EACH() can accelerate many range queries,
+  the following stuff must be resolved one by one.
+
+  * support accessors as column
+  * support tables which have deleted records
+  * support various operators
+  * support various column types
+*/
+grn_rc
+grn_column_filter(grn_ctx *ctx, grn_obj *column,
+                  grn_operator operator,
+                  grn_obj *value, grn_obj *result_set,
+                  grn_operator set_operation)
+{
+  uint32_t *vp;
+  grn_rset_posinfo pi;
+  uint32_t value_ = grn_atoui(GRN_TEXT_VALUE(value), GRN_BULK_CURR(value), NULL);
+  GRN_COLUMN_EACH(ctx, column, id, vp, {
+    if (*vp < value_) {
+      pi.rid = id;
+      res_add(ctx, (grn_hash *)result_set, &pi, 1, set_operation);
+    }
+  });
+  grn_ii_resolve_sel_and(ctx, (grn_hash *)result_set, set_operation);
+  return ctx->rc;
+}

  Modified: plugins/table/table.c (+57 -0)
===================================================================
--- plugins/table/table.c    2012-06-26 14:38:25 +0900 (ea8701b)
+++ plugins/table/table.c    2012-06-26 14:50:36 +0900 (e6354c5)
@@ -175,6 +175,55 @@ command_filter_by_script(grn_ctx *ctx, int nargs,
 }
 
 static grn_obj *
+command_filter(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
+{
+  grn_operator operator = GRN_OP_NOP;
+  grn_obj *table, *column, *result_set = NULL;
+  if (!(table = grn_ctx_get_table_by_name_or_id(ctx, TEXT_VALUE_LEN(VAR(0))))) {
+    goto exit;
+  }
+  if (!(column = grn_obj_column(ctx, table, TEXT_VALUE_LEN(VAR(1))))) {
+    ERR(GRN_INVALID_ARGUMENT, "invalid column name: <%.*s>",
+        GRN_TEXT_LEN(VAR(1)), GRN_TEXT_VALUE(VAR(1)));
+    goto exit;
+  }
+  if (TEXT_VALUE_LEN(VAR(2)) == 0) {
+    ERR(GRN_INVALID_ARGUMENT, "missing mandatory argument: operator");
+    goto exit;
+  } else {
+    uint32_t operator_len = GRN_TEXT_LEN(VAR(2));
+    const char *operator_text = GRN_TEXT_VALUE(VAR(2));
+    switch (operator_text[0]) {
+    case '<' :
+      if (operator_len == 1) {
+        operator = GRN_OP_LESS;
+      }
+      break;
+    }
+    if (operator == GRN_OP_NOP) {
+      ERR(GRN_INVALID_ARGUMENT, "invalid operator: <%.*s>",
+          operator_len, operator_text);
+      goto exit;
+    }
+  }
+  if (GRN_TEXT_LEN(VAR(4))) {
+    result_set = grn_ctx_get_table_by_name_or_id(ctx, TEXT_VALUE_LEN(VAR(4)));
+  } else {
+    result_set = grn_table_create(ctx, NULL, 0, NULL,
+                                  GRN_TABLE_HASH_KEY|
+                                  GRN_OBJ_WITH_SUBREC,
+                                  table, NULL);
+  }
+  if (result_set) {
+    grn_column_filter(ctx, column, operator, VAR(3), result_set,
+                      parse_set_operator_value(ctx, VAR(5)));
+  }
+exit :
+  grn_output_table_name_or_id(ctx, result_set);
+  return NULL;
+}
+
+static grn_obj *
 command_group(grn_ctx *ctx, int nargs, grn_obj **args,
               grn_user_data *user_data)
 {
@@ -549,6 +598,14 @@ GRN_PLUGIN_REGISTER(grn_ctx *ctx)
   DEF_COMMAND("filter_by_script", command_filter_by_script, 5, vars);
 
   DEF_VAR(vars[0], "table");
+  DEF_VAR(vars[1], "column");
+  DEF_VAR(vars[2], "operator");
+  DEF_VAR(vars[3], "value");
+  DEF_VAR(vars[4], "result_set");
+  DEF_VAR(vars[5], "set_operation");
+  DEF_COMMAND("filter", command_filter, 6, vars);
+
+  DEF_VAR(vars[0], "table");
   DEF_VAR(vars[1], "key");
   DEF_VAR(vars[2], "result_set");
   DEF_VAR(vars[3], "range_gap");

  Added: test/function/suite/table/filter.expected (+71 -0) 100644
===================================================================
--- /dev/null
+++ test/function/suite/table/filter.expected    2012-06-26 14:50:36 +0900 (9afe66e)
@@ -0,0 +1,71 @@
+register table/table
+[[0,0.0,0.0],true]
+table_create Shops TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Tags TABLE_PAT_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Shops tags COLUMN_VECTOR Tags
+[[0,0.0,0.0],true]
+column_create Tags shops_tag COLUMN_INDEX Shops tags
+[[0,0.0,0.0],true]
+column_create Shops budget COLUMN_SCALAR UInt32
+[[0,0.0,0.0],true]
+add Shops '{"_key":"くりこあん","tags":["たいやき","養殖"],"budget":180}'
+[[0,0.0,0.0],true]
+add Shops '{"_key":"なか一","tags":["季節料理"],"budget":800}'
+[[0,0.0,0.0],true]
+add Shops '{"_key":"魚寅食堂","tags":["漁師","季節料理"],"budget":750}'
+[[0,0.0,0.0],true]
+add Shops '{"_key":"DRAGON飯店","tags":["中華"],"budget":600}'
+[[0,0.0,0.0],true]
+add Shops '{"_key":"魚浜","tags":["回転寿司"],"budget":600}'
+[[0,0.0,0.0],true]
+add Shops '{"_key":"beanDaisy","tags":["caffe","カプチーノ"],"budget":650}'
+[[0,0.0,0.0],true]
+add Shops '{"_key":"維新","tags":["麺や"],"budget":800}'
+[[0,0.0,0.0],true]
+add Shops '{"_key":"ひづめ","tags":["とんかつ"],"budget":900}'
+[[0,0.0,0.0],true]
+add Shops '{"_key":"和互","tags":["魚"],"budget":1000}'
+[[0,0.0,0.0],true]
+filter Shops budget < 700
+[[0,0.0,0.0],2147483649]
+output 2147483649 _key,budget
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      4
+    ],
+    [
+      [
+        "_key",
+        "ShortText"
+      ],
+      [
+        "budget",
+        "UInt32"
+      ]
+    ],
+    [
+      "くりこあん",
+      180
+    ],
+    [
+      "DRAGON飯店",
+      600
+    ],
+    [
+      "魚浜",
+      600
+    ],
+    [
+      "beanDaisy",
+      650
+    ]
+  ]
+]

  Added: test/function/suite/table/filter.test (+18 -0) 100644
===================================================================
--- /dev/null
+++ test/function/suite/table/filter.test    2012-06-26 14:50:36 +0900 (569780b)
@@ -0,0 +1,18 @@
+register table/table
+table_create Shops TABLE_PAT_KEY ShortText
+table_create Tags TABLE_PAT_KEY ShortText
+column_create Shops tags COLUMN_VECTOR Tags
+column_create Tags shops_tag COLUMN_INDEX Shops tags
+column_create Shops budget COLUMN_SCALAR UInt32
+
+add Shops '{"_key":"くりこあん","tags":["たいやき","養殖"],"budget":180}'
+add Shops '{"_key":"なか一","tags":["季節料理"],"budget":800}'
+add Shops '{"_key":"魚寅食堂","tags":["漁師","季節料理"],"budget":750}'
+add Shops '{"_key":"DRAGON飯店","tags":["中華"],"budget":600}'
+add Shops '{"_key":"魚浜","tags":["回転寿司"],"budget":600}'
+add Shops '{"_key":"beanDaisy","tags":["caffe","カプチーノ"],"budget":650}'
+add Shops '{"_key":"維新","tags":["麺や"],"budget":800}'
+add Shops '{"_key":"ひづめ","tags":["とんかつ"],"budget":900}'
+add Shops '{"_key":"和互","tags":["魚"],"budget":1000}'
+filter Shops budget < 700
+output 2147483649 _key,budget
-------------- next part --------------
HTML$B$NE:IU%U%!%$%k$rJ]4I$7$^$7$?(B...
다운로드 



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