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