Kouhei Sutou
null+****@clear*****
Wed Apr 19 11:48:01 JST 2017
Kouhei Sutou 2017-04-19 11:48:01 +0900 (Wed, 19 Apr 2017) New Revision: 49fe82b6d9c122fdea2fb386c7db7532d1b05a70 https://github.com/groonga/groonga/commit/49fe82b6d9c122fdea2fb386c7db7532d1b05a70 Message: in_records: add Added files: lib/proc/proc_in_records.c test/command/suite/select/function/in_records/multiple.expected test/command/suite/select/function/in_records/multiple.test test/command/suite/select/function/in_records/one.expected test/command/suite/select/function/in_records/one.test Modified files: lib/grn_proc.h lib/proc.c lib/proc/sources.am Modified: lib/grn_proc.h (+2 -1) =================================================================== --- lib/grn_proc.h 2017-04-19 11:06:49 +0900 (302fea4) +++ lib/grn_proc.h 2017-04-19 11:48:01 +0900 (9792938) @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2009-2016 Brazil + Copyright(C) 2009-2017 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -52,6 +52,7 @@ void grn_proc_init_fuzzy_search(grn_ctx *ctx); void grn_proc_init_highlight(grn_ctx *ctx); void grn_proc_init_highlight_full(grn_ctx *ctx); void grn_proc_init_highlight_html(grn_ctx *ctx); +void grn_proc_init_in_records(grn_ctx *ctx); void grn_proc_init_lock_acquire(grn_ctx *ctx); void grn_proc_init_lock_clear(grn_ctx *ctx); void grn_proc_init_lock_release(grn_ctx *ctx); Modified: lib/proc.c (+2 -0) =================================================================== --- lib/proc.c 2017-04-19 11:06:49 +0900 (6cbdbb8) +++ lib/proc.c 2017-04-19 11:48:01 +0900 (f253c77) @@ -3972,4 +3972,6 @@ grn_db_init_builtin_commands(grn_ctx *ctx) grn_proc_init_object_list(ctx); grn_proc_init_table_copy(ctx); + + grn_proc_init_in_records(ctx); } Added: lib/proc/proc_in_records.c (+170 -0) 100644 =================================================================== --- /dev/null +++ lib/proc/proc_in_records.c 2017-04-19 11:48:01 +0900 (4ab3201) @@ -0,0 +1,170 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2017 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "../grn_proc.h" + +#include <groonga/plugin.h> + +static grn_obj * +func_in_records(grn_ctx *ctx, + int n_args, + grn_obj **args, + grn_user_data *user_data) +{ + grn_obj *found; + grn_obj *table; + grn_obj columns; + int i; + + found = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_BOOL, 0); + if (!found) { + return NULL; + } + GRN_BOOL_SET(ctx, found, GRN_FALSE); + + if (n_args < 3) { + GRN_PLUGIN_ERROR(ctx, + GRN_INVALID_ARGUMENT, + "in_records(): wrong number of arguments (%d for 3..)", + n_args); + return found; + } + + if ((n_args % 2) != 1) { + GRN_PLUGIN_ERROR(ctx, + GRN_INVALID_ARGUMENT, + "in_records(): the number of arguments must be odd (%d)", + n_args); + return found; + } + + table = args[0]; + if (!grn_obj_is_table(ctx, table)) { + grn_obj inspected; + GRN_TEXT_INIT(&inspected, 0); + grn_inspect(ctx, &inspected, table); + GRN_PLUGIN_ERROR(ctx, + GRN_INVALID_ARGUMENT, + "in_records(): the first argument must be a table: <%.*s>", + (int)GRN_TEXT_LEN(&inspected), + GRN_TEXT_VALUE(&inspected)); + GRN_OBJ_FIN(ctx, &inspected); + return found; + } + + GRN_PTR_INIT(&columns, GRN_OBJ_VECTOR, GRN_ID_NIL); + for (i = 1; i < n_args; i += 2) { + grn_obj *column_name = args[i + 1]; + grn_obj *column; + + if (!grn_obj_is_text_family_bulk(ctx, column_name)) { + grn_obj inspected; + GRN_TEXT_INIT(&inspected, 0); + grn_inspect(ctx, &inspected, table); + GRN_PLUGIN_ERROR(ctx, + GRN_INVALID_ARGUMENT, + "in_records(): " + "the %dth argument must be column name as string: " + "<%.*s>", + i + 1, + (int)GRN_TEXT_LEN(&inspected), + GRN_TEXT_VALUE(&inspected)); + GRN_OBJ_FIN(ctx, &inspected); + goto exit; + } + + column = grn_obj_column(ctx, table, + GRN_TEXT_VALUE(column_name), + GRN_TEXT_LEN(column_name)); + if (!column) { + grn_obj inspected; + GRN_TEXT_INIT(&inspected, 0); + grn_inspect(ctx, &inspected, table); + GRN_PLUGIN_ERROR(ctx, + GRN_INVALID_ARGUMENT, + "in_records(): " + "the %dth argument must be existing column name: " + "<%.*s>", + i + 1, + (int)GRN_TEXT_LEN(&inspected), + GRN_TEXT_VALUE(&inspected)); + GRN_OBJ_FIN(ctx, &inspected); + goto exit; + } + GRN_PTR_PUT(ctx, &columns, column); + } + + { + grn_obj column_value; + + GRN_VOID_INIT(&column_value); + GRN_TABLE_EACH_BEGIN(ctx, table, cursor, id) { + grn_bool found_record = GRN_TRUE; + + for (i = 1; i < n_args; i += 2) { + grn_obj *value = args[i]; + grn_obj *column = GRN_PTR_VALUE_AT(&columns, (i - 1) / 2); + + if (grn_obj_is_data_column(ctx, column)) { + grn_bool found_value = GRN_FALSE; + + GRN_BULK_REWIND(&column_value); + grn_obj_get_value(ctx, column, id, &column_value); + + found_value = grn_operator_exec_equal(ctx, value, &column_value); + if (ctx->rc != GRN_SUCCESS) { + found_record = GRN_FALSE; + break; + } + + if (!found_value) { + found_record = GRN_FALSE; + break; + } + } else { + found_record = GRN_FALSE; + break; + } + } + + if (found_record) { + GRN_BOOL_SET(ctx, found, GRN_TRUE); + break; + } + } GRN_TABLE_EACH_END(ctx, cursor); + GRN_OBJ_FIN(ctx, &column_value); + } + +exit : + for (i = 1; i < n_args; i += 2) { + grn_obj *column = GRN_PTR_VALUE_AT(&columns, (i - 1) / 2); + if (column->header.type == GRN_ACCESSOR) { + grn_obj_unlink(ctx, column); + } + } + GRN_OBJ_FIN(ctx, &columns); + + return found; +} + +void +grn_proc_init_in_records(grn_ctx *ctx) +{ + grn_proc_create(ctx, "in_records", -1, GRN_PROC_FUNCTION, + func_in_records, NULL, NULL, 0, NULL); +} Modified: lib/proc/sources.am (+2 -1) =================================================================== --- lib/proc/sources.am 2017-04-19 11:06:49 +0900 (e84cf7f) +++ lib/proc/sources.am 2017-04-19 11:48:01 +0900 (3113901) @@ -3,6 +3,8 @@ libgrnproc_la_SOURCES = \ proc_config.c \ proc_dump.c \ proc_fuzzy_search.c \ + proc_highlight.c \ + proc_in_records.c \ proc_lock.c \ proc_object.c \ proc_object_inspect.c \ @@ -11,6 +13,5 @@ libgrnproc_la_SOURCES = \ proc_schema.c \ proc_select.c \ proc_snippet.c \ - proc_highlight.c \ proc_table.c \ proc_tokenize.c Added: test/command/suite/select/function/in_records/multiple.expected (+84 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/function/in_records/multiple.expected 2017-04-19 11:48:01 +0900 (ea0c26e) @@ -0,0 +1,84 @@ +plugin_register functions/time +[[0,0.0,0.0],true] +table_create Users TABLE_HASH_KEY ShortText +[[0,0.0,0.0],true] +table_create Tags TABLE_HASH_KEY ShortText +[[0,0.0,0.0],true] +table_create Reports TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Reports user COLUMN_SCALAR Users +[[0,0.0,0.0],true] +column_create Reports tag COLUMN_SCALAR Tags +[[0,0.0,0.0],true] +column_create Reports day COLUMN_SCALAR Time +[[0,0.0,0.0],true] +table_create Logs TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Logs user COLUMN_SCALAR Users +[[0,0.0,0.0],true] +column_create Logs tag COLUMN_SCALAR Tags +[[0,0.0,0.0],true] +column_create Logs time COLUMN_SCALAR Time +[[0,0.0,0.0],true] +load --table Reports +[ +{"user": "alice", "tag": "tag1", "day": "2017-04-18 00:00:00"}, +{"user": "alice", "tag": "tag1", "day": "2017-04-19 00:00:00"}, +{"user": "david", "tag": "tag2", "day": "2017-04-20 00:00:00"}, +{"user": "david", "tag": "tag3", "day": "2017-04-21 00:00:00"} +] +[[0,0.0,0.0],4] +load --table Logs +[ +{"user": "alice", "tag": "tag1", "time": "2017-04-18 11:22:33"}, +{"user": "alice", "tag": "tag1", "time": "2017-04-20 11:22:33"}, +{"user": "bob", "tag": "tag1", "time": "2017-04-19 11:22:33"}, +{"user": "david", "tag": "tag1", "time": "2017-04-19 11:22:33"}, +{"user": "david", "tag": "tag2", "time": "2017-04-20 11:22:33"} +] +[[0,0.0,0.0],5] +select Logs --filter 'in_records(Reports, user, "user", tag, "tag", time_classify_day(time), "day")' +[ + [ + 0, + 0.0, + 0.0 + ], + [ + [ + [ + 2 + ], + [ + [ + "_id", + "UInt32" + ], + [ + "tag", + "Tags" + ], + [ + "time", + "Time" + ], + [ + "user", + "Users" + ] + ], + [ + 1, + "tag1", + 1492482153.0, + "alice" + ], + [ + 5, + "tag2", + 1492654953.0, + "david" + ] + ] + ] +] Added: test/command/suite/select/function/in_records/multiple.test (+37 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/function/in_records/multiple.test 2017-04-19 11:48:01 +0900 (6c04630) @@ -0,0 +1,37 @@ +plugin_register functions/time + +table_create Users TABLE_HASH_KEY ShortText +table_create Tags TABLE_HASH_KEY ShortText + +table_create Reports TABLE_NO_KEY +column_create Reports user COLUMN_SCALAR Users +column_create Reports tag COLUMN_SCALAR Tags +column_create Reports day COLUMN_SCALAR Time + +table_create Logs TABLE_NO_KEY +column_create Logs user COLUMN_SCALAR Users +column_create Logs tag COLUMN_SCALAR Tags +column_create Logs time COLUMN_SCALAR Time + +load --table Reports +[ +{"user": "alice", "tag": "tag1", "day": "2017-04-18 00:00:00"}, +{"user": "alice", "tag": "tag1", "day": "2017-04-19 00:00:00"}, +{"user": "david", "tag": "tag2", "day": "2017-04-20 00:00:00"}, +{"user": "david", "tag": "tag3", "day": "2017-04-21 00:00:00"} +] + +load --table Logs +[ +{"user": "alice", "tag": "tag1", "time": "2017-04-18 11:22:33"}, +{"user": "alice", "tag": "tag1", "time": "2017-04-20 11:22:33"}, +{"user": "bob", "tag": "tag1", "time": "2017-04-19 11:22:33"}, +{"user": "david", "tag": "tag1", "time": "2017-04-19 11:22:33"}, +{"user": "david", "tag": "tag2", "time": "2017-04-20 11:22:33"} +] + +select Logs \ + --filter 'in_records(Reports, \ + user, "user", \ + tag, "tag", \ + time_classify_day(time), "day")' Added: test/command/suite/select/function/in_records/one.expected (+57 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/function/in_records/one.expected 2017-04-19 11:48:01 +0900 (22ac7e1) @@ -0,0 +1,57 @@ +table_create Users TABLE_HASH_KEY ShortText +[[0,0.0,0.0],true] +table_create Reports TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Reports user COLUMN_SCALAR Users +[[0,0.0,0.0],true] +table_create Logs TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Logs user COLUMN_SCALAR Users +[[0,0.0,0.0],true] +load --table Reports +[ +{"user": "alice"}, +{"user": "david"} +] +[[0,0.0,0.0],2] +load --table Logs +[ +{"user": "alice"}, +{"user": "bob"}, +{"user": "chris"}, +{"user": "david"} +] +[[0,0.0,0.0],4] +select Logs --filter 'in_records(Reports, user, "user")' +[ + [ + 0, + 0.0, + 0.0 + ], + [ + [ + [ + 2 + ], + [ + [ + "_id", + "UInt32" + ], + [ + "user", + "Users" + ] + ], + [ + 1, + "alice" + ], + [ + 4, + "david" + ] + ] + ] +] Added: test/command/suite/select/function/in_records/one.test (+24 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/function/in_records/one.test 2017-04-19 11:48:01 +0900 (9e7163c) @@ -0,0 +1,24 @@ +table_create Users TABLE_HASH_KEY ShortText + +table_create Reports TABLE_NO_KEY +column_create Reports user COLUMN_SCALAR Users + +table_create Logs TABLE_NO_KEY +column_create Logs user COLUMN_SCALAR Users + +load --table Reports +[ +{"user": "alice"}, +{"user": "david"} +] + +load --table Logs +[ +{"user": "alice"}, +{"user": "bob"}, +{"user": "chris"}, +{"user": "david"} +] + +select Logs \ + --filter 'in_records(Reports, user, "user")' -------------- next part -------------- HTML����������������������������...下載