/* grn_ts_writer_output() outputs search results into the output buffer. */ static grn_rc grn_ts_writer_output(grn_ctx *ctx, grn_ts_writer *writer, const grn_ts_record *in, size_t n_in, size_t n_hits) { grn_rc rc; GRN_OUTPUT_ARRAY_OPEN("RESULT", 1); GRN_OUTPUT_ARRAY_OPEN("RESULTSET", 2 + n_in); GRN_OUTPUT_ARRAY_OPEN("NHITS", 1); rc = grn_text_ulltoa(ctx, ctx->impl->output.buf, n_hits); if (rc != GRN_SUCCESS) { return rc; } GRN_OUTPUT_ARRAY_CLOSE(); /* NHITS. */ rc = grn_ts_writer_output_header(ctx, writer); if (rc != GRN_SUCCESS) { return rc; } rc = grn_ts_writer_output_body(ctx, writer, in, n_in); if (rc != GRN_SUCCESS) { return rc; } GRN_OUTPUT_ARRAY_CLOSE(); /* RESULTSET. */ GRN_OUTPUT_ARRAY_CLOSE(); /* RESET. */ return GRN_SUCCESS; }
static mrb_value writer_close_array(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; GRN_OUTPUT_ARRAY_CLOSE(); return mrb_nil_value(); }
/* * grn_ts_writer_output_body() evaluates expressions and outputs the results. */ static grn_rc grn_ts_writer_output_body(grn_ctx *ctx, grn_ts_writer *writer, const grn_ts_record *in, size_t n_in) { size_t i, j, count = 0; writer->bufs = GRN_MALLOCN(grn_ts_buf, writer->n_exprs); if (!writer->bufs) { GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE, "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x %" GRN_FMT_SIZE, sizeof(grn_ts_buf), writer->n_exprs); } for (i = 0; i < writer->n_exprs; i++) { grn_ts_buf_init(ctx, &writer->bufs[i]); } while (count < n_in) { size_t batch_size = GRN_TS_BATCH_SIZE; if (batch_size > (n_in - count)) { batch_size = n_in - count; } for (i = 0; i < writer->n_exprs; ++i) { grn_rc rc = grn_ts_expr_evaluate_to_buf(ctx, writer->exprs[i], in + count, batch_size, &writer->bufs[i]); if (rc != GRN_SUCCESS) { return rc; } } for (i = 0; i < batch_size; ++i) { GRN_OUTPUT_ARRAY_OPEN("HIT", writer->n_exprs); for (j = 0; j < writer->n_exprs; ++j) { if (j) { GRN_TEXT_PUTC(ctx, ctx->impl->output.buf, ','); } switch (writer->exprs[j]->data_kind) { GRN_TS_WRITER_OUTPUT_BODY_CASE(BOOL, bool); GRN_TS_WRITER_OUTPUT_BODY_CASE(INT, int); GRN_TS_WRITER_OUTPUT_BODY_CASE(FLOAT, float); GRN_TS_WRITER_OUTPUT_BODY_CASE(TIME, time); GRN_TS_WRITER_OUTPUT_BODY_CASE(TEXT, text); GRN_TS_WRITER_OUTPUT_BODY_CASE(GEO, geo); GRN_TS_WRITER_OUTPUT_BODY_VECTOR_CASE(BOOL, bool); GRN_TS_WRITER_OUTPUT_BODY_VECTOR_CASE(INT, int); GRN_TS_WRITER_OUTPUT_BODY_VECTOR_CASE(FLOAT, float); GRN_TS_WRITER_OUTPUT_BODY_VECTOR_CASE(TIME, time); GRN_TS_WRITER_OUTPUT_BODY_VECTOR_CASE(TEXT, text); GRN_TS_WRITER_OUTPUT_BODY_VECTOR_CASE(GEO, geo); default: { break; } } } GRN_OUTPUT_ARRAY_CLOSE(); /* HITS. */ } count += batch_size; } return GRN_SUCCESS; }
/* grn_ts_writer_output_header() outputs names and data types. */ static grn_rc grn_ts_writer_output_header(grn_ctx *ctx, grn_ts_writer *writer) { grn_rc rc; GRN_OUTPUT_ARRAY_OPEN("COLUMNS", writer->n_exprs); for (size_t i = 0; i < writer->n_exprs; ++i) { GRN_OUTPUT_ARRAY_OPEN("COLUMN", 2); rc = grn_text_esc(ctx, ctx->impl->output.buf, writer->names[i].ptr, writer->names[i].size); if (rc != GRN_SUCCESS) { return rc; } GRN_TEXT_PUT(ctx, ctx->impl->output.buf, ",\"", 2); switch (writer->exprs[i]->data_type) { case GRN_DB_VOID: { if (writer->exprs[i]->data_kind == GRN_TS_GEO) { GRN_TEXT_PUTS(ctx, ctx->impl->output.buf, "GeoPoint"); } else { GRN_TEXT_PUTS(ctx, ctx->impl->output.buf, "Void"); } break; } GRN_TS_WRITER_OUTPUT_HEADER_CASE(BOOL, "Bool") GRN_TS_WRITER_OUTPUT_HEADER_CASE(INT8, "Int8") GRN_TS_WRITER_OUTPUT_HEADER_CASE(INT16, "Int16") GRN_TS_WRITER_OUTPUT_HEADER_CASE(INT32, "Int32") GRN_TS_WRITER_OUTPUT_HEADER_CASE(INT64, "Int64") GRN_TS_WRITER_OUTPUT_HEADER_CASE(UINT8, "UInt8") GRN_TS_WRITER_OUTPUT_HEADER_CASE(UINT16, "UInt16") GRN_TS_WRITER_OUTPUT_HEADER_CASE(UINT32, "UInt32") GRN_TS_WRITER_OUTPUT_HEADER_CASE(UINT64, "UInt64") GRN_TS_WRITER_OUTPUT_HEADER_CASE(FLOAT, "Float") GRN_TS_WRITER_OUTPUT_HEADER_CASE(TIME, "Time") GRN_TS_WRITER_OUTPUT_HEADER_CASE(SHORT_TEXT, "ShortText") GRN_TS_WRITER_OUTPUT_HEADER_CASE(TEXT, "Text") GRN_TS_WRITER_OUTPUT_HEADER_CASE(LONG_TEXT, "LongText") GRN_TS_WRITER_OUTPUT_HEADER_CASE(TOKYO_GEO_POINT, "TokyoGeoPoint") GRN_TS_WRITER_OUTPUT_HEADER_CASE(WGS84_GEO_POINT, "WGS84GeoPoint") default: { char name_buf[GRN_TABLE_MAX_KEY_SIZE]; size_t name_size; grn_obj *obj = grn_ctx_at(ctx, writer->exprs[i]->data_type); if (!obj) { GRN_TS_ERR_RETURN(GRN_UNKNOWN_ERROR, "grn_ctx_at failed: %d", writer->exprs[i]->data_type); } if (!grn_ts_obj_is_table(ctx, obj)) { grn_obj_unlink(ctx, obj); GRN_TS_ERR_RETURN(GRN_UNKNOWN_ERROR, "not table: %d", writer->exprs[i]->data_type); } name_size = grn_obj_name(ctx, obj, name_buf, sizeof(name_buf)); GRN_TEXT_PUT(ctx, ctx->impl->output.buf, name_buf, name_size); grn_obj_unlink(ctx, obj); break; } } GRN_TEXT_PUTC(ctx, ctx->impl->output.buf, '"'); GRN_OUTPUT_ARRAY_CLOSE(); } GRN_OUTPUT_ARRAY_CLOSE(); /* COLUMNS. */ return GRN_SUCCESS; }