VACUUM reset them to false rather than trying to clean 'em up during DROP.
-<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.181 2008/11/09 21:24:32 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.182 2008/11/10 00:49:36 tgl Exp $ -->
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
-->
</para>
</note>
+ <note>
+ <para>
+ <literal>pg_class.relhastriggers</literal>
+ must be true if a table has any triggers in this catalog.
+ </para>
+ </note>
+
</sect1>
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.127 2008/11/02 01:45:27 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.128 2008/11/10 00:49:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
*/
if (!vacstmt->vacuum)
{
- vac_update_relstats(RelationGetRelid(onerel),
+ vac_update_relstats(onerel,
RelationGetNumberOfBlocks(onerel),
- totalrows, hasindex,
- InvalidTransactionId);
+ totalrows, hasindex, InvalidTransactionId);
for (ind = 0; ind < nindexes; ind++)
{
double totalindexrows;
totalindexrows = ceil(thisdata->tupleFract * totalrows);
- vac_update_relstats(RelationGetRelid(Irel[ind]),
+ vac_update_relstats(Irel[ind],
RelationGetNumberOfBlocks(Irel[ind]),
- totalindexrows, false,
- InvalidTransactionId);
+ totalindexrows, false, InvalidTransactionId);
}
/* report results to the stats collector, too */
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.379 2008/10/31 15:05:00 heikki Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.380 2008/11/10 00:49:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* pg_class would've been obsoleted. Of course, this only works for
* fixed-size never-null columns, but these are.
*
+ * Note another assumption: that two VACUUMs/ANALYZEs on a table can't
+ * run in parallel, nor can VACUUM/ANALYZE run in parallel with a
+ * schema alteration such as adding an index, rule, or trigger. Otherwise
+ * our updates of relhasindex etc might overwrite uncommitted updates.
+ *
* Another reason for doing it this way is that when we are in a lazy
* VACUUM and have PROC_IN_VACUUM set, we mustn't do any updates ---
* somebody vacuuming pg_class might think they could delete a tuple
* ANALYZE.
*/
void
-vac_update_relstats(Oid relid, BlockNumber num_pages, double num_tuples,
+vac_update_relstats(Relation relation,
+ BlockNumber num_pages, double num_tuples,
bool hasindex, TransactionId frozenxid)
{
+ Oid relid = RelationGetRelid(relation);
Relation rd;
HeapTuple ctup;
Form_pg_class pgcform;
}
}
+ /* We also clear relhasrules and relhastriggers if needed */
+ if (pgcform->relhasrules && relation->rd_rules == NULL)
+ {
+ pgcform->relhasrules = false;
+ dirty = true;
+ }
+ if (pgcform->relhastriggers && relation->trigdesc == NULL)
+ {
+ pgcform->relhastriggers = false;
+ dirty = true;
+ }
+
/*
* relfrozenxid should never go backward. Caller can pass
* InvalidTransactionId if it has no new data.
FreeSpaceMapVacuum(onerel);
/* update statistics in pg_class */
- vac_update_relstats(RelationGetRelid(onerel), vacrelstats->rel_pages,
- vacrelstats->rel_tuples, vacrelstats->hasindex,
- FreezeLimit);
+ vac_update_relstats(onerel,
+ vacrelstats->rel_pages, vacrelstats->rel_tuples,
+ vacrelstats->hasindex, FreezeLimit);
/* report results to the stats collector, too */
pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared,
return;
/* now update statistics in pg_class */
- vac_update_relstats(RelationGetRelid(indrel),
+ vac_update_relstats(indrel,
stats->num_pages, stats->num_index_tuples,
false, InvalidTransactionId);
return;
/* now update statistics in pg_class */
- vac_update_relstats(RelationGetRelid(indrel),
+ vac_update_relstats(indrel,
stats->num_pages, stats->num_index_tuples,
false, InvalidTransactionId);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.109 2008/10/31 15:05:00 heikki Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.110 2008/11/10 00:49:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
FreeSpaceMapVacuum(onerel);
/* Update statistics in pg_class */
- vac_update_relstats(RelationGetRelid(onerel),
- vacrelstats->rel_pages,
- vacrelstats->rel_tuples,
- vacrelstats->hasindex,
- FreezeLimit);
+ vac_update_relstats(onerel,
+ vacrelstats->rel_pages, vacrelstats->rel_tuples,
+ vacrelstats->hasindex, FreezeLimit);
/* report results to the stats collector, too */
pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared,
return;
/* now update statistics in pg_class */
- vac_update_relstats(RelationGetRelid(indrel),
- stats->num_pages,
- stats->num_index_tuples,
+ vac_update_relstats(indrel,
+ stats->num_pages, stats->num_index_tuples,
false, InvalidTransactionId);
ereport(elevel,
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/rewrite/rewriteRemove.c,v 1.73 2008/06/19 00:46:05 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/rewrite/rewriteRemove.c,v 1.74 2008/11/10 00:49:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "catalog/pg_rewrite.h"
#include "miscadmin.h"
#include "rewrite/rewriteRemove.h"
-#include "rewrite/rewriteSupport.h"
#include "utils/acl.h"
#include "utils/fmgroids.h"
+#include "utils/inval.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.h"
Relation event_relation;
HeapTuple tuple;
Oid eventRelationOid;
- bool hasMoreRules;
/*
* Open the pg_rewrite relation.
elog(ERROR, "could not find tuple for rule %u", ruleOid);
/*
- * We had better grab AccessExclusiveLock so that we know no other rule
- * additions/deletions are going on for this relation. Else we cannot set
- * relhasrules correctly. Besides, we don't want to be changing the
- * ruleset while queries are executing on the rel.
+ * We had better grab AccessExclusiveLock to ensure that no queries
+ * are going on that might depend on this rule. (Note: a weaker lock
+ * would suffice if it's not an ON SELECT rule.)
*/
eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
event_relation = heap_open(eventRelationOid, AccessExclusiveLock);
- hasMoreRules = event_relation->rd_rules != NULL &&
- event_relation->rd_rules->numLocks > 1;
-
/*
* Now delete the pg_rewrite tuple for the rule
*/
heap_close(RewriteRelation, RowExclusiveLock);
/*
- * Set pg_class 'relhasrules' field correctly for event relation.
- *
- * Important side effect: an SI notice is broadcast to force all backends
- * (including me!) to update relcache entries with the new rule set.
- * Therefore, must do this even if relhasrules is still true!
+ * Issue shared-inval notice to force all backends (including me!) to
+ * update relcache entries with the new rule set.
*/
- SetRelationRuleStatus(eventRelationOid, hasMoreRules, false);
+ CacheInvalidateRelcache(event_relation);
/* Close rel, but keep lock till commit... */
heap_close(event_relation, NoLock);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.275 2008/11/09 21:24:32 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.276 2008/11/10 00:49:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
systable_endscan(rewrite_scan);
heap_close(rewrite_desc, AccessShareLock);
+ /*
+ * there might not be any rules (if relhasrules is out-of-date)
+ */
+ if (numlocks == 0)
+ {
+ relation->rd_rules = NULL;
+ relation->rd_rulescxt = NULL;
+ MemoryContextDelete(rulescxt);
+ return;
+ }
+
/*
* form a RuleLock and insert into relation
*/
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.80 2008/08/13 00:07:50 alvherre Exp $
+ * $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.81 2008/11/10 00:49:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern void vac_open_indexes(Relation relation, LOCKMODE lockmode,
int *nindexes, Relation **Irel);
extern void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode);
-extern void vac_update_relstats(Oid relid,
+extern void vac_update_relstats(Relation relation,
BlockNumber num_pages,
double num_tuples,
bool hasindex,