[Groonga-commit] groonga/groonga at e298117 [select-drilldown-sortby-support-real-column] select drilldown_sortby: support real column

Back to archive index

Kouhei Sutou null+****@clear*****
Wed Jun 25 22:45:26 JST 2014


Kouhei Sutou	2014-06-25 22:45:26 +0900 (Wed, 25 Jun 2014)

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

  Message:
    select drilldown_sortby: support real column
    
    drilldown_output_columns also supports real column.
    
    It always uses the first sub record. Should we support Nth sub record?

  Added files:
    test/command/suite/select/drilldown_sortby/real_column.expected
    test/command/suite/select/drilldown_sortby/real_column.test
  Modified files:
    lib/db.c
    lib/db.h
    lib/output.c
    lib/proc.c

  Modified: lib/db.c (+67 -19)
===================================================================
--- lib/db.c    2014-06-25 22:16:31 +0900 (0bc37b8)
+++ lib/db.c    2014-06-25 22:45:26 +0900 (5a146a0)
@@ -4481,6 +4481,7 @@ grn_obj_get_accessor(grn_ctx *ctx, grn_obj *obj, const char *name, unsigned int
           (*rp)->action = GRN_ACCESSOR_GET_COLUMN_VALUE;
           break;
         } else {
+          grn_obj *domain;
           if (!obj->header.domain) {
             // ERR(GRN_INVALID_ARGUMENT, "no such column: <%s>", name);
             if (!is_chained) {
@@ -4491,23 +4492,40 @@ grn_obj_get_accessor(grn_ctx *ctx, grn_obj *obj, const char *name, unsigned int
           }
           *rp = accessor_new(ctx);
           (*rp)->obj = obj;
-          if (!(obj = grn_ctx_at(ctx, obj->header.domain))) {
+          if (!(domain = grn_ctx_at(ctx, obj->header.domain))) {
             grn_obj_close(ctx, (grn_obj *)res);
             res = NULL;
             goto exit;
           }
-          switch (obj->header.type) {
+          switch (domain->header.type) {
           case GRN_TABLE_PAT_KEY :
           case GRN_TABLE_DAT_KEY :
           case GRN_TABLE_HASH_KEY :
           case GRN_TABLE_NO_KEY :
             (*rp)->action = GRN_ACCESSOR_GET_KEY;
+            obj = domain;
             break;
           default :
-            /* lookup failed */
-            grn_obj_close(ctx, (grn_obj *)res);
-            res = NULL;
-            goto exit;
+            {
+              grn_obj *range;
+              if (!(range = grn_ctx_at(ctx, DB_OBJ(obj)->range))) {
+                grn_obj_close(ctx, (grn_obj *)res);
+                res = NULL;
+                goto exit;
+              }
+              switch (range->header.type) {
+              case GRN_TABLE_HASH_KEY :
+                (*rp)->action = GRN_ACCESSOR_GET_VALUE;
+                obj = range;
+                break;
+              default :
+                /* lookup failed */
+                grn_obj_close(ctx, (grn_obj *)res);
+                res = NULL;
+                goto exit;
+              }
+            }
+            break;
           }
         }
       }
@@ -5080,13 +5098,28 @@ grn_accessor_get_value_(grn_ctx *ctx, grn_accessor *a, grn_id id, uint32_t *size
       break;
     case GRN_ACCESSOR_GET_VALUE :
       value = grn_obj_get_value_(ctx, a->obj, id, size);
-      break;
-    case GRN_ACCESSOR_GET_SCORE :
-      if ((value = grn_obj_get_value_(ctx, a->obj, id, size))) {
-        value = (const char *)&((grn_rset_recinfo *)value)->score;
-        *size = sizeof(int);
+      if (a->obj->header.flags & GRN_OBJ_WITH_SUBREC) {
+        if (DB_OBJ(a->obj)->max_n_subrecs > 0 &&
+            DB_OBJ(a->obj)->subrec_offset == 0) {
+          const grn_rset_recinfo *ri = (const grn_rset_recinfo *)value;
+          const grn_rset_posinfo *pi;
+          int nth_subrec = 0;
+          uint8_t subrec_size = DB_OBJ(a->obj)->subrec_size;
+          pi = GRN_RSET_SUBRECS_NTH_BODY(ri->subrecs, subrec_size, nth_subrec);
+          value = (const char *)(&(pi->rid));
+          *size = sizeof(grn_id);
+        } else {
+          value = NULL;
+          *size = 0;
+        }
       }
       break;
+    case GRN_ACCESSOR_GET_SCORE :
+       if ((value = grn_obj_get_value_(ctx, a->obj, id, size))) {
+         value = (const char *)&((grn_rset_recinfo *)value)->score;
+         *size = sizeof(int);
+       }
+       break;
     case GRN_ACCESSOR_GET_NSUBRECS :
       if ((value = grn_obj_get_value_(ctx, a->obj, id, size))) {
         value = (const char *)&((grn_rset_recinfo *)value)->n_subrecs;
@@ -5147,7 +5180,6 @@ grn_accessor_get_value(grn_ctx *ctx, grn_accessor *a, grn_id id, grn_obj *value)
       vs = GRN_BULK_VSIZE(value) - size0;
       break;
     case GRN_ACCESSOR_GET_SCORE :
-      grn_obj_get_value(ctx, a->obj, id, value);
       {
         grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs);
         GRN_INT32_PUT(ctx, value, ri->score);
@@ -6048,14 +6080,30 @@ grn_obj_get_value(grn_ctx *ctx, grn_obj *obj, grn_id id, grn_obj *value)
   case GRN_TABLE_HASH_KEY :
     {
       grn_hash *hash = (grn_hash *)obj;
-      uint32_t size = hash->value_size;
       grn_obj_ensure_bulk(ctx, value);
-      if (grn_bulk_space(ctx, value, size)) {
-        MERR("grn_bulk_space failed");
-        goto exit;
-      }
-      {
-        char *curr = GRN_BULK_CURR(value);
+      if (obj->header.flags & GRN_OBJ_WITH_SUBREC) {
+        if (DB_OBJ(obj)->max_n_subrecs > 0 && DB_OBJ(obj)->subrec_offset == 0) {
+          uint32_t size;
+          const char *raw_value;
+          const grn_rset_recinfo *ri;
+          grn_rset_posinfo *pi;
+          int nth_subrec = 0;
+          uint8_t subrec_size = DB_OBJ(obj)->subrec_size;
+          raw_value = grn_hash_get_value_(ctx, hash, id, &size);
+          ri = (const grn_rset_recinfo *)raw_value;
+          pi = GRN_RSET_SUBRECS_NTH_BODY(ri->subrecs, subrec_size, nth_subrec);
+          GRN_RECORD_PUT(ctx, value, pi->rid);
+        } else {
+          GRN_RECORD_PUT(ctx, value, GRN_ID_NIL);
+        }
+      } else {
+        uint32_t size = hash->value_size;
+        char *curr;
+        if (grn_bulk_space(ctx, value, size)) {
+          MERR("grn_bulk_space failed");
+          goto exit;
+        }
+        curr = GRN_BULK_CURR(value);
         grn_hash_get_value(ctx, hash, id, curr - size);
       }
       value->header.type = GRN_BULK;

  Modified: lib/db.h (+5 -1)
===================================================================
--- lib/db.h    2014-06-25 22:16:31 +0900 (1fb7ee5)
+++ lib/db.h    2014-06-25 22:45:26 +0900 (856c9d5)
@@ -58,7 +58,11 @@ typedef struct {
 
 #define GRN_RSET_SUBRECS_CMP(a,b,dir) (((a) - (b))*(dir))
 #define GRN_RSET_SUBRECS_NTH(subrecs,size,n) \
-  ((int *)((byte *)subrecs + n * (GRN_RSET_SCORE_SIZE + size)))
+  ((int *)((byte *)(subrecs) + n * (GRN_RSET_SCORE_SIZE + size)))
+#define GRN_RSET_SUBRECS_NTH_BODY(subrecs,size,n) \
+  ((grn_rset_posinfo *)((byte *)(subrecs) + \
+                        n * (GRN_RSET_SCORE_SIZE + size) + \
+                        GRN_RSET_SCORE_SIZE))
 #define GRN_RSET_SUBRECS_COPY(subrecs,size,n,src) \
   (memcpy(GRN_RSET_SUBRECS_NTH(subrecs, size, n), src, GRN_RSET_SCORE_SIZE + size))
 

  Modified: lib/output.c (+0 -1)
===================================================================
--- lib/output.c    2014-06-25 22:16:31 +0900 (855c65b)
+++ lib/output.c    2014-06-25 22:45:26 +0900 (097d253)
@@ -521,7 +521,6 @@ grn_text_atoj(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type,
         buf.header.domain = DB_OBJ(a->obj)->range;
         break;
       case GRN_ACCESSOR_GET_SCORE :
-        grn_obj_get_value(ctx, a->obj, id, &buf);
         {
           grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs);
           GRN_INT32_PUT(ctx, &buf, ri->score);

  Modified: lib/proc.c (+3 -1)
===================================================================
--- lib/proc.c    2014-06-25 22:16:31 +0900 (f61fed9)
+++ lib/proc.c    2014-06-25 22:45:26 +0900 (618ad56)
@@ -830,8 +830,10 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len,
         grn_table_group_result g = {NULL, 0, 0, 1, GRN_TABLE_GROUP_CALC_COUNT, 0};
         if (gkeys) {
           for (i = 0; i < ngkeys; i++) {
+            unsigned int max_n_subrecs = 1;
             if ((g.table = grn_table_create_for_group(ctx, NULL, 0, NULL,
-                                                      gkeys[i].key, res, 0))) {
+                                                      gkeys[i].key, res,
+                                                      max_n_subrecs))) {
               int n_drilldown_offset = drilldown_offset,
                   n_drilldown_limit = drilldown_limit;
 

  Added: test/command/suite/select/drilldown_sortby/real_column.expected (+82 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldown_sortby/real_column.expected    2014-06-25 22:45:26 +0900 (0a19a71)
@@ -0,0 +1,82 @@
+table_create Bookmarks TABLE_HASH_KEY UInt32
+[[0,0.0,0.0],true]
+column_create Bookmarks url COLUMN_SCALAR ShortText
+[[0,0.0,0.0],true]
+column_create Bookmarks user COLUMN_SCALAR ShortText
+[[0,0.0,0.0],true]
+load --table Bookmarks
+[
+{"_key": 1, "url": "http://groonga.org/", "user": "mori"},
+{"_key": 2, "url": "http://groonga.org/", "user": "kou"},
+{"_key": 3, "url": "http://groonga.org/", "user": "s-yata"},
+{"_key": 4, "url": "http://mroonga.org/", "user": "kou"},
+{"_key": 5, "url": "http://droonga.org/", "user": "piro"}
+]
+[[0,0.0,0.0],5]
+select Bookmarks   --limit 0   --drilldown url   --drilldown_sortby user   --drilldown_output_columns _key,_nsubrecs,user
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        5
+      ],
+      [
+        [
+          "_id",
+          "UInt32"
+        ],
+        [
+          "_key",
+          "UInt32"
+        ],
+        [
+          "url",
+          "ShortText"
+        ],
+        [
+          "user",
+          "ShortText"
+        ]
+      ]
+    ],
+    [
+      [
+        3
+      ],
+      [
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "_nsubrecs",
+          "Int32"
+        ],
+        [
+          "user",
+          "ShortText"
+        ]
+      ],
+      [
+        "http://mroonga.org/",
+        1,
+        "kou"
+      ],
+      [
+        "http://groonga.org/",
+        3,
+        "mori"
+      ],
+      [
+        "http://droonga.org/",
+        1,
+        "piro"
+      ]
+    ]
+  ]
+]

  Added: test/command/suite/select/drilldown_sortby/real_column.test (+18 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/drilldown_sortby/real_column.test    2014-06-25 22:45:26 +0900 (d07b112)
@@ -0,0 +1,18 @@
+table_create Bookmarks TABLE_HASH_KEY UInt32
+column_create Bookmarks url COLUMN_SCALAR ShortText
+column_create Bookmarks user COLUMN_SCALAR ShortText
+
+load --table Bookmarks
+[
+{"_key": 1, "url": "http://groonga.org/", "user": "mori"},
+{"_key": 2, "url": "http://groonga.org/", "user": "kou"},
+{"_key": 3, "url": "http://groonga.org/", "user": "s-yata"},
+{"_key": 4, "url": "http://mroonga.org/", "user": "kou"},
+{"_key": 5, "url": "http://droonga.org/", "user": "piro"}
+]
+
+select Bookmarks \
+  --limit 0 \
+  --drilldown url \
+  --drilldown_sortby user \
+  --drilldown_output_columns _key,_nsubrecs,user
-------------- next part --------------
HTML����������������������������...
下载 



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