diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2008-09-28 20:42:12 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2008-09-28 20:42:12 +0000 |
commit | 2dbc0ca937f8ba9c76866a99fd04866232acea95 (patch) | |
tree | d37f6e1b7ad254fcbf16ee4127274192bcc1cf87 | |
parent | 7b7df9f0b147bfb15599b73ae1a5fcf26739fd93 (diff) | |
download | postgresql-2dbc0ca937f8ba9c76866a99fd04866232acea95.tar.gz postgresql-2dbc0ca937f8ba9c76866a99fd04866232acea95.zip |
Dept of second thoughts: let's make sure that get_index_stats_hook is only
applied to expression indexes, not to plain relations. The original coding
in btcostestimate conflated the two cases, but it's not hard to use
get_relation_stats_hook instead when we're looking to the underlying relation.
-rw-r--r-- | src/backend/utils/adt/selfuncs.c | 69 |
1 files changed, 46 insertions, 23 deletions
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index e2336ea4f21..fc9853a43a9 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.254 2008/09/28 19:51:40 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.255 2008/09/28 20:42:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -5777,40 +5777,63 @@ btcostestimate(PG_FUNCTION_ARGS) if (found_saop) PG_RETURN_VOID(); + MemSet(&vardata, 0, sizeof(vardata)); + if (index->indexkeys[0] != 0) { /* Simple variable --- look to stats for the underlying table */ - relid = getrelid(index->rel->relid, root->parse->rtable); + RangeTblEntry *rte = planner_rt_fetch(index->rel->relid, root); + + Assert(rte->rtekind == RTE_RELATION); + relid = rte->relid; Assert(relid != InvalidOid); colnum = index->indexkeys[0]; + + if (get_relation_stats_hook && + (*get_relation_stats_hook) (root, rte, colnum, &vardata)) + { + /* + * The hook took control of acquiring a stats tuple. If it did + * supply a tuple, it'd better have supplied a freefunc. + */ + if (HeapTupleIsValid(vardata.statsTuple) && + !vardata.freefunc) + elog(ERROR, "no function provided to release variable stats with"); + } + else + { + vardata.statsTuple = SearchSysCache(STATRELATT, + ObjectIdGetDatum(relid), + Int16GetDatum(colnum), + 0, 0); + vardata.freefunc = ReleaseSysCache; + } } else { /* Expression --- maybe there are stats for the index itself */ relid = index->indexoid; colnum = 1; - } - - MemSet(&vardata, 0, sizeof(vardata)); - if (get_index_stats_hook && - (*get_index_stats_hook) (root, relid, colnum, &vardata)) - { - /* - * The hook took control of acquiring a stats tuple. If it did supply - * a tuple, it'd better have supplied a freefunc. - */ - if (HeapTupleIsValid(vardata.statsTuple) && - !vardata.freefunc) - elog(ERROR, "no function provided to release variable stats with"); - } - else - { - vardata.statsTuple = SearchSysCache(STATRELATT, - ObjectIdGetDatum(relid), - Int16GetDatum(colnum), - 0, 0); - vardata.freefunc = ReleaseSysCache; + if (get_index_stats_hook && + (*get_index_stats_hook) (root, relid, colnum, &vardata)) + { + /* + * The hook took control of acquiring a stats tuple. If it did + * supply a tuple, it'd better have supplied a freefunc. + */ + if (HeapTupleIsValid(vardata.statsTuple) && + !vardata.freefunc) + elog(ERROR, "no function provided to release variable stats with"); + } + else + { + vardata.statsTuple = SearchSysCache(STATRELATT, + ObjectIdGetDatum(relid), + Int16GetDatum(colnum), + 0, 0); + vardata.freefunc = ReleaseSysCache; + } } if (HeapTupleIsValid(vardata.statsTuple)) |