Exemplo n.º 1
0
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));
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
/*
 * 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;
}
Exemplo n.º 5
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));
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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)));
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
  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);
  }
Exemplo n.º 10
0
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);
}
Exemplo n.º 11
0
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));
  }
}
Exemplo n.º 12
0
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);
}
Exemplo n.º 13
0
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);
}
Exemplo n.º 14
0
/* 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);
}
Exemplo n.º 15
0
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);
}
Exemplo n.º 16
0
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);
  }
Exemplo n.º 17
0
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);
}
Exemplo n.º 18
0
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);
}
Exemplo n.º 19
0
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);
}
Exemplo n.º 20
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;
}
Exemplo n.º 21
0
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;
}
Exemplo n.º 22
0
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);
}
Exemplo n.º 23
0
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;
}
Exemplo n.º 24
0
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;
}
Exemplo n.º 25
0
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;
}