Skip to content
Snippets Groups Projects
Commit 74151052 authored by Vadim B. Mikheev's avatar Vadim B. Mikheev
Browse files

XLOG stuff for sequences.

CommitDelay in guc.c
parent 680b7357
Branches
Tags
No related merge requests found
...@@ -7,8 +7,7 @@ ...@@ -7,8 +7,7 @@
#include "access/xact.h" #include "access/xact.h"
#include "access/xlog.h" #include "access/xlog.h"
#include "storage/smgr.h" #include "storage/smgr.h"
#include "commands/sequence.h"
#ifdef XLOG
RmgrData RmgrTable[] = { RmgrData RmgrTable[] = {
{"XLOG", xlog_redo, xlog_undo, xlog_desc}, {"XLOG", xlog_redo, xlog_undo, xlog_desc},
...@@ -25,15 +24,7 @@ RmgrData RmgrTable[] = { ...@@ -25,15 +24,7 @@ RmgrData RmgrTable[] = {
{"Btree", btree_redo, btree_undo, btree_desc}, {"Btree", btree_redo, btree_undo, btree_desc},
{"Hash", hash_redo, hash_undo, hash_desc}, {"Hash", hash_redo, hash_undo, hash_desc},
{"Rtree", rtree_redo, rtree_undo, rtree_desc}, {"Rtree", rtree_redo, rtree_undo, rtree_desc},
{"Gist", gist_redo, gist_undo, gist_desc} {"Gist", gist_redo, gist_undo, gist_desc},
{"Sequence", seq_redo, seq_undo, seq_desc}
}; };
#else /* not XLOG */
/*
* This is a dummy, but don't write RmgrTable[] = {} here,
* that's not accepted by some compilers. -- petere
*/
RmgrData RmgrTable[1];
#endif /* not XLOG */
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.84 2000/11/21 21:15:57 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.85 2000/11/30 01:47:31 vadim Exp $
* *
* NOTES * NOTES
* Transaction aborts can now occur two ways: * Transaction aborts can now occur two ways:
...@@ -222,7 +222,7 @@ int XactIsoLevel; ...@@ -222,7 +222,7 @@ int XactIsoLevel;
#ifdef XLOG #ifdef XLOG
#include "access/xlogutils.h" #include "access/xlogutils.h"
int CommitDelay = 5; /* 1/200 sec */ int CommitDelay = 5; /* 1/200000 sec */
static void (*_RollbackFunc)(void*) = NULL; static void (*_RollbackFunc)(void*) = NULL;
static void *_RollbackData = NULL; static void *_RollbackData = NULL;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.36 2000/11/28 23:27:54 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.37 2000/11/30 01:47:31 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -249,8 +249,17 @@ XLogInsert(RmgrId rmid, uint8 info, char *hdr, uint32 hdrlen, char *buf, uint32 ...@@ -249,8 +249,17 @@ XLogInsert(RmgrId rmid, uint8 info, char *hdr, uint32 hdrlen, char *buf, uint32
wlen; wlen;
uint16 curridx; uint16 curridx;
bool updrqst = false; bool updrqst = false;
bool no_tran = (rmid == RM_XLOG_ID) ? true : false;
if (info & XLR_INFO_MASK)
{
if ((info & XLR_INFO_MASK) != XLOG_NO_TRAN)
elog(STOP, "XLogInsert: invalid info mask %02X",
(info & XLR_INFO_MASK));
no_tran = true;
info &= ~XLR_INFO_MASK;
}
Assert(!(info & XLR_INFO_MASK));
if (len == 0 || len > MAXLOGRECSZ) if (len == 0 || len > MAXLOGRECSZ)
elog(STOP, "XLogInsert: invalid record len %u", len); elog(STOP, "XLogInsert: invalid record len %u", len);
...@@ -324,13 +333,14 @@ XLogInsert(RmgrId rmid, uint8 info, char *hdr, uint32 hdrlen, char *buf, uint32 ...@@ -324,13 +333,14 @@ XLogInsert(RmgrId rmid, uint8 info, char *hdr, uint32 hdrlen, char *buf, uint32
freespace -= SizeOfXLogRecord; freespace -= SizeOfXLogRecord;
record = (XLogRecord *) Insert->currpos; record = (XLogRecord *) Insert->currpos;
record->xl_prev = Insert->PrevRecord; record->xl_prev = Insert->PrevRecord;
if (rmid != RM_XLOG_ID) if (no_tran)
record->xl_xact_prev = MyLastRecPtr;
else
{ {
record->xl_xact_prev.xlogid = 0; record->xl_xact_prev.xlogid = 0;
record->xl_xact_prev.xrecoff = 0; record->xl_xact_prev.xrecoff = 0;
} }
else
record->xl_xact_prev = MyLastRecPtr;
record->xl_xid = GetCurrentTransactionId(); record->xl_xid = GetCurrentTransactionId();
record->xl_len = (len > freespace) ? freespace : len; record->xl_len = (len > freespace) ? freespace : len;
record->xl_info = (len > freespace) ? record->xl_info = (len > freespace) ?
...@@ -340,7 +350,7 @@ XLogInsert(RmgrId rmid, uint8 info, char *hdr, uint32 hdrlen, char *buf, uint32 ...@@ -340,7 +350,7 @@ XLogInsert(RmgrId rmid, uint8 info, char *hdr, uint32 hdrlen, char *buf, uint32
RecPtr.xrecoff = RecPtr.xrecoff =
XLogCtl->xlblocks[curridx].xrecoff - BLCKSZ + XLogCtl->xlblocks[curridx].xrecoff - BLCKSZ +
Insert->currpos - ((char *) Insert->currpage); Insert->currpos - ((char *) Insert->currpage);
if (MyLastRecPtr.xrecoff == 0 && rmid != RM_XLOG_ID) if (MyLastRecPtr.xrecoff == 0 && !no_tran)
{ {
SpinAcquire(SInvalLock); SpinAcquire(SInvalLock);
MyProc->logRec = RecPtr; MyProc->logRec = RecPtr;
......
...@@ -22,19 +22,12 @@ ...@@ -22,19 +22,12 @@
#define SEQ_MAXVALUE ((int4)0x7FFFFFFF) #define SEQ_MAXVALUE ((int4)0x7FFFFFFF)
#define SEQ_MINVALUE -(SEQ_MAXVALUE) #define SEQ_MINVALUE -(SEQ_MAXVALUE)
typedef struct FormData_pg_sequence /*
{ * We don't want to log each fetching values from sequences,
NameData sequence_name; * so we pre-log a few fetches in advance. In the event of
int4 last_value; * crash we can lose as much as we pre-logged.
int4 increment_by; */
int4 max_value; #define SEQ_LOG_VALS 32
int4 min_value;
int4 cache_value;
char is_cycled;
char is_called;
} FormData_pg_sequence;
typedef FormData_pg_sequence *Form_pg_sequence;
typedef struct sequence_magic typedef struct sequence_magic
{ {
...@@ -138,6 +131,11 @@ DefineSequence(CreateSeqStmt *seq) ...@@ -138,6 +131,11 @@ DefineSequence(CreateSeqStmt *seq)
coldef->colname = "cache_value"; coldef->colname = "cache_value";
value[i - 1] = Int32GetDatum(new.cache_value); value[i - 1] = Int32GetDatum(new.cache_value);
break; break;
case SEQ_COL_LOG:
typnam->name = "int4";
coldef->colname = "log_cnt";
value[i - 1] = Int32GetDatum((int32)1);
break;
case SEQ_COL_CYCLE: case SEQ_COL_CYCLE:
typnam->name = "char"; typnam->name = "char";
coldef->colname = "is_cycled"; coldef->colname = "is_cycled";
...@@ -196,10 +194,14 @@ nextval(PG_FUNCTION_ARGS) ...@@ -196,10 +194,14 @@ nextval(PG_FUNCTION_ARGS)
int32 incby, int32 incby,
maxv, maxv,
minv, minv,
cache; cache,
log,
fetch,
last;
int32 result, int32 result,
next, next,
rescnt = 0; rescnt = 0;
bool logit = false;
if (pg_aclcheck(seqname, GetUserId(), ACL_WR) != ACLCHECK_OK) if (pg_aclcheck(seqname, GetUserId(), ACL_WR) != ACLCHECK_OK)
elog(ERROR, "%s.nextval: you don't have permissions to set sequence %s", elog(ERROR, "%s.nextval: you don't have permissions to set sequence %s",
...@@ -219,16 +221,27 @@ nextval(PG_FUNCTION_ARGS) ...@@ -219,16 +221,27 @@ nextval(PG_FUNCTION_ARGS)
seq = read_info("nextval", elm, &buf); /* lock page' buffer and seq = read_info("nextval", elm, &buf); /* lock page' buffer and
* read tuple */ * read tuple */
next = result = seq->last_value; last = next = result = seq->last_value;
incby = seq->increment_by; incby = seq->increment_by;
maxv = seq->max_value; maxv = seq->max_value;
minv = seq->min_value; minv = seq->min_value;
cache = seq->cache_value; fetch = cache = seq->cache_value;
log = seq->log_cnt;
if (seq->is_called != 't') if (seq->is_called != 't')
{
rescnt++; /* last_value if not called */ rescnt++; /* last_value if not called */
fetch--;
log--;
}
while (rescnt < cache) /* try to fetch cache numbers */ if (log < fetch)
{
fetch = log = fetch - log + SEQ_LOG_VALS;
logit = true;
}
while (fetch) /* try to fetch cache [+ log ] numbers */
{ {
/* /*
...@@ -242,7 +255,7 @@ nextval(PG_FUNCTION_ARGS) ...@@ -242,7 +255,7 @@ nextval(PG_FUNCTION_ARGS)
(maxv < 0 && next + incby > maxv)) (maxv < 0 && next + incby > maxv))
{ {
if (rescnt > 0) if (rescnt > 0)
break; /* stop caching */ break; /* stop fetching */
if (seq->is_cycled != 't') if (seq->is_cycled != 't')
elog(ERROR, "%s.nextval: got MAXVALUE (%d)", elog(ERROR, "%s.nextval: got MAXVALUE (%d)",
elm->name, maxv); elm->name, maxv);
...@@ -258,7 +271,7 @@ nextval(PG_FUNCTION_ARGS) ...@@ -258,7 +271,7 @@ nextval(PG_FUNCTION_ARGS)
(minv >= 0 && next + incby < minv)) (minv >= 0 && next + incby < minv))
{ {
if (rescnt > 0) if (rescnt > 0)
break; /* stop caching */ break; /* stop fetching */
if (seq->is_cycled != 't') if (seq->is_cycled != 't')
elog(ERROR, "%s.nextval: got MINVALUE (%d)", elog(ERROR, "%s.nextval: got MINVALUE (%d)",
elm->name, minv); elm->name, minv);
...@@ -267,17 +280,43 @@ nextval(PG_FUNCTION_ARGS) ...@@ -267,17 +280,43 @@ nextval(PG_FUNCTION_ARGS)
else else
next += incby; next += incby;
} }
rescnt++; /* got result */ fetch--;
if (rescnt == 1) /* if it's first one - */ if (rescnt < cache)
{
log--;
rescnt++;
last = next;
if (rescnt == 1) /* if it's first result - */
result = next; /* it's what to return */ result = next; /* it's what to return */
} }
}
/* save info in local cache */ /* save info in local cache */
elm->last = result; /* last returned number */ elm->last = result; /* last returned number */
elm->cached = next; /* last cached number */ elm->cached = last; /* last fetched number */
if (logit)
{
xl_seq_rec xlrec;
XLogRecPtr recptr;
if (fetch) /* not all numbers were fetched */
log -= fetch;
xlrec.node = elm->rel->rd_node;
xlrec.value = next;
recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG|XLOG_NO_TRAN,
(char*) &xlrec, sizeof(xlrec), NULL, 0);
PageSetLSN(BufferGetPage(buf), recptr);
PageSetSUI(BufferGetPage(buf), ThisStartUpID);
}
/* save info in sequence relation */ /* save info in sequence relation */
seq->last_value = next; /* last fetched number */ seq->last_value = last; /* last fetched number */
Assert(log >= 0);
seq->log_cnt = log; /* how much is logged */
seq->is_called = 't'; seq->is_called = 't';
LockBuffer(buf, BUFFER_LOCK_UNLOCK); LockBuffer(buf, BUFFER_LOCK_UNLOCK);
...@@ -349,6 +388,21 @@ do_setval(char *seqname, int32 next, bool iscalled) ...@@ -349,6 +388,21 @@ do_setval(char *seqname, int32 next, bool iscalled)
/* save info in sequence relation */ /* save info in sequence relation */
seq->last_value = next; /* last fetched number */ seq->last_value = next; /* last fetched number */
seq->is_called = iscalled ? 't' : 'f'; seq->is_called = iscalled ? 't' : 'f';
seq->log_cnt = (iscalled) ? 0 : 1;
{
xl_seq_rec xlrec;
XLogRecPtr recptr;
xlrec.node = elm->rel->rd_node;
xlrec.value = next;
recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_SET|XLOG_NO_TRAN,
(char*) &xlrec, sizeof(xlrec), NULL, 0);
PageSetLSN(BufferGetPage(buf), recptr);
PageSetSUI(BufferGetPage(buf), ThisStartUpID);
}
LockBuffer(buf, BUFFER_LOCK_UNLOCK); LockBuffer(buf, BUFFER_LOCK_UNLOCK);
...@@ -638,7 +692,6 @@ init_params(CreateSeqStmt *seq, Form_pg_sequence new) ...@@ -638,7 +692,6 @@ init_params(CreateSeqStmt *seq, Form_pg_sequence new)
} }
static int static int
get_param(DefElem *def) get_param(DefElem *def)
{ {
...@@ -651,3 +704,80 @@ get_param(DefElem *def) ...@@ -651,3 +704,80 @@ get_param(DefElem *def)
elog(ERROR, "DefineSequence: \"%s\" is to be integer", def->defname); elog(ERROR, "DefineSequence: \"%s\" is to be integer", def->defname);
return -1; return -1;
} }
void seq_redo(XLogRecPtr lsn, XLogRecord *record)
{
uint8 info = record->xl_info & ~XLR_INFO_MASK;
Relation reln;
Buffer buffer;
Page page;
ItemId lp;
HeapTupleData tuple;
Form_pg_sequence seq;
xl_seq_rec *xlrec;
if (info != XLOG_SEQ_LOG && info != XLOG_SEQ_SET)
elog(STOP, "seq_redo: unknown op code %u", info);
xlrec = (xl_seq_rec*) XLogRecGetData(record);
reln = XLogOpenRelation(true, RM_SEQ_ID, xlrec->node);
if (!RelationIsValid(reln))
return;
buffer = XLogReadBuffer(false, reln, 0);
if (!BufferIsValid(buffer))
elog(STOP, "seq_redo: can't read block of %u/%u",
xlrec->node.tblNode, xlrec->node.relNode);
page = (Page) BufferGetPage(buffer);
if (PageIsNew((PageHeader) page) ||
((sequence_magic *) PageGetSpecialPointer(page))->magic != SEQ_MAGIC)
elog(STOP, "seq_redo: uninitialized page of %u/%u",
xlrec->node.tblNode, xlrec->node.relNode);
if (XLByteLE(lsn, PageGetLSN(page)))
{
UnlockAndReleaseBuffer(buffer);
return;
}
lp = PageGetItemId(page, FirstOffsetNumber);
Assert(ItemIdIsUsed(lp));
tuple.t_data = (HeapTupleHeader) PageGetItem((Page) page, lp);
seq = (Form_pg_sequence) GETSTRUCT(&tuple);
seq->last_value = xlrec->value; /* last logged value */
seq->is_called = 't';
seq->log_cnt = 0;
PageSetLSN(page, lsn);
PageSetSUI(page, ThisStartUpID);
UnlockAndWriteBuffer(buffer);
return;
}
void seq_undo(XLogRecPtr lsn, XLogRecord *record)
{
}
void seq_desc(char *buf, uint8 xl_info, char* rec)
{
uint8 info = xl_info & ~XLR_INFO_MASK;
xl_seq_rec *xlrec = (xl_seq_rec*) rec;
if (info == XLOG_SEQ_LOG)
strcat(buf, "log: ");
else if (info == XLOG_SEQ_SET)
strcat(buf, "set: ");
else
{
strcat(buf, "UNKNOWN");
return;
}
sprintf(buf + strlen(buf), "node %u/%u; value %d",
xlrec->node.tblNode, xlrec->node.relNode, xlrec->value);
}
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Support for grand unified configuration scheme, including SET * Support for grand unified configuration scheme, including SET
* command, configuration file, and command line options. * command, configuration file, and command line options.
* *
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.24 2000/11/29 20:59:53 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.25 2000/11/30 01:47:32 vadim Exp $
* *
* Copyright 2000 by PostgreSQL Global Development Group * Copyright 2000 by PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
...@@ -39,6 +39,8 @@ extern bool Log_connections; ...@@ -39,6 +39,8 @@ extern bool Log_connections;
extern int CheckPointTimeout; extern int CheckPointTimeout;
extern int XLOGbuffers; extern int XLOGbuffers;
extern int XLOG_DEBUG; extern int XLOG_DEBUG;
extern int CommitDelay;
#ifdef ENABLE_SYSLOG #ifdef ENABLE_SYSLOG
extern char *Syslog_facility; extern char *Syslog_facility;
extern char *Syslog_ident; extern char *Syslog_ident;
...@@ -272,9 +274,12 @@ ConfigureNamesInt[] = ...@@ -272,9 +274,12 @@ ConfigureNamesInt[] =
{"wal_buffers", PGC_POSTMASTER, &XLOGbuffers, {"wal_buffers", PGC_POSTMASTER, &XLOGbuffers,
8, 4, INT_MAX}, 8, 4, INT_MAX},
{"wal_debug", PGC_POSTMASTER, &XLOG_DEBUG, {"wal_debug", PGC_SUSET, &XLOG_DEBUG,
0, 0, 16}, 0, 0, 16},
{"commit_delay", PGC_USERSET, &CommitDelay,
5, 0, 1000},
{NULL, 0, NULL, 0, 0, 0} {NULL, 0, NULL, 0, 0, 0}
}; };
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: htup.h,v 1.39 2000/11/14 21:04:32 tgl Exp $ * $Id: htup.h,v 1.40 2000/11/30 01:47:32 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
......
...@@ -21,6 +21,7 @@ typedef uint8 RmgrId; ...@@ -21,6 +21,7 @@ typedef uint8 RmgrId;
#define RM_HASH_ID 12 #define RM_HASH_ID 12
#define RM_RTREE_ID 13 #define RM_RTREE_ID 13
#define RM_GIST_ID 14 #define RM_GIST_ID 14
#define RM_MAX_ID RM_GIST_ID #define RM_SEQ_ID 15
#define RM_MAX_ID RM_SEQ_ID
#endif /* RMGR_H */ #endif /* RMGR_H */
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* PostgreSQL transaction log manager * PostgreSQL transaction log manager
* *
* $Header: /cvsroot/pgsql/src/include/access/xlog.h,v 1.11 2000/11/25 20:33:53 tgl Exp $ * $Header: /cvsroot/pgsql/src/include/access/xlog.h,v 1.12 2000/11/30 01:47:32 vadim Exp $
*/ */
#ifndef XLOG_H #ifndef XLOG_H
#define XLOG_H #define XLOG_H
...@@ -54,6 +54,12 @@ typedef struct XLogSubRecord ...@@ -54,6 +54,12 @@ typedef struct XLogSubRecord
#define XLR_TO_BE_CONTINUED 0x01 #define XLR_TO_BE_CONTINUED 0x01
#define XLR_INFO_MASK 0x0F #define XLR_INFO_MASK 0x0F
/*
* Sometimes we log records which are out of transaction control.
* Rmgr may use flag below for this purpose.
*/
#define XLOG_NO_TRAN XLR_INFO_MASK
#define XLOG_PAGE_MAGIC 0x17345168 #define XLOG_PAGE_MAGIC 0x17345168
typedef struct XLogPageHeaderData typedef struct XLogPageHeaderData
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: catversion.h,v 1.64 2000/11/25 20:33:53 tgl Exp $ * $Id: catversion.h,v 1.65 2000/11/30 01:47:33 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200011251 #define CATALOG_VERSION_NO 200011291
#endif #endif
...@@ -10,6 +10,22 @@ ...@@ -10,6 +10,22 @@
#define SEQUENCE_H #define SEQUENCE_H
#include "nodes/parsenodes.h" #include "nodes/parsenodes.h"
#include "access/xlog.h"
typedef struct FormData_pg_sequence
{
NameData sequence_name;
int4 last_value;
int4 increment_by;
int4 max_value;
int4 min_value;
int4 cache_value;
int4 log_cnt;
char is_cycled;
char is_called;
} FormData_pg_sequence;
typedef FormData_pg_sequence *Form_pg_sequence;
/* /*
* Columns of a sequence relation * Columns of a sequence relation
...@@ -21,12 +37,23 @@ ...@@ -21,12 +37,23 @@
#define SEQ_COL_MAXVALUE 4 #define SEQ_COL_MAXVALUE 4
#define SEQ_COL_MINVALUE 5 #define SEQ_COL_MINVALUE 5
#define SEQ_COL_CACHE 6 #define SEQ_COL_CACHE 6
#define SEQ_COL_CYCLE 7 #define SEQ_COL_LOG 7
#define SEQ_COL_CALLED 8 #define SEQ_COL_CYCLE 8
#define SEQ_COL_CALLED 9
#define SEQ_COL_FIRSTCOL SEQ_COL_NAME #define SEQ_COL_FIRSTCOL SEQ_COL_NAME
#define SEQ_COL_LASTCOL SEQ_COL_CALLED #define SEQ_COL_LASTCOL SEQ_COL_CALLED
/* XLOG stuff */
#define XLOG_SEQ_LOG 0x00
#define XLOG_SEQ_SET 0x10
typedef struct xl_seq_rec
{
RelFileNode node;
int4 value; /* last logged value */
} xl_seq_rec;
extern Datum nextval(PG_FUNCTION_ARGS); extern Datum nextval(PG_FUNCTION_ARGS);
extern Datum currval(PG_FUNCTION_ARGS); extern Datum currval(PG_FUNCTION_ARGS);
extern Datum setval(PG_FUNCTION_ARGS); extern Datum setval(PG_FUNCTION_ARGS);
...@@ -35,4 +62,8 @@ extern Datum setval_and_iscalled(PG_FUNCTION_ARGS); ...@@ -35,4 +62,8 @@ extern Datum setval_and_iscalled(PG_FUNCTION_ARGS);
extern void DefineSequence(CreateSeqStmt *stmt); extern void DefineSequence(CreateSeqStmt *stmt);
extern void CloseSequences(void); extern void CloseSequences(void);
extern void seq_redo(XLogRecPtr lsn, XLogRecord *rptr);
extern void seq_undo(XLogRecPtr lsn, XLogRecord *rptr);
extern void seq_desc(char *buf, uint8 xl_info, char* rec);
#endif /* SEQUENCE_H */ #endif /* SEQUENCE_H */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment