15
15
tsstat_in (PG_FUNCTION_ARGS )
16
16
{
17
17
tsstat * stat = palloc (STATHDRSIZE );
18
-
18
+
19
19
stat -> len = STATHDRSIZE ;
20
20
stat -> size = 0 ;
21
+ stat -> weight = 0 ;
21
22
PG_RETURN_POINTER (stat );
22
23
}
23
24
@@ -32,6 +33,20 @@ tsstat_out(PG_FUNCTION_ARGS)
32
33
PG_RETURN_NULL ();
33
34
}
34
35
36
+ static int
37
+ check_weight (tsvector * txt ,WordEntry * wptr ,int8 weight ) {
38
+ int len = POSDATALEN (txt ,wptr );
39
+ int num = 0 ;
40
+ WordEntryPos * ptr = POSDATAPTR (txt ,wptr );
41
+
42
+ while (len -- ) {
43
+ if (weight & (1 <<ptr -> weight ))
44
+ num ++ ;
45
+ ptr ++ ;
46
+ }
47
+ return num ;
48
+ }
49
+
35
50
static WordEntry * *
36
51
SEI_realloc (WordEntry * * in ,uint32 * len )
37
52
{
@@ -83,6 +98,7 @@ formstat(tsstat * stat, tsvector * txt, WordEntry ** entry, uint32 len)
83
98
totallen = CALCSTATSIZE (nentry ,slen );
84
99
newstat = palloc (totallen );
85
100
newstat -> len = totallen ;
101
+ newstat -> weight = stat -> weight ;
86
102
newstat -> size = nentry ;
87
103
88
104
memcpy (STATSTRPTR (newstat ),STATSTRPTR (stat ),STATSTRSIZE (stat ));
@@ -107,8 +123,9 @@ formstat(tsstat * stat, tsvector * txt, WordEntry ** entry, uint32 len)
107
123
}
108
124
nptr = STATPTR (newstat )+ (StopLow - STATPTR (stat ));
109
125
memcpy (STATPTR (newstat ),STATPTR (stat ),sizeof (StatEntry )* (StopLow - STATPTR (stat )));
110
- nptr -> nentry = POSDATALEN (txt ,* ptr );
111
- if (nptr -> nentry == 0 )
126
+ if ( (* ptr )-> haspos ) {
127
+ nptr -> nentry = (stat -> weight ) ?check_weight (txt ,* ptr ,stat -> weight ) :POSDATALEN (txt ,* ptr );
128
+ }else
112
129
nptr -> nentry = 1 ;
113
130
nptr -> ndoc = 1 ;
114
131
nptr -> len = (* ptr )-> len ;
@@ -127,8 +144,9 @@ formstat(tsstat * stat, tsvector * txt, WordEntry ** entry, uint32 len)
127
144
}
128
145
else
129
146
{
130
- nptr -> nentry = POSDATALEN (txt ,* ptr );
131
- if (nptr -> nentry == 0 )
147
+ if ( (* ptr )-> haspos ) {
148
+ nptr -> nentry = (stat -> weight ) ?check_weight (txt ,* ptr ,stat -> weight ) :POSDATALEN (txt ,* ptr );
149
+ }else
132
150
nptr -> nentry = 1 ;
133
151
nptr -> ndoc = 1 ;
134
152
nptr -> len = (* ptr )-> len ;
@@ -144,8 +162,9 @@ formstat(tsstat * stat, tsvector * txt, WordEntry ** entry, uint32 len)
144
162
145
163
while (ptr - entry < len )
146
164
{
147
- nptr -> nentry = POSDATALEN (txt ,* ptr );
148
- if (nptr -> nentry == 0 )
165
+ if ( (* ptr )-> haspos ) {
166
+ nptr -> nentry = (stat -> weight ) ?check_weight (txt ,* ptr ,stat -> weight ) :POSDATALEN (txt ,* ptr );
167
+ }else
149
168
nptr -> nentry = 1 ;
150
169
nptr -> ndoc = 1 ;
151
170
nptr -> len = (* ptr )-> len ;
@@ -173,12 +192,14 @@ ts_accum(PG_FUNCTION_ARGS)
173
192
cur = 0 ;
174
193
StatEntry * sptr ;
175
194
WordEntry * wptr ;
195
+ int n = 0 ;
176
196
177
197
if (stat == NULL || PG_ARGISNULL (0 ))
178
198
{/* Init in first */
179
199
stat = palloc (STATHDRSIZE );
180
200
stat -> len = STATHDRSIZE ;
181
201
stat -> size = 0 ;
202
+ stat -> weight = 0 ;
182
203
}
183
204
184
205
/* simple check of correctness */
@@ -201,32 +222,37 @@ ts_accum(PG_FUNCTION_ARGS)
201
222
sptr ++ ;
202
223
else if (cmp == 0 )
203
224
{
204
- int n = POSDATALEN (txt ,wptr );
205
-
206
- if (n == 0 )
207
- n = 1 ;
208
- sptr -> ndoc ++ ;
209
- sptr -> nentry += n ;
225
+ if (stat -> weight == 0 ) {
226
+ sptr -> ndoc ++ ;
227
+ sptr -> nentry += (wptr -> haspos ) ?POSDATALEN (txt ,wptr ) :1 ;
228
+ }else if (wptr -> haspos && (n = check_weight (txt ,wptr ,stat -> weight ))!= 0 ) {
229
+ sptr -> ndoc ++ ;
230
+ sptr -> nentry += n ;
231
+ }
210
232
sptr ++ ;
211
233
wptr ++ ;
212
234
}
213
235
else
214
236
{
215
- if (cur == len )
216
- newentry = SEI_realloc (newentry ,& len );
217
- newentry [cur ]= wptr ;
237
+ if (stat -> weight == 0 || check_weight (txt ,wptr ,stat -> weight )!= 0 ) {
238
+ if (cur == len )
239
+ newentry = SEI_realloc (newentry ,& len );
240
+ newentry [cur ]= wptr ;
241
+ cur ++ ;
242
+ }
218
243
wptr ++ ;
219
- cur ++ ;
220
244
}
221
245
}
222
246
223
247
while (wptr - ARRPTR (txt )< txt -> size )
224
248
{
225
- if (cur == len )
226
- newentry = SEI_realloc (newentry ,& len );
227
- newentry [cur ]= wptr ;
249
+ if (stat -> weight == 0 || check_weight (txt ,wptr ,stat -> weight )!= 0 ) {
250
+ if (cur == len )
251
+ newentry = SEI_realloc (newentry ,& len );
252
+ newentry [cur ]= wptr ;
253
+ cur ++ ;
254
+ }
228
255
wptr ++ ;
229
- cur ++ ;
230
256
}
231
257
}
232
258
else
@@ -243,12 +269,13 @@ ts_accum(PG_FUNCTION_ARGS)
243
269
cmp = compareStatWord (sptr ,wptr ,stat ,txt );
244
270
if (cmp == 0 )
245
271
{
246
- int n = POSDATALEN (txt ,wptr );
247
-
248
- if (n == 0 )
249
- n = 1 ;
250
- sptr -> ndoc ++ ;
251
- sptr -> nentry += n ;
272
+ if (stat -> weight == 0 ) {
273
+ sptr -> ndoc ++ ;
274
+ sptr -> nentry += (wptr -> haspos ) ?POSDATALEN (txt ,wptr ) :1 ;
275
+ }else if (wptr -> haspos && (n = check_weight (txt ,wptr ,stat -> weight ))!= 0 ) {
276
+ sptr -> ndoc ++ ;
277
+ sptr -> nentry += n ;
278
+ }
252
279
break ;
253
280
}
254
281
else if (cmp < 0 )
@@ -259,10 +286,12 @@ ts_accum(PG_FUNCTION_ARGS)
259
286
260
287
if (StopLow >=StopHigh )
261
288
{/* not found */
262
- if (cur == len )
263
- newentry = SEI_realloc (newentry ,& len );
264
- newentry [cur ]= wptr ;
265
- cur ++ ;
289
+ if (stat -> weight == 0 || check_weight (txt ,wptr ,stat -> weight )!= 0 ) {
290
+ if (cur == len )
291
+ newentry = SEI_realloc (newentry ,& len );
292
+ newentry [cur ]= wptr ;
293
+ cur ++ ;
294
+ }
266
295
}
267
296
wptr ++ ;
268
297
}
@@ -389,7 +418,7 @@ get_ti_Oid(void)
389
418
}
390
419
391
420
static tsstat *
392
- ts_stat_sql (text * txt )
421
+ ts_stat_sql (text * txt , text * ws )
393
422
{
394
423
char * query = text2char (txt );
395
424
int i ;
@@ -423,6 +452,31 @@ ts_stat_sql(text *txt)
423
452
stat = palloc (STATHDRSIZE );
424
453
stat -> len = STATHDRSIZE ;
425
454
stat -> size = 0 ;
455
+ stat -> weight = 0 ;
456
+
457
+ if (ws ) {
458
+ char * buf ;
459
+ buf = VARDATA (ws );
460
+ while (buf - VARDATA (ws )< VARSIZE (buf )- VARHDRSZ ) {
461
+ switch (tolower (* buf )) {
462
+ case 'a' :
463
+ stat -> weight |=1 <<3 ;
464
+ break ;
465
+ case 'b' :
466
+ stat -> weight |=1 <<2 ;
467
+ break ;
468
+ case 'c' :
469
+ stat -> weight |=1 <<1 ;
470
+ break ;
471
+ case 'd' :
472
+ stat -> weight |=1 ;
473
+ break ;
474
+ default :
475
+ stat -> weight |=0 ;
476
+ }
477
+ buf ++ ;
478
+ }
479
+ }
426
480
427
481
while (SPI_processed > 0 )
428
482
{
@@ -467,11 +521,13 @@ ts_stat(PG_FUNCTION_ARGS)
467
521
{
468
522
tsstat * stat ;
469
523
text * txt = PG_GETARG_TEXT_P (0 );
524
+ text * ws = (PG_NARGS ()> 1 ) ?PG_GETARG_TEXT_P (1 ) :NULL ;
470
525
471
526
funcctx = SRF_FIRSTCALL_INIT ();
472
527
SPI_connect ();
473
- stat = ts_stat_sql (txt );
528
+ stat = ts_stat_sql (txt , ws );
474
529
PG_FREE_IF_COPY (txt ,0 );
530
+ if (PG_NARGS ()> 1 )PG_FREE_IF_COPY (ws ,1 );
475
531
ts_setup_firstcall (funcctx ,stat );
476
532
SPI_finish ();
477
533
}