Fold vacuum's 'int options' parameter into VacuumParams.
authorRobert Haas <[email protected]>
Mon, 18 Mar 2019 17:57:33 +0000 (13:57 -0400)
committerRobert Haas <[email protected]>
Mon, 18 Mar 2019 17:57:33 +0000 (13:57 -0400)
Many places need both, so this allows a few functions to take one
fewer parameter.  More importantly, as soon as we add a VACUUM
option that takes a non-Boolean parameter, we need to replace
'int options' with a struct, and it seems better to think
of adding more fields to VacuumParams rather than passing around
both VacuumParams and a separate struct as well.

 by me, reviewed by Masahiko Sawada

Discussion: http://postgr.es/m/CA+Tgmob6g6-s50fyv8E8he7APfwCYYJ4z0wbZC2yZeSz=26CYQ@mail.gmail.com

src/backend/access/heap/vacuumlazy.c
src/backend/commands/analyze.c
src/backend/commands/vacuum.c
src/backend/postmaster/autovacuum.c
src/include/access/heapam.h
src/include/commands/vacuum.h

index 9416c31889ede10803d20a451f9bc4a043965501..5c554f94659b60ff658e1156c20ba97d664c9ee4 100644 (file)
@@ -186,7 +186,7 @@ static bool heap_page_is_all_visible(Relation rel, Buffer buf,
  *     and locked the relation.
  */
 void
-heap_vacuum_rel(Relation onerel, int options, VacuumParams *params,
+heap_vacuum_rel(Relation onerel, VacuumParams *params,
                BufferAccessStrategy bstrategy)
 {
    LVRelStats *vacrelstats;
@@ -217,7 +217,7 @@ heap_vacuum_rel(Relation onerel, int options, VacuumParams *params,
        starttime = GetCurrentTimestamp();
    }
 
-   if (options & VACOPT_VERBOSE)
+   if (params->options & VACOPT_VERBOSE)
        elevel = INFO;
    else
        elevel = DEBUG2;
@@ -245,7 +245,7 @@ heap_vacuum_rel(Relation onerel, int options, VacuumParams *params,
                                               xidFullScanLimit);
    aggressive |= MultiXactIdPrecedesOrEquals(onerel->rd_rel->relminmxid,
                                              mxactFullScanLimit);
-   if (options & VACOPT_DISABLE_PAGE_SKIPPING)
+   if (params->options & VACOPT_DISABLE_PAGE_SKIPPING)
        aggressive = true;
 
    vacrelstats = (LVRelStats *) palloc0(sizeof(LVRelStats));
@@ -261,7 +261,7 @@ heap_vacuum_rel(Relation onerel, int options, VacuumParams *params,
    vacrelstats->hasindex = (nindexes > 0);
 
    /* Do the vacuuming */
-   lazy_scan_heap(onerel, options, vacrelstats, Irel, nindexes, aggressive);
+   lazy_scan_heap(onerel, params->options, vacrelstats, Irel, nindexes, aggressive);
 
    /* Done with indexes */
    vac_close_indexes(nindexes, Irel, NoLock);
index c8192353ebe2643858ef9123a82c07c598523fc6..3465713d1084dc63fa3c4e3f66803157eefe7b24 100644 (file)
@@ -84,7 +84,7 @@ static MemoryContext anl_context = NULL;
 static BufferAccessStrategy vac_strategy;
 
 
-static void do_analyze_rel(Relation onerel, int options,
+static void do_analyze_rel(Relation onerel,
               VacuumParams *params, List *va_cols,
               AcquireSampleRowsFunc acquirefunc, BlockNumber relpages,
               bool inh, bool in_outer_xact, int elevel);
@@ -115,7 +115,7 @@ static Datum ind_fetch_func(VacAttrStatsP stats, int rownum, bool *isNull);
  * use it once we've successfully opened the rel, since it might be stale.
  */
 void
-analyze_rel(Oid relid, RangeVar *relation, int options,
+analyze_rel(Oid relid, RangeVar *relation,
            VacuumParams *params, List *va_cols, bool in_outer_xact,
            BufferAccessStrategy bstrategy)
 {
@@ -125,7 +125,7 @@ analyze_rel(Oid relid, RangeVar *relation, int options,
    BlockNumber relpages = 0;
 
    /* Select logging level */
-   if (options & VACOPT_VERBOSE)
+   if (params->options & VACOPT_VERBOSE)
        elevel = INFO;
    else
        elevel = DEBUG2;
@@ -147,8 +147,8 @@ analyze_rel(Oid relid, RangeVar *relation, int options,
     *
     * Make sure to generate only logs for ANALYZE in this case.
     */
-   onerel = vacuum_open_relation(relid, relation, params,
-                                 options & ~(VACOPT_VACUUM),
+   onerel = vacuum_open_relation(relid, relation, params->options & ~(VACOPT_VACUUM),
+                                 params->log_min_duration >= 0,
                                  ShareUpdateExclusiveLock);
 
    /* leave if relation could not be opened or locked */
@@ -165,7 +165,7 @@ analyze_rel(Oid relid, RangeVar *relation, int options,
     */
    if (!vacuum_is_relation_owner(RelationGetRelid(onerel),
                                  onerel->rd_rel,
-                                 options & VACOPT_ANALYZE))
+                                 params->options & VACOPT_ANALYZE))
    {
        relation_close(onerel, ShareUpdateExclusiveLock);
        return;
@@ -237,7 +237,7 @@ analyze_rel(Oid relid, RangeVar *relation, int options,
    else
    {
        /* No need for a WARNING if we already complained during VACUUM */
-       if (!(options & VACOPT_VACUUM))
+       if (!(params->options & VACOPT_VACUUM))
            ereport(WARNING,
                    (errmsg("skipping \"%s\" --- cannot analyze non-tables or special system tables",
                            RelationGetRelationName(onerel))));
@@ -257,14 +257,14 @@ analyze_rel(Oid relid, RangeVar *relation, int options,
     * tables, which don't contain any rows.
     */
    if (onerel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
-       do_analyze_rel(onerel, options, params, va_cols, acquirefunc,
+       do_analyze_rel(onerel, params, va_cols, acquirefunc,
                       relpages, false, in_outer_xact, elevel);
 
    /*
     * If there are child tables, do recursive ANALYZE.
     */
    if (onerel->rd_rel->relhassubclass)
-       do_analyze_rel(onerel, options, params, va_cols, acquirefunc, relpages,
+       do_analyze_rel(onerel, params, va_cols, acquirefunc, relpages,
                       true, in_outer_xact, elevel);
 
    /*
@@ -292,7 +292,7 @@ analyze_rel(Oid relid, RangeVar *relation, int options,
  * appropriate acquirefunc for each child table.
  */
 static void
-do_analyze_rel(Relation onerel, int options, VacuumParams *params,
+do_analyze_rel(Relation onerel, VacuumParams *params,
               List *va_cols, AcquireSampleRowsFunc acquirefunc,
               BlockNumber relpages, bool inh, bool in_outer_xact,
               int elevel)
@@ -603,7 +603,7 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params,
     * VACUUM ANALYZE, don't overwrite the accurate count already inserted by
     * VACUUM.
     */
-   if (!inh && !(options & VACOPT_VACUUM))
+   if (!inh && !(params->options & VACOPT_VACUUM))
    {
        for (ind = 0; ind < nindexes; ind++)
        {
@@ -634,7 +634,7 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params,
                              (va_cols == NIL));
 
    /* If this isn't part of VACUUM ANALYZE, let index AMs do cleanup */
-   if (!(options & VACOPT_VACUUM))
+   if (!(params->options & VACOPT_VACUUM))
    {
        for (ind = 0; ind < nindexes; ind++)
        {
index 1b5b50cf01958848bb09cbefd848f53656e8be93..be03185a7f7d7d4d813ce18d0efe764cb7d1b856 100644 (file)
@@ -74,8 +74,7 @@ static void vac_truncate_clog(TransactionId frozenXID,
                  MultiXactId minMulti,
                  TransactionId lastSaneFrozenXid,
                  MultiXactId lastSaneMinMulti);
-static bool vacuum_rel(Oid relid, RangeVar *relation, int options,
-          VacuumParams *params);
+static bool vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params);
 
 /*
  * Primary entry point for manual VACUUM and ANALYZE commands
@@ -112,6 +111,9 @@ ExecVacuum(VacuumStmt *vacstmt, bool isTopLevel)
        }
    }
 
+   /* copy options from parse tree */
+   params.options = vacstmt->options;
+
    /*
     * All freeze ages are zero if the FREEZE option is given; otherwise pass
     * them as -1 which means to use the default values.
@@ -138,14 +140,12 @@ ExecVacuum(VacuumStmt *vacstmt, bool isTopLevel)
    params.log_min_duration = -1;
 
    /* Now go through the common routine */
-   vacuum(vacstmt->options, vacstmt->rels, &params, NULL, isTopLevel);
+   vacuum(vacstmt->rels, &params, NULL, isTopLevel);
 }
 
 /*
  * Internal entry point for VACUUM and ANALYZE commands.
  *
- * options is a bitmask of VacuumOption flags, indicating what to do.
- *
  * relations, if not NIL, is a list of VacuumRelation to process; otherwise,
  * we process all relevant tables in the database.  For each VacuumRelation,
  * if a valid OID is supplied, the table with that OID is what to process;
@@ -163,7 +163,7 @@ ExecVacuum(VacuumStmt *vacstmt, bool isTopLevel)
  * memory context that will not disappear at transaction commit.
  */
 void
-vacuum(int options, List *relations, VacuumParams *params,
+vacuum(List *relations, VacuumParams *params,
       BufferAccessStrategy bstrategy, bool isTopLevel)
 {
    static bool in_vacuum = false;
@@ -174,7 +174,7 @@ vacuum(int options, List *relations, VacuumParams *params,
 
    Assert(params != NULL);
 
-   stmttype = (options & VACOPT_VACUUM) ? "VACUUM" : "ANALYZE";
+   stmttype = (params->options & VACOPT_VACUUM) ? "VACUUM" : "ANALYZE";
 
    /*
     * We cannot run VACUUM inside a user transaction block; if we were inside
@@ -184,7 +184,7 @@ vacuum(int options, List *relations, VacuumParams *params,
     *
     * ANALYZE (without VACUUM) can run either way.
     */
-   if (options & VACOPT_VACUUM)
+   if (params->options & VACOPT_VACUUM)
    {
        PreventInTransactionBlock(isTopLevel, stmttype);
        in_outer_xact = false;
@@ -206,8 +206,8 @@ vacuum(int options, List *relations, VacuumParams *params,
    /*
     * Sanity check DISABLE_PAGE_SKIPPING option.
     */
-   if ((options & VACOPT_FULL) != 0 &&
-       (options & VACOPT_DISABLE_PAGE_SKIPPING) != 0)
+   if ((params->options & VACOPT_FULL) != 0 &&
+       (params->options & VACOPT_DISABLE_PAGE_SKIPPING) != 0)
        ereport(ERROR,
                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                 errmsg("VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL")));
@@ -216,7 +216,7 @@ vacuum(int options, List *relations, VacuumParams *params,
     * Send info about dead objects to the statistics collector, unless we are
     * in autovacuum --- autovacuum.c does this for itself.
     */
-   if ((options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess())
+   if ((params->options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess())
        pgstat_vacuum_stat();
 
    /*
@@ -257,7 +257,7 @@ vacuum(int options, List *relations, VacuumParams *params,
            List       *sublist;
            MemoryContext old_context;
 
-           sublist = expand_vacuum_rel(vrel, options);
+           sublist = expand_vacuum_rel(vrel, params->options);
            old_context = MemoryContextSwitchTo(vac_context);
            newrels = list_concat(newrels, sublist);
            MemoryContextSwitchTo(old_context);
@@ -265,7 +265,7 @@ vacuum(int options, List *relations, VacuumParams *params,
        relations = newrels;
    }
    else
-       relations = get_all_vacuum_rels(options);
+       relations = get_all_vacuum_rels(params->options);
 
    /*
     * Decide whether we need to start/commit our own transactions.
@@ -281,11 +281,11 @@ vacuum(int options, List *relations, VacuumParams *params,
     * transaction block, and also in an autovacuum worker, use own
     * transactions so we can release locks sooner.
     */
-   if (options & VACOPT_VACUUM)
+   if (params->options & VACOPT_VACUUM)
        use_own_xacts = true;
    else
    {
-       Assert(options & VACOPT_ANALYZE);
+       Assert(params->options & VACOPT_ANALYZE);
        if (IsAutoVacuumWorkerProcess())
            use_own_xacts = true;
        else if (in_outer_xact)
@@ -335,13 +335,13 @@ vacuum(int options, List *relations, VacuumParams *params,
        {
            VacuumRelation *vrel = lfirst_node(VacuumRelation, cur);
 
-           if (options & VACOPT_VACUUM)
+           if (params->options & VACOPT_VACUUM)
            {
-               if (!vacuum_rel(vrel->oid, vrel->relation, options, params))
+               if (!vacuum_rel(vrel->oid, vrel->relation, params))
                    continue;
            }
 
-           if (options & VACOPT_ANALYZE)
+           if (params->options & VACOPT_ANALYZE)
            {
                /*
                 * If using separate xacts, start one for analyze. Otherwise,
@@ -354,7 +354,7 @@ vacuum(int options, List *relations, VacuumParams *params,
                    PushActiveSnapshot(GetTransactionSnapshot());
                }
 
-               analyze_rel(vrel->oid, vrel->relation, options, params,
+               analyze_rel(vrel->oid, vrel->relation, params,
                            vrel->va_cols, in_outer_xact, vac_strategy);
 
                if (use_own_xacts)
@@ -390,7 +390,7 @@ vacuum(int options, List *relations, VacuumParams *params,
        StartTransactionCommand();
    }
 
-   if ((options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess())
+   if ((params->options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess())
    {
        /*
         * Update pg_database.datfrozenxid, and truncate pg_xact if possible.
@@ -490,14 +490,13 @@ vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, int options)
  * or locked, a log is emitted if possible.
  */
 Relation
-vacuum_open_relation(Oid relid, RangeVar *relation, VacuumParams *params,
-                    int options, LOCKMODE lmode)
+vacuum_open_relation(Oid relid, RangeVar *relation, int options,
+                    bool verbose, LOCKMODE lmode)
 {
    Relation    onerel;
    bool        rel_lock = true;
    int         elevel;
 
-   Assert(params != NULL);
    Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0);
 
    /*
@@ -538,13 +537,12 @@ vacuum_open_relation(Oid relid, RangeVar *relation, VacuumParams *params,
    /*
     * Determine the log level.
     *
-    * For autovacuum logs, we emit a LOG if log_autovacuum_min_duration is
-    * not disabled.  For manual VACUUM or ANALYZE, we emit a WARNING to match
-    * the log statements in the permission checks.
+    * For manual VACUUM or ANALYZE, we emit a WARNING to match the log statements
+    * in the permission checks; otherwise, only log if the caller so requested.
     */
    if (!IsAutoVacuumWorkerProcess())
        elevel = WARNING;
-   else if (params->log_min_duration >= 0)
+   else if (verbose)
        elevel = LOG;
    else
        return NULL;
@@ -1521,7 +1519,7 @@ vac_truncate_clog(TransactionId frozenXID,
  *     At entry and exit, we are not inside a transaction.
  */
 static bool
-vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params)
+vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
 {
    LOCKMODE    lmode;
    Relation    onerel;
@@ -1542,7 +1540,7 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params)
     */
    PushActiveSnapshot(GetTransactionSnapshot());
 
-   if (!(options & VACOPT_FULL))
+   if (!(params->options & VACOPT_FULL))
    {
        /*
         * In lazy vacuum, we can set the PROC_IN_VACUUM flag, which lets
@@ -1582,10 +1580,12 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params)
     * vacuum, but just ShareUpdateExclusiveLock for concurrent vacuum. Either
     * way, we can be sure that no other backend is vacuuming the same table.
     */
-   lmode = (options & VACOPT_FULL) ? AccessExclusiveLock : ShareUpdateExclusiveLock;
+   lmode = (params->options & VACOPT_FULL) ?
+       AccessExclusiveLock : ShareUpdateExclusiveLock;
 
    /* open the relation and get the appropriate lock on it */
-   onerel = vacuum_open_relation(relid, relation, params, options, lmode);
+   onerel = vacuum_open_relation(relid, relation, params->options,
+                                 params->log_min_duration >= 0, lmode);
 
    /* leave if relation could not be opened or locked */
    if (!onerel)
@@ -1605,7 +1605,7 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params)
     */
    if (!vacuum_is_relation_owner(RelationGetRelid(onerel),
                                  onerel->rd_rel,
-                                 options & VACOPT_VACUUM))
+                                 params->options & VACOPT_VACUUM))
    {
        relation_close(onerel, lmode);
        PopActiveSnapshot();
@@ -1677,7 +1677,7 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params)
     * us to process it.  In VACUUM FULL, though, the toast table is
     * automatically rebuilt by cluster_rel so we shouldn't recurse to it.
     */
-   if (!(options & VACOPT_SKIPTOAST) && !(options & VACOPT_FULL))
+   if (!(params->options & VACOPT_SKIPTOAST) && !(params->options & VACOPT_FULL))
        toast_relid = onerel->rd_rel->reltoastrelid;
    else
        toast_relid = InvalidOid;
@@ -1696,7 +1696,7 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params)
    /*
     * Do the actual work --- either FULL or "lazy" vacuum
     */
-   if (options & VACOPT_FULL)
+   if (params->options & VACOPT_FULL)
    {
        int         cluster_options = 0;
 
@@ -1704,14 +1704,14 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params)
        relation_close(onerel, NoLock);
        onerel = NULL;
 
-       if ((options & VACOPT_VERBOSE) != 0)
+       if ((params->options & VACOPT_VERBOSE) != 0)
            cluster_options |= CLUOPT_VERBOSE;
 
        /* VACUUM FULL is now a variant of CLUSTER; see cluster.c */
        cluster_rel(relid, InvalidOid, cluster_options);
    }
    else
-       heap_vacuum_rel(onerel, options, params, vac_strategy);
+       heap_vacuum_rel(onerel, params, vac_strategy);
 
    /* Roll back any GUC changes executed by index functions */
    AtEOXact_GUC(false, save_nestlevel);
@@ -1737,7 +1737,7 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params)
     * totally unimportant for toast relations.
     */
    if (toast_relid != InvalidOid)
-       vacuum_rel(toast_relid, NULL, options, params);
+       vacuum_rel(toast_relid, NULL, params);
 
    /*
     * Now release the session-level lock on the master table.
index 3bfac919c43eeecea1dcf8433608891d5f106585..fa875db8160c440d5fbd7828c119e1136aa8dd0f 100644 (file)
@@ -188,7 +188,6 @@ typedef struct av_relation
 typedef struct autovac_table
 {
    Oid         at_relid;
-   int         at_vacoptions;  /* bitmask of VacuumOption */
    VacuumParams at_params;
    double      at_vacuum_cost_delay;
    int         at_vacuum_cost_limit;
@@ -2482,7 +2481,7 @@ do_autovacuum(void)
             * next table in our list.
             */
            HOLD_INTERRUPTS();
-           if (tab->at_vacoptions & VACOPT_VACUUM)
+           if (tab->at_params.options & VACOPT_VACUUM)
                errcontext("automatic vacuum of table \"%s.%s.%s\"",
                           tab->at_datname, tab->at_nspname, tab->at_relname);
            else
@@ -2883,7 +2882,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
        tab = palloc(sizeof(autovac_table));
        tab->at_relid = relid;
        tab->at_sharedrel = classForm->relisshared;
-       tab->at_vacoptions = VACOPT_SKIPTOAST |
+       tab->at_params.options = VACOPT_SKIPTOAST |
            (dovacuum ? VACOPT_VACUUM : 0) |
            (doanalyze ? VACOPT_ANALYZE : 0) |
            (!wraparound ? VACOPT_SKIP_LOCKED : 0);
@@ -3110,7 +3109,7 @@ autovacuum_do_vac_analyze(autovac_table *tab, BufferAccessStrategy bstrategy)
    rel = makeVacuumRelation(rangevar, tab->at_relid, NIL);
    rel_list = list_make1(rel);
 
-   vacuum(tab->at_vacoptions, rel_list, &tab->at_params, bstrategy, true);
+   vacuum(rel_list, &tab->at_params, bstrategy, true);
 }
 
 /*
@@ -3132,10 +3131,10 @@ autovac_report_activity(autovac_table *tab)
    int         len;
 
    /* Report the command and possible options */
-   if (tab->at_vacoptions & VACOPT_VACUUM)
+   if (tab->at_params.options & VACOPT_VACUUM)
        snprintf(activity, MAX_AUTOVAC_ACTIV_LEN,
                 "autovacuum: VACUUM%s",
-                tab->at_vacoptions & VACOPT_ANALYZE ? " ANALYZE" : "");
+                tab->at_params.options & VACOPT_ANALYZE ? " ANALYZE" : "");
    else
        snprintf(activity, MAX_AUTOVAC_ACTIV_LEN,
                 "autovacuum: ANALYZE");
index 1b6607fe902bae5608c755c35ff6902ce0f444fd..eb9e160bfd94657566e8f1e21ed00c396c5680ff 100644 (file)
@@ -217,7 +217,7 @@ extern Size SyncScanShmemSize(void);
 
 /* in heap/vacuumlazy.c */
 struct VacuumParams;
-extern void heap_vacuum_rel(Relation onerel, int options,
+extern void heap_vacuum_rel(Relation onerel,
                struct VacuumParams *params, BufferAccessStrategy bstrategy);
 
 /* in heap/heapam_visibility.c */
index 0a051ec06e2badcc157663da7564c96a4b848af2..c0df9c9054b08bc472ad9f0b4b5f7633702f937d 100644 (file)
@@ -141,6 +141,7 @@ typedef struct VacAttrStats
  */
 typedef struct VacuumParams
 {
+   int         options;        /* bitmask of VacuumOption */
    int         freeze_min_age; /* min freeze age, -1 to use default */
    int         freeze_table_age;   /* age at which to scan whole table */
    int         multixact_freeze_min_age;   /* min multixact freeze age, -1 to
@@ -163,7 +164,7 @@ extern int  vacuum_multixact_freeze_table_age;
 
 /* in commands/vacuum.c */
 extern void ExecVacuum(VacuumStmt *vacstmt, bool isTopLevel);
-extern void vacuum(int options, List *relations, VacuumParams *params,
+extern void vacuum(List *relations, VacuumParams *params,
       BufferAccessStrategy bstrategy, bool isTopLevel);
 extern void vac_open_indexes(Relation relation, LOCKMODE lockmode,
                 int *nindexes, Relation **Irel);
@@ -194,10 +195,10 @@ extern void vacuum_delay_point(void);
 extern bool vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple,
                         int options);
 extern Relation vacuum_open_relation(Oid relid, RangeVar *relation,
-                    VacuumParams *params, int options, LOCKMODE lmode);
+                    int options, bool verbose, LOCKMODE lmode);
 
 /* in commands/analyze.c */
-extern void analyze_rel(Oid relid, RangeVar *relation, int options,
+extern void analyze_rel(Oid relid, RangeVar *relation,
            VacuumParams *params, List *va_cols, bool in_outer_xact,
            BufferAccessStrategy bstrategy);
 extern bool std_typanalyze(VacAttrStats *stats);