Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit c69bdf8

Browse files
committed
Take pg_attribute out of VacAttrStats
The VacAttrStats structure contained the whole Form_pg_attribute for a column, but it actually only needs attstattarget from there. So remove the Form_pg_attribute field and make a separate field for attstattarget. This simplifies some code for extended statistics that doesn't deal with a column but an expression, which had to fake up pg_attribute rows to satisfy internal APIs. Also, we can remove some comments that essentially said "don't look at pg_attribute directly". Reviewed-by: Tomas Vondra <tomas.vondra@enterprisedb.com> Discussion: https://www.postgresql.org/message-id/flat/d6069765-5971-04d3-c10d-e4f7b2e9c459%40eisentraut.org
1 parent 7a7f60a commit c69bdf8

File tree

6 files changed

+43
-80
lines changed

6 files changed

+43
-80
lines changed

src/backend/commands/analyze.c

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
572572
* If the appropriate flavor of the n_distinct option is
573573
* specified, override with the corresponding value.
574574
*/
575-
aopt = get_attribute_options(onerel->rd_id, stats->attr->attnum);
575+
aopt = get_attribute_options(onerel->rd_id, stats->tupattnum);
576576
if (aopt != NULL)
577577
{
578578
float8 n_distinct;
@@ -927,7 +927,7 @@ compute_index_stats(Relation onerel, double totalrows,
927927
for (i = 0; i < attr_cnt; i++)
928928
{
929929
VacAttrStats *stats = thisdata->vacattrstats[i];
930-
int attnum = stats->attr->attnum;
930+
int attnum = stats->tupattnum;
931931

932932
if (isnull[attnum - 1])
933933
{
@@ -1014,12 +1014,10 @@ examine_attribute(Relation onerel, int attnum, Node *index_expr)
10141014
return NULL;
10151015

10161016
/*
1017-
* Create the VacAttrStats struct. Note that we only have a copy of the
1018-
* fixed fields of the pg_attribute tuple.
1017+
* Create the VacAttrStats struct.
10191018
*/
10201019
stats = (VacAttrStats *) palloc0(sizeof(VacAttrStats));
1021-
stats->attr = (Form_pg_attribute) palloc(ATTRIBUTE_FIXED_PART_SIZE);
1022-
memcpy(stats->attr, attr, ATTRIBUTE_FIXED_PART_SIZE);
1020+
stats->attstattarget = attr->attstattarget;
10231021

10241022
/*
10251023
* When analyzing an expression index, believe the expression tree's type
@@ -1086,7 +1084,6 @@ examine_attribute(Relation onerel, int attnum, Node *index_expr)
10861084
if (!ok || stats->compute_stats == NULL || stats->minrows <= 0)
10871085
{
10881086
heap_freetuple(typtuple);
1089-
pfree(stats->attr);
10901087
pfree(stats);
10911088
return NULL;
10921089
}
@@ -1659,7 +1656,7 @@ update_attstats(Oid relid, bool inh, int natts, VacAttrStats **vacattrstats)
16591656
}
16601657

16611658
values[Anum_pg_statistic_starelid - 1] = ObjectIdGetDatum(relid);
1662-
values[Anum_pg_statistic_staattnum - 1] = Int16GetDatum(stats->attr->attnum);
1659+
values[Anum_pg_statistic_staattnum - 1] = Int16GetDatum(stats->tupattnum);
16631660
values[Anum_pg_statistic_stainherit - 1] = BoolGetDatum(inh);
16641661
values[Anum_pg_statistic_stanullfrac - 1] = Float4GetDatum(stats->stanullfrac);
16651662
values[Anum_pg_statistic_stawidth - 1] = Int32GetDatum(stats->stawidth);
@@ -1725,7 +1722,7 @@ update_attstats(Oid relid, bool inh, int natts, VacAttrStats **vacattrstats)
17251722
/* Is there already a pg_statistic tuple for this attribute? */
17261723
oldtup = SearchSysCache3(STATRELATTINH,
17271724
ObjectIdGetDatum(relid),
1728-
Int16GetDatum(stats->attr->attnum),
1725+
Int16GetDatum(stats->tupattnum),
17291726
BoolGetDatum(inh));
17301727

17311728
/* Open index information when we know we need it */
@@ -1860,15 +1857,13 @@ static int analyze_mcv_list(int *mcv_counts,
18601857
bool
18611858
std_typanalyze(VacAttrStats *stats)
18621859
{
1863-
Form_pg_attribute attr = stats->attr;
18641860
Oid ltopr;
18651861
Oid eqopr;
18661862
StdAnalyzeData *mystats;
18671863

18681864
/* If the attstattarget column is negative, use the default value */
1869-
/* NB: it is okay to scribble on stats->attr since it's a copy */
1870-
if (attr->attstattarget < 0)
1871-
attr->attstattarget = default_statistics_target;
1865+
if (stats->attstattarget < 0)
1866+
stats->attstattarget = default_statistics_target;
18721867

18731868
/* Look for default "<" and "=" operators for column's type */
18741869
get_sort_group_operators(stats->attrtypid,
@@ -1909,21 +1904,21 @@ std_typanalyze(VacAttrStats *stats)
19091904
* know it at this point.
19101905
*--------------------
19111906
*/
1912-
stats->minrows = 300 * attr->attstattarget;
1907+
stats->minrows = 300 * stats->attstattarget;
19131908
}
19141909
else if (OidIsValid(eqopr))
19151910
{
19161911
/* We can still recognize distinct values */
19171912
stats->compute_stats = compute_distinct_stats;
19181913
/* Might as well use the same minrows as above */
1919-
stats->minrows = 300 * attr->attstattarget;
1914+
stats->minrows = 300 * stats->attstattarget;
19201915
}
19211916
else
19221917
{
19231918
/* Can't do much but the trivial stuff */
19241919
stats->compute_stats = compute_trivial_stats;
19251920
/* Might as well use the same minrows as above */
1926-
stats->minrows = 300 * attr->attstattarget;
1921+
stats->minrows = 300 * stats->attstattarget;
19271922
}
19281923

19291924
return true;
@@ -2051,7 +2046,7 @@ compute_distinct_stats(VacAttrStatsP stats,
20512046
TrackItem *track;
20522047
int track_cnt,
20532048
track_max;
2054-
int num_mcv = stats->attr->attstattarget;
2049+
int num_mcv = stats->attstattarget;
20552050
StdAnalyzeData *mystats = (StdAnalyzeData *) stats->extra_data;
20562051

20572052
/*
@@ -2392,8 +2387,8 @@ compute_scalar_stats(VacAttrStatsP stats,
23922387
int *tupnoLink;
23932388
ScalarMCVItem *track;
23942389
int track_cnt = 0;
2395-
int num_mcv = stats->attr->attstattarget;
2396-
int num_bins = stats->attr->attstattarget;
2390+
int num_mcv = stats->attstattarget;
2391+
int num_bins = stats->attstattarget;
23972392
StdAnalyzeData *mystats = (StdAnalyzeData *) stats->extra_data;
23982393

23992394
values = (ScalarItem *) palloc(samplerows * sizeof(ScalarItem));

src/backend/statistics/extended_stats.c

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,8 @@ statext_compute_stattarget(int stattarget, int nattrs, VacAttrStats **stats)
366366
for (i = 0; i < nattrs; i++)
367367
{
368368
/* keep the maximum statistics target */
369-
if (stats[i]->attr->attstattarget > stattarget)
370-
stattarget = stats[i]->attr->attstattarget;
369+
if (stats[i]->attstattarget > stattarget)
370+
stattarget = stats[i]->attstattarget;
371371
}
372372

373373
/*
@@ -534,14 +534,10 @@ examine_attribute(Node *expr)
534534
bool ok;
535535

536536
/*
537-
* Create the VacAttrStats struct. Note that we only have a copy of the
538-
* fixed fields of the pg_attribute tuple.
537+
* Create the VacAttrStats struct.
539538
*/
540539
stats = (VacAttrStats *) palloc0(sizeof(VacAttrStats));
541-
542-
/* fake the attribute */
543-
stats->attr = (Form_pg_attribute) palloc0(ATTRIBUTE_FIXED_PART_SIZE);
544-
stats->attr->attstattarget = -1;
540+
stats->attstattarget = -1;
545541

546542
/*
547543
* When analyzing an expression, believe the expression tree's type not
@@ -595,7 +591,6 @@ examine_attribute(Node *expr)
595591
if (!ok || stats->compute_stats == NULL || stats->minrows <= 0)
596592
{
597593
heap_freetuple(typtuple);
598-
pfree(stats->attr);
599594
pfree(stats);
600595
return NULL;
601596
}
@@ -624,6 +619,13 @@ examine_expression(Node *expr, int stattarget)
624619
*/
625620
stats = (VacAttrStats *) palloc0(sizeof(VacAttrStats));
626621

622+
/*
623+
* We can't have statistics target specified for the expression, so we
624+
* could use either the default_statistics_target, or the target computed
625+
* for the extended statistics. The second option seems more reasonable.
626+
*/
627+
stats->attstattarget = stattarget;
628+
627629
/*
628630
* When analyzing an expression, believe the expression tree's type.
629631
*/
@@ -638,25 +640,6 @@ examine_expression(Node *expr, int stattarget)
638640
*/
639641
stats->attrcollid = exprCollation(expr);
640642

641-
/*
642-
* We don't have any pg_attribute for expressions, so let's fake something
643-
* reasonable into attstattarget, which is the only thing std_typanalyze
644-
* needs.
645-
*/
646-
stats->attr = (Form_pg_attribute) palloc(ATTRIBUTE_FIXED_PART_SIZE);
647-
648-
/*
649-
* We can't have statistics target specified for the expression, so we
650-
* could use either the default_statistics_target, or the target computed
651-
* for the extended statistics. The second option seems more reasonable.
652-
*/
653-
stats->attr->attstattarget = stattarget;
654-
655-
/* initialize some basic fields */
656-
stats->attr->attrelid = InvalidOid;
657-
stats->attr->attnum = InvalidAttrNumber;
658-
stats->attr->atttypid = stats->attrtypid;
659-
660643
typtuple = SearchSysCacheCopy1(TYPEOID,
661644
ObjectIdGetDatum(stats->attrtypid));
662645
if (!HeapTupleIsValid(typtuple))
@@ -747,12 +730,6 @@ lookup_var_attr_stats(Relation rel, Bitmapset *attrs, List *exprs,
747730
return NULL;
748731
}
749732

750-
/*
751-
* Sanity check that the column is not dropped - stats should have
752-
* been removed in this case.
753-
*/
754-
Assert(!stats[i]->attr->attisdropped);
755-
756733
i++;
757734
}
758735

@@ -2237,8 +2214,7 @@ compute_expr_stats(Relation onerel, double totalrows,
22372214
if (tcnt > 0)
22382215
{
22392216
AttributeOpts *aopt =
2240-
get_attribute_options(stats->attr->attrelid,
2241-
stats->attr->attnum);
2217+
get_attribute_options(onerel->rd_id, stats->tupattnum);
22422218

22432219
stats->exprvals = exprvals;
22442220
stats->exprnulls = exprnulls;

src/backend/tsearch/ts_typanalyze.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,14 @@ Datum
5858
ts_typanalyze(PG_FUNCTION_ARGS)
5959
{
6060
VacAttrStats *stats = (VacAttrStats *) PG_GETARG_POINTER(0);
61-
Form_pg_attribute attr = stats->attr;
6261

6362
/* If the attstattarget column is negative, use the default value */
64-
/* NB: it is okay to scribble on stats->attr since it's a copy */
65-
if (attr->attstattarget < 0)
66-
attr->attstattarget = default_statistics_target;
63+
if (stats->attstattarget < 0)
64+
stats->attstattarget = default_statistics_target;
6765

6866
stats->compute_stats = compute_tsvector_stats;
6967
/* see comment about the choice of minrows in commands/analyze.c */
70-
stats->minrows = 300 * attr->attstattarget;
68+
stats->minrows = 300 * stats->attstattarget;
7169

7270
PG_RETURN_BOOL(true);
7371
}
@@ -169,7 +167,7 @@ compute_tsvector_stats(VacAttrStats *stats,
169167
* the number of individual lexeme values tracked in pg_statistic ought to
170168
* be more than the number of values for a simple scalar column.
171169
*/
172-
num_mcelem = stats->attr->attstattarget * 10;
170+
num_mcelem = stats->attstattarget * 10;
173171

174172
/*
175173
* We set bucket width equal to (num_mcelem + 10) / 0.007 as per the

src/backend/utils/adt/array_typanalyze.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ compute_array_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc,
263263
* the number of individual elements tracked in pg_statistic ought to be
264264
* more than the number of values for a simple scalar column.
265265
*/
266-
num_mcelem = stats->attr->attstattarget * 10;
266+
num_mcelem = stats->attstattarget * 10;
267267

268268
/*
269269
* We set bucket width equal to num_mcelem / 0.007 as per the comment
@@ -575,7 +575,7 @@ compute_array_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc,
575575
count_items_count = hash_get_num_entries(count_tab);
576576
if (count_items_count > 0)
577577
{
578-
int num_hist = stats->attr->attstattarget;
578+
int num_hist = stats->attstattarget;
579579
DECountItem **sorted_count_items;
580580
int j;
581581
int delta;

src/backend/utils/adt/rangetypes_typanalyze.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,17 @@ range_typanalyze(PG_FUNCTION_ARGS)
4747
{
4848
VacAttrStats *stats = (VacAttrStats *) PG_GETARG_POINTER(0);
4949
TypeCacheEntry *typcache;
50-
Form_pg_attribute attr = stats->attr;
5150

5251
/* Get information about range type; note column might be a domain */
5352
typcache = range_get_typcache(fcinfo, getBaseType(stats->attrtypid));
5453

55-
if (attr->attstattarget < 0)
56-
attr->attstattarget = default_statistics_target;
54+
if (stats->attstattarget < 0)
55+
stats->attstattarget = default_statistics_target;
5756

5857
stats->compute_stats = compute_range_stats;
5958
stats->extra_data = typcache;
6059
/* same as in std_typanalyze */
61-
stats->minrows = 300 * attr->attstattarget;
60+
stats->minrows = 300 * stats->attstattarget;
6261

6362
PG_RETURN_BOOL(true);
6463
}
@@ -74,18 +73,17 @@ multirange_typanalyze(PG_FUNCTION_ARGS)
7473
{
7574
VacAttrStats *stats = (VacAttrStats *) PG_GETARG_POINTER(0);
7675
TypeCacheEntry *typcache;
77-
Form_pg_attribute attr = stats->attr;
7876

7977
/* Get information about multirange type; note column might be a domain */
8078
typcache = multirange_get_typcache(fcinfo, getBaseType(stats->attrtypid));
8179

82-
if (attr->attstattarget < 0)
83-
attr->attstattarget = default_statistics_target;
80+
if (stats->attstattarget < 0)
81+
stats->attstattarget = default_statistics_target;
8482

8583
stats->compute_stats = compute_range_stats;
8684
stats->extra_data = typcache;
8785
/* same as in std_typanalyze */
88-
stats->minrows = 300 * attr->attstattarget;
86+
stats->minrows = 300 * stats->attstattarget;
8987

9088
PG_RETURN_BOOL(true);
9189
}
@@ -136,7 +134,7 @@ compute_range_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc,
136134
int empty_cnt = 0;
137135
int range_no;
138136
int slot_idx;
139-
int num_bins = stats->attr->attstattarget;
137+
int num_bins = stats->attstattarget;
140138
int num_hist;
141139
float8 *lengths;
142140
RangeBound *lowers,

src/include/commands/vacuum.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,16 +116,12 @@ typedef struct VacAttrStats
116116
{
117117
/*
118118
* These fields are set up by the main ANALYZE code before invoking the
119-
* type-specific typanalyze function.
120-
*
121-
* Note: do not assume that the data being analyzed has the same datatype
122-
* shown in attr, ie do not trust attr->atttypid, attlen, etc. This is
123-
* because some index opclasses store a different type than the underlying
124-
* column/expression. Instead use attrtypid, attrtypmod, and attrtype for
119+
* type-specific typanalyze function. They don't necessarily match what
120+
* is in pg_attribute, because some index opclasses store a different type
121+
* than the underlying column/expression. Therefore, use these fields for
125122
* information about the datatype being fed to the typanalyze function.
126-
* Likewise, use attrcollid not attr->attcollation.
127123
*/
128-
Form_pg_attribute attr; /* copy of pg_attribute row for column */
124+
int attstattarget;
129125
Oid attrtypid; /* type of data being analyzed */
130126
int32 attrtypmod; /* typmod of data being analyzed */
131127
Form_pg_type attrtype; /* copy of pg_type row for attrtypid */

0 commit comments

Comments
 (0)