Beispiel #1
0
static void
exec_search(grn_ctx *ctx, grn_ii *i, grn_query *q, grn_cell *c,
            grn_hash *r, grn_operator op)
{
  grn_hash *s;
  grn_cell *e, *ope = NIL;
  int n = *r->n_entries;
  grn_operator op0 = GRN_OP_OR, *opp = &op0, op1 = q->default_op;
  if (!n && op != GRN_OP_OR) { return; }
  if (n) {
    s = grn_hash_create(ctx, NULL, r->key_size, r->value_size, r->obj.header.flags);
    s->obj.header.impl_flags = 0;
    s->obj.header.domain = r->obj.header.domain;
    s->obj.range = r->obj.range;
    s->obj.max_n_subrecs = r->obj.max_n_subrecs;
    s->obj.subrec_size = r->obj.subrec_size;
    s->obj.subrec_offset = r->obj.subrec_offset;
    s->obj.id = r->obj.id;
    s->obj.db = r->obj.db;
    s->obj.source = r->obj.source;
    s->obj.source_size = r->obj.source_size;
    /*
    grn_hook_entry entry;
    for (entry = 0; entry < N_HOOK_ENTRIES; entry++) {
      s->obj.hooks[entry] = NULL;
    }
    */
  } else {
    s = r;
  }
  while (c != NIL) {
    POP(e, c);
    switch (e->header.type) {
    case GRN_CELL_OP :
      if (opp == &op0 && e->u.op.op == GRN_OP_BUT) {
        POP(e, c);
      } else {
        ope = e;
        op1 = ope->u.op.op;
      }
      continue;
    case GRN_CELL_STR :
      if (ope != NIL) {
        q->opt.mode = ope->u.op.mode == -1 ? q->default_mode : ope->u.op.mode;
        q->opt.max_interval = q->opt.similarity_threshold = ope->u.op.option;
        if (!q->opt.weight_vector) {
          q->opt.vector_size = ope->u.op.weight + q->weight_offset;
        }
        if (ope->u.op.mode == GRN_OP_SIMILAR) {
          q->opt.max_interval = q->default_mode;
        }
      } else {
        q->opt.mode = q->default_mode;
        q->opt.max_interval = DEFAULT_MAX_INTERVAL;
        q->opt.similarity_threshold = DEFAULT_SIMILARITY_THRESHOLD;
        if (!q->opt.weight_vector) {
          q->opt.vector_size = DEFAULT_WEIGHT + q->weight_offset;
        }
      }
      if (grn_ii_select(ctx, i, e->u.b.value, e->u.b.size, s, *opp, &q->opt)) {
        GRN_LOG(ctx, GRN_LOG_ERROR, "grn_inv_select on exec_search failed !");
        return;
      }
      break;
    case GRN_CELL_LIST :
      exec_search(ctx, i, q, e, s, *opp);
      break;
    default :
      GRN_LOG(ctx, GRN_LOG_NOTICE, "invalid object assigned in query (%d)", e->header.type);
      break;
    }
    opp = &op1;
    ope = NIL;
    op1 = q->default_op;
  }
  if (n) {
    grn_table_setoperation(ctx, (grn_obj *)r, (grn_obj *)s, (grn_obj *)r, op);
    grn_hash_close(ctx, s);
  }
}
Beispiel #2
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);
  }