]> granicus.if.org Git - postgresql/commitdiff
Fix "element <@ range" cost estimation.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 21 Mar 2013 09:15:45 +0000 (11:15 +0200)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 21 Mar 2013 09:21:51 +0000 (11:21 +0200)
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.

src/backend/utils/adt/rangetypes_selfuncs.c
src/test/regress/expected/rangetypes.out
src/test/regress/sql/rangetypes.sql

index 76dc9138111aca162576150bf005890a4c2f128b..c450c6a1580f6b9e7f17b59ba8f115ee3c7ce886 100644 (file)
@@ -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);
        }
index 0cb6e53bf0773f2d59e391b97e4004b31e21ea7a..39db9927291965f581461ef6c6e371c12bf1bbd8 100644 (file)
@@ -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 "="
index 035fceca19a1834264f6628324cc02b49b1c4d10..fad843a405f599203b27e4a6d4cf9bc18a25e7b5 100644 (file)
@@ -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 "="