@ -25,6 +25,7 @@
# include "catalog/pg_statistic_ext.h"
# include "catalog/pg_statistic_ext_data.h"
# include "executor/executor.h"
# include "commands/defrem.h"
# include "commands/progress.h"
# include "miscadmin.h"
# include "nodes/nodeFuncs.h"
@ -78,7 +79,7 @@ typedef struct StatExtEntry
static List * fetch_statentries_for_relation ( Relation pg_statext , Oid relid ) ;
static VacAttrStats * * lookup_var_attr_stats ( Relation rel , Bitmapset * attrs , List * exprs ,
int nvacatts , VacAttrStats * * vacatts ) ;
static void statext_store ( Oid statOid ,
static void statext_store ( Oid statOid , bool inh ,
MVNDistinct * ndistinct , MVDependencies * dependencies ,
MCVList * mcv , Datum exprs , VacAttrStats * * stats ) ;
static int statext_compute_stattarget ( int stattarget ,
@ -111,7 +112,7 @@ static StatsBuildData *make_build_data(Relation onerel, StatExtEntry *stat,
* requested stats , and serializes them back into the catalog .
*/
void
BuildRelationExtStatistics ( Relation onerel , double totalrows ,
BuildRelationExtStatistics ( Relation onerel , bool inh , double totalrows ,
int numrows , HeapTuple * rows ,
int natts , VacAttrStats * * vacattrstats )
{
@ -231,7 +232,8 @@ BuildRelationExtStatistics(Relation onerel, double totalrows,
}
/* store the statistics in the catalog */
statext_store ( stat - > statOid , ndistinct , dependencies , mcv , exprstats , stats ) ;
statext_store ( stat - > statOid , inh ,
ndistinct , dependencies , mcv , exprstats , stats ) ;
/* for reporting progress */
pgstat_progress_update_param ( PROGRESS_ANALYZE_EXT_STATS_COMPUTED ,
@ -782,23 +784,27 @@ lookup_var_attr_stats(Relation rel, Bitmapset *attrs, List *exprs,
* tuple .
*/
static void
statext_store ( Oid statOid ,
statext_store ( Oid statOid , bool inh ,
MVNDistinct * ndistinct , MVDependencies * dependencies ,
MCVList * mcv , Datum exprs , VacAttrStats * * stats )
{
Relation pg_stextdata ;
HeapTuple stup ,
oldtup ;
HeapTuple stup ;
Datum values [ Natts_pg_statistic_ext_data ] ;
bool nulls [ Natts_pg_statistic_ext_data ] ;
bool replaces [ Natts_pg_statistic_ext_data ] ;
pg_stextdata = table_open ( StatisticExtDataRelationId , RowExclusiveLock ) ;
memset ( nulls , true , sizeof ( nulls ) ) ;
memset ( replaces , false , sizeof ( replaces ) ) ;
memset ( values , 0 , sizeof ( values ) ) ;
/* basic info */
values [ Anum_pg_statistic_ext_data_stxoid - 1 ] = ObjectIdGetDatum ( statOid ) ;
nulls [ Anum_pg_statistic_ext_data_stxoid - 1 ] = false ;
values [ Anum_pg_statistic_ext_data_stxdinherit - 1 ] = BoolGetDatum ( inh ) ;
nulls [ Anum_pg_statistic_ext_data_stxdinherit - 1 ] = false ;
/*
* Construct a new pg_statistic_ext_data tuple , replacing the calculated
* stats .
@ -831,25 +837,15 @@ statext_store(Oid statOid,
values [ Anum_pg_statistic_ext_data_stxdexpr - 1 ] = exprs ;
}
/* always replace the value (either by bytea or NULL) */
replaces [ Anum_pg_statistic_ext_data_stxdndistinct - 1 ] = true ;
replaces [ Anum_pg_statistic_ext_data_stxddependencies - 1 ] = true ;
replaces [ Anum_pg_statistic_ext_data_stxdmcv - 1 ] = true ;
replaces [ Anum_pg_statistic_ext_data_stxdexpr - 1 ] = true ;
/* there should already be a pg_statistic_ext_data tuple */
oldtup = SearchSysCache1 ( STATEXTDATASTXOID , ObjectIdGetDatum ( statOid ) ) ;
if ( ! HeapTupleIsValid ( oldtup ) )
elog ( ERROR , " cache lookup failed for statistics object %u " , statOid ) ;
/* replace it */
stup = heap_modify_tuple ( oldtup ,
RelationGetDescr ( pg_stextdata ) ,
values ,
nulls ,
replaces ) ;
ReleaseSysCache ( oldtup ) ;
CatalogTupleUpdate ( pg_stextdata , & stup - > t_self , stup ) ;
/*
* Delete the old tuple if it exists , and insert a new one . It ' s easier
* than trying to update or insert , based on various conditions .
*/
RemoveStatisticsDataById ( statOid , inh ) ;
/* form and insert a new tuple */
stup = heap_form_tuple ( RelationGetDescr ( pg_stextdata ) , values , nulls ) ;
CatalogTupleInsert ( pg_stextdata , stup ) ;
heap_freetuple ( stup ) ;
@ -1235,7 +1231,7 @@ stat_covers_expressions(StatisticExtInfo *stat, List *exprs,
* further tiebreakers are needed .
*/
StatisticExtInfo *
choose_best_statistics ( List * stats , char requiredkind ,
choose_best_statistics ( List * stats , char requiredkind , bool inh ,
Bitmapset * * clause_attnums , List * * clause_exprs ,
int nclauses )
{
@ -1257,6 +1253,10 @@ choose_best_statistics(List *stats, char requiredkind,
if ( info - > kind ! = requiredkind )
continue ;
/* skip statistics with mismatching inheritance flag */
if ( info - > inherit ! = inh )
continue ;
/*
* Collect attributes and expressions in remaining ( unestimated )
* clauses fully covered by this statistic object .
@ -1697,16 +1697,6 @@ statext_mcv_clauselist_selectivity(PlannerInfo *root, List *clauses, int varReli
Selectivity sel = ( is_or ) ? 0.0 : 1.0 ;
RangeTblEntry * rte = planner_rt_fetch ( rel - > relid , root ) ;
/*
* When dealing with regular inheritance trees , ignore extended stats
* ( which were built without data from child rels , and thus do not
* represent them ) . For partitioned tables data there ' s no data in the
* non - leaf relations , so we build stats only for the inheritance tree .
* So for partitioned tables we do consider extended stats .
*/
if ( rte - > inh & & rte - > relkind ! = RELKIND_PARTITIONED_TABLE )
return sel ;
/* check if there's any stats that might be useful for us. */
if ( ! has_stats_of_kind ( rel - > statlist , STATS_EXT_MCV ) )
return sel ;
@ -1758,7 +1748,7 @@ statext_mcv_clauselist_selectivity(PlannerInfo *root, List *clauses, int varReli
Bitmapset * simple_clauses ;
/* find the best suited statistics object for these attnums */
stat = choose_best_statistics ( rel - > statlist , STATS_EXT_MCV ,
stat = choose_best_statistics ( rel - > statlist , STATS_EXT_MCV , rte - > inh ,
list_attnums , list_exprs ,
list_length ( clauses ) ) ;
@ -1847,7 +1837,7 @@ statext_mcv_clauselist_selectivity(PlannerInfo *root, List *clauses, int varReli
MCVList * mcv_list ;
/* Load the MCV list stored in the statistics object */
mcv_list = statext_mcv_load ( stat - > statOid ) ;
mcv_list = statext_mcv_load ( stat - > statOid , rte - > inh ) ;
/*
* Compute the selectivity of the ORed list of clauses covered by
@ -2408,7 +2398,7 @@ serialize_expr_stats(AnlExprData *exprdata, int nexprs)
* identified by the supplied index .
*/
HeapTuple
statext_expressions_load ( Oid stxoid , int idx )
statext_expressions_load ( Oid stxoid , bool inh , int idx )
{
bool isnull ;
Datum value ;
@ -2418,7 +2408,8 @@ statext_expressions_load(Oid stxoid, int idx)
HeapTupleData tmptup ;
HeapTuple tup ;
htup = SearchSysCache1 ( STATEXTDATASTXOID , ObjectIdGetDatum ( stxoid ) ) ;
htup = SearchSysCache2 ( STATEXTDATASTXOID ,
ObjectIdGetDatum ( stxoid ) , BoolGetDatum ( inh ) ) ;
if ( ! HeapTupleIsValid ( htup ) )
elog ( ERROR , " cache lookup failed for statistics object %u " , stxoid ) ;