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