Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 8e9d69d

Browse files
committed
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.
1 parent 88b17d9 commit 8e9d69d

File tree

4 files changed

+60
-5
lines changed

4 files changed

+60
-5
lines changed

src/backend/commands/sequence.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <string.h>
1010

1111
#include <postgres.h>
12+
#include <miscadmin.h>
1213

1314
#include <storage/bufmgr.h>
1415
#include <storage/bufpage.h>
@@ -18,6 +19,7 @@
1819
#include <commands/creatinh.h>
1920
#include <commands/sequence.h>
2021
#include <utils/builtins.h>
22+
#include <utils/acl.h>
2123

2224
#define SEQ_MAGIC 0x1717
2325

@@ -311,6 +313,52 @@ currval(struct varlena * seqin)
311313

312314
}
313315

316+
int4
317+
setval(struct varlena * seqin, int4 next)
318+
{
319+
char *seqname = textout(seqin);
320+
SeqTable elm;
321+
Buffer buf;
322+
SequenceTupleForm seq;
323+
ItemPointerData iptr;
324+
325+
#ifndef NO_SECURITY
326+
if (pg_aclcheck(seqname, getpgusername(), ACL_WR) != ACLCHECK_OK)
327+
elog(ERROR, "%s.setval: you don't have permissions to set sequence %s",
328+
seqname, seqname);
329+
#endif
330+
331+
/* open and WIntentLock sequence */
332+
elm = init_sequence ("setval", seqname);
333+
seq = read_info ("setval", elm, &buf); /* lock page and read tuple */
334+
335+
if ( seq->cache_value != 1 ) {
336+
elog (ERROR, "%s.setval: can't set value of sequence %s, cache != 1",
337+
seqname, seqname);
338+
}
339+
340+
if ((next < seq->min_value) || (next > seq->max_value)) {
341+
elog (ERROR, "%s.setval: value %d is of of bounds (%d,%d)",
342+
seqname, next, seq->min_value, seq->max_value);
343+
}
344+
345+
/* save info in local cache */
346+
elm->last = next; /* last returned number */
347+
elm->cached = next; /* last cached number */
348+
349+
/* save info in sequence relation */
350+
seq->last_value = next; /* last fetched number */
351+
seq->is_called = 't';
352+
353+
if ( WriteBuffer (buf) == STATUS_ERROR )
354+
elog (ERROR, "%s.settval: WriteBuffer failed", seqname);
355+
356+
ItemPointerSet(&iptr, 0, FirstOffsetNumber);
357+
RelationUnsetSingleWLockPage (elm->rel, &iptr);
358+
359+
return (next);
360+
}
361+
314362
static SequenceTupleForm
315363
read_info(char *caller, SeqTable elm, Buffer *buf)
316364
{

src/backend/parser/parse_func.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.25 1998/08/19 02:02:20 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.26 1998/08/25 21:25:42 scrappy Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -427,15 +427,16 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
427427
* Sequence handling.
428428
*/
429429
if (funcid == F_NEXTVAL ||
430-
funcid == F_CURRVAL)
430+
funcid == F_CURRVAL ||
431+
funcid == F_SETVAL)
431432
{
432433
Const *seq;
433434
char *seqrel;
434435
text *seqname;
435436
int32 aclcheck_result = -1;
436437
extern text *lower(text *string);
437438

438-
Assert(length(fargs) == 1);
439+
Assert(length(fargs) == ((funcid == F_SETVAL) ? 2 : 1));
439440
seq = (Const *) lfirst(fargs);
440441
if (!IsA((Node *) seq, Const))
441442
elog(ERROR, "Only constant sequence names are acceptable for function '%s'", funcname);
@@ -445,7 +446,8 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
445446
seqrel = textout(seqname);
446447

447448
if ((aclcheck_result = pg_aclcheck(seqrel, GetPgUserName(),
448-
((funcid == F_NEXTVAL) ? ACL_WR : ACL_RD)))
449+
(((funcid == F_NEXTVAL) || (funcid == F_SETVAL)) ?
450+
ACL_WR : ACL_RD)))
449451
!= ACLCHECK_OK)
450452
elog(ERROR, "%s.%s: %s",
451453
seqrel, funcname, aclcheck_error_strings[aclcheck_result]);
@@ -454,6 +456,8 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
454456

455457
if (funcid == F_NEXTVAL && pstate->p_in_where_clause)
456458
elog(ERROR, "Sequence function nextval is not allowed in WHERE clauses");
459+
if (funcid == F_SETVAL && pstate->p_in_where_clause)
460+
elog(ERROR, "Sequence function setval is not allowed in WHERE clauses");
457461
}
458462

459463
expr = makeNode(Expr);

src/include/catalog/pg_proc.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: pg_proc.h,v 1.67 1998/08/24 01:38:08 momjian Exp $
9+
* $Id: pg_proc.h,v 1.68 1998/08/25 21:25:44 scrappy Exp $
1010
*
1111
* NOTES
1212
* 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
20292029
DESCR("sequence next value");
20302030
DATA(insert OID = 1319 ( currval PGUID 11 f t f 1 f 23 "25" 100 0 0 100 foo bar ));
20312031
DESCR("sequence current value");
2032+
DATA(insert OID = 1618 ( setval PGUID 11 f t f 2 f 23 "25 23" 100 0 0 100 foo bar ));
2033+
DESCR("sequence set value");
20322034

20332035
/* for multi-byte support */
20342036
DATA(insert OID = 1039 ( getdatabaseencoding PGUID 11 f t f 0 f 19 "0" 100 0 0 100 foo bar ));

src/include/commands/sequence.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
extern void DefineSequence(CreateSeqStmt *stmt);
3131
extern int4 nextval(struct varlena * seqname);
3232
extern int4 currval(struct varlena * seqname);
33+
extern int4 setval (struct varlena * seqname, int4 next);
3334
extern void CloseSequences(void);
3435

3536
#endif /* SEQUENCE_H */

0 commit comments

Comments
 (0)