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_text_to_table(gconstpointer data) { gsize expected_size; grn_obj_reinit(&context, &dest, users, 0); expected_size = gcut_data_get_size(data, "expected-size"); if (expected_size == 0) { cast_text(GRN_INVALID_ARGUMENT, gcut_data_get_string(data, "text")); cut_assert_equal_uint(0, GRN_BULK_VSIZE(&dest)); } else { cast_text(GRN_SUCCESS, gcut_data_get_string(data, "text")); grn_test_assert_equal_record_id(&context, grn_ctx_at(&context, users), gcut_data_get_uint(data, "expected"), GRN_RECORD_VALUE(&dest)); cut_assert_equal_uint(expected_size, GRN_BULK_VSIZE(&dest)); } }
mrb_value grn_mrb_value_from_bulk(mrb_state *mrb, grn_obj *bulk) { mrb_value mrb_value_; grn_ctx *ctx = (grn_ctx *)mrb->ud; switch (bulk->header.domain) { case GRN_DB_INT32 : { int32_t value; value = GRN_INT32_VALUE(bulk); mrb_value_ = mrb_fixnum_value(value); } break; case GRN_DB_UINT32 : { int64_t value; value = GRN_UINT32_VALUE(bulk); if (!FIXABLE(value)) { mrb_raisef(mrb, E_RANGE_ERROR, "can't handle large number: <%S>: max: <%S>", mrb_fixnum_value(value), /* TODO: This will cause overflow */ mrb_fixnum_value(MRB_INT_MAX)); } mrb_value_ = mrb_fixnum_value(value); } break; case GRN_DB_TIME : { int64_t value; int32_t sec; int32_t usec; value = GRN_TIME_VALUE(bulk); GRN_TIME_UNPACK(value, sec, usec); mrb_value_ = mrb_funcall(mrb, mrb_obj_value(ctx->impl->mrb.builtin.time_class), "at", 2, mrb_fixnum_value(sec), mrb_fixnum_value(usec)); } break; case GRN_DB_SHORT_TEXT : case GRN_DB_TEXT : case GRN_DB_LONG_TEXT : mrb_value_ = mrb_str_new(mrb, GRN_TEXT_VALUE(bulk), GRN_TEXT_LEN(bulk)); break; default : { grn_obj *domain; grn_bool is_record = GRN_FALSE; domain = grn_ctx_at(ctx, bulk->header.domain); if (domain) { switch (domain->header.type) { case GRN_TABLE_HASH_KEY : case GRN_TABLE_PAT_KEY : case GRN_TABLE_DAT_KEY : case GRN_TABLE_NO_KEY : is_record = GRN_TRUE; break; default : break; } } if (is_record) { mrb_value_ = mrb_fixnum_value(GRN_RECORD_VALUE(bulk)); grn_obj_unlink(ctx, domain); } else { #define MESSAGE_SIZE 4096 char message[MESSAGE_SIZE]; char domain_name[GRN_TABLE_MAX_KEY_SIZE]; int domain_name_size; if (domain) { domain_name_size = grn_obj_name(ctx, domain, domain_name, GRN_TABLE_MAX_KEY_SIZE); grn_obj_unlink(ctx, domain); } else { grn_strcpy(domain_name, GRN_TABLE_MAX_KEY_SIZE, "unknown"); domain_name_size = strlen(domain_name); } grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "unsupported bulk value type: <%d>(%.*s)", bulk->header.domain, domain_name_size, domain_name); mrb_raise(mrb, E_RANGE_ERROR, message); } #undef MESSAGE_SIZE } break; } return mrb_value_; }
static grn_rc sequential_fuzzy_search(grn_ctx *ctx, grn_obj *table, grn_obj *column, grn_obj *query, uint32_t max_distance, uint32_t prefix_match_size, uint32_t max_expansion, int flags, grn_obj *res, grn_operator op) { grn_table_cursor *tc; char *sx = GRN_TEXT_VALUE(query); char *ex = GRN_BULK_CURR(query); if (op == GRN_OP_AND) { tc = grn_table_cursor_open(ctx, res, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_BY_ID); } else { tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_BY_ID); } if (tc) { grn_id id; grn_obj value; score_heap *heap; int i, n; GRN_TEXT_INIT(&value, 0); heap = score_heap_open(ctx, SCORE_HEAP_SIZE); if (!heap) { grn_table_cursor_close(ctx, tc); grn_obj_unlink(ctx, &value); return GRN_NO_MEMORY_AVAILABLE; } while ((id = grn_table_cursor_next(ctx, tc))) { unsigned int distance = 0; grn_obj *domain; GRN_BULK_REWIND(&value); grn_obj_get_value(ctx, column, id, &value); domain = grn_ctx_at(ctx, ((&value))->header.domain); if ((&(value))->header.type == GRN_VECTOR) { n = grn_vector_size(ctx, &value); for (i = 0; i < n; i++) { unsigned int length; const char *vector_value = NULL; length = grn_vector_get_element(ctx, &value, i, &vector_value, NULL, NULL); if (!prefix_match_size || (prefix_match_size > 0 && length >= prefix_match_size && !memcmp(sx, vector_value, prefix_match_size))) { distance = calc_edit_distance(ctx, sx, ex, (char *)vector_value, (char *)vector_value + length, flags); if (distance <= max_distance) { score_heap_push(ctx, heap, id, distance); break; } } } } else if ((&(value))->header.type == GRN_UVECTOR && grn_obj_is_table(ctx, domain)) { n = grn_vector_size(ctx, &value); for (i = 0; i < n; i++) { grn_id rid; char key_name[GRN_TABLE_MAX_KEY_SIZE]; int key_length; rid = grn_uvector_get_element(ctx, &value, i, NULL); key_length = grn_table_get_key(ctx, domain, rid, key_name, GRN_TABLE_MAX_KEY_SIZE); if (!prefix_match_size || (prefix_match_size > 0 && key_length >= prefix_match_size && !memcmp(sx, key_name, prefix_match_size))) { distance = calc_edit_distance(ctx, sx, ex, key_name, key_name + key_length, flags); if (distance <= max_distance) { score_heap_push(ctx, heap, id, distance); break; } } } } else { if (grn_obj_is_reference_column(ctx, column)) { grn_id rid; char key_name[GRN_TABLE_MAX_KEY_SIZE]; int key_length; rid = GRN_RECORD_VALUE(&value); key_length = grn_table_get_key(ctx, domain, rid, key_name, GRN_TABLE_MAX_KEY_SIZE); if (!prefix_match_size || (prefix_match_size > 0 && key_length >= prefix_match_size && !memcmp(sx, key_name, prefix_match_size))) { distance = calc_edit_distance(ctx, sx, ex, key_name, key_name + key_length, flags); if (distance <= max_distance) { score_heap_push(ctx, heap, id, distance); } } } else { if (!prefix_match_size || (prefix_match_size > 0 && GRN_TEXT_LEN(&value) >= prefix_match_size && !memcmp(sx, GRN_TEXT_VALUE(&value), prefix_match_size))) { distance = calc_edit_distance(ctx, sx, ex, GRN_TEXT_VALUE(&value), GRN_BULK_CURR(&value), flags); if (distance <= max_distance) { score_heap_push(ctx, heap, id, distance); } } } } grn_obj_unlink(ctx, domain); } grn_table_cursor_close(ctx, tc); grn_obj_unlink(ctx, &value); for (i = 0; i < heap->n_entries; i++) { if (max_expansion > 0 && i >= max_expansion) { break; } { grn_posting posting; posting.rid = heap->nodes[i].id; posting.sid = 1; posting.pos = 0; posting.weight = max_distance - heap->nodes[i].score; grn_ii_posting_add(ctx, &posting, (grn_hash *)res, op); } } grn_ii_resolve_sel_and(ctx, (grn_hash *)res, op); score_heap_close(ctx, heap); } return GRN_SUCCESS; }
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)); }
static grn_bool exec_text_operator_record_text(grn_ctx *ctx, grn_operator op, grn_obj *record, grn_obj *table, grn_obj *query) { grn_obj *normalizer; char record_key[GRN_TABLE_MAX_KEY_SIZE]; int record_key_len; grn_bool matched = GRN_FALSE; if (table->header.domain != GRN_DB_SHORT_TEXT) { return GRN_FALSE; } if (GRN_TEXT_LEN(query) == 0) { return GRN_FALSE; } record_key_len = grn_table_get_key(ctx, table, GRN_RECORD_VALUE(record), record_key, GRN_TABLE_MAX_KEY_SIZE); grn_table_get_info(ctx, table, NULL, NULL, NULL, &normalizer, NULL); if (normalizer) { grn_obj *norm_query; const char *norm_query_raw; unsigned int norm_query_raw_length_in_bytes; if (op == GRN_OP_REGEXP) { norm_query = NULL; norm_query_raw = GRN_TEXT_VALUE(query); norm_query_raw_length_in_bytes = GRN_TEXT_LEN(query); } else { norm_query = grn_string_open(ctx, GRN_TEXT_VALUE(query), GRN_TEXT_LEN(query), table, 0); grn_string_get_normalized(ctx, norm_query, &norm_query_raw, &norm_query_raw_length_in_bytes, NULL); } matched = exec_text_operator(ctx, op, record_key, record_key_len, norm_query_raw, norm_query_raw_length_in_bytes); if (norm_query) { grn_obj_close(ctx, norm_query); } } else { matched = exec_text_operator_raw_text_raw_text(ctx, op, record_key, record_key_len, GRN_TEXT_VALUE(query), GRN_TEXT_LEN(query)); } return matched; }
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); }
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; }