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

Commit874d97c

Browse files
committed
Fix bugs in contrib/pg_trgm's LIKE pattern analysis code.
Extraction of trigrams did not process LIKE escape sequences properly,leading to possible misidentification of trigrams near escapes, resultingin incorrect index search results.Fujii Masao
1 parent7665e82 commit874d97c

File tree

3 files changed

+39
-19
lines changed

3 files changed

+39
-19
lines changed

‎contrib/pg_trgm/expected/pg_trgm.out

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3497,6 +3497,12 @@ select * from test2 where t like '%bcd%';
34973497
abcdef
34983498
(1 row)
34993499

3500+
select * from test2 where t like E'%\\bcd%';
3501+
t
3502+
--------
3503+
abcdef
3504+
(1 row)
3505+
35003506
select * from test2 where t ilike '%BCD%';
35013507
t
35023508
--------
@@ -3539,6 +3545,12 @@ select * from test2 where t like '%bcd%';
35393545
abcdef
35403546
(1 row)
35413547

3548+
select * from test2 where t like E'%\\bcd%';
3549+
t
3550+
--------
3551+
abcdef
3552+
(1 row)
3553+
35423554
select * from test2 where t ilike '%BCD%';
35433555
t
35443556
--------

‎contrib/pg_trgm/sql/pg_trgm.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ explain (costs off)
4949
select * from test2 where t ilike'%BCD%';
5050
select * from test2 where t like'%BCD%';
5151
select * from test2 where t like'%bcd%';
52+
select * from test2 where t like E'%\\bcd%';
5253
select * from test2 where t ilike'%BCD%';
5354
select * from test2 where t ilike'qua%';
5455
drop index test2_idx_gin;
@@ -60,5 +61,6 @@ explain (costs off)
6061
select * from test2 where t ilike'%BCD%';
6162
select * from test2 where t like'%BCD%';
6263
select * from test2 where t like'%bcd%';
64+
select * from test2 where t like E'%\\bcd%';
6365
select * from test2 where t ilike'%BCD%';
6466
select * from test2 where t ilike'qua%';

‎contrib/pg_trgm/trgm_op.c

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -273,33 +273,36 @@ get_wildcard_part(const char *str, int lenstr,
273273
constchar*beginword=str;
274274
constchar*endword;
275275
char*s=buf;
276-
boolin_wildcard_meta= false;
276+
boolin_leading_wildcard_meta= false;
277+
boolin_trailing_wildcard_meta= false;
277278
boolin_escape= false;
278279
intclen;
279280

280281
/*
281-
* Find the first word character remembering whether last character was
282-
* wildcard meta-character.
282+
* Find the first word character, remembering whether preceding character
283+
* was wildcard meta-character. Note that the in_escape state persists
284+
* from this loop to the next one, since we may exit at a word character
285+
* that is in_escape.
283286
*/
284287
while (beginword-str<lenstr)
285288
{
286289
if (in_escape)
287290
{
288-
in_escape= false;
289-
in_wildcard_meta= false;
290291
if (iswordchr(beginword))
291292
break;
293+
in_escape= false;
294+
in_leading_wildcard_meta= false;
292295
}
293296
else
294297
{
295298
if (ISESCAPECHAR(beginword))
296299
in_escape= true;
297300
elseif (ISWILDCARDCHAR(beginword))
298-
in_wildcard_meta= true;
301+
in_leading_wildcard_meta= true;
299302
elseif (iswordchr(beginword))
300303
break;
301304
else
302-
in_wildcard_meta= false;
305+
in_leading_wildcard_meta= false;
303306
}
304307
beginword+=pg_mblen(beginword);
305308
}
@@ -311,11 +314,11 @@ get_wildcard_part(const char *str, int lenstr,
311314
returnNULL;
312315

313316
/*
314-
* Add left padding spaces iflast character wasn't wildcard
317+
* Add left padding spaces ifpreceding character wasn't wildcard
315318
* meta-character.
316319
*/
317320
*charlen=0;
318-
if (!in_wildcard_meta)
321+
if (!in_leading_wildcard_meta)
319322
{
320323
if (LPADDING>0)
321324
{
@@ -334,31 +337,37 @@ get_wildcard_part(const char *str, int lenstr,
334337
* string boundary. Strip escapes during copy.
335338
*/
336339
endword=beginword;
337-
in_wildcard_meta= false;
338-
in_escape= false;
339340
while (endword-str<lenstr)
340341
{
341342
clen=pg_mblen(endword);
342343
if (in_escape)
343344
{
344-
in_escape= false;
345-
in_wildcard_meta= false;
346345
if (iswordchr(endword))
347346
{
348347
memcpy(s,endword,clen);
349348
(*charlen)++;
350349
s+=clen;
351350
}
352351
else
352+
{
353+
/*
354+
* Back up endword to the escape character when stopping at
355+
* an escaped char, so that subsequent get_wildcard_part will
356+
* restart from the escape character. We assume here that
357+
* escape chars are single-byte.
358+
*/
359+
endword--;
353360
break;
361+
}
362+
in_escape= false;
354363
}
355364
else
356365
{
357366
if (ISESCAPECHAR(endword))
358367
in_escape= true;
359368
elseif (ISWILDCARDCHAR(endword))
360369
{
361-
in_wildcard_meta= true;
370+
in_trailing_wildcard_meta= true;
362371
break;
363372
}
364373
elseif (iswordchr(endword))
@@ -368,19 +377,16 @@ get_wildcard_part(const char *str, int lenstr,
368377
s+=clen;
369378
}
370379
else
371-
{
372-
in_wildcard_meta= false;
373380
break;
374-
}
375381
}
376382
endword+=clen;
377383
}
378384

379385
/*
380-
* Add right padding spaces iflast characterwasn't wildcard
386+
* Add right padding spaces ifnext characterisn't wildcard
381387
* meta-character.
382388
*/
383-
if (!in_wildcard_meta)
389+
if (!in_trailing_wildcard_meta)
384390
{
385391
if (RPADDING>0)
386392
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp