rangetype-stat-crash.patch
text/x-diff
Filename: rangetype-stat-crash.patch
Type: text/x-diff
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/utils/adt/rangetypes_selfuncs.c | 3 | 1 |
| src/test/regress/expected/rangetypes.out | 13 | 0 |
| src/test/regress/sql/rangetypes.sql | 10 | 0 |
diff --git a/src/backend/utils/adt/rangetypes_selfuncs.c b/src/backend/utils/adt/rangetypes_selfuncs.c
index ab4f86e3fd..abe3f6170d 100644
--- a/src/backend/utils/adt/rangetypes_selfuncs.c
+++ b/src/backend/utils/adt/rangetypes_selfuncs.c
@@ -1045,7 +1045,9 @@ calc_hist_selectivity_contained(TypeCacheEntry *typcache,
bin_width = upper_bin_width;
sum_frac = 0.0;
- for (i = upper_index; i >= 0; i--)
+
+ /* Make sure to not count for the first bin */
+ for (i = upper_index - 1; i >= 0; i--)
{
double dist;
double length_hist_frac;
diff --git a/src/test/regress/expected/rangetypes.out b/src/test/regress/expected/rangetypes.out
index 6fd16bddd1..7656e5ea2c 100644
--- a/src/test/regress/expected/rangetypes.out
+++ b/src/test/regress/expected/rangetypes.out
@@ -1431,3 +1431,16 @@ create function table_fail(i anyelement) returns table(i anyelement, r anyrange)
as $$ select $1, '[1,10]' $$ language sql;
ERROR: cannot determine result data type
DETAIL: A function returning "anyrange" must have at least one "anyrange" argument.
+-- Corner case with selectivity of range operators, per bug #16122.
+CREATE TABLE rangetab (a numrange);
+INSERT INTO rangetab
+SELECT ('['|| (45.0 - a::numeric/10000000) || ',' ||
+ (45.1 + a::numeric/10000000) || ')')::numrange
+ FROM generate_series(1,1000) as a;
+ANALYZE rangetab;
+SELECT a FROM rangetab WHERE a <@ '[89.9999998611111,90.0000001388889)';
+ a
+---
+(0 rows)
+
+DROP TABLE rangetab;
diff --git a/src/test/regress/sql/rangetypes.sql b/src/test/regress/sql/rangetypes.sql
index 8960add976..b17e64113c 100644
--- a/src/test/regress/sql/rangetypes.sql
+++ b/src/test/regress/sql/rangetypes.sql
@@ -507,3 +507,13 @@ create function inoutparam_fail(inout i anyelement, out r anyrange)
--should fail
create function table_fail(i anyelement) returns table(i anyelement, r anyrange)
as $$ select $1, '[1,10]' $$ language sql;
+
+-- Corner case with selectivity of range operators, per bug #16122.
+CREATE TABLE rangetab (a numrange);
+INSERT INTO rangetab
+SELECT ('['|| (45.0 - a::numeric/10000000) || ',' ||
+ (45.1 + a::numeric/10000000) || ')')::numrange
+ FROM generate_series(1,1000) as a;
+ANALYZE rangetab;
+SELECT a FROM rangetab WHERE a <@ '[89.9999998611111,90.0000001388889)';
+DROP TABLE rangetab;