]> granicus.if.org Git - postgis/commitdiff
#2102, SQL hooks for calling selectivity functions
authorPaul Ramsey <pramsey@cleverelephant.ca>
Tue, 20 Nov 2012 20:51:42 +0000 (20:51 +0000)
committerPaul Ramsey <pramsey@cleverelephant.ca>
Tue, 20 Nov 2012 20:51:42 +0000 (20:51 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@10720 b70326c6-7e19-0410-871a-916f4a2858ee

postgis/geometry_estimate.c
postgis/postgis.sql.in.c

index 54b349fd912ab0c369fa277c87466e8f46f82adc..d260ed80fa450635789e9dd28f41e93366a51148 100644 (file)
@@ -116,6 +116,7 @@ static float8 estimate_selectivity(GBOX *box, GEOM_STATS *geomstats);
 
 Datum geometry_gist_sel_2d(PG_FUNCTION_ARGS);
 Datum geometry_gist_joinsel_2d(PG_FUNCTION_ARGS);
+Datum geometry_gist_read_selectivity(PG_FUNCTION_ARGS);
 Datum geometry_analyze_2d(PG_FUNCTION_ARGS);
 Datum geometry_estimated_extent(PG_FUNCTION_ARGS);
 
@@ -609,6 +610,52 @@ estimate_selectivity(GBOX *box, GEOM_STATS *geomstats)
        return selectivity;
 }
 
+/**
+* Utility function to read the calculated selectivity for a given search
+* box and table/column. Used for debugging the selectivity code.
+*/
+PG_FUNCTION_INFO_V1(geometry_gist_read_selectivity);
+Datum geometry_gist_read_selectivity(PG_FUNCTION_ARGS)
+{
+       HeapTuple stats_tuple;
+       float4 *floatptr;
+       int32 table_oid = PG_GETARG_INT32(0);
+       int32 attr_num = PG_GETARG_INT32(1);
+       Datum geom_datum = PG_GETARG_DATUM(2);
+       int rv;
+       GBOX gbox;
+       int32 nvalues = 0;
+       float8 selectivity = 0;
+
+       /* Calculate the gbox */
+       if ( ! gserialized_datum_get_gbox_p(geom_datum, &gbox) )
+               elog(ERROR, "Unable to calculate search box from geometry");
+       
+       /* First pull the stats tuple */
+       stats_tuple = SearchSysCache2(STATRELATT, Int32GetDatum(table_oid), Int32GetDatum(attr_num));
+       if ( ! stats_tuple )
+               elog(ERROR, "Unable to retreive stats tuple for oid(%d) attrnum(%d)", table_oid, attr_num);
+               
+       /* Then read the geom status histogram from that */
+       rv = get_attstatsslot(stats_tuple, 0, 0, STATISTIC_KIND_GEOMETRY, InvalidOid, NULL, NULL, NULL, &floatptr, &nvalues);
+       if ( ! rv )
+       {
+               ReleaseSysCache(stats_tuple);
+               elog(ERROR, "Unable to retreive geomstats");            
+       }
+       
+       /* Do the estimation */
+       selectivity = estimate_selectivity(&gbox, (GEOM_STATS*)floatptr);
+
+       /* Clean up */
+       free_attstatsslot(0, NULL, 0, floatptr, nvalues);
+       ReleaseSysCache(stats_tuple);
+       
+       PG_RETURN_FLOAT8(selectivity);
+}
+
+
+
 /**
  * This function should return an estimation of the number of
  * rows returned by a query involving an overlap check
index 71ec381f37056790726f072d5bfa53fd9b1d4266..664aeafb9bdd13a3cb8f716786adc51760b0fdcc 100644 (file)
@@ -428,6 +428,35 @@ CREATE OR REPLACE FUNCTION geometry_gist_joinsel_2d(internal, oid, internal, sma
        AS 'MODULE_PATHNAME', 'geometry_gist_joinsel_2d'
        LANGUAGE 'c';
 
+-- Availability: 2.1.0
+CREATE OR REPLACE FUNCTION geometry_gist_read_selectivity(relid integer, attnum integer, geom geometry)
+       RETURNS float8
+       AS 'MODULE_PATHNAME', 'geometry_gist_read_selectivity'
+       LANGUAGE 'c';
+       
+-- Availability: 2.1.0
+CREATE OR REPLACE FUNCTION geometry_gist_selectivity(schemaname varchar, tablename varchar, attrname varchar, geom geometry)
+       RETURNS float8
+       AS $$
+         DECLARE
+               selectivity float8;
+         BEGIN
+               SELECT geometry_gist_read_selectivity(r.oid::integer, a.attnum::integer, 'SRID=4326;LINESTRING(0 0, 1 1)'::geometry)
+               INTO selectivity
+               FROM pg_class r 
+           JOIN pg_attribute a ON (r.oid = a.attrelid) 
+           JOIN pg_namespace n ON (r.relnamespace = n.oid) 
+           WHERE  n.nspname = $1 AND r.relname = $2 and a.attname = $3;
+           IF NOT FOUND THEN
+                  RAISE EXCEPTION 'Couldn''t find table? column?';
+               END IF;
+               RETURN selectivity;
+         END;
+       $$
+       LANGUAGE 'plpgsql';
+
+
+
 -----------------------------------------------------------------------------
 -- GEOMETRY Operators
 -----------------------------------------------------------------------------