[Groonga-commit] groonga/groonga at 5fcdfa1 [master] query: support default_mode option

Back to archive index

Kouhei Sutou null+****@clear*****
Wed Dec 28 14:46:08 JST 2016


Kouhei Sutou	2016-12-28 14:46:08 +0900 (Wed, 28 Dec 2016)

  New Revision: 5fcdfa1b4e45fb8ae3423734eae58f871462ead6
  https://github.com/groonga/groonga/commit/5fcdfa1b4e45fb8ae3423734eae58f871462ead6

  Message:
    query: support default_mode option
    
    query_expander is also supported as option.

  Added files:
    test/command/suite/select/function/query/options/default_mode.expected
    test/command/suite/select/function/query/options/default_mode.test
    test/command/suite/select/function/query/options/invalid_default_mode_type.expected
    test/command/suite/select/function/query/options/invalid_default_mode_type.test
    test/command/suite/select/function/query/options/query_expander.expected
    test/command/suite/select/function/query/options/query_expander.test
    test/command/suite/select/function/query/options/unknown_default_mode.expected
    test/command/suite/select/function/query/options/unknown_default_mode.test
    test/command/suite/select/function/query/options/unknown_name.expected
    test/command/suite/select/function/query/options/unknown_name.test
  Modified files:
    lib/proc.c

  Modified: lib/proc.c (+137 -3)
===================================================================
--- lib/proc.c    2016-12-28 11:01:42 +0900 (b59a23f)
+++ lib/proc.c    2016-12-28 14:46:08 +0900 (e770d95)
@@ -1694,6 +1694,76 @@ selector_to_function_data_fin(grn_ctx *ctx,
   }
 }
 
+static grn_operator
+parse_mode(grn_ctx *ctx, grn_obj *mode, const char *context)
+{
+  if (mode->header.domain != GRN_DB_TEXT) {
+    grn_obj inspected;
+    GRN_TEXT_INIT(&inspected, 0);
+    grn_inspect(ctx, &inspected, mode);
+    GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+                     "%s: mode must be text: <%.*s>",
+                     context,
+                     (int)GRN_TEXT_LEN(&inspected),
+                     GRN_TEXT_VALUE(&inspected));
+    GRN_OBJ_FIN(ctx, &inspected);
+    return GRN_OP_NOP;
+  }
+
+#define EQUAL_MODE(name)                                        \
+  (GRN_TEXT_LEN(mode) == strlen(name) &&                        \
+   memcmp(GRN_TEXT_VALUE(mode), name, strlen(name)) == 0)
+
+  if (EQUAL_MODE("==") || EQUAL_MODE("EQUAL")) {
+    return GRN_OP_EQUAL;
+  } else if (EQUAL_MODE("!=") || EQUAL_MODE("NOT_EQUAL")) {
+    return GRN_OP_NOT_EQUAL;
+  } else if (EQUAL_MODE("<") || EQUAL_MODE("LESS")) {
+    return GRN_OP_LESS;
+  } else if (EQUAL_MODE(">") || EQUAL_MODE("GREATER")) {
+    return GRN_OP_GREATER;
+  } else if (EQUAL_MODE("<=") || EQUAL_MODE("LESS_EQUAL")) {
+    return GRN_OP_LESS_EQUAL;
+  } else if (EQUAL_MODE(">=") || EQUAL_MODE("GREATER_EQUAL")) {
+    return GRN_OP_GREATER_EQUAL;
+  } else if (EQUAL_MODE("@") || EQUAL_MODE("MATCH")) {
+    return GRN_OP_MATCH;
+  } else if (EQUAL_MODE("*N") || EQUAL_MODE("NEAR")) {
+    return GRN_OP_NEAR;
+  } else if (EQUAL_MODE("*S") || EQUAL_MODE("SIMILAR")) {
+    return GRN_OP_SIMILAR;
+  } else if (EQUAL_MODE("^") || EQUAL_MODE("PREFIX")) {
+    return GRN_OP_PREFIX;
+  } else if (EQUAL_MODE("$") || EQUAL_MODE("SUFFIX")) {
+    return GRN_OP_SUFFIX;
+  } else if (EQUAL_MODE("~") || EQUAL_MODE("REGEXP")) {
+    return GRN_OP_REGEXP;
+  } else {
+    GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+                     "%s: mode must be one of them: "
+                     "["
+                     "\"==\", \"EQUAL\", "
+                     "\"!=\", \"NOT_EQUAL\", "
+                     "\"<\", \"LESS\", "
+                     "\">\", \"GREATER\", "
+                     "\"<=\", \"LESS_EQUAL\", "
+                     "\">=\", \"GREATER_EQUAL\", "
+                     "\"@\", \"MATCH\", "
+                     "\"*N\", \"NEAR\", "
+                     "\"*S\", \"SIMILAR\", "
+                     "\"^\", \"PREFIX\", "
+                     "\"$\", \"SUFFIX\", "
+                     "\"~\", \"REGEXP\""
+                     "]: <%.*s>",
+                     context,
+                     (int)GRN_TEXT_LEN(mode),
+                     GRN_TEXT_VALUE(mode));
+    return GRN_OP_NOP;
+  }
+
+#undef EQUAL_MODE
+}
+
 static grn_rc
 run_query(grn_ctx *ctx, grn_obj *table,
           int nargs, grn_obj **args,
@@ -1703,6 +1773,7 @@ run_query(grn_ctx *ctx, grn_obj *table,
   grn_obj *match_columns_string;
   grn_obj *query;
   grn_obj *query_expander_name = NULL;
+  grn_operator default_mode = GRN_OP_MATCH;
   grn_obj *match_columns = NULL;
   grn_obj *condition = NULL;
   grn_obj *dummy_variable;
@@ -1710,7 +1781,7 @@ run_query(grn_ctx *ctx, grn_obj *table,
   /* TODO: support flags by parameters */
   if (!(2 <= nargs && nargs <= 3)) {
     ERR(GRN_INVALID_ARGUMENT,
-        "wrong number of arguments (%d for 2..3)", nargs);
+        "query(): wrong number of arguments (%d for 2..3)", nargs);
     rc = ctx->rc;
     goto exit;
   }
@@ -1718,7 +1789,70 @@ run_query(grn_ctx *ctx, grn_obj *table,
   match_columns_string = args[0];
   query = args[1];
   if (nargs > 2) {
-    query_expander_name = args[2];
+    grn_obj *options = args[2];
+
+    switch (options->header.type) {
+    case GRN_BULK :
+      query_expander_name = options;
+      break;
+    case GRN_TABLE_HASH_KEY :
+      {
+        grn_hash_cursor *cursor;
+        void *key;
+        grn_obj *value;
+        int key_size;
+        cursor = grn_hash_cursor_open(ctx, (grn_hash *)options,
+                                      NULL, 0, NULL, 0,
+                                      0, -1, 0);
+        if (!cursor) {
+          GRN_PLUGIN_ERROR(ctx, GRN_NO_MEMORY_AVAILABLE,
+                           "query(): failed to open cursor for options");
+          rc = ctx->rc;
+          goto exit;
+        }
+        while (grn_hash_cursor_next(ctx, cursor) != GRN_ID_NIL) {
+          grn_hash_cursor_get_key_value(ctx, cursor, &key, &key_size,
+                                        (void **)&value);
+
+#define KEY_EQUAL(name)                                                 \
+          (key_size == strlen(name) && memcmp(key, name, strlen(name)) == 0)
+          if (KEY_EQUAL("query_expander")) {
+            query_expander_name = value;
+          } else if (KEY_EQUAL("default_mode")) {
+            default_mode = parse_mode(ctx, value, "query()");
+            if (ctx->rc != GRN_SUCCESS) {
+              grn_hash_cursor_close(ctx, cursor);
+              rc = ctx->rc;
+              goto exit;
+            }
+          } else {
+            GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+                             "query(): unknown option name: <%.*s>",
+                             key_size, (char *)key);
+            grn_hash_cursor_close(ctx, cursor);
+            rc = ctx->rc;
+            goto exit;
+          }
+#undef KEY_EQUAL
+        }
+        grn_hash_cursor_close(ctx, cursor);
+      }
+      break;
+    default :
+      {
+        grn_obj inspected;
+        GRN_TEXT_INIT(&inspected, 0);
+        grn_inspect(ctx, &inspected, options);
+        GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+                         "query(): "
+                         "3rd argument must be string or object literal: <%.*s>",
+                         (int)GRN_TEXT_LEN(&inspected),
+                         GRN_TEXT_VALUE(&inspected));
+        GRN_OBJ_FIN(ctx, &inspected);
+      }
+      rc = ctx->rc;
+      goto exit;
+    }
   }
 
   if (match_columns_string->header.domain == GRN_DB_TEXT &&
@@ -1777,7 +1911,7 @@ run_query(grn_ctx *ctx, grn_obj *table,
     grn_expr_parse(ctx, condition,
                    query_string,
                    query_string_len,
-                   match_columns, GRN_OP_MATCH, GRN_OP_AND, flags);
+                   match_columns, default_mode, GRN_OP_AND, flags);
     rc = ctx->rc;
     GRN_OBJ_FIN(ctx, &expanded_query);
     if (rc != GRN_SUCCESS) {

  Added: test/command/suite/select/function/query/options/default_mode.expected (+48 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/query/options/default_mode.expected    2016-12-28 14:46:08 +0900 (6de2ef8)
@@ -0,0 +1,48 @@
+table_create Products TABLE_NO_KEY
+[[0,0.0,0.0],true]
+column_create Products name COLUMN_SCALAR ShortText
+[[0,0.0,0.0],true]
+load --table Products
+[
+["name"],
+["Groonga"],
+["Mroonga"],
+["Rroonga"],
+["PGroonga"],
+["Ruby"],
+["PostgreSQL"]
+]
+[[0,0.0,0.0],6]
+select   --table Products   --filter 'query("name", "r", {"default_mode": "^"})'
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        2
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "name",
+          "ShortText"
+        ]
+      ],
+      [
+        3,
+        "Rroonga"
+      ],
+      [
+        5,
+        "Ruby"
+      ]
+    ]
+  ]
+]

  Added: test/command/suite/select/function/query/options/default_mode.test (+17 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/query/options/default_mode.test    2016-12-28 14:46:08 +0900 (b0ca76e)
@@ -0,0 +1,17 @@
+table_create Products TABLE_NO_KEY
+column_create Products name COLUMN_SCALAR ShortText
+
+load --table Products
+[
+["name"],
+["Groonga"],
+["Mroonga"],
+["Rroonga"],
+["PGroonga"],
+["Ruby"],
+["PostgreSQL"]
+]
+
+select \
+  --table Products \
+  --filter 'query("name", "r", {"default_mode": "^"})'

  Added: test/command/suite/select/function/query/options/invalid_default_mode_type.expected (+18 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/query/options/invalid_default_mode_type.expected    2016-12-28 14:46:08 +0900 (b79d71c)
@@ -0,0 +1,18 @@
+table_create Products TABLE_NO_KEY
+[[0,0.0,0.0],true]
+column_create Products name COLUMN_SCALAR ShortText
+[[0,0.0,0.0],true]
+load --table Products
+[
+["name"],
+["Groonga"],
+["Mroonga"],
+["Rroonga"],
+["PGroonga"],
+["Ruby"],
+["PostgreSQL"]
+]
+[[0,0.0,0.0],6]
+select   --table Products   --filter 'query("name", "r", {"default_mode": 29})'
+[[[-22,0.0,0.0],"query(): mode must be text: <29>"]]
+#|e| query(): mode must be text: <29>

  Added: test/command/suite/select/function/query/options/invalid_default_mode_type.test (+17 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/query/options/invalid_default_mode_type.test    2016-12-28 14:46:08 +0900 (3f1e511)
@@ -0,0 +1,17 @@
+table_create Products TABLE_NO_KEY
+column_create Products name COLUMN_SCALAR ShortText
+
+load --table Products
+[
+["name"],
+["Groonga"],
+["Mroonga"],
+["Rroonga"],
+["PGroonga"],
+["Ruby"],
+["PostgreSQL"]
+]
+
+select \
+  --table Products \
+  --filter 'query("name", "r", {"default_mode": 29})'

  Added: test/command/suite/select/function/query/options/query_expander.expected (+53 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/query/options/query_expander.expected    2016-12-28 14:46:08 +0900 (1979cae)
@@ -0,0 +1,53 @@
+plugin_register "query_expanders/tsv"
+[[0,0.0,0.0],true]
+table_create Memos TABLE_NO_KEY
+[[0,0.0,0.0],true]
+column_create Memos content COLUMN_SCALAR ShortText
+[[0,0.0,0.0],true]
+table_create Lexicon TABLE_PAT_KEY ShortText   --normalizer NormalizerAuto   --default_tokenizer TokenBigram
+[[0,0.0,0.0],true]
+column_create Lexicon memos_content COLUMN_INDEX|WITH_POSITION Memos content
+[[0,0.0,0.0],true]
+load --table Memos
+[
+["content"],
+["Start Groonga!"],
+["Start Mroonga!"],
+["Start Rroonga!"],
+["Start Ruby!"],
+["Learning Ruby and Groonga..."]
+]
+[[0,0.0,0.0],5]
+select   --table Memos   --filter 'query("content", "rroonga", {"query_expander": "QueryExpanderTSV"})'
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        2
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "content",
+          "ShortText"
+        ]
+      ],
+      [
+        3,
+        "Start Rroonga!"
+      ],
+      [
+        5,
+        "Learning Ruby and Groonga..."
+      ]
+    ]
+  ]
+]

  Added: test/command/suite/select/function/query/options/query_expander.test (+25 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/query/options/query_expander.test    2016-12-28 14:46:08 +0900 (6af78b8)
@@ -0,0 +1,25 @@
+#$GRN_QUERY_EXPANDER_TSV_SYNONYMS_FILE=#{base_directory}/tmp/synonyms.tsv
+#@copy-path fixture/query_expander/tsv/expand.tsv tmp/synonyms.tsv
+plugin_register "query_expanders/tsv"
+
+table_create Memos TABLE_NO_KEY
+column_create Memos content COLUMN_SCALAR ShortText
+
+table_create Lexicon TABLE_PAT_KEY ShortText \
+  --normalizer NormalizerAuto \
+  --default_tokenizer TokenBigram
+column_create Lexicon memos_content COLUMN_INDEX|WITH_POSITION Memos content
+
+load --table Memos
+[
+["content"],
+["Start Groonga!"],
+["Start Mroonga!"],
+["Start Rroonga!"],
+["Start Ruby!"],
+["Learning Ruby and Groonga..."]
+]
+
+select \
+  --table Memos \
+  --filter 'query("content", "rroonga", {"query_expander": "QueryExpanderTSV"})'

  Added: test/command/suite/select/function/query/options/unknown_default_mode.expected (+27 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/query/options/unknown_default_mode.expected    2016-12-28 14:46:08 +0900 (dbab043)
@@ -0,0 +1,27 @@
+table_create Products TABLE_NO_KEY
+[[0,0.0,0.0],true]
+column_create Products name COLUMN_SCALAR ShortText
+[[0,0.0,0.0],true]
+load --table Products
+[
+["name"],
+["Groonga"],
+["Mroonga"],
+["Rroonga"],
+["PGroonga"],
+["Ruby"],
+["PostgreSQL"]
+]
+[[0,0.0,0.0],6]
+select   --table Products   --filter 'query("name", "r", {"default_mode": "unknown"})'
+[
+  [
+    [
+      -22,
+      0.0,
+      0.0
+    ],
+    "query(): mode must be one of them: [\"==\", \"EQUAL\", \"!=\", \"NOT_EQUAL\", \"<\", \"LESS\", \">\", \"GREATER\", \"<=\", \"LESS_EQUAL\", \">=\", \"G"
+  ]
+]
+#|e| query(): mode must be one of them: ["==", "EQUAL", "!=", "NOT_EQUAL", "<", "LESS", ">", "GREATER", "<=", "LESS_EQUAL", ">=", "GREATER_EQUAL", "@", "MATCH", "*N", "NEAR", "*S", "SIMILAR", "^", "PREFIX", "$", "SUFFIX", "~", "REGEXP"]: <unknown>

  Added: test/command/suite/select/function/query/options/unknown_default_mode.test (+17 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/query/options/unknown_default_mode.test    2016-12-28 14:46:08 +0900 (19e0aa1)
@@ -0,0 +1,17 @@
+table_create Products TABLE_NO_KEY
+column_create Products name COLUMN_SCALAR ShortText
+
+load --table Products
+[
+["name"],
+["Groonga"],
+["Mroonga"],
+["Rroonga"],
+["PGroonga"],
+["Ruby"],
+["PostgreSQL"]
+]
+
+select \
+  --table Products \
+  --filter 'query("name", "r", {"default_mode": "unknown"})'

  Added: test/command/suite/select/function/query/options/unknown_name.expected (+18 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/query/options/unknown_name.expected    2016-12-28 14:46:08 +0900 (e7d062c)
@@ -0,0 +1,18 @@
+table_create Products TABLE_NO_KEY
+[[0,0.0,0.0],true]
+column_create Products name COLUMN_SCALAR ShortText
+[[0,0.0,0.0],true]
+load --table Products
+[
+["name"],
+["Groonga"],
+["Mroonga"],
+["Rroonga"],
+["PGroonga"],
+["Ruby"],
+["PostgreSQL"]
+]
+[[0,0.0,0.0],6]
+select   --table Products   --filter 'query("name", "r", {"unknown": "^"})'
+[[[-22,0.0,0.0],"query(): unknown option name: <unknown>"]]
+#|e| query(): unknown option name: <unknown>

  Added: test/command/suite/select/function/query/options/unknown_name.test (+17 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/query/options/unknown_name.test    2016-12-28 14:46:08 +0900 (5c3b2ba)
@@ -0,0 +1,17 @@
+table_create Products TABLE_NO_KEY
+column_create Products name COLUMN_SCALAR ShortText
+
+load --table Products
+[
+["name"],
+["Groonga"],
+["Mroonga"],
+["Rroonga"],
+["PGroonga"],
+["Ruby"],
+["PostgreSQL"]
+]
+
+select \
+  --table Products \
+  --filter 'query("name", "r", {"unknown": "^"})'
-------------- next part --------------
HTML����������������������������...
下载 



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