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����������������������������... 下载