isomorfeus-ferret 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (222) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +612 -0
  3. data/README.md +44 -0
  4. data/ext/isomorfeus_ferret_ext/benchmark.c +223 -0
  5. data/ext/isomorfeus_ferret_ext/benchmark.h +45 -0
  6. data/ext/isomorfeus_ferret_ext/benchmarks_all.h +25 -0
  7. data/ext/isomorfeus_ferret_ext/bm_bitvector.c +123 -0
  8. data/ext/isomorfeus_ferret_ext/bm_hash.c +118 -0
  9. data/ext/isomorfeus_ferret_ext/bm_micro_string.c +40 -0
  10. data/ext/isomorfeus_ferret_ext/bm_store.c +93 -0
  11. data/ext/isomorfeus_ferret_ext/email.rl +21 -0
  12. data/ext/isomorfeus_ferret_ext/extconf.rb +5 -0
  13. data/ext/isomorfeus_ferret_ext/fio_tmpfile.h +53 -0
  14. data/ext/isomorfeus_ferret_ext/frb_analysis.c +2577 -0
  15. data/ext/isomorfeus_ferret_ext/frb_index.c +3457 -0
  16. data/ext/isomorfeus_ferret_ext/frb_lang.c +9 -0
  17. data/ext/isomorfeus_ferret_ext/frb_lang.h +17 -0
  18. data/ext/isomorfeus_ferret_ext/frb_qparser.c +629 -0
  19. data/ext/isomorfeus_ferret_ext/frb_search.c +4460 -0
  20. data/ext/isomorfeus_ferret_ext/frb_store.c +515 -0
  21. data/ext/isomorfeus_ferret_ext/frb_threading.h +30 -0
  22. data/ext/isomorfeus_ferret_ext/frb_utils.c +1127 -0
  23. data/ext/isomorfeus_ferret_ext/frt_analysis.c +1644 -0
  24. data/ext/isomorfeus_ferret_ext/frt_analysis.h +247 -0
  25. data/ext/isomorfeus_ferret_ext/frt_array.c +124 -0
  26. data/ext/isomorfeus_ferret_ext/frt_array.h +54 -0
  27. data/ext/isomorfeus_ferret_ext/frt_bitvector.c +95 -0
  28. data/ext/isomorfeus_ferret_ext/frt_bitvector.h +586 -0
  29. data/ext/isomorfeus_ferret_ext/frt_compound_io.c +374 -0
  30. data/ext/isomorfeus_ferret_ext/frt_config.h +44 -0
  31. data/ext/isomorfeus_ferret_ext/frt_document.c +134 -0
  32. data/ext/isomorfeus_ferret_ext/frt_document.h +52 -0
  33. data/ext/isomorfeus_ferret_ext/frt_except.c +95 -0
  34. data/ext/isomorfeus_ferret_ext/frt_except.h +188 -0
  35. data/ext/isomorfeus_ferret_ext/frt_field_index.c +233 -0
  36. data/ext/isomorfeus_ferret_ext/frt_field_index.h +42 -0
  37. data/ext/isomorfeus_ferret_ext/frt_filter.c +157 -0
  38. data/ext/isomorfeus_ferret_ext/frt_fs_store.c +502 -0
  39. data/ext/isomorfeus_ferret_ext/frt_global.c +427 -0
  40. data/ext/isomorfeus_ferret_ext/frt_global.h +290 -0
  41. data/ext/isomorfeus_ferret_ext/frt_hash.c +518 -0
  42. data/ext/isomorfeus_ferret_ext/frt_hash.h +466 -0
  43. data/ext/isomorfeus_ferret_ext/frt_hashset.c +191 -0
  44. data/ext/isomorfeus_ferret_ext/frt_hashset.h +206 -0
  45. data/ext/isomorfeus_ferret_ext/frt_helper.c +62 -0
  46. data/ext/isomorfeus_ferret_ext/frt_helper.h +13 -0
  47. data/ext/isomorfeus_ferret_ext/frt_ind.c +353 -0
  48. data/ext/isomorfeus_ferret_ext/frt_ind.h +54 -0
  49. data/ext/isomorfeus_ferret_ext/frt_index.c +6377 -0
  50. data/ext/isomorfeus_ferret_ext/frt_index.h +880 -0
  51. data/ext/isomorfeus_ferret_ext/frt_lang.c +104 -0
  52. data/ext/isomorfeus_ferret_ext/frt_lang.h +44 -0
  53. data/ext/isomorfeus_ferret_ext/frt_mempool.c +87 -0
  54. data/ext/isomorfeus_ferret_ext/frt_mempool.h +33 -0
  55. data/ext/isomorfeus_ferret_ext/frt_multimapper.c +349 -0
  56. data/ext/isomorfeus_ferret_ext/frt_multimapper.h +52 -0
  57. data/ext/isomorfeus_ferret_ext/frt_posh.c +1006 -0
  58. data/ext/isomorfeus_ferret_ext/frt_posh.h +973 -0
  59. data/ext/isomorfeus_ferret_ext/frt_priorityqueue.c +147 -0
  60. data/ext/isomorfeus_ferret_ext/frt_priorityqueue.h +147 -0
  61. data/ext/isomorfeus_ferret_ext/frt_q_boolean.c +1612 -0
  62. data/ext/isomorfeus_ferret_ext/frt_q_const_score.c +157 -0
  63. data/ext/isomorfeus_ferret_ext/frt_q_filtered_query.c +209 -0
  64. data/ext/isomorfeus_ferret_ext/frt_q_fuzzy.c +281 -0
  65. data/ext/isomorfeus_ferret_ext/frt_q_match_all.c +147 -0
  66. data/ext/isomorfeus_ferret_ext/frt_q_multi_term.c +672 -0
  67. data/ext/isomorfeus_ferret_ext/frt_q_parser.c +3084 -0
  68. data/ext/isomorfeus_ferret_ext/frt_q_phrase.c +1182 -0
  69. data/ext/isomorfeus_ferret_ext/frt_q_prefix.c +98 -0
  70. data/ext/isomorfeus_ferret_ext/frt_q_range.c +665 -0
  71. data/ext/isomorfeus_ferret_ext/frt_q_span.c +2386 -0
  72. data/ext/isomorfeus_ferret_ext/frt_q_term.c +311 -0
  73. data/ext/isomorfeus_ferret_ext/frt_q_wildcard.c +166 -0
  74. data/ext/isomorfeus_ferret_ext/frt_ram_store.c +460 -0
  75. data/ext/isomorfeus_ferret_ext/frt_scanner.c +899 -0
  76. data/ext/isomorfeus_ferret_ext/frt_scanner.h +28 -0
  77. data/ext/isomorfeus_ferret_ext/frt_scanner_mb.c +6705 -0
  78. data/ext/isomorfeus_ferret_ext/frt_scanner_utf8.c +4419 -0
  79. data/ext/isomorfeus_ferret_ext/frt_search.c +1824 -0
  80. data/ext/isomorfeus_ferret_ext/frt_search.h +924 -0
  81. data/ext/isomorfeus_ferret_ext/frt_similarity.c +150 -0
  82. data/ext/isomorfeus_ferret_ext/frt_similarity.h +79 -0
  83. data/ext/isomorfeus_ferret_ext/frt_sort.c +796 -0
  84. data/ext/isomorfeus_ferret_ext/frt_stopwords.c +395 -0
  85. data/ext/isomorfeus_ferret_ext/frt_store.c +680 -0
  86. data/ext/isomorfeus_ferret_ext/frt_store.h +789 -0
  87. data/ext/isomorfeus_ferret_ext/frt_term_vectors.c +72 -0
  88. data/ext/isomorfeus_ferret_ext/frt_threading.h +23 -0
  89. data/ext/isomorfeus_ferret_ext/frt_win32.h +54 -0
  90. data/ext/isomorfeus_ferret_ext/isomorfeus_ferret.c +409 -0
  91. data/ext/isomorfeus_ferret_ext/isomorfeus_ferret.h +95 -0
  92. data/ext/isomorfeus_ferret_ext/libstemmer.c +93 -0
  93. data/ext/isomorfeus_ferret_ext/libstemmer.h +73 -0
  94. data/ext/isomorfeus_ferret_ext/q_parser.y +1366 -0
  95. data/ext/isomorfeus_ferret_ext/scanner.h +28 -0
  96. data/ext/isomorfeus_ferret_ext/scanner.in +43 -0
  97. data/ext/isomorfeus_ferret_ext/scanner.rl +84 -0
  98. data/ext/isomorfeus_ferret_ext/scanner_mb.rl +200 -0
  99. data/ext/isomorfeus_ferret_ext/scanner_utf8.rl +85 -0
  100. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_danish.c +324 -0
  101. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_danish.h +7 -0
  102. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_dutch.c +610 -0
  103. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_dutch.h +6 -0
  104. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_english.c +1104 -0
  105. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_english.h +6 -0
  106. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_finnish.c +749 -0
  107. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_finnish.h +7 -0
  108. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_french.c +1233 -0
  109. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_french.h +6 -0
  110. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_german.c +490 -0
  111. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_german.h +6 -0
  112. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_hungarian.c +1217 -0
  113. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_hungarian.h +7 -0
  114. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_italian.c +1052 -0
  115. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_italian.h +6 -0
  116. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_norwegian.c +283 -0
  117. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_norwegian.h +6 -0
  118. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_porter.c +735 -0
  119. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_porter.h +6 -0
  120. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_portuguese.c +1003 -0
  121. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_portuguese.h +7 -0
  122. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_spanish.c +1079 -0
  123. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_spanish.h +6 -0
  124. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_swedish.c +293 -0
  125. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_swedish.h +6 -0
  126. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_2_romanian.c +984 -0
  127. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_2_romanian.h +6 -0
  128. data/ext/isomorfeus_ferret_ext/stem_KOI8_R_russian.c +686 -0
  129. data/ext/isomorfeus_ferret_ext/stem_KOI8_R_russian.h +6 -0
  130. data/ext/isomorfeus_ferret_ext/stem_UTF_8_danish.c +325 -0
  131. data/ext/isomorfeus_ferret_ext/stem_UTF_8_danish.h +6 -0
  132. data/ext/isomorfeus_ferret_ext/stem_UTF_8_dutch.c +620 -0
  133. data/ext/isomorfeus_ferret_ext/stem_UTF_8_dutch.h +6 -0
  134. data/ext/isomorfeus_ferret_ext/stem_UTF_8_english.c +1111 -0
  135. data/ext/isomorfeus_ferret_ext/stem_UTF_8_english.h +6 -0
  136. data/ext/isomorfeus_ferret_ext/stem_UTF_8_finnish.c +754 -0
  137. data/ext/isomorfeus_ferret_ext/stem_UTF_8_finnish.h +6 -0
  138. data/ext/isomorfeus_ferret_ext/stem_UTF_8_french.c +1242 -0
  139. data/ext/isomorfeus_ferret_ext/stem_UTF_8_french.h +6 -0
  140. data/ext/isomorfeus_ferret_ext/stem_UTF_8_german.c +495 -0
  141. data/ext/isomorfeus_ferret_ext/stem_UTF_8_german.h +6 -0
  142. data/ext/isomorfeus_ferret_ext/stem_UTF_8_hungarian.c +1220 -0
  143. data/ext/isomorfeus_ferret_ext/stem_UTF_8_hungarian.h +6 -0
  144. data/ext/isomorfeus_ferret_ext/stem_UTF_8_italian.c +1059 -0
  145. data/ext/isomorfeus_ferret_ext/stem_UTF_8_italian.h +6 -0
  146. data/ext/isomorfeus_ferret_ext/stem_UTF_8_norwegian.c +285 -0
  147. data/ext/isomorfeus_ferret_ext/stem_UTF_8_norwegian.h +6 -0
  148. data/ext/isomorfeus_ferret_ext/stem_UTF_8_porter.c +741 -0
  149. data/ext/isomorfeus_ferret_ext/stem_UTF_8_porter.h +6 -0
  150. data/ext/isomorfeus_ferret_ext/stem_UTF_8_portuguese.c +1009 -0
  151. data/ext/isomorfeus_ferret_ext/stem_UTF_8_portuguese.h +6 -0
  152. data/ext/isomorfeus_ferret_ext/stem_UTF_8_romanian.c +990 -0
  153. data/ext/isomorfeus_ferret_ext/stem_UTF_8_romanian.h +6 -0
  154. data/ext/isomorfeus_ferret_ext/stem_UTF_8_russian.c +680 -0
  155. data/ext/isomorfeus_ferret_ext/stem_UTF_8_russian.h +6 -0
  156. data/ext/isomorfeus_ferret_ext/stem_UTF_8_spanish.c +1083 -0
  157. data/ext/isomorfeus_ferret_ext/stem_UTF_8_spanish.h +6 -0
  158. data/ext/isomorfeus_ferret_ext/stem_UTF_8_swedish.c +294 -0
  159. data/ext/isomorfeus_ferret_ext/stem_UTF_8_swedish.h +6 -0
  160. data/ext/isomorfeus_ferret_ext/stem_UTF_8_turkish.c +2191 -0
  161. data/ext/isomorfeus_ferret_ext/stem_UTF_8_turkish.h +6 -0
  162. data/ext/isomorfeus_ferret_ext/stem_api.c +66 -0
  163. data/ext/isomorfeus_ferret_ext/stem_api.h +26 -0
  164. data/ext/isomorfeus_ferret_ext/stem_header.h +57 -0
  165. data/ext/isomorfeus_ferret_ext/stem_modules.h +190 -0
  166. data/ext/isomorfeus_ferret_ext/stem_modules.txt +50 -0
  167. data/ext/isomorfeus_ferret_ext/stem_utilities.c +478 -0
  168. data/ext/isomorfeus_ferret_ext/test.c +850 -0
  169. data/ext/isomorfeus_ferret_ext/test.h +416 -0
  170. data/ext/isomorfeus_ferret_ext/test_1710.c +63 -0
  171. data/ext/isomorfeus_ferret_ext/test_analysis.c +1221 -0
  172. data/ext/isomorfeus_ferret_ext/test_array.c +272 -0
  173. data/ext/isomorfeus_ferret_ext/test_bitvector.c +600 -0
  174. data/ext/isomorfeus_ferret_ext/test_compound_io.c +170 -0
  175. data/ext/isomorfeus_ferret_ext/test_document.c +156 -0
  176. data/ext/isomorfeus_ferret_ext/test_except.c +244 -0
  177. data/ext/isomorfeus_ferret_ext/test_fields.c +522 -0
  178. data/ext/isomorfeus_ferret_ext/test_file_deleter.c +185 -0
  179. data/ext/isomorfeus_ferret_ext/test_filter.c +331 -0
  180. data/ext/isomorfeus_ferret_ext/test_fs_store.c +25 -0
  181. data/ext/isomorfeus_ferret_ext/test_global.c +299 -0
  182. data/ext/isomorfeus_ferret_ext/test_hash.c +485 -0
  183. data/ext/isomorfeus_ferret_ext/test_hashset.c +288 -0
  184. data/ext/isomorfeus_ferret_ext/test_helper.c +47 -0
  185. data/ext/isomorfeus_ferret_ext/test_highlighter.c +548 -0
  186. data/ext/isomorfeus_ferret_ext/test_index.c +2323 -0
  187. data/ext/isomorfeus_ferret_ext/test_lang.c +74 -0
  188. data/ext/isomorfeus_ferret_ext/test_mempool.c +102 -0
  189. data/ext/isomorfeus_ferret_ext/test_multimapper.c +64 -0
  190. data/ext/isomorfeus_ferret_ext/test_priorityqueue.c +213 -0
  191. data/ext/isomorfeus_ferret_ext/test_q_const_score.c +84 -0
  192. data/ext/isomorfeus_ferret_ext/test_q_filtered.c +61 -0
  193. data/ext/isomorfeus_ferret_ext/test_q_fuzzy.c +241 -0
  194. data/ext/isomorfeus_ferret_ext/test_q_parser.c +464 -0
  195. data/ext/isomorfeus_ferret_ext/test_q_span.c +575 -0
  196. data/ext/isomorfeus_ferret_ext/test_ram_store.c +77 -0
  197. data/ext/isomorfeus_ferret_ext/test_search.c +1874 -0
  198. data/ext/isomorfeus_ferret_ext/test_segments.c +167 -0
  199. data/ext/isomorfeus_ferret_ext/test_similarity.c +25 -0
  200. data/ext/isomorfeus_ferret_ext/test_sort.c +333 -0
  201. data/ext/isomorfeus_ferret_ext/test_store.c +591 -0
  202. data/ext/isomorfeus_ferret_ext/test_store.h +3 -0
  203. data/ext/isomorfeus_ferret_ext/test_term.c +351 -0
  204. data/ext/isomorfeus_ferret_ext/test_term_vectors.c +373 -0
  205. data/ext/isomorfeus_ferret_ext/test_test.c +83 -0
  206. data/ext/isomorfeus_ferret_ext/test_threading.c +188 -0
  207. data/ext/isomorfeus_ferret_ext/testhelper.c +561 -0
  208. data/ext/isomorfeus_ferret_ext/testhelper.h +25 -0
  209. data/ext/isomorfeus_ferret_ext/tests_all.h +87 -0
  210. data/ext/isomorfeus_ferret_ext/uchar-ucs4.rl +1854 -0
  211. data/ext/isomorfeus_ferret_ext/uchar-utf8.rl +1999 -0
  212. data/ext/isomorfeus_ferret_ext/url.rl +27 -0
  213. data/ext/isomorfeus_ferret_ext/word_list.h +15156 -0
  214. data/lib/isomorfeus/ferret/document.rb +132 -0
  215. data/lib/isomorfeus/ferret/field_symbol.rb +85 -0
  216. data/lib/isomorfeus/ferret/index/field_infos.rb +48 -0
  217. data/lib/isomorfeus/ferret/index/index.rb +970 -0
  218. data/lib/isomorfeus/ferret/monitor.rb +323 -0
  219. data/lib/isomorfeus/ferret/stdlib_patches.rb +151 -0
  220. data/lib/isomorfeus/ferret/version.rb +5 -0
  221. data/lib/isomorfeus-ferret.rb +8 -0
  222. metadata +307 -0
