aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2013-03-21 11:15:45 +0200
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2013-03-21 11:21:51 +0200
commitf897c4744fea221dfc7bbd277081edad41d1d58d (patch)
tree75da93ace14f37af7ee4819efcd1db9ff9ff7427 /src
parentf8348ea32ec8d713cd6e5d5e16f15edef22c4d03 (diff)
downloadpostgresql-f897c4744fea221dfc7bbd277081edad41d1d58d.tar.gz
postgresql-f897c4744fea221dfc7bbd277081edad41d1d58d.zip
Fix "element <@ range" cost estimation.
The statistics-based cost estimation patch for range types broke that, by incorrectly assuming that the left operand of all range oeprators is a range. That lead to a "type x is not a range type" error. Because it took so long for anyone to notice, add a regression test for that case. We still don't do proper statistics-based cost estimation for that, so you just get a default constant estimate. We should look into implementing that, but this patch at least fixes the regression. Spotted by Tom Lane, when testing query from Josh Berkus.
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/rangetypes_selfuncs.c6
-rw-r--r--src/test/regress/expected/rangetypes.out11
-rw-r--r--src/test/regress/sql/rangetypes.sql9
3 files changed, 24 insertions, 2 deletions
diff --git a/src/backend/utils/adt/rangetypes_selfuncs.c b/src/backend/utils/adt/rangetypes_selfuncs.c
index 76dc9138111..c450c6a1580 100644
--- a/src/backend/utils/adt/rangetypes_selfuncs.c
+++ b/src/backend/utils/adt/rangetypes_selfuncs.c
@@ -154,8 +154,6 @@ rangesel(PG_FUNCTION_ARGS)
}
}
- typcache = range_get_typcache(fcinfo, vardata.vartype);
-
/*
* OK, there's a Var and a Const we're dealing with here. We need the
* Const to be of same range type as the column, else we can't do anything
@@ -169,6 +167,8 @@ rangesel(PG_FUNCTION_ARGS)
*/
if (operator == OID_RANGE_CONTAINS_ELEM_OP)
{
+ typcache = range_get_typcache(fcinfo, vardata.vartype);
+
if (((Const *) other)->consttype == typcache->rngelemtype->type_id)
{
RangeBound lower, upper;
@@ -185,6 +185,8 @@ rangesel(PG_FUNCTION_ARGS)
}
else
{
+ typcache = range_get_typcache(fcinfo, ((Const *) other)->consttype);
+
if (((Const *) other)->consttype == vardata.vartype)
constrange = DatumGetRangeType(((Const *) other)->constvalue);
}
diff --git a/src/test/regress/expected/rangetypes.out b/src/test/regress/expected/rangetypes.out
index 0cb6e53bf07..39db9927291 100644
--- a/src/test/regress/expected/rangetypes.out
+++ b/src/test/regress/expected/rangetypes.out
@@ -1043,6 +1043,17 @@ select count(*) from test_range_spgist where ir -|- int4range(100,500);
RESET enable_seqscan;
RESET enable_indexscan;
RESET enable_bitmapscan;
+-- test elem <@ range operator
+create table test_range_elem(i int4);
+create index test_range_elem_idx on test_range_elem (i);
+insert into test_range_elem select i from generate_series(1,100) i;
+select count(*) from test_range_elem where i <@ int4range(10,50);
+ count
+-------
+ 40
+(1 row)
+
+drop table test_range_elem;
--
-- Btree_gist is not included by default, so to test exclusion
-- constraints with range types, use singleton int ranges for the "="
diff --git a/src/test/regress/sql/rangetypes.sql b/src/test/regress/sql/rangetypes.sql
index 035fceca19a..fad843a405f 100644
--- a/src/test/regress/sql/rangetypes.sql
+++ b/src/test/regress/sql/rangetypes.sql
@@ -286,6 +286,15 @@ RESET enable_seqscan;
RESET enable_indexscan;
RESET enable_bitmapscan;
+-- test elem <@ range operator
+create table test_range_elem(i int4);
+create index test_range_elem_idx on test_range_elem (i);
+insert into test_range_elem select i from generate_series(1,100) i;
+
+select count(*) from test_range_elem where i <@ int4range(10,50);
+
+drop table test_range_elem;
+
--
-- Btree_gist is not included by default, so to test exclusion
-- constraints with range types, use singleton int ranges for the "="