PostGIS  2.1.10dev-r@@SVN_REVISION@@
Datum gserialized_gist_sel ( PG_FUNCTION_ARGS  )

Definition at line 2052 of file gserialized_estimate.c.

References DEFAULT_ND_SEL, estimate_selectivity(), FALLBACK_ND_SEL, gbox_to_string(), nd_stats_to_json(), and pg_get_nd_stats().

Referenced by gserialized_gist_sel_2d(), and gserialized_gist_sel_nd().

2053 {
2054  PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);
2055  /* Oid operator_oid = PG_GETARG_OID(1); */
2056  List *args = (List *) PG_GETARG_POINTER(2);
2057  /* int varRelid = PG_GETARG_INT32(3); */
2058  int mode = PG_GETARG_INT32(4);
2059 
2060  Oid relid;
2061  ND_STATS *nd_stats;
2062 
2063  Node *other;
2064  Var *self;
2065  GBOX search_box;
2066  float8 selectivity = 0;
2067 
2068  POSTGIS_DEBUG(2, "gserialized_gist_sel called");
2069 
2070  /*
2071  * TODO: This is a big one,
2072  * All this statistics code *only* tries to generate a valid
2073  * selectivity for && and &&&. That leaves all the other
2074  * geometry operators with bad stats! The selectivity
2075  * calculation should take account of the incoming operator
2076  * type and do the right thing.
2077  */
2078 
2079  /* Fail if not a binary opclause (probably shouldn't happen) */
2080  if (list_length(args) != 2)
2081  {
2082  POSTGIS_DEBUG(3, "gserialized_gist_sel: not a binary opclause");
2083  PG_RETURN_FLOAT8(DEFAULT_ND_SEL);
2084  }
2085 
2086  /* Find the constant part */
2087  other = (Node *) linitial(args);
2088  if ( ! IsA(other, Const) )
2089  {
2090  self = (Var *)other;
2091  other = (Node *) lsecond(args);
2092  }
2093  else
2094  {
2095  self = (Var *) lsecond(args);
2096  }
2097 
2098  if ( ! IsA(other, Const) )
2099  {
2100  POSTGIS_DEBUG(3, " no constant arguments - returning a default selectivity");
2101  PG_RETURN_FLOAT8(DEFAULT_ND_SEL);
2102  }
2103 
2104  /*
2105  * We don't have a nice <const> && <var> or <var> && <const>
2106  * situation here. <const> && <const> would probably get evaluated
2107  * away by PgSQL earlier on. <func> && <const> is harder, and the
2108  * case we get often is <const> && ST_Expand(<var>), which does
2109  * actually have a subtly different selectivity than a bae
2110  * <const> && <var> call. It's calculatable though, by expanding
2111  * every cell in the histgram appropriately.
2112  *
2113  * Discussion: http://trac.osgeo.org/postgis/ticket/1828
2114  *
2115  * To do? Do variable selectivity based on the <func> node.
2116  */
2117  if ( ! IsA(self, Var) )
2118  {
2119  POSTGIS_DEBUG(3, " no bare variable argument ? - returning a moderate selectivity");
2120  PG_RETURN_FLOAT8(FALLBACK_ND_SEL);
2121  }
2122 
2123  /* Convert the constant to a BOX */
2124  if( ! gserialized_datum_get_gbox_p(((Const*)other)->constvalue, &search_box) )
2125  {
2126  POSTGIS_DEBUG(3, "search box is EMPTY");
2127  PG_RETURN_FLOAT8(0.0);
2128  }
2129  POSTGIS_DEBUGF(4, " requested search box is: %s", gbox_to_string(&search_box));
2130 
2131  /* Get pg_statistic row */
2132  relid = getrelid(self->varno, root->parse->rtable);
2133  nd_stats = pg_get_nd_stats(relid, self->varattno, mode);
2134  if ( ! nd_stats )
2135  {
2136  POSTGIS_DEBUG(3, " unable to load stats from syscache, not analyzed yet?");
2137  PG_RETURN_FLOAT8(FALLBACK_ND_SEL);
2138  }
2139  POSTGIS_DEBUGF(4, " got stats:\n%s", nd_stats_to_json(nd_stats));
2140 
2141  /* Do the estimation! */
2142  selectivity = estimate_selectivity(&search_box, nd_stats, mode);
2143  POSTGIS_DEBUGF(3, " returning computed value: %f", selectivity);
2144 
2145  pfree(nd_stats);
2146  PG_RETURN_FLOAT8(selectivity);
2147 }
char * gbox_to_string(const GBOX *gbox)
Allocate a string representation of the GBOX, based on dimensionality of flags.
Definition: g_box.c:328
#define FALLBACK_ND_SEL
More modest fallback selectivity factor.
static float8 estimate_selectivity(const GBOX *box, const ND_STATS *nd_stats, int mode)
This function returns an estimate of the selectivity of a search GBOX by looking at data in the ND_ST...
static ND_STATS * pg_get_nd_stats(const Oid table_oid, AttrNumber att_num, int mode)
Pull the stats object from the PgSQL system catalogs.
static char * nd_stats_to_json(const ND_STATS *nd_stats)
Convert an ND_STATS to a JSON representation for external use.
N-dimensional statistics structure.
#define DEFAULT_ND_SEL
Default geometry selectivity factor.

Here is the call graph for this function:

Here is the caller graph for this function: