1 | /* -*- c-basic-offset: 2 -*- */ |
2 | /* |
3 | Copyright(C) 2014-2017 Brazil |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License version 2.1 as published by the Free Software Foundation. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Lesser General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Lesser General Public |
15 | License along with this library; if not, write to the Free Software |
16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ |
18 | |
19 | #include "grn.h" |
20 | #include "grn_db.h" |
21 | #include "grn_str.h" |
22 | #include "grn_normalizer.h" |
23 | |
24 | #include <string.h> |
25 | |
26 | #ifdef GRN_WITH_ONIGMO |
27 | # define GRN_SUPPORT_REGEXP |
28 | #endif |
29 | |
30 | #ifdef GRN_SUPPORT_REGEXP |
31 | # include <onigmo.h> |
32 | #endif |
33 | |
34 | static const char *operator_names[] = { |
35 | "push" , |
36 | "pop" , |
37 | "nop" , |
38 | "call" , |
39 | "intern" , |
40 | "get_ref" , |
41 | "get_value" , |
42 | "and" , |
43 | "and_not" , |
44 | "or" , |
45 | "assign" , |
46 | "star_assign" , |
47 | "slash_assign" , |
48 | "mod_assign" , |
49 | "plus_assign" , |
50 | "minus_assign" , |
51 | "shiftl_assign" , |
52 | "shiftr_assign" , |
53 | "shiftrr_assign" , |
54 | "and_assign" , |
55 | "xor_assign" , |
56 | "or_assign" , |
57 | "jump" , |
58 | "cjump" , |
59 | "comma" , |
60 | "bitwise_or" , |
61 | "bitwise_xor" , |
62 | "bitwise_and" , |
63 | "bitwise_not" , |
64 | "equal" , |
65 | "not_equal" , |
66 | "less" , |
67 | "greater" , |
68 | "less_equal" , |
69 | "greater_equal" , |
70 | "in" , |
71 | "match" , |
72 | "near" , |
73 | "near2" , |
74 | "similar" , |
75 | "term_extract" , |
76 | "shiftl" , |
77 | "shiftr" , |
78 | "shiftrr" , |
79 | "plus" , |
80 | "minus" , |
81 | "star" , |
82 | "slash" , |
83 | "mod" , |
84 | "delete" , |
85 | "incr" , |
86 | "decr" , |
87 | "incr_post" , |
88 | "decr_post" , |
89 | "not" , |
90 | "adjust" , |
91 | "exact" , |
92 | "lcp" , |
93 | "partial" , |
94 | "unsplit" , |
95 | "prefix" , |
96 | "suffix" , |
97 | "geo_distance1" , |
98 | "geo_distance2" , |
99 | "geo_distance3" , |
100 | "geo_distance4" , |
101 | "geo_withinp5" , |
102 | "geo_withinp6" , |
103 | "geo_withinp8" , |
104 | "obj_search" , |
105 | "expr_get_var" , |
106 | "table_create" , |
107 | "table_select" , |
108 | "table_sort" , |
109 | "table_group" , |
110 | "json_put" , |
111 | "get_member" , |
112 | "regexp" , |
113 | "fuzzy" |
114 | }; |
115 | |
116 | #define GRN_OP_LAST GRN_OP_FUZZY |
117 | |
118 | const char * |
119 | grn_operator_to_string(grn_operator op) |
120 | { |
121 | if (op <= GRN_OP_LAST) { |
122 | return operator_names[op]; |
123 | } else { |
124 | return "unknown" ; |
125 | } |
126 | } |
127 | |
128 | grn_operator_exec_func * |
129 | grn_operator_to_exec_func(grn_operator op) |
130 | { |
131 | grn_operator_exec_func *func = NULL; |
132 | |
133 | switch (op) { |
134 | case GRN_OP_EQUAL : |
135 | func = grn_operator_exec_equal; |
136 | break; |
137 | case GRN_OP_NOT_EQUAL : |
138 | func = grn_operator_exec_not_equal; |
139 | break; |
140 | case GRN_OP_LESS : |
141 | func = grn_operator_exec_less; |
142 | break; |
143 | case GRN_OP_GREATER : |
144 | func = grn_operator_exec_greater; |
145 | break; |
146 | case GRN_OP_LESS_EQUAL : |
147 | func = grn_operator_exec_less_equal; |
148 | break; |
149 | case GRN_OP_GREATER_EQUAL : |
150 | func = grn_operator_exec_greater_equal; |
151 | break; |
152 | case GRN_OP_MATCH : |
153 | func = grn_operator_exec_match; |
154 | break; |
155 | case GRN_OP_PREFIX : |
156 | func = grn_operator_exec_prefix; |
157 | break; |
158 | case GRN_OP_REGEXP : |
159 | func = grn_operator_exec_regexp; |
160 | break; |
161 | default : |
162 | break; |
163 | } |
164 | |
165 | return func; |
166 | } |
167 | |
168 | #define DO_EQ_SUB do {\ |
169 | switch (y->header.domain) {\ |
170 | case GRN_DB_INT8 :\ |
171 | r = (x_ == GRN_INT8_VALUE(y));\ |
172 | break;\ |
173 | case GRN_DB_UINT8 :\ |
174 | r = (x_ == GRN_UINT8_VALUE(y));\ |
175 | break;\ |
176 | case GRN_DB_INT16 :\ |
177 | r = (x_ == GRN_INT16_VALUE(y));\ |
178 | break;\ |
179 | case GRN_DB_UINT16 :\ |
180 | r = (x_ == GRN_UINT16_VALUE(y));\ |
181 | break;\ |
182 | case GRN_DB_INT32 :\ |
183 | r = (x_ == GRN_INT32_VALUE(y));\ |
184 | break;\ |
185 | case GRN_DB_UINT32 :\ |
186 | r = (x_ == GRN_UINT32_VALUE(y));\ |
187 | break;\ |
188 | case GRN_DB_INT64 :\ |
189 | r = (x_ == GRN_INT64_VALUE(y));\ |
190 | break;\ |
191 | case GRN_DB_TIME :\ |
192 | r = (GRN_TIME_PACK(x_,0) == GRN_INT64_VALUE(y));\ |
193 | break;\ |
194 | case GRN_DB_UINT64 :\ |
195 | r = (x_ == GRN_UINT64_VALUE(y));\ |
196 | break;\ |
197 | case GRN_DB_FLOAT :\ |
198 | r = ((x_ <= GRN_FLOAT_VALUE(y)) && (x_ >= GRN_FLOAT_VALUE(y)));\ |
199 | break;\ |
200 | case GRN_DB_SHORT_TEXT :\ |
201 | case GRN_DB_TEXT :\ |
202 | case GRN_DB_LONG_TEXT :\ |
203 | {\ |
204 | const char *p_ = GRN_TEXT_VALUE(y);\ |
205 | int i_ = grn_atoi(p_, p_ + GRN_TEXT_LEN(y), NULL);\ |
206 | r = (x_ == i_);\ |
207 | }\ |
208 | break;\ |
209 | default :\ |
210 | r = GRN_FALSE;\ |
211 | break;\ |
212 | }\ |
213 | } while (0) |
214 | |
215 | #define DO_EQ(x,y,r) do {\ |
216 | switch (x->header.domain) {\ |
217 | case GRN_DB_VOID :\ |
218 | r = GRN_FALSE;\ |
219 | break;\ |
220 | case GRN_DB_INT8 :\ |
221 | {\ |
222 | int8_t x_ = GRN_INT8_VALUE(x);\ |
223 | DO_EQ_SUB;\ |
224 | }\ |
225 | break;\ |
226 | case GRN_DB_UINT8 :\ |
227 | {\ |
228 | uint8_t x_ = GRN_UINT8_VALUE(x);\ |
229 | DO_EQ_SUB;\ |
230 | }\ |
231 | break;\ |
232 | case GRN_DB_INT16 :\ |
233 | {\ |
234 | int16_t x_ = GRN_INT16_VALUE(x);\ |
235 | DO_EQ_SUB;\ |
236 | }\ |
237 | break;\ |
238 | case GRN_DB_UINT16 :\ |
239 | {\ |
240 | uint16_t x_ = GRN_UINT16_VALUE(x);\ |
241 | DO_EQ_SUB;\ |
242 | }\ |
243 | break;\ |
244 | case GRN_DB_INT32 :\ |
245 | {\ |
246 | int32_t x_ = GRN_INT32_VALUE(x);\ |
247 | DO_EQ_SUB;\ |
248 | }\ |
249 | break;\ |
250 | case GRN_DB_UINT32 :\ |
251 | {\ |
252 | uint32_t x_ = GRN_UINT32_VALUE(x);\ |
253 | DO_EQ_SUB;\ |
254 | }\ |
255 | break;\ |
256 | case GRN_DB_INT64 :\ |
257 | {\ |
258 | int64_t x_ = GRN_INT64_VALUE(x);\ |
259 | DO_EQ_SUB;\ |
260 | }\ |
261 | break;\ |
262 | case GRN_DB_TIME :\ |
263 | {\ |
264 | int64_t x_ = GRN_INT64_VALUE(x);\ |
265 | switch (y->header.domain) {\ |
266 | case GRN_DB_INT32 :\ |
267 | r = (x_ == GRN_TIME_PACK(GRN_INT32_VALUE(y), 0));\ |
268 | break;\ |
269 | case GRN_DB_UINT32 :\ |
270 | r = (x_ == GRN_TIME_PACK(GRN_UINT32_VALUE(y), 0));\ |
271 | break;\ |
272 | case GRN_DB_INT64 :\ |
273 | case GRN_DB_TIME :\ |
274 | r = (x_ == GRN_INT64_VALUE(y));\ |
275 | break;\ |
276 | case GRN_DB_UINT64 :\ |
277 | r = (x_ == GRN_UINT64_VALUE(y));\ |
278 | break;\ |
279 | case GRN_DB_FLOAT :\ |
280 | r = (x_ == GRN_TIME_PACK(GRN_FLOAT_VALUE(y), 0));\ |
281 | break;\ |
282 | case GRN_DB_SHORT_TEXT :\ |
283 | case GRN_DB_TEXT :\ |
284 | case GRN_DB_LONG_TEXT :\ |
285 | {\ |
286 | grn_obj time_value_;\ |
287 | GRN_TIME_INIT(&time_value_, 0);\ |
288 | if (grn_obj_cast(ctx, y, &time_value_, GRN_FALSE) == GRN_SUCCESS) {\ |
289 | r = (x_ == GRN_TIME_VALUE(&time_value_));\ |
290 | } else {\ |
291 | r = GRN_FALSE;\ |
292 | }\ |
293 | GRN_OBJ_FIN(ctx, &time_value_);\ |
294 | }\ |
295 | break;\ |
296 | default :\ |
297 | r = GRN_FALSE;\ |
298 | break;\ |
299 | }\ |
300 | }\ |
301 | break;\ |
302 | case GRN_DB_UINT64 :\ |
303 | {\ |
304 | uint64_t x_ = GRN_UINT64_VALUE(x);\ |
305 | DO_EQ_SUB;\ |
306 | }\ |
307 | break;\ |
308 | case GRN_DB_FLOAT :\ |
309 | {\ |
310 | double x_ = GRN_FLOAT_VALUE(x);\ |
311 | switch (y->header.domain) {\ |
312 | case GRN_DB_INT32 :\ |
313 | r = ((x_ <= GRN_INT32_VALUE(y)) && (x_ >= GRN_INT32_VALUE(y)));\ |
314 | break;\ |
315 | case GRN_DB_UINT32 :\ |
316 | r = ((x_ <= GRN_UINT32_VALUE(y)) && (x_ >= GRN_UINT32_VALUE(y)));\ |
317 | break;\ |
318 | case GRN_DB_INT64 :\ |
319 | case GRN_DB_TIME :\ |
320 | r = ((x_ <= GRN_INT64_VALUE(y)) && (x_ >= GRN_INT64_VALUE(y)));\ |
321 | break;\ |
322 | case GRN_DB_UINT64 :\ |
323 | r = ((x_ <= GRN_UINT64_VALUE(y)) && (x_ >= GRN_UINT64_VALUE(y)));\ |
324 | break;\ |
325 | case GRN_DB_FLOAT :\ |
326 | r = ((x_ <= GRN_FLOAT_VALUE(y)) && (x_ >= GRN_FLOAT_VALUE(y)));\ |
327 | break;\ |
328 | case GRN_DB_SHORT_TEXT :\ |
329 | case GRN_DB_TEXT :\ |
330 | case GRN_DB_LONG_TEXT :\ |
331 | {\ |
332 | const char *p_ = GRN_TEXT_VALUE(y);\ |
333 | int i_ = grn_atoi(p_, p_ + GRN_TEXT_LEN(y), NULL);\ |
334 | r = (x_ <= i_ && x_ >= i_);\ |
335 | }\ |
336 | break;\ |
337 | default :\ |
338 | r = GRN_FALSE;\ |
339 | break;\ |
340 | }\ |
341 | }\ |
342 | break;\ |
343 | case GRN_DB_SHORT_TEXT :\ |
344 | case GRN_DB_TEXT :\ |
345 | case GRN_DB_LONG_TEXT :\ |
346 | if (GRN_DB_SHORT_TEXT <= y->header.domain && y->header.domain <= GRN_DB_LONG_TEXT) {\ |
347 | uint32_t la = GRN_TEXT_LEN(x), lb = GRN_TEXT_LEN(y);\ |
348 | r = (la == lb && !memcmp(GRN_TEXT_VALUE(x), GRN_TEXT_VALUE(y), lb));\ |
349 | } else {\ |
350 | const char *q_ = GRN_TEXT_VALUE(x);\ |
351 | int x_ = grn_atoi(q_, q_ + GRN_TEXT_LEN(x), NULL);\ |
352 | DO_EQ_SUB;\ |
353 | }\ |
354 | break;\ |
355 | default :\ |
356 | if ((x->header.domain == y->header.domain)) {\ |
357 | r = (GRN_BULK_VSIZE(x) == GRN_BULK_VSIZE(y) &&\ |
358 | !(memcmp(GRN_BULK_HEAD(x), GRN_BULK_HEAD(y), GRN_BULK_VSIZE(x))));\ |
359 | } else {\ |
360 | grn_obj dest;\ |
361 | if (x->header.domain < y->header.domain) {\ |
362 | GRN_OBJ_INIT(&dest, GRN_BULK, 0, y->header.domain);\ |
363 | if (!grn_obj_cast(ctx, x, &dest, GRN_FALSE)) {\ |
364 | r = (GRN_BULK_VSIZE(&dest) == GRN_BULK_VSIZE(y) &&\ |
365 | !memcmp(GRN_BULK_HEAD(&dest), GRN_BULK_HEAD(y), GRN_BULK_VSIZE(y))); \ |
366 | } else {\ |
367 | r = GRN_FALSE;\ |
368 | }\ |
369 | } else {\ |
370 | GRN_OBJ_INIT(&dest, GRN_BULK, 0, x->header.domain);\ |
371 | if (!grn_obj_cast(ctx, y, &dest, GRN_FALSE)) {\ |
372 | r = (GRN_BULK_VSIZE(&dest) == GRN_BULK_VSIZE(x) &&\ |
373 | !memcmp(GRN_BULK_HEAD(&dest), GRN_BULK_HEAD(x), GRN_BULK_VSIZE(x))); \ |
374 | } else {\ |
375 | r = GRN_FALSE;\ |
376 | }\ |
377 | }\ |
378 | GRN_OBJ_FIN(ctx, &dest);\ |
379 | }\ |
380 | break;\ |
381 | }\ |
382 | } while (0) |
383 | |
384 | grn_bool |
385 | grn_operator_exec_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y) |
386 | { |
387 | grn_bool r = GRN_FALSE; |
388 | GRN_API_ENTER; |
389 | DO_EQ(x, y, r); |
390 | GRN_API_RETURN(r); |
391 | } |
392 | |
393 | grn_bool |
394 | grn_operator_exec_not_equal(grn_ctx *ctx, grn_obj *x, grn_obj *y) |
395 | { |
396 | grn_bool r = GRN_FALSE; |
397 | GRN_API_ENTER; |
398 | DO_EQ(x, y, r); |
399 | GRN_API_RETURN(!r); |
400 | } |
401 | |
402 | #define DO_COMPARE_SCALAR_SUB_NUMERIC(y,op) do {\ |
403 | switch ((y)->header.domain) {\ |
404 | case GRN_DB_BOOL :\ |
405 | r = (x_ op (uint8_t)(GRN_BOOL_VALUE(y) ? 1 : 0));\ |
406 | break;\ |
407 | case GRN_DB_INT8 :\ |
408 | r = (x_ op GRN_INT8_VALUE(y));\ |
409 | break;\ |
410 | case GRN_DB_UINT8 :\ |
411 | r = (x_ op GRN_UINT8_VALUE(y));\ |
412 | break;\ |
413 | case GRN_DB_INT16 :\ |
414 | r = (x_ op GRN_INT16_VALUE(y));\ |
415 | break;\ |
416 | case GRN_DB_UINT16 :\ |
417 | r = (x_ op GRN_UINT16_VALUE(y));\ |
418 | break;\ |
419 | case GRN_DB_INT32 :\ |
420 | r = (x_ op GRN_INT32_VALUE(y));\ |
421 | break;\ |
422 | case GRN_DB_UINT32 :\ |
423 | r = (x_ op GRN_UINT32_VALUE(y));\ |
424 | break;\ |
425 | case GRN_DB_INT64 :\ |
426 | r = (x_ op GRN_INT64_VALUE(y));\ |
427 | break;\ |
428 | case GRN_DB_TIME :\ |
429 | r = (GRN_TIME_PACK(x_,0) op GRN_INT64_VALUE(y));\ |
430 | break;\ |
431 | case GRN_DB_UINT64 :\ |
432 | r = (x_ op GRN_UINT64_VALUE(y));\ |
433 | break;\ |
434 | case GRN_DB_FLOAT :\ |
435 | r = (x_ op GRN_FLOAT_VALUE(y));\ |
436 | break;\ |
437 | default :\ |
438 | r = GRN_FALSE;\ |
439 | break;\ |
440 | }\ |
441 | } while (0) |
442 | |
443 | #define DO_COMPARE_SCALAR_SUB_BUILTIN(op) do {\ |
444 | switch (y->header.domain) {\ |
445 | case GRN_DB_SHORT_TEXT :\ |
446 | case GRN_DB_TEXT :\ |
447 | case GRN_DB_LONG_TEXT :\ |
448 | {\ |
449 | grn_obj |
---|