diff options
Diffstat (limited to 'storage/mroonga/vendor/groonga/lib/output.c')
-rw-r--r-- | storage/mroonga/vendor/groonga/lib/output.c | 282 |
1 files changed, 239 insertions, 43 deletions
diff --git a/storage/mroonga/vendor/groonga/lib/output.c b/storage/mroonga/vendor/groonga/lib/output.c index 9b745c89a01..0036e9a8619 100644 --- a/storage/mroonga/vendor/groonga/lib/output.c +++ b/storage/mroonga/vendor/groonga/lib/output.c @@ -15,15 +15,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef GROONGA_IN_H -#include "groonga_in.h" -#endif /* GROONGA_IN_H */ +#include "grn.h" #include <string.h> -#include "str.h" -#include "db.h" -#include "util.h" -#include "output.h" +#include "grn_str.h" +#include "grn_db.h" +#include "grn_util.h" +#include "grn_output.h" #define LEVELS (&ctx->impl->levels) #define DEPTH (GRN_BULK_VSIZE(LEVELS)>>2) @@ -56,6 +54,8 @@ put_delimiter(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type) case GRN_CONTENT_MSGPACK : // do nothing break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + break; case GRN_CONTENT_NONE: break; } @@ -90,6 +90,8 @@ grn_output_array_open(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_typ msgpack_pack_array(&ctx->impl->msgpacker, nelements); #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + break; case GRN_CONTENT_NONE: break; } @@ -121,6 +123,8 @@ grn_output_array_close(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_ty case GRN_CONTENT_MSGPACK : // do nothing break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + break; case GRN_CONTENT_NONE: break; } @@ -157,6 +161,8 @@ grn_output_map_open(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, msgpack_pack_map(&ctx->impl->msgpacker, nelements); #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + break; case GRN_CONTENT_NONE: break; } @@ -188,6 +194,8 @@ grn_output_map_close(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type case GRN_CONTENT_MSGPACK : // do nothing break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + break; case GRN_CONTENT_NONE: break; } @@ -216,6 +224,9 @@ grn_output_int32(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, in msgpack_pack_int32(&ctx->impl->msgpacker, value); #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + grn_text_itoa(ctx, outbuf, value); + break; case GRN_CONTENT_NONE: break; } @@ -243,6 +254,9 @@ grn_output_int64(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, in msgpack_pack_int64(&ctx->impl->msgpacker, value); #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + grn_text_lltoa(ctx, outbuf, value); + break; case GRN_CONTENT_NONE: break; } @@ -270,6 +284,9 @@ grn_output_uint64(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, i msgpack_pack_uint64(&ctx->impl->msgpacker, value); #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + grn_text_ulltoa(ctx, outbuf, value); + break; case GRN_CONTENT_NONE: break; } @@ -297,6 +314,9 @@ grn_output_float(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, do msgpack_pack_double(&ctx->impl->msgpacker, value); #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + grn_text_ftoa(ctx, outbuf, value); + break; case GRN_CONTENT_NONE: break; } @@ -322,10 +342,13 @@ grn_output_str(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, break; case GRN_CONTENT_MSGPACK : #ifdef GRN_WITH_MESSAGE_PACK - msgpack_pack_raw(&ctx->impl->msgpacker, value_len); - msgpack_pack_raw_body(&ctx->impl->msgpacker, value, value_len); + msgpack_pack_str(&ctx->impl->msgpacker, value_len); + msgpack_pack_str_body(&ctx->impl->msgpacker, value, value_len); #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + GRN_TEXT_PUT(ctx, outbuf, value, value_len); + break; case GRN_CONTENT_NONE: break; } @@ -364,6 +387,9 @@ grn_output_bool(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, grn } #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + GRN_TEXT_PUTS(ctx, outbuf, value ? "true" : "false"); + break; case GRN_CONTENT_NONE: break; } @@ -388,6 +414,8 @@ grn_output_null(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type) msgpack_pack_nil(&ctx->impl->msgpacker); #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + break; case GRN_CONTENT_NONE: break; } @@ -428,6 +456,9 @@ grn_output_time(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, int msgpack_pack_double(&ctx->impl->msgpacker, dv); #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + grn_text_ftoa(ctx, outbuf, dv); + break; case GRN_CONTENT_NONE: break; } @@ -479,8 +510,8 @@ grn_output_geo_point(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type grn_text_itoa(ctx, &buf, value->latitude); GRN_TEXT_PUTC(ctx, &buf, 'x'); grn_text_itoa(ctx, &buf, value->longitude); - msgpack_pack_raw(&ctx->impl->msgpacker, GRN_TEXT_LEN(&buf)); - msgpack_pack_raw_body(&ctx->impl->msgpacker, + msgpack_pack_str(&ctx->impl->msgpacker, GRN_TEXT_LEN(&buf)); + msgpack_pack_str_body(&ctx->impl->msgpacker, GRN_TEXT_VALUE(&buf), GRN_TEXT_LEN(&buf)); grn_obj_close(ctx, &buf); @@ -489,6 +520,17 @@ grn_output_geo_point(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type } #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + if (value) { + GRN_TEXT_PUTC(ctx, outbuf, '"'); + grn_text_itoa(ctx, outbuf, value->latitude); + GRN_TEXT_PUTC(ctx, outbuf, 'x'); + grn_text_itoa(ctx, outbuf, value->longitude); + GRN_TEXT_PUTC(ctx, outbuf, '"'); + } else { + GRN_TEXT_PUTS(ctx, outbuf, "\"\""); + } + break; case GRN_CONTENT_NONE: break; } @@ -521,10 +563,10 @@ grn_text_atoj(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, buf.header.domain = DB_OBJ(a->obj)->range; break; case GRN_ACCESSOR_GET_SCORE : - grn_obj_get_value(ctx, a->obj, id, &buf); { grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs); - GRN_INT32_PUT(ctx, &buf, ri->score); + int32_t int32_score = ri->score; + GRN_INT32_PUT(ctx, &buf, int32_score); } buf.header.domain = GRN_DB_INT32; break; @@ -535,6 +577,42 @@ grn_text_atoj(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, } buf.header.domain = GRN_DB_INT32; break; + case GRN_ACCESSOR_GET_MAX : + { + grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs); + int64_t max; + max = grn_rset_recinfo_get_max(ctx, ri, a->obj); + GRN_INT64_PUT(ctx, &buf, max); + } + buf.header.domain = GRN_DB_INT64; + break; + case GRN_ACCESSOR_GET_MIN : + { + grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs); + int64_t min; + min = grn_rset_recinfo_get_min(ctx, ri, a->obj); + GRN_INT64_PUT(ctx, &buf, min); + } + buf.header.domain = GRN_DB_INT64; + break; + case GRN_ACCESSOR_GET_SUM : + { + grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs); + int64_t sum; + sum = grn_rset_recinfo_get_sum(ctx, ri, a->obj); + GRN_INT64_PUT(ctx, &buf, sum); + } + buf.header.domain = GRN_DB_INT64; + break; + case GRN_ACCESSOR_GET_AVG : + { + grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs); + double avg; + avg = grn_rset_recinfo_get_avg(ctx, ri, a->obj); + GRN_FLOAT_PUT(ctx, &buf, avg); + } + buf.header.domain = GRN_DB_FLOAT; + break; case GRN_ACCESSOR_GET_COLUMN_VALUE : if ((a->obj->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) == GRN_OBJ_COLUMN_VECTOR) { if (a->next) { @@ -1023,6 +1101,7 @@ grn_output_table_header(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, grn_obj *table, 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); @@ -1030,6 +1109,7 @@ grn_output_table_header(grn_ctx *ctx, grn_obj *outbuf, grn_output_int32(ctx, outbuf, output_type, format->nhits); } grn_output_array_close(ctx, outbuf, output_type); + } } static inline int @@ -1105,6 +1185,20 @@ count_used_n_codes(grn_ctx *ctx, grn_expr_code *start, grn_expr_code *target) return n_codes; } +static grn_bool +is_score_accessor(grn_ctx *ctx, grn_obj *obj) +{ + grn_accessor *a; + + if (obj->header.type != GRN_ACCESSOR) { + return GRN_FALSE; + } + + for (a = (grn_accessor *)obj; a->next; a = a->next) { + } + return a->action == GRN_ACCESSOR_GET_SCORE; +} + static inline void grn_output_table_column(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, @@ -1112,11 +1206,18 @@ grn_output_table_column(grn_ctx *ctx, grn_obj *outbuf, { grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2); if (column) { - grn_id range_id; + 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); - range_id = grn_obj_get_range(ctx, column); + if (column->header.type == GRN_COLUMN_INDEX) { + range_id = GRN_DB_UINT32; + } else if (is_score_accessor(ctx, column)) { + range_id = GRN_DB_INT32; + } + 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 { @@ -1139,6 +1240,46 @@ grn_output_table_column(grn_ctx *ctx, grn_obj *outbuf, } static inline void +grn_output_table_column_by_expression(grn_ctx *ctx, grn_obj *outbuf, + grn_content_type output_type, + grn_expr_code *code, + grn_expr_code *code_end, + 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); + 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_output_obj(ctx, outbuf, output_type, buf, NULL); + grn_output_null(ctx, outbuf, output_type); + + grn_output_array_close(ctx, outbuf, output_type); + } else { + grn_output_table_column(ctx, outbuf, output_type, code->value, buf); + } + break; + default : + grn_output_table_column(ctx, outbuf, output_type, code->value, buf); + break; + } +} + +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, @@ -1163,30 +1304,35 @@ grn_output_table_columns_by_expression(grn_ctx *ctx, grn_obj *outbuf, } have_comma = GRN_TRUE; - code_start_offset = previous_comma_offset + 1; if (is_first_comma) { + int n_used_codes; int code_end_offset; - int n_used_code; - grn_output_table_column(ctx, outbuf, output_type, - expr->codes[0].value, buf); + n_used_codes = count_used_n_codes(ctx, expr->codes, code - 1); + code_end_offset = code - expr->codes - n_used_codes; - code_end_offset = code - expr->codes - code_start_offset - 1; - n_used_code = count_used_n_codes(ctx, - expr->codes, - expr->codes + code_end_offset); - code_start_offset = code_end_offset - n_used_code + 1; + grn_output_table_column_by_expression(ctx, outbuf, output_type, + expr->codes, + expr->codes + code_end_offset, + buf); + code_start_offset = code_end_offset; is_first_comma = GRN_FALSE; + } else { + code_start_offset = previous_comma_offset + 1; } - grn_output_table_column(ctx, outbuf, output_type, - expr->codes[code_start_offset].value, buf); + grn_output_table_column_by_expression(ctx, outbuf, output_type, + expr->codes + code_start_offset, + code, + buf); previous_comma_offset = code - expr->codes; } if (!have_comma && expr->codes_curr > 0) { - grn_output_table_column(ctx, outbuf, output_type, - expr->codes[0].value, buf); + grn_output_table_column_by_expression(ctx, outbuf, output_type, + expr->codes, + code_end, + buf); } grn_output_array_close(ctx, outbuf, output_type); @@ -1209,7 +1355,7 @@ grn_output_table_columns_by_columns(grn_ctx *ctx, grn_obj *outbuf, grn_output_array_close(ctx, outbuf, output_type); } -static inline void +void grn_output_table_columns(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, grn_obj *table, grn_obj_format *format) @@ -1322,7 +1468,7 @@ grn_output_table_records_by_columns(grn_ctx *ctx, grn_obj *outbuf, } } -static inline void +void grn_output_table_records(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, grn_obj *table, grn_obj_format *format) @@ -1700,7 +1846,7 @@ typedef struct { } msgpack_writer_ctx; static inline int -msgpack_buffer_writer(void* data, const char* buf, unsigned int len) +msgpack_buffer_writer(void* data, const char* buf, msgpack_size_t len) { msgpack_writer_ctx *writer_ctx = (msgpack_writer_ctx *)data; return grn_bulk_write(writer_ctx->ctx, writer_ctx->buffer, buf, len); @@ -1878,8 +2024,8 @@ grn_output_envelope(grn_ctx *ctx, msgpack_pack_double(&header_packer, elapsed); if (rc != GRN_SUCCESS) { - msgpack_pack_raw(&header_packer, strlen(ctx->errbuf)); - msgpack_pack_raw_body(&header_packer, ctx->errbuf, strlen(ctx->errbuf)); + msgpack_pack_str(&header_packer, strlen(ctx->errbuf)); + msgpack_pack_str_body(&header_packer, ctx->errbuf, strlen(ctx->errbuf)); if (ctx->errfunc && ctx->errfile) { grn_obj *command = GRN_CTX_USER_DATA(ctx)->ptr; int error_detail_size; @@ -1894,34 +2040,84 @@ grn_output_envelope(grn_ctx *ctx, } msgpack_pack_array(&header_packer, error_detail_size); - msgpack_pack_raw(&header_packer, strlen(ctx->errfunc)); - msgpack_pack_raw_body(&header_packer, ctx->errfunc, strlen(ctx->errfunc)); + msgpack_pack_str(&header_packer, strlen(ctx->errfunc)); + msgpack_pack_str_body(&header_packer, ctx->errfunc, strlen(ctx->errfunc)); - msgpack_pack_raw(&header_packer, strlen(ctx->errfile)); - msgpack_pack_raw_body(&header_packer, ctx->errfile, strlen(ctx->errfile)); + msgpack_pack_str(&header_packer, strlen(ctx->errfile)); + msgpack_pack_str_body(&header_packer, ctx->errfile, strlen(ctx->errfile)); msgpack_pack_int(&header_packer, ctx->errline); if (command) { if (file) { - msgpack_pack_raw(&header_packer, strlen(file)); - msgpack_pack_raw_body(&header_packer, file, strlen(file)); + msgpack_pack_str(&header_packer, strlen(file)); + msgpack_pack_str_body(&header_packer, file, strlen(file)); } else { - msgpack_pack_raw(&header_packer, 7); - msgpack_pack_raw_body(&header_packer, "(stdin)", 7); + msgpack_pack_str(&header_packer, 7); + msgpack_pack_str_body(&header_packer, "(stdin)", 7); } msgpack_pack_int(&header_packer, line); - msgpack_pack_raw(&header_packer, GRN_TEXT_LEN(command)); - msgpack_pack_raw_body(&header_packer, GRN_TEXT_VALUE(command), GRN_TEXT_LEN(command)); + msgpack_pack_str(&header_packer, GRN_TEXT_LEN(command)); + msgpack_pack_str_body(&header_packer, GRN_TEXT_VALUE(command), GRN_TEXT_LEN(command)); } } } } #endif break; + case GRN_CONTENT_GROONGA_COMMAND_LIST : + break; case GRN_CONTENT_NONE: break; } } + +static inline grn_bool +is_output_columns_format_v1(grn_ctx *ctx, + const char *output_columns, + unsigned int output_columns_len) +{ + unsigned int i; + + /* TODO: REMOVE ME. If new output_columns handler is marked as stable, + this check is removed. We need more error checks. */ + if (grn_ctx_get_command_version(ctx) == GRN_COMMAND_VERSION_1) { + return GRN_TRUE; + } + + for (i = 0; i < output_columns_len; i++) { + switch (output_columns[i]) { + case ',' : + case '(' : + case '[' : + return GRN_FALSE; + default : + break; + } + } + + return GRN_TRUE; +} + +grn_rc +grn_output_format_set_columns(grn_ctx *ctx, grn_obj_format *format, + grn_obj *table, + const char *columns, int columns_len) +{ + grn_rc rc; + + if (is_output_columns_format_v1(ctx, columns, columns_len)) { + rc = grn_obj_columns(ctx, table, columns, columns_len, &(format->columns)); + } else { + grn_obj *variable; + GRN_EXPR_CREATE_FOR_QUERY(ctx, table, format->expression, variable); + rc = grn_expr_parse(ctx, format->expression, + columns, columns_len, NULL, + GRN_OP_MATCH, GRN_OP_AND, + GRN_EXPR_SYNTAX_OUTPUT_COLUMNS); + } + + return rc; +} |