aboutsummaryrefslogtreecommitdiff
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
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.
-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 "="