1 /* -*- c-basic-offset: 2 -*- */
2 /*
3 Copyright(C) 2015-2016 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 "ts_expr_node.h"
20
21 #include <math.h>
22 #include <string.h>
23
24 #include "../grn_ctx.h"
25 #include "../grn_dat.h"
26 #include "../grn_db.h"
27 #include "../grn_geo.h"
28 #include "../grn_hash.h"
29 #include "../grn_pat.h"
30 #include "../grn_store.h"
31
32 #include "ts_log.h"
33 #include "ts_str.h"
34 #include "ts_util.h"
35
36 /*-------------------------------------------------------------
37 * Built-in data kinds.
38 */
39
40 /* grn_ts_bool_is_valid() returns whether a value is valid or not. */
41 inline static grn_ts_bool
grn_ts_bool_is_valid(grn_ts_bool value)42 grn_ts_bool_is_valid(grn_ts_bool value)
43 {
44 return GRN_TRUE;
45 }
46
47 /* grn_ts_int_is_valid() returns whether a value is valid or not. */
48 inline static grn_ts_bool
grn_ts_int_is_valid(grn_ts_int value)49 grn_ts_int_is_valid(grn_ts_int value)
50 {
51 return GRN_TRUE;
52 }
53
54 /* grn_ts_float_is_valid() returns whether a value is valid or not. */
55 inline static grn_ts_bool
grn_ts_float_is_valid(grn_ts_float value)56 grn_ts_float_is_valid(grn_ts_float value)
57 {
58 return isfinite(value);
59 }
60
61 /* grn_ts_time_is_valid() returns whether a value is valid or not. */
62 inline static grn_ts_bool
grn_ts_time_is_valid(grn_ts_time value)63 grn_ts_time_is_valid(grn_ts_time value)
64 {
65 return GRN_TRUE;
66 }
67
68 /* grn_ts_text_is_valid() returns whether a value is valid or not. */
69 inline static grn_ts_bool
grn_ts_text_is_valid(grn_ts_text value)70 grn_ts_text_is_valid(grn_ts_text value)
71 {
72 return value.ptr || !value.size;
73 }
74
75 /* grn_ts_geo_is_valid() returns whether a value is valid or not. */
76 inline static grn_ts_bool
grn_ts_geo_is_valid(grn_ts_geo value)77 grn_ts_geo_is_valid(grn_ts_geo value)
78 {
79 return ((value.latitude >= GRN_GEO_MIN_LATITUDE) &&
80 (value.latitude <= GRN_GEO_MAX_LATITUDE)) &&
81 ((value.longitude >= GRN_GEO_MIN_LONGITUDE) &&
82 (value.longitude <= GRN_GEO_MAX_LONGITUDE));
83 }
84
85 #define GRN_TS_VECTOR_IS_VALID(type)\
86 if (value.size) {\
87 size_t i;\
88 if (!value.ptr) {\
89 return GRN_FALSE;\
90 }\
91 for (i = 0; i < value.size; i++) {\
92 if (!grn_ts_ ## type ## _is_valid(value.ptr[i])) {\
93 return GRN_FALSE;\
94 }\
95 }\
96 }\
97 return GRN_TRUE;
98 /* grn_ts_bool_vector_is_valid() returns whether a value is valid or not. */
99 inline static grn_ts_bool
grn_ts_bool_vector_is_valid(grn_ts_bool_vector value)100 grn_ts_bool_vector_is_valid(grn_ts_bool_vector value)
101 {
102 GRN_TS_VECTOR_IS_VALID(bool)
103 }
104
105 /* grn_ts_int_vector_is_valid() returns whether a value is valid or not. */
106 inline static grn_ts_bool
grn_ts_int_vector_is_valid(grn_ts_int_vector value)107 grn_ts_int_vector_is_valid(grn_ts_int_vector value)
108 {
109 GRN_TS_VECTOR_IS_VALID(int)
110 }
111
112 /* grn_ts_float_vector_is_valid() returns whether a value is valid or not. */
113 inline static grn_ts_bool
grn_ts_float_vector_is_valid(grn_ts_float_vector value)114 grn_ts_float_vector_is_valid(grn_ts_float_vector value)
115 {
116 GRN_TS_VECTOR_IS_VALID(float)
117 }
118
119 /* grn_ts_time_vector_is_valid() returns whether a value is valid or not. */
120 inline static grn_ts_bool
grn_ts_time_vector_is_valid(grn_ts_time_vector value)121 grn_ts_time_vector_is_valid(grn_ts_time_vector value)
122 {
123 GRN_TS_VECTOR_IS_VALID(time)
124 }
125
126 /* grn_ts_text_vector_is_valid() returns whether a value is valid or not. */
127 inline static grn_ts_bool
grn_ts_text_vector_is_valid(grn_ts_text_vector value)128 grn_ts_text_vector_is_valid(grn_ts_text_vector value)
129 {
130 GRN_TS_VECTOR_IS_VALID(text)
131 }
132
133 /* grn_ts_geo_vector_is_valid() returns whether a value is valid or not. */
134 inline static grn_ts_bool
grn_ts_geo_vector_is_valid(grn_ts_geo_vector value)135 grn_ts_geo_vector_is_valid(grn_ts_geo_vector value)
136 {
137 GRN_TS_VECTOR_IS_VALID(geo)
138 }
139 #undef GRN_TS_VECTOR_IS_VALID
140
141 /* grn_ts_bool_zero() returns a zero. */
142 inline static grn_ts_bool
grn_ts_bool_zero(void)143 grn_ts_bool_zero(void)
144 {
145 return GRN_FALSE;
146 }
147
148 /* grn_ts_int_zero() returns a zero. */
149 inline static grn_ts_int
grn_ts_int_zero(void)150 grn_ts_int_zero(void)
151 {
152 return 0;
153 }
154
155 /* grn_ts_float_zero() returns a zero. */
156 inline static grn_ts_float
grn_ts_float_zero(void)157 grn_ts_float_zero(void)
158 {
159 return 0.0;
160 }
161
162 /* grn_ts_time_zero() returns a zero. */
163 inline static grn_ts_time
grn_ts_time_zero(void)164 grn_ts_time_zero(void)
165 {
166 return 0;
167 }
168
169 /* grn_ts_text_zero() returns a zero. */
170 inline static grn_ts_text
grn_ts_text_zero(void)171 grn_ts_text_zero(void)
172 {
173 return (grn_ts_text){ NULL, 0 };
174 }
175
176 /* grn_ts_geo_zero() returns a zero. */
177 inline static grn_ts_geo
grn_ts_geo_zero(void)178 grn_ts_geo_zero(void)
179 {
180 return (grn_ts_geo){ 0, 0 };
181 }
182
183 /* grn_ts_ref_zero() returns a zero. */
184 inline static grn_ts_ref
grn_ts_ref_zero(void)185 grn_ts_ref_zero(void)
186 {
187 return (grn_ts_ref){ 0, 0.0 };
188 }
189
190 /* grn_ts_data_type_to_kind() returns a kind associated with a type. */
191 static grn_ts_data_kind
grn_ts_data_type_to_kind(grn_ts_data_type type)192 grn_ts_data_type_to_kind(grn_ts_data_type type)
193 {
194 switch (type) {
195 case GRN_DB_VOID: {
196 return GRN_TS_VOID;
197 }
198 case GRN_DB_BOOL: {
199 return GRN_TS_BOOL;
200 }
201 case GRN_DB_INT8:
202 case GRN_DB_INT16:
203 case GRN_DB_INT32:
204 case GRN_DB_INT64:
205 case GRN_DB_UINT8:
206 case GRN_DB_UINT16:
207 case GRN_DB_UINT32:
208 case GRN_DB_UINT64: {
209 return GRN_TS_INT;
210 }
211 case GRN_DB_FLOAT: {
212 return GRN_TS_FLOAT;
213 }
214 case GRN_DB_TIME: {
215 return GRN_TS_TIME;
216 }
217 case GRN_DB_SHORT_TEXT:
218 case GRN_DB_TEXT:
219 case GRN_DB_LONG_TEXT: {
220 return GRN_TS_TEXT;
221 }
222 case GRN_DB_TOKYO_GEO_POINT:
223 case GRN_DB_WGS84_GEO_POINT: {
224 return GRN_TS_GEO;
225 }
226 default: {
227 return GRN_TS_REF;
228 }
229 }
230 }
231
232 /* grn_ts_data_kind_to_type() returns a type associated with a kind. */
233 static grn_ts_data_type
grn_ts_data_kind_to_type(grn_ts_data_kind kind)234 grn_ts_data_kind_to_type(grn_ts_data_kind kind)
235 {
236 switch (kind & ~GRN_TS_VECTOR_FLAG) {
237 case GRN_TS_BOOL: {
238 return GRN_DB_BOOL;
239 }
240 case GRN_TS_INT: {
241 return GRN_DB_INT64;
242 }
243 case GRN_TS_FLOAT: {
244 return GRN_DB_FLOAT;
245 }
246 case GRN_TS_TIME: {
247 return GRN_DB_TIME;
248 }
249 case GRN_TS_TEXT: {
250 return GRN_DB_TEXT;
251 }
252 case GRN_TS_GEO: {
253 /* GRN_DB_TOKYO_GEO_POINT or GRN_DB_WGS84_GEO_POINT. */
254 return GRN_DB_VOID;
255 }
256 case GRN_TS_REF: {
257 /*
258 * grn_ts_data_kind does not have enough information to get a correct
259 * table ID.
260 */
261 return GRN_DB_VOID;
262 }
263 default: {
264 return GRN_DB_VOID;
265 }
266 }
267 }
268
269 /*-------------------------------------------------------------
270 * Operators.
271 */
272
273 /* grn_ts_op_logical_not_bool() returns !arg. */
274 inline static grn_ts_bool
grn_ts_op_logical_not_bool(grn_ts_bool arg)275 grn_ts_op_logical_not_bool(grn_ts_bool arg)
276 {
277 return !arg;
278 }
279
280 /* grn_ts_op_bitwise_not_bool() returns ~arg. */
281 inline static grn_ts_bool
grn_ts_op_bitwise_not_bool(grn_ts_bool arg)282 grn_ts_op_bitwise_not_bool(grn_ts_bool arg)
283 {
284 return !arg;
285 }
286
287 /* grn_ts_op_bitwise_not_int() returns ~arg. */
288 inline static grn_ts_int
grn_ts_op_bitwise_not_int(grn_ts_int arg)289 grn_ts_op_bitwise_not_int(grn_ts_int arg)
290 {
291 return ~arg;
292 }
293
294 /* grn_ts_op_positive_int() returns +arg. */
295 inline static grn_ts_int
grn_ts_op_positive_int(grn_ts_int arg)296 grn_ts_op_positive_int(grn_ts_int arg)
297 {
298 return arg;
299 }
300
301 /* grn_ts_op_positive_float() returns +arg. */
302 inline static grn_ts_float
grn_ts_op_positive_float(grn_ts_float arg)303 grn_ts_op_positive_float(grn_ts_float arg)
304 {
305 return arg;
306 }
307
308 /* grn_ts_op_negative_int() returns -arg. */
309 inline static grn_ts_int
grn_ts_op_negative_int(grn_ts_int arg)310 grn_ts_op_negative_int(grn_ts_int arg)
311 {
312 return -arg;
313 }
314
315 /* grn_ts_op_negative_float() returns -arg. */
316 inline static grn_ts_float
grn_ts_op_negative_float(grn_ts_float arg)317 grn_ts_op_negative_float(grn_ts_float arg)
318 {
319 return -arg;
320 }
321
322 /* grn_ts_op_float() returns (Float)arg. */
323 static grn_rc
grn_ts_op_float(grn_ctx * ctx,grn_ts_int arg,grn_ts_float * out)324 grn_ts_op_float(grn_ctx *ctx, grn_ts_int arg, grn_ts_float *out)
325 {
326 *out = (grn_ts_float)arg;
327 return GRN_SUCCESS;
328 }
329
330 /* grn_ts_op_time() returns (Time)arg. */
331 static grn_rc
grn_ts_op_time(grn_ctx * ctx,grn_ts_text arg,grn_ts_time * out)332 grn_ts_op_time(grn_ctx *ctx, grn_ts_text arg, grn_ts_time *out)
333 {
334 grn_timeval value;
335 grn_rc rc = grn_str2timeval(arg.ptr, arg.size, &value);
336 if (rc != GRN_SUCCESS) {
337 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "grn_str2timeval failed");
338 }
339 *out = (grn_ts_time)((value.tv_sec * 1000000) + (value.tv_nsec / 1000));
340 return GRN_SUCCESS;
341 }
342
343 /* grn_ts_op_bitwise_and_bool() returns lhs & rhs. */
344 inline static grn_ts_bool
grn_ts_op_bitwise_and_bool(grn_ts_bool lhs,grn_ts_bool rhs)345 grn_ts_op_bitwise_and_bool(grn_ts_bool lhs, grn_ts_bool rhs)
346 {
347 return lhs & rhs;
348 }
349
350 /* grn_ts_op_bitwise_and_int() returns lhs & rhs. */
351 inline static grn_ts_int
grn_ts_op_bitwise_and_int(grn_ts_int lhs,grn_ts_int rhs)352 grn_ts_op_bitwise_and_int(grn_ts_int lhs, grn_ts_int rhs)
353 {
354 return lhs & rhs;
355 }
356
357 /* grn_ts_op_bitwise_or_bool() returns lhs | rhs. */
358 inline static grn_ts_bool
grn_ts_op_bitwise_or_bool(grn_ts_bool lhs,grn_ts_bool rhs)359 grn_ts_op_bitwise_or_bool(grn_ts_bool lhs, grn_ts_bool rhs)
360 {
361 return lhs | rhs;
362 }
363
364 /* grn_ts_op_bitwise_or_int() returns lhs | rhs. */
365 inline static grn_ts_int
grn_ts_op_bitwise_or_int(grn_ts_int lhs,grn_ts_int rhs)366 grn_ts_op_bitwise_or_int(grn_ts_int lhs, grn_ts_int rhs)
367 {
368 return lhs | rhs;
369 }
370
371 /* grn_ts_op_bitwise_xor_bool() returns lhs ^ rhs. */
372 inline static grn_ts_bool
grn_ts_op_bitwise_xor_bool(grn_ts_bool lhs,grn_ts_bool rhs)373 grn_ts_op_bitwise_xor_bool(grn_ts_bool lhs, grn_ts_bool rhs)
374 {
375 return lhs ^ rhs;
376 }
377
378 /* grn_ts_op_bitwise_xor_int() returns lhs ^ rhs. */
379 inline static grn_ts_int
grn_ts_op_bitwise_xor_int(grn_ts_int lhs,grn_ts_int rhs)380 grn_ts_op_bitwise_xor_int(grn_ts_int lhs, grn_ts_int rhs)
381 {
382 return lhs ^ rhs;
383 }
384
385 /* grn_ts_op_equal_bool() returns lhs == rhs. */
386 inline static grn_ts_bool
grn_ts_op_equal_bool(grn_ts_bool lhs,grn_ts_bool rhs)387 grn_ts_op_equal_bool(grn_ts_bool lhs, grn_ts_bool rhs)
388 {
389 return lhs == rhs;
390 }
391
392 /* grn_ts_op_equal_int() returns lhs == rhs. */
393 inline static grn_ts_bool
grn_ts_op_equal_int(grn_ts_int lhs,grn_ts_int rhs)394 grn_ts_op_equal_int(grn_ts_int lhs, grn_ts_int rhs)
395 {
396 return lhs == rhs;
397 }
398
399 /* grn_ts_op_equal_float() returns lhs == rhs. */
400 inline static grn_ts_bool
grn_ts_op_equal_float(grn_ts_float lhs,grn_ts_float rhs)401 grn_ts_op_equal_float(grn_ts_float lhs, grn_ts_float rhs)
402 {
403 /* To suppress warnings, "lhs == rhs" is not used. */
404 return (lhs <= rhs) && (lhs >= rhs);
405 }
406
407 /* grn_ts_op_equal_time() returns lhs == rhs. */
408 inline static grn_ts_bool
grn_ts_op_equal_time(grn_ts_time lhs,grn_ts_time rhs)409 grn_ts_op_equal_time(grn_ts_time lhs, grn_ts_time rhs)
410 {
411 return lhs == rhs;
412 }
413
414 /* grn_ts_op_equal_text() returns lhs == rhs. */
415 inline static grn_ts_bool
grn_ts_op_equal_text(grn_ts_text lhs,grn_ts_text rhs)416 grn_ts_op_equal_text(grn_ts_text lhs, grn_ts_text rhs)
417 {
418 return (lhs.size == rhs.size) && !memcmp(lhs.ptr, rhs.ptr, lhs.size);
419 }
420
421 /* grn_ts_op_equal_geo() returns lhs == rhs. */
422 inline static grn_ts_bool
grn_ts_op_equal_geo(grn_ts_geo lhs,grn_ts_geo rhs)423 grn_ts_op_equal_geo(grn_ts_geo lhs, grn_ts_geo rhs)
424 {
425 return (lhs.latitude == rhs.latitude) && (lhs.longitude == rhs.longitude);
426 }
427
428 /* grn_ts_op_equal_ref() returns lhs == rhs. */
429 inline static grn_ts_bool
grn_ts_op_equal_ref(grn_ts_ref lhs,grn_ts_ref rhs)430 grn_ts_op_equal_ref(grn_ts_ref lhs, grn_ts_ref rhs)
431 {
432 /* Ignore scores. */
433 return lhs.id == rhs.id;
434 }
435
436 #define GRN_TS_OP_EQUAL_VECTOR(kind)\
437 size_t i;\
438 if (lhs.size != rhs.size) {\
439 return GRN_FALSE;\
440 }\
441 for (i = 0; i < lhs.size; i++) {\
442 if (!grn_ts_op_equal_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
443 return GRN_FALSE;\
444 }\
445 }\
446 return GRN_TRUE;
447 /* grn_ts_op_equal_bool_vector() returns lhs == rhs. */
448 inline static grn_ts_bool
grn_ts_op_equal_bool_vector(grn_ts_bool_vector lhs,grn_ts_bool_vector rhs)449 grn_ts_op_equal_bool_vector(grn_ts_bool_vector lhs, grn_ts_bool_vector rhs)
450 {
451 GRN_TS_OP_EQUAL_VECTOR(bool)
452 }
453
454 /* grn_ts_op_equal_int_vector() returns lhs == rhs. */
455 inline static grn_ts_bool
grn_ts_op_equal_int_vector(grn_ts_int_vector lhs,grn_ts_int_vector rhs)456 grn_ts_op_equal_int_vector(grn_ts_int_vector lhs, grn_ts_int_vector rhs)
457 {
458 GRN_TS_OP_EQUAL_VECTOR(int)
459 }
460
461 /* grn_ts_op_equal_float_vector() returns lhs == rhs. */
462 inline static grn_ts_bool
grn_ts_op_equal_float_vector(grn_ts_float_vector lhs,grn_ts_float_vector rhs)463 grn_ts_op_equal_float_vector(grn_ts_float_vector lhs, grn_ts_float_vector rhs)
464 {
465 GRN_TS_OP_EQUAL_VECTOR(float)
466 }
467
468 /* grn_ts_op_equal_time_vector() returns lhs == rhs. */
469 inline static grn_ts_bool
grn_ts_op_equal_time_vector(grn_ts_time_vector lhs,grn_ts_time_vector rhs)470 grn_ts_op_equal_time_vector(grn_ts_time_vector lhs, grn_ts_time_vector rhs)
471 {
472 GRN_TS_OP_EQUAL_VECTOR(time)
473 }
474
475 /* grn_ts_op_equal_text_vector() returns lhs == rhs. */
476 inline static grn_ts_bool
grn_ts_op_equal_text_vector(grn_ts_text_vector lhs,grn_ts_text_vector rhs)477 grn_ts_op_equal_text_vector(grn_ts_text_vector lhs, grn_ts_text_vector rhs)
478 {
479 GRN_TS_OP_EQUAL_VECTOR(text)
480 }
481
482 /* grn_ts_op_equal_geo_vector() returns lhs == rhs. */
483 inline static grn_ts_bool
grn_ts_op_equal_geo_vector(grn_ts_geo_vector lhs,grn_ts_geo_vector rhs)484 grn_ts_op_equal_geo_vector(grn_ts_geo_vector lhs, grn_ts_geo_vector rhs)
485 {
486 GRN_TS_OP_EQUAL_VECTOR(geo)
487 }
488
489 /* grn_ts_op_equal_ref_vector() returns lhs == rhs. */
490 inline static grn_ts_bool
grn_ts_op_equal_ref_vector(grn_ts_ref_vector lhs,grn_ts_ref_vector rhs)491 grn_ts_op_equal_ref_vector(grn_ts_ref_vector lhs, grn_ts_ref_vector rhs)
492 {
493 GRN_TS_OP_EQUAL_VECTOR(ref)
494 }
495 #undef GRN_TS_OP_EQUAL_VECTOR
496
497 /* grn_ts_op_not_equal_bool() returns lhs != rhs. */
498 inline static grn_ts_bool
grn_ts_op_not_equal_bool(grn_ts_bool lhs,grn_ts_bool rhs)499 grn_ts_op_not_equal_bool(grn_ts_bool lhs, grn_ts_bool rhs)
500 {
501 return lhs != rhs;
502 }
503
504 /* grn_ts_op_not_equal_int() returns lhs != rhs. */
505 inline static grn_ts_bool
grn_ts_op_not_equal_int(grn_ts_int lhs,grn_ts_int rhs)506 grn_ts_op_not_equal_int(grn_ts_int lhs, grn_ts_int rhs)
507 {
508 return lhs != rhs;
509 }
510
511 /* grn_ts_op_not_equal_float() returns lhs != rhs. */
512 inline static grn_ts_bool
grn_ts_op_not_equal_float(grn_ts_float lhs,grn_ts_float rhs)513 grn_ts_op_not_equal_float(grn_ts_float lhs, grn_ts_float rhs)
514 {
515 /* To suppress warnings, "lhs != rhs" is not used. */
516 return !grn_ts_op_equal_float(lhs, rhs);
517 }
518
519 /* grn_ts_op_not_equal_time() returns lhs != rhs. */
520 inline static grn_ts_bool
grn_ts_op_not_equal_time(grn_ts_time lhs,grn_ts_time rhs)521 grn_ts_op_not_equal_time(grn_ts_time lhs, grn_ts_time rhs)
522 {
523 return lhs != rhs;
524 }
525
526 /* grn_ts_op_not_equal_text() returns lhs != rhs. */
527 inline static grn_ts_bool
grn_ts_op_not_equal_text(grn_ts_text lhs,grn_ts_text rhs)528 grn_ts_op_not_equal_text(grn_ts_text lhs, grn_ts_text rhs)
529 {
530 return (lhs.size != rhs.size) || memcmp(lhs.ptr, rhs.ptr, lhs.size);
531 }
532
533 /* grn_ts_op_not_equal_geo() returns lhs != rhs. */
534 inline static grn_ts_bool
grn_ts_op_not_equal_geo(grn_ts_geo lhs,grn_ts_geo rhs)535 grn_ts_op_not_equal_geo(grn_ts_geo lhs, grn_ts_geo rhs)
536 {
537 return (lhs.latitude != rhs.latitude) || (lhs.longitude != rhs.longitude);
538 }
539
540 /* grn_ts_op_not_equal_ref() returns lhs != rhs. */
541 inline static grn_ts_bool
grn_ts_op_not_equal_ref(grn_ts_ref lhs,grn_ts_ref rhs)542 grn_ts_op_not_equal_ref(grn_ts_ref lhs, grn_ts_ref rhs)
543 {
544 /* Ignore scores. */
545 return lhs.id != rhs.id;
546 }
547
548 #define GRN_TS_OP_NOT_EQUAL_VECTOR(kind)\
549 size_t i;\
550 if (lhs.size != rhs.size) {\
551 return GRN_TRUE;\
552 }\
553 for (i = 0; i < lhs.size; i++) {\
554 if (grn_ts_op_not_equal_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
555 return GRN_TRUE;\
556 }\
557 }\
558 return GRN_FALSE;
559 /* grn_ts_op_not_equal_bool_vector() returns lhs != rhs. */
560 inline static grn_ts_bool
grn_ts_op_not_equal_bool_vector(grn_ts_bool_vector lhs,grn_ts_bool_vector rhs)561 grn_ts_op_not_equal_bool_vector(grn_ts_bool_vector lhs, grn_ts_bool_vector rhs)
562 {
563 GRN_TS_OP_NOT_EQUAL_VECTOR(bool)
564 }
565
566 /* grn_ts_op_not_equal_int_vector() returns lhs != rhs. */
567 inline static grn_ts_bool
grn_ts_op_not_equal_int_vector(grn_ts_int_vector lhs,grn_ts_int_vector rhs)568 grn_ts_op_not_equal_int_vector(grn_ts_int_vector lhs, grn_ts_int_vector rhs)
569 {
570 GRN_TS_OP_NOT_EQUAL_VECTOR(int)
571 }
572
573 /* grn_ts_op_not_equal_float_vector() returns lhs != rhs. */
574 inline static grn_ts_bool
grn_ts_op_not_equal_float_vector(grn_ts_float_vector lhs,grn_ts_float_vector rhs)575 grn_ts_op_not_equal_float_vector(grn_ts_float_vector lhs,
576 grn_ts_float_vector rhs)
577 {
578 GRN_TS_OP_NOT_EQUAL_VECTOR(float)
579 }
580
581 /* grn_ts_op_not_equal_time_vector() returns lhs != rhs. */
582 inline static grn_ts_bool
grn_ts_op_not_equal_time_vector(grn_ts_time_vector lhs,grn_ts_time_vector rhs)583 grn_ts_op_not_equal_time_vector(grn_ts_time_vector lhs, grn_ts_time_vector rhs)
584 {
585 GRN_TS_OP_NOT_EQUAL_VECTOR(time)
586 }
587
588 /* grn_ts_op_not_equal_text_vector() returns lhs != rhs. */
589 inline static grn_ts_bool
grn_ts_op_not_equal_text_vector(grn_ts_text_vector lhs,grn_ts_text_vector rhs)590 grn_ts_op_not_equal_text_vector(grn_ts_text_vector lhs, grn_ts_text_vector rhs)
591 {
592 GRN_TS_OP_NOT_EQUAL_VECTOR(text)
593 }
594
595 /* grn_ts_op_not_equal_geo_vector() returns lhs != rhs. */
596 inline static grn_ts_bool
grn_ts_op_not_equal_geo_vector(grn_ts_geo_vector lhs,grn_ts_geo_vector rhs)597 grn_ts_op_not_equal_geo_vector(grn_ts_geo_vector lhs, grn_ts_geo_vector rhs)
598 {
599 GRN_TS_OP_NOT_EQUAL_VECTOR(geo)
600 }
601
602 /* grn_ts_op_not_equal_ref_vector() returns lhs != rhs. */
603 inline static grn_ts_bool
grn_ts_op_not_equal_ref_vector(grn_ts_ref_vector lhs,grn_ts_ref_vector rhs)604 grn_ts_op_not_equal_ref_vector(grn_ts_ref_vector lhs, grn_ts_ref_vector rhs)
605 {
606 GRN_TS_OP_NOT_EQUAL_VECTOR(ref)
607 }
608 #undef GRN_TS_OP_NOT_EQUAL_VECTOR
609
610 /* grn_ts_op_less_int() returns lhs < rhs. */
611 inline static grn_ts_bool
grn_ts_op_less_int(grn_ts_int lhs,grn_ts_int rhs)612 grn_ts_op_less_int(grn_ts_int lhs, grn_ts_int rhs)
613 {
614 return lhs < rhs;
615 }
616
617 /* grn_ts_op_less_float() returns lhs < rhs. */
618 inline static grn_ts_bool
grn_ts_op_less_float(grn_ts_float lhs,grn_ts_float rhs)619 grn_ts_op_less_float(grn_ts_float lhs, grn_ts_float rhs)
620 {
621 return lhs < rhs;
622 }
623
624 /* grn_ts_op_less_time() returns lhs < rhs. */
625 inline static grn_ts_bool
grn_ts_op_less_time(grn_ts_time lhs,grn_ts_time rhs)626 grn_ts_op_less_time(grn_ts_time lhs, grn_ts_time rhs)
627 {
628 return lhs < rhs;
629 }
630
631 /* grn_ts_op_less_text() returns lhs < rhs. */
632 inline static grn_ts_bool
grn_ts_op_less_text(grn_ts_text lhs,grn_ts_text rhs)633 grn_ts_op_less_text(grn_ts_text lhs, grn_ts_text rhs)
634 {
635 size_t min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;
636 int cmp = memcmp(lhs.ptr, rhs.ptr, min_size);
637 return cmp ? (cmp < 0) : (lhs.size < rhs.size);
638 }
639
640 #define GRN_TS_OP_LESS_VECTOR(kind)\
641 size_t i, min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;\
642 for (i = 0; i < min_size; i++) {\
643 if (grn_ts_op_not_equal_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
644 if (grn_ts_op_less_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
645 return GRN_TRUE;\
646 }\
647 }\
648 }\
649 return lhs.size < rhs.size;
650 /* grn_ts_op_less_int_vector() returns lhs < rhs. */
651 inline static grn_ts_bool
grn_ts_op_less_int_vector(grn_ts_int_vector lhs,grn_ts_int_vector rhs)652 grn_ts_op_less_int_vector(grn_ts_int_vector lhs, grn_ts_int_vector rhs)
653 {
654 GRN_TS_OP_LESS_VECTOR(int)
655 }
656
657 /* grn_ts_op_less_float_vector() returns lhs < rhs. */
658 inline static grn_ts_bool
grn_ts_op_less_float_vector(grn_ts_float_vector lhs,grn_ts_float_vector rhs)659 grn_ts_op_less_float_vector(grn_ts_float_vector lhs, grn_ts_float_vector rhs)
660 {
661 GRN_TS_OP_LESS_VECTOR(float)
662 }
663
664 /* grn_ts_op_less_time_vector() returns lhs < rhs. */
665 inline static grn_ts_bool
grn_ts_op_less_time_vector(grn_ts_time_vector lhs,grn_ts_time_vector rhs)666 grn_ts_op_less_time_vector(grn_ts_time_vector lhs, grn_ts_time_vector rhs)
667 {
668 GRN_TS_OP_LESS_VECTOR(time)
669 }
670
671 /* grn_ts_op_less_text_vector() returns lhs < rhs. */
672 inline static grn_ts_bool
grn_ts_op_less_text_vector(grn_ts_text_vector lhs,grn_ts_text_vector rhs)673 grn_ts_op_less_text_vector(grn_ts_text_vector lhs, grn_ts_text_vector rhs)
674 {
675 GRN_TS_OP_LESS_VECTOR(text)
676 }
677 #undef GRN_TS_OP_LESS_VECTOR
678
679 /* grn_ts_op_less_equal_int() returns lhs <= rhs. */
680 inline static grn_ts_bool
grn_ts_op_less_equal_int(grn_ts_int lhs,grn_ts_int rhs)681 grn_ts_op_less_equal_int(grn_ts_int lhs, grn_ts_int rhs)
682 {
683 return lhs <= rhs;
684 }
685
686 /* grn_ts_op_less_equal_float() returns lhs <= rhs. */
687 inline static grn_ts_bool
grn_ts_op_less_equal_float(grn_ts_float lhs,grn_ts_float rhs)688 grn_ts_op_less_equal_float(grn_ts_float lhs, grn_ts_float rhs)
689 {
690 return lhs <= rhs;
691 }
692
693 /* grn_ts_op_less_equal_time() returns lhs <= rhs. */
694 inline static grn_ts_bool
grn_ts_op_less_equal_time(grn_ts_time lhs,grn_ts_time rhs)695 grn_ts_op_less_equal_time(grn_ts_time lhs, grn_ts_time rhs)
696 {
697 return lhs <= rhs;
698 }
699
700 /* grn_ts_op_less_equal_text() returns lhs <= rhs. */
701 inline static grn_ts_bool
grn_ts_op_less_equal_text(grn_ts_text lhs,grn_ts_text rhs)702 grn_ts_op_less_equal_text(grn_ts_text lhs, grn_ts_text rhs)
703 {
704 size_t min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;
705 int cmp = memcmp(lhs.ptr, rhs.ptr, min_size);
706 return cmp ? (cmp < 0) : (lhs.size <= rhs.size);
707 }
708
709 #define GRN_TS_OP_LESS_EQUAL_VECTOR(kind)\
710 size_t i, min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;\
711 for (i = 0; i < min_size; i++) {\
712 if (grn_ts_op_not_equal_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
713 if (grn_ts_op_less_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
714 return GRN_TRUE;\
715 }\
716 }\
717 }\
718 return lhs.size <= rhs.size;
719 /* grn_ts_op_less_equal_int_vector() returns lhs <= rhs. */
720 inline static grn_ts_bool
grn_ts_op_less_equal_int_vector(grn_ts_int_vector lhs,grn_ts_int_vector rhs)721 grn_ts_op_less_equal_int_vector(grn_ts_int_vector lhs, grn_ts_int_vector rhs)
722 {
723 GRN_TS_OP_LESS_EQUAL_VECTOR(int)
724 }
725
726 /* grn_ts_op_less_equal_float_vector() returns lhs <= rhs. */
727 inline static grn_ts_bool
grn_ts_op_less_equal_float_vector(grn_ts_float_vector lhs,grn_ts_float_vector rhs)728 grn_ts_op_less_equal_float_vector(grn_ts_float_vector lhs,
729 grn_ts_float_vector rhs)
730 {
731 GRN_TS_OP_LESS_EQUAL_VECTOR(float)
732 }
733
734 /* grn_ts_op_less_equal_time_vector() returns lhs <= rhs. */
735 inline static grn_ts_bool
grn_ts_op_less_equal_time_vector(grn_ts_time_vector lhs,grn_ts_time_vector rhs)736 grn_ts_op_less_equal_time_vector(grn_ts_time_vector lhs,
737 grn_ts_time_vector rhs)
738 {
739 GRN_TS_OP_LESS_EQUAL_VECTOR(time)
740 }
741
742 /* grn_ts_op_less_equal_text_vector() returns lhs <= rhs. */
743 inline static grn_ts_bool
grn_ts_op_less_equal_text_vector(grn_ts_text_vector lhs,grn_ts_text_vector rhs)744 grn_ts_op_less_equal_text_vector(grn_ts_text_vector lhs,
745 grn_ts_text_vector rhs)
746 {
747 GRN_TS_OP_LESS_EQUAL_VECTOR(text)
748 }
749 #undef GRN_TS_OP_LESS_EQUAL_VECTOR
750
751 /* grn_ts_op_greater_int() returns lhs > rhs. */
752 inline static grn_ts_bool
grn_ts_op_greater_int(grn_ts_int lhs,grn_ts_int rhs)753 grn_ts_op_greater_int(grn_ts_int lhs, grn_ts_int rhs)
754 {
755 return lhs > rhs;
756 }
757
758 /* grn_ts_op_greater_float() returns lhs > rhs. */
759 inline static grn_ts_bool
grn_ts_op_greater_float(grn_ts_float lhs,grn_ts_float rhs)760 grn_ts_op_greater_float(grn_ts_float lhs, grn_ts_float rhs)
761 {
762 return lhs > rhs;
763 }
764
765 /* grn_ts_op_greater_time() returns lhs > rhs. */
766 inline static grn_ts_bool
grn_ts_op_greater_time(grn_ts_time lhs,grn_ts_time rhs)767 grn_ts_op_greater_time(grn_ts_time lhs, grn_ts_time rhs)
768 {
769 return lhs > rhs;
770 }
771
772 /* grn_ts_op_greater_text() returns lhs > rhs. */
773 inline static grn_ts_bool
grn_ts_op_greater_text(grn_ts_text lhs,grn_ts_text rhs)774 grn_ts_op_greater_text(grn_ts_text lhs, grn_ts_text rhs)
775 {
776 size_t min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;
777 int cmp = memcmp(lhs.ptr, rhs.ptr, min_size);
778 return cmp ? (cmp > 0) : (lhs.size > rhs.size);
779 }
780
781 #define GRN_TS_OP_GREATER_VECTOR(kind)\
782 size_t i, min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;\
783 for (i = 0; i < min_size; i++) {\
784 if (grn_ts_op_not_equal_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
785 if (grn_ts_op_greater_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
786 return GRN_TRUE;\
787 }\
788 }\
789 }\
790 return lhs.size > rhs.size;
791 /* grn_ts_op_greater_int_vector() returns lhs > rhs. */
792 inline static grn_ts_bool
grn_ts_op_greater_int_vector(grn_ts_int_vector lhs,grn_ts_int_vector rhs)793 grn_ts_op_greater_int_vector(grn_ts_int_vector lhs, grn_ts_int_vector rhs)
794 {
795 GRN_TS_OP_GREATER_VECTOR(int)
796 }
797
798 /* grn_ts_op_greater_float_vector() returns lhs > rhs. */
799 inline static grn_ts_bool
grn_ts_op_greater_float_vector(grn_ts_float_vector lhs,grn_ts_float_vector rhs)800 grn_ts_op_greater_float_vector(grn_ts_float_vector lhs,
801 grn_ts_float_vector rhs)
802 {
803 GRN_TS_OP_GREATER_VECTOR(float)
804 }
805
806 /* grn_ts_op_greater_time_vector() returns lhs > rhs. */
807 inline static grn_ts_bool
grn_ts_op_greater_time_vector(grn_ts_time_vector lhs,grn_ts_time_vector rhs)808 grn_ts_op_greater_time_vector(grn_ts_time_vector lhs, grn_ts_time_vector rhs)
809 {
810 GRN_TS_OP_GREATER_VECTOR(time)
811 }
812
813 /* grn_ts_op_greater_text_vector() returns lhs > rhs. */
814 inline static grn_ts_bool
grn_ts_op_greater_text_vector(grn_ts_text_vector lhs,grn_ts_text_vector rhs)815 grn_ts_op_greater_text_vector(grn_ts_text_vector lhs, grn_ts_text_vector rhs)
816 {
817 GRN_TS_OP_GREATER_VECTOR(text)
818 }
819 #undef GRN_TS_OP_GREATER_VECTOR
820
821 /* grn_ts_op_greater_equal_int() returns lhs >= rhs. */
822 inline static grn_ts_bool
grn_ts_op_greater_equal_int(grn_ts_int lhs,grn_ts_int rhs)823 grn_ts_op_greater_equal_int(grn_ts_int lhs, grn_ts_int rhs)
824 {
825 return lhs >= rhs;
826 }
827
828 /* grn_ts_op_greater_equal_float() returns lhs >= rhs. */
829 inline static grn_ts_bool
grn_ts_op_greater_equal_float(grn_ts_float lhs,grn_ts_float rhs)830 grn_ts_op_greater_equal_float(grn_ts_float lhs, grn_ts_float rhs)
831 {
832 return lhs >= rhs;
833 }
834
835 /* grn_ts_op_greater_equal_time() returns lhs >= rhs. */
836 inline static grn_ts_bool
grn_ts_op_greater_equal_time(grn_ts_time lhs,grn_ts_time rhs)837 grn_ts_op_greater_equal_time(grn_ts_time lhs, grn_ts_time rhs)
838 {
839 return lhs >= rhs;
840 }
841
842 /* grn_ts_op_greater_equal_text() returns lhs >= rhs. */
843 inline static grn_ts_bool
grn_ts_op_greater_equal_text(grn_ts_text lhs,grn_ts_text rhs)844 grn_ts_op_greater_equal_text(grn_ts_text lhs, grn_ts_text rhs)
845 {
846 size_t min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;
847 int cmp = memcmp(lhs.ptr, rhs.ptr, min_size);
848 return cmp ? (cmp > 0) : (lhs.size >= rhs.size);
849 }
850
851 #define GRN_TS_OP_GREATER_EQUAL_VECTOR(kind)\
852 size_t i, min_size = (lhs.size < rhs.size) ? lhs.size : rhs.size;\
853 for (i = 0; i < min_size; i++) {\
854 if (grn_ts_op_not_equal_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
855 if (grn_ts_op_greater_ ## kind(lhs.ptr[i], rhs.ptr[i])) {\
856 return GRN_TRUE;\
857 }\
858 }\
859 }\
860 return lhs.size >= rhs.size;
861 /* grn_ts_op_greater_equal_int_vector() returns lhs >= rhs. */
862 inline static grn_ts_bool
grn_ts_op_greater_equal_int_vector(grn_ts_int_vector lhs,grn_ts_int_vector rhs)863 grn_ts_op_greater_equal_int_vector(grn_ts_int_vector lhs,
864 grn_ts_int_vector rhs)
865 {
866 GRN_TS_OP_GREATER_EQUAL_VECTOR(int)
867 }
868
869 /* grn_ts_op_greater_equal_float_vector() returns lhs >= rhs. */
870 inline static grn_ts_bool
grn_ts_op_greater_equal_float_vector(grn_ts_float_vector lhs,grn_ts_float_vector rhs)871 grn_ts_op_greater_equal_float_vector(grn_ts_float_vector lhs,
872 grn_ts_float_vector rhs)
873 {
874 GRN_TS_OP_GREATER_EQUAL_VECTOR(float)
875 }
876
877 /* grn_ts_op_greater_equal_time_vector() returns lhs >= rhs. */
878 inline static grn_ts_bool
grn_ts_op_greater_equal_time_vector(grn_ts_time_vector lhs,grn_ts_time_vector rhs)879 grn_ts_op_greater_equal_time_vector(grn_ts_time_vector lhs,
880 grn_ts_time_vector rhs)
881 {
882 GRN_TS_OP_GREATER_EQUAL_VECTOR(time)
883 }
884
885 /* grn_ts_op_greater_equal_text_vector() returns lhs >= rhs. */
886 inline static grn_ts_bool
grn_ts_op_greater_equal_text_vector(grn_ts_text_vector lhs,grn_ts_text_vector rhs)887 grn_ts_op_greater_equal_text_vector(grn_ts_text_vector lhs,
888 grn_ts_text_vector rhs)
889 {
890 GRN_TS_OP_GREATER_EQUAL_VECTOR(text)
891 }
892 #undef GRN_TS_OP_GREATER_EQUAL_VECTOR
893
894 /* grn_ts_op_shift_arithmetic_left() returns lhs << rhs. */
895 inline static grn_ts_int
grn_ts_op_shift_arithmetic_left(grn_ts_int lhs,grn_ts_int rhs)896 grn_ts_op_shift_arithmetic_left(grn_ts_int lhs, grn_ts_int rhs)
897 {
898 return lhs << rhs;
899 }
900
901 /* grn_ts_op_shift_arithmetic_right() returns lhs << rhs. */
902 inline static grn_ts_int
grn_ts_op_shift_arithmetic_right(grn_ts_int lhs,grn_ts_int rhs)903 grn_ts_op_shift_arithmetic_right(grn_ts_int lhs, grn_ts_int rhs)
904 {
905 return lhs >> rhs;
906 }
907
908 /* grn_ts_op_shift_logical_left() returns lhs << rhs. */
909 inline static grn_ts_int
grn_ts_op_shift_logical_left(grn_ts_int lhs,grn_ts_int rhs)910 grn_ts_op_shift_logical_left(grn_ts_int lhs, grn_ts_int rhs)
911 {
912 return lhs << rhs;
913 }
914
915 /* grn_ts_op_shift_logical_right() returns lhs << rhs. */
916 inline static grn_ts_int
grn_ts_op_shift_logical_right(grn_ts_int lhs,grn_ts_int rhs)917 grn_ts_op_shift_logical_right(grn_ts_int lhs, grn_ts_int rhs)
918 {
919 return (uint64_t)lhs >> rhs;
920 }
921
922 inline static grn_rc
grn_ts_op_plus_int_int(grn_ctx * ctx,grn_ts_int lhs,grn_ts_int rhs,grn_ts_int * out)923 grn_ts_op_plus_int_int(grn_ctx *ctx, grn_ts_int lhs, grn_ts_int rhs,
924 grn_ts_int *out)
925 {
926 *out = lhs + rhs;
927 return GRN_SUCCESS;
928 }
929
930 inline static grn_rc
grn_ts_op_plus_float_float(grn_ctx * ctx,grn_ts_float lhs,grn_ts_float rhs,grn_ts_float * out)931 grn_ts_op_plus_float_float(grn_ctx *ctx, grn_ts_float lhs, grn_ts_float rhs,
932 grn_ts_float *out)
933 {
934 *out = lhs + rhs;
935 if (!grn_ts_float_is_valid(*out)) {
936 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "%g + %g = %g", lhs, rhs, *out);
937 }
938 return GRN_SUCCESS;
939 }
940
941 inline static grn_rc
grn_ts_op_plus_time_int(grn_ctx * ctx,grn_ts_time lhs,grn_ts_int rhs,grn_ts_time * out)942 grn_ts_op_plus_time_int(grn_ctx *ctx, grn_ts_time lhs, grn_ts_int rhs,
943 grn_ts_time *out)
944 {
945 *out = lhs + (rhs * 1000000);
946 return GRN_SUCCESS;
947 }
948
949 inline static grn_rc
grn_ts_op_plus_time_float(grn_ctx * ctx,grn_ts_time lhs,grn_ts_float rhs,grn_ts_time * out)950 grn_ts_op_plus_time_float(grn_ctx *ctx, grn_ts_time lhs, grn_ts_float rhs,
951 grn_ts_time *out)
952 {
953 *out = (grn_ts_time)(lhs + (rhs * 1000000.0));
954 return GRN_SUCCESS;
955 }
956
957 inline static grn_rc
grn_ts_op_minus_int_int(grn_ctx * ctx,grn_ts_int lhs,grn_ts_int rhs,grn_ts_int * out)958 grn_ts_op_minus_int_int(grn_ctx *ctx, grn_ts_int lhs, grn_ts_int rhs,
959 grn_ts_int *out)
960 {
961 *out = lhs - rhs;
962 return GRN_SUCCESS;
963 }
964
965 inline static grn_rc
grn_ts_op_minus_float_float(grn_ctx * ctx,grn_ts_float lhs,grn_ts_float rhs,grn_ts_float * out)966 grn_ts_op_minus_float_float(grn_ctx *ctx, grn_ts_float lhs, grn_ts_float rhs,
967 grn_ts_float *out)
968 {
969 *out = lhs - rhs;
970 if (!grn_ts_float_is_valid(*out)) {
971 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "%g - %g = %g", lhs, rhs, *out);
972 }
973 return GRN_SUCCESS;
974 }
975
976 inline static grn_rc
grn_ts_op_minus_time_time(grn_ctx * ctx,grn_ts_time lhs,grn_ts_time rhs,grn_ts_float * out)977 grn_ts_op_minus_time_time(grn_ctx *ctx, grn_ts_time lhs, grn_ts_time rhs,
978 grn_ts_float *out)
979 {
980 *out = (lhs - rhs) * 0.000001;
981 return GRN_SUCCESS;
982 }
983
984 inline static grn_rc
grn_ts_op_minus_time_int(grn_ctx * ctx,grn_ts_time lhs,grn_ts_int rhs,grn_ts_time * out)985 grn_ts_op_minus_time_int(grn_ctx *ctx, grn_ts_time lhs, grn_ts_int rhs,
986 grn_ts_time *out)
987 {
988 *out = lhs - (rhs * 1000000);
989 return GRN_SUCCESS;
990 }
991
992 inline static grn_rc
grn_ts_op_minus_time_float(grn_ctx * ctx,grn_ts_time lhs,grn_ts_float rhs,grn_ts_time * out)993 grn_ts_op_minus_time_float(grn_ctx *ctx, grn_ts_time lhs, grn_ts_float rhs,
994 grn_ts_time *out)
995 {
996 *out = lhs - (grn_ts_int)(rhs * 1000000.0);
997 return GRN_SUCCESS;
998 }
999
1000 inline static grn_rc
grn_ts_op_multiplication_int_int(grn_ctx * ctx,grn_ts_int lhs,grn_ts_int rhs,grn_ts_int * out)1001 grn_ts_op_multiplication_int_int(grn_ctx *ctx, grn_ts_int lhs, grn_ts_int rhs,
1002 grn_ts_int *out)
1003 {
1004 *out = lhs * rhs;
1005 return GRN_SUCCESS;
1006 }
1007
1008 inline static grn_rc
grn_ts_op_multiplication_float_float(grn_ctx * ctx,grn_ts_float lhs,grn_ts_float rhs,grn_ts_float * out)1009 grn_ts_op_multiplication_float_float(grn_ctx *ctx, grn_ts_float lhs,
1010 grn_ts_float rhs, grn_ts_float *out)
1011 {
1012 *out = lhs * rhs;
1013 if (!grn_ts_float_is_valid(*out)) {
1014 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "%g * %g = %g", lhs, rhs, *out);
1015 }
1016 return GRN_SUCCESS;
1017 }
1018
1019 inline static grn_rc
grn_ts_op_division_int_int(grn_ctx * ctx,grn_ts_int lhs,grn_ts_int rhs,grn_ts_int * out)1020 grn_ts_op_division_int_int(grn_ctx *ctx, grn_ts_int lhs, grn_ts_int rhs,
1021 grn_ts_int *out)
1022 {
1023 if (!rhs) {
1024 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT,
1025 "%" GRN_FMT_INT64D " / %" GRN_FMT_INT64D
1026 " causes division by zero",
1027 lhs, rhs);
1028 }
1029 *out = (rhs != -1) ? (lhs / rhs) : -lhs;
1030 return GRN_SUCCESS;
1031 }
1032
1033 inline static grn_rc
grn_ts_op_division_float_float(grn_ctx * ctx,grn_ts_float lhs,grn_ts_float rhs,grn_ts_float * out)1034 grn_ts_op_division_float_float(grn_ctx *ctx, grn_ts_float lhs,
1035 grn_ts_float rhs, grn_ts_float *out)
1036 {
1037 *out = lhs / rhs;
1038 if (!grn_ts_float_is_valid(*out)) {
1039 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "%g / %g = %g", lhs, rhs, *out);
1040 }
1041 return GRN_SUCCESS;
1042 }
1043
1044 inline static grn_rc
grn_ts_op_modulus_int_int(grn_ctx * ctx,grn_ts_int lhs,grn_ts_int rhs,grn_ts_int * out)1045 grn_ts_op_modulus_int_int(grn_ctx *ctx, grn_ts_int lhs, grn_ts_int rhs,
1046 grn_ts_int *out)
1047 {
1048 if (!rhs) {
1049 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT,
1050 "%" GRN_FMT_INT64D " %% %" GRN_FMT_INT64D
1051 " causes division by zero",
1052 lhs, rhs);
1053 }
1054 *out = (rhs != -1) ? (lhs % rhs) : -lhs;
1055 return GRN_SUCCESS;
1056 }
1057
1058 inline static grn_rc
grn_ts_op_modulus_float_float(grn_ctx * ctx,grn_ts_float lhs,grn_ts_float rhs,grn_ts_float * out)1059 grn_ts_op_modulus_float_float(grn_ctx *ctx, grn_ts_float lhs, grn_ts_float rhs,
1060 grn_ts_float *out)
1061 {
1062 *out = fmod(lhs, rhs);
1063 if (!grn_ts_float_is_valid(*out)) {
1064 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "%g %% %g = %g", lhs, rhs, *out);
1065 }
1066 return GRN_SUCCESS;
1067 }
1068
1069 static grn_ts_bool
grn_ts_op_match(grn_ts_text lhs,grn_ts_text rhs)1070 grn_ts_op_match(grn_ts_text lhs, grn_ts_text rhs)
1071 {
1072 const char *lhs_ptr, *lhs_ptr_last;
1073 if (lhs.size < rhs.size) {
1074 return GRN_FALSE;
1075 }
1076 lhs_ptr_last = lhs.ptr + lhs.size - rhs.size;
1077 for (lhs_ptr = lhs.ptr; lhs_ptr <= lhs_ptr_last; lhs_ptr++) {
1078 size_t i;
1079 for (i = 0; i < rhs.size; i++) {
1080 if (lhs_ptr[i] != rhs.ptr[i]) {
1081 break;
1082 }
1083 }
1084 if (i == rhs.size) {
1085 return GRN_TRUE;
1086 }
1087 }
1088 return GRN_FALSE;
1089 }
1090
1091 static grn_ts_bool
grn_ts_op_prefix_match(grn_ts_text lhs,grn_ts_text rhs)1092 grn_ts_op_prefix_match(grn_ts_text lhs, grn_ts_text rhs)
1093 {
1094 size_t i;
1095 if (lhs.size < rhs.size) {
1096 return GRN_FALSE;
1097 }
1098 for (i = 0; i < rhs.size; i++) {
1099 if (lhs.ptr[i] != rhs.ptr[i]) {
1100 return GRN_FALSE;
1101 }
1102 }
1103 return GRN_TRUE;
1104 }
1105
1106 static grn_ts_bool
grn_ts_op_suffix_match(grn_ts_text lhs,grn_ts_text rhs)1107 grn_ts_op_suffix_match(grn_ts_text lhs, grn_ts_text rhs)
1108 {
1109 size_t i;
1110 const char *lhs_ptr;
1111 if (lhs.size < rhs.size) {
1112 return GRN_FALSE;
1113 }
1114 lhs_ptr = lhs.ptr + lhs.size - rhs.size;
1115 for (i = 0; i < rhs.size; i++) {
1116 if (lhs_ptr[i] != rhs.ptr[i]) {
1117 return GRN_FALSE;
1118 }
1119 }
1120 return GRN_TRUE;
1121 }
1122
1123 /*-------------------------------------------------------------
1124 * Groonga objects.
1125 */
1126
1127 #define GRN_TS_TABLE_GET_KEY(type)\
1128 uint32_t key_size;\
1129 const void *key_ptr = _grn_ ## type ## _key(ctx, type, id, &key_size);\
1130 if (!key_ptr) {\
1131 GRN_TS_ERR_RETURN(GRN_UNKNOWN_ERROR, "_grn_" #type "_key failed: %u", id);\
1132 }\
1133 /* grn_ts_hash_get_bool_key() gets a reference to a key (_key). */
1134 static grn_rc
grn_ts_hash_get_bool_key(grn_ctx * ctx,grn_hash * hash,grn_ts_id id,grn_ts_bool * key)1135 grn_ts_hash_get_bool_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
1136 grn_ts_bool *key)
1137 {
1138 GRN_TS_TABLE_GET_KEY(hash)
1139 *key = *(const grn_ts_bool *)key_ptr;
1140 return GRN_SUCCESS;
1141 }
1142
1143 /* grn_ts_hash_get_int8_key() gets a reference to a key (_key). */
1144 static grn_rc
grn_ts_hash_get_int8_key(grn_ctx * ctx,grn_hash * hash,grn_ts_id id,grn_ts_int * key)1145 grn_ts_hash_get_int8_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
1146 grn_ts_int *key)
1147 {
1148 GRN_TS_TABLE_GET_KEY(hash)
1149 *key = *(const int8_t *)key_ptr;
1150 return GRN_SUCCESS;
1151 }
1152
1153 /* grn_ts_hash_get_int16_key() gets a reference to a key (_key). */
1154 static grn_rc
grn_ts_hash_get_int16_key(grn_ctx * ctx,grn_hash * hash,grn_ts_id id,grn_ts_int * key)1155 grn_ts_hash_get_int16_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
1156 grn_ts_int *key)
1157 {
1158 GRN_TS_TABLE_GET_KEY(hash)
1159 *key = *(const int16_t *)key_ptr;
1160 return GRN_SUCCESS;
1161 }
1162
1163 /* grn_ts_hash_get_int32_key() gets a reference to a key (_key). */
1164 static grn_rc
grn_ts_hash_get_int32_key(grn_ctx * ctx,grn_hash * hash,grn_ts_id id,grn_ts_int * key)1165 grn_ts_hash_get_int32_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
1166 grn_ts_int *key)
1167 {
1168 GRN_TS_TABLE_GET_KEY(hash)
1169 *key = *(const int32_t *)key_ptr;
1170 return GRN_SUCCESS;
1171 }
1172
1173 /* grn_ts_hash_get_int64_key() gets a reference to a key (_key). */
1174 static grn_rc
grn_ts_hash_get_int64_key(grn_ctx * ctx,grn_hash * hash,grn_ts_id id,grn_ts_int * key)1175 grn_ts_hash_get_int64_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
1176 grn_ts_int *key)
1177 {
1178 GRN_TS_TABLE_GET_KEY(hash)
1179 *key = *(const int64_t *)key_ptr;
1180 return GRN_SUCCESS;
1181 }
1182
1183 /* grn_ts_hash_get_uint8_key() gets a reference to a key (_key). */
1184 static grn_rc
grn_ts_hash_get_uint8_key(grn_ctx * ctx,grn_hash * hash,grn_ts_id id,grn_ts_int * key)1185 grn_ts_hash_get_uint8_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
1186 grn_ts_int *key)
1187 {
1188 GRN_TS_TABLE_GET_KEY(hash)
1189 *key = *(const uint8_t *)key_ptr;
1190 return GRN_SUCCESS;
1191 }
1192
1193 /* grn_ts_hash_get_uint16_key() gets a reference to a key (_key). */
1194 static grn_rc
grn_ts_hash_get_uint16_key(grn_ctx * ctx,grn_hash * hash,grn_ts_id id,grn_ts_int * key)1195 grn_ts_hash_get_uint16_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
1196 grn_ts_int *key)
1197 {
1198 GRN_TS_TABLE_GET_KEY(hash)
1199 *key = *(const uint16_t *)key_ptr;
1200 return GRN_SUCCESS;
1201 }
1202
1203 /* grn_ts_hash_get_uint32_key() gets a reference to a key (_key). */
1204 static grn_rc
grn_ts_hash_get_uint32_key(grn_ctx * ctx,grn_hash * hash,grn_ts_id id,grn_ts_int * key)1205 grn_ts_hash_get_uint32_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
1206 grn_ts_int *key)
1207 {
1208 GRN_TS_TABLE_GET_KEY(hash)
1209 *key = *(const uint32_t *)key_ptr;
1210 return GRN_SUCCESS;
1211 }
1212
1213 /* grn_ts_hash_get_uint64_key() gets a reference to a key (_key). */
1214 static grn_rc
grn_ts_hash_get_uint64_key(grn_ctx * ctx,grn_hash * hash,grn_ts_id id,grn_ts_int * key)1215 grn_ts_hash_get_uint64_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
1216 grn_ts_int *key)
1217 {
1218 GRN_TS_TABLE_GET_KEY(hash)
1219 *key = (grn_ts_int)*(const uint64_t *)key_ptr;
1220 return GRN_SUCCESS;
1221 }
1222
1223 /* grn_ts_hash_get_float_key() gets a reference to a key (_key). */
1224 static grn_rc
grn_ts_hash_get_float_key(grn_ctx * ctx,grn_hash * hash,grn_ts_id id,grn_ts_float * key)1225 grn_ts_hash_get_float_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
1226 grn_ts_float *key)
1227 {
1228 GRN_TS_TABLE_GET_KEY(hash)
1229 *key = *(const grn_ts_float *)key_ptr;
1230 return GRN_SUCCESS;
1231 }
1232
1233 /* grn_ts_hash_get_time_key() gets a reference to a key (_key). */
1234 static grn_rc
grn_ts_hash_get_time_key(grn_ctx * ctx,grn_hash * hash,grn_ts_id id,grn_ts_time * key)1235 grn_ts_hash_get_time_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
1236 grn_ts_time *key)
1237 {
1238 GRN_TS_TABLE_GET_KEY(hash)
1239 *key = *(const grn_ts_time *)key_ptr;
1240 return GRN_SUCCESS;
1241 }
1242
1243 /* grn_ts_hash_get_geo_key() gets a reference to a key (_key). */
1244 static grn_rc
grn_ts_hash_get_geo_key(grn_ctx * ctx,grn_hash * hash,grn_ts_id id,grn_ts_geo * key)1245 grn_ts_hash_get_geo_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
1246 grn_ts_geo *key)
1247 {
1248 GRN_TS_TABLE_GET_KEY(hash)
1249 *key = *(const grn_ts_geo *)key_ptr;
1250 return GRN_SUCCESS;
1251 }
1252
1253 /* grn_ts_hash_get_text_key() gets a reference to a key (_key). */
1254 static grn_rc
grn_ts_hash_get_text_key(grn_ctx * ctx,grn_hash * hash,grn_ts_id id,grn_ts_text * key)1255 grn_ts_hash_get_text_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
1256 grn_ts_text *key)
1257 {
1258 GRN_TS_TABLE_GET_KEY(hash)
1259 key->ptr = key_ptr;
1260 key->size = key_size;
1261 return GRN_SUCCESS;
1262 }
1263
1264 /* grn_ts_hash_get_ref_key() gets a reference to a key (_key). */
1265 static grn_rc
grn_ts_hash_get_ref_key(grn_ctx * ctx,grn_hash * hash,grn_ts_id id,grn_ts_ref * key)1266 grn_ts_hash_get_ref_key(grn_ctx *ctx, grn_hash *hash, grn_ts_id id,
1267 grn_ts_ref *key)
1268 {
1269 GRN_TS_TABLE_GET_KEY(hash)
1270 key->id = *(const grn_ts_id *)key_ptr;
1271 return GRN_SUCCESS;
1272 }
1273
1274 /* grn_ts_pat_get_bool_key() gets a reference to a key (_key). */
1275 static grn_rc
grn_ts_pat_get_bool_key(grn_ctx * ctx,grn_pat * pat,grn_ts_id id,grn_ts_bool * key)1276 grn_ts_pat_get_bool_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
1277 grn_ts_bool *key)
1278 {
1279 GRN_TS_TABLE_GET_KEY(pat)
1280 *key = *(const grn_ts_bool *)key_ptr;
1281 return GRN_SUCCESS;
1282 }
1283
1284 /* grn_ts_pat_get_int8_key() gets a reference to a key (_key). */
1285 static grn_rc
grn_ts_pat_get_int8_key(grn_ctx * ctx,grn_pat * pat,grn_ts_id id,grn_ts_int * key)1286 grn_ts_pat_get_int8_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
1287 grn_ts_int *key)
1288 {
1289 int8_t tmp;
1290 GRN_TS_TABLE_GET_KEY(pat)
1291 grn_ntohi(&tmp, key_ptr, sizeof(tmp));
1292 *key = tmp;
1293 return GRN_SUCCESS;
1294 }
1295
1296 /* grn_ts_pat_get_int16_key() gets a reference to a key (_key). */
1297 static grn_rc
grn_ts_pat_get_int16_key(grn_ctx * ctx,grn_pat * pat,grn_ts_id id,grn_ts_int * key)1298 grn_ts_pat_get_int16_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
1299 grn_ts_int *key)
1300 {
1301 int16_t tmp;
1302 GRN_TS_TABLE_GET_KEY(pat)
1303 grn_ntohi(&tmp, key_ptr, sizeof(tmp));
1304 *key = tmp;
1305 return GRN_SUCCESS;
1306 }
1307
1308 /* grn_ts_pat_get_int32_key() gets a reference to a key (_key). */
1309 static grn_rc
grn_ts_pat_get_int32_key(grn_ctx * ctx,grn_pat * pat,grn_ts_id id,grn_ts_int * key)1310 grn_ts_pat_get_int32_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
1311 grn_ts_int *key)
1312 {
1313 int32_t tmp;
1314 GRN_TS_TABLE_GET_KEY(pat)
1315 grn_ntohi(&tmp, key_ptr, sizeof(tmp));
1316 *key = tmp;
1317 return GRN_SUCCESS;
1318 }
1319
1320 /* grn_ts_pat_get_int64_key() gets a reference to a key (_key). */
1321 static grn_rc
grn_ts_pat_get_int64_key(grn_ctx * ctx,grn_pat * pat,grn_ts_id id,grn_ts_int * key)1322 grn_ts_pat_get_int64_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
1323 grn_ts_int *key)
1324 {
1325 GRN_TS_TABLE_GET_KEY(pat)
1326 grn_ntohi(key, key_ptr, sizeof(grn_ts_int));
1327 return GRN_SUCCESS;
1328 }
1329
1330 /* grn_ts_pat_get_uint8_key() gets a reference to a key (_key). */
1331 static grn_rc
grn_ts_pat_get_uint8_key(grn_ctx * ctx,grn_pat * pat,grn_ts_id id,grn_ts_int * key)1332 grn_ts_pat_get_uint8_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
1333 grn_ts_int *key)
1334 {
1335 GRN_TS_TABLE_GET_KEY(pat)
1336 *key = *(const uint8_t *)key_ptr;
1337 return GRN_SUCCESS;
1338 }
1339
1340 /* grn_ts_pat_get_uint16_key() gets a reference to a key (_key). */
1341 static grn_rc
grn_ts_pat_get_uint16_key(grn_ctx * ctx,grn_pat * pat,grn_ts_id id,grn_ts_int * key)1342 grn_ts_pat_get_uint16_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
1343 grn_ts_int *key)
1344 {
1345 uint16_t tmp;
1346 GRN_TS_TABLE_GET_KEY(pat)
1347 grn_ntoh(&tmp, key_ptr, sizeof(tmp));
1348 *key = tmp;
1349 return GRN_SUCCESS;
1350 }
1351
1352 /* grn_ts_pat_get_uint32_key() gets a reference to a key (_key). */
1353 static grn_rc
grn_ts_pat_get_uint32_key(grn_ctx * ctx,grn_pat * pat,grn_ts_id id,grn_ts_int * key)1354 grn_ts_pat_get_uint32_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
1355 grn_ts_int *key)
1356 {
1357 uint32_t tmp;
1358 GRN_TS_TABLE_GET_KEY(pat)
1359 grn_ntoh(&tmp, key_ptr, sizeof(tmp));
1360 *key = tmp;
1361 return GRN_SUCCESS;
1362 }
1363
1364 /* grn_ts_pat_get_uint64_key() gets a reference to a key (_key). */
1365 static grn_rc
grn_ts_pat_get_uint64_key(grn_ctx * ctx,grn_pat * pat,grn_ts_id id,grn_ts_int * key)1366 grn_ts_pat_get_uint64_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
1367 grn_ts_int *key)
1368 {
1369 GRN_TS_TABLE_GET_KEY(pat)
1370 grn_ntoh(key, key_ptr, sizeof(grn_ts_int));
1371 return GRN_SUCCESS;
1372 }
1373
1374 /* grn_ts_pat_get_float_key() gets a reference to a key (_key). */
1375 static grn_rc
grn_ts_pat_get_float_key(grn_ctx * ctx,grn_pat * pat,grn_ts_id id,grn_ts_float * key)1376 grn_ts_pat_get_float_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
1377 grn_ts_float *key)
1378 {
1379 int64_t tmp;
1380 GRN_TS_TABLE_GET_KEY(pat)
1381 grn_ntoh(&tmp, key_ptr, sizeof(tmp));
1382 tmp ^= (((tmp ^ ((int64_t)1 << 63)) >> 63) | ((int64_t)1 << 63));
1383 *(int64_t *)key = tmp;
1384 return GRN_SUCCESS;
1385 }
1386
1387 /* grn_ts_pat_get_time_key() gets a reference to a key (_key). */
1388 static grn_rc
grn_ts_pat_get_time_key(grn_ctx * ctx,grn_pat * pat,grn_ts_id id,grn_ts_time * key)1389 grn_ts_pat_get_time_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
1390 grn_ts_time *key)
1391 {
1392 GRN_TS_TABLE_GET_KEY(pat)
1393 grn_ntohi(key, key_ptr, sizeof(grn_ts_time));
1394 return GRN_SUCCESS;
1395 }
1396
1397 /* grn_ts_pat_get_geo_key() gets a reference to a key (_key). */
1398 static grn_rc
grn_ts_pat_get_geo_key(grn_ctx * ctx,grn_pat * pat,grn_ts_id id,grn_ts_geo * key)1399 grn_ts_pat_get_geo_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
1400 grn_ts_geo *key)
1401 {
1402 GRN_TS_TABLE_GET_KEY(pat)
1403 grn_ntog(key, key_ptr, sizeof(grn_ts_geo));
1404 return GRN_SUCCESS;
1405 }
1406
1407 /* grn_ts_pat_get_text_key() gets a reference to a key (_key). */
1408 static grn_rc
grn_ts_pat_get_text_key(grn_ctx * ctx,grn_pat * pat,grn_ts_id id,grn_ts_text * key)1409 grn_ts_pat_get_text_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
1410 grn_ts_text *key)
1411 {
1412 GRN_TS_TABLE_GET_KEY(pat)
1413 key->ptr = key_ptr;
1414 key->size = key_size;
1415 return GRN_SUCCESS;
1416 }
1417
1418 /* grn_ts_pat_get_ref_key() gets a reference to a key (_key). */
1419 static grn_rc
grn_ts_pat_get_ref_key(grn_ctx * ctx,grn_pat * pat,grn_ts_id id,grn_ts_ref * key)1420 grn_ts_pat_get_ref_key(grn_ctx *ctx, grn_pat *pat, grn_ts_id id,
1421 grn_ts_ref *key)
1422 {
1423 GRN_TS_TABLE_GET_KEY(pat)
1424 grn_ntoh(&key->id, key_ptr, sizeof(key->id));
1425 return GRN_SUCCESS;
1426 }
1427
1428 /* grn_ts_dat_get_text_key() gets a reference to a key (_key). */
1429 static grn_rc
grn_ts_dat_get_text_key(grn_ctx * ctx,grn_dat * dat,grn_ts_id id,grn_ts_text * key)1430 grn_ts_dat_get_text_key(grn_ctx *ctx, grn_dat *dat, grn_ts_id id,
1431 grn_ts_text *key)
1432 {
1433 GRN_TS_TABLE_GET_KEY(dat)
1434 key->ptr = key_ptr;
1435 key->size = key_size;
1436 return GRN_SUCCESS;
1437 }
1438 #undef GRN_TS_TABLE_GET_KEY
1439
1440 /*-------------------------------------------------------------
1441 * grn_ts_expr_id_node.
1442 */
1443
1444 typedef struct {
1445 GRN_TS_EXPR_NODE_COMMON_MEMBERS
1446 } grn_ts_expr_id_node;
1447
1448 /* grn_ts_expr_id_node_init() initializes a node. */
1449 static void
grn_ts_expr_id_node_init(grn_ctx * ctx,grn_ts_expr_id_node * node)1450 grn_ts_expr_id_node_init(grn_ctx *ctx, grn_ts_expr_id_node *node)
1451 {
1452 memset(node, 0, sizeof(*node));
1453 node->type = GRN_TS_EXPR_ID_NODE;
1454 node->data_kind = GRN_TS_INT;
1455 node->data_type = GRN_DB_UINT32;
1456 }
1457
1458 /* grn_ts_expr_id_node_fin() finalizes a node. */
1459 static void
grn_ts_expr_id_node_fin(grn_ctx * ctx,grn_ts_expr_id_node * node)1460 grn_ts_expr_id_node_fin(grn_ctx *ctx, grn_ts_expr_id_node *node)
1461 {
1462 /* Nothing to do. */
1463 }
1464
1465 grn_rc
grn_ts_expr_id_node_open(grn_ctx * ctx,grn_ts_expr_node ** node)1466 grn_ts_expr_id_node_open(grn_ctx *ctx, grn_ts_expr_node **node)
1467 {
1468 grn_ts_expr_id_node *new_node = GRN_MALLOCN(grn_ts_expr_id_node, 1);
1469 if (!new_node) {
1470 GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
1471 "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
1472 sizeof(grn_ts_expr_id_node));
1473 }
1474 grn_ts_expr_id_node_init(ctx, new_node);
1475 *node = (grn_ts_expr_node *)new_node;
1476 return GRN_SUCCESS;
1477 }
1478
1479 /* grn_ts_expr_id_node_close() destroys a node. */
1480 static void
grn_ts_expr_id_node_close(grn_ctx * ctx,grn_ts_expr_id_node * node)1481 grn_ts_expr_id_node_close(grn_ctx *ctx, grn_ts_expr_id_node *node)
1482 {
1483 grn_ts_expr_id_node_fin(ctx, node);
1484 GRN_FREE(node);
1485 }
1486
1487 /* grn_ts_expr_id_node_evaluate() outputs IDs. */
1488 static grn_rc
grn_ts_expr_id_node_evaluate(grn_ctx * ctx,grn_ts_expr_id_node * node,const grn_ts_record * in,size_t n_in,void * out)1489 grn_ts_expr_id_node_evaluate(grn_ctx *ctx, grn_ts_expr_id_node *node,
1490 const grn_ts_record *in, size_t n_in, void *out)
1491 {
1492 size_t i;
1493 grn_ts_int *out_ptr = (grn_ts_int *)out;
1494 for (i = 0; i < n_in; i++) {
1495 out_ptr[i] = (grn_ts_int)in[i].id;
1496 }
1497 return GRN_SUCCESS;
1498 }
1499
1500 /*-------------------------------------------------------------
1501 * grn_ts_expr_score_node.
1502 */
1503
1504 typedef struct {
1505 GRN_TS_EXPR_NODE_COMMON_MEMBERS
1506 } grn_ts_expr_score_node;
1507
1508 /* grn_ts_expr_score_node_init() initializes a node. */
1509 static void
grn_ts_expr_score_node_init(grn_ctx * ctx,grn_ts_expr_score_node * node)1510 grn_ts_expr_score_node_init(grn_ctx *ctx, grn_ts_expr_score_node *node)
1511 {
1512 memset(node, 0, sizeof(*node));
1513 node->type = GRN_TS_EXPR_SCORE_NODE;
1514 node->data_kind = GRN_TS_FLOAT;
1515 node->data_type = GRN_DB_FLOAT;
1516 }
1517
1518 /* grn_ts_expr_score_node_fin() finalizes a node. */
1519 static void
grn_ts_expr_score_node_fin(grn_ctx * ctx,grn_ts_expr_score_node * node)1520 grn_ts_expr_score_node_fin(grn_ctx *ctx, grn_ts_expr_score_node *node)
1521 {
1522 /* Nothing to do. */
1523 }
1524
1525 grn_rc
grn_ts_expr_score_node_open(grn_ctx * ctx,grn_ts_expr_node ** node)1526 grn_ts_expr_score_node_open(grn_ctx *ctx, grn_ts_expr_node **node)
1527 {
1528 grn_ts_expr_score_node *new_node = GRN_MALLOCN(grn_ts_expr_score_node, 1);
1529 if (!new_node) {
1530 GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
1531 "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
1532 sizeof(grn_ts_expr_score_node));
1533 }
1534 grn_ts_expr_score_node_init(ctx, new_node);
1535 *node = (grn_ts_expr_node *)new_node;
1536 return GRN_SUCCESS;
1537 }
1538
1539 /* grn_ts_expr_score_node_close() destroys a node. */
1540 static void
grn_ts_expr_score_node_close(grn_ctx * ctx,grn_ts_expr_score_node * node)1541 grn_ts_expr_score_node_close(grn_ctx *ctx, grn_ts_expr_score_node *node)
1542 {
1543 grn_ts_expr_score_node_fin(ctx, node);
1544 GRN_FREE(node);
1545 }
1546
1547 /* grn_ts_expr_score_node_evaluate() outputs scores. */
1548 static grn_rc
grn_ts_expr_score_node_evaluate(grn_ctx * ctx,grn_ts_expr_score_node * node,const grn_ts_record * in,size_t n_in,void * out)1549 grn_ts_expr_score_node_evaluate(grn_ctx *ctx, grn_ts_expr_score_node *node,
1550 const grn_ts_record *in, size_t n_in,
1551 void *out)
1552 {
1553 size_t i;
1554 grn_ts_float *out_ptr = (grn_ts_float *)out;
1555 for (i = 0; i < n_in; i++) {
1556 out_ptr[i] = (grn_ts_float)in[i].score;
1557 }
1558 return GRN_SUCCESS;
1559 }
1560
1561 /* grn_ts_expr_score_node_adjust() does nothing. */
1562 static grn_rc
grn_ts_expr_score_node_adjust(grn_ctx * ctx,grn_ts_expr_score_node * node,grn_ts_record * io,size_t n_io)1563 grn_ts_expr_score_node_adjust(grn_ctx *ctx, grn_ts_expr_score_node *node,
1564 grn_ts_record *io, size_t n_io)
1565 {
1566 /* Nothing to do. */
1567 return GRN_SUCCESS;
1568 }
1569
1570 /*-------------------------------------------------------------
1571 * grn_ts_expr_key_node.
1572 */
1573
1574 typedef struct {
1575 GRN_TS_EXPR_NODE_COMMON_MEMBERS
1576 grn_obj *table;
1577 grn_ts_buf buf;
1578 } grn_ts_expr_key_node;
1579
1580 /* grn_ts_expr_key_node_init() initializes a node. */
1581 static void
grn_ts_expr_key_node_init(grn_ctx * ctx,grn_ts_expr_key_node * node)1582 grn_ts_expr_key_node_init(grn_ctx *ctx, grn_ts_expr_key_node *node)
1583 {
1584 memset(node, 0, sizeof(*node));
1585 node->type = GRN_TS_EXPR_KEY_NODE;
1586 node->table = NULL;
1587 grn_ts_buf_init(ctx, &node->buf);
1588 }
1589
1590 /* grn_ts_expr_key_node_fin() finalizes a node. */
1591 static void
grn_ts_expr_key_node_fin(grn_ctx * ctx,grn_ts_expr_key_node * node)1592 grn_ts_expr_key_node_fin(grn_ctx *ctx, grn_ts_expr_key_node *node)
1593 {
1594 grn_ts_buf_fin(ctx, &node->buf);
1595 if (node->table) {
1596 grn_obj_unlink(ctx, node->table);
1597 }
1598 }
1599
1600 grn_rc
grn_ts_expr_key_node_open(grn_ctx * ctx,grn_obj * table,grn_ts_expr_node ** node)1601 grn_ts_expr_key_node_open(grn_ctx *ctx, grn_obj *table,
1602 grn_ts_expr_node **node)
1603 {
1604 grn_rc rc;
1605 grn_ts_expr_key_node *new_node;
1606 if (!grn_ts_table_has_key(ctx, table)) {
1607 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "the table has no _key");
1608 }
1609 new_node = GRN_MALLOCN(grn_ts_expr_key_node, 1);
1610 if (!new_node) {
1611 GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
1612 "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
1613 sizeof(grn_ts_expr_key_node));
1614 }
1615 grn_ts_expr_key_node_init(ctx, new_node);
1616 rc = grn_ts_obj_increment_ref_count(ctx, table);
1617 if (rc != GRN_SUCCESS) {
1618 grn_ts_expr_key_node_fin(ctx, new_node);
1619 GRN_FREE(new_node);
1620 return rc;
1621 }
1622 new_node->data_kind = grn_ts_data_type_to_kind(table->header.domain);
1623 new_node->data_type = table->header.domain;
1624 new_node->table = table;
1625 *node = (grn_ts_expr_node *)new_node;
1626 return GRN_SUCCESS;
1627 }
1628
1629 /* grn_ts_expr_key_node_close() destroys a node. */
1630 static void
grn_ts_expr_key_node_close(grn_ctx * ctx,grn_ts_expr_key_node * node)1631 grn_ts_expr_key_node_close(grn_ctx *ctx, grn_ts_expr_key_node *node)
1632 {
1633 grn_ts_expr_key_node_fin(ctx, node);
1634 GRN_FREE(node);
1635 }
1636
1637 #define GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE(table, KIND, kind)\
1638 case GRN_TS_ ## KIND: {\
1639 grn_ts_ ## kind *out_ptr = (grn_ts_ ## kind *)out;\
1640 for (i = 0; i < n_in; i++) {\
1641 rc = grn_ts_ ## table ## _get_ ## kind ## _key(ctx, table, in[i].id,\
1642 &out_ptr[i]);\
1643 if (rc != GRN_SUCCESS) {\
1644 out_ptr[i] = grn_ts_ ## kind ## _zero();\
1645 }\
1646 }\
1647 return GRN_SUCCESS;\
1648 }
1649 #define GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(table, TYPE, type)\
1650 case GRN_DB_ ## TYPE: {\
1651 grn_ts_int *out_ptr = (grn_ts_int *)out;\
1652 for (i = 0; i < n_in; i++) {\
1653 rc = grn_ts_ ## table ## _get_ ## type ## _key(ctx, table, in[i].id,\
1654 &out_ptr[i]);\
1655 if (rc != GRN_SUCCESS) {\
1656 out_ptr[i] = grn_ts_int_zero();\
1657 }\
1658 }\
1659 return GRN_SUCCESS;\
1660 }
1661 #define GRN_TS_EXPR_KEY_NODE_EVALUATE_TEXT_CASE(table)\
1662 case GRN_TS_TEXT: {\
1663 char *buf_ptr;\
1664 grn_ts_text *out_ptr = (grn_ts_text *)out;\
1665 node->buf.pos = 0;\
1666 for (i = 0; i < n_in; i++) {\
1667 grn_ts_text key;\
1668 rc = grn_ts_ ## table ## _get_text_key(ctx, table, in[i].id, &key);\
1669 if (rc != GRN_SUCCESS) {\
1670 key = grn_ts_text_zero();\
1671 }\
1672 rc = grn_ts_buf_write(ctx, &node->buf, key.ptr, key.size);\
1673 if (rc != GRN_SUCCESS) {\
1674 return rc;\
1675 }\
1676 out_ptr[i].size = key.size;\
1677 }\
1678 buf_ptr = (char *)node->buf.ptr;\
1679 for (i = 0; i < n_in; i++) {\
1680 out_ptr[i].ptr = buf_ptr;\
1681 buf_ptr += out_ptr[i].size;\
1682 }\
1683 return GRN_SUCCESS;\
1684 }
1685 #define GRN_TS_EXPR_KEY_NODE_EVALUATE_REF_CASE(table)\
1686 case GRN_TS_REF: {\
1687 grn_ts_ref *out_ptr = (grn_ts_ref *)out;\
1688 for (i = 0; i < n_in; i++) {\
1689 rc = grn_ts_ ## table ## _get_ref_key(ctx, table, in[i].id,\
1690 &out_ptr[i]);\
1691 if (rc != GRN_SUCCESS) {\
1692 out_ptr[i] = grn_ts_ref_zero();\
1693 }\
1694 out_ptr[i].score = in[i].score;\
1695 }\
1696 return GRN_SUCCESS;\
1697 }
1698 /* grn_ts_expr_key_node_evaluate() outputs keys. */
1699 static grn_rc
grn_ts_expr_key_node_evaluate(grn_ctx * ctx,grn_ts_expr_key_node * node,const grn_ts_record * in,size_t n_in,void * out)1700 grn_ts_expr_key_node_evaluate(grn_ctx *ctx, grn_ts_expr_key_node *node,
1701 const grn_ts_record *in, size_t n_in, void *out)
1702 {
1703 size_t i;
1704 grn_rc rc;
1705 switch (node->table->header.type) {
1706 case GRN_TABLE_HASH_KEY: {
1707 grn_hash *hash = (grn_hash *)node->table;
1708 switch (node->data_kind) {
1709 GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE(hash, BOOL, bool)
1710 case GRN_TS_INT: {
1711 switch (node->data_type) {
1712 GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(hash, INT8, int8)
1713 GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(hash, INT16, int16)
1714 GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(hash, INT32, int32)
1715 GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(hash, INT64, int64)
1716 GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(hash, UINT8, uint8)
1717 GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(hash, UINT16, uint16)
1718 GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(hash, UINT32, uint32)
1719 GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(hash, UINT64, uint64)
1720 }
1721 }
1722 GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE(hash, FLOAT, float)
1723 GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE(hash, TIME, time)
1724 GRN_TS_EXPR_KEY_NODE_EVALUATE_TEXT_CASE(hash)
1725 GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE(hash, GEO, geo)
1726 GRN_TS_EXPR_KEY_NODE_EVALUATE_REF_CASE(hash)
1727 default: {
1728 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
1729 node->data_kind);
1730 }
1731 }
1732 }
1733 case GRN_TABLE_PAT_KEY: {
1734 grn_pat *pat = (grn_pat *)node->table;
1735 switch (node->data_kind) {
1736 GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE(pat, BOOL, bool)
1737 case GRN_TS_INT: {
1738 switch (node->data_type) {
1739 GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(pat, INT8, int8)
1740 GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(pat, INT16, int16)
1741 GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(pat, INT32, int32)
1742 GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(pat, INT64, int64)
1743 GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(pat, UINT8, uint8)
1744 GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(pat, UINT16, uint16)
1745 GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(pat, UINT32, uint32)
1746 GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE(pat, UINT64, uint64)
1747 }
1748 }
1749 GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE(pat, FLOAT, float)
1750 GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE(pat, TIME, time)
1751 GRN_TS_EXPR_KEY_NODE_EVALUATE_TEXT_CASE(pat)
1752 GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE(pat, GEO, geo)
1753 GRN_TS_EXPR_KEY_NODE_EVALUATE_REF_CASE(pat)
1754 default: {
1755 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
1756 node->data_kind);
1757 }
1758 }
1759 }
1760 case GRN_TABLE_DAT_KEY: {
1761 grn_dat *dat = (grn_dat *)node->table;
1762 switch (node->data_kind) {
1763 GRN_TS_EXPR_KEY_NODE_EVALUATE_TEXT_CASE(dat)
1764 /* GRN_TABLE_DAT_KEY supports only Text. */
1765 default: {
1766 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
1767 node->data_kind);
1768 }
1769 }
1770 }
1771 /* GRN_TABLE_NO_KEY doesn't support _key. */
1772 default: {
1773 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid table type: %d",
1774 node->table->header.type);
1775 }
1776 }
1777 }
1778 #undef GRN_TS_EXPR_KEY_NODE_EVALUATE_REF_CASE
1779 #undef GRN_TS_EXPR_KEY_NODE_EVALUATE_TEXT_CASE
1780 #undef GRN_TS_EXPR_KEY_NODE_EVALUATE_INT_CASE
1781 #undef GRN_TS_EXPR_KEY_NODE_EVALUATE_CASE
1782
1783 /* grn_ts_expr_key_node_filter() filters records. */
1784 static grn_rc
grn_ts_expr_key_node_filter(grn_ctx * ctx,grn_ts_expr_key_node * node,grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)1785 grn_ts_expr_key_node_filter(grn_ctx *ctx, grn_ts_expr_key_node *node,
1786 grn_ts_record *in, size_t n_in,
1787 grn_ts_record *out, size_t *n_out)
1788 {
1789 size_t i, count;
1790 grn_ts_bool key;
1791 switch (node->table->header.type) {
1792 case GRN_TABLE_HASH_KEY: {
1793 grn_hash *hash = (grn_hash *)node->table;
1794 for (i = 0, count = 0; i < n_in; i++) {
1795 grn_rc rc = grn_ts_hash_get_bool_key(ctx, hash, in[i].id, &key);
1796 if (rc != GRN_SUCCESS) {
1797 key = grn_ts_bool_zero();
1798 }
1799 if (key) {
1800 out[count++] = in[i];
1801 }
1802 }
1803 *n_out = count;
1804 return GRN_SUCCESS;
1805 }
1806 case GRN_TABLE_PAT_KEY: {
1807 grn_pat *pat = (grn_pat *)node->table;
1808 for (i = 0, count = 0; i < n_in; i++) {
1809 grn_rc rc = grn_ts_pat_get_bool_key(ctx, pat, in[i].id, &key);
1810 if (rc != GRN_SUCCESS) {
1811 key = grn_ts_bool_zero();
1812 }
1813 if (key) {
1814 out[count++] = in[i];
1815 }
1816 }
1817 *n_out = count;
1818 return GRN_SUCCESS;
1819 }
1820 /* GRN_TABLE_DAT_KEY and GRN_TABLE_NO_KEY don't support a Bool key. */
1821 default: {
1822 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid table type: %d",
1823 node->table->header.type);
1824 }
1825 }
1826 }
1827
1828 /* grn_ts_expr_key_node_adjust() updates scores. */
1829 static grn_rc
grn_ts_expr_key_node_adjust(grn_ctx * ctx,grn_ts_expr_key_node * node,grn_ts_record * io,size_t n_io)1830 grn_ts_expr_key_node_adjust(grn_ctx *ctx, grn_ts_expr_key_node *node,
1831 grn_ts_record *io, size_t n_io)
1832 {
1833 size_t i;
1834 grn_ts_float key;
1835 switch (node->table->header.type) {
1836 case GRN_TABLE_HASH_KEY: {
1837 grn_hash *hash = (grn_hash *)node->table;
1838 for (i = 0; i < n_io; i++) {
1839 grn_rc rc = grn_ts_hash_get_float_key(ctx, hash, io[i].id, &key);
1840 if (rc != GRN_SUCCESS) {
1841 key = grn_ts_float_zero();
1842 }
1843 io[i].score = (grn_ts_score)key;
1844 }
1845 return GRN_SUCCESS;
1846 }
1847 case GRN_TABLE_PAT_KEY: {
1848 grn_pat *pat = (grn_pat *)node->table;
1849 for (i = 0; i < n_io; i++) {
1850 grn_rc rc = grn_ts_pat_get_float_key(ctx, pat, io[i].id, &key);
1851 if (rc != GRN_SUCCESS) {
1852 key = grn_ts_float_zero();
1853 }
1854 io[i].score = (grn_ts_score)key;
1855 }
1856 return GRN_SUCCESS;
1857 }
1858 /* GRN_TABLE_DAT_KEY and GRN_TABLE_NO_KEY don't support a Float key. */
1859 default: {
1860 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid table type: %d",
1861 node->table->header.type);
1862 }
1863 }
1864 }
1865
1866 /*-------------------------------------------------------------
1867 * grn_ts_expr_value_node.
1868 */
1869
1870 typedef struct {
1871 GRN_TS_EXPR_NODE_COMMON_MEMBERS
1872 grn_obj *table;
1873 } grn_ts_expr_value_node;
1874
1875 /* grn_ts_expr_value_node_init() initializes a node. */
1876 static void
grn_ts_expr_value_node_init(grn_ctx * ctx,grn_ts_expr_value_node * node)1877 grn_ts_expr_value_node_init(grn_ctx *ctx, grn_ts_expr_value_node *node)
1878 {
1879 memset(node, 0, sizeof(*node));
1880 node->type = GRN_TS_EXPR_VALUE_NODE;
1881 node->table = NULL;
1882 }
1883
1884 /* grn_ts_expr_value_node_fin() finalizes a node. */
1885 static void
grn_ts_expr_value_node_fin(grn_ctx * ctx,grn_ts_expr_value_node * node)1886 grn_ts_expr_value_node_fin(grn_ctx *ctx, grn_ts_expr_value_node *node)
1887 {
1888 if (node->table) {
1889 grn_obj_unlink(ctx, node->table);
1890 }
1891 }
1892
1893 grn_rc
grn_ts_expr_value_node_open(grn_ctx * ctx,grn_obj * table,grn_ts_expr_node ** node)1894 grn_ts_expr_value_node_open(grn_ctx *ctx, grn_obj *table,
1895 grn_ts_expr_node **node)
1896 {
1897 grn_rc rc;
1898 grn_ts_expr_value_node *new_node;
1899 if (!grn_ts_table_has_value(ctx, table)) {
1900 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "table has no _value");
1901 }
1902 new_node = GRN_MALLOCN(grn_ts_expr_value_node, 1);
1903 if (!new_node) {
1904 GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
1905 "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
1906 sizeof(grn_ts_expr_value_node));
1907 }
1908 grn_ts_expr_value_node_init(ctx, new_node);
1909 rc = grn_ts_obj_increment_ref_count(ctx, table);
1910 if (rc != GRN_SUCCESS) {
1911 GRN_FREE(new_node);
1912 return rc;
1913 }
1914 new_node->data_kind = grn_ts_data_type_to_kind(DB_OBJ(table)->range);
1915 new_node->data_type = DB_OBJ(table)->range;
1916 new_node->table = table;
1917 *node = (grn_ts_expr_node *)new_node;
1918 return GRN_SUCCESS;
1919 }
1920
1921 /* grn_ts_expr_value_node_close() destroys a node. */
1922 static void
grn_ts_expr_value_node_close(grn_ctx * ctx,grn_ts_expr_value_node * node)1923 grn_ts_expr_value_node_close(grn_ctx *ctx, grn_ts_expr_value_node *node)
1924 {
1925 grn_ts_expr_value_node_fin(ctx, node);
1926 GRN_FREE(node);
1927 }
1928
1929 #define GRN_TS_EXPR_VALUE_NODE_EVALUATE_CASE(KIND, kind)\
1930 case GRN_TS_ ## KIND: {\
1931 size_t i;\
1932 grn_ts_ ## kind *out_ptr = (grn_ts_ ## kind *)out;\
1933 for (i = 0; i < n_in; i++) {\
1934 const void *ptr = grn_ts_table_get_value(ctx, node->table, in[i].id);\
1935 if (ptr) {\
1936 out_ptr[i] = *(const grn_ts_ ## kind *)ptr;\
1937 } else {\
1938 out_ptr[i] = grn_ts_ ## kind ## _zero();\
1939 }\
1940 }\
1941 return GRN_SUCCESS;\
1942 }
1943 #define GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE(TYPE, type)\
1944 case GRN_DB_ ## TYPE: {\
1945 size_t i;\
1946 grn_ts_int *out_ptr = (grn_ts_int *)out;\
1947 for (i = 0; i < n_in; i++) {\
1948 const void *ptr = grn_ts_table_get_value(ctx, node->table, in[i].id);\
1949 if (ptr) {\
1950 out_ptr[i] = (grn_ts_int)*(const type ## _t *)ptr;\
1951 } else {\
1952 out_ptr[i] = grn_ts_int_zero();\
1953 }\
1954 }\
1955 return GRN_SUCCESS;\
1956 }
1957 /* grn_ts_expr_value_node_evaluate() outputs values. */
1958 static grn_rc
grn_ts_expr_value_node_evaluate(grn_ctx * ctx,grn_ts_expr_value_node * node,const grn_ts_record * in,size_t n_in,void * out)1959 grn_ts_expr_value_node_evaluate(grn_ctx *ctx, grn_ts_expr_value_node *node,
1960 const grn_ts_record *in, size_t n_in,
1961 void *out)
1962 {
1963 switch (node->data_kind) {
1964 GRN_TS_EXPR_VALUE_NODE_EVALUATE_CASE(BOOL, bool)
1965 case GRN_TS_INT: {
1966 switch (node->data_type) {
1967 GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE(INT8, int8)
1968 GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE(INT16, int16)
1969 GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE(INT32, int32)
1970 GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE(INT64, int64)
1971 GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE(UINT8, uint8)
1972 GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE(UINT16, uint16)
1973 GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE(UINT32, uint32)
1974 GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE(UINT64, uint64)
1975 default: {
1976 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data type: %d",
1977 node->data_type);
1978 }
1979 }
1980 }
1981 GRN_TS_EXPR_VALUE_NODE_EVALUATE_CASE(FLOAT, float)
1982 GRN_TS_EXPR_VALUE_NODE_EVALUATE_CASE(TIME, time)
1983 GRN_TS_EXPR_VALUE_NODE_EVALUATE_CASE(GEO, geo)
1984 case GRN_TS_REF: {
1985 size_t i;
1986 grn_ts_ref *out_ptr = (grn_ts_ref *)out;
1987 for (i = 0; i < n_in; i++) {
1988 const void *ptr = grn_ts_table_get_value(ctx, node->table, in[i].id);
1989 if (ptr) {
1990 out_ptr[i].id = *(const grn_ts_id *)ptr;
1991 out_ptr[i].score = in[i].score;
1992 } else {
1993 out_ptr[i] = grn_ts_ref_zero();
1994 }
1995 }
1996 return GRN_SUCCESS;
1997 }
1998 default: {
1999 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
2000 node->data_kind);
2001 }
2002 }
2003 }
2004 #undef GRN_TS_EXPR_VALUE_NODE_EVALUATE_INT_CASE
2005 #undef GRN_TS_EXPR_VALUE_NODE_EVALUATE_CASE
2006
2007 /* grn_ts_expr_value_node_filter() filters records. */
2008 static grn_rc
grn_ts_expr_value_node_filter(grn_ctx * ctx,grn_ts_expr_value_node * node,grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)2009 grn_ts_expr_value_node_filter(grn_ctx *ctx, grn_ts_expr_value_node *node,
2010 grn_ts_record *in, size_t n_in,
2011 grn_ts_record *out, size_t *n_out)
2012 {
2013 size_t i, count = 0;
2014 for (i = 0; i < n_in; i++) {
2015 const void *ptr = grn_ts_table_get_value(ctx, node->table, in[i].id);
2016 if (ptr && *(const grn_ts_bool *)ptr) {
2017 out[count++] = in[i];
2018 }
2019 }
2020 *n_out = count;
2021 return GRN_SUCCESS;
2022 }
2023
2024 /* grn_ts_expr_value_node_adjust() updates scores. */
2025 static grn_rc
grn_ts_expr_value_node_adjust(grn_ctx * ctx,grn_ts_expr_value_node * node,grn_ts_record * io,size_t n_io)2026 grn_ts_expr_value_node_adjust(grn_ctx *ctx, grn_ts_expr_value_node *node,
2027 grn_ts_record *io, size_t n_io)
2028 {
2029 size_t i;
2030 for (i = 0; i < n_io; i++) {
2031 const void *ptr = grn_ts_table_get_value(ctx, node->table, io[i].id);
2032 if (ptr) {
2033 io[i].score = (grn_ts_score)*(const grn_ts_float *)ptr;
2034 }
2035 }
2036 return GRN_SUCCESS;
2037 }
2038
2039 /*-------------------------------------------------------------
2040 * grn_ts_expr_const_node.
2041 */
2042
2043 typedef struct {
2044 GRN_TS_EXPR_NODE_COMMON_MEMBERS
2045 grn_ts_any content;
2046 grn_ts_buf text_buf;
2047 grn_ts_buf vector_buf;
2048 } grn_ts_expr_const_node;
2049
2050 /* grn_ts_expr_const_node_init() initializes a node. */
2051 static void
grn_ts_expr_const_node_init(grn_ctx * ctx,grn_ts_expr_const_node * node)2052 grn_ts_expr_const_node_init(grn_ctx *ctx, grn_ts_expr_const_node *node)
2053 {
2054 memset(node, 0, sizeof(*node));
2055 node->type = GRN_TS_EXPR_CONST_NODE;
2056 grn_ts_buf_init(ctx, &node->text_buf);
2057 grn_ts_buf_init(ctx, &node->vector_buf);
2058 }
2059
2060 /* grn_ts_expr_const_node_fin() finalizes a node. */
2061 static void
grn_ts_expr_const_node_fin(grn_ctx * ctx,grn_ts_expr_const_node * node)2062 grn_ts_expr_const_node_fin(grn_ctx *ctx, grn_ts_expr_const_node *node)
2063 {
2064 grn_ts_buf_fin(ctx, &node->vector_buf);
2065 grn_ts_buf_fin(ctx, &node->text_buf);
2066 }
2067
2068 #define GRN_TS_EXPR_CONST_NODE_SET_SCALAR_CASE(KIND, kind)\
2069 case GRN_TS_ ## KIND: {\
2070 node->content.as_ ## kind = value.as_ ## kind;\
2071 return GRN_SUCCESS;\
2072 }
2073 /* grn_ts_expr_const_node_set_scalar() sets a scalar value. */
2074 static grn_rc
grn_ts_expr_const_node_set_scalar(grn_ctx * ctx,grn_ts_expr_const_node * node,grn_ts_any value)2075 grn_ts_expr_const_node_set_scalar(grn_ctx *ctx, grn_ts_expr_const_node *node,
2076 grn_ts_any value)
2077 {
2078 switch (node->data_kind) {
2079 GRN_TS_EXPR_CONST_NODE_SET_SCALAR_CASE(BOOL, bool)
2080 GRN_TS_EXPR_CONST_NODE_SET_SCALAR_CASE(INT, int)
2081 GRN_TS_EXPR_CONST_NODE_SET_SCALAR_CASE(FLOAT, float)
2082 GRN_TS_EXPR_CONST_NODE_SET_SCALAR_CASE(TIME, time)
2083 case GRN_TS_TEXT: {
2084 grn_rc rc = grn_ts_buf_write(ctx, &node->text_buf,
2085 value.as_text.ptr, value.as_text.size);
2086 if (rc != GRN_SUCCESS) {
2087 return rc;
2088 }
2089 node->content.as_text.ptr = (const char *)node->text_buf.ptr;
2090 node->content.as_text.size = value.as_text.size;
2091 return GRN_SUCCESS;
2092 }
2093 GRN_TS_EXPR_CONST_NODE_SET_SCALAR_CASE(GEO, geo)
2094 default: {
2095 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
2096 node->data_kind);
2097 }
2098 }
2099 }
2100 #undef GRN_TS_EXPR_CONST_NODE_SET_SCALAR_CASE
2101
2102 #define GRN_TS_EXPR_CONST_NODE_SET_VECTOR_CASE(KIND, kind)\
2103 case GRN_TS_ ## KIND ## _VECTOR: {\
2104 grn_rc rc;\
2105 size_t n_bytes;\
2106 const grn_ts_ ## kind *buf_ptr;\
2107 grn_ts_ ## kind ## _vector vector;\
2108 vector = value.as_ ## kind ## _vector;\
2109 n_bytes = sizeof(grn_ts_ ## kind) * vector.size;\
2110 rc = grn_ts_buf_write(ctx, &node->vector_buf, vector.ptr, n_bytes);\
2111 if (rc != GRN_SUCCESS) {\
2112 return rc;\
2113 }\
2114 buf_ptr = (const grn_ts_ ## kind *)node->vector_buf.ptr;\
2115 node->content.as_ ## kind ## _vector.ptr = buf_ptr;\
2116 node->content.as_ ## kind ## _vector.size = vector.size;\
2117 return GRN_SUCCESS;\
2118 }
2119 /* grn_ts_expr_const_node_set_vector() sets a vector value. */
2120 static grn_rc
grn_ts_expr_const_node_set_vector(grn_ctx * ctx,grn_ts_expr_const_node * node,grn_ts_any value)2121 grn_ts_expr_const_node_set_vector(grn_ctx *ctx, grn_ts_expr_const_node *node,
2122 grn_ts_any value)
2123 {
2124 switch (node->data_kind) {
2125 GRN_TS_EXPR_CONST_NODE_SET_VECTOR_CASE(BOOL, bool)
2126 GRN_TS_EXPR_CONST_NODE_SET_VECTOR_CASE(INT, int)
2127 GRN_TS_EXPR_CONST_NODE_SET_VECTOR_CASE(FLOAT, float)
2128 GRN_TS_EXPR_CONST_NODE_SET_VECTOR_CASE(TIME, time)
2129 case GRN_TS_TEXT_VECTOR: {
2130 grn_rc rc;
2131 size_t i, n_bytes, offset, total_size;
2132 grn_ts_text_vector vector = value.as_text_vector;
2133 grn_ts_text *vector_buf;
2134 char *text_buf;
2135 n_bytes = sizeof(grn_ts_text) * vector.size;
2136 rc = grn_ts_buf_resize(ctx, &node->vector_buf, n_bytes);
2137 if (rc != GRN_SUCCESS) {
2138 return rc;
2139 }
2140 vector_buf = (grn_ts_text *)node->vector_buf.ptr;
2141 total_size = 0;
2142 for (i = 0; i < vector.size; i++) {
2143 total_size += vector.ptr[i].size;
2144 }
2145 rc = grn_ts_buf_resize(ctx, &node->text_buf, total_size);
2146 if (rc != GRN_SUCCESS) {
2147 return rc;
2148 }
2149 text_buf = (char *)node->text_buf.ptr;
2150 offset = 0;
2151 for (i = 0; i < vector.size; i++) {
2152 grn_memcpy(text_buf + offset, vector.ptr[i].ptr, vector.ptr[i].size);
2153 vector_buf[i].ptr = text_buf + offset;
2154 vector_buf[i].size = vector.ptr[i].size;
2155 offset += vector.ptr[i].size;
2156 }
2157 node->content.as_text_vector.ptr = vector_buf;
2158 node->content.as_text_vector.size = vector.size;
2159 return GRN_SUCCESS;
2160 }
2161 GRN_TS_EXPR_CONST_NODE_SET_VECTOR_CASE(GEO, geo)
2162 default: {
2163 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
2164 node->data_kind);
2165 }
2166 }
2167 }
2168 #undef GRN_TS_EXPR_CONST_NODE_SET_VECTOR_CASE
2169
2170 #define GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(KIND, kind)\
2171 case GRN_TS_ ## KIND: {\
2172 if (!grn_ts_ ## kind ## _is_valid(value.as_ ## kind)) {\
2173 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");\
2174 }\
2175 return GRN_SUCCESS;\
2176 }
2177 static grn_rc
grn_ts_expr_const_node_check_value(grn_ctx * ctx,grn_ts_data_kind kind,grn_ts_any value)2178 grn_ts_expr_const_node_check_value(grn_ctx *ctx, grn_ts_data_kind kind,
2179 grn_ts_any value)
2180 {
2181 switch (kind) {
2182 GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(BOOL, bool)
2183 GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(INT, int)
2184 GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(FLOAT, float)
2185 GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(TIME, time)
2186 GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(TEXT, text)
2187 GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(GEO, geo)
2188 GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(BOOL_VECTOR, bool_vector)
2189 GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(INT_VECTOR, int_vector)
2190 GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(FLOAT_VECTOR, float_vector)
2191 GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(TIME_VECTOR, time_vector)
2192 GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(TEXT_VECTOR, text_vector)
2193 GRN_TS_EXPR_CONST_NODE_CHECK_VALUE(GEO_VECTOR, geo_vector)
2194 default: {
2195 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid argument");
2196 }
2197 }
2198 }
2199 #undef GRN_TS_EXPR_CONST_NODE_CHECK_VALUE
2200
2201 grn_rc
grn_ts_expr_const_node_open(grn_ctx * ctx,grn_ts_data_kind data_kind,grn_ts_data_type data_type,grn_ts_any value,grn_ts_expr_node ** node)2202 grn_ts_expr_const_node_open(grn_ctx *ctx, grn_ts_data_kind data_kind,
2203 grn_ts_data_type data_type,
2204 grn_ts_any value, grn_ts_expr_node **node)
2205 {
2206 grn_rc rc = grn_ts_expr_const_node_check_value(ctx, data_kind, value);
2207 grn_ts_expr_const_node *new_node;
2208 if (rc != GRN_SUCCESS) {
2209 return rc;
2210 }
2211 new_node = GRN_MALLOCN(grn_ts_expr_const_node, 1);
2212 if (!new_node) {
2213 GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
2214 "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
2215 sizeof(grn_ts_expr_const_node));
2216 }
2217 grn_ts_expr_const_node_init(ctx, new_node);
2218 new_node->data_kind = data_kind;
2219 if (data_type != GRN_DB_VOID) {
2220 new_node->data_type = data_type;
2221 } else {
2222 new_node->data_type = grn_ts_data_kind_to_type(data_kind);
2223 }
2224 if (data_kind & GRN_TS_VECTOR_FLAG) {
2225 rc = grn_ts_expr_const_node_set_vector(ctx, new_node, value);
2226 } else {
2227 rc = grn_ts_expr_const_node_set_scalar(ctx, new_node, value);
2228 }
2229 if (rc != GRN_SUCCESS) {
2230 grn_ts_expr_const_node_fin(ctx, new_node);
2231 GRN_FREE(new_node);
2232 return rc;
2233 }
2234 *node = (grn_ts_expr_node *)new_node;
2235 return GRN_SUCCESS;
2236 }
2237
2238 /* grn_ts_expr_const_node_close() destroys a node. */
2239 static void
grn_ts_expr_const_node_close(grn_ctx * ctx,grn_ts_expr_const_node * node)2240 grn_ts_expr_const_node_close(grn_ctx *ctx, grn_ts_expr_const_node *node)
2241 {
2242 grn_ts_expr_const_node_fin(ctx, node);
2243 GRN_FREE(node);
2244 }
2245
2246 #define GRN_TS_EXPR_CONST_NODE_EVALUATE_CASE(KIND, kind)\
2247 case GRN_TS_ ## KIND: {\
2248 size_t i;\
2249 grn_ts_ ## kind *out_ptr = (grn_ts_ ## kind *)out;\
2250 for (i = 0; i < n_in; i++) {\
2251 out_ptr[i] = node->content.as_ ## kind;\
2252 }\
2253 return GRN_SUCCESS;\
2254 }
2255 #define GRN_TS_EXPR_CONST_NODE_EVALUATE_VECTOR_CASE(KIND, kind)\
2256 GRN_TS_EXPR_CONST_NODE_EVALUATE_CASE(KIND ## _VECTOR, kind ## _vector)
2257 /* grn_ts_expr_const_node_evaluate() outputs the stored const. */
2258 static grn_rc
grn_ts_expr_const_node_evaluate(grn_ctx * ctx,grn_ts_expr_const_node * node,const grn_ts_record * in,size_t n_in,void * out)2259 grn_ts_expr_const_node_evaluate(grn_ctx *ctx, grn_ts_expr_const_node *node,
2260 const grn_ts_record *in, size_t n_in,
2261 void *out)
2262 {
2263 switch (node->data_kind) {
2264 GRN_TS_EXPR_CONST_NODE_EVALUATE_CASE(BOOL, bool)
2265 GRN_TS_EXPR_CONST_NODE_EVALUATE_CASE(INT, int)
2266 GRN_TS_EXPR_CONST_NODE_EVALUATE_CASE(FLOAT, float)
2267 GRN_TS_EXPR_CONST_NODE_EVALUATE_CASE(TIME, time)
2268 GRN_TS_EXPR_CONST_NODE_EVALUATE_CASE(TEXT, text)
2269 GRN_TS_EXPR_CONST_NODE_EVALUATE_CASE(GEO, geo)
2270 GRN_TS_EXPR_CONST_NODE_EVALUATE_VECTOR_CASE(BOOL, bool)
2271 GRN_TS_EXPR_CONST_NODE_EVALUATE_VECTOR_CASE(INT, int)
2272 GRN_TS_EXPR_CONST_NODE_EVALUATE_VECTOR_CASE(FLOAT, float)
2273 GRN_TS_EXPR_CONST_NODE_EVALUATE_VECTOR_CASE(TIME, time)
2274 GRN_TS_EXPR_CONST_NODE_EVALUATE_VECTOR_CASE(TEXT, text)
2275 GRN_TS_EXPR_CONST_NODE_EVALUATE_VECTOR_CASE(GEO, geo)
2276 default: {
2277 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
2278 node->data_kind);
2279 }
2280 }
2281 }
2282 #undef GRN_TS_EXPR_CONST_NODE_EVALUATE_VECTOR_CASE
2283 #undef GRN_TS_EXPR_CONST_NODE_EVALUATE_CASE
2284
2285 /* grn_ts_expr_const_node_filter() filters records. */
2286 static grn_rc
grn_ts_expr_const_node_filter(grn_ctx * ctx,grn_ts_expr_const_node * node,grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)2287 grn_ts_expr_const_node_filter(grn_ctx *ctx, grn_ts_expr_const_node *node,
2288 grn_ts_record *in, size_t n_in,
2289 grn_ts_record *out, size_t *n_out)
2290 {
2291 if (node->content.as_bool) {
2292 /* All the records pass through the filter. */
2293 if (in != out) {
2294 size_t i;
2295 for (i = 0; i < n_in; i++) {
2296 out[i] = in[i];
2297 }
2298 }
2299 *n_out = n_in;
2300 } else {
2301 /* All the records are discarded. */
2302 *n_out = 0;
2303 }
2304 return GRN_SUCCESS;
2305 }
2306
2307 /* grn_ts_expr_const_node_adjust() updates scores. */
2308 static grn_rc
grn_ts_expr_const_node_adjust(grn_ctx * ctx,grn_ts_expr_const_node * node,grn_ts_record * io,size_t n_io)2309 grn_ts_expr_const_node_adjust(grn_ctx *ctx, grn_ts_expr_const_node *node,
2310 grn_ts_record *io, size_t n_io)
2311 {
2312 size_t i;
2313 grn_ts_score score = (grn_ts_score)node->content.as_float;
2314 for (i = 0; i < n_io; i++) {
2315 io[i].score = score;
2316 }
2317 return GRN_SUCCESS;
2318 }
2319
2320 /*-------------------------------------------------------------
2321 * grn_ts_expr_column_node.
2322 */
2323
2324 typedef struct {
2325 GRN_TS_EXPR_NODE_COMMON_MEMBERS
2326 grn_obj *column;
2327 grn_ts_buf buf;
2328 grn_ts_buf body_buf;
2329 grn_ja_reader *reader;
2330 } grn_ts_expr_column_node;
2331
2332 /* grn_ts_expr_column_node_init() initializes a node. */
2333 static void
grn_ts_expr_column_node_init(grn_ctx * ctx,grn_ts_expr_column_node * node)2334 grn_ts_expr_column_node_init(grn_ctx *ctx, grn_ts_expr_column_node *node)
2335 {
2336 memset(node, 0, sizeof(*node));
2337 node->type = GRN_TS_EXPR_COLUMN_NODE;
2338 node->column = NULL;
2339 grn_ts_buf_init(ctx, &node->buf);
2340 grn_ts_buf_init(ctx, &node->body_buf);
2341 node->reader = NULL;
2342 }
2343
2344 /* grn_ts_expr_column_node_fin() finalizes a node. */
2345 static void
grn_ts_expr_column_node_fin(grn_ctx * ctx,grn_ts_expr_column_node * node)2346 grn_ts_expr_column_node_fin(grn_ctx *ctx, grn_ts_expr_column_node *node)
2347 {
2348 if (node->reader) {
2349 grn_ja_reader_close(ctx, node->reader);
2350 }
2351 grn_ts_buf_fin(ctx, &node->body_buf);
2352 grn_ts_buf_fin(ctx, &node->buf);
2353 if (node->column) {
2354 grn_obj_unlink(ctx, node->column);
2355 }
2356 }
2357
2358 #define GRN_TS_EXPR_COLUMN_NODE_OPEN_CASE(TYPE)\
2359 case GRN_DB_ ## TYPE: {\
2360 GRN_ ## TYPE ## _INIT(&new_node->buf, GRN_OBJ_VECTOR);\
2361 break;\
2362 }
2363 grn_rc
grn_ts_expr_column_node_open(grn_ctx * ctx,grn_obj * column,grn_ts_expr_node ** node)2364 grn_ts_expr_column_node_open(grn_ctx *ctx, grn_obj *column,
2365 grn_ts_expr_node **node)
2366 {
2367 grn_rc rc;
2368 grn_ts_expr_column_node *new_node = GRN_MALLOCN(grn_ts_expr_column_node, 1);
2369 if (!new_node) {
2370 GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
2371 "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
2372 sizeof(grn_ts_expr_column_node));
2373 }
2374 grn_ts_expr_column_node_init(ctx, new_node);
2375 new_node->data_kind = grn_ts_data_type_to_kind(DB_OBJ(column)->range);
2376 if (column->header.type == GRN_COLUMN_VAR_SIZE) {
2377 grn_obj_flags type = column->header.flags & GRN_OBJ_COLUMN_TYPE_MASK;
2378 if (type == GRN_OBJ_COLUMN_VECTOR) {
2379 new_node->data_kind |= GRN_TS_VECTOR_FLAG;
2380 }
2381 }
2382 new_node->data_type = DB_OBJ(column)->range;
2383 rc = grn_ts_obj_increment_ref_count(ctx, column);
2384 if (rc != GRN_SUCCESS) {
2385 grn_ts_expr_column_node_fin(ctx, new_node);
2386 GRN_FREE(new_node);
2387 return rc;
2388 }
2389 new_node->column = column;
2390 *node = (grn_ts_expr_node *)new_node;
2391 return GRN_SUCCESS;
2392 }
2393 #undef GRN_TS_EXPR_COLUMN_NODE_OPEN_CASE
2394
2395 /* grn_ts_expr_column_node_close() destroys a node. */
2396 static void
grn_ts_expr_column_node_close(grn_ctx * ctx,grn_ts_expr_column_node * node)2397 grn_ts_expr_column_node_close(grn_ctx *ctx, grn_ts_expr_column_node *node)
2398 {
2399 grn_ts_expr_column_node_fin(ctx, node);
2400 GRN_FREE(node);
2401 }
2402
2403 #define GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_CASE(KIND, kind)\
2404 case GRN_TS_ ## KIND: {\
2405 size_t i;\
2406 grn_ts_ ## kind *out_ptr = (grn_ts_ ## kind *)out;\
2407 grn_ra *ra = (grn_ra *)node->column;\
2408 grn_ra_cache cache;\
2409 GRN_RA_CACHE_INIT(ra, &cache);\
2410 for (i = 0; i < n_in; i++) {\
2411 grn_ts_ ## kind *ptr = NULL;\
2412 if (in[i].id) {\
2413 ptr = (grn_ts_ ## kind *)grn_ra_ref_cache(ctx, ra, in[i].id, &cache);\
2414 }\
2415 out_ptr[i] = ptr ? *ptr : grn_ts_ ## kind ## _zero();\
2416 }\
2417 GRN_RA_CACHE_FIN(ra, &cache);\
2418 return GRN_SUCCESS;\
2419 }
2420 #define GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE(TYPE, type)\
2421 case GRN_DB_ ## TYPE: {\
2422 size_t i;\
2423 grn_ts_int *out_ptr = (grn_ts_int *)out;\
2424 grn_ra *ra = (grn_ra *)node->column;\
2425 grn_ra_cache cache;\
2426 GRN_RA_CACHE_INIT(ra, &cache);\
2427 for (i = 0; i < n_in; i++) {\
2428 type ## _t *ptr = NULL;\
2429 if (in[i].id) {\
2430 ptr = (type ## _t *)grn_ra_ref_cache(ctx, ra, in[i].id, &cache);\
2431 }\
2432 out_ptr[i] = ptr ? (grn_ts_int)*ptr : grn_ts_int_zero();\
2433 }\
2434 GRN_RA_CACHE_FIN(ra, &cache);\
2435 return GRN_SUCCESS;\
2436 }
2437 /* grn_ts_expr_column_node_evaluate_scalar() outputs scalar column values. */
2438 static grn_rc
grn_ts_expr_column_node_evaluate_scalar(grn_ctx * ctx,grn_ts_expr_column_node * node,const grn_ts_record * in,size_t n_in,void * out)2439 grn_ts_expr_column_node_evaluate_scalar(grn_ctx *ctx,
2440 grn_ts_expr_column_node *node,
2441 const grn_ts_record *in, size_t n_in,
2442 void *out)
2443 {
2444 switch (node->data_kind) {
2445 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_CASE(BOOL, bool)
2446 case GRN_TS_INT: {
2447 switch (node->data_type) {
2448 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE(INT8, int8)
2449 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE(INT16, int16)
2450 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE(INT32, int32)
2451 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE(INT64, int64)
2452 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE(UINT8, uint8)
2453 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE(UINT16, uint16)
2454 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE(UINT32, uint32)
2455 /* The behavior is undefined if a value is greater than 2^63 - 1. */
2456 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE(UINT64, uint64)
2457 default: {
2458 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data type: %d",
2459 node->data_type);
2460 }
2461 }
2462 }
2463 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_CASE(FLOAT, float)
2464 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_CASE(TIME, time)
2465 case GRN_TS_TEXT: {
2466 size_t i;
2467 char *buf_ptr;
2468 grn_rc rc;
2469 grn_ts_text *out_ptr = (grn_ts_text *)out;
2470 if (!node->reader) {
2471 rc = grn_ja_reader_open(ctx, (grn_ja *)node->column, &node->reader);
2472 if (rc != GRN_SUCCESS) {
2473 GRN_TS_ERR_RETURN(rc, "grn_ja_reader_open failed");
2474 }
2475 } else {
2476 grn_ja_reader_unref(ctx, node->reader);
2477 }
2478 node->buf.pos = 0;
2479 for (i = 0; i < n_in; i++) {
2480 rc = grn_ja_reader_seek(ctx, node->reader, in[i].id);
2481 if (rc == GRN_SUCCESS) {
2482 if (node->reader->ref_avail) {
2483 void *addr;
2484 rc = grn_ja_reader_ref(ctx, node->reader, &addr);
2485 if (rc == GRN_SUCCESS) {
2486 out_ptr[i].ptr = (char *)addr;
2487 }
2488 } else {
2489 rc = grn_ts_buf_reserve(ctx, &node->buf,
2490 node->buf.pos + node->reader->value_size);
2491 if (rc == GRN_SUCCESS) {
2492 rc = grn_ja_reader_read(ctx, node->reader,
2493 (char *)node->buf.ptr + node->buf.pos);
2494 if (rc == GRN_SUCCESS) {
2495 out_ptr[i].ptr = NULL;
2496 node->buf.pos += node->reader->value_size;
2497 }
2498 }
2499 }
2500 }
2501 if (rc == GRN_SUCCESS) {
2502 out_ptr[i].size = node->reader->value_size;
2503 } else {
2504 out_ptr[i].ptr = NULL;
2505 out_ptr[i].size = 0;
2506 }
2507 }
2508 buf_ptr = (char *)node->buf.ptr;
2509 for (i = 0; i < n_in; i++) {
2510 if (!out_ptr[i].ptr) {
2511 out_ptr[i].ptr = buf_ptr;
2512 buf_ptr += out_ptr[i].size;
2513 }
2514 }
2515 return GRN_SUCCESS;
2516 }
2517 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_CASE(GEO, geo)
2518 case GRN_TS_REF: {
2519 size_t i;
2520 grn_ts_ref *out_ptr = (grn_ts_ref *)out;
2521 grn_ra *ra = (grn_ra *)node->column;
2522 grn_ra_cache cache;
2523 GRN_RA_CACHE_INIT(ra, &cache);
2524 for (i = 0; i < n_in; i++) {
2525 grn_ts_id *ptr = NULL;
2526 if (in[i].id) {
2527 ptr = (grn_ts_id *)grn_ra_ref_cache(ctx, ra, in[i].id, &cache);
2528 }
2529 out_ptr[i].id = ptr ? *ptr : GRN_ID_NIL;
2530 out_ptr[i].score = in[i].score;
2531 }
2532 GRN_RA_CACHE_FIN(ra, &cache);
2533 return GRN_SUCCESS;
2534 }
2535 default: {
2536 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
2537 node->data_kind);
2538 }
2539 }
2540 }
2541 #undef GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_INT_CASE
2542 #undef GRN_TS_EXPR_COLUMN_NODE_EVALUATE_SCALAR_CASE
2543
2544 /*
2545 * grn_ts_expr_column_node_evaluate_text_vector() outputs text vector column
2546 * values.
2547 */
2548 static grn_rc
grn_ts_expr_column_node_evaluate_text_vector(grn_ctx * ctx,grn_ts_expr_column_node * node,const grn_ts_record * in,size_t n_in,void * out)2549 grn_ts_expr_column_node_evaluate_text_vector(grn_ctx *ctx,
2550 grn_ts_expr_column_node *node,
2551 const grn_ts_record *in,
2552 size_t n_in, void *out)
2553 {
2554 grn_rc rc;
2555 char *buf_ptr;
2556 size_t i, j, n_bytes, n_values, total_n_bytes = 0, total_n_values = 0;
2557 grn_ts_text *text_ptr;
2558 grn_ts_text_vector *out_ptr = (grn_ts_text_vector *)out;
2559 /* Read encoded values into node->body_buf and get the size of each value. */
2560 node->body_buf.pos = 0;
2561 for (i = 0; i < n_in; i++) {
2562 char *ptr;
2563 rc = grn_ts_ja_get_value(ctx, node->column, in[i].id,
2564 &node->body_buf, &n_bytes);
2565 if (rc == GRN_SUCCESS) {
2566 ptr = (char *)node->body_buf.ptr + total_n_bytes;
2567 GRN_B_DEC(n_values, ptr);
2568 } else {
2569 n_bytes = 0;
2570 n_values = 0;
2571 }
2572 grn_memcpy(&out_ptr[i].ptr, &n_bytes, sizeof(n_bytes));
2573 out_ptr[i].size = n_values;
2574 total_n_bytes += n_bytes;
2575 total_n_values += n_values;
2576 }
2577 /* Resize node->buf. */
2578 n_bytes = sizeof(grn_ts_text) * total_n_values;
2579 rc = grn_ts_buf_reserve(ctx, &node->buf, n_bytes);
2580 if (rc != GRN_SUCCESS) {
2581 return rc;
2582 }
2583 /* Decode values and compose the result. */
2584 buf_ptr = (char *)node->body_buf.ptr;
2585 text_ptr = (grn_ts_text *)node->buf.ptr;
2586 for (i = 0; i < n_in; i++) {
2587 char *ptr = buf_ptr;
2588 grn_memcpy(&n_bytes, &out_ptr[i].ptr, sizeof(n_bytes));
2589 buf_ptr += n_bytes;
2590 GRN_B_DEC(n_values, ptr);
2591 out_ptr[i].ptr = text_ptr;
2592 for (j = 0; j < out_ptr[i].size; j++) {
2593 GRN_B_DEC(text_ptr[j].size, ptr);
2594 }
2595 for (j = 0; j < out_ptr[i].size; j++) {
2596 text_ptr[j].ptr = ptr;
2597 ptr += text_ptr[j].size;
2598 }
2599 text_ptr += out_ptr[i].size;
2600 }
2601 return GRN_SUCCESS;
2602 }
2603
2604 /*
2605 * grn_ts_expr_column_node_evaluate_ref_vector() outputs ref vector column
2606 * values.
2607 */
2608 static grn_rc
grn_ts_expr_column_node_evaluate_ref_vector(grn_ctx * ctx,grn_ts_expr_column_node * node,const grn_ts_record * in,size_t n_in,void * out)2609 grn_ts_expr_column_node_evaluate_ref_vector(grn_ctx *ctx,
2610 grn_ts_expr_column_node *node,
2611 const grn_ts_record *in,
2612 size_t n_in, void *out)
2613 {
2614 grn_rc rc;
2615 size_t i, j, n_bytes, offset = 0;
2616 grn_ts_id *buf_ptr;
2617 grn_ts_ref *ref_ptr;
2618 grn_ts_ref_vector *out_ptr = (grn_ts_ref_vector *)out;
2619 /* Read column values into node->body_buf and get the size of each value. */
2620 node->body_buf.pos = 0;
2621 for (i = 0; i < n_in; i++) {
2622 size_t size;
2623 rc = grn_ts_ja_get_value(ctx, node->column, in[i].id,
2624 &node->body_buf, &size);
2625 if (rc == GRN_SUCCESS) {
2626 out_ptr[i].size = size / sizeof(grn_ts_id);
2627 offset += out_ptr[i].size;
2628 } else {
2629 out_ptr[i].size = 0;
2630 }
2631 }
2632 /* Resize node->buf. */
2633 n_bytes = sizeof(grn_ts_ref) * offset;
2634 rc = grn_ts_buf_reserve(ctx, &node->buf, n_bytes);
2635 if (rc != GRN_SUCCESS) {
2636 return rc;
2637 }
2638 /* Compose the result. */
2639 buf_ptr = (grn_ts_id *)node->body_buf.ptr;
2640 ref_ptr = (grn_ts_ref *)node->buf.ptr;
2641 for (i = 0; i < n_in; i++) {
2642 out_ptr[i].ptr = ref_ptr;
2643 for (j = 0; j < out_ptr[i].size; j++, buf_ptr++, ref_ptr++) {
2644 ref_ptr->id = *buf_ptr;
2645 ref_ptr->score = in[i].score;
2646 }
2647 }
2648 return GRN_SUCCESS;
2649 }
2650
2651 #define GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_CASE(KIND, kind)\
2652 case GRN_TS_ ## KIND ## _VECTOR: {\
2653 size_t i;\
2654 grn_ts_ ## kind *buf_ptr;\
2655 grn_ts_ ## kind ## _vector *out_ptr = (grn_ts_ ## kind ## _vector *)out;\
2656 /* Read column values into node->buf and save the size of each value. */\
2657 node->buf.pos = 0;\
2658 for (i = 0; i < n_in; i++) {\
2659 size_t n_bytes;\
2660 grn_rc rc = grn_ts_ja_get_value(ctx, node->column, in[i].id,\
2661 &node->buf, &n_bytes);\
2662 if (rc == GRN_SUCCESS) {\
2663 out_ptr[i].size = n_bytes / sizeof(grn_ts_ ## kind);\
2664 } else {\
2665 out_ptr[i].size = 0;\
2666 }\
2667 }\
2668 buf_ptr = (grn_ts_ ## kind *)node->buf.ptr;\
2669 for (i = 0; i < n_in; i++) {\
2670 out_ptr[i].ptr = buf_ptr;\
2671 buf_ptr += out_ptr[i].size;\
2672 }\
2673 return GRN_SUCCESS;\
2674 }
2675 #define GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE(TYPE, type)\
2676 case GRN_DB_ ## TYPE: {\
2677 size_t i, j;\
2678 grn_ts_int *buf_ptr;\
2679 grn_ts_int_vector *out_ptr = (grn_ts_int_vector *)out;\
2680 /*
2681 * Read column values into body_buf and typecast the values to grn_ts_int.
2682 * Then, store the grn_ts_int values into node->buf and save the size of
2683 * each value.
2684 */\
2685 node->buf.pos = 0;\
2686 for (i = 0; i < n_in; i++) {\
2687 grn_rc rc;\
2688 size_t n_bytes, new_n_bytes;\
2689 node->body_buf.pos = 0;\
2690 rc = grn_ts_ja_get_value(ctx, node->column, in[i].id,\
2691 &node->body_buf, &n_bytes);\
2692 if (rc == GRN_SUCCESS) {\
2693 out_ptr[i].size = n_bytes / sizeof(type ## _t);\
2694 } else {\
2695 out_ptr[i].size = 0;\
2696 }\
2697 new_n_bytes = node->buf.pos + (sizeof(grn_ts_int) * out_ptr[i].size);\
2698 rc = grn_ts_buf_reserve(ctx, &node->buf, new_n_bytes);\
2699 if (rc == GRN_SUCCESS) {\
2700 type ## _t *src_ptr = (type ## _t *)node->body_buf.ptr;\
2701 grn_ts_int *dest_ptr;\
2702 dest_ptr = (grn_ts_int *)((char *)node->buf.ptr + node->buf.pos);\
2703 for (j = 0; j < out_ptr[i].size; j++) {\
2704 dest_ptr[j] = (grn_ts_int)src_ptr[j];\
2705 }\
2706 node->buf.pos = new_n_bytes;\
2707 } else {\
2708 out_ptr[i].size = 0;\
2709 }\
2710 }\
2711 buf_ptr = (grn_ts_int *)node->buf.ptr;\
2712 for (i = 0; i < n_in; i++) {\
2713 out_ptr[i].ptr = buf_ptr;\
2714 buf_ptr += out_ptr[i].size;\
2715 }\
2716 return GRN_SUCCESS;\
2717 }
2718 /* grn_ts_expr_column_node_evaluate_vector() outputs vector column values. */
2719 static grn_rc
grn_ts_expr_column_node_evaluate_vector(grn_ctx * ctx,grn_ts_expr_column_node * node,const grn_ts_record * in,size_t n_in,void * out)2720 grn_ts_expr_column_node_evaluate_vector(grn_ctx *ctx,
2721 grn_ts_expr_column_node *node,
2722 const grn_ts_record *in, size_t n_in,
2723 void *out)
2724 {
2725 switch (node->data_kind) {
2726 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_CASE(BOOL, bool)
2727 case GRN_TS_INT_VECTOR: {
2728 switch (node->data_type) {
2729 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE(INT8, int8)
2730 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE(INT16, int16)
2731 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE(INT32, int32)
2732 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE(INT64, int64)
2733 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE(UINT8, uint8)
2734 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE(UINT16, uint16)
2735 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE(UINT32, uint32)
2736 /* The behavior is undefined if a value is greater than 2^63 - 1. */
2737 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE(UINT64, uint64)
2738 default: {
2739 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data type: %d",
2740 node->data_type);
2741 }
2742 }
2743 }
2744 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_CASE(FLOAT, float)
2745 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_CASE(TIME, time)
2746 case GRN_TS_TEXT_VECTOR: {
2747 return grn_ts_expr_column_node_evaluate_text_vector(ctx, node, in, n_in,
2748 out);
2749 }
2750 GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_CASE(GEO, geo)
2751 case GRN_TS_REF_VECTOR: {
2752 return grn_ts_expr_column_node_evaluate_ref_vector(ctx, node, in, n_in,
2753 out);
2754 }
2755 default: {
2756 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
2757 node->data_kind);
2758 }
2759 }
2760 }
2761 #undef GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_INT_CASE
2762 #undef GRN_TS_EXPR_COLUMN_NODE_EVALUATE_VECTOR_CASE
2763
2764 /* grn_ts_expr_column_node_evaluate() outputs column values. */
2765 static grn_rc
grn_ts_expr_column_node_evaluate(grn_ctx * ctx,grn_ts_expr_column_node * node,const grn_ts_record * in,size_t n_in,void * out)2766 grn_ts_expr_column_node_evaluate(grn_ctx *ctx, grn_ts_expr_column_node *node,
2767 const grn_ts_record *in, size_t n_in,
2768 void *out)
2769 {
2770 if (node->data_kind & GRN_TS_VECTOR_FLAG) {
2771 return grn_ts_expr_column_node_evaluate_vector(ctx, node, in, n_in, out);
2772 } else {
2773 return grn_ts_expr_column_node_evaluate_scalar(ctx, node, in, n_in, out);
2774 }
2775 }
2776
2777 /* grn_ts_expr_column_node_filter() filters records. */
2778 static grn_rc
grn_ts_expr_column_node_filter(grn_ctx * ctx,grn_ts_expr_column_node * node,grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)2779 grn_ts_expr_column_node_filter(grn_ctx *ctx, grn_ts_expr_column_node *node,
2780 grn_ts_record *in, size_t n_in,
2781 grn_ts_record *out, size_t *n_out)
2782 {
2783 size_t i, count = 0;
2784 grn_ra *ra = (grn_ra *)node->column;
2785 grn_ra_cache cache;
2786 GRN_RA_CACHE_INIT(ra, &cache);
2787 for (i = 0; i < n_in; i++) {
2788 grn_ts_bool *ptr = NULL;
2789 if (in[i].id) {
2790 ptr = grn_ra_ref_cache(ctx, ra, in[i].id, &cache);
2791 }
2792 if (ptr && *ptr) {
2793 out[count++] = in[i];
2794 }
2795 }
2796 GRN_RA_CACHE_FIN(ra, &cache);
2797 *n_out = count;
2798 return GRN_SUCCESS;
2799 }
2800
2801 /* grn_ts_expr_column_node_adjust() updates scores. */
2802 static grn_rc
grn_ts_expr_column_node_adjust(grn_ctx * ctx,grn_ts_expr_column_node * node,grn_ts_record * io,size_t n_io)2803 grn_ts_expr_column_node_adjust(grn_ctx *ctx, grn_ts_expr_column_node *node,
2804 grn_ts_record *io, size_t n_io)
2805 {
2806 size_t i;
2807 grn_ra *ra = (grn_ra *)node->column;
2808 grn_ra_cache cache;
2809 GRN_RA_CACHE_INIT(ra, &cache);
2810 for (i = 0; i < n_io; i++) {
2811 grn_ts_float *ptr = NULL;
2812 if (io[i].id) {
2813 ptr = grn_ra_ref_cache(ctx, ra, io[i].id, &cache);
2814 }
2815 if (ptr) {
2816 io[i].score = (grn_ts_score)*ptr;
2817 }
2818 }
2819 GRN_RA_CACHE_FIN(ra, &cache);
2820 return GRN_SUCCESS;
2821 }
2822
2823 /*-------------------------------------------------------------
2824 * grn_ts_expr_op_node.
2825 */
2826
2827 enum {
2828 GRN_TS_EXPR_OP_NODE_MAX_N_ARGS = 3,
2829 GRN_TS_EXPR_OP_NODE_N_BUFS = 3
2830 };
2831
2832 typedef struct {
2833 GRN_TS_EXPR_NODE_COMMON_MEMBERS
2834 grn_ts_op_type op_type;
2835 grn_ts_expr_node *args[GRN_TS_EXPR_OP_NODE_MAX_N_ARGS];
2836 size_t n_args;
2837 grn_ts_buf bufs[GRN_TS_EXPR_OP_NODE_N_BUFS];
2838 } grn_ts_expr_op_node;
2839
2840 /* grn_ts_expr_op_node_init() initializes a node. */
2841 static void
grn_ts_expr_op_node_init(grn_ctx * ctx,grn_ts_expr_op_node * node)2842 grn_ts_expr_op_node_init(grn_ctx *ctx, grn_ts_expr_op_node *node)
2843 {
2844 size_t i;
2845 memset(node, 0, sizeof(*node));
2846 node->type = GRN_TS_EXPR_OP_NODE;
2847 for (i = 0; i < GRN_TS_EXPR_OP_NODE_MAX_N_ARGS; i++) {
2848 node->args[i] = NULL;
2849 }
2850 for (i = 0; i < GRN_TS_EXPR_OP_NODE_N_BUFS; i++) {
2851 grn_ts_buf_init(ctx, &node->bufs[i]);
2852 }
2853 }
2854
2855 /* grn_ts_expr_op_node_fin() finalizes a node. */
2856 static void
grn_ts_expr_op_node_fin(grn_ctx * ctx,grn_ts_expr_op_node * node)2857 grn_ts_expr_op_node_fin(grn_ctx *ctx, grn_ts_expr_op_node *node)
2858 {
2859 size_t i;
2860 for (i = 0; i < GRN_TS_EXPR_OP_NODE_N_BUFS; i++) {
2861 grn_ts_buf_fin(ctx, &node->bufs[i]);
2862 }
2863 for (i = 0; i < GRN_TS_EXPR_OP_NODE_MAX_N_ARGS; i++) {
2864 if (node->args[i]) {
2865 grn_ts_expr_node_close(ctx, node->args[i]);
2866 }
2867 }
2868 }
2869
2870 /*
2871 * grn_ts_expr_op_node_deref_args_for_equal() resolves references if required.
2872 */
2873 static grn_rc
grn_ts_expr_op_node_deref_args_for_equal(grn_ctx * ctx,grn_ts_expr_op_node * node)2874 grn_ts_expr_op_node_deref_args_for_equal(grn_ctx *ctx,
2875 grn_ts_expr_op_node *node)
2876 {
2877 grn_rc rc;
2878 if (node->n_args != 2) {
2879 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid #args: %" GRN_FMT_SIZE,
2880 node->n_args);
2881 }
2882 if ((node->args[0]->data_kind & ~GRN_TS_VECTOR_FLAG) != GRN_TS_REF) {
2883 return grn_ts_expr_node_deref(ctx, &node->args[1]);
2884 }
2885 if ((node->args[1]->data_kind & ~GRN_TS_VECTOR_FLAG) != GRN_TS_REF) {
2886 return grn_ts_expr_node_deref(ctx, &node->args[0]);
2887 }
2888
2889 /* FIXME: Arguments should be compared as references if possible. */
2890 rc = grn_ts_expr_node_deref(ctx, &node->args[0]);
2891 if (rc != GRN_SUCCESS) {
2892 return rc;
2893 }
2894 rc = grn_ts_expr_node_deref(ctx, &node->args[1]);
2895 if (rc != GRN_SUCCESS) {
2896 return rc;
2897 }
2898 return GRN_SUCCESS;
2899 }
2900
2901 /* grn_ts_expr_op_node_deref_args() resolves references if required. */
2902 static grn_rc
grn_ts_expr_op_node_deref_args(grn_ctx * ctx,grn_ts_expr_op_node * node)2903 grn_ts_expr_op_node_deref_args(grn_ctx *ctx, grn_ts_expr_op_node *node)
2904 {
2905 switch (node->op_type) {
2906 case GRN_TS_OP_EQUAL:
2907 case GRN_TS_OP_NOT_EQUAL: {
2908 return grn_ts_expr_op_node_deref_args_for_equal(ctx, node);
2909 }
2910 /* TODO: Add a ternary operator. */
2911 default: {
2912 size_t i;
2913 for (i = 0; i < node->n_args; i++) {
2914 grn_rc rc = grn_ts_expr_node_deref(ctx, &node->args[i]);
2915 if (rc != GRN_SUCCESS) {
2916 return rc;
2917 }
2918 }
2919 return GRN_SUCCESS;
2920 }
2921 }
2922 }
2923
2924 /*
2925 * grn_ts_op_plus_check_args() checks arguments. Note that arguments are
2926 * rearranged in some cases.
2927 */
2928 static grn_rc
grn_ts_op_plus_check_args(grn_ctx * ctx,grn_ts_expr_op_node * node)2929 grn_ts_op_plus_check_args(grn_ctx *ctx, grn_ts_expr_op_node *node)
2930 {
2931 grn_rc rc;
2932 if ((node->args[0]->data_kind == GRN_TS_INT) &&
2933 (node->args[1]->data_kind == GRN_TS_FLOAT)) {
2934 rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_FLOAT, &node->args[0],
2935 1, &node->args[0]);
2936 if (rc != GRN_SUCCESS) {
2937 node->args[0] = NULL;
2938 return rc;
2939 }
2940 } else if ((node->args[0]->data_kind == GRN_TS_FLOAT) &&
2941 (node->args[1]->data_kind == GRN_TS_INT)) {
2942 rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_FLOAT, &node->args[1],
2943 1, &node->args[1]);
2944 if (rc != GRN_SUCCESS) {
2945 node->args[1] = NULL;
2946 return rc;
2947 }
2948 }
2949
2950 switch (node->args[0]->data_kind) {
2951 case GRN_TS_INT: {
2952 switch (node->args[1]->data_kind) {
2953 case GRN_TS_INT: {
2954 /* Int + Int = Int. */
2955 node->data_kind = GRN_TS_INT;
2956 node->data_type = GRN_DB_INT64;
2957 return GRN_SUCCESS;
2958 }
2959 case GRN_TS_TIME: {
2960 /* Int + Time = Time + Int = Time. */
2961 grn_ts_expr_node *tmp = node->args[0];
2962 node->args[0] = node->args[1];
2963 node->args[1] = tmp;
2964 node->data_kind = GRN_TS_TIME;
2965 node->data_type = GRN_DB_TIME;
2966 return GRN_SUCCESS;
2967 }
2968 default: {
2969 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
2970 node->args[1]->data_kind);
2971 }
2972 }
2973 }
2974 case GRN_TS_FLOAT: {
2975 switch (node->args[1]->data_kind) {
2976 case GRN_TS_FLOAT: {
2977 /* Float + Float = Float. */
2978 node->data_kind = GRN_TS_FLOAT;
2979 node->data_type = GRN_DB_FLOAT;
2980 return GRN_SUCCESS;
2981 }
2982 case GRN_TS_TIME: {
2983 /* Float + Time = Time + Float = Time. */
2984 grn_ts_expr_node *tmp = node->args[0];
2985 node->args[0] = node->args[1];
2986 node->args[1] = tmp;
2987 node->data_kind = GRN_TS_TIME;
2988 node->data_type = GRN_DB_TIME;
2989 return GRN_SUCCESS;
2990 }
2991 default: {
2992 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
2993 node->args[1]->data_kind);
2994 }
2995 }
2996 }
2997 case GRN_TS_TIME: {
2998 switch (node->args[1]->data_kind) {
2999 case GRN_TS_INT:
3000 case GRN_TS_FLOAT: {
3001 /* Time + Int or Float = Time. */
3002 node->data_kind = GRN_TS_TIME;
3003 node->data_type = GRN_DB_TIME;
3004 return GRN_SUCCESS;
3005 }
3006 default: {
3007 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
3008 node->args[1]->data_kind);
3009 }
3010 }
3011 }
3012 default: {
3013 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
3014 node->args[0]->data_kind);
3015 }
3016 }
3017 }
3018
3019 /* grn_ts_op_minus_check_args() checks arguments. */
3020 static grn_rc
grn_ts_op_minus_check_args(grn_ctx * ctx,grn_ts_expr_op_node * node)3021 grn_ts_op_minus_check_args(grn_ctx *ctx, grn_ts_expr_op_node *node)
3022 {
3023 grn_rc rc;
3024 if ((node->args[0]->data_kind == GRN_TS_INT) &&
3025 (node->args[1]->data_kind == GRN_TS_FLOAT)) {
3026 rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_FLOAT, &node->args[0],
3027 1, &node->args[0]);
3028 if (rc != GRN_SUCCESS) {
3029 node->args[0] = NULL;
3030 return rc;
3031 }
3032 } else if ((node->args[0]->data_kind == GRN_TS_FLOAT) &&
3033 (node->args[1]->data_kind == GRN_TS_INT)) {
3034 rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_FLOAT, &node->args[1],
3035 1, &node->args[1]);
3036 if (rc != GRN_SUCCESS) {
3037 node->args[1] = NULL;
3038 return rc;
3039 }
3040 }
3041
3042 switch (node->args[0]->data_kind) {
3043 case GRN_TS_INT: {
3044 if (node->args[1]->data_kind != GRN_TS_INT) {
3045 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
3046 node->args[1]->data_kind);
3047 }
3048 /* Int - Int = Int. */
3049 node->data_kind = GRN_TS_INT;
3050 node->data_type = GRN_DB_INT64;
3051 return GRN_SUCCESS;
3052 }
3053 case GRN_TS_FLOAT: {
3054 if (node->args[1]->data_kind != GRN_TS_FLOAT) {
3055 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
3056 node->args[1]->data_kind);
3057 }
3058 /* Float - Float = Float. */
3059 node->data_kind = GRN_TS_FLOAT;
3060 node->data_type = GRN_DB_FLOAT;
3061 return GRN_SUCCESS;
3062 }
3063 case GRN_TS_TIME: {
3064 switch (node->args[1]->data_kind) {
3065 case GRN_TS_INT:
3066 case GRN_TS_FLOAT: {
3067 /* Time - Int or Float = Time. */
3068 node->data_kind = GRN_TS_TIME;
3069 node->data_type = GRN_DB_TIME;
3070 return GRN_SUCCESS;
3071 }
3072 case GRN_TS_TIME: {
3073 /* Time - Time = Float. */
3074 node->data_kind = GRN_TS_FLOAT;
3075 node->data_type = GRN_DB_FLOAT;
3076 return GRN_SUCCESS;
3077 }
3078 default: {
3079 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
3080 node->args[1]->data_kind);
3081 }
3082 }
3083 }
3084 default: {
3085 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
3086 node->args[0]->data_kind);
3087 }
3088 }
3089 }
3090
3091 /*
3092 * grn_ts_expr_op_node_typecast_args_for_cmp() inserts a typecast operator for
3093 * comparison.
3094 */
3095 static grn_rc
grn_ts_expr_op_node_typecast_args_for_cmp(grn_ctx * ctx,grn_ts_expr_op_node * node)3096 grn_ts_expr_op_node_typecast_args_for_cmp(grn_ctx *ctx,
3097 grn_ts_expr_op_node *node)
3098 {
3099 grn_rc rc;
3100 if ((node->args[0]->data_kind == GRN_TS_INT) &&
3101 (node->args[1]->data_kind == GRN_TS_FLOAT)) {
3102 rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_FLOAT, &node->args[0],
3103 1, &node->args[0]);
3104 if (rc != GRN_SUCCESS) {
3105 node->args[0] = NULL;
3106 return rc;
3107 }
3108 } else if ((node->args[0]->data_kind == GRN_TS_FLOAT) &&
3109 (node->args[1]->data_kind == GRN_TS_INT)) {
3110 rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_FLOAT, &node->args[1],
3111 1, &node->args[1]);
3112 if (rc != GRN_SUCCESS) {
3113 node->args[1] = NULL;
3114 return rc;
3115 }
3116 } else if ((node->args[0]->data_kind == GRN_TS_TIME) &&
3117 (node->args[1]->data_kind == GRN_TS_TEXT)) {
3118 rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_TIME, &node->args[1],
3119 1, &node->args[1]);
3120 if (rc != GRN_SUCCESS) {
3121 node->args[1] = NULL;
3122 return rc;
3123 }
3124 } else if ((node->args[0]->data_kind == GRN_TS_TEXT) &&
3125 (node->args[1]->data_kind == GRN_TS_TIME)) {
3126 rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_TIME, &node->args[0],
3127 1, &node->args[0]);
3128 if (rc != GRN_SUCCESS) {
3129 node->args[0] = NULL;
3130 return rc;
3131 }
3132 } else {
3133 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT,
3134 "data kind conflict: %d != %d",
3135 node->args[0]->data_kind,
3136 node->args[1]->data_kind);
3137 }
3138 return GRN_SUCCESS;
3139 }
3140
3141 /*
3142 * grn_ts_expr_op_node_check_args() checks the combination of an operator and
3143 * its arguments.
3144 */
3145 static grn_rc
grn_ts_expr_op_node_check_args(grn_ctx * ctx,grn_ts_expr_op_node * node)3146 grn_ts_expr_op_node_check_args(grn_ctx *ctx, grn_ts_expr_op_node *node)
3147 {
3148 switch (node->op_type) {
3149 case GRN_TS_OP_LOGICAL_NOT: {
3150 if (node->args[0]->data_kind != GRN_TS_BOOL) {
3151 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
3152 node->args[0]->data_kind);
3153 }
3154 node->data_kind = GRN_TS_BOOL;
3155 node->data_type = GRN_DB_BOOL;
3156 return GRN_SUCCESS;
3157 }
3158 case GRN_TS_OP_BITWISE_NOT: {
3159 switch (node->args[0]->data_kind) {
3160 case GRN_TS_BOOL:
3161 case GRN_TS_INT: {
3162 node->data_kind = node->args[0]->data_kind;
3163 node->data_type = grn_ts_data_kind_to_type(node->data_kind);
3164 return GRN_SUCCESS;
3165 }
3166 default: {
3167 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
3168 node->args[0]->data_kind);
3169 }
3170 }
3171 }
3172 case GRN_TS_OP_POSITIVE:
3173 case GRN_TS_OP_NEGATIVE: {
3174 if ((node->args[0]->data_kind != GRN_TS_INT) &&
3175 (node->args[0]->data_kind != GRN_TS_FLOAT)) {
3176 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
3177 node->args[0]->data_kind);
3178 }
3179 node->data_kind = node->args[0]->data_kind;
3180 node->data_type = grn_ts_data_kind_to_type(node->data_kind);
3181 return GRN_SUCCESS;
3182 }
3183 case GRN_TS_OP_FLOAT: {
3184 if (node->args[0]->data_kind != GRN_TS_INT) {
3185 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
3186 node->args[0]->data_kind);
3187 }
3188 node->data_kind = GRN_TS_FLOAT;
3189 node->data_type = GRN_DB_FLOAT;
3190 return GRN_SUCCESS;
3191 }
3192 case GRN_TS_OP_TIME: {
3193 if (node->args[0]->data_kind != GRN_TS_TEXT) {
3194 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
3195 node->args[0]->data_kind);
3196 }
3197 node->data_kind = GRN_TS_TIME;
3198 node->data_type = GRN_DB_TIME;
3199 return GRN_SUCCESS;
3200 }
3201 case GRN_TS_OP_LOGICAL_AND:
3202 case GRN_TS_OP_LOGICAL_OR:
3203 case GRN_TS_OP_LOGICAL_SUB: {
3204 if ((node->args[0]->data_kind != GRN_TS_BOOL) ||
3205 (node->args[1]->data_kind != GRN_TS_BOOL)) {
3206 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d, %d",
3207 node->args[0]->data_kind, node->args[1]->data_kind);
3208 }
3209 node->data_kind = GRN_TS_BOOL;
3210 node->data_type = GRN_DB_BOOL;
3211 return GRN_SUCCESS;
3212 }
3213 case GRN_TS_OP_BITWISE_AND:
3214 case GRN_TS_OP_BITWISE_OR:
3215 case GRN_TS_OP_BITWISE_XOR: {
3216 if (node->args[0]->data_kind != node->args[1]->data_kind) {
3217 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "data kind conflict: %d != %d",
3218 node->args[0]->data_kind, node->args[1]->data_kind);
3219 }
3220 switch (node->args[0]->data_kind) {
3221 case GRN_TS_BOOL:
3222 case GRN_TS_INT: {
3223 node->data_kind = node->args[0]->data_kind;
3224 node->data_type = grn_ts_data_kind_to_type(node->data_kind);
3225 return GRN_SUCCESS;
3226 }
3227 default: {
3228 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
3229 node->args[0]->data_kind);
3230 }
3231 }
3232 node->data_kind = GRN_TS_BOOL;
3233 node->data_type = GRN_DB_BOOL;
3234 return GRN_SUCCESS;
3235 }
3236 case GRN_TS_OP_EQUAL:
3237 case GRN_TS_OP_NOT_EQUAL: {
3238 grn_ts_data_kind scalar_data_kind;
3239 if (node->args[0]->data_kind != node->args[1]->data_kind) {
3240 grn_rc rc = grn_ts_expr_op_node_typecast_args_for_cmp(ctx, node);
3241 if (rc != GRN_SUCCESS) {
3242 return rc;
3243 }
3244 }
3245 scalar_data_kind = node->args[0]->data_kind & ~GRN_TS_VECTOR_FLAG;
3246 if (((scalar_data_kind == GRN_TS_REF) ||
3247 (scalar_data_kind == GRN_TS_GEO)) &&
3248 (node->args[0]->data_type != node->args[1]->data_type)) {
3249 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "data type conflict: %d != %d",
3250 node->args[0]->data_type, node->args[1]->data_type);
3251 }
3252 node->data_kind = GRN_TS_BOOL;
3253 node->data_type = GRN_DB_BOOL;
3254 return GRN_SUCCESS;
3255 }
3256 case GRN_TS_OP_LESS:
3257 case GRN_TS_OP_LESS_EQUAL:
3258 case GRN_TS_OP_GREATER:
3259 case GRN_TS_OP_GREATER_EQUAL: {
3260 if (node->args[0]->data_kind != node->args[1]->data_kind) {
3261 grn_rc rc = grn_ts_expr_op_node_typecast_args_for_cmp(ctx, node);
3262 if (rc != GRN_SUCCESS) {
3263 return rc;
3264 }
3265 }
3266 switch (node->args[0]->data_kind) {
3267 case GRN_TS_INT:
3268 case GRN_TS_FLOAT:
3269 case GRN_TS_TIME:
3270 case GRN_TS_TEXT:
3271 case GRN_TS_INT_VECTOR:
3272 case GRN_TS_FLOAT_VECTOR:
3273 case GRN_TS_TIME_VECTOR:
3274 case GRN_TS_TEXT_VECTOR: {
3275 node->data_kind = GRN_TS_BOOL;
3276 node->data_type = GRN_DB_BOOL;
3277 return GRN_SUCCESS;
3278 }
3279 default: {
3280 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
3281 node->args[0]->data_kind);
3282 }
3283 }
3284 case GRN_TS_OP_SHIFT_ARITHMETIC_LEFT:
3285 case GRN_TS_OP_SHIFT_ARITHMETIC_RIGHT:
3286 case GRN_TS_OP_SHIFT_LOGICAL_LEFT:
3287 case GRN_TS_OP_SHIFT_LOGICAL_RIGHT: {
3288 if ((node->args[0]->data_kind != GRN_TS_INT) ||
3289 (node->args[1]->data_kind != GRN_TS_INT)) {
3290 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d, %d",
3291 node->args[0]->data_kind,
3292 node->args[1]->data_kind);
3293 }
3294 node->data_kind = GRN_TS_INT;
3295 node->data_type = GRN_DB_INT64;
3296 return GRN_SUCCESS;
3297 }
3298 case GRN_TS_OP_PLUS: {
3299 return grn_ts_op_plus_check_args(ctx, node);
3300 }
3301 case GRN_TS_OP_MINUS: {
3302 return grn_ts_op_minus_check_args(ctx, node);
3303 }
3304 case GRN_TS_OP_MULTIPLICATION:
3305 case GRN_TS_OP_DIVISION:
3306 case GRN_TS_OP_MODULUS: {
3307 if (node->args[0]->data_kind != node->args[1]->data_kind) {
3308 grn_rc rc;
3309 if ((node->args[0]->data_kind == GRN_TS_INT) &&
3310 (node->args[1]->data_kind == GRN_TS_FLOAT)) {
3311 rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_FLOAT, &node->args[0],
3312 1, &node->args[0]);
3313 if (rc != GRN_SUCCESS) {
3314 node->args[0] = NULL;
3315 return rc;
3316 }
3317 } else if ((node->args[0]->data_kind == GRN_TS_FLOAT) &&
3318 (node->args[1]->data_kind == GRN_TS_INT)) {
3319 rc = grn_ts_expr_op_node_open(ctx, GRN_TS_OP_FLOAT, &node->args[1],
3320 1, &node->args[1]);
3321 if (rc != GRN_SUCCESS) {
3322 node->args[1] = NULL;
3323 return rc;
3324 }
3325 } else {
3326 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT,
3327 "data kind conflict: %d != %d",
3328 node->args[0]->data_kind,
3329 node->args[1]->data_kind);
3330 }
3331 }
3332 switch (node->args[0]->data_kind) {
3333 case GRN_TS_INT:
3334 case GRN_TS_FLOAT: {
3335 node->data_kind = node->args[0]->data_kind;
3336 node->data_type = grn_ts_data_kind_to_type(node->data_kind);
3337 return GRN_SUCCESS;
3338 }
3339 default: {
3340 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d",
3341 node->args[0]->data_kind);
3342 }
3343 }
3344 }
3345 }
3346 case GRN_TS_OP_MATCH:
3347 case GRN_TS_OP_PREFIX_MATCH:
3348 case GRN_TS_OP_SUFFIX_MATCH: {
3349 if ((node->args[0]->data_kind != GRN_TS_TEXT) ||
3350 (node->args[1]->data_kind != GRN_TS_TEXT)) {
3351 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid data kind: %d, %d",
3352 node->args[0]->data_kind,
3353 node->args[1]->data_kind);
3354 }
3355 node->data_kind = GRN_TS_BOOL;
3356 node->data_type = GRN_DB_BOOL;
3357 return GRN_SUCCESS;
3358 }
3359 default: {
3360 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid operator: %d",
3361 node->op_type);
3362 }
3363 }
3364 }
3365
3366 /* grn_ts_expr_op_node_setup() sets up an operator node. */
3367 static grn_rc
grn_ts_expr_op_node_setup(grn_ctx * ctx,grn_ts_expr_op_node * node)3368 grn_ts_expr_op_node_setup(grn_ctx *ctx, grn_ts_expr_op_node *node)
3369 {
3370 grn_rc rc = grn_ts_expr_op_node_deref_args(ctx, node);
3371 if (rc != GRN_SUCCESS) {
3372 return rc;
3373 }
3374 rc = grn_ts_expr_op_node_check_args(ctx, node);
3375 if (rc != GRN_SUCCESS) {
3376 return rc;
3377 }
3378 if (node->data_kind == GRN_TS_VOID) {
3379 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
3380 GRN_TS_VOID);
3381 } else if (node->data_type == GRN_DB_VOID) {
3382 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data type: %d",
3383 GRN_DB_VOID);
3384 }
3385 return GRN_SUCCESS;
3386 }
3387
3388 grn_rc
grn_ts_expr_op_node_open(grn_ctx * ctx,grn_ts_op_type op_type,grn_ts_expr_node ** args,size_t n_args,grn_ts_expr_node ** node)3389 grn_ts_expr_op_node_open(grn_ctx *ctx, grn_ts_op_type op_type,
3390 grn_ts_expr_node **args, size_t n_args,
3391 grn_ts_expr_node **node)
3392 {
3393 size_t i;
3394 grn_rc rc;
3395 grn_ts_expr_op_node *new_node = GRN_MALLOCN(grn_ts_expr_op_node, 1);
3396 if (!new_node) {
3397 for (i = 0; i < n_args; i++) {
3398 grn_ts_expr_node_close(ctx, args[i]);
3399 }
3400 GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
3401 "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
3402 sizeof(grn_ts_expr_op_node));
3403 }
3404 grn_ts_expr_op_node_init(ctx, new_node);
3405 new_node->op_type = op_type;
3406 for (i = 0; i < n_args; i++) {
3407 new_node->args[i] = args[i];
3408 }
3409 new_node->n_args = n_args;
3410 rc = grn_ts_expr_op_node_setup(ctx, new_node);
3411 if (rc != GRN_SUCCESS) {
3412 grn_ts_expr_op_node_fin(ctx, new_node);
3413 GRN_FREE(new_node);
3414 return rc;
3415 }
3416 *node = (grn_ts_expr_node *)new_node;
3417 return GRN_SUCCESS;
3418 }
3419
3420 /* grn_ts_expr_op_node_close() destroys a node. */
3421 static void
grn_ts_expr_op_node_close(grn_ctx * ctx,grn_ts_expr_op_node * node)3422 grn_ts_expr_op_node_close(grn_ctx *ctx, grn_ts_expr_op_node *node)
3423 {
3424 grn_ts_expr_op_node_fin(ctx, node);
3425 GRN_FREE(node);
3426 }
3427
3428 /* grn_ts_op_logical_not_evaluate() evaluates an operator. */
3429 static grn_rc
grn_ts_op_logical_not_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3430 grn_ts_op_logical_not_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
3431 const grn_ts_record *in, size_t n_in, void *out)
3432 {
3433 size_t i;
3434 grn_ts_bool *out_ptr = (grn_ts_bool *)out;
3435 grn_rc rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);
3436 if (rc != GRN_SUCCESS) {
3437 return rc;
3438 }
3439 for (i = 0; i < n_in; i++) {
3440 out_ptr[i] = grn_ts_op_logical_not_bool(out_ptr[i]);
3441 }
3442 return GRN_SUCCESS;
3443 }
3444
3445 /* grn_ts_op_bitwise_not_evaluate() evaluates an operator. */
3446 static grn_rc
grn_ts_op_bitwise_not_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3447 grn_ts_op_bitwise_not_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
3448 const grn_ts_record *in, size_t n_in, void *out)
3449 {
3450 size_t i;
3451 grn_rc rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);
3452 if (rc != GRN_SUCCESS) {
3453 return rc;
3454 }
3455 switch (node->data_kind) {
3456 case GRN_TS_BOOL: {
3457 grn_ts_bool *out_ptr = (grn_ts_bool *)out;
3458 for (i = 0; i < n_in; i++) {
3459 out_ptr[i] = grn_ts_op_bitwise_not_bool(out_ptr[i]);
3460 }
3461 return GRN_SUCCESS;
3462 }
3463 case GRN_TS_INT: {
3464 grn_ts_int *out_ptr = (grn_ts_int *)out;
3465 for (i = 0; i < n_in; i++) {
3466 out_ptr[i] = grn_ts_op_bitwise_not_int(out_ptr[i]);
3467 }
3468 return GRN_SUCCESS;
3469 }
3470 default: {
3471 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
3472 node->data_kind);
3473 }
3474 }
3475 }
3476
3477 #define GRN_TS_OP_SIGN_EVALUATE_CASE(type, KIND, kind) \
3478 case GRN_TS_ ## KIND: {\
3479 grn_ts_ ## kind *out_ptr = (grn_ts_ ## kind *)out;\
3480 for (i = 0; i < n_in; i++) {\
3481 out_ptr[i] = grn_ts_op_ ## type ## _ ## kind(out_ptr[i]);\
3482 }\
3483 return GRN_SUCCESS;\
3484 }
3485 #define GRN_TS_OP_SIGN_EVALUATE(type) \
3486 size_t i;\
3487 grn_rc rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);\
3488 if (rc != GRN_SUCCESS) {\
3489 return rc;\
3490 }\
3491 switch (node->data_kind) {\
3492 GRN_TS_OP_SIGN_EVALUATE_CASE(type, INT, int)\
3493 GRN_TS_OP_SIGN_EVALUATE_CASE(type, FLOAT, float)\
3494 default: {\
3495 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",\
3496 node->data_kind);\
3497 }\
3498 }
3499 /* grn_ts_op_positive_evaluate() evaluates an operator. */
3500 static grn_rc
grn_ts_op_positive_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3501 grn_ts_op_positive_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
3502 const grn_ts_record *in, size_t n_in, void *out)
3503 {
3504 GRN_TS_OP_SIGN_EVALUATE(positive)
3505 }
3506
3507 /* grn_ts_op_negative_evaluate() evaluates an operator. */
3508 static grn_rc
grn_ts_op_negative_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3509 grn_ts_op_negative_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
3510 const grn_ts_record *in, size_t n_in, void *out)
3511 {
3512 GRN_TS_OP_SIGN_EVALUATE(negative)
3513 }
3514 #undef GRN_TS_OP_SIGN_EVALUATE
3515 #undef GRN_TS_OP_SIGN_EVALUATE_CASE
3516
3517 /* grn_ts_op_float_evaluate() evaluates an operator. */
3518 static grn_rc
grn_ts_op_float_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3519 grn_ts_op_float_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
3520 const grn_ts_record *in, size_t n_in, void *out)
3521 {
3522 size_t i;
3523 grn_ts_int *buf_ptr;
3524 grn_ts_float *out_ptr = (grn_ts_float *)out;
3525 grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], in, n_in,
3526 &node->bufs[0]);
3527 if (rc != GRN_SUCCESS) {
3528 return rc;
3529 }
3530 buf_ptr = (grn_ts_int *)node->bufs[0].ptr;
3531 for (i = 0; i < n_in; i++) {
3532 rc = grn_ts_op_float(ctx, buf_ptr[i], &out_ptr[i]);
3533 if (rc != GRN_SUCCESS) {
3534 return rc;
3535 }
3536 }
3537 return GRN_SUCCESS;
3538 }
3539
3540 /* grn_ts_op_time_evaluate() evaluates an operator. */
3541 static grn_rc
grn_ts_op_time_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3542 grn_ts_op_time_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
3543 const grn_ts_record *in, size_t n_in, void *out)
3544 {
3545 size_t i;
3546 grn_ts_text *buf_ptr;
3547 grn_ts_time *out_ptr = (grn_ts_time *)out;
3548 grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], in, n_in,
3549 &node->bufs[0]);
3550 if (rc != GRN_SUCCESS) {
3551 return rc;
3552 }
3553 buf_ptr = (grn_ts_text *)node->bufs[0].ptr;
3554 for (i = 0; i < n_in; i++) {
3555 rc = grn_ts_op_time(ctx, buf_ptr[i], &out_ptr[i]);
3556 if (rc != GRN_SUCCESS) {
3557 return rc;
3558 }
3559 }
3560 return GRN_SUCCESS;
3561 }
3562
3563 /* grn_ts_op_logical_and_evaluate() evaluates an operator. */
3564 static grn_rc
grn_ts_op_logical_and_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3565 grn_ts_op_logical_and_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
3566 const grn_ts_record *in, size_t n_in, void *out)
3567 {
3568 size_t i, j, count;
3569 grn_rc rc;
3570 grn_ts_bool *buf_ptrs[2], *out_ptr = (grn_ts_bool *)out;
3571 grn_ts_buf *tmp_in_buf = &node->bufs[2];
3572 grn_ts_record *tmp_in;
3573
3574 /* Evaluate the 1st argument. */
3575 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], in, n_in,
3576 &node->bufs[0]);
3577 if (rc != GRN_SUCCESS) {
3578 return rc;
3579 }
3580 buf_ptrs[0] = (grn_ts_bool *)node->bufs[0].ptr;
3581
3582 /* Create a list of true records. */
3583 rc = grn_ts_buf_reserve(ctx, tmp_in_buf, sizeof(grn_ts_record) * n_in);
3584 if (rc != GRN_SUCCESS) {
3585 return rc;
3586 }
3587 tmp_in = (grn_ts_record *)tmp_in_buf->ptr;
3588 count = 0;
3589 for (i = 0; i < n_in; i++) {
3590 if (buf_ptrs[0][i]) {
3591 tmp_in[count++] = in[i];
3592 }
3593 }
3594
3595 /* Evaluate the 2nd argument. */
3596 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1], tmp_in, count,
3597 &node->bufs[1]);
3598 buf_ptrs[1] = (grn_ts_bool *)node->bufs[1].ptr;
3599
3600 /* Merge the results. */
3601 count = 0;
3602 for (i = 0, j = 0; i < n_in; i++) {
3603 out_ptr[count++] = buf_ptrs[0][i] && buf_ptrs[1][j++];
3604 }
3605 return GRN_SUCCESS;
3606 }
3607
3608 /* grn_ts_op_logical_or_evaluate() evaluates an operator. */
3609 static grn_rc
grn_ts_op_logical_or_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3610 grn_ts_op_logical_or_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
3611 const grn_ts_record *in, size_t n_in, void *out)
3612 {
3613 size_t i, j, count;
3614 grn_rc rc;
3615 grn_ts_bool *buf_ptrs[2], *out_ptr = (grn_ts_bool *)out;
3616 grn_ts_buf *tmp_in_buf = &node->bufs[2];
3617 grn_ts_record *tmp_in;
3618
3619 /* Evaluate the 1st argument. */
3620 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], in, n_in,
3621 &node->bufs[0]);
3622 if (rc != GRN_SUCCESS) {
3623 return rc;
3624 }
3625 buf_ptrs[0] = (grn_ts_bool *)node->bufs[0].ptr;
3626
3627 /* Create a list of false records. */
3628 rc = grn_ts_buf_reserve(ctx, tmp_in_buf, sizeof(grn_ts_record) * n_in);
3629 if (rc != GRN_SUCCESS) {
3630 return rc;
3631 }
3632 tmp_in = (grn_ts_record *)tmp_in_buf->ptr;
3633 count = 0;
3634 for (i = 0; i < n_in; i++) {
3635 if (!buf_ptrs[0][i]) {
3636 tmp_in[count++] = in[i];
3637 }
3638 }
3639
3640 /* Evaluate the 2nd argument. */
3641 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1], tmp_in, count,
3642 &node->bufs[1]);
3643 buf_ptrs[1] = (grn_ts_bool *)node->bufs[1].ptr;
3644
3645 /* Merge the results. */
3646 count = 0;
3647 for (i = 0, j = 0; i < n_in; i++) {
3648 out_ptr[count++] = buf_ptrs[0][i] || buf_ptrs[1][j++];
3649 }
3650 return GRN_SUCCESS;
3651 }
3652
3653 /* grn_ts_op_logical_sub_evaluate() evaluates an operator. */
3654 static grn_rc
grn_ts_op_logical_sub_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3655 grn_ts_op_logical_sub_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
3656 const grn_ts_record *in, size_t n_in, void *out)
3657 {
3658 size_t i, j, count;
3659 grn_rc rc;
3660 grn_ts_bool *buf_ptrs[2], *out_ptr = (grn_ts_bool *)out;
3661 grn_ts_buf *tmp_in_buf = &node->bufs[2];
3662 grn_ts_record *tmp_in;
3663
3664 /* Evaluate the 1st argument. */
3665 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], in, n_in,
3666 &node->bufs[0]);
3667 if (rc != GRN_SUCCESS) {
3668 return rc;
3669 }
3670 buf_ptrs[0] = (grn_ts_bool *)node->bufs[0].ptr;
3671
3672 /* Create a list of true records. */
3673 rc = grn_ts_buf_reserve(ctx, tmp_in_buf, sizeof(grn_ts_record) * n_in);
3674 if (rc != GRN_SUCCESS) {
3675 return rc;
3676 }
3677 tmp_in = (grn_ts_record *)tmp_in_buf->ptr;
3678 count = 0;
3679 for (i = 0; i < n_in; i++) {
3680 if (buf_ptrs[0][i]) {
3681 tmp_in[count++] = in[i];
3682 }
3683 }
3684
3685 /* Evaluate the 2nd argument. */
3686 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1], tmp_in, count,
3687 &node->bufs[1]);
3688 buf_ptrs[1] = (grn_ts_bool *)node->bufs[1].ptr;
3689
3690 /* Merge the results. */
3691 count = 0;
3692 for (i = 0, j = 0; i < n_in; i++) {
3693 out_ptr[count++] = buf_ptrs[0][i] &&
3694 grn_ts_op_logical_not_bool(buf_ptrs[1][j++]);
3695 }
3696 return GRN_SUCCESS;
3697 }
3698
3699 #define GRN_TS_OP_BITWISE_EVALUATE_CASE(type, KIND, kind)\
3700 case GRN_TS_ ## KIND: {\
3701 /*
3702 * Use the output buffer to put evaluation results of the 1st argument,
3703 * because the data kind is same.
3704 */\
3705 size_t i;\
3706 grn_rc rc;\
3707 grn_ts_ ## kind *out_ptr = (grn_ts_ ## kind *)out;\
3708 rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);\
3709 if (rc == GRN_SUCCESS) {\
3710 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1],\
3711 in, n_in, &node->bufs[0]);\
3712 if (rc == GRN_SUCCESS) {\
3713 grn_ts_ ## kind *buf_ptr = (grn_ts_ ## kind *)node->bufs[0].ptr;\
3714 for (i = 0; i < n_in; i++) {\
3715 out_ptr[i] = grn_ts_op_bitwise_ ## type ## _ ## kind(out_ptr[i],\
3716 buf_ptr[i]);\
3717 }\
3718 }\
3719 }\
3720 return rc;\
3721 }
3722 /* grn_ts_op_bitwise_and_evaluate() evaluates an operator. */
3723 static grn_rc
grn_ts_op_bitwise_and_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3724 grn_ts_op_bitwise_and_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
3725 const grn_ts_record *in, size_t n_in, void *out)
3726 {
3727 switch (node->args[0]->data_kind) {
3728 GRN_TS_OP_BITWISE_EVALUATE_CASE(and, BOOL, bool)
3729 GRN_TS_OP_BITWISE_EVALUATE_CASE(and, INT, int)
3730 default: {
3731 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
3732 node->args[0]->data_kind);
3733 }
3734 }
3735 }
3736
3737 /* grn_ts_op_bitwise_or_evaluate() evaluates an operator. */
3738 static grn_rc
grn_ts_op_bitwise_or_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3739 grn_ts_op_bitwise_or_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
3740 const grn_ts_record *in, size_t n_in, void *out)
3741 {
3742 switch (node->args[0]->data_kind) {
3743 GRN_TS_OP_BITWISE_EVALUATE_CASE(or, BOOL, bool)
3744 GRN_TS_OP_BITWISE_EVALUATE_CASE(or, INT, int)
3745 default: {
3746 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
3747 node->args[0]->data_kind);
3748 }
3749 }
3750 }
3751
3752 /* grn_ts_op_bitwise_xor_evaluate() evaluates an operator. */
3753 static grn_rc
grn_ts_op_bitwise_xor_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3754 grn_ts_op_bitwise_xor_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
3755 const grn_ts_record *in, size_t n_in, void *out)
3756 {
3757 switch (node->args[0]->data_kind) {
3758 GRN_TS_OP_BITWISE_EVALUATE_CASE(xor, BOOL, bool)
3759 GRN_TS_OP_BITWISE_EVALUATE_CASE(xor, INT, int)
3760 default: {
3761 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
3762 node->args[0]->data_kind);
3763 }
3764 }
3765 }
3766 #undef GRN_TS_OP_BITWISE_EVALUATE_CASE
3767
3768 #define GRN_TS_OP_CHK_EVALUATE_CASE(type, KIND, kind)\
3769 case GRN_TS_ ## KIND: {\
3770 grn_ts_ ## kind *buf_ptrs[] = {\
3771 (grn_ts_ ## kind *)node->bufs[0].ptr,\
3772 (grn_ts_ ## kind *)node->bufs[1].ptr\
3773 };\
3774 for (i = 0; i < n_in; i++) {\
3775 out_ptr[i] = grn_ts_op_ ## type ## _ ## kind(buf_ptrs[0][i],\
3776 buf_ptrs[1][i]);\
3777 }\
3778 return GRN_SUCCESS;\
3779 }
3780 #define GRN_TS_OP_CHK_EVALUATE_VECTOR_CASE(type, KIND, kind)\
3781 GRN_TS_OP_CHK_EVALUATE_CASE(type, KIND ## _VECTOR, kind ## _vector)
3782 #define GRN_TS_OP_CHK_EVALUATE(type)\
3783 size_t i;\
3784 grn_rc rc;\
3785 grn_ts_bool *out_ptr = (grn_ts_bool *)out;\
3786 if (node->args[0]->data_kind == GRN_TS_BOOL) {\
3787 /*
3788 * Use the output buffer to put evaluation results of the 1st argument,
3789 * because the data kind is same.
3790 */\
3791 rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);\
3792 if (rc == GRN_SUCCESS) {\
3793 grn_ts_buf *buf = &node->bufs[0];\
3794 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1],\
3795 in, n_in, buf);\
3796 if (rc == GRN_SUCCESS) {\
3797 grn_ts_bool *buf_ptr = (grn_ts_bool *)buf->ptr;\
3798 for (i = 0; i < n_in; i++) {\
3799 out_ptr[i] = grn_ts_op_ ## type ## _bool(out_ptr[i], buf_ptr[i]);\
3800 }\
3801 }\
3802 }\
3803 return rc;\
3804 }\
3805 for (i = 0; i < 2; i++) {\
3806 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[i], in, n_in,\
3807 &node->bufs[i]);\
3808 if (rc != GRN_SUCCESS) {\
3809 return rc;\
3810 }\
3811 }\
3812 switch (node->args[0]->data_kind) {\
3813 GRN_TS_OP_CHK_EVALUATE_CASE(type, INT, int)\
3814 GRN_TS_OP_CHK_EVALUATE_CASE(type, FLOAT, float)\
3815 GRN_TS_OP_CHK_EVALUATE_CASE(type, TIME, time)\
3816 GRN_TS_OP_CHK_EVALUATE_CASE(type, TEXT, text)\
3817 GRN_TS_OP_CHK_EVALUATE_CASE(type, GEO, geo)\
3818 GRN_TS_OP_CHK_EVALUATE_CASE(type, REF, ref)\
3819 GRN_TS_OP_CHK_EVALUATE_VECTOR_CASE(type, BOOL, bool)\
3820 GRN_TS_OP_CHK_EVALUATE_VECTOR_CASE(type, INT, int)\
3821 GRN_TS_OP_CHK_EVALUATE_VECTOR_CASE(type, FLOAT, float)\
3822 GRN_TS_OP_CHK_EVALUATE_VECTOR_CASE(type, TIME, time)\
3823 GRN_TS_OP_CHK_EVALUATE_VECTOR_CASE(type, TEXT, text)\
3824 GRN_TS_OP_CHK_EVALUATE_VECTOR_CASE(type, GEO, geo)\
3825 GRN_TS_OP_CHK_EVALUATE_VECTOR_CASE(type, REF, ref)\
3826 default: {\
3827 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",\
3828 node->args[0]->data_kind);\
3829 }\
3830 }
3831 /* grn_ts_op_equal_evaluate() evaluates an operator. */
3832 static grn_rc
grn_ts_op_equal_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3833 grn_ts_op_equal_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
3834 const grn_ts_record *in, size_t n_in, void *out)
3835 {
3836 GRN_TS_OP_CHK_EVALUATE(equal)
3837 }
3838
3839 /* grn_ts_op_not_equal_evaluate() evaluates an operator. */
3840 static grn_rc
grn_ts_op_not_equal_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3841 grn_ts_op_not_equal_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
3842 const grn_ts_record *in, size_t n_in, void *out)
3843 {
3844 GRN_TS_OP_CHK_EVALUATE(not_equal)
3845 }
3846 #undef GRN_TS_OP_CHK_EVALUATE
3847 #undef GRN_TS_OP_CHK_EVALUATE_VECTOR_CASE
3848 #undef GRN_TS_OP_CHK_EVALUATE_CASE
3849
3850 #define GRN_TS_OP_CMP_EVALUATE_CASE(type, KIND, kind)\
3851 case GRN_TS_ ## KIND: {\
3852 grn_ts_ ## kind *buf_ptrs[] = {\
3853 (grn_ts_ ## kind *)node->bufs[0].ptr,\
3854 (grn_ts_ ## kind *)node->bufs[1].ptr\
3855 };\
3856 for (i = 0; i < n_in; i++) {\
3857 out_ptr[i] = grn_ts_op_ ## type ## _ ## kind(buf_ptrs[0][i],\
3858 buf_ptrs[1][i]);\
3859 }\
3860 return GRN_SUCCESS;\
3861 }
3862 #define GRN_TS_OP_CMP_EVALUATE_VECTOR_CASE(type, KIND, kind)\
3863 GRN_TS_OP_CMP_EVALUATE_CASE(type, KIND ## _VECTOR, kind ## _vector)
3864 #define GRN_TS_OP_CMP_EVALUATE(type)\
3865 size_t i;\
3866 grn_rc rc;\
3867 grn_ts_bool *out_ptr = (grn_ts_bool *)out;\
3868 for (i = 0; i < 2; i++) {\
3869 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[i], in, n_in,\
3870 &node->bufs[i]);\
3871 if (rc != GRN_SUCCESS) {\
3872 return rc;\
3873 }\
3874 }\
3875 switch (node->args[0]->data_kind) {\
3876 GRN_TS_OP_CMP_EVALUATE_CASE(type, INT, int)\
3877 GRN_TS_OP_CMP_EVALUATE_CASE(type, FLOAT, float)\
3878 GRN_TS_OP_CMP_EVALUATE_CASE(type, TIME, time)\
3879 GRN_TS_OP_CMP_EVALUATE_CASE(type, TEXT, text)\
3880 GRN_TS_OP_CMP_EVALUATE_VECTOR_CASE(type, INT, int)\
3881 GRN_TS_OP_CMP_EVALUATE_VECTOR_CASE(type, FLOAT, float)\
3882 GRN_TS_OP_CMP_EVALUATE_VECTOR_CASE(type, TIME, time)\
3883 GRN_TS_OP_CMP_EVALUATE_VECTOR_CASE(type, TEXT, text)\
3884 default: {\
3885 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",\
3886 node->args[0]->data_kind);\
3887 }\
3888 }
3889 /* grn_ts_op_less_evaluate() evaluates an operator. */
3890 static grn_rc
grn_ts_op_less_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3891 grn_ts_op_less_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
3892 const grn_ts_record *in, size_t n_in, void *out)
3893 {
3894 GRN_TS_OP_CMP_EVALUATE(less)
3895 }
3896
3897 /* grn_ts_op_less_equal_evaluate() evaluates an operator. */
3898 static grn_rc
grn_ts_op_less_equal_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3899 grn_ts_op_less_equal_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
3900 const grn_ts_record *in, size_t n_in, void *out)
3901 {
3902 GRN_TS_OP_CMP_EVALUATE(less_equal)
3903 }
3904
3905 /* grn_ts_op_greater_evaluate() evaluates an operator. */
3906 static grn_rc
grn_ts_op_greater_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3907 grn_ts_op_greater_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
3908 const grn_ts_record *in, size_t n_in, void *out)
3909 {
3910 GRN_TS_OP_CMP_EVALUATE(greater)
3911 }
3912
3913 /* grn_ts_op_greater_equal_evaluate() evaluates an operator. */
3914 static grn_rc
grn_ts_op_greater_equal_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3915 grn_ts_op_greater_equal_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
3916 const grn_ts_record *in, size_t n_in,
3917 void *out)
3918 {
3919 GRN_TS_OP_CMP_EVALUATE(greater_equal)
3920 }
3921 #undef GRN_TS_OP_CMP_EVALUATE
3922 #undef GRN_TS_OP_CMP_EVALUATE_VECTOR_CASE
3923 #undef GRN_TS_OP_CMP_EVALUATE_CASE
3924
3925 #define GRN_TS_OP_SHIFT_EVALUATE(type)\
3926 size_t i;\
3927 grn_rc rc;\
3928 grn_ts_int *out_ptr = (grn_ts_int *)out;\
3929 rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);\
3930 if (rc == GRN_SUCCESS) {\
3931 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1],\
3932 in, n_in, &node->bufs[0]);\
3933 if (rc == GRN_SUCCESS) {\
3934 grn_ts_int *buf_ptr = (grn_ts_int *)node->bufs[0].ptr;\
3935 for (i = 0; i < n_in; i++) {\
3936 out_ptr[i] = grn_ts_op_shift_ ## type(out_ptr[i], buf_ptr[i]);\
3937 }\
3938 }\
3939 }\
3940 return rc;
3941 /* grn_ts_op_shift_arithmetic_left_evaluate() evaluates an operator. */
3942 static grn_rc
grn_ts_op_shift_arithmetic_left_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3943 grn_ts_op_shift_arithmetic_left_evaluate(grn_ctx *ctx,
3944 grn_ts_expr_op_node *node,
3945 const grn_ts_record *in, size_t n_in,
3946 void *out)
3947 {
3948 GRN_TS_OP_SHIFT_EVALUATE(arithmetic_left)
3949 }
3950
3951 /* grn_ts_op_shift_arithmetic_right_evaluate() evaluates an operator. */
3952 static grn_rc
grn_ts_op_shift_arithmetic_right_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3953 grn_ts_op_shift_arithmetic_right_evaluate(grn_ctx *ctx,
3954 grn_ts_expr_op_node *node,
3955 const grn_ts_record *in, size_t n_in,
3956 void *out)
3957 {
3958 GRN_TS_OP_SHIFT_EVALUATE(arithmetic_right)
3959 }
3960
3961 /* grn_ts_op_shift_logical_left_evaluate() evaluates an operator. */
3962 static grn_rc
grn_ts_op_shift_logical_left_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3963 grn_ts_op_shift_logical_left_evaluate(grn_ctx *ctx,
3964 grn_ts_expr_op_node *node,
3965 const grn_ts_record *in, size_t n_in,
3966 void *out)
3967 {
3968 GRN_TS_OP_SHIFT_EVALUATE(logical_left)
3969 }
3970
3971 /* grn_ts_op_shift_logical_right_evaluate() evaluates an operator. */
3972 static grn_rc
grn_ts_op_shift_logical_right_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)3973 grn_ts_op_shift_logical_right_evaluate(grn_ctx *ctx,
3974 grn_ts_expr_op_node *node,
3975 const grn_ts_record *in, size_t n_in,
3976 void *out)
3977 {
3978 GRN_TS_OP_SHIFT_EVALUATE(logical_right)
3979 }
3980 #undef GRN_TS_OP_SHIFT_EVALUATE
3981
3982 #define GRN_TS_OP_ARITH_EVALUATE(type, lhs_kind, rhs_kind)\
3983 /*
3984 * Use the output buffer to put evaluation results of the 1st argument,
3985 * because the data kind is same.
3986 */\
3987 size_t i;\
3988 grn_rc rc;\
3989 grn_ts_ ## lhs_kind *out_ptr = (grn_ts_ ## lhs_kind *)out;\
3990 rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);\
3991 if (rc == GRN_SUCCESS) {\
3992 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1],\
3993 in, n_in, &node->bufs[0]);\
3994 if (rc == GRN_SUCCESS) {\
3995 grn_ts_ ## rhs_kind *buf_ptr = (grn_ts_ ## rhs_kind *)node->bufs[0].ptr;\
3996 for (i = 0; i < n_in; i++) {\
3997 rc = grn_ts_op_ ## type ## _ ## lhs_kind ## _ ## rhs_kind(\
3998 ctx, out_ptr[i], buf_ptr[i], &out_ptr[i]);\
3999 if (rc != GRN_SUCCESS) {\
4000 return rc;\
4001 }\
4002 }\
4003 }\
4004 }\
4005 return rc;
4006
4007 #define GRN_TS_OP_ARITH_EVALUATE_CASE(type, KIND, kind)\
4008 case GRN_TS_ ## KIND: {\
4009 /*
4010 * Use the output buffer to put evaluation results of the 1st argument,
4011 * because the data kind is same.
4012 */\
4013 size_t i;\
4014 grn_rc rc;\
4015 grn_ts_ ## kind *out_ptr = (grn_ts_ ## kind *)out;\
4016 rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);\
4017 if (rc == GRN_SUCCESS) {\
4018 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1],\
4019 in, n_in, &node->bufs[0]);\
4020 if (rc == GRN_SUCCESS) {\
4021 grn_ts_ ## kind *buf_ptr = (grn_ts_ ## kind *)node->bufs[0].ptr;\
4022 for (i = 0; i < n_in; i++) {\
4023 out_ptr[i] = grn_ts_op_ ## type ## _ ## kind(out_ptr[i],\
4024 buf_ptr[i]);\
4025 }\
4026 }\
4027 }\
4028 return rc;\
4029 }
4030 #define GRN_TS_OP_ARITH_EVALUATE_TIME_CASE(type, KIND, lhs, rhs)\
4031 case GRN_TS_ ## KIND: {\
4032 /*
4033 * Use the output buffer to put evaluation results of the 1st argument,
4034 * because the data kind is same.
4035 */\
4036 size_t i;\
4037 grn_rc rc;\
4038 grn_ts_ ## lhs *out_ptr = (grn_ts_ ## lhs *)out;\
4039 rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);\
4040 if (rc == GRN_SUCCESS) {\
4041 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1],\
4042 in, n_in, &node->bufs[0]);\
4043 if (rc == GRN_SUCCESS) {\
4044 grn_ts_ ## rhs *buf_ptr = (grn_ts_ ## rhs *)node->bufs[0].ptr;\
4045 for (i = 0; i < n_in; i++) {\
4046 out_ptr[i] = grn_ts_op_ ## type ## _ ## lhs ## _ ## rhs(out_ptr[i],\
4047 buf_ptr[i]);\
4048 }\
4049 }\
4050 }\
4051 return rc;\
4052 }
4053 /* grn_ts_op_plus_evaluate() evaluates an operator. */
4054 static grn_rc
grn_ts_op_plus_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)4055 grn_ts_op_plus_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
4056 const grn_ts_record *in, size_t n_in, void *out)
4057 {
4058 switch (node->args[0]->data_kind) {
4059 case GRN_TS_INT: {
4060 GRN_TS_OP_ARITH_EVALUATE(plus, int, int)
4061 }
4062 case GRN_TS_FLOAT: {
4063 GRN_TS_OP_ARITH_EVALUATE(plus, float, float)
4064 }
4065 case GRN_TS_TIME: {
4066 switch (node->args[1]->data_kind) {
4067 case GRN_TS_INT: {
4068 GRN_TS_OP_ARITH_EVALUATE(plus, time, int)
4069 }
4070 case GRN_TS_FLOAT: {
4071 GRN_TS_OP_ARITH_EVALUATE(plus, time, float)
4072 }
4073 default: {
4074 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "data kind conflict: %d, %d",
4075 node->args[0]->data_kind,
4076 node->args[1]->data_kind);
4077 }
4078 }
4079 }
4080 default: {
4081 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
4082 node->args[0]->data_kind);
4083 }
4084 }
4085 }
4086
4087 /* grn_ts_op_minus_evaluate() evaluates an operator. */
4088 static grn_rc
grn_ts_op_minus_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)4089 grn_ts_op_minus_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
4090 const grn_ts_record *in, size_t n_in, void *out)
4091 {
4092 switch (node->args[0]->data_kind) {
4093 case GRN_TS_INT: {
4094 GRN_TS_OP_ARITH_EVALUATE(minus, int, int)
4095 }
4096 case GRN_TS_FLOAT: {
4097 GRN_TS_OP_ARITH_EVALUATE(minus, float, float)
4098 }
4099 case GRN_TS_TIME: {
4100 switch (node->args[1]->data_kind) {
4101 case GRN_TS_INT: {
4102 GRN_TS_OP_ARITH_EVALUATE(minus, time, int)
4103 }
4104 case GRN_TS_FLOAT: {
4105 GRN_TS_OP_ARITH_EVALUATE(minus, time, float)
4106 }
4107 case GRN_TS_TIME: {
4108 size_t i;
4109 grn_rc rc;
4110 grn_ts_float *out_ptr = (grn_ts_float *)out;
4111 grn_ts_time *buf_ptrs[2];
4112 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], in, n_in,
4113 &node->bufs[0]);
4114 if (rc != GRN_SUCCESS) {
4115 return rc;
4116 }
4117 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1], in, n_in,
4118 &node->bufs[1]);
4119 if (rc != GRN_SUCCESS) {
4120 return rc;
4121 }
4122 buf_ptrs[0] = (grn_ts_time *)node->bufs[0].ptr;
4123 buf_ptrs[1] = (grn_ts_time *)node->bufs[1].ptr;
4124 for (i = 0; i < n_in; i++) {
4125 rc = grn_ts_op_minus_time_time(ctx, buf_ptrs[0][i], buf_ptrs[1][i],
4126 &out_ptr[i]);
4127 if (rc != GRN_SUCCESS) {
4128 return rc;
4129 }
4130 }
4131 return GRN_SUCCESS;
4132 }
4133 default: {
4134 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "data kind conflict: %d, %d",
4135 node->args[0]->data_kind,
4136 node->args[1]->data_kind);
4137 }
4138 }
4139 }
4140 default: {
4141 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
4142 node->args[0]->data_kind);
4143 }
4144 }
4145 }
4146 #undef GRN_TS_OP_ARITH_EVALUATE_TIME_CASE
4147
4148 /* grn_ts_op_multiplication_evaluate() evaluates an operator. */
4149 static grn_rc
grn_ts_op_multiplication_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)4150 grn_ts_op_multiplication_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
4151 const grn_ts_record *in, size_t n_in,
4152 void *out)
4153 {
4154 switch (node->data_kind) {
4155 case GRN_TS_INT: {
4156 GRN_TS_OP_ARITH_EVALUATE(multiplication, int, int)
4157 }
4158 case GRN_TS_FLOAT: {
4159 GRN_TS_OP_ARITH_EVALUATE(multiplication, float, float)
4160 }
4161 default: {
4162 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
4163 node->data_kind);
4164 }
4165 }
4166 }
4167
4168 /* grn_ts_op_division_evaluate() evaluates an operator. */
4169 static grn_rc
grn_ts_op_division_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)4170 grn_ts_op_division_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
4171 const grn_ts_record *in, size_t n_in, void *out)
4172 {
4173 switch (node->data_kind) {
4174 case GRN_TS_INT: {
4175 GRN_TS_OP_ARITH_EVALUATE(division, int, int)
4176 }
4177 case GRN_TS_FLOAT: {
4178 GRN_TS_OP_ARITH_EVALUATE(division, float, float)
4179 }
4180 default: {
4181 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
4182 node->data_kind);
4183 }
4184 }
4185 }
4186
4187 /* grn_ts_op_modulus_evaluate() evaluates an operator. */
4188 static grn_rc
grn_ts_op_modulus_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)4189 grn_ts_op_modulus_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
4190 const grn_ts_record *in, size_t n_in, void *out)
4191 {
4192 switch (node->data_kind) {
4193 case GRN_TS_INT: {
4194 GRN_TS_OP_ARITH_EVALUATE(modulus, int, int)
4195 }
4196 case GRN_TS_FLOAT: {
4197 GRN_TS_OP_ARITH_EVALUATE(modulus, float, float)
4198 }
4199 default: {
4200 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",
4201 node->data_kind);
4202 }
4203 }
4204 }
4205 #undef GRN_TS_OP_ARITH_EVALUATE_CASE
4206
4207 #define GRN_TS_OP_MATCH_EVALUATE(type)\
4208 size_t i;\
4209 grn_rc rc;\
4210 grn_ts_bool *out_ptr = (grn_ts_bool *)out;\
4211 grn_ts_text *buf_ptrs[2];\
4212 for (i = 0; i < 2; i++) {\
4213 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[i], in, n_in,\
4214 &node->bufs[i]);\
4215 if (rc != GRN_SUCCESS) {\
4216 return rc;\
4217 }\
4218 }\
4219 buf_ptrs[0] = (grn_ts_text *)node->bufs[0].ptr;\
4220 buf_ptrs[1] = (grn_ts_text *)node->bufs[1].ptr;\
4221 for (i = 0; i < n_in; i++) {\
4222 out_ptr[i] = grn_ts_op_ ## type(buf_ptrs[0][i], buf_ptrs[1][i]);\
4223 }\
4224 return GRN_SUCCESS;\
4225 /* grn_ts_op_match_evaluate() evaluates an operator. */
4226 static grn_rc
grn_ts_op_match_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)4227 grn_ts_op_match_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
4228 const grn_ts_record *in, size_t n_in, void *out)
4229 {
4230 GRN_TS_OP_MATCH_EVALUATE(match)
4231 }
4232
4233 /* grn_ts_op_prefix_match_evaluate() evaluates an operator. */
4234 static grn_rc
grn_ts_op_prefix_match_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)4235 grn_ts_op_prefix_match_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
4236 const grn_ts_record *in, size_t n_in,
4237 void *out)
4238 {
4239 GRN_TS_OP_MATCH_EVALUATE(prefix_match)
4240 }
4241
4242 /* grn_ts_op_suffix_match_evaluate() evaluates an operator. */
4243 static grn_rc
grn_ts_op_suffix_match_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)4244 grn_ts_op_suffix_match_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
4245 const grn_ts_record *in, size_t n_in,
4246 void *out)
4247 {
4248 GRN_TS_OP_MATCH_EVALUATE(suffix_match)
4249 }
4250 #undef GRN_TS_OP_MATCH_EVALUATE
4251
4252 /* grn_ts_expr_op_node_evaluate() evaluates an operator. */
4253 static grn_rc
grn_ts_expr_op_node_evaluate(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,void * out)4254 grn_ts_expr_op_node_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
4255 const grn_ts_record *in, size_t n_in, void *out)
4256 {
4257 switch (node->op_type) {
4258 case GRN_TS_OP_LOGICAL_NOT: {
4259 return grn_ts_op_logical_not_evaluate(ctx, node, in, n_in, out);
4260 }
4261 case GRN_TS_OP_BITWISE_NOT: {
4262 return grn_ts_op_bitwise_not_evaluate(ctx, node, in, n_in, out);
4263 }
4264 case GRN_TS_OP_POSITIVE: {
4265 return grn_ts_op_positive_evaluate(ctx, node, in, n_in, out);
4266 }
4267 case GRN_TS_OP_NEGATIVE: {
4268 return grn_ts_op_negative_evaluate(ctx, node, in, n_in, out);
4269 }
4270 case GRN_TS_OP_FLOAT: {
4271 return grn_ts_op_float_evaluate(ctx, node, in, n_in, out);
4272 }
4273 case GRN_TS_OP_TIME: {
4274 return grn_ts_op_time_evaluate(ctx, node, in, n_in, out);
4275 }
4276 case GRN_TS_OP_LOGICAL_AND: {
4277 return grn_ts_op_logical_and_evaluate(ctx, node, in, n_in, out);
4278 }
4279 case GRN_TS_OP_LOGICAL_OR: {
4280 return grn_ts_op_logical_or_evaluate(ctx, node, in, n_in, out);
4281 }
4282 case GRN_TS_OP_LOGICAL_SUB: {
4283 return grn_ts_op_logical_sub_evaluate(ctx, node, in, n_in, out);
4284 }
4285 case GRN_TS_OP_BITWISE_AND: {
4286 return grn_ts_op_bitwise_and_evaluate(ctx, node, in, n_in, out);
4287 }
4288 case GRN_TS_OP_BITWISE_OR: {
4289 return grn_ts_op_bitwise_or_evaluate(ctx, node, in, n_in, out);
4290 }
4291 case GRN_TS_OP_BITWISE_XOR: {
4292 return grn_ts_op_bitwise_xor_evaluate(ctx, node, in, n_in, out);
4293 }
4294 case GRN_TS_OP_EQUAL: {
4295 return grn_ts_op_equal_evaluate(ctx, node, in, n_in, out);
4296 }
4297 case GRN_TS_OP_NOT_EQUAL: {
4298 return grn_ts_op_not_equal_evaluate(ctx, node, in, n_in, out);
4299 }
4300 case GRN_TS_OP_LESS: {
4301 return grn_ts_op_less_evaluate(ctx, node, in, n_in, out);
4302 }
4303 case GRN_TS_OP_LESS_EQUAL: {
4304 return grn_ts_op_less_equal_evaluate(ctx, node, in, n_in, out);
4305 }
4306 case GRN_TS_OP_GREATER: {
4307 return grn_ts_op_greater_evaluate(ctx, node, in, n_in, out);
4308 }
4309 case GRN_TS_OP_GREATER_EQUAL: {
4310 return grn_ts_op_greater_equal_evaluate(ctx, node, in, n_in, out);
4311 }
4312 case GRN_TS_OP_SHIFT_ARITHMETIC_LEFT: {
4313 return grn_ts_op_shift_arithmetic_left_evaluate(ctx, node, in, n_in, out);
4314 }
4315 case GRN_TS_OP_SHIFT_ARITHMETIC_RIGHT: {
4316 return grn_ts_op_shift_arithmetic_right_evaluate(ctx, node, in, n_in, out);
4317 }
4318 case GRN_TS_OP_SHIFT_LOGICAL_LEFT: {
4319 return grn_ts_op_shift_logical_left_evaluate(ctx, node, in, n_in, out);
4320 }
4321 case GRN_TS_OP_SHIFT_LOGICAL_RIGHT: {
4322 return grn_ts_op_shift_logical_right_evaluate(ctx, node, in, n_in, out);
4323 }
4324 case GRN_TS_OP_PLUS: {
4325 return grn_ts_op_plus_evaluate(ctx, node, in, n_in, out);
4326 }
4327 case GRN_TS_OP_MINUS: {
4328 return grn_ts_op_minus_evaluate(ctx, node, in, n_in, out);
4329 }
4330 case GRN_TS_OP_MULTIPLICATION: {
4331 return grn_ts_op_multiplication_evaluate(ctx, node, in, n_in, out);
4332 }
4333 case GRN_TS_OP_DIVISION: {
4334 return grn_ts_op_division_evaluate(ctx, node, in, n_in, out);
4335 }
4336 case GRN_TS_OP_MODULUS: {
4337 return grn_ts_op_modulus_evaluate(ctx, node, in, n_in, out);
4338 }
4339 case GRN_TS_OP_MATCH: {
4340 return grn_ts_op_match_evaluate(ctx, node, in, n_in, out);
4341 }
4342 case GRN_TS_OP_PREFIX_MATCH: {
4343 return grn_ts_op_prefix_match_evaluate(ctx, node, in, n_in, out);
4344 }
4345 case GRN_TS_OP_SUFFIX_MATCH: {
4346 return grn_ts_op_suffix_match_evaluate(ctx, node, in, n_in, out);
4347 }
4348 // TODO: Add operators.
4349 default: {
4350 GRN_TS_ERR_RETURN(GRN_OPERATION_NOT_SUPPORTED,
4351 "operator not supported: %d", node->op_type);
4352 }
4353 }
4354 }
4355
4356 /* grn_ts_op_logical_not_filter() filters records. */
4357 static grn_rc
grn_ts_op_logical_not_filter(grn_ctx * ctx,grn_ts_expr_op_node * node,grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)4358 grn_ts_op_logical_not_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
4359 grn_ts_record *in, size_t n_in,
4360 grn_ts_record *out, size_t *n_out)
4361 {
4362 size_t i, count;
4363 grn_rc rc;
4364 grn_ts_bool *buf_ptr;
4365 rc = grn_ts_buf_reserve(ctx, &node->bufs[0], sizeof(grn_ts_bool) * n_in);
4366 if (rc != GRN_SUCCESS) {
4367 return rc;
4368 }
4369 buf_ptr = (grn_ts_bool *)node->bufs[0].ptr;
4370 rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, buf_ptr);
4371 if (rc != GRN_SUCCESS) {
4372 return rc;
4373 }
4374 for (i = 0, count = 0; i < n_in; i++) {
4375 if (grn_ts_op_logical_not_bool(buf_ptr[i])) {
4376 out[count++] = in[i];
4377 }
4378 }
4379 *n_out = count;
4380 return GRN_SUCCESS;
4381 }
4382
4383 /* grn_ts_op_bitwise_not_filter() filters records. */
4384 static grn_rc
grn_ts_op_bitwise_not_filter(grn_ctx * ctx,grn_ts_expr_op_node * node,grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)4385 grn_ts_op_bitwise_not_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
4386 grn_ts_record *in, size_t n_in,
4387 grn_ts_record *out, size_t *n_out)
4388 {
4389 size_t i, count;
4390 grn_rc rc;
4391 grn_ts_bool *buf_ptr;
4392 rc = grn_ts_buf_reserve(ctx, &node->bufs[0], sizeof(grn_ts_bool) * n_in);
4393 if (rc != GRN_SUCCESS) {
4394 return rc;
4395 }
4396 buf_ptr = (grn_ts_bool *)node->bufs[0].ptr;
4397 rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, buf_ptr);
4398 if (rc != GRN_SUCCESS) {
4399 return rc;
4400 }
4401 for (i = 0, count = 0; i < n_in; i++) {
4402 if (grn_ts_op_bitwise_not_bool(buf_ptr[i])) {
4403 out[count++] = in[i];
4404 }
4405 }
4406 *n_out = count;
4407 return GRN_SUCCESS;
4408 }
4409
4410 /* grn_ts_op_logical_and_filter() filters records. */
4411 static grn_rc
grn_ts_op_logical_and_filter(grn_ctx * ctx,grn_ts_expr_op_node * node,grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)4412 grn_ts_op_logical_and_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
4413 grn_ts_record *in, size_t n_in,
4414 grn_ts_record *out, size_t *n_out)
4415 {
4416 grn_rc rc = grn_ts_expr_node_filter(ctx, node->args[0], in, n_in,
4417 out, n_out);
4418 if (rc != GRN_SUCCESS) {
4419 return rc;
4420 }
4421 return grn_ts_expr_node_filter(ctx, node->args[1], out, *n_out, out, n_out);
4422 }
4423
4424 /* grn_ts_op_logical_or_filter() filters records. */
4425 static grn_rc
grn_ts_op_logical_or_filter(grn_ctx * ctx,grn_ts_expr_op_node * node,grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)4426 grn_ts_op_logical_or_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
4427 grn_ts_record *in, size_t n_in,
4428 grn_ts_record *out, size_t *n_out)
4429 {
4430 size_t i, j, count;
4431 grn_rc rc;
4432 grn_ts_bool *buf_ptrs[2];
4433 grn_ts_buf *tmp_in_buf = &node->bufs[2];
4434 grn_ts_record *tmp_in;
4435
4436 /* Evaluate the 1st argument. */
4437 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], in, n_in,
4438 &node->bufs[0]);
4439 if (rc != GRN_SUCCESS) {
4440 return rc;
4441 }
4442 buf_ptrs[0] = (grn_ts_bool *)node->bufs[0].ptr;
4443
4444 /* Create a list of false records. */
4445 rc = grn_ts_buf_reserve(ctx, tmp_in_buf, sizeof(grn_ts_record) * n_in);
4446 if (rc != GRN_SUCCESS) {
4447 return rc;
4448 }
4449 tmp_in = (grn_ts_record *)tmp_in_buf->ptr;
4450 count = 0;
4451 for (i = 0; i < n_in; i++) {
4452 if (!buf_ptrs[0][i]) {
4453 tmp_in[count++] = in[i];
4454 }
4455 }
4456
4457 /* Evaluate the 2nd argument. */
4458 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1], tmp_in, count,
4459 &node->bufs[1]);
4460 buf_ptrs[1] = (grn_ts_bool *)node->bufs[1].ptr;
4461
4462 /* Merge the results. */
4463 count = 0;
4464 for (i = 0, j = 0; i < n_in; i++) {
4465 if (buf_ptrs[0][i] || buf_ptrs[1][j++]) {
4466 out[count++] = in[i];
4467 }
4468 }
4469 *n_out = count;
4470 return GRN_SUCCESS;
4471 }
4472
4473 /* grn_ts_op_logical_sub_filter() filters records. */
4474 static grn_rc
grn_ts_op_logical_sub_filter(grn_ctx * ctx,grn_ts_expr_op_node * node,grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)4475 grn_ts_op_logical_sub_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
4476 grn_ts_record *in, size_t n_in,
4477 grn_ts_record *out, size_t *n_out)
4478 {
4479 size_t i, n, count;
4480 grn_ts_bool *buf_ptr;
4481 grn_rc rc = grn_ts_expr_node_filter(ctx, node->args[0], in, n_in, out, &n);
4482 if (rc != GRN_SUCCESS) {
4483 return rc;
4484 }
4485 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[1], out, n,
4486 &node->bufs[0]);
4487 buf_ptr = (grn_ts_bool *)node->bufs[0].ptr;
4488 for (i = 0, count = 0; i < n; i++) {
4489 if (grn_ts_op_logical_not_bool(buf_ptr[i])) {
4490 out[count++] = out[i];
4491 }
4492 }
4493 *n_out = count;
4494 return GRN_SUCCESS;
4495 }
4496
4497 #define GRN_TS_OP_BITWISE_FILTER(type)\
4498 size_t i, count = 0;\
4499 grn_ts_bool *buf_ptrs[2];\
4500 for (i = 0; i < 2; i++) {\
4501 grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[i], in, n_in,\
4502 &node->bufs[i]);\
4503 if (rc != GRN_SUCCESS) {\
4504 return rc;\
4505 }\
4506 buf_ptrs[i] = (grn_ts_bool *)node->bufs[i].ptr;\
4507 }\
4508 for (i = 0; i < n_in; i++) {\
4509 if (grn_ts_op_bitwise_ ## type ## _bool(buf_ptrs[0][i], buf_ptrs[1][i])) {\
4510 out[count++] = in[i];\
4511 }\
4512 }\
4513 *n_out = count;\
4514 return GRN_SUCCESS;\
4515 /* grn_ts_op_bitwise_and_filter() filters records. */
4516 static grn_rc
grn_ts_op_bitwise_and_filter(grn_ctx * ctx,grn_ts_expr_op_node * node,grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)4517 grn_ts_op_bitwise_and_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
4518 grn_ts_record *in, size_t n_in,
4519 grn_ts_record *out, size_t *n_out)
4520 {
4521 GRN_TS_OP_BITWISE_FILTER(and);
4522 }
4523
4524 /* grn_ts_op_bitwise_or_filter() filters records. */
4525 static grn_rc
grn_ts_op_bitwise_or_filter(grn_ctx * ctx,grn_ts_expr_op_node * node,grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)4526 grn_ts_op_bitwise_or_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
4527 grn_ts_record *in, size_t n_in,
4528 grn_ts_record *out, size_t *n_out)
4529 {
4530 GRN_TS_OP_BITWISE_FILTER(or);
4531 }
4532
4533 /* grn_ts_op_bitwise_xor_filter() filters records. */
4534 static grn_rc
grn_ts_op_bitwise_xor_filter(grn_ctx * ctx,grn_ts_expr_op_node * node,grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)4535 grn_ts_op_bitwise_xor_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
4536 grn_ts_record *in, size_t n_in,
4537 grn_ts_record *out, size_t *n_out)
4538 {
4539 GRN_TS_OP_BITWISE_FILTER(xor);
4540 }
4541 #undef GRN_TS_OP_BITWISE_FILTER_CASE
4542
4543 #define GRN_TS_OP_CHK_FILTER_CASE(type, KIND, kind)\
4544 case GRN_TS_ ## KIND: {\
4545 grn_ts_ ## kind *buf_ptrs[] = {\
4546 (grn_ts_ ## kind *)node->bufs[0].ptr,\
4547 (grn_ts_ ## kind *)node->bufs[1].ptr\
4548 };\
4549 for (i = 0; i < n_in; i++) {\
4550 if (grn_ts_op_ ## type ## _ ## kind(buf_ptrs[0][i], buf_ptrs[1][i])) {\
4551 out[count++] = in[i];\
4552 }\
4553 }\
4554 *n_out = count;\
4555 return GRN_SUCCESS;\
4556 }
4557 #define GRN_TS_OP_CHK_FILTER_VECTOR_CASE(type, KIND, kind)\
4558 GRN_TS_OP_CHK_FILTER_CASE(type, KIND ## _VECTOR, kind ## _vector)
4559 #define GRN_TS_OP_CHK_FILTER(type)\
4560 size_t i, count = 0;\
4561 for (i = 0; i < 2; i++) {\
4562 grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[i], in, n_in,\
4563 &node->bufs[i]);\
4564 if (rc != GRN_SUCCESS) {\
4565 return rc;\
4566 }\
4567 }\
4568 switch (node->args[0]->data_kind) {\
4569 GRN_TS_OP_CHK_FILTER_CASE(type, BOOL, bool)\
4570 GRN_TS_OP_CHK_FILTER_CASE(type, INT, int)\
4571 GRN_TS_OP_CHK_FILTER_CASE(type, FLOAT, float)\
4572 GRN_TS_OP_CHK_FILTER_CASE(type, TIME, time)\
4573 GRN_TS_OP_CHK_FILTER_CASE(type, TEXT, text)\
4574 GRN_TS_OP_CHK_FILTER_CASE(type, GEO, geo)\
4575 GRN_TS_OP_CHK_FILTER_CASE(type, REF, ref)\
4576 GRN_TS_OP_CHK_FILTER_VECTOR_CASE(type, BOOL, bool)\
4577 GRN_TS_OP_CHK_FILTER_VECTOR_CASE(type, INT, int)\
4578 GRN_TS_OP_CHK_FILTER_VECTOR_CASE(type, FLOAT, float)\
4579 GRN_TS_OP_CHK_FILTER_VECTOR_CASE(type, TIME, time)\
4580 GRN_TS_OP_CHK_FILTER_VECTOR_CASE(type, TEXT, text)\
4581 GRN_TS_OP_CHK_FILTER_VECTOR_CASE(type, GEO, geo)\
4582 GRN_TS_OP_CHK_FILTER_VECTOR_CASE(type, REF, ref)\
4583 default: {\
4584 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",\
4585 node->args[0]->data_kind);\
4586 }\
4587 }
4588 /* grn_ts_op_equal_filter() filters records. */
4589 static grn_rc
grn_ts_op_equal_filter(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)4590 grn_ts_op_equal_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
4591 const grn_ts_record *in, size_t n_in,
4592 grn_ts_record *out, size_t *n_out)
4593 {
4594 GRN_TS_OP_CHK_FILTER(equal)
4595 }
4596
4597 /* grn_ts_op_not_equal_filter() filters records. */
4598 static grn_rc
grn_ts_op_not_equal_filter(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)4599 grn_ts_op_not_equal_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
4600 const grn_ts_record *in, size_t n_in,
4601 grn_ts_record *out, size_t *n_out)
4602 {
4603 GRN_TS_OP_CHK_FILTER(not_equal)
4604 }
4605 #undef GRN_TS_OP_CHK_FILTER
4606 #undef GRN_TS_OP_CHK_FILTER_VECTOR_CASE
4607 #undef GRN_TS_OP_CHK_FILTER_CASE
4608
4609 #define GRN_TS_OP_CMP_FILTER_CASE(type, KIND, kind)\
4610 case GRN_TS_ ## KIND: {\
4611 grn_ts_ ## kind *buf_ptrs[] = {\
4612 (grn_ts_ ## kind *)node->bufs[0].ptr,\
4613 (grn_ts_ ## kind *)node->bufs[1].ptr\
4614 };\
4615 for (i = 0; i < n_in; i++) {\
4616 if (grn_ts_op_ ## type ## _ ## kind(buf_ptrs[0][i], buf_ptrs[1][i])) {\
4617 out[count++] = in[i];\
4618 }\
4619 }\
4620 *n_out = count;\
4621 return GRN_SUCCESS;\
4622 }
4623 #define GRN_TS_OP_CMP_FILTER_VECTOR_CASE(type, KIND, kind)\
4624 GRN_TS_OP_CMP_FILTER_CASE(type, KIND ## _VECTOR, kind ## _vector)
4625 #define GRN_TS_OP_CMP_FILTER(type)\
4626 size_t i, count = 0;\
4627 for (i = 0; i < 2; i++) {\
4628 grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[i], in, n_in,\
4629 &node->bufs[i]);\
4630 if (rc != GRN_SUCCESS) {\
4631 return rc;\
4632 }\
4633 }\
4634 switch (node->args[0]->data_kind) {\
4635 GRN_TS_OP_CMP_FILTER_CASE(type, INT, int)\
4636 GRN_TS_OP_CMP_FILTER_CASE(type, FLOAT, float)\
4637 GRN_TS_OP_CMP_FILTER_CASE(type, TIME, time)\
4638 GRN_TS_OP_CMP_FILTER_CASE(type, TEXT, text)\
4639 GRN_TS_OP_CMP_FILTER_VECTOR_CASE(type, INT, int)\
4640 GRN_TS_OP_CMP_FILTER_VECTOR_CASE(type, FLOAT, float)\
4641 GRN_TS_OP_CMP_FILTER_VECTOR_CASE(type, TIME, time)\
4642 GRN_TS_OP_CMP_FILTER_VECTOR_CASE(type, TEXT, text)\
4643 default: {\
4644 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "invalid data kind: %d",\
4645 node->args[0]->data_kind);\
4646 }\
4647 }
4648 /* grn_ts_op_less_filter() filters records. */
4649 static grn_rc
grn_ts_op_less_filter(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)4650 grn_ts_op_less_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
4651 const grn_ts_record *in, size_t n_in,
4652 grn_ts_record *out, size_t *n_out)
4653 {
4654 GRN_TS_OP_CMP_FILTER(less)
4655 }
4656
4657 /* grn_ts_op_less_equal_filter() filters records. */
4658 static grn_rc
grn_ts_op_less_equal_filter(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)4659 grn_ts_op_less_equal_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
4660 const grn_ts_record *in, size_t n_in,
4661 grn_ts_record *out, size_t *n_out)
4662 {
4663 GRN_TS_OP_CMP_FILTER(less_equal)
4664 }
4665
4666 /* grn_ts_op_greater_filter() filters records. */
4667 static grn_rc
grn_ts_op_greater_filter(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)4668 grn_ts_op_greater_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
4669 const grn_ts_record *in, size_t n_in,
4670 grn_ts_record *out, size_t *n_out)
4671 {
4672 GRN_TS_OP_CMP_FILTER(greater)
4673 }
4674
4675 /* grn_ts_op_greater_equal_filter() filters records. */
4676 static grn_rc
grn_ts_op_greater_equal_filter(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)4677 grn_ts_op_greater_equal_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
4678 const grn_ts_record *in, size_t n_in,
4679 grn_ts_record *out, size_t *n_out)
4680 {
4681 GRN_TS_OP_CMP_FILTER(greater_equal)
4682 }
4683 #undef GRN_TS_OP_CMP_FILTER
4684 #undef GRN_TS_OP_CMP_FILTER_VECTOR_CASE
4685 #undef GRN_TS_OP_CMP_FILTER_CASE
4686
4687 #define GRN_TS_OP_MATCH_FILTER_CASE(type, KIND, kind)\
4688 case GRN_TS_ ## KIND: {\
4689 grn_ts_ ## kind *buf_ptrs[] = {\
4690 (grn_ts_ ## kind *)node->bufs[0].ptr,\
4691 (grn_ts_ ## kind *)node->bufs[1].ptr\
4692 };\
4693 for (i = 0; i < n_in; i++) {\
4694 if (grn_ts_op_ ## type ## _ ## kind(buf_ptrs[0][i], buf_ptrs[1][i])) {\
4695 out[count++] = in[i];\
4696 }\
4697 }\
4698 *n_out = count;\
4699 return GRN_SUCCESS;\
4700 }
4701
4702 #define GRN_TS_OP_MATCH_FILTER(type)\
4703 size_t i, count = 0;\
4704 grn_ts_text *buf_ptrs[2];\
4705 for (i = 0; i < 2; i++) {\
4706 grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[i], in, n_in,\
4707 &node->bufs[i]);\
4708 if (rc != GRN_SUCCESS) {\
4709 return rc;\
4710 }\
4711 }\
4712 buf_ptrs[0] = (grn_ts_text *)node->bufs[0].ptr;\
4713 buf_ptrs[1] = (grn_ts_text *)node->bufs[1].ptr;\
4714 for (i = 0; i < n_in; i++) {\
4715 if (grn_ts_op_ ## type(buf_ptrs[0][i], buf_ptrs[1][i])) {\
4716 out[count++] = in[i];\
4717 }\
4718 }\
4719 *n_out = count;\
4720 return GRN_SUCCESS;\
4721 /* grn_ts_op_match_filter() filters records. */
4722 static grn_rc
grn_ts_op_match_filter(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)4723 grn_ts_op_match_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
4724 const grn_ts_record *in, size_t n_in,
4725 grn_ts_record *out, size_t *n_out)
4726 {
4727 GRN_TS_OP_MATCH_FILTER(match)
4728 }
4729
4730 /* grn_ts_op_prefix_match_filter() filters records. */
4731 static grn_rc
grn_ts_op_prefix_match_filter(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)4732 grn_ts_op_prefix_match_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
4733 const grn_ts_record *in, size_t n_in,
4734 grn_ts_record *out, size_t *n_out)
4735 {
4736 GRN_TS_OP_MATCH_FILTER(prefix_match)
4737 }
4738
4739 /* grn_ts_op_suffix_match_filter() filters records. */
4740 static grn_rc
grn_ts_op_suffix_match_filter(grn_ctx * ctx,grn_ts_expr_op_node * node,const grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)4741 grn_ts_op_suffix_match_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
4742 const grn_ts_record *in, size_t n_in,
4743 grn_ts_record *out, size_t *n_out)
4744 {
4745 GRN_TS_OP_MATCH_FILTER(suffix_match)
4746 }
4747 #undef GRN_TS_OP_MATCH_FILTER
4748
4749 /* grn_ts_expr_op_node_filter() filters records. */
4750 static grn_rc
grn_ts_expr_op_node_filter(grn_ctx * ctx,grn_ts_expr_op_node * node,grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)4751 grn_ts_expr_op_node_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
4752 grn_ts_record *in, size_t n_in,
4753 grn_ts_record *out, size_t *n_out)
4754 {
4755 switch (node->op_type) {
4756 case GRN_TS_OP_LOGICAL_NOT: {
4757 return grn_ts_op_logical_not_filter(ctx, node, in, n_in, out, n_out);
4758 }
4759 case GRN_TS_OP_BITWISE_NOT: {
4760 return grn_ts_op_bitwise_not_filter(ctx, node, in, n_in, out, n_out);
4761 }
4762 case GRN_TS_OP_LOGICAL_AND: {
4763 return grn_ts_op_logical_and_filter(ctx, node, in, n_in, out, n_out);
4764 }
4765 case GRN_TS_OP_LOGICAL_OR: {
4766 return grn_ts_op_logical_or_filter(ctx, node, in, n_in, out, n_out);
4767 }
4768 case GRN_TS_OP_LOGICAL_SUB: {
4769 return grn_ts_op_logical_sub_filter(ctx, node, in, n_in, out, n_out);
4770 }
4771 case GRN_TS_OP_BITWISE_AND: {
4772 return grn_ts_op_bitwise_and_filter(ctx, node, in, n_in, out, n_out);
4773 }
4774 case GRN_TS_OP_BITWISE_OR: {
4775 return grn_ts_op_bitwise_or_filter(ctx, node, in, n_in, out, n_out);
4776 }
4777 case GRN_TS_OP_BITWISE_XOR: {
4778 return grn_ts_op_bitwise_xor_filter(ctx, node, in, n_in, out, n_out);
4779 }
4780 case GRN_TS_OP_EQUAL: {
4781 return grn_ts_op_equal_filter(ctx, node, in, n_in, out, n_out);
4782 }
4783 case GRN_TS_OP_NOT_EQUAL: {
4784 return grn_ts_op_not_equal_filter(ctx, node, in, n_in, out, n_out);
4785 }
4786 case GRN_TS_OP_LESS: {
4787 return grn_ts_op_less_filter(ctx, node, in, n_in, out, n_out);
4788 }
4789 case GRN_TS_OP_LESS_EQUAL: {
4790 return grn_ts_op_less_equal_filter(ctx, node, in, n_in, out, n_out);
4791 }
4792 case GRN_TS_OP_GREATER: {
4793 return grn_ts_op_greater_filter(ctx, node, in, n_in, out, n_out);
4794 }
4795 case GRN_TS_OP_GREATER_EQUAL: {
4796 return grn_ts_op_greater_equal_filter(ctx, node, in, n_in, out, n_out);
4797 }
4798 case GRN_TS_OP_MATCH: {
4799 return grn_ts_op_match_filter(ctx, node, in, n_in, out, n_out);
4800 }
4801 case GRN_TS_OP_PREFIX_MATCH: {
4802 return grn_ts_op_prefix_match_filter(ctx, node, in, n_in, out, n_out);
4803 }
4804 case GRN_TS_OP_SUFFIX_MATCH: {
4805 return grn_ts_op_suffix_match_filter(ctx, node, in, n_in, out, n_out);
4806 }
4807 // TODO: Add operators.
4808 default: {
4809 GRN_TS_ERR_RETURN(GRN_OPERATION_NOT_SUPPORTED,
4810 "operator not supported: %d", node->op_type);
4811 }
4812 }
4813 }
4814
4815 #define GRN_TS_OP_SIGN_ADJUST(type)\
4816 size_t i;\
4817 grn_ts_float *buf_ptr;\
4818 grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], io, n_io,\
4819 &node->bufs[0]);\
4820 if (rc != GRN_SUCCESS) {\
4821 return rc;\
4822 }\
4823 buf_ptr = (grn_ts_float *)node->bufs[0].ptr;\
4824 for (i = 0; i < n_io; i++) {\
4825 grn_ts_float result = grn_ts_op_ ## type ## _float(buf_ptr[i]);\
4826 io[i].score = (grn_ts_score)result;\
4827 if (!isfinite(io[i].score)) {\
4828 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid score: %g", result);\
4829 }\
4830 }\
4831 return GRN_SUCCESS;
4832 /* grn_ts_op_positive_adjust() updates scores. */
4833 static grn_rc
grn_ts_op_positive_adjust(grn_ctx * ctx,grn_ts_expr_op_node * node,grn_ts_record * io,size_t n_io)4834 grn_ts_op_positive_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
4835 grn_ts_record *io, size_t n_io)
4836 {
4837 GRN_TS_OP_SIGN_ADJUST(positive)
4838 }
4839
4840 /* grn_ts_op_negative_adjust() updates scores. */
4841 static grn_rc
grn_ts_op_negative_adjust(grn_ctx * ctx,grn_ts_expr_op_node * node,grn_ts_record * io,size_t n_io)4842 grn_ts_op_negative_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
4843 grn_ts_record *io, size_t n_io)
4844 {
4845 GRN_TS_OP_SIGN_ADJUST(negative)
4846 }
4847 #undef GRN_TS_OP_SIGN_ADJUST
4848
4849 /* grn_ts_op_float_adjust() updates scores. */
4850 static grn_rc
grn_ts_op_float_adjust(grn_ctx * ctx,grn_ts_expr_op_node * node,grn_ts_record * io,size_t n_io)4851 grn_ts_op_float_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
4852 grn_ts_record *io, size_t n_io)
4853 {
4854 size_t i;
4855 grn_ts_int *buf_ptr;
4856 grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[0], io, n_io,
4857 &node->bufs[0]);
4858 if (rc != GRN_SUCCESS) {
4859 return rc;
4860 }
4861 buf_ptr = (grn_ts_int *)node->bufs[0].ptr;
4862 for (i = 0; i < n_io; i++) {
4863 grn_ts_float result;
4864 rc = grn_ts_op_float(ctx, buf_ptr[i], &result);
4865 io[i].score = (grn_ts_score)result;
4866 if (!isfinite(io[i].score)) {
4867 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid score: %g", result);
4868 }
4869 }
4870 return GRN_SUCCESS;
4871 }
4872
4873 #define GRN_TS_OP_ARITH_ADJUST(type)\
4874 grn_rc rc;\
4875 size_t i;\
4876 grn_ts_float *buf_ptrs[2];\
4877 for (i = 0; i < 2; i++) {\
4878 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->args[i], io, n_io,\
4879 &node->bufs[i]);\
4880 if (rc != GRN_SUCCESS) {\
4881 return rc;\
4882 }\
4883 }\
4884 buf_ptrs[0] = (grn_ts_float *)node->bufs[0].ptr;\
4885 buf_ptrs[1] = (grn_ts_float *)node->bufs[1].ptr;\
4886 for (i = 0; i < n_io; i++) {\
4887 grn_ts_float result;\
4888 rc = grn_ts_op_ ## type ## _float_float(ctx, buf_ptrs[0][i],\
4889 buf_ptrs[1][i], &result);\
4890 io[i].score = (grn_ts_score)result;\
4891 if (!isfinite(io[i].score)) {\
4892 GRN_TS_ERR_RETURN(GRN_INVALID_ARGUMENT, "invalid score: %g", result);\
4893 }\
4894 }\
4895 return GRN_SUCCESS;
4896 /* grn_ts_op_plus_adjust() updates scores. */
4897 static grn_rc
grn_ts_op_plus_adjust(grn_ctx * ctx,grn_ts_expr_op_node * node,grn_ts_record * io,size_t n_io)4898 grn_ts_op_plus_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
4899 grn_ts_record *io, size_t n_io)
4900 {
4901 GRN_TS_OP_ARITH_ADJUST(plus)
4902 }
4903
4904 /* grn_ts_op_minus_adjust() updates scores. */
4905 static grn_rc
grn_ts_op_minus_adjust(grn_ctx * ctx,grn_ts_expr_op_node * node,grn_ts_record * io,size_t n_io)4906 grn_ts_op_minus_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
4907 grn_ts_record *io, size_t n_io)
4908 {
4909 GRN_TS_OP_ARITH_ADJUST(minus)
4910 }
4911
4912 /* grn_ts_op_multiplication_adjust() updates scores. */
4913 static grn_rc
grn_ts_op_multiplication_adjust(grn_ctx * ctx,grn_ts_expr_op_node * node,grn_ts_record * io,size_t n_io)4914 grn_ts_op_multiplication_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
4915 grn_ts_record *io, size_t n_io)
4916 {
4917 GRN_TS_OP_ARITH_ADJUST(multiplication)
4918 }
4919
4920 /* grn_ts_op_division_adjust() updates scores. */
4921 static grn_rc
grn_ts_op_division_adjust(grn_ctx * ctx,grn_ts_expr_op_node * node,grn_ts_record * io,size_t n_io)4922 grn_ts_op_division_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
4923 grn_ts_record *io, size_t n_io)
4924 {
4925 GRN_TS_OP_ARITH_ADJUST(division)
4926 }
4927
4928 /* grn_ts_op_modulus_adjust() updates scores. */
4929 static grn_rc
grn_ts_op_modulus_adjust(grn_ctx * ctx,grn_ts_expr_op_node * node,grn_ts_record * io,size_t n_io)4930 grn_ts_op_modulus_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
4931 grn_ts_record *io, size_t n_io)
4932 {
4933 GRN_TS_OP_ARITH_ADJUST(modulus)
4934 }
4935 #undef GRN_TS_OP_ARITH_ADJUST
4936
4937 /* grn_ts_expr_op_node_adjust() updates scores. */
4938 static grn_rc
grn_ts_expr_op_node_adjust(grn_ctx * ctx,grn_ts_expr_op_node * node,grn_ts_record * io,size_t n_io)4939 grn_ts_expr_op_node_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
4940 grn_ts_record *io, size_t n_io)
4941 {
4942 switch (node->op_type) {
4943 case GRN_TS_OP_POSITIVE: {
4944 return grn_ts_op_positive_adjust(ctx, node, io, n_io);
4945 }
4946 case GRN_TS_OP_NEGATIVE: {
4947 return grn_ts_op_negative_adjust(ctx, node, io, n_io);
4948 }
4949 case GRN_TS_OP_FLOAT: {
4950 return grn_ts_op_float_adjust(ctx, node, io, n_io);
4951 }
4952 case GRN_TS_OP_PLUS: {
4953 return grn_ts_op_plus_adjust(ctx, node, io, n_io);
4954 }
4955 case GRN_TS_OP_MINUS: {
4956 return grn_ts_op_minus_adjust(ctx, node, io, n_io);
4957 }
4958 case GRN_TS_OP_MULTIPLICATION: {
4959 return grn_ts_op_multiplication_adjust(ctx, node, io, n_io);
4960 }
4961 case GRN_TS_OP_DIVISION: {
4962 return grn_ts_op_division_adjust(ctx, node, io, n_io);
4963 }
4964 case GRN_TS_OP_MODULUS: {
4965 return grn_ts_op_modulus_adjust(ctx, node, io, n_io);
4966 }
4967 // TODO: Add operators.
4968 default: {
4969 GRN_TS_ERR_RETURN(GRN_OPERATION_NOT_SUPPORTED,
4970 "operator not supported: %d", node->op_type);
4971 }
4972 }
4973 }
4974
4975 /*-------------------------------------------------------------
4976 * grn_ts_expr_bridge_node.
4977 */
4978
4979 enum { GRN_TS_EXPR_BRIDGE_NODE_N_BUFS = 2 };
4980
4981 typedef struct {
4982 GRN_TS_EXPR_NODE_COMMON_MEMBERS
4983 grn_ts_expr_node *src;
4984 grn_ts_expr_node *dest;
4985 grn_ts_buf bufs[GRN_TS_EXPR_BRIDGE_NODE_N_BUFS];
4986 } grn_ts_expr_bridge_node;
4987
4988 /* grn_ts_expr_bridge_node_init() initializes a node. */
4989 static void
grn_ts_expr_bridge_node_init(grn_ctx * ctx,grn_ts_expr_bridge_node * node)4990 grn_ts_expr_bridge_node_init(grn_ctx *ctx, grn_ts_expr_bridge_node *node)
4991 {
4992 size_t i;
4993 memset(node, 0, sizeof(*node));
4994 node->type = GRN_TS_EXPR_BRIDGE_NODE;
4995 node->src = NULL;
4996 node->dest = NULL;
4997 for (i = 0; i < GRN_TS_EXPR_BRIDGE_NODE_N_BUFS; i++) {
4998 grn_ts_buf_init(ctx, &node->bufs[i]);
4999 }
5000 }
5001
5002 /* grn_ts_expr_bridge_node_fin() finalizes a node. */
5003 static void
grn_ts_expr_bridge_node_fin(grn_ctx * ctx,grn_ts_expr_bridge_node * node)5004 grn_ts_expr_bridge_node_fin(grn_ctx *ctx, grn_ts_expr_bridge_node *node)
5005 {
5006 size_t i;
5007 for (i = 0; i < GRN_TS_EXPR_BRIDGE_NODE_N_BUFS; i++) {
5008 grn_ts_buf_fin(ctx, &node->bufs[i]);
5009 }
5010 if (node->dest) {
5011 grn_ts_expr_node_close(ctx, node->dest);
5012 }
5013 if (node->src) {
5014 grn_ts_expr_node_close(ctx, node->src);
5015 }
5016 }
5017
5018 grn_rc
grn_ts_expr_bridge_node_open(grn_ctx * ctx,grn_ts_expr_node * src,grn_ts_expr_node * dest,grn_ts_expr_node ** node)5019 grn_ts_expr_bridge_node_open(grn_ctx *ctx, grn_ts_expr_node *src,
5020 grn_ts_expr_node *dest, grn_ts_expr_node **node)
5021 {
5022 grn_ts_expr_bridge_node *new_node = GRN_MALLOCN(grn_ts_expr_bridge_node, 1);
5023 if (!new_node) {
5024 GRN_TS_ERR_RETURN(GRN_NO_MEMORY_AVAILABLE,
5025 "GRN_MALLOCN failed: %" GRN_FMT_SIZE " x 1",
5026 sizeof(grn_ts_expr_bridge_node));
5027 }
5028 grn_ts_expr_bridge_node_init(ctx, new_node);
5029 new_node->data_kind = dest->data_kind;
5030 new_node->data_type = dest->data_type;
5031 new_node->src = src;
5032 new_node->dest = dest;
5033 *node = (grn_ts_expr_node *)new_node;
5034 return GRN_SUCCESS;
5035 }
5036
5037 /* grn_ts_expr_bridge_node_close() destroys a node. */
5038 static void
grn_ts_expr_bridge_node_close(grn_ctx * ctx,grn_ts_expr_bridge_node * node)5039 grn_ts_expr_bridge_node_close(grn_ctx *ctx, grn_ts_expr_bridge_node *node)
5040 {
5041 grn_ts_expr_bridge_node_fin(ctx, node);
5042 GRN_FREE(node);
5043 }
5044
5045 /* grn_ts_expr_bridge_node_evaluate() evaluates a bridge. */
5046 static grn_rc
grn_ts_expr_bridge_node_evaluate(grn_ctx * ctx,grn_ts_expr_bridge_node * node,const grn_ts_record * in,size_t n_in,void * out)5047 grn_ts_expr_bridge_node_evaluate(grn_ctx *ctx, grn_ts_expr_bridge_node *node,
5048 const grn_ts_record *in, size_t n_in,
5049 void *out)
5050 {
5051 grn_ts_record *tmp;
5052 grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->src, in, n_in,
5053 &node->bufs[0]);
5054 if (rc != GRN_SUCCESS) {
5055 return rc;
5056 }
5057 tmp = (grn_ts_record *)node->bufs[0].ptr;
5058 return grn_ts_expr_node_evaluate(ctx, node->dest, tmp, n_in, out);
5059 }
5060
5061 /* grn_ts_expr_bridge_node_filter() filters records. */
5062 static grn_rc
grn_ts_expr_bridge_node_filter(grn_ctx * ctx,grn_ts_expr_bridge_node * node,grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)5063 grn_ts_expr_bridge_node_filter(grn_ctx *ctx, grn_ts_expr_bridge_node *node,
5064 grn_ts_record *in, size_t n_in,
5065 grn_ts_record *out, size_t *n_out)
5066 {
5067 size_t i, count;
5068 grn_ts_bool *values;
5069 grn_ts_record *tmp;
5070 grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->src, in, n_in,
5071 &node->bufs[0]);
5072 if (rc != GRN_SUCCESS) {
5073 return rc;
5074 }
5075 tmp = (grn_ts_record *)node->bufs[0].ptr;
5076 rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->dest, in, n_in,
5077 &node->bufs[1]);
5078 if (rc != GRN_SUCCESS) {
5079 return rc;
5080 }
5081 values = (grn_ts_bool *)&node->bufs[1].ptr;
5082 for (i = 0, count = 0; i < n_in; i++) {
5083 if (values[i]) {
5084 out[count++] = in[i];
5085 }
5086 }
5087 *n_out = count;
5088 return GRN_SUCCESS;
5089 }
5090
5091 /* grn_ts_expr_bridge_node_adjust() updates scores. */
5092 static grn_rc
grn_ts_expr_bridge_node_adjust(grn_ctx * ctx,grn_ts_expr_bridge_node * node,grn_ts_record * io,size_t n_io)5093 grn_ts_expr_bridge_node_adjust(grn_ctx *ctx, grn_ts_expr_bridge_node *node,
5094 grn_ts_record *io, size_t n_io)
5095 {
5096 size_t i;
5097 grn_ts_record *tmp;
5098 grn_rc rc = grn_ts_expr_node_evaluate_to_buf(ctx, node->src, io, n_io,
5099 &node->bufs[0]);
5100 if (rc != GRN_SUCCESS) {
5101 return rc;
5102 }
5103 tmp = (grn_ts_record *)node->bufs[0].ptr;
5104 rc = grn_ts_expr_node_adjust(ctx, node->dest, tmp, n_io);
5105 if (rc != GRN_SUCCESS) {
5106 return rc;
5107 }
5108 for (i = 0; i < n_io; i++) {
5109 io[i].score = tmp[i].score;
5110 }
5111 return GRN_SUCCESS;
5112 }
5113
5114 /*-------------------------------------------------------------
5115 * grn_ts_expr_node.
5116 */
5117
5118 #define GRN_TS_EXPR_NODE_CLOSE_CASE(TYPE, type)\
5119 case GRN_TS_EXPR_ ## TYPE ## _NODE: {\
5120 grn_ts_expr_ ## type ## _node *type ## _node;\
5121 type ## _node = (grn_ts_expr_ ## type ## _node *)node;\
5122 grn_ts_expr_ ## type ## _node_close(ctx, type ## _node);\
5123 return;\
5124 }
5125 void
grn_ts_expr_node_close(grn_ctx * ctx,grn_ts_expr_node * node)5126 grn_ts_expr_node_close(grn_ctx *ctx, grn_ts_expr_node *node)
5127 {
5128 switch (node->type) {
5129 GRN_TS_EXPR_NODE_CLOSE_CASE(ID, id)
5130 GRN_TS_EXPR_NODE_CLOSE_CASE(SCORE, score)
5131 GRN_TS_EXPR_NODE_CLOSE_CASE(KEY, key)
5132 GRN_TS_EXPR_NODE_CLOSE_CASE(VALUE, value)
5133 GRN_TS_EXPR_NODE_CLOSE_CASE(CONST, const)
5134 GRN_TS_EXPR_NODE_CLOSE_CASE(COLUMN, column)
5135 GRN_TS_EXPR_NODE_CLOSE_CASE(OP, op)
5136 GRN_TS_EXPR_NODE_CLOSE_CASE(BRIDGE, bridge)
5137 }
5138 }
5139 #undef GRN_TS_EXPR_NODE_CLOSE_CASE
5140
5141 /* grn_ts_expr_node_deref_once() resolves a reference. */
5142 static grn_rc
grn_ts_expr_node_deref_once(grn_ctx * ctx,grn_ts_expr_node * in,grn_ts_expr_node ** out)5143 grn_ts_expr_node_deref_once(grn_ctx *ctx, grn_ts_expr_node *in,
5144 grn_ts_expr_node **out)
5145 {
5146 grn_rc rc;
5147 grn_id table_id = in->data_type;
5148 grn_ts_expr_node *key_node, *bridge_node;
5149 grn_obj *table = grn_ctx_at(ctx, table_id);
5150 if (!table) {
5151 GRN_TS_ERR_RETURN(GRN_UNKNOWN_ERROR, "grn_ctx_at failed: %d", table_id);
5152 }
5153 if (!grn_ts_obj_is_table(ctx, table)) {
5154 grn_obj_unlink(ctx, table);
5155 GRN_TS_ERR_RETURN(GRN_UNKNOWN_ERROR, "not table: %d", table_id);
5156 }
5157 rc = grn_ts_expr_key_node_open(ctx, table, &key_node);
5158 grn_obj_unlink(ctx, table);
5159 if (rc != GRN_SUCCESS) {
5160 return rc;
5161 }
5162 rc = grn_ts_expr_bridge_node_open(ctx, in, key_node, &bridge_node);
5163 if (rc != GRN_SUCCESS) {
5164 grn_ts_expr_node_close(ctx, key_node);
5165 return rc;
5166 }
5167 *out = bridge_node;
5168 return GRN_SUCCESS;
5169 }
5170
5171 grn_rc
grn_ts_expr_node_deref(grn_ctx * ctx,grn_ts_expr_node ** node_ptr)5172 grn_ts_expr_node_deref(grn_ctx *ctx, grn_ts_expr_node **node_ptr)
5173 {
5174 grn_ts_expr_node *node = *node_ptr, **in_ptr = NULL;
5175 while ((node->data_kind & ~GRN_TS_VECTOR_FLAG) == GRN_TS_REF) {
5176 grn_ts_expr_node *new_node= 0;
5177 grn_rc rc = grn_ts_expr_node_deref_once(ctx, node, &new_node);
5178 if (rc != GRN_SUCCESS) {
5179 if (in_ptr) {
5180 *in_ptr = NULL;
5181 grn_ts_expr_node_close(ctx, node);
5182 }
5183 return rc;
5184 }
5185 if (node == *node_ptr) {
5186 grn_ts_expr_bridge_node *bridge_node;
5187 bridge_node = (grn_ts_expr_bridge_node *)new_node;
5188 if (bridge_node->src != node) {
5189 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT, "broken bridge node");
5190 }
5191 in_ptr = &bridge_node->src;
5192 }
5193 node = new_node;
5194 }
5195 *node_ptr = node;
5196 return GRN_SUCCESS;
5197 }
5198
5199 #define GRN_TS_EXPR_NODE_EVALUATE_CASE(TYPE, type)\
5200 case GRN_TS_EXPR_ ## TYPE ## _NODE: {\
5201 grn_ts_expr_ ## type ## _node *type ## _node;\
5202 type ## _node = (grn_ts_expr_ ## type ## _node *)node;\
5203 return grn_ts_expr_ ## type ## _node_evaluate(ctx, type ## _node,\
5204 in, n_in, out);\
5205 }
5206 grn_rc
grn_ts_expr_node_evaluate(grn_ctx * ctx,grn_ts_expr_node * node,const grn_ts_record * in,size_t n_in,void * out)5207 grn_ts_expr_node_evaluate(grn_ctx *ctx, grn_ts_expr_node *node,
5208 const grn_ts_record *in, size_t n_in, void *out)
5209 {
5210 switch (node->type) {
5211 GRN_TS_EXPR_NODE_EVALUATE_CASE(ID, id)
5212 GRN_TS_EXPR_NODE_EVALUATE_CASE(SCORE, score)
5213 GRN_TS_EXPR_NODE_EVALUATE_CASE(KEY, key)
5214 GRN_TS_EXPR_NODE_EVALUATE_CASE(VALUE, value)
5215 GRN_TS_EXPR_NODE_EVALUATE_CASE(CONST, const)
5216 GRN_TS_EXPR_NODE_EVALUATE_CASE(COLUMN, column)
5217 GRN_TS_EXPR_NODE_EVALUATE_CASE(OP, op)
5218 GRN_TS_EXPR_NODE_EVALUATE_CASE(BRIDGE, bridge)
5219 default: {
5220 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT,
5221 "invalid node type: %d", node->type);
5222 }
5223 }
5224 }
5225 #undef GRN_TS_EXPR_NODE_EVALUATE_CASE
5226
5227 #define GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE(KIND, kind)\
5228 case GRN_TS_ ## KIND: {\
5229 grn_rc rc = grn_ts_buf_reserve(ctx, out, sizeof(grn_ts_ ## kind) * n_in);\
5230 if (rc != GRN_SUCCESS) {\
5231 return rc;\
5232 }\
5233 return grn_ts_expr_node_evaluate(ctx, node, in, n_in, out->ptr);\
5234 }
5235 #define GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_VECTOR_CASE(KIND, kind)\
5236 GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE(KIND ## _VECTOR, kind ## _vector)
5237 grn_rc
grn_ts_expr_node_evaluate_to_buf(grn_ctx * ctx,grn_ts_expr_node * node,const grn_ts_record * in,size_t n_in,grn_ts_buf * out)5238 grn_ts_expr_node_evaluate_to_buf(grn_ctx *ctx, grn_ts_expr_node *node,
5239 const grn_ts_record *in, size_t n_in,
5240 grn_ts_buf *out)
5241 {
5242 switch (node->data_kind) {
5243 GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE(BOOL, bool)
5244 GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE(INT, int)
5245 GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE(FLOAT, float)
5246 GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE(TIME, time)
5247 GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE(TEXT, text)
5248 GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE(GEO, geo)
5249 GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE(REF, ref)
5250 GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_VECTOR_CASE(BOOL, bool)
5251 GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_VECTOR_CASE(INT, int)
5252 GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_VECTOR_CASE(FLOAT, float)
5253 GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_VECTOR_CASE(TIME, time)
5254 GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_VECTOR_CASE(TEXT, text)
5255 GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_VECTOR_CASE(GEO, geo)
5256 GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_VECTOR_CASE(REF, ref)
5257 default: {
5258 GRN_TS_ERR_RETURN(GRN_OBJECT_CORRUPT,
5259 "invalid data kind: %d", node->data_kind);
5260 }
5261 }
5262 }
5263 #undef GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_VECTOR_CASE
5264 #undef GRN_TS_EXPR_NODE_EVALUATE_TO_BUF_CASE
5265
5266 #define GRN_TS_EXPR_NODE_FILTER_CASE(TYPE, type)\
5267 case GRN_TS_EXPR_ ## TYPE ## _NODE: {\
5268 grn_ts_expr_ ## type ## _node *type ## _node;\
5269 type ## _node = (grn_ts_expr_ ## type ## _node *)node;\
5270 return grn_ts_expr_ ## type ## _node_filter(ctx, type ## _node,\
5271 in, n_in, out, n_out);\
5272 }
5273 grn_rc
grn_ts_expr_node_filter(grn_ctx * ctx,grn_ts_expr_node * node,grn_ts_record * in,size_t n_in,grn_ts_record * out,size_t * n_out)5274 grn_ts_expr_node_filter(grn_ctx *ctx, grn_ts_expr_node *node,
5275 grn_ts_record *in, size_t n_in,
5276 grn_ts_record *out, size_t *n_out)
5277 {
5278 if (node->data_kind != GRN_TS_BOOL) {
5279 GRN_TS_ERR_RETURN(GRN_OPERATION_NOT_SUPPORTED,
5280 "invalid data kind: %d", node->data_kind);
5281 }
5282 switch (node->type) {
5283 GRN_TS_EXPR_NODE_FILTER_CASE(KEY, key)
5284 GRN_TS_EXPR_NODE_FILTER_CASE(VALUE, value)
5285 GRN_TS_EXPR_NODE_FILTER_CASE(CONST, const)
5286 GRN_TS_EXPR_NODE_FILTER_CASE(COLUMN, column)
5287 GRN_TS_EXPR_NODE_FILTER_CASE(OP, op)
5288 GRN_TS_EXPR_NODE_FILTER_CASE(BRIDGE, bridge)
5289 default: {
5290 GRN_TS_ERR_RETURN(GRN_OPERATION_NOT_SUPPORTED,
5291 "invalid node type: %d", node->type);
5292 }
5293 }
5294 }
5295 #undef GRN_TS_EXPR_NODE_FILTER_CASE
5296
5297 #define GRN_TS_EXPR_NODE_ADJUST_CASE(TYPE, type)\
5298 case GRN_TS_EXPR_ ## TYPE ## _NODE: {\
5299 grn_ts_expr_ ## type ## _node *type ## _node;\
5300 type ## _node = (grn_ts_expr_ ## type ## _node *)node;\
5301 return grn_ts_expr_ ## type ## _node_adjust(ctx, type ## _node, io, n_io);\
5302 }
5303 grn_rc
grn_ts_expr_node_adjust(grn_ctx * ctx,grn_ts_expr_node * node,grn_ts_record * io,size_t n_io)5304 grn_ts_expr_node_adjust(grn_ctx *ctx, grn_ts_expr_node *node,
5305 grn_ts_record *io, size_t n_io)
5306 {
5307 if (node->data_kind != GRN_TS_FLOAT) {
5308 GRN_TS_ERR_RETURN(GRN_OPERATION_NOT_SUPPORTED,
5309 "invalid data kind: %d", node->data_kind);
5310 }
5311 switch (node->type) {
5312 GRN_TS_EXPR_NODE_ADJUST_CASE(SCORE, score)
5313 GRN_TS_EXPR_NODE_ADJUST_CASE(KEY, key)
5314 GRN_TS_EXPR_NODE_ADJUST_CASE(VALUE, value)
5315 GRN_TS_EXPR_NODE_ADJUST_CASE(CONST, const)
5316 GRN_TS_EXPR_NODE_ADJUST_CASE(COLUMN, column)
5317 GRN_TS_EXPR_NODE_ADJUST_CASE(OP, op)
5318 GRN_TS_EXPR_NODE_ADJUST_CASE(BRIDGE, bridge)
5319 default: {
5320 GRN_TS_ERR_RETURN(GRN_OPERATION_NOT_SUPPORTED,
5321 "invalid node type: %d", node->type);
5322 }
5323 }
5324 }
5325 #undef GRN_TS_EXPR_NODE_ADJUST_CASE
5326