diff --git a/contrib/pg_trgm/expected/pg_trgm.out b/contrib/pg_trgm/expected/pg_trgm.out index 78e8174f86..9bc55f1d0d 100644 --- a/contrib/pg_trgm/expected/pg_trgm.out +++ b/contrib/pg_trgm/expected/pg_trgm.out @@ -3838,3 +3838,56 @@ select * from test2 where t ~ ' z foo'; z foo bar (1 row) +-- Check similarity threshold (bug #14202) +CREATE TEMP TABLE restaurants (city text); +INSERT INTO restaurants SELECT 'Warsaw' FROM generate_series(1, 10000); +INSERT INTO restaurants SELECT 'Szczecin' FROM generate_series(1, 10000); +CREATE INDEX ON restaurants USING gist(city gist_trgm_ops); +-- Similarity of the two names (for reference). +SELECT similarity('Szczecin', 'Warsaw'); + similarity +------------ + 0 +(1 row) + +-- Should get only 'Warsaw' for either setting of set_limit. +EXPLAIN (COSTS OFF) +SELECT DISTINCT city, similarity(city, 'Warsaw'), show_limit() + FROM restaurants WHERE city % 'Warsaw'; + QUERY PLAN +------------------------------------------------------------- + Unique + -> Sort + Sort Key: city, (similarity(city, 'Warsaw'::text)) + -> Bitmap Heap Scan on restaurants + Recheck Cond: (city % 'Warsaw'::text) + -> Bitmap Index Scan on restaurants_city_idx + Index Cond: (city % 'Warsaw'::text) +(7 rows) + +SELECT set_limit(0.3); + set_limit +----------- + 0.3 +(1 row) + +SELECT DISTINCT city, similarity(city, 'Warsaw'), show_limit() + FROM restaurants WHERE city % 'Warsaw'; + city | similarity | show_limit +--------+------------+------------ + Warsaw | 1 | 0.3 +(1 row) + +SELECT set_limit(0.5); + set_limit +----------- + 0.5 +(1 row) + +SELECT DISTINCT city, similarity(city, 'Warsaw'), show_limit() + FROM restaurants WHERE city % 'Warsaw'; + city | similarity | show_limit +--------+------------+------------ + Warsaw | 1 | 0.5 +(1 row) + diff --git a/contrib/pg_trgm/sql/pg_trgm.sql b/contrib/pg_trgm/sql/pg_trgm.sql index 6cefc8e643..244946bb8d 100644 --- a/contrib/pg_trgm/sql/pg_trgm.sql +++ b/contrib/pg_trgm/sql/pg_trgm.sql @@ -113,3 +113,24 @@ select * from test2 where t ~ 'z foo bar'; select * from test2 where t ~ ' z foo bar'; select * from test2 where t ~ ' z foo bar'; select * from test2 where t ~ ' z foo'; + +-- Check similarity threshold (bug #14202) + +CREATE TEMP TABLE restaurants (city text); +INSERT INTO restaurants SELECT 'Warsaw' FROM generate_series(1, 10000); +INSERT INTO restaurants SELECT 'Szczecin' FROM generate_series(1, 10000); +CREATE INDEX ON restaurants USING gist(city gist_trgm_ops); + +-- Similarity of the two names (for reference). +SELECT similarity('Szczecin', 'Warsaw'); + +-- Should get only 'Warsaw' for either setting of set_limit. +EXPLAIN (COSTS OFF) +SELECT DISTINCT city, similarity(city, 'Warsaw'), show_limit() + FROM restaurants WHERE city % 'Warsaw'; +SELECT set_limit(0.3); +SELECT DISTINCT city, similarity(city, 'Warsaw'), show_limit() + FROM restaurants WHERE city % 'Warsaw'; +SELECT set_limit(0.5); +SELECT DISTINCT city, similarity(city, 'Warsaw'), show_limit() + FROM restaurants WHERE city % 'Warsaw'; diff --git a/contrib/pg_trgm/trgm_gist.c b/contrib/pg_trgm/trgm_gist.c index 3a5aff9ede..f52867df32 100644 --- a/contrib/pg_trgm/trgm_gist.c +++ b/contrib/pg_trgm/trgm_gist.c @@ -296,16 +296,9 @@ gtrgm_consistent(PG_FUNCTION_ARGS) if (GIST_LEAF(entry)) { /* all leafs contains orig trgm */ + double tmpsml = cnt_sml(qtrg, key, *recheck); - /* - * Prevent gcc optimizing the tmpsml variable using volatile - * keyword. Otherwise comparison of nlimit and tmpsml may give - * wrong results. - */ - float4 volatile tmpsml = cnt_sml(qtrg, key, *recheck); - - /* strange bug at freebsd 5.2.1 and gcc 3.3.3 */ - res = (*(int *) &tmpsml == *(int *) &nlimit || tmpsml > nlimit); + res = (tmpsml >= nlimit); } else if (ISALLTRUE(key)) { /* non-leaf contains signature */