null+****@clear*****
null+****@clear*****
2012年 6月 26日 (火) 14:50:36 JST
Daijiro MORI 2012-06-26 14:50:36 +0900 (Tue, 26 Jun 2012) New Revision: b2a7fb3eb5be1a999fe75fe5a859a257bb29f128 https://github.com/groonga/groonga/commit/b2a7fb3eb5be1a999fe75fe5a859a257bb29f128 Log: table: add filter command. Added files: test/function/suite/table/filter.expected test/function/suite/table/filter.test Modified files: lib/db.h lib/expr.c plugins/table/table.c Modified: lib/db.h (+7 -1) =================================================================== --- lib/db.h 2012-06-26 14:38:25 +0900 (6054433) +++ lib/db.h 2012-06-26 14:50:36 +0900 (b973242) @@ -442,7 +442,13 @@ GRN_API void grn_load_(grn_ctx *ctx, grn_content_type input_type, GRN_API grn_rc grn_table_group_with_range_gap(grn_ctx *ctx, grn_obj *table, grn_table_sort_key *group_key, - grn_obj *result_set, uint32_t range_gap); + grn_obj *result_set, + uint32_t range_gap); + +GRN_API grn_rc grn_column_filter(grn_ctx *ctx, grn_obj *column, + grn_operator op, + grn_obj *value, grn_obj *result_set, + grn_operator set_op); #ifdef __cplusplus } Modified: lib/expr.c (+29 -0) =================================================================== --- lib/expr.c 2012-06-26 14:38:25 +0900 (5e5a7b3) +++ lib/expr.c 2012-06-26 14:50:36 +0900 (afb5660) @@ -5758,3 +5758,32 @@ grn_expr_snip(grn_ctx *ctx, grn_obj *expr, int flags, } GRN_API_RETURN(res); } + +/* + So far, grn_column_filter() is nothing but a very rough prototype. + Although GRN_COLUMN_EACH() can accelerate many range queries, + the following stuff must be resolved one by one. + + * support accessors as column + * support tables which have deleted records + * support various operators + * support various column types +*/ +grn_rc +grn_column_filter(grn_ctx *ctx, grn_obj *column, + grn_operator operator, + grn_obj *value, grn_obj *result_set, + grn_operator set_operation) +{ + uint32_t *vp; + grn_rset_posinfo pi; + uint32_t value_ = grn_atoui(GRN_TEXT_VALUE(value), GRN_BULK_CURR(value), NULL); + GRN_COLUMN_EACH(ctx, column, id, vp, { + if (*vp < value_) { + pi.rid = id; + res_add(ctx, (grn_hash *)result_set, &pi, 1, set_operation); + } + }); + grn_ii_resolve_sel_and(ctx, (grn_hash *)result_set, set_operation); + return ctx->rc; +} Modified: plugins/table/table.c (+57 -0) =================================================================== --- plugins/table/table.c 2012-06-26 14:38:25 +0900 (ea8701b) +++ plugins/table/table.c 2012-06-26 14:50:36 +0900 (e6354c5) @@ -175,6 +175,55 @@ command_filter_by_script(grn_ctx *ctx, int nargs, } static grn_obj * +command_filter(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) +{ + grn_operator operator = GRN_OP_NOP; + grn_obj *table, *column, *result_set = NULL; + if (!(table = grn_ctx_get_table_by_name_or_id(ctx, TEXT_VALUE_LEN(VAR(0))))) { + goto exit; + } + if (!(column = grn_obj_column(ctx, table, TEXT_VALUE_LEN(VAR(1))))) { + ERR(GRN_INVALID_ARGUMENT, "invalid column name: <%.*s>", + GRN_TEXT_LEN(VAR(1)), GRN_TEXT_VALUE(VAR(1))); + goto exit; + } + if (TEXT_VALUE_LEN(VAR(2)) == 0) { + ERR(GRN_INVALID_ARGUMENT, "missing mandatory argument: operator"); + goto exit; + } else { + uint32_t operator_len = GRN_TEXT_LEN(VAR(2)); + const char *operator_text = GRN_TEXT_VALUE(VAR(2)); + switch (operator_text[0]) { + case '<' : + if (operator_len == 1) { + operator = GRN_OP_LESS; + } + break; + } + if (operator == GRN_OP_NOP) { + ERR(GRN_INVALID_ARGUMENT, "invalid operator: <%.*s>", + operator_len, operator_text); + goto exit; + } + } + if (GRN_TEXT_LEN(VAR(4))) { + result_set = grn_ctx_get_table_by_name_or_id(ctx, TEXT_VALUE_LEN(VAR(4))); + } else { + result_set = grn_table_create(ctx, NULL, 0, NULL, + GRN_TABLE_HASH_KEY| + GRN_OBJ_WITH_SUBREC, + table, NULL); + } + if (result_set) { + grn_column_filter(ctx, column, operator, VAR(3), result_set, + parse_set_operator_value(ctx, VAR(5))); + } +exit : + grn_output_table_name_or_id(ctx, result_set); + return NULL; +} + +static grn_obj * command_group(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) { @@ -549,6 +598,14 @@ GRN_PLUGIN_REGISTER(grn_ctx *ctx) DEF_COMMAND("filter_by_script", command_filter_by_script, 5, vars); DEF_VAR(vars[0], "table"); + DEF_VAR(vars[1], "column"); + DEF_VAR(vars[2], "operator"); + DEF_VAR(vars[3], "value"); + DEF_VAR(vars[4], "result_set"); + DEF_VAR(vars[5], "set_operation"); + DEF_COMMAND("filter", command_filter, 6, vars); + + DEF_VAR(vars[0], "table"); DEF_VAR(vars[1], "key"); DEF_VAR(vars[2], "result_set"); DEF_VAR(vars[3], "range_gap"); Added: test/function/suite/table/filter.expected (+71 -0) 100644 =================================================================== --- /dev/null +++ test/function/suite/table/filter.expected 2012-06-26 14:50:36 +0900 (9afe66e) @@ -0,0 +1,71 @@ +register table/table +[[0,0.0,0.0],true] +table_create Shops TABLE_PAT_KEY ShortText +[[0,0.0,0.0],true] +table_create Tags TABLE_PAT_KEY ShortText +[[0,0.0,0.0],true] +column_create Shops tags COLUMN_VECTOR Tags +[[0,0.0,0.0],true] +column_create Tags shops_tag COLUMN_INDEX Shops tags +[[0,0.0,0.0],true] +column_create Shops budget COLUMN_SCALAR UInt32 +[[0,0.0,0.0],true] +add Shops '{"_key":"くりこあん","tags":["たいやき","養殖"],"budget":180}' +[[0,0.0,0.0],true] +add Shops '{"_key":"なか一","tags":["季節料理"],"budget":800}' +[[0,0.0,0.0],true] +add Shops '{"_key":"魚寅食堂","tags":["漁師","季節料理"],"budget":750}' +[[0,0.0,0.0],true] +add Shops '{"_key":"DRAGON飯店","tags":["中華"],"budget":600}' +[[0,0.0,0.0],true] +add Shops '{"_key":"魚浜","tags":["回転寿司"],"budget":600}' +[[0,0.0,0.0],true] +add Shops '{"_key":"beanDaisy","tags":["caffe","カプチーノ"],"budget":650}' +[[0,0.0,0.0],true] +add Shops '{"_key":"維新","tags":["麺や"],"budget":800}' +[[0,0.0,0.0],true] +add Shops '{"_key":"ひづめ","tags":["とんかつ"],"budget":900}' +[[0,0.0,0.0],true] +add Shops '{"_key":"和互","tags":["魚"],"budget":1000}' +[[0,0.0,0.0],true] +filter Shops budget < 700 +[[0,0.0,0.0],2147483649] +output 2147483649 _key,budget +[ + [ + 0, + 0.0, + 0.0 + ], + [ + [ + 4 + ], + [ + [ + "_key", + "ShortText" + ], + [ + "budget", + "UInt32" + ] + ], + [ + "くりこあん", + 180 + ], + [ + "DRAGON飯店", + 600 + ], + [ + "魚浜", + 600 + ], + [ + "beanDaisy", + 650 + ] + ] +] Added: test/function/suite/table/filter.test (+18 -0) 100644 =================================================================== --- /dev/null +++ test/function/suite/table/filter.test 2012-06-26 14:50:36 +0900 (569780b) @@ -0,0 +1,18 @@ +register table/table +table_create Shops TABLE_PAT_KEY ShortText +table_create Tags TABLE_PAT_KEY ShortText +column_create Shops tags COLUMN_VECTOR Tags +column_create Tags shops_tag COLUMN_INDEX Shops tags +column_create Shops budget COLUMN_SCALAR UInt32 + +add Shops '{"_key":"くりこあん","tags":["たいやき","養殖"],"budget":180}' +add Shops '{"_key":"なか一","tags":["季節料理"],"budget":800}' +add Shops '{"_key":"魚寅食堂","tags":["漁師","季節料理"],"budget":750}' +add Shops '{"_key":"DRAGON飯店","tags":["中華"],"budget":600}' +add Shops '{"_key":"魚浜","tags":["回転寿司"],"budget":600}' +add Shops '{"_key":"beanDaisy","tags":["caffe","カプチーノ"],"budget":650}' +add Shops '{"_key":"維新","tags":["麺や"],"budget":800}' +add Shops '{"_key":"ひづめ","tags":["とんかつ"],"budget":900}' +add Shops '{"_key":"和互","tags":["魚"],"budget":1000}' +filter Shops budget < 700 +output 2147483649 _key,budget -------------- next part -------------- HTML$B$NE:IU%U%!%$%k$rJ]4I$7$^$7$?(B... 다운로드