ferret 0.10.4 → 0.10.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/ext/analysis.c +7 -1
- data/ext/bitvector.c +5 -2
- data/ext/bitvector.h +1 -0
- data/ext/ferret.c +55 -8
- data/ext/ferret.h +8 -2
- data/ext/index.c +34 -43
- data/ext/index.h +1 -1
- data/ext/q_boolean.c +1 -1
- data/ext/q_multi_term.c +13 -1
- data/ext/q_parser.c +33 -18
- data/ext/r_analysis.c +68 -45
- data/ext/r_index.c +64 -10
- data/ext/r_search.c +145 -10
- data/ext/search.c +71 -12
- data/lib/ferret/index.rb +42 -28
- data/lib/ferret_version.rb +1 -1
- data/test/unit/analysis/tc_analyzer.rb +1 -1
- data/test/unit/analysis/tc_token_stream.rb +0 -1
- data/test/unit/index/tc_index.rb +3 -3
- data/test/unit/index/tc_index_reader.rb +5 -0
- data/test/unit/search/tc_filter.rb +15 -0
- data/test/unit/search/tm_searcher.rb +13 -2
- metadata +2 -2
data/Rakefile
CHANGED
data/ext/analysis.c
CHANGED
@@ -843,9 +843,14 @@ static Token *std_next(TokenStream *ts)
|
|
843
843
|
/* strip possesive */
|
844
844
|
if ((t[-1] == 's' || t[-1] == 'S') && t[-2] == '\'') {
|
845
845
|
t -= 2;
|
846
|
+
tk_set_ts(&(CTS(ts)->token), start, t, ts->text, 1);
|
847
|
+
CTS(ts)->token.end += 2;
|
848
|
+
}
|
849
|
+
else {
|
850
|
+
tk_set_ts(&(CTS(ts)->token), start, t, ts->text, 1);
|
846
851
|
}
|
847
852
|
|
848
|
-
return
|
853
|
+
return &(CTS(ts)->token);
|
849
854
|
}
|
850
855
|
|
851
856
|
if (*t == '&') { /* apostrophe case. */
|
@@ -1434,6 +1439,7 @@ Analyzer *per_field_analyzer_new(Analyzer *default_a)
|
|
1434
1439
|
|
1435
1440
|
a->destroy_i = &pfa_destroy_i;
|
1436
1441
|
a->get_ts = pfa_get_ts;
|
1442
|
+
a->ref_cnt = 1;
|
1437
1443
|
|
1438
1444
|
return a;
|
1439
1445
|
}
|
data/ext/bitvector.c
CHANGED
@@ -14,6 +14,7 @@ BitVector *bv_new_capa(int capa)
|
|
14
14
|
bv->count = 0;
|
15
15
|
bv->curr_bit = -1;
|
16
16
|
bv->extends_as_ones = 0;
|
17
|
+
bv->ref_cnt = 1;
|
17
18
|
return bv;
|
18
19
|
}
|
19
20
|
|
@@ -24,8 +25,10 @@ BitVector *bv_new()
|
|
24
25
|
|
25
26
|
void bv_destroy(BitVector * bv)
|
26
27
|
{
|
27
|
-
|
28
|
-
|
28
|
+
if (--(bv->ref_cnt) == 0) {
|
29
|
+
free(bv->bits);
|
30
|
+
free(bv);
|
31
|
+
}
|
29
32
|
}
|
30
33
|
|
31
34
|
void bv_set(BitVector * bv, int bit)
|
data/ext/bitvector.h
CHANGED
data/ext/ferret.c
CHANGED
@@ -10,10 +10,12 @@ static HashTable *object_map;
|
|
10
10
|
|
11
11
|
/* IDs */
|
12
12
|
ID id_new;
|
13
|
+
ID id_call;
|
14
|
+
ID id_eql;
|
15
|
+
ID id_hash;
|
13
16
|
ID id_capacity;
|
14
17
|
ID id_less_than;
|
15
18
|
ID id_lt;
|
16
|
-
ID id_call;
|
17
19
|
ID id_is_directory;
|
18
20
|
ID id_close;
|
19
21
|
ID id_cclass;
|
@@ -36,6 +38,7 @@ VALUE mStringHelper;
|
|
36
38
|
VALUE mSpans;
|
37
39
|
|
38
40
|
/* Classes */
|
41
|
+
VALUE cTerm;
|
39
42
|
/*
|
40
43
|
*/
|
41
44
|
|
@@ -98,13 +101,6 @@ VALUE frt_data_alloc(VALUE klass)
|
|
98
101
|
return Frt_Make_Struct(klass);
|
99
102
|
}
|
100
103
|
|
101
|
-
VALUE frt_define_class_under(VALUE module, char *name, VALUE super)
|
102
|
-
{
|
103
|
-
VALUE klass = rb_define_class_under(module, name, super);
|
104
|
-
rb_ivar_set(klass, id_cclass, Qtrue);
|
105
|
-
return klass;
|
106
|
-
}
|
107
|
-
|
108
104
|
void frt_deref_free(void *p)
|
109
105
|
{
|
110
106
|
object_del(p);
|
@@ -233,6 +229,54 @@ void FRT_EXIT(const char *err_type, const char *fmt, ...)
|
|
233
229
|
va_end(args);
|
234
230
|
}
|
235
231
|
|
232
|
+
/****************************************************************************
|
233
|
+
*
|
234
|
+
* Term Methods
|
235
|
+
*
|
236
|
+
****************************************************************************/
|
237
|
+
static ID id_field;
|
238
|
+
static ID id_text;
|
239
|
+
|
240
|
+
VALUE frt_get_term(const char *field, const char *text)
|
241
|
+
{
|
242
|
+
return rb_struct_new(cTerm,
|
243
|
+
ID2SYM(rb_intern(field)),
|
244
|
+
rb_str_new2(text),
|
245
|
+
NULL);
|
246
|
+
}
|
247
|
+
|
248
|
+
static VALUE frt_term_to_s(VALUE self)
|
249
|
+
{
|
250
|
+
VALUE rstr;
|
251
|
+
VALUE rfield = rb_funcall(self, id_field, 0);
|
252
|
+
VALUE rtext = rb_funcall(self, id_text, 0);
|
253
|
+
char *field = StringValuePtr(rfield);
|
254
|
+
char *text = StringValuePtr(rtext);
|
255
|
+
char *term_str = ALLOC_N(char,
|
256
|
+
5 + RSTRING(rfield)->len + RSTRING(rtext)->len);
|
257
|
+
sprintf(term_str, "%s:%s", field, text);
|
258
|
+
rstr = rb_str_new2(term_str);
|
259
|
+
free(term_str);
|
260
|
+
return rstr;
|
261
|
+
}
|
262
|
+
/*
|
263
|
+
* Document-class: Ferret::Term
|
264
|
+
*
|
265
|
+
* == Summary
|
266
|
+
*
|
267
|
+
* A Term holds a term from a document and its field name (as a Symbol).
|
268
|
+
*/
|
269
|
+
void Init_Term(void)
|
270
|
+
{
|
271
|
+
const char *term_class = "Term";
|
272
|
+
cTerm = rb_struct_define(term_class, "field", "text", NULL);
|
273
|
+
rb_set_class_path(cTerm, mFerret, term_class);
|
274
|
+
rb_const_set(mFerret, rb_intern(term_class), cTerm);
|
275
|
+
rb_define_method(cTerm, "to_s", frt_term_to_s, 0);
|
276
|
+
id_field = rb_intern("field");
|
277
|
+
id_text = rb_intern("text");
|
278
|
+
}
|
279
|
+
|
236
280
|
/*
|
237
281
|
* Document-module: Ferret
|
238
282
|
*
|
@@ -241,6 +285,7 @@ void FRT_EXIT(const char *err_type, const char *fmt, ...)
|
|
241
285
|
void Init_Ferret(void)
|
242
286
|
{
|
243
287
|
mFerret = rb_define_module("Ferret");
|
288
|
+
Init_Term();
|
244
289
|
}
|
245
290
|
|
246
291
|
void Init_ferret_ext(void)
|
@@ -254,6 +299,8 @@ void Init_ferret_ext(void)
|
|
254
299
|
/* IDs */
|
255
300
|
id_new = rb_intern("new");
|
256
301
|
id_call = rb_intern("call");
|
302
|
+
id_eql = rb_intern("eql?");
|
303
|
+
id_hash = rb_intern("hash");
|
257
304
|
|
258
305
|
id_capacity = rb_intern("capacity");
|
259
306
|
id_less_than = rb_intern("less_than");
|
data/ext/ferret.h
CHANGED
@@ -7,10 +7,12 @@
|
|
7
7
|
|
8
8
|
/* IDs */
|
9
9
|
extern ID id_new;
|
10
|
+
extern ID id_call;
|
11
|
+
extern ID id_hash;
|
12
|
+
extern ID id_eql;
|
10
13
|
extern ID id_capacity;
|
11
14
|
extern ID id_less_than;
|
12
15
|
extern ID id_lt;
|
13
|
-
extern ID id_call;
|
14
16
|
extern ID id_is_directory;
|
15
17
|
extern ID id_close;
|
16
18
|
extern ID id_cclass;
|
@@ -35,6 +37,7 @@ extern VALUE mSpans;
|
|
35
37
|
/* Classes */
|
36
38
|
extern VALUE cDirectory;
|
37
39
|
extern VALUE cLockError;
|
40
|
+
extern VALUE cTerm;
|
38
41
|
|
39
42
|
/* Ferret Inits */
|
40
43
|
extern void Init_Utils();
|
@@ -61,7 +64,7 @@ extern void frt_create_dir(VALUE rpath);
|
|
61
64
|
extern VALUE frt_hs_to_rb_ary(HashSet *hs);
|
62
65
|
extern void *frt_rb_data_ptr(VALUE val);
|
63
66
|
extern char * frt_field(VALUE rfield);
|
64
|
-
extern VALUE
|
67
|
+
extern VALUE frt_get_term(const char *field, const char *term);
|
65
68
|
|
66
69
|
#define Frt_Make_Struct(klass)\
|
67
70
|
rb_data_object_alloc(klass,NULL,(RUBY_DATA_FUNC)NULL,(RUBY_DATA_FUNC)NULL)
|
@@ -81,3 +84,6 @@ extern VALUE frt_define_class_under(VALUE module, char *name, VALUE super);
|
|
81
84
|
} while (0)
|
82
85
|
|
83
86
|
#endif
|
87
|
+
|
88
|
+
#define frt_mark_cclass(klass) rb_ivar_set(klass, id_cclass, Qtrue)
|
89
|
+
#define frt_is_cclass(obj) (rb_ivar_get(CLASS_OF(obj), id_cclass) == Qtrue)
|
data/ext/index.c
CHANGED
@@ -2899,10 +2899,9 @@ void ir_set_norm(IndexReader *ir, int doc_num, const char *field, uchar val)
|
|
2899
2899
|
}
|
2900
2900
|
}
|
2901
2901
|
|
2902
|
-
uchar *
|
2902
|
+
uchar *ir_get_norms_i(IndexReader *ir, int field_num)
|
2903
2903
|
{
|
2904
2904
|
uchar *norms = NULL;
|
2905
|
-
int field_num = fis_get_field_num(ir->fis, field);
|
2906
2905
|
if (field_num >= 0) {
|
2907
2906
|
norms = ir->get_norms(ir, field_num);
|
2908
2907
|
}
|
@@ -2915,6 +2914,12 @@ uchar *ir_get_norms(IndexReader *ir, const char *field)
|
|
2915
2914
|
return norms;
|
2916
2915
|
}
|
2917
2916
|
|
2917
|
+
uchar *ir_get_norms(IndexReader *ir, const char *field)
|
2918
|
+
{
|
2919
|
+
int field_num = fis_get_field_num(ir->fis, field);
|
2920
|
+
return ir_get_norms_i(ir, field_num);
|
2921
|
+
}
|
2922
|
+
|
2918
2923
|
uchar *ir_get_norms_into(IndexReader *ir, const char *field, uchar *buf)
|
2919
2924
|
{
|
2920
2925
|
int field_num = fis_get_field_num(ir->fis, field);
|
@@ -3286,6 +3291,7 @@ static BitVector *bv_read(Store *store, char *name)
|
|
3286
3291
|
bv->size = (int)is_read_vint(is);
|
3287
3292
|
bv->capa = (bv->size >> 5) + 1;
|
3288
3293
|
bv->bits = ALLOC_AND_ZERO_N(f_u32, bv->capa);
|
3294
|
+
bv->ref_cnt = 1;
|
3289
3295
|
for (i = (bv->size >> 5); i >= 0; i--) {
|
3290
3296
|
bv->bits[i] = is_read_u32(is);
|
3291
3297
|
}
|
@@ -5022,17 +5028,6 @@ int iw_doc_count(IndexWriter *iw)
|
|
5022
5028
|
return doc_cnt;
|
5023
5029
|
}
|
5024
5030
|
|
5025
|
-
void iw_delete_term(IndexWriter *iw, const char *field, const char *term)
|
5026
|
-
{
|
5027
|
-
int field_num = fis_get_field_num(iw->fis, field);
|
5028
|
-
if (field_num >= 0) {
|
5029
|
-
DelTerm *dt = ALLOC(DelTerm);
|
5030
|
-
dt->field_num = field_num;
|
5031
|
-
dt->term = estrdup(term);
|
5032
|
-
ary_push(iw->del_terms, dt);
|
5033
|
-
}
|
5034
|
-
}
|
5035
|
-
|
5036
5031
|
static void delete_files(char **file_names, Store *store)
|
5037
5032
|
{
|
5038
5033
|
int i;
|
@@ -5277,37 +5272,9 @@ void iw_add_doc(IndexWriter *iw, Document *doc)
|
|
5277
5272
|
|
5278
5273
|
static void iw_commit_i(IndexWriter *iw)
|
5279
5274
|
{
|
5280
|
-
/* optimized term deletion method */
|
5281
|
-
const int del_term_cnt = ary_size(iw->del_terms);
|
5282
5275
|
if (iw->dw && iw->dw->doc_num > 0) {
|
5283
5276
|
iw_flush_ram_segment(iw);
|
5284
5277
|
}
|
5285
|
-
if (del_term_cnt) {
|
5286
|
-
DelTerm **del_terms = iw->del_terms;
|
5287
|
-
int i;
|
5288
|
-
SegmentInfos *sis = iw->sis;
|
5289
|
-
const int seg_cnt = sis->size;
|
5290
|
-
for (i = 0; i < seg_cnt; i++) {
|
5291
|
-
int j;
|
5292
|
-
IndexReader *ir = sr_open(sis, iw->fis, i, false);
|
5293
|
-
TermDocEnum *tde = ir->term_docs(ir);
|
5294
|
-
for (j = 0; j < del_term_cnt; j++) {
|
5295
|
-
DelTerm *del_term = del_terms[j];
|
5296
|
-
stde_seek(tde, del_term->field_num, del_term->term);
|
5297
|
-
while (tde->next(tde)) {
|
5298
|
-
sr_delete_doc_i(ir, STDE(tde)->doc_num);
|
5299
|
-
}
|
5300
|
-
}
|
5301
|
-
tde_destroy(tde);
|
5302
|
-
sr_commit_i(ir);
|
5303
|
-
ir_close(ir);
|
5304
|
-
}
|
5305
|
-
ary_each_rev(del_terms, i) {
|
5306
|
-
free(del_terms[i]->term);
|
5307
|
-
free(del_terms[i]);
|
5308
|
-
}
|
5309
|
-
ary_size(del_terms) = 0;
|
5310
|
-
}
|
5311
5278
|
}
|
5312
5279
|
|
5313
5280
|
void iw_commit(IndexWriter *iw)
|
@@ -5317,6 +5284,32 @@ void iw_commit(IndexWriter *iw)
|
|
5317
5284
|
mutex_unlock(&iw->mutex);
|
5318
5285
|
}
|
5319
5286
|
|
5287
|
+
void iw_delete_term(IndexWriter *iw, const char *field, const char *term)
|
5288
|
+
{
|
5289
|
+
int field_num = fis_get_field_num(iw->fis, field);
|
5290
|
+
if (field_num >= 0) {
|
5291
|
+
int i;
|
5292
|
+
mutex_lock(&iw->mutex);
|
5293
|
+
iw_commit_i(iw);
|
5294
|
+
do {
|
5295
|
+
SegmentInfos *sis = iw->sis;
|
5296
|
+
const int seg_cnt = sis->size;
|
5297
|
+
for (i = 0; i < seg_cnt; i++) {
|
5298
|
+
IndexReader *ir = sr_open(sis, iw->fis, i, false);
|
5299
|
+
TermDocEnum *tde = ir->term_docs(ir);
|
5300
|
+
stde_seek(tde, field_num, term);
|
5301
|
+
while (tde->next(tde)) {
|
5302
|
+
sr_delete_doc_i(ir, STDE(tde)->doc_num);
|
5303
|
+
}
|
5304
|
+
tde_destroy(tde);
|
5305
|
+
sr_commit_i(ir);
|
5306
|
+
ir_close(ir);
|
5307
|
+
}
|
5308
|
+
} while (0);
|
5309
|
+
mutex_unlock(&iw->mutex);
|
5310
|
+
}
|
5311
|
+
}
|
5312
|
+
|
5320
5313
|
static void iw_optimize_i(IndexWriter *iw)
|
5321
5314
|
{
|
5322
5315
|
int min_segment;
|
@@ -5351,7 +5344,6 @@ void iw_close(IndexWriter *iw)
|
|
5351
5344
|
sis_destroy(iw->sis);
|
5352
5345
|
fis_deref(iw->fis);
|
5353
5346
|
sim_destroy(iw->similarity);
|
5354
|
-
ary_free(iw->del_terms);
|
5355
5347
|
|
5356
5348
|
iw->write_lock->release(iw->write_lock);
|
5357
5349
|
iw->store->close_lock(iw->write_lock);
|
@@ -5392,7 +5384,6 @@ IndexWriter *iw_open(Store *store, Analyzer *analyzer, const Config *config)
|
|
5392
5384
|
XENDTRY
|
5393
5385
|
|
5394
5386
|
iw->similarity = sim_create_default();
|
5395
|
-
iw->del_terms = ary_new_type(DelTerm *);
|
5396
5387
|
iw->analyzer = analyzer ? analyzer : mb_standard_analyzer_new(true);
|
5397
5388
|
|
5398
5389
|
REF(store);
|
data/ext/index.h
CHANGED
@@ -744,6 +744,7 @@ extern void ir_undelete_all(IndexReader *ir);
|
|
744
744
|
extern int ir_doc_freq(IndexReader *ir, const char *field, const char *term);
|
745
745
|
extern void ir_set_norm(IndexReader *ir, int doc_num, const char *field,
|
746
746
|
uchar val);
|
747
|
+
extern uchar *ir_get_norms_i(IndexReader *ir, int field_num);
|
747
748
|
extern uchar *ir_get_norms(IndexReader *ir, const char *field);
|
748
749
|
extern uchar *ir_get_norms_into(IndexReader *ir, const char *field, uchar *buf);
|
749
750
|
extern void ir_destroy(IndexReader *self);
|
@@ -868,7 +869,6 @@ struct IndexWriter
|
|
868
869
|
FieldInfos *fis;
|
869
870
|
DocWriter *dw;
|
870
871
|
Similarity *similarity;
|
871
|
-
DelTerm **del_terms;
|
872
872
|
Lock *write_lock;
|
873
873
|
};
|
874
874
|
|
data/ext/q_boolean.c
CHANGED
data/ext/q_multi_term.c
CHANGED
@@ -357,7 +357,7 @@ static Scorer *multi_tw_scorer(Weight *self, IndexReader *ir)
|
|
357
357
|
te->close(te);
|
358
358
|
if (tdew_cnt) {
|
359
359
|
multi_tsc = multi_tsc_new(self, MTQ(self->query)->field, tdew_a,
|
360
|
-
tdew_cnt,
|
360
|
+
tdew_cnt, ir_get_norms_i(ir, field_num));
|
361
361
|
}
|
362
362
|
else {
|
363
363
|
free(tdew_a);
|
@@ -559,6 +559,17 @@ static void multi_tq_destroy_i(Query *self)
|
|
559
559
|
q_destroy_i(self);
|
560
560
|
}
|
561
561
|
|
562
|
+
static void multi_tq_extract_terms(Query *self, HashSet *terms)
|
563
|
+
{
|
564
|
+
int i;
|
565
|
+
char *field = MTQ(self)->field;
|
566
|
+
PriorityQueue *boosted_terms = MTQ(self)->boosted_terms;
|
567
|
+
for (i = boosted_terms->size; i > 0; i--) {
|
568
|
+
BoostedTerm *bt = (BoostedTerm *)boosted_terms->heap[i];
|
569
|
+
hs_add(terms, term_new(field, bt->term));
|
570
|
+
}
|
571
|
+
}
|
572
|
+
|
562
573
|
static ulong multi_tq_hash(Query *self)
|
563
574
|
{
|
564
575
|
int i;
|
@@ -631,6 +642,7 @@ Query *multi_tq_new_conf(const char *field, int max_terms, float min_boost)
|
|
631
642
|
|
632
643
|
self->type = MULTI_TERM_QUERY;
|
633
644
|
self->to_s = &multi_tq_to_s;
|
645
|
+
self->extract_terms = &multi_tq_extract_terms;
|
634
646
|
self->hash = &multi_tq_hash;
|
635
647
|
self->eq = &multi_tq_eq;
|
636
648
|
self->destroy_i = &multi_tq_destroy_i;
|
data/ext/q_parser.c
CHANGED
@@ -170,8 +170,8 @@ static Phrase *ph_first_word(char *word);
|
|
170
170
|
static Phrase *ph_add_word(Phrase *self, char *word);
|
171
171
|
static Phrase *ph_add_multi_word(Phrase *self, char *word);
|
172
172
|
|
173
|
-
static Query *
|
174
|
-
|
173
|
+
static Query *get_r_q(QParser *qp, char *field, char *from, char *to,
|
174
|
+
bool inc_lower, bool inc_upper);
|
175
175
|
|
176
176
|
#define FLDS(q, func) do {\
|
177
177
|
char *field;\
|
@@ -1405,62 +1405,62 @@ yyreduce:
|
|
1405
1405
|
|
1406
1406
|
case 39:
|
1407
1407
|
#line 146 "src/q_parser.y"
|
1408
|
-
{ FLDS((yyval.query),
|
1408
|
+
{ FLDS((yyval.query), get_r_q(qp, field, (yyvsp[-2].str), (yyvsp[-1].str), true, true)); }
|
1409
1409
|
break;
|
1410
1410
|
|
1411
1411
|
case 40:
|
1412
1412
|
#line 147 "src/q_parser.y"
|
1413
|
-
{ FLDS((yyval.query),
|
1413
|
+
{ FLDS((yyval.query), get_r_q(qp, field, (yyvsp[-2].str), (yyvsp[-1].str), true, false)); }
|
1414
1414
|
break;
|
1415
1415
|
|
1416
1416
|
case 41:
|
1417
1417
|
#line 148 "src/q_parser.y"
|
1418
|
-
{ FLDS((yyval.query),
|
1418
|
+
{ FLDS((yyval.query), get_r_q(qp, field, (yyvsp[-2].str), (yyvsp[-1].str), false, true)); }
|
1419
1419
|
break;
|
1420
1420
|
|
1421
1421
|
case 42:
|
1422
1422
|
#line 149 "src/q_parser.y"
|
1423
|
-
{ FLDS((yyval.query),
|
1423
|
+
{ FLDS((yyval.query), get_r_q(qp, field, (yyvsp[-2].str), (yyvsp[-1].str), false, false)); }
|
1424
1424
|
break;
|
1425
1425
|
|
1426
1426
|
case 43:
|
1427
1427
|
#line 150 "src/q_parser.y"
|
1428
|
-
{ FLDS((yyval.query),
|
1428
|
+
{ FLDS((yyval.query), get_r_q(qp, field, NULL,(yyvsp[-1].str), false, false)); }
|
1429
1429
|
break;
|
1430
1430
|
|
1431
1431
|
case 44:
|
1432
1432
|
#line 151 "src/q_parser.y"
|
1433
|
-
{ FLDS((yyval.query),
|
1433
|
+
{ FLDS((yyval.query), get_r_q(qp, field, NULL,(yyvsp[-1].str), false, true)); }
|
1434
1434
|
break;
|
1435
1435
|
|
1436
1436
|
case 45:
|
1437
1437
|
#line 152 "src/q_parser.y"
|
1438
|
-
{ FLDS((yyval.query),
|
1438
|
+
{ FLDS((yyval.query), get_r_q(qp, field, (yyvsp[-1].str), NULL,true, false)); }
|
1439
1439
|
break;
|
1440
1440
|
|
1441
1441
|
case 46:
|
1442
1442
|
#line 153 "src/q_parser.y"
|
1443
|
-
{ FLDS((yyval.query),
|
1443
|
+
{ FLDS((yyval.query), get_r_q(qp, field, (yyvsp[-1].str), NULL,false, false)); }
|
1444
1444
|
break;
|
1445
1445
|
|
1446
1446
|
case 47:
|
1447
1447
|
#line 154 "src/q_parser.y"
|
1448
|
-
{ FLDS((yyval.query),
|
1448
|
+
{ FLDS((yyval.query), get_r_q(qp, field, NULL,(yyvsp[0].str), false, false)); }
|
1449
1449
|
break;
|
1450
1450
|
|
1451
1451
|
case 48:
|
1452
1452
|
#line 155 "src/q_parser.y"
|
1453
|
-
{ FLDS((yyval.query),
|
1453
|
+
{ FLDS((yyval.query), get_r_q(qp, field, NULL,(yyvsp[0].str), false, true)); }
|
1454
1454
|
break;
|
1455
1455
|
|
1456
1456
|
case 49:
|
1457
1457
|
#line 156 "src/q_parser.y"
|
1458
|
-
{ FLDS((yyval.query),
|
1458
|
+
{ FLDS((yyval.query), get_r_q(qp, field, (yyvsp[0].str), NULL,true, false)); }
|
1459
1459
|
break;
|
1460
1460
|
|
1461
1461
|
case 50:
|
1462
1462
|
#line 157 "src/q_parser.y"
|
1463
|
-
{ FLDS((yyval.query),
|
1463
|
+
{ FLDS((yyval.query), get_r_q(qp, field, (yyvsp[0].str), NULL,false, false)); }
|
1464
1464
|
break;
|
1465
1465
|
|
1466
1466
|
|
@@ -1756,7 +1756,7 @@ static int get_word(YYSTYPE *lvalp, QParser *qp)
|
|
1756
1756
|
while (!strchr(not_word, (c=*qp->qstrp++))) {
|
1757
1757
|
switch (c) {
|
1758
1758
|
case '\\':
|
1759
|
-
if ((c=*qp->qstrp) == '
|
1759
|
+
if ((c=*qp->qstrp) == '\0') {
|
1760
1760
|
*bufp++ = '\\';
|
1761
1761
|
}
|
1762
1762
|
else {
|
@@ -2248,10 +2248,25 @@ static Query *get_phrase_q(QParser *qp, Phrase *phrase, char *slop_str)
|
|
2248
2248
|
return q;
|
2249
2249
|
}
|
2250
2250
|
|
2251
|
-
static Query *
|
2252
|
-
|
2251
|
+
static Query *get_r_q(QParser *qp, char *field, char *from, char *to,
|
2252
|
+
bool inc_lower, bool inc_upper)
|
2253
2253
|
{
|
2254
|
-
|
2254
|
+
Query *rq;
|
2255
|
+
if (from) {
|
2256
|
+
TokenStream *stream = get_cached_ts(qp, field, from);
|
2257
|
+
Token *token = ts_next(stream);
|
2258
|
+
from = token ? estrdup(token->text) : NULL;
|
2259
|
+
}
|
2260
|
+
if (to) {
|
2261
|
+
TokenStream *stream = get_cached_ts(qp, field, to);
|
2262
|
+
Token *token = ts_next(stream);
|
2263
|
+
to = token ? estrdup(token->text) : NULL;
|
2264
|
+
}
|
2265
|
+
|
2266
|
+
rq = rq_new(field, from, to, inc_lower, inc_upper);
|
2267
|
+
if (from) free(from);
|
2268
|
+
if (to) free(to);
|
2269
|
+
return rq;
|
2255
2270
|
}
|
2256
2271
|
|
2257
2272
|
void qp_destroy(QParser *self)
|