@@ -0,0 +1,1874 @@
1
+ #include <ctype.h>
2
+ #include "frt_search.h"
3
+ #include "frt_array.h"
4
+ #include "frt_helper.h"
5
+ #include "testhelper.h"
6
+ #include "test.h"
7
+
8
+ #define ARRAY_SIZE 40
9
+
10
+ static FrtSymbol date, field, cat, number;
11
+
12
+ static void test_byte_float_conversion(TestCase *tc, void *data)
13
+ {
14
+ int i;
15
+ (void)data;
16
+
17
+ for (i = 0; i < 256; i++) {
18
+ Aiequal(i, frt_float2byte(frt_byte2float((char)i)));
19
+ }
20
+ }
21
+
22
+ static int my_doc_freq(FrtSearcher *searcher, FrtSymbol field,
23
+ const char *term)
24
+ {
25
+ (void)searcher; (void)field; (void)term;
26
+ return 9;
27
+ }
28
+
29
+ static int my_max_doc(FrtSearcher *searcher)
30
+ {
31
+ (void)searcher;
32
+ return 10;
33
+ }
34
+
35
+ static void test_explanation(TestCase *tc, void *data)
36
+ {
37
+ FrtExplanation *expl = frt_expl_new(1.6f, "short description");
38
+ char *str = frt_expl_to_s(expl);
39
+ (void)data;
40
+ Asequal("1.6 = short description\n", str);
41
+ free(str);
42
+ frt_expl_add_detail(expl, frt_expl_new(0.8f, "half the score"));
43
+ frt_expl_add_detail(expl, frt_expl_new(2.0f, "to make the difference"));
44
+ frt_expl_add_detail(expl->details[1], frt_expl_new(0.5f, "sub-sub"));
45
+ frt_expl_add_detail(expl->details[1], frt_expl_new(4.0f, "another sub-sub"));
46
+ frt_expl_add_detail(expl->details[0], frt_expl_new(0.8f, "and sub-sub for 1st sub"));
47
+
48
+ str = frt_expl_to_s(expl);
49
+ Asequal("1.6 = short description\n"
50
+ " 0.8 = half the score\n"
51
+ " 0.8 = and sub-sub for 1st sub\n"
52
+ " 2.0 = to make the difference\n"
53
+ " 0.5 = sub-sub\n"
54
+ " 4.0 = another sub-sub\n", str);
55
+ frt_expl_destroy(expl);
56
+ free(str);
57
+ }
58
+
59
+ static void test_default_similarity(TestCase *tc, void *data)
60
+ {
61
+ FrtPhrasePosition positions[4];
62
+ FrtSearcher searcher;
63
+ FrtSimilarity *dsim = frt_sim_create_default();
64
+ (void)data;
65
+ positions[0].pos = 0;
66
+ positions[0].terms = frt_ary_new_type(char *);
67
+ frt_ary_push(positions[0].terms, (char *)"term1");
68
+ frt_ary_push(positions[0].terms, (char *)"term2");
69
+ frt_ary_push(positions[0].terms, (char *)"term3");
70
+
71
+ positions[1].pos = 0;
72
+ positions[1].terms = frt_ary_new_type(char *);
73
+ frt_ary_push(positions[0].terms, (char *)"term1");
74
+ frt_ary_push(positions[0].terms, (char *)"term2");
75
+
76
+ positions[2].pos = -100;
77
+ positions[2].terms = frt_ary_new_type(char *);
78
+ frt_ary_push(positions[0].terms, (char *)"term1");
79
+
80
+ positions[3].pos = 100;
81
+ positions[3].terms = frt_ary_new_type(char *);
82
+ frt_ary_push(positions[3].terms, (char *)"term1");
83
+ frt_ary_push(positions[3].terms, (char *)"term2");
84
+ frt_ary_push(positions[3].terms, (char *)"term2");
85
+ frt_ary_push(positions[3].terms, (char *)"term3");
86
+ frt_ary_push(positions[3].terms, (char *)"term4");
87
+ frt_ary_push(positions[3].terms, (char *)"term5");
88
+
89
+ Afequal(1.0/4, frt_sim_length_norm(dsim, field, 16));
90
+ Afequal(1.0/4, frt_sim_query_norm(dsim, 16));
91
+ Afequal(3.0, frt_sim_tf(dsim, 9));
92
+ Afequal(1.0/10, frt_sim_sloppy_freq(dsim, 9));
93
+ Afequal(1.0, frt_sim_idf(dsim, 9, 10));
94
+ Afequal(4.0, frt_sim_coord(dsim, 12, 3));
95
+ searcher.doc_freq = &my_doc_freq;
96
+ searcher.max_doc = &my_max_doc;
97
+ Afequal(1.0, frt_sim_idf_term(dsim, field, positions[0].terms[0], &searcher));
98
+ Afequal(12.0, frt_sim_idf_phrase(dsim, field, positions, 4, &searcher));
99
+
100
+ frt_ary_free(positions[0].terms);
101
+ frt_ary_free(positions[1].terms);
102
+ frt_ary_free(positions[2].terms);
103
+ frt_ary_free(positions[3].terms);
104
+ }
105
+
106
+ typedef struct DoubleFilter {
107
+ FrtTokenFilter super;
108
+ FrtToken *tk;
109
+ } DoubleFilter;
110
+
111
+ static FrtToken *dbl_tf_next(FrtTokenStream *ts)
112
+ {
113
+ FrtToken *tk;
114
+ tk = ((DoubleFilter *)ts)->tk;
115
+ if (tk && islower(tk->text[0])) {
116
+ char *t = tk->text;
117
+ while (*t) {
118
+ *t = toupper(*t);
119
+ t++;
120
+ }
121
+ tk->pos_inc = 1;
122
+ }
123
+ else {
124
+ tk = ((DoubleFilter *)ts)->tk
125
+ = ((FrtTokenFilter *)ts)->sub_ts->next(((FrtTokenFilter *)ts)->sub_ts);
126
+ if (tk && islower(tk->text[0])) {
127
+ tk->pos_inc = 0;
128
+ }
129
+ }
130
+ return tk;
131
+ }
132
+
133
+ static FrtTokenStream *dbl_tf_clone_i(FrtTokenStream *ts)
134
+ {
135
+ return frt_filter_clone_size(ts, sizeof(DoubleFilter));
136
+ }
137
+
138
+ static FrtTokenStream *dbl_tf_new(FrtTokenStream *sub_ts)
139
+ {
140
+ FrtTokenStream *ts = tf_new(DoubleFilter, sub_ts);
141
+ ts->next = &dbl_tf_next;
142
+ ts->clone_i = &dbl_tf_clone_i;
143
+ return ts;
144
+ }
145
+
146
+ FrtAnalyzer *dbl_analyzer_new()
147
+ {
148
+ FrtTokenStream *ts;
149
+ ts = dbl_tf_new(frt_whitespace_tokenizer_new());
150
+ return frt_analyzer_new(ts, NULL, NULL);
151
+ }
152
+
153
+ struct Data {
154
+ const char *date;
155
+ const char *field;
156
+ const char *cat;
157
+ const char *number;
158
+ };
159
+
160
+ #define SEARCH_DOCS_SIZE 18
161
+ struct Data test_data[SEARCH_DOCS_SIZE] = {
162
+ {"20050930", "word1",
163
+ "cat1/", ".123"},
164
+ {"20051001", "word1 word2 the quick brown fox the quick brown fox",
165
+ "cat1/sub1", "0.0"},
166
+ {"20051002", "word1 word3 one two one",
167
+ "cat1/sub1/subsub1", "908.123434"},
168
+ {"20051003", "word1 word3 one two",
169
+ "cat1/sub2", "3999"},
170
+ /* we have 33 * "word2" below to cause cache miss in TermQuery */
171
+ {"20051004", "word1 word2 word2 word2 word2 word2 word2 word2 word2 "
172
+ "word2 word2 word2 word2 word2 word2 word2 word2 word2 "
173
+ "word2 word2 word2 word2 word2 word2 word2 word2 word2 "
174
+ "word2 word2 word2 word2 word2 word2 word2",
175
+ "cat1/sub2/subsub2", "+.3413"},
176
+ {"20051005", "word1 one two x x x x x one two",
177
+ "cat2/sub1", "-1.1298"},
178
+ {"20051006", "word1 word3",
179
+ "cat2/sub1", "2"},
180
+ {"20051007", "word1",
181
+ "cat2/sub1", "+8.894"},
182
+ {"20051008", "word1 word2 word3 the fast brown fox",
183
+ "cat2/sub1", "+84783.13747"},
184
+ {"20051009", "word1",
185
+ "cat3/sub1", "10.0"},
186
+ {"20051010", "word1",
187
+ "cat3/sub1", "1"},
188
+ {"20051011", "word1 word3 the quick red fox",
189
+ "cat3/sub1", "-12518419"},
190
+ {"20051012", "word1",
191
+ "cat3/sub1", "10"},
192
+ {"20051013", "word1",
193
+ "cat1/sub2", "15682954"},
194
+ {"20051014", "word1 word3 the quick hairy fox",
195
+ "cat1/sub1", "98132"},
196
+ {"20051015", "word1",
197
+ "cat1/sub2/subsub1", "-.89321"},
198
+ {"20051016", "word1 the quick fox is brown and hairy and a little red",
199
+ "cat1/sub1/subsub2", "-89"},
200
+ {"20051017", "word1 the brown fox is quick and red",
201
+ "cat1/", "-1.0"}
202
+ };
203
+
204
+ static void prepare_search_index(FrtStore *store)
205
+ {
206
+ int i;
207
+ FrtIndexWriter *iw;
208
+
209
+ FrtFieldInfos *fis = frt_fis_new(FRT_STORE_YES, FRT_INDEX_YES, FRT_TERM_VECTOR_WITH_POSITIONS_OFFSETS);
210
+ FrtFieldInfo *fi = frt_fi_new(rb_intern("empty-field"), FRT_STORE_NO, FRT_INDEX_NO, FRT_TERM_VECTOR_NO);
211
+ frt_fis_add_field(fis, fi);
212
+ frt_index_create(store, fis);
213
+ frt_fis_deref(fis);
214
+
215
+ iw = frt_iw_open(store, dbl_analyzer_new(), NULL);
216
+ for (i = 0; i < SEARCH_DOCS_SIZE; i++) {
217
+ FrtDocument *doc = frt_doc_new();
218
+ doc->boost = (float)(i+1);
219
+ frt_doc_add_field(doc, frt_df_add_data(frt_df_new(date), (char *)test_data[i].date));
220
+ frt_doc_add_field(doc, frt_df_add_data(frt_df_new(field), (char *)test_data[i].field));
221
+ frt_doc_add_field(doc, frt_df_add_data(frt_df_new(cat), (char *)test_data[i].cat));
222
+ frt_doc_add_field(doc, frt_df_add_data(frt_df_new(number), (char *)test_data[i].number));
223
+ frt_iw_add_doc(iw, doc);
224
+ frt_doc_destroy(doc);
225
+ }
226
+ frt_iw_close(iw);
227
+ }
228
+
229
+ static void test_get_doc(TestCase *tc, void *data)
230
+ {
231
+ FrtSearcher *searcher = (FrtSearcher *)data;
232
+ FrtDocument *doc;
233
+ FrtDocField *df;
234
+ Aiequal(SEARCH_DOCS_SIZE, frt_searcher_max_doc(searcher));
235
+
236
+ doc = frt_searcher_get_doc(searcher, 0);
237
+ df = frt_doc_get_field(doc, date);
238
+ Aiequal(1, df->size);
239
+ Asequal("20050930", df->data[0]);
240
+ frt_doc_destroy(doc);
241
+
242
+ doc = frt_searcher_get_doc(searcher, 4);
243
+ df = frt_doc_get_field(doc, cat);
244
+ Aiequal(1, df->size);
245
+ Asequal("cat1/sub2/subsub2", df->data[0]);
246
+ frt_doc_destroy(doc);
247
+
248
+ doc = frt_searcher_get_doc(searcher, 12);
249
+ df = frt_doc_get_field(doc, date);
250
+ Aiequal(1, df->size);
251
+ Asequal("20051012", df->data[0]);
252
+ frt_doc_destroy(doc);
253
+ }
254
+
255
+ void check_to_s(TestCase *tc, FrtQuery *query, FrtSymbol field, const char *q_str)
256
+ {
257
+ char *q_res = query->to_s(query, field);
258
+ Asequal(q_str, q_res);
259
+ free(q_res);
260
+ }
261
+
262
+ void tst_check_hits(TestCase *tc, FrtSearcher *searcher, FrtQuery *query, const char *expected_hits, int top)
263
+ {
264
+ static int num_array[ARRAY_SIZE];
265
+ static int num_array2[ARRAY_SIZE];
266
+ int i, count;
267
+ int total_hits = s2l(expected_hits, num_array);
268
+ FrtTopDocs *top_docs = frt_searcher_search(searcher, query, 0, total_hits + 1, NULL, NULL, NULL);
269
+ frt_p_pause();
270
+ if (!tc->failed && !Aiequal(total_hits, top_docs->total_hits)) {
271
+ int i;
272
+ Tmsg_nf("\texpected docs:\n\t ");
273
+ for (i = 0; i < total_hits; i++) {
274
+ Tmsg_nf("%d ", num_array[i]);
275
+ }
276
+ Tmsg_nf("\n\tseen docs:\n\t ");
277
+ for (i = 0; i < top_docs->size; i++) {
278
+ Tmsg_nf("%d ", top_docs->hits[i]->doc);
279
+ }
280
+ Tmsg_nf("\n");
281
+ }
282
+ Aiequal(total_hits, top_docs->size);
283
+ /* FIXME add this code once search_unscored is working
284
+ frt_searcher_search_unscored(searcher, query, buf, ARRAY_SIZE, 0);
285
+ Aaiequal(num_array, buf, total_hits);
286
+ */
287
+
288
+ if ((top >= 0) && top_docs->size)
289
+ Aiequal(top, top_docs->hits[0]->doc);
290
+ for (i = 0; i < top_docs->size; i++) {
291
+ FrtHit *hit = top_docs->hits[i];
292
+ float normalized_score = hit->score / top_docs->max_score;
293
+ Assert(0.0 < normalized_score && normalized_score <= 1.0, "hit->score <%f> is out of range (0.0..1.0]", normalized_score);
294
+ Assert(frt_ary_includes(num_array, total_hits, hit->doc), "doc %d was found unexpectedly", hit->doc);
295
+ /* only check the explanation if we got the correct docs. Obviously we
296
+ * might want to remove this to visually check the explanations */
297
+ if (!tc->failed && total_hits == top_docs->total_hits) {
298
+ FrtExplanation *e = frt_searcher_explain(searcher, query, hit->doc);
299
+ if (! Afequal(hit->score, e->value)) {
300
+ char *t;
301
+ Tmsg("\n\"\"\"\n%d>>\n%f\n%s\n\"\"\"\n", hit->doc, hit->score, t = frt_expl_to_s(e));
302
+ free(t);
303
+ }
304
+ frt_expl_destroy(e);
305
+ }
306
+ }
307
+ frt_td_destroy(top_docs);
308
+
309
+ /* test search_unscored method */
310
+ qsort(num_array, total_hits, sizeof(int), &frt_icmp_risky);
311
+ count = frt_searcher_search_unscored(searcher, query, num_array2, ARRAY_SIZE, 0);
312
+ Aaiequal(num_array, num_array2, total_hits);
313
+ if (count > 3) {
314
+ count = frt_searcher_search_unscored(searcher, query, num_array2, ARRAY_SIZE, num_array2[3]);
315
+ Aaiequal(num_array + 3, num_array2, count);
316
+ }
317
+ frt_p_resume();
318
+ }
319
+
320
+ void check_match_vector(TestCase *tc, FrtSearcher *searcher, FrtQuery *query,
321
+ int doc, FrtSymbol field, const char *ranges)
322
+ {
323
+ static int range_array[ARRAY_SIZE];
324
+ FrtMatchVector *mv = frt_searcher_get_match_vector(searcher, query, doc, field);
325
+ int num_matches = s2l(ranges, range_array)/2;
326
+ if (Aiequal(num_matches, mv->size)) {
327
+ int i;
328
+ for (i = 0; i < num_matches; i++) {
329
+ Aiequal(range_array[i*2 ], mv->matches[i].start);
330
+ Aiequal(range_array[i*2 + 1], mv->matches[i].end);
331
+ }
332
+ }
333
+ frt_matchv_destroy(mv);
334
+ }
335
+
336
+ static void test_term_query(TestCase *tc, void *data)
337
+ {
338
+ FrtHashSet *hs;
339
+ FrtSearcher *searcher = (FrtSearcher *)data;
340
+ FrtTopDocs *top_docs;
341
+ FrtWeight *w;
342
+ char *t, e[100];
343
+ FrtQuery *tq = frt_tq_new(field, "word2");
344
+ check_to_s(tc, tq, field, "word2");
345
+ check_to_s(tc, tq, (FrtSymbol)NULL, "field:word2");
346
+ tq->boost = 100;
347
+ tst_check_hits(tc, searcher, tq, "4, 8, 1", -1);
348
+ check_to_s(tc, tq, field, "word2^100.0");
349
+ check_to_s(tc, tq, (FrtSymbol)NULL, "field:word2^100.0");
350
+
351
+ /* test TermWeight.to_s */
352
+ w = searcher->create_weight(searcher, tq);
353
+ sprintf(e, "TermWeight("FRT_DBL2S")", w->value);
354
+ t = w->to_s(w); Asequal(e, t); free(t);
355
+ tq->boost = 10.5f;
356
+ sprintf(e, "TermWeight("FRT_DBL2S")", w->value);
357
+ t = w->to_s(w); Asequal(e, t); free(t);
358
+ w->destroy(w);
359
+
360
+ frt_q_deref(tq);
361
+
362
+ tq = frt_tq_new(field, "2342");
363
+ tst_check_hits(tc, searcher, tq, "", -1);
364
+ frt_q_deref(tq);
365
+
366
+ tq = frt_tq_new(field, "");
367
+ tst_check_hits(tc, searcher, tq, "", -1);
368
+ frt_q_deref(tq);
369
+
370
+ tq = frt_tq_new(rb_intern("not_a_field"), "word2");
371
+ tst_check_hits(tc, searcher, tq, "", -1);
372
+ frt_q_deref(tq);
373
+
374
+ tq = frt_tq_new(field, "word1");
375
+ top_docs = frt_searcher_search(searcher, tq, 0, 10, NULL, NULL, NULL);
376
+ Aiequal(SEARCH_DOCS_SIZE, top_docs->total_hits);
377
+ Aiequal(10, top_docs->size);
378
+ frt_td_destroy(top_docs);
379
+
380
+ top_docs = frt_searcher_search(searcher, tq, 0, 20, NULL, NULL, NULL);
381
+ Aiequal(SEARCH_DOCS_SIZE, top_docs->total_hits);
382
+ Aiequal(SEARCH_DOCS_SIZE, top_docs->size);
383
+ frt_td_destroy(top_docs);
384
+
385
+ top_docs = frt_searcher_search(searcher, tq, 10, 20, NULL, NULL, NULL);
386
+ Aiequal(SEARCH_DOCS_SIZE, top_docs->total_hits);
387
+ Aiequal(SEARCH_DOCS_SIZE - 10, top_docs->size);
388
+ frt_td_destroy(top_docs);
389
+ frt_q_deref(tq);
390
+
391
+ tq = frt_tq_new(field, "quick");
392
+ /* test get_matchv_i */
393
+ tst_check_hits(tc, searcher, tq, "1,11,14,16,17", -1);
394
+ check_match_vector(tc, searcher, tq, 1, field, "3,3,7,7");
395
+
396
+ /* test extract_terms */
397
+ hs = frt_hs_new((frt_hash_ft)&frt_term_hash, (frt_eq_ft)&frt_term_eq, (frt_free_ft)&frt_term_destroy);
398
+ tq->extract_terms(tq, hs);
399
+ Aiequal(1, hs->size);
400
+ Asequal("quick", ((FrtTerm *)hs->first->elem)->text);
401
+ Apequal(rb_id2name(field), rb_id2name(((FrtTerm *)hs->first->elem)->field));
402
+ frt_hs_destroy(hs);
403
+ frt_q_deref(tq);
404
+ }
405
+
406
+ static void test_term_query_hash(TestCase *tc, void *data)
407
+ {
408
+ FrtQuery *q1, *q2;
409
+ (void)data;
410
+ q1 = frt_tq_new(rb_intern("A"), "a");
411
+
412
+ q2 = frt_tq_new(rb_intern("A"), "a");
413
+ Aiequal(frt_q_hash(q1), frt_q_hash(q2));
414
+ Assert(frt_q_eq(q1, q2), "Queries are equal");
415
+ Assert(frt_q_eq(q1, q1), "Queries are equal");
416
+ frt_q_deref(q2);
417
+
418
+ q2 = frt_tq_new(rb_intern("A"), "b");
419
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "texts differ");
420
+ Assert(!frt_q_eq(q1, q2), "texts differ");
421
+ frt_q_deref(q2);
422
+
423
+ q2 = frt_tq_new(rb_intern("B"), "a");
424
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "fields differ");
425
+ Assert(!frt_q_eq(q1, q2), "fields differ");
426
+ frt_q_deref(q2);
427
+
428
+ frt_q_deref(q1);
429
+ }
430
+
431
+ static void test_boolean_query(TestCase *tc, void *data)
432
+ {
433
+ FrtSearcher *searcher = (FrtSearcher *)data;
434
+ FrtQuery *bq = frt_bq_new(false);
435
+ FrtQuery *tq1 = frt_tq_new(field, "word1");
436
+ FrtQuery *tq2 = frt_tq_new(field, "word3");
437
+ FrtQuery *tq3 = frt_tq_new(field, "word2");
438
+ frt_bq_add_query_nr(bq, tq1, FRT_BC_MUST);
439
+ frt_bq_add_query_nr(bq, tq2, FRT_BC_MUST);
440
+ tst_check_hits(tc, searcher, bq, "2, 3, 6, 8, 11, 14", 14);
441
+
442
+ frt_bq_add_query_nr(bq, tq3, FRT_BC_SHOULD);
443
+ tst_check_hits(tc, searcher, bq, "2, 3, 6, 8, 11, 14", 8);
444
+ frt_q_deref(bq);
445
+
446
+ tq2 = frt_tq_new(field, "word3");
447
+ tq3 = frt_tq_new(field, "word2");
448
+ bq = frt_bq_new(false);
449
+ frt_bq_add_query_nr(bq, tq2, FRT_BC_MUST);
450
+ frt_bq_add_query_nr(bq, tq3, FRT_BC_MUST_NOT);
451
+ tst_check_hits(tc, searcher, bq, "2, 3, 6, 11, 14", -1);
452
+ frt_q_deref(bq);
453
+
454
+ tq2 = frt_tq_new(field, "word3");
455
+ bq = frt_bq_new(false);
456
+ frt_bq_add_query_nr(bq, tq2, FRT_BC_MUST_NOT);
457
+ tst_check_hits(tc, searcher, bq, "0,1,4,5,7,9,10,12,13,15,16,17", -1);
458
+ frt_q_deref(bq);
459
+
460
+ tq2 = frt_tq_new(field, "word3");
461
+ bq = frt_bq_new(false);
462
+ frt_bq_add_query_nr(bq, tq2, FRT_BC_SHOULD);
463
+ tst_check_hits(tc, searcher, bq, "2, 3, 6, 8, 11, 14", 14);
464
+ frt_q_deref(bq);
465
+
466
+ tq2 = frt_tq_new(field, "word3");
467
+ tq3 = frt_tq_new(field, "word2");
468
+ bq = frt_bq_new(false);
469
+ frt_bq_add_query_nr(bq, tq2, FRT_BC_SHOULD);
470
+ frt_bq_add_query_nr(bq, tq3, FRT_BC_SHOULD);
471
+ tst_check_hits(tc, searcher, bq, "1, 2, 3, 4, 6, 8, 11, 14", -1);
472
+ frt_q_deref(bq);
473
+
474
+ bq = frt_bq_new(false);
475
+ tq1 = frt_tq_new(rb_intern("not a field"), "word1");
476
+ tq2 = frt_tq_new(rb_intern("not a field"), "word3");
477
+ tq3 = frt_tq_new(field, "word2");
478
+ frt_bq_add_query_nr(bq, tq1, FRT_BC_SHOULD);
479
+ frt_bq_add_query_nr(bq, tq2, FRT_BC_SHOULD);
480
+ tst_check_hits(tc, searcher, bq, "", -1);
481
+
482
+ frt_bq_add_query_nr(bq, tq3, FRT_BC_SHOULD);
483
+ tst_check_hits(tc, searcher, bq, "1, 4, 8", 4);
484
+
485
+ frt_q_deref(bq);
486
+ }
487
+
488
+ static void test_boolean_query_hash(TestCase *tc, void *data)
489
+ {
490
+ FrtQuery *tq1, *tq2, *tq3, *q1, *q2;
491
+ (void)data;
492
+
493
+ tq1 = frt_tq_new(rb_intern("A"), "1");
494
+ tq2 = frt_tq_new(rb_intern("B"), "2");
495
+ tq3 = frt_tq_new(rb_intern("C"), "3");
496
+ q1 = frt_bq_new(false);
497
+ frt_bq_add_query(q1, tq1, FRT_BC_MUST);
498
+ frt_bq_add_query(q1, tq2, FRT_BC_MUST);
499
+
500
+ q2 = frt_bq_new(false);
501
+ frt_bq_add_query(q2, tq1, FRT_BC_MUST);
502
+ frt_bq_add_query(q2, tq2, FRT_BC_MUST);
503
+
504
+ Aiequal(frt_q_hash(q1), frt_q_hash(q2));
505
+ Assert(frt_q_eq(q1, q1), "Queries are equal");
506
+ Assert(frt_q_eq(q1, q2), "Queries are equal");
507
+ Assert(frt_q_hash(q1) != frt_q_hash(tq1), "Queries are not equal");
508
+ Assert(!frt_q_eq(q1, tq1), "Queries are not equal");
509
+ Assert(!frt_q_eq(tq1, q1), "Queries are not equal");
510
+ frt_q_deref(q2);
511
+
512
+ q2 = frt_bq_new(true);
513
+ frt_bq_add_query(q2, tq1, FRT_BC_MUST);
514
+ frt_bq_add_query(q2, tq2, FRT_BC_MUST);
515
+
516
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Queries are not equal");
517
+ Assert(!frt_q_eq(q1, q2), "Queries are not equal");
518
+ frt_q_deref(q2);
519
+
520
+ q2 = frt_bq_new(false);
521
+ frt_bq_add_query(q2, tq1, FRT_BC_SHOULD);
522
+ frt_bq_add_query(q2, tq2, FRT_BC_MUST_NOT);
523
+
524
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Queries are not equal");
525
+ Assert(!frt_q_eq(q1, q2), "Queries are not equal");
526
+ frt_q_deref(q2);
527
+
528
+ q2 = frt_bq_new(false);
529
+ frt_bq_add_query(q2, tq1, FRT_BC_MUST);
530
+ frt_bq_add_query(q2, tq2, FRT_BC_MUST);
531
+ frt_bq_add_query(q2, tq3, FRT_BC_MUST);
532
+
533
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Queries are not equal");
534
+ Assert(!frt_q_eq(q1, q2), "Queries are not equal");
535
+
536
+ frt_bq_add_query(q1, tq3, FRT_BC_MUST);
537
+
538
+ Aiequal(frt_q_hash(q1), frt_q_hash(q2));
539
+ Assert(frt_q_eq(q1, q2), "Queries are equal");
540
+ frt_q_deref(q2);
541
+
542
+ frt_q_deref(q1);
543
+ frt_q_deref(tq1);
544
+ frt_q_deref(tq2);
545
+ frt_q_deref(tq3);
546
+ }
547
+
548
+ static void test_phrase_query(TestCase *tc, void *data)
549
+ {
550
+ FrtSearcher *searcher = (FrtSearcher *)data;
551
+ FrtExplanation *explanation;
552
+ FrtQuery *q;
553
+ FrtQuery *phq = frt_phq_new(field);
554
+ FrtWeight *w;
555
+ char *t, e[100];
556
+ check_to_s(tc, phq, field, "\"\"");
557
+ check_to_s(tc, phq, (FrtSymbol)NULL, "field:\"\"");
558
+
559
+
560
+ frt_phq_add_term(phq, "quick", 1);
561
+ frt_phq_add_term(phq, "brown", 1);
562
+ frt_phq_add_term(phq, "fox", 1);
563
+ check_to_s(tc, phq, field, "\"quick brown fox\"");
564
+ check_to_s(tc, phq, (FrtSymbol)NULL, "field:\"quick brown fox\"");
565
+ tst_check_hits(tc, searcher, phq, "1", 1);
566
+
567
+ frt_phq_set_slop(phq, 4);
568
+ tst_check_hits(tc, searcher, phq, "1, 16, 17", 17);
569
+
570
+ /* test PhraseWeight.to_s */
571
+ w = searcher->create_weight(searcher, phq);
572
+ sprintf(e, "PhraseWeight("FRT_DBL2S")", w->value);
573
+ t = w->to_s(w); Asequal(e, t); free(t);
574
+ phq->boost = 10.5f;
575
+ sprintf(e, "PhraseWeight("FRT_DBL2S")", w->value);
576
+ t = w->to_s(w); Asequal(e, t); free(t);
577
+ w->destroy(w);
578
+
579
+ frt_q_deref(phq);
580
+
581
+ phq = frt_phq_new(field);
582
+ frt_phq_add_term(phq, "quick", 1);
583
+ frt_phq_add_term(phq, "fox", 2);
584
+ check_to_s(tc, phq, field, "\"quick <> fox\"");
585
+ check_to_s(tc, phq, (FrtSymbol)NULL, "field:\"quick <> fox\"");
586
+ tst_check_hits(tc, searcher, phq, "1, 11, 14", 14);
587
+
588
+ frt_phq_set_slop(phq, 1);
589
+ tst_check_hits(tc, searcher, phq, "1, 11, 14, 16", 14);
590
+
591
+ frt_phq_set_slop(phq, 4);
592
+ tst_check_hits(tc, searcher, phq, "1, 11, 14, 16, 17", 14);
593
+ frt_phq_add_term(phq, "red", -1);
594
+ check_to_s(tc, phq, (FrtSymbol)NULL, "field:\"quick red fox\"~4");
595
+ tst_check_hits(tc, searcher, phq, "11", 11);
596
+ frt_phq_add_term(phq, "RED", 0);
597
+ check_to_s(tc, phq, (FrtSymbol)NULL, "field:\"quick red RED&fox\"~4");
598
+ tst_check_hits(tc, searcher, phq, "11", 11);
599
+ frt_phq_add_term(phq, "QUICK", -1);
600
+ frt_phq_add_term(phq, "red", 0);
601
+ check_to_s(tc, phq, (FrtSymbol)NULL, "field:\"quick QUICK&red&red RED&fox\"~4");
602
+ tst_check_hits(tc, searcher, phq, "11", 11);
603
+ frt_phq_add_term(phq, "green", 0);
604
+ frt_phq_add_term(phq, "yellow", 0);
605
+ frt_phq_add_term(phq, "sentinel", 1);
606
+ check_to_s(tc, phq, (FrtSymbol)NULL,
607
+ "field:\"quick QUICK&red&red RED&fox&green&yellow sentinel\"~4");
608
+ tst_check_hits(tc, searcher, phq, "", -1);
609
+ frt_q_deref(phq);
610
+
611
+ phq = frt_phq_new(field);
612
+ frt_phq_add_term(phq, "the", 0);
613
+ frt_phq_add_term(phq, "WORD3", 0);
614
+ tst_check_hits(tc, searcher, phq, "8, 11, 14", 14);
615
+ frt_phq_add_term(phq, "THE", 1);
616
+ frt_phq_add_term(phq, "quick", 0);
617
+ frt_phq_add_term(phq, "QUICK", 1);
618
+ tst_check_hits(tc, searcher, phq, "11, 14", 14);
619
+ check_to_s(tc, phq, (FrtSymbol)NULL, "field:\"WORD3&the THE&quick QUICK\"");
620
+ frt_q_deref(phq);
621
+
622
+ /* test repeating terms check */
623
+ phq = frt_phq_new(field);
624
+ frt_phq_add_term(phq, "one", 0);
625
+ frt_phq_add_term(phq, "two", 1);
626
+ frt_phq_add_term(phq, "one", 1);
627
+ tst_check_hits(tc, searcher, phq, "2", 2);
628
+ frt_phq_set_slop(phq, 2);
629
+ tst_check_hits(tc, searcher, phq, "2", 2);
630
+ frt_q_deref(phq);
631
+
632
+ phq = frt_phq_new(rb_intern("not a field"));
633
+ frt_phq_add_term(phq, "the", 0);
634
+ frt_phq_add_term(phq, "quick", 1);
635
+ tst_check_hits(tc, searcher, phq, "", -1);
636
+ explanation = searcher->explain(searcher, phq, 0);
637
+ Afequal(0.0, explanation->value);
638
+ frt_expl_destroy(explanation);
639
+ frt_q_deref(phq);
640
+
641
+ /* test single-term case, query is rewritten to TermQuery */
642
+ phq = frt_phq_new(field);
643
+ frt_phq_add_term(phq, "word2", 1);
644
+ tst_check_hits(tc, searcher, phq, "4, 8, 1", -1);
645
+ q = frt_searcher_rewrite(searcher, phq);
646
+ Aiequal(q->type, TERM_QUERY);
647
+ frt_q_deref(q);
648
+
649
+ /* test single-position/multi-term query is rewritten as MultiTermQuery */
650
+ frt_phq_append_multi_term(phq, "word3");
651
+ tst_check_hits(tc, searcher, phq, "1,2,3,4,6,8,11,14", -1);
652
+ q = frt_searcher_rewrite(searcher, phq);
653
+ Aiequal(q->type, MULTI_TERM_QUERY);
654
+ frt_q_deref(q);
655
+
656
+ /* check boost doesn't break anything */;
657
+ frt_phq_add_term(phq, "one", 1); /* make sure it won't be rewritten */
658
+ phq->boost = 10.0;
659
+ tst_check_hits(tc, searcher, phq, "2,3", -1);
660
+ frt_q_deref(phq);
661
+
662
+ /* test get_matchv_i */
663
+ phq = frt_phq_new(field);
664
+ frt_phq_add_term(phq, "quick", 0);
665
+ frt_phq_add_term(phq, "brown", 1);
666
+ tst_check_hits(tc, searcher, phq, "1", -1);
667
+ check_match_vector(tc, searcher, phq, 1, field, "3,4,7,8");
668
+
669
+ frt_phq_set_slop(phq, 4);
670
+ tst_check_hits(tc, searcher, phq, "1,16,17", -1);
671
+ check_match_vector(tc, searcher, phq, 16, field, "2,5");
672
+
673
+ frt_phq_add_term(phq, "chicken", 1);
674
+ tst_check_hits(tc, searcher, phq, "", -1);
675
+ check_match_vector(tc, searcher, phq, 16, field, "");
676
+ frt_q_deref(phq);
677
+ }
678
+
679
+ static void test_phrase_query_hash(TestCase *tc, void *data)
680
+ {
681
+ FrtQuery *q1, *q2;
682
+ (void)data;
683
+
684
+ q1 = frt_phq_new(field);
685
+ frt_phq_add_term(q1, "quick", 1);
686
+ frt_phq_add_term(q1, "brown", 2);
687
+ frt_phq_add_term(q1, "fox", 0);
688
+
689
+ q2 = frt_phq_new(field);
690
+ frt_phq_add_term(q2, "quick", 1);
691
+ frt_phq_add_term(q2, "brown", 2);
692
+ frt_phq_add_term(q2, "fox", 0);
693
+
694
+ Aiequal(frt_q_hash(q1), frt_q_hash(q2));
695
+ Assert(frt_q_eq(q1, q1), "Test query equals itself");
696
+ Assert(frt_q_eq(q1, q2), "Queries should be equal");
697
+
698
+ frt_phq_set_slop(q2, 5);
699
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Queries should not be equal");
700
+ Assert(!frt_q_eq(q1, q2), "Queries should not be equal");
701
+ frt_q_deref(q2);
702
+
703
+ q2 = frt_phq_new(field);
704
+ frt_phq_add_term(q2, "quick", 1);
705
+ frt_phq_add_term(q2, "brown", 1);
706
+ frt_phq_add_term(q2, "fox", 1);
707
+
708
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Queries should not be equal");
709
+ Assert(!frt_q_eq(q1, q2), "Queries should not be equal");
710
+ frt_q_deref(q2);
711
+
712
+ q2 = frt_phq_new(field);
713
+ frt_phq_add_term(q2, "fox", 1);
714
+ frt_phq_add_term(q2, "brown", 2);
715
+ frt_phq_add_term(q2, "quick", 0);
716
+
717
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Queries should not be equal");
718
+ Assert(!frt_q_eq(q1, q2), "Queries should not be equal");
719
+ frt_q_deref(q2);
720
+
721
+ q2 = frt_phq_new(rb_intern("other_field"));
722
+ frt_phq_add_term(q2, "quick", 1);
723
+ frt_phq_add_term(q2, "brown", 2);
724
+ frt_phq_add_term(q2, "fox", 0);
725
+
726
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Queries should not be equal");
727
+ Assert(!frt_q_eq(q1, q2), "Queries should not be equal");
728
+ frt_q_deref(q2);
729
+ frt_q_deref(q1);
730
+ }
731
+
732
+ static void test_multi_phrase_query(TestCase *tc, void *data)
733
+ {
734
+ FrtSearcher *searcher = (FrtSearcher *)data;
735
+ FrtQuery *phq, *q;
736
+
737
+
738
+ phq = frt_phq_new(field);
739
+ /* ok to use append_multi_term to start */
740
+ frt_phq_append_multi_term(phq, "quick");
741
+ frt_phq_append_multi_term(phq, "fast");
742
+ tst_check_hits(tc, searcher, phq, "1, 8, 11, 14, 16, 17", -1);
743
+ check_to_s(tc, phq, field, "\"quick|fast\"");
744
+ check_to_s(tc, phq, (FrtSymbol)NULL, "field:\"quick|fast\"");
745
+
746
+ frt_phq_add_term(phq, "brown", 1);
747
+ frt_phq_append_multi_term(phq, "red");
748
+ frt_phq_append_multi_term(phq, "hairy");
749
+ frt_phq_add_term(phq, "fox", 1);
750
+ check_to_s(tc, phq, field, "\"quick|fast brown|red|hairy fox\"");
751
+ check_to_s(tc, phq, (FrtSymbol)NULL, "field:\"quick|fast brown|red|hairy fox\"");
752
+ tst_check_hits(tc, searcher, phq, "1, 8, 11, 14", -1);
753
+
754
+ frt_phq_set_slop(phq, 4);
755
+ tst_check_hits(tc, searcher, phq, "1, 8, 11, 14, 16, 17", -1);
756
+ check_to_s(tc, phq, (FrtSymbol)NULL, "field:\"quick|fast brown|red|hairy fox\"~4");
757
+
758
+ frt_phq_add_term(phq, "QUICK", -1);
759
+ frt_phq_append_multi_term(phq, "FAST");
760
+ tst_check_hits(tc, searcher, phq, "1, 8, 11, 14, 16, 17", -1);
761
+ check_to_s(tc, phq, (FrtSymbol)NULL,
762
+ "field:\"quick|fast QUICK|FAST&brown|red|hairy fox\"~4");
763
+
764
+ frt_phq_add_term(phq, "WORD3", -3);
765
+ frt_phq_append_multi_term(phq, "WORD2");
766
+ tst_check_hits(tc, searcher, phq, "1, 8, 11, 14", -1);
767
+ check_to_s(tc, phq, (FrtSymbol)NULL, "field:\"WORD3|WORD2 quick|fast "
768
+ "QUICK|FAST&brown|red|hairy fox\"~4");
769
+
770
+ frt_q_deref(phq);
771
+
772
+ /* test repeating terms check */
773
+ phq = frt_phq_new(field);
774
+ frt_phq_add_term(phq, "WORD3", 0);
775
+ frt_phq_append_multi_term(phq, "x");
776
+ frt_phq_add_term(phq, "one", 0);
777
+ frt_phq_add_term(phq, "two", 1);
778
+ frt_phq_add_term(phq, "one", 1);
779
+ tst_check_hits(tc, searcher, phq, "2", -1);
780
+ check_to_s(tc, phq, (FrtSymbol)NULL, "field:\"WORD3|x&one two one\"");
781
+
782
+ frt_phq_set_slop(phq, 4);
783
+ tst_check_hits(tc, searcher, phq, "2", -1);
784
+ check_to_s(tc, phq, (FrtSymbol)NULL, "field:\"WORD3|x&one two one\"~4");
785
+ frt_q_deref(phq);
786
+
787
+ /* test phrase query on non-existing field doesn't break anything */
788
+ phq = frt_phq_new(rb_intern("not a field"));
789
+ frt_phq_add_term(phq, "the", 0);
790
+ frt_phq_add_term(phq, "quick", 1);
791
+ frt_phq_append_multi_term(phq, "THE");
792
+ tst_check_hits(tc, searcher, phq, "", -1);
793
+ frt_q_deref(phq);
794
+
795
+ phq = frt_phq_new(field);
796
+ frt_phq_add_term(phq, "word2", 1);
797
+ frt_phq_append_multi_term(phq, "word3");
798
+ tst_check_hits(tc, searcher, phq, "1, 2, 3, 4, 6, 8, 11, 14", -1);
799
+ q = frt_searcher_rewrite(searcher, phq);
800
+ Aiequal(q->type, MULTI_TERM_QUERY);
801
+ frt_q_deref(phq);
802
+ frt_q_deref(q);
803
+
804
+ /* test get_matchv_i */
805
+ phq = frt_phq_new(field);
806
+ frt_phq_add_term(phq, "quick", 0);
807
+ frt_phq_add_term(phq, "brown", 1);
808
+ frt_phq_append_multi_term(phq, "dirty");
809
+ frt_phq_append_multi_term(phq, "red");
810
+ tst_check_hits(tc, searcher, phq, "1,11", -1);
811
+ check_match_vector(tc, searcher, phq, 1, field, "3,4,7,8");
812
+
813
+ frt_phq_set_slop(phq, 1);
814
+ tst_check_hits(tc, searcher, phq, "1,11,17", -1);
815
+ check_match_vector(tc, searcher, phq, 1, field, "3,4,7,8");
816
+ check_match_vector(tc, searcher, phq, 17, field, "5,7");
817
+
818
+ frt_phq_add_term(phq, "chicken", 1);
819
+ frt_phq_append_multi_term(phq, "turtle");
820
+ tst_check_hits(tc, searcher, phq, "", -1);
821
+ check_match_vector(tc, searcher, phq, 17, field, "");
822
+ frt_q_deref(phq);
823
+ }
824
+
825
+ static void test_multi_phrase_query_hash(TestCase *tc, void *data)
826
+ {
827
+ FrtQuery *q1, *q2;
828
+ (void)data;
829
+
830
+ q1 = frt_phq_new(field);
831
+ frt_phq_add_term(q1, "quick", 1);
832
+ frt_phq_append_multi_term(q1, "fast");
833
+ frt_phq_add_term(q1, "brown", 1);
834
+ frt_phq_append_multi_term(q1, "red");
835
+ frt_phq_append_multi_term(q1, "hairy");
836
+ frt_phq_add_term(q1, "fox", 1);
837
+
838
+ q2 = frt_phq_new(field);
839
+ frt_phq_add_term(q2, "quick", 1);
840
+ frt_phq_append_multi_term(q2, "fast");
841
+ frt_phq_add_term(q2, "brown", 1);
842
+ frt_phq_append_multi_term(q2, "red");
843
+ frt_phq_append_multi_term(q2, "hairy");
844
+ frt_phq_add_term(q2, "fox", 1);
845
+
846
+ Aiequal(frt_q_hash(q1), frt_q_hash(q2));
847
+ Assert(frt_q_eq(q1, q1), "Test query equals itself");
848
+ Assert(frt_q_eq(q1, q2), "Queries should be equal");
849
+
850
+ frt_phq_set_slop(q2, 5);
851
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Queries should not be equal");
852
+ Assert(!frt_q_eq(q1, q2), "Queries should not be equal");
853
+
854
+ frt_phq_append_multi_term(q2, "hairy");
855
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Queries should not be equal");
856
+ Assert(!frt_q_eq(q1, q2), "Queries should not be equal");
857
+ frt_q_deref(q2);
858
+
859
+ /* test same but different order */
860
+ q2 = frt_phq_new(field);
861
+ frt_phq_add_term(q2, "quick", 1);
862
+ frt_phq_append_multi_term(q2, "fast");
863
+ frt_phq_add_term(q2, "fox", 1);
864
+ frt_phq_add_term(q2, "brown", 1);
865
+ frt_phq_append_multi_term(q2, "red");
866
+ frt_phq_append_multi_term(q2, "hairy");
867
+
868
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Queries should not be equal");
869
+ Assert(!frt_q_eq(q1, q2), "Queries should not be equal");
870
+ frt_q_deref(q2);
871
+
872
+ /* test same but different pos values */
873
+ q2 = frt_phq_new(field);
874
+ frt_phq_add_term(q2, "quick", 1);
875
+ frt_phq_append_multi_term(q2, "fast");
876
+ frt_phq_add_term(q2, "brown", 1);
877
+ frt_phq_append_multi_term(q2, "red");
878
+ frt_phq_append_multi_term(q2, "hairy");
879
+ frt_phq_add_term(q2, "fox", 2);
880
+
881
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Queries should not be equal");
882
+ Assert(!frt_q_eq(q1, q2), "Queries should not be equal");
883
+ frt_q_deref(q2);
884
+
885
+ frt_q_deref(q1);
886
+ }
887
+
888
+ static void mtq_zero_max_terms(void *p)
889
+ { (void)p; frt_multi_tq_new_conf(field, 0, 0.5); }
890
+
891
+ static void test_multi_term_query(TestCase *tc, void *data)
892
+ {
893
+ FrtWeight *w;
894
+ char *t, e[100];
895
+ FrtSearcher *searcher = (FrtSearcher *)data;
896
+ FrtQuery *mtq, *bq;
897
+ FrtExplanation *exp;
898
+
899
+ Araise(FRT_ARG_ERROR, &mtq_zero_max_terms, NULL);
900
+
901
+ mtq = frt_multi_tq_new_conf(field, 4, 0.5);
902
+ tst_check_hits(tc, searcher, mtq, "", -1);
903
+ check_to_s(tc, mtq, field, "\"\"");
904
+ check_to_s(tc, mtq, (FrtSymbol)NULL, "field:\"\"");
905
+
906
+ frt_multi_tq_add_term(mtq, "brown");
907
+ tst_check_hits(tc, searcher, mtq, "1, 8, 16, 17", -1);
908
+ check_to_s(tc, mtq, field, "\"brown\"");
909
+ check_to_s(tc, mtq, (FrtSymbol)NULL, "field:\"brown\"");
910
+
911
+
912
+ /* 0.4f boost is below the 0.5 threshold so term is ignored */
913
+ frt_multi_tq_add_term_boost(mtq, "fox", 0.4f);
914
+ tst_check_hits(tc, searcher, mtq, "1, 8, 16, 17", -1);
915
+ check_to_s(tc, mtq, field, "\"brown\"");
916
+ check_to_s(tc, mtq, (FrtSymbol)NULL, "field:\"brown\"");
917
+
918
+ /* 0.6f boost is above the 0.5 threshold so term is included */
919
+ frt_multi_tq_add_term_boost(mtq, "fox", 0.6f);
920
+ tst_check_hits(tc, searcher, mtq, "1, 8, 11, 14, 16, 17", -1);
921
+ check_to_s(tc, mtq, field, "\"fox^0.6|brown\"");
922
+ check_to_s(tc, mtq, (FrtSymbol)NULL, "field:\"fox^0.6|brown\"");
923
+
924
+ frt_multi_tq_add_term_boost(mtq, "fast", 50.0f);
925
+ tst_check_hits(tc, searcher, mtq, "1, 8, 11, 14, 16, 17", 8);
926
+ check_to_s(tc, mtq, field, "\"fox^0.6|brown|fast^50.0\"");
927
+ check_to_s(tc, mtq, (FrtSymbol)NULL, "field:\"fox^0.6|brown|fast^50.0\"");
928
+
929
+
930
+ mtq->boost = 80.1f;
931
+ check_to_s(tc, mtq, (FrtSymbol)NULL, "field:\"fox^0.6|brown|fast^50.0\"^80.1");
932
+ frt_multi_tq_add_term(mtq, "word1");
933
+ check_to_s(tc, mtq, (FrtSymbol)NULL, "field:\"fox^0.6|brown|word1|fast^50.0\"^80.1");
934
+ frt_multi_tq_add_term(mtq, "word2");
935
+ check_to_s(tc, mtq, (FrtSymbol)NULL, "field:\"brown|word1|word2|fast^50.0\"^80.1");
936
+ frt_multi_tq_add_term(mtq, "word3");
937
+ check_to_s(tc, mtq, (FrtSymbol)NULL, "field:\"brown|word1|word2|fast^50.0\"^80.1");
938
+
939
+ /* test MultiTermWeight.to_s */
940
+ w = searcher->create_weight(searcher, mtq);
941
+ sprintf(e, "MultiTermWeight("FRT_DBL2S")", w->value);
942
+ t = w->to_s(w); Asequal(e, t); free(t);
943
+ mtq->boost = 10.5f;
944
+ sprintf(e, "MultiTermWeight("FRT_DBL2S")", w->value);
945
+ t = w->to_s(w); Asequal(e, t); free(t);
946
+ w->destroy(w);
947
+
948
+ frt_q_deref(mtq);
949
+
950
+ /* exercise tdew_skip_to */
951
+ mtq = frt_multi_tq_new_conf(field, 4, 0.5);
952
+ frt_multi_tq_add_term(mtq, "brown");
953
+ frt_multi_tq_add_term_boost(mtq, "fox", 0.6f);
954
+ frt_multi_tq_add_term(mtq, "word1");
955
+ bq = frt_bq_new(false);
956
+ frt_bq_add_query_nr(bq, frt_tq_new(field, "quick"), FRT_BC_MUST);
957
+ frt_bq_add_query(bq, mtq, FRT_BC_MUST);
958
+ tst_check_hits(tc, searcher, bq, "1, 11, 14, 16, 17", -1);
959
+ check_to_s(tc, bq, field, "+quick +\"fox^0.6|brown|word1\"");
960
+ check_to_s(tc, bq, (FrtSymbol)NULL, "+field:quick +field:\"fox^0.6|brown|word1\"");
961
+ frt_q_deref(bq);
962
+ frt_q_deref(mtq);
963
+
964
+ /* test incorrect field explanation */
965
+ mtq = frt_multi_tq_new_conf(rb_intern("hello"), 4, 0.5);
966
+ frt_multi_tq_add_term(mtq, "brown");
967
+ frt_multi_tq_add_term(mtq, "quick");
968
+ exp = frt_searcher_explain(searcher, mtq, 0);
969
+ Afequal(0.0, exp->value);
970
+ Asequal("field \"hello\" does not exist in the index", exp->description);
971
+
972
+ frt_q_deref(mtq);
973
+ }
974
+
975
+ static void test_multi_term_query_hash(TestCase *tc, void *data)
976
+ {
977
+ FrtQuery *q1 = frt_multi_tq_new_conf(field, 100, 0.4);
978
+ FrtQuery *q2 = frt_multi_tq_new(field);
979
+ (void)data;
980
+
981
+
982
+ check_to_s(tc, q1, (FrtSymbol)NULL, "field:\"\"");
983
+ Assert(frt_q_hash(q1) == frt_q_hash(q2), "Queries should be equal");
984
+ Assert(frt_q_eq(q1, q1), "Same queries should be equal");
985
+ Assert(frt_q_eq(q1, q2), "Queries should be equal");
986
+
987
+ frt_multi_tq_add_term(q1, "word1");
988
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Queries should not be equal");
989
+ Assert(!frt_q_eq(q1, q2), "Queries should not be equal");
990
+
991
+ frt_multi_tq_add_term(q2, "word1");
992
+ Assert(frt_q_hash(q1) == frt_q_hash(q2), "Queries should be equal");
993
+ Assert(frt_q_eq(q1, q2), "Queries should be equal");
994
+
995
+ frt_multi_tq_add_term(q1, "word2");
996
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Queries should not be equal");
997
+ Assert(!frt_q_eq(q1, q2), "Queries should not be equal");
998
+
999
+ frt_multi_tq_add_term_boost(q2, "word2", 1.5);
1000
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Queries should not be equal");
1001
+ Assert(!frt_q_eq(q1, q2), "Queries should not be equal");
1002
+
1003
+ frt_q_deref(q1);
1004
+ frt_q_deref(q2);
1005
+ }
1006
+
1007
+ static void test_prefix_query(TestCase *tc, void *data)
1008
+ {
1009
+ FrtSearcher *searcher = (FrtSearcher *)data;
1010
+ FrtQuery *prq = frt_prefixq_new(cat, "cat1");
1011
+ check_to_s(tc, prq, cat, "cat1*");
1012
+ tst_check_hits(tc, searcher, prq, "0, 1, 2, 3, 4, 13, 14, 15, 16, 17", -1);
1013
+ frt_q_deref(prq);
1014
+
1015
+ prq = frt_prefixq_new(cat, "cat1/sub2");
1016
+ check_to_s(tc, prq, cat, "cat1/sub2*");
1017
+ prq->boost = 20.0f;
1018
+ check_to_s(tc, prq, cat, "cat1/sub2*^20.0");
1019
+ tst_check_hits(tc, searcher, prq, "3, 4, 13, 15", -1);
1020
+ frt_q_deref(prq);
1021
+
1022
+ prq = frt_prefixq_new(cat, "cat1/sub");
1023
+ check_to_s(tc, prq, cat, "cat1/sub*");
1024
+ tst_check_hits(tc, searcher, prq, "1, 2, 3, 4, 13, 14, 15, 16", -1);
1025
+ frt_q_deref(prq);
1026
+
1027
+ prq = frt_prefixq_new(rb_intern("unknown field"), "cat1/sub");
1028
+ check_to_s(tc, prq, cat, "unknown field:cat1/sub*");
1029
+ tst_check_hits(tc, searcher, prq, "", -1);
1030
+ frt_q_deref(prq);
1031
+
1032
+ prq = frt_prefixq_new(cat, "unknown_term");
1033
+ check_to_s(tc, prq, cat, "unknown_term*");
1034
+ tst_check_hits(tc, searcher, prq, "", -1);
1035
+ frt_q_deref(prq);
1036
+ }
1037
+
1038
+ static void test_prefix_query_hash(TestCase *tc, void *data)
1039
+ {
1040
+ FrtQuery *q1, *q2;
1041
+ (void)data;
1042
+ q1 = frt_prefixq_new(rb_intern("A"), "a");
1043
+
1044
+ q2 = frt_prefixq_new(rb_intern("A"), "a");
1045
+ Aiequal(frt_q_hash(q1), frt_q_hash(q2));
1046
+ Assert(frt_q_eq(q1, q2), "TermQueries are equal");
1047
+ Assert(frt_q_eq(q1, q1), "TermQueries are same");
1048
+ frt_q_deref(q2);
1049
+
1050
+ q2 = frt_prefixq_new(rb_intern("A"), "b");
1051
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "TermQueries are not equal");
1052
+ Assert(!frt_q_eq(q1, q2), "TermQueries are not equal");
1053
+ frt_q_deref(q2);
1054
+
1055
+ q2 = frt_prefixq_new(rb_intern("B"), "a");
1056
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "TermQueries are not equal");
1057
+ Assert(!frt_q_eq(q1, q2), "TermQueries are not equal");
1058
+ frt_q_deref(q2);
1059
+
1060
+ frt_q_deref(q1);
1061
+ }
1062
+
1063
+ static void rq_new_lower_gt_upper(void *p)
1064
+ { (void)p; frt_rq_new(date, "20050101", "20040101", true, true); }
1065
+
1066
+ static void rq_new_include_lower_and_null_lower(void *p)
1067
+ { (void)p; frt_rq_new(date, NULL, "20040101", true, true); }
1068
+
1069
+ static void rq_new_include_upper_and_null_upper(void *p)
1070
+ { (void)p; frt_rq_new(date, "20050101", NULL, true, true); }
1071
+
1072
+ static void rq_new_null_lower_and_upper(void *p)
1073
+ { (void)p; frt_rq_new(date, NULL, NULL, false, false); }
1074
+
1075
+ static void test_range_query(TestCase *tc, void *data)
1076
+ {
1077
+ FrtSearcher *searcher = (FrtSearcher *)data;
1078
+ FrtQuery *rq;
1079
+
1080
+ Araise(FRT_ARG_ERROR, &rq_new_lower_gt_upper, NULL);
1081
+ Araise(FRT_ARG_ERROR, &rq_new_include_lower_and_null_lower, NULL);
1082
+ Araise(FRT_ARG_ERROR, &rq_new_include_upper_and_null_upper, NULL);
1083
+ Araise(FRT_ARG_ERROR, &rq_new_null_lower_and_upper, NULL);
1084
+
1085
+ rq = frt_rq_new(date, "20051006", "20051010", true, true);
1086
+ tst_check_hits(tc, searcher, rq, "6,7,8,9,10", -1);
1087
+ frt_q_deref(rq);
1088
+
1089
+ rq = frt_rq_new(date, "20051006", "20051010", false, true);
1090
+ tst_check_hits(tc, searcher, rq, "7,8,9,10", -1);
1091
+ frt_q_deref(rq);
1092
+
1093
+ rq = frt_rq_new(date, "20051006", "20051010", true, false);
1094
+ tst_check_hits(tc, searcher, rq, "6,7,8,9", -1);
1095
+ frt_q_deref(rq);
1096
+
1097
+ rq = frt_rq_new(date, "20051006", "20051010", false, false);
1098
+ tst_check_hits(tc, searcher, rq, "7,8,9", -1);
1099
+ frt_q_deref(rq);
1100
+
1101
+ rq = frt_rq_new(date, NULL, "20051003", false, true);
1102
+ tst_check_hits(tc, searcher, rq, "0,1,2,3", -1);
1103
+ frt_q_deref(rq);
1104
+
1105
+ rq = frt_rq_new(date, NULL, "20051003", false, false);
1106
+ tst_check_hits(tc, searcher, rq, "0,1,2", -1);
1107
+ frt_q_deref(rq);
1108
+
1109
+ rq = frt_rq_new_less(date, "20051003", true);
1110
+ tst_check_hits(tc, searcher, rq, "0,1,2,3", -1);
1111
+ frt_q_deref(rq);
1112
+
1113
+ rq = frt_rq_new_less(date, "20051003", false);
1114
+ tst_check_hits(tc, searcher, rq, "0,1,2", -1);
1115
+ frt_q_deref(rq);
1116
+
1117
+ rq = frt_rq_new(date, "20051014", NULL, true, false);
1118
+ tst_check_hits(tc, searcher, rq, "14,15,16,17", -1);
1119
+ frt_q_deref(rq);
1120
+
1121
+ rq = frt_rq_new(date, "20051014", NULL, false, false);
1122
+ tst_check_hits(tc, searcher, rq, "15,16,17", -1);
1123
+ frt_q_deref(rq);
1124
+
1125
+ rq = frt_rq_new_more(date, "20051014", true);
1126
+ tst_check_hits(tc, searcher, rq, "14,15,16,17", -1);
1127
+ frt_q_deref(rq);
1128
+
1129
+ rq = frt_rq_new_more(date, "20051014", false);
1130
+ tst_check_hits(tc, searcher, rq, "15,16,17", -1);
1131
+ frt_q_deref(rq);
1132
+
1133
+ rq = frt_rq_new(rb_intern("not_a_field"), "20051006", "20051010", false, false);
1134
+ tst_check_hits(tc, searcher, rq, "", -1);
1135
+ frt_q_deref(rq);
1136
+
1137
+ /* below range - no results */
1138
+ rq = frt_rq_new(date, "10051006", "10051010", false, false);
1139
+ tst_check_hits(tc, searcher, rq, "", -1);
1140
+ frt_q_deref(rq);
1141
+
1142
+ /* above range - no results */
1143
+ rq = frt_rq_new(date, "30051006", "30051010", false, false);
1144
+ tst_check_hits(tc, searcher, rq, "", -1);
1145
+ frt_q_deref(rq);
1146
+
1147
+ /* test get_matchv_i */
1148
+ /* NOTE: if you are reading this to learn how to use RangeQuery the
1149
+ * following is not a good idea. You should usually only use a RangeQuery
1150
+ * on an untokenized field. This is just done for testing purposes to
1151
+ * check that it works correctly. */
1152
+ rq = frt_rq_new(field, "word1", "word3", true, true);
1153
+ tst_check_hits(tc, searcher, rq, "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17", -1);
1154
+ check_match_vector(tc, searcher, rq, 2, rb_intern("not a field"), "");
1155
+ check_match_vector(tc, searcher, rq, 2, field, "0,0,1,1");
1156
+ frt_q_deref(rq);
1157
+
1158
+ rq = frt_rq_new(field, "word1", "word3", false, true);
1159
+ check_match_vector(tc, searcher, rq, 2, field, "1,1");
1160
+ frt_q_deref(rq);
1161
+
1162
+ rq = frt_rq_new(field, "word1", "word3", true, false);
1163
+ check_match_vector(tc, searcher, rq, 2, field, "0,0");
1164
+ frt_q_deref(rq);
1165
+
1166
+ rq = frt_rq_new(field, "word1", "word3", false, false);
1167
+ check_match_vector(tc, searcher, rq, 2, field, "");
1168
+ frt_q_deref(rq);
1169
+ }
1170
+
1171
+ static void test_range_query_hash(TestCase *tc, void *data)
1172
+ {
1173
+ FrtQuery *q1, *q2;
1174
+ (void)data;
1175
+ q1 = frt_rq_new(date, "20051006", "20051010", true, true);
1176
+ q2 = frt_rq_new(date, "20051006", "20051010", true, true);
1177
+
1178
+ Assert(frt_q_eq(q1, q1), "Test same queries are equal");
1179
+ Aiequal(frt_q_hash(q1), frt_q_hash(q2));
1180
+ Assert(frt_q_eq(q1, q2), "Queries are equal");
1181
+ frt_q_deref(q2);
1182
+
1183
+ q2 = frt_rq_new(date, "20051006", "20051010", true, false);
1184
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Upper bound include differs");
1185
+ Assert(!frt_q_eq(q1, q2), "Upper bound include differs");
1186
+ frt_q_deref(q2);
1187
+
1188
+ q2 = frt_rq_new(date, "20051006", "20051010", false, true);
1189
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Lower bound include differs");
1190
+ Assert(!frt_q_eq(q1, q2), "Lower bound include differs");
1191
+ frt_q_deref(q2);
1192
+
1193
+ q2 = frt_rq_new(date, "20051006", "20051011", true, true);
1194
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Upper bound differs");
1195
+ Assert(!frt_q_eq(q1, q2), "Upper bound differs");
1196
+ frt_q_deref(q2);
1197
+
1198
+ q2 = frt_rq_new(date, "20051005", "20051010", true, true);
1199
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Lower bound differs");
1200
+ Assert(!frt_q_eq(q1, q2), "Lower bound differs");
1201
+ frt_q_deref(q2);
1202
+
1203
+ q2 = frt_rq_new(date, "20051006", NULL, true, false);
1204
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Upper bound is NULL");
1205
+ Assert(!frt_q_eq(q1, q2), "Upper bound is NULL");
1206
+ frt_q_deref(q2);
1207
+
1208
+ q2 = frt_rq_new(date, NULL, "20051010", false, true);
1209
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Lower bound is NULL");
1210
+ Assert(!frt_q_eq(q1, q2), "Lower bound is NULL");
1211
+ frt_q_deref(q2);
1212
+
1213
+ q2 = frt_rq_new(field, "20051006", "20051010", true, true);
1214
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Field differs");
1215
+ Assert(!frt_q_eq(q1, q2), "Field differs");
1216
+ frt_q_deref(q2);
1217
+ frt_q_deref(q1);
1218
+
1219
+ q1 = frt_rq_new(date, NULL, "20051010", false, true);
1220
+ q2 = frt_rq_new(date, NULL, "20051010", false, true);
1221
+ Aiequal(frt_q_hash(q1), frt_q_hash(q2));
1222
+ Assert(frt_q_eq(q1, q2), "Queries are equal");
1223
+ frt_q_deref(q2);
1224
+ frt_q_deref(q1);
1225
+
1226
+ q1 = frt_rq_new(date, "20051010", NULL, true, false);
1227
+ q2 = frt_rq_new(date, "20051010", NULL, true, false);
1228
+ Aiequal(frt_q_hash(q1), frt_q_hash(q2));
1229
+ Assert(frt_q_eq(q1, q2), "Queries are equal");
1230
+ frt_q_deref(q2);
1231
+ frt_q_deref(q1);
1232
+ }
1233
+
1234
+ static void trq_new_int_lower_gt_upper(void *p)
1235
+ { (void)p; frt_trq_new(date, "20050101", "20040101", true, true); }
1236
+
1237
+ static void trq_new_float_lower_gt_upper(void *p)
1238
+ { (void)p; frt_trq_new(number, "2.5", "-2.5", true, true); }
1239
+
1240
+ static void trq_new_string_lower_gt_upper(void *p)
1241
+ { (void)p; frt_trq_new(cat, "cat_b", "cat_a", true, true); }
1242
+
1243
+ static void trq_new_include_lower_and_null_lower(void *p)
1244
+ { (void)p; frt_trq_new(date, NULL, "20040101", true, true); }
1245
+
1246
+ static void trq_new_include_upper_and_null_upper(void *p)
1247
+ { (void)p; frt_trq_new(date, "20050101", NULL, true, true); }
1248
+
1249
+ static void trq_new_null_lower_and_upper(void *p)
1250
+ { (void)p; frt_trq_new(date, NULL, NULL, false, false); }
1251
+
1252
+ static void test_typed_range_query(TestCase *tc, void *data)
1253
+ {
1254
+ FrtSearcher *searcher = (FrtSearcher *)data;
1255
+ FrtQuery *trq;
1256
+
1257
+ Araise(FRT_ARG_ERROR, trq_new_int_lower_gt_upper, NULL);
1258
+ Araise(FRT_ARG_ERROR, trq_new_float_lower_gt_upper, NULL);
1259
+ Araise(FRT_ARG_ERROR, trq_new_string_lower_gt_upper, NULL);
1260
+ Araise(FRT_ARG_ERROR, trq_new_include_lower_and_null_lower, NULL);
1261
+ Araise(FRT_ARG_ERROR, trq_new_include_upper_and_null_upper, NULL);
1262
+ Araise(FRT_ARG_ERROR, trq_new_null_lower_and_upper, NULL);
1263
+
1264
+ trq = frt_trq_new(number, "-1.0", "1.0", true, true);
1265
+ tst_check_hits(tc, searcher, trq, "0,1,4,10,15,17", -1);
1266
+ check_match_vector(tc, searcher, trq, 0, number, "0,0");
1267
+ check_match_vector(tc, searcher, trq, 10, number, "0,0");
1268
+ check_match_vector(tc, searcher, trq, 17, number, "0,0");
1269
+ check_match_vector(tc, searcher, trq, 2, number, "");
1270
+ frt_q_deref(trq);
1271
+
1272
+ trq = frt_trq_new(number, "-1.0", "1.0", false, false);
1273
+ tst_check_hits(tc, searcher, trq, "0,1,4,15", -1);
1274
+ check_match_vector(tc, searcher, trq, 0, number, "0,0");
1275
+ check_match_vector(tc, searcher, trq, 10, number, "");
1276
+ check_match_vector(tc, searcher, trq, 17, number, "");
1277
+ frt_q_deref(trq);
1278
+
1279
+ trq = frt_trq_new(number, "-1.0", "1.0", false, true);
1280
+ tst_check_hits(tc, searcher, trq, "0,1,4,10,15", -1);
1281
+ check_match_vector(tc, searcher, trq, 0, number, "0,0");
1282
+ check_match_vector(tc, searcher, trq, 10, number, "0,0");
1283
+ check_match_vector(tc, searcher, trq, 17, number, "");
1284
+ frt_q_deref(trq);
1285
+
1286
+ trq = frt_trq_new(number, "-1.0", "1.0", true, false);
1287
+ tst_check_hits(tc, searcher, trq, "0,1,4,15,17", -1);
1288
+ check_match_vector(tc, searcher, trq, 0, number, "0,0");
1289
+ check_match_vector(tc, searcher, trq, 10, number, "");
1290
+ check_match_vector(tc, searcher, trq, 17, number, "0,0");
1291
+ frt_q_deref(trq);
1292
+
1293
+ /* test field with no numbers */
1294
+ trq = frt_trq_new(field, "-1.0", "1.0", false, true);
1295
+ tst_check_hits(tc, searcher, trq, "", -1);
1296
+ check_match_vector(tc, searcher, trq, 0, number, "");
1297
+ frt_q_deref(trq);
1298
+
1299
+ /* test empty field */
1300
+ trq = frt_trq_new(rb_intern("empty-field"), "-1.0", "1.0", false, true);
1301
+ tst_check_hits(tc, searcher, trq, "", -1);
1302
+ check_match_vector(tc, searcher, trq, 0, number, "");
1303
+ frt_q_deref(trq);
1304
+
1305
+ /* FIXME: This was a hexidecimal test but unfortunately scanf doesn't do
1306
+ * hexidecimal on some machines. Would be nice to test for this in
1307
+ * ./configure when we eventually integrate autotools */
1308
+ /* text hexadecimal */
1309
+ trq = frt_trq_new(number, "1.0", "10", false, true);
1310
+ tst_check_hits(tc, searcher, trq, "6,7,9,12", -1);
1311
+ frt_q_deref(trq);
1312
+
1313
+ /* test single bound */
1314
+ trq = frt_trq_new(number, NULL, "0", false, true);
1315
+ tst_check_hits(tc, searcher, trq, "1,5,11,15,16,17", -1);
1316
+ check_match_vector(tc, searcher, trq, 1, number, "0.0");
1317
+ check_match_vector(tc, searcher, trq, 5, number, "0,0");
1318
+ frt_q_deref(trq);
1319
+
1320
+ trq = frt_trq_new_less(number, "0", true);
1321
+ tst_check_hits(tc, searcher, trq, "1,5,11,15,16,17", -1);
1322
+ check_match_vector(tc, searcher, trq, 1, number, "0.0");
1323
+ check_match_vector(tc, searcher, trq, 5, number, "0,0");
1324
+ frt_q_deref(trq);
1325
+
1326
+ trq = frt_trq_new(number, NULL, "0", false, false);
1327
+ tst_check_hits(tc, searcher, trq, "5,11,15,16,17", -1);
1328
+ check_match_vector(tc, searcher, trq, 1, number, "");
1329
+ check_match_vector(tc, searcher, trq, 5, number, "0,0");
1330
+ frt_q_deref(trq);
1331
+
1332
+ trq = frt_trq_new_less(number, "0", false);
1333
+ tst_check_hits(tc, searcher, trq, "5,11,15,16,17", -1);
1334
+ check_match_vector(tc, searcher, trq, 1, number, "");
1335
+ check_match_vector(tc, searcher, trq, 5, number, "0,0");
1336
+ frt_q_deref(trq);
1337
+
1338
+ /* test single bound */
1339
+ trq = frt_trq_new(number, "0", NULL, true, false);
1340
+ tst_check_hits(tc, searcher, trq, "0,1,2,3,4,6,7,8,9,10,12,13,14", -1);
1341
+ check_match_vector(tc, searcher, trq, 1, number, "0.0");
1342
+ check_match_vector(tc, searcher, trq, 0, number, "0,0");
1343
+ frt_q_deref(trq);
1344
+
1345
+ trq = frt_trq_new_more(number, "0", true);
1346
+ tst_check_hits(tc, searcher, trq, "0,1,2,3,4,6,7,8,9,10,12,13,14", -1);
1347
+ check_match_vector(tc, searcher, trq, 1, number, "0.0");
1348
+ check_match_vector(tc, searcher, trq, 0, number, "0,0");
1349
+ frt_q_deref(trq);
1350
+
1351
+ trq = frt_trq_new(number, "0", NULL, false, false);
1352
+ tst_check_hits(tc, searcher, trq, "0,2,3,4,6,7,8,9,10,12,13,14", -1);
1353
+ check_match_vector(tc, searcher, trq, 1, number, "");
1354
+ check_match_vector(tc, searcher, trq, 0, number, "0,0");
1355
+ frt_q_deref(trq);
1356
+
1357
+ trq = frt_trq_new_more(number, "0", false);
1358
+ tst_check_hits(tc, searcher, trq, "0,2,3,4,6,7,8,9,10,12,13,14", -1);
1359
+ check_match_vector(tc, searcher, trq, 1, number, "");
1360
+ check_match_vector(tc, searcher, trq, 0, number, "0,0");
1361
+ frt_q_deref(trq);
1362
+
1363
+ /* below range - no results */
1364
+ trq = frt_trq_new(number, "10051006", "10051010", false, false);
1365
+ tst_check_hits(tc, searcher, trq, "", -1);
1366
+ frt_q_deref(trq);
1367
+
1368
+ /* above range - no results */
1369
+ trq = frt_trq_new(number, "-12518421", "-12518420", true, true);
1370
+ tst_check_hits(tc, searcher, trq, "", -1);
1371
+ frt_q_deref(trq);
1372
+
1373
+ /* should be normal range query for string fields */
1374
+ trq = frt_trq_new(cat, "cat2", NULL, true, false);
1375
+ tst_check_hits(tc, searcher, trq, "5,6,7,8,9,10,11,12", -1);
1376
+ frt_q_deref(trq);
1377
+
1378
+ /* test get_matchv_i */
1379
+ /* NOTE: if you are reading this to learn how to use RangeQuery the
1380
+ * following is not a good idea. You should usually only use a RangeQuery
1381
+ * on an untokenized field. This is just done for testing purposes to
1382
+ * check that it works correctly. */
1383
+ /* The following tests should use the basic RangeQuery functionality */
1384
+ trq = frt_trq_new(field, "word1", "word3", true, true);
1385
+ tst_check_hits(tc, searcher, trq, "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17", -1);
1386
+ check_match_vector(tc, searcher, trq, 2, rb_intern("not a field"), "");
1387
+ check_match_vector(tc, searcher, trq, 2, field, "0,0,1,1");
1388
+ frt_q_deref(trq);
1389
+
1390
+ trq = frt_trq_new(field, "word1", "word3", false, true);
1391
+ check_match_vector(tc, searcher, trq, 2, field, "1,1");
1392
+ frt_q_deref(trq);
1393
+
1394
+ trq = frt_trq_new(field, "word1", "word3", true, false);
1395
+ check_match_vector(tc, searcher, trq, 2, field, "0,0");
1396
+ frt_q_deref(trq);
1397
+
1398
+ trq = frt_trq_new(field, "word1", "word3", false, false);
1399
+ check_match_vector(tc, searcher, trq, 2, field, "");
1400
+ frt_q_deref(trq);
1401
+ }
1402
+
1403
+ static void test_typed_range_query_hash(TestCase *tc, void *data)
1404
+ {
1405
+ FrtQuery *q1, *q2;
1406
+ (void)data;
1407
+ q1 = frt_trq_new(date, "20051006", "20051010", true, true);
1408
+ q2 = frt_trq_new(date, "20051006", "20051010", true, true);
1409
+
1410
+ Assert(frt_q_eq(q1, q1), "Test same queries are equal");
1411
+ Aiequal(frt_q_hash(q1), frt_q_hash(q2));
1412
+ Assert(frt_q_eq(q1, q2), "Queries are equal");
1413
+ frt_q_deref(q2);
1414
+
1415
+ q2 = frt_trq_new(date, "20051006", "20051010", true, false);
1416
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Upper bound include differs");
1417
+ Assert(!frt_q_eq(q1, q2), "Upper bound include differs");
1418
+ frt_q_deref(q2);
1419
+
1420
+ q2 = frt_trq_new(date, "20051006", "20051010", false, true);
1421
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Lower bound include differs");
1422
+ Assert(!frt_q_eq(q1, q2), "Lower bound include differs");
1423
+ frt_q_deref(q2);
1424
+
1425
+ q2 = frt_trq_new(date, "20051006", "20051011", true, true);
1426
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Upper bound differs");
1427
+ Assert(!frt_q_eq(q1, q2), "Upper bound differs");
1428
+ frt_q_deref(q2);
1429
+
1430
+ q2 = frt_trq_new(date, "20051005", "20051010", true, true);
1431
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Lower bound differs");
1432
+ Assert(!frt_q_eq(q1, q2), "Lower bound differs");
1433
+ frt_q_deref(q2);
1434
+
1435
+ q2 = frt_trq_new(date, "20051006", NULL, true, false);
1436
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Upper bound is NULL");
1437
+ Assert(!frt_q_eq(q1, q2), "Upper bound is NULL");
1438
+ frt_q_deref(q2);
1439
+
1440
+ q2 = frt_trq_new(date, NULL, "20051010", false, true);
1441
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Lower bound is NULL");
1442
+ Assert(!frt_q_eq(q1, q2), "Lower bound is NULL");
1443
+ frt_q_deref(q2);
1444
+
1445
+ q2 = frt_trq_new(field, "20051006", "20051010", true, true);
1446
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Field differs");
1447
+ Assert(!frt_q_eq(q1, q2), "Field differs");
1448
+ frt_q_deref(q2);
1449
+ frt_q_deref(q1);
1450
+
1451
+ q1 = frt_trq_new(date, NULL, "20051010", false, true);
1452
+ q2 = frt_trq_new(date, NULL, "20051010", false, true);
1453
+ Aiequal(frt_q_hash(q1), frt_q_hash(q2));
1454
+ Assert(frt_q_eq(q1, q2), "Queries are equal");
1455
+ frt_q_deref(q2);
1456
+ frt_q_deref(q1);
1457
+
1458
+ q1 = frt_trq_new(date, "20051010", NULL, true, false);
1459
+ q2 = frt_trq_new(date, "20051010", NULL, true, false);
1460
+ Aiequal(frt_q_hash(q1), frt_q_hash(q2));
1461
+ Assert(frt_q_eq(q1, q2), "Queries are equal");
1462
+ frt_q_deref(q2);
1463
+ frt_q_deref(q1);
1464
+
1465
+ q1 = frt_trq_new(date, "20051010", NULL, true, false);
1466
+ q2 = frt_rq_new(date, "20051010", NULL, true, false);
1467
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "TypedRangeQuery is not RangeQuery");
1468
+ Assert(!frt_q_eq(q1, q2), "Queries are not equal");
1469
+ frt_q_deref(q2);
1470
+ frt_q_deref(q1);
1471
+ }
1472
+
1473
+ static void test_wildcard_match(TestCase *tc, void *data)
1474
+ {
1475
+ (void)data;
1476
+ (void)tc;
1477
+ Assert(!frt_wc_match("", "abc"), "Empty pattern matches nothing");
1478
+ Assert(frt_wc_match("*", "asdasdg"), "Star matches everything");
1479
+ Assert(frt_wc_match("asd*", "asdasdg"), "Star matches everything after");
1480
+ Assert(frt_wc_match("*dg", "asdasdg"), "Star matches everything before");
1481
+ Assert(frt_wc_match("a?d*", "asdasdg"), "Q-mark matchs one char");
1482
+ Assert(frt_wc_match("?sd*", "asdasdg"), "Q-mark can come first");
1483
+ Assert(frt_wc_match("asd?", "asdg"), "Q-mark can come last");
1484
+ Assert(frt_wc_match("asdg", "asdg"), "No special chars");
1485
+ Assert(!frt_wc_match("asdf", "asdi"), "Do not match");
1486
+ Assert(!frt_wc_match("asd??", "asdg"), "Q-mark must match");
1487
+ Assert(frt_wc_match("as?g", "asdg"), "Q-mark matches in");
1488
+ Assert(!frt_wc_match("as??g", "asdg"), "Q-mark must match");
1489
+ Assert(frt_wc_match("a*?f", "asdf"), "Q-mark and star can appear together");
1490
+ Assert(frt_wc_match("a?*f", "asdf"), "Q-mark and star can appear together");
1491
+ Assert(frt_wc_match("a*?df", "asdf"), "Q-mark and star can appear together");
1492
+ Assert(frt_wc_match("a?*df", "asdf"), "Q-mark and star can appear together");
1493
+ Assert(!frt_wc_match("as*?df", "asdf"), "Q-mark must match");
1494
+ Assert(!frt_wc_match("as?*df", "asdf"), "Q-mark must match");
1495
+ Assert(frt_wc_match("asdf*", "asdf"), "Star can match nothing");
1496
+ Assert(frt_wc_match("asd*f", "asdf"), "Star can match nothing");
1497
+ Assert(frt_wc_match("*asdf*", "asdf"), "Star can match nothing");
1498
+ Assert(frt_wc_match("asd?*****", "asdf"), "Can have multiple stars");
1499
+ Assert(frt_wc_match("as?*****g", "asdg"), "Can have multiple stars");
1500
+ Assert(!frt_wc_match("*asdf", "asdi"), "Do not match");
1501
+ Assert(!frt_wc_match("asdf*", "asdi"), "Do not match");
1502
+ Assert(!frt_wc_match("*asdf*", "asdi"), "Do not match");
1503
+ Assert(!frt_wc_match("cat1*", "cat2/sub1"), "Do not match");
1504
+ }
1505
+
1506
+ static void test_wildcard_query(TestCase *tc, void *data)
1507
+ {
1508
+ FrtSearcher *searcher = (FrtSearcher *)data;
1509
+ FrtQuery *wq = frt_wcq_new(cat, "cat1*"), *bq;
1510
+ tst_check_hits(tc, searcher, wq, "0, 1, 2, 3, 4, 13, 14, 15, 16, 17", -1);
1511
+ frt_q_deref(wq);
1512
+
1513
+ wq = frt_wcq_new(cat, "cat1*/s*sub2");
1514
+ tst_check_hits(tc, searcher, wq, "4, 16", -1);
1515
+ frt_q_deref(wq);
1516
+
1517
+ wq = frt_wcq_new(cat, "cat1/sub?/su??ub2");
1518
+ tst_check_hits(tc, searcher, wq, "4, 16", -1);
1519
+ frt_q_deref(wq);
1520
+
1521
+ wq = frt_wcq_new(cat, "cat1/");
1522
+ tst_check_hits(tc, searcher, wq, "0, 17", -1);
1523
+ frt_q_deref(wq);
1524
+
1525
+ wq = frt_wcq_new(rb_intern("unknown_field"), "cat1/");
1526
+ tst_check_hits(tc, searcher, wq, "", -1);
1527
+ frt_q_deref(wq);
1528
+
1529
+ wq = frt_wcq_new(cat, "unknown_term");
1530
+ tst_check_hits(tc, searcher, wq, "", -1);
1531
+ frt_q_deref(wq);
1532
+
1533
+ bq = frt_bq_new(false);
1534
+ frt_bq_add_query_nr(bq, frt_tq_new(field, "word1"), FRT_BC_MUST);
1535
+ wq = frt_wcq_new(cat, "cat1*");
1536
+ tst_check_hits(tc, searcher, wq, "0, 1, 2, 3, 4, 13, 14, 15, 16, 17", -1);
1537
+
1538
+ frt_bq_add_query_nr(bq, wq, FRT_BC_MUST);
1539
+ tst_check_hits(tc, searcher, bq, "0, 1, 2, 3, 4, 13, 14, 15, 16, 17", -1);
1540
+
1541
+ frt_q_deref(bq);
1542
+ }
1543
+
1544
+ static void test_wildcard_query_hash(TestCase *tc, void *data)
1545
+ {
1546
+ FrtQuery *q1, *q2;
1547
+ (void)data;
1548
+ q1 = frt_wcq_new(rb_intern("A"), "a*");
1549
+
1550
+ q2 = frt_wcq_new(rb_intern("A"), "a*");
1551
+ Assert(frt_q_eq(q1, q1), "Test same queries are equal");
1552
+ Aiequal(frt_q_hash(q1), frt_q_hash(q2));
1553
+ Assert(frt_q_eq(q1, q2), "Queries are equal");
1554
+ frt_q_deref(q2);
1555
+
1556
+ q2 = frt_wcq_new(rb_intern("A"), "a?");
1557
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Queries are not equal");
1558
+ Assert(!frt_q_eq(q1, q2), "Queries are not equal");
1559
+ frt_q_deref(q2);
1560
+
1561
+ q2 = frt_wcq_new(rb_intern("B"), "a?");
1562
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Queries are not equal");
1563
+ Assert(!frt_q_eq(q1, q2), "Queries are not equal");
1564
+ frt_q_deref(q2);
1565
+
1566
+ frt_q_deref(q1);
1567
+ }
1568
+
1569
+ static void test_match_all_query_hash(TestCase *tc, void *data)
1570
+ {
1571
+ FrtQuery *q1, *q2;
1572
+ (void)data;
1573
+ q1 = frt_maq_new();
1574
+ q2 = frt_maq_new();
1575
+
1576
+ Assert(frt_q_eq(q1, q1), "Test same queries are equal");
1577
+ Aiequal(frt_q_hash(q1), frt_q_hash(q2));
1578
+ Assert(frt_q_eq(q1, q2), "Queries are equal");
1579
+ frt_q_deref(q2);
1580
+
1581
+ q2 = frt_wcq_new(rb_intern("A"), "a*");
1582
+ Assert(frt_q_hash(q1) != frt_q_hash(q2), "Queries are not equal");
1583
+ Assert(!frt_q_eq(q1, q2), "Queries are not equal");
1584
+ frt_q_deref(q2);
1585
+
1586
+ frt_q_deref(q1);
1587
+ }
1588
+
1589
+ static void test_search_unscored(TestCase *tc, void *data)
1590
+ {
1591
+ FrtSearcher *searcher = (FrtSearcher *)data;
1592
+ int buf[5], expected[5], count;
1593
+ FrtQuery *tq = frt_tq_new(field, "word1");
1594
+ count = frt_searcher_search_unscored(searcher, tq, buf, 5, 0);
1595
+ Aiequal(s2l("0, 1, 2, 3, 4", expected), count);
1596
+ Aaiequal(expected, buf, count);
1597
+ count = frt_searcher_search_unscored(searcher, tq, buf, 5, 1);
1598
+ Aiequal(s2l("1, 2, 3, 4, 5", expected), count);
1599
+ Aaiequal(expected, buf, count);
1600
+ count = frt_searcher_search_unscored(searcher, tq, buf, 5, 12);
1601
+ Aiequal(s2l("12, 13, 14, 15, 16", expected), count);
1602
+ Aaiequal(expected, buf, count);
1603
+ count = frt_searcher_search_unscored(searcher, tq, buf, 5, 15);
1604
+ Aiequal(s2l("15, 16, 17", expected), count);
1605
+ Aaiequal(expected, buf, count);
1606
+ count = frt_searcher_search_unscored(searcher, tq, buf, 5, 16);
1607
+ Aiequal(s2l("16, 17", expected), count);
1608
+ Aaiequal(expected, buf, count);
1609
+ count = frt_searcher_search_unscored(searcher, tq, buf, 5, 17);
1610
+ Aiequal(s2l("17", expected), count);
1611
+ Aaiequal(expected, buf, count);
1612
+ count = frt_searcher_search_unscored(searcher, tq, buf, 5, 18);
1613
+ Aiequal(s2l("", expected), count);
1614
+ Aaiequal(expected, buf, count);
1615
+ frt_q_deref(tq);
1616
+
1617
+ tq = frt_tq_new(field, "word3");
1618
+ count = frt_searcher_search_unscored(searcher, tq, buf, 3, 0);
1619
+ Aiequal(s2l("2, 3, 6", expected), count);
1620
+ Aaiequal(expected, buf, count);
1621
+ count = frt_searcher_search_unscored(searcher, tq, buf, 3, 7);
1622
+ Aiequal(s2l("8, 11, 14", expected), count);
1623
+ Aaiequal(expected, buf, count);
1624
+ count = frt_searcher_search_unscored(searcher, tq, buf, 3, 6);
1625
+ Aiequal(s2l("6, 8, 11", expected), count);
1626
+ Aaiequal(expected, buf, count);
1627
+ count = frt_searcher_search_unscored(searcher, tq, buf, 3, 11);
1628
+ Aiequal(s2l("11, 14", expected), count);
1629
+ Aaiequal(expected, buf, count);
1630
+ count = frt_searcher_search_unscored(searcher, tq, buf, 3, 14);
1631
+ Aiequal(s2l("14", expected), count);
1632
+ Aaiequal(expected, buf, count);
1633
+ count = frt_searcher_search_unscored(searcher, tq, buf, 3, 15);
1634
+ Aiequal(s2l("", expected), count);
1635
+ Aaiequal(expected, buf, count);
1636
+ frt_q_deref(tq);
1637
+ }
1638
+
1639
+ TestSuite *ts_search(TestSuite *suite)
1640
+ {
1641
+ FrtStore *store = frt_open_ram_store();
1642
+ FrtIndexReader *ir;
1643
+ FrtSearcher *searcher;
1644
+
1645
+ date = rb_intern("date");
1646
+ field = rb_intern("field");
1647
+ cat = rb_intern("cat");
1648
+ number = rb_intern("number");
1649
+
1650
+ suite = ADD_SUITE(suite);
1651
+
1652
+ tst_run_test(suite, test_explanation, NULL);
1653
+ tst_run_test(suite, test_byte_float_conversion, NULL);
1654
+ tst_run_test(suite, test_default_similarity, NULL);
1655
+
1656
+ prepare_search_index(store);
1657
+ ir = frt_ir_open(store);
1658
+ searcher = frt_isea_new(ir);
1659
+
1660
+ tst_run_test(suite, test_get_doc, (void *)searcher);
1661
+
1662
+ tst_run_test(suite, test_term_query, (void *)searcher);
1663
+ tst_run_test(suite, test_term_query_hash, NULL);
1664
+
1665
+ tst_run_test(suite, test_boolean_query, (void *)searcher);
1666
+ tst_run_test(suite, test_boolean_query_hash, NULL);
1667
+
1668
+ tst_run_test(suite, test_phrase_query, (void *)searcher);
1669
+ tst_run_test(suite, test_phrase_query_hash, NULL);
1670
+
1671
+ tst_run_test(suite, test_multi_phrase_query, (void *)searcher);
1672
+ tst_run_test(suite, test_multi_phrase_query_hash, NULL);
1673
+
1674
+ tst_run_test(suite, test_multi_term_query, (void *)searcher);
1675
+ tst_run_test(suite, test_multi_term_query_hash, NULL);
1676
+
1677
+ tst_run_test(suite, test_prefix_query, (void *)searcher);
1678
+ tst_run_test(suite, test_prefix_query_hash, NULL);
1679
+
1680
+ tst_run_test(suite, test_range_query, (void *)searcher);
1681
+ tst_run_test(suite, test_range_query_hash, NULL);
1682
+
1683
+ tst_run_test(suite, test_typed_range_query, (void *)searcher);
1684
+ tst_run_test(suite, test_typed_range_query_hash, NULL);
1685
+
1686
+ tst_run_test(suite, test_wildcard_match, (void *)searcher);
1687
+ tst_run_test(suite, test_wildcard_query, (void *)searcher);
1688
+ tst_run_test(suite, test_wildcard_query_hash, NULL);
1689
+
1690
+ tst_run_test(suite, test_match_all_query_hash, NULL);
1691
+
1692
+ tst_run_test(suite, test_search_unscored, (void *)searcher);
1693
+
1694
+ frt_store_deref(store);
1695
+ frt_searcher_close(searcher);
1696
+ return suite;
1697
+ }
1698
+
1699
+
1700
+
1701
+ static void prepare_multi_search_index(FrtStore *store, struct Data data[],
1702
+ int d_cnt, int w)
1703
+ {
1704
+ int i;
1705
+ FrtIndexWriter *iw;
1706
+ FrtFieldInfos *fis = frt_fis_new(FRT_STORE_YES,
1707
+ FRT_INDEX_YES,
1708
+ FRT_TERM_VECTOR_WITH_POSITIONS_OFFSETS);
1709
+ FrtFieldInfo *fi = frt_fi_new(rb_intern("empty-field"), FRT_STORE_NO, FRT_INDEX_NO, FRT_TERM_VECTOR_NO);
1710
+ frt_fis_add_field(fis, fi);
1711
+ frt_index_create(store, fis);
1712
+ frt_fis_deref(fis);
1713
+
1714
+ iw = frt_iw_open(store, dbl_analyzer_new(), NULL);
1715
+ for (i = 0; i < d_cnt; i++) {
1716
+ FrtDocument *doc = frt_doc_new();
1717
+ doc->boost = (float)(i+w);
1718
+ frt_doc_add_field(doc, frt_df_add_data(frt_df_new(date), (char *)data[i].date));
1719
+ frt_doc_add_field(doc, frt_df_add_data(frt_df_new(field), (char *)data[i].field));
1720
+ frt_doc_add_field(doc, frt_df_add_data(frt_df_new(cat), (char *)data[i].cat));
1721
+ frt_doc_add_field(doc, frt_df_add_data(frt_df_new(number), (char *)data[i].number));
1722
+ frt_iw_add_doc(iw, doc);
1723
+ frt_doc_destroy(doc);
1724
+ }
1725
+ frt_iw_close(iw);
1726
+ }
1727
+
1728
+ static void test_query_combine(TestCase *tc, void *data)
1729
+ {
1730
+ FrtQuery *q, *cq, **queries;
1731
+ FrtBooleanQuery *bq;
1732
+ (void)data;
1733
+
1734
+ queries = FRT_ALLOC_N(FrtQuery *, 3);
1735
+ queries[0] = frt_tq_new(rb_intern("A"), "a");
1736
+ queries[1] = frt_tq_new(rb_intern("A"), "a");
1737
+ queries[2] = frt_tq_new(rb_intern("A"), "a");
1738
+
1739
+ cq = frt_q_combine(queries, 3);
1740
+ Assert(frt_q_eq(cq, queries[1]), "One unique query submitted");
1741
+ frt_q_deref(cq);
1742
+
1743
+ Aiequal(1, queries[1]->ref_cnt);
1744
+ frt_q_deref(queries[1]);
1745
+
1746
+ q = frt_bq_new(false);
1747
+ frt_bq_add_query_nr(q, frt_tq_new(rb_intern("A"), "a"), FRT_BC_SHOULD);
1748
+ frt_bq_add_query_nr(q, frt_tq_new(rb_intern("A"), "a"), FRT_BC_SHOULD);
1749
+ frt_bq_add_query_nr(q, frt_tq_new(rb_intern("A"), "a"), FRT_BC_SHOULD);
1750
+
1751
+ queries[1] = q;
1752
+
1753
+ cq = frt_q_combine(queries, 3);
1754
+ bq = (FrtBooleanQuery *)cq;
1755
+ Aiequal(2, bq->clause_cnt);
1756
+ Assert(frt_q_eq(bq->clauses[0]->query, queries[0]), "Query should be equal");
1757
+ Assert(frt_q_eq(bq->clauses[1]->query, queries[1]), "Query should be equal");
1758
+ frt_q_deref(cq);
1759
+ frt_q_deref(queries[1]); /* queries[1] */
1760
+
1761
+ q = frt_bq_new(true);
1762
+ frt_bq_add_query_nr(q, frt_tq_new(rb_intern("A"), "a"), FRT_BC_SHOULD);
1763
+ frt_bq_add_query_nr(q, frt_tq_new(rb_intern("A"), "a"), FRT_BC_SHOULD);
1764
+ frt_bq_add_query_nr(q, frt_tq_new(rb_intern("A"), "a"), FRT_BC_SHOULD);
1765
+
1766
+ queries[1] = q;
1767
+
1768
+ cq = frt_q_combine(queries, 3);
1769
+ Assert(frt_q_eq(cq, queries[0]), "Again only one unique query submitted");
1770
+ frt_q_deref(cq);
1771
+ Aiequal(1, queries[0]->ref_cnt);
1772
+
1773
+ frt_bq_add_query_nr(q, frt_tq_new(rb_intern("B"), "b"), FRT_BC_SHOULD);
1774
+ frt_bq_add_query_nr(q, frt_tq_new(rb_intern("C"), "c"), FRT_BC_SHOULD);
1775
+
1776
+ cq = frt_q_combine(queries, 3);
1777
+ Aiequal(BOOLEAN_QUERY, cq->type);
1778
+
1779
+ bq = (FrtBooleanQuery *)cq;
1780
+ Aiequal(3, bq->clause_cnt);
1781
+ q = frt_tq_new(rb_intern("A"), "a");
1782
+ Assert(frt_q_eq(bq->clauses[0]->query, q), "Query should be equal");
1783
+ frt_q_deref(q);
1784
+ q = frt_tq_new(rb_intern("B"), "b");
1785
+ Assert(frt_q_eq(bq->clauses[1]->query, q), "Query should be equal");
1786
+ frt_q_deref(q);
1787
+ q = frt_tq_new(rb_intern("C"), "c");
1788
+ Assert(frt_q_eq(bq->clauses[2]->query, q), "Query should be equal");
1789
+ frt_q_deref(q);
1790
+
1791
+ frt_q_deref(cq);
1792
+ Aiequal(1, queries[0]->ref_cnt);
1793
+
1794
+ Aiequal(1, queries[2]->ref_cnt);
1795
+ frt_q_deref(queries[2]);
1796
+
1797
+ q = frt_bq_new(true);
1798
+ frt_bq_add_query_nr(q, frt_tq_new(rb_intern("A"), "a"), FRT_BC_SHOULD);
1799
+ frt_bq_add_query_nr(q, frt_tq_new(rb_intern("B"), "b"), FRT_BC_SHOULD);
1800
+ frt_bq_add_query_nr(q, frt_tq_new(rb_intern("C"), "c"), FRT_BC_MUST);
1801
+ queries[2] = q;
1802
+
1803
+ cq = frt_q_combine(queries, 3);
1804
+ Aiequal(BOOLEAN_QUERY, cq->type);
1805
+
1806
+ bq = (FrtBooleanQuery *)cq;
1807
+ Aiequal(4, bq->clause_cnt);
1808
+ q = frt_tq_new(rb_intern("A"), "a");
1809
+ Assert(frt_q_eq(bq->clauses[0]->query, q), "Query should be equal");
1810
+ frt_q_deref(q);
1811
+ q = frt_tq_new(rb_intern("B"), "b");
1812
+ Assert(frt_q_eq(bq->clauses[1]->query, q), "Query should be equal");
1813
+ frt_q_deref(q);
1814
+ q = frt_tq_new(rb_intern("C"), "c");
1815
+ Assert(frt_q_eq(bq->clauses[2]->query, q), "Query should be equal");
1816
+ frt_q_deref(q);
1817
+ Assert(frt_q_eq(bq->clauses[3]->query, queries[2]), "Query should be equal");
1818
+
1819
+ frt_q_deref(cq);
1820
+ Aiequal(1, queries[0]->ref_cnt);
1821
+
1822
+ frt_q_deref(queries[0]);
1823
+ frt_q_deref(queries[1]);
1824
+ frt_q_deref(queries[2]);
1825
+ free(queries);
1826
+ }
1827
+
1828
+ TestSuite *ts_multi_search(TestSuite *suite)
1829
+ {
1830
+ FrtStore *store0 = frt_open_ram_store();
1831
+ FrtStore *store1 = frt_open_ram_store();
1832
+
1833
+ FrtIndexReader *ir0, *ir1;
1834
+ FrtSearcher **searchers;
1835
+ FrtSearcher *searcher;
1836
+
1837
+ date = rb_intern("date");
1838
+ field = rb_intern("field");
1839
+ cat = rb_intern("cat");
1840
+ number = rb_intern("number");
1841
+
1842
+ suite = tst_add_suite(suite, "test_multi_search");
1843
+
1844
+ prepare_multi_search_index(store0, test_data, 9, 1);
1845
+ prepare_multi_search_index(store1, test_data + 9, FRT_NELEMS(test_data) - 9, 10);
1846
+
1847
+ ir0 = frt_ir_open(store0);
1848
+ ir1 = frt_ir_open(store1);
1849
+ searchers = FRT_ALLOC_N(FrtSearcher *, 2);
1850
+ searchers[0] = frt_isea_new(ir0);
1851
+ searchers[1] = frt_isea_new(ir1);
1852
+ searcher = frt_msea_new(searchers, 2, true);
1853
+
1854
+ tst_run_test(suite, test_get_doc, (void *)searcher);
1855
+
1856
+ tst_run_test(suite, test_term_query, (void *)searcher);
1857
+ tst_run_test(suite, test_boolean_query, (void *)searcher);
1858
+ tst_run_test(suite, test_multi_term_query, (void *)searcher);
1859
+ tst_run_test(suite, test_phrase_query, (void *)searcher);
1860
+ tst_run_test(suite, test_multi_phrase_query, (void *)searcher);
1861
+ tst_run_test(suite, test_prefix_query, (void *)searcher);
1862
+ tst_run_test(suite, test_range_query, (void *)searcher);
1863
+ tst_run_test(suite, test_typed_range_query, (void *)searcher);
1864
+ tst_run_test(suite, test_wildcard_query, (void *)searcher);
1865
+ tst_run_test(suite, test_search_unscored, (void *)searcher);
1866
+
1867
+ tst_run_test(suite, test_query_combine, NULL);
1868
+
1869
+ frt_store_deref(store0);
1870
+ frt_store_deref(store1);
1871
+ frt_searcher_close(searcher);
1872
+ return suite;
1873
+ }
1874
+