]> granicus.if.org Git - postgresql/commitdiff
From: Massimo Dal Zotto <dz@cs.unitn.it>
authorMarc G. Fournier <scrappy@hub.org>
Tue, 25 Aug 1998 21:25:46 +0000 (21:25 +0000)
committerMarc G. Fournier <scrappy@hub.org>
Tue, 25 Aug 1998 21:25:46 +0000 (21:25 +0000)
> 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.

src/backend/commands/sequence.c
src/backend/parser/parse_func.c
src/include/catalog/pg_proc.h
src/include/commands/sequence.h

index f28ec52b0099faa18a407e9730b6c0a784e11465..20f9bef503a2de9a98ec2da2adbea1506347867e 100644 (file)
@@ -9,6 +9,7 @@
 #include <string.h>
 
 #include <postgres.h>
+#include <miscadmin.h>
 
 #include <storage/bufmgr.h>
 #include <storage/bufpage.h>
@@ -18,6 +19,7 @@
 #include <commands/creatinh.h>
 #include <commands/sequence.h>
 #include <utils/builtins.h>
+#include <utils/acl.h>
 
 #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
 read_info(char *caller, SeqTable elm, Buffer *buf)
 {
index 4b02a1f344f004cfc1c06b046d476f5bbcd1d682..88871fa3eeff0c3fe55055c24d31b132c3e5d52e 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * 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.
         */
        if (funcid == F_NEXTVAL ||
-               funcid == F_CURRVAL)
+               funcid == F_CURRVAL ||
+               funcid == F_SETVAL)
        {
                Const      *seq;
                char       *seqrel;
@@ -435,7 +436,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
                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);
@@ -445,7 +446,8 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
                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]);
@@ -454,6 +456,8 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
 
                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);
index 902b057f172ebc9186851077b36644a38382f39a..88f304ea1ade4894bff1d59fe330e8b08d0b0447 100644 (file)
@@ -6,7 +6,7 @@
  *
  * 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
@@ -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");
 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 ));
index 2ffa42639b46ac54b004652e20d1b92e4930d5c8..f2186cccda31656b9cfde18a47548c9f00fc309e 100644 (file)
@@ -30,6 +30,7 @@
 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 */