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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy