static mrb_value object_find_index(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; grn_obj *object; mrb_value mrb_operator; grn_obj *index; int n_indexes; int section_id; mrb_get_args(mrb, "o", &mrb_operator); object = DATA_PTR(self); n_indexes = grn_column_index(ctx, object, mrb_fixnum(mrb_operator), &index, 1, §ion_id); if (n_indexes == 0) { return mrb_nil_value(); } else { grn_mrb_data *data; struct RClass *klass; mrb_value args[2]; data = &(ctx->impl->mrb); klass = mrb_class_get_under(mrb, data->module, "IndexInfo"); args[0] = grn_mrb_value_from_grn_obj(mrb, index); args[1] = mrb_fixnum_value(section_id); return mrb_obj_new(mrb, klass, 2, args); } }
/* * Document-method: indexes * * call-seq: * column.indexes(operator=Groonga::Operator::MATCH) -> [index_column, ...] * * _operation_ を実行できる _column_ のインデックスを返す。 * * @since 1.0.9 */ static VALUE rb_grn_column_get_indexes (int argc, VALUE *argv, VALUE self) { grn_ctx *context; grn_obj *column; grn_obj **indexes = NULL; int i, n_indexes; grn_operator operator = GRN_OP_MATCH; VALUE rb_operator, rb_indexes; rb_scan_args(argc, argv, "01", &rb_operator); rb_grn_column_deconstruct(SELF(self), &column, &context, NULL, NULL, NULL, NULL, NULL); if (!NIL_P(rb_operator)) { operator = RVAL2GRNOPERATOR(rb_operator); } rb_indexes = rb_ary_new(); n_indexes = grn_column_index(context, column, operator, NULL, 0, NULL); if (n_indexes == 0) return rb_indexes; indexes = xmalloc(sizeof(grn_obj *) * n_indexes); n_indexes = grn_column_index(context, column, operator, indexes, n_indexes, NULL); for (i = 0; i < n_indexes; i++) { VALUE rb_index; rb_index = GRNOBJECT2RVAL(Qnil, context, indexes[i], GRN_FALSE); rb_ary_push(rb_indexes, rb_index); grn_obj_unlink(context, indexes[i]); } xfree(indexes); return rb_indexes; }
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 grn_rc selector_fuzzy_search(grn_ctx *ctx, grn_obj *table, grn_obj *index, int nargs, grn_obj **args, grn_obj *res, grn_operator op) { grn_rc rc = GRN_SUCCESS; grn_obj *target = NULL; grn_obj *obj; grn_obj *query; uint32_t max_distance = 1; uint32_t prefix_length = 0; uint32_t prefix_match_size = 0; uint32_t max_expansion = 0; int flags = 0; grn_bool use_sequential_search = GRN_FALSE; if ((nargs - 1) < 2) { GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "fuzzy_search(): wrong number of arguments (%d ...)", nargs - 1); rc = ctx->rc; goto exit; } obj = args[1]; query = args[2]; if (nargs == 4) { grn_obj *options = args[3]; grn_hash_cursor *cursor; void *key; grn_obj *value; int key_size; if (options->header.type != GRN_TABLE_HASH_KEY) { GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "fuzzy_search(): " "3rd argument must be object literal: <%.*s>", (int)GRN_TEXT_LEN(options), GRN_TEXT_VALUE(options)); goto exit; } cursor = grn_hash_cursor_open(ctx, (grn_hash *)options, NULL, 0, NULL, 0, 0, -1, 0); if (!cursor) { GRN_PLUGIN_ERROR(ctx, GRN_NO_MEMORY_AVAILABLE, "fuzzy_search(): couldn't open cursor"); goto exit; } while (grn_hash_cursor_next(ctx, cursor) != GRN_ID_NIL) { grn_hash_cursor_get_key_value(ctx, cursor, &key, &key_size, (void **)&value); if (key_size == 12 && !memcmp(key, "max_distance", 12)) { max_distance = GRN_UINT32_VALUE(value); } else if (key_size == 13 && !memcmp(key, "prefix_length", 13)) { prefix_length = GRN_UINT32_VALUE(value); } else if (key_size == 13 && !memcmp(key, "max_expansion", 13)) { max_expansion = GRN_UINT32_VALUE(value); } else if (key_size == 18 && !memcmp(key, "with_transposition", 18)) { if (GRN_BOOL_VALUE(value)) { flags |= GRN_TABLE_FUZZY_SEARCH_WITH_TRANSPOSITION; } } else { GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "invalid option name: <%.*s>", key_size, (char *)key); grn_hash_cursor_close(ctx, cursor); goto exit; } } grn_hash_cursor_close(ctx, cursor); } if (index) { target = index; } else { if (obj->header.type == GRN_COLUMN_INDEX) { target = obj; } else { grn_column_index(ctx, obj, GRN_OP_FUZZY, &target, 1, NULL); } } if (target) { grn_obj *lexicon; use_sequential_search = GRN_TRUE; lexicon = grn_ctx_at(ctx, target->header.domain); if (lexicon) { if (lexicon->header.type == GRN_TABLE_PAT_KEY) { use_sequential_search = GRN_FALSE; } grn_obj_unlink(ctx, lexicon); } } else { if (grn_obj_is_key_accessor(ctx, obj) && table->header.type == GRN_TABLE_PAT_KEY) { target = table; } else { use_sequential_search = GRN_TRUE; } } if (prefix_length) { const char *s = GRN_TEXT_VALUE(query); const char *e = GRN_BULK_CURR(query); const char *p; unsigned int cl = 0; unsigned int length = 0; for (p = s; p < e && (cl = grn_charlen(ctx, p, e)); p += cl) { length++; if (length > prefix_length) { break; } } prefix_match_size = p - s; } if (use_sequential_search) { rc = sequential_fuzzy_search(ctx, table, obj, query, max_distance, prefix_match_size, max_expansion, flags, res, op); goto exit; } if (!target) { grn_obj inspected; GRN_TEXT_INIT(&inspected, 0); grn_inspect(ctx, &inspected, target); GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "fuzzy_search(): " "column must be COLUMN_INDEX or TABLE_PAT_KEY: <%.*s>", (int)GRN_TEXT_LEN(&inspected), GRN_TEXT_VALUE(&inspected)); rc = ctx->rc; GRN_OBJ_FIN(ctx, &inspected); } else { grn_search_optarg options = {0}; options.mode = GRN_OP_FUZZY; options.fuzzy.prefix_match_size = prefix_match_size; options.fuzzy.max_distance = max_distance; options.fuzzy.max_expansion = max_expansion; options.fuzzy.flags = flags; grn_obj_search(ctx, target, query, res, op, &options); } exit : return rc; }