PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
sequence.h File Reference
#include "access/xlogreader.h"
#include "catalog/objectaddress.h"
#include "fmgr.h"
#include "lib/stringinfo.h"
#include "nodes/parsenodes.h"
#include "parser/parse_node.h"
#include "storage/relfilenode.h"
Include dependency graph for sequence.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  FormData_pg_sequence_data
 
struct  xl_seq_rec
 

Macros

#define SEQ_COL_LASTVAL   1
 
#define SEQ_COL_LOG   2
 
#define SEQ_COL_CALLED   3
 
#define SEQ_COL_FIRSTCOL   SEQ_COL_LASTVAL
 
#define SEQ_COL_LASTCOL   SEQ_COL_CALLED
 
#define XLOG_SEQ_LOG   0x00
 

Typedefs

typedef struct
FormData_pg_sequence_data 
FormData_pg_sequence_data
 
typedef FormData_pg_sequence_dataForm_pg_sequence_data
 
typedef struct xl_seq_rec xl_seq_rec
 

Functions

Datum nextval (PG_FUNCTION_ARGS)
 
ObjectAddress DefineSequence (ParseState *pstate, CreateSeqStmt *stmt)
 
ObjectAddress AlterSequence (ParseState *pstate, AlterSeqStmt *stmt)
 
void DeleteSequenceTuple (Oid relid)
 
void ResetSequence (Oid seq_relid)
 
void ResetSequenceCaches (void)
 
void seq_redo (XLogReaderState *rptr)
 
void seq_desc (StringInfo buf, XLogReaderState *rptr)
 
const char * seq_identify (uint8 info)
 
void seq_mask (char *pagedata, BlockNumber blkno)
 

Macro Definition Documentation

#define SEQ_COL_CALLED   3

Definition at line 40 of file sequence.h.

Referenced by DefineSequence().

#define SEQ_COL_FIRSTCOL   SEQ_COL_LASTVAL

Definition at line 42 of file sequence.h.

Referenced by DefineSequence().

#define SEQ_COL_LASTCOL   SEQ_COL_CALLED

Definition at line 43 of file sequence.h.

Referenced by DefineSequence().

#define SEQ_COL_LASTVAL   1

Definition at line 38 of file sequence.h.

Referenced by DefineSequence().

#define SEQ_COL_LOG   2

Definition at line 39 of file sequence.h.

Referenced by DefineSequence().

#define XLOG_SEQ_LOG   0x00

Typedef Documentation

Function Documentation

ObjectAddress AlterSequence ( ParseState pstate,
AlterSeqStmt stmt 
)

Definition at line 410 of file sequence.c.

References AccessShareLock, ACL_KIND_CLASS, aclcheck_error(), ACLCHECK_NOT_OWNER, buf, BufferGetPage, SeqTableData::cached, CatalogTupleUpdate(), elog, END_CRIT_SECTION, ereport, errmsg(), ERROR, GETSTRUCT, GetTopTransactionId(), GetUserId(), heap_close, heap_open(), HeapTupleIsValid, init_params(), init_sequence(), InvalidObjectAddress, InvalidOid, InvokeObjectPostAlterHook, SeqTableData::last, MarkBufferDirty(), AlterSeqStmt::missing_ok, xl_seq_rec::node, NoLock, NOTICE, ObjectAddressSet, ObjectIdGetDatum, AlterSeqStmt::options, PageSetLSN, pg_class_ownercheck(), process_owned_by(), RangeVarGetRelid, RelationData::rd_node, read_seq_tuple(), REGBUF_WILL_INIT, relation_close(), RelationNeedsWAL, RelationRelationId, RangeVar::relname, RowExclusiveLock, SearchSysCacheCopy1, SEQRELID, AlterSeqStmt::sequence, SequenceRelationId, START_CRIT_SECTION, HeapTupleData::t_data, HeapTupleData::t_len, HeapTupleData::t_self, UnlockReleaseBuffer(), XLOG_SEQ_LOG, XLogBeginInsert(), XLogInsert(), XLogRegisterBuffer(), and XLogRegisterData().

Referenced by ProcessUtilitySlow().

411 {
412  Oid relid;
413  SeqTable elm;
414  Relation seqrel;
415  Buffer buf;
416  HeapTupleData seqdatatuple;
417  Form_pg_sequence seqform;
418  Form_pg_sequence_data seqdata;
419  FormData_pg_sequence_data newseqdata;
420  List *owned_by;
421  ObjectAddress address;
422  Relation rel;
423  HeapTuple tuple;
424 
425  /* Open and lock sequence. */
426  relid = RangeVarGetRelid(stmt->sequence, AccessShareLock, stmt->missing_ok);
427  if (relid == InvalidOid)
428  {
429  ereport(NOTICE,
430  (errmsg("relation \"%s\" does not exist, skipping",
431  stmt->sequence->relname)));
432  return InvalidObjectAddress;
433  }
434 
435  init_sequence(relid, &elm, &seqrel);
436 
437  /* allow ALTER to sequence owner only */
438  if (!pg_class_ownercheck(relid, GetUserId()))
440  stmt->sequence->relname);
441 
442  /* lock page' buffer and read tuple into new sequence structure */
443  seqdata = read_seq_tuple(seqrel, &buf, &seqdatatuple);
444 
445  /* Copy old values of options into workspace */
446  memcpy(&newseqdata, seqdata, sizeof(FormData_pg_sequence_data));
447 
450  ObjectIdGetDatum(relid));
451  if (!HeapTupleIsValid(tuple))
452  elog(ERROR, "cache lookup failed for sequence %u",
453  relid);
454 
455  seqform = (Form_pg_sequence) GETSTRUCT(tuple);
456 
457  /* Check and set new values */
458  init_params(pstate, stmt->options, false, seqform, &newseqdata, &owned_by);
459 
460  /* Clear local cache so that we don't think we have cached numbers */
461  /* Note that we do not change the currval() state */
462  elm->cached = elm->last;
463 
464  /* check the comment above nextval_internal()'s equivalent call. */
465  if (RelationNeedsWAL(seqrel))
467 
468  /* Now okay to update the on-disk tuple */
470 
471  memcpy(seqdata, &newseqdata, sizeof(FormData_pg_sequence_data));
472 
473  MarkBufferDirty(buf);
474 
475  /* XLOG stuff */
476  if (RelationNeedsWAL(seqrel))
477  {
478  xl_seq_rec xlrec;
479  XLogRecPtr recptr;
480  Page page = BufferGetPage(buf);
481 
482  XLogBeginInsert();
484 
485  xlrec.node = seqrel->rd_node;
486  XLogRegisterData((char *) &xlrec, sizeof(xl_seq_rec));
487 
488  XLogRegisterData((char *) seqdatatuple.t_data, seqdatatuple.t_len);
489 
490  recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG);
491 
492  PageSetLSN(page, recptr);
493  }
494 
496 
497  UnlockReleaseBuffer(buf);
498 
499  /* process OWNED BY if given */
500  if (owned_by)
501  process_owned_by(seqrel, owned_by);
502 
504 
505  ObjectAddressSet(address, RelationRelationId, relid);
506 
507  relation_close(seqrel, NoLock);
508 
509  CatalogTupleUpdate(rel, &tuple->t_self, tuple);
511 
512  return address;
513 }
int64 cached
Definition: sequence.c:79
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
Oid GetUserId(void)
Definition: miscinit.c:283
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:1445
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
Definition: xloginsert.c:213
#define RangeVarGetRelid(relation, lockmode, missing_ok)
Definition: namespace.h:53
#define RelationRelationId
Definition: pg_class.h:29
#define END_CRIT_SECTION()
Definition: miscadmin.h:132
#define AccessShareLock
Definition: lockdefs.h:36
#define REGBUF_WILL_INIT
Definition: xloginsert.h:32
#define START_CRIT_SECTION()
Definition: miscadmin.h:130
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1263
#define SequenceRelationId
Definition: pg_sequence.h:6
FormData_pg_sequence * Form_pg_sequence
Definition: pg_sequence.h:20
#define heap_close(r, l)
Definition: heapam.h:97
TransactionId GetTopTransactionId(void)
Definition: xact.c:388
RelFileNode node
Definition: sequence.h:50
unsigned int Oid
Definition: postgres_ext.h:31
static void process_owned_by(Relation seqrel, List *owned_by)
Definition: sequence.c:1568
List * options
Definition: parsenodes.h:2367
HeapTupleHeader t_data
Definition: htup.h:67
char * relname
Definition: primnodes.h:67
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3315
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
#define NoLock
Definition: lockdefs.h:34
static char * buf
Definition: pg_test_fsync.c:65
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3378
#define RowExclusiveLock
Definition: lockdefs.h:38
int64 last
Definition: sequence.c:78
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
static Form_pg_sequence_data read_seq_tuple(Relation rel, Buffer *buf, HeapTuple seqdatatuple)
Definition: sequence.c:1167
static void init_params(ParseState *pstate, List *options, bool isInit, Form_pg_sequence seqform, Form_pg_sequence_data seqdataform, List **owned_by)
Definition: sequence.c:1222
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define InvalidOid
Definition: postgres_ext.h:36
RangeVar * sequence
Definition: parsenodes.h:2366
#define NOTICE
Definition: elog.h:37
RelFileNode rd_node
Definition: rel.h:85
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
uint64 XLogRecPtr
Definition: xlogdefs.h:21
bool pg_class_ownercheck(Oid class_oid, Oid roleid)
Definition: aclchk.c:4521
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define RelationNeedsWAL(relation)
Definition: rel.h:502
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:158
static void init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel)
Definition: sequence.c:1100
const ObjectAddress InvalidObjectAddress
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
#define XLOG_SEQ_LOG
Definition: sequence.h:46
void XLogBeginInsert(void)
Definition: xloginsert.c:120
#define PageSetLSN(page, lsn)
Definition: bufpage.h:365
Definition: pg_list.h:45
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
ObjectAddress DefineSequence ( ParseState pstate,
CreateSeqStmt stmt 
)

Definition at line 114 of file sequence.c.

References AccessExclusiveLock, Anum_pg_sequence_seqcache, Anum_pg_sequence_seqcycle, Anum_pg_sequence_seqincrement, Anum_pg_sequence_seqmax, Anum_pg_sequence_seqmin, Anum_pg_sequence_seqrelid, Anum_pg_sequence_seqstart, Anum_pg_sequence_seqtypid, Assert, BoolGetDatum, BOOLOID, CatalogTupleInsert(), ColumnDef::collClause, ColumnDef::collOid, ColumnDef::colname, ColumnDef::constraints, CreateStmt::constraints, ColumnDef::cooked_default, DefineRelation(), ereport, errcode(), errmsg(), ERROR, fill_seq_with_data(), FormData_pg_sequence, heap_close, heap_form_tuple(), heap_freetuple(), heap_open(), i, CreateStmt::if_not_exists, CreateSeqStmt::if_not_exists, ColumnDef::inhcount, CreateStmt::inhRelations, init_params(), Int64GetDatum(), Int64GetDatumFast, INT8OID, InvalidObjectAddress, InvalidOid, ColumnDef::is_from_type, ColumnDef::is_local, ColumnDef::is_not_null, lappend(), FormData_pg_sequence_data::last_value, ColumnDef::location, makeNode, makeTypeNameFromOid(), Natts_pg_sequence, NIL, NoLock, NOTICE, NULL, ObjectAddress::objectId, ObjectIdGetDatum, OidIsValid, CreateStmt::oncommit, ONCOMMIT_NOOP, CreateStmt::options, CreateSeqStmt::options, CreateSeqStmt::ownerId, process_owned_by(), RangeVarGetAndCheckCreationNamespace(), ColumnDef::raw_default, CreateStmt::relation, RelationGetDescr, RELKIND_SEQUENCE, RangeVar::relname, RangeVar::relpersistence, RELPERSISTENCE_UNLOGGED, RowExclusiveLock, SEQ_COL_CALLED, SEQ_COL_FIRSTCOL, SEQ_COL_LASTCOL, SEQ_COL_LASTVAL, SEQ_COL_LOG, CreateSeqStmt::sequence, SequenceRelationId, ColumnDef::storage, CreateStmt::tableElts, CreateStmt::tablespacename, ColumnDef::typeName, and value.

Referenced by ProcessUtilitySlow().

