Kouhei Sutou
null+****@clear*****
Tue May 24 23:29:34 JST 2016
Kouhei Sutou 2016-05-24 23:29:34 +0900 (Tue, 24 May 2016) New Revision: 779168442b394b93c3fb40d30791db092756dfe7 https://github.com/groonga/groonga/commit/779168442b394b93c3fb40d30791db092756dfe7 Message: select: support object based output in command version 3 Added files: test/command/suite/select/slices/command_version_3.expected test/command/suite/select/slices/command_version_3.test Modified files: include/groonga/output.h lib/ctx.c lib/grn_output.h lib/output.c lib/proc/proc_select.c Modified: include/groonga/output.h (+3 -0) =================================================================== --- include/groonga/output.h 2016-05-24 17:04:38 +0900 (738fefd) +++ include/groonga/output.h 2016-05-24 23:29:34 +0900 (ef3c82d) @@ -93,6 +93,9 @@ GRN_API void grn_ctx_output_str(grn_ctx *ctx, GRN_API void grn_ctx_output_bool(grn_ctx *ctx, grn_bool value); GRN_API void grn_ctx_output_obj(grn_ctx *ctx, grn_obj *value, grn_obj_format *format); +GRN_API void grn_ctx_output_result_set(grn_ctx *ctx, + grn_obj *result_set, + grn_obj_format *format); GRN_API void grn_ctx_output_table_columns(grn_ctx *ctx, grn_obj *table, grn_obj_format *format); Modified: lib/ctx.c (+12 -0) =================================================================== --- lib/ctx.c 2016-05-24 17:04:38 +0900 (f9946db) +++ lib/ctx.c 2016-05-24 23:29:34 +0900 (9bf66f3) @@ -1772,6 +1772,18 @@ grn_ctx_output_obj(grn_ctx *ctx, grn_obj *value, grn_obj_format *format) } void +grn_ctx_output_result_set(grn_ctx *ctx, + grn_obj *result_set, + grn_obj_format *format) +{ + grn_output_result_set(ctx, + ctx->impl->output.buf, + ctx->impl->output.type, + result_set, + format); +} + +void grn_ctx_output_table_columns(grn_ctx *ctx, grn_obj *table, grn_obj_format *format) { Modified: lib/grn_output.h (+5 -0) =================================================================== --- lib/grn_output.h 2016-05-24 17:04:38 +0900 (758443a) +++ lib/grn_output.h 2016-05-24 23:29:34 +0900 (a1972c0) @@ -54,6 +54,11 @@ GRN_API void grn_output_bool(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, grn_bool value); +GRN_API void grn_output_result_set(grn_ctx *ctx, + grn_obj *outbuf, + grn_content_type output_type, + grn_obj *result_set, + grn_obj_format *format); GRN_API void grn_output_table_columns(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, Modified: lib/output.c (+282 -66) =================================================================== --- lib/output.c 2016-05-24 17:04:38 +0900 (20266cd) +++ lib/output.c 2016-05-24 23:29:34 +0900 (44542b2) @@ -1226,18 +1226,82 @@ grn_output_pvector(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, } static inline void -grn_output_table_header(grn_ctx *ctx, grn_obj *outbuf, - grn_content_type output_type, - grn_obj *table, grn_obj_format *format) +grn_output_result_set_n_hits_v1(grn_ctx *ctx, + grn_obj *outbuf, + grn_content_type output_type, + grn_obj_format *format) +{ + 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); +} + +static inline void +grn_output_result_set_n_hits_v3(grn_ctx *ctx, + grn_obj *outbuf, + grn_content_type output_type, + grn_obj_format *format) { - if (format->nhits != -1) { - grn_output_array_open(ctx, outbuf, output_type, "NHITS", 1); - if (output_type == GRN_CONTENT_XML) { - grn_text_itoa(ctx, outbuf, format->nhits); + grn_output_cstr(ctx, outbuf, output_type, "n_hits"); + grn_output_int32(ctx, outbuf, output_type, format->nhits); +} + +static inline void +grn_output_result_set_n_hits(grn_ctx *ctx, + grn_obj *outbuf, + grn_content_type output_type, + grn_obj_format *format) +{ + if (format->nhits == -1) { + return; + } + + if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) { + grn_output_result_set_n_hits_v1(ctx, outbuf, output_type, format); + } else { + grn_output_result_set_n_hits_v3(ctx, outbuf, output_type, format); + } +} + +static inline void +grn_output_table_column_info(grn_ctx *ctx, + grn_obj *outbuf, + grn_content_type output_type, + const char *name, + const char *type) +{ + if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) { + grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2); + if (name) { + grn_output_cstr(ctx, outbuf, output_type, name); } else { - grn_output_int32(ctx, outbuf, output_type, format->nhits); + grn_output_null(ctx, outbuf, output_type); + } + if (type) { + grn_output_cstr(ctx, outbuf, output_type, type); + } else { + grn_output_null(ctx, outbuf, output_type); } grn_output_array_close(ctx, outbuf, output_type); + } else { + grn_output_map_open(ctx, outbuf, output_type, "column", 2); + grn_output_cstr(ctx, outbuf, output_type, "name"); + if (name) { + grn_output_cstr(ctx, outbuf, output_type, name); + } else { + grn_output_null(ctx, outbuf, output_type); + } + grn_output_cstr(ctx, outbuf, output_type, "type"); + if (type) { + grn_output_cstr(ctx, outbuf, output_type, type); + } else { + grn_output_null(ctx, outbuf, output_type); + } + grn_output_map_close(ctx, outbuf, output_type); } } @@ -1282,43 +1346,52 @@ grn_output_table_column(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, grn_obj *column, grn_obj *buf) { - grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2); - if (column) { - grn_id range_id = GRN_ID_NIL; - GRN_BULK_REWIND(buf); - grn_column_name_(ctx, column, buf); - grn_output_obj(ctx, outbuf, output_type, buf, NULL); - if (column->header.type == GRN_COLUMN_INDEX) { - range_id = GRN_DB_UINT32; - } else if (is_score_accessor(ctx, column)) { - if (grn_ctx_get_command_version(ctx) == GRN_COMMAND_VERSION_1) { - range_id = GRN_DB_INT32; - } else { - range_id = GRN_DB_FLOAT; - } - } - if (range_id == GRN_ID_NIL) { - range_id = grn_obj_get_range(ctx, column); - } - if (range_id == GRN_ID_NIL) { - grn_output_cstr(ctx, outbuf, output_type, "null"); - } else { - int name_len; - grn_obj *range_obj; - char name_buf[GRN_TABLE_MAX_KEY_SIZE]; + grn_id range_id = GRN_ID_NIL; - 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); + if (!column) { + grn_output_table_column_info(ctx, outbuf, output_type, NULL, NULL); + return; + } + + GRN_BULK_REWIND(buf); + grn_column_name_(ctx, column, buf); + GRN_TEXT_PUTC(ctx, buf, '\0'); + + if (column->header.type == GRN_COLUMN_INDEX) { + range_id = GRN_DB_UINT32; + } else if (is_score_accessor(ctx, column)) { + if (grn_ctx_get_command_version(ctx) == GRN_COMMAND_VERSION_1) { + range_id = GRN_DB_INT32; + } else { + range_id = GRN_DB_FLOAT; } + } + if (range_id == GRN_ID_NIL) { + range_id = grn_obj_get_range(ctx, column); + } + if (range_id == GRN_ID_NIL) { + grn_output_table_column_info(ctx, + outbuf, + output_type, + GRN_TEXT_VALUE(buf), + "null"); } else { - grn_output_cstr(ctx, outbuf, output_type, ""); - grn_output_cstr(ctx, outbuf, output_type, ""); + grn_obj *range_obj; + char type_name[GRN_TABLE_MAX_KEY_SIZE]; + int type_name_len; + + range_obj = grn_ctx_at(ctx, range_id); + type_name_len = grn_obj_name(ctx, + range_obj, + type_name, + GRN_TABLE_MAX_KEY_SIZE); + type_name[type_name_len] = '\0'; + grn_output_table_column_info(ctx, + outbuf, + output_type, + GRN_TEXT_VALUE(buf), + type_name); } - grn_output_array_close(ctx, outbuf, output_type); } static inline void @@ -1329,28 +1402,29 @@ grn_output_table_column_by_expression(grn_ctx *ctx, grn_obj *outbuf, grn_obj *buf) { if (code_end <= code) { - grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2); - grn_output_null(ctx, outbuf, output_type); - grn_output_null(ctx, outbuf, output_type); - grn_output_array_close(ctx, outbuf, output_type); + grn_output_table_column_info(ctx, + outbuf, + output_type, + NULL, + NULL); return; } switch (code_end[-1].op) { case GRN_OP_GET_MEMBER : if ((code_end - code) == 3) { - grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2); - GRN_BULK_REWIND(buf); grn_column_name_(ctx, code[0].value, buf); GRN_TEXT_PUTC(ctx, buf, '['); grn_inspect(ctx, buf, code[1].value); GRN_TEXT_PUTC(ctx, buf, ']'); + GRN_TEXT_PUTC(ctx, buf, '\0'); - grn_output_obj(ctx, outbuf, output_type, buf, NULL); - grn_output_null(ctx, outbuf, output_type); - - grn_output_array_close(ctx, outbuf, output_type); + grn_output_table_column_info(ctx, + outbuf, + output_type, + GRN_TEXT_VALUE(buf), + NULL); } else { grn_output_table_column(ctx, outbuf, output_type, code->value, buf); } @@ -1362,6 +1436,32 @@ grn_output_table_column_by_expression(grn_ctx *ctx, grn_obj *outbuf, } static inline void +grn_output_table_columns_open(grn_ctx *ctx, + grn_obj *outbuf, + grn_content_type output_type, + int n_columns) +{ + if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) { + grn_output_array_open(ctx, outbuf, output_type, "COLUMNS", n_columns); + } else { + grn_output_cstr(ctx, outbuf, output_type, "columns"); + grn_output_array_open(ctx, outbuf, output_type, "columns", n_columns); + } +} + +static inline void +grn_output_table_columns_close(grn_ctx *ctx, + grn_obj *outbuf, + grn_content_type output_type) +{ + if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) { + grn_output_array_close(ctx, outbuf, output_type); + } else { + grn_output_array_close(ctx, outbuf, output_type); + } +} + +static inline void grn_output_table_columns_by_expression(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, grn_obj *table, grn_obj_format *format, @@ -1377,7 +1477,8 @@ grn_output_table_columns_by_expression(grn_ctx *ctx, grn_obj *outbuf, n_elements = count_n_elements_in_expression(ctx, format->expression); - grn_output_array_open(ctx, outbuf, output_type, "COLUMNS", n_elements); + grn_output_table_columns_open(ctx, outbuf, output_type, n_elements); + for (code = expr->codes; code < code_end; code++) { int code_start_offset; @@ -1417,7 +1518,7 @@ grn_output_table_columns_by_expression(grn_ctx *ctx, grn_obj *outbuf, buf); } - grn_output_array_close(ctx, outbuf, output_type); + grn_output_table_columns_close(ctx, outbuf, output_type); } static inline void @@ -1430,11 +1531,11 @@ grn_output_table_columns_by_columns(grn_ctx *ctx, grn_obj *outbuf, 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, "COLUMNS", ncolumns); + grn_output_table_columns_open(ctx, outbuf, output_type, ncolumns); for (i = 0; i < ncolumns; i++) { grn_output_table_column(ctx, outbuf, output_type, columns[i], buf); } - grn_output_array_close(ctx, outbuf, output_type); + grn_output_table_columns_close(ctx, outbuf, output_type); } void @@ -1456,6 +1557,31 @@ grn_output_table_columns(grn_ctx *ctx, grn_obj *outbuf, } static inline void +grn_output_table_record_open(grn_ctx *ctx, + grn_obj *outbuf, + grn_content_type output_type, + int n_columns) +{ + if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) { + grn_output_array_open(ctx, outbuf, output_type, "HIT", n_columns); + } else { + grn_output_array_open(ctx, outbuf, output_type, "record", n_columns); + } +} + +static inline void +grn_output_table_record_close(grn_ctx *ctx, + grn_obj *outbuf, + grn_content_type output_type) +{ + if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) { + grn_output_array_close(ctx, outbuf, output_type); + } else { + grn_output_array_close(ctx, outbuf, output_type); + } +} + +static inline void grn_output_table_record_by_column(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, @@ -1512,7 +1638,7 @@ grn_output_table_records_by_expression(grn_ctx *ctx, grn_obj *outbuf, grn_bool is_first_comma = GRN_TRUE; grn_bool have_comma = GRN_FALSE; GRN_RECORD_SET(ctx, record, id); - grn_output_array_open(ctx, outbuf, output_type, "HIT", n_elements); + grn_output_table_record_open(ctx, outbuf, output_type, n_elements); for (code = expr->codes; code < code_end; code++) { if (code->op == GRN_OP_COMMA) { int code_start_offset = previous_comma_offset + 1; @@ -1559,7 +1685,7 @@ grn_output_table_records_by_expression(grn_ctx *ctx, grn_obj *outbuf, record); } - grn_output_array_close(ctx, outbuf, output_type); + grn_output_table_record_close(ctx, outbuf, output_type); } } @@ -1574,7 +1700,7 @@ grn_output_table_records_by_columns(grn_ctx *ctx, grn_obj *outbuf, int ncolumns = GRN_BULK_VSIZE(&format->columns)/sizeof(grn_obj *); grn_obj **columns = (grn_obj **)GRN_BULK_HEAD(&format->columns); while ((id = grn_table_cursor_next(ctx, tc)) != GRN_ID_NIL) { - grn_output_array_open(ctx, outbuf, output_type, "HIT", ncolumns); + grn_output_table_record_open(ctx, outbuf, output_type, ncolumns); for (i = 0; i < ncolumns; i++) { grn_output_table_record_by_column(ctx, outbuf, @@ -1582,6 +1708,28 @@ grn_output_table_records_by_columns(grn_ctx *ctx, grn_obj *outbuf, columns[i], id); } + grn_output_table_record_close(ctx, outbuf, output_type); + } +} + +static inline void +grn_output_table_records_open(grn_ctx *ctx, + grn_obj *outbuf, + grn_content_type output_type, + int n_records) +{ + if (grn_ctx_get_command_version(ctx) >= GRN_COMMAND_VERSION_3) { + grn_output_cstr(ctx, outbuf, output_type, "records"); + grn_output_array_open(ctx, outbuf, output_type, "records", n_records); + } +} + +static inline void +grn_output_table_records_close(grn_ctx *ctx, + grn_obj *outbuf, + grn_content_type output_type) +{ + if (grn_ctx_get_command_version(ctx) >= GRN_COMMAND_VERSION_3) { grn_output_array_close(ctx, outbuf, output_type); } } @@ -1591,9 +1739,12 @@ grn_output_table_records(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, grn_obj *table, grn_obj_format *format) { - grn_table_cursor *tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, - format->offset, format->limit, - GRN_CURSOR_ASCENDING); + grn_table_cursor *tc; + + grn_output_table_records_open(ctx, outbuf, output_type, format->limit); + tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, + format->offset, format->limit, + GRN_CURSOR_ASCENDING); if (tc) { if (format->expression) { grn_output_table_records_by_expression(ctx, outbuf, output_type, @@ -1606,11 +1757,15 @@ grn_output_table_records(grn_ctx *ctx, grn_obj *outbuf, } else { ERRCLR(ctx); } + grn_output_table_records_close(ctx, outbuf, output_type); } -static inline void -grn_output_table(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, - grn_obj *table, grn_obj_format *format) +static void +grn_output_result_set_v1(grn_ctx *ctx, + grn_obj *outbuf, + grn_content_type output_type, + grn_obj *table, + grn_obj_format *format) { grn_obj buf; GRN_TEXT_INIT(&buf, 0); @@ -1622,7 +1777,7 @@ grn_output_table(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, } resultset_size += format->limit; grn_output_array_open(ctx, outbuf, output_type, "RESULTSET", resultset_size); - grn_output_table_header(ctx, outbuf, output_type, table, format); + grn_output_result_set_n_hits(ctx, outbuf, output_type, format); if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) { grn_output_table_columns(ctx, outbuf, output_type, table, format); } @@ -1651,6 +1806,66 @@ grn_output_table(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, GRN_OBJ_FIN(ctx, &buf); } +static void +grn_output_result_set_v3(grn_ctx *ctx, + grn_obj *outbuf, + grn_content_type output_type, + grn_obj *result_set, + grn_obj_format *format) +{ + grn_obj buf; + GRN_TEXT_INIT(&buf, 0); + if (format) { + int n_elements = 2; + /* result_set: {"n_hits": N, ("columns": COLUMNS,) "records": records} */ + if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) { + n_elements++; + } + grn_output_map_open(ctx, outbuf, output_type, "result_set", n_elements); + grn_output_result_set_n_hits(ctx, outbuf, output_type, format); + if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) { + grn_output_table_columns(ctx, outbuf, output_type, result_set, format); + } + grn_output_table_records(ctx, outbuf, output_type, result_set, format); + grn_output_map_close(ctx, outbuf, output_type); + } else { + grn_obj *column; + int n_records; + + column = grn_obj_column(ctx, + result_set, + GRN_COLUMN_NAME_KEY, + GRN_COLUMN_NAME_KEY_LEN); + grn_output_map_open(ctx, outbuf, output_type, "result_set", 1); + n_records = grn_table_size(ctx, result_set); + grn_output_cstr(ctx, outbuf, output_type, "keys"); + grn_output_array_open(ctx, outbuf, output_type, "keys", n_records); + GRN_TABLE_EACH_BEGIN(ctx, result_set, cursor, id) { + GRN_BULK_REWIND(&buf); + grn_obj_get_value(ctx, column, id, &buf); + grn_text_esc(ctx, outbuf, GRN_BULK_HEAD(&buf), GRN_BULK_VSIZE(&buf)); + } GRN_TABLE_EACH_END(ctx, cursor); + grn_output_array_close(ctx, outbuf, output_type); + grn_output_map_close(ctx, outbuf, output_type); + grn_obj_unlink(ctx, column); + } + GRN_OBJ_FIN(ctx, &buf); +} + +void +grn_output_result_set(grn_ctx *ctx, + grn_obj *outbuf, + grn_content_type output_type, + grn_obj *result_set, + grn_obj_format *format) +{ + if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) { + grn_output_result_set_v1(ctx, outbuf, output_type, result_set, format); + } else { + grn_output_result_set_v3(ctx, outbuf, output_type, result_set, format); + } +} + void grn_output_obj(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, grn_obj *obj, grn_obj_format *format) @@ -1677,7 +1892,8 @@ grn_output_obj(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, case GRN_TABLE_PAT_KEY : case GRN_TABLE_DAT_KEY : case GRN_TABLE_NO_KEY : - grn_output_table(ctx, outbuf, output_type, obj, format); + /* Deprecated. Use grn_output_result_set() directly. */ + grn_output_result_set(ctx, outbuf, output_type, obj, format); break; } GRN_OBJ_FIN(ctx, &buf); Modified: lib/proc/proc_select.c (+266 -15) =================================================================== --- lib/proc/proc_select.c 2016-05-24 17:04:38 +0900 (36fff15) +++ lib/proc/proc_select.c 2016-05-24 23:29:34 +0900 (c032ca9) @@ -102,6 +102,8 @@ typedef struct { grn_obj *filtered_result; } grn_drilldown_data; +typedef struct _grn_select_output_formatter grn_select_output_formatter; + typedef struct { /* inputs */ grn_select_string table; @@ -138,9 +140,51 @@ typedef struct { uint16_t taintable; struct { int n_elements; + grn_select_output_formatter *formatter; } output; } grn_select_data; +typedef void grn_select_output_result_sets_open_func(grn_ctx *ctx, + grn_select_data *data); +typedef void grn_select_output_result_sets_close_func(grn_ctx *ctx, + grn_select_data *data); +typedef void grn_select_output_match_label_func(grn_ctx *ctx, + grn_select_data *data); +typedef void grn_select_output_slices_label_func(grn_ctx *ctx, + grn_select_data *data); +typedef void grn_select_output_slices_open_func(grn_ctx *ctx, + grn_select_data *data, + unsigned int n_result_sets); +typedef void grn_select_output_slices_close_func(grn_ctx *ctx, + grn_select_data *data); +typedef void grn_select_output_slice_label_func(grn_ctx *ctx, + grn_select_data *data, + grn_slice_data *slice); +typedef void grn_select_output_drilldowns_label_func(grn_ctx *ctx, + grn_select_data *data); +typedef void grn_select_output_drilldowns_open_func(grn_ctx *ctx, + grn_select_data *data, + unsigned int n_result_sets); +typedef void grn_select_output_drilldowns_close_func(grn_ctx *ctx, + grn_select_data *data); +typedef void grn_select_output_drilldown_label_func(grn_ctx *ctx, + grn_select_data *data, + grn_drilldown_data *drilldown); + +struct _grn_select_output_formatter { + grn_select_output_result_sets_open_func *result_sets_open; + grn_select_output_result_sets_close_func *result_sets_close; + grn_select_output_match_label_func *match_label; + grn_select_output_slices_label_func *slices_label; + grn_select_output_slices_open_func *slices_open; + grn_select_output_slices_close_func *slices_close; + grn_select_output_slice_label_func *slice_label; + grn_select_output_drilldowns_label_func *drilldowns_label; + grn_select_output_drilldowns_open_func *drilldowns_open; + grn_select_output_drilldowns_close_func *drilldowns_close; + grn_select_output_drilldown_label_func *drilldown_label; +}; + grn_rc grn_proc_syntax_expand_query(grn_ctx *ctx, const char *query, @@ -1441,12 +1485,14 @@ grn_select_sort(grn_ctx *ctx, } static grn_bool -grn_select_output_records(grn_ctx *ctx, - grn_select_data *data) +grn_select_output_match(grn_ctx *ctx, + grn_select_data *data) { int offset; grn_obj *output_table; + data->output.formatter->match_label(ctx, data); + if (data->tables.sorted) { offset = 0; output_table = data->tables.sorted; @@ -1586,6 +1632,8 @@ grn_select_output_slices(grn_ctx *ctx, return GRN_TRUE; } + data->output.formatter->slices_label(ctx, data); + GRN_HASH_EACH_BEGIN(ctx, data->slices, cursor, id) { grn_slice_data *slice; @@ -1595,7 +1643,8 @@ grn_select_output_slices(grn_ctx *ctx, } } GRN_HASH_EACH_END(ctx, cursor); - GRN_OUTPUT_MAP_OPEN("SLICES", n_available_results); + data->output.formatter->slices_open(ctx, data, n_available_results); + GRN_HASH_EACH_BEGIN(ctx, data->slices, cursor, id) { grn_slice_data *slice; uint32_t n_hits; @@ -1607,7 +1656,7 @@ grn_select_output_slices(grn_ctx *ctx, continue; } - GRN_OUTPUT_STR(slice->label.value, slice->label.length); + data->output.formatter->slice_label(ctx, data, slice); n_hits = grn_table_size(ctx, slice->table); @@ -1666,7 +1715,8 @@ grn_select_output_slices(grn_ctx *ctx, (int)(slice->label.length), slice->label.value); } GRN_HASH_EACH_END(ctx, cursor); - GRN_OUTPUT_MAP_CLOSE(); + + data->output.formatter->slices_close(ctx, data); return succeeded; } @@ -2137,6 +2187,8 @@ grn_select_output_drilldowns(grn_ctx *ctx, return GRN_TRUE; } + data->output.formatter->drilldowns_label(ctx, data); + GRN_HASH_EACH_BEGIN(ctx, data->drilldowns, cursor, id) { grn_drilldown_data *drilldown; grn_table_group_result *result; @@ -2150,7 +2202,7 @@ grn_select_output_drilldowns(grn_ctx *ctx, is_labeled = (data->drilldown.keys.length == 0); if (is_labeled) { - GRN_OUTPUT_MAP_OPEN("DRILLDOWNS", n_available_results); + data->output.formatter->drilldowns_open(ctx, data, n_available_results); } GRN_HASH_EACH_BEGIN(ctx, data->drilldowns, cursor, id) { @@ -2174,9 +2226,7 @@ grn_select_output_drilldowns(grn_ctx *ctx, target_table = result->table; } - if (is_labeled) { - GRN_OUTPUT_STR(drilldown->label.value, drilldown->label.length); - } + data->output.formatter->drilldown_label(ctx, data, drilldown); n_hits = grn_table_size(ctx, target_table); @@ -2241,9 +2291,7 @@ grn_select_output_drilldowns(grn_ctx *ctx, } } GRN_HASH_EACH_END(ctx, cursor); - if (is_labeled) { - GRN_OUTPUT_MAP_CLOSE(); - } + data->output.formatter->drilldowns_close(ctx, data); return succeeded; } @@ -2251,7 +2299,7 @@ grn_select_output_drilldowns(grn_ctx *ctx, static grn_bool grn_select_output(grn_ctx *ctx, grn_select_data *data) { - if (!grn_select_output_records(ctx, data)) { + if (!grn_select_output_match(ctx, data)) { return GRN_FALSE; } @@ -2266,6 +2314,203 @@ grn_select_output(grn_ctx *ctx, grn_select_data *data) return GRN_TRUE; } +static void +grn_select_output_result_sets_open_v1(grn_ctx *ctx, grn_select_data *data) +{ + GRN_OUTPUT_ARRAY_OPEN("RESULT", data->output.n_elements); +} + +static void +grn_select_output_result_sets_close_v1(grn_ctx *ctx, grn_select_data *data) +{ + GRN_OUTPUT_ARRAY_CLOSE(); +} + +static void +grn_select_output_match_label_v1(grn_ctx *ctx, grn_select_data *data) +{ +} + +static void +grn_select_output_slices_label_v1(grn_ctx *ctx, grn_select_data *data) +{ +} + +static void +grn_select_output_slices_open_v1(grn_ctx *ctx, + grn_select_data *data, + unsigned int n_result_sets) +{ + GRN_OUTPUT_MAP_OPEN("SLICES", n_result_sets); +} + +static void +grn_select_output_slices_close_v1(grn_ctx *ctx, grn_select_data *data) +{ + GRN_OUTPUT_MAP_CLOSE(); +} + +static void +grn_select_output_slice_label_v1(grn_ctx *ctx, + grn_select_data *data, + grn_slice_data *slice) +{ + GRN_OUTPUT_STR(slice->label.value, slice->label.length); +} + +static void +grn_select_output_drilldowns_label_v1(grn_ctx *ctx, grn_select_data *data) +{ +} + +static void +grn_select_output_drilldowns_open_v1(grn_ctx *ctx, + grn_select_data *data, + unsigned int n_result_sets) +{ + if (data->drilldown.keys.length == 0) { + GRN_OUTPUT_MAP_OPEN("DRILLDOWNS", n_result_sets); + } +} + +static void +grn_select_output_drilldowns_close_v1(grn_ctx *ctx, grn_select_data *data) +{ + if (data->drilldown.keys.length == 0) { + GRN_OUTPUT_MAP_CLOSE(); + } +} + +static void +grn_select_output_drilldown_label_v1(grn_ctx *ctx, + grn_select_data *data, + grn_drilldown_data *drilldown) +{ + if (data->drilldown.keys.length == 0) { + GRN_OUTPUT_STR(drilldown->label.value, drilldown->label.length); + } +} + +static grn_select_output_formatter grn_select_output_formatter_v1 = { + grn_select_output_result_sets_open_v1, + grn_select_output_result_sets_close_v1, + grn_select_output_match_label_v1, + grn_select_output_slices_label_v1, + grn_select_output_slices_open_v1, + grn_select_output_slices_close_v1, + grn_select_output_slice_label_v1, + grn_select_output_drilldowns_label_v1, + grn_select_output_drilldowns_open_v1, + grn_select_output_drilldowns_close_v1, + grn_select_output_drilldown_label_v1 +}; + +static void +grn_select_output_result_sets_open_v3(grn_ctx *ctx, grn_select_data *data) +{ + int n_elements = 1; + if (data->slices) { + n_elements++; + } + if (data->drilldowns) { + n_elements++; + } + GRN_OUTPUT_MAP_OPEN("result_sets", n_elements); +} + +static void +grn_select_output_result_sets_close_v3(grn_ctx *ctx, grn_select_data *data) +{ + GRN_OUTPUT_MAP_CLOSE(); +} + +static void +grn_select_output_match_label_v3(grn_ctx *ctx, grn_select_data *data) +{ + GRN_OUTPUT_CSTR("match"); +} + +static void +grn_select_output_slices_label_v3(grn_ctx *ctx, grn_select_data *data) +{ + GRN_OUTPUT_CSTR("slices"); +} + +static void +grn_select_output_slices_open_v3(grn_ctx *ctx, + grn_select_data *data, + unsigned int n_result_sets) +{ + GRN_OUTPUT_MAP_OPEN("slices", n_result_sets); +} + +static void +grn_select_output_slices_close_v3(grn_ctx *ctx, grn_select_data *data) +{ + GRN_OUTPUT_MAP_CLOSE(); +} + +static void +grn_select_output_slice_label_v3(grn_ctx *ctx, + grn_select_data *data, + grn_slice_data *slice) +{ + GRN_OUTPUT_STR(slice->label.value, slice->label.length); +} + +static void +grn_select_output_drilldowns_label_v3(grn_ctx *ctx, grn_select_data *data) +{ + GRN_OUTPUT_CSTR("drilldowns"); +} + +static void +grn_select_output_drilldowns_open_v3(grn_ctx *ctx, + grn_select_data *data, + unsigned int n_result_sets) +{ + GRN_OUTPUT_MAP_OPEN("drilldowns", n_result_sets); +} + +static void +grn_select_output_drilldowns_close_v3(grn_ctx *ctx, grn_select_data *data) +{ + GRN_OUTPUT_MAP_CLOSE(); +} + +static void +grn_select_output_drilldown_label_v3(grn_ctx *ctx, + grn_select_data *data, + grn_drilldown_data *drilldown) +{ + if (data->drilldown.keys.length == 0) { + GRN_OUTPUT_STR(drilldown->label.value, drilldown->label.length); + } else { + char name[GRN_TABLE_MAX_KEY_SIZE]; + int name_len; + + name_len = grn_obj_name(ctx, + drilldown->parsed_keys[0].key, + name, + GRN_TABLE_MAX_KEY_SIZE); + GRN_OUTPUT_STR(name, name_len); + } +} + +static grn_select_output_formatter grn_select_output_formatter_v3 = { + grn_select_output_result_sets_open_v3, + grn_select_output_result_sets_close_v3, + grn_select_output_match_label_v3, + grn_select_output_slices_label_v3, + grn_select_output_slices_open_v3, + grn_select_output_slices_close_v3, + grn_select_output_slice_label_v3, + grn_select_output_drilldowns_label_v3, + grn_select_output_drilldowns_open_v3, + grn_select_output_drilldowns_close_v3, + grn_select_output_drilldown_label_v3 +}; + static grn_rc grn_select(grn_ctx *ctx, grn_select_data *data) { @@ -2277,6 +2522,12 @@ grn_select(grn_ctx *ctx, grn_select_data *data) long long int threshold, original_threshold = 0; grn_cache *cache_obj = grn_cache_current_get(ctx); + if (grn_ctx_get_command_version(ctx) < GRN_COMMAND_VERSION_3) { + data->output.formatter = &grn_select_output_formatter_v1; + } else { + data->output.formatter = &grn_select_output_formatter_v3; + } + data->tables.target = NULL; data->tables.initial = NULL; data->tables.result = NULL; @@ -2520,9 +2771,9 @@ grn_select(grn_ctx *ctx, grn_select_data *data) goto exit; } - GRN_OUTPUT_ARRAY_OPEN("RESULT", data->output.n_elements); + data->output.formatter->result_sets_open(ctx, data); succeeded = grn_select_output(ctx, data); - GRN_OUTPUT_ARRAY_CLOSE(); + data->output.formatter->result_sets_close(ctx, data); if (!succeeded) { goto exit; } Added: test/command/suite/select/slices/command_version_3.expected (+98 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/slices/command_version_3.expected 2016-05-24 23:29:34 +0900 (f449326) @@ -0,0 +1,98 @@ +table_create Tags TABLE_PAT_KEY ShortText +[[0,0.0,0.0],true] +table_create Memos TABLE_HASH_KEY ShortText +[[0,0.0,0.0],true] +column_create Memos date COLUMN_SCALAR Time +[[0,0.0,0.0],true] +column_create Memos tag COLUMN_SCALAR Tags +[[0,0.0,0.0],true] +load --table Memos +[ +{"_key": "Groonga is fast!", "date": "2016-05-19 12:00:00", "tag": "Groonga"}, +{"_key": "Mroonga is fast!", "date": "2016-05-19 12:00:01", "tag": "Mroonga"}, +{"_key": "Groonga sticker!", "date": "2016-05-19 12:00:02", "tag": "Groonga"}, +{"_key": "Rroonga is fast!", "date": "2016-05-19 12:00:03", "tag": "Rroonga"} +] +[[0,0.0,0.0],4] +select Memos --slices[groonga].filter 'tag == "Groonga"' --slices[groonga].sort_keys 'date' --slices[groonga].output_columns '_key, date' --command_version 3 +{ + "header": { + "return_code": 0, + "start_time": 0.0, + "elapsed_time": 0.0 + }, + "body": { + "match": { + "n_hits": 4, + "columns": [ + { + "name": "_id", + "type": "UInt32" + }, + { + "name": "_key", + "type": "ShortText" + }, + { + "name": "date", + "type": "Time" + }, + { + "name": "tag", + "type": "Tags" + } + ], + "records": [ + [ + 1, + "Groonga is fast!", + 1463626800.0, + "Groonga" + ], + [ + 2, + "Mroonga is fast!", + 1463626801.0, + "Mroonga" + ], + [ + 3, + "Groonga sticker!", + 1463626802.0, + "Groonga" + ], + [ + 4, + "Rroonga is fast!", + 1463626803.0, + "Rroonga" + ] + ] + }, + "slices": { + "groonga": { + "n_hits": 2, + "columns": [ + { + "name": "_key", + "type": "ShortText" + }, + { + "name": "date", + "type": "Time" + } + ], + "records": [ + [ + "Groonga is fast!", + 1463626800.0 + ], + [ + "Groonga sticker!", + 1463626802.0 + ] + ] + } + } + } +} Added: test/command/suite/select/slices/command_version_3.test (+19 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/slices/command_version_3.test 2016-05-24 23:29:34 +0900 (9d625c5) @@ -0,0 +1,19 @@ +table_create Tags TABLE_PAT_KEY ShortText + +table_create Memos TABLE_HASH_KEY ShortText +column_create Memos date COLUMN_SCALAR Time +column_create Memos tag COLUMN_SCALAR Tags + +load --table Memos +[ +{"_key": "Groonga is fast!", "date": "2016-05-19 12:00:00", "tag": "Groonga"}, +{"_key": "Mroonga is fast!", "date": "2016-05-19 12:00:01", "tag": "Mroonga"}, +{"_key": "Groonga sticker!", "date": "2016-05-19 12:00:02", "tag": "Groonga"}, +{"_key": "Rroonga is fast!", "date": "2016-05-19 12:00:03", "tag": "Rroonga"} +] + +select Memos \ + --slices[groonga].filter 'tag == "Groonga"' \ + --slices[groonga].sort_keys 'date' \ + --slices[groonga].output_columns '_key, date' \ + --command_version 3 -------------- next part -------------- HTML����������������������������... Télécharger