Kouhei Sutou
null+****@clear*****
Wed Dec 28 14:46:08 JST 2016
Kouhei Sutou 2016-12-28 14:46:08 +0900 (Wed, 28 Dec 2016) New Revision: 5fcdfa1b4e45fb8ae3423734eae58f871462ead6 https://github.com/groonga/groonga/commit/5fcdfa1b4e45fb8ae3423734eae58f871462ead6 Message: query: support default_mode option query_expander is also supported as option. Added files: test/command/suite/select/function/query/options/default_mode.expected test/command/suite/select/function/query/options/default_mode.test test/command/suite/select/function/query/options/invalid_default_mode_type.expected test/command/suite/select/function/query/options/invalid_default_mode_type.test test/command/suite/select/function/query/options/query_expander.expected test/command/suite/select/function/query/options/query_expander.test test/command/suite/select/function/query/options/unknown_default_mode.expected test/command/suite/select/function/query/options/unknown_default_mode.test test/command/suite/select/function/query/options/unknown_name.expected test/command/suite/select/function/query/options/unknown_name.test Modified files: lib/proc.c Modified: lib/proc.c (+137 -3) =================================================================== --- lib/proc.c 2016-12-28 11:01:42 +0900 (b59a23f) +++ lib/proc.c 2016-12-28 14:46:08 +0900 (e770d95) @@ -1694,6 +1694,76 @@ selector_to_function_data_fin(grn_ctx *ctx, } } +static grn_operator +parse_mode(grn_ctx *ctx, grn_obj *mode, const char *context) +{ + if (mode->header.domain != GRN_DB_TEXT) { + grn_obj inspected; + GRN_TEXT_INIT(&inspected, 0); + grn_inspect(ctx, &inspected, mode); + GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, + "%s: mode must be text: <%.*s>", + context, + (int)GRN_TEXT_LEN(&inspected), + GRN_TEXT_VALUE(&inspected)); + GRN_OBJ_FIN(ctx, &inspected); + return GRN_OP_NOP; + } + +#define EQUAL_MODE(name) \ + (GRN_TEXT_LEN(mode) == strlen(name) && \ + memcmp(GRN_TEXT_VALUE(mode), name, strlen(name)) == 0) + + if (EQUAL_MODE("==") || EQUAL_MODE("EQUAL")) { + return GRN_OP_EQUAL; + } else if (EQUAL_MODE("!=") || EQUAL_MODE("NOT_EQUAL")) { + return GRN_OP_NOT_EQUAL; + } else if (EQUAL_MODE("<") || EQUAL_MODE("LESS")) { + return GRN_OP_LESS; + } else if (EQUAL_MODE(">") || EQUAL_MODE("GREATER")) { + return GRN_OP_GREATER; + } else if (EQUAL_MODE("<=") || EQUAL_MODE("LESS_EQUAL")) { + return GRN_OP_LESS_EQUAL; + } else if (EQUAL_MODE(">=") || EQUAL_MODE("GREATER_EQUAL")) { + return GRN_OP_GREATER_EQUAL; + } else if (EQUAL_MODE("@") || EQUAL_MODE("MATCH")) { + return GRN_OP_MATCH; + } else if (EQUAL_MODE("*N") || EQUAL_MODE("NEAR")) { + return GRN_OP_NEAR; + } else if (EQUAL_MODE("*S") || EQUAL_MODE("SIMILAR")) { + return GRN_OP_SIMILAR; + } else if (EQUAL_MODE("^") || EQUAL_MODE("PREFIX")) { + return GRN_OP_PREFIX; + } else if (EQUAL_MODE("$") || EQUAL_MODE("SUFFIX")) { + return GRN_OP_SUFFIX; + } else if (EQUAL_MODE("~") || EQUAL_MODE("REGEXP")) { + return GRN_OP_REGEXP; + } else { + GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, + "%s: mode must be one of them: " + "[" + "\"==\", \"EQUAL\", " + "\"!=\", \"NOT_EQUAL\", " + "\"<\", \"LESS\", " + "\">\", \"GREATER\", " + "\"<=\", \"LESS_EQUAL\", " + "\">=\", \"GREATER_EQUAL\", " + "\"@\", \"MATCH\", " + "\"*N\", \"NEAR\", " + "\"*S\", \"SIMILAR\", " + "\"^\", \"PREFIX\", " + "\"$\", \"SUFFIX\", " + "\"~\", \"REGEXP\"" + "]: <%.*s>", + context, + (int)GRN_TEXT_LEN(mode), + GRN_TEXT_VALUE(mode)); + return GRN_OP_NOP; + } + +#undef EQUAL_MODE +} + static grn_rc run_query(grn_ctx *ctx, grn_obj *table, int nargs, grn_obj **args, @@ -1703,6 +1773,7 @@ run_query(grn_ctx *ctx, grn_obj *table, grn_obj *match_columns_string; grn_obj *query; grn_obj *query_expander_name = NULL; + grn_operator default_mode = GRN_OP_MATCH; grn_obj *match_columns = NULL; grn_obj *condition = NULL; grn_obj *dummy_variable; @@ -1710,7 +1781,7 @@ run_query(grn_ctx *ctx, grn_obj *table, /* TODO: support flags by parameters */ if (!(2 <= nargs && nargs <= 3)) { ERR(GRN_INVALID_ARGUMENT, - "wrong number of arguments (%d for 2..3)", nargs); + "query(): wrong number of arguments (%d for 2..3)", nargs); rc = ctx->rc; goto exit; } @@ -1718,7 +1789,70 @@ run_query(grn_ctx *ctx, grn_obj *table, match_columns_string = args[0]; query = args[1]; if (nargs > 2) { - query_expander_name = args[2]; + grn_obj *options = args[2]; + + switch (options->header.type) { + case GRN_BULK : + query_expander_name = options; + break; + case GRN_TABLE_HASH_KEY : + { + grn_hash_cursor *cursor; + void *key; + grn_obj *value; + int key_size; + cursor = grn_hash_cursor_open(ctx, (grn_hash *)options, + NULL, 0, NULL, 0, + 0, -1, 0); + if (!cursor) { + GRN_PLUGIN_ERROR(ctx, GRN_NO_MEMORY_AVAILABLE, + "query(): failed to open cursor for options"); + rc = ctx->rc; + goto exit; + } + while (grn_hash_cursor_next(ctx, cursor) != GRN_ID_NIL) { + grn_hash_cursor_get_key_value(ctx, cursor, &key, &key_size, + (void **)&value); + +#define KEY_EQUAL(name) \ + (key_size == strlen(name) && memcmp(key, name, strlen(name)) == 0) + if (KEY_EQUAL("query_expander")) { + query_expander_name = value; + } else if (KEY_EQUAL("default_mode")) { + default_mode = parse_mode(ctx, value, "query()"); + if (ctx->rc != GRN_SUCCESS) { + grn_hash_cursor_close(ctx, cursor); + rc = ctx->rc; + goto exit; + } + } else { + GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, + "query(): unknown option name: <%.*s>", + key_size, (char *)key); + grn_hash_cursor_close(ctx, cursor); + rc = ctx->rc; + goto exit; + } +#undef KEY_EQUAL + } + grn_hash_cursor_close(ctx, cursor); + } + break; + default : + { + grn_obj inspected; + GRN_TEXT_INIT(&inspected, 0); + grn_inspect(ctx, &inspected, options); + GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, + "query(): " + "3rd argument must be string or object literal: <%.*s>", + (int)GRN_TEXT_LEN(&inspected), + GRN_TEXT_VALUE(&inspected)); + GRN_OBJ_FIN(ctx, &inspected); + } + rc = ctx->rc; + goto exit; + } } if (match_columns_string->header.domain == GRN_DB_TEXT && @@ -1777,7 +1911,7 @@ run_query(grn_ctx *ctx, grn_obj *table, grn_expr_parse(ctx, condition, query_string, query_string_len, - match_columns, GRN_OP_MATCH, GRN_OP_AND, flags); + match_columns, default_mode, GRN_OP_AND, flags); rc = ctx->rc; GRN_OBJ_FIN(ctx, &expanded_query); if (rc != GRN_SUCCESS) { Added: test/command/suite/select/function/query/options/default_mode.expected (+48 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/function/query/options/default_mode.expected 2016-12-28 14:46:08 +0900 (6de2ef8) @@ -0,0 +1,48 @@ +table_create Products TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Products name COLUMN_SCALAR ShortText +[[0,0.0,0.0],true] +load --table Products +[ +["name"], +["Groonga"], +["Mroonga"], +["Rroonga"], +["PGroonga"], +["Ruby"], +["PostgreSQL"] +] +[[0,0.0,0.0],6] +select --table Products --filter 'query("name", "r", {"default_mode": "^"})' +[ + [ + 0, + 0.0, + 0.0 + ], + [ + [ + [ + 2 + ], + [ + [ + "_id", + "UInt32" + ], + [ + "name", + "ShortText" + ] + ], + [ + 3, + "Rroonga" + ], + [ + 5, + "Ruby" + ] + ] + ] +] Added: test/command/suite/select/function/query/options/default_mode.test (+17 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/function/query/options/default_mode.test 2016-12-28 14:46:08 +0900 (b0ca76e) @@ -0,0 +1,17 @@ +table_create Products TABLE_NO_KEY +column_create Products name COLUMN_SCALAR ShortText + +load --table Products +[ +["name"], +["Groonga"], +["Mroonga"], +["Rroonga"], +["PGroonga"], +["Ruby"], +["PostgreSQL"] +] + +select \ + --table Products \ + --filter 'query("name", "r", {"default_mode": "^"})' Added: test/command/suite/select/function/query/options/invalid_default_mode_type.expected (+18 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/function/query/options/invalid_default_mode_type.expected 2016-12-28 14:46:08 +0900 (b79d71c) @@ -0,0 +1,18 @@ +table_create Products TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Products name COLUMN_SCALAR ShortText +[[0,0.0,0.0],true] +load --table Products +[ +["name"], +["Groonga"], +["Mroonga"], +["Rroonga"], +["PGroonga"], +["Ruby"], +["PostgreSQL"] +] +[[0,0.0,0.0],6] +select --table Products --filter 'query("name", "r", {"default_mode": 29})' +[[[-22,0.0,0.0],"query(): mode must be text: <29>"]] +#|e| query(): mode must be text: <29> Added: test/command/suite/select/function/query/options/invalid_default_mode_type.test (+17 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/function/query/options/invalid_default_mode_type.test 2016-12-28 14:46:08 +0900 (3f1e511) @@ -0,0 +1,17 @@ +table_create Products TABLE_NO_KEY +column_create Products name COLUMN_SCALAR ShortText + +load --table Products +[ +["name"], +["Groonga"], +["Mroonga"], +["Rroonga"], +["PGroonga"], +["Ruby"], +["PostgreSQL"] +] + +select \ + --table Products \ + --filter 'query("name", "r", {"default_mode": 29})' Added: test/command/suite/select/function/query/options/query_expander.expected (+53 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/function/query/options/query_expander.expected 2016-12-28 14:46:08 +0900 (1979cae) @@ -0,0 +1,53 @@ +plugin_register "query_expanders/tsv" +[[0,0.0,0.0],true] +table_create Memos TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Memos content COLUMN_SCALAR ShortText +[[0,0.0,0.0],true] +table_create Lexicon TABLE_PAT_KEY ShortText --normalizer NormalizerAuto --default_tokenizer TokenBigram +[[0,0.0,0.0],true] +column_create Lexicon memos_content COLUMN_INDEX|WITH_POSITION Memos content +[[0,0.0,0.0],true] +load --table Memos +[ +["content"], +["Start Groonga!"], +["Start Mroonga!"], +["Start Rroonga!"], +["Start Ruby!"], +["Learning Ruby and Groonga..."] +] +[[0,0.0,0.0],5] +select --table Memos --filter 'query("content", "rroonga", {"query_expander": "QueryExpanderTSV"})' +[ + [ + 0, + 0.0, + 0.0 + ], + [ + [ + [ + 2 + ], + [ + [ + "_id", + "UInt32" + ], + [ + "content", + "ShortText" + ] + ], + [ + 3, + "Start Rroonga!" + ], + [ + 5, + "Learning Ruby and Groonga..." + ] + ] + ] +] Added: test/command/suite/select/function/query/options/query_expander.test (+25 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/function/query/options/query_expander.test 2016-12-28 14:46:08 +0900 (6af78b8) @@ -0,0 +1,25 @@ +#$GRN_QUERY_EXPANDER_TSV_SYNONYMS_FILE=#{base_directory}/tmp/synonyms.tsv +#@copy-path fixture/query_expander/tsv/expand.tsv tmp/synonyms.tsv +plugin_register "query_expanders/tsv" + +table_create Memos TABLE_NO_KEY +column_create Memos content COLUMN_SCALAR ShortText + +table_create Lexicon TABLE_PAT_KEY ShortText \ + --normalizer NormalizerAuto \ + --default_tokenizer TokenBigram +column_create Lexicon memos_content COLUMN_INDEX|WITH_POSITION Memos content + +load --table Memos +[ +["content"], +["Start Groonga!"], +["Start Mroonga!"], +["Start Rroonga!"], +["Start Ruby!"], +["Learning Ruby and Groonga..."] +] + +select \ + --table Memos \ + --filter 'query("content", "rroonga", {"query_expander": "QueryExpanderTSV"})' Added: test/command/suite/select/function/query/options/unknown_default_mode.expected (+27 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/function/query/options/unknown_default_mode.expected 2016-12-28 14:46:08 +0900 (dbab043) @@ -0,0 +1,27 @@ +table_create Products TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Products name COLUMN_SCALAR ShortText +[[0,0.0,0.0],true] +load --table Products +[ +["name"], +["Groonga"], +["Mroonga"], +["Rroonga"], +["PGroonga"], +["Ruby"], +["PostgreSQL"] +] +[[0,0.0,0.0],6] +select --table Products --filter 'query("name", "r", {"default_mode": "unknown"})' +[ + [ + [ + -22, + 0.0, + 0.0 + ], + "query(): mode must be one of them: [\"==\", \"EQUAL\", \"!=\", \"NOT_EQUAL\", \"<\", \"LESS\", \">\", \"GREATER\", \"<=\", \"LESS_EQUAL\", \">=\", \"G" + ] +] +#|e| query(): mode must be one of them: ["==", "EQUAL", "!=", "NOT_EQUAL", "<", "LESS", ">", "GREATER", "<=", "LESS_EQUAL", ">=", "GREATER_EQUAL", "@", "MATCH", "*N", "NEAR", "*S", "SIMILAR", "^", "PREFIX", "$", "SUFFIX", "~", "REGEXP"]: <unknown> Added: test/command/suite/select/function/query/options/unknown_default_mode.test (+17 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/function/query/options/unknown_default_mode.test 2016-12-28 14:46:08 +0900 (19e0aa1) @@ -0,0 +1,17 @@ +table_create Products TABLE_NO_KEY +column_create Products name COLUMN_SCALAR ShortText + +load --table Products +[ +["name"], +["Groonga"], +["Mroonga"], +["Rroonga"], +["PGroonga"], +["Ruby"], +["PostgreSQL"] +] + +select \ + --table Products \ + --filter 'query("name", "r", {"default_mode": "unknown"})' Added: test/command/suite/select/function/query/options/unknown_name.expected (+18 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/function/query/options/unknown_name.expected 2016-12-28 14:46:08 +0900 (e7d062c) @@ -0,0 +1,18 @@ +table_create Products TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Products name COLUMN_SCALAR ShortText +[[0,0.0,0.0],true] +load --table Products +[ +["name"], +["Groonga"], +["Mroonga"], +["Rroonga"], +["PGroonga"], +["Ruby"], +["PostgreSQL"] +] +[[0,0.0,0.0],6] +select --table Products --filter 'query("name", "r", {"unknown": "^"})' +[[[-22,0.0,0.0],"query(): unknown option name: <unknown>"]] +#|e| query(): unknown option name: <unknown> Added: test/command/suite/select/function/query/options/unknown_name.test (+17 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/function/query/options/unknown_name.test 2016-12-28 14:46:08 +0900 (5c3b2ba) @@ -0,0 +1,17 @@ +table_create Products TABLE_NO_KEY +column_create Products name COLUMN_SCALAR ShortText + +load --table Products +[ +["name"], +["Groonga"], +["Mroonga"], +["Rroonga"], +["PGroonga"], +["Ruby"], +["PostgreSQL"] +] + +select \ + --table Products \ + --filter 'query("name", "r", {"unknown": "^"})' -------------- next part -------------- HTML����������������������������... 下载