While I was hacking around sequence stuff, I felt the urge to look into
an old peeve: That sequence metadata is not stored in a proper catalog.
Right now in order to find out some metadata about sequences (min, max,
increment, etc.), you need to look into the sequence.  That is like
having to query a table in order to find out about its schema.

There are also known issues with the current storage such as that we
can't safely update the sequence name stored in the sequence when we
rename, so we just don't.

This patch introduces a new catalog pg_sequence that stores the sequence
metadata.  The sequences themselves now only store the counter and
supporting information.

I don't know if this is a net improvement.  Maybe this introduces as
many new issues as it removes.  But I figured I'll post this, so that at
least we can discuss it.

-- 
Peter Eisentraut              http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile
index 1ce7610..cbf0d79 100644
--- a/src/backend/catalog/Makefile
+++ b/src/backend/catalog/Makefile
@@ -41,7 +41,7 @@ POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\
 	pg_foreign_data_wrapper.h pg_foreign_server.h pg_user_mapping.h \
 	pg_foreign_table.h pg_policy.h pg_replication_origin.h \
 	pg_default_acl.h pg_init_privs.h pg_seclabel.h pg_shseclabel.h \
-	pg_collation.h pg_range.h pg_transform.h \
+	pg_collation.h pg_range.h pg_transform.h pg_sequence.h \
 	toasting.h indexing.h \
     )
 
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 04d7840..8e1e1ac 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -66,6 +66,7 @@
 #include "commands/proclang.h"
 #include "commands/schemacmds.h"
 #include "commands/seclabel.h"
+#include "commands/sequence.h"
 #include "commands/trigger.h"
 #include "commands/typecmds.h"
 #include "nodes/nodeFuncs.h"
@@ -1155,6 +1156,8 @@ doDeletion(const ObjectAddress *object, int flags)
 					else
 						heap_drop_with_catalog(object->objectId);
 				}
+				if (relKind == RELKIND_SEQUENCE)
+					DeleteSequenceTuple(object->objectId);
 				break;
 			}
 
diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql
index 00550eb..182d2d0 100644
--- a/src/backend/catalog/information_schema.sql
+++ b/src/backend/catalog/information_schema.sql
@@ -1535,15 +1535,16 @@ CREATE VIEW sequences AS
            CAST(64 AS cardinal_number) AS numeric_precision,
            CAST(2 AS cardinal_number) AS numeric_precision_radix,
            CAST(0 AS cardinal_number) AS numeric_scale,
-           CAST(p.start_value AS character_data) AS start_value,
-           CAST(p.minimum_value AS character_data) AS minimum_value,
-           CAST(p.maximum_value AS character_data) AS maximum_value,
-           CAST(p.increment AS character_data) AS increment,
-           CAST(CASE WHEN p.cycle_option THEN 'YES' ELSE 'NO' END AS yes_or_no) AS cycle_option
-    FROM pg_namespace nc, pg_class c, LATERAL pg_sequence_parameters(c.oid) p
+           CAST(s.seqstart AS character_data) AS start_value,
+           CAST(s.seqmin AS character_data) AS minimum_value,
+           CAST(s.seqmax AS character_data) AS maximum_value,
+           CAST(s.seqincrement AS character_data) AS increment,
+           CAST(CASE WHEN s.seqcycle THEN 'YES' ELSE 'NO' END AS yes_or_no) AS cycle_option
+    FROM pg_namespace nc, pg_class c, pg_sequence s
     WHERE c.relnamespace = nc.oid
           AND c.relkind = 'S'
           AND (NOT pg_is_other_temp_schema(nc.oid))
+          AND c.oid = s.seqrelid
           AND (pg_has_role(c.relowner, 'USAGE')
                OR has_sequence_privilege(c.oid, 'SELECT, UPDATE, USAGE') );
 
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index c98f981..95bd172 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -22,8 +22,10 @@
 #include "access/xloginsert.h"
 #include "access/xlogutils.h"
 #include "catalog/dependency.h"
+#include "catalog/indexing.h"
 #include "catalog/namespace.h"
 #include "catalog/objectaccess.h"
+#include "catalog/pg_sequence.h"
 #include "catalog/pg_type.h"
 #include "commands/defrem.h"
 #include "commands/sequence.h"
@@ -74,7 +76,7 @@ typedef struct SeqTableData
 	int64		cached;			/* last value already cached for nextval */
 	/* if last != cached, we have not used up all the cached values */
 	int64		increment;		/* copy of sequence's increment field */
-	/* note that increment is zero until we first do read_seq_tuple() */
+	/* note that increment is zero until we first do nextval_internal() */
 } SeqTableData;
 
 typedef SeqTableData *SeqTable;
@@ -92,10 +94,11 @@ static int64 nextval_internal(Oid relid);
 static Relation open_share_lock(SeqTable seq);
 static void create_seq_hashtable(void);
 static void init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel);
-static Form_pg_sequence read_seq_tuple(SeqTable elm, Relation rel,
-			   Buffer *buf, HeapTuple seqtuple);
+static Form_pg_sequence_data read_seq_tuple(Relation rel,
+			   Buffer *buf, HeapTuple seqdatatuple);
 static void init_params(List *options, bool isInit,
-			Form_pg_sequence new, List **owned_by);
+						Form_pg_sequence seqform,
+						Form_pg_sequence_data seqdataform, List **owned_by);
 static void do_setval(Oid relid, int64 next, bool iscalled);
 static void process_owned_by(Relation seqrel, List *owned_by);
 
@@ -107,7 +110,8 @@ static void process_owned_by(Relation seqrel, List *owned_by);
 ObjectAddress
 DefineSequence(CreateSeqStmt *seq)
 {
-	FormData_pg_sequence new;
+	FormData_pg_sequence seqform;
+	FormData_pg_sequence_data seqdataform;
 	List	   *owned_by;
 	CreateStmt *stmt = makeNode(CreateStmt);
 	Oid			seqoid;
@@ -117,8 +121,9 @@ DefineSequence(CreateSeqStmt *seq)
 	TupleDesc	tupDesc;
 	Datum		value[SEQ_COL_LASTCOL];
 	bool		null[SEQ_COL_LASTCOL];
+	Datum		pgs_values[Natts_pg_sequence];
+	bool		pgs_nulls[Natts_pg_sequence];
 	int			i;
-	NameData	name;
 
 	/* Unlogged sequences are not implemented -- not clear if useful. */
 	if (seq->sequence->relpersistence == RELPERSISTENCE_UNLOGGED)
@@ -145,7 +150,7 @@ DefineSequence(CreateSeqStmt *seq)
 	}
 
 	/* Check and set all option values */
