Naoya Murakami
null+****@clear*****
Mon May 9 21:27:06 JST 2016
Naoya Murakami 2016-05-09 21:27:06 +0900 (Mon, 09 May 2016) New Revision: 08b4d7c88a0914d33e7af7b33c5724cab9a1b772 https://github.com/groonga/groonga/commit/08b4d7c88a0914d33e7af7b33c5724cab9a1b772 Merged 95aeba5: Merge pull request #542 from naoa/drilldown-dynamic-column Message: select drilldown: support dynamic column creation as initial stage Added files: test/command/suite/select/drilldown/labeled/column/stage/initial/output_columns.expected test/command/suite/select/drilldown/labeled/column/stage/initial/output_columns.test Modified files: lib/proc/proc_select.c Modified: lib/proc/proc_select.c (+126 -4) =================================================================== --- lib/proc/proc_select.c 2016-05-09 18:47:55 +0900 (65c009e) +++ lib/proc/proc_select.c 2016-05-09 21:27:06 +0900 (81ccbdc) @@ -61,9 +61,13 @@ typedef struct { grn_table_group_flags calc_types; grn_select_string calc_target_name; grn_select_string table_name; + struct { + grn_hash *initial; + } columns; } grn_drilldown_data; typedef enum { + GRN_COLUMN_STAGE_INITIAL, GRN_COLUMN_STAGE_FILTERED } grn_column_stage; @@ -309,6 +313,8 @@ static const char * grn_column_stage_name(grn_column_stage stage) { switch (stage) { + case GRN_COLUMN_STAGE_INITIAL : + return "initial"; case GRN_COLUMN_STAGE_FILTERED : return "filtered"; default : @@ -839,6 +845,10 @@ grn_select_drilldowns_execute(grn_ctx *ctx, if (keys) { grn_table_sort_key_close(ctx, keys, n_keys); } + if (drilldown->columns.initial) { + grn_select_apply_columns(ctx, result->table, drilldown->columns.initial, + condition); + } } exit : @@ -1504,7 +1514,9 @@ grn_column_data_fill(grn_ctx *ctx, static grn_bool grn_column_data_collect(grn_ctx *ctx, grn_user_data *user_data, - grn_hash *columns) + grn_hash *columns, + const char *prefix_label, + size_t prefix_label_len) { grn_hash_cursor *cursor = NULL; cursor = grn_hash_cursor_open(ctx, columns, @@ -1526,7 +1538,9 @@ grn_column_data_collect(grn_ctx *ctx, grn_snprintf(key_name, \ GRN_TABLE_MAX_KEY_SIZE, \ GRN_TABLE_MAX_KEY_SIZE, \ - "column[%.*s]." # name, \ + "%.*scolumn[%.*s]." # name, \ + (int)prefix_label_len, \ + prefix_label, \ (int)(column->label.length), \ column->label.value); \ name = grn_plugin_proc_get_var(ctx, user_data, key_name, -1); @@ -1621,7 +1635,8 @@ grn_select_data_fill_columns(grn_ctx *ctx, return GRN_TRUE; } - if (!grn_column_data_collect(ctx, user_data, data->columns.filtered)) { + if (!grn_column_data_collect(ctx, user_data, data->columns.filtered, + NULL, 0)) { return GRN_FALSE; } @@ -1629,6 +1644,98 @@ grn_select_data_fill_columns(grn_ctx *ctx, } static grn_bool +grn_drilldown_data_fill_columns_collect(grn_ctx *ctx, + grn_user_data *user_data, + grn_drilldown_data *data, + const char *drilldown_label) +{ + grn_obj *vars; + grn_table_cursor *cursor; + const char *prefix = "column["; + size_t prefix_len; + const char *suffix = "].stage"; + size_t suffix_len; + size_t drilldown_label_len = strlen(drilldown_label); + + vars = grn_plugin_proc_get_vars(ctx, user_data); + cursor = grn_table_cursor_open(ctx, vars, NULL, 0, NULL, 0, 0, -1, 0); + if (!cursor) { + return GRN_FALSE; + } + + prefix_len = strlen(prefix); + suffix_len = strlen(suffix); + while (grn_table_cursor_next(ctx, cursor)) { + void *key; + char *name; + int name_len; + void *value_raw; + grn_obj *value; + grn_column_stage stage; + + name_len = grn_table_cursor_get_key(ctx, cursor, &key); + name = key; + + name += drilldown_label_len; + name_len -= drilldown_label_len; + + if (name_len < prefix_len + suffix_len + 1) { + continue; + } + + if (memcmp(prefix, name, prefix_len) != 0) { + continue; + } + + if (memcmp(suffix, name + (name_len - suffix_len), suffix_len) != 0) { + continue; + } + + grn_table_cursor_get_value(ctx, cursor, &value_raw); + value = value_raw; + if (GRN_BULK_EQUAL_STRING(value, "initial")) { + stage = GRN_COLUMN_STAGE_INITIAL; + } else { + continue; + } + + if (!grn_column_data_init(ctx, + name + prefix_len, + name_len - prefix_len - suffix_len, + stage, + &(data->columns.initial))) { + grn_table_cursor_close(ctx, cursor); + return GRN_FALSE; + } + } + grn_table_cursor_close(ctx, cursor); + + return GRN_TRUE; +} + +static grn_bool +grn_drilldown_data_fill_columns(grn_ctx *ctx, + grn_user_data *user_data, + grn_drilldown_data *data, + const char *drilldown_label) +{ + if (!grn_drilldown_data_fill_columns_collect(ctx, user_data, data, + drilldown_label)) { + return GRN_FALSE; + } + + if (!data->columns.initial) { + return GRN_TRUE; + } + + if (!grn_column_data_collect(ctx, user_data, data->columns.initial, + drilldown_label, strlen(drilldown_label))) { + return GRN_FALSE; + } + return GRN_TRUE; +} + +static grn_bool grn_select_data_fill_drilldown_labels(grn_ctx *ctx, grn_user_data *user_data, grn_select_data *data) @@ -1702,6 +1809,7 @@ grn_select_data_fill_drilldowns(grn_ctx *ctx, drilldown_data = &(data->drilldowns[0]); drilldown_data->label.value = NULL; drilldown_data->label.length = 0; + drilldown_data->columns.initial = NULL; grn_drilldown_data_fill(ctx, drilldown_data, drilldown, @@ -1746,6 +1854,7 @@ grn_select_data_fill_drilldowns(grn_ctx *ctx, grn_drilldown_data *drilldown = &(data->drilldowns[i]); const char *label; int label_len; + char drilldown_label[GRN_TABLE_MAX_KEY_SIZE]; char key_name[GRN_TABLE_MAX_KEY_SIZE]; grn_obj *keys; grn_obj *sortby; @@ -1759,12 +1868,16 @@ grn_select_data_fill_drilldowns(grn_ctx *ctx, label_len = grn_table_cursor_get_key(ctx, cursor, (void **)&label); drilldown->label.value = label; drilldown->label.length = label_len; + grn_snprintf(drilldown_label, + GRN_TABLE_MAX_KEY_SIZE, + GRN_TABLE_MAX_KEY_SIZE, + "drilldown[%.*s].", label_len, label); #define GET_VAR(name) \ grn_snprintf(key_name, \ GRN_TABLE_MAX_KEY_SIZE, \ GRN_TABLE_MAX_KEY_SIZE, \ - "drilldown[%.*s]." # name, label_len, label); \ + "%s" # name, drilldown_label); \ name = grn_plugin_proc_get_var(ctx, user_data, key_name, -1); GET_VAR(keys); @@ -1778,6 +1891,8 @@ grn_select_data_fill_drilldowns(grn_ctx *ctx, #undef GET_VAR + grn_drilldown_data_fill_columns(ctx, user_data, drilldown, + drilldown_label); grn_drilldown_data_fill(ctx, drilldown, keys, sortby, output_columns, offset, limit, calc_types, calc_target, table); @@ -1881,6 +1996,13 @@ exit : } if (data.drilldowns) { + int i; + for (i = 0; i < data.n_drilldowns; i++) { + grn_drilldown_data *drilldown = &(data.drilldowns[i]); + if (drilldown->columns.initial) { + grn_hash_close(ctx, drilldown->columns.initial); + } + } GRN_PLUGIN_FREE(ctx, data.drilldowns); } if (data.drilldown_labels) { Added: test/command/suite/select/drilldown/labeled/column/stage/initial/output_columns.expected (+109 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/drilldown/labeled/column/stage/initial/output_columns.expected 2016-05-09 21:27:06 +0900 (2ccba59) @@ -0,0 +1,109 @@ +table_create Items TABLE_HASH_KEY ShortText +[[0,0.0,0.0],true] +column_create Items price COLUMN_SCALAR UInt32 +[[0,0.0,0.0],true] +load --table Items +[ +{"_key": "Book", "price": 1000}, +{"_key": "Note", "price": 1000}, +{"_key": "Box", "price": 500}, +{"_key": "Pen", "price": 500}, +{"_key": "Food", "price": 500}, +{"_key": "Drink", "price": 300} +] +[[0,0.0,0.0],6] +select Items --drilldown[label].keys price --drilldown[label].output_columns _key,_nsubrecs,tax_included --drilldown[label].column[tax_included].stage initial --drilldown[label].column[tax_included].type UInt32 --drilldown[label].column[tax_included].flags COLUMN_SCALAR --drilldown[label].column[tax_included].value '_key * 1.08' +[ + [ + 0, + 0.0, + 0.0 + ], + [ + [ + [ + 6 + ], + [ + [ + "_id", + "UInt32" + ], + [ + "_key", + "ShortText" + ], + [ + "price", + "UInt32" + ] + ], + [ + 1, + "Book", + 1000 + ], + [ + 2, + "Note", + 1000 + ], + [ + 3, + "Box", + 500 + ], + [ + 4, + "Pen", + 500 + ], + [ + 5, + "Food", + 500 + ], + [ + 6, + "Drink", + 300 + ] + ], + { + "label": [ + [ + 3 + ], + [ + [ + "_key", + "UInt32" + ], + [ + "_nsubrecs", + "Int32" + ], + [ + "tax_included", + "UInt32" + ] + ], + [ + 1000, + 2, + 1080 + ], + [ + 500, + 3, + 540 + ], + [ + 300, + 1, + 324 + ] + ] + } + ] +] Added: test/command/suite/select/drilldown/labeled/column/stage/initial/output_columns.test (+20 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/drilldown/labeled/column/stage/initial/output_columns.test 2016-05-09 21:27:06 +0900 (1f23c41) @@ -0,0 +1,20 @@ +table_create Items TABLE_HASH_KEY ShortText +column_create Items price COLUMN_SCALAR UInt32 + +load --table Items +[ +{"_key": "Book", "price": 1000}, +{"_key": "Note", "price": 1000}, +{"_key": "Box", "price": 500}, +{"_key": "Pen", "price": 500}, +{"_key": "Food", "price": 500}, +{"_key": "Drink", "price": 300} +] + +select Items \ + --drilldown[label].keys price \ + --drilldown[label].output_columns _key,_nsubrecs,tax_included \ + --drilldown[label].column[tax_included].stage initial \ + --drilldown[label].column[tax_included].type UInt32 \ + --drilldown[label].column[tax_included].flags COLUMN_SCALAR \ + --drilldown[label].column[tax_included].value '_key * 1.08' -------------- next part -------------- HTML����������������������������... 下載