1 /* -*- c-basic-offset: 2 -*- */
2 /*
3   Copyright(C) 2010-2017 Brazil
4 
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License version 2.1 as published by the Free Software Foundation.
8 
9   This library is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   Lesser General Public License for more details.
13 
14   You should have received a copy of the GNU Lesser General Public
15   License along with this library; if not, write to the Free Software
16   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1335  USA
17 */
18 
19 #include "grn.h"
20 #include "grn_ctx_impl.h"
21 #include "grn_expr_executor.h"
22 
23 #ifdef GRN_WITH_ONIGMO
24 # define GRN_SUPPORT_REGEXP
25 #endif
26 
27 #ifdef GRN_SUPPORT_REGEXP
28 # include "grn_normalizer.h"
29 # include <onigmo.h>
30 #endif
31 
32 typedef union {
33   struct {
34     grn_obj result_buffer;
35   } constant;
36   struct {
37     grn_obj *column;
38     grn_obj value_buffer;
39   } value;
40 #ifdef GRN_SUPPORT_REGEXP
41   struct {
42     grn_obj result_buffer;
43     OnigRegex regex;
44     grn_obj value_buffer;
45     grn_obj *normalizer;
46   } simple_regexp;
47 #endif /* GRN_SUPPORT_REGEXP */
48   struct {
49     grn_proc_ctx proc_ctx;
50     int n_args;
51   } proc;
52   struct {
53     grn_obj result_buffer;
54     grn_ra *ra;
55     grn_ra_cache ra_cache;
56     unsigned int ra_element_size;
57     grn_obj value_buffer;
58     grn_obj constant_buffer;
59     grn_operator_exec_func *exec;
60   } simple_condition_ra;
61   struct {
62     grn_bool need_exec;
63     grn_obj result_buffer;
64     grn_obj value_buffer;
65     grn_obj constant_buffer;
66     grn_operator_exec_func *exec;
67   } simple_condition;
68 } grn_expr_executor_data;
69 
70 typedef grn_obj *(*grn_expr_executor_exec_func)(grn_ctx *ctx,
71                                                 grn_expr_executor *executor,
72                                                 grn_id id);
73 typedef void (*grn_expr_executor_fin_func)(grn_ctx *ctx,
74                                            grn_expr_executor *executor);
75 
76 struct _grn_expr_executor {
77   grn_obj *expr;
78   grn_obj *variable;
79   grn_expr_executor_exec_func exec;
80   grn_expr_executor_fin_func fin;
81   grn_expr_executor_data data;
82 };
83 
84 static void
grn_expr_executor_init_general(grn_ctx * ctx,grn_expr_executor * executor)85 grn_expr_executor_init_general(grn_ctx *ctx,
86                                grn_expr_executor *executor)
87 {
88 }
89 
90 static grn_obj *
grn_expr_executor_exec_general(grn_ctx * ctx,grn_expr_executor * executor,grn_id id)91 grn_expr_executor_exec_general(grn_ctx *ctx,
92                                grn_expr_executor *executor,
93                                grn_id id)
94 {
95   GRN_RECORD_SET(ctx, executor->variable, id);
96   return grn_expr_exec(ctx, executor->expr, 0);
97 }
98 
99 static void
grn_expr_executor_fin_general(grn_ctx * ctx,grn_expr_executor * executor)100 grn_expr_executor_fin_general(grn_ctx *ctx,
101                               grn_expr_executor *executor)
102 {
103 }
104 
105 static grn_bool
grn_expr_executor_is_constant(grn_ctx * ctx,grn_obj * expr)106 grn_expr_executor_is_constant(grn_ctx *ctx, grn_obj *expr)
107 {
108   grn_expr *e = (grn_expr *)expr;
109   grn_expr_code *target;
110 
111   if (e->codes_curr != 1) {
112     return GRN_FALSE;
113   }
114 
115   target = &(e->codes[0]);
116 
117   if (target->op != GRN_OP_PUSH) {
118     return GRN_FALSE;
119   }
120   if (!target->value) {
121     return GRN_FALSE;
122   }
123 
124   return GRN_TRUE;
125 }
126 
127 static void
grn_expr_executor_init_constant(grn_ctx * ctx,grn_expr_executor * executor)128 grn_expr_executor_init_constant(grn_ctx *ctx,
129                                 grn_expr_executor *executor)
130 {
131   grn_obj *result_buffer = &(executor->data.constant.result_buffer);
132   grn_obj *result;
133 
134   GRN_VOID_INIT(result_buffer);
135   result = grn_expr_exec(ctx, executor->expr, 0);
136   if (ctx->rc == GRN_SUCCESS) {
137     grn_obj_reinit(ctx,
138                    result_buffer,
139                    result->header.domain,
140                    result->header.flags);
141     /* TODO: Support vector */
142     grn_bulk_write(ctx,
143                    result_buffer,
144                    GRN_BULK_HEAD(result),
145                    GRN_BULK_VSIZE(result));
146   }
147 }
148 
149 static grn_obj *
grn_expr_executor_exec_constant(grn_ctx * ctx,grn_expr_executor * executor,grn_id id)150 grn_expr_executor_exec_constant(grn_ctx *ctx,
151                                 grn_expr_executor *executor,
152                                 grn_id id)
153 {
154   return &(executor->data.constant.result_buffer);
155 }
156 
157 static void
grn_expr_executor_fin_constant(grn_ctx * ctx,grn_expr_executor * executor)158 grn_expr_executor_fin_constant(grn_ctx *ctx,
159                                grn_expr_executor *executor)
160 {
161   GRN_OBJ_FIN(ctx, &(executor->data.constant.result_buffer));
162 }
163 
164 static grn_bool
grn_expr_executor_is_value(grn_ctx * ctx,grn_obj * expr)165 grn_expr_executor_is_value(grn_ctx *ctx, grn_obj *expr)
166 {
167   grn_expr *e = (grn_expr *)expr;
168   grn_expr_code *target;
169 
170   if (e->codes_curr != 1) {
171     return GRN_FALSE;
172   }
173 
174   target = &(e->codes[0]);
175 
176   if (target->op != GRN_OP_GET_VALUE) {
177     return GRN_FALSE;
178   }
179   if (!target->value) {
180     return GRN_FALSE;
181   }
182 
183   return GRN_TRUE;
184 }
185 
186 static void
grn_expr_executor_init_value(grn_ctx * ctx,grn_expr_executor * executor)187 grn_expr_executor_init_value(grn_ctx *ctx,
188                              grn_expr_executor *executor)
189 {
190   grn_expr *e = (grn_expr *)(executor->expr);
191 
192   executor->data.value.column = e->codes[0].value;
193   GRN_VOID_INIT(&(executor->data.value.value_buffer));
194 }
195 
196 static grn_obj *
grn_expr_executor_exec_value(grn_ctx * ctx,grn_expr_executor * executor,grn_id id)197 grn_expr_executor_exec_value(grn_ctx *ctx,
198                              grn_expr_executor *executor,
199                              grn_id id)
200 {
201   grn_obj *value_buffer = &(executor->data.value.value_buffer);
202 
203   GRN_BULK_REWIND(value_buffer);
204   grn_obj_get_value(ctx, executor->data.value.column, id, value_buffer);
205 
206   return value_buffer;
207 }
208 
209 static void
grn_expr_executor_fin_value(grn_ctx * ctx,grn_expr_executor * executor)210 grn_expr_executor_fin_value(grn_ctx *ctx,
211                             grn_expr_executor *executor)
212 {
213   GRN_OBJ_FIN(ctx, &(executor->data.value.value_buffer));
214 }
215 
216 #ifdef GRN_SUPPORT_REGEXP
217 static grn_bool
grn_expr_executor_is_simple_regexp(grn_ctx * ctx,grn_obj * expr)218 grn_expr_executor_is_simple_regexp(grn_ctx *ctx, grn_obj *expr)
219 {
220   grn_expr *e = (grn_expr *)expr;
221   grn_expr_code *target;
222   grn_expr_code *pattern;
223   grn_expr_code *operator;
224 
225   if (e->codes_curr != 3) {
226     return GRN_FALSE;
227   }
228 
229   target = &(e->codes[0]);
230   pattern = &(e->codes[1]);
231   operator = &(e->codes[2]);
232 
233   if (operator->op != GRN_OP_REGEXP) {
234     return GRN_FALSE;
235   }
236   if (operator->nargs != 2) {
237     return GRN_FALSE;
238   }
239 
240   if (target->op != GRN_OP_GET_VALUE) {
241     return GRN_FALSE;
242   }
243   if (target->nargs != 1) {
244     return GRN_FALSE;
245   }
246   if (!target->value) {
247     return GRN_FALSE;
248   }
249   if (target->value->header.type != GRN_COLUMN_VAR_SIZE) {
250     return GRN_FALSE;
251   }
252   if ((target->value->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) !=
253       GRN_OBJ_COLUMN_SCALAR) {
254     return GRN_FALSE;
255   }
256   switch (grn_obj_get_range(ctx, target->value)) {
257   case GRN_DB_SHORT_TEXT :
258   case GRN_DB_TEXT :
259   case GRN_DB_LONG_TEXT :
260     break;
261   default :
262     return GRN_FALSE;
263   }
264 
265   if (pattern->op != GRN_OP_PUSH) {
266     return GRN_FALSE;
267   }
268   if (pattern->nargs != 1) {
269     return GRN_FALSE;
270   }
271   if (!pattern->value) {
272     return GRN_FALSE;
273   }
274   if (pattern->value->header.type != GRN_BULK) {
275     return GRN_FALSE;
276   }
277   switch (pattern->value->header.domain) {
278   case GRN_DB_SHORT_TEXT :
279   case GRN_DB_TEXT :
280   case GRN_DB_LONG_TEXT :
281     break;
282   default :
283     return GRN_FALSE;
284   }
285 
286   return GRN_TRUE;
287 }
288 
289 static void
grn_expr_executor_init_simple_regexp(grn_ctx * ctx,grn_expr_executor * executor)290 grn_expr_executor_init_simple_regexp(grn_ctx *ctx,
291                                      grn_expr_executor *executor)
292 {
293   grn_expr *e = (grn_expr *)(executor->expr);
294   grn_obj *result_buffer = &(executor->data.simple_regexp.result_buffer);
295   OnigEncoding onig_encoding;
296   int onig_result;
297   OnigErrorInfo onig_error_info;
298   grn_obj *pattern;
299 
300   GRN_BOOL_INIT(result_buffer, 0);
301   GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE);
302 
303   if (ctx->encoding == GRN_ENC_NONE) {
304     executor->data.simple_regexp.regex = NULL;
305     return;
306   }
307 
308   switch (ctx->encoding) {
309   case GRN_ENC_EUC_JP :
310     onig_encoding = ONIG_ENCODING_EUC_JP;
311     break;
312   case GRN_ENC_UTF8 :
313     onig_encoding = ONIG_ENCODING_UTF8;
314     break;
315   case GRN_ENC_SJIS :
316     onig_encoding = ONIG_ENCODING_CP932;
317     break;
318   case GRN_ENC_LATIN1 :
319     onig_encoding = ONIG_ENCODING_ISO_8859_1;
320     break;
321   case GRN_ENC_KOI8R :
322     onig_encoding = ONIG_ENCODING_KOI8_R;
323     break;
324   default :
325     executor->data.simple_regexp.regex = NULL;
326     return;
327   }
328 
329   pattern = e->codes[1].value;
330   onig_result = onig_new(&(executor->data.simple_regexp.regex),
331                          GRN_TEXT_VALUE(pattern),
332                          GRN_TEXT_VALUE(pattern) + GRN_TEXT_LEN(pattern),
333                          ONIG_OPTION_ASCII_RANGE |
334                          ONIG_OPTION_MULTILINE,
335                          onig_encoding,
336                          ONIG_SYNTAX_RUBY,
337                          &onig_error_info);
338   if (onig_result != ONIG_NORMAL) {
339     char message[ONIG_MAX_ERROR_MESSAGE_LEN];
340     onig_error_code_to_str(message, onig_result, onig_error_info);
341     ERR(GRN_INVALID_ARGUMENT,
342         "[expr-executor][regexp] "
343         "failed to create regular expression object: <%.*s>: %s",
344         (int)GRN_TEXT_LEN(pattern), GRN_TEXT_VALUE(pattern),
345         message);
346     return;
347   }
348 
349   GRN_VOID_INIT(&(executor->data.simple_regexp.value_buffer));
350 
351   executor->data.simple_regexp.normalizer =
352     grn_ctx_get(ctx, GRN_NORMALIZER_AUTO_NAME, -1);
353 }
354 
355 static grn_obj *
grn_expr_executor_exec_simple_regexp(grn_ctx * ctx,grn_expr_executor * executor,grn_id id)356 grn_expr_executor_exec_simple_regexp(grn_ctx *ctx,
357                                      grn_expr_executor *executor,
358                                      grn_id id)
359 {
360   grn_expr *e = (grn_expr *)(executor->expr);
361   OnigRegex regex = executor->data.simple_regexp.regex;
362   grn_obj *value_buffer = &(executor->data.simple_regexp.value_buffer);
363   grn_obj *result_buffer = &(executor->data.simple_regexp.result_buffer);
364 
365   if (ctx->rc) {
366     GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE);
367     return result_buffer;
368   }
369 
370   if (!regex) {
371     return result_buffer;
372   }
373 
374   grn_obj_reinit_for(ctx, value_buffer, e->codes[0].value);
375   grn_obj_get_value(ctx, e->codes[0].value, id, value_buffer);
376   {
377     grn_obj *norm_target;
378     const char *norm_target_raw;
379     unsigned int norm_target_raw_length_in_bytes;
380 
381     norm_target = grn_string_open(ctx,
382                                   GRN_TEXT_VALUE(value_buffer),
383                                   GRN_TEXT_LEN(value_buffer),
384                                   executor->data.simple_regexp.normalizer,
385                                   0);
386     grn_string_get_normalized(ctx, norm_target,
387                               &norm_target_raw,
388                               &norm_target_raw_length_in_bytes,
389                               NULL);
390 
391     {
392       OnigPosition position;
393       position = onig_search(regex,
394                              norm_target_raw,
395                              norm_target_raw + norm_target_raw_length_in_bytes,
396                              norm_target_raw,
397                              norm_target_raw + norm_target_raw_length_in_bytes,
398                              NULL,
399                              ONIG_OPTION_NONE);
400       grn_obj_close(ctx, norm_target);
401       GRN_BOOL_SET(ctx, result_buffer, (position != ONIG_MISMATCH));
402       return result_buffer;
403     }
404   }
405 }
406 
407 static void
grn_expr_executor_fin_simple_regexp(grn_ctx * ctx,grn_expr_executor * executor)408 grn_expr_executor_fin_simple_regexp(grn_ctx *ctx,
409                                     grn_expr_executor *executor)
410 {
411   GRN_OBJ_FIN(ctx, &(executor->data.simple_regexp.result_buffer));
412 
413   if (!executor->data.simple_regexp.regex) {
414     return;
415   }
416 
417   onig_free(executor->data.simple_regexp.regex);
418   GRN_OBJ_FIN(ctx, &(executor->data.simple_regexp.value_buffer));
419 }
420 #endif /* GRN_SUPPORT_REGEXP */
421 
422 static grn_bool
grn_expr_executor_is_proc(grn_ctx * ctx,grn_obj * expr)423 grn_expr_executor_is_proc(grn_ctx *ctx, grn_obj *expr)
424 {
425   grn_expr *e = (grn_expr *)expr;
426   grn_obj *first;
427   grn_proc *proc;
428 
429   if (e->codes_curr < 2) {
430     return GRN_FALSE;
431   }
432 
433   first = e->codes[0].value;
434   if (!grn_obj_is_function_proc(ctx, first)) {
435     return GRN_FALSE;
436   }
437 
438   proc = (grn_proc *)first;
439   if (!(proc->funcs[PROC_INIT] &&
440         proc->funcs[PROC_NEXT])) {
441     return GRN_FALSE;
442   }
443 
444   if (e->codes[e->codes_curr - 1].op != GRN_OP_CALL) {
445     return GRN_FALSE;
446   }
447 
448   return GRN_TRUE;
449 }
450 
451 static void
grn_expr_executor_init_proc(grn_ctx * ctx,grn_expr_executor * executor)452 grn_expr_executor_init_proc(grn_ctx *ctx,
453                             grn_expr_executor *executor)
454 {
455   grn_proc_ctx *proc_ctx = &(executor->data.proc.proc_ctx);
456   grn_expr *expr;
457   grn_proc *proc;
458 
459   expr = (grn_expr *)(executor->expr);
460   proc = (grn_proc *)(expr->codes[0].value);
461   proc_ctx->proc = proc;
462   proc_ctx->caller = executor->expr;
463   proc_ctx->phase = PROC_INIT;
464 
465   executor->data.proc.n_args = expr->codes[expr->codes_curr - 1].nargs - 1;
466 
467   proc->funcs[PROC_INIT](ctx, 0, NULL, &(proc_ctx->user_data));
468 }
469 
470 static grn_obj *
grn_expr_executor_exec_proc(grn_ctx * ctx,grn_expr_executor * executor,grn_id id)471 grn_expr_executor_exec_proc(grn_ctx *ctx,
472                             grn_expr_executor *executor,
473                             grn_id id)
474 {
475   grn_proc_ctx *proc_ctx = &(executor->data.proc.proc_ctx);
476   int n_args = executor->data.proc.n_args;
477   grn_proc *proc;
478   grn_expr *expr;
479   grn_obj **args;
480   uint32_t values_curr;
481   uint32_t values_tail;
482   grn_obj *result;
483 
484   proc = proc_ctx->proc;
485   proc_ctx->phase = PROC_NEXT;
486   GRN_RECORD_SET(ctx, executor->variable, id);
487 
488   expr = (grn_expr *)(executor->expr);
489   values_curr = expr->values_curr;
490   values_tail = expr->values_tail;
491 
492   expr->codes += 1;
493   expr->codes_curr -= 2;
494   grn_expr_exec(ctx, executor->expr, 0);
495   expr->codes_curr += 2;
496   expr->codes -= 1;
497 
498   args = ctx->impl->stack + ctx->impl->stack_curr;
499   ctx->impl->stack_curr += n_args;
500   expr->values_curr = expr->values_tail;
501   result = proc->funcs[PROC_NEXT](ctx,
502                                   n_args,
503                                   args,
504                                   &(proc_ctx->user_data));
505   ctx->impl->stack_curr -= n_args;
506 
507   expr->values_tail = values_tail;
508   expr->values_curr = values_curr;
509 
510   return result;
511 }
512 
513 static void
grn_expr_executor_fin_proc(grn_ctx * ctx,grn_expr_executor * executor)514 grn_expr_executor_fin_proc(grn_ctx *ctx,
515                            grn_expr_executor *executor)
516 {
517   grn_proc_ctx *proc_ctx = &(executor->data.proc.proc_ctx);
518   grn_proc *proc;
519 
520   proc = proc_ctx->proc;
521   proc_ctx->phase = PROC_FIN;
522   if (proc->funcs[PROC_FIN]) {
523     proc->funcs[PROC_FIN](ctx, 0, NULL, &(proc_ctx->user_data));
524   }
525 }
526 
527 static grn_bool
grn_expr_executor_is_simple_condition_ra(grn_ctx * ctx,grn_obj * expr)528 grn_expr_executor_is_simple_condition_ra(grn_ctx *ctx, grn_obj *expr)
529 {
530   grn_expr *e = (grn_expr *)expr;
531   grn_expr_code *target;
532   grn_expr_code *constant;
533   grn_expr_code *operator;
534 
535   if (e->codes_curr != 3) {
536     return GRN_FALSE;
537   }
538 
539   target = &(e->codes[0]);
540   constant = &(e->codes[1]);
541   operator = &(e->codes[2]);
542 
543   switch (operator->op) {
544   case GRN_OP_EQUAL :
545   case GRN_OP_NOT_EQUAL :
546   case GRN_OP_LESS :
547   case GRN_OP_GREATER :
548   case GRN_OP_LESS_EQUAL :
549   case GRN_OP_GREATER_EQUAL :
550     break;
551   default :
552     return GRN_FALSE;
553   }
554   if (operator->nargs != 2) {
555     return GRN_FALSE;
556   }
557 
558   if (target->op != GRN_OP_GET_VALUE) {
559     return GRN_FALSE;
560   }
561   if (target->nargs != 1) {
562     return GRN_FALSE;
563   }
564   if (target->value->header.type != GRN_COLUMN_FIX_SIZE) {
565     return GRN_FALSE;
566   }
567 
568   if (constant->op != GRN_OP_PUSH) {
569     return GRN_FALSE;
570   }
571   if (constant->nargs != 1) {
572     return GRN_FALSE;
573   }
574   if (!constant->value) {
575     return GRN_FALSE;
576   }
577   if (constant->value->header.type != GRN_BULK) {
578     return GRN_FALSE;
579   }
580 
581   {
582     grn_obj constant_buffer;
583     grn_rc rc;
584     GRN_VOID_INIT(&constant_buffer);
585     grn_obj_reinit_for(ctx, &constant_buffer, target->value);
586     rc = grn_obj_cast(ctx, constant->value, &constant_buffer, GRN_FALSE);
587     GRN_OBJ_FIN(ctx, &constant_buffer);
588     if (rc != GRN_SUCCESS) {
589       return GRN_FALSE;
590     }
591   }
592 
593   return GRN_TRUE;
594 }
595 
596 static void
grn_expr_executor_init_simple_condition_ra(grn_ctx * ctx,grn_expr_executor * executor)597 grn_expr_executor_init_simple_condition_ra(grn_ctx *ctx,
598                                            grn_expr_executor *executor)
599 {
600   grn_expr *e = (grn_expr *)(executor->expr);
601   grn_obj *target;
602   grn_obj *constant;
603   grn_operator op;
604   grn_obj *result_buffer;
605   grn_obj *value_buffer;
606   grn_obj *constant_buffer;
607 
608   target = e->codes[0].value;
609   constant = e->codes[1].value;
610   op = e->codes[2].op;
611 
612   result_buffer = &(executor->data.simple_condition_ra.result_buffer);
613   GRN_BOOL_INIT(result_buffer, 0);
614   GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE);
615 
616   value_buffer = &(executor->data.simple_condition_ra.value_buffer);
617   GRN_VOID_INIT(value_buffer);
618   grn_obj_reinit_for(ctx, value_buffer, target);
619 
620   executor->data.simple_condition_ra.ra = (grn_ra *)target;
621   GRN_RA_CACHE_INIT(executor->data.simple_condition_ra.ra,
622                     &(executor->data.simple_condition_ra.ra_cache));
623   grn_ra_info(ctx,
624               executor->data.simple_condition_ra.ra,
625               &(executor->data.simple_condition_ra.ra_element_size));
626 
627   executor->data.simple_condition_ra.exec = grn_operator_to_exec_func(op);
628 
629   constant_buffer = &(executor->data.simple_condition_ra.constant_buffer);
630   GRN_VOID_INIT(constant_buffer);
631   grn_obj_reinit_for(ctx, constant_buffer, target);
632   grn_obj_cast(ctx, constant, constant_buffer, GRN_FALSE);
633 }
634 
635 static grn_obj *
grn_expr_executor_exec_simple_condition_ra(grn_ctx * ctx,grn_expr_executor * executor,grn_id id)636 grn_expr_executor_exec_simple_condition_ra(grn_ctx *ctx,
637                                            grn_expr_executor *executor,
638                                            grn_id id)
639 {
640   grn_obj *result_buffer = &(executor->data.simple_condition_ra.result_buffer);
641   grn_obj *value_buffer = &(executor->data.simple_condition_ra.value_buffer);
642   grn_obj *constant_buffer =
643     &(executor->data.simple_condition_ra.constant_buffer);
644 
645   if (ctx->rc) {
646     GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE);
647     return result_buffer;
648   }
649 
650   {
651     grn_ra *ra = executor->data.simple_condition_ra.ra;
652     grn_ra_cache *ra_cache = &(executor->data.simple_condition_ra.ra_cache);
653     unsigned int ra_element_size =
654       executor->data.simple_condition_ra.ra_element_size;
655     void *raw_value;
656     raw_value = grn_ra_ref_cache(ctx, ra, id, ra_cache);
657     GRN_BULK_REWIND(value_buffer);
658     grn_bulk_write(ctx, value_buffer, raw_value, ra_element_size);
659   }
660 
661   if (executor->data.simple_condition_ra.exec(ctx,
662                                               value_buffer,
663                                               constant_buffer)) {
664     GRN_BOOL_SET(ctx, result_buffer, GRN_TRUE);
665   } else {
666     GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE);
667   }
668   return result_buffer;
669 }
670 
671 static void
grn_expr_executor_fin_simple_condition_ra(grn_ctx * ctx,grn_expr_executor * executor)672 grn_expr_executor_fin_simple_condition_ra(grn_ctx *ctx,
673                                           grn_expr_executor *executor)
674 {
675   GRN_OBJ_FIN(ctx, &(executor->data.simple_condition_ra.result_buffer));
676   GRN_RA_CACHE_FIN(executor->data.simple_condition_ra.ra,
677                    &(executor->data.simple_condition_ra.ra_cache));
678   GRN_OBJ_FIN(ctx, &(executor->data.simple_condition_ra.value_buffer));
679   GRN_OBJ_FIN(ctx, &(executor->data.simple_condition_ra.constant_buffer));
680 }
681 
682 static grn_bool
grn_expr_executor_is_simple_condition(grn_ctx * ctx,grn_obj * expr)683 grn_expr_executor_is_simple_condition(grn_ctx *ctx, grn_obj *expr)
684 {
685   grn_expr *e = (grn_expr *)expr;
686   grn_expr_code *target;
687   grn_expr_code *constant;
688   grn_expr_code *operator;
689 
690   if (e->codes_curr != 3) {
691     return GRN_FALSE;
692   }
693 
694   target = &(e->codes[0]);
695   constant = &(e->codes[1]);
696   operator = &(e->codes[2]);
697 
698   switch (operator->op) {
699   case GRN_OP_EQUAL :
700   case GRN_OP_NOT_EQUAL :
701   case GRN_OP_LESS :
702   case GRN_OP_GREATER :
703   case GRN_OP_LESS_EQUAL :
704   case GRN_OP_GREATER_EQUAL :
705     break;
706   default :
707     return GRN_FALSE;
708   }
709   if (operator->nargs != 2) {
710     return GRN_FALSE;
711   }
712 
713   if (target->op != GRN_OP_GET_VALUE) {
714     return GRN_FALSE;
715   }
716   if (target->nargs != 1) {
717     return GRN_FALSE;
718   }
719   if (!grn_obj_is_scalar_column(ctx, target->value)) {
720     return GRN_FALSE;
721   }
722 
723   if (constant->op != GRN_OP_PUSH) {
724     return GRN_FALSE;
725   }
726   if (constant->nargs != 1) {
727     return GRN_FALSE;
728   }
729   if (!constant->value) {
730     return GRN_FALSE;
731   }
732   if (constant->value->header.type != GRN_BULK) {
733     return GRN_FALSE;
734   }
735 
736   return GRN_TRUE;
737 }
738 
739 static void
grn_expr_executor_init_simple_condition(grn_ctx * ctx,grn_expr_executor * executor)740 grn_expr_executor_init_simple_condition(grn_ctx *ctx,
741                                         grn_expr_executor *executor)
742 {
743   grn_expr *e = (grn_expr *)(executor->expr);
744   grn_obj *target;
745   grn_obj *constant;
746   grn_operator op;
747   grn_obj *result_buffer;
748   grn_obj *value_buffer;
749   grn_obj *constant_buffer;
750   grn_rc rc;
751 
752   target = e->codes[0].value;
753   constant = e->codes[1].value;
754   op = e->codes[2].op;
755 
756   executor->data.simple_condition.need_exec = GRN_TRUE;
757 
758   result_buffer = &(executor->data.simple_condition.result_buffer);
759   GRN_BOOL_INIT(result_buffer, 0);
760   GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE);
761 
762   value_buffer = &(executor->data.simple_condition.value_buffer);
763   GRN_VOID_INIT(value_buffer);
764   grn_obj_reinit_for(ctx, value_buffer, target);
765 
766   executor->data.simple_condition.exec = grn_operator_to_exec_func(op);
767 
768   constant_buffer = &(executor->data.simple_condition.constant_buffer);
769   GRN_VOID_INIT(constant_buffer);
770   grn_obj_reinit_for(ctx, constant_buffer, target);
771   rc = grn_obj_cast(ctx, constant, constant_buffer, GRN_FALSE);
772   if (rc != GRN_SUCCESS) {
773     grn_obj *type;
774 
775     type = grn_ctx_at(ctx, constant_buffer->header.domain);
776     if (grn_obj_is_table(ctx, type)) {
777       GRN_BOOL_SET(ctx, result_buffer, (op == GRN_OP_NOT_EQUAL));
778       executor->data.simple_condition.need_exec = GRN_FALSE;
779     } else {
780       int type_name_size;
781       char type_name[GRN_TABLE_MAX_KEY_SIZE];
782       grn_obj inspected;
783 
784       type_name_size = grn_obj_name(ctx, type, type_name,
785                                     GRN_TABLE_MAX_KEY_SIZE);
786       GRN_TEXT_INIT(&inspected, 0);
787       grn_inspect(ctx, &inspected, constant);
788       ERR(rc,
789           "[expr-executor][condition] "
790           "failed to cast to <%.*s>: <%.*s>",
791           type_name_size, type_name,
792           (int)GRN_TEXT_LEN(&inspected), GRN_TEXT_VALUE(&inspected));
793     }
794   }
795 }
796 
797 static grn_obj *
grn_expr_executor_exec_simple_condition(grn_ctx * ctx,grn_expr_executor * executor,grn_id id)798 grn_expr_executor_exec_simple_condition(grn_ctx *ctx,
799                                         grn_expr_executor *executor,
800                                         grn_id id)
801 {
802   grn_expr *e = (grn_expr *)(executor->expr);
803   grn_obj *target;
804   grn_obj *result_buffer = &(executor->data.simple_condition.result_buffer);
805   grn_obj *value_buffer = &(executor->data.simple_condition.value_buffer);
806   grn_obj *constant_buffer = &(executor->data.simple_condition.constant_buffer);
807 
808   if (ctx->rc) {
809     GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE);
810     return result_buffer;
811   }
812 
813   if (!executor->data.simple_condition.need_exec) {
814     return result_buffer;
815   }
816 
817   target = e->codes[0].value;
818   GRN_BULK_REWIND(value_buffer);
819   grn_obj_get_value(ctx, target, id, value_buffer);
820 
821   if (executor->data.simple_condition.exec(ctx, value_buffer, constant_buffer)) {
822     GRN_BOOL_SET(ctx, result_buffer, GRN_TRUE);
823   } else {
824     GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE);
825   }
826   return result_buffer;
827 }
828 
829 static void
grn_expr_executor_fin_simple_condition(grn_ctx * ctx,grn_expr_executor * executor)830 grn_expr_executor_fin_simple_condition(grn_ctx *ctx,
831                                        grn_expr_executor *executor)
832 {
833   GRN_OBJ_FIN(ctx, &(executor->data.simple_condition.result_buffer));
834   GRN_OBJ_FIN(ctx, &(executor->data.simple_condition.value_buffer));
835   GRN_OBJ_FIN(ctx, &(executor->data.simple_condition.constant_buffer));
836 }
837 
838 grn_expr_executor *
grn_expr_executor_open(grn_ctx * ctx,grn_obj * expr)839 grn_expr_executor_open(grn_ctx *ctx, grn_obj *expr)
840 {
841   grn_obj *variable;
842   grn_expr_executor *executor;
843 
844   GRN_API_ENTER;
845 
846   if (!grn_obj_is_expr(ctx, expr)) {
847     grn_obj inspected;
848     GRN_TEXT_INIT(&inspected, 0);
849     grn_inspect(ctx, &inspected, expr);
850     ERR(ctx->rc,
851         "[expr-executor][open] invalid expression: %.*s",
852         (int)GRN_TEXT_LEN(&inspected),
853         GRN_TEXT_VALUE(&inspected));
854     GRN_OBJ_FIN(ctx, &inspected);
855     GRN_API_RETURN(NULL);
856   }
857 
858   variable = grn_expr_get_var_by_offset(ctx, expr, 0);
859   if (!variable) {
860     grn_obj inspected;
861     GRN_TEXT_INIT(&inspected, 0);
862     grn_inspect(ctx, &inspected, expr);
863     ERR(ctx->rc,
864         "[expr-executor][open] expression has no variable: %.*s",
865         (int)GRN_TEXT_LEN(&inspected),
866         GRN_TEXT_VALUE(&inspected));
867     GRN_OBJ_FIN(ctx, &inspected);
868     GRN_API_RETURN(NULL);
869   }
870 
871   executor = GRN_CALLOC(sizeof(grn_expr_executor));
872   if (!executor) {
873     ERR(ctx->rc,
874         "[expr-executor][open] failed to allocate: %s",
875         ctx->errbuf);
876     GRN_API_RETURN(NULL);
877   }
878 
879   executor->expr = expr;
880   executor->variable = variable;
881   if (grn_expr_executor_is_constant(ctx, expr)) {
882     grn_expr_executor_init_constant(ctx, executor);
883     executor->exec = grn_expr_executor_exec_constant;
884     executor->fin = grn_expr_executor_fin_constant;
885   } else if (grn_expr_executor_is_value(ctx, expr)) {
886     grn_expr_executor_init_value(ctx, executor);
887     executor->exec = grn_expr_executor_exec_value;
888     executor->fin = grn_expr_executor_fin_value;
889 #ifdef GRN_SUPPORT_REGEXP
890   } else if (grn_expr_executor_is_simple_regexp(ctx, expr)) {
891     grn_expr_executor_init_simple_regexp(ctx, executor);
892     executor->exec = grn_expr_executor_exec_simple_regexp;
893     executor->fin = grn_expr_executor_fin_simple_regexp;
894 #endif /* GRN_SUPPORT_REGEXP */
895   } else if (grn_expr_executor_is_proc(ctx, expr)) {
896     grn_expr_executor_init_proc(ctx, executor);
897     executor->exec = grn_expr_executor_exec_proc;
898     executor->fin = grn_expr_executor_fin_proc;
899   } else if (grn_expr_executor_is_simple_condition_ra(ctx, expr)) {
900     grn_expr_executor_init_simple_condition_ra(ctx, executor);
901     executor->exec = grn_expr_executor_exec_simple_condition_ra;
902     executor->fin = grn_expr_executor_fin_simple_condition_ra;
903   } else if (grn_expr_executor_is_simple_condition(ctx, expr)) {
904     grn_expr_executor_init_simple_condition(ctx, executor);
905     executor->exec = grn_expr_executor_exec_simple_condition;
906     executor->fin = grn_expr_executor_fin_simple_condition;
907   } else {
908     grn_expr_executor_init_general(ctx, executor);
909     executor->exec = grn_expr_executor_exec_general;
910     executor->fin = grn_expr_executor_fin_general;
911   }
912 
913   GRN_API_RETURN(executor);
914 }
915 
916 grn_obj *
grn_expr_executor_exec(grn_ctx * ctx,grn_expr_executor * executor,grn_id id)917 grn_expr_executor_exec(grn_ctx *ctx, grn_expr_executor *executor, grn_id id)
918 {
919   grn_obj *value;
920 
921   GRN_API_ENTER;
922 
923   if (!executor) {
924     GRN_API_RETURN(NULL);
925   }
926 
927   value = executor->exec(ctx, executor, id);
928 
929   GRN_API_RETURN(value);
930 }
931 
932 grn_rc
grn_expr_executor_close(grn_ctx * ctx,grn_expr_executor * executor)933 grn_expr_executor_close(grn_ctx *ctx, grn_expr_executor *executor)
934 {
935   GRN_API_ENTER;
936 
937   if (!executor) {
938     GRN_API_RETURN(GRN_SUCCESS);
939   }
940 
941   executor->fin(ctx, executor);
942   GRN_FREE(executor);
943 
944   GRN_API_RETURN(GRN_SUCCESS);
945 }
946