Kouhei Sutou
null+****@clear*****
Thu May 12 11:59:05 JST 2016
Kouhei Sutou 2016-05-12 11:59:05 +0900 (Thu, 12 May 2016) New Revision: dbfe26e9a9fb0232fdf6726a5d16205323450d48 https://github.com/groonga/groonga/commit/dbfe26e9a9fb0232fdf6726a5d16205323450d48 Message: select: add drilldown_filter TODO: * Write document * Clean implementation Added files: test/command/suite/select/drilldown/plain/filter/key.expected test/command/suite/select/drilldown/plain/filter/key.test Modified files: lib/proc/proc_select.c Modified: lib/proc/proc_select.c (+88 -10) =================================================================== --- lib/proc/proc_select.c 2016-05-12 10:05:21 +0900 (0a698be) +++ lib/proc/proc_select.c 2016-05-12 11:59:05 +0900 (00222bf) @@ -79,6 +79,7 @@ typedef struct { int limit; grn_table_group_flags calc_types; grn_select_string calc_target_name; + grn_select_string filter; grn_select_string table_name; grn_columns columns; } grn_drilldown_data; @@ -558,6 +559,7 @@ grn_drilldown_data_fill(grn_ctx *ctx, grn_obj *limit, grn_obj *calc_types, grn_obj *calc_target, + grn_obj *filter, grn_obj *table) { GRN_SELECT_FILL_STRING(drilldown->keys, keys); @@ -595,6 +597,8 @@ grn_drilldown_data_fill(grn_ctx *ctx, GRN_SELECT_FILL_STRING(drilldown->calc_target_name, calc_target); + GRN_SELECT_FILL_STRING(drilldown->filter, filter); + GRN_SELECT_FILL_STRING(drilldown->table_name, table); } @@ -606,6 +610,7 @@ grn_select_drilldown(grn_ctx *ctx, grn_obj *table, uint32_t i; for (i = 0; i < n_keys; i++) { grn_table_group_result g = {NULL, 0, 0, 1, GRN_TABLE_GROUP_CALC_COUNT, 0}; + grn_obj *target_table; uint32_t n_hits; int offset; int limit; @@ -623,7 +628,67 @@ grn_select_drilldown(grn_ctx *ctx, grn_obj *table, if (ctx->rc != GRN_SUCCESS) { break; } - n_hits = grn_table_size(ctx, g.table); + + if (drilldown->filter.length > 0) { + grn_obj *expression; + grn_obj *record; + GRN_EXPR_CREATE_FOR_QUERY(ctx, g.table, expression, record); + if (!expression) { + char error_message[GRN_CTX_MSGSIZE]; + grn_memcpy(error_message, ctx->errbuf, GRN_CTX_MSGSIZE); + grn_obj_close(ctx, g.table); + GRN_PLUGIN_ERROR(ctx, + GRN_INVALID_ARGUMENT, + "[select][drilldown][filter] " + "failed to create expression for filter: %s", + error_message); + break; + } + grn_expr_parse(ctx, + expression, + drilldown->filter.value, + drilldown->filter.length, + NULL, + GRN_OP_MATCH, + GRN_OP_AND, + GRN_EXPR_SYNTAX_SCRIPT); + if (ctx->rc != GRN_SUCCESS) { + char error_message[GRN_CTX_MSGSIZE]; + grn_memcpy(error_message, ctx->errbuf, GRN_CTX_MSGSIZE); + grn_obj_close(ctx, expression); + grn_obj_close(ctx, g.table); + GRN_PLUGIN_ERROR(ctx, + GRN_INVALID_ARGUMENT, + "[select][drilldown][filter] " + "failed to parse filter: <%.*s>: %s", + (int)(drilldown->filter.length), + drilldown->filter.value, + error_message); + break; + } + target_table = grn_table_select(ctx, g.table, expression, NULL, GRN_OP_OR); + if (ctx->rc != GRN_SUCCESS) { + char error_message[GRN_CTX_MSGSIZE]; + grn_memcpy(error_message, ctx->errbuf, GRN_CTX_MSGSIZE); + grn_obj_close(ctx, expression); + if (target_table) { + grn_obj_close(ctx, target_table); + } + grn_obj_close(ctx, g.table); + GRN_PLUGIN_ERROR(ctx, + GRN_INVALID_ARGUMENT, + "[select][drilldown][filter] " + "failed to execute filter: <%.*s>: %s", + (int)(drilldown->filter.length), + drilldown->filter.value, + error_message); + break; + } + } else { + target_table = g.table; + } + + n_hits = grn_table_size(ctx, target_table); offset = drilldown->offset; limit = drilldown->limit; @@ -635,14 +700,14 @@ grn_select_drilldown(grn_ctx *ctx, grn_obj *table, sort_keys = grn_table_sort_key_from_str(ctx, drilldown->sortby.value, drilldown->sortby.length, - g.table, &n_sort_keys); + target_table, &n_sort_keys); if (sort_keys) { grn_obj *sorted; sorted = grn_table_create(ctx, NULL, 0, NULL, GRN_OBJ_TABLE_NO_KEY, - NULL, g.table); + NULL, target_table); if (sorted) { grn_obj_format format; - grn_table_sort(ctx, g.table, offset, limit, + grn_table_sort(ctx, target_table, offset, limit, sorted, sort_keys, n_sort_keys); GRN_OBJ_FORMAT_INIT(&format, n_hits, 0, limit, offset); format.flags = @@ -664,14 +729,17 @@ grn_select_drilldown(grn_ctx *ctx, grn_obj *table, format.flags = GRN_OBJ_FORMAT_WITH_COLUMN_NAMES| GRN_OBJ_FORMAT_XML_ELEMENT_NAVIGATIONENTRY; - grn_obj_columns(ctx, g.table, + grn_obj_columns(ctx, target_table, drilldown->output_columns.value, drilldown->output_columns.length, &format.columns); - GRN_OUTPUT_OBJ(g.table, &format); + GRN_OUTPUT_OBJ(target_table, &format); GRN_OBJ_FORMAT_FIN(ctx, &format); } - grn_obj_unlink(ctx, g.table); + if (target_table != g.table) { + grn_obj_close(ctx, target_table); + } + grn_obj_close(ctx, g.table); GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_SIZE, ":", "drilldown(%d)", n_hits); } @@ -1878,6 +1946,8 @@ grn_select_data_fill_drilldowns(grn_ctx *ctx, "drilldown_calc_types", -1), grn_plugin_proc_get_var(ctx, user_data, "drilldown_calc_target", -1), + grn_plugin_proc_get_var(ctx, user_data, + "drilldown_filter", -1), NULL); } else { unsigned int i; @@ -1954,8 +2024,15 @@ grn_select_data_fill_drilldowns(grn_ctx *ctx, #undef GET_VAR grn_drilldown_data_fill(ctx, drilldown, - keys, sortby, output_columns, offset, limit, - calc_types, calc_target, table); + keys, + sortby, + output_columns, + offset, + limit, + calc_types, + calc_target, + NULL, + table); i++; } grn_table_cursor_close(ctx, cursor); @@ -2067,7 +2144,7 @@ exit : return NULL; } -#define N_VARS 23 +#define N_VARS 24 #define DEFINE_VARS grn_expr_var vars[N_VARS] static void @@ -2097,6 +2174,7 @@ init_vars(grn_ctx *ctx, grn_expr_var *vars) grn_plugin_expr_var_init(ctx, &(vars[20]), "adjuster", -1); grn_plugin_expr_var_init(ctx, &(vars[21]), "drilldown_calc_types", -1); grn_plugin_expr_var_init(ctx, &(vars[22]), "drilldown_calc_target", -1); + grn_plugin_expr_var_init(ctx, &(vars[23]), "drilldown_filter", -1); } void Added: test/command/suite/select/drilldown/plain/filter/key.expected (+86 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/drilldown/plain/filter/key.expected 2016-05-12 11:59:05 +0900 (57435d0) @@ -0,0 +1,86 @@ +table_create Tags TABLE_PAT_KEY 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 Tags +[[0,0.0,0.0],true] +load --table Memos +[ +{"_key": "Groonga is fast!", "tag": "Groonga"}, +{"_key": "Mroonga is fast!", "tag": "Mroonga"}, +{"_key": "Groonga sticker!", "tag": "Groonga"}, +{"_key": "Rroonga is fast!", "tag": "Rroonga"} +] +[[0,0.0,0.0],4] +select Memos --drilldown tag --drilldown_filter '_key != "Groonga"' +[ + [ + 0, + 0.0, + 0.0 + ], + [ + [ + [ + 4 + ], + [ + [ + "_id", + "UInt32" + ], + [ + "_key", + "ShortText" + ], + [ + "tag", + "Tags" + ] + ], + [ + 1, + "Groonga is fast!", + "Groonga" + ], + [ + 2, + "Mroonga is fast!", + "Mroonga" + ], + [ + 3, + "Groonga sticker!", + "Groonga" + ], + [ + 4, + "Rroonga is fast!", + "Rroonga" + ] + ], + [ + [ + 2 + ], + [ + [ + "_key", + "ShortText" + ], + [ + "_nsubrecs", + "Int32" + ] + ], + [ + "Mroonga", + 1 + ], + [ + "Rroonga", + 1 + ] + ] + ] +] Added: test/command/suite/select/drilldown/plain/filter/key.test (+17 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/drilldown/plain/filter/key.test 2016-05-12 11:59:05 +0900 (9f6aa9d) @@ -0,0 +1,17 @@ +table_create Tags TABLE_PAT_KEY ShortText + +table_create Memos TABLE_HASH_KEY ShortText +column_create Memos tag COLUMN_SCALAR Tags + +load --table Memos +[ +{"_key": "Groonga is fast!", "tag": "Groonga"}, +{"_key": "Mroonga is fast!", "tag": "Mroonga"}, +{"_key": "Groonga sticker!", "tag": "Groonga"}, +{"_key": "Rroonga is fast!", "tag": "Rroonga"} +] + +select Memos \ + --drilldown tag \ + --drilldown_filter '_key != "Groonga"' + -------------- next part -------------- HTML����������������������������...ダウンロード