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