115 {
116  FormData_pg_sequence seqform;
117  FormData_pg_sequence_data seqdataform;
118  List *owned_by;
119  CreateStmt *stmt = makeNode(CreateStmt);
120  Oid seqoid;
121  ObjectAddress address;
122  Relation rel;
123  HeapTuple tuple;
124  TupleDesc tupDesc;
126  bool null[SEQ_COL_LASTCOL];
127  Datum pgs_values[Natts_pg_sequence];
128  bool pgs_nulls[Natts_pg_sequence];
129  int i;
130 
131  /* Unlogged sequences are not implemented -- not clear if useful. */
132  if (seq->sequence->relpersistence == RELPERSISTENCE_UNLOGGED)
133  ereport(ERROR,
134  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
135  errmsg("unlogged sequences are not supported")));
136 
137  /*
138  * If if_not_exists was given and a relation with the same name already
139  * exists, bail out. (Note: we needn't check this when not if_not_exists,
140  * because DefineRelation will complain anyway.)
141  */
142  if (seq->if_not_exists)
143  {
144  RangeVarGetAndCheckCreationNamespace(seq->sequence, NoLock, &seqoid);
145  if (OidIsValid(seqoid))
146  {
147  ereport(NOTICE,
148  (errcode(ERRCODE_DUPLICATE_TABLE),
149  errmsg("relation \"%s\" already exists, skipping",
150  seq->sequence->relname)));
151  return InvalidObjectAddress;
152  }
153  }
154 
155  /* Check and set all option values */
156  init_params(pstate, seq->options, true, &seqform, &seqdataform, &owned_by);
157 
158  /*
159  * Create relation (and fill value[] and null[] for the tuple)
160  */
161  stmt->tableElts = NIL;
162  for (i = SEQ_COL_FIRSTCOL; i <= SEQ_COL_LASTCOL; i++)
163  {
164  ColumnDef *coldef = makeNode(ColumnDef);
165 
166  coldef->inhcount = 0;
167  coldef->is_local = true;
168  coldef->is_not_null = true;
169  coldef->is_from_type = false;
170  coldef->storage = 0;
171  coldef->raw_default = NULL;
172  coldef->cooked_default = NULL;
173  coldef->collClause = NULL;
174  coldef->collOid = InvalidOid;
175  coldef->constraints = NIL;
176  coldef->location = -1;
177 
178  null[i - 1] = false;
179 
180  switch (i)
181  {
182  case SEQ_COL_LASTVAL:
183  coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
184  coldef->colname = "last_value";
185  value[i - 1] = Int64GetDatumFast(seqdataform.last_value);
186  break;
187  case SEQ_COL_LOG:
188  coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
189  coldef->colname = "log_cnt";
190  value[i - 1] = Int64GetDatum((int64) 0);
191  break;
192  case SEQ_COL_CALLED:
193  coldef->typeName = makeTypeNameFromOid(BOOLOID, -1);
194  coldef->colname = "is_called";
195  value[i - 1] = BoolGetDatum(false);
196  break;
197  }
198  stmt->tableElts = lappend(stmt->tableElts, coldef);
199  }
200 
201  stmt->relation = seq->sequence;
202  stmt->inhRelations = NIL;
203  stmt->constraints = NIL;
204  stmt->options = NIL;
205  stmt->oncommit = ONCOMMIT_NOOP;
206  stmt->tablespacename = NULL;
207  stmt->if_not_exists = seq->if_not_exists;
208 
209  address = DefineRelation(stmt, RELKIND_SEQUENCE, seq->ownerId, NULL, NULL);
210  seqoid = address.objectId;
211  Assert(seqoid != InvalidOid);
212 
213  rel = heap_open(seqoid, AccessExclusiveLock);
214  tupDesc = RelationGetDescr(rel);
215 
216  /* now initialize the sequence's data */
217  tuple = heap_form_tuple(tupDesc, value, null);
218  fill_seq_with_data(rel, tuple);
219 
220  /* process OWNED BY if given */
221  if (owned_by)
222  process_owned_by(rel, owned_by);
223 
224  heap_close(rel, NoLock);
225 
226  /* fill in pg_sequence */
228  tupDesc = RelationGetDescr(rel);
229 
230  memset(pgs_nulls, 0, sizeof(pgs_nulls));
231 
232  pgs_values[Anum_pg_sequence_seqrelid - 1] = ObjectIdGetDatum(seqoid);
233  pgs_values[Anum_pg_sequence_seqtypid - 1] = ObjectIdGetDatum(seqform.seqtypid);
234  pgs_values[Anum_pg_sequence_seqstart - 1] = Int64GetDatumFast(seqform.seqstart);
235  pgs_values[Anum_pg_sequence_seqincrement - 1] = Int64GetDatumFast(seqform.seqincrement);
236  pgs_values[Anum_pg_sequence_seqmax - 1] = Int64GetDatumFast(seqform.seqmax);
237  pgs_values[Anum_pg_sequence_seqmin - 1] = Int64GetDatumFast(seqform.seqmin);
238  pgs_values[Anum_pg_sequence_seqcache - 1] = Int64GetDatumFast(seqform.seqcache);
239  pgs_values[Anum_pg_sequence_seqcycle - 1] = BoolGetDatum(seqform.seqcycle);
240 
241  tuple = heap_form_tuple(tupDesc, pgs_values, pgs_nulls);
242  CatalogTupleInsert(rel, tuple);
243 
244  heap_freetuple(tuple);
246 
247  return address;
248 }
RangeVar * relation
Definition: parsenodes.h:1894
#define NIL
Definition: pg_list.h:69
OnCommitAction oncommit
Definition: parsenodes.h:1903
List * inhRelations
Definition: parsenodes.h:1896
static struct @76 value
char storage
Definition: parsenodes.h:604
#define RELPERSISTENCE_UNLOGGED
Definition: pg_class.h:171
bool is_local
Definition: parsenodes.h:601
#define RelationGetDescr(relation)
Definition: rel.h:425
List * constraints
Definition: parsenodes.h:609
#define Anum_pg_sequence_seqcache
Definition: pg_sequence.h:29
int errcode(int sqlerrcode)
Definition: elog.c:575
#define SequenceRelationId
Definition: pg_sequence.h:6
#define SEQ_COL_FIRSTCOL
Definition: sequence.h:42
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
#define heap_close(r, l)
Definition: heapam.h:97
bool is_not_null
Definition: parsenodes.h:602
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:533
#define Anum_pg_sequence_seqtypid
Definition: pg_sequence.h:24
static void process_owned_by(Relation seqrel, List *owned_by)
Definition: sequence.c:1568
List * constraints
Definition: parsenodes.h:1901
bool if_not_exists
Definition: parsenodes.h:1905
Node * cooked_default
Definition: parsenodes.h:606
#define SEQ_COL_LASTVAL
Definition: sequence.h:38
FormData_pg_sequence
Definition: pg_sequence.h:18
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
#define Natts_pg_sequence
Definition: pg_sequence.h:22
#define NoLock
Definition: lockdefs.h:34
Oid collOid
Definition: parsenodes.h:608
#define RowExclusiveLock
Definition: lockdefs.h:38
List * options
Definition: parsenodes.h:1902
int location
Definition: parsenodes.h:611
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:2102
ObjectAddress DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ObjectAddress *typaddress, const char *queryString)
Definition: tablecmds.c:481
#define ereport(elevel, rest)
Definition: elog.h:122
#define SEQ_COL_LOG
Definition: sequence.h:39
Node * raw_default
Definition: parsenodes.h:605
static void init_params(ParseState *pstate, List *options, bool isInit, Form_pg_sequence seqform, Form_pg_sequence_data seqdataform, List **owned_by)
Definition: sequence.c:1222
List * lappend(List *list, void *datum)
Definition: list.c:128
char * tablespacename
Definition: parsenodes.h:1904
Oid RangeVarGetAndCheckCreationNamespace(RangeVar *relation, LOCKMODE lockmode, Oid *existing_relation_id)
Definition: namespace.c:507
uintptr_t Datum
Definition: postgres.h:374
#define Anum_pg_sequence_seqmin
Definition: pg_sequence.h:28
#define Anum_pg_sequence_seqcycle
Definition: pg_sequence.h:30
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define Int64GetDatumFast(X)
Definition: postgres.h:783
#define BoolGetDatum(X)
Definition: postgres.h:410
TypeName * makeTypeNameFromOid(Oid typeOid, int32 typmod)
Definition: makefuncs.c:469
#define InvalidOid
Definition: postgres_ext.h:36
bool is_from_type
Definition: parsenodes.h:603
#define NOTICE
Definition: elog.h:37
#define INT8OID
Definition: pg_type.h:304
List * tableElts
Definition: parsenodes.h:1895
#define makeNode(_type_)
Definition: nodes.h:556
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
TypeName * typeName
Definition: parsenodes.h:599
CollateClause * collClause
Definition: parsenodes.h:607
#define Anum_pg_sequence_seqstart
Definition: pg_sequence.h:25
#define BOOLOID
Definition: pg_type.h:288
#define SEQ_COL_LASTCOL
Definition: sequence.h:43
#define AccessExclusiveLock
Definition: lockdefs.h:46
const ObjectAddress InvalidObjectAddress
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define SEQ_COL_CALLED
Definition: sequence.h:40
#define Anum_pg_sequence_seqrelid
Definition: pg_sequence.h:23
int i
int inhcount
Definition: parsenodes.h:600
char * colname
Definition: parsenodes.h:598
#define Anum_pg_sequence_seqincrement
Definition: pg_sequence.h:26
#define Anum_pg_sequence_seqmax
Definition: pg_sequence.h:27
#define RELKIND_SEQUENCE
Definition: pg_class.h:162
Definition: pg_list.h:45
static void fill_seq_with_data(Relation rel, HeapTuple tuple)
Definition: sequence.c:331
void DeleteSequenceTuple ( Oid  relid)

Definition at line 516 of file sequence.c.

References CatalogTupleDelete(), elog, ERROR, heap_close, heap_open(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1, SEQRELID, SequenceRelationId, and HeapTupleData::t_self.

Referenced by doDeletion().

517 {
518  Relation rel;
519  HeapTuple tuple;
520 
522 
523  tuple = SearchSysCache1(SEQRELID, ObjectIdGetDatum(relid));
524  if (!HeapTupleIsValid(tuple))
525  elog(ERROR, "cache lookup failed for sequence %u", relid);
526 
527  CatalogTupleDelete(rel, &tuple->t_self);
528 
529  ReleaseSysCache(tuple);
531 }
#define SequenceRelationId
Definition: pg_sequence.h:6
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define elog
Definition: elog.h:219
Datum nextval ( PG_FUNCTION_ARGS  )

Definition at line 539 of file sequence.c.

References makeRangeVarFromNameList(), nextval_internal(), NoLock, PG_GETARG_TEXT_P, PG_RETURN_INT64, RangeVarGetRelid, and textToQualifiedNameList().

Referenced by autoinc(), and ttdummy().

540 {
541  text *seqin = PG_GETARG_TEXT_P(0);
542  RangeVar *sequence;
543  Oid relid;
544 
546 
547  /*
548  * XXX: This is not safe in the presence of concurrent DDL, but acquiring
549  * a lock here is more expensive than letting nextval_internal do it,
550  * since the latter maintains a cache that keeps us from hitting the lock
551  * manager more than once per transaction. It's not clear whether the
552  * performance penalty is material in practice, but for now, we do it this
553  * way.
554  */
555  relid = RangeVarGetRelid(sequence, NoLock, false);
556 
558 }
#define PG_RETURN_INT64(x)
Definition: fmgr.h:311
#define RangeVarGetRelid(relation, lockmode, missing_ok)
Definition: namespace.h:53
RangeVar * makeRangeVarFromNameList(List *names)
Definition: namespace.c:2857
unsigned int Oid
Definition: postgres_ext.h:31
#define NoLock
Definition: lockdefs.h:34
List * textToQualifiedNameList(text *textval)
Definition: varlena.c:3071
#define PG_GETARG_TEXT_P(n)
Definition: fmgr.h:269
Definition: c.h:434
static int64 nextval_internal(Oid relid)
Definition: sequence.c:569
void ResetSequence ( Oid  seq_relid)

Definition at line 263 of file sequence.c.

References buf, SeqTableData::cached, elog, ERROR, fill_seq_with_data(), GETSTRUCT, heap_copytuple(), HeapTupleIsValid, init_sequence(), InvalidMultiXactId, InvalidTransactionId, FormData_pg_sequence_data::is_called, SeqTableData::last, FormData_pg_sequence_data::last_value, FormData_pg_sequence_data::log_cnt, NoLock, ObjectIdGetDatum, RelationData::rd_rel, read_seq_tuple(), relation_close(), RelationSetNewRelfilenode(), ReleaseSysCache(), SearchSysCache1, SEQRELID, and UnlockReleaseBuffer().

Referenced by ExecuteTruncate().

264 {
265  Relation seq_rel;
266  SeqTable elm;
268  Buffer buf;
269  HeapTupleData seqdatatuple;
270  HeapTuple tuple;
271  HeapTuple pgstuple;
272  Form_pg_sequence pgsform;
273  int64 startv;
274 
275  /*
276  * Read the old sequence. This does a bit more work than really
277  * necessary, but it's simple, and we do want to double-check that it's
278  * indeed a sequence.
279  */
280  init_sequence(seq_relid, &elm, &seq_rel);
281  (void) read_seq_tuple(seq_rel, &buf, &seqdatatuple);
282 
283  pgstuple = SearchSysCache1(SEQRELID, ObjectIdGetDatum(seq_relid));
284  if (!HeapTupleIsValid(pgstuple))
285  elog(ERROR, "cache lookup failed for sequence %u", seq_relid);
286  pgsform = (Form_pg_sequence) GETSTRUCT(pgstuple);
287  startv = pgsform->seqstart;
288  ReleaseSysCache(pgstuple);
289 
290  /*
291  * Copy the existing sequence tuple.
292  */
293  tuple = heap_copytuple(&seqdatatuple);
294 
295  /* Now we're done with the old page */
296  UnlockReleaseBuffer(buf);
297 
298  /*
299  * Modify the copied tuple to execute the restart (compare the RESTART
300  * action in AlterSequence)
301  */
302  seq = (Form_pg_sequence_data) GETSTRUCT(tuple);
303  seq->last_value = startv;
304  seq->is_called = false;
305  seq->log_cnt = 0;
306 
307  /*
308  * Create a new storage file for the sequence. We want to keep the
309  * sequence's relfrozenxid at 0, since it won't contain any unfrozen XIDs.
310  * Same with relminmxid, since a sequence will never contain multixacts.
311  */
312  RelationSetNewRelfilenode(seq_rel, seq_rel->rd_rel->relpersistence,
314 
315  /*
316  * Insert the modified tuple into the new storage file.
317  */
318  fill_seq_with_data(seq_rel, tuple);
319 
320  /* Clear local cache so that we don't think we have cached numbers */
321  /* Note that we do not change the currval() state */
322  elm->cached = elm->last;
323 
324  relation_close(seq_rel, NoLock);
325 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:608
int64 cached
Definition: sequence.c:79
void RelationSetNewRelfilenode(Relation relation, char persistence, TransactionId freezeXid, MultiXactId minmulti)
Definition: relcache.c:3414
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1263
FormData_pg_sequence * Form_pg_sequence
Definition: pg_sequence.h:20
Form_pg_class rd_rel
Definition: rel.h:113
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3315
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define NoLock
Definition: lockdefs.h:34
static char * buf
Definition: pg_test_fsync.c:65
#define InvalidTransactionId
Definition: transam.h:31
int64 last
Definition: sequence.c:78
static Form_pg_sequence_data read_seq_tuple(Relation rel, Buffer *buf, HeapTuple seqdatatuple)
Definition: sequence.c:1167
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
#define InvalidMultiXactId
Definition: multixact.h:23
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
static void init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel)
Definition: sequence.c:1100
#define elog
Definition: elog.h:219
int Buffer
Definition: buf.h:23
static void fill_seq_with_data(Relation rel, HeapTuple tuple)
Definition: sequence.c:331
FormData_pg_sequence_data * Form_pg_sequence_data
Definition: sequence.h:32
void ResetSequenceCaches ( void  )

Definition at line 1807 of file sequence.c.

References hash_destroy(), and NULL.

Referenced by DiscardAll(), and DiscardCommand().

1808 {
1809  if (seqhashtab)
1810  {
1812  seqhashtab = NULL;
1813  }
1814 
1815  last_used_seq = NULL;
1816 }
void hash_destroy(HTAB *hashp)
Definition: dynahash.c:793
static HTAB * seqhashtab
Definition: sequence.c:87
#define NULL
Definition: c.h:226
static SeqTableData * last_used_seq
Definition: sequence.c:93
void seq_desc ( StringInfo  buf,
XLogReaderState rptr 
)

Definition at line 21 of file seqdesc.c.

References appendStringInfo(), RelFileNode::dbNode, xl_seq_rec::node, RelFileNode::relNode, RelFileNode::spcNode, XLOG_SEQ_LOG, XLogRecGetData, XLogRecGetInfo, and XLR_INFO_MASK.

22 {
23  char *rec = XLogRecGetData(record);
24  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
25  xl_seq_rec *xlrec = (xl_seq_rec *) rec;
26 
27  if (info == XLOG_SEQ_LOG)
28  appendStringInfo(buf, "rel %u/%u/%u",
29  xlrec->node.spcNode, xlrec->node.dbNode,
30  xlrec->node.relNode);
31 }
unsigned char uint8
Definition: c.h:263
RelFileNode node
Definition: sequence.h:50
#define XLogRecGetData(decoder)
Definition: xlogreader.h:202
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:198
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
#define XLOG_SEQ_LOG
Definition: sequence.h:46
const char* seq_identify ( uint8  info)

Definition at line 34 of file seqdesc.c.

References NULL, XLOG_SEQ_LOG, and XLR_INFO_MASK.

35 {
36  const char *id = NULL;
37 
38  switch (info & ~XLR_INFO_MASK)
39  {
40  case XLOG_SEQ_LOG:
41  id = "LOG";
42  break;
43  }
44 
45  return id;
46 }
#define NULL
Definition: c.h:226
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
#define XLOG_SEQ_LOG
Definition: sequence.h:46
void seq_mask ( char *  pagedata,
BlockNumber  blkno 
)

Definition at line 1822 of file sequence.c.

References mask_page_lsn(), and mask_unused_space().

1823 {
1824  mask_page_lsn(page);
1825 
1826  mask_unused_space(page);
1827 }
void mask_unused_space(Page page)
Definition: bufmask.c:69
void mask_page_lsn(Page page)
Definition: bufmask.c:30
void seq_redo ( XLogReaderState rptr)

Definition at line 1754 of file sequence.c.

References BufferGetPage, BufferGetPageSize, elog, XLogReaderState::EndRecPtr, FirstOffsetNumber, InvalidOffsetNumber, sequence_magic::magic, MarkBufferDirty(), PageAddItem, PageGetSpecialPointer, PageInit(), PageSetLSN, palloc(), PANIC, pfree(), SEQ_MAGIC, UnlockReleaseBuffer(), XLOG_SEQ_LOG, XLogInitBufferForRedo(), XLogRecGetData, XLogRecGetDataLen, XLogRecGetInfo, and XLR_INFO_MASK.

1755 {
1756  XLogRecPtr lsn = record->EndRecPtr;
1757  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
1758  Buffer buffer;
1759  Page page;
1760  Page localpage;
1761  char *item;
1762  Size itemsz;
1763  xl_seq_rec *xlrec = (xl_seq_rec *) XLogRecGetData(record);
1764  sequence_magic *sm;
1765 
1766  if (info != XLOG_SEQ_LOG)
1767  elog(PANIC, "seq_redo: unknown op code %u", info);
1768 
1769  buffer = XLogInitBufferForRedo(record, 0);
1770  page = (Page) BufferGetPage(buffer);
1771 
1772  /*
1773  * We always reinit the page. However, since this WAL record type is also
1774  * used for updating sequences, it's possible that a hot-standby backend
1775  * is examining the page concurrently; so we mustn't transiently trash the
1776  * buffer. The solution is to build the correct new page contents in
1777  * local workspace and then memcpy into the buffer. Then only bytes that
1778  * are supposed to change will change, even transiently. We must palloc
1779  * the local page for alignment reasons.
1780  */
1781  localpage = (Page) palloc(BufferGetPageSize(buffer));
1782 
1783  PageInit(localpage, BufferGetPageSize(buffer), sizeof(sequence_magic));
1784  sm = (sequence_magic *) PageGetSpecialPointer(localpage);
1785  sm->magic = SEQ_MAGIC;
1786 
1787  item = (char *) xlrec + sizeof(xl_seq_rec);
1788  itemsz = XLogRecGetDataLen(record) - sizeof(xl_seq_rec);
1789 
1790  if (PageAddItem(localpage, (Item) item, itemsz,
1791  FirstOffsetNumber, false, false) == InvalidOffsetNumber)
1792  elog(PANIC, "seq_redo: failed to add item to page");
1793 
1794  PageSetLSN(localpage, lsn);
1795 
1796  memcpy(page, localpage, BufferGetPageSize(buffer));
1797  MarkBufferDirty(buffer);
1798  UnlockReleaseBuffer(buffer);
1799 
1800  pfree(localpage);
1801 }
#define SEQ_MAGIC
Definition: sequence.c:59
struct xl_seq_rec xl_seq_rec
void MarkBufferDirty(Buffer buffer)
Definition: bufmgr.c:1445
unsigned char uint8
Definition: c.h:263
Pointer Item
Definition: item.h:17
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
Definition: bufpage.h:413
#define PANIC
Definition: elog.h:53
void pfree(void *pointer)
Definition: mcxt.c:992
#define XLogRecGetData(decoder)
Definition: xlogreader.h:202
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3315
#define XLogRecGetDataLen(decoder)
Definition: xlogreader.h:203
Buffer XLogInitBufferForRedo(XLogReaderState *record, uint8 block_id)
Definition: xlogutils.c:300
#define FirstOffsetNumber
Definition: off.h:27
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:198
#define BufferGetPageSize(buffer)
Definition: bufmgr.h:147
#define InvalidOffsetNumber
Definition: off.h:26
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
uint32 magic
Definition: sequence.c:63
size_t Size
Definition: c.h:352
#define PageGetSpecialPointer(page)
Definition: bufpage.h:323
void * palloc(Size size)
Definition: mcxt.c:891
#define elog
Definition: elog.h:219
#define XLOG_SEQ_LOG
Definition: sequence.h:46
#define PageSetLSN(page, lsn)
Definition: bufpage.h:365
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
void PageInit(Page page, Size pageSize, Size specialSize)
Definition: bufpage.c:41