-	init_params(seq->options, true, &new, &owned_by);
+	init_params(seq->options, true, &seqform, &seqdataform, &owned_by);
 
 	/*
 	 * Create relation (and fill value[] and null[] for the tuple)
@@ -171,52 +176,16 @@ DefineSequence(CreateSeqStmt *seq)
 
 		switch (i)
 		{
-			case SEQ_COL_NAME:
-				coldef->typeName = makeTypeNameFromOid(NAMEOID, -1);
-				coldef->colname = "sequence_name";
-				namestrcpy(&name, seq->sequence->relname);
-				value[i - 1] = NameGetDatum(&name);
-				break;
 			case SEQ_COL_LASTVAL:
 				coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
 				coldef->colname = "last_value";
-				value[i - 1] = Int64GetDatumFast(new.last_value);
-				break;
-			case SEQ_COL_STARTVAL:
-				coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
-				coldef->colname = "start_value";
-				value[i - 1] = Int64GetDatumFast(new.start_value);
-				break;
-			case SEQ_COL_INCBY:
-				coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
-				coldef->colname = "increment_by";
-				value[i - 1] = Int64GetDatumFast(new.increment_by);
-				break;
-			case SEQ_COL_MAXVALUE:
-				coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
-				coldef->colname = "max_value";
-				value[i - 1] = Int64GetDatumFast(new.max_value);
-				break;
-			case SEQ_COL_MINVALUE:
-				coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
-				coldef->colname = "min_value";
-				value[i - 1] = Int64GetDatumFast(new.min_value);
-				break;
-			case SEQ_COL_CACHE:
-				coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
-				coldef->colname = "cache_value";
-				value[i - 1] = Int64GetDatumFast(new.cache_value);
+				value[i - 1] = Int64GetDatumFast(seqdataform.last_value);
 				break;
 			case SEQ_COL_LOG:
 				coldef->typeName = makeTypeNameFromOid(INT8OID, -1);
 				coldef->colname = "log_cnt";
 				value[i - 1] = Int64GetDatum((int64) 0);
 				break;
-			case SEQ_COL_CYCLE:
-				coldef->typeName = makeTypeNameFromOid(BOOLOID, -1);
-				coldef->colname = "is_cycled";
-				value[i - 1] = BoolGetDatum(new.is_cycled);
-				break;
 			case SEQ_COL_CALLED:
 				coldef->typeName = makeTypeNameFromOid(BOOLOID, -1);
 				coldef->colname = "is_called";
@@ -251,6 +220,27 @@ DefineSequence(CreateSeqStmt *seq)
 
 	heap_close(rel, NoLock);
 
+	/* fill in pg_sequence */
+	rel = heap_open(SequenceRelationId, RowExclusiveLock);
+	tupDesc = RelationGetDescr(rel);
+
+	memset(pgs_nulls, 0, sizeof(pgs_nulls));
+
+	pgs_values[Anum_pg_sequence_seqrelid - 1] = ObjectIdGetDatum(seqoid);
+	pgs_values[Anum_pg_sequence_seqstart - 1] = Int64GetDatumFast(seqform.seqstart);
+	pgs_values[Anum_pg_sequence_seqincrement - 1] = Int64GetDatumFast(seqform.seqincrement);
+	pgs_values[Anum_pg_sequence_seqmax - 1] = Int64GetDatumFast(seqform.seqmax);
+	pgs_values[Anum_pg_sequence_seqmin - 1] = Int64GetDatumFast(seqform.seqmin);
+	pgs_values[Anum_pg_sequence_seqcache - 1] = Int64GetDatumFast(seqform.seqcache);
+	pgs_values[Anum_pg_sequence_seqcycle - 1] = BoolGetDatum(seqform.seqcycle);
+
+	tuple = heap_form_tuple(tupDesc, pgs_values, pgs_nulls);
+	simple_heap_insert(rel, tuple);
+	CatalogUpdateIndexes(rel, tuple);
+
+	heap_freetuple(tuple);
+	heap_close(rel, RowExclusiveLock);
+
 	return address;
 }
 
@@ -271,10 +261,13 @@ ResetSequence(Oid seq_relid)
 {
 	Relation	seq_rel;
 	SeqTable	elm;
-	Form_pg_sequence seq;
+	Form_pg_sequence_data seq;
 	Buffer		buf;
-	HeapTupleData seqtuple;
+	HeapTupleData seqdatatuple;
 	HeapTuple	tuple;
+	HeapTuple	pgstuple;
+	Form_pg_sequence pgsform;
+	int64		startv;
 
 	/*
 	 * Read the old sequence.  This does a bit more work than really
@@ -282,12 +275,19 @@ ResetSequence(Oid seq_relid)
 	 * indeed a sequence.
 	 */
 	init_sequence(seq_relid, &elm, &seq_rel);
-	(void) read_seq_tuple(elm, seq_rel, &buf, &seqtuple);
+	(void) read_seq_tuple(seq_rel, &buf, &seqdatatuple);
+
+	pgstuple = SearchSysCache1(SEQRELID, ObjectIdGetDatum(seq_relid));
+	if (!HeapTupleIsValid(pgstuple))
+		elog(ERROR, "cache lookup failed for sequence %u", seq_relid);
+	pgsform = (Form_pg_sequence) GETSTRUCT(pgstuple);
+	startv = pgsform->seqstart;
+	ReleaseSysCache(pgstuple);
 
 	/*
 	 * Copy the existing sequence tuple.
 	 */
-	tuple = heap_copytuple(&seqtuple);
+	tuple = heap_copytuple(&seqdatatuple);
 
 	/* Now we're done with the old page */
 	UnlockReleaseBuffer(buf);
@@ -296,8 +296,8 @@ ResetSequence(Oid seq_relid)
 	 * Modify the copied tuple to execute the restart (compare the RESTART
 	 * action in AlterSequence)
 	 */
-	seq = (Form_pg_sequence) GETSTRUCT(tuple);
-	seq->last_value = seq->start_value;
+	seq = (Form_pg_sequence_data) GETSTRUCT(tuple);
+	seq->last_value = startv;
 	seq->is_called = false;
 	seq->log_cnt = 0;
 
@@ -410,11 +410,14 @@ AlterSequence(AlterSeqStmt *stmt)
 	SeqTable	elm;
 	Relation	seqrel;
 	Buffer		buf;
-	HeapTupleData seqtuple;
-	Form_pg_sequence seq;
-	FormData_pg_sequence new;
+	HeapTupleData seqdatatuple;
+	Form_pg_sequence seqform;
+	Form_pg_sequence_data seqdata;
+	FormData_pg_sequence_data newseqdata;
 	List	   *owned_by;
 	ObjectAddress address;
+	Relation	rel;
+	HeapTuple	tuple;
 
 	/* Open and lock sequence. */
 	relid = RangeVarGetRelid(stmt->sequence, AccessShareLock, stmt->missing_ok);
@@ -434,13 +437,22 @@ AlterSequence(AlterSeqStmt *stmt)
 					   stmt->sequence->relname);
 
 	/* lock page' buffer and read tuple into new sequence structure */
-	seq = read_seq_tuple(elm, seqrel, &buf, &seqtuple);
+	seqdata = read_seq_tuple(seqrel, &buf, &seqdatatuple);
 
 	/* Copy old values of options into workspace */
-	memcpy(&new, seq, sizeof(FormData_pg_sequence));
+	memcpy(&newseqdata, seqdata, sizeof(FormData_pg_sequence_data));
+
+	rel = heap_open(SequenceRelationId, RowExclusiveLock);
+	tuple = SearchSysCacheCopy1(SEQRELID,
+								ObjectIdGetDatum(relid));
+	if (!HeapTupleIsValid(tuple))
+		elog(ERROR, "cache lookup failed for sequence %u",
+			 relid);
+
+	seqform = (Form_pg_sequence) GETSTRUCT(tuple);
 
 	/* Check and set new values */
-	init_params(stmt->options, false, &new, &owned_by);
+	init_params(stmt->options, false, seqform, &newseqdata, &owned_by);
 
 	/* Clear local cache so that we don't think we have cached numbers */
 	/* Note that we do not change the currval() state */
@@ -453,7 +465,7 @@ AlterSequence(AlterSeqStmt *stmt)
 	/* Now okay to update the on-disk tuple */
 	START_CRIT_SECTION();
 
-	memcpy(seq, &new, sizeof(FormData_pg_sequence));
+	memcpy(seqdata, &newseqdata, sizeof(FormData_pg_sequence_data));
 
 	MarkBufferDirty(buf);
 
@@ -470,7 +482,7 @@ AlterSequence(AlterSeqStmt *stmt)
 		xlrec.node = seqrel->rd_node;
 		XLogRegisterData((char *) &xlrec, sizeof(xl_seq_rec));
 
-		XLogRegisterData((char *) seqtuple.t_data, seqtuple.t_len);
+		XLogRegisterData((char *) seqdatatuple.t_data, seqdatatuple.t_len);
 
 		recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG);
 
@@ -491,9 +503,30 @@ AlterSequence(AlterSeqStmt *stmt)
 
 	relation_close(seqrel, NoLock);
 
+	simple_heap_update(rel, &tuple->t_self, tuple);
+	CatalogUpdateIndexes(rel, tuple);
+	heap_close(rel, RowExclusiveLock);
+
 	return address;
 }
 
+void
+DeleteSequenceTuple(Oid relid)
+{
+	Relation	rel;
+	HeapTuple	tuple;
+
+	rel = heap_open(SequenceRelationId, RowExclusiveLock);
+
+	tuple = SearchSysCache1(SEQRELID, ObjectIdGetDatum(relid));
+	if (!HeapTupleIsValid(tuple))
+		elog(ERROR, "cache lookup failed for sequence %u", relid);
+
+	simple_heap_delete(rel, &tuple->t_self);
+
+	ReleaseSysCache(tuple);
+	heap_close(rel, RowExclusiveLock);
+}
 
 /*
  * Note: nextval with a text argument is no longer exported as a pg_proc
@@ -537,8 +570,10 @@ nextval_internal(Oid relid)
 	Relation	seqrel;
 	Buffer		buf;
 	Page		page;
-	HeapTupleData seqtuple;
-	Form_pg_sequence seq;
+	HeapTuple	pgstuple;
+	Form_pg_sequence pgsform;
+	HeapTupleData seqdatatuple;
+	Form_pg_sequence_data seq;
 	int64		incby,
 				maxv,
 				minv,
@@ -549,6 +584,7 @@ nextval_internal(Oid relid)
 	int64		result,
 				next,
 				rescnt = 0;
+	bool		cycle;
 	bool		logit = false;
 
 	/* open and AccessShareLock sequence */
@@ -582,15 +618,24 @@ nextval_internal(Oid relid)
 		return elm->last;
 	}
 
+	pgstuple = SearchSysCache1(SEQRELID, ObjectIdGetDatum(relid));
+	if (!HeapTupleIsValid(pgstuple))
+		elog(ERROR, "cache lookup failed for sequence %u", relid);
+	pgsform = (Form_pg_sequence) GETSTRUCT(pgstuple);
+	incby = pgsform->seqincrement;
+	maxv = pgsform->seqmax;
+	minv = pgsform->seqmin;
+	cache = pgsform->seqcache;
+	cycle = pgsform->seqcycle;
+	ReleaseSysCache(pgstuple);
+
 	/* lock page' buffer and read tuple */
-	seq = read_seq_tuple(elm, seqrel, &buf, &seqtuple);
+	seq = read_seq_tuple(seqrel, &buf, &seqdatatuple);
 	page = BufferGetPage(buf);
 
+	elm->increment = incby;
 	last = next = result = seq->last_value;
-	incby = seq->increment_by;
-	maxv = seq->max_value;
-	minv = seq->min_value;
-	fetch = cache = seq->cache_value;
+	fetch = cache;
 	log = seq->log_cnt;
 
 	if (!seq->is_called)
