[Groonga-commit] groonga/groonga at d0cce94 [master] select: support operator as table key

Back to archive index

Kouhei Sutou null+****@clear*****
Sat May 9 21:10:39 JST 2015


Kouhei Sutou	2015-05-09 21:10:39 +0900 (Sat, 09 May 2015)

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

  Message:
    select: support operator as table key
    
    See the committed test case for details.

  Added files:
    lib/expr_code.c
    lib/grn_expr_code.h
    test/command/suite/select/filter/record/key/operator.expected
    test/command/suite/select/filter/record/key/operator.test
  Modified files:
    lib/expr.c
    lib/output.c
    lib/sources.am

  Modified: lib/expr.c (+19 -2)
===================================================================
--- lib/expr.c    2015-05-09 20:33:42 +0900 (3f13072)
+++ lib/expr.c    2015-05-09 21:10:39 +0900 (dc047c4)
@@ -22,6 +22,7 @@
 #include "grn_ii.h"
 #include "grn_geo.h"
 #include "grn_expr.h"
+#include "grn_expr_code.h"
 #include "grn_util.h"
 #include "grn_mrb.h"
 #include "mrb/mrb_expr.h"
@@ -6157,14 +6158,30 @@ parse_script_extract_name_resolve_context(grn_ctx *ctx, efs_info *q)
   grn_expr_code *code_start;
   grn_expr_code *code_last;
 
+  if (expr->codes_curr == 0) {
+    return NULL;
+  }
+
   code_start = expr->codes;
   code_last = code_start + (expr->codes_curr - 1);
   switch (code_last->op) {
   case GRN_OP_GET_MEMBER :
+    if (code_last - 1 < code_start) {
+      return NULL;
+    }
     {
+      unsigned int n_used_codes_for_key;
+      grn_expr_code *code_key;
       grn_expr_code *code_receiver;
-      /* TODO: Support non literal key case. */
-      code_receiver = code_last - 2;
+
+      code_key = code_last - 1;
+      n_used_codes_for_key = grn_expr_code_n_used_codes(ctx,
+                                                        code_start,
+                                                        code_key);
+      if (n_used_codes_for_key == 0) {
+        return NULL;
+      }
+      code_receiver = code_key - n_used_codes_for_key;
       if (code_receiver < code_start) {
         return NULL;
       }

  Added: lib/expr_code.c (+71 -0) 100644
===================================================================
--- /dev/null
+++ lib/expr_code.c    2015-05-09 21:10:39 +0900 (4f03867)
@@ -0,0 +1,71 @@
+/* -*- c-basic-offset: 2 -*- */
+/* Copyright(C) 2014-2015 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_expr_code.h"
+
+unsigned int
+grn_expr_code_n_used_codes(grn_ctx *ctx,
+                           grn_expr_code *start,
+                           grn_expr_code *target)
+{
+  unsigned int n_codes;
+  int i, n_args;
+  grn_bool have_proc_push_code = GRN_FALSE;
+  grn_expr_code *sub_code;
+
+  if (start == target) {
+    return 0;
+  }
+
+  n_args = target->nargs;
+  if (target->op == GRN_OP_CALL) {
+    if (!target->value) {
+      have_proc_push_code = GRN_TRUE;
+    }
+  } else {
+    if (target->value) {
+      n_args--;
+      if (n_args == 0) {
+        return 1;
+      }
+    }
+  }
+
+  n_codes = 1;
+  sub_code = target - 1;
+  for (i = 0; i < n_args; i++) {
+    int sub_n_codes;
+    sub_n_codes = grn_expr_code_n_used_codes(ctx, start, sub_code);
+    n_codes += sub_n_codes;
+    sub_code -= sub_n_codes;
+    if (sub_code < start) {
+      /* TODO: report error */
+      return 0;
+    }
+  }
+
+  if (have_proc_push_code) {
+    n_codes++;
+    sub_code--;
+    if (sub_code < start) {
+      /* TODO: report error */
+      return 0;
+    }
+  }
+
+  return n_codes;
+}

  Added: lib/grn_expr_code.h (+37 -0) 100644
===================================================================
--- /dev/null
+++ lib/grn_expr_code.h    2015-05-09 21:10:39 +0900 (a0fd680)
@@ -0,0 +1,37 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+  Copyright(C) 2015 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
+*/
+
+#ifndef GRN_EXPR_CODE_H
+#define GRN_EXPR_CODE_H
+
+#include "grn_db.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+unsigned int grn_expr_code_n_used_codes(grn_ctx *ctx,
+                                        grn_expr_code *start,
+                                        grn_expr_code *target);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRN_EXPR_CODE_H */
+

  Modified: lib/output.c (+6 -57)
===================================================================
--- lib/output.c    2015-05-09 20:33:42 +0900 (0036e9a)
+++ lib/output.c    2015-05-09 21:10:39 +0900 (48ff6bc)
@@ -1134,57 +1134,6 @@ count_n_elements_in_expression(grn_ctx *ctx, grn_obj *expression)
   return n_elements;
 }
 
-static inline int
-count_used_n_codes(grn_ctx *ctx, grn_expr_code *start, grn_expr_code *target)
-{
-  int n_codes;
-  int i, n_args;
-  grn_bool have_proc_push_code = GRN_FALSE;
-  grn_expr_code *sub_code;
-
-  if (start == target) {
-    return 0;
-  }
-
-  n_args = target->nargs;
-  if (target->op == GRN_OP_CALL) {
-    if (!target->value) {
-      have_proc_push_code = GRN_TRUE;
-    }
-  } else {
-    if (target->value) {
-      n_args--;
-      if (n_args == 0) {
-        return 1;
-      }
-    }
-  }
-
-  n_codes = 1;
-  sub_code = target - 1;
-  for (i = 0; i < n_args; i++) {
-    int sub_n_codes;
-    sub_n_codes = count_used_n_codes(ctx, start, sub_code);
-    n_codes += sub_n_codes;
-    sub_code -= sub_n_codes;
-    if (sub_code < start) {
-      /* TODO: report error */
-      return 0;
-    }
-  }
-
-  if (have_proc_push_code) {
-    n_codes++;
-    sub_code--;
-    if (sub_code < start) {
-      /* TODO: report error */
-      return 0;
-    }
-  }
-
-  return n_codes;
-}
-
 static grn_bool
 is_score_accessor(grn_ctx *ctx, grn_obj *obj)
 {
@@ -1305,10 +1254,10 @@ grn_output_table_columns_by_expression(grn_ctx *ctx, grn_obj *outbuf,
 
     have_comma = GRN_TRUE;
     if (is_first_comma) {
-      int n_used_codes;
+      unsigned int n_used_codes;
       int code_end_offset;
 
-      n_used_codes = count_used_n_codes(ctx, expr->codes, code - 1);
+      n_used_codes = grn_expr_code_n_used_codes(ctx, expr->codes, code - 1);
       code_end_offset = code - expr->codes - n_used_codes;
 
       grn_output_table_column_by_expression(ctx, outbuf, output_type,
@@ -1417,12 +1366,12 @@ grn_output_table_records_by_expression(grn_ctx *ctx, grn_obj *outbuf,
         have_comma = GRN_TRUE;
         if (is_first_comma) {
           int second_code_offset;
-          int second_code_n_used_code;
+          unsigned int second_code_n_used_code;
           second_code_offset = code - expr->codes - 1;
           second_code_n_used_code =
-            count_used_n_codes(ctx,
-                               expr->codes,
-                               expr->codes + second_code_offset);
+            grn_expr_code_n_used_codes(ctx,
+                                       expr->codes,
+                                       expr->codes + second_code_offset);
           expr->codes_curr = second_code_offset - second_code_n_used_code + 1;
           grn_output_table_record_by_expression(ctx, outbuf, output_type,
                                                 format->expression);

  Modified: lib/sources.am (+2 -0)
===================================================================
--- lib/sources.am    2015-05-09 20:33:42 +0900 (459b737)
+++ lib/sources.am    2015-05-09 21:10:39 +0900 (3ad3664)
@@ -15,6 +15,8 @@ libgroonga_la_SOURCES =				\
 	grn_error.h				\
 	expr.c					\
 	grn_expr.h				\
+	expr_code.c				\
+	grn_expr_code.h				\
 	geo.c					\
 	grn_geo.h				\
 	grn.h					\

  Added: test/command/suite/select/filter/record/key/operator.expected (+59 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/filter/record/key/operator.expected    2015-05-09 21:10:39 +0900 (c6a72b9)
@@ -0,0 +1,59 @@
+table_create Keywords TABLE_HASH_KEY ShortText   --normalizer NormalizerAuto
+[[0,0.0,0.0],true]
+column_create Keywords label COLUMN_SCALAR ShortText
+[[0,0.0,0.0],true]
+table_create Memos TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Memos tag COLUMN_SCALAR ShortText
+[[0,0.0,0.0],true]
+load --table Keywords
+[
+{"_key": "groonga", "label": "Groonga"}
+]
+[[0,0.0,0.0],1]
+load --table Memos
+[
+{"_key": "Groonga is very fast",       "tag": "Groonga"},
+{"_key": "Groonga is easy to install", "tag": "Groonga"},
+{"_key": "Mroonga is very fast",       "tag": "Mroonga"}
+]
+[[0,0.0,0.0],3]
+select Memos --filter 'tag == Keywords["groo" + "nga"].label'
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        2
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "tag",
+          "ShortText"
+        ]
+      ],
+      [
+        1,
+        "Groonga is very fast",
+        "Groonga"
+      ],
+      [
+        2,
+        "Groonga is easy to install",
+        "Groonga"
+      ]
+    ]
+  ]
+]

  Added: test/command/suite/select/filter/record/key/operator.test (+20 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/filter/record/key/operator.test    2015-05-09 21:10:39 +0900 (3baeced)
@@ -0,0 +1,20 @@
+table_create Keywords TABLE_HASH_KEY ShortText \
+  --normalizer NormalizerAuto
+column_create Keywords label COLUMN_SCALAR ShortText
+
+table_create Memos TABLE_HASH_KEY ShortText
+column_create Memos tag COLUMN_SCALAR ShortText
+
+load --table Keywords
+[
+{"_key": "groonga", "label": "Groonga"}
+]
+
+load --table Memos
+[
+{"_key": "Groonga is very fast",       "tag": "Groonga"},
+{"_key": "Groonga is easy to install", "tag": "Groonga"},
+{"_key": "Mroonga is very fast",       "tag": "Mroonga"}
+]
+
+select Memos --filter 'tag == Keywords["groo" + "nga"].label'
-------------- next part --------------
HTML����������������������������...
Download 



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