void test_accessor(void) { int i; grn_obj *t1, *t2, *c1, *c2, r1, r2; t1 = grn_table_create(context, "t1", 2, NULL, GRN_OBJ_TABLE_NO_KEY|GRN_OBJ_PERSISTENT, NULL, NULL); cut_assert_not_null(t1); t2 = grn_table_create(context, "t2", 2, NULL, GRN_OBJ_TABLE_NO_KEY|GRN_OBJ_PERSISTENT, NULL, NULL); cut_assert_not_null(t2); c1 = grn_column_create(context, t1, "c1", 2, NULL, GRN_OBJ_PERSISTENT, t2); cut_assert_not_null(c1); c2 = grn_column_create(context, t2, "c2", 2, NULL, GRN_OBJ_PERSISTENT, t1); cut_assert_not_null(c2); GRN_RECORD_INIT(&r1, 0, grn_obj_id(context, t1)); GRN_RECORD_INIT(&r2, 0, grn_obj_id(context, t2)); for (i = 0; i < NRECORDS; i++) { grn_id i1, i2; i1 = grn_table_add(context, t1, NULL, 0, NULL); i2 = grn_table_add(context, t2, NULL, 0, NULL); GRN_RECORD_SET(context, &r1, i1); GRN_RECORD_SET(context, &r2, i2); grn_obj_set_value(context, c1, i1, &r2, GRN_OBJ_SET); grn_obj_set_value(context, c2, i2, &r1, GRN_OBJ_SET); } { grn_id id; uint64_t et; int nerr = 0; struct timeval tvb, tve; grn_obj *a = grn_obj_column(context, t1, "c1.c2.c1", 8); grn_table_cursor *tc = grn_table_cursor_open(context, t1, NULL, 0, NULL, 0, 0, -1, 0); cut_assert_not_null(a); cut_assert_not_null(tc); gettimeofday(&tvb, NULL); while ((id = grn_table_cursor_next(context, tc))) { GRN_BULK_REWIND(&r2); grn_obj_get_value(context, a, id, &r2); if (GRN_RECORD_VALUE(&r2) != id) { nerr++; } } gettimeofday(&tve, NULL); et = (tve.tv_sec - tvb.tv_sec) * 1000000 + (tve.tv_usec - tvb.tv_usec); // printf("et=%zu\n", et); cut_assert_equal_uint(0, nerr); grn_test_assert(grn_table_cursor_close(context, tc)); grn_test_assert(grn_obj_close(context, a)); } grn_test_assert(grn_obj_close(context, &r1)); grn_test_assert(grn_obj_close(context, &r2)); }
void test_table_scan(void) { grn_obj *cond, *v, *res, textbuf, intbuf; GRN_TEXT_INIT(&textbuf, 0); GRN_UINT32_INIT(&intbuf, 0); prepare_data(&textbuf, &intbuf); cut_assert_not_null((cond = grn_expr_create(&context, NULL, 0))); v = grn_expr_add_var(&context, cond, NULL, 0); GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs)); grn_expr_append_obj(&context, cond, v); GRN_TEXT_SETS(&context, &textbuf, "size"); grn_expr_append_const(&context, cond, &textbuf); grn_expr_append_op(&context, cond, GRN_OP_OBJ_GET_VALUE, 2); GRN_UINT32_SET(&context, &intbuf, 14); grn_expr_append_const(&context, cond, &intbuf); grn_expr_append_op(&context, cond, GRN_OP_EQUAL, 2); grn_expr_compile(&context, cond); res = grn_table_create(&context, NULL, 0, NULL, GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, docs, 0); cut_assert_not_null(res); grn_test_assert(grn_table_scan(&context, docs, cond, res, GRN_SEL_OR)); cut_assert_equal_uint(3, grn_table_size(&context, res)); grn_test_assert(grn_obj_close(&context, res)); grn_test_assert(grn_obj_close(&context, cond)); grn_test_assert(grn_obj_close(&context, &textbuf)); grn_test_assert(grn_obj_close(&context, &intbuf)); }
void test_equal_indexed(void) { grn_obj *v; prepare_data(); cut_assert_not_null((cond = grn_expr_create(&context, NULL, 0))); v = grn_expr_add_var(&context, cond, NULL, 0); GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs)); grn_expr_append_obj(&context, cond, v, GRN_OP_PUSH, 1); GRN_TEXT_SETS(&context, &text_buf, "body"); grn_expr_append_const(&context, cond, &text_buf, GRN_OP_GET_VALUE, 1); GRN_TEXT_SETS(&context, &text_buf, "hoge"); grn_expr_append_const(&context, cond, &text_buf, GRN_OP_PUSH, 1); grn_expr_append_op(&context, cond, GRN_OP_EQUAL, 2); grn_expr_compile(&context, cond); res = grn_table_create(&context, NULL, 0, NULL, GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, docs, NULL); cut_assert_not_null(res); cut_assert_not_null(grn_table_select(&context, docs, cond, res, GRN_OP_OR)); grn_test_assert_select(&context, gcut_take_new_list_string("hoge", NULL), res, "body"); }
static void command_schema_column_output_sources(grn_ctx *ctx, grn_obj *column) { grn_obj *source_table; grn_obj source_ids; unsigned int i, n_ids; source_table = grn_ctx_at(ctx, grn_obj_get_range(ctx, column)); GRN_RECORD_INIT(&source_ids, GRN_OBJ_VECTOR, GRN_ID_NIL); if (column->header.type == GRN_COLUMN_INDEX) { grn_obj_get_info(ctx, column, GRN_INFO_SOURCE, &source_ids); } n_ids = GRN_BULK_VSIZE(&source_ids) / sizeof(grn_id); grn_ctx_output_array_open(ctx, "sources", n_ids); for (i = 0; i < n_ids; i++) { grn_id source_id; grn_obj *source; source_id = GRN_RECORD_VALUE_AT(&source_ids, i); source = grn_ctx_at(ctx, source_id); grn_ctx_output_map_open(ctx, "source", 3); grn_ctx_output_cstr(ctx, "name"); if (grn_obj_is_table(ctx, source)) { grn_ctx_output_cstr(ctx, "_key"); } else { command_schema_output_column_name(ctx, source); } grn_ctx_output_cstr(ctx, "table"); command_schema_output_name(ctx, source_table); grn_ctx_output_cstr(ctx, "full_name"); if (grn_obj_is_table(ctx, source)) { char name[GRN_TABLE_MAX_KEY_SIZE]; unsigned int name_size; name_size = grn_obj_name(ctx, source, name, GRN_TABLE_MAX_KEY_SIZE); name[name_size] = '\0'; grn_strcat(name, GRN_TABLE_MAX_KEY_SIZE, "._key"); grn_ctx_output_cstr(ctx, name); } else { command_schema_output_name(ctx, source); } grn_ctx_output_map_close(ctx); } grn_ctx_output_array_close(ctx); GRN_OBJ_FIN(ctx, &source_ids); }
/* * Tokenize a string using the table as lexicon. * * @overload tokenize(string, options={}) * @param [String] string The string to be tokenized. * @param [::Hash] options * @option options [Bool] :add (true) Adds a new token to the table if true. * Returned tokens include the new token. Otherwise, a new token is * just ignored. * @return [::Array<Groonga::Record>] Tokenized tokens. */ static VALUE rb_grn_table_key_support_tokenize (int argc, VALUE *argv, VALUE self) { VALUE rb_string, rb_add_p; VALUE rb_options; VALUE rb_tokens = Qnil; grn_ctx *context; grn_obj *table; char *string; int string_size; grn_bool add_p; grn_obj tokens; rb_scan_args(argc, argv, "11", &rb_string, &rb_options); rb_grn_scan_options(rb_options, "add", &rb_add_p, NULL); if (NIL_P(rb_add_p)) { rb_add_p = Qtrue; } rb_grn_table_key_support_deconstruct(SELF(self), &table, &context, NULL, NULL, NULL, NULL, NULL, NULL, NULL); string = StringValueCStr(rb_string); string_size = RSTRING_LEN(rb_string); add_p = RVAL2CBOOL(rb_add_p); GRN_RECORD_INIT(&tokens, GRN_OBJ_VECTOR, grn_obj_id(context, table)); grn_table_tokenize(context, table, string, string_size, &tokens, add_p); if (context->rc == GRN_SUCCESS) { rb_tokens = GRNUVECTOR2RVAL(context, &tokens, table, self); } grn_obj_unlink(context, &tokens); rb_grn_context_check(context, self); return rb_tokens; }
void test_select(void) { grn_obj *v; prepare_data(); cut_assert_not_null((cond = grn_expr_create(&context, NULL, 0))); v = grn_expr_add_var(&context, cond, NULL, 0); GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs)); grn_expr_append_obj(&context, cond, v, GRN_OP_PUSH, 1); GRN_TEXT_SETS(&context, &text_buf, "size"); grn_expr_append_const(&context, cond, &text_buf, GRN_OP_PUSH, 1); grn_expr_append_op(&context, cond, GRN_OP_GET_VALUE, 2); GRN_UINT32_SET(&context, &int_buf, 14); grn_expr_append_const(&context, cond, &int_buf, GRN_OP_PUSH, 1); grn_expr_append_op(&context, cond, GRN_OP_EQUAL, 2); grn_expr_compile(&context, cond); res = grn_table_create(&context, NULL, 0, NULL, GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, docs, NULL); cut_assert_not_null(res); cut_assert_not_null((expr = grn_expr_create(&context, NULL, 0))); grn_expr_append_obj(&context, expr, docs, GRN_OP_PUSH, 1); grn_expr_append_obj(&context, expr, cond, GRN_OP_PUSH, 1); grn_expr_append_obj(&context, expr, res, GRN_OP_PUSH, 1); GRN_UINT32_SET(&context, &int_buf, GRN_OP_OR); grn_expr_append_const(&context, expr, &int_buf, GRN_OP_PUSH, 1); grn_expr_append_op(&context, expr, GRN_OP_TABLE_SELECT, 4); grn_expr_exec(&context, expr, 0); grn_test_assert_select(&context, gcut_take_new_list_string("moge moge moge", "hoge fuga fuga", "moge hoge hoge", NULL), res, "body"); }
void test_match_without_index(void) { grn_obj *v; create_properties_table(); create_documents_table(); insert_data(); cut_assert_not_null((cond = grn_expr_create(&context, NULL, 0))); v = grn_expr_add_var(&context, cond, NULL, 0); GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs)); grn_expr_append_obj(&context, cond, v, GRN_OP_PUSH, 1); GRN_TEXT_SETS(&context, &text_buf, "body"); grn_expr_append_const(&context, cond, &text_buf, GRN_OP_PUSH, 1); grn_expr_append_op(&context, cond, GRN_OP_GET_VALUE, 1); GRN_TEXT_SETS(&context, &text_buf, "moge"); grn_expr_append_const(&context, cond, &text_buf, GRN_OP_PUSH, 1); grn_expr_append_op(&context, cond, GRN_OP_MATCH, 2); grn_expr_compile(&context, cond); res = grn_table_create(&context, NULL, 0, NULL, GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, docs, NULL); cut_assert_not_null(res); cut_assert_not_null(grn_table_select(&context, docs, cond, res, GRN_OP_OR)); grn_test_assert_select( &context, gcut_take_new_list_string("moge moge moge", "hoge moge moge moge", "moge hoge hoge", "moge hoge fuga fuga", "moge hoge moge moge moge", "poyo moge hoge moge moge moge", NULL), res, "body"); }
/* * _expression_ で使用可能な変数を作成する。 * * @overload define_variable(options={}) * @param [::Hash] options The name and value * pairs. Omitted names are initialized as the default value. * @option options :name [String] (nil) * 変数の名前。省略した場合は名前を付けない。 * @option options :domain [Groonga::Table] (nil) * テーブルを指定すると、そのテーブル用のレコードとして初期化する。 * @option options :reference [Bool] (nil) * Initializes this variable as reference hold variable if * @:reference@ is true. Reference hold variable is GRN_PTR type * in groonga. You can't use @:reference@ with @:domain@. * @return [Groonga::Variable] * */ static VALUE rb_grn_expression_define_variable (int argc, VALUE *argv, VALUE self) { grn_ctx *context = NULL; grn_obj *expression, *variable; char *name = NULL; unsigned name_size = 0; VALUE options, rb_name, rb_domain, rb_variable, rb_reference; rb_scan_args(argc, argv, "01", &options); rb_grn_expression_deconstruct(SELF(self), &expression, &context, NULL, NULL, NULL, NULL, NULL); rb_grn_scan_options(options, "name", &rb_name, "domain", &rb_domain, "reference", &rb_reference, NULL); if (!NIL_P(rb_name)) { name = StringValuePtr(rb_name); name_size = RSTRING_LEN(rb_name); } variable = grn_expr_add_var(context, expression, name, name_size); rb_variable = GRNVARIABLE2RVAL(context, variable); if (RVAL2CBOOL(rb_obj_is_kind_of(rb_domain, rb_cGrnTable))) { grn_id domain_id; domain_id = NUM2UINT(rb_funcall(rb_domain, rb_intern("id"), 0)); GRN_RECORD_INIT(variable, 0, domain_id); } else if (!NIL_P(rb_reference) && RVAL2CBOOL(rb_reference)) { GRN_PTR_INIT(variable, 0, GRN_DB_OBJECT); } return rb_variable; }
void test_allow_update(gconstpointer data) { grn_obj *v; prepare_data(); expr = grn_expr_create(&context, NULL, 0); cut_assert_not_null(expr); v = grn_expr_add_var(&context, expr, NULL, 0); cut_assert_not_null(v); GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs)); PARSE(expr, gcut_data_get_string(data, "query"), GRN_EXPR_SYNTAX_QUERY | GRN_EXPR_ALLOW_COLUMN | GRN_EXPR_ALLOW_UPDATE); res = grn_table_select(&context, docs, expr, NULL, GRN_OP_OR); cut_assert_not_null(res); grn_test_assert_select(&context, gcut_data_get_pointer(data, "expected_keys"), res, "body"); }
void test_persistent_expr(void) { int i; grn_obj *t1, *t2, *c1, *c2, buf; t1 = grn_table_create(&context, "t1", 2, NULL, GRN_OBJ_TABLE_NO_KEY|GRN_OBJ_PERSISTENT, NULL, 0); cut_assert_not_null(t1); t2 = grn_table_create(&context, "t2", 2, NULL, GRN_OBJ_TABLE_NO_KEY|GRN_OBJ_PERSISTENT, NULL, 0); cut_assert_not_null(t2); c1 = grn_column_create(&context, t1, "c1", 2, NULL, GRN_OBJ_PERSISTENT, t2); cut_assert_not_null(c1); c2 = grn_column_create(&context, t2, "c2", 2, NULL, GRN_OBJ_PERSISTENT, t1); cut_assert_not_null(c2); GRN_TEXT_INIT(&buf, 0); for (i = 0; i < NRECORDS; i++) { grn_id i1, i2; i1 = grn_table_add(&context, t1, NULL, 0, NULL); i2 = grn_table_add(&context, t2, NULL, 0, NULL); GRN_BULK_REWIND(&buf); grn_bulk_write(&context, &buf, (char *)&i2, sizeof(grn_id)); grn_obj_set_value(&context, c1, i1, &buf, GRN_OBJ_SET); grn_obj_set_value(&context, c2, i2, &buf, GRN_OBJ_SET); } { grn_obj *expr = grn_expr_create(&context, "test", 4); grn_obj *v; cut_assert_not_null(expr); v = grn_expr_add_var(&context, expr, "foo", 3); GRN_RECORD_INIT(v, 0, grn_obj_id(&context, t1)); grn_expr_append_obj(&context, expr, v); GRN_TEXT_SETS(&context, &buf, "c1"); grn_expr_append_const(&context, expr, &buf); grn_expr_append_op(&context, expr, GRN_OP_OBJ_GET_VALUE, 2); GRN_TEXT_SETS(&context, &buf, "c2"); grn_expr_append_const(&context, expr, &buf); grn_expr_append_op(&context, expr, GRN_OP_OBJ_GET_VALUE, 2); GRN_TEXT_SETS(&context, &buf, "c1"); grn_expr_append_const(&context, expr, &buf); /* GRN_TEXT_SETS(&context, &buf, "c1.c2.c1"); grn_expr_append_const(&context, expr, &buf); */ grn_expr_append_op(&context, expr, GRN_OP_OBJ_GET_VALUE, 2); grn_expr_compile(&context, expr); } cut_assert_equal_uint(0, grn_obj_close(&context, &buf)); grn_db_close(&context, database); database = grn_db_open(&context, path); GRN_TEXT_INIT(&buf, 0); { grn_id id; uint64_t et; int nerr = 0; grn_obj *r, *v; grn_table_cursor *tc; struct timeval tvb, tve; grn_obj *expr = grn_ctx_get(&context, "test", 4); v = grn_expr_get_var(&context, expr, "foo", 3); t1 = grn_ctx_get(&context, "t1", 2); tc = grn_table_cursor_open(&context, t1, NULL, 0, NULL, 0, 0); cut_assert_not_null(tc); gettimeofday(&tvb, NULL); while ((id = grn_table_cursor_next(&context, tc))) { GRN_RECORD_SET(&context, v, id); r = grn_expr_exec(&context, expr); if (GRN_RECORD_VALUE(r) != id) { nerr++; } } gettimeofday(&tve, NULL); et = (tve.tv_sec - tvb.tv_sec) * 1000000 + (tve.tv_usec - tvb.tv_usec); // printf("et=%zu\n", et); cut_assert_equal_uint(0, nerr); cut_assert_equal_uint(0, grn_table_cursor_close(&context, tc)); } cut_assert_equal_uint(0, grn_obj_close(&context, &buf)); }
void test_select_search(void) { grn_obj *v; prepare_data(); cut_assert_not_null((cond = grn_expr_create(&context, NULL, 0))); v = grn_expr_add_var(&context, cond, NULL, 0); GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs)); grn_expr_append_obj(&context, cond, v, GRN_OP_PUSH, 1); GRN_TEXT_SETS(&context, &text_buf, "size"); grn_expr_append_const(&context, cond, &text_buf, GRN_OP_PUSH, 1); grn_expr_append_op(&context, cond, GRN_OP_GET_VALUE, 2); GRN_UINT32_SET(&context, &int_buf, 14); grn_expr_append_const(&context, cond, &int_buf, GRN_OP_PUSH, 1); grn_expr_append_op(&context, cond, GRN_OP_EQUAL, 2); grn_expr_compile(&context, cond); cut_assert_not_null((expr = grn_expr_create(&context, NULL, 0))); v = grn_expr_add_var(&context, expr, NULL, 0); grn_expr_append_obj(&context, expr, v, GRN_OP_PUSH, 1); GRN_BULK_REWIND(&text_buf); grn_expr_append_const(&context, expr, &text_buf, GRN_OP_PUSH, 1); GRN_UINT32_SET(&context, &int_buf, GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC); grn_expr_append_const(&context, expr, &int_buf, GRN_OP_PUSH, 1); grn_expr_append_obj(&context, expr, docs, GRN_OP_PUSH, 1); GRN_PTR_SET(&context, &ptr_buf, NULL); grn_expr_append_obj(&context, expr, &ptr_buf, GRN_OP_PUSH, 1); grn_expr_append_op(&context, expr, GRN_OP_TABLE_CREATE, 4); grn_expr_append_op(&context, expr, GRN_OP_ASSIGN, 2); grn_expr_append_obj(&context, expr, docs, GRN_OP_PUSH, 1); grn_expr_append_obj(&context, expr, cond, GRN_OP_PUSH, 1); grn_expr_append_obj(&context, expr, v, GRN_OP_PUSH, 1); GRN_UINT32_SET(&context, &int_buf, GRN_OP_OR); grn_expr_append_const(&context, expr, &int_buf, GRN_OP_PUSH, 1); grn_expr_append_op(&context, expr, GRN_OP_TABLE_SELECT, 4); grn_expr_append_obj(&context, expr, index_body, GRN_OP_PUSH, 1); GRN_TEXT_SETS(&context, &text_buf, "moge"); grn_expr_append_const(&context, expr, &text_buf, GRN_OP_PUSH, 1); grn_expr_append_obj(&context, expr, v, GRN_OP_PUSH, 1); GRN_UINT32_SET(&context, &int_buf, GRN_OP_AND); grn_expr_append_const(&context, expr, &int_buf, GRN_OP_PUSH, 1); grn_expr_append_op(&context, expr, GRN_OP_OBJ_SEARCH, 4); grn_expr_append_obj(&context, expr, v, GRN_OP_PUSH, 1); GRN_TEXT_SETS(&context, &text_buf, ".size ._score .body"); grn_expr_append_const(&context, expr, &text_buf, GRN_OP_PUSH, 1); GRN_BULK_REWIND(&text_buf); grn_expr_append_obj(&context, expr, &text_buf, GRN_OP_PUSH, 1); grn_expr_append_op(&context, expr, GRN_OP_JSON_PUT, 3); grn_expr_exec(&context, expr, 0); cut_assert_equal_substring("[[2],[14,4,\"moge moge moge\"],[14,2,\"moge hoge hoge\"]]", GRN_TEXT_VALUE(&text_buf), GRN_TEXT_LEN(&text_buf)); }
void test_parse(gconstpointer data) { grn_obj *v; prepare_data(); cond = grn_expr_create(&context, NULL, 0); cut_assert_not_null(cond); v = grn_expr_add_var(&context, cond, NULL, 0); cut_assert_not_null(v); GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs)); PARSE(cond, gcut_data_get_string(data, "query_hoge_moge"), gcut_data_get_int(data, "query_hoge_moge_parse_level")); PARSE(cond, gcut_data_get_string(data, "query_poyo"), gcut_data_get_int(data, "query_poyo_parse_level")); grn_expr_append_op(&context, cond, GRN_OP_AND, 2); grn_test_assert_expr( &context, "#<expr\n" " vars:{\n" " $1:#<record:no_key:docs id:0(nonexistent)>\n" " },\n" " codes:{\n" " 0:<get_value(), modify:2, " "value:#<column:var_size docs.body range:Text type:scalar compress:none>>,\n" " 1:<push(), modify:0, value:\"hoge\">,\n" " 2:<match(), modify:4, value:(NULL)>,\n" " 3:<get_value(), modify:2, " "value:#<column:var_size docs.body range:Text type:scalar compress:none>>,\n" " 4:<push(), modify:0, value:\"moge\">,\n" " 5:<match(), modify:0, value:(NULL)>,\n" " 6:<and(), modify:4, value:(NULL)>,\n" " 7:<get_value(), modify:2, " "value:#<column:var_size docs.body range:Text type:scalar compress:none>>,\n" " 8:<push(), modify:0, value:\"poyo\">,\n" " 9:<match(), modify:0, value:(NULL)>,\n" " 10:<and(), modify:0, value:(NULL)>\n" " }\n" ">", cond); res = grn_table_create(&context, NULL, 0, NULL, GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, docs, NULL); cut_assert_not_null(res); cut_assert_not_null(grn_table_select(&context, docs, cond, res, GRN_OP_OR)); grn_test_assert_select(&context, gcut_take_new_list_string("poyo moge hoge " "moge moge moge", NULL), res, "body"); grn_test_assert(grn_obj_close(&context, res)); res = NULL; grn_test_assert(grn_obj_close(&context, cond)); cond = NULL; cond = grn_expr_create(&context, NULL, 0); cut_assert_not_null(cond); v = grn_expr_add_var(&context, cond, NULL, 0); cut_assert_not_null(v); GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs)); PARSE(cond, gcut_data_get_string(data, "query_size"), gcut_data_get_int(data, "query_size_parse_level")); grn_test_assert_expr( &context, "#<expr\n" " vars:{\n" " $1:#<record:no_key:docs id:0(nonexistent)>\n" " },\n" " codes:{\n" " 0:<get_value(), modify:2, " "value:#<column:fix_size docs.size range:UInt32 type:scalar compress:none>>,\n" " 1:<push(), modify:0, value:14>,\n" " 2:<equal(), modify:0, value:(NULL)>\n" " }\n" ">", cond); res = grn_table_create(&context, NULL, 0, NULL, GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, docs, NULL); cut_assert_not_null(res); cut_assert_not_null(grn_table_select(&context, docs, cond, res, GRN_OP_OR)); grn_test_assert_select(&context, gcut_take_new_list_string("moge moge moge", "hoge fuga fuga", "moge hoge hoge", NULL), res, "body"); }
void test_scan_search(void) { grn_obj *cond, *expr, *v, textbuf, intbuf; GRN_TEXT_INIT(&textbuf, 0); GRN_UINT32_INIT(&intbuf, 0); prepare_data(&textbuf, &intbuf); cut_assert_not_null((cond = grn_expr_create(&context, NULL, 0))); v = grn_expr_add_var(&context, cond, NULL, 0); GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs)); grn_expr_append_obj(&context, cond, v); GRN_TEXT_SETS(&context, &textbuf, "size"); grn_expr_append_const(&context, cond, &textbuf); grn_expr_append_op(&context, cond, GRN_OP_OBJ_GET_VALUE, 2); GRN_UINT32_SET(&context, &intbuf, 14); grn_expr_append_const(&context, cond, &intbuf); grn_expr_append_op(&context, cond, GRN_OP_EQUAL, 2); grn_expr_compile(&context, cond); cut_assert_not_null((expr = grn_expr_create(&context, NULL, 0))); v = grn_expr_add_var(&context, expr, NULL, 0); GRN_BULK_REWIND(&textbuf); grn_expr_append_const(&context, expr, &textbuf); GRN_UINT32_SET(&context, &intbuf, GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC); grn_expr_append_const(&context, expr, &intbuf); grn_expr_append_obj(&context, expr, docs); GRN_UINT32_SET(&context, &intbuf, 0); grn_expr_append_const(&context, expr, &intbuf); grn_expr_append_op(&context, expr, GRN_OP_TABLE_CREATE, 4); grn_expr_append_obj(&context, expr, v); grn_expr_append_op(&context, expr, GRN_OP_VAR_SET_VALUE, 2); grn_expr_append_obj(&context, expr, docs); grn_expr_append_obj(&context, expr, cond); grn_expr_append_obj(&context, expr, v); GRN_UINT32_SET(&context, &intbuf, GRN_SEL_OR); grn_expr_append_const(&context, expr, &intbuf); grn_expr_append_op(&context, expr, GRN_OP_TABLE_SCAN, 4); grn_expr_append_obj(&context, expr, index_body); GRN_TEXT_SETS(&context, &textbuf, "moge"); grn_expr_append_const(&context, expr, &textbuf); grn_expr_append_obj(&context, expr, v); GRN_UINT32_SET(&context, &intbuf, GRN_SEL_AND); grn_expr_append_const(&context, expr, &intbuf); grn_expr_append_op(&context, expr, GRN_OP_OBJ_SEARCH, 4); grn_expr_append_obj(&context, expr, v); GRN_TEXT_SETS(&context, &textbuf, ".size .:score .body"); grn_expr_append_const(&context, expr, &textbuf); GRN_BULK_REWIND(&textbuf); grn_expr_append_obj(&context, expr, &textbuf); grn_expr_append_op(&context, expr, GRN_OP_JSON_PUT, 3); grn_expr_exec(&context, expr); cut_assert_equal_substring("[[14, 4, \"moge moge moge\"], [14, 2, \"moge hoge hoge\"]]", GRN_TEXT_VALUE(&textbuf), GRN_TEXT_LEN(&textbuf)); grn_test_assert(grn_obj_close(&context, expr)); grn_test_assert(grn_obj_close(&context, cond)); grn_test_assert(grn_obj_close(&context, &textbuf)); grn_test_assert(grn_obj_close(&context, &intbuf)); }
static grn_obj * command_tag_synonym(grn_ctx *ctx, GNUC_UNUSED int nargs, GNUC_UNUSED grn_obj **args, GNUC_UNUSED grn_user_data *user_data) { GNUC_UNUSED grn_obj *flags = grn_ctx_pop(ctx); grn_obj *newvalue = grn_ctx_pop(ctx); grn_obj *oldvalue = grn_ctx_pop(ctx); GNUC_UNUSED grn_obj *id = grn_ctx_pop(ctx); grn_obj buf; grn_obj record; grn_obj *domain; grn_obj *table; grn_obj *column; int i,n; if (GRN_BULK_VSIZE(newvalue) == 0 || GRN_INT32_VALUE(flags) == 0) { return NULL; } table = grn_ctx_at(ctx, oldvalue->header.domain); if (table && !is_table(table)) { GRN_PLUGIN_LOG(ctx, GRN_LOG_WARNING, "[tag-synonym] " "hooked column must be reference type"); return NULL; } column = grn_obj_column(ctx, table, SYNONYM_COLUMN_NAME, SYNONYM_COLUMN_NAME_LEN); if (!column) { GRN_PLUGIN_LOG(ctx, GRN_LOG_WARNING, "[tag-synonym] " "couldn't open synonym column"); return NULL; } GRN_TEXT_INIT(&buf, 0); domain = grn_ctx_at(ctx, newvalue->header.domain); if (domain && is_string(domain)) { GRN_RECORD_INIT(&record, GRN_OBJ_VECTOR, oldvalue->header.domain); grn_table_tokenize(ctx, table, GRN_TEXT_VALUE(newvalue), GRN_TEXT_LEN(newvalue), &record, GRN_TRUE); } else if (newvalue->header.type == GRN_UVECTOR) { record = *newvalue; } if (is_string(domain) || newvalue->header.type == GRN_UVECTOR) { grn_obj value; GRN_RECORD_INIT(newvalue, GRN_OBJ_VECTOR, oldvalue->header.domain); GRN_UINT32_INIT(&value, 0); n = grn_vector_size(ctx, &record); for (i = 0; i < n; i++) { grn_id tid; tid = grn_uvector_get_element(ctx, &record, i, NULL); GRN_BULK_REWIND(&value); grn_obj_get_value(ctx, column, tid, &value); if (GRN_UINT32_VALUE(&value)) { GRN_PLUGIN_LOG(ctx, GRN_LOG_INFO, "[tag-synonym] " "changed: tid %d -> %d", tid, GRN_UINT32_VALUE(&value)); tid = GRN_UINT32_VALUE(&value); } grn_uvector_add_element(ctx, newvalue, tid, 0); } grn_obj_unlink(ctx, &value); } else { grn_id tid; grn_obj value; tid = GRN_RECORD_VALUE(newvalue); GRN_UINT32_INIT(&value, 0); grn_obj_get_value(ctx, column, tid, &value); if (GRN_UINT32_VALUE(&value)) { GRN_PLUGIN_LOG(ctx, GRN_LOG_INFO, "[tag-synonym] " "changed: tid %d -> %d", tid, GRN_UINT32_VALUE(&value)); tid = GRN_UINT32_VALUE(&value); GRN_BULK_REWIND(newvalue); GRN_RECORD_SET(ctx, newvalue, tid); } grn_obj_unlink(ctx, &value); } grn_obj_unlink(ctx, &buf); return NULL; }
static void command_schema_column_command_collect_arguments(grn_ctx *ctx, grn_obj *table, grn_obj *column, grn_obj *arguments) { #define ADD(name_, value_) \ grn_vector_add_element(ctx, arguments, \ name_, strlen(name_), \ 0, GRN_DB_TEXT); \ grn_vector_add_element(ctx, arguments, \ value_, strlen(value_), \ 0, GRN_DB_TEXT) #define ADD_OBJECT_NAME(name_, object_) do { \ char object_name[GRN_TABLE_MAX_KEY_SIZE]; \ unsigned int object_name_size; \ object_name_size = grn_obj_name(ctx, object_, \ object_name, \ GRN_TABLE_MAX_KEY_SIZE); \ object_name[object_name_size] = '\0'; \ ADD(name_, object_name); \ } while (GRN_FALSE) ADD_OBJECT_NAME("table", table); { char column_name[GRN_TABLE_MAX_KEY_SIZE]; unsigned int column_name_size; column_name_size = grn_column_name(ctx, column, column_name, GRN_TABLE_MAX_KEY_SIZE); column_name[column_name_size] = '\0'; ADD("name", column_name); } { grn_obj flags; GRN_TEXT_INIT(&flags, 0); grn_dump_column_create_flags(ctx, column->header.flags & ~GRN_OBJ_PERSISTENT, &flags); GRN_TEXT_PUTC(ctx, &flags, '\0'); ADD("flags", GRN_TEXT_VALUE(&flags)); GRN_OBJ_FIN(ctx, &flags); } { grn_obj *value_type; value_type = grn_ctx_at(ctx, grn_obj_get_range(ctx, column)); ADD_OBJECT_NAME("type", value_type); } if (column->header.type == GRN_COLUMN_INDEX) { grn_obj source_ids; unsigned int n_ids; GRN_RECORD_INIT(&source_ids, GRN_OBJ_VECTOR, GRN_ID_NIL); grn_obj_get_info(ctx, column, GRN_INFO_SOURCE, &source_ids); n_ids = GRN_BULK_VSIZE(&source_ids) / sizeof(grn_id); if (n_ids > 0) { grn_obj sources; unsigned int i; GRN_TEXT_INIT(&sources, 0); for (i = 0; i < n_ids; i++) { grn_id source_id; grn_obj *source; char name[GRN_TABLE_MAX_KEY_SIZE]; unsigned int name_size; source_id = GRN_RECORD_VALUE_AT(&source_ids, i); source = grn_ctx_at(ctx, source_id); if (grn_obj_is_table(ctx, source)) { grn_strcpy(name, GRN_TABLE_MAX_KEY_SIZE, "_key"); name_size = strlen(name); } else { name_size = grn_column_name(ctx, source, name, GRN_TABLE_MAX_KEY_SIZE); } if (i > 0) { GRN_TEXT_PUTC(ctx, &sources, ','); } GRN_TEXT_PUT(ctx, &sources, name, name_size); } GRN_TEXT_PUTC(ctx, &sources, '\0'); ADD("sources", GRN_TEXT_VALUE(&sources)); GRN_OBJ_FIN(ctx, &sources); } GRN_OBJ_FIN(ctx, &source_ids); } #undef ADD_OBJECT_NAME #undef ADD }
void test_parse(gconstpointer data) { grn_obj *v; prepare_data(); cond = grn_expr_create(&context, NULL, 0); cut_assert_not_null(cond); v = grn_expr_add_var(&context, cond, NULL, 0); cut_assert_not_null(v); GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs)); PARSE(cond, gcut_data_get_string(data, "query_hoge_moge"), gcut_data_get_int(data, "query_hoge_moge_parse_level")); PARSE(cond, gcut_data_get_string(data, "query_poyo"), gcut_data_get_int(data, "query_poyo_parse_level")); grn_expr_append_op(&context, cond, GRN_OP_AND, 2); grn_test_assert_expr(&context, "noname($1:0){2body GET_VALUE,0\"hoge\",4MATCH," "2body GET_VALUE,0\"moge\",0MATCH,4AND," "2body GET_VALUE,0\"poyo\",0MATCH,0AND}", cond); res = grn_table_create(&context, NULL, 0, NULL, GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, docs, NULL); cut_assert_not_null(res); cut_assert_not_null(grn_table_select(&context, docs, cond, res, GRN_OP_OR)); grn_test_assert_select(&context, gcut_take_new_list_string("poyo moge hoge " "moge moge moge", NULL), res, "body"); grn_test_assert(grn_obj_close(&context, res)); res = NULL; grn_test_assert(grn_obj_close(&context, cond)); cond = NULL; cond = grn_expr_create(&context, NULL, 0); cut_assert_not_null(cond); v = grn_expr_add_var(&context, cond, NULL, 0); cut_assert_not_null(v); GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs)); PARSE(cond, gcut_data_get_string(data, "query_size"), gcut_data_get_int(data, "query_size_parse_level")); grn_test_assert_expr(&context, "noname($1:0){2size GET_VALUE,014,0EQUAL}", cond); res = grn_table_create(&context, NULL, 0, NULL, GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, docs, NULL); cut_assert_not_null(res); cut_assert_not_null(grn_table_select(&context, docs, cond, res, GRN_OP_OR)); grn_test_assert_select(&context, gcut_take_new_list_string("moge moge moge", "hoge fuga fuga", "moge hoge hoge", NULL), res, "body"); }
void test_expr(void) { int i; grn_obj *t1, *t2, *c1, *c2, r1, r2, buf; t1 = grn_table_create(context, "t1", 2, NULL, GRN_OBJ_TABLE_NO_KEY|GRN_OBJ_PERSISTENT, NULL, NULL); cut_assert_not_null(t1); t2 = grn_table_create(context, "t2", 2, NULL, GRN_OBJ_TABLE_NO_KEY|GRN_OBJ_PERSISTENT, NULL, NULL); cut_assert_not_null(t2); c1 = grn_column_create(context, t1, "c1", 2, NULL, GRN_OBJ_PERSISTENT, t2); cut_assert_not_null(c1); c2 = grn_column_create(context, t2, "c2", 2, NULL, GRN_OBJ_PERSISTENT, t1); cut_assert_not_null(c2); GRN_TEXT_INIT(&buf, 0); GRN_RECORD_INIT(&r1, 0, grn_obj_id(context, t1)); GRN_RECORD_INIT(&r2, 0, grn_obj_id(context, t2)); for (i = 0; i < NRECORDS; i++) { grn_id i1, i2; i1 = grn_table_add(context, t1, NULL, 0, NULL); i2 = grn_table_add(context, t2, NULL, 0, NULL); GRN_RECORD_SET(context, &r1, i1); GRN_RECORD_SET(context, &r2, i2); grn_obj_set_value(context, c1, i1, &r2, GRN_OBJ_SET); grn_obj_set_value(context, c2, i2, &r1, GRN_OBJ_SET); } { grn_obj *r, *v; expr = grn_expr_create(context, NULL, 0); cut_assert_not_null(expr); v = grn_expr_add_var(context, expr, NULL, 0); GRN_RECORD_INIT(v, 0, grn_obj_id(context, t1)); grn_expr_append_obj(context, expr, v, GRN_OP_PUSH, 1); GRN_TEXT_SETS(context, &buf, "c1"); grn_expr_append_const(context, expr, &buf, GRN_OP_PUSH, 1); grn_expr_append_op(context, expr, GRN_OP_GET_VALUE, 2); GRN_TEXT_SETS(context, &buf, "c2"); grn_expr_append_const(context, expr, &buf, GRN_OP_PUSH, 1); grn_expr_append_op(context, expr, GRN_OP_GET_VALUE, 2); GRN_TEXT_SETS(context, &buf, "c1"); grn_expr_append_const(context, expr, &buf, GRN_OP_PUSH, 1); // GRN_TEXT_SETS(context, &buf, "c1.c2.c1"); // grn_expr_append_const(context, expr, &buf); grn_expr_append_op(context, expr, GRN_OP_GET_VALUE, 2); grn_expr_compile(context, expr); { grn_id id; uint64_t et; int nerr = 0; grn_table_cursor *tc; struct timeval tvb, tve; tc = grn_table_cursor_open(context, t1, NULL, 0, NULL, 0, 0, -1, 0); cut_assert_not_null(tc); gettimeofday(&tvb, NULL); while ((id = grn_table_cursor_next(context, tc))) { GRN_RECORD_SET(context, v, id); grn_expr_exec(context, expr, 0); r = grn_ctx_pop(context); if (GRN_RECORD_VALUE(r) != id) { nerr++; } } gettimeofday(&tve, NULL); et = (tve.tv_sec - tvb.tv_sec) * 1000000 + (tve.tv_usec - tvb.tv_usec); // printf("et=%zu\n", et); cut_assert_equal_uint(0, nerr); grn_test_assert(grn_table_cursor_close(context, tc)); } } grn_test_assert(grn_obj_close(context, &r1)); grn_test_assert(grn_obj_close(context, &r2)); grn_test_assert(grn_obj_close(context, &buf)); }
static void set_vector(grn_ctx *ctx, grn_obj *column, grn_id id, grn_obj *vector) { int n = GRN_UINT32_VALUE(vector); grn_obj buf, *v = vector + 1; grn_id range_id; grn_obj *range; range_id = DB_OBJ(column)->range; range = grn_ctx_at(ctx, range_id); if (grn_obj_is_table(ctx, range)) { GRN_RECORD_INIT(&buf, GRN_OBJ_VECTOR, range_id); while (n--) { grn_bool cast_failed = GRN_FALSE; grn_obj record, *element = v; if (range_id != element->header.domain) { GRN_RECORD_INIT(&record, 0, range_id); if (grn_obj_cast(ctx, element, &record, GRN_TRUE)) { cast_failed = GRN_TRUE; ERR_CAST(column, range, element); } element = &record; } if (!cast_failed) { GRN_UINT32_PUT(ctx, &buf, GRN_RECORD_VALUE(element)); } if (element == &record) { GRN_OBJ_FIN(ctx, element); } v = values_next(ctx, v); } } else { if (((struct _grn_type *)range)->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) { GRN_TEXT_INIT(&buf, GRN_OBJ_VECTOR); while (n--) { switch (v->header.domain) { case GRN_DB_TEXT : { grn_bool cast_failed = GRN_FALSE; grn_obj casted_element, *element = v; if (range_id != element->header.domain) { GRN_OBJ_INIT(&casted_element, GRN_BULK, 0, range_id); if (grn_obj_cast(ctx, element, &casted_element, GRN_TRUE)) { cast_failed = GRN_TRUE; ERR_CAST(column, range, element); } element = &casted_element; } if (!cast_failed) { grn_vector_add_element(ctx, &buf, GRN_TEXT_VALUE(element), GRN_TEXT_LEN(element), 0, element->header.domain); } if (element == &casted_element) { GRN_OBJ_FIN(ctx, element); } break; } case GRN_JSON_LOAD_OPEN_BRACE : add_weight_vector(ctx, column, v, &buf); n -= GRN_UINT32_VALUE(v); break; default : ERR(GRN_INVALID_ARGUMENT, "array must contain string or object"); break; } v = values_next(ctx, v); } } else { grn_id value_size = ((grn_db_obj *)range)->range; GRN_VALUE_FIX_SIZE_INIT(&buf, GRN_OBJ_VECTOR, range_id); while (n--) { grn_bool cast_failed = GRN_FALSE; grn_obj casted_element, *element = v; if (range_id != element->header.domain) { GRN_OBJ_INIT(&casted_element, GRN_BULK, 0, range_id); if (grn_obj_cast(ctx, element, &casted_element, GRN_TRUE)) { cast_failed = GRN_TRUE; ERR_CAST(column, range, element); } element = &casted_element; } if (!cast_failed) { grn_bulk_write(ctx, &buf, GRN_TEXT_VALUE(element), value_size); } if (element == &casted_element) { GRN_OBJ_FIN(ctx, element); } v = values_next(ctx, v); } } } grn_obj_set_value(ctx, column, id, &buf, GRN_OBJ_SET); GRN_OBJ_FIN(ctx, &buf); }