@@ -641,7 +686,7 @@ nextval_internal(Oid relid)
 			{
 				if (rescnt > 0)
 					break;		/* stop fetching */
-				if (!seq->is_cycled)
+				if (!cycle)
 				{
 					char		buf[100];
 
@@ -664,7 +709,7 @@ nextval_internal(Oid relid)
 			{
 				if (rescnt > 0)
 					break;		/* stop fetching */
-				if (!seq->is_cycled)
+				if (!cycle)
 				{
 					char		buf[100];
 
@@ -747,7 +792,7 @@ nextval_internal(Oid relid)
 		xlrec.node = seqrel->rd_node;
 
 		XLogRegisterData((char *) &xlrec, sizeof(xl_seq_rec));
-		XLogRegisterData((char *) seqtuple.t_data, seqtuple.t_len);
+		XLogRegisterData((char *) seqdatatuple.t_data, seqdatatuple.t_len);
 
 		recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG);
 
@@ -853,8 +898,12 @@ do_setval(Oid relid, int64 next, bool iscalled)
 	SeqTable	elm;
 	Relation	seqrel;
 	Buffer		buf;
-	HeapTupleData seqtuple;
-	Form_pg_sequence seq;
+	HeapTupleData seqdatatuple;
+	Form_pg_sequence_data seq;
+	HeapTuple	pgstuple;
+	Form_pg_sequence pgsform;
+	int64		maxv,
+				minv;
 
 	/* open and AccessShareLock sequence */
 	init_sequence(relid, &elm, &seqrel);
@@ -865,6 +914,14 @@ do_setval(Oid relid, int64 next, bool iscalled)
 				 errmsg("permission denied for sequence %s",
 						RelationGetRelationName(seqrel))));
 
+	pgstuple = SearchSysCache1(SEQRELID, ObjectIdGetDatum(relid));
+	if (!HeapTupleIsValid(pgstuple))
+		elog(ERROR, "cache lookup failed for sequence %u", relid);
+	pgsform = (Form_pg_sequence) GETSTRUCT(pgstuple);
+	maxv = pgsform->seqmax;
+	minv = pgsform->seqmin;
+	ReleaseSysCache(pgstuple);
+
 	/* read-only transactions may only modify temp sequences */
 	if (!seqrel->rd_islocaltemp)
 		PreventCommandIfReadOnly("setval()");
@@ -877,17 +934,17 @@ do_setval(Oid relid, int64 next, bool iscalled)
 	PreventCommandIfParallelMode("setval()");
 
 	/* lock page' buffer and read tuple */
-	seq = read_seq_tuple(elm, seqrel, &buf, &seqtuple);
+	seq = read_seq_tuple(seqrel, &buf, &seqdatatuple);
 
-	if ((next < seq->min_value) || (next > seq->max_value))
+	if ((next < minv) || (next > maxv))
 	{
 		char		bufv[100],
 					bufm[100],
 					bufx[100];
 
 		snprintf(bufv, sizeof(bufv), INT64_FORMAT, next);
-		snprintf(bufm, sizeof(bufm), INT64_FORMAT, seq->min_value);
-		snprintf(bufx, sizeof(bufx), INT64_FORMAT, seq->max_value);
+		snprintf(bufm, sizeof(bufm), INT64_FORMAT, minv);
+		snprintf(bufx, sizeof(bufx), INT64_FORMAT, maxv);
 		ereport(ERROR,
 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
 				 errmsg("setval: value %s is out of bounds for sequence \"%s\" (%s..%s)",
@@ -930,7 +987,7 @@ do_setval(Oid relid, int64 next, bool iscalled)
 
 		xlrec.node = seqrel->rd_node;
 		XLogRegisterData((char *) &xlrec, sizeof(xl_seq_rec));
-		XLogRegisterData((char *) seqtuple.t_data, seqtuple.t_len);
+		XLogRegisterData((char *) seqdatatuple.t_data, seqdatatuple.t_len);
 
 		recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG);
 
@@ -1064,7 +1121,7 @@ init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel)
 		elm->filenode = InvalidOid;
 		elm->lxid = InvalidLocalTransactionId;
 		elm->last_valid = false;
-		elm->last = elm->cached = elm->increment = 0;
+		elm->last = elm->cached = 0;
 	}
 
 	/*
@@ -1099,18 +1156,18 @@ init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel)
  * Given an opened sequence relation, lock the page buffer and find the tuple
  *
  * *buf receives the reference to the pinned-and-ex-locked buffer
- * *seqtuple receives the reference to the sequence tuple proper
+ * *seqdatatuple receives the reference to the sequence tuple proper
  *		(this arg should point to a local variable of type HeapTupleData)
  *
  * Function's return value points to the data payload of the tuple
  */
-static Form_pg_sequence
-read_seq_tuple(SeqTable elm, Relation rel, Buffer *buf, HeapTuple seqtuple)
+static Form_pg_sequence_data
+read_seq_tuple(Relation rel, Buffer *buf, HeapTuple seqdatatuple)
 {
 	Page		page;
 	ItemId		lp;
 	sequence_magic *sm;
-	Form_pg_sequence seq;
+	Form_pg_sequence_data seq;
 
 	*buf = ReadBuffer(rel, 0);
 	LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);
@@ -1125,9 +1182,9 @@ read_seq_tuple(SeqTable elm, Relation rel, Buffer *buf, HeapTuple seqtuple)
 	lp = PageGetItemId(page, FirstOffsetNumber);
 	Assert(ItemIdIsNormal(lp));
 
-	/* Note we currently only bother to set these two fields of *seqtuple */
-	seqtuple->t_data = (HeapTupleHeader) PageGetItem(page, lp);
-	seqtuple->t_len = ItemIdGetLength(lp);
+	/* Note we currently only bother to set these two fields of *seqdatatuple */
+	seqdatatuple->t_data = (HeapTupleHeader) PageGetItem(page, lp);
+	seqdatatuple->t_len = ItemIdGetLength(lp);
 
 	/*
 	 * Previous releases of Postgres neglected to prevent SELECT FOR UPDATE on
@@ -1137,19 +1194,16 @@ read_seq_tuple(SeqTable elm, Relation rel, Buffer *buf, HeapTuple seqtuple)
 	 * bit update, ie, don't bother to WAL-log it, since we can certainly do
 	 * this again if the update gets lost.
 	 */
-	Assert(!(seqtuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI));
-	if (HeapTupleHeaderGetRawXmax(seqtuple->t_data) != InvalidTransactionId)
+	Assert(!(seqdatatuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI));
+	if (HeapTupleHeaderGetRawXmax(seqdatatuple->t_data) != InvalidTransactionId)
 	{
-		HeapTupleHeaderSetXmax(seqtuple->t_data, InvalidTransactionId);
-		seqtuple->t_data->t_infomask &= ~HEAP_XMAX_COMMITTED;
-		seqtuple->t_data->t_infomask |= HEAP_XMAX_INVALID;
+		HeapTupleHeaderSetXmax(seqdatatuple->t_data, InvalidTransactionId);
+		seqdatatuple->t_data->t_infomask &= ~HEAP_XMAX_COMMITTED;
+		seqdatatuple->t_data->t_infomask |= HEAP_XMAX_INVALID;
 		MarkBufferDirtyHint(*buf, true);
 	}
 
-	seq = (Form_pg_sequence) GETSTRUCT(seqtuple);
-
-	/* this is a handy place to update our copy of the increment */
-	elm->increment = seq->increment_by;
+	seq = (Form_pg_sequence_data) GETSTRUCT(seqdatatuple);
 
 	return seq;
 }
