~ubuntu-branches/debian/experimental/postgresql-11/experimental

« back to all changes in this revision

Viewing changes to src/backend/commands/analyze.c

  • Committer: Package Import Robot
  • Author(s): Christoph Berg
  • Date: 2018-05-22 14:19:08 UTC
  • Revision ID: package-import@ubuntu.com-20180522141908-0oy9ujs1b5vrda74
Tags: upstream-11~beta1
ImportĀ upstreamĀ versionĀ 11~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------------------------------------------------------------------------
 
2
 *
 
3
 * analyze.c
 
4
 *        the Postgres statistics generator
 
5
 *
 
6
 * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
 
7
 * Portions Copyright (c) 1994, Regents of the University of California
 
8
 *
 
9
 *
 
10
 * IDENTIFICATION
 
11
 *        src/backend/commands/analyze.c
 
12
 *
 
13
 *-------------------------------------------------------------------------
 
14
 */
 
15
#include "postgres.h"
 
16
 
 
17
#include <math.h>
 
18
 
 
19
#include "access/multixact.h"
 
20
#include "access/sysattr.h"
 
21
#include "access/transam.h"
 
22
#include "access/tupconvert.h"
 
23
#include "access/tuptoaster.h"
 
24
#include "access/visibilitymap.h"
 
25
#include "access/xact.h"
 
26
#include "catalog/catalog.h"
 
27
#include "catalog/index.h"
 
28
#include "catalog/indexing.h"
 
29
#include "catalog/pg_collation.h"
 
30
#include "catalog/pg_inherits.h"
 
31
#include "catalog/pg_namespace.h"
 
32
#include "catalog/pg_statistic_ext.h"
 
33
#include "commands/dbcommands.h"
 
34
#include "commands/tablecmds.h"
 
35
#include "commands/vacuum.h"
 
36
#include "executor/executor.h"
 
37
#include "foreign/fdwapi.h"
 
38
#include "miscadmin.h"
 
39
#include "nodes/nodeFuncs.h"
 
40
#include "parser/parse_oper.h"
 
41
#include "parser/parse_relation.h"
 
42
#include "pgstat.h"
 
43
#include "postmaster/autovacuum.h"
 
44
#include "statistics/extended_stats_internal.h"
 
45
#include "statistics/statistics.h"
 
46
#include "storage/bufmgr.h"
 
47
#include "storage/lmgr.h"
 
48
#include "storage/proc.h"
 
49
#include "storage/procarray.h"
 
50
#include "utils/acl.h"
 
51
#include "utils/attoptcache.h"
 
52
#include "utils/builtins.h"
 
53
#include "utils/datum.h"
 
54
#include "utils/fmgroids.h"
 
55
#include "utils/guc.h"
 
56
#include "utils/lsyscache.h"
 
57
#include "utils/memutils.h"
 
58
#include "utils/pg_rusage.h"
 
59
#include "utils/sampling.h"
 
60
#include "utils/sortsupport.h"
 
61
#include "utils/syscache.h"
 
62
#include "utils/timestamp.h"
 
63
#include "utils/tqual.h"
 
64
 
 
65
 
 
66
/* Per-index data for ANALYZE */
 
67
typedef struct AnlIndexData
 
68
{
 
69
        IndexInfo  *indexInfo;          /* BuildIndexInfo result */
 
70
        double          tupleFract;             /* fraction of rows for partial index */
 
71
        VacAttrStats **vacattrstats;    /* index attrs to analyze */
 
72
        int                     attr_cnt;
 
73
} AnlIndexData;
 
74
 
 
75
 
 
76
/* Default statistics target (GUC parameter) */
 
77
int                     default_statistics_target = 100;
 
78
 
 
79
/* A few variables that don't seem worth passing around as parameters */
 
80
static MemoryContext anl_context = NULL;
 
81
static BufferAccessStrategy vac_strategy;
 
82
 
 
83
 
 
84
static void do_analyze_rel(Relation onerel, int options,
 
85
                           VacuumParams *params, List *va_cols,
 
86
                           AcquireSampleRowsFunc acquirefunc, BlockNumber relpages,
 
87
                           bool inh, bool in_outer_xact, int elevel);
 
88
static void compute_index_stats(Relation onerel, double totalrows,
 
89
                                        AnlIndexData *indexdata, int nindexes,
 
90
                                        HeapTuple *rows, int numrows,
 
91
                                        MemoryContext col_context);
 
92
static VacAttrStats *examine_attribute(Relation onerel, int attnum,
 
93
                                  Node *index_expr);
 
94
static int acquire_sample_rows(Relation onerel, int elevel,
 
95
                                        HeapTuple *rows, int targrows,
 
96
                                        double *totalrows, double *totaldeadrows);
 
97
static int      compare_rows(const void *a, const void *b);
 
98
static int acquire_inherited_sample_rows(Relation onerel, int elevel,
 
99
                                                          HeapTuple *rows, int targrows,
 
100
                                                          double *totalrows, double *totaldeadrows);
 
101
static void update_attstats(Oid relid, bool inh,
 
102
                                int natts, VacAttrStats **vacattrstats);
 
103
static Datum std_fetch_func(VacAttrStatsP stats, int rownum, bool *isNull);
 
104
static Datum ind_fetch_func(VacAttrStatsP stats, int rownum, bool *isNull);
 
105
 
 
106
 
 
107
/*
 
108
 *      analyze_rel() -- analyze one relation
 
109
 *
 
110
 * relid identifies the relation to analyze.  If relation is supplied, use
 
111
 * the name therein for reporting any failure to open/lock the rel; do not
 
112
 * use it once we've successfully opened the rel, since it might be stale.
 
113
 */
 
114
void
 
115
analyze_rel(Oid relid, RangeVar *relation, int options,
 
116
                        VacuumParams *params, List *va_cols, bool in_outer_xact,
 
117
                        BufferAccessStrategy bstrategy)
 
118
{
 
119
        Relation        onerel;
 
120
        int                     elevel;
 
121
        AcquireSampleRowsFunc acquirefunc = NULL;
 
122
        BlockNumber relpages = 0;
 
123
        bool            rel_lock = true;
 
124
 
 
125
        /* Select logging level */
 
126
        if (options & VACOPT_VERBOSE)
 
127
                elevel = INFO;
 
128
        else
 
129
                elevel = DEBUG2;
 
130
 
 
131
        /* Set up static variables */
 
132
        vac_strategy = bstrategy;
 
133
 
 
134
        /*
 
135
         * Check for user-requested abort.
 
136
         */
 
137
        CHECK_FOR_INTERRUPTS();
 
138
 
 
139
        /*
 
140
         * Open the relation, getting ShareUpdateExclusiveLock to ensure that two
 
141
         * ANALYZEs don't run on it concurrently.  (This also locks out a
 
142
         * concurrent VACUUM, which doesn't matter much at the moment but might
 
143
         * matter if we ever try to accumulate stats on dead tuples.) If the rel
 
144
         * has been dropped since we last saw it, we don't need to process it.
 
145
         */
 
146
        if (!(options & VACOPT_NOWAIT))
 
147
                onerel = try_relation_open(relid, ShareUpdateExclusiveLock);
 
148
        else if (ConditionalLockRelationOid(relid, ShareUpdateExclusiveLock))
 
149
                onerel = try_relation_open(relid, NoLock);
 
150
        else
 
151
        {
 
152
                onerel = NULL;
 
153
                rel_lock = false;
 
154
        }
 
155
 
 
156
        /*
 
157
         * If we failed to open or lock the relation, emit a log message before
 
158
         * exiting.
 
159
         */
 
160
        if (!onerel)
 
161
        {
 
162
                /*
 
163
                 * If the RangeVar is not defined, we do not have enough information
 
164
                 * to provide a meaningful log statement.  Chances are that
 
165
                 * analyze_rel's caller has intentionally not provided this
 
166
                 * information so that this logging is skipped, anyway.
 
167
                 */
 
168
                if (relation == NULL)
 
169
                        return;
 
170
 
 
171
                /*
 
172
                 * Determine the log level.  For autovacuum logs, we emit a LOG if
 
173
                 * log_autovacuum_min_duration is not disabled.  For manual ANALYZE,
 
174
                 * we emit a WARNING to match the log statements in the permissions
 
175
                 * checks.
 
176
                 */
 
177
                if (!IsAutoVacuumWorkerProcess())
 
178
                        elevel = WARNING;
 
179
                else if (params->log_min_duration >= 0)
 
180
                        elevel = LOG;
 
181
                else
 
182
                        return;
 
183
 
 
184
                if (!rel_lock)
 
185
                        ereport(elevel,
 
186
                                        (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
 
187
                                         errmsg("skipping analyze of \"%s\" --- lock not available",
 
188
                                                        relation->relname)));
 
189
                else
 
190
                        ereport(elevel,
 
191
                                        (errcode(ERRCODE_UNDEFINED_TABLE),
 
192
                                         errmsg("skipping analyze of \"%s\" --- relation no longer exists",
 
193
                                                        relation->relname)));
 
194
 
 
195
                return;
 
196
        }
 
197
 
 
198
        /*
 
199
         * Check permissions --- this should match vacuum's check!
 
200
         */
 
201
        if (!(pg_class_ownercheck(RelationGetRelid(onerel), GetUserId()) ||
 
202
                  (pg_database_ownercheck(MyDatabaseId, GetUserId()) && !onerel->rd_rel->relisshared)))
 
203
        {
 
204
                /* No need for a WARNING if we already complained during VACUUM */
 
205
                if (!(options & VACOPT_VACUUM))
 
206
                {
 
207
                        if (onerel->rd_rel->relisshared)
 
208
                                ereport(WARNING,
 
209
                                                (errmsg("skipping \"%s\" --- only superuser can analyze it",
 
210
                                                                RelationGetRelationName(onerel))));
 
211
                        else if (onerel->rd_rel->relnamespace == PG_CATALOG_NAMESPACE)
 
212
                                ereport(WARNING,
 
213
                                                (errmsg("skipping \"%s\" --- only superuser or database owner can analyze it",
 
214
                                                                RelationGetRelationName(onerel))));
 
215
                        else
 
216
                                ereport(WARNING,
 
217
                                                (errmsg("skipping \"%s\" --- only table or database owner can analyze it",
 
218
                                                                RelationGetRelationName(onerel))));
 
219
                }
 
220
                relation_close(onerel, ShareUpdateExclusiveLock);
 
221
                return;
 
222
        }
 
223
 
 
224
        /*
 
225
         * Silently ignore tables that are temp tables of other backends ---
 
226
         * trying to analyze these is rather pointless, since their contents are
 
227
         * probably not up-to-date on disk.  (We don't throw a warning here; it
 
228
         * would just lead to chatter during a database-wide ANALYZE.)
 
229
         */
 
230
        if (RELATION_IS_OTHER_TEMP(onerel))
 
231
        {
 
232
                relation_close(onerel, ShareUpdateExclusiveLock);
 
233
                return;
 
234
        }
 
235
 
 
236
        /*
 
237
         * We can ANALYZE any table except pg_statistic. See update_attstats
 
238
         */
 
239
        if (RelationGetRelid(onerel) == StatisticRelationId)
 
240
        {
 
241
                relation_close(onerel, ShareUpdateExclusiveLock);
 
242
                return;
 
243
        }
 
244
 
 
245
        /*
 
246
         * Check that it's of an analyzable relkind, and set up appropriately.
 
247
         */
 
248
        if (onerel->rd_rel->relkind == RELKIND_RELATION ||
 
249
                onerel->rd_rel->relkind == RELKIND_MATVIEW)
 
250
        {
 
251
                /* Regular table, so we'll use the regular row acquisition function */
 
252
                acquirefunc = acquire_sample_rows;
 
253
                /* Also get regular table's size */
 
254
                relpages = RelationGetNumberOfBlocks(onerel);
 
255
        }
 
256
        else if (onerel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
 
257
        {
 
258
                /*
 
259
                 * For a foreign table, call the FDW's hook function to see whether it
 
260
                 * supports analysis.
 
261
                 */
 
262
                FdwRoutine *fdwroutine;
 
263
                bool            ok = false;
 
264
 
 
265
                fdwroutine = GetFdwRoutineForRelation(onerel, false);
 
266
 
 
267
                if (fdwroutine->AnalyzeForeignTable != NULL)
 
268
                        ok = fdwroutine->AnalyzeForeignTable(onerel,
 
269
                                                                                                 &acquirefunc,
 
270
                                                                                                 &relpages);
 
271
 
 
272
                if (!ok)
 
273
                {
 
274
                        ereport(WARNING,
 
275
                                        (errmsg("skipping \"%s\" --- cannot analyze this foreign table",
 
276
                                                        RelationGetRelationName(onerel))));
 
277
                        relation_close(onerel, ShareUpdateExclusiveLock);
 
278
                        return;
 
279
                }
 
280
        }
 
281
        else if (onerel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
 
282
        {
 
283
                /*
 
284
                 * For partitioned tables, we want to do the recursive ANALYZE below.
 
285
                 */
 
286
        }
 
287
        else
 
288
        {
 
289
                /* No need for a WARNING if we already complained during VACUUM */
 
290
                if (!(options & VACOPT_VACUUM))
 
291
                        ereport(WARNING,
 
292
                                        (errmsg("skipping \"%s\" --- cannot analyze non-tables or special system tables",
 
293
                                                        RelationGetRelationName(onerel))));
 
294
                relation_close(onerel, ShareUpdateExclusiveLock);
 
295
                return;
 
296
        }
 
297
 
 
298
        /*
 
299
         * OK, let's do it.  First let other backends know I'm in ANALYZE.
 
300
         */
 
301
        LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
 
302
        MyPgXact->vacuumFlags |= PROC_IN_ANALYZE;
 
303
        LWLockRelease(ProcArrayLock);
 
304
 
 
305
        /*
 
306
         * Do the normal non-recursive ANALYZE.  We can skip this for partitioned
 
307
         * tables, which don't contain any rows.
 
308
         */
 
309
        if (onerel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
 
310
                do_analyze_rel(onerel, options, params, va_cols, acquirefunc,
 
311
                                           relpages, false, in_outer_xact, elevel);
 
312
 
 
313
        /*
 
314
         * If there are child tables, do recursive ANALYZE.
 
315
         */
 
316
        if (onerel->rd_rel->relhassubclass)
 
317
                do_analyze_rel(onerel, options, params, va_cols, acquirefunc, relpages,
 
318
                                           true, in_outer_xact, elevel);
 
319
 
 
320
        /*
 
321
         * Close source relation now, but keep lock so that no one deletes it
 
322
         * before we commit.  (If someone did, they'd fail to clean up the entries
 
323
         * we made in pg_statistic.  Also, releasing the lock before commit would
 
324
         * expose us to concurrent-update failures in update_attstats.)
 
325
         */
 
326
        relation_close(onerel, NoLock);
 
327
 
 
328
        /*
 
329
         * Reset my PGXACT flag.  Note: we need this here, and not in vacuum_rel,
 
330
         * because the vacuum flag is cleared by the end-of-xact code.
 
331
         */
 
332
        LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
 
333
        MyPgXact->vacuumFlags &= ~PROC_IN_ANALYZE;
 
334
        LWLockRelease(ProcArrayLock);
 
335
}
 
336
 
 
337
/*
 
338
 *      do_analyze_rel() -- analyze one relation, recursively or not
 
339
 *
 
340
 * Note that "acquirefunc" is only relevant for the non-inherited case.
 
341
 * For the inherited case, acquire_inherited_sample_rows() determines the
 
342
 * appropriate acquirefunc for each child table.
 
343
 */
 
344
static void
 
345
do_analyze_rel(Relation onerel, int options, VacuumParams *params,
 
346
                           List *va_cols, AcquireSampleRowsFunc acquirefunc,
 
347
                           BlockNumber relpages, bool inh, bool in_outer_xact,
 
348
                           int elevel)
 
349
{
 
350
        int                     attr_cnt,
 
351
                                tcnt,
 
352
                                i,
 
353
                                ind;
 
354
        Relation   *Irel;
 
355
        int                     nindexes;
 
356
        bool            hasindex;
 
357
        VacAttrStats **vacattrstats;
 
358
        AnlIndexData *indexdata;
 
359
        int                     targrows,
 
360
                                numrows;
 
361
        double          totalrows,
 
362
                                totaldeadrows;
 
363
        HeapTuple  *rows;
 
364
        PGRUsage        ru0;
 
365
        TimestampTz starttime = 0;
 
366
        MemoryContext caller_context;
 
367
        Oid                     save_userid;
 
368
        int                     save_sec_context;
 
369
        int                     save_nestlevel;
 
370
 
 
371
        if (inh)
 
372
                ereport(elevel,
 
373
                                (errmsg("analyzing \"%s.%s\" inheritance tree",
 
374
                                                get_namespace_name(RelationGetNamespace(onerel)),
 
375
                                                RelationGetRelationName(onerel))));
 
376
        else
 
377
                ereport(elevel,
 
378
                                (errmsg("analyzing \"%s.%s\"",
 
379
                                                get_namespace_name(RelationGetNamespace(onerel)),
 
380
                                                RelationGetRelationName(onerel))));
 
381
 
 
382
        /*
 
383
         * Set up a working context so that we can easily free whatever junk gets
 
384
         * created.
 
385
         */
 
386
        anl_context = AllocSetContextCreate(CurrentMemoryContext,
 
387
                                                                                "Analyze",
 
388
                                                                                ALLOCSET_DEFAULT_SIZES);
 
389
        caller_context = MemoryContextSwitchTo(anl_context);
 
390
 
 
391
        /*
 
392
         * Switch to the table owner's userid, so that any index functions are run
 
393
         * as that user.  Also lock down security-restricted operations and
 
394
         * arrange to make GUC variable changes local to this command.
 
395
         */
 
396
        GetUserIdAndSecContext(&save_userid, &save_sec_context);
 
397
        SetUserIdAndSecContext(onerel->rd_rel->relowner,
 
398
                                                   save_sec_context | SECURITY_RESTRICTED_OPERATION);
 
399
        save_nestlevel = NewGUCNestLevel();
 
400
 
 
401
        /* measure elapsed time iff autovacuum logging requires it */
 
402
        if (IsAutoVacuumWorkerProcess() && params->log_min_duration >= 0)
 
403
        {
 
404
                pg_rusage_init(&ru0);
 
405
                if (params->log_min_duration > 0)
 
406
                        starttime = GetCurrentTimestamp();
 
407
        }
 
408
 
 
409
        /*
 
410
         * Determine which columns to analyze
 
411
         *
 
412
         * Note that system attributes are never analyzed, so we just reject them
 
413
         * at the lookup stage.  We also reject duplicate column mentions.  (We
 
414
         * could alternatively ignore duplicates, but analyzing a column twice
 
415
         * won't work; we'd end up making a conflicting update in pg_statistic.)
 
416
         */
 
417
        if (va_cols != NIL)
 
418
        {
 
419
                Bitmapset  *unique_cols = NULL;
 
420
                ListCell   *le;
 
421
 
 
422
                vacattrstats = (VacAttrStats **) palloc(list_length(va_cols) *
 
423
                                                                                                sizeof(VacAttrStats *));
 
424
                tcnt = 0;
 
425
                foreach(le, va_cols)
 
426
                {
 
427
                        char       *col = strVal(lfirst(le));
 
428
 
 
429
                        i = attnameAttNum(onerel, col, false);
 
430
                        if (i == InvalidAttrNumber)
 
431
                                ereport(ERROR,
 
432
                                                (errcode(ERRCODE_UNDEFINED_COLUMN),
 
433
                                                 errmsg("column \"%s\" of relation \"%s\" does not exist",
 
434
                                                                col, RelationGetRelationName(onerel))));
 
435
                        if (bms_is_member(i, unique_cols))
 
436
                                ereport(ERROR,
 
437
                                                (errcode(ERRCODE_DUPLICATE_COLUMN),
 
438
                                                 errmsg("column \"%s\" of relation \"%s\" appears more than once",
 
439
                                                                col, RelationGetRelationName(onerel))));
 
440
                        unique_cols = bms_add_member(unique_cols, i);
 
441
 
 
442
                        vacattrstats[tcnt] = examine_attribute(onerel, i, NULL);
 
443
                        if (vacattrstats[tcnt] != NULL)
 
444
                                tcnt++;
 
445
                }
 
446
                attr_cnt = tcnt;
 
447
        }
 
448
        else
 
449
        {
 
450
                attr_cnt = onerel->rd_att->natts;
 
451
                vacattrstats = (VacAttrStats **)
 
452
                        palloc(attr_cnt * sizeof(VacAttrStats *));
 
453
                tcnt = 0;
 
454
                for (i = 1; i <= attr_cnt; i++)
 
455
                {
 
456
                        vacattrstats[tcnt] = examine_attribute(onerel, i, NULL);
 
457
                        if (vacattrstats[tcnt] != NULL)
 
458
                                tcnt++;
 
459
                }
 
460
                attr_cnt = tcnt;
 
461
        }
 
462
 
 
463
        /*
 
464
         * Open all indexes of the relation, and see if there are any analyzable
 
465
         * columns in the indexes.  We do not analyze index columns if there was
 
466
         * an explicit column list in the ANALYZE command, however.  If we are
 
467
         * doing a recursive scan, we don't want to touch the parent's indexes at
 
468
         * all.
 
469
         */
 
470
        if (!inh)
 
471
                vac_open_indexes(onerel, AccessShareLock, &nindexes, &Irel);
 
472
        else
 
473
        {
 
474
                Irel = NULL;
 
475
                nindexes = 0;
 
476
        }
 
477
        hasindex = (nindexes > 0);
 
478
        indexdata = NULL;
 
479
        if (hasindex)
 
480
        {
 
481
                indexdata = (AnlIndexData *) palloc0(nindexes * sizeof(AnlIndexData));
 
482
                for (ind = 0; ind < nindexes; ind++)
 
483
                {
 
484
                        AnlIndexData *thisdata = &indexdata[ind];
 
485
                        IndexInfo  *indexInfo;
 
486
 
 
487
                        thisdata->indexInfo = indexInfo = BuildIndexInfo(Irel[ind]);
 
488
                        thisdata->tupleFract = 1.0; /* fix later if partial */
 
489
                        if (indexInfo->ii_Expressions != NIL && va_cols == NIL)
 
490
                        {
 
491
                                ListCell   *indexpr_item = list_head(indexInfo->ii_Expressions);
 
492
 
 
493
                                thisdata->vacattrstats = (VacAttrStats **)
 
494
                                        palloc(indexInfo->ii_NumIndexAttrs * sizeof(VacAttrStats *));
 
495
                                tcnt = 0;
 
496
                                for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
 
497
                                {
 
498
                                        int                     keycol = indexInfo->ii_IndexAttrNumbers[i];
 
499
 
 
500
                                        if (keycol == 0)
 
501
                                        {
 
502
                                                /* Found an index expression */
 
503
                                                Node       *indexkey;
 
504
 
 
505
                                                if (indexpr_item == NULL)       /* shouldn't happen */
 
506
                                                        elog(ERROR, "too few entries in indexprs list");
 
507
                                                indexkey = (Node *) lfirst(indexpr_item);
 
508
                                                indexpr_item = lnext(indexpr_item);
 
509
                                                thisdata->vacattrstats[tcnt] =
 
510
                                                        examine_attribute(Irel[ind], i + 1, indexkey);
 
511
                                                if (thisdata->vacattrstats[tcnt] != NULL)
 
512
                                                        tcnt++;
 
513
                                        }
 
514
                                }
 
515
                                thisdata->attr_cnt = tcnt;
 
516
                        }
 
517
                }
 
518
        }
 
519
 
 
520
        /*
 
521
         * Determine how many rows we need to sample, using the worst case from
 
522
         * all analyzable columns.  We use a lower bound of 100 rows to avoid
 
523
         * possible overflow in Vitter's algorithm.  (Note: that will also be the
 
524
         * target in the corner case where there are no analyzable columns.)
 
525
         */
 
526
        targrows = 100;
 
527
        for (i = 0; i < attr_cnt; i++)
 
528
        {
 
529
                if (targrows < vacattrstats[i]->minrows)
 
530
                        targrows = vacattrstats[i]->minrows;
 
531
        }
 
532
        for (ind = 0; ind < nindexes; ind++)
 
533
        {
 
534
                AnlIndexData *thisdata = &indexdata[ind];
 
535
 
 
536
                for (i = 0; i < thisdata->attr_cnt; i++)
 
537
                {
 
538
                        if (targrows < thisdata->vacattrstats[i]->minrows)
 
539
                                targrows = thisdata->vacattrstats[i]->minrows;
 
540
                }
 
541
        }
 
542
 
 
543
        /*
 
544
         * Acquire the sample rows
 
545
         */
 
546
        rows = (HeapTuple *) palloc(targrows * sizeof(HeapTuple));
 
547
        if (inh)
 
548
                numrows = acquire_inherited_sample_rows(onerel, elevel,
 
549
                                                                                                rows, targrows,
 
550
                                                                                                &totalrows, &totaldeadrows);
 
551
        else
 
552
                numrows = (*acquirefunc) (onerel, elevel,
 
553
                                                                  rows, targrows,
 
554
                                                                  &totalrows, &totaldeadrows);
 
555
 
 
556
        /*
 
557
         * Compute the statistics.  Temporary results during the calculations for
 
558
         * each column are stored in a child context.  The calc routines are
 
559
         * responsible to make sure that whatever they store into the VacAttrStats
 
560
         * structure is allocated in anl_context.
 
561
         */
 
562
        if (numrows > 0)
 
563
        {
 
564
                MemoryContext col_context,
 
565
                                        old_context;
 
566
 
 
567
                col_context = AllocSetContextCreate(anl_context,
 
568
                                                                                        "Analyze Column",
 
569
                                                                                        ALLOCSET_DEFAULT_SIZES);
 
570
                old_context = MemoryContextSwitchTo(col_context);
 
571
 
 
572
                for (i = 0; i < attr_cnt; i++)
 
573
                {
 
574
                        VacAttrStats *stats = vacattrstats[i];
 
575
                        AttributeOpts *aopt;
 
576
 
 
577
                        stats->rows = rows;
 
578
                        stats->tupDesc = onerel->rd_att;
 
579
                        stats->compute_stats(stats,
 
580
                                                                 std_fetch_func,
 
581
                                                                 numrows,
 
582
                                                                 totalrows);
 
583
 
 
584
                        /*
 
585
                         * If the appropriate flavor of the n_distinct option is
 
586
                         * specified, override with the corresponding value.
 
587
                         */
 
588
                        aopt = get_attribute_options(onerel->rd_id, stats->attr->attnum);
 
589
                        if (aopt != NULL)
 
590
                        {
 
591
                                float8          n_distinct;
 
592
 
 
593
                                n_distinct = inh ? aopt->n_distinct_inherited : aopt->n_distinct;
 
594
                                if (n_distinct != 0.0)
 
595
                                        stats->stadistinct = n_distinct;
 
596
                        }
 
597
 
 
598
                        MemoryContextResetAndDeleteChildren(col_context);
 
599
                }
 
600
 
 
601
                if (hasindex)
 
602
                        compute_index_stats(onerel, totalrows,
 
603
                                                                indexdata, nindexes,
 
604
                                                                rows, numrows,
 
605
                                                                col_context);
 
606
 
 
607
                MemoryContextSwitchTo(old_context);
 
608
                MemoryContextDelete(col_context);
 
609
 
 
610
                /*
 
611
                 * Emit the completed stats rows into pg_statistic, replacing any
 
612
                 * previous statistics for the target columns.  (If there are stats in
 
613
                 * pg_statistic for columns we didn't process, we leave them alone.)
 
614
                 */
 
615
                update_attstats(RelationGetRelid(onerel), inh,
 
616
                                                attr_cnt, vacattrstats);
 
617
 
 
618
                for (ind = 0; ind < nindexes; ind++)
 
619
                {
 
620
                        AnlIndexData *thisdata = &indexdata[ind];
 
621
 
 
622
                        update_attstats(RelationGetRelid(Irel[ind]), false,
 
623
                                                        thisdata->attr_cnt, thisdata->vacattrstats);
 
624
                }
 
625
 
 
626
                /* Build extended statistics (if there are any). */
 
627
                BuildRelationExtStatistics(onerel, totalrows, numrows, rows, attr_cnt,
 
628
                                                                   vacattrstats);
 
629
        }
 
630
 
 
631
        /*
 
632
         * Update pages/tuples stats in pg_class ... but not if we're doing
 
633
         * inherited stats.
 
634
         */
 
635
        if (!inh)
 
636
        {
 
637
                BlockNumber relallvisible;
 
638
 
 
639
                visibilitymap_count(onerel, &relallvisible, NULL);
 
640
 
 
641
                vac_update_relstats(onerel,
 
642
                                                        relpages,
 
643
                                                        totalrows,
 
644
                                                        relallvisible,
 
645
                                                        hasindex,
 
646
                                                        InvalidTransactionId,
 
647
                                                        InvalidMultiXactId,
 
648
                                                        in_outer_xact);
 
649
        }
 
650
 
 
651
        /*
 
652
         * Same for indexes. Vacuum always scans all indexes, so if we're part of
 
653
         * VACUUM ANALYZE, don't overwrite the accurate count already inserted by
 
654
         * VACUUM.
 
655
         */
 
656
        if (!inh && !(options & VACOPT_VACUUM))
 
657
        {
 
658
                for (ind = 0; ind < nindexes; ind++)
 
659
                {
 
660
                        AnlIndexData *thisdata = &indexdata[ind];
 
661
                        double          totalindexrows;
 
662
 
 
663
                        totalindexrows = ceil(thisdata->tupleFract * totalrows);
 
664
                        vac_update_relstats(Irel[ind],
 
665
                                                                RelationGetNumberOfBlocks(Irel[ind]),
 
666
                                                                totalindexrows,
 
667
                                                                0,
 
668
                                                                false,
 
669
                                                                InvalidTransactionId,
 
670
                                                                InvalidMultiXactId,
 
671
                                                                in_outer_xact);
 
672
                }
 
673
        }
 
674
 
 
675
        /*
 
676
         * Report ANALYZE to the stats collector, too.  However, if doing
 
677
         * inherited stats we shouldn't report, because the stats collector only
 
678
         * tracks per-table stats.  Reset the changes_since_analyze counter only
 
679
         * if we analyzed all columns; otherwise, there is still work for
 
680
         * auto-analyze to do.
 
681
         */
 
682
        if (!inh)
 
683
                pgstat_report_analyze(onerel, totalrows, totaldeadrows,
 
684
                                                          (va_cols == NIL));
 
685
 
 
686
        /* If this isn't part of VACUUM ANALYZE, let index AMs do cleanup */
 
687
        if (!(options & VACOPT_VACUUM))
 
688
        {
 
689
                for (ind = 0; ind < nindexes; ind++)
 
690
                {
 
691
                        IndexBulkDeleteResult *stats;
 
692
                        IndexVacuumInfo ivinfo;
 
693
 
 
694
                        ivinfo.index = Irel[ind];
 
695
                        ivinfo.analyze_only = true;
 
696
                        ivinfo.estimated_count = true;
 
697
                        ivinfo.message_level = elevel;
 
698
                        ivinfo.num_heap_tuples = onerel->rd_rel->reltuples;
 
699
                        ivinfo.strategy = vac_strategy;
 
700
 
 
701
                        stats = index_vacuum_cleanup(&ivinfo, NULL);
 
702
 
 
703
                        if (stats)
 
704
                                pfree(stats);
 
705
                }
 
706
        }
 
707
 
 
708
        /* Done with indexes */
 
709
        vac_close_indexes(nindexes, Irel, NoLock);
 
710
 
 
711
        /* Log the action if appropriate */
 
712
        if (IsAutoVacuumWorkerProcess() && params->log_min_duration >= 0)
 
713
        {
 
714
                if (params->log_min_duration == 0 ||
 
715
                        TimestampDifferenceExceeds(starttime, GetCurrentTimestamp(),
 
716
                                                                           params->log_min_duration))
 
717
                        ereport(LOG,
 
718
                                        (errmsg("automatic analyze of table \"%s.%s.%s\" system usage: %s",
 
719
                                                        get_database_name(MyDatabaseId),
 
720
                                                        get_namespace_name(RelationGetNamespace(onerel)),
 
721
                                                        RelationGetRelationName(onerel),
 
722
                                                        pg_rusage_show(&ru0))));
 
723
        }
 
724
 
 
725
        /* Roll back any GUC changes executed by index functions */
 
726
        AtEOXact_GUC(false, save_nestlevel);
 
727
 
 
728
        /* Restore userid and security context */
 
729
        SetUserIdAndSecContext(save_userid, save_sec_context);
 
730
 
 
731
        /* Restore current context and release memory */
 
732
        MemoryContextSwitchTo(caller_context);
 
733
        MemoryContextDelete(anl_context);
 
734
        anl_context = NULL;
 
735
}
 
736
 
 
737
/*
 
738
 * Compute statistics about indexes of a relation
 
739
 */
 
740
static void
 
741
compute_index_stats(Relation onerel, double totalrows,
 
742
                                        AnlIndexData *indexdata, int nindexes,
 
743
                                        HeapTuple *rows, int numrows,
 
744
                                        MemoryContext col_context)
 
745
{
 
746
        MemoryContext ind_context,
 
747
                                old_context;
 
748
        Datum           values[INDEX_MAX_KEYS];
 
749
        bool            isnull[INDEX_MAX_KEYS];
 
750
        int                     ind,
 
751
                                i;
 
752
 
 
753
        ind_context = AllocSetContextCreate(anl_context,
 
754
                                                                                "Analyze Index",
 
755
                                                                                ALLOCSET_DEFAULT_SIZES);
 
756
        old_context = MemoryContextSwitchTo(ind_context);
 
757
 
 
758
        for (ind = 0; ind < nindexes; ind++)
 
759
        {
 
760
                AnlIndexData *thisdata = &indexdata[ind];
 
761
                IndexInfo  *indexInfo = thisdata->indexInfo;
 
762
                int                     attr_cnt = thisdata->attr_cnt;
 
763
                TupleTableSlot *slot;
 
764
                EState     *estate;
 
765
                ExprContext *econtext;
 
766
                ExprState  *predicate;
 
767
                Datum      *exprvals;
 
768
                bool       *exprnulls;
 
769
                int                     numindexrows,
 
770
                                        tcnt,
 
771
                                        rowno;
 
772
                double          totalindexrows;
 
773
 
 
774
                /* Ignore index if no columns to analyze and not partial */
 
775
                if (attr_cnt == 0 && indexInfo->ii_Predicate == NIL)
 
776
                        continue;
 
777
 
 
778
                /*
 
779
                 * Need an EState for evaluation of index expressions and
 
780
                 * partial-index predicates.  Create it in the per-index context to be
 
781
                 * sure it gets cleaned up at the bottom of the loop.
 
782
                 */
 
783
                estate = CreateExecutorState();
 
784
                econtext = GetPerTupleExprContext(estate);
 
785
                /* Need a slot to hold the current heap tuple, too */
 
786
                slot = MakeSingleTupleTableSlot(RelationGetDescr(onerel));
 
787
 
 
788
                /* Arrange for econtext's scan tuple to be the tuple under test */
 
789
                econtext->ecxt_scantuple = slot;
 
790
 
 
791
                /* Set up execution state for predicate. */
 
792
                predicate = ExecPrepareQual(indexInfo->ii_Predicate, estate);
 
793
 
 
794
                /* Compute and save index expression values */
 
795
                exprvals = (Datum *) palloc(numrows * attr_cnt * sizeof(Datum));
 
796
                exprnulls = (bool *) palloc(numrows * attr_cnt * sizeof(bool));
 
797
                numindexrows = 0;
 
798
                tcnt = 0;
 
799
                for (rowno = 0; rowno < numrows; rowno++)
 
800
                {
 
801
                        HeapTuple       heapTuple = rows[rowno];
 
802
 
 
803
                        vacuum_delay_point();
 
804
 
 
805
                        /*
 
806
                         * Reset the per-tuple context each time, to reclaim any cruft
 
807
                         * left behind by evaluating the predicate or index expressions.
 
808
                         */
 
809
                        ResetExprContext(econtext);
 
810
 
 
811
                        /* Set up for predicate or expression evaluation */
 
812
                        ExecStoreTuple(heapTuple, slot, InvalidBuffer, false);
 
813
 
 
814
                        /* If index is partial, check predicate */
 
815
                        if (predicate != NULL)
 
816
                        {
 
817
                                if (!ExecQual(predicate, econtext))
 
818
                                        continue;
 
819
                        }
 
820
                        numindexrows++;
 
821
 
 
822
                        if (attr_cnt > 0)
 
823
                        {
 
824
                                /*
 
825
                                 * Evaluate the index row to compute expression values. We
 
826
                                 * could do this by hand, but FormIndexDatum is convenient.
 
827
                                 */
 
828
                                FormIndexDatum(indexInfo,
 
829
                                                           slot,
 
830
                                                           estate,
 
831
                                                           values,
 
832
                                                           isnull);
 
833
 
 
834
                                /*
 
835
                                 * Save just the columns we care about.  We copy the values
 
836
                                 * into ind_context from the estate's per-tuple context.
 
837
                                 */
 
838
                                for (i = 0; i < attr_cnt; i++)
 
839
                                {
 
840
                                        VacAttrStats *stats = thisdata->vacattrstats[i];
 
841
                                        int                     attnum = stats->attr->attnum;
 
842
 
 
843
                                        if (isnull[attnum - 1])
 
844
                                        {
 
845
                                                exprvals[tcnt] = (Datum) 0;
 
846
                                                exprnulls[tcnt] = true;
 
847
                                        }
 
848
                                        else
 
849
                                        {
 
850
                                                exprvals[tcnt] = datumCopy(values[attnum - 1],
 
851
                                                                                                   stats->attrtype->typbyval,
 
852
                                                                                                   stats->attrtype->typlen);
 
853
                                                exprnulls[tcnt] = false;
 
854
                                        }
 
855
                                        tcnt++;
 
856
                                }
 
857
                        }
 
858
                }
 
859
 
 
860
                /*
 
861
                 * Having counted the number of rows that pass the predicate in the
 
862
                 * sample, we can estimate the total number of rows in the index.
 
863
                 */
 
864
                thisdata->tupleFract = (double) numindexrows / (double) numrows;
 
865
                totalindexrows = ceil(thisdata->tupleFract * totalrows);
 
866
 
 
867
                /*
 
868
                 * Now we can compute the statistics for the expression columns.
 
869
                 */
 
870
                if (numindexrows > 0)
 
871
                {
 
872
                        MemoryContextSwitchTo(col_context);
 
873
                        for (i = 0; i < attr_cnt; i++)
 
874
                        {
 
875
                                VacAttrStats *stats = thisdata->vacattrstats[i];
 
876
                                AttributeOpts *aopt =
 
877
                                get_attribute_options(stats->attr->attrelid,
 
878
                                                                          stats->attr->attnum);
 
879
 
 
880
                                stats->exprvals = exprvals + i;
 
881
                                stats->exprnulls = exprnulls + i;
 
882
                                stats->rowstride = attr_cnt;
 
883
                                stats->compute_stats(stats,
 
884
                                                                         ind_fetch_func,
 
885
                                                                         numindexrows,
 
886
                                                                         totalindexrows);
 
887
 
 
888
                                /*
 
889
                                 * If the n_distinct option is specified, it overrides the
 
890
                                 * above computation.  For indices, we always use just
 
891
                                 * n_distinct, not n_distinct_inherited.
 
892
                                 */
 
893
                                if (aopt != NULL && aopt->n_distinct != 0.0)
 
894
                                        stats->stadistinct = aopt->n_distinct;
 
895
 
 
896
                                MemoryContextResetAndDeleteChildren(col_context);
 
897
                        }
 
898
                }
 
899
 
 
900
                /* And clean up */
 
901
                MemoryContextSwitchTo(ind_context);
 
902
 
 
903
                ExecDropSingleTupleTableSlot(slot);
 
904
                FreeExecutorState(estate);
 
905
                MemoryContextResetAndDeleteChildren(ind_context);
 
906
        }
 
907
 
 
908
        MemoryContextSwitchTo(old_context);
 
909
        MemoryContextDelete(ind_context);
 
910
}
 
911
 
 
912
/*
 
913
 * examine_attribute -- pre-analysis of a single column
 
914
 *
 
915
 * Determine whether the column is analyzable; if so, create and initialize
 
916
 * a VacAttrStats struct for it.  If not, return NULL.
 
917
 *
 
918
 * If index_expr isn't NULL, then we're trying to analyze an expression index,
 
919
 * and index_expr is the expression tree representing the column's data.
 
920
 */
 
921
static VacAttrStats *
 
922
examine_attribute(Relation onerel, int attnum, Node *index_expr)
 
923
{
 
924
        Form_pg_attribute attr = TupleDescAttr(onerel->rd_att, attnum - 1);
 
925
        HeapTuple       typtuple;
 
926
        VacAttrStats *stats;
 
927
        int                     i;
 
928
        bool            ok;
 
929
 
 
930
        /* Never analyze dropped columns */
 
931
        if (attr->attisdropped)
 
932
                return NULL;
 
933
 
 
934
        /* Don't analyze column if user has specified not to */
 
935
        if (attr->attstattarget == 0)
 
936
                return NULL;
 
937
 
 
938
        /*
 
939
         * Create the VacAttrStats struct.  Note that we only have a copy of the
 
940
         * fixed fields of the pg_attribute tuple.
 
941
         */
 
942
        stats = (VacAttrStats *) palloc0(sizeof(VacAttrStats));
 
943
        stats->attr = (Form_pg_attribute) palloc(ATTRIBUTE_FIXED_PART_SIZE);
 
944
        memcpy(stats->attr, attr, ATTRIBUTE_FIXED_PART_SIZE);
 
945
 
 
946
        /*
 
947
         * When analyzing an expression index, believe the expression tree's type
 
948
         * not the column datatype --- the latter might be the opckeytype storage
 
949
         * type of the opclass, which is not interesting for our purposes.  (Note:
 
950
         * if we did anything with non-expression index columns, we'd need to
 
951
         * figure out where to get the correct type info from, but for now that's
 
952
         * not a problem.)      It's not clear whether anyone will care about the
 
953
         * typmod, but we store that too just in case.
 
954
         */
 
955
        if (index_expr)
 
956
        {
 
957
                stats->attrtypid = exprType(index_expr);
 
958
                stats->attrtypmod = exprTypmod(index_expr);
 
959
        }
 
960
        else
 
961
        {
 
962
                stats->attrtypid = attr->atttypid;
 
963
                stats->attrtypmod = attr->atttypmod;
 
964
        }
 
965
 
 
966
        typtuple = SearchSysCacheCopy1(TYPEOID,
 
967
                                                                   ObjectIdGetDatum(stats->attrtypid));
 
968
        if (!HeapTupleIsValid(typtuple))
 
969
                elog(ERROR, "cache lookup failed for type %u", stats->attrtypid);
 
970
        stats->attrtype = (Form_pg_type) GETSTRUCT(typtuple);
 
971
        stats->anl_context = anl_context;
 
972
        stats->tupattnum = attnum;
 
973
 
 
974
        /*
 
975
         * The fields describing the stats->stavalues[n] element types default to
 
976
         * the type of the data being analyzed, but the type-specific typanalyze
 
977
         * function can change them if it wants to store something else.
 
978
         */
 
979
        for (i = 0; i < STATISTIC_NUM_SLOTS; i++)
 
980
        {
 
981
                stats->statypid[i] = stats->attrtypid;
 
982
                stats->statyplen[i] = stats->attrtype->typlen;
 
983
                stats->statypbyval[i] = stats->attrtype->typbyval;
 
984
                stats->statypalign[i] = stats->attrtype->typalign;
 
985
        }
 
986
 
 
987
        /*
 
988
         * Call the type-specific typanalyze function.  If none is specified, use
 
989
         * std_typanalyze().
 
990
         */
 
991
        if (OidIsValid(stats->attrtype->typanalyze))
 
992
                ok = DatumGetBool(OidFunctionCall1(stats->attrtype->typanalyze,
 
993
                                                                                   PointerGetDatum(stats)));
 
994
        else
 
995
                ok = std_typanalyze(stats);
 
996
 
 
997
        if (!ok || stats->compute_stats == NULL || stats->minrows <= 0)
 
998
        {
 
999
                heap_freetuple(typtuple);
 
1000
                pfree(stats->attr);
 
1001
                pfree(stats);
 
1002
                return NULL;
 
1003
        }
 
1004
 
 
1005
        return stats;
 
1006
}
 
1007
 
 
1008
/*
 
1009
 * acquire_sample_rows -- acquire a random sample of rows from the table
 
1010
 *
 
1011
 * Selected rows are returned in the caller-allocated array rows[], which
 
1012
 * must have at least targrows entries.
 
1013
 * The actual number of rows selected is returned as the function result.
 
1014
 * We also estimate the total numbers of live and dead rows in the table,
 
1015
 * and return them into *totalrows and *totaldeadrows, respectively.
 
1016
 *
 
1017
 * The returned list of tuples is in order by physical position in the table.
 
1018
 * (We will rely on this later to derive correlation estimates.)
 
1019
 *
 
1020
 * As of May 2004 we use a new two-stage method:  Stage one selects up
 
1021
 * to targrows random blocks (or all blocks, if there aren't so many).
 
1022
 * Stage two scans these blocks and uses the Vitter algorithm to create
 
1023
 * a random sample of targrows rows (or less, if there are less in the
 
1024
 * sample of blocks).  The two stages are executed simultaneously: each
 
1025
 * block is processed as soon as stage one returns its number and while
 
1026
 * the rows are read stage two controls which ones are to be inserted
 
1027
 * into the sample.
 
1028
 *
 
1029
 * Although every row has an equal chance of ending up in the final
 
1030
 * sample, this sampling method is not perfect: not every possible
 
1031
 * sample has an equal chance of being selected.  For large relations
 
1032
 * the number of different blocks represented by the sample tends to be
 
1033
 * too small.  We can live with that for now.  Improvements are welcome.
 
1034
 *
 
1035
 * An important property of this sampling method is that because we do
 
1036
 * look at a statistically unbiased set of blocks, we should get
 
1037
 * unbiased estimates of the average numbers of live and dead rows per
 
1038
 * block.  The previous sampling method put too much credence in the row
 
1039
 * density near the start of the table.
 
1040
 */
 
1041
static int
 
1042
acquire_sample_rows(Relation onerel, int elevel,
 
1043
                                        HeapTuple *rows, int targrows,
 
1044
                                        double *totalrows, double *totaldeadrows)
 
1045
{
 
1046
        int                     numrows = 0;    /* # rows now in reservoir */
 
1047
        double          samplerows = 0; /* total # rows collected */
 
1048
        double          liverows = 0;   /* # live rows seen */
 
1049
        double          deadrows = 0;   /* # dead rows seen */
 
1050
        double          rowstoskip = -1;        /* -1 means not set yet */
 
1051
        BlockNumber totalblocks;
 
1052
        TransactionId OldestXmin;
 
1053
        BlockSamplerData bs;
 
1054
        ReservoirStateData rstate;
 
1055
 
 
1056
        Assert(targrows > 0);
 
1057
 
 
1058
        totalblocks = RelationGetNumberOfBlocks(onerel);
 
1059
 
 
1060
        /* Need a cutoff xmin for HeapTupleSatisfiesVacuum */
 
1061
        OldestXmin = GetOldestXmin(onerel, PROCARRAY_FLAGS_VACUUM);
 
1062
 
 
1063
        /* Prepare for sampling block numbers */
 
1064
        BlockSampler_Init(&bs, totalblocks, targrows, random());
 
1065
        /* Prepare for sampling rows */
 
1066
        reservoir_init_selection_state(&rstate, targrows);
 
1067
 
 
1068
        /* Outer loop over blocks to sample */
 
1069
        while (BlockSampler_HasMore(&bs))
 
1070
        {
 
1071
                BlockNumber targblock = BlockSampler_Next(&bs);
 
1072
                Buffer          targbuffer;
 
1073
                Page            targpage;
 
1074
                OffsetNumber targoffset,
 
1075
                                        maxoffset;
 
1076
 
 
1077
                vacuum_delay_point();
 
1078
 
 
1079
                /*
 
1080
                 * We must maintain a pin on the target page's buffer to ensure that
 
1081
                 * the maxoffset value stays good (else concurrent VACUUM might delete
 
1082
                 * tuples out from under us).  Hence, pin the page until we are done
 
1083
                 * looking at it.  We also choose to hold sharelock on the buffer
 
1084
                 * throughout --- we could release and re-acquire sharelock for each
 
1085
                 * tuple, but since we aren't doing much work per tuple, the extra
 
1086
                 * lock traffic is probably better avoided.
 
1087
                 */
 
1088
                targbuffer = ReadBufferExtended(onerel, MAIN_FORKNUM, targblock,
 
1089
                                                                                RBM_NORMAL, vac_strategy);
 
1090
                LockBuffer(targbuffer, BUFFER_LOCK_SHARE);
 
1091
                targpage = BufferGetPage(targbuffer);
 
1092
                maxoffset = PageGetMaxOffsetNumber(targpage);
 
1093
 
 
1094
                /* Inner loop over all tuples on the selected page */
 
1095
                for (targoffset = FirstOffsetNumber; targoffset <= maxoffset; targoffset++)
 
1096
                {
 
1097
                        ItemId          itemid;
 
1098
                        HeapTupleData targtuple;
 
1099
                        bool            sample_it = false;
 
1100
 
 
1101
                        itemid = PageGetItemId(targpage, targoffset);
 
1102
 
 
1103
                        /*
 
1104
                         * We ignore unused and redirect line pointers.  DEAD line
 
1105
                         * pointers should be counted as dead, because we need vacuum to
 
1106
                         * run to get rid of them.  Note that this rule agrees with the
 
1107
                         * way that heap_page_prune() counts things.
 
1108
                         */
 
1109
                        if (!ItemIdIsNormal(itemid))
 
1110
                        {
 
1111
                                if (ItemIdIsDead(itemid))
 
1112
                                        deadrows += 1;
 
1113
                                continue;
 
1114
                        }
 
1115
 
 
1116
                        ItemPointerSet(&targtuple.t_self, targblock, targoffset);
 
1117
 
 
1118
                        targtuple.t_tableOid = RelationGetRelid(onerel);
 
1119
                        targtuple.t_data = (HeapTupleHeader) PageGetItem(targpage, itemid);
 
1120
                        targtuple.t_len = ItemIdGetLength(itemid);
 
1121
 
 
1122
                        switch (HeapTupleSatisfiesVacuum(&targtuple,
 
1123
                                                                                         OldestXmin,
 
1124
                                                                                         targbuffer))
 
1125
                        {
 
1126
                                case HEAPTUPLE_LIVE:
 
1127
                                        sample_it = true;
 
1128
                                        liverows += 1;
 
1129
                                        break;
 
1130
 
 
1131
                                case HEAPTUPLE_DEAD:
 
1132
                                case HEAPTUPLE_RECENTLY_DEAD:
 
1133
                                        /* Count dead and recently-dead rows */
 
1134
                                        deadrows += 1;
 
1135
                                        break;
 
1136
 
 
1137
                                case HEAPTUPLE_INSERT_IN_PROGRESS:
 
1138
 
 
1139
                                        /*
 
1140
                                         * Insert-in-progress rows are not counted.  We assume
 
1141
                                         * that when the inserting transaction commits or aborts,
 
1142
                                         * it will send a stats message to increment the proper
 
1143
                                         * count.  This works right only if that transaction ends
 
1144
                                         * after we finish analyzing the table; if things happen
 
1145
                                         * in the other order, its stats update will be
 
1146
                                         * overwritten by ours.  However, the error will be large
 
1147
                                         * only if the other transaction runs long enough to
 
1148
                                         * insert many tuples, so assuming it will finish after us
 
1149
                                         * is the safer option.
 
1150
                                         *
 
1151
                                         * A special case is that the inserting transaction might
 
1152
                                         * be our own.  In this case we should count and sample
 
1153
                                         * the row, to accommodate users who load a table and
 
1154
                                         * analyze it in one transaction.  (pgstat_report_analyze
 
1155
                                         * has to adjust the numbers we send to the stats
 
1156
                                         * collector to make this come out right.)
 
1157
                                         */
 
1158
                                        if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(targtuple.t_data)))
 
1159
                                        {
 
1160
                                                sample_it = true;
 
1161
                                                liverows += 1;
 
1162
                                        }
 
1163
                                        break;
 
1164
 
 
1165
                                case HEAPTUPLE_DELETE_IN_PROGRESS:
 
1166
 
 
1167
                                        /*
 
1168
                                         * We count delete-in-progress rows as still live, using
 
1169
                                         * the same reasoning given above; but we don't bother to
 
1170
                                         * include them in the sample.
 
1171
                                         *
 
1172
                                         * If the delete was done by our own transaction, however,
 
1173
                                         * we must count the row as dead to make
 
1174
                                         * pgstat_report_analyze's stats adjustments come out
 
1175
                                         * right.  (Note: this works out properly when the row was
 
1176
                                         * both inserted and deleted in our xact.)
 
1177
                                         */
 
1178
                                        if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetUpdateXid(targtuple.t_data)))
 
1179
                                                deadrows += 1;
 
1180
                                        else
 
1181
                                                liverows += 1;
 
1182
                                        break;
 
1183
 
 
1184
                                default:
 
1185
                                        elog(ERROR, "unexpected HeapTupleSatisfiesVacuum result");
 
1186
                                        break;
 
1187
                        }
 
1188
 
 
1189
                        if (sample_it)
 
1190
                        {
 
1191
                                /*
 
1192
                                 * The first targrows sample rows are simply copied into the
 
1193
                                 * reservoir. Then we start replacing tuples in the sample
 
1194
                                 * until we reach the end of the relation.  This algorithm is
 
1195
                                 * from Jeff Vitter's paper (see full citation below). It
 
1196
                                 * works by repeatedly computing the number of tuples to skip
 
1197
                                 * before selecting a tuple, which replaces a randomly chosen
 
1198
                                 * element of the reservoir (current set of tuples).  At all
 
1199
                                 * times the reservoir is a true random sample of the tuples
 
1200
                                 * we've passed over so far, so when we fall off the end of
 
1201
                                 * the relation we're done.
 
1202
                                 */
 
1203
                                if (numrows < targrows)
 
1204
                                        rows[numrows++] = heap_copytuple(&targtuple);
 
1205
                                else
 
1206
                                {
 
1207
                                        /*
 
1208
                                         * t in Vitter's paper is the number of records already
 
1209
                                         * processed.  If we need to compute a new S value, we
 
1210
                                         * must use the not-yet-incremented value of samplerows as
 
1211
                                         * t.
 
1212
                                         */
 
1213
                                        if (rowstoskip < 0)
 
1214
                                                rowstoskip = reservoir_get_next_S(&rstate, samplerows, targrows);
 
1215
 
 
1216
                                        if (rowstoskip <= 0)
 
1217
                                        {
 
1218
                                                /*
 
1219
                                                 * Found a suitable tuple, so save it, replacing one
 
1220
                                                 * old tuple at random
 
1221
                                                 */
 
1222
                                                int                     k = (int) (targrows * sampler_random_fract(rstate.randstate));
 
1223
 
 
1224
                                                Assert(k >= 0 && k < targrows);
 
1225
                                                heap_freetuple(rows[k]);
 
1226
                                                rows[k] = heap_copytuple(&targtuple);
 
1227
                                        }
 
1228
 
 
1229
                                        rowstoskip -= 1;
 
1230
                                }
 
1231
 
 
1232
                                samplerows += 1;
 
1233
                        }
 
1234
                }
 
1235
 
 
1236
                /* Now release the lock and pin on the page */
 
1237
                UnlockReleaseBuffer(targbuffer);
 
1238
        }
 
1239
 
 
1240
        /*
 
1241
         * If we didn't find as many tuples as we wanted then we're done. No sort
 
1242
         * is needed, since they're already in order.
 
1243
         *
 
1244
         * Otherwise we need to sort the collected tuples by position
 
1245
         * (itempointer). It's not worth worrying about corner cases where the
 
1246
         * tuples are already sorted.
 
1247
         */
 
1248
        if (numrows == targrows)
 
1249
                qsort((void *) rows, numrows, sizeof(HeapTuple), compare_rows);
 
1250
 
 
1251
        /*
 
1252
         * Estimate total numbers of live and dead rows in relation, extrapolating
 
1253
         * on the assumption that the average tuple density in pages we didn't
 
1254
         * scan is the same as in the pages we did scan.  Since what we scanned is
 
1255
         * a random sample of the pages in the relation, this should be a good
 
1256
         * assumption.
 
1257
         */
 
1258
        if (bs.m > 0)
 
1259
        {
 
1260
                *totalrows = floor((liverows / bs.m) * totalblocks + 0.5);
 
1261
                *totaldeadrows = floor((deadrows / bs.m) * totalblocks + 0.5);
 
1262
        }
 
1263
        else
 
1264
        {
 
1265
                *totalrows = 0.0;
 
1266
                *totaldeadrows = 0.0;
 
1267
        }
 
1268
 
 
1269
        /*
 
1270
         * Emit some interesting relation info
 
1271
         */
 
1272
        ereport(elevel,
 
1273
                        (errmsg("\"%s\": scanned %d of %u pages, "
 
1274
                                        "containing %.0f live rows and %.0f dead rows; "
 
1275
                                        "%d rows in sample, %.0f estimated total rows",
 
1276
                                        RelationGetRelationName(onerel),
 
1277
                                        bs.m, totalblocks,
 
1278
                                        liverows, deadrows,
 
1279
                                        numrows, *totalrows)));
 
1280
 
 
1281
        return numrows;
 
1282
}
 
1283
 
 
1284
/*
 
1285
 * qsort comparator for sorting rows[] array
 
1286
 */
 
1287
static int
 
1288
compare_rows(const void *a, const void *b)
 
1289
{
 
1290
        HeapTuple       ha = *(const HeapTuple *) a;
 
1291
        HeapTuple       hb = *(const HeapTuple *) b;
 
1292
        BlockNumber ba = ItemPointerGetBlockNumber(&ha->t_self);
 
1293
        OffsetNumber oa = ItemPointerGetOffsetNumber(&ha->t_self);
 
1294
        BlockNumber bb = ItemPointerGetBlockNumber(&hb->t_self);
 
1295
        OffsetNumber ob = ItemPointerGetOffsetNumber(&hb->t_self);
 
1296
 
 
1297
        if (ba < bb)
 
1298
                return -1;
 
1299
        if (ba > bb)
 
1300
                return 1;
 
1301
        if (oa < ob)
 
1302
                return -1;
 
1303
        if (oa > ob)
 
1304
                return 1;
 
1305
        return 0;
 
1306
}
 
1307
 
 
1308
 
 
1309
/*
 
1310
 * acquire_inherited_sample_rows -- acquire sample rows from inheritance tree
 
1311
 *
 
1312
 * This has the same API as acquire_sample_rows, except that rows are
 
1313
 * collected from all inheritance children as well as the specified table.
 
1314
 * We fail and return zero if there are no inheritance children, or if all
 
1315
 * children are foreign tables that don't support ANALYZE.
 
1316
 */
 
1317
static int
 
1318
acquire_inherited_sample_rows(Relation onerel, int elevel,
 
1319
                                                          HeapTuple *rows, int targrows,
 
1320
                                                          double *totalrows, double *totaldeadrows)
 
1321
{
 
1322
        List       *tableOIDs;
 
1323
        Relation   *rels;
 
1324
        AcquireSampleRowsFunc *acquirefuncs;
 
1325
        double     *relblocks;
 
1326
        double          totalblocks;
 
1327
        int                     numrows,
 
1328
                                nrels,
 
1329
                                i;
 
1330
        ListCell   *lc;
 
1331
        bool            has_child;
 
1332
 
 
1333
        /*
 
1334
         * Find all members of inheritance set.  We only need AccessShareLock on
 
1335
         * the children.
 
1336
         */
 
1337
        tableOIDs =
 
1338
                find_all_inheritors(RelationGetRelid(onerel), AccessShareLock, NULL);
 
1339
 
 
1340
        /*
 
1341
         * Check that there's at least one descendant, else fail.  This could
 
1342
         * happen despite analyze_rel's relhassubclass check, if table once had a
 
1343
         * child but no longer does.  In that case, we can clear the
 
1344
         * relhassubclass field so as not to make the same mistake again later.
 
1345
         * (This is safe because we hold ShareUpdateExclusiveLock.)
 
1346
         */
 
1347
        if (list_length(tableOIDs) < 2)
 
1348
        {
 
1349
                /* CCI because we already updated the pg_class row in this command */
 
1350
                CommandCounterIncrement();
 
1351
                SetRelationHasSubclass(RelationGetRelid(onerel), false);
 
1352
                ereport(elevel,
 
1353
                                (errmsg("skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no child tables",
 
1354
                                                get_namespace_name(RelationGetNamespace(onerel)),
 
1355
                                                RelationGetRelationName(onerel))));
 
1356
                return 0;
 
1357
        }
 
1358
 
 
1359
        /*
 
1360
         * Identify acquirefuncs to use, and count blocks in all the relations.
 
1361
         * The result could overflow BlockNumber, so we use double arithmetic.
 
1362
         */
 
1363
        rels = (Relation *) palloc(list_length(tableOIDs) * sizeof(Relation));
 
1364
        acquirefuncs = (AcquireSampleRowsFunc *)
 
1365
                palloc(list_length(tableOIDs) * sizeof(AcquireSampleRowsFunc));
 
1366
        relblocks = (double *) palloc(list_length(tableOIDs) * sizeof(double));
 
1367
        totalblocks = 0;
 
1368
        nrels = 0;
 
1369
        has_child = false;
 
1370
        foreach(lc, tableOIDs)
 
1371
        {
 
1372
                Oid                     childOID = lfirst_oid(lc);
 
1373
                Relation        childrel;
 
1374
                AcquireSampleRowsFunc acquirefunc = NULL;
 
1375
                BlockNumber relpages = 0;
 
1376
 
 
1377
                /* We already got the needed lock */
 
1378
                childrel = heap_open(childOID, NoLock);
 
1379
 
 
1380
                /* Ignore if temp table of another backend */
 
1381
                if (RELATION_IS_OTHER_TEMP(childrel))
 
1382
                {
 
1383
                        /* ... but release the lock on it */
 
1384
                        Assert(childrel != onerel);
 
1385
                        heap_close(childrel, AccessShareLock);
 
1386
                        continue;
 
1387
                }
 
1388
 
 
1389
                /* Check table type (MATVIEW can't happen, but might as well allow) */
 
1390
                if (childrel->rd_rel->relkind == RELKIND_RELATION ||
 
1391
                        childrel->rd_rel->relkind == RELKIND_MATVIEW)
 
1392
                {
 
1393
                        /* Regular table, so use the regular row acquisition function */
 
1394
                        acquirefunc = acquire_sample_rows;
 
1395
                        relpages = RelationGetNumberOfBlocks(childrel);
 
1396
                }
 
1397
                else if (childrel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
 
1398
                {
 
1399
                        /*
 
1400
                         * For a foreign table, call the FDW's hook function to see
 
1401
                         * whether it supports analysis.
 
1402
                         */
 
1403
                        FdwRoutine *fdwroutine;
 
1404
                        bool            ok = false;
 
1405
 
 
1406
                        fdwroutine = GetFdwRoutineForRelation(childrel, false);
 
1407
 
 
1408
                        if (fdwroutine->AnalyzeForeignTable != NULL)
 
1409
                                ok = fdwroutine->AnalyzeForeignTable(childrel,
 
1410
                                                                                                         &acquirefunc,
 
1411
                                                                                                         &relpages);
 
1412
 
 
1413
                        if (!ok)
 
1414
                        {
 
1415
                                /* ignore, but release the lock on it */
 
1416
                                Assert(childrel != onerel);
 
1417
                                heap_close(childrel, AccessShareLock);
 
1418
                                continue;
 
1419
                        }
 
1420
                }
 
1421
                else
 
1422
                {
 
1423
                        /*
 
1424
                         * ignore, but release the lock on it.  don't try to unlock the
 
1425
                         * passed-in relation
 
1426
                         */
 
1427
                        Assert(childrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
 
1428
                        if (childrel != onerel)
 
1429
                                heap_close(childrel, AccessShareLock);
 
1430
                        else
 
1431
                                heap_close(childrel, NoLock);
 
1432
                        continue;
 
1433
                }
 
1434
 
 
1435
                /* OK, we'll process this child */
 
1436
                has_child = true;
 
1437
                rels[nrels] = childrel;
 
1438
                acquirefuncs[nrels] = acquirefunc;
 
1439
                relblocks[nrels] = (double) relpages;
 
1440
                totalblocks += (double) relpages;
 
1441
                nrels++;
 
1442
        }
 
1443
 
 
1444
        /*
 
1445
         * If we don't have at least one child table to consider, fail.  If the
 
1446
         * relation is a partitioned table, it's not counted as a child table.
 
1447
         */
 
1448
        if (!has_child)
 
1449
        {
 
1450
                ereport(elevel,
 
1451
                                (errmsg("skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no analyzable child tables",
 
1452
                                                get_namespace_name(RelationGetNamespace(onerel)),
 
1453
                                                RelationGetRelationName(onerel))));
 
1454
                return 0;
 
1455
        }
 
1456
 
 
1457
        /*
 
1458
         * Now sample rows from each relation, proportionally to its fraction of
 
1459
         * the total block count.  (This might be less than desirable if the child
 
1460
         * rels have radically different free-space percentages, but it's not
 
1461
         * clear that it's worth working harder.)
 
1462
         */
 
1463
        numrows = 0;
 
1464
        *totalrows = 0;
 
1465
        *totaldeadrows = 0;
 
1466
        for (i = 0; i < nrels; i++)
 
1467
        {
 
1468
                Relation        childrel = rels[i];
 
1469
                AcquireSampleRowsFunc acquirefunc = acquirefuncs[i];
 
1470
                double          childblocks = relblocks[i];
 
1471
 
 
1472
                if (childblocks > 0)
 
1473
                {
 
1474
                        int                     childtargrows;
 
1475
 
 
1476
                        childtargrows = (int) rint(targrows * childblocks / totalblocks);
 
1477
                        /* Make sure we don't overrun due to roundoff error */
 
1478
                        childtargrows = Min(childtargrows, targrows - numrows);
 
1479
                        if (childtargrows > 0)
 
1480
                        {
 
1481
                                int                     childrows;
 
1482
                                double          trows,
 
1483
                                                        tdrows;
 
1484
 
 
1485
                                /* Fetch a random sample of the child's rows */
 
1486
                                childrows = (*acquirefunc) (childrel, elevel,
 
1487
                                                                                        rows + numrows, childtargrows,
 
1488
                                                                                        &trows, &tdrows);
 
1489
 
 
1490
                                /* We may need to convert from child's rowtype to parent's */
 
1491
                                if (childrows > 0 &&
 
1492
                                        !equalTupleDescs(RelationGetDescr(childrel),
 
1493
                                                                         RelationGetDescr(onerel)))
 
1494
                                {
 
1495
                                        TupleConversionMap *map;
 
1496
 
 
1497
                                        map = convert_tuples_by_name(RelationGetDescr(childrel),
 
1498
                                                                                                 RelationGetDescr(onerel),
 
1499
                                                                                                 gettext_noop("could not convert row type"));
 
1500
                                        if (map != NULL)
 
1501
                                        {
 
1502
                                                int                     j;
 
1503
 
 
1504
                                                for (j = 0; j < childrows; j++)
 
1505
                                                {
 
1506
                                                        HeapTuple       newtup;
 
1507
 
 
1508
                                                        newtup = do_convert_tuple(rows[numrows + j], map);
 
1509
                                                        heap_freetuple(rows[numrows + j]);
 
1510
                                                        rows[numrows + j] = newtup;
 
1511
                                                }
 
1512
                                                free_conversion_map(map);
 
1513
                                        }
 
1514
                                }
 
1515
 
 
1516
                                /* And add to counts */
 
1517
                                numrows += childrows;
 
1518
                                *totalrows += trows;
 
1519
                                *totaldeadrows += tdrows;
 
1520
                        }
 
1521
                }
 
1522
 
 
1523
                /*
 
1524
                 * Note: we cannot release the child-table locks, since we may have
 
1525
                 * pointers to their TOAST tables in the sampled rows.
 
1526
                 */
 
1527
                heap_close(childrel, NoLock);
 
1528
        }
 
1529
 
 
1530
        return numrows;
 
1531
}
 
1532
 
 
1533
 
 
1534
/*
 
1535
 *      update_attstats() -- update attribute statistics for one relation
 
1536
 *
 
1537
 *              Statistics are stored in several places: the pg_class row for the
 
1538
 *              relation has stats about the whole relation, and there is a
 
1539
 *              pg_statistic row for each (non-system) attribute that has ever
 
1540
 *              been analyzed.  The pg_class values are updated by VACUUM, not here.
 
1541
 *
 
1542
 *              pg_statistic rows are just added or updated normally.  This means
 
1543
 *              that pg_statistic will probably contain some deleted rows at the
 
1544
 *              completion of a vacuum cycle, unless it happens to get vacuumed last.
 
1545
 *
 
1546
 *              To keep things simple, we punt for pg_statistic, and don't try
 
1547
 *              to compute or store rows for pg_statistic itself in pg_statistic.
 
1548
 *              This could possibly be made to work, but it's not worth the trouble.
 
1549
 *              Note analyze_rel() has seen to it that we won't come here when
 
1550
 *              vacuuming pg_statistic itself.
 
1551
 *
 
1552
 *              Note: there would be a race condition here if two backends could
 
1553
 *              ANALYZE the same table concurrently.  Presently, we lock that out
 
1554
 *              by taking a self-exclusive lock on the relation in analyze_rel().
 
1555
 */
 
1556
static void
 
1557
update_attstats(Oid relid, bool inh, int natts, VacAttrStats **vacattrstats)
 
1558
{
 
1559
        Relation        sd;
 
1560
        int                     attno;
 
1561
 
 
1562
        if (natts <= 0)
 
1563
                return;                                 /* nothing to do */
 
1564
 
 
1565
        sd = heap_open(StatisticRelationId, RowExclusiveLock);
 
1566
 
 
1567
        for (attno = 0; attno < natts; attno++)
 
1568
        {
 
1569
                VacAttrStats *stats = vacattrstats[attno];
 
1570
                HeapTuple       stup,
 
1571
                                        oldtup;
 
1572
                int                     i,
 
1573
                                        k,
 
1574
                                        n;
 
1575
                Datum           values[Natts_pg_statistic];
 
1576
                bool            nulls[Natts_pg_statistic];
 
1577
                bool            replaces[Natts_pg_statistic];
 
1578
 
 
1579
                /* Ignore attr if we weren't able to collect stats */
 
1580
                if (!stats->stats_valid)
 
1581
                        continue;
 
1582
 
 
1583
                /*
 
1584
                 * Construct a new pg_statistic tuple
 
1585
                 */
 
1586
                for (i = 0; i < Natts_pg_statistic; ++i)
 
1587
                {
 
1588
                        nulls[i] = false;
 
1589
                        replaces[i] = true;
 
1590
                }
 
1591
 
 
1592
                values[Anum_pg_statistic_starelid - 1] = ObjectIdGetDatum(relid);
 
1593
                values[Anum_pg_statistic_staattnum - 1] = Int16GetDatum(stats->attr->attnum);
 
1594
                values[Anum_pg_statistic_stainherit - 1] = BoolGetDatum(inh);
 
1595
                values[Anum_pg_statistic_stanullfrac - 1] = Float4GetDatum(stats->stanullfrac);
 
1596
                values[Anum_pg_statistic_stawidth - 1] = Int32GetDatum(stats->stawidth);
 
1597
                values[Anum_pg_statistic_stadistinct - 1] = Float4GetDatum(stats->stadistinct);
 
1598
                i = Anum_pg_statistic_stakind1 - 1;
 
1599
                for (k = 0; k < STATISTIC_NUM_SLOTS; k++)
 
1600
                {
 
1601
                        values[i++] = Int16GetDatum(stats->stakind[k]); /* stakindN */
 
1602
                }
 
1603
                i = Anum_pg_statistic_staop1 - 1;
 
1604
                for (k = 0; k < STATISTIC_NUM_SLOTS; k++)
 
1605
                {
 
1606
                        values[i++] = ObjectIdGetDatum(stats->staop[k]);        /* staopN */
 
1607
                }
 
1608
                i = Anum_pg_statistic_stanumbers1 - 1;
 
1609
                for (k = 0; k < STATISTIC_NUM_SLOTS; k++)
 
1610
                {
 
1611
                        int                     nnum = stats->numnumbers[k];
 
1612
 
 
1613
                        if (nnum > 0)
 
1614
                        {
 
1615
                                Datum      *numdatums = (Datum *) palloc(nnum * sizeof(Datum));
 
1616
                                ArrayType  *arry;
 
1617
 
 
1618
                                for (n = 0; n < nnum; n++)
 
1619
                                        numdatums[n] = Float4GetDatum(stats->stanumbers[k][n]);
 
1620
                                /* XXX knows more than it should about type float4: */
 
1621
                                arry = construct_array(numdatums, nnum,
 
1622
                                                                           FLOAT4OID,
 
1623
                                                                           sizeof(float4), FLOAT4PASSBYVAL, 'i');
 
1624
                                values[i++] = PointerGetDatum(arry);    /* stanumbersN */
 
1625
                        }
 
1626
                        else
 
1627
                        {
 
1628
                                nulls[i] = true;
 
1629
                                values[i++] = (Datum) 0;
 
1630
                        }
 
1631
                }
 
1632
                i = Anum_pg_statistic_stavalues1 - 1;
 
1633
                for (k = 0; k < STATISTIC_NUM_SLOTS; k++)
 
1634
                {
 
1635
                        if (stats->numvalues[k] > 0)
 
1636
                        {
 
1637
                                ArrayType  *arry;
 
1638
 
 
1639
                                arry = construct_array(stats->stavalues[k],
 
1640
                                                                           stats->numvalues[k],
 
1641
                                                                           stats->statypid[k],
 
1642
                                                                           stats->statyplen[k],
 
1643
                                                                           stats->statypbyval[k],
 
1644
                                                                           stats->statypalign[k]);
 
1645
                                values[i++] = PointerGetDatum(arry);    /* stavaluesN */
 
1646
                        }
 
1647
                        else
 
1648
                        {
 
1649
                                nulls[i] = true;
 
1650
                                values[i++] = (Datum) 0;
 
1651
                        }
 
1652
                }
 
1653
 
 
1654
                /* Is there already a pg_statistic tuple for this attribute? */
 
1655
                oldtup = SearchSysCache3(STATRELATTINH,
 
1656
                                                                 ObjectIdGetDatum(relid),
 
1657
                                                                 Int16GetDatum(stats->attr->attnum),
 
1658
                                                                 BoolGetDatum(inh));
 
1659
 
 
1660
                if (HeapTupleIsValid(oldtup))
 
1661
                {
 
1662
                        /* Yes, replace it */
 
1663
                        stup = heap_modify_tuple(oldtup,
 
1664
                                                                         RelationGetDescr(sd),
 
1665
                                                                         values,
 
1666
                                                                         nulls,
 
1667
                                                                         replaces);
 
1668
                        ReleaseSysCache(oldtup);
 
1669
                        CatalogTupleUpdate(sd, &stup->t_self, stup);
 
1670
                }
 
1671
                else
 
1672
                {
 
1673
                        /* No, insert new tuple */
 
1674
                        stup = heap_form_tuple(RelationGetDescr(sd), values, nulls);
 
1675
                        CatalogTupleInsert(sd, stup);
 
1676
                }
 
1677
 
 
1678
                heap_freetuple(stup);
 
1679
        }
 
1680
 
 
1681
        heap_close(sd, RowExclusiveLock);
 
1682
}
 
1683
 
 
1684
/*
 
1685
 * Standard fetch function for use by compute_stats subroutines.
 
1686
 *
 
1687
 * This exists to provide some insulation between compute_stats routines
 
1688
 * and the actual storage of the sample data.
 
1689
 */
 
1690
static Datum
 
1691
std_fetch_func(VacAttrStatsP stats, int rownum, bool *isNull)
 
1692
{
 
1693
        int                     attnum = stats->tupattnum;
 
1694
        HeapTuple       tuple = stats->rows[rownum];
 
1695
        TupleDesc       tupDesc = stats->tupDesc;
 
1696
 
 
1697
        return heap_getattr(tuple, attnum, tupDesc, isNull);
 
1698
}
 
1699
 
 
1700
/*
 
1701
 * Fetch function for analyzing index expressions.
 
1702
 *
 
1703
 * We have not bothered to construct index tuples, instead the data is
 
1704
 * just in Datum arrays.
 
1705
 */
 
1706
static Datum
 
1707
ind_fetch_func(VacAttrStatsP stats, int rownum, bool *isNull)
 
1708
{
 
1709
        int                     i;
 
1710
 
 
1711
        /* exprvals and exprnulls are already offset for proper column */
 
1712
        i = rownum * stats->rowstride;
 
1713
        *isNull = stats->exprnulls[i];
 
1714
        return stats->exprvals[i];
 
1715
}
 
1716
 
 
1717
 
 
1718
/*==========================================================================
 
1719
 *
 
1720
 * Code below this point represents the "standard" type-specific statistics
 
1721
 * analysis algorithms.  This code can be replaced on a per-data-type basis
 
1722
 * by setting a nonzero value in pg_type.typanalyze.
 
1723
 *
 
1724
 *==========================================================================
 
1725
 */
 
1726
 
 
1727
 
 
1728
/*
 
1729
 * To avoid consuming too much memory during analysis and/or too much space
 
1730
 * in the resulting pg_statistic rows, we ignore varlena datums that are wider
 
1731
 * than WIDTH_THRESHOLD (after detoasting!).  This is legitimate for MCV
 
1732
 * and distinct-value calculations since a wide value is unlikely to be
 
1733
 * duplicated at all, much less be a most-common value.  For the same reason,
 
1734
 * ignoring wide values will not affect our estimates of histogram bin
 
1735
 * boundaries very much.
 
1736
 */
 
1737
#define WIDTH_THRESHOLD  1024
 
1738
 
 
1739
#define swapInt(a,b)    do {int _tmp; _tmp=a; a=b; b=_tmp;} while(0)
 
1740
#define swapDatum(a,b)  do {Datum _tmp; _tmp=a; a=b; b=_tmp;} while(0)
 
1741
 
 
1742
/*
 
1743
 * Extra information used by the default analysis routines
 
1744
 */
 
1745
typedef struct
 
1746
{
 
1747
        int                     count;                  /* # of duplicates */
 
1748
        int                     first;                  /* values[] index of first occurrence */
 
1749
} ScalarMCVItem;
 
1750
 
 
1751
typedef struct
 
1752
{
 
1753
        SortSupport ssup;
 
1754
        int                *tupnoLink;
 
1755
} CompareScalarsContext;
 
1756
 
 
1757
 
 
1758
static void compute_trivial_stats(VacAttrStatsP stats,
 
1759
                                          AnalyzeAttrFetchFunc fetchfunc,
 
1760
                                          int samplerows,
 
1761
                                          double totalrows);
 
1762
static void compute_distinct_stats(VacAttrStatsP stats,
 
1763
                                           AnalyzeAttrFetchFunc fetchfunc,
 
1764
                                           int samplerows,
 
1765
                                           double totalrows);
 
1766
static void compute_scalar_stats(VacAttrStatsP stats,
 
1767
                                         AnalyzeAttrFetchFunc fetchfunc,
 
1768
                                         int samplerows,
 
1769
                                         double totalrows);
 
1770
static int      compare_scalars(const void *a, const void *b, void *arg);
 
1771
static int      compare_mcvs(const void *a, const void *b);
 
1772
static int analyze_mcv_list(int *mcv_counts,
 
1773
                                 int num_mcv,
 
1774
                                 double stadistinct,
 
1775
                                 double stanullfrac,
 
1776
                                 int samplerows,
 
1777
                                 double totalrows);
 
1778
 
 
1779
 
 
1780
/*
 
1781
 * std_typanalyze -- the default type-specific typanalyze function
 
1782
 */
 
1783
bool
 
1784
std_typanalyze(VacAttrStats *stats)
 
1785
{
 
1786
        Form_pg_attribute attr = stats->attr;
 
1787
        Oid                     ltopr;
 
1788
        Oid                     eqopr;
 
1789
        StdAnalyzeData *mystats;
 
1790
 
 
1791
        /* If the attstattarget column is negative, use the default value */
 
1792
        /* NB: it is okay to scribble on stats->attr since it's a copy */
 
1793
        if (attr->attstattarget < 0)
 
1794
                attr->attstattarget = default_statistics_target;
 
1795
 
 
1796
        /* Look for default "<" and "=" operators for column's type */
 
1797
        get_sort_group_operators(stats->attrtypid,
 
1798
                                                         false, false, false,
 
1799
                                                         &ltopr, &eqopr, NULL,
 
1800
                                                         NULL);
 
1801
 
 
1802
        /* Save the operator info for compute_stats routines */
 
1803
        mystats = (StdAnalyzeData *) palloc(sizeof(StdAnalyzeData));
 
1804
        mystats->eqopr = eqopr;
 
1805
        mystats->eqfunc = OidIsValid(eqopr) ? get_opcode(eqopr) : InvalidOid;
 
1806
        mystats->ltopr = ltopr;
 
1807
        stats->extra_data = mystats;
 
1808
 
 
1809
        /*
 
1810
         * Determine which standard statistics algorithm to use
 
1811
         */
 
1812
        if (OidIsValid(eqopr) && OidIsValid(ltopr))
 
1813
        {
 
1814
                /* Seems to be a scalar datatype */
 
1815
                stats->compute_stats = compute_scalar_stats;
 
1816
                /*--------------------
 
1817
                 * The following choice of minrows is based on the paper
 
1818
                 * "Random sampling for histogram construction: how much is enough?"
 
1819
                 * by Surajit Chaudhuri, Rajeev Motwani and Vivek Narasayya, in
 
1820
                 * Proceedings of ACM SIGMOD International Conference on Management
 
1821
                 * of Data, 1998, Pages 436-447.  Their Corollary 1 to Theorem 5
 
1822
                 * says that for table size n, histogram size k, maximum relative
 
1823
                 * error in bin size f, and error probability gamma, the minimum
 
1824
                 * random sample size is
 
1825
                 *              r = 4 * k * ln(2*n/gamma) / f^2
 
1826
                 * Taking f = 0.5, gamma = 0.01, n = 10^6 rows, we obtain
 
1827
                 *              r = 305.82 * k
 
1828
                 * Note that because of the log function, the dependence on n is
 
1829
                 * quite weak; even at n = 10^12, a 300*k sample gives <= 0.66
 
1830
                 * bin size error with probability 0.99.  So there's no real need to
 
1831
                 * scale for n, which is a good thing because we don't necessarily
 
1832
                 * know it at this point.
 
1833
                 *--------------------
 
1834
                 */
 
1835
                stats->minrows = 300 * attr->attstattarget;
 
1836
        }
 
1837
        else if (OidIsValid(eqopr))
 
1838
        {
 
1839
                /* We can still recognize distinct values */
 
1840
                stats->compute_stats = compute_distinct_stats;
 
1841
                /* Might as well use the same minrows as above */
 
1842
                stats->minrows = 300 * attr->attstattarget;
 
1843
        }
 
1844
        else
 
1845
        {
 
1846
                /* Can't do much but the trivial stuff */
 
1847
                stats->compute_stats = compute_trivial_stats;
 
1848
                /* Might as well use the same minrows as above */
 
1849
                stats->minrows = 300 * attr->attstattarget;
 
1850
        }
 
1851
 
 
1852
        return true;
 
1853
}
 
1854
 
 
1855
 
 
1856
/*
 
1857
 *      compute_trivial_stats() -- compute very basic column statistics
 
1858
 *
 
1859
 *      We use this when we cannot find a hash "=" operator for the datatype.
 
1860
 *
 
1861
 *      We determine the fraction of non-null rows and the average datum width.
 
1862
 */
 
1863
static void
 
1864
compute_trivial_stats(VacAttrStatsP stats,
 
1865
                                          AnalyzeAttrFetchFunc fetchfunc,
 
1866
                                          int samplerows,
 
1867
                                          double totalrows)
 
1868
{
 
1869
        int                     i;
 
1870
        int                     null_cnt = 0;
 
1871
        int                     nonnull_cnt = 0;
 
1872
        double          total_width = 0;
 
1873
        bool            is_varlena = (!stats->attrtype->typbyval &&
 
1874
                                                          stats->attrtype->typlen == -1);
 
1875
        bool            is_varwidth = (!stats->attrtype->typbyval &&
 
1876
                                                           stats->attrtype->typlen < 0);
 
1877
 
 
1878
        for (i = 0; i < samplerows; i++)
 
1879
        {
 
1880
                Datum           value;
 
1881
                bool            isnull;
 
1882
 
 
1883
                vacuum_delay_point();
 
1884
 
 
1885
                value = fetchfunc(stats, i, &isnull);
 
1886
 
 
1887
                /* Check for null/nonnull */
 
1888
                if (isnull)
 
1889
                {
 
1890
                        null_cnt++;
 
1891
                        continue;
 
1892
                }
 
1893
                nonnull_cnt++;
 
1894
 
 
1895
                /*
 
1896
                 * If it's a variable-width field, add up widths for average width
 
1897
                 * calculation.  Note that if the value is toasted, we use the toasted
 
1898
                 * width.  We don't bother with this calculation if it's a fixed-width
 
1899
                 * type.
 
1900
                 */
 
1901
                if (is_varlena)
 
1902
                {
 
1903
                        total_width += VARSIZE_ANY(DatumGetPointer(value));
 
1904
                }
 
1905
                else if (is_varwidth)
 
1906
                {
 
1907
                        /* must be cstring */
 
1908
                        total_width += strlen(DatumGetCString(value)) + 1;
 
1909
                }
 
1910
        }
 
1911
 
 
1912
        /* We can only compute average width if we found some non-null values. */
 
1913
        if (nonnull_cnt > 0)
 
1914
        {
 
1915
                stats->stats_valid = true;
 
1916
                /* Do the simple null-frac and width stats */
 
1917
                stats->stanullfrac = (double) null_cnt / (double) samplerows;
 
1918
                if (is_varwidth)
 
1919
                        stats->stawidth = total_width / (double) nonnull_cnt;
 
1920
                else
 
1921
                        stats->stawidth = stats->attrtype->typlen;
 
1922
                stats->stadistinct = 0.0;       /* "unknown" */
 
1923
        }
 
1924
        else if (null_cnt > 0)
 
1925
        {
 
1926
                /* We found only nulls; assume the column is entirely null */
 
1927
                stats->stats_valid = true;
 
1928
                stats->stanullfrac = 1.0;
 
1929
                if (is_varwidth)
 
1930
                        stats->stawidth = 0;    /* "unknown" */
 
1931
                else
 
1932
                        stats->stawidth = stats->attrtype->typlen;
 
1933
                stats->stadistinct = 0.0;       /* "unknown" */
 
1934
        }
 
1935
}
 
1936
 
 
1937
 
 
1938
/*
 
1939
 *      compute_distinct_stats() -- compute column statistics including ndistinct
 
1940
 *
 
1941
 *      We use this when we can find only an "=" operator for the datatype.
 
1942
 *
 
1943
 *      We determine the fraction of non-null rows, the average width, the
 
1944
 *      most common values, and the (estimated) number of distinct values.
 
1945
 *
 
1946
 *      The most common values are determined by brute force: we keep a list
 
1947
 *      of previously seen values, ordered by number of times seen, as we scan
 
1948
 *      the samples.  A newly seen value is inserted just after the last
 
1949
 *      multiply-seen value, causing the bottommost (oldest) singly-seen value
 
1950
 *      to drop off the list.  The accuracy of this method, and also its cost,
 
1951
 *      depend mainly on the length of the list we are willing to keep.
 
1952
 */
 
1953
static void
 
1954
compute_distinct_stats(VacAttrStatsP stats,
 
1955
                                           AnalyzeAttrFetchFunc fetchfunc,
 
1956
                                           int samplerows,
 
1957
                                           double totalrows)
 
1958
{
 
1959
        int                     i;
 
1960
        int                     null_cnt = 0;
 
1961
        int                     nonnull_cnt = 0;
 
1962
        int                     toowide_cnt = 0;
 
1963
        double          total_width = 0;
 
1964
        bool            is_varlena = (!stats->attrtype->typbyval &&
 
1965
                                                          stats->attrtype->typlen == -1);
 
1966
        bool            is_varwidth = (!stats->attrtype->typbyval &&
 
1967
                                                           stats->attrtype->typlen < 0);
 
1968
        FmgrInfo        f_cmpeq;
 
1969
        typedef struct
 
1970
        {
 
1971
                Datum           value;
 
1972
                int                     count;
 
1973
        } TrackItem;
 
1974
        TrackItem  *track;
 
1975
        int                     track_cnt,
 
1976
                                track_max;
 
1977
        int                     num_mcv = stats->attr->attstattarget;
 
1978
        StdAnalyzeData *mystats = (StdAnalyzeData *) stats->extra_data;
 
1979
 
 
1980
        /*
 
1981
         * We track up to 2*n values for an n-element MCV list; but at least 10
 
1982
         */
 
1983
        track_max = 2 * num_mcv;
 
1984
        if (track_max < 10)
 
1985
                track_max = 10;
 
1986
        track = (TrackItem *) palloc(track_max * sizeof(TrackItem));
 
1987
        track_cnt = 0;
 
1988
 
 
1989
        fmgr_info(mystats->eqfunc, &f_cmpeq);
 
1990
 
 
1991
        for (i = 0; i < samplerows; i++)
 
1992
        {
 
1993
                Datum           value;
 
1994
                bool            isnull;
 
1995
                bool            match;
 
1996
                int                     firstcount1,
 
1997
                                        j;
 
1998
 
 
1999
                vacuum_delay_point();
 
2000
 
 
2001
                value = fetchfunc(stats, i, &isnull);
 
2002
 
 
2003
                /* Check for null/nonnull */
 
2004
                if (isnull)
 
2005
                {
 
2006
                        null_cnt++;
 
2007
                        continue;
 
2008
                }
 
2009
                nonnull_cnt++;
 
2010
 
 
2011
                /*
 
2012
                 * If it's a variable-width field, add up widths for average width
 
2013
                 * calculation.  Note that if the value is toasted, we use the toasted
 
2014
                 * width.  We don't bother with this calculation if it's a fixed-width
 
2015
                 * type.
 
2016
                 */
 
2017
                if (is_varlena)
 
2018
                {
 
2019
                        total_width += VARSIZE_ANY(DatumGetPointer(value));
 
2020
 
 
2021
                        /*
 
2022
                         * If the value is toasted, we want to detoast it just once to
 
2023
                         * avoid repeated detoastings and resultant excess memory usage
 
2024
                         * during the comparisons.  Also, check to see if the value is
 
2025
                         * excessively wide, and if so don't detoast at all --- just
 
2026
                         * ignore the value.
 
2027
                         */
 
2028
                        if (toast_raw_datum_size(value) > WIDTH_THRESHOLD)
 
2029
                        {
 
2030
                                toowide_cnt++;
 
2031
                                continue;
 
2032
                        }
 
2033
                        value = PointerGetDatum(PG_DETOAST_DATUM(value));
 
2034
                }
 
2035
                else if (is_varwidth)
 
2036
                {
 
2037
                        /* must be cstring */
 
2038
                        total_width += strlen(DatumGetCString(value)) + 1;
 
2039
                }
 
2040
 
 
2041
                /*
 
2042
                 * See if the value matches anything we're already tracking.
 
2043
                 */
 
2044
                match = false;
 
2045
                firstcount1 = track_cnt;
 
2046
                for (j = 0; j < track_cnt; j++)
 
2047
                {
 
2048
                        /* We always use the default collation for statistics */
 
2049
                        if (DatumGetBool(FunctionCall2Coll(&f_cmpeq,
 
2050
                                                                                           DEFAULT_COLLATION_OID,
 
2051
                                                                                           value, track[j].value)))
 
2052
                        {
 
2053
                                match = true;
 
2054
                                break;
 
2055
                        }
 
2056
                        if (j < firstcount1 && track[j].count == 1)
 
2057
                                firstcount1 = j;
 
2058
                }
 
2059
 
 
2060
                if (match)
 
2061
                {
 
2062
                        /* Found a match */
 
2063
                        track[j].count++;
 
2064
                        /* This value may now need to "bubble up" in the track list */
 
2065
                        while (j > 0 && track[j].count > track[j - 1].count)
 
2066
                        {
 
2067
                                swapDatum(track[j].value, track[j - 1].value);
 
2068
                                swapInt(track[j].count, track[j - 1].count);
 
2069
                                j--;
 
2070
                        }
 
2071
                }
 
2072
                else
 
2073
                {
 
2074
                        /* No match.  Insert at head of count-1 list */
 
2075
                        if (track_cnt < track_max)
 
2076
                                track_cnt++;
 
2077
                        for (j = track_cnt - 1; j > firstcount1; j--)
 
2078
                        {
 
2079
                                track[j].value = track[j - 1].value;
 
2080
                                track[j].count = track[j - 1].count;
 
2081
                        }
 
2082
                        if (firstcount1 < track_cnt)
 
2083
                        {
 
2084
                                track[firstcount1].value = value;
 
2085
                                track[firstcount1].count = 1;
 
2086
                        }
 
2087
                }
 
2088
        }
 
2089
 
 
2090
        /* We can only compute real stats if we found some non-null values. */
 
2091
        if (nonnull_cnt > 0)
 
2092
        {
 
2093
                int                     nmultiple,
 
2094
                                        summultiple;
 
2095
 
 
2096
                stats->stats_valid = true;
 
2097
                /* Do the simple null-frac and width stats */
 
2098
                stats->stanullfrac = (double) null_cnt / (double) samplerows;
 
2099
                if (is_varwidth)
 
2100
                        stats->stawidth = total_width / (double) nonnull_cnt;
 
2101
                else
 
2102
                        stats->stawidth = stats->attrtype->typlen;
 
2103
 
 
2104
                /* Count the number of values we found multiple times */
 
2105
                summultiple = 0;
 
2106
                for (nmultiple = 0; nmultiple < track_cnt; nmultiple++)
 
2107
                {
 
2108
                        if (track[nmultiple].count == 1)
 
2109
                                break;
 
2110
                        summultiple += track[nmultiple].count;
 
2111
                }
 
2112
 
 
2113
                if (nmultiple == 0)
 
2114
                {
 
2115
                        /*
 
2116
                         * If we found no repeated non-null values, assume it's a unique
 
2117
                         * column; but be sure to discount for any nulls we found.
 
2118
                         */
 
2119
                        stats->stadistinct = -1.0 * (1.0 - stats->stanullfrac);
 
2120
                }
 
2121
                else if (track_cnt < track_max && toowide_cnt == 0 &&
 
2122
                                 nmultiple == track_cnt)
 
2123
                {
 
2124
                        /*
 
2125
                         * Our track list includes every value in the sample, and every
 
2126
                         * value appeared more than once.  Assume the column has just
 
2127
                         * these values.  (This case is meant to address columns with
 
2128
                         * small, fixed sets of possible values, such as boolean or enum
 
2129
                         * columns.  If there are any values that appear just once in the
 
2130
                         * sample, including too-wide values, we should assume that that's
 
2131
                         * not what we're dealing with.)
 
2132
                         */
 
2133
                        stats->stadistinct = track_cnt;
 
2134
                }
 
2135
                else
 
2136
                {
 
2137
                        /*----------
 
2138
                         * Estimate the number of distinct values using the estimator
 
2139
                         * proposed by Haas and Stokes in IBM Research Report RJ 10025:
 
2140
                         *              n*d / (n - f1 + f1*n/N)
 
2141
                         * where f1 is the number of distinct values that occurred
 
2142
                         * exactly once in our sample of n rows (from a total of N),
 
2143
                         * and d is the total number of distinct values in the sample.
 
2144
                         * This is their Duj1 estimator; the other estimators they
 
2145
                         * recommend are considerably more complex, and are numerically
 
2146
                         * very unstable when n is much smaller than N.
 
2147
                         *
 
2148
                         * In this calculation, we consider only non-nulls.  We used to
 
2149
                         * include rows with null values in the n and N counts, but that
 
2150
                         * leads to inaccurate answers in columns with many nulls, and
 
2151
                         * it's intuitively bogus anyway considering the desired result is
 
2152
                         * the number of distinct non-null values.
 
2153
                         *
 
2154
                         * We assume (not very reliably!) that all the multiply-occurring
 
2155
                         * values are reflected in the final track[] list, and the other
 
2156
                         * nonnull values all appeared but once.  (XXX this usually
 
2157
                         * results in a drastic overestimate of ndistinct.  Can we do
 
2158
                         * any better?)
 
2159
                         *----------
 
2160
                         */
 
2161
                        int                     f1 = nonnull_cnt - summultiple;
 
2162
                        int                     d = f1 + nmultiple;
 
2163
                        double          n = samplerows - null_cnt;
 
2164
                        double          N = totalrows * (1.0 - stats->stanullfrac);
 
2165
                        double          stadistinct;
 
2166
 
 
2167
                        /* N == 0 shouldn't happen, but just in case ... */
 
2168
                        if (N > 0)
 
2169
                                stadistinct = (n * d) / ((n - f1) + f1 * n / N);
 
2170
                        else
 
2171
                                stadistinct = 0;
 
2172
 
 
2173
                        /* Clamp to sane range in case of roundoff error */
 
2174
                        if (stadistinct < d)
 
2175
                                stadistinct = d;
 
2176
                        if (stadistinct > N)
 
2177
                                stadistinct = N;
 
2178
                        /* And round to integer */
 
2179
                        stats->stadistinct = floor(stadistinct + 0.5);
 
2180
                }
 
2181
 
 
2182
                /*
 
2183
                 * If we estimated the number of distinct values at more than 10% of
 
2184
                 * the total row count (a very arbitrary limit), then assume that
 
2185
                 * stadistinct should scale with the row count rather than be a fixed
 
2186
                 * value.
 
2187
                 */
 
2188
                if (stats->stadistinct > 0.1 * totalrows)
 
2189
                        stats->stadistinct = -(stats->stadistinct / totalrows);
 
2190
 
 
2191
                /*
 
2192
                 * Decide how many values are worth storing as most-common values. If
 
2193
                 * we are able to generate a complete MCV list (all the values in the
 
2194
                 * sample will fit, and we think these are all the ones in the table),
 
2195
                 * then do so.  Otherwise, store only those values that are
 
2196
                 * significantly more common than the values not in the list.
 
2197
                 *
 
2198
                 * Note: the first of these cases is meant to address columns with
 
2199
                 * small, fixed sets of possible values, such as boolean or enum
 
2200
                 * columns.  If we can *completely* represent the column population by
 
2201
                 * an MCV list that will fit into the stats target, then we should do
 
2202
                 * so and thus provide the planner with complete information.  But if
 
2203
                 * the MCV list is not complete, it's generally worth being more
 
2204
                 * selective, and not just filling it all the way up to the stats
 
2205
                 * target.
 
2206
                 */
 
2207
                if (track_cnt < track_max && toowide_cnt == 0 &&
 
2208
                        stats->stadistinct > 0 &&
 
2209
                        track_cnt <= num_mcv)
 
2210
                {
 
2211
                        /* Track list includes all values seen, and all will fit */
 
2212
                        num_mcv = track_cnt;
 
2213
                }
 
2214
                else
 
2215
                {
 
2216
                        int                *mcv_counts;
 
2217
 
 
2218
                        /* Incomplete list; decide how many values are worth keeping */
 
2219
                        if (num_mcv > track_cnt)
 
2220
                                num_mcv = track_cnt;
 
2221
 
 
2222
                        if (num_mcv > 0)
 
2223
                        {
 
2224
                                mcv_counts = (int *) palloc(num_mcv * sizeof(int));
 
2225
                                for (i = 0; i < num_mcv; i++)
 
2226
                                        mcv_counts[i] = track[i].count;
 
2227
 
 
2228
                                num_mcv = analyze_mcv_list(mcv_counts, num_mcv,
 
2229
                                                                                   stats->stadistinct,
 
2230
                                                                                   stats->stanullfrac,
 
2231
                                                                                   samplerows, totalrows);
 
2232
                        }
 
2233
                }
 
2234
 
 
2235
                /* Generate MCV slot entry */
 
2236
                if (num_mcv > 0)
 
2237
                {
 
2238
                        MemoryContext old_context;
 
2239
                        Datum      *mcv_values;
 
2240
                        float4     *mcv_freqs;
 
2241
 
 
2242
                        /* Must copy the target values into anl_context */
 
2243
                        old_context = MemoryContextSwitchTo(stats->anl_context);
 
2244
                        mcv_values = (Datum *) palloc(num_mcv * sizeof(Datum));
 
2245
                        mcv_freqs = (float4 *) palloc(num_mcv * sizeof(float4));
 
2246
                        for (i = 0; i < num_mcv; i++)
 
2247
                        {
 
2248
                                mcv_values[i] = datumCopy(track[i].value,
 
2249
                                                                                  stats->attrtype->typbyval,
 
2250
                                                                                  stats->attrtype->typlen);
 
2251
                                mcv_freqs[i] = (double) track[i].count / (double) samplerows;
 
2252
                        }
 
2253
                        MemoryContextSwitchTo(old_context);
 
2254
 
 
2255
                        stats->stakind[0] = STATISTIC_KIND_MCV;
 
2256
                        stats->staop[0] = mystats->eqopr;
 
2257
                        stats->stanumbers[0] = mcv_freqs;
 
2258
                        stats->numnumbers[0] = num_mcv;
 
2259
                        stats->stavalues[0] = mcv_values;
 
2260
                        stats->numvalues[0] = num_mcv;
 
2261
 
 
2262
                        /*
 
2263
                         * Accept the defaults for stats->statypid and others. They have
 
2264
                         * been set before we were called (see vacuum.h)
 
2265
                         */
 
2266
                }
 
2267
        }
 
2268
        else if (null_cnt > 0)
 
2269
        {
 
2270
                /* We found only nulls; assume the column is entirely null */
 
2271
                stats->stats_valid = true;
 
2272
                stats->stanullfrac = 1.0;
 
2273
                if (is_varwidth)
 
2274
                        stats->stawidth = 0;    /* "unknown" */
 
2275
                else
 
2276
                        stats->stawidth = stats->attrtype->typlen;
 
2277
                stats->stadistinct = 0.0;       /* "unknown" */
 
2278
        }
 
2279
 
 
2280
        /* We don't need to bother cleaning up any of our temporary palloc's */
 
2281
}
 
2282
 
 
2283
 
 
2284
/*
 
2285
 *      compute_scalar_stats() -- compute column statistics
 
2286
 *
 
2287
 *      We use this when we can find "=" and "<" operators for the datatype.
 
2288
 *
 
2289
 *      We determine the fraction of non-null rows, the average width, the
 
2290
 *      most common values, the (estimated) number of distinct values, the
 
2291
 *      distribution histogram, and the correlation of physical to logical order.
 
2292
 *
 
2293
 *      The desired stats can be determined fairly easily after sorting the
 
2294
 *      data values into order.
 
2295
 */
 
2296
static void
 
2297
compute_scalar_stats(VacAttrStatsP stats,
 
2298
                                         AnalyzeAttrFetchFunc fetchfunc,
 
2299
                                         int samplerows,
 
2300
                                         double totalrows)
 
2301
{
 
2302
        int                     i;
 
2303
        int                     null_cnt = 0;
 
2304
        int                     nonnull_cnt = 0;
 
2305
        int                     toowide_cnt = 0;
 
2306
        double          total_width = 0;
 
2307
        bool            is_varlena = (!stats->attrtype->typbyval &&
 
2308
                                                          stats->attrtype->typlen == -1);
 
2309
        bool            is_varwidth = (!stats->attrtype->typbyval &&
 
2310
                                                           stats->attrtype->typlen < 0);
 
2311
        double          corr_xysum;
 
2312
        SortSupportData ssup;
 
2313
        ScalarItem *values;
 
2314
        int                     values_cnt = 0;
 
2315
        int                *tupnoLink;
 
2316
        ScalarMCVItem *track;
 
2317
        int                     track_cnt = 0;
 
2318
        int                     num_mcv = stats->attr->attstattarget;
 
2319
        int                     num_bins = stats->attr->attstattarget;
 
2320
        StdAnalyzeData *mystats = (StdAnalyzeData *) stats->extra_data;
 
2321
 
 
2322
        values = (ScalarItem *) palloc(samplerows * sizeof(ScalarItem));
 
2323
        tupnoLink = (int *) palloc(samplerows * sizeof(int));
 
2324
        track = (ScalarMCVItem *) palloc(num_mcv * sizeof(ScalarMCVItem));
 
2325
 
 
2326
        memset(&ssup, 0, sizeof(ssup));
 
2327
        ssup.ssup_cxt = CurrentMemoryContext;
 
2328
        /* We always use the default collation for statistics */
 
2329
        ssup.ssup_collation = DEFAULT_COLLATION_OID;
 
2330
        ssup.ssup_nulls_first = false;
 
2331
 
 
2332
        /*
 
2333
         * For now, don't perform abbreviated key conversion, because full values
 
2334
         * are required for MCV slot generation.  Supporting that optimization
 
2335
         * would necessitate teaching compare_scalars() to call a tie-breaker.
 
2336
         */
 
2337
        ssup.abbreviate = false;
 
2338
 
 
2339
        PrepareSortSupportFromOrderingOp(mystats->ltopr, &ssup);
 
2340
 
 
2341
        /* Initial scan to find sortable values */
 
2342
        for (i = 0; i < samplerows; i++)
 
2343
        {
 
2344
                Datum           value;
 
2345
                bool            isnull;
 
2346
 
 
2347
                vacuum_delay_point();
 
2348
 
 
2349
                value = fetchfunc(stats, i, &isnull);
 
2350
 
 
2351
                /* Check for null/nonnull */
 
2352
                if (isnull)
 
2353
                {
 
2354
                        null_cnt++;
 
2355
                        continue;
 
2356
                }
 
2357
                nonnull_cnt++;
 
2358
 
 
2359
                /*
 
2360
                 * If it's a variable-width field, add up widths for average width
 
2361
                 * calculation.  Note that if the value is toasted, we use the toasted
 
2362
                 * width.  We don't bother with this calculation if it's a fixed-width
 
2363
                 * type.
 
2364
                 */
 
2365
                if (is_varlena)
 
2366
                {
 
2367
                        total_width += VARSIZE_ANY(DatumGetPointer(value));
 
2368
 
 
2369
                        /*
 
2370
                         * If the value is toasted, we want to detoast it just once to
 
2371
                         * avoid repeated detoastings and resultant excess memory usage
 
2372
                         * during the comparisons.  Also, check to see if the value is
 
2373
                         * excessively wide, and if so don't detoast at all --- just
 
2374
                         * ignore the value.
 
2375
                         */
 
2376
                        if (toast_raw_datum_size(value) > WIDTH_THRESHOLD)
 
2377
                        {
 
2378
                                toowide_cnt++;
 
2379
                                continue;
 
2380
                        }
 
2381
                        value = PointerGetDatum(PG_DETOAST_DATUM(value));
 
2382
                }
 
2383
                else if (is_varwidth)
 
2384
                {
 
2385
                        /* must be cstring */
 
2386
                        total_width += strlen(DatumGetCString(value)) + 1;
 
2387
                }
 
2388
 
 
2389
                /* Add it to the list to be sorted */
 
2390
                values[values_cnt].value = value;
 
2391
                values[values_cnt].tupno = values_cnt;
 
2392
                tupnoLink[values_cnt] = values_cnt;
 
2393
                values_cnt++;
 
2394
        }
 
2395
 
 
2396
        /* We can only compute real stats if we found some sortable values. */
 
2397
        if (values_cnt > 0)
 
2398
        {
 
2399
                int                     ndistinct,      /* # distinct values in sample */
 
2400
                                        nmultiple,      /* # that appear multiple times */
 
2401
                                        num_hist,
 
2402
                                        dups_cnt;
 
2403
                int                     slot_idx = 0;
 
2404
                CompareScalarsContext cxt;
 
2405
 
 
2406
                /* Sort the collected values */
 
2407
                cxt.ssup = &ssup;
 
2408
                cxt.tupnoLink = tupnoLink;
 
2409
                qsort_arg((void *) values, values_cnt, sizeof(ScalarItem),
 
2410
                                  compare_scalars, (void *) &cxt);
 
2411
 
 
2412
                /*
 
2413
                 * Now scan the values in order, find the most common ones, and also
 
2414
                 * accumulate ordering-correlation statistics.
 
2415
                 *
 
2416
                 * To determine which are most common, we first have to count the
 
2417
                 * number of duplicates of each value.  The duplicates are adjacent in
 
2418
                 * the sorted list, so a brute-force approach is to compare successive
 
2419
                 * datum values until we find two that are not equal. However, that
 
2420
                 * requires N-1 invocations of the datum comparison routine, which are
 
2421
                 * completely redundant with work that was done during the sort.  (The
 
2422
                 * sort algorithm must at some point have compared each pair of items
 
2423
                 * that are adjacent in the sorted order; otherwise it could not know
 
2424
                 * that it's ordered the pair correctly.) We exploit this by having
 
2425
                 * compare_scalars remember the highest tupno index that each
 
2426
                 * ScalarItem has been found equal to.  At the end of the sort, a
 
2427
                 * ScalarItem's tupnoLink will still point to itself if and only if it
 
2428
                 * is the last item of its group of duplicates (since the group will
 
2429
                 * be ordered by tupno).
 
2430
                 */
 
2431
                corr_xysum = 0;
 
2432
                ndistinct = 0;
 
2433
                nmultiple = 0;
 
2434
                dups_cnt = 0;
 
2435
                for (i = 0; i < values_cnt; i++)
 
2436
                {
 
2437
                        int                     tupno = values[i].tupno;
 
2438
 
 
2439
                        corr_xysum += ((double) i) * ((double) tupno);
 
2440
                        dups_cnt++;
 
2441
                        if (tupnoLink[tupno] == tupno)
 
2442
                        {
 
2443
                                /* Reached end of duplicates of this value */
 
2444
                                ndistinct++;
 
2445
                                if (dups_cnt > 1)
 
2446
                                {
 
2447
                                        nmultiple++;
 
2448
                                        if (track_cnt < num_mcv ||
 
2449
                                                dups_cnt > track[track_cnt - 1].count)
 
2450
                                        {
 
2451
                                                /*
 
2452
                                                 * Found a new item for the mcv list; find its
 
2453
                                                 * position, bubbling down old items if needed. Loop
 
2454
                                                 * invariant is that j points at an empty/ replaceable
 
2455
                                                 * slot.
 
2456
                                                 */
 
2457
                                                int                     j;
 
2458
 
 
2459
                                                if (track_cnt < num_mcv)
 
2460
                                                        track_cnt++;
 
2461
                                                for (j = track_cnt - 1; j > 0; j--)
 
2462
                                                {
 
2463
                                                        if (dups_cnt <= track[j - 1].count)
 
2464
                                                                break;
 
2465
                                                        track[j].count = track[j - 1].count;
 
2466
                                                        track[j].first = track[j - 1].first;
 
2467
                                                }
 
2468
                                                track[j].count = dups_cnt;
 
2469
                                                track[j].first = i + 1 - dups_cnt;
 
2470
                                        }
 
2471
                                }
 
2472
                                dups_cnt = 0;
 
2473
                        }
 
2474
                }
 
2475
 
 
2476
                stats->stats_valid = true;
 
2477
                /* Do the simple null-frac and width stats */
 
2478
                stats->stanullfrac = (double) null_cnt / (double) samplerows;
 
2479
                if (is_varwidth)
 
2480
                        stats->stawidth = total_width / (double) nonnull_cnt;
 
2481
                else
 
2482
                        stats->stawidth = stats->attrtype->typlen;
 
2483
 
 
2484
                if (nmultiple == 0)
 
2485
                {
 
2486
                        /*
 
2487
                         * If we found no repeated non-null values, assume it's a unique
 
2488
                         * column; but be sure to discount for any nulls we found.
 
2489
                         */
 
2490
                        stats->stadistinct = -1.0 * (1.0 - stats->stanullfrac);
 
2491
                }
 
2492
                else if (toowide_cnt == 0 && nmultiple == ndistinct)
 
2493
                {
 
2494
                        /*
 
2495
                         * Every value in the sample appeared more than once.  Assume the
 
2496
                         * column has just these values.  (This case is meant to address
 
2497
                         * columns with small, fixed sets of possible values, such as
 
2498
                         * boolean or enum columns.  If there are any values that appear
 
2499
                         * just once in the sample, including too-wide values, we should
 
2500
                         * assume that that's not what we're dealing with.)
 
2501
                         */
 
2502
                        stats->stadistinct = ndistinct;
 
2503
                }
 
2504
                else
 
2505
                {
 
2506
                        /*----------
 
2507
                         * Estimate the number of distinct values using the estimator
 
2508
                         * proposed by Haas and Stokes in IBM Research Report RJ 10025:
 
2509
                         *              n*d / (n - f1 + f1*n/N)
 
2510
                         * where f1 is the number of distinct values that occurred
 
2511
                         * exactly once in our sample of n rows (from a total of N),
 
2512
                         * and d is the total number of distinct values in the sample.
 
2513
                         * This is their Duj1 estimator; the other estimators they
 
2514
                         * recommend are considerably more complex, and are numerically
 
2515
                         * very unstable when n is much smaller than N.
 
2516
                         *
 
2517
                         * In this calculation, we consider only non-nulls.  We used to
 
2518
                         * include rows with null values in the n and N counts, but that
 
2519
                         * leads to inaccurate answers in columns with many nulls, and
 
2520
                         * it's intuitively bogus anyway considering the desired result is
 
2521
                         * the number of distinct non-null values.
 
2522
                         *
 
2523
                         * Overwidth values are assumed to have been distinct.
 
2524
                         *----------
 
2525
                         */
 
2526
                        int                     f1 = ndistinct - nmultiple + toowide_cnt;
 
2527
                        int                     d = f1 + nmultiple;
 
2528
                        double          n = samplerows - null_cnt;
 
2529
                        double          N = totalrows * (1.0 - stats->stanullfrac);
 
2530
                        double          stadistinct;
 
2531
 
 
2532
                        /* N == 0 shouldn't happen, but just in case ... */
 
2533
                        if (N > 0)
 
2534
                                stadistinct = (n * d) / ((n - f1) + f1 * n / N);
 
2535
                        else
 
2536
                                stadistinct = 0;
 
2537
 
 
2538
                        /* Clamp to sane range in case of roundoff error */
 
2539
                        if (stadistinct < d)
 
2540
                                stadistinct = d;
 
2541
                        if (stadistinct > N)
 
2542
                                stadistinct = N;
 
2543
                        /* And round to integer */
 
2544
                        stats->stadistinct = floor(stadistinct + 0.5);
 
2545
                }
 
2546
 
 
2547
                /*
 
2548
                 * If we estimated the number of distinct values at more than 10% of
 
2549
                 * the total row count (a very arbitrary limit), then assume that
 
2550
                 * stadistinct should scale with the row count rather than be a fixed
 
2551
                 * value.
 
2552
                 */
 
2553
                if (stats->stadistinct > 0.1 * totalrows)
 
2554
                        stats->stadistinct = -(stats->stadistinct / totalrows);
 
2555
 
 
2556
                /*
 
2557
                 * Decide how many values are worth storing as most-common values. If
 
2558
                 * we are able to generate a complete MCV list (all the values in the
 
2559
                 * sample will fit, and we think these are all the ones in the table),
 
2560
                 * then do so.  Otherwise, store only those values that are
 
2561
                 * significantly more common than the values not in the list.
 
2562
                 *
 
2563
                 * Note: the first of these cases is meant to address columns with
 
2564
                 * small, fixed sets of possible values, such as boolean or enum
 
2565
                 * columns.  If we can *completely* represent the column population by
 
2566
                 * an MCV list that will fit into the stats target, then we should do
 
2567
                 * so and thus provide the planner with complete information.  But if
 
2568
                 * the MCV list is not complete, it's generally worth being more
 
2569
                 * selective, and not just filling it all the way up to the stats
 
2570
                 * target.
 
2571
                 */
 
2572
                if (track_cnt == ndistinct && toowide_cnt == 0 &&
 
2573
                        stats->stadistinct > 0 &&
 
2574
                        track_cnt <= num_mcv)
 
2575
                {
 
2576
                        /* Track list includes all values seen, and all will fit */
 
2577
                        num_mcv = track_cnt;
 
2578
                }
 
2579
                else
 
2580
                {
 
2581
                        int                *mcv_counts;
 
2582
 
 
2583
                        /* Incomplete list; decide how many values are worth keeping */
 
2584
                        if (num_mcv > track_cnt)
 
2585
                                num_mcv = track_cnt;
 
2586
 
 
2587
                        if (num_mcv > 0)
 
2588
                        {
 
2589
                                mcv_counts = (int *) palloc(num_mcv * sizeof(int));
 
2590
                                for (i = 0; i < num_mcv; i++)
 
2591
                                        mcv_counts[i] = track[i].count;
 
2592
 
 
2593
                                num_mcv = analyze_mcv_list(mcv_counts, num_mcv,
 
2594
                                                                                   stats->stadistinct,
 
2595
                                                                                   stats->stanullfrac,
 
2596
                                                                                   samplerows, totalrows);
 
2597
                        }
 
2598
                }
 
2599
 
 
2600
                /* Generate MCV slot entry */
 
2601
                if (num_mcv > 0)
 
2602
                {
 
2603
                        MemoryContext old_context;
 
2604
                        Datum      *mcv_values;
 
2605
                        float4     *mcv_freqs;
 
2606
 
 
2607
                        /* Must copy the target values into anl_context */
 
2608
                        old_context = MemoryContextSwitchTo(stats->anl_context);
 
2609
                        mcv_values = (Datum *) palloc(num_mcv * sizeof(Datum));
 
2610
                        mcv_freqs = (float4 *) palloc(num_mcv * sizeof(float4));
 
2611
                        for (i = 0; i < num_mcv; i++)
 
2612
                        {
 
2613
                                mcv_values[i] = datumCopy(values[track[i].first].value,
 
2614
                                                                                  stats->attrtype->typbyval,
 
2615
                                                                                  stats->attrtype->typlen);
 
2616
                                mcv_freqs[i] = (double) track[i].count / (double) samplerows;
 
2617
                        }
 
2618
                        MemoryContextSwitchTo(old_context);
 
2619
 
 
2620
                        stats->stakind[slot_idx] = STATISTIC_KIND_MCV;
 
2621
                        stats->staop[slot_idx] = mystats->eqopr;
 
2622
                        stats->stanumbers[slot_idx] = mcv_freqs;
 
2623
                        stats->numnumbers[slot_idx] = num_mcv;
 
2624
                        stats->stavalues[slot_idx] = mcv_values;
 
2625
                        stats->numvalues[slot_idx] = num_mcv;
 
2626
 
 
2627
                        /*
 
2628
                         * Accept the defaults for stats->statypid and others. They have
 
2629
                         * been set before we were called (see vacuum.h)
 
2630
                         */
 
2631
                        slot_idx++;
 
2632
                }
 
2633
 
 
2634
                /*
 
2635
                 * Generate a histogram slot entry if there are at least two distinct
 
2636
                 * values not accounted for in the MCV list.  (This ensures the
 
2637
                 * histogram won't collapse to empty or a singleton.)
 
2638
                 */
 
2639
                num_hist = ndistinct - num_mcv;
 
2640
                if (num_hist > num_bins)
 
2641
                        num_hist = num_bins + 1;
 
2642
                if (num_hist >= 2)
 
2643
                {
 
2644
                        MemoryContext old_context;
 
2645
                        Datum      *hist_values;
 
2646
                        int                     nvals;
 
2647
                        int                     pos,
 
2648
                                                posfrac,
 
2649
                                                delta,
 
2650
                                                deltafrac;
 
2651
 
 
2652
                        /* Sort the MCV items into position order to speed next loop */
 
2653
                        qsort((void *) track, num_mcv,
 
2654
                                  sizeof(ScalarMCVItem), compare_mcvs);
 
2655
 
 
2656
                        /*
 
2657
                         * Collapse out the MCV items from the values[] array.
 
2658
                         *
 
2659
                         * Note we destroy the values[] array here... but we don't need it
 
2660
                         * for anything more.  We do, however, still need values_cnt.
 
2661
                         * nvals will be the number of remaining entries in values[].
 
2662
                         */
 
2663
                        if (num_mcv > 0)
 
2664
                        {
 
2665
                                int                     src,
 
2666
                                                        dest;
 
2667
                                int                     j;
 
2668
 
 
2669
                                src = dest = 0;
 
2670
                                j = 0;                  /* index of next interesting MCV item */
 
2671
                                while (src < values_cnt)
 
2672
                                {
 
2673
                                        int                     ncopy;
 
2674
 
 
2675
                                        if (j < num_mcv)
 
2676
                                        {
 
2677
                                                int                     first = track[j].first;
 
2678
 
 
2679
                                                if (src >= first)
 
2680
                                                {
 
2681
                                                        /* advance past this MCV item */
 
2682
                                                        src = first + track[j].count;
 
2683
                                                        j++;
 
2684
                                                        continue;
 
2685
                                                }
 
2686
                                                ncopy = first - src;
 
2687
                                        }
 
2688
                                        else
 
2689
                                                ncopy = values_cnt - src;
 
2690
                                        memmove(&values[dest], &values[src],
 
2691
                                                        ncopy * sizeof(ScalarItem));
 
2692
                                        src += ncopy;
 
2693
                                        dest += ncopy;
 
2694
                                }
 
2695
                                nvals = dest;
 
2696
                        }
 
2697
                        else
 
2698
                                nvals = values_cnt;
 
2699
                        Assert(nvals >= num_hist);
 
2700
 
 
2701
                        /* Must copy the target values into anl_context */
 
2702
                        old_context = MemoryContextSwitchTo(stats->anl_context);
 
2703
                        hist_values = (Datum *) palloc(num_hist * sizeof(Datum));
 
2704
 
 
2705
                        /*
 
2706
                         * The object of this loop is to copy the first and last values[]
 
2707
                         * entries along with evenly-spaced values in between.  So the
 
2708
                         * i'th value is values[(i * (nvals - 1)) / (num_hist - 1)].  But
 
2709
                         * computing that subscript directly risks integer overflow when
 
2710
                         * the stats target is more than a couple thousand.  Instead we
 
2711
                         * add (nvals - 1) / (num_hist - 1) to pos at each step, tracking
 
2712
                         * the integral and fractional parts of the sum separately.
 
2713
                         */
 
2714
                        delta = (nvals - 1) / (num_hist - 1);
 
2715
                        deltafrac = (nvals - 1) % (num_hist - 1);
 
2716
                        pos = posfrac = 0;
 
2717
 
 
2718
                        for (i = 0; i < num_hist; i++)
 
2719
                        {
 
2720
                                hist_values[i] = datumCopy(values[pos].value,
 
2721
                                                                                   stats->attrtype->typbyval,
 
2722
                                                                                   stats->attrtype->typlen);
 
2723
                                pos += delta;
 
2724
                                posfrac += deltafrac;
 
2725
                                if (posfrac >= (num_hist - 1))
 
2726
                                {
 
2727
                                        /* fractional part exceeds 1, carry to integer part */
 
2728
                                        pos++;
 
2729
                                        posfrac -= (num_hist - 1);
 
2730
                                }
 
2731
                        }
 
2732
 
 
2733
                        MemoryContextSwitchTo(old_context);
 
2734
 
 
2735
                        stats->stakind[slot_idx] = STATISTIC_KIND_HISTOGRAM;
 
2736
                        stats->staop[slot_idx] = mystats->ltopr;
 
2737
                        stats->stavalues[slot_idx] = hist_values;
 
2738
                        stats->numvalues[slot_idx] = num_hist;
 
2739
 
 
2740
                        /*
 
2741
                         * Accept the defaults for stats->statypid and others. They have
 
2742
                         * been set before we were called (see vacuum.h)
 
2743
                         */
 
2744
                        slot_idx++;
 
2745
                }
 
2746
 
 
2747
                /* Generate a correlation entry if there are multiple values */
 
2748
                if (values_cnt > 1)
 
2749
                {
 
2750
                        MemoryContext old_context;
 
2751
                        float4     *corrs;
 
2752
                        double          corr_xsum,
 
2753
                                                corr_x2sum;
 
2754
 
 
2755
                        /* Must copy the target values into anl_context */
 
2756
                        old_context = MemoryContextSwitchTo(stats->anl_context);
 
2757
                        corrs = (float4 *) palloc(sizeof(float4));
 
2758
                        MemoryContextSwitchTo(old_context);
 
2759
 
 
2760
                        /*----------
 
2761
                         * Since we know the x and y value sets are both
 
2762
                         *              0, 1, ..., values_cnt-1
 
2763
                         * we have sum(x) = sum(y) =
 
2764
                         *              (values_cnt-1)*values_cnt / 2
 
2765
                         * and sum(x^2) = sum(y^2) =
 
2766
                         *              (values_cnt-1)*values_cnt*(2*values_cnt-1) / 6.
 
2767
                         *----------
 
2768
                         */
 
2769
                        corr_xsum = ((double) (values_cnt - 1)) *
 
2770
                                ((double) values_cnt) / 2.0;
 
2771
                        corr_x2sum = ((double) (values_cnt - 1)) *
 
2772
                                ((double) values_cnt) * (double) (2 * values_cnt - 1) / 6.0;
 
2773
 
 
2774
                        /* And the correlation coefficient reduces to */
 
2775
                        corrs[0] = (values_cnt * corr_xysum - corr_xsum * corr_xsum) /
 
2776
                                (values_cnt * corr_x2sum - corr_xsum * corr_xsum);
 
2777
 
 
2778
                        stats->stakind[slot_idx] = STATISTIC_KIND_CORRELATION;
 
2779
                        stats->staop[slot_idx] = mystats->ltopr;
 
2780
                        stats->stanumbers[slot_idx] = corrs;
 
2781
                        stats->numnumbers[slot_idx] = 1;
 
2782
                        slot_idx++;
 
2783
                }
 
2784
        }
 
2785
        else if (nonnull_cnt > 0)
 
2786
        {
 
2787
                /* We found some non-null values, but they were all too wide */
 
2788
                Assert(nonnull_cnt == toowide_cnt);
 
2789
                stats->stats_valid = true;
 
2790
                /* Do the simple null-frac and width stats */
 
2791
                stats->stanullfrac = (double) null_cnt / (double) samplerows;
 
2792
                if (is_varwidth)
 
2793
                        stats->stawidth = total_width / (double) nonnull_cnt;
 
2794
                else
 
2795
                        stats->stawidth = stats->attrtype->typlen;
 
2796
                /* Assume all too-wide values are distinct, so it's a unique column */
 
2797
                stats->stadistinct = -1.0 * (1.0 - stats->stanullfrac);
 
2798
        }
 
2799
        else if (null_cnt > 0)
 
2800
        {
 
2801
                /* We found only nulls; assume the column is entirely null */
 
2802
                stats->stats_valid = true;
 
2803
                stats->stanullfrac = 1.0;
 
2804
                if (is_varwidth)
 
2805
                        stats->stawidth = 0;    /* "unknown" */
 
2806
                else
 
2807
                        stats->stawidth = stats->attrtype->typlen;
 
2808
                stats->stadistinct = 0.0;       /* "unknown" */
 
2809
        }
 
2810
 
 
2811
        /* We don't need to bother cleaning up any of our temporary palloc's */
 
2812
}
 
2813
 
 
2814
/*
 
2815
 * qsort_arg comparator for sorting ScalarItems
 
2816
 *
 
2817
 * Aside from sorting the items, we update the tupnoLink[] array
 
2818
 * whenever two ScalarItems are found to contain equal datums.  The array
 
2819
 * is indexed by tupno; for each ScalarItem, it contains the highest
 
2820
 * tupno that that item's datum has been found to be equal to.  This allows
 
2821
 * us to avoid additional comparisons in compute_scalar_stats().
 
2822
 */
 
2823
static int
 
2824
compare_scalars(const void *a, const void *b, void *arg)
 
2825
{
 
2826
        Datum           da = ((const ScalarItem *) a)->value;
 
2827
        int                     ta = ((const ScalarItem *) a)->tupno;
 
2828
        Datum           db = ((const ScalarItem *) b)->value;
 
2829
        int                     tb = ((const ScalarItem *) b)->tupno;
 
2830
        CompareScalarsContext *cxt = (CompareScalarsContext *) arg;
 
2831
        int                     compare;
 
2832
 
 
2833
        compare = ApplySortComparator(da, false, db, false, cxt->ssup);
 
2834
        if (compare != 0)
 
2835
                return compare;
 
2836
 
 
2837
        /*
 
2838
         * The two datums are equal, so update cxt->tupnoLink[].
 
2839
         */
 
2840
        if (cxt->tupnoLink[ta] < tb)
 
2841
                cxt->tupnoLink[ta] = tb;
 
2842
        if (cxt->tupnoLink[tb] < ta)
 
2843
                cxt->tupnoLink[tb] = ta;
 
2844
 
 
2845
        /*
 
2846
         * For equal datums, sort by tupno
 
2847
         */
 
2848
        return ta - tb;
 
2849
}
 
2850
 
 
2851
/*
 
2852
 * qsort comparator for sorting ScalarMCVItems by position
 
2853
 */
 
2854
static int
 
2855
compare_mcvs(const void *a, const void *b)
 
2856
{
 
2857
        int                     da = ((const ScalarMCVItem *) a)->first;
 
2858
        int                     db = ((const ScalarMCVItem *) b)->first;
 
2859
 
 
2860
        return da - db;
 
2861
}
 
2862
 
 
2863
/*
 
2864
 * Analyze the list of common values in the sample and decide how many are
 
2865
 * worth storing in the table's MCV list.
 
2866
 *
 
2867
 * mcv_counts is assumed to be a list of the counts of the most common values
 
2868
 * seen in the sample, starting with the most common.  The return value is the
 
2869
 * number that are significantly more common than the values not in the list,
 
2870
 * and which are therefore deemed worth storing in the table's MCV list.
 
2871
 */
 
2872
static int
 
2873
analyze_mcv_list(int *mcv_counts,
 
2874
                                 int num_mcv,
 
2875
                                 double stadistinct,
 
2876
                                 double stanullfrac,
 
2877
                                 int samplerows,
 
2878
                                 double totalrows)
 
2879
{
 
2880
        double          ndistinct_table;
 
2881
        double          sumcount;
 
2882
        int                     i;
 
2883
 
 
2884
        /*
 
2885
         * If the entire table was sampled, keep the whole list.  This also
 
2886
         * protects us against division by zero in the code below.
 
2887
         */
 
2888
        if (samplerows == totalrows || totalrows <= 1.0)
 
2889
                return num_mcv;
 
2890
 
 
2891
        /* Re-extract the estimated number of distinct nonnull values in table */
 
2892
        ndistinct_table = stadistinct;
 
2893
        if (ndistinct_table < 0)
 
2894
                ndistinct_table = -ndistinct_table * totalrows;
 
2895
 
 
2896
        /*
 
2897
         * Exclude the least common values from the MCV list, if they are not
 
2898
         * significantly more common than the estimated selectivity they would
 
2899
         * have if they weren't in the list.  All non-MCV values are assumed to be
 
2900
         * equally common, after taking into account the frequencies of all the
 
2901
         * the values in the MCV list and the number of nulls (c.f. eqsel()).
 
2902
         *
 
2903
         * Here sumcount tracks the total count of all but the last (least common)
 
2904
         * value in the MCV list, allowing us to determine the effect of excluding
 
2905
         * that value from the list.
 
2906
         *
 
2907
         * Note that we deliberately do this by removing values from the full
 
2908
         * list, rather than starting with an empty list and adding values,
 
2909
         * because the latter approach can fail to add any values if all the most
 
2910
         * common values have around the same frequency and make up the majority
 
2911
         * of the table, so that the overall average frequency of all values is
 
2912
         * roughly the same as that of the common values.  This would lead to any
 
2913
         * uncommon values being significantly overestimated.
 
2914
         */
 
2915
        sumcount = 0.0;
 
2916
        for (i = 0; i < num_mcv - 1; i++)
 
2917
                sumcount += mcv_counts[i];
 
2918
 
 
2919
        while (num_mcv > 0)
 
2920
        {
 
2921
                double          selec,
 
2922
                                        otherdistinct,
 
2923
                                        N,
 
2924
                                        n,
 
2925
                                        K,
 
2926
                                        variance,
 
2927
                                        stddev;
 
2928
 
 
2929
                /*
 
2930
                 * Estimated selectivity the least common value would have if it
 
2931
                 * wasn't in the MCV list (c.f. eqsel()).
 
2932
                 */
 
2933
                selec = 1.0 - sumcount / samplerows - stanullfrac;
 
2934
                if (selec < 0.0)
 
2935
                        selec = 0.0;
 
2936
                if (selec > 1.0)
 
2937
                        selec = 1.0;
 
2938
                otherdistinct = ndistinct_table - (num_mcv - 1);
 
2939
                if (otherdistinct > 1)
 
2940
                        selec /= otherdistinct;
 
2941
 
 
2942
                /*
 
2943
                 * If the value is kept in the MCV list, its population frequency is
 
2944
                 * assumed to equal its sample frequency.  We use the lower end of a
 
2945
                 * textbook continuity-corrected Wald-type confidence interval to
 
2946
                 * determine if that is significantly more common than the non-MCV
 
2947
                 * frequency --- specifically we assume the population frequency is
 
2948
                 * highly likely to be within around 2 standard errors of the sample
 
2949
                 * frequency, which equates to an interval of 2 standard deviations
 
2950
                 * either side of the sample count, plus an additional 0.5 for the
 
2951
                 * continuity correction.  Since we are sampling without replacement,
 
2952
                 * this is a hypergeometric distribution.
 
2953
                 *
 
2954
                 * XXX: Empirically, this approach seems to work quite well, but it
 
2955
                 * may be worth considering more advanced techniques for estimating
 
2956
                 * the confidence interval of the hypergeometric distribution.
 
2957
                 */
 
2958
                N = totalrows;
 
2959
                n = samplerows;
 
2960
                K = N * mcv_counts[num_mcv - 1] / n;
 
2961
                variance = n * K * (N - K) * (N - n) / (N * N * (N - 1));
 
2962
                stddev = sqrt(variance);
 
2963
 
 
2964
                if (mcv_counts[num_mcv - 1] > selec * samplerows + 2 * stddev + 0.5)
 
2965
                {
 
2966
                        /*
 
2967
                         * The value is significantly more common than the non-MCV
 
2968
                         * selectivity would suggest.  Keep it, and all the other more
 
2969
                         * common values in the list.
 
2970
                         */
 
2971
                        break;
 
2972
                }
 
2973
                else
 
2974
                {
 
2975
                        /* Discard this value and consider the next least common value */
 
2976
                        num_mcv--;
 
2977
                        if (num_mcv == 0)
 
2978
                                break;
 
2979
                        sumcount -= mcv_counts[num_mcv - 1];
 
2980
                }
 
2981
        }
 
2982
        return num_mcv;
 
2983
}