[Groonga-commit] groonga/groonga [query-flags] Add --query_flags option to select command

アーカイブの一覧に戻る

null+****@clear***** null+****@clear*****
2012年 8月 6日 (月) 16:49:12 JST


Kouhei Sutou	2012-08-06 16:49:12 +0900 (Mon, 06 Aug 2012)

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

  Log:
    Add --query_flags option to select command
    
    By this change, GRN_EXPR_ALLOW_UPDATE can be enabled in query syntax
    by `select --query_flags ALLOW_COLUMN|ALLOW_UPDATE ...`.

  Added files:
    test/function/suite/select/query_flags/allow_update.expected
    test/function/suite/select/query_flags/allow_update.test
  Modified files:
    doc/source/reference/commands/select.txt
    doc/source/reference/grn_expr/query_syntax.txt
    lib/proc.c

  Modified: doc/source/reference/commands/select.txt (+36 -0)
===================================================================
--- doc/source/reference/commands/select.txt    2012-08-06 15:50:25 +0900 (04b338b)
+++ doc/source/reference/commands/select.txt    2012-08-06 16:49:12 +0900 (c15d4b0)
@@ -40,6 +40,7 @@ Syntax
          [cache=yes]
          [match_escalation_threshold=0]
          [query_expansion=null]
+         [query_flags=ALLOW_PRAGMA|ALLOW_COLUMN]
 
 Usage
 -----
@@ -534,6 +535,41 @@ more liked entries.
 The ``select`` command outputs records that ``n_likes`` column value
 is equal to or more than ``10`` from ``Entries`` table.
 