@@ -1164,7 +1218,8 @@ read_seq_tuple(SeqTable elm, Relation rel, Buffer *buf, HeapTuple seqtuple)
  */
 static void
 init_params(List *options, bool isInit,
-			Form_pg_sequence new, List **owned_by)
+			Form_pg_sequence seqform,
+			Form_pg_sequence_data seqdataform, List **owned_by)
 {
 	DefElem    *start_value = NULL;
 	DefElem    *restart_value = NULL;
@@ -1255,69 +1310,69 @@ init_params(List *options, bool isInit,
 	 * would affect future nextval allocations.
 	 */
 	if (isInit)
-		new->log_cnt = 0;
+		seqdataform->log_cnt = 0;
 
 	/* INCREMENT BY */
 	if (increment_by != NULL)
 	{
-		new->increment_by = defGetInt64(increment_by);
-		if (new->increment_by == 0)
+		seqform->seqincrement = defGetInt64(increment_by);
+		if (seqform->seqincrement == 0)
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 					 errmsg("INCREMENT must not be zero")));
-		new->log_cnt = 0;
+		seqdataform->log_cnt = 0;
 	}
 	else if (isInit)
-		new->increment_by = 1;
+		seqform->seqincrement = 1;
 
 	/* CYCLE */
 	if (is_cycled != NULL)
 	{
-		new->is_cycled = intVal(is_cycled->arg);
-		Assert(BoolIsValid(new->is_cycled));
-		new->log_cnt = 0;
+		seqform->seqcycle = intVal(is_cycled->arg);
+		Assert(BoolIsValid(seqform->seqcycle));
+		seqdataform->log_cnt = 0;
 	}
 	else if (isInit)
-		new->is_cycled = false;
+		seqform->seqcycle = false;
 
 	/* MAXVALUE (null arg means NO MAXVALUE) */
 	if (max_value != NULL && max_value->arg)
 	{
-		new->max_value = defGetInt64(max_value);
-		new->log_cnt = 0;
+		seqform->seqmax = defGetInt64(max_value);
+		seqdataform->log_cnt = 0;
 	}
 	else if (isInit || max_value != NULL)
 	{
-		if (new->increment_by > 0)
-			new->max_value = SEQ_MAXVALUE;		/* ascending seq */
+		if (seqform->seqincrement > 0)
+			seqform->seqmax = SEQ_MAXVALUE;		/* ascending seq */
 		else
-			new->max_value = -1;	/* descending seq */
-		new->log_cnt = 0;
+			seqform->seqmax = -1;	/* descending seq */
+		seqdataform->log_cnt = 0;
 	}
 
 	/* MINVALUE (null arg means NO MINVALUE) */
 	if (min_value != NULL && min_value->arg)
 	{
-		new->min_value = defGetInt64(min_value);
-		new->log_cnt = 0;
+		seqform->seqmin = defGetInt64(min_value);
+		seqdataform->log_cnt = 0;
 	}
 	else if (isInit || min_value != NULL)
 	{
-		if (new->increment_by > 0)
-			new->min_value = 1; /* ascending seq */
+		if (seqform->seqincrement > 0)
+			seqform->seqmin = 1; /* ascending seq */
 		else
-			new->min_value = SEQ_MINVALUE;		/* descending seq */
-		new->log_cnt = 0;
+			seqform->seqmin = SEQ_MINVALUE;		/* descending seq */
+		seqdataform->log_cnt = 0;
 	}
 
 	/* crosscheck min/max */
-	if (new->min_value >= new->max_value)
+	if (seqform->seqmin >= seqform->seqmax)
 	{
 		char		bufm[100],
 					bufx[100];
 
-		snprintf(bufm, sizeof(bufm), INT64_FORMAT, new->min_value);
-		snprintf(bufx, sizeof(bufx), INT64_FORMAT, new->max_value);
+		snprintf(bufm, sizeof(bufm), INT64_FORMAT, seqform->seqmin);
+		snprintf(bufx, sizeof(bufx), INT64_FORMAT, seqform->seqmax);
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 				 errmsg("MINVALUE (%s) must be less than MAXVALUE (%s)",
@@ -1326,35 +1381,35 @@ init_params(List *options, bool isInit,
 
 	/* START WITH */
 	if (start_value != NULL)
-		new->start_value = defGetInt64(start_value);
+		seqform->seqstart = defGetInt64(start_value);
 	else if (isInit)
 	{
-		if (new->increment_by > 0)
-			new->start_value = new->min_value;	/* ascending seq */
+		if (seqform->seqincrement > 0)
+			seqform->seqstart = seqform->seqmin;	/* ascending seq */
 		else
-			new->start_value = new->max_value;	/* descending seq */
+			seqform->seqstart = seqform->seqmax;	/* descending seq */
 	}
 
 	/* crosscheck START */
-	if (new->start_value < new->min_value)
+	if (seqform->seqstart < seqform->seqmin)
 	{
 		char		bufs[100],
 					bufm[100];
 
-		snprintf(bufs, sizeof(bufs), INT64_FORMAT, new->start_value);
-		snprintf(bufm, sizeof(bufm), INT64_FORMAT, new->min_value);
+		snprintf(bufs, sizeof(bufs), INT64_FORMAT, seqform->seqstart);
+		snprintf(bufm, sizeof(bufm), INT64_FORMAT, seqform->seqmin);
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 				 errmsg("START value (%s) cannot be less than MINVALUE (%s)",
 						bufs, bufm)));
 	}
-	if (new->start_value > new->max_value)
+	if (seqform->seqstart > seqform->seqmax)
 	{
 		char		bufs[100],
 					bufm[100];
 
-		snprintf(bufs, sizeof(bufs), INT64_FORMAT, new->start_value);
-		snprintf(bufm, sizeof(bufm), INT64_FORMAT, new->max_value);
+		snprintf(bufs, sizeof(bufs), INT64_FORMAT, seqform->seqstart);
+		snprintf(bufm, sizeof(bufm), INT64_FORMAT, seqform->seqmax);
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 			  errmsg("START value (%s) cannot be greater than MAXVALUE (%s)",
@@ -1365,38 +1420,38 @@ init_params(List *options, bool isInit,
 	if (restart_value != NULL)
 	{
 		if (restart_value->arg != NULL)
-			new->last_value = defGetInt64(restart_value);
+			seqdataform->last_value = defGetInt64(restart_value);
 		else
-			new->last_value = new->start_value;
-		new->is_called = false;
-		new->log_cnt = 0;
+			seqdataform->last_value = seqform->seqstart;
+		seqdataform->is_called = false;
+		seqdataform->log_cnt = 0;
 	}
 	else if (isInit)
 	{
-		new->last_value = new->start_value;
-		new->is_called = false;
+		seqdataform->last_value = seqform->seqstart;
+		seqdataform->is_called = false;
 	}
 
 	/* crosscheck RESTART (or current value, if changing MIN/MAX) */
-	if (new->last_value < new->min_value)
+	if (seqdataform->last_value < seqform->seqmin)
 	{
 		char		bufs[100],
 					bufm[100];
 
-		snprintf(bufs, sizeof(bufs), INT64_FORMAT, new->last_value);
-		snprintf(bufm, sizeof(bufm), INT64_FORMAT, new->min_value);
+		snprintf(bufs, sizeof(bufs), INT64_FORMAT, seqdataform->last_value);
+		snprintf(bufm, sizeof(bufm), INT64_FORMAT, seqform->seqmin);
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 			   errmsg("RESTART value (%s) cannot be less than MINVALUE (%s)",
 					  bufs, bufm)));
 	}
-	if (new->last_value > new->max_value)
+	if (seqdataform->last_value > seqform->seqmax)
 	{
 		char		bufs[100],
 					bufm[100];
 
-		snprintf(bufs, sizeof(bufs), INT64_FORMAT, new->last_value);
-		snprintf(bufm, sizeof(bufm), INT64_FORMAT, new->max_value);
+		snprintf(bufs, sizeof(bufs), INT64_FORMAT, seqdataform->last_value);
+		snprintf(bufm, sizeof(bufm), INT64_FORMAT, seqform->seqmax);
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 			errmsg("RESTART value (%s) cannot be greater than MAXVALUE (%s)",
@@ -1406,21 +1461,21 @@ init_params(List *options, bool isInit,
 	/* CACHE */
 	if (cache_value != NULL)
 	{
-		new->cache_value = defGetInt64(cache_value);
-		if (new->cache_value <= 0)
+		seqform->seqcache = defGetInt64(cache_value);
+		if (seqform->seqcache <= 0)
 		{
 			char		buf[100];
 
-			snprintf(buf, sizeof(buf), INT64_FORMAT, new->cache_value);
+			snprintf(buf, sizeof(buf), INT64_FORMAT, seqform->seqcache);
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 					 errmsg("CACHE (%s) must be greater than zero",
 							buf)));
 		}
-		new->log_cnt = 0;
+		seqdataform->log_cnt = 0;
 	}
 	else if (isInit)
-		new->cache_value = 1;
+		seqform->seqcache = 1;
 }
 
 /*
@@ -1519,7 +1574,7 @@ process_owned_by(Relation seqrel, List *owned_by)
 
 
 /*
- * Return sequence parameters, for use by information schema
+ * Return sequence parameters (formerly for use by information schema)
  */
 Datum
 pg_sequence_parameters(PG_FUNCTION_ARGS)
@@ -1528,20 +1583,14 @@ pg_sequence_parameters(PG_FUNCTION_ARGS)
 	TupleDesc	tupdesc;
 	Datum		values[5];
 	bool		isnull[5];
-	SeqTable	elm;
-	Relation	seqrel;
-	Buffer		buf;
-	HeapTupleData seqtuple;
-	Form_pg_sequence seq;
-
-	/* open and AccessShareLock sequence */
-	init_sequence(relid, &elm, &seqrel);
+	HeapTuple	pgstuple;
+	Form_pg_sequence pgsform;
 
 	if (pg_class_aclcheck(relid, GetUserId(), ACL_SELECT | ACL_UPDATE | ACL_USAGE) != ACLCHECK_OK)
 		ereport(ERROR,
 				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
 				 errmsg("permission denied for sequence %s",
-						RelationGetRelationName(seqrel))));
+						get_rel_name(relid))));
 
 	tupdesc = CreateTemplateTupleDesc(5, false);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "start_value",
@@ -1559,16 +1608,18 @@ pg_sequence_parameters(PG_FUNCTION_ARGS)
 
 	memset(isnull, 0, sizeof(isnull));
 
-	seq = read_seq_tuple(elm, seqrel, &buf, &seqtuple);
+	pgstuple = SearchSysCache1(SEQRELID, relid);
+	if (!HeapTupleIsValid(pgstuple))
+		elog(ERROR, "cache lookup failed for sequence %u", relid);
+	pgsform = (Form_pg_sequence) GETSTRUCT(pgstuple);
 
-	values[0] = Int64GetDatum(seq->start_value);
-	values[1] = Int64GetDatum(seq->min_value);
-	values[2] = Int64GetDatum(seq->max_value);
-	values[3] = Int64GetDatum(seq->increment_by);
-	values[4] = BoolGetDatum(seq->is_cycled);
+	values[0] = Int64GetDatum(pgsform->seqstart);
+	values[1] = Int64GetDatum(pgsform->seqmin);
+	values[2] = Int64GetDatum(pgsform->seqmax);
+	values[3] = Int64GetDatum(pgsform->seqincrement);
+	values[4] = BoolGetDatum(pgsform->seqcycle);
 
-	UnlockReleaseBuffer(buf);
-	relation_close(seqrel, NoLock);
+	ReleaseSysCache(pgstuple);
 
 	return HeapTupleGetDatum(heap_form_tuple(tupdesc, values, isnull));
 }
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 65ffe84..1a6205b 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -52,6 +52,7 @@
 #include "catalog/pg_range.h"
 #include "catalog/pg_rewrite.h"
 #include "catalog/pg_seclabel.h"
+#include "catalog/pg_sequence.h"
 #include "catalog/pg_shdepend.h"
 #include "catalog/pg_shdescription.h"
 #include "catalog/pg_shseclabel.h"
@@ -656,6 +657,17 @@ static const struct cachedesc cacheinfo[] = {
 		},
 		8
 	},
+	{SequenceRelationId,			/* SEQRELID */
+		SequenceRelidIndexId,
+		1,
+		{
+			Anum_pg_sequence_seqrelid,
+			0,
+			0,
+			0
+		},
+		32
+	},
 	{StatisticRelationId,		/* STATRELATTINH */
 		StatisticRelidAttnumInhIndexId,
 		3,
diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h
index ca5eb3d..3ef880e 100644
--- a/src/include/catalog/indexing.h
+++ b/src/include/catalog/indexing.h
@@ -209,6 +209,9 @@ DECLARE_UNIQUE_INDEX(pg_rewrite_oid_index, 2692, on pg_rewrite using btree(oid o
 DECLARE_UNIQUE_INDEX(pg_rewrite_rel_rulename_index, 2693, on pg_rewrite using btree(ev_class oid_ops, rulename name_ops));
 #define RewriteRelRulenameIndexId  2693
 
+DECLARE_UNIQUE_INDEX(pg_sequence_seqrelid_index, 5002, on pg_sequence using btree(seqrelid oid_ops));
+#define SequenceRelidIndexId	5002
+
 DECLARE_INDEX(pg_shdepend_depender_index, 1232, on pg_shdepend using btree(dbid oid_ops, classid oid_ops, objid oid_ops, objsubid int4_ops));
 #define SharedDependDependerIndexId		1232
 DECLARE_INDEX(pg_shdepend_reference_index, 1233, on pg_shdepend using btree(refclassid oid_ops, refobjid oid_ops));
diff --git a/src/include/catalog/pg_sequence.h b/src/include/catalog/pg_sequence.h
new file mode 100644
index 0000000..2e24329
--- /dev/null
+++ b/src/include/catalog/pg_sequence.h
@@ -0,0 +1,30 @@
+#ifndef PG_SEQUENCE_H
+#define PG_SEQUENCE_H
+
+#include "catalog/genbki.h"
+
+#define SequenceRelationId	4032
+
+CATALOG(pg_sequence,4032) BKI_WITHOUT_OIDS
+{
+	Oid			seqrelid;
+	int64		seqstart;
+	int64		seqincrement;
+	int64		seqmax;
+	int64		seqmin;
+	int64		seqcache;
+	bool		seqcycle;
+} FormData_pg_sequence;
+
+typedef FormData_pg_sequence *Form_pg_sequence;
+
+#define Natts_pg_sequence				7
+#define Anum_pg_sequence_seqrelid		1
+#define Anum_pg_sequence_seqstart		2
+#define Anum_pg_sequence_seqincrement	3
+#define Anum_pg_sequence_seqmax			4
+#define Anum_pg_sequence_seqmin			5
+#define Anum_pg_sequence_seqcache		6
+#define Anum_pg_sequence_seqcycle		7
+
+#endif	/* PG_SEQUENCE_H */
diff --git a/src/include/commands/sequence.h b/src/include/commands/sequence.h
index 6af60d8..5f08c3b 100644
--- a/src/include/commands/sequence.h
+++ b/src/include/commands/sequence.h
@@ -21,38 +21,24 @@
 #include "storage/relfilenode.h"
 
 
-typedef struct FormData_pg_sequence
+typedef struct FormData_pg_sequence_data
 {
-	NameData	sequence_name;
 	int64		last_value;
-	int64		start_value;
-	int64		increment_by;
-	int64		max_value;
-	int64		min_value;
-	int64		cache_value;
 	int64		log_cnt;
-	bool		is_cycled;
 	bool		is_called;
-} FormData_pg_sequence;
+} FormData_pg_sequence_data;
 
-typedef FormData_pg_sequence *Form_pg_sequence;
+typedef FormData_pg_sequence_data *Form_pg_sequence_data;
 
 /*
  * Columns of a sequence relation
  */
 
-#define SEQ_COL_NAME			1
-#define SEQ_COL_LASTVAL			2
-#define SEQ_COL_STARTVAL		3
-#define SEQ_COL_INCBY			4
-#define SEQ_COL_MAXVALUE		5
-#define SEQ_COL_MINVALUE		6
-#define SEQ_COL_CACHE			7
-#define SEQ_COL_LOG				8
-#define SEQ_COL_CYCLE			9
-#define SEQ_COL_CALLED			10
+#define SEQ_COL_LASTVAL			1
+#define SEQ_COL_LOG				2
+#define SEQ_COL_CALLED			3
 
-#define SEQ_COL_FIRSTCOL		SEQ_COL_NAME
+#define SEQ_COL_FIRSTCOL		SEQ_COL_LASTVAL
 #define SEQ_COL_LASTCOL			SEQ_COL_CALLED
 
 /* XLOG stuff */
@@ -75,6 +61,7 @@ extern Datum pg_sequence_parameters(PG_FUNCTION_ARGS);
 
 extern ObjectAddress DefineSequence(CreateSeqStmt *stmt);
 extern ObjectAddress AlterSequence(AlterSeqStmt *stmt);
+extern void DeleteSequenceTuple(Oid relid);
 extern void ResetSequence(Oid seq_relid);
 extern void ResetSequenceCaches(void);
 
diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h
index 256615b..9c52be4 100644
--- a/src/include/utils/syscache.h
+++ b/src/include/utils/syscache.h
@@ -80,6 +80,7 @@ enum SysCacheIdentifier
 	REPLORIGIDENT,
 	REPLORIGNAME,
 	RULERELNAME,
+	SEQRELID,
 	STATRELATTINH,
 	TABLESPACEOID,
 	TRFOID,
diff --git a/src/test/regress/expected/sanity_check.out b/src/test/regress/expected/sanity_check.out
index 1c087a3..2e1b1b3 100644
--- a/src/test/regress/expected/sanity_check.out
+++ b/src/test/regress/expected/sanity_check.out
@@ -125,6 +125,7 @@ pg_range|t
 pg_replication_origin|t
 pg_rewrite|t
 pg_seclabel|t
+pg_sequence|t
 pg_shdepend|t
 pg_shdescription|t
 pg_shseclabel|t
diff --git a/src/test/regress/expected/sequence.out b/src/test/regress/expected/sequence.out
index 4ffbe92..11541b6 100644
--- a/src/test/regress/expected/sequence.out
+++ b/src/test/regress/expected/sequence.out
@@ -173,9 +173,9 @@ DROP SEQUENCE sequence_test;
 CREATE SEQUENCE foo_seq;
 ALTER TABLE foo_seq RENAME TO foo_seq_new;
 SELECT * FROM foo_seq_new;
- sequence_name | last_value | start_value | increment_by |      max_value      | min_value | cache_value | log_cnt | is_cycled | is_called 
----------------+------------+-------------+--------------+---------------------+-----------+-------------+---------+-----------+-----------
- foo_seq       |          1 |           1 |            1 | 9223372036854775807 |         1 |           1 |       0 | f         | f
+ last_value | log_cnt | is_called 
+------------+---------+-----------
+          1 |       0 | f
 (1 row)
 
 SELECT nextval('foo_seq_new');
@@ -191,9 +191,9 @@ SELECT nextval('foo_seq_new');
 (1 row)
 
 SELECT * FROM foo_seq_new;
- sequence_name | last_value | start_value | increment_by |      max_value      | min_value | cache_value | log_cnt | is_cycled | is_called 
----------------+------------+-------------+--------------+---------------------+-----------+-------------+---------+-----------+-----------
- foo_seq       |          2 |           1 |            1 | 9223372036854775807 |         1 |           1 |      31 | f         | t
+ last_value | log_cnt | is_called 
+------------+---------+-----------
+          2 |      31 | t
 (1 row)
 
 DROP SEQUENCE foo_seq_new;
@@ -517,3 +517,24 @@ SELECT * FROM information_schema.sequences WHERE sequence_name IN
 
 DROP USER regress_seq_user;
 DROP SEQUENCE seq;
+-- cache tests
+CREATE SEQUENCE test_seq1 CACHE 10;
+SELECT nextval('test_seq1');
+ nextval 
+---------
+       1
+(1 row)
+
+SELECT nextval('test_seq1');
+ nextval 
+---------
+       2
+(1 row)
+
+SELECT nextval('test_seq1');
+ nextval 
+---------
+       3
+(1 row)
+
+DROP SEQUENCE test_seq1;
diff --git a/src/test/regress/expected/updatable_views.out b/src/test/regress/expected/updatable_views.out
index f60991e..db3570f 100644
--- a/src/test/regress/expected/updatable_views.out
+++ b/src/test/regress/expected/updatable_views.out
@@ -86,55 +86,48 @@ SELECT table_name, column_name, is_updatable
   FROM information_schema.columns
  WHERE table_name LIKE E'r_\\_view%'
  ORDER BY table_name, ordinal_position;
- table_name |  column_name  | is_updatable 
-------------+---------------+--------------
- ro_view1   | a             | NO
- ro_view1   | b             | NO
- ro_view10  | a             | NO
- ro_view11  | a             | NO
- ro_view11  | b             | NO
- ro_view12  | a             | NO
- ro_view13  | a             | NO
- ro_view13  | b             | NO
- ro_view17  | a             | NO
- ro_view17  | b             | NO
- ro_view18  | a             | NO
- ro_view19  | sequence_name | NO
- ro_view19  | last_value    | NO
- ro_view19  | start_value   | NO
- ro_view19  | increment_by  | NO
- ro_view19  | max_value     | NO
- ro_view19  | min_value     | NO
- ro_view19  | cache_value   | NO
- ro_view19  | log_cnt       | NO
- ro_view19  | is_cycled     | NO
- ro_view19  | is_called     | NO
- ro_view2   | a             | NO
- ro_view2   | b             | NO
- ro_view20  | a             | NO
- ro_view20  | b             | NO
- ro_view20  | g             | NO
- ro_view3   | ?column?      | NO
- ro_view4   | count         | NO
- ro_view5   | a             | NO
- ro_view5   | rank          | NO
- ro_view6   | a             | NO
- ro_view6   | b             | NO
- ro_view7   | a             | NO
- ro_view7   | b             | NO
- ro_view8   | a             | NO
- ro_view8   | b             | NO
- ro_view9   | a             | NO
- ro_view9   | b             | NO
- rw_view14  | ctid          | NO
- rw_view14  | a             | YES
- rw_view14  | b             | YES
- rw_view15  | a             | YES
- rw_view15  | upper         | NO
- rw_view16  | a             | YES
- rw_view16  | b             | YES
- rw_view16  | aa            | YES
-(46 rows)
+ table_name | column_name | is_updatable 
+------------+-------------+--------------
+ ro_view1   | a           | NO
+ ro_view1   | b           | NO
+ ro_view10  | a           | NO
+ ro_view11  | a           | NO
+ ro_view11  | b           | NO
+ ro_view12  | a           | NO
+ ro_view13  | a           | NO
+ ro_view13  | b           | NO
+ ro_view17  | a           | NO
+ ro_view17  | b           | NO
+ ro_view18  | a           | NO
+ ro_view19  | last_value  | NO
+ ro_view19  | log_cnt     | NO
+ ro_view19  | is_called   | NO
+ ro_view2   | a           | NO
+ ro_view2   | b           | NO
+ ro_view20  | a           | NO
+ ro_view20  | b           | NO
+ ro_view20  | g           | NO
+ ro_view3   | ?column?    | NO
+ ro_view4   | count       | NO
+ ro_view5   | a           | NO
+ ro_view5   | rank        | NO
+ ro_view6   | a           | NO
+ ro_view6   | b           | NO
+ ro_view7   | a           | NO
+ ro_view7   | b           | NO
+ ro_view8   | a           | NO
+ ro_view8   | b           | NO
+ ro_view9   | a           | NO
+ ro_view9   | b           | NO
+ rw_view14  | ctid        | NO
+ rw_view14  | a           | YES
+ rw_view14  | b           | YES
+ rw_view15  | a           | YES
+ rw_view15  | upper       | NO
+ rw_view16  | a           | YES
+ rw_view16  | b           | YES
+ rw_view16  | aa          | YES
+(39 rows)
 
 -- Read-only views
 DELETE FROM ro_view1;
@@ -327,7 +320,7 @@ DELETE FROM ro_view18;
 ERROR:  cannot delete from view "ro_view18"
 DETAIL:  Views that do not select from a single table or view are not automatically updatable.
 HINT:  To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule.
-UPDATE ro_view19 SET max_value=1000;
+UPDATE ro_view19 SET last_value=1000;
 ERROR:  cannot update view "ro_view19"
 DETAIL:  Views that do not select from a single table or view are not automatically updatable.
 HINT:  To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule.
diff --git a/src/test/regress/sql/sequence.sql b/src/test/regress/sql/sequence.sql
index 98a2e7d..4dcb806 100644
--- a/src/test/regress/sql/sequence.sql
+++ b/src/test/regress/sql/sequence.sql
@@ -262,3 +262,11 @@ CREATE SEQUENCE seq3;
 
 DROP USER regress_seq_user;
 DROP SEQUENCE seq;
+
+-- cache tests
+CREATE SEQUENCE test_seq1 CACHE 10;
+SELECT nextval('test_seq1');
+SELECT nextval('test_seq1');
+SELECT nextval('test_seq1');
+
+DROP SEQUENCE test_seq1;
diff --git a/src/test/regress/sql/updatable_views.sql b/src/test/regress/sql/updatable_views.sql
index 03c3f9d..f008479 100644
--- a/src/test/regress/sql/updatable_views.sql
+++ b/src/test/regress/sql/updatable_views.sql
@@ -95,7 +95,7 @@ CREATE VIEW ro_view20 AS SELECT a, b, generate_series(1, a) g FROM base_tbl; --
 -- Read-only views
 INSERT INTO ro_view17 VALUES (3, 'ROW 3');
 DELETE FROM ro_view18;
-UPDATE ro_view19 SET max_value=1000;
+UPDATE ro_view19 SET last_value=1000;
 UPDATE ro_view20 SET b=upper(b);
 
 DROP TABLE base_tbl CASCADE;
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to