Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit10059c2

Browse files
committed
Fix two bugs in tsquery @> operator.
1. The comparison for matching terms used only the CRC to decide if there'sa match. Two different terms with the same CRC gave a match.2. It assumed that if the second operand has more terms than the first, it'snever a match. That assumption is bogus, because there can be duplicateterms in either operand.Rewrite the implementation in a way that doesn't have those bugs.Backpatch to all supported versions.
1 parent21fa26b commit10059c2

File tree

1 file changed

+89
-40
lines changed

1 file changed

+89
-40
lines changed

‎src/backend/utils/adt/tsquery_op.c

Lines changed: 89 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -216,63 +216,112 @@ makeTSQuerySign(TSQuery a)
216216
returnsign;
217217
}
218218

219-
Datum
220-
tsq_mcontains(PG_FUNCTION_ARGS)
219+
staticchar**
220+
collectTSQueryValues(TSQuerya,int*nvalues_p)
221221
{
222-
TSQueryquery=PG_GETARG_TSQUERY(0);
223-
TSQueryex=PG_GETARG_TSQUERY(1);
224-
TSQuerySignsq,
225-
se;
226-
inti,
227-
j;
228-
QueryItem*iq,
229-
*ie;
230-
231-
if (query->size<ex->size)
222+
QueryItem*ptr=GETQUERY(a);
223+
char*operand=GETOPERAND(a);
224+
char**values;
225+
intnvalues=0;
226+
inti;
227+
228+
values= (char**)palloc(sizeof(char*)*a->size);
229+
230+
for (i=0;i<a->size;i++)
232231
{
233-
PG_FREE_IF_COPY(query,0);
234-
PG_FREE_IF_COPY(ex,1);
232+
if (ptr->type==QI_VAL)
233+
{
234+
intlen=ptr->qoperand.length;
235+
char*val;
236+
237+
val=palloc(len+1);
238+
memcpy(val,operand+ptr->qoperand.distance,len);
239+
val[len]='\0';
235240

236-
PG_RETURN_BOOL(false);
241+
values[nvalues++]=val;
242+
}
243+
ptr++;
237244
}
238245

239-
sq=makeTSQuerySign(query);
240-
se=makeTSQuerySign(ex);
246+
*nvalues_p=nvalues;
247+
returnvalues;
248+
}
249+
250+
staticint
251+
cmp_string(constvoid*a,constvoid*b)
252+
{
253+
constchar*sa=*((constchar**)a);
254+
constchar*sb=*((constchar**)b);
255+
returnstrcmp(sa,sb);
256+
}
241257

242-
if ((sq&se)!=se)
258+
staticint
259+
remove_duplicates(char**strings,intn)
260+
{
261+
if (n <=1)
262+
returnn;
263+
else
243264
{
244-
PG_FREE_IF_COPY(query,0);
245-
PG_FREE_IF_COPY(ex,1);
265+
inti;
266+
char*prev=strings[0];
267+
intnew_n=1;
246268

247-
PG_RETURN_BOOL(false);
269+
for (i=1;i<n;i++)
270+
{
271+
if (strcmp(strings[i],prev)!=0)
272+
{
273+
strings[new_n++]=strings[i];
274+
prev=strings[i];
275+
}
276+
}
277+
returnnew_n;
248278
}
279+
}
249280

250-
ie=GETQUERY(ex);
251-
252-
for (i=0;i<ex->size;i++)
281+
Datum
282+
tsq_mcontains(PG_FUNCTION_ARGS)
283+
{
284+
TSQueryquery=PG_GETARG_TSQUERY(0);
285+
TSQueryex=PG_GETARG_TSQUERY(1);
286+
char**query_values;
287+
intquery_nvalues;
288+
char**ex_values;
289+
intex_nvalues;
290+
boolresult= true;
291+
292+
/* Extract the query terms into arrays */
293+
query_values=collectTSQueryValues(query,&query_nvalues);
294+
ex_values=collectTSQueryValues(ex,&ex_nvalues);
295+
296+
/* Sort and remove duplicates from both arrays */
297+
qsort(query_values,query_nvalues,sizeof(char*),cmp_string);
298+
query_nvalues=remove_duplicates(query_values,query_nvalues);
299+
qsort(ex_values,ex_nvalues,sizeof(char*),cmp_string);
300+
ex_nvalues=remove_duplicates(ex_values,ex_nvalues);
301+
302+
if (ex_nvalues>query_nvalues)
303+
result= false;
304+
else
253305
{
254-
iq=GETQUERY(query);
255-
if (ie[i].type!=QI_VAL)
256-
continue;
257-
for (j=0;j<query->size;j++)
258-
if (iq[j].type==QI_VAL&&ie[i].qoperand.valcrc==iq[j].qoperand.valcrc)
306+
inti;
307+
intj=0;
308+
309+
for (i=0;i<ex_nvalues;i++)
310+
{
311+
for (;j<query_nvalues;j++)
312+
{
313+
if (strcmp(ex_values[i],query_values[j])==0)
314+
break;
315+
}
316+
if (j==query_nvalues)
259317
{
260-
j=query->size+1;
318+
result=false;
261319
break;
262320
}
263-
if (j==query->size)
264-
{
265-
PG_FREE_IF_COPY(query,0);
266-
PG_FREE_IF_COPY(ex,1);
267-
268-
PG_RETURN_BOOL(false);
269321
}
270322
}
271323

272-
PG_FREE_IF_COPY(query,0);
273-
PG_FREE_IF_COPY(ex,1);
274-
275-
PG_RETURN_BOOL(true);
324+
PG_RETURN_BOOL(result);
276325
}
277326

278327
Datum

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp