summaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c57
1 files changed, 56 insertions, 1 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 48e229e0fb5..0bef48e07bf 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.253 2008/05/12 00:00:48 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.254 2008/05/16 23:36:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -37,6 +37,7 @@
#include "catalog/toasting.h"
#include "commands/cluster.h"
#include "commands/defrem.h"
+#include "commands/sequence.h"
#include "commands/tablecmds.h"
#include "commands/tablespace.h"
#include "commands/trigger.h"
@@ -531,6 +532,7 @@ ExecuteTruncate(TruncateStmt *stmt)
{
List *rels = NIL;
List *relids = NIL;
+ List *seq_relids = NIL;
EState *estate;
ResultRelInfo *resultRelInfos;
ResultRelInfo *resultRelInfo;
@@ -596,6 +598,40 @@ ExecuteTruncate(TruncateStmt *stmt)
heap_truncate_check_FKs(rels, false);
#endif
+ /*
+ * If we are asked to restart sequences, find all the sequences,
+ * lock them (we only need AccessShareLock because that's all that
+ * ALTER SEQUENCE takes), and check permissions. We want to do this
+ * early since it's pointless to do all the truncation work only to fail
+ * on sequence permissions.
+ */
+ if (stmt->restart_seqs)
+ {
+ foreach(cell, rels)
+ {
+ Relation rel = (Relation) lfirst(cell);
+ List *seqlist = getOwnedSequences(RelationGetRelid(rel));
+ ListCell *seqcell;
+
+ foreach(seqcell, seqlist)
+ {
+ Oid seq_relid = lfirst_oid(seqcell);
+ Relation seq_rel;
+
+ seq_rel = relation_open(seq_relid, AccessShareLock);
+
+ /* This check must match AlterSequence! */
+ if (!pg_class_ownercheck(seq_relid, GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
+ RelationGetRelationName(seq_rel));
+
+ seq_relids = lappend_oid(seq_relids, seq_relid);
+
+ relation_close(seq_rel, NoLock);
+ }
+ }
+ }
+
/* Prepare to catch AFTER triggers. */
AfterTriggerBeginQuery();
@@ -694,6 +730,25 @@ ExecuteTruncate(TruncateStmt *stmt)
heap_close(rel, NoLock);
}
+
+ /*
+ * Lastly, restart any owned sequences if we were asked to. This is done
+ * last because it's nontransactional: restarts will not roll back if
+ * we abort later. Hence it's important to postpone them as long as
+ * possible. (This is also a big reason why we locked and
+ * permission-checked the sequences beforehand.)
+ */
+ if (stmt->restart_seqs)
+ {
+ List *options = list_make1(makeDefElem("restart", NULL));
+
+ foreach(cell, seq_relids)
+ {
+ Oid seq_relid = lfirst_oid(cell);
+
+ AlterSequenceInternal(seq_relid, options);
+ }
+ }
}
/*