Index: src/backend/utils/adt/selfuncs.c =================================================================== RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/utils/adt/selfuncs.c,v retrieving revision 1.250 diff -c -r1.250 selfuncs.c *** src/backend/utils/adt/selfuncs.c 7 Jul 2008 20:24:55 -0000 1.250 --- src/backend/utils/adt/selfuncs.c 6 Aug 2008 09:06:26 -0000 *************** *** 103,108 **** --- 103,111 ---- #include "utils/selfuncs.h" #include "utils/syscache.h" + /* Hook for plugins to get control when we ask for stats */ + get_relation_stats_hook_type get_relation_stats_hook = NULL; + release_relation_stats_hook_type release_relation_stats_hook = NULL; static double var_eq_const(VariableStatData *vardata, Oid operator, Datum constval, bool constisnull, *************** *** 3769,3775 **** } else if (rte->rtekind == RTE_RELATION) { ! vardata->statsTuple = SearchSysCache(STATRELATT, ObjectIdGetDatum(rte->relid), Int16GetDatum(var->varattno), 0, 0); --- 3772,3783 ---- } else if (rte->rtekind == RTE_RELATION) { ! if (get_relation_stats_hook) ! vardata->statsTuple = (*get_relation_stats_hook) ! (ObjectIdGetDatum(rte->relid), ! Int16GetDatum(var->varattno)); ! else ! vardata->statsTuple = SearchSysCache(STATRELATT, ObjectIdGetDatum(rte->relid), Int16GetDatum(var->varattno), 0, 0); *************** *** 3889,3898 **** index->indpred == NIL) vardata->isunique = true; /* Has it got stats? */ ! vardata->statsTuple = SearchSysCache(STATRELATT, ObjectIdGetDatum(index->indexoid), ! Int16GetDatum(pos + 1), ! 0, 0); if (vardata->statsTuple) break; } --- 3897,3911 ---- index->indpred == NIL) vardata->isunique = true; /* Has it got stats? */ ! if (get_relation_stats_hook) ! vardata->statsTuple = (*get_relation_stats_hook) ! (ObjectIdGetDatum(index->indexoid), ! Int16GetDatum(pos + 1)); ! else ! vardata->statsTuple = SearchSysCache(STATRELATT, ObjectIdGetDatum(index->indexoid), ! Int16GetDatum(pos + 1), ! 0, 0); if (vardata->statsTuple) break; } *************** *** 5527,5536 **** colnum = 1; } ! tuple = SearchSysCache(STATRELATT, ! ObjectIdGetDatum(relid), ! Int16GetDatum(colnum), ! 0, 0); if (HeapTupleIsValid(tuple)) { --- 5540,5554 ---- colnum = 1; } ! if (get_relation_stats_hook) ! tuple = (*get_relation_stats_hook) ( ! ObjectIdGetDatum(relid), ! Int16GetDatum(colnum)); ! else ! tuple = SearchSysCache(STATRELATT, ! ObjectIdGetDatum(relid), ! Int16GetDatum(colnum), ! 0, 0); if (HeapTupleIsValid(tuple)) { Index: src/backend/utils/cache/lsyscache.c =================================================================== RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/utils/cache/lsyscache.c,v retrieving revision 1.157 diff -c -r1.157 lsyscache.c *** src/backend/utils/cache/lsyscache.c 13 Apr 2008 20:51:21 -0000 1.157 --- src/backend/utils/cache/lsyscache.c 6 Aug 2008 09:10:41 -0000 *************** *** 27,32 **** --- 27,33 ---- #include "catalog/pg_proc.h" #include "catalog/pg_statistic.h" #include "catalog/pg_type.h" + #include "optimizer/plancat.h" #include "miscadmin.h" #include "nodes/makefuncs.h" #include "utils/array.h" *************** *** 35,40 **** --- 36,43 ---- #include "utils/lsyscache.h" #include "utils/syscache.h" + /* Hook for plugins to get control in get_attavgwidth() */ + get_attavgwidth_hook_type get_attavgwidth_hook = NULL; /* ---------- AMOP CACHES ---------- */ *************** *** 2451,2466 **** * * Given the table and attribute number of a column, get the average * width of entries in the column. Return zero if no data available. */ int32 get_attavgwidth(Oid relid, AttrNumber attnum) { HeapTuple tp; ! tp = SearchSysCache(STATRELATT, ObjectIdGetDatum(relid), Int16GetDatum(attnum), 0, 0); if (HeapTupleIsValid(tp)) { int32 stawidth = ((Form_pg_statistic) GETSTRUCT(tp))->stawidth; --- 2454,2480 ---- * * Given the table and attribute number of a column, get the average * width of entries in the column. Return zero if no data available. + * + * Calling a hook at this point looks somewhat strange, but is required + * because the optimizer handles inheritance relations by calling for + * the avg width later in the planner than get_relation_info_hook(). + * So the APIs and call points of hooks must match the optimizer. */ int32 get_attavgwidth(Oid relid, AttrNumber attnum) { HeapTuple tp; ! if (get_attavgwidth_hook) ! return (*get_attavgwidth_hook) ( ! ObjectIdGetDatum(relid), ! Int16GetDatum(attnum)); ! else ! tp = SearchSysCache(STATRELATT, ObjectIdGetDatum(relid), Int16GetDatum(attnum), 0, 0); + if (HeapTupleIsValid(tp)) { int32 stawidth = ((Form_pg_statistic) GETSTRUCT(tp))->stawidth; Index: src/include/optimizer/plancat.h =================================================================== RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/include/optimizer/plancat.h,v retrieving revision 1.50 diff -c -r1.50 plancat.h *** src/include/optimizer/plancat.h 19 Jun 2008 00:46:06 -0000 1.50 --- src/include/optimizer/plancat.h 6 Aug 2008 09:05:19 -0000 *************** *** 14,19 **** --- 14,20 ---- #ifndef PLANCAT_H #define PLANCAT_H + #include "access/htup.h" #include "nodes/relation.h" #include "utils/relcache.h" *************** *** 24,29 **** --- 25,41 ---- RelOptInfo *rel); extern PGDLLIMPORT get_relation_info_hook_type get_relation_info_hook; + /* Hooks for plugins to get control in lsyscache.c and selfuncs.c */ + typedef HeapTuple (*get_relation_stats_hook_type) (Datum relid, Datum attnum); + extern PGDLLIMPORT get_relation_stats_hook_type get_relation_stats_hook; + + typedef void (*release_relation_stats_hook_type) (HeapTuple statstup); + extern PGDLLIMPORT release_relation_stats_hook_type release_relation_stats_hook; + + typedef int32 (*get_attavgwidth_hook_type) (Datum relid, Datum attnum); + extern PGDLLIMPORT get_attavgwidth_hook_type get_attavgwidth_hook; + + extern void get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, RelOptInfo *rel); Index: src/include/utils/selfuncs.h =================================================================== RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/include/utils/selfuncs.h,v retrieving revision 1.44 diff -c -r1.44 selfuncs.h *** src/include/utils/selfuncs.h 9 Mar 2008 00:32:09 -0000 1.44 --- src/include/utils/selfuncs.h 6 Aug 2008 05:07:09 -0000 *************** *** 79,85 **** #define ReleaseVariableStats(vardata) \ do { \ if (HeapTupleIsValid((vardata).statsTuple)) \ ! ReleaseSysCache((vardata).statsTuple); \ } while(0) --- 79,90 ---- #define ReleaseVariableStats(vardata) \ do { \ if (HeapTupleIsValid((vardata).statsTuple)) \ ! { \ ! if (release_relation_stats_hook) \ ! (* release_relation_stats_hook)((vardata).statsTuple); \ ! else \ ! ReleaseSysCache((vardata).statsTuple); \ ! } \ } while(0)