Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
test-table-select.c
Go to the documentation of this file.
1 /* -*- c-basic-offset: 2; coding: utf-8 -*- */
2 /*
3  Copyright(C) 2009 Brazil
4  Copyright(C) 2011 Kouhei Sutou <kou@clear-code.com>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either
9  version 2.1 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 
21 #include "db.h"
22 #include <stdio.h>
23 
24 #include <gcutter.h>
25 
26 #include "../lib/grn-assertions.h"
27 
28 static gchar *tmp_directory;
29 static gchar *path;
30 static grn_ctx context;
31 static grn_obj *database;
32 static grn_obj *cond, *res, *expr;
33 static grn_obj text_buf, int_buf, ptr_buf;
34 
35 void test_equal(void);
36 void test_equal_indexed(void);
39 void test_select(void);
40 void test_search(void);
41 void test_select_search(void);
42 void test_match(void);
43 void test_match_equal(void);
44 void test_match_without_index(void);
45 
46 void
48 {
49  tmp_directory = g_build_filename(grn_test_get_tmp_dir(),
50  "test-table-select",
51  NULL);
52 }
53 
54 void
56 {
57  g_free(tmp_directory);
58 }
59 
60 void
61 cut_setup(void)
62 {
63  cut_remove_path(tmp_directory, NULL);
64  g_mkdir_with_parents(tmp_directory, 0700);
65  path = g_build_filename(tmp_directory, "text-table-select", NULL);
66  grn_ctx_init(&context, 0);
67  database = grn_db_create(&context, path, NULL);
68 
69  cond = NULL;
70  expr = NULL;
71  res = NULL;
72 
73  GRN_TEXT_INIT(&text_buf, 0);
74  GRN_UINT32_INIT(&int_buf, 0);
75  GRN_PTR_INIT(&ptr_buf, 0, GRN_ID_NIL);
76 }
77 
78 void
80 {
81  grn_obj_close(&context, &text_buf);
82  grn_obj_close(&context, &int_buf);
83  grn_obj_close(&context, &ptr_buf);
84 
85  if (res)
86  grn_obj_close(&context, res);
87  if (expr)
88  grn_obj_close(&context, expr);
89  if (cond)
90  grn_obj_close(&context, cond);
91 
92  grn_obj_close(&context, database);
93  grn_ctx_fin(&context);
94  cut_remove_path(tmp_directory, NULL);
95  g_free(path);
96 }
97 
98 static grn_obj *properties, *docs, *terms, *size, *body, *author, *index_body;
99 
100 static void
101 insert_document(const gchar *author_content, const gchar *body_content)
102 {
103  uint32_t s = (uint32_t)strlen(body_content);
104  grn_id docid = grn_table_add(&context, docs, NULL, 0, NULL);
105 
106  if (author_content) {
107  GRN_TEXT_SET(&context, &text_buf, author_content, strlen(author_content));
108  grn_test_assert(grn_obj_set_value(&context, author, docid, &text_buf,
109  GRN_OBJ_SET));
110  }
111 
112  GRN_TEXT_SET(&context, &text_buf, body_content, s);
113  grn_test_assert(grn_obj_set_value(&context, body, docid, &text_buf,
114  GRN_OBJ_SET));
115 
116  GRN_UINT32_SET(&context, &int_buf, s);
117  grn_test_assert(grn_obj_set_value(&context, size, docid, &int_buf,
118  GRN_OBJ_SET));
119 }
120 
121 #define INSERT_DOCUMENT(author, body) \
122  cut_trace(insert_document(author, body))
123 
124 static void
125 create_properties_table(void)
126 {
127  const gchar *table_name = "properties";
128  properties = grn_table_create(&context, table_name, strlen(table_name), NULL,
130  grn_ctx_at(&context, GRN_DB_SHORT_TEXT), NULL);
131  cut_assert_not_null(properties);
132 }
133 
134 static void
135 create_documents_table(void)
136 {
137  docs = grn_table_create(&context, "docs", 4, NULL,
139  cut_assert_not_null(docs);
140 
141  size = grn_column_create(&context, docs, "size", 4, NULL,
143  grn_ctx_at(&context, GRN_DB_UINT32));
144  cut_assert_not_null(size);
145 
146  body = grn_column_create(&context, docs, "body", 4, NULL,
148  grn_ctx_at(&context, GRN_DB_TEXT));
149  cut_assert_not_null(body);
150 
151  author = grn_column_create(&context, docs, "author", 6, NULL,
153  properties);
154  cut_assert_not_null(author);
155 }
156 
157 static void
158 create_terms_table(void)
159 {
160  terms = grn_table_create(&context, "terms", 5, NULL,
162  grn_ctx_at(&context, GRN_DB_SHORT_TEXT), NULL);
163  cut_assert_not_null(terms);
165  grn_ctx_at(&context, GRN_DB_BIGRAM)));
166 
167  index_body = grn_column_create(&context, terms, "docs_body", 4, NULL,
169  docs);
170  cut_assert_not_null(index_body);
171 
172  GRN_UINT32_SET(&context, &int_buf, grn_obj_id(&context, body));
173  grn_obj_set_info(&context, index_body, GRN_INFO_SOURCE, &int_buf);
174 }
175 
176 static void
177 insert_data(void)
178 {
179  INSERT_DOCUMENT("morita", "hoge");
180  INSERT_DOCUMENT("morita", "fuga fuga");
181  INSERT_DOCUMENT("gunyara-kun", "moge moge moge");
182  INSERT_DOCUMENT(NULL, "hoge hoge");
183  INSERT_DOCUMENT(NULL, "hoge fuga fuga");
184  INSERT_DOCUMENT("gunyara-kun", "hoge moge moge moge");
185  INSERT_DOCUMENT("yu", "moge hoge hoge");
186  INSERT_DOCUMENT(NULL, "moge hoge fuga fuga");
187  INSERT_DOCUMENT(NULL, "moge hoge moge moge moge");
188  INSERT_DOCUMENT("morita", "poyo moge hoge moge moge moge");
189 }
190 
191 static void
192 prepare_data(void)
193 {
194  create_properties_table();
195  create_documents_table();
196  create_terms_table();
197  insert_data();
198 }
199 
200 #define PARSE(expr, str, flags) \
201  grn_test_assert(grn_expr_parse(&context, (expr), (str), strlen(str), \
202  body, GRN_OP_MATCH, GRN_OP_AND, flags))
203 
204 void
206 {
207  grn_obj *v;
208 
209  prepare_data();
210 
211  cut_assert_not_null((cond = grn_expr_create(&context, NULL, 0)));
212  v = grn_expr_add_var(&context, cond, NULL, 0);
213  GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs));
214  grn_expr_append_obj(&context, cond, v, GRN_OP_PUSH, 1);
215  GRN_TEXT_SETS(&context, &text_buf, "body");
216  grn_expr_append_const(&context, cond, &text_buf, GRN_OP_PUSH, 1);
217  grn_expr_append_op(&context, cond, GRN_OP_GET_VALUE, 1);
218  GRN_TEXT_SETS(&context, &text_buf, "poyo moge hoge moge moge moge");
219  grn_expr_append_const(&context, cond, &text_buf, GRN_OP_PUSH, 1);
220  grn_expr_append_op(&context, cond, GRN_OP_EQUAL, 2);
221  grn_expr_compile(&context, cond);
222 
223  res = grn_table_create(&context, NULL, 0, NULL,
225  cut_assert_not_null(res);
226 
227  cut_assert_not_null(grn_table_select(&context, docs, cond, res, GRN_OP_OR));
228 
229  grn_test_assert_select(&context,
230  gcut_take_new_list_string("poyo moge hoge "
231  "moge moge moge",
232  NULL),
233  res,
234  "body");
235 }
236 
237 void
239 {
240  grn_obj *v;
241 
242  prepare_data();
243 
244  cut_assert_not_null((cond = grn_expr_create(&context, NULL, 0)));
245  v = grn_expr_add_var(&context, cond, NULL, 0);
246  GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs));
247  grn_expr_append_obj(&context, cond, v, GRN_OP_PUSH, 1);
248  GRN_TEXT_SETS(&context, &text_buf, "body");
249  grn_expr_append_const(&context, cond, &text_buf, GRN_OP_GET_VALUE, 1);
250  GRN_TEXT_SETS(&context, &text_buf, "hoge");
251  grn_expr_append_const(&context, cond, &text_buf, GRN_OP_PUSH, 1);
252  grn_expr_append_op(&context, cond, GRN_OP_EQUAL, 2);
253  grn_expr_compile(&context, cond);
254 
255  res = grn_table_create(&context, NULL, 0, NULL,
257  cut_assert_not_null(res);
258 
259  cut_assert_not_null(grn_table_select(&context, docs, cond, res, GRN_OP_OR));
260 
261  grn_test_assert_select(&context,
262  gcut_take_new_list_string("hoge", NULL),
263  res,
264  "body");
265 }
266 
267 void
269 {
270  grn_obj *v;
271 
272  prepare_data();
273 
274  GRN_EXPR_CREATE_FOR_QUERY(&context, docs, cond, v);
275  cut_assert_not_null(cond);
276  cut_assert_not_null(v);
277  PARSE(cond, "author == \"morita\"", GRN_EXPR_SYNTAX_SCRIPT);
278  res = grn_table_select(&context, docs, cond, NULL, GRN_OP_OR);
279  cut_assert_not_null(res);
280 
281  grn_test_assert_select(&context,
282  gcut_take_new_list_string(
283  "fuga fuga",
284  "hoge",
285  "poyo moge hoge moge moge moge",
286  NULL),
287  res,
288  "body");
289 }
290 
291 void
293 {
294  grn_obj *v;
295 
296  prepare_data();
297 
298  GRN_EXPR_CREATE_FOR_QUERY(&context, docs, cond, v);
299  cut_assert_not_null(cond);
300  cut_assert_not_null(v);
301  PARSE(cond, "author == \"nonexistent\"", GRN_EXPR_SYNTAX_SCRIPT);
302  res = grn_table_select(&context, docs, cond, NULL, GRN_OP_OR);
303  cut_assert_not_null(res);
304 
305  grn_test_assert_select(&context,
306  NULL,
307  res,
308  "body");
309 }
310 
311 void
312 test_select(void)
313 {
314  grn_obj *v;
315 
316  prepare_data();
317 
318  cut_assert_not_null((cond = grn_expr_create(&context, NULL, 0)));
319  v = grn_expr_add_var(&context, cond, NULL, 0);
320  GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs));
321  grn_expr_append_obj(&context, cond, v, GRN_OP_PUSH, 1);
322  GRN_TEXT_SETS(&context, &text_buf, "size");
323  grn_expr_append_const(&context, cond, &text_buf, GRN_OP_PUSH, 1);
324  grn_expr_append_op(&context, cond, GRN_OP_GET_VALUE, 2);
325  GRN_UINT32_SET(&context, &int_buf, 14);
326  grn_expr_append_const(&context, cond, &int_buf, GRN_OP_PUSH, 1);
327  grn_expr_append_op(&context, cond, GRN_OP_EQUAL, 2);
328  grn_expr_compile(&context, cond);
329 
330  res = grn_table_create(&context, NULL, 0, NULL,
332  cut_assert_not_null(res);
333 
334  cut_assert_not_null((expr = grn_expr_create(&context, NULL, 0)));
335  grn_expr_append_obj(&context, expr, docs, GRN_OP_PUSH, 1);
336  grn_expr_append_obj(&context, expr, cond, GRN_OP_PUSH, 1);
337  grn_expr_append_obj(&context, expr, res, GRN_OP_PUSH, 1);
338  GRN_UINT32_SET(&context, &int_buf, GRN_OP_OR);
339  grn_expr_append_const(&context, expr, &int_buf, GRN_OP_PUSH, 1);
340  grn_expr_append_op(&context, expr, GRN_OP_TABLE_SELECT, 4);
341 
342  grn_expr_exec(&context, expr, 0);
343 
344  grn_test_assert_select(&context,
345  gcut_take_new_list_string("moge moge moge",
346  "hoge fuga fuga",
347  "moge hoge hoge",
348  NULL),
349  res,
350  "body");
351 }
352 
353 void
355 {
356  grn_obj *v;
357 
358  prepare_data();
359 
360  cut_assert_not_null((cond = grn_expr_create(&context, NULL, 0)));
361  v = grn_expr_add_var(&context, cond, NULL, 0);
362  GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs));
363  grn_expr_append_obj(&context, cond, v, GRN_OP_PUSH, 1);
364  GRN_TEXT_SETS(&context, &text_buf, "size");
365  grn_expr_append_const(&context, cond, &text_buf, GRN_OP_PUSH, 1);
366  grn_expr_append_op(&context, cond, GRN_OP_GET_VALUE, 2);
367  GRN_UINT32_SET(&context, &int_buf, 14);
368  grn_expr_append_const(&context, cond, &int_buf, GRN_OP_PUSH, 1);
369  grn_expr_append_op(&context, cond, GRN_OP_EQUAL, 2);
370  grn_expr_compile(&context, cond);
371 
372  cut_assert_not_null((expr = grn_expr_create(&context, NULL, 0)));
373 
374  v = grn_expr_add_var(&context, expr, NULL, 0);
375 
376  grn_expr_append_obj(&context, expr, v, GRN_OP_PUSH, 1);
377 
378  GRN_BULK_REWIND(&text_buf);
379  grn_expr_append_const(&context, expr, &text_buf, GRN_OP_PUSH, 1);
381  grn_expr_append_const(&context, expr, &int_buf, GRN_OP_PUSH, 1);
382  grn_expr_append_obj(&context, expr, docs, GRN_OP_PUSH, 1);
383  GRN_PTR_SET(&context, &ptr_buf, NULL);
384  grn_expr_append_obj(&context, expr, &ptr_buf, GRN_OP_PUSH, 1);
385  grn_expr_append_op(&context, expr, GRN_OP_TABLE_CREATE, 4);
386 
387  grn_expr_append_op(&context, expr, GRN_OP_ASSIGN, 2);
388 
389  grn_expr_append_obj(&context, expr, index_body, GRN_OP_PUSH, 1);
390  GRN_TEXT_SETS(&context, &text_buf, "moge");
391  grn_expr_append_const(&context, expr, &text_buf, GRN_OP_PUSH, 1);
392  grn_expr_append_obj(&context, expr, v, GRN_OP_PUSH, 1);
393  GRN_UINT32_SET(&context, &int_buf, GRN_OP_OR);
394  grn_expr_append_const(&context, expr, &int_buf, GRN_OP_PUSH, 1);
395  grn_expr_append_op(&context, expr, GRN_OP_OBJ_SEARCH, 4);
396 
397  grn_expr_append_obj(&context, expr, docs, GRN_OP_PUSH, 1);
398  grn_expr_append_obj(&context, expr, cond, GRN_OP_PUSH, 1);
399  grn_expr_append_obj(&context, expr, v, GRN_OP_PUSH, 1);
400  GRN_UINT32_SET(&context, &int_buf, GRN_OP_AND);
401  grn_expr_append_const(&context, expr, &int_buf, GRN_OP_PUSH, 1);
402  grn_expr_append_op(&context, expr, GRN_OP_TABLE_SELECT, 4);
403 
404  grn_expr_append_obj(&context, expr, v, GRN_OP_PUSH, 1);
405  GRN_TEXT_SETS(&context, &text_buf, ".size ._score .body");
406  grn_expr_append_const(&context, expr, &text_buf, GRN_OP_PUSH, 1);
407  GRN_BULK_REWIND(&text_buf);
408  grn_expr_append_obj(&context, expr, &text_buf, GRN_OP_PUSH, 1);
409  grn_expr_append_op(&context, expr, GRN_OP_JSON_PUT, 3);
410 
411  grn_expr_exec(&context, expr, 0);
412 
413  cut_assert_equal_substring("[[2],[14,4,\"moge moge moge\"],[14,2,\"moge hoge hoge\"]]",
414  GRN_TEXT_VALUE(&text_buf), GRN_TEXT_LEN(&text_buf));
415 }
416 
417 void
419 {
420  grn_obj *v;
421 
422  prepare_data();
423 
424  cut_assert_not_null((cond = grn_expr_create(&context, NULL, 0)));
425  v = grn_expr_add_var(&context, cond, NULL, 0);
426  GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs));
427  grn_expr_append_obj(&context, cond, v, GRN_OP_PUSH, 1);
428  GRN_TEXT_SETS(&context, &text_buf, "size");
429  grn_expr_append_const(&context, cond, &text_buf, GRN_OP_PUSH, 1);
430  grn_expr_append_op(&context, cond, GRN_OP_GET_VALUE, 2);
431  GRN_UINT32_SET(&context, &int_buf, 14);
432  grn_expr_append_const(&context, cond, &int_buf, GRN_OP_PUSH, 1);
433  grn_expr_append_op(&context, cond, GRN_OP_EQUAL, 2);
434  grn_expr_compile(&context, cond);
435 
436  cut_assert_not_null((expr = grn_expr_create(&context, NULL, 0)));
437 
438  v = grn_expr_add_var(&context, expr, NULL, 0);
439 
440  grn_expr_append_obj(&context, expr, v, GRN_OP_PUSH, 1);
441 
442  GRN_BULK_REWIND(&text_buf);
443  grn_expr_append_const(&context, expr, &text_buf, GRN_OP_PUSH, 1);
445  grn_expr_append_const(&context, expr, &int_buf, GRN_OP_PUSH, 1);
446  grn_expr_append_obj(&context, expr, docs, GRN_OP_PUSH, 1);
447  GRN_PTR_SET(&context, &ptr_buf, NULL);
448  grn_expr_append_obj(&context, expr, &ptr_buf, GRN_OP_PUSH, 1);
449  grn_expr_append_op(&context, expr, GRN_OP_TABLE_CREATE, 4);
450 
451  grn_expr_append_op(&context, expr, GRN_OP_ASSIGN, 2);
452 
453  grn_expr_append_obj(&context, expr, docs, GRN_OP_PUSH, 1);
454  grn_expr_append_obj(&context, expr, cond, GRN_OP_PUSH, 1);
455  grn_expr_append_obj(&context, expr, v, GRN_OP_PUSH, 1);
456  GRN_UINT32_SET(&context, &int_buf, GRN_OP_OR);
457  grn_expr_append_const(&context, expr, &int_buf, GRN_OP_PUSH, 1);
458  grn_expr_append_op(&context, expr, GRN_OP_TABLE_SELECT, 4);
459 
460  grn_expr_append_obj(&context, expr, index_body, GRN_OP_PUSH, 1);
461  GRN_TEXT_SETS(&context, &text_buf, "moge");
462  grn_expr_append_const(&context, expr, &text_buf, GRN_OP_PUSH, 1);
463  grn_expr_append_obj(&context, expr, v, GRN_OP_PUSH, 1);
464  GRN_UINT32_SET(&context, &int_buf, GRN_OP_AND);
465  grn_expr_append_const(&context, expr, &int_buf, GRN_OP_PUSH, 1);
466  grn_expr_append_op(&context, expr, GRN_OP_OBJ_SEARCH, 4);
467 
468  grn_expr_append_obj(&context, expr, v, GRN_OP_PUSH, 1);
469  GRN_TEXT_SETS(&context, &text_buf, ".size ._score .body");
470  grn_expr_append_const(&context, expr, &text_buf, GRN_OP_PUSH, 1);
471  GRN_BULK_REWIND(&text_buf);
472  grn_expr_append_obj(&context, expr, &text_buf, GRN_OP_PUSH, 1);
473  grn_expr_append_op(&context, expr, GRN_OP_JSON_PUT, 3);
474 
475  grn_expr_exec(&context, expr, 0);
476 
477  cut_assert_equal_substring("[[2],[14,4,\"moge moge moge\"],[14,2,\"moge hoge hoge\"]]",
478  GRN_TEXT_VALUE(&text_buf), GRN_TEXT_LEN(&text_buf));
479 }
480 
481 void
483 {
484  grn_obj *v;
485 
486  prepare_data();
487 
488  cut_assert_not_null((cond = grn_expr_create(&context, NULL, 0)));
489  v = grn_expr_add_var(&context, cond, NULL, 0);
490  GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs));
491  grn_expr_append_obj(&context, cond, v, GRN_OP_PUSH, 1);
492  GRN_TEXT_SETS(&context, &text_buf, "body");
493  grn_expr_append_const(&context, cond, &text_buf, GRN_OP_PUSH, 1);
494  grn_expr_append_op(&context, cond, GRN_OP_GET_VALUE, 2);
495  GRN_TEXT_SETS(&context, &text_buf, "moge");
496  grn_expr_append_const(&context, cond, &text_buf, GRN_OP_PUSH, 1);
497  grn_expr_append_op(&context, cond, GRN_OP_MATCH, 2);
498  grn_expr_compile(&context, cond);
499 
500  res = grn_table_create(&context, NULL, 0, NULL,
502  cut_assert_not_null(res);
503 
504  cut_assert_not_null(grn_table_select(&context, docs, cond, res, GRN_OP_OR));
505 
506  grn_test_assert_select(&context,
507  gcut_take_new_list_string("moge moge moge",
508  "hoge moge moge moge",
509  "moge hoge hoge",
510  "moge hoge fuga fuga",
511  "moge hoge moge moge moge",
512  "poyo moge hoge "
513  "moge moge moge",
514  NULL),
515  res,
516  "body");
517 }
518 
519 void
521 {
522  grn_obj *v;
523 
524  prepare_data();
525 
526  cut_assert_not_null((cond = grn_expr_create(&context, NULL, 0)));
527  v = grn_expr_add_var(&context, cond, NULL, 0);
528  GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs));
529 
530  grn_expr_append_obj(&context, cond, v, GRN_OP_PUSH, 1);
531  GRN_TEXT_SETS(&context, &text_buf, "body");
532  grn_expr_append_const(&context, cond, &text_buf, GRN_OP_PUSH, 1);
533  grn_expr_append_op(&context, cond, GRN_OP_GET_VALUE, 2);
534  GRN_TEXT_SETS(&context, &text_buf, "moge");
535  grn_expr_append_const(&context, cond, &text_buf, GRN_OP_PUSH, 1);
536  grn_expr_append_op(&context, cond, GRN_OP_MATCH, 2);
537 
538  grn_expr_append_obj(&context, cond, v, GRN_OP_PUSH, 1);
539  GRN_TEXT_SETS(&context, &text_buf, "size");
540  grn_expr_append_const(&context, cond, &text_buf, GRN_OP_PUSH, 1);
541  grn_expr_append_op(&context, cond, GRN_OP_GET_VALUE, 2);
542  GRN_UINT32_SET(&context, &int_buf, 14);
543  grn_expr_append_const(&context, cond, &int_buf, GRN_OP_PUSH, 1);
544  grn_expr_append_op(&context, cond, GRN_OP_EQUAL, 2);
545 
546  grn_expr_append_op(&context, cond, GRN_OP_AND, 2);
547 
548  grn_expr_compile(&context, cond);
549 
550  res = grn_table_create(&context, NULL, 0, NULL,
552  cut_assert_not_null(res);
553 
554  cut_assert_not_null(grn_table_select(&context, docs, cond, res, GRN_OP_OR));
555 
556  grn_test_assert_select(&context,
557  gcut_take_new_list_string("moge moge moge",
558  "moge hoge hoge",
559  NULL),
560  res,
561  "body");
562 }
563 
564 void
566 {
567  grn_obj *v;
568 
569  create_properties_table();
570  create_documents_table();
571  insert_data();
572 
573  cut_assert_not_null((cond = grn_expr_create(&context, NULL, 0)));
574  v = grn_expr_add_var(&context, cond, NULL, 0);
575  GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs));
576 
577  grn_expr_append_obj(&context, cond, v, GRN_OP_PUSH, 1);
578  GRN_TEXT_SETS(&context, &text_buf, "body");
579  grn_expr_append_const(&context, cond, &text_buf, GRN_OP_PUSH, 1);
580  grn_expr_append_op(&context, cond, GRN_OP_GET_VALUE, 1);
581  GRN_TEXT_SETS(&context, &text_buf, "moge");
582  grn_expr_append_const(&context, cond, &text_buf, GRN_OP_PUSH, 1);
583  grn_expr_append_op(&context, cond, GRN_OP_MATCH, 2);
584 
585  grn_expr_compile(&context, cond);
586 
587  res = grn_table_create(&context, NULL, 0, NULL,
589  cut_assert_not_null(res);
590 
591  cut_assert_not_null(grn_table_select(&context, docs, cond, res, GRN_OP_OR));
592 
594  &context,
595  gcut_take_new_list_string("moge moge moge",
596  "hoge moge moge moge",
597  "moge hoge hoge",
598  "moge hoge fuga fuga",
599  "moge hoge moge moge moge",
600  "poyo moge hoge moge moge moge",
601  NULL),
602  res,
603  "body");
604 }