Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbf2a691

Browse files
committed
Fix extended statistics with partial analyzes
Either because of a previous ALTER TABLE .. SET STATISTICS 0 or becauseof being invoked with a partial column list, ANALYZE could fail toacquire sufficient data to build extended statistics. Previously, thiswould draw an ERROR and fail to collect any statistics at all (extendedand regular). Change things so that we raise a WARNING instead, andremove a hint that was wrong in half the cases.Reported by: David RowleyDiscussion:https://postgr.es/m/CAKJS1f9Kk0NF6Fg7TA=JUXsjpS9kX6NVu27pb5QDCpOYAvb-Og@mail.gmail.com
1 parent419a23b commitbf2a691

File tree

3 files changed

+60
-31
lines changed

3 files changed

+60
-31
lines changed

‎src/backend/statistics/extended_stats.c

Lines changed: 54 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@
2323
#include"catalog/pg_collation.h"
2424
#include"catalog/pg_statistic_ext.h"
2525
#include"nodes/relation.h"
26+
#include"postmaster/autovacuum.h"
2627
#include"statistics/extended_stats_internal.h"
2728
#include"statistics/statistics.h"
2829
#include"utils/builtins.h"
2930
#include"utils/fmgroids.h"
3031
#include"utils/lsyscache.h"
32+
#include"utils/memutils.h"
3133
#include"utils/rel.h"
3234
#include"utils/syscache.h"
3335

@@ -38,14 +40,16 @@
3840
typedefstructStatExtEntry
3941
{
4042
OidstatOid;/* OID of pg_statistic_ext entry */
43+
char*schema;/* statistics schema */
44+
char*name;/* statistics name */
4145
Bitmapset*columns;/* attribute numbers covered by the statistics */
4246
List*types;/* 'char' list of enabled statistic kinds */
4347
}StatExtEntry;
4448

4549

4650
staticList*fetch_statentries_for_relation(Relationpg_statext,Oidrelid);
4751
staticVacAttrStats**lookup_var_attr_stats(Relationrel,Bitmapset*attrs,
48-
intnatts,VacAttrStats**vacattrstats);
52+
intnvacatts,VacAttrStats**vacatts);
4953
staticvoidstatext_store(Relationpg_stext,Oidrelid,
5054
MVNDistinct*ndistinct,MVDependencies*dependencies,
5155
VacAttrStats**stats);
@@ -66,6 +70,12 @@ BuildRelationExtStatistics(Relation onerel, double totalrows,
6670
Relationpg_stext;
6771
ListCell*lc;
6872
List*stats;
73+
MemoryContextcxt;
74+
MemoryContextoldcxt;
75+
76+
cxt=AllocSetContextCreate(CurrentMemoryContext,"stats ext",
77+
ALLOCSET_DEFAULT_SIZES);
78+
oldcxt=MemoryContextSwitchTo(cxt);
6979

7080
pg_stext=heap_open(StatisticExtRelationId,RowExclusiveLock);
7181
stats=fetch_statentries_for_relation(pg_stext,RelationGetRelid(onerel));
@@ -78,9 +88,23 @@ BuildRelationExtStatistics(Relation onerel, double totalrows,
7888
VacAttrStats**stats;
7989
ListCell*lc2;
8090

81-
/* filter only the interesting vacattrstats records */
91+
/*
92+
* Check if we can build these stats based on the column analyzed.
93+
* If not, report this fact (except in autovacuum) and move on.
94+
*/
8295
stats=lookup_var_attr_stats(onerel,stat->columns,
8396
natts,vacattrstats);
97+
if (!stats&& !IsAutoVacuumWorkerProcess())
98+
{
99+
ereport(WARNING,
100+
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
101+
errmsg("extended statistics \"%s.%s\" could not be collected for relation %s.%s",
102+
stat->schema,stat->name,
103+
get_namespace_name(onerel->rd_rel->relnamespace),
104+
RelationGetRelationName(onerel)),
105+
errtable(onerel)));
106+
continue;
107+
}
84108

85109
/* check allowed number of dimensions */
86110
Assert(bms_num_members(stat->columns) >=2&&
@@ -104,6 +128,9 @@ BuildRelationExtStatistics(Relation onerel, double totalrows,
104128
}
105129

106130
heap_close(pg_stext,RowExclusiveLock);
131+
132+
MemoryContextSwitchTo(oldcxt);
133+
MemoryContextDelete(cxt);
107134
}
108135

109136
/*
@@ -168,6 +195,8 @@ fetch_statentries_for_relation(Relation pg_statext, Oid relid)
168195
entry=palloc0(sizeof(StatExtEntry));
169196
entry->statOid=HeapTupleGetOid(htup);
170197
staForm= (Form_pg_statistic_ext)GETSTRUCT(htup);
198+
entry->schema=get_namespace_name(staForm->stanamespace);
199+
entry->name=pstrdup(NameStr(staForm->staname));
171200
for (i=0;i<staForm->stakeys.dim1;i++)
172201
{
173202
entry->columns=bms_add_member(entry->columns,
@@ -200,18 +229,19 @@ fetch_statentries_for_relation(Relation pg_statext, Oid relid)
200229
}
201230

202231
/*
203-
* Using 'vacattrstats' of size 'natts' as input data, return a newly built
204-
* VacAttrStats array which includes only the items corresponding to attributes
205-
* indicated by 'attrs'.
232+
* Using 'vacatts' of size 'nvacatts' as input data, return a newly built
233+
* VacAttrStats array which includes only the items corresponding to
234+
* attributes indicated by 'stakeys'. If we don't have all of the per column
235+
* stats available to compute the extended stats, then we return NULL to indicate
236+
* to the caller that the stats should not be built.
206237
*/
207238
staticVacAttrStats**
208-
lookup_var_attr_stats(Relationrel,Bitmapset*attrs,intnatts,
209-
VacAttrStats**vacattrstats)
239+
lookup_var_attr_stats(Relationrel,Bitmapset*attrs,
240+
intnvacatts,VacAttrStats**vacatts)
210241
{
211242
inti=0;
212243
intx=-1;
213244
VacAttrStats**stats;
214-
Bitmapset*matched=NULL;
215245

216246
stats= (VacAttrStats**)
217247
palloc(bms_num_members(attrs)*sizeof(VacAttrStats*));
@@ -222,39 +252,34 @@ lookup_var_attr_stats(Relation rel, Bitmapset *attrs, int natts,
222252
intj;
223253

224254
stats[i]=NULL;
225-
for (j=0;j<natts;j++)
255+
for (j=0;j<nvacatts;j++)
226256
{
227-
if (x==vacattrstats[j]->tupattnum)
257+
if (x==vacatts[j]->tupattnum)
228258
{
229-
stats[i]=vacattrstats[j];
259+
stats[i]=vacatts[j];
230260
break;
231261
}
232262
}
233263

234264
if (!stats[i])
235-
ereport(ERROR,
236-
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
237-
errmsg("extended statistics could not be collected for column \"%s\" of relation %s.%s",
238-
NameStr(RelationGetDescr(rel)->attrs[x-1]->attname),
239-
get_namespace_name(rel->rd_rel->relnamespace),
240-
RelationGetRelationName(rel)),
241-
errhint("Consider ALTER TABLE \"%s\".\"%s\" ALTER \"%s\" SET STATISTICS -1",
242-
get_namespace_name(rel->rd_rel->relnamespace),
243-
RelationGetRelationName(rel),
244-
NameStr(RelationGetDescr(rel)->attrs[x-1]->attname))));
265+
{
266+
/*
267+
* Looks like stats were not gathered for one of the columns
268+
* required. We'll be unable to build the extended stats without
269+
* this column.
270+
*/
271+
pfree(stats);
272+
returnNULL;
273+
}
245274

246-
/*
247-
* Checkthatwe found a non-droppedcolumn and that the attnum
248-
* matches.
249-
*/
275+
/*
276+
* Sanity checkthatthe column is notdropped- stats should have
277+
* been removed in this case.
278+
*/
250279
Assert(!stats[i]->attr->attisdropped);
251-
matched=bms_add_member(matched,stats[i]->tupattnum);
252280

253281
i++;
254282
}
255-
if (bms_subset_compare(matched,attrs)!=BMS_EQUAL)
256-
elog(ERROR,"could not find all attributes in attribute stats array");
257-
bms_free(matched);
258283

259284
returnstats;
260285
}

‎src/test/regress/expected/stats_ext.out

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@ ALTER TABLE ab1 ALTER a SET STATISTICS 0;
4040
INSERT INTO ab1 SELECT a, a%23 FROM generate_series(1, 1000) a;
4141
CREATE STATISTICS ab1_a_b_stats ON (a, b) FROM ab1;
4242
ANALYZE ab1;
43-
ERROR: extended statistics could not be collected for column "a" of relation public.ab1
44-
HINT: Consider ALTER TABLE "public"."ab1" ALTER "a" SET STATISTICS -1
43+
WARNING: extended statistics "public.ab1_a_b_stats" could not be collected for relation public.ab1
4544
ALTER TABLE ab1 ALTER a SET STATISTICS -1;
45+
-- partial analyze doesn't build stats either
46+
ANALYZE ab1 (a);
47+
WARNING: extended statistics "public.ab1_a_b_stats" could not be collected for relation public.ab1
4648
ANALYZE ab1;
4749
DROP TABLE ab1;
4850
-- n-distinct tests

‎src/test/regress/sql/stats_ext.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ INSERT INTO ab1 SELECT a, a%23 FROM generate_series(1, 1000) a;
3535
CREATE STATISTICS ab1_a_b_statsON (a, b)FROM ab1;
3636
ANALYZE ab1;
3737
ALTERTABLE ab1 ALTER aSET STATISTICS-1;
38+
-- partial analyze doesn't build stats either
39+
ANALYZE ab1 (a);
3840
ANALYZE ab1;
3941
DROPTABLE ab1;
4042

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp