static void create_geo_table(const gchar *load_data) { const char *table_name = "Data"; const char *column_name = "location"; assert_send_commands( cut_take_printf("table_create %s TABLE_NO_KEY", table_name)); assert_send_commands( cut_take_printf("column_create %s %s COLUMN_SCALAR WGS84GeoPoint", table_name, column_name)); assert_send_commands("table_create Index TABLE_PAT_KEY WGS84GeoPoint"); assert_send_commands( cut_take_printf("column_create Index %s_%s COLUMN_INDEX %s %s", table_name, column_name, table_name, column_name)); assert_send_commands( cut_take_printf("load --table %s\n" "[\n" " [\"%s\"],\n" "%s\n" "]", table_name, column_name, load_data)); table = grn_ctx_get(context, table_name, strlen(table_name)); column = grn_obj_column(context, table, column_name, strlen(column_name)); }
const GList * grn_test_table_collect_string(grn_ctx *context, grn_obj *table, const gchar *text_column_name) { GList *records = NULL; grn_table_cursor *cursor; grn_id id; grn_obj *text_column; grn_obj value; cursor = grn_table_cursor_open(context, table, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_ASCENDING); grn_test_assert_context(context); text_column = grn_obj_column(context, table, text_column_name, strlen(text_column_name)); GRN_TEXT_INIT(&value, 0); while ((id = grn_table_cursor_next(context, cursor)) != GRN_ID_NIL) { GRN_BULK_REWIND(&value); grn_obj_get_value(context, text_column, id, &value); records = g_list_append(records, g_strndup(GRN_TEXT_VALUE(&value), GRN_TEXT_LEN(&value))); } grn_obj_unlink(context, &value); grn_obj_unlink(context, text_column); gcut_take_list(records, g_free); grn_test_assert(grn_table_cursor_close(context, cursor)); grn_test_assert_context(context); return records; }
const GList * grn_test_view_collect_string(grn_ctx *context, grn_obj *view, const gchar *text_column_name) { GList *records = NULL; grn_table_cursor *cursor; grn_obj id, value; grn_obj *text_column; cursor = grn_table_cursor_open(context, view, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_ASCENDING); cut_assert_not_null(cursor); GRN_TEXT_INIT(&id, 0); GRN_TEXT_INIT(&value, 0); text_column = grn_obj_column(context, view, text_column_name, strlen(text_column_name)); while (grn_table_cursor_next_o(context, cursor, &id) == GRN_SUCCESS) { GRN_BULK_REWIND(&value); grn_obj_get_value_o(context, text_column, &id, &value); records = g_list_append(records, g_strndup(GRN_TEXT_VALUE(&value), GRN_TEXT_LEN(&value))); } grn_obj_unlink(context, &id); grn_obj_unlink(context, &value); grn_obj_unlink(context, text_column); gcut_take_list(records, g_free); grn_test_assert(grn_table_cursor_close(context, cursor)); grn_test_assert_context(context); return records; }
/* * Document-method: column_value * * call-seq: * view.column_value(id, name) -> 値 * * _view_の_id_に対応するカラム_name_の値を返す。 */ static VALUE rb_grn_view_get_column_value (VALUE self, VALUE rb_id, VALUE rb_name) { VALUE rb_value = Qnil; #ifdef WIN32 rb_raise(rb_eNotImpError, "grn_obj_get_value_o() isn't available on Windows."); #else RbGrnTable *rb_view; grn_ctx *context = NULL; grn_obj *view, *value, *accessor; grn_obj id; rb_view = SELF(self); rb_grn_table_deconstruct(rb_view, &view, &context, NULL, NULL, &value, NULL, NULL, NULL); GRN_BULK_REWIND(value); GRN_TEXT_INIT(&id, 0); GRN_TEXT_PUT(context, &id, RSTRING_PTR(rb_id), RSTRING_LEN(rb_id)); accessor = grn_obj_column(context, view, RSTRING_PTR(rb_name), RSTRING_LEN(rb_name)); grn_obj_get_value_o(context, accessor, &id, value); grn_obj_unlink(context, accessor); rb_value = GRNOBJ2RVAL(Qnil, context, value, self); GRN_OBJ_FIN(context, &id); #endif return rb_value; }
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)); }
static grn_obj * command_tag_synonym_delete(grn_ctx *ctx, GNUC_UNUSED int nargs, GNUC_UNUSED grn_obj **args, grn_user_data *user_data) { grn_obj *var, *table, *column; unsigned int nhooks = 0; char *table_name = NULL; unsigned int table_len = 0; char *column_name = NULL; unsigned int column_len = 0; var = grn_plugin_proc_get_var(ctx, user_data, "table", -1); if (GRN_TEXT_LEN(var) != 0) { table_name = GRN_TEXT_VALUE(var); table_len = GRN_TEXT_LEN(var); } var = grn_plugin_proc_get_var(ctx, user_data, "column", -1); if (GRN_TEXT_LEN(var) != 0) { column_name = GRN_TEXT_VALUE(var); column_len = GRN_TEXT_LEN(var); } table = grn_ctx_get(ctx, table_name, table_len); column = grn_obj_column(ctx, table, column_name, column_len); nhooks = grn_obj_get_nhooks(ctx, column, GRN_HOOK_SET); if (nhooks) { grn_obj *hook; unsigned int i; grn_obj data; grn_obj buf; GRN_TEXT_INIT(&buf, 0); GRN_TEXT_INIT(&data, 0); for (i=0; i < nhooks; i++) { GRN_BULK_REWIND(&buf); GRN_BULK_REWIND(&data); hook = grn_obj_get_hook(ctx, column, GRN_HOOK_SET, i, &data); grn_inspect_name(ctx, &buf, hook); if (GRN_TEXT_LEN(&buf) == strlen("tag_synonym") && strncmp(GRN_TEXT_VALUE(&buf), "tag_synonym", GRN_TEXT_LEN(&buf)) == 0) { grn_obj_delete_hook(ctx, column, GRN_HOOK_SET, i); break; } } grn_obj_unlink(ctx, &data); grn_obj_unlink(ctx, &buf); } nhooks = grn_obj_get_nhooks(ctx, column, GRN_HOOK_SET); //grn_ctx_output_array_open(ctx, "RESULT", 1); grn_ctx_output_int32(ctx, nhooks); //grn_ctx_output_array_close(ctx); return NULL; }
void test_nonexistent_column(void) { grn_obj *table; char table_name[] = "users"; char nonexistent_column_name[] = "nonexistent"; table = grn_table_create(context, table_name, strlen(table_name), NULL, GRN_OBJ_TABLE_NO_KEY, NULL, NULL); grn_test_assert_null(context, grn_obj_column(context, table, nonexistent_column_name, strlen(nonexistent_column_name))); }
static grn_id resolve_source_id (grn_ctx *context, grn_obj *column, VALUE rb_source) { grn_id source_id; if (CBOOL2RVAL(rb_obj_is_kind_of(rb_source, rb_cInteger))) { source_id = NUM2UINT(rb_source); } else { grn_obj *source; if (TYPE(rb_source) == T_STRING) { grn_obj *table; const char *name; const char *dot_point; int length; table = grn_ctx_at(context, grn_obj_get_range(context, column)); name = StringValueCStr(rb_source); length = RSTRING_LEN(rb_source); dot_point = strstr(name, "."); if (dot_point) { char table_name[4096]; int table_name_length; table_name_length = grn_obj_name(context, table, table_name, sizeof(table_name)); table_name[table_name_length] = '\0'; if (strncmp(table_name, name, dot_point - name) != 0) { rb_raise(rb_eArgError, "wrong table's column: <%s>: " "expected table: <%s>", name, table_name); } length -= (dot_point - name) + 1; name = dot_point + 1; } source = grn_obj_column(context, table, name, length); } else { source = RVAL2GRNOBJECT(rb_source, &context); } rb_grn_context_check(context, rb_source); source_id = grn_obj_id(context, source); } return source_id; }
bool ConditionConverter::have_index(const Item_field *field_item, grn_operator _operator) { MRN_DBUG_ENTER_METHOD(); grn_obj *column; column = grn_obj_column(ctx_, table_, MRN_ITEM_FIELD_GET_NAME(field_item), MRN_ITEM_FIELD_GET_NAME_LENGTH(field_item)); if (!column) { DBUG_RETURN(false); } mrn::SmartGrnObj smart_column(ctx_, column); int n_indexes = grn_column_index(ctx_, column, _operator, NULL, 0, NULL); bool convertable = (n_indexes > 0); DBUG_RETURN(convertable); }
static mrb_value mrb_grn_table_find_column(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; grn_obj *table; mrb_value mrb_column_name; grn_obj *column; mrb_get_args(mrb, "o", &mrb_column_name); table = DATA_PTR(self); column = grn_obj_column(ctx, table, RSTRING_PTR(mrb_column_name), RSTRING_LEN(mrb_column_name)); grn_mrb_ctx_check(mrb); return grn_mrb_value_from_grn_obj(mrb, column); }
void test_is_accessor(gconstpointer data) { const gchar *name; grn_obj *table; grn_obj *object; assert_send_command("table_create Users TABLE_HASH_KEY ShortText"); assert_send_command("column_create Users name COLUMN_SCALAR ShortText"); table = grn_ctx_get(context, "Users", -1); name = gcut_data_get_string(data, "name"); object = grn_obj_column(context, table, name, strlen(name)); if (gcut_data_get_string(data, "expected")) { cut_assert_true(grn_obj_is_accessor(context, object)); } else { cut_assert_false(grn_obj_is_accessor(context, object)); } }
void test_mroonga_index_score(void) { grn_obj *t1,*c1,*lc,*ft; grn_obj buff; grn_id r1,r2,r3,r4; const gchar *mrn_dir; mrn_dir = cut_build_path(tmp_directory, "mrn", NULL); g_mkdir_with_parents(mrn_dir, 0700); grn_obj_close(context, db); db = grn_db_create(context, cut_build_path(mrn_dir, "mroonga.grn", NULL), NULL); cut_assert_not_null(db); /* actual table */ t1 = grn_table_create(context, "t1", 2, cut_build_path(mrn_dir, "t1.grn", NULL), GRN_OBJ_TABLE_NO_KEY|GRN_OBJ_PERSISTENT, NULL, 0); cut_assert_not_null(t1); /* lexicon table */ lc = grn_table_create(context, "lc", 2, cut_build_path(mrn_dir, "lc.grn", NULL), GRN_OBJ_TABLE_PAT_KEY|GRN_OBJ_PERSISTENT, grn_ctx_at(context, GRN_DB_SHORT_TEXT), 0); cut_assert_not_null(lc); grn_test_assert(grn_obj_set_info(context, lc, GRN_INFO_DEFAULT_TOKENIZER, grn_ctx_at(context, GRN_DB_BIGRAM))); /* actual column */ c1 = grn_column_create(context, t1, "c1", 2, cut_build_path(mrn_dir, "t1.c1.grn", NULL), GRN_OBJ_COLUMN_SCALAR|GRN_OBJ_PERSISTENT, grn_ctx_at(context, GRN_DB_TEXT)); cut_assert_not_null(c1); /* fulltext index */ ft = grn_column_create(context, lc, "ft", 2, cut_build_path(mrn_dir, "lc.ft.grn", NULL), GRN_OBJ_COLUMN_INDEX|GRN_OBJ_PERSISTENT, t1); cut_assert_not_null(ft); GRN_TEXT_INIT(&buff,0); /* link between actual column and fulltext index */ GRN_UINT32_SET(context, &buff, grn_obj_id(context, c1)); grn_obj_set_info(context, ft, GRN_INFO_SOURCE, &buff); /* need to use grn_id */ /* insert row */ r1 = grn_table_add(context, t1, NULL, 0, NULL); cut_assert_equal_int(1,r1); GRN_TEXT_SETS(context, &buff, "abcde"); grn_test_assert(grn_obj_set_value(context, c1, r1, &buff, GRN_OBJ_SET)); r2 = grn_table_add(context, t1, NULL, 0, NULL); cut_assert_equal_int(2,r2); GRN_TEXT_SETS(context, &buff, "fghij"); grn_test_assert(grn_obj_set_value(context, c1, r2, &buff, GRN_OBJ_SET)); r3 = grn_table_add(context, t1, NULL, 0, NULL); cut_assert_equal_int(3,r3); GRN_TEXT_SETS(context, &buff, "11 22 33"); grn_test_assert(grn_obj_set_value(context, c1, r3, &buff, GRN_OBJ_SET)); r4 = grn_table_add(context, t1, NULL, 0, NULL); cut_assert_equal_int(4,r4); GRN_TEXT_SETS(context, &buff, "44 22 55"); grn_test_assert(grn_obj_set_value(context, c1, r4, &buff, GRN_OBJ_SET)); /* confirm record are inserted in both column and index */ cut_assert_equal_int(4,grn_table_size(context,t1)); cut_assert_equal_int(23,grn_table_size(context,lc)); /* nlq search */ { grn_id id, docid; grn_obj *res; grn_table_cursor *tc; grn_obj score, *score_column; res = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, t1, 0); GRN_FLOAT_INIT(&score, 0); GRN_BULK_REWIND(&buff); GRN_TEXT_SETS(context, &buff, "hij"); grn_obj_search(context, ft, &buff, res, GRN_OP_OR, NULL); cut_assert_equal_int(1, grn_table_size(context, res)); score_column = grn_obj_column(context, res, "_score", 6); tc = grn_table_cursor_open(context, res, NULL, 0, NULL, 0, 0, -1, 0); while ((id = grn_table_cursor_next(context, tc))) { GRN_BULK_REWIND(&buff); grn_table_get_key(context, res, id, &docid, sizeof(grn_id)); cut_assert_equal_int(2, docid); cut_assert_not_null(grn_obj_get_value(context, c1, docid, &buff)); cut_assert_equal_int(5 ,GRN_TEXT_LEN(&buff)); cut_assert_equal_substring("fghij", (char*) GRN_BULK_HEAD(&buff),GRN_TEXT_LEN(&buff)); grn_obj_get_value(context, score_column, id, &score); cut_assert_equal_double(1.0, DBL_EPSILON, GRN_FLOAT_VALUE(&score)); } grn_table_cursor_close(context, tc); grn_obj_close(context, score_column); grn_obj_close(context, res); } /* boolean search */ { grn_id id, docid; grn_obj *res; grn_obj *match_columns, *match_columns_variable; grn_obj *expression, *expression_variable; grn_table_cursor *tc; grn_obj score, *score_column; const char *match_columns_expression = "c1 * 5"; const char *qstr = "+22 -55"; GRN_EXPR_CREATE_FOR_QUERY(context, t1, match_columns, match_columns_variable); grn_expr_parse(context, match_columns, match_columns_expression, strlen(match_columns_expression), NULL, GRN_OP_MATCH, GRN_OP_AND, GRN_EXPR_SYNTAX_SCRIPT); GRN_EXPR_CREATE_FOR_QUERY(context, t1, expression, expression_variable); res = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, t1, 0); grn_test_assert(grn_expr_parse(context, expression, qstr, strlen(qstr), match_columns, GRN_OP_MATCH, GRN_OP_OR, GRN_EXPR_SYNTAX_QUERY)); grn_table_select(context, t1, expression, res, GRN_OP_OR); cut_assert_equal_int(1, grn_table_size(context, res)); GRN_FLOAT_INIT(&score, 0); score_column = grn_obj_column(context, res, "_score", 6); tc = grn_table_cursor_open(context, res, NULL, 0, NULL, 0, 0, -1, 0); while ((id = grn_table_cursor_next(context, tc))) { GRN_BULK_REWIND(&buff); grn_table_get_key(context, res, id, &docid, sizeof(grn_id)); cut_assert_equal_int(3, docid); cut_assert_not_null(grn_obj_get_value(context, c1, docid, &buff)); cut_assert_equal_int(8, GRN_TEXT_LEN(&buff)); cut_assert_equal_substring("11 22 33", (char*) GRN_BULK_HEAD(&buff),GRN_TEXT_LEN(&buff)); grn_obj_get_value(context, score_column, id, &score); cut_assert_equal_double(5, DBL_EPSILON, GRN_FLOAT_VALUE(&score)); } grn_obj_close(context, expression); grn_obj_close(context, match_columns); grn_table_cursor_close(context ,tc); grn_obj_close(context, score_column); grn_obj_close(context, res); } grn_obj_close(context, &buff); grn_obj_close(context, ft); grn_obj_close(context, c1); grn_obj_close(context, lc); grn_obj_close(context, t1); }
void test_mroonga_index_score(void) { grn_obj *t1,*c1,*lc,*ft; grn_obj buff; grn_id r1,r2,r3,r4; remove_tmp_directory(); g_mkdir_with_parents(tmp_directory,0700); g_chdir(tmp_directory); g_mkdir_with_parents("mrn",0700); db = grn_db_create(context,"mroonga.grn",NULL); cut_assert_not_null(db); /* actual table */ t1 = grn_table_create(context,"t1",2,"mrn/t1.grn", GRN_OBJ_TABLE_NO_KEY|GRN_OBJ_PERSISTENT,NULL,0); cut_assert_not_null(t1); /* lexicon table */ lc = grn_table_create(context,"lc",2,"mrn/lc.grn", GRN_OBJ_TABLE_PAT_KEY|GRN_OBJ_PERSISTENT, grn_ctx_at(context, GRN_DB_SHORT_TEXT), 0); cut_assert_not_null(lc); grn_test_assert(grn_obj_set_info(context, lc, GRN_INFO_DEFAULT_TOKENIZER, grn_ctx_at(context, GRN_DB_BIGRAM))); /* actual column */ c1 = grn_column_create(context,t1,"c1",2,"mrn/t1.c1.grn", GRN_OBJ_COLUMN_SCALAR|GRN_OBJ_PERSISTENT, grn_ctx_at(context, GRN_DB_TEXT)); cut_assert_not_null(c1); /* fulltext index */ ft = grn_column_create(context,lc,"ft",2,"mrn/lc.ft.grn", GRN_OBJ_COLUMN_INDEX|GRN_OBJ_PERSISTENT,t1); cut_assert_not_null(ft); GRN_TEXT_INIT(&buff,0); /* link between actual column and fulltext index */ GRN_UINT32_SET(context, &buff, grn_obj_id(context, c1)); grn_obj_set_info(context, ft, GRN_INFO_SOURCE, &buff); /* need to use grn_id */ /* insert row */ r1 = grn_table_add(context, t1, NULL, 0, NULL); cut_assert_equal_int(1,r1); GRN_TEXT_SETS(context, &buff, "abcde"); grn_test_assert(grn_obj_set_value(context, c1, r1, &buff, GRN_OBJ_SET)); r2 = grn_table_add(context, t1, NULL, 0, NULL); cut_assert_equal_int(2,r2); GRN_TEXT_SETS(context, &buff, "fghij"); grn_test_assert(grn_obj_set_value(context, c1, r2, &buff, GRN_OBJ_SET)); r3 = grn_table_add(context, t1, NULL, 0, NULL); cut_assert_equal_int(3,r3); GRN_TEXT_SETS(context, &buff, "11 22 33"); grn_test_assert(grn_obj_set_value(context, c1, r3, &buff, GRN_OBJ_SET)); r4 = grn_table_add(context, t1, NULL, 0, NULL); cut_assert_equal_int(4,r4); GRN_TEXT_SETS(context, &buff, "44 22 55"); grn_test_assert(grn_obj_set_value(context, c1, r4, &buff, GRN_OBJ_SET)); /* confirm record are inserted in both column and index */ cut_assert_equal_int(4,grn_table_size(context,t1)); cut_assert_equal_int(23,grn_table_size(context,lc)); /* nlq search */ { grn_id id, docid; grn_obj *res; grn_table_cursor *tc; grn_obj score, *score_column; res = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, t1, 0); GRN_UINT32_INIT(&score, 0); GRN_BULK_REWIND(&buff); GRN_TEXT_SETS(context, &buff, "hij"); grn_obj_search(context, ft, &buff, res, GRN_OP_OR, NULL); cut_assert_equal_int(1, grn_table_size(context, res)); score_column = grn_obj_column(context, res, ".:score", 7); tc = grn_table_cursor_open(context, res, NULL, 0, NULL, 0, 0, 0, 0); while ((id = grn_table_cursor_next(context, tc))) { GRN_BULK_REWIND(&buff); grn_table_get_key(context, res, id, &docid, sizeof(grn_id)); cut_assert_equal_int(2, docid); cut_assert_not_null(grn_obj_get_value(context, c1, docid, &buff)); cut_assert_equal_int(5 ,GRN_TEXT_LEN(&buff)); cut_assert_equal_substring("fghij", (char*) GRN_BULK_HEAD(&buff),GRN_TEXT_LEN(&buff)); grn_obj_get_value(context, score_column, id, &score); cut_assert_equal_uint(1, GRN_UINT32_VALUE(&score)); } grn_table_cursor_close(context, tc); grn_obj_close(context, score_column); grn_obj_close(context, res); } /* boolean search */ { grn_id id, docid; grn_obj *res; grn_query *query; grn_table_cursor *tc; grn_obj score, *score_column; const char *qstr = "+22 -55"; res = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, t1, 0); GRN_UINT32_INIT(&score, 0); query = grn_query_open(context, qstr, strlen(qstr), GRN_OP_OR, 32); grn_obj_search(context, ft, (grn_obj*) query, res, GRN_OP_OR, NULL); cut_assert_equal_int(1, grn_table_size(context, res)); score_column = grn_obj_column(context, res, ".:score", 7); tc = grn_table_cursor_open(context, res, NULL, 0, NULL, 0, 0, 0, 0); while ((id = grn_table_cursor_next(context, tc))) { GRN_BULK_REWIND(&buff); grn_table_get_key(context, res, id, &docid, sizeof(grn_id)); cut_assert_equal_int(3, docid); cut_assert_not_null(grn_obj_get_value(context, c1, docid, &buff)); cut_assert_equal_int(8 ,GRN_TEXT_LEN(&buff)); cut_assert_equal_substring("11 22 33", (char*) GRN_BULK_HEAD(&buff),GRN_TEXT_LEN(&buff)); grn_obj_get_value(context, score_column, id, &score); cut_assert_equal_uint(5, GRN_UINT32_VALUE(&score)); } grn_query_close(context, query); grn_table_cursor_close(context ,tc); grn_obj_close(context, score_column); grn_obj_close(context, res); } grn_obj_close(context, &buff); grn_obj_close(context, ft); grn_obj_close(context, c1); grn_obj_close(context, lc); grn_obj_close(context, t1); }
/* TODO: Fix memory leak on error */ static mrb_value mrb_grn_table_sort(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; grn_obj *table; grn_obj *result = NULL; grn_table_sort_key *keys; int i, n_keys; int offset = 0; int limit = -1; mrb_value mrb_keys; mrb_value mrb_options = mrb_nil_value(); table = DATA_PTR(self); mrb_get_args(mrb, "o|H", &mrb_keys, &mrb_options); mrb_keys = mrb_convert_type(mrb, mrb_keys, MRB_TT_ARRAY, "Array", "to_ary"); n_keys = RARRAY_LEN(mrb_keys); keys = GRN_MALLOCN(grn_table_sort_key, n_keys); for (i = 0; i < n_keys; i++) { mrb_value mrb_sort_options; mrb_value mrb_sort_key; mrb_value mrb_sort_order; mrb_sort_options = RARRAY_PTR(mrb_keys)[i]; mrb_sort_key = grn_mrb_options_get_lit(mrb, mrb_sort_options, "key"); switch (mrb_type(mrb_sort_key)) { case MRB_TT_STRING : keys[i].key = grn_obj_column(ctx, table, RSTRING_PTR(mrb_sort_key), RSTRING_LEN(mrb_sort_key)); break; case MRB_TT_SYMBOL : { const char *name; mrb_int name_length; name = mrb_sym2name_len(mrb, mrb_symbol(mrb_sort_key), &name_length); keys[i].key = grn_obj_column(ctx, table, name, name_length); } break; default : /* TODO: free */ mrb_raisef(mrb, E_ARGUMENT_ERROR, "sort key must be string or symbol: %S", mrb_sort_key); break; } keys[i].flags = 0; mrb_sort_order = grn_mrb_options_get_lit(mrb, mrb_sort_options, "order"); if (mrb_nil_p(mrb_sort_order) || (mrb_symbol(mrb_sort_order) == mrb_intern_lit(mrb, "ascending"))) { keys[i].flags |= GRN_TABLE_SORT_ASC; } else { keys[i].flags |= GRN_TABLE_SORT_DESC; } } if (!mrb_nil_p(mrb_options)) { mrb_value mrb_offset; mrb_value mrb_limit; mrb_offset = grn_mrb_options_get_lit(mrb, mrb_options, "offset"); if (!mrb_nil_p(mrb_offset)) { offset = mrb_fixnum(mrb_offset); } mrb_limit = grn_mrb_options_get_lit(mrb, mrb_options, "limit"); if (!mrb_nil_p(mrb_limit)) { limit = mrb_fixnum(mrb_limit); } } result = grn_table_create(ctx, NULL, 0, NULL, GRN_TABLE_NO_KEY, NULL, table); grn_table_sort(ctx, table, offset, limit, result, keys, n_keys); for (i = 0; i < n_keys; i++) { grn_obj_unlink(ctx, keys[i].key); } GRN_FREE(keys); grn_mrb_ctx_check(mrb); return grn_mrb_value_from_grn_obj(mrb, result); }
MRN_API mrn_bool mroonga_query_expand_init(UDF_INIT *init, UDF_ARGS *args, char *message) { mrn::QueryExpandInfo *info = NULL; MRN_DBUG_ENTER_FUNCTION(); init->ptr = NULL; if (args->arg_count != 4) { sprintf(message, "mroonga_query_expand(): wrong number of arguments: %u for 4", args->arg_count); goto error; } if (args->arg_type[0] != STRING_RESULT) { strcpy(message, "mroonga_query_expand(): " "the 1st argument must be table name as string"); goto error; } if (args->arg_type[1] != STRING_RESULT) { strcpy(message, "mroonga_query_expand(): " "the 2nd argument must be term column name as string"); goto error; } if (args->arg_type[2] != STRING_RESULT) { strcpy(message, "mroonga_query_expand(): " "the 3nd argument must be expanded term column name as string"); goto error; } if (args->arg_type[3] != STRING_RESULT) { strcpy(message, "mroonga_query_expand(): " "the 4th argument must be query as string"); goto error; } init->maybe_null = 1; info = static_cast<mrn::QueryExpandInfo *>( mrn_my_malloc(sizeof(mrn::QueryExpandInfo), MYF(MY_WME | MY_ZEROFILL))); if (!info) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_query_expand(): failed to allocate memory"); goto error; } { const char *current_db_path = MRN_THD_DB_PATH(current_thd); if (!current_db_path) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_query_expand(): no current database"); goto error; } mrn::Database *db; int error = mrn_db_manager->open(current_db_path, &db); if (error != 0) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_query_expand(): failed to open database: %s", mrn_db_manager->error_message()); goto error; } info->ctx = mrn_context_pool->pull(); grn_ctx_use(info->ctx, db->get()); } GRN_TEXT_INIT(&(info->expanded_query), 0); { const char *table_name = args->args[0]; unsigned int table_name_length = args->lengths[0]; grn_obj *table = grn_ctx_get(info->ctx, table_name, table_name_length); if (!table) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_query_expand(): table doesn't exist: <%.*s>", static_cast<int>(table_name_length), table_name); goto error; } const char *term_column_name = args->args[1]; unsigned int term_column_name_length = args->lengths[1]; info->term_column = grn_obj_column(info->ctx, table, term_column_name, term_column_name_length); if (!info->term_column) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_query_expand(): term column doesn't exist: <%.*s.%.*s>", static_cast<int>(table_name_length), table_name, static_cast<int>(term_column_name_length), term_column_name); goto error; } const char *expanded_term_column_name = args->args[2]; unsigned int expanded_term_column_name_length = args->lengths[2]; info->expanded_term_column = grn_obj_column(info->ctx, table, expanded_term_column_name, expanded_term_column_name_length); if (!info->expanded_term_column) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_query_expand(): " "expanded term column doesn't exist: <%.*s.%.*s>", static_cast<int>(table_name_length), table_name, static_cast<int>(expanded_term_column_name_length), expanded_term_column_name); goto error; } } init->ptr = reinterpret_cast<char *>(info); DBUG_RETURN(false); error: mrn_query_expand_info_free(info); DBUG_RETURN(true); }
void test_setoperation(gconstpointer data) { grn_operator operator; grn_obj *entries; grn_obj *result1; grn_obj *result2; const char *dump; operator = gcut_data_get_int(data, "operator"); assert_send_command("table_create Entries TABLE_HASH_KEY ShortText"); send_command( "load " "--table Entries " "--values '[{\"_key\": \"a\"}, {\"_key\": \"b\"}, {\"_key\": \"c\"}]'"); entries = grn_ctx_get(context, "Entries", -1); { const char *condition = "_id < 3"; grn_obj *expr; grn_obj *variable; GRN_EXPR_CREATE_FOR_QUERY(context, entries, expr, variable); grn_expr_parse(context, expr, condition, strlen(condition), NULL, GRN_OP_AND, GRN_OP_MATCH, GRN_EXPR_SYNTAX_SCRIPT); result1 = grn_table_select(context, entries, expr, NULL, GRN_OP_OR); grn_obj_unlink(context, expr); } { const char *condition = "_id > 1"; grn_obj *expr; grn_obj *variable; GRN_EXPR_CREATE_FOR_QUERY(context, entries, expr, variable); grn_expr_parse(context, expr, condition, strlen(condition), NULL, GRN_OP_AND, GRN_OP_MATCH, GRN_EXPR_SYNTAX_SCRIPT); result2 = grn_table_select(context, entries, expr, NULL, GRN_OP_OR); grn_obj_unlink(context, expr); } grn_table_setoperation(context, result1, result2, result1, operator); { grn_bool first_record = GRN_TRUE; grn_obj buffer; grn_obj *score_accessor; grn_obj score; GRN_TEXT_INIT(&buffer, 0); GRN_TEXT_PUTS(context, &buffer, "["); score_accessor = grn_obj_column(context, result1, GRN_COLUMN_NAME_SCORE, GRN_COLUMN_NAME_SCORE_LEN); GRN_FLOAT_INIT(&score, 0); GRN_TABLE_EACH_BEGIN(context, result1, cursor, id) { void *result_key; grn_id entry_id; char entry_key[GRN_TABLE_MAX_KEY_SIZE]; int entry_key_size; if (first_record) { first_record = GRN_FALSE; } else { GRN_TEXT_PUTS(context, &buffer, ", "); } GRN_TEXT_PUTS(context, &buffer, "["); grn_table_cursor_get_key(context, cursor, &result_key); entry_id = *((grn_id *)result_key); entry_key_size = grn_table_get_key(context, entries, entry_id, entry_key, GRN_TABLE_MAX_KEY_SIZE); GRN_TEXT_PUT(context, &buffer, entry_key, entry_key_size); GRN_TEXT_PUTS(context, &buffer, ", "); GRN_BULK_REWIND(&score); grn_obj_get_value(context, score_accessor, id, &score); grn_text_printf(context, &buffer, "%.1f", GRN_FLOAT_VALUE(&score)); GRN_TEXT_PUTS(context, &buffer, "]"); } GRN_TABLE_EACH_END(context, cursor); GRN_OBJ_FIN(context, &score); grn_obj_unlink(context, score_accessor); GRN_TEXT_PUTS(context, &buffer, "]"); dump = cut_take_strndup(GRN_TEXT_VALUE(&buffer), GRN_TEXT_LEN(&buffer)); GRN_OBJ_FIN(context, &buffer); }
static void bracket_close(grn_ctx *ctx, grn_loader *loader) { grn_id id = GRN_ID_NIL; grn_obj *value, *value_end, *id_value = NULL, *key_value = NULL; grn_obj *col, **cols; /* Columns except _id and _key. */ uint32_t i, begin; uint32_t ncols; /* Number of columns except _id and _key. */ uint32_t nvalues; /* Number of values in brackets. */ uint32_t depth; grn_bool is_record_load = GRN_FALSE; cols = (grn_obj **)GRN_BULK_HEAD(&loader->columns); ncols = GRN_BULK_VSIZE(&loader->columns) / sizeof(grn_obj *); GRN_UINT32_POP(&loader->level, begin); value = (grn_obj *)GRN_TEXT_VALUE(&loader->values) + begin; value_end = (grn_obj *)GRN_TEXT_VALUE(&loader->values) + loader->values_size; GRN_ASSERT(value->header.domain == GRN_JSON_LOAD_OPEN_BRACKET); GRN_UINT32_SET(ctx, value, loader->values_size - begin - 1); value++; depth = GRN_BULK_VSIZE(&loader->level); if (depth > sizeof(uint32_t) * loader->emit_level) { return; } if (depth == 0 || !loader->table || loader->columns_status == GRN_LOADER_COLUMNS_BROKEN) { goto exit; } nvalues = values_len(ctx, value, value_end); if (loader->columns_status == GRN_LOADER_COLUMNS_UNSET) { /* * Target columns and _id or _key are not specified yet and values are * handled as column names and "_id" or "_key". */ for (i = 0; i < nvalues; i++) { const char *col_name; unsigned int col_name_size; if (value->header.domain != GRN_DB_TEXT) { grn_obj buffer; GRN_TEXT_INIT(&buffer, 0); grn_inspect(ctx, &buffer, value); ERR(GRN_INVALID_ARGUMENT, "column name must be string: <%.*s>", (int)GRN_TEXT_LEN(&buffer), GRN_TEXT_VALUE(&buffer)); grn_loader_save_error(ctx, loader); GRN_OBJ_FIN(ctx, &buffer); loader->columns_status = GRN_LOADER_COLUMNS_BROKEN; goto exit; } col_name = GRN_TEXT_VALUE(value); col_name_size = GRN_TEXT_LEN(value); col = grn_obj_column(ctx, loader->table, col_name, col_name_size); if (!col) { ERR(GRN_INVALID_ARGUMENT, "nonexistent column: <%.*s>", col_name_size, col_name); grn_loader_save_error(ctx, loader); loader->columns_status = GRN_LOADER_COLUMNS_BROKEN; goto exit; } if (name_equal(col_name, col_name_size, GRN_COLUMN_NAME_ID)) { grn_obj_unlink(ctx, col); if (loader->id_offset != -1 || loader->key_offset != -1) { /* _id and _key must not appear more than once. */ if (loader->id_offset != -1) { ERR(GRN_INVALID_ARGUMENT, "duplicated id and key columns: <%s> at %d and <%s> at %d", GRN_COLUMN_NAME_ID, i, GRN_COLUMN_NAME_ID, loader->id_offset); } else { ERR(GRN_INVALID_ARGUMENT, "duplicated id and key columns: <%s> at %d and <%s> at %d", GRN_COLUMN_NAME_ID, i, GRN_COLUMN_NAME_KEY, loader->key_offset); } grn_loader_save_error(ctx, loader); loader->columns_status = GRN_LOADER_COLUMNS_BROKEN; goto exit; } loader->id_offset = i; } else if (name_equal(col_name, col_name_size, GRN_COLUMN_NAME_KEY)) { grn_obj_unlink(ctx, col); if (loader->id_offset != -1 || loader->key_offset != -1) { /* _id and _key must not appear more than once. */ if (loader->id_offset != -1) { ERR(GRN_INVALID_ARGUMENT, "duplicated id and key columns: <%s> at %d and <%s> at %d", GRN_COLUMN_NAME_KEY, i, GRN_COLUMN_NAME_ID, loader->id_offset); } else { ERR(GRN_INVALID_ARGUMENT, "duplicated id and key columns: <%s> at %d and <%s> at %d", GRN_COLUMN_NAME_KEY, i, GRN_COLUMN_NAME_KEY, loader->key_offset); } grn_loader_save_error(ctx, loader); loader->columns_status = GRN_LOADER_COLUMNS_BROKEN; goto exit; } loader->key_offset = i; } else { GRN_PTR_PUT(ctx, &loader->columns, col); } value++; } switch (loader->table->header.type) { case GRN_TABLE_HASH_KEY : case GRN_TABLE_PAT_KEY : case GRN_TABLE_DAT_KEY : if (loader->id_offset == -1 && loader->key_offset == -1) { ERR(GRN_INVALID_ARGUMENT, "missing id or key column"); grn_loader_save_error(ctx, loader); loader->columns_status = GRN_LOADER_COLUMNS_BROKEN; goto exit; } break; } loader->columns_status = GRN_LOADER_COLUMNS_SET; goto exit; } is_record_load = GRN_TRUE; /* Target columns and _id or _key are already specified. */ if (!nvalues) { /* * Accept empty arrays because a dump command may output a load command * which contains empty arrays for a table with deleted records. */ id = grn_table_add(ctx, loader->table, NULL, 0, NULL); } else { uint32_t expected_nvalues = ncols; if (loader->id_offset != -1 || loader->key_offset != -1) { expected_nvalues++; } if (nvalues != expected_nvalues) { ERR(GRN_INVALID_ARGUMENT, "unexpected #values: expected:%u, actual:%u", expected_nvalues, nvalues); grn_loader_save_error(ctx, loader); goto exit; } if (loader->id_offset != -1) { id_value = value + loader->id_offset; id = parse_id_value(ctx, id_value); if (grn_table_at(ctx, loader->table, id) == GRN_ID_NIL) { id = grn_table_add(ctx, loader->table, NULL, 0, NULL); } } else if (loader->key_offset != -1) { key_value = value + loader->key_offset; id = loader_add(ctx, key_value); } else { id = grn_table_add(ctx, loader->table, NULL, 0, NULL); } } if (id == GRN_ID_NIL) { /* Target record is not available. */ goto exit; } for (i = 0; i < nvalues; i++, value = values_next(ctx, value)) { if (i == loader->id_offset || i == loader->key_offset) { /* Skip _id and _key, because it's already used to get id. */ continue; } col = *cols; if (value->header.domain == GRN_JSON_LOAD_OPEN_BRACKET) { set_vector(ctx, col, id, value); } else if (value->header.domain == GRN_JSON_LOAD_OPEN_BRACE) { set_weight_vector(ctx, col, id, value); } else { grn_obj_set_value(ctx, col, id, value, GRN_OBJ_SET); } if (ctx->rc != GRN_SUCCESS) { char column_name[GRN_TABLE_MAX_KEY_SIZE]; unsigned int column_name_size; grn_loader_save_error(ctx, loader); column_name_size = grn_obj_name(ctx, col, column_name, GRN_TABLE_MAX_KEY_SIZE); report_set_column_value_failure(ctx, key_value, column_name, column_name_size, value); loader->n_column_errors++; ERRCLR(ctx); } cols++; } if (loader->each) { grn_obj *v = grn_expr_get_var_by_offset(ctx, loader->each, 0); GRN_RECORD_SET(ctx, v, id); grn_expr_exec(ctx, loader->each, 0); } loader->nrecords++; exit: if (is_record_load) { if (ctx->rc != GRN_SUCCESS) { loader->n_record_errors++; } if (loader->output_ids) { GRN_UINT32_PUT(ctx, &(loader->ids), id); } if (loader->output_errors) { GRN_INT32_PUT(ctx, &(loader->return_codes), ctx->rc); grn_vector_add_element(ctx, &(loader->error_messages), ctx->errbuf, strlen(ctx->errbuf), 0, GRN_DB_TEXT); } } loader->values_size = begin; ERRCLR(ctx); }
static void brace_close(grn_ctx *ctx, grn_loader *loader) { grn_id id = GRN_ID_NIL; grn_obj *value, *value_begin, *value_end; grn_obj *id_value = NULL, *key_value = NULL; uint32_t begin; GRN_UINT32_POP(&loader->level, begin); value_begin = (grn_obj *)GRN_TEXT_VALUE(&loader->values) + begin; value_end = (grn_obj *)GRN_TEXT_VALUE(&loader->values) + loader->values_size; GRN_ASSERT(value->header.domain == GRN_JSON_LOAD_OPEN_BRACE); GRN_UINT32_SET(ctx, value_begin, loader->values_size - begin - 1); value_begin++; if (GRN_BULK_VSIZE(&loader->level) > sizeof(uint32_t) * loader->emit_level) { return; } if (!loader->table) { goto exit; } /* Scan values to find _id or _key. */ for (value = value_begin; value + 1 < value_end; value = values_next(ctx, value)) { const char *name = GRN_TEXT_VALUE(value); unsigned int name_size = GRN_TEXT_LEN(value); if (value->header.domain != GRN_DB_TEXT) { grn_obj buffer; GRN_TEXT_INIT(&buffer, 0); grn_inspect(ctx, &buffer, value); GRN_LOG(ctx, GRN_LOG_ERROR, "column name must be string: <%.*s>", (int)GRN_TEXT_LEN(&buffer), GRN_TEXT_VALUE(&buffer)); GRN_OBJ_FIN(ctx, &buffer); goto exit; } value++; if (name_equal(name, name_size, GRN_COLUMN_NAME_ID)) { if (id_value || key_value) { if (loader->table->header.type == GRN_TABLE_NO_KEY) { GRN_LOG(ctx, GRN_LOG_ERROR, "duplicated '_id' column"); goto exit; } else { GRN_LOG(ctx, GRN_LOG_ERROR, "duplicated key columns: %s and %s", id_value ? GRN_COLUMN_NAME_ID : GRN_COLUMN_NAME_KEY, GRN_COLUMN_NAME_ID); goto exit; } } id_value = value; } else if (name_equal(name, name_size, GRN_COLUMN_NAME_KEY)) { if (id_value || key_value) { GRN_LOG(ctx, GRN_LOG_ERROR, "duplicated key columns: %s and %s", id_value ? GRN_COLUMN_NAME_ID : GRN_COLUMN_NAME_KEY, GRN_COLUMN_NAME_KEY); goto exit; } key_value = value; } } switch (loader->table->header.type) { case GRN_TABLE_HASH_KEY : case GRN_TABLE_PAT_KEY : case GRN_TABLE_DAT_KEY : /* The target table requires _id or _key. */ if (!id_value && !key_value) { GRN_LOG(ctx, GRN_LOG_ERROR, "neither _key nor _id is assigned"); goto exit; } break; default : /* The target table does not have _key. */ if (key_value) { GRN_LOG(ctx, GRN_LOG_ERROR, "nonexistent key value"); goto exit; } break; } if (id_value) { id = parse_id_value(ctx, id_value); if (grn_table_at(ctx, loader->table, id) == GRN_ID_NIL) { if (ctx->rc == GRN_SUCCESS) { id = grn_table_add(ctx, loader->table, NULL, 0, NULL); } } } else if (key_value) { id = loader_add(ctx, key_value); } else { id = grn_table_add(ctx, loader->table, NULL, 0, NULL); } if (id == GRN_ID_NIL) { /* Target record is not available. */ goto exit; } for (value = value_begin; value + 1 < value_end; value = values_next(ctx, value)) { grn_obj *col; const char *name = GRN_TEXT_VALUE(value); unsigned int name_size = GRN_TEXT_LEN(value); value++; if (value == id_value || value == key_value) { /* Skip _id and _key, because it's already used to get id. */ continue; } col = grn_obj_column(ctx, loader->table, name, name_size); if (!col) { GRN_LOG(ctx, GRN_LOG_ERROR, "invalid column('%.*s')", (int)name_size, name); /* Automatic column creation is disabled. */ /* if (value->header.domain == GRN_JSON_LOAD_OPEN_BRACKET) { grn_obj *v = value + 1; col = grn_column_create(ctx, loader->table, name, name_size, NULL, GRN_OBJ_PERSISTENT|GRN_OBJ_COLUMN_VECTOR, grn_ctx_at(ctx, v->header.domain)); } else { col = grn_column_create(ctx, loader->table, name, name_size, NULL, GRN_OBJ_PERSISTENT, grn_ctx_at(ctx, value->header.domain)); } */ } else { if (value->header.domain == GRN_JSON_LOAD_OPEN_BRACKET) { set_vector(ctx, col, id, value); } else if (value->header.domain == GRN_JSON_LOAD_OPEN_BRACE) { set_weight_vector(ctx, col, id, value); } else { grn_obj_set_value(ctx, col, id, value, GRN_OBJ_SET); } if (ctx->rc != GRN_SUCCESS) { grn_loader_save_error(ctx, loader); report_set_column_value_failure(ctx, key_value, name, name_size, value); loader->n_column_errors++; ERRCLR(ctx); } grn_obj_unlink(ctx, col); } } if (loader->each) { value = grn_expr_get_var_by_offset(ctx, loader->each, 0); GRN_RECORD_SET(ctx, value, id); grn_expr_exec(ctx, loader->each, 0); } loader->nrecords++; exit: if (ctx->rc != GRN_SUCCESS) { loader->n_record_errors++; } if (loader->output_ids) { GRN_UINT32_PUT(ctx, &(loader->ids), id); } if (loader->output_errors) { GRN_INT32_PUT(ctx, &(loader->return_codes), ctx->rc); grn_vector_add_element(ctx, &(loader->error_messages), ctx->errbuf, strlen(ctx->errbuf), 0, GRN_DB_TEXT); } loader->values_size = begin; ERRCLR(ctx); }
void grn_output_obj(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, grn_obj *obj, grn_obj_format *format) { grn_obj buf; GRN_TEXT_INIT(&buf, 0); switch (obj->header.type) { case GRN_BULK : switch (obj->header.domain) { case GRN_DB_VOID : grn_output_void(ctx, outbuf, output_type, GRN_BULK_HEAD(obj), GRN_BULK_VSIZE(obj)); break; case GRN_DB_SHORT_TEXT : case GRN_DB_TEXT : case GRN_DB_LONG_TEXT : grn_output_str(ctx, outbuf, output_type, GRN_BULK_HEAD(obj), GRN_BULK_VSIZE(obj)); break; case GRN_DB_BOOL : grn_output_bool(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_UINT8_VALUE(obj) : 0); break; case GRN_DB_INT8 : grn_output_int32(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_INT8_VALUE(obj) : 0); break; case GRN_DB_UINT8 : grn_output_int32(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_UINT8_VALUE(obj) : 0); break; case GRN_DB_INT16 : grn_output_int32(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_INT16_VALUE(obj) : 0); break; case GRN_DB_UINT16 : grn_output_int32(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_UINT16_VALUE(obj) : 0); break; case GRN_DB_INT32 : grn_output_int32(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_INT32_VALUE(obj) : 0); break; case GRN_DB_UINT32 : grn_output_int64(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_UINT32_VALUE(obj) : 0); break; case GRN_DB_INT64 : grn_output_int64(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_INT64_VALUE(obj) : 0); break; case GRN_DB_UINT64 : grn_output_uint64(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_UINT64_VALUE(obj) : 0); break; case GRN_DB_FLOAT : grn_output_float(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_FLOAT_VALUE(obj) : 0); break; case GRN_DB_TIME : grn_output_time(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_INT64_VALUE(obj) : 0); break; case GRN_DB_TOKYO_GEO_POINT : case GRN_DB_WGS84_GEO_POINT : grn_output_geo_point(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? (grn_geo_point *)GRN_BULK_HEAD(obj) : NULL); break; default : if (format) { int j; int ncolumns = GRN_BULK_VSIZE(&format->columns)/sizeof(grn_obj *); grn_obj **columns = (grn_obj **)GRN_BULK_HEAD(&format->columns); if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) { grn_output_array_open(ctx, outbuf, output_type, "COLUMNS", ncolumns); for (j = 0; j < ncolumns; j++) { grn_id range_id; grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2); GRN_BULK_REWIND(&buf); grn_column_name_(ctx, columns[j], &buf); grn_output_obj(ctx, outbuf, output_type, &buf, NULL); /* column range */ range_id = grn_obj_get_range(ctx, columns[j]); if (range_id == GRN_ID_NIL) { GRN_TEXT_PUTS(ctx, outbuf, "null"); } else { int name_len; grn_obj *range_obj; char name_buf[GRN_TABLE_MAX_KEY_SIZE]; range_obj = grn_ctx_at(ctx, range_id); name_len = grn_obj_name(ctx, range_obj, name_buf, GRN_TABLE_MAX_KEY_SIZE); GRN_BULK_REWIND(&buf); GRN_TEXT_PUT(ctx, &buf, name_buf, name_len); grn_output_obj(ctx, outbuf, output_type, &buf, NULL); } grn_output_array_close(ctx, outbuf, output_type); } grn_output_array_close(ctx, outbuf, output_type); } grn_output_array_open(ctx, outbuf, output_type, "HIT", ncolumns); for (j = 0; j < ncolumns; j++) { grn_text_atoj_o(ctx, outbuf, output_type, columns[j], obj); } grn_output_array_close(ctx, outbuf, output_type); } else { grn_obj *table = grn_ctx_at(ctx, obj->header.domain); grn_id id = *((grn_id *)GRN_BULK_HEAD(obj)); if (table && table->header.type != GRN_TABLE_NO_KEY) { grn_obj *accessor = grn_obj_column(ctx, table, "_key", 4); if (accessor) { grn_obj_get_value(ctx, accessor, id, &buf); grn_obj_unlink(ctx, accessor); } grn_output_obj(ctx, outbuf, output_type, &buf, format); } else { grn_output_int64(ctx, outbuf, output_type, id); } } break; } break; case GRN_UVECTOR : if (format) { int i, j; grn_id *v = (grn_id *)GRN_BULK_HEAD(obj), *ve = (grn_id *)GRN_BULK_CURR(obj); int ncolumns = GRN_BULK_VSIZE(&format->columns) / sizeof(grn_obj *); grn_obj **columns = (grn_obj **)GRN_BULK_HEAD(&format->columns); grn_output_array_open(ctx, outbuf, output_type, "RESULTSET", -1); grn_output_array_open(ctx, outbuf, output_type, "NHITS", 1); grn_text_itoa(ctx, outbuf, ve - v); grn_output_array_close(ctx, outbuf, output_type); if (v < ve) { if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) { grn_output_array_open(ctx, outbuf, output_type, "COLUMNS", -1); for (j = 0; j < ncolumns; j++) { grn_id range_id; grn_output_array_open(ctx, outbuf, output_type, "COLUMN", -1); GRN_BULK_REWIND(&buf); grn_column_name_(ctx, columns[j], &buf); grn_output_obj(ctx, outbuf, output_type, &buf, NULL); /* column range */ range_id = grn_obj_get_range(ctx, columns[j]); if (range_id == GRN_ID_NIL) { GRN_TEXT_PUTS(ctx, outbuf, "null"); } else { int name_len; grn_obj *range_obj; char name_buf[GRN_TABLE_MAX_KEY_SIZE]; range_obj = grn_ctx_at(ctx, range_id); name_len = grn_obj_name(ctx, range_obj, name_buf, GRN_TABLE_MAX_KEY_SIZE); GRN_BULK_REWIND(&buf); GRN_TEXT_PUT(ctx, &buf, name_buf, name_len); grn_output_obj(ctx, outbuf, output_type, &buf, NULL); } grn_output_array_close(ctx, outbuf, output_type); } grn_output_array_close(ctx, outbuf, output_type); } for (i = 0;; i++) { grn_output_array_open(ctx, outbuf, output_type, "HITS", -1); for (j = 0; j < ncolumns; j++) { GRN_BULK_REWIND(&buf); grn_obj_get_value(ctx, columns[j], *v, &buf); grn_output_obj(ctx, outbuf, output_type, &buf, NULL); } grn_output_array_close(ctx, outbuf, output_type); v++; if (v < ve) { } else { break; } } } grn_output_array_close(ctx, outbuf, output_type); } else { grn_obj *range = grn_ctx_at(ctx, obj->header.domain); if (range && range->header.type == GRN_TYPE) { int value_size = ((struct _grn_type *)range)->obj.range; char *v = (char *)GRN_BULK_HEAD(obj), *ve = (char *)GRN_BULK_CURR(obj); grn_output_array_open(ctx, outbuf, output_type, "VECTOR", -1); if (v < ve) { for (;;) { grn_obj value; GRN_OBJ_INIT(&value, GRN_BULK, 0, obj->header.domain); grn_bulk_write_from(ctx, &value, v, 0, value_size); grn_output_obj(ctx, outbuf, output_type, &value, NULL); v += value_size; if (v < ve) { } else { break; } } } grn_output_array_close(ctx, outbuf, output_type); } else { grn_id *v = (grn_id *)GRN_BULK_HEAD(obj), *ve = (grn_id *)GRN_BULK_CURR(obj); grn_output_array_open(ctx, outbuf, output_type, "VECTOR", ve - v); if (v < ve) { grn_obj key; GRN_OBJ_INIT(&key, GRN_BULK, 0, range->header.domain); for (;;) { if (range->header.type != GRN_TABLE_NO_KEY) { grn_table_get_key2(ctx, range, *v, &key); grn_output_obj(ctx, outbuf, output_type, &key, NULL); GRN_BULK_REWIND(&key); } else { grn_obj id; GRN_UINT32_INIT(&id, 0); GRN_UINT32_SET(ctx, &id, *v); grn_output_obj(ctx, outbuf, output_type, &id, NULL); GRN_OBJ_FIN(ctx, &id); } v++; if (v < ve) { } else { break; } } GRN_OBJ_FIN(ctx, &key); } grn_output_array_close(ctx, outbuf, output_type); } } break; case GRN_VECTOR : if (obj->header.domain == GRN_DB_VOID) { ERR(GRN_INVALID_ARGUMENT, "invalid obj->header.domain"); } if (format) { ERR(GRN_FUNCTION_NOT_IMPLEMENTED, "cannot print GRN_VECTOR using grn_obj_format"); } else { unsigned int i, n; grn_obj value; GRN_VOID_INIT(&value); n = grn_vector_size(ctx, obj); grn_output_array_open(ctx, outbuf, output_type, "VECTOR", -1); for (i = 0; i < n; i++) { const char *_value; unsigned int weight, length; grn_id domain; length = grn_vector_get_element(ctx, obj, i, &_value, &weight, &domain); if (domain != GRN_DB_VOID) { grn_obj_reinit(ctx, &value, domain, 0); } else { grn_obj_reinit(ctx, &value, obj->header.domain, 0); } grn_bulk_write(ctx, &value, _value, length); grn_output_obj(ctx, outbuf, output_type, &value, NULL); } grn_output_array_close(ctx, outbuf, output_type); GRN_OBJ_FIN(ctx, &value); } break; case GRN_PVECTOR : if (format) { ERR(GRN_FUNCTION_NOT_IMPLEMENTED, "cannot print GRN_PVECTOR using grn_obj_format"); } else { unsigned int i, n; grn_output_array_open(ctx, outbuf, output_type, "VECTOR", -1); n = GRN_BULK_VSIZE(obj) / sizeof(grn_obj *); for (i = 0; i < n; i++) { grn_obj *value; value = GRN_PTR_VALUE_AT(obj, i); grn_output_obj(ctx, outbuf, output_type, value, NULL); } grn_output_array_close(ctx, outbuf, output_type); } break; case GRN_TABLE_HASH_KEY : case GRN_TABLE_PAT_KEY : case GRN_TABLE_NO_KEY : case GRN_TABLE_VIEW : if (format) { int i, j; int ncolumns = GRN_BULK_VSIZE(&format->columns)/sizeof(grn_obj *); grn_obj **columns = (grn_obj **)GRN_BULK_HEAD(&format->columns); grn_table_cursor *tc = grn_table_cursor_open(ctx, obj, NULL, 0, NULL, 0, format->offset, format->limit, GRN_CURSOR_ASCENDING); int resultset_size = -1; if (!tc) { ERRCLR(ctx); } #ifdef HAVE_MESSAGE_PACK resultset_size = 1; /* [NHITS, (COLUMNS), (HITS)] */ if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) { resultset_size++; } resultset_size += format->limit; #endif grn_output_array_open(ctx, outbuf, output_type, "RESULTSET", resultset_size); grn_output_array_open(ctx, outbuf, output_type, "NHITS", 1); if (output_type == GRN_CONTENT_XML) { grn_text_itoa(ctx, outbuf, format->nhits); } else { grn_output_int32(ctx, outbuf, output_type, format->nhits); } grn_output_array_close(ctx, outbuf, output_type); if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) { grn_output_array_open(ctx, outbuf, output_type, "COLUMNS", ncolumns); for (j = 0; j < ncolumns; j++) { grn_id range_id; grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2); GRN_BULK_REWIND(&buf); grn_column_name_(ctx, columns[j], &buf); grn_output_obj(ctx, outbuf, output_type, &buf, NULL); /* column range */ range_id = grn_obj_get_range(ctx, columns[j]); if (range_id == GRN_ID_NIL) { GRN_TEXT_PUTS(ctx, outbuf, "null"); } else { int name_len; grn_obj *range_obj; char name_buf[GRN_TABLE_MAX_KEY_SIZE]; range_obj = grn_ctx_at(ctx, range_id); name_len = grn_obj_name(ctx, range_obj, name_buf, GRN_TABLE_MAX_KEY_SIZE); GRN_BULK_REWIND(&buf); GRN_TEXT_PUT(ctx, &buf, name_buf, name_len); grn_output_obj(ctx, outbuf, output_type, &buf, NULL); } grn_output_array_close(ctx, outbuf, output_type); } grn_output_array_close(ctx, outbuf, output_type); } if (tc) { grn_obj id; GRN_TEXT_INIT(&id, 0); for (i = 0; !grn_table_cursor_next_o(ctx, tc, &id); i++) { grn_output_array_open(ctx, outbuf, output_type, "HIT", ncolumns); for (j = 0; j < ncolumns; j++) { grn_text_atoj_o(ctx, outbuf, output_type, columns[j], &id); } grn_output_array_close(ctx, outbuf, output_type); } GRN_OBJ_FIN(ctx, &id); grn_table_cursor_close(ctx, tc); } grn_output_array_close(ctx, outbuf, output_type); } else { int i; grn_obj *column = grn_obj_column(ctx, obj, "_key", 4); grn_table_cursor *tc = grn_table_cursor_open(ctx, obj, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_ASCENDING); grn_output_array_open(ctx, outbuf, output_type, "HIT", -1); if (tc) { grn_obj id; GRN_TEXT_INIT(&id, 0); for (i = 0; !grn_table_cursor_next_o(ctx, tc, &id); i++) { /* todo: grn_text_atoj_o(ctx, outbuf, output_type, column, &id); */ GRN_BULK_REWIND(&buf); grn_obj_get_value_o(ctx, column, &id, &buf); grn_text_esc(ctx, outbuf, GRN_BULK_HEAD(&buf), GRN_BULK_VSIZE(&buf)); } GRN_OBJ_FIN(ctx, &id); grn_table_cursor_close(ctx, tc); } grn_output_array_close(ctx, outbuf, output_type); grn_obj_unlink(ctx, column); } break; } 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; }
static grn_obj * command_tag_synonym_add(grn_ctx *ctx, GNUC_UNUSED int nargs, GNUC_UNUSED grn_obj **args, grn_user_data *user_data) { grn_obj *var, *proc, *table, *column; unsigned int nhooks = 0; char *table_name = NULL; unsigned int table_len = 0; char *column_name = NULL; unsigned int column_len = 0; var = grn_plugin_proc_get_var(ctx, user_data, "table", -1); if (GRN_TEXT_LEN(var) != 0) { table_name = GRN_TEXT_VALUE(var); table_len = GRN_TEXT_LEN(var); } var = grn_plugin_proc_get_var(ctx, user_data, "column", -1); if (GRN_TEXT_LEN(var) != 0) { column_name = GRN_TEXT_VALUE(var); column_len = GRN_TEXT_LEN(var); } table = grn_ctx_get(ctx, table_name, table_len); column = grn_obj_column(ctx, table, column_name, column_len); { grn_obj *range; grn_obj *col; grn_id range_id; range_id = grn_obj_get_range(ctx, column); range = grn_ctx_at(ctx, range_id); if (!range) { GRN_PLUGIN_LOG(ctx, GRN_LOG_ERROR, "[tag-synonym] " "hooked column must be reference type"); return NULL; } col = grn_obj_column(ctx, range, SYNONYM_COLUMN_NAME, SYNONYM_COLUMN_NAME_LEN); if (!col) { GRN_PLUGIN_LOG(ctx, GRN_LOG_ERROR, "[tag-synonym] " "couldn't open synonym column"); return NULL; } } proc = grn_ctx_get(ctx, "tag_synonym", -1); { grn_obj data; default_set_value_hook_data hook_data = { grn_obj_id(ctx, proc), 0 }; GRN_TEXT_INIT(&data, GRN_OBJ_DO_SHALLOW_COPY); GRN_TEXT_SET_REF(&data, &hook_data, sizeof(hook_data)); grn_obj_add_hook(ctx, column, GRN_HOOK_SET, 0, proc, &data); grn_obj_unlink(ctx, &data); } //grn_ctx_output_array_open(ctx, "RESULT", 1); nhooks = grn_obj_get_nhooks(ctx, column, GRN_HOOK_SET); grn_ctx_output_int32(ctx, nhooks); //grn_ctx_output_array_close(ctx); return NULL; }
static mrn_bool mrn_snippet_html_prepare(mrn_snippet_html_info *info, UDF_ARGS *args, char *message, grn_obj **snippet) { MRN_DBUG_ENTER_FUNCTION(); grn_ctx *ctx = info->ctx; int flags = GRN_SNIP_SKIP_LEADING_SPACES; unsigned int width = 200; unsigned int max_n_results = 3; const char *open_tag = "<span class=\"keyword\">"; const char *close_tag = "</span>"; grn_snip_mapping *mapping = GRN_SNIP_MAPPING_HTML_ESCAPE; grn_obj *expr = NULL; *snippet = NULL; mrn::encoding::set_raw(ctx, system_charset_info); if (!(system_charset_info->state & (MY_CS_BINSORT | MY_CS_CSSORT))) { flags |= GRN_SNIP_NORMALIZE; } *snippet = grn_snip_open(ctx, flags, width, max_n_results, open_tag, strlen(open_tag), close_tag, strlen(close_tag), mapping); if (ctx->rc != GRN_SUCCESS) { if (message) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_snippet_html(): failed to open grn_snip: <%s>", ctx->errbuf); } goto error; } if (info->query_mode.used) { if (!info->query_mode.table) { grn_obj *short_text; short_text = grn_ctx_at(info->ctx, GRN_DB_SHORT_TEXT); info->query_mode.table = grn_table_create(info->ctx, NULL, 0, NULL, GRN_TABLE_HASH_KEY, short_text, NULL); } if (!info->query_mode.default_column) { info->query_mode.default_column = grn_obj_column(info->ctx, info->query_mode.table, GRN_COLUMN_NAME_KEY, GRN_COLUMN_NAME_KEY_LEN); } grn_obj *record = NULL; GRN_EXPR_CREATE_FOR_QUERY(info->ctx, info->query_mode.table, expr, record); if (!expr) { if (message) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_snippet_html(): " "failed to create expression: <%s>", ctx->errbuf); } goto error; } mrn::QueryParser query_parser(info->ctx, current_thd, expr, info->query_mode.default_column, 0, NULL); grn_rc rc = query_parser.parse(args->args[1], args->lengths[1]); if (rc != GRN_SUCCESS) { if (message) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_snippet_html(): " "failed to parse query: <%s>", ctx->errbuf); } goto error; } rc = grn_expr_snip_add_conditions(info->ctx, expr, *snippet, 0, NULL, NULL, NULL, NULL); if (rc != GRN_SUCCESS) { if (message) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_snippet_html(): " "failed to add conditions: <%s>", ctx->errbuf); } goto error; } } else { unsigned int i; for (i = 1; i < args->arg_count; ++i) { if (!args->args[i]) { continue; } grn_rc rc = grn_snip_add_cond(ctx, *snippet, args->args[i], args->lengths[i], NULL, 0, NULL, 0); if (rc != GRN_SUCCESS) { if (message) { snprintf(message, MYSQL_ERRMSG_SIZE, "mroonga_snippet_html(): " "failed to add a condition to grn_snip: <%s>", ctx->errbuf); } goto error; } } } DBUG_RETURN(false); error: if (expr) { grn_obj_close(ctx, expr); } if (*snippet) { grn_obj_close(ctx, *snippet); } DBUG_RETURN(true); }
static grn_id resolve_source_id (grn_ctx *context, grn_obj *column, grn_id range_id, VALUE rb_source) { grn_id source_id; if (CBOOL2RVAL(rb_obj_is_kind_of(rb_source, rb_cInteger))) { source_id = NUM2UINT(rb_source); } else { grn_obj *source; grn_bool need_source_unlink = GRN_FALSE; if (TYPE(rb_source) == T_STRING) { grn_obj *table; const char *name; const char *dot_point; int length; table = grn_ctx_at(context, grn_obj_get_range(context, column)); name = StringValueCStr(rb_source); length = RSTRING_LEN(rb_source); dot_point = strstr(name, "."); if (dot_point) { char table_name[4096]; int table_name_length; table_name_length = grn_obj_name(context, table, table_name, sizeof(table_name)); table_name[table_name_length] = '\0'; if (strncmp(table_name, name, dot_point - name) != 0) { rb_raise(rb_eArgError, "wrong table's column: <%s>: " "expected table: <%s>", name, table_name); } length -= (dot_point - name) + 1; name = dot_point + 1; } source = grn_obj_column(context, table, name, length); need_source_unlink = GRN_TRUE; } else { source = RVAL2GRNOBJECT(rb_source, &context); } rb_grn_context_check(context, rb_source); if (source->header.type == GRN_ACCESSOR) { char name[256]; int length; length = grn_column_name(context, source, name, sizeof(name)); name[length] = '\0'; if (strcmp(name, "_key") != 0) { rb_raise(rb_eArgError, "source accessor must be '_key': <%s>", name); } source_id = range_id; } else { source_id = grn_obj_id(context, source); } if (need_source_unlink) { grn_obj_unlink(context, source); } } return source_id; }
static grn_obj * command_table_tokenize(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) { grn_obj *table_name; grn_obj *string; grn_obj *flag_names; grn_obj *mode_name; grn_obj *index_column_name; table_name = grn_plugin_proc_get_var(ctx, user_data, "table", -1); string = grn_plugin_proc_get_var(ctx, user_data, "string", -1); flag_names = grn_plugin_proc_get_var(ctx, user_data, "flags", -1); mode_name = grn_plugin_proc_get_var(ctx, user_data, "mode", -1); index_column_name = grn_plugin_proc_get_var(ctx, user_data, "index_column", -1); if (GRN_TEXT_LEN(table_name) == 0) { GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "[table_tokenize] table name is missing"); return NULL; } if (GRN_TEXT_LEN(string) == 0) { GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "[table_tokenize] string is missing"); return NULL; } { unsigned int flags; grn_obj *lexicon; grn_obj *index_column = NULL; flags = parse_tokenize_flags(ctx, flag_names); if (ctx->rc != GRN_SUCCESS) { return NULL; } lexicon = grn_ctx_get(ctx, GRN_TEXT_VALUE(table_name), GRN_TEXT_LEN(table_name)); if (!lexicon) { return NULL; } #define MODE_NAME_EQUAL(name)\ (GRN_TEXT_LEN(mode_name) == strlen(name) &&\ memcmp(GRN_TEXT_VALUE(mode_name), name, strlen(name)) == 0) if (GRN_TEXT_LEN(index_column_name) > 0) { index_column = grn_obj_column(ctx, lexicon, GRN_TEXT_VALUE(index_column_name), GRN_TEXT_LEN(index_column_name)); if (!index_column) { GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "[table_tokenize] nonexistent index column: <%.*s>", (int)GRN_TEXT_LEN(index_column_name), GRN_TEXT_VALUE(index_column_name)); goto exit; } if (index_column->header.type != GRN_COLUMN_INDEX) { GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "[table_tokenize] index column must be COLUMN_INDEX: <%.*s>", (int)GRN_TEXT_LEN(index_column_name), GRN_TEXT_VALUE(index_column_name)); goto exit; } } { grn_obj tokens; GRN_VALUE_FIX_SIZE_INIT(&tokens, GRN_OBJ_VECTOR, GRN_ID_NIL); if (GRN_TEXT_LEN(mode_name) == 0 || MODE_NAME_EQUAL("GET")) { tokenize(ctx, lexicon, string, GRN_TOKEN_GET, flags, &tokens); output_tokens(ctx, &tokens, lexicon, index_column); } else if (MODE_NAME_EQUAL("ADD")) { tokenize(ctx, lexicon, string, GRN_TOKEN_ADD, flags, &tokens); output_tokens(ctx, &tokens, lexicon, index_column); } else { GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "[table_tokenize] invalid mode: <%.*s>", (int)GRN_TEXT_LEN(mode_name), GRN_TEXT_VALUE(mode_name)); } GRN_OBJ_FIN(ctx, &tokens); } #undef MODE_NAME_EQUAL exit: grn_obj_unlink(ctx, lexicon); if (index_column) { grn_obj_unlink(ctx, index_column); } } return NULL; }
static grn_obj * command_table_tokenize(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) { grn_raw_string table_raw; grn_raw_string string_raw; grn_raw_string flags_raw; grn_raw_string mode_raw; grn_raw_string index_column_raw; #define GET_VALUE(name) \ name ## _raw.value = \ grn_plugin_proc_get_var_string(ctx, \ user_data, \ #name, \ strlen(#name), \ &(name ## _raw.length)) GET_VALUE(table); GET_VALUE(string); GET_VALUE(flags); GET_VALUE(mode); GET_VALUE(index_column); #undef GET_VALUE if (table_raw.length == 0) { GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "[table_tokenize] table name is missing"); return NULL; } if (string_raw.length == 0) { GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "[table_tokenize] string is missing"); return NULL; } { unsigned int flags; grn_obj *lexicon; grn_obj *index_column = NULL; flags = parse_tokenize_flags(ctx, &flags_raw); if (ctx->rc != GRN_SUCCESS) { return NULL; } lexicon = grn_ctx_get(ctx, table_raw.value, table_raw.length); if (!lexicon) { GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "[table_tokenize] nonexistent lexicon: <%.*s>", (int)table_raw.length, table_raw.value); return NULL; } if (index_column_raw.length > 0) { index_column = grn_obj_column(ctx, lexicon, index_column_raw.value, index_column_raw.length); if (!index_column) { GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "[table_tokenize] nonexistent index column: <%.*s>", (int)index_column_raw.length, index_column_raw.value); goto exit; } if (index_column->header.type != GRN_COLUMN_INDEX) { GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "[table_tokenize] " "index column must be COLUMN_INDEX: <%.*s>", (int)index_column_raw.length, index_column_raw.value); goto exit; } } { grn_obj tokens; GRN_VALUE_FIX_SIZE_INIT(&tokens, GRN_OBJ_VECTOR, GRN_ID_NIL); if (mode_raw.length == 0 || GRN_RAW_STRING_EQUAL_CSTRING(mode_raw, "GET")) { tokenize(ctx, lexicon, &string_raw, GRN_TOKEN_GET, flags, &tokens); output_tokens(ctx, &tokens, lexicon, index_column); } else if (GRN_RAW_STRING_EQUAL_CSTRING(mode_raw, "ADD")) { tokenize(ctx, lexicon, &string_raw, GRN_TOKEN_ADD, flags, &tokens); output_tokens(ctx, &tokens, lexicon, index_column); } else { GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "[table_tokenize] invalid mode: <%.*s>", (int)mode_raw.length, mode_raw.value); } GRN_OBJ_FIN(ctx, &tokens); } #undef MODE_NAME_EQUAL exit: grn_obj_unlink(ctx, lexicon); if (index_column) { grn_obj_unlink(ctx, index_column); } } return NULL; }