* If the appropriate flavor of the n_distinct option is
* specified, override with the corresponding value.
*/
- aopt = get_attribute_options(onerel->rd_id, stats->attr->attnum);
+ aopt = get_attribute_options(onerel->rd_id, stats->tupattnum);
if (aopt != NULL)
{
float8 n_distinct;
for (i = 0; i < attr_cnt; i++)
{
VacAttrStats *stats = thisdata->vacattrstats[i];
- int attnum = stats->attr->attnum;
+ int attnum = stats->tupattnum;
if (isnull[attnum - 1])
{
return NULL;
/*
- * Create the VacAttrStats struct. Note that we only have a copy of the
- * fixed fields of the pg_attribute tuple.
+ * Create the VacAttrStats struct.
*/
stats = (VacAttrStats *) palloc0(sizeof(VacAttrStats));
- stats->attr = (Form_pg_attribute) palloc(ATTRIBUTE_FIXED_PART_SIZE);
- memcpy(stats->attr, attr, ATTRIBUTE_FIXED_PART_SIZE);
+ stats->attstattarget = attr->attstattarget;
/*
* When analyzing an expression index, believe the expression tree's type
if (!ok || stats->compute_stats == NULL || stats->minrows <= 0)
{
heap_freetuple(typtuple);
- pfree(stats->attr);
pfree(stats);
return NULL;
}
}
values[Anum_pg_statistic_starelid - 1] = ObjectIdGetDatum(relid);
- values[Anum_pg_statistic_staattnum - 1] = Int16GetDatum(stats->attr->attnum);
+ values[Anum_pg_statistic_staattnum - 1] = Int16GetDatum(stats->tupattnum);
values[Anum_pg_statistic_stainherit - 1] = BoolGetDatum(inh);
values[Anum_pg_statistic_stanullfrac - 1] = Float4GetDatum(stats->stanullfrac);
values[Anum_pg_statistic_stawidth - 1] = Int32GetDatum(stats->stawidth);
/* Is there already a pg_statistic tuple for this attribute? */
oldtup = SearchSysCache3(STATRELATTINH,
ObjectIdGetDatum(relid),
- Int16GetDatum(stats->attr->attnum),
+ Int16GetDatum(stats->tupattnum),
BoolGetDatum(inh));
/* Open index information when we know we need it */
bool
std_typanalyze(VacAttrStats *stats)
{
- Form_pg_attribute attr = stats->attr;
Oid ltopr;
Oid eqopr;
StdAnalyzeData *mystats;
/* If the attstattarget column is negative, use the default value */
- /* NB: it is okay to scribble on stats->attr since it's a copy */
- if (attr->attstattarget < 0)
- attr->attstattarget = default_statistics_target;
+ if (stats->attstattarget < 0)
+ stats->attstattarget = default_statistics_target;
/* Look for default "<" and "=" operators for column's type */
get_sort_group_operators(stats->attrtypid,
* know it at this point.
*--------------------
*/
- stats->minrows = 300 * attr->attstattarget;
+ stats->minrows = 300 * stats->attstattarget;
}
else if (OidIsValid(eqopr))
{
/* We can still recognize distinct values */
stats->compute_stats = compute_distinct_stats;
/* Might as well use the same minrows as above */
- stats->minrows = 300 * attr->attstattarget;
+ stats->minrows = 300 * stats->attstattarget;
}
else
{
/* Can't do much but the trivial stuff */
stats->compute_stats = compute_trivial_stats;
/* Might as well use the same minrows as above */
- stats->minrows = 300 * attr->attstattarget;
+ stats->minrows = 300 * stats->attstattarget;
}
return true;
TrackItem *track;
int track_cnt,
track_max;
- int num_mcv = stats->attr->attstattarget;
+ int num_mcv = stats->attstattarget;
StdAnalyzeData *mystats = (StdAnalyzeData *) stats->extra_data;
/*
int *tupnoLink;
ScalarMCVItem *track;
int track_cnt = 0;
- int num_mcv = stats->attr->attstattarget;
- int num_bins = stats->attr->attstattarget;
+ int num_mcv = stats->attstattarget;
+ int num_bins = stats->attstattarget;
StdAnalyzeData *mystats = (StdAnalyzeData *) stats->extra_data;
values = (ScalarItem *) palloc(samplerows * sizeof(ScalarItem));
for (i = 0; i < nattrs; i++)
{
/* keep the maximum statistics target */
- if (stats[i]->attr->attstattarget > stattarget)
- stattarget = stats[i]->attr->attstattarget;
+ if (stats[i]->attstattarget > stattarget)
+ stattarget = stats[i]->attstattarget;
}
/*
bool ok;
/*
- * Create the VacAttrStats struct. Note that we only have a copy of the
- * fixed fields of the pg_attribute tuple.
+ * Create the VacAttrStats struct.
*/
stats = (VacAttrStats *) palloc0(sizeof(VacAttrStats));
-
- /* fake the attribute */
- stats->attr = (Form_pg_attribute) palloc0(ATTRIBUTE_FIXED_PART_SIZE);
- stats->attr->attstattarget = -1;
+ stats->attstattarget = -1;
/*
* When analyzing an expression, believe the expression tree's type not
if (!ok || stats->compute_stats == NULL || stats->minrows <= 0)
{
heap_freetuple(typtuple);
- pfree(stats->attr);
pfree(stats);
return NULL;
}
*/
stats = (VacAttrStats *) palloc0(sizeof(VacAttrStats));
+ /*
+ * We can't have statistics target specified for the expression, so we
+ * could use either the default_statistics_target, or the target computed
+ * for the extended statistics. The second option seems more reasonable.
+ */
+ stats->attstattarget = stattarget;
+
/*
* When analyzing an expression, believe the expression tree's type.
*/
*/
stats->attrcollid = exprCollation(expr);
- /*
- * We don't have any pg_attribute for expressions, so let's fake something
- * reasonable into attstattarget, which is the only thing std_typanalyze
- * needs.
- */
- stats->attr = (Form_pg_attribute) palloc(ATTRIBUTE_FIXED_PART_SIZE);
-
- /*
- * We can't have statistics target specified for the expression, so we
- * could use either the default_statistics_target, or the target computed
- * for the extended statistics. The second option seems more reasonable.
- */
- stats->attr->attstattarget = stattarget;
-
- /* initialize some basic fields */
- stats->attr->attrelid = InvalidOid;
- stats->attr->attnum = InvalidAttrNumber;
- stats->attr->atttypid = stats->attrtypid;
-
typtuple = SearchSysCacheCopy1(TYPEOID,
ObjectIdGetDatum(stats->attrtypid));
if (!HeapTupleIsValid(typtuple))
return NULL;
}
- /*
- * Sanity check that the column is not dropped - stats should have
- * been removed in this case.
- */
- Assert(!stats[i]->attr->attisdropped);
-
i++;
}
if (tcnt > 0)
{
AttributeOpts *aopt =
- get_attribute_options(stats->attr->attrelid,
- stats->attr->attnum);
+ get_attribute_options(onerel->rd_id, stats->tupattnum);
stats->exprvals = exprvals;
stats->exprnulls = exprnulls;
ts_typanalyze(PG_FUNCTION_ARGS)
{
VacAttrStats *stats = (VacAttrStats *) PG_GETARG_POINTER(0);
- Form_pg_attribute attr = stats->attr;
/* If the attstattarget column is negative, use the default value */
- /* NB: it is okay to scribble on stats->attr since it's a copy */
- if (attr->attstattarget < 0)
- attr->attstattarget = default_statistics_target;
+ if (stats->attstattarget < 0)
+ stats->attstattarget = default_statistics_target;
stats->compute_stats = compute_tsvector_stats;
/* see comment about the choice of minrows in commands/analyze.c */
- stats->minrows = 300 * attr->attstattarget;
+ stats->minrows = 300 * stats->attstattarget;
PG_RETURN_BOOL(true);
}
* the number of individual lexeme values tracked in pg_statistic ought to
* be more than the number of values for a simple scalar column.
*/
- num_mcelem = stats->attr->attstattarget * 10;
+ num_mcelem = stats->attstattarget * 10;
/*
* We set bucket width equal to (num_mcelem + 10) / 0.007 as per the
* the number of individual elements tracked in pg_statistic ought to be
* more than the number of values for a simple scalar column.
*/
- num_mcelem = stats->attr->attstattarget * 10;
+ num_mcelem = stats->attstattarget * 10;
/*
* We set bucket width equal to num_mcelem / 0.007 as per the comment
count_items_count = hash_get_num_entries(count_tab);
if (count_items_count > 0)
{
- int num_hist = stats->attr->attstattarget;
+ int num_hist = stats->attstattarget;
DECountItem **sorted_count_items;
int j;
int delta;
{
VacAttrStats *stats = (VacAttrStats *) PG_GETARG_POINTER(0);
TypeCacheEntry *typcache;
- Form_pg_attribute attr = stats->attr;
/* Get information about range type; note column might be a domain */
typcache = range_get_typcache(fcinfo, getBaseType(stats->attrtypid));
- if (attr->attstattarget < 0)
- attr->attstattarget = default_statistics_target;
+ if (stats->attstattarget < 0)
+ stats->attstattarget = default_statistics_target;
stats->compute_stats = compute_range_stats;
stats->extra_data = typcache;
/* same as in std_typanalyze */
- stats->minrows = 300 * attr->attstattarget;
+ stats->minrows = 300 * stats->attstattarget;
PG_RETURN_BOOL(true);
}
{
VacAttrStats *stats = (VacAttrStats *) PG_GETARG_POINTER(0);
TypeCacheEntry *typcache;
- Form_pg_attribute attr = stats->attr;
/* Get information about multirange type; note column might be a domain */
typcache = multirange_get_typcache(fcinfo, getBaseType(stats->attrtypid));
- if (attr->attstattarget < 0)
- attr->attstattarget = default_statistics_target;
+ if (stats->attstattarget < 0)
+ stats->attstattarget = default_statistics_target;
stats->compute_stats = compute_range_stats;
stats->extra_data = typcache;
/* same as in std_typanalyze */
- stats->minrows = 300 * attr->attstattarget;
+ stats->minrows = 300 * stats->attstattarget;
PG_RETURN_BOOL(true);
}
int empty_cnt = 0;
int range_no;
int slot_idx;
- int num_bins = stats->attr->attstattarget;
+ int num_bins = stats->attstattarget;
int num_hist;
float8 *lengths;
RangeBound *lowers,
{
/*
* These fields are set up by the main ANALYZE code before invoking the
- * type-specific typanalyze function.
- *
- * Note: do not assume that the data being analyzed has the same datatype
- * shown in attr, ie do not trust attr->atttypid, attlen, etc. This is
- * because some index opclasses store a different type than the underlying
- * column/expression. Instead use attrtypid, attrtypmod, and attrtype for
+ * type-specific typanalyze function. They don't necessarily match what
+ * is in pg_attribute, because some index opclasses store a different type
+ * than the underlying column/expression. Therefore, use these fields for
* information about the datatype being fed to the typanalyze function.
- * Likewise, use attrcollid not attr->attcollation.
*/
- Form_pg_attribute attr; /* copy of pg_attribute row for column */
+ int attstattarget;
Oid attrtypid; /* type of data being analyzed */
int32 attrtypmod; /* typmod of data being analyzed */
Form_pg_type attrtype; /* copy of pg_type row for attrtypid */