Пример #1
0
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));
}
Пример #2
0
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));
}
Пример #3
0
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");
}
Пример #4
0
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);
}
Пример #5
0
/*
 * 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;
}
Пример #6
0
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");
}
Пример #7
0
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");
}
Пример #8
0
/*
 * _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;
}
Пример #9
0
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");
}
Пример #10
0
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));
}
Пример #11
0
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));
}
Пример #12
0
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");
}
Пример #13
0
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));
}
Пример #14
0
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;
}
Пример #15
0
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
}
Пример #16
0
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");
}
Пример #17
0
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));
}
Пример #18
0
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);
}