mirror of
https://github.com/postgres/postgres.git
synced 2025-06-14 18:42:34 +03:00
From: Massimo Dal Zotto <dz@cs.unitn.it>
> sequence.patch > > adds the missing setval command to sequences. Owner of sequences > can now set the last value to any value between min and max > without recreating the sequence. This is useful after loading > data from external files.
This commit is contained in:
@ -9,6 +9,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <postgres.h>
|
#include <postgres.h>
|
||||||
|
#include <miscadmin.h>
|
||||||
|
|
||||||
#include <storage/bufmgr.h>
|
#include <storage/bufmgr.h>
|
||||||
#include <storage/bufpage.h>
|
#include <storage/bufpage.h>
|
||||||
@ -18,6 +19,7 @@
|
|||||||
#include <commands/creatinh.h>
|
#include <commands/creatinh.h>
|
||||||
#include <commands/sequence.h>
|
#include <commands/sequence.h>
|
||||||
#include <utils/builtins.h>
|
#include <utils/builtins.h>
|
||||||
|
#include <utils/acl.h>
|
||||||
|
|
||||||
#define SEQ_MAGIC 0x1717
|
#define SEQ_MAGIC 0x1717
|
||||||
|
|
||||||
@ -311,6 +313,52 @@ currval(struct varlena * seqin)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int4
|
||||||
|
setval(struct varlena * seqin, int4 next)
|
||||||
|
{
|
||||||
|
char *seqname = textout(seqin);
|
||||||
|
SeqTable elm;
|
||||||
|
Buffer buf;
|
||||||
|
SequenceTupleForm seq;
|
||||||
|
ItemPointerData iptr;
|
||||||
|
|
||||||
|
#ifndef NO_SECURITY
|
||||||
|
if (pg_aclcheck(seqname, getpgusername(), ACL_WR) != ACLCHECK_OK)
|
||||||
|
elog(ERROR, "%s.setval: you don't have permissions to set sequence %s",
|
||||||
|
seqname, seqname);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* open and WIntentLock sequence */
|
||||||
|
elm = init_sequence ("setval", seqname);
|
||||||
|
seq = read_info ("setval", elm, &buf); /* lock page and read tuple */
|
||||||
|
|
||||||
|
if ( seq->cache_value != 1 ) {
|
||||||
|
elog (ERROR, "%s.setval: can't set value of sequence %s, cache != 1",
|
||||||
|
seqname, seqname);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((next < seq->min_value) || (next > seq->max_value)) {
|
||||||
|
elog (ERROR, "%s.setval: value %d is of of bounds (%d,%d)",
|
||||||
|
seqname, next, seq->min_value, seq->max_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save info in local cache */
|
||||||
|
elm->last = next; /* last returned number */
|
||||||
|
elm->cached = next; /* last cached number */
|
||||||
|
|
||||||
|
/* save info in sequence relation */
|
||||||
|
seq->last_value = next; /* last fetched number */
|
||||||
|
seq->is_called = 't';
|
||||||
|
|
||||||
|
if ( WriteBuffer (buf) == STATUS_ERROR )
|
||||||
|
elog (ERROR, "%s.settval: WriteBuffer failed", seqname);
|
||||||
|
|
||||||
|
ItemPointerSet(&iptr, 0, FirstOffsetNumber);
|
||||||
|
RelationUnsetSingleWLockPage (elm->rel, &iptr);
|
||||||
|
|
||||||
|
return (next);
|
||||||
|
}
|
||||||
|
|
||||||
static SequenceTupleForm
|
static SequenceTupleForm
|
||||||
read_info(char *caller, SeqTable elm, Buffer *buf)
|
read_info(char *caller, SeqTable elm, Buffer *buf)
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.25 1998/08/19 02:02:20 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.26 1998/08/25 21:25:42 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -427,7 +427,8 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
|
|||||||
* Sequence handling.
|
* Sequence handling.
|
||||||
*/
|
*/
|
||||||
if (funcid == F_NEXTVAL ||
|
if (funcid == F_NEXTVAL ||
|
||||||
funcid == F_CURRVAL)
|
funcid == F_CURRVAL ||
|
||||||
|
funcid == F_SETVAL)
|
||||||
{
|
{
|
||||||
Const *seq;
|
Const *seq;
|
||||||
char *seqrel;
|
char *seqrel;
|
||||||
@ -435,7 +436,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
|
|||||||
int32 aclcheck_result = -1;
|
int32 aclcheck_result = -1;
|
||||||
extern text *lower(text *string);
|
extern text *lower(text *string);
|
||||||
|
|
||||||
Assert(length(fargs) == 1);
|
Assert(length(fargs) == ((funcid == F_SETVAL) ? 2 : 1));
|
||||||
seq = (Const *) lfirst(fargs);
|
seq = (Const *) lfirst(fargs);
|
||||||
if (!IsA((Node *) seq, Const))
|
if (!IsA((Node *) seq, Const))
|
||||||
elog(ERROR, "Only constant sequence names are acceptable for function '%s'", funcname);
|
elog(ERROR, "Only constant sequence names are acceptable for function '%s'", funcname);
|
||||||
@ -445,7 +446,8 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
|
|||||||
seqrel = textout(seqname);
|
seqrel = textout(seqname);
|
||||||
|
|
||||||
if ((aclcheck_result = pg_aclcheck(seqrel, GetPgUserName(),
|
if ((aclcheck_result = pg_aclcheck(seqrel, GetPgUserName(),
|
||||||
((funcid == F_NEXTVAL) ? ACL_WR : ACL_RD)))
|
(((funcid == F_NEXTVAL) || (funcid == F_SETVAL)) ?
|
||||||
|
ACL_WR : ACL_RD)))
|
||||||
!= ACLCHECK_OK)
|
!= ACLCHECK_OK)
|
||||||
elog(ERROR, "%s.%s: %s",
|
elog(ERROR, "%s.%s: %s",
|
||||||
seqrel, funcname, aclcheck_error_strings[aclcheck_result]);
|
seqrel, funcname, aclcheck_error_strings[aclcheck_result]);
|
||||||
@ -454,6 +456,8 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
|
|||||||
|
|
||||||
if (funcid == F_NEXTVAL && pstate->p_in_where_clause)
|
if (funcid == F_NEXTVAL && pstate->p_in_where_clause)
|
||||||
elog(ERROR, "Sequence function nextval is not allowed in WHERE clauses");
|
elog(ERROR, "Sequence function nextval is not allowed in WHERE clauses");
|
||||||
|
if (funcid == F_SETVAL && pstate->p_in_where_clause)
|
||||||
|
elog(ERROR, "Sequence function setval is not allowed in WHERE clauses");
|
||||||
}
|
}
|
||||||
|
|
||||||
expr = makeNode(Expr);
|
expr = makeNode(Expr);
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_proc.h,v 1.67 1998/08/24 01:38:08 momjian Exp $
|
* $Id: pg_proc.h,v 1.68 1998/08/25 21:25:44 scrappy Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* The script catalog/genbki.sh reads this file and generates .bki
|
* The script catalog/genbki.sh reads this file and generates .bki
|
||||||
@ -2029,6 +2029,8 @@ DATA(insert OID = 1317 ( nextval PGUID 11 f t f 1 f 23 "25" 100 0 0 100 fo
|
|||||||
DESCR("sequence next value");
|
DESCR("sequence next value");
|
||||||
DATA(insert OID = 1319 ( currval PGUID 11 f t f 1 f 23 "25" 100 0 0 100 foo bar ));
|
DATA(insert OID = 1319 ( currval PGUID 11 f t f 1 f 23 "25" 100 0 0 100 foo bar ));
|
||||||
DESCR("sequence current value");
|
DESCR("sequence current value");
|
||||||
|
DATA(insert OID = 1618 ( setval PGUID 11 f t f 2 f 23 "25 23" 100 0 0 100 foo bar ));
|
||||||
|
DESCR("sequence set value");
|
||||||
|
|
||||||
/* for multi-byte support */
|
/* for multi-byte support */
|
||||||
DATA(insert OID = 1039 ( getdatabaseencoding PGUID 11 f t f 0 f 19 "0" 100 0 0 100 foo bar ));
|
DATA(insert OID = 1039 ( getdatabaseencoding PGUID 11 f t f 0 f 19 "0" 100 0 0 100 foo bar ));
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
extern void DefineSequence(CreateSeqStmt *stmt);
|
extern void DefineSequence(CreateSeqStmt *stmt);
|
||||||
extern int4 nextval(struct varlena * seqname);
|
extern int4 nextval(struct varlena * seqname);
|
||||||
extern int4 currval(struct varlena * seqname);
|
extern int4 currval(struct varlena * seqname);
|
||||||
|
extern int4 setval (struct varlena * seqname, int4 next);
|
||||||
extern void CloseSequences(void);
|
extern void CloseSequences(void);
|
||||||
|
|
||||||
#endif /* SEQUENCE_H */
|
#endif /* SEQUENCE_H */
|
||||||
|
Reference in New Issue
Block a user