mirror of
https://github.com/postgres/postgres.git
synced 2025-06-14 18:42:34 +03:00
Add a RESTART (without parameter) option to ALTER SEQUENCE, allowing a
sequence to be reset to its original starting value. This requires adding the original start value to the set of parameters (columns) of a sequence object, which is a user-visible change with potential compatibility implications; it also forces initdb. Also add hopefully-SQL-compatible RESTART/CONTINUE IDENTITY options to TRUNCATE TABLE. RESTART IDENTITY executes ALTER SEQUENCE RESTART for all sequences "owned by" any of the truncated relations. CONTINUE IDENTITY is a no-op option. Zoltan Boszormenyi
This commit is contained in:
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user