+.. _query-flags:
+
+``query_flags``
+"""""""""""""""
+
+It customs ``query`` parameter syntax. You cannot update column value
+by ``query`` parameter by default. But if you specify
+``ALLOW_COLUMN|ALLOW_UPDATE`` as ``query_flags``, you can update
+column value ``query``.
+
+Here are available values:
+
+* ``ALLOW_PRAGMA``
+* ``ALLOW_COLUMN``
+* ``ALLOW_UPDATE``
+
+``ALLOW_PRAGMA`` enables pragma at the head of ``query``.
+
+``ALLOW_COLUMN`` enables search againt columns that are not included
+in ``match_columns``. To specify column, there are ``COLUMN:...``
+syntaxes.
+
+``ALLOW_UPDATE`` enables column update by ``query`` with
+``COLUMN:=NEW_VALUE`` syntax. ``ALLOW_COLUMN`` is also required to
+update column because the column update syntax specifies column.
+
+They can be combined by separated ``|`` such as
+``ALLOW_COLUMN|ALLOW_UPDATE``.
+
+The default value is ``ALLOW_PRAGMA|ALLOW_COLUMN``.
+
+TODO: example
+
+See also :doc:`/reference/grn_expr/query_syntax`.
+
 Output related parameters
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 

  Modified: doc/source/reference/grn_expr/query_syntax.txt (+3 -3)
===================================================================
--- doc/source/reference/grn_expr/query_syntax.txt    2012-08-06 15:50:25 +0900 (5f2eba7)
+++ doc/source/reference/grn_expr/query_syntax.txt    2012-08-06 16:49:12 +0900 (efd997d)
@@ -564,9 +564,9 @@ Assignment expression
 ---------------------
 
 This section is for advanced users. Because assignment expression is
-disabled in ``--query`` option of :doc:`/reference/commands/select`. You need to
-use groonga as a library instead of server or command line tool for
-assignment expression.
+disabled in ``--query`` option of :doc:`/reference/commands/select` by
+default. You need to specify ``ALLOW_COLUMN|ALLOW_UPDATE`` as
+``--query_flags`` option value to enable assignment expression.
 
 Assignment expression in query syntax has some limitations. So you
 should use :doc:`/reference/grn_expr/script_syntax` instead of query syntax for

  Modified: lib/proc.c (+59 -8)
===================================================================
--- lib/proc.c    2012-08-06 15:50:25 +0900 (b6dfc8f)
+++ lib/proc.c    2012-08-06 16:49:12 +0900 (5e855a4)
@@ -246,6 +246,43 @@ exit :
 #define DEFAULT_DRILLDOWN_OUTPUT_COLUMNS  "_key, _nsubrecs"
 #define DUMP_COLUMNS            "_id, _key, _value, *"
 
+static grn_expr_flags
+grn_parse_query_flags(grn_ctx *ctx, const char *query_flags,
+                      unsigned int query_flags_len)
+{
+  grn_expr_flags flags = 0;
+  const char *query_flags_end = query_flags + query_flags_len;
+
+  while (query_flags < query_flags_end) {
+    if (*query_flags == '|' || *query_flags == ' ') {
+      query_flags += 1;
+      continue;
+    }
+
+#define CHECK_EXPR_FLAG(name)\
+  if (((query_flags_end - query_flags) >= (sizeof(#name) - 1)) &&\
+      (!memcmp(query_flags, #name, sizeof(#name) - 1))) {\
+    flags |= GRN_EXPR_ ## name;\
+    query_flags += sizeof(#name);\
+    break;\
+  }
+    switch (*query_flags) {
+    case 'A' :
+      CHECK_EXPR_FLAG(ALLOW_PRAGMA);
+      CHECK_EXPR_FLAG(ALLOW_COLUMN);
+      CHECK_EXPR_FLAG(ALLOW_UPDATE);
+    default :
+      ERR(GRN_INVALID_ARGUMENT, "invalid query flag: <%.*s>",
+          (int)(query_flags_end - query_flags), query_flags);
+      return 0;
+    }
+#undef CHECK_EXPR_FLAG
+
+  }
+
+  return flags;
+}
+
 grn_rc
 grn_select(grn_ctx *ctx, const char *table, unsigned int table_len,
            const char *match_columns, unsigned int match_columns_len,
@@ -261,7 +298,8 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len,
            int drilldown_offset, int drilldown_limit,
            const char *cache, unsigned int cache_len,
            const char *match_escalation_threshold, unsigned int match_escalation_threshold_len,
-           const char *query_expansion, unsigned int query_expansion_len)
+           const char *query_expansion, unsigned int query_expansion_len,
+           const char *query_flags, unsigned int query_flags_len)
 {
   uint32_t nkeys, nhits;
   uint16_t cacheable = 1, taintable = 0;
@@ -274,8 +312,8 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len,
   uint32_t cache_key_size = table_len + 1 + match_columns_len + 1 + query_len + 1 +
     filter_len + 1 + scorer_len + 1 + sortby_len + 1 + output_columns_len + 1 +
     drilldown_len + 1 + drilldown_sortby_len + 1 +
-    drilldown_output_columns_len + 1 +
-    match_escalation_threshold_len + 1 + query_expansion_len + 1 +
+    drilldown_output_columns_len + 1 + match_escalation_threshold_len + 1 +
+    query_expansion_len + 1 + query_flags_len + 1 +
     sizeof(grn_content_type) + sizeof(int) * 4;
   long long int threshold, original_threshold = 0;
   if (cache_key_size <= GRN_TABLE_MAX_KEY_SIZE) {
@@ -305,6 +343,8 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len,
     cp += match_escalation_threshold_len; *cp++ = '\0';
     memcpy(cp, query_expansion, query_expansion_len);
     cp += query_expansion_len; *cp++ = '\0';
+    memcpy(cp, query_flags, query_flags_len);
+    cp += query_flags_len; *cp++ = '\0';
     memcpy(cp, &output_type, sizeof(grn_content_type)); cp += sizeof(grn_content_type);
     memcpy(cp, &offset, sizeof(int)); cp += sizeof(int);
     memcpy(cp, &limit, sizeof(int)); cp += sizeof(int);
@@ -346,7 +386,16 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len,
           grn_expr_flags flags;
           grn_obj query_expansion_buf;
           GRN_TEXT_INIT(&query_expansion_buf, 0);
-          flags = GRN_EXPR_SYNTAX_QUERY|GRN_EXPR_ALLOW_PRAGMA|GRN_EXPR_ALLOW_COLUMN;
+          flags = GRN_EXPR_SYNTAX_QUERY;
+          if (query_flags_len) {
+            flags |= grn_parse_query_flags(ctx, query_flags, query_flags_len);
+          } else {
+            flags |= GRN_EXPR_ALLOW_PRAGMA|GRN_EXPR_ALLOW_COLUMN;
+            if (ctx->rc) {
+              grn_obj_unlink(ctx, cond);
+              goto exit;
+            }
+          }
           if (query_expansion_len) {
             grn_obj *query_expansion_column;
             query_expansion_column = grn_ctx_get(ctx, query_expansion, query_expansion_len);
@@ -591,7 +640,8 @@ proc_select(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
                  drilldown_offset, drilldown_limit,
                  GRN_TEXT_VALUE(VAR(14)), GRN_TEXT_LEN(VAR(14)),
                  GRN_TEXT_VALUE(VAR(15)), GRN_TEXT_LEN(VAR(15)),
-                 GRN_TEXT_VALUE(VAR(16)), GRN_TEXT_LEN(VAR(16)))) {
+                 GRN_TEXT_VALUE(VAR(16)), GRN_TEXT_LEN(VAR(16)),
+                 GRN_TEXT_VALUE(VAR(17)), GRN_TEXT_LEN(VAR(17)))) {
   }
   return NULL;
 }
@@ -2790,7 +2840,7 @@ func_edit_distance(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_
 void
 grn_db_init_builtin_query(grn_ctx *ctx)
 {
-  grn_expr_var vars[18];
+  grn_expr_var vars[19];
 
   DEF_VAR(vars[0], "name");
   DEF_VAR(vars[1], "table");
@@ -2810,8 +2860,9 @@ grn_db_init_builtin_query(grn_ctx *ctx)
   DEF_VAR(vars[15], "cache");
   DEF_VAR(vars[16], "match_escalation_threshold");
   DEF_VAR(vars[17], "query_expansion");
-  DEF_COMMAND("define_selector", proc_define_selector, 18, vars);
-  DEF_COMMAND("select", proc_select, 17, vars + 1);
+  DEF_VAR(vars[18], "query_flags");
+  DEF_COMMAND("define_selector", proc_define_selector, 19, vars);
+  DEF_COMMAND("select", proc_select, 18, vars + 1);
 
   DEF_VAR(vars[0], "values");
   DEF_VAR(vars[1], "table");

  Added: test/function/suite/select/query_flags/allow_update.expected (+88 -0) 100644
===================================================================
--- /dev/null
+++ test/function/suite/select/query_flags/allow_update.expected    2012-08-06 16:49:12 +0900 (fa129a5)
@@ -0,0 +1,88 @@
+table_create Users TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Users age COLUMN_SCALAR UInt32
+[[0,0.0,0.0],true]
+load --table Users
+[
+{"_key": "alice", "age": 18},
+{"_key": "bob",   "age": 20}
+]
+[[0,0.0,0.0],2]
+select Users   --query "age:=19"   --query_flags "ALLOW_COLUMN|ALLOW_UPDATE"
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        2
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "age",
+          "UInt32"
+        ]
+      ],
+      [
+        1,
+        "alice",
+        19
+      ],
+      [
+        2,
+        "bob",
+        19
+      ]
+    ]
+  ]
+]
+select Users
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        2
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "age",
+          "UInt32"
+        ]
+      ],
+      [
+        1,
+        "alice",
+        19
+      ],
+      [
+        2,
+        "bob",
+        19
+      ]
+    ]
+  ]
+]

  Added: test/function/suite/select/query_flags/allow_update.test (+14 -0) 100644
===================================================================
--- /dev/null
+++ test/function/suite/select/query_flags/allow_update.test    2012-08-06 16:49:12 +0900 (64aef97)
@@ -0,0 +1,14 @@
+table_create Users TABLE_HASH_KEY ShortText
+column_create Users age COLUMN_SCALAR UInt32
+
+load --table Users
+[
+{"_key": "alice", "age": 18},
+{"_key": "bob",   "age": 20}
+]
+
+select Users \
+  --query "age:=19" \
+  --query_flags "ALLOW_COLUMN|ALLOW_UPDATE"
+
+select Users
-------------- next part --------------
HTML$B$NE:IU%U%!%$%k$rJ]4I$7$^$7$?(B...
ダウンロード 



Groonga-commit メーリングリストの案内
アーカイブの一覧に戻る