ferret 0.10.4 → 0.10.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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)
|