summaryrefslogtreecommitdiffstats
path: root/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c')
-rw-r--r--storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c1079
1 files changed, 1079 insertions, 0 deletions
diff --git a/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c b/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c
new file mode 100644
index 00000000..2b8f6a04
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/lib/mrb/mrb_expr.c
@@ -0,0 +1,1079 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+ Copyright(C) 2013-2017 Brazil
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+#include "../grn_ctx_impl.h"
+
+#ifdef GRN_WITH_MRUBY
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/variable.h>
+#include <mruby/data.h>
+#include <mruby/string.h>
+#include <mruby/array.h>
+#include <mruby/hash.h>
+
+#include "../grn_expr.h"
+#include "../grn_proc.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",
+ NULL
+};
+static struct mrb_data_type mrb_grn_expr_code_type = {
+ "Groonga::ExpressionCode",
+ NULL
+};
+static struct mrb_data_type mrb_grn_expression_type = {
+ "Groonga::Expression",
+ NULL
+};
+
+static mrb_value
+mrb_grn_scan_info_new(mrb_state *mrb, scan_info *scan_info)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ struct RClass *module = ctx->impl->mrb.module;
+ struct RClass *klass;
+ mrb_value mrb_scan_info;
+
+ mrb_scan_info = mrb_cptr_value(mrb, scan_info);
+ klass = mrb_class_get_under(mrb, module, "ScanInfo");
+ return mrb_obj_new(mrb, klass, 1, &mrb_scan_info);
+}
+
+static mrb_value
+mrb_grn_expr_code_new(mrb_state *mrb, grn_expr_code *code)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ struct RClass *module = ctx->impl->mrb.module;
+ struct RClass *klass;
+ mrb_value mrb_code;
+
+ mrb_code = mrb_cptr_value(mrb, code);
+ klass = mrb_class_get_under(mrb, module, "ExpressionCode");
+ return mrb_obj_new(mrb, klass, 1, &mrb_code);
+}
+
+static mrb_value
+mrb_grn_scan_info_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_ptr);
+ DATA_TYPE(self) = &mrb_grn_scan_info_type;
+ DATA_PTR(self) = mrb_cptr(mrb_ptr);
+ return self;
+}
+
+static mrb_value
+mrb_grn_expr_code_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mrb_code;
+
+ mrb_get_args(mrb, "o", &mrb_code);
+ DATA_TYPE(self) = &mrb_grn_expr_code_type;
+ DATA_PTR(self) = mrb_cptr(mrb_code);
+ return 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;
+ mrb_int sid;
+ mrb_int weight;
+ mrb_value mrb_scorer;
+ mrb_value mrb_scorer_args_expr;
+ mrb_int scorer_args_expr_offset;
+ grn_obj *index;
+ 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);
+ 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;
+}
+
+static mrb_value
+mrb_grn_scan_info_get_op(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ grn_operator op;
+
+ si = DATA_PTR(self);
+ op = grn_scan_info_get_op(si);
+ 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, "o", &mrb_op);
+ si = DATA_PTR(self);
+ op = grn_mrb_value_to_operator(mrb, mrb_op);
+ grn_scan_info_set_op(si, op);
+ return self;
+}
+
+static mrb_value
+mrb_grn_scan_info_set_end(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ mrb_int end;
+
+ mrb_get_args(mrb, "i", &end);
+ si = DATA_PTR(self);
+ grn_scan_info_set_end(si, end);
+ return self;
+}
+
+static mrb_value
+mrb_grn_scan_info_set_query(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ mrb_value mrb_query;
+
+ mrb_get_args(mrb, "o", &mrb_query);
+ si = DATA_PTR(self);
+ if (mrb_nil_p(mrb_query)) {
+ grn_scan_info_set_query(si, NULL);
+ } else {
+ grn_scan_info_set_query(si, DATA_PTR(mrb_query));
+ }
+ return self;
+}
+
+static mrb_value
+mrb_grn_scan_info_set_flags(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ mrb_int flags;
+
+ mrb_get_args(mrb, "i", &flags);
+ si = DATA_PTR(self);
+ grn_scan_info_set_flags(si, flags);
+ return self;
+}
+
+static mrb_value
+mrb_grn_scan_info_get_flags(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ int flags;
+
+ si = DATA_PTR(self);
+ flags = grn_scan_info_get_flags(si);
+ return mrb_fixnum_value(flags);
+}
+
+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, "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;
+}
+
+static mrb_value
+mrb_grn_scan_info_get_logical_op(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ grn_operator logical_op;
+
+ si = DATA_PTR(self);
+ logical_op = grn_scan_info_get_logical_op(si);
+ return grn_mrb_value_from_operator(mrb, logical_op);
+}
+
+static mrb_value
+mrb_grn_scan_info_set_max_interval(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ mrb_int max_interval;
+
+ mrb_get_args(mrb, "i", &max_interval);
+ si = DATA_PTR(self);
+ grn_scan_info_set_max_interval(si, max_interval);
+ return self;
+}
+
+static mrb_value
+mrb_grn_scan_info_get_max_interval(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ int max_interval;
+
+ si = DATA_PTR(self);
+ max_interval = grn_scan_info_get_max_interval(si);
+ return mrb_fixnum_value(max_interval);
+}
+
+static mrb_value
+mrb_grn_scan_info_set_similarity_threshold(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ mrb_int similarity_threshold;
+
+ mrb_get_args(mrb, "i", &similarity_threshold);
+ si = DATA_PTR(self);
+ grn_scan_info_set_similarity_threshold(si, similarity_threshold);
+ return self;
+}
+
+static mrb_value
+mrb_grn_scan_info_get_similarity_threshold(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ int similarity_threshold;
+
+ si = DATA_PTR(self);
+ similarity_threshold = grn_scan_info_get_similarity_threshold(si);
+ return mrb_fixnum_value(similarity_threshold);
+}
+
+static mrb_value
+mrb_grn_scan_info_get_arg(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ scan_info *si;
+ mrb_int index;
+ grn_obj *arg;
+
+ mrb_get_args(mrb, "i", &index);
+
+ si = DATA_PTR(self);
+ arg = grn_scan_info_get_arg(ctx, si, index);
+
+ return grn_mrb_value_from_grn_obj(mrb, arg);
+}
+
+static mrb_value
+mrb_grn_scan_info_push_arg(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ mrb_value mrb_arg;
+ grn_bool success;
+
+ mrb_get_args(mrb, "o", &mrb_arg);
+
+ si = DATA_PTR(self);
+ success = grn_scan_info_push_arg(si, DATA_PTR(mrb_arg));
+
+ return mrb_bool_value(success);
+}
+
+static mrb_value
+mrb_grn_scan_info_get_start_position(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ int start_position;
+
+ si = DATA_PTR(self);
+ start_position = grn_scan_info_get_start_position(si);
+ return mrb_fixnum_value(start_position);
+}
+
+static mrb_value
+mrb_grn_scan_info_set_start_position(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+ mrb_int start_position;
+
+ mrb_get_args(mrb, "i", &start_position);
+ si = DATA_PTR(self);
+ grn_scan_info_set_start_position(si, start_position);
+ return self;
+}
+
+static mrb_value
+mrb_grn_scan_info_reset_position(mrb_state *mrb, mrb_value self)
+{
+ scan_info *si;
+
+ si = DATA_PTR(self);
+ grn_scan_info_reset_position(si);
+ return 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, ", n_args=");
+ mrb_str_concat(mrb, inspected,
+ mrb_funcall(mrb,
+ mrb_fixnum_value(code->nargs),
+ "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];
+
+ 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
+mrb_grn_expr_code_get_value(mrb_state *mrb, mrb_value self)
+{
+ grn_expr_code *expr_code;
+
+ expr_code = DATA_PTR(self);
+ return grn_mrb_value_from_grn_obj(mrb, expr_code->value);
+}
+
+static mrb_value
+mrb_grn_expr_code_get_n_args(mrb_state *mrb, mrb_value self)
+{
+ grn_expr_code *expr_code;
+
+ expr_code = DATA_PTR(self);
+ return mrb_fixnum_value(expr_code->nargs);
+}
+
+static mrb_value
+mrb_grn_expr_code_get_op(mrb_state *mrb, mrb_value self)
+{
+ grn_expr_code *expr_code;
+
+ expr_code = DATA_PTR(self);
+ return grn_mrb_value_from_operator(mrb, expr_code->op);
+}
+
+static mrb_value
+mrb_grn_expr_code_get_flags(mrb_state *mrb, mrb_value self)
+{
+ grn_expr_code *expr_code;
+
+ expr_code = DATA_PTR(self);
+ return mrb_fixnum_value(expr_code->flags);
+}
+
+static mrb_value
+mrb_grn_expr_code_get_modify(mrb_state *mrb, mrb_value self)
+{
+ grn_expr_code *expr_code;
+
+ expr_code = DATA_PTR(self);
+ return mrb_fixnum_value(expr_code->modify);
+}
+
+static mrb_value
+mrb_grn_expression_class_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;
+
+ mrb_get_args(mrb, "o", &mrb_expression_ptr);
+ DATA_TYPE(self) = &mrb_grn_expression_type;
+ DATA_PTR(self) = mrb_cptr(mrb_expression_ptr);
+ return self;
+}
+
+static mrb_value
+mrb_grn_expression_is_empty(mrb_state *mrb, mrb_value self)
+{
+ grn_expr *expr;
+
+ expr = DATA_PTR(self);
+ return mrb_bool_value(expr->codes_curr == 0);
+}
+
+static mrb_value
+mrb_grn_expression_codes(mrb_state *mrb, mrb_value self)
+{
+ grn_expr *expr;
+ mrb_value mrb_codes;
+ int i;
+
+ expr = DATA_PTR(self);
+ mrb_codes = mrb_ary_new_capa(mrb, expr->codes_curr);
+ for (i = 0; i < expr->codes_curr; i++) {
+ grn_expr_code *code = expr->codes + i;
+ mrb_ary_push(mrb, mrb_codes, mrb_grn_expr_code_new(mrb, code));
+ }
+
+ return mrb_codes;
+}
+
+static mrb_value
+mrb_grn_expression_array_reference(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *expr;
+ mrb_value mrb_key;
+ grn_obj *var;
+
+ mrb_get_args(mrb, "o", &mrb_key);
+
+ expr = DATA_PTR(self);
+ switch (mrb_type(mrb_key)) {
+ case MRB_TT_SYMBOL :
+ {
+ const char *name;
+ mrb_int name_length;
+
+ name = mrb_sym2name_len(mrb, mrb_symbol(mrb_key), &name_length);
+ var = grn_expr_get_var(ctx, expr, name, name_length);
+ }
+ break;
+ case MRB_TT_STRING :
+ var = grn_expr_get_var(ctx, expr,
+ RSTRING_PTR(mrb_key), RSTRING_LEN(mrb_key));
+ break;
+ case MRB_TT_FIXNUM :
+ var = grn_expr_get_var_by_offset(ctx, expr, mrb_fixnum(mrb_key));
+ break;
+ default :
+ mrb_raisef(mrb, E_ARGUMENT_ERROR,
+ "key must be Symbol, String or Fixnum: %S",
+ mrb_key);
+ break;
+ }
+
+ return grn_mrb_value_from_grn_obj(mrb, var);
+}
+
+static mrb_value
+mrb_grn_expression_set_condition(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *expr;
+ mrb_value mrb_condition;
+ grn_obj *condition_ptr;
+
+ mrb_get_args(mrb, "o", &mrb_condition);
+
+ expr = DATA_PTR(self);
+ condition_ptr = grn_expr_get_or_add_var(ctx,
+ expr,
+ GRN_SELECT_INTERNAL_VAR_CONDITION,
+ GRN_SELECT_INTERNAL_VAR_CONDITION_LEN);
+ GRN_OBJ_FIN(ctx, condition_ptr);
+ GRN_PTR_INIT(condition_ptr, 0, GRN_DB_OBJECT);
+ GRN_PTR_SET(ctx, condition_ptr, GRN_MRB_DATA_PTR(mrb_condition));
+
+ return mrb_nil_value();
+}
+
+static mrb_value
+mrb_grn_expression_take_object(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *expr;
+ mrb_value mrb_object;
+ grn_obj *grn_object;
+
+ mrb_get_args(mrb, "o", &mrb_object);
+ expr = DATA_PTR(self);
+ grn_object = DATA_PTR(mrb_object);
+ grn_expr_take_obj(ctx, expr, grn_object);
+
+ return mrb_object;
+}
+
+static mrb_value
+mrb_grn_expression_allocate_constant(mrb_state *mrb, mrb_value self)
+{
+ grn_ctx *ctx = (grn_ctx *)mrb->ud;
+ grn_obj *expr;
+ mrb_value mrb_object;
+ grn_obj *grn_object;
+
+ mrb_get_args(mrb, "o", &mrb_object);
+ expr = DATA_PTR(self);
+
+ switch (mrb_type(mrb_object)) {
+ case MRB_TT_STRING:
+ grn_object = grn_expr_alloc_const(ctx, expr);
+ if (!grn_object) {
+ grn_mrb_ctx_check(mrb);
+ }
+ GRN_TEXT_INIT(grn_object, 0);
+ GRN_TEXT_SET(ctx, grn_object,
+ RSTRING_PTR(mrb_object), RSTRING_LEN(mrb_object));
+ break;
+ case MRB_TT_TRUE:
+ grn_object = grn_expr_alloc_const(ctx, expr);
+ if (!grn_object) {
+ grn_mrb_ctx_check(mrb);
+ }
+ GRN_BOOL_INIT(grn_object, 0);
+ GRN_BOOL_SET(ctx, grn_object, GRN_TRUE);
+ break;
+ default:
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "unsupported type: %S", mrb_object);
+ break;
+ }
+
+ 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_default_column;
+ mrb_value mrb_flags;
+
+ mrb_default_column =
+ grn_mrb_options_get_lit(mrb, mrb_options, "default_column");
+ default_column = GRN_MRB_DATA_PTR(mrb_default_column);
+
+ 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;
+ mrb_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;
+ mrb_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;
+ mrb_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)
+{
+ mrb_state *mrb = ctx->impl->mrb.state;
+ struct RClass *module = ctx->impl->mrb.module;
+ struct RClass *object_class = ctx->impl->mrb.object_class;
+ struct RClass *klass;
+
+ klass = mrb_define_class_under(mrb, module, "ScanInfo", mrb->object_class);
+ MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
+ 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(6));
+ mrb_define_method(mrb, klass, "op",
+ mrb_grn_scan_info_get_op, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "op=",
+ mrb_grn_scan_info_set_op, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "end=",
+ mrb_grn_scan_info_set_end, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "query=",
+ mrb_grn_scan_info_set_query, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "flags",
+ mrb_grn_scan_info_get_flags, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "flags=",
+ mrb_grn_scan_info_set_flags, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "logical_op",
+ mrb_grn_scan_info_get_logical_op, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "logical_op=",
+ mrb_grn_scan_info_set_logical_op, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "max_interval",
+ mrb_grn_scan_info_get_max_interval, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "max_interval=",
+ mrb_grn_scan_info_set_max_interval, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "similarity_threshold",
+ mrb_grn_scan_info_get_similarity_threshold, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "similarity_threshold=",
+ mrb_grn_scan_info_set_similarity_threshold, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "get_arg",
+ mrb_grn_scan_info_get_arg, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "push_arg",
+ mrb_grn_scan_info_push_arg, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "start_position",
+ mrb_grn_scan_info_get_start_position, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "start_position=",
+ mrb_grn_scan_info_set_start_position, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "reset_position",
+ mrb_grn_scan_info_reset_position, MRB_ARGS_NONE());
+
+ klass = mrb_define_class_under(mrb, module,
+ "ExpressionCode", mrb->object_class);
+ 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",
+ mrb_grn_expr_code_get_value, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "n_args",
+ mrb_grn_expr_code_get_n_args, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "op",
+ mrb_grn_expr_code_get_op, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "flags",
+ mrb_grn_expr_code_get_flags, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "modify",
+ mrb_grn_expr_code_get_modify, 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);
+
+#define DEFINE_FLAG(name) \
+ mrb_define_const(mrb, klass, \
+ #name, \
+ mrb_fixnum_value(GRN_EXPR_ ## name))
+
+ DEFINE_FLAG(SYNTAX_QUERY);
+ DEFINE_FLAG(SYNTAX_SCRIPT);
+ DEFINE_FLAG(SYNTAX_OUTPUT_COLUMNS);
+ DEFINE_FLAG(ALLOW_PRAGMA);
+ DEFINE_FLAG(ALLOW_COLUMN);
+ DEFINE_FLAG(ALLOW_UPDATE);
+ DEFINE_FLAG(ALLOW_LEADING_NOT);
+
+#undef DEFINE_FLAG
+
+ mrb_define_class_method(mrb, klass, "create",
+ mrb_grn_expression_class_create,
+ MRB_ARGS_REQ(1));
+
+ mrb_define_method(mrb, klass, "initialize",
+ mrb_grn_expression_initialize, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "empty?",
+ mrb_grn_expression_is_empty, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "codes",
+ mrb_grn_expression_codes, MRB_ARGS_NONE());
+ mrb_define_method(mrb, klass, "[]",
+ mrb_grn_expression_array_reference, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "condition=",
+ mrb_grn_expression_set_condition, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "take_object",
+ mrb_grn_expression_take_object, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, klass, "allocate_constant",
+ mrb_grn_expression_allocate_constant, MRB_ARGS_REQ(1));
+
+ 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));
+}
+
+grn_obj *
+grn_mrb_expr_rewrite(grn_ctx *ctx, grn_obj *expr)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ mrb_value mrb_expression;
+ mrb_value mrb_rewritten_expression;
+ grn_obj *rewritten_expression = NULL;
+ int arena_index;
+
+ arena_index = mrb_gc_arena_save(mrb);
+
+ mrb_expression = grn_mrb_value_from_grn_obj(mrb, expr);
+ mrb_rewritten_expression = mrb_funcall(mrb, mrb_expression, "rewrite", 0);
+ if (mrb_nil_p(mrb_rewritten_expression)) {
+ goto exit;
+ }
+
+ if (mrb_type(mrb_rewritten_expression) == MRB_TT_EXCEPTION) {
+ mrb->exc = mrb_obj_ptr(mrb_rewritten_expression);
+ mrb_print_error(mrb);
+ goto exit;
+ }
+
+ rewritten_expression = DATA_PTR(mrb_rewritten_expression);
+
+exit:
+ mrb_gc_arena_restore(mrb, arena_index);
+
+ return rewritten_expression;
+}
+
+scan_info **
+grn_mrb_scan_info_build(grn_ctx *ctx,
+ grn_obj *expr,
+ int *n,
+ grn_operator op,
+ grn_bool record_exist)
+{
+ grn_mrb_data *data = &(ctx->impl->mrb);
+ mrb_state *mrb = data->state;
+ mrb_value mrb_expression;
+ mrb_value mrb_sis;
+ scan_info **sis = NULL;
+ int i;
+ int arena_index;
+
+ arena_index = mrb_gc_arena_save(mrb);
+
+ mrb_expression = grn_mrb_value_from_grn_obj(mrb, expr);
+ mrb_sis = mrb_funcall(mrb, mrb_expression, "build_scan_info", 2,
+ grn_mrb_value_from_operator(mrb, op),
+ mrb_bool_value(record_exist));
+
+ if (mrb_nil_p(mrb_sis)) {
+ goto exit;
+ }
+
+ if (mrb_type(mrb_sis) == MRB_TT_EXCEPTION) {
+ mrb->exc = mrb_obj_ptr(mrb_sis);
+ mrb_print_error(mrb);
+ goto exit;
+ }
+
+ *n = RARRAY_LEN(mrb_sis);
+ sis = GRN_MALLOCN(scan_info *, *n);
+ for (i = 0; i < *n; i++) {
+ mrb_value mrb_si;
+ mrb_value mrb_si_data;
+ scan_info *si;
+ int start;
+
+ mrb_si_data = RARRAY_PTR(mrb_sis)[i];
+ start = mrb_fixnum(mrb_funcall(mrb, mrb_si_data, "start", 0));
+ si = grn_scan_info_open(ctx, start);
+ mrb_si = mrb_grn_scan_info_new(mrb, si);
+ mrb_funcall(mrb, mrb_si, "apply", 1, mrb_si_data);
+ sis[i] = si;
+ }
+
+exit:
+ mrb_gc_arena_restore(mrb, arena_index);
+
+ 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