aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/cluster.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-01-02 23:34:42 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-01-02 23:34:42 +0000
commit20e862155f1000804f9e2ae20b7fbb9a55623951 (patch)
treeaa73bd2379ab9fa89abc9e3ba73e723934fc8b06 /src/backend/commands/cluster.c
parent69528aefbbf2c1bfb68b488fafd08bea390eb3f5 (diff)
downloadpostgresql-20e862155f1000804f9e2ae20b7fbb9a55623951.tar.gz
postgresql-20e862155f1000804f9e2ae20b7fbb9a55623951.zip
Forbid ALTER TABLE and CLUSTER when there are pending AFTER-trigger events
in the current backend for the target table. These operations move tuples around and would thus invalidate the TIDs stored in the trigger event records. (We need not worry about events in other backends, since acquiring exclusive lock should be enough to ensure there aren't any.) It might be sufficient to forbid only the table-rewriting variants of ALTER TABLE, but in the absence of any compelling use-case, let's just be safe and simple. Per follow-on investigation of bug #3847, though this is not actually the same problem reported therein. Possibly this should be back-patched, but since the case has never been reported from the field, I didn't bother.
Diffstat (limited to 'src/backend/commands/cluster.c')
-rw-r--r--src/backend/commands/cluster.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index 9ba6077464a..5176e8d6ace 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.166 2008/01/01 19:45:48 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.167 2008/01/02 23:34:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -30,6 +30,7 @@
#include "catalog/namespace.h"
#include "catalog/toasting.h"
#include "commands/cluster.h"
+#include "commands/trigger.h"
#include "commands/vacuum.h"
#include "miscadmin.h"
#include "storage/procarray.h"
@@ -457,6 +458,17 @@ check_index_is_clusterable(Relation OldHeap, Oid indexOid, bool recheck)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot cluster temporary tables of other sessions")));
+ /*
+ * Also check for pending AFTER trigger events on the relation. We can't
+ * just leave those be, since they will try to fetch tuples that the
+ * CLUSTER has moved to new TIDs.
+ */
+ if (AfterTriggerPendingOnRel(RelationGetRelid(OldHeap)))
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_IN_USE),
+ errmsg("cannot cluster table \"%s\" because it has pending trigger events",
+ RelationGetRelationName(OldHeap))));
+
/* Drop relcache refcnt on OldIndex, but keep lock */
index_close(OldIndex, NoLock);
}