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); } }
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); }