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

Commit8787bc8

Browse files
committed
After further thought about support for gathering stats on functional
indexes, it seems like we ought to put another layer of indirectionbetween the compute_stats functions and the actual data storage. Thiswould allow us to compute the values on-the-fly, for example.
1 parent1a46523 commit8787bc8

File tree

2 files changed

+81
-52
lines changed

2 files changed

+81
-52
lines changed

‎src/backend/commands/analyze.c

Lines changed: 61 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.68 2004/02/12 23:41:02 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.69 2004/02/13 06:39:49 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -52,6 +52,7 @@ static double init_selection_state(int n);
5252
staticdoubleselect_next_random_record(doublet,intn,double*stateptr);
5353
staticintcompare_rows(constvoid*a,constvoid*b);
5454
staticvoidupdate_attstats(Oidrelid,intnatts,VacAttrStats**vacattrstats);
55+
staticDatumstd_fetch_func(VacAttrStatsPstats,intrownum,bool*isNull);
5556

5657
staticboolstd_typanalyze(VacAttrStats*stats);
5758

@@ -259,12 +260,14 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
259260
old_context=MemoryContextSwitchTo(col_context);
260261
for (i=0;i<attr_cnt;i++)
261262
{
262-
(*vacattrstats[i]->compute_stats) (vacattrstats[i],
263-
vacattrstats[i]->tupattnum,
264-
onerel->rd_att,
265-
totalrows,
266-
rows,
267-
numrows);
263+
VacAttrStats*stats=vacattrstats[i];
264+
265+
stats->rows=rows;
266+
stats->tupDesc=onerel->rd_att;
267+
(*stats->compute_stats) (stats,
268+
std_fetch_func,
269+
numrows,
270+
totalrows);
268271
MemoryContextResetAndDeleteChildren(col_context);
269272
}
270273
MemoryContextSwitchTo(old_context);
@@ -861,6 +864,22 @@ update_attstats(Oid relid, int natts, VacAttrStats **vacattrstats)
861864
heap_close(sd,RowExclusiveLock);
862865
}
863866

867+
/*
868+
* Standard fetch function for use by compute_stats subroutines.
869+
*
870+
* This exists to provide some insulation between compute_stats routines
871+
* and the actual storage of the sample data.
872+
*/
873+
staticDatum
874+
std_fetch_func(VacAttrStatsPstats,intrownum,bool*isNull)
875+
{
876+
intattnum=stats->tupattnum;
877+
HeapTupletuple=stats->rows[rownum];
878+
TupleDesctupDesc=stats->tupDesc;
879+
880+
returnheap_getattr(tuple,attnum,tupDesc,isNull);
881+
}
882+
864883

865884
/*==========================================================================
866885
*
@@ -915,12 +934,14 @@ static SortFunctionKind datumCmpFnKind;
915934
staticint*datumCmpTupnoLink;
916935

917936

918-
staticvoidcompute_minimal_stats(VacAttrStats*stats,intattnum,
919-
TupleDesctupDesc,doubletotalrows,
920-
HeapTuple*rows,intnumrows);
921-
staticvoidcompute_scalar_stats(VacAttrStats*stats,intattnum,
922-
TupleDesctupDesc,doubletotalrows,
923-
HeapTuple*rows,intnumrows);
937+
staticvoidcompute_minimal_stats(VacAttrStatsPstats,
938+
AnalyzeAttrFetchFuncfetchfunc,
939+
intsamplerows,
940+
doubletotalrows);
941+
staticvoidcompute_scalar_stats(VacAttrStatsPstats,
942+
AnalyzeAttrFetchFuncfetchfunc,
943+
intsamplerows,
944+
doubletotalrows);
924945
staticintcompare_scalars(constvoid*a,constvoid*b);
925946
staticintcompare_mcvs(constvoid*a,constvoid*b);
926947

@@ -1024,9 +1045,10 @@ std_typanalyze(VacAttrStats *stats)
10241045
*depend mainly on the length of the list we are willing to keep.
10251046
*/
10261047
staticvoid
1027-
compute_minimal_stats(VacAttrStats*stats,intattnum,
1028-
TupleDesctupDesc,doubletotalrows,
1029-
HeapTuple*rows,intnumrows)
1048+
compute_minimal_stats(VacAttrStatsPstats,
1049+
AnalyzeAttrFetchFuncfetchfunc,
1050+
intsamplerows,
1051+
doubletotalrows)
10301052
{
10311053
inti;
10321054
intnull_cnt=0;
@@ -1061,9 +1083,8 @@ compute_minimal_stats(VacAttrStats *stats, int attnum,
10611083

10621084
fmgr_info(mystats->eqfunc,&f_cmpeq);
10631085

1064-
for (i=0;i<numrows;i++)
1086+
for (i=0;i<samplerows;i++)
10651087
{
1066-
HeapTupletuple=rows[i];
10671088
Datumvalue;
10681089
boolisnull;
10691090
boolmatch;
@@ -1072,7 +1093,7 @@ compute_minimal_stats(VacAttrStats *stats, int attnum,
10721093

10731094
vacuum_delay_point();
10741095

1075-
value=heap_getattr(tuple,attnum,tupDesc,&isnull);
1096+
value=fetchfunc(stats,i,&isnull);
10761097

10771098
/* Check for null/nonnull */
10781099
if (isnull)
@@ -1166,7 +1187,7 @@ compute_minimal_stats(VacAttrStats *stats, int attnum,
11661187

11671188
stats->stats_valid= true;
11681189
/* Do the simple null-frac and width stats */
1169-
stats->stanullfrac= (double)null_cnt / (double)numrows;
1190+
stats->stanullfrac= (double)null_cnt / (double)samplerows;
11701191
if (is_varwidth)
11711192
stats->stawidth=total_width / (double)nonnull_cnt;
11721193
else
@@ -1222,10 +1243,10 @@ compute_minimal_stats(VacAttrStats *stats, int attnum,
12221243
denom,
12231244
stadistinct;
12241245

1225-
numer= (double)numrows*(double)d;
1246+
numer= (double)samplerows*(double)d;
12261247

1227-
denom= (double) (numrows-f1)+
1228-
(double)f1*(double)numrows /totalrows;
1248+
denom= (double) (samplerows-f1)+
1249+
(double)f1*(double)samplerows /totalrows;
12291250

12301251
stadistinct=numer /denom;
12311252
/* Clamp to sane range in case of roundoff error */
@@ -1270,7 +1291,7 @@ compute_minimal_stats(VacAttrStats *stats, int attnum,
12701291
if (ndistinct<0)
12711292
ndistinct=-ndistinct*totalrows;
12721293
/* estimate # of occurrences in sample of a typical value */
1273-
avgcount= (double)numrows /ndistinct;
1294+
avgcount= (double)samplerows /ndistinct;
12741295
/* set minimum threshold count to store a value */
12751296
mincount=avgcount*1.25;
12761297
if (mincount<2)
@@ -1303,7 +1324,7 @@ compute_minimal_stats(VacAttrStats *stats, int attnum,
13031324
mcv_values[i]=datumCopy(track[i].value,
13041325
stats->attr->attbyval,
13051326
stats->attr->attlen);
1306-
mcv_freqs[i]= (double)track[i].count / (double)numrows;
1327+
mcv_freqs[i]= (double)track[i].count / (double)samplerows;
13071328
}
13081329
MemoryContextSwitchTo(old_context);
13091330

@@ -1333,9 +1354,10 @@ compute_minimal_stats(VacAttrStats *stats, int attnum,
13331354
*data values into order.
13341355
*/
13351356
staticvoid
1336-
compute_scalar_stats(VacAttrStats*stats,intattnum,
1337-
TupleDesctupDesc,doubletotalrows,
1338-
HeapTuple*rows,intnumrows)
1357+
compute_scalar_stats(VacAttrStatsPstats,
1358+
AnalyzeAttrFetchFuncfetchfunc,
1359+
intsamplerows,
1360+
doubletotalrows)
13391361
{
13401362
inti;
13411363
intnull_cnt=0;
@@ -1359,23 +1381,22 @@ compute_scalar_stats(VacAttrStats *stats, int attnum,
13591381
intnum_bins=stats->attr->attstattarget;
13601382
StdAnalyzeData*mystats= (StdAnalyzeData*)stats->extra_data;
13611383

1362-
values= (ScalarItem*)palloc(numrows*sizeof(ScalarItem));
1363-
tupnoLink= (int*)palloc(numrows*sizeof(int));
1384+
values= (ScalarItem*)palloc(samplerows*sizeof(ScalarItem));
1385+
tupnoLink= (int*)palloc(samplerows*sizeof(int));
13641386
track= (ScalarMCVItem*)palloc(num_mcv*sizeof(ScalarMCVItem));
13651387

13661388
SelectSortFunction(mystats->ltopr,&cmpFn,&cmpFnKind);
13671389
fmgr_info(cmpFn,&f_cmpfn);
13681390

13691391
/* Initial scan to find sortable values */
1370-
for (i=0;i<numrows;i++)
1392+
for (i=0;i<samplerows;i++)
13711393
{
1372-
HeapTupletuple=rows[i];
13731394
Datumvalue;
13741395
boolisnull;
13751396

13761397
vacuum_delay_point();
13771398

1378-
value=heap_getattr(tuple,attnum,tupDesc,&isnull);
1399+
value=fetchfunc(stats,i,&isnull);
13791400

13801401
/* Check for null/nonnull */
13811402
if (isnull)
@@ -1505,7 +1526,7 @@ compute_scalar_stats(VacAttrStats *stats, int attnum,
15051526

15061527
stats->stats_valid= true;
15071528
/* Do the simple null-frac and width stats */
1508-
stats->stanullfrac= (double)null_cnt / (double)numrows;
1529+
stats->stanullfrac= (double)null_cnt / (double)samplerows;
15091530
if (is_varwidth)
15101531
stats->stawidth=total_width / (double)nonnull_cnt;
15111532
else
@@ -1546,10 +1567,10 @@ compute_scalar_stats(VacAttrStats *stats, int attnum,
15461567
denom,
15471568
stadistinct;
15481569

1549-
numer= (double)numrows*(double)d;
1570+
numer= (double)samplerows*(double)d;
15501571

1551-
denom= (double) (numrows-f1)+
1552-
(double)f1*(double)numrows /totalrows;
1572+
denom= (double) (samplerows-f1)+
1573+
(double)f1*(double)samplerows /totalrows;
15531574

15541575
stadistinct=numer /denom;
15551576
/* Clamp to sane range in case of roundoff error */
@@ -1599,13 +1620,13 @@ compute_scalar_stats(VacAttrStats *stats, int attnum,
15991620
if (ndistinct<0)
16001621
ndistinct=-ndistinct*totalrows;
16011622
/* estimate # of occurrences in sample of a typical value */
1602-
avgcount= (double)numrows /ndistinct;
1623+
avgcount= (double)samplerows /ndistinct;
16031624
/* set minimum threshold count to store a value */
16041625
mincount=avgcount*1.25;
16051626
if (mincount<2)
16061627
mincount=2;
16071628
/* don't let threshold exceed 1/K, however */
1608-
maxmincount= (double)numrows / (double)num_bins;
1629+
maxmincount= (double)samplerows / (double)num_bins;
16091630
if (mincount>maxmincount)
16101631
mincount=maxmincount;
16111632
if (num_mcv>track_cnt)
@@ -1636,7 +1657,7 @@ compute_scalar_stats(VacAttrStats *stats, int attnum,
16361657
mcv_values[i]=datumCopy(values[track[i].first].value,
16371658
stats->attr->attbyval,
16381659
stats->attr->attlen);
1639-
mcv_freqs[i]= (double)track[i].count / (double)numrows;
1660+
mcv_freqs[i]= (double)track[i].count / (double)samplerows;
16401661
}
16411662
MemoryContextSwitchTo(old_context);
16421663

‎src/include/commands/vacuum.h

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.49 2004/02/12 23:41:04 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.50 2004/02/13 06:39:49 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -40,18 +40,18 @@
4040
* and must return TRUE to continue analysis, FALSE to skip analysis of this
4141
* column. In the TRUE case it must set the compute_stats and minrows fields,
4242
* and can optionally set extra_data to pass additional info to compute_stats.
43+
* minrows is its request for the minimum number of sample rows to be gathered
44+
* (but note this request might not be honored, eg if there are fewer rows
45+
* than that in the table).
4346
*
4447
* The compute_stats routine will be called after sample rows have been
4548
* gathered. Aside from this struct, it is passed:
46-
*attnum: attribute number within the supplied tuples
47-
*tupDesc: tuple descriptor for the supplied tuples
49+
*fetchfunc: a function for accessing the column values from the
50+
* sample rows
51+
*samplerows: the number of sample tuples
4852
*totalrows: estimated total number of rows in relation
49-
*rows: an array of the sample tuples
50-
*numrows: the number of sample tuples
51-
* Note that the passed attnum and tupDesc could possibly be different from
52-
* what one would expect by looking at the pg_attribute row. It is important
53-
* to use these values for extracting attribute values from the given rows
54-
* (and not for any other purpose).
53+
* The fetchfunc may be called with rownum running from 0 to samplerows-1.
54+
* It returns a Datum and an isNull flag.
5555
*
5656
* compute_stats should set stats_valid TRUE if it is able to compute
5757
* any useful statistics. If it does, the remainder of the struct holds
@@ -60,6 +60,11 @@
6060
* be CurrentMemoryContext when compute_stats is called.
6161
*----------
6262
*/
63+
typedefstructVacAttrStats*VacAttrStatsP;
64+
65+
typedefDatum (*AnalyzeAttrFetchFunc) (VacAttrStatsPstats,intrownum,
66+
bool*isNull);
67+
6368
typedefstructVacAttrStats
6469
{
6570
/*
@@ -74,9 +79,10 @@ typedef struct VacAttrStats
7479
* These fields must be filled in by the typanalyze routine,
7580
* unless it returns FALSE.
7681
*/
77-
void (*compute_stats) (structVacAttrStats*stats,intattnum,
78-
TupleDesctupDesc,doubletotalrows,
79-
HeapTuple*rows,intnumrows);
82+
void (*compute_stats) (VacAttrStatsPstats,
83+
AnalyzeAttrFetchFuncfetchfunc,
84+
intsamplerows,
85+
doubletotalrows);
8086
intminrows;/* Minimum # of rows wanted for stats */
8187
void*extra_data;/* for extra type-specific data */
8288

@@ -100,6 +106,8 @@ typedef struct VacAttrStats
100106
* be looked at by type-specific functions.
101107
*/
102108
inttupattnum;/* attribute number within tuples */
109+
HeapTuple*rows;/* access info for fetch function */
110+
TupleDesctupDesc;
103111
}VacAttrStats;
104112

105113

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp