]> granicus.if.org Git - postgresql/blobdiff - src/backend/commands/vacuum.c
Fix "ANALYZE t, t" inside a transaction block.
[postgresql] / src / backend / commands / vacuum.c
index 94fb6f2606397ed8fb24f6acf79746923f64a65d..7d6c50b49d9301bbacdbfd280d5633a23cc91c93 100644 (file)
@@ -72,9 +72,9 @@ static BufferAccessStrategy vac_strategy;
 static List *expand_vacuum_rel(VacuumRelation *vrel, int options);
 static List *get_all_vacuum_rels(int options);
 static void vac_truncate_clog(TransactionId frozenXID,
-                                 MultiXactId minMulti,
-                                 TransactionId lastSaneFrozenXid,
-                                 MultiXactId lastSaneMinMulti);
+                                                         MultiXactId minMulti,
+                                                         TransactionId lastSaneFrozenXid,
+                                                         MultiXactId lastSaneMinMulti);
 static bool vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params);
 static VacOptTernaryValue get_vacopt_ternary_value(DefElem *def);
 
@@ -88,21 +88,22 @@ void
 ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
 {
        VacuumParams params;
-       bool verbose = false;
-       bool skip_locked = false;
-       bool analyze = false;
-       bool freeze = false;
-       bool full = false;
-       bool disable_page_skipping = false;
-       ListCell        *lc;
+       bool            verbose = false;
+       bool            skip_locked = false;
+       bool            analyze = false;
+       bool            freeze = false;
+       bool            full = false;
+       bool            disable_page_skipping = false;
+       ListCell   *lc;
 
        /* Set default value */
        params.index_cleanup = VACOPT_TERNARY_DEFAULT;
+       params.truncate = VACOPT_TERNARY_DEFAULT;
 
        /* Parse options list */
        foreach(lc, vacstmt->options)
        {
-               DefElem *opt = (DefElem *) lfirst(lc);
+               DefElem    *opt = (DefElem *) lfirst(lc);
 
                /* Parse common options for VACUUM and ANALYZE */
                if (strcmp(opt->defname, "verbose") == 0)
@@ -126,6 +127,8 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
                        disable_page_skipping = defGetBoolean(opt);
                else if (strcmp(opt->defname, "index_cleanup") == 0)
                        params.index_cleanup = get_vacopt_ternary_value(opt);
+               else if (strcmp(opt->defname, "truncate") == 0)
+                       params.truncate = get_vacopt_ternary_value(opt);
                else
                        ereport(ERROR,
                                        (errcode(ERRCODE_SYNTAX_ERROR),
@@ -415,6 +418,15 @@ vacuum(List *relations, VacuumParams *params,
                                        PopActiveSnapshot();
                                        CommitTransactionCommand();
                                }
+                               else
+                               {
+                                       /*
+                                        * If we're not using separate xacts, better separate the
+                                        * ANALYZE actions with CCIs.  This avoids trouble if user
+                                        * says "ANALYZE t, t".
+                                        */
+                                       CommandCounterIncrement();
+                               }
                        }
                }
        }
@@ -590,8 +602,9 @@ vacuum_open_relation(Oid relid, RangeVar *relation, int options,
        /*
         * Determine the log level.
         *
-        * 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.
+        * 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;
@@ -843,7 +856,7 @@ get_all_vacuum_rels(int options)
 }
 
 /*
- * vacuum_set_xid_limits() -- compute oldest-Xmin and freeze cutoff points
+ * vacuum_set_xid_limits() -- compute oldestXmin and freeze cutoff points
  *
  * The output parameters are:
  * - oldestXmin is the cutoff value used to distinguish whether tuples are
@@ -1325,9 +1338,9 @@ vac_update_datfrozenxid(void)
                }
 
                /*
-                * Some table AMs might not need per-relation xid / multixid
-                * horizons. It therefore seems reasonable to allow relfrozenxid and
-                * relminmxid to not be set (i.e. set to their respective Invalid*Id)
+                * Some table AMs might not need per-relation xid / multixid horizons.
+                * It therefore seems reasonable to allow relfrozenxid and relminmxid
+                * to not be set (i.e. set to their respective Invalid*Id)
                 * independently. Thus validate and compute horizon for each only if
                 * set.
                 *
@@ -1760,6 +1773,16 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
                        params->index_cleanup = VACOPT_TERNARY_DISABLED;
        }
 
+       /* Set truncate option based on reloptions if not yet */
+       if (params->truncate == VACOPT_TERNARY_DEFAULT)
+       {
+               if (onerel->rd_options == NULL ||
+                       ((StdRdOptions *) onerel->rd_options)->vacuum_truncate)
+                       params->truncate = VACOPT_TERNARY_ENABLED;
+               else
+                       params->truncate = VACOPT_TERNARY_DISABLED;
+       }
+
        /*
         * Remember the relation's TOAST relation for later, if the caller asked
         * us to process it.  In VACUUM FULL, though, the toast table is