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

Commit22926e0

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 parenta4da35a commit22926e0

File tree

1 file changed

+90
-41
lines changed

1 file changed

+90
-41
lines changed

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

Lines changed: 90 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -213,63 +213,112 @@ makeTSQuerySign(TSQuery a)
213213
returnsign;
214214
}
215215

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

233-
PG_RETURN_BOOL(false);
238+
values[nvalues++]=val;
239+
}
240+
ptr++;
234241
}
235242

236-
sq=makeTSQuerySign(query);
237-
se=makeTSQuerySign(ex);
243+
*nvalues_p=nvalues;
244+
returnvalues;
245+
}
246+
247+
staticint
248+
cmp_string(constvoid*a,constvoid*b)
249+
{
250+
constchar*sa=*((constchar**)a);
251+
constchar*sb=*((constchar**)b);
252+
returnstrcmp(sa,sb);
253+
}
238254

239-
if ((sq&se)!=se)
255+
staticint
256+
remove_duplicates(char**strings,intn)
257+
{
258+
if (n <=1)
259+
returnn;
260+
else
240261
{
241-
PG_FREE_IF_COPY(query,0);
242-
PG_FREE_IF_COPY(ex,1);
262+
inti;
263+
char*prev=strings[0];
264+
intnew_n=1;
243265

244-
PG_RETURN_BOOL(false);
266+
for (i=1;i<n;i++)
267+
{
268+
if (strcmp(strings[i],prev)!=0)
269+
{
270+
strings[new_n++]=strings[i];
271+
prev=strings[i];
272+
}
273+
}
274+
returnnew_n;
245275
}
276+
}
246277

247-
iq=GETQUERY(query);
248-
ie=GETQUERY(ex);
249-
250-
for (i=0;i<ex->size;i++)
278+
Datum
279+
tsq_mcontains(PG_FUNCTION_ARGS)
280+
{
281+
TSQueryquery=PG_GETARG_TSQUERY(0);
282+
TSQueryex=PG_GETARG_TSQUERY(1);
283+
char**query_values;
284+
intquery_nvalues;
285+
char**ex_values;
286+
intex_nvalues;
287+
boolresult= true;
288+
289+
/* Extract the query terms into arrays */
290+
query_values=collectTSQueryValues(query,&query_nvalues);
291+
ex_values=collectTSQueryValues(ex,&ex_nvalues);
292+
293+
/* Sort and remove duplicates from both arrays */
294+
qsort(query_values,query_nvalues,sizeof(char*),cmp_string);
295+
query_nvalues=remove_duplicates(query_values,query_nvalues);
296+
qsort(ex_values,ex_nvalues,sizeof(char*),cmp_string);
297+
ex_nvalues=remove_duplicates(ex_values,ex_nvalues);
298+
299+
if (ex_nvalues>query_nvalues)
300+
result= false;
301+
else
251302
{
252-
if (ie[i].type!=QI_VAL)
253-
continue;
254-
for (j=0;j<query->size;j++)
303+
inti;
304+
intj=0;
305+
306+
for (i=0;i<ex_nvalues;i++)
255307
{
256-
if (iq[j].type==QI_VAL&&
257-
ie[i].qoperand.valcrc==iq[j].qoperand.valcrc)
308+
for (;j<query_nvalues;j++)
309+
{
310+
if (strcmp(ex_values[i],query_values[j])==0)
311+
break;
312+
}
313+
if (j==query_nvalues)
314+
{
315+
result= false;
258316
break;
259-
}
260-
if (j >=query->size)
261-
{
262-
PG_FREE_IF_COPY(query,0);
263-
PG_FREE_IF_COPY(ex,1);
264-
265-
PG_RETURN_BOOL(false);
317+
}
266318
}
267319
}
268320

269-
PG_FREE_IF_COPY(query,0);
270-
PG_FREE_IF_COPY(ex,1);
271-
272-
PG_RETURN_BOOL(true);
321+
PG_RETURN_BOOL(result);
273322
}
274323

275324
Datum

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp