#include <string.h>
#include <postgres.h>
+#include <miscadmin.h>
#include <storage/bufmgr.h>
#include <storage/bufpage.h>
#include <commands/creatinh.h>
#include <commands/sequence.h>
#include <utils/builtins.h>
+#include <utils/acl.h>
#define SEQ_MAGIC 0x1717
}
+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
read_info(char *caller, SeqTable elm, Buffer *buf)
{
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
* Sequence handling.
*/
if (funcid == F_NEXTVAL ||
- funcid == F_CURRVAL)
+ funcid == F_CURRVAL ||
+ funcid == F_SETVAL)
{
Const *seq;
char *seqrel;
int32 aclcheck_result = -1;
extern text *lower(text *string);
- Assert(length(fargs) == 1);
+ Assert(length(fargs) == ((funcid == F_SETVAL) ? 2 : 1));
seq = (Const *) lfirst(fargs);
if (!IsA((Node *) seq, Const))
elog(ERROR, "Only constant sequence names are acceptable for function '%s'", funcname);
seqrel = textout(seqname);
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)
elog(ERROR, "%s.%s: %s",
seqrel, funcname, aclcheck_error_strings[aclcheck_result]);
if (funcid == F_NEXTVAL && pstate->p_in_where_clause)
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);
*
* 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
* The script catalog/genbki.sh reads this file and generates .bki
DESCR("sequence next value");
DATA(insert OID = 1319 ( currval PGUID 11 f t f 1 f 23 "25" 100 0 0 100 foo bar ));
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 */
DATA(insert OID = 1039 ( getdatabaseencoding PGUID 11 f t f 0 f 19 "0" 100 0 0 100 foo bar ));
extern void DefineSequence(CreateSeqStmt *stmt);
extern int4 nextval(struct varlena * seqname);
extern int4 currval(struct varlena * seqname);
+extern int4 setval (struct varlena * seqname, int4 next);
extern void CloseSequences(void);
#endif /* SEQUENCE_H */