diff options
Diffstat (limited to 'storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c')
-rw-r--r-- | storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c | 397 |
1 files changed, 374 insertions, 23 deletions
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c index 3d0499c6b5c..dcae12a131a 100644 --- a/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c +++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2013-2014 Brazil + Copyright(C) 2013-2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -16,7 +16,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../ctx_impl.h" +#include "../grn_ctx_impl.h" #ifdef GRN_WITH_MRUBY #include <mruby.h> @@ -25,14 +25,17 @@ #include <mruby/data.h> #include <mruby/string.h> #include <mruby/array.h> +#include <mruby/hash.h> -#include "../expr.h" -#include "../util.h" -#include "../mrb.h" +#include "../grn_expr.h" +#include "../grn_util.h" +#include "../grn_mrb.h" #include "mrb_accessor.h" #include "mrb_ctx.h" #include "mrb_expr.h" +#include "mrb_operator.h" #include "mrb_converter.h" +#include "mrb_options.h" static struct mrb_data_type mrb_grn_scan_info_type = { "Groonga::ScanInfo", @@ -98,17 +101,35 @@ mrb_grn_expr_code_initialize(mrb_state *mrb, mrb_value self) static mrb_value mrb_grn_scan_info_put_index(mrb_state *mrb, mrb_value self) { + grn_ctx *ctx = (grn_ctx *)mrb->ud; + scan_info *si; + mrb_value mrb_index; int sid; int32_t weight; - scan_info *si; - grn_ctx *ctx = (grn_ctx *)mrb->ud; + mrb_value mrb_scorer; + mrb_value mrb_scorer_args_expr; + int32_t scorer_args_expr_offset; grn_obj *index; - mrb_value mrb_index; - - mrb_get_args(mrb, "oii", &mrb_index, &sid, &weight); + grn_obj *scorer = NULL; + grn_obj *scorer_args_expr = NULL; + + mrb_get_args(mrb, "oiiooi", + &mrb_index, &sid, &weight, + &mrb_scorer, + &mrb_scorer_args_expr, + &scorer_args_expr_offset); si = DATA_PTR(self); index = DATA_PTR(mrb_index); - grn_scan_info_put_index(ctx, si, index, sid, weight); + if (!mrb_nil_p(mrb_scorer)) { + scorer = DATA_PTR(mrb_scorer); + } + if (!mrb_nil_p(mrb_scorer_args_expr)) { + scorer_args_expr = DATA_PTR(mrb_scorer_args_expr); + } + grn_scan_info_put_index(ctx, si, index, sid, weight, + scorer, + scorer_args_expr, + scorer_args_expr_offset); return self; } @@ -120,17 +141,19 @@ mrb_grn_scan_info_get_op(mrb_state *mrb, mrb_value self) si = DATA_PTR(self); op = grn_scan_info_get_op(si); - return mrb_fixnum_value(op); + return grn_mrb_value_from_operator(mrb, op); } static mrb_value mrb_grn_scan_info_set_op(mrb_state *mrb, mrb_value self) { scan_info *si; + mrb_value mrb_op; grn_operator op; - mrb_get_args(mrb, "i", &op); + mrb_get_args(mrb, "o", &mrb_op, &op); si = DATA_PTR(self); + op = grn_mrb_value_to_operator(mrb, mrb_op); grn_scan_info_set_op(si, op); return self; } @@ -190,10 +213,12 @@ static mrb_value mrb_grn_scan_info_set_logical_op(mrb_state *mrb, mrb_value self) { scan_info *si; + mrb_value mrb_logical_op; grn_operator logical_op; - mrb_get_args(mrb, "i", &logical_op); + mrb_get_args(mrb, "o", &mrb_logical_op); si = DATA_PTR(self); + logical_op = grn_mrb_value_to_operator(mrb, mrb_logical_op); grn_scan_info_set_logical_op(si, logical_op); return self; } @@ -206,7 +231,7 @@ mrb_grn_scan_info_get_logical_op(mrb_state *mrb, mrb_value self) si = DATA_PTR(self); logical_op = grn_scan_info_get_logical_op(si); - return mrb_fixnum_value(logical_op); + return grn_mrb_value_from_operator(mrb, logical_op); } static mrb_value @@ -287,11 +312,86 @@ mrb_grn_scan_info_push_arg(mrb_state *mrb, mrb_value self) } static mrb_value +mrb_grn_expr_code_inspect(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_expr_code *code; + mrb_value inspected; + + code = DATA_PTR(self); + + inspected = mrb_str_buf_new(mrb, 48); + + mrb_str_cat_lit(mrb, inspected, "#<"); + mrb_str_cat_cstr(mrb, inspected, mrb_obj_classname(mrb, self)); + mrb_str_cat_lit(mrb, inspected, ":"); + mrb_str_concat(mrb, inspected, mrb_ptr_to_str(mrb, mrb_cptr(self))); + + { + int32_t weight; + uint32_t offset; + + weight = grn_expr_code_get_weight(ctx, DATA_PTR(self), &offset); + + mrb_str_cat_lit(mrb, inspected, " weight="); + mrb_str_concat(mrb, inspected, + mrb_funcall(mrb, + mrb_fixnum_value(weight), + "inspect", + 0)); + mrb_str_cat_lit(mrb, inspected, ", offset="); + mrb_str_concat(mrb, inspected, + mrb_funcall(mrb, + mrb_fixnum_value(offset), + "inspect", + 0)); + } + + mrb_str_cat_lit(mrb, inspected, ", modify="); + mrb_str_concat(mrb, inspected, + mrb_funcall(mrb, + mrb_fixnum_value(code->modify), + "inspect", + 0)); + + mrb_str_cat_lit(mrb, inspected, ", op="); + mrb_str_concat(mrb, inspected, + mrb_funcall(mrb, + grn_mrb_value_from_operator(mrb, code->op), + "inspect", + 0)); + + mrb_str_cat_lit(mrb, inspected, ", flags="); + mrb_str_concat(mrb, inspected, + mrb_funcall(mrb, + mrb_fixnum_value(code->flags), + "inspect", + 0)); + + mrb_str_cat_lit(mrb, inspected, ", value="); + mrb_str_concat(mrb, inspected, + mrb_funcall(mrb, + grn_mrb_value_from_grn_obj(mrb, code->value), + "inspect", + 0)); + + mrb_str_cat_lit(mrb, inspected, ">"); + + return inspected; +} + +static mrb_value mrb_grn_expr_code_get_weight(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; + int32_t weight; + uint32_t offset; + mrb_value mrb_values[2]; - return mrb_fixnum_value(grn_expr_code_get_weight(ctx, DATA_PTR(self))); + weight = grn_expr_code_get_weight(ctx, DATA_PTR(self), &offset); + mrb_values[0] = mrb_fixnum_value(weight); + mrb_values[1] = mrb_fixnum_value(offset); + return mrb_ary_new_from_values(mrb, 2, mrb_values); } static mrb_value @@ -309,7 +409,7 @@ mrb_grn_expr_code_get_op(mrb_state *mrb, mrb_value self) grn_expr_code *expr_code; expr_code = DATA_PTR(self); - return mrb_fixnum_value(expr_code->op); + return grn_mrb_value_from_operator(mrb, expr_code->op); } static mrb_value @@ -322,6 +422,41 @@ mrb_grn_expr_code_get_flags(mrb_state *mrb, mrb_value self) } static mrb_value +mrb_grn_expression_singleton_create(mrb_state *mrb, mrb_value klass) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + mrb_value mrb_expr; + mrb_value mrb_table; + mrb_value mrb_new_arguments[1]; + grn_obj *expr, *variable = NULL; + + mrb_get_args(mrb, "o", &mrb_table); + if (mrb_nil_p(mrb_table)) { + expr = grn_expr_create(ctx, NULL, 0); + } else { + grn_obj *table = DATA_PTR(mrb_table); + GRN_EXPR_CREATE_FOR_QUERY(ctx, table, expr, variable); + } + + if (!expr) { + grn_mrb_ctx_check(mrb); + return mrb_nil_value(); + } + + mrb_new_arguments[0] = mrb_cptr_value(mrb, expr); + mrb_expr = mrb_obj_new(mrb, mrb_class_ptr(klass), 1, mrb_new_arguments); + { + mrb_value mrb_variable = mrb_nil_value(); + if (variable) { + mrb_variable = grn_mrb_value_from_grn_obj(mrb, variable); + } + mrb_iv_set(mrb, mrb_expr, mrb_intern_lit(mrb, "@variable"), mrb_variable); + } + + return mrb_expr; +} + +static mrb_value mrb_grn_expression_initialize(mrb_state *mrb, mrb_value self) { mrb_value mrb_expression_ptr; @@ -409,6 +544,175 @@ mrb_grn_expression_allocate_constant(mrb_state *mrb, mrb_value self) return grn_mrb_value_from_grn_obj(mrb, grn_object); } +static mrb_value +mrb_grn_expression_parse(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_obj *expr; + char *query; + mrb_int query_size; + grn_obj *default_column = NULL; + grn_operator default_mode = GRN_OP_MATCH; + grn_operator default_operator = GRN_OP_AND; + grn_expr_flags flags = GRN_EXPR_SYNTAX_SCRIPT; + mrb_value mrb_options = mrb_nil_value(); + + expr = DATA_PTR(self); + mrb_get_args(mrb, "s|H", &query, &query_size, &mrb_options); + + if (!mrb_nil_p(mrb_options)) { + mrb_value mrb_flags; + + mrb_flags = grn_mrb_options_get_lit(mrb, mrb_options, "flags"); + if (!mrb_nil_p(mrb_flags)) { + flags = mrb_fixnum(mrb_flags); + } + } + + grn_expr_parse(ctx, expr, query, query_size, default_column, + default_mode, default_operator, flags); + grn_mrb_ctx_check(mrb); + + return mrb_nil_value(); +} + +static mrb_value +mrb_grn_expression_append_object(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_obj *expr; + mrb_value mrb_object; + grn_obj *object; + mrb_value mrb_op; + grn_operator op; + int n_args; + + expr = DATA_PTR(self); + mrb_get_args(mrb, "ooi", &mrb_object, &mrb_op, &n_args); + + object = DATA_PTR(mrb_object); + op = grn_mrb_value_to_operator(mrb, mrb_op); + grn_expr_append_obj(ctx, expr, object, op, n_args); + grn_mrb_ctx_check(mrb); + + return mrb_nil_value(); +} + +static mrb_value +mrb_grn_expression_append_constant(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_obj *expr; + mrb_value mrb_constant; + mrb_value mrb_op; + grn_operator op; + int n_args; + + expr = DATA_PTR(self); + mrb_get_args(mrb, "ooi", &mrb_constant, &mrb_op, &n_args); + + op = grn_mrb_value_to_operator(mrb, mrb_op); + switch (mrb_type(mrb_constant)) { + case MRB_TT_FALSE : + if (mrb_nil_p(mrb_constant)) { + grn_obj constant; + GRN_VOID_INIT(&constant); + grn_expr_append_const(ctx, expr, &constant, op, n_args); + GRN_OBJ_FIN(ctx, &constant); + } else { + grn_obj constant; + GRN_BOOL_INIT(&constant, 0); + GRN_BOOL_SET(ctx, &constant, GRN_FALSE); + grn_expr_append_const(ctx, expr, &constant, op, n_args); + GRN_OBJ_FIN(ctx, &constant); + } + break; + case MRB_TT_TRUE : + { + grn_obj constant; + GRN_BOOL_INIT(&constant, 0); + GRN_BOOL_SET(ctx, &constant, GRN_TRUE); + grn_expr_append_const(ctx, expr, &constant, op, n_args); + GRN_OBJ_FIN(ctx, &constant); + } + break; + case MRB_TT_FIXNUM : + grn_expr_append_const_int(ctx, expr, mrb_fixnum(mrb_constant), op, n_args); + break; + case MRB_TT_SYMBOL : + { + const char *value; + mrb_int value_length; + + value = mrb_sym2name_len(mrb, mrb_symbol(mrb_constant), &value_length); + grn_expr_append_const_str(ctx, expr, value, value_length, op, n_args); + } + break; + case MRB_TT_FLOAT : + { + grn_obj constant; + GRN_FLOAT_INIT(&constant, 0); + GRN_FLOAT_SET(ctx, &constant, mrb_float(mrb_constant)); + grn_expr_append_const(ctx, expr, &constant, op, n_args); + GRN_OBJ_FIN(ctx, &constant); + } + break; + case MRB_TT_STRING : + grn_expr_append_const_str(ctx, expr, + RSTRING_PTR(mrb_constant), + RSTRING_LEN(mrb_constant), + op, n_args); + break; + default : + { + struct RClass *klass; + + klass = mrb_class(mrb, mrb_constant); + if (klass == ctx->impl->mrb.builtin.time_class) { + grn_obj constant; + mrb_value mrb_sec; + mrb_value mrb_usec; + + mrb_sec = mrb_funcall(mrb, mrb_constant, "to_i", 0); + mrb_usec = mrb_funcall(mrb, mrb_constant, "usec", 0); + GRN_TIME_INIT(&constant, 0); + GRN_TIME_SET(ctx, &constant, + GRN_TIME_PACK(mrb_fixnum(mrb_sec), mrb_fixnum(mrb_usec))); + grn_expr_append_const(ctx, expr, &constant, op, n_args); + GRN_OBJ_FIN(ctx, &constant); + } else { + mrb_raisef(mrb, E_ARGUMENT_ERROR, + "unsupported constant to append to expression: %S", + mrb_constant); + } + } + break; + } + + grn_mrb_ctx_check(mrb); + + return mrb_nil_value(); +} + +static mrb_value +mrb_grn_expression_append_operator(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_obj *expr; + mrb_value mrb_op; + int n_args; + grn_operator op; + + expr = DATA_PTR(self); + mrb_get_args(mrb, "oi", &mrb_op, &n_args); + + op = grn_mrb_value_to_operator(mrb, mrb_op); + grn_expr_append_op(ctx, expr, op, n_args); + grn_mrb_ctx_check(mrb); + + return mrb_nil_value(); +} + void grn_mrb_expr_init(grn_ctx *ctx) { @@ -422,7 +726,7 @@ grn_mrb_expr_init(grn_ctx *ctx) mrb_define_method(mrb, klass, "initialize", mrb_grn_scan_info_initialize, MRB_ARGS_REQ(1)); mrb_define_method(mrb, klass, "put_index", - mrb_grn_scan_info_put_index, MRB_ARGS_REQ(3)); + mrb_grn_scan_info_put_index, MRB_ARGS_REQ(6)); mrb_define_method(mrb, klass, "op", mrb_grn_scan_info_get_op, MRB_ARGS_NONE()); mrb_define_method(mrb, klass, "op=", @@ -457,6 +761,8 @@ grn_mrb_expr_init(grn_ctx *ctx) MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA); mrb_define_method(mrb, klass, "initialize", mrb_grn_expr_code_initialize, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "inspect", + mrb_grn_expr_code_inspect, MRB_ARGS_NONE()); mrb_define_method(mrb, klass, "weight", mrb_grn_expr_code_get_weight, MRB_ARGS_NONE()); mrb_define_method(mrb, klass, "value", @@ -466,8 +772,21 @@ grn_mrb_expr_init(grn_ctx *ctx) mrb_define_method(mrb, klass, "flags", mrb_grn_expr_code_get_flags, MRB_ARGS_NONE()); + { + struct RClass *expression_code_class = klass; + struct RClass *flags_module; + flags_module = mrb_define_module_under(mrb, expression_code_class, "Flags"); + mrb_define_const(mrb, flags_module, "RELATIONAL_EXPRESSION", + mrb_fixnum_value(GRN_EXPR_CODE_RELATIONAL_EXPRESSION)); + } + klass = mrb_define_class_under(mrb, module, "Expression", object_class); MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA); + + mrb_define_singleton_method(mrb, (struct RObject *)klass, "create", + mrb_grn_expression_singleton_create, + MRB_ARGS_REQ(1)); + mrb_define_method(mrb, klass, "initialize", mrb_grn_expression_initialize, MRB_ARGS_REQ(1)); mrb_define_method(mrb, klass, "codes", @@ -479,10 +798,15 @@ grn_mrb_expr_init(grn_ctx *ctx) mrb_define_method(mrb, klass, "allocate_constant", mrb_grn_expression_allocate_constant, MRB_ARGS_REQ(1)); - grn_mrb_load(ctx, "expression.rb"); - grn_mrb_load(ctx, "scan_info.rb"); - grn_mrb_load(ctx, "scan_info_data.rb"); - grn_mrb_load(ctx, "scan_info_builder.rb"); + mrb_define_method(mrb, klass, "parse", + mrb_grn_expression_parse, MRB_ARGS_ARG(1, 1)); + + mrb_define_method(mrb, klass, "append_object", + mrb_grn_expression_append_object, MRB_ARGS_REQ(2)); + mrb_define_method(mrb, klass, "append_constant", + mrb_grn_expression_append_constant, MRB_ARGS_REQ(3)); + mrb_define_method(mrb, klass, "append_operator", + mrb_grn_expression_append_operator, MRB_ARGS_REQ(2)); } scan_info ** @@ -501,7 +825,7 @@ grn_mrb_scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, mrb_expression = grn_mrb_value_from_grn_obj(mrb, expr); mrb_sis = mrb_funcall(mrb, mrb_expression, "build_scan_info", 2, - mrb_fixnum_value(op), + grn_mrb_value_from_operator(mrb, op), mrb_fixnum_value(size)); if (mrb_nil_p(mrb_sis)) { @@ -535,4 +859,31 @@ exit: return sis; } + +unsigned int +grn_mrb_expr_estimate_size(grn_ctx *ctx, grn_obj *expr, grn_obj *table) +{ + grn_mrb_data *data = &(ctx->impl->mrb); + mrb_state *mrb = data->state; + mrb_value mrb_expression; + mrb_value mrb_table; + mrb_value mrb_size; + unsigned int size; + int arena_index; + + arena_index = mrb_gc_arena_save(mrb); + + mrb_expression = grn_mrb_value_from_grn_obj(mrb, expr); + mrb_table = grn_mrb_value_from_grn_obj(mrb, table); + mrb_size = mrb_funcall(mrb, mrb_expression, "estimate_size", 1, mrb_table); + if (mrb->exc) { + size = grn_table_size(ctx, table); + } else { + size = mrb_fixnum(mrb_size); + } + + mrb_gc_arena_restore(mrb, arena_index); + + return size; +} #endif |