Sequences are now based on int8, not int4, arithmetic. SERIAL pseudo-type
has an alias SERIAL4 and a sister SERIAL8. SERIAL8 is just the same except the created column is type int8 not int4. initdb forced. Note this also breaks any chance of pg_upgrade from 7.1, unless we hack up pg_upgrade to drop and recreate sequences. (Which is not out of the question, but I don't wanna do it.)
This commit is contained in:
parent
bcb0ccf5be
commit
d4f4b971a4
@ -79,8 +79,13 @@ autoinc(PG_FUNCTION_ARGS)
|
||||
seqname = DirectFunctionCall1(textin,
|
||||
CStringGetDatum(args[i]));
|
||||
newvals[chnattrs] = DirectFunctionCall1(nextval, seqname);
|
||||
/* nextval now returns int64; coerce down to int32 */
|
||||
newvals[chnattrs] = Int32GetDatum((int32) DatumGetInt64(newvals[chnattrs]));
|
||||
if (DatumGetInt32(newvals[chnattrs]) == 0)
|
||||
{
|
||||
newvals[chnattrs] = DirectFunctionCall1(nextval, seqname);
|
||||
newvals[chnattrs] = Int32GetDatum((int32) DatumGetInt64(newvals[chnattrs]));
|
||||
}
|
||||
pfree(DatumGetTextP(seqname));
|
||||
chnattrs++;
|
||||
i++;
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.57 2001/08/07 22:41:49 petere Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.58 2001/08/16 20:38:53 tgl Exp $
|
||||
-->
|
||||
|
||||
<chapter id="datatype">
|
||||
@ -199,10 +199,16 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.57 2001/08/07 22:41:49 pe
|
||||
|
||||
<row>
|
||||
<entry><type>serial</type></entry>
|
||||
<entry></entry>
|
||||
<entry><type>serial4</type></entry>
|
||||
<entry>autoincrementing four-byte integer</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><type>serial8</type></entry>
|
||||
<entry></entry>
|
||||
<entry>autoincrementing eight-byte integer</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><type>text</type></entry>
|
||||
<entry></entry>
|
||||
@ -394,10 +400,17 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.57 2001/08/07 22:41:49 pe
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>serial</entry>
|
||||
<entry>serial4</entry>
|
||||
<entry>4 bytes</entry>
|
||||
<entry>Identifier or cross-reference</entry>
|
||||
<entry>0 to +2147483647</entry>
|
||||
<entry>1 to 2147483647</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>serial8</entry>
|
||||
<entry>8 bytes</entry>
|
||||
<entry>Identifier or cross-reference</entry>
|
||||
<entry>1 to 9223372036854775807</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
@ -413,17 +426,27 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.57 2001/08/07 22:41:49 pe
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <type>bigint</type> type may not be available on all platforms since
|
||||
it relies on compiler support for eight-byte integers.
|
||||
The <type>bigint</type> type may not function correctly on all platforms,
|
||||
since it relies on compiler support for eight-byte integers. On a machine
|
||||
without such support, <type>bigint</type> acts the same
|
||||
as <type>integer</type> (but still takes up eight bytes of storage).
|
||||
</para>
|
||||
|
||||
<sect2 id="datatype-serial">
|
||||
<title>The Serial Type</title>
|
||||
<title>The Serial Types</title>
|
||||
|
||||
<indexterm zone="datatype-serial">
|
||||
<primary>serial</primary>
|
||||
</indexterm>
|
||||
|
||||
<indexterm zone="datatype-serial">
|
||||
<primary>serial4</primary>
|
||||
</indexterm>
|
||||
|
||||
<indexterm zone="datatype-serial">
|
||||
<primary>serial8</primary>
|
||||
</indexterm>
|
||||
|
||||
<indexterm>
|
||||
<primary>auto-increment</primary>
|
||||
<see>serial</see>
|
||||
@ -435,9 +458,9 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.57 2001/08/07 22:41:49 pe
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
The <type>serial</type> type is a special-case type constructed by
|
||||
<productname>Postgres</productname> from other existing components.
|
||||
It is typically used to create unique identifiers for table entries.
|
||||
The <type>serial</type> datatypes are not truly types, but are a
|
||||
notational convenience for setting up unique identifier columns
|
||||
in tables.
|
||||
In the current implementation, specifying
|
||||
|
||||
<programlisting>
|
||||
@ -449,10 +472,14 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (<replaceabl
|
||||
<programlisting>
|
||||
CREATE SEQUENCE <replaceable class="parameter">tablename</replaceable>_<replaceable class="parameter">colname</replaceable>_seq;
|
||||
CREATE TABLE <replaceable class="parameter">tablename</replaceable>
|
||||
(<replaceable class="parameter">colname</replaceable> integer DEFAULT nextval('<replaceable class="parameter">tablename</replaceable>_<replaceable class="parameter">colname</replaceable>_seq');
|
||||
CREATE UNIQUE INDEX <replaceable class="parameter">tablename</replaceable>_<replaceable class="parameter">colname</replaceable>_key on <replaceable class="parameter">tablename</replaceable> (<replaceable class="parameter">colname</replaceable>);
|
||||
(<replaceable class="parameter">colname</replaceable> integer DEFAULT nextval('<replaceable class="parameter">tablename</replaceable>_<replaceable class="parameter">colname</replaceable>_seq') UNIQUE NOT NULL;
|
||||
</programlisting>
|
||||
|
||||
Thus, we have created an integer column and arranged for its default
|
||||
values to be assigned from a sequence generator. UNIQUE and NOT NULL
|
||||
constraints are applied to ensure that explicitly-inserted values
|
||||
will never be duplicates, either.
|
||||
|
||||
<caution>
|
||||
<para>
|
||||
The implicit sequence created for the <type>serial</type> type will
|
||||
@ -460,7 +487,18 @@ CREATE UNIQUE INDEX <replaceable class="parameter">tablename</replaceable>_<repl
|
||||
table is dropped.
|
||||
</para>
|
||||
</caution>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The type names <type>serial</type> and <type>serial4</type> are
|
||||
equivalent: both create <type>integer</type> columns. The type
|
||||
name <type>serial8</type> works just the same way, except that it
|
||||
creates a <type>bigint</type> column. <type>serial8</type> should
|
||||
be used if you anticipate use of more than 2^31 identifiers over
|
||||
the lifetime of the table.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Implicit sequences supporting the <type>serial</type> are
|
||||
not automatically dropped when a table containing a serial type
|
||||
is dropped. So, the following commands executed in order will likely fail:
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_sequence.sgml,v 1.17 2001/06/30 22:01:17 petere Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_sequence.sgml,v 1.18 2001/08/16 20:38:53 tgl Exp $
|
||||
Postgres documentation
|
||||
-->
|
||||
|
||||
@ -79,7 +79,7 @@ CREATE [ TEMPORARY | TEMP ] SEQUENCE <replaceable class="parameter">seqname</rep
|
||||
The optional clause <option>MINVALUE
|
||||
<replaceable class="parameter">minvalue</replaceable></option>
|
||||
determines the minimum value
|
||||
a sequence can generate. The defaults are 1 and -2147483647 for
|
||||
a sequence can generate. The defaults are 1 and -2^63-1 for
|
||||
ascending and descending sequences, respectively.
|
||||
</para>
|
||||
</listitem>
|
||||
@ -92,7 +92,7 @@ CREATE [ TEMPORARY | TEMP ] SEQUENCE <replaceable class="parameter">seqname</rep
|
||||
The optional clause <option>MAXVALUE
|
||||
<replaceable class="parameter">maxvalue</replaceable></option>
|
||||
determines the maximum
|
||||
value for the sequence. The defaults are 2147483647 and -1 for
|
||||
value for the sequence. The defaults are 2^63-1 and -1 for
|
||||
ascending and descending sequences, respectively.
|
||||
</para>
|
||||
</listitem>
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.79 2001/08/10 18:57:34 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.80 2001/08/16 20:38:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -447,7 +447,6 @@ MergeAttributes(List *schema, List *supers, bool istemp,
|
||||
typename->typmod = attribute->atttypmod;
|
||||
def->typename = typename;
|
||||
def->is_not_null = attribute->attnotnull;
|
||||
def->is_sequence = false;
|
||||
def->raw_default = NULL;
|
||||
def->cooked_default = NULL;
|
||||
def->constraints = NIL;
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.62 2001/08/10 18:57:34 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.63 2001/08/16 20:38:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -22,6 +22,7 @@
|
||||
#include "miscadmin.h"
|
||||
#include "utils/acl.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/int8.h"
|
||||
#ifdef MULTIBYTE
|
||||
#include "mb/pg_wchar.h"
|
||||
#endif
|
||||
@ -29,8 +30,17 @@
|
||||
|
||||
#define SEQ_MAGIC 0x1717
|
||||
|
||||
#define SEQ_MAXVALUE ((int4)0x7FFFFFFF)
|
||||
#define SEQ_MINVALUE -(SEQ_MAXVALUE)
|
||||
#ifndef INT64_IS_BUSTED
|
||||
#ifdef HAVE_LL_CONSTANTS
|
||||
#define SEQ_MAXVALUE ((int64) 0x7FFFFFFFFFFFFFFFLL)
|
||||
#else
|
||||
#define SEQ_MAXVALUE ((int64) 0x7FFFFFFFFFFFFFFF)
|
||||
#endif
|
||||
#else /* INT64_IS_BUSTED */
|
||||
#define SEQ_MAXVALUE ((int64) 0x7FFFFFFF)
|
||||
#endif /* INT64_IS_BUSTED */
|
||||
|
||||
#define SEQ_MINVALUE (-SEQ_MAXVALUE)
|
||||
|
||||
/*
|
||||
* We don't want to log each fetching values from sequences,
|
||||
@ -48,10 +58,10 @@ typedef struct SeqTableData
|
||||
{
|
||||
char *name;
|
||||
Oid relid;
|
||||
Relation rel;
|
||||
int4 cached;
|
||||
int4 last;
|
||||
int4 increment;
|
||||
Relation rel; /* NULL if rel is not open in cur xact */
|
||||
int64 cached;
|
||||
int64 last;
|
||||
int64 increment;
|
||||
struct SeqTableData *next;
|
||||
} SeqTableData;
|
||||
|
||||
@ -63,8 +73,8 @@ static char *get_seq_name(text *seqin);
|
||||
static SeqTable init_sequence(char *caller, char *name);
|
||||
static Form_pg_sequence read_info(char *caller, SeqTable elm, Buffer *buf);
|
||||
static void init_params(CreateSeqStmt *seq, Form_pg_sequence new);
|
||||
static int get_param(DefElem *def);
|
||||
static void do_setval(char *seqname, int32 next, bool iscalled);
|
||||
static int64 get_param(DefElem *def);
|
||||
static void do_setval(char *seqname, int64 next, bool iscalled);
|
||||
|
||||
/*
|
||||
* DefineSequence
|
||||
@ -117,44 +127,44 @@ DefineSequence(CreateSeqStmt *seq)
|
||||
value[i - 1] = NameGetDatum(&name);
|
||||
break;
|
||||
case SEQ_COL_LASTVAL:
|
||||
typnam->name = "int4";
|
||||
typnam->name = "int8";
|
||||
coldef->colname = "last_value";
|
||||
value[i - 1] = Int32GetDatum(new.last_value);
|
||||
value[i - 1] = Int64GetDatumFast(new.last_value);
|
||||
break;
|
||||
case SEQ_COL_INCBY:
|
||||
typnam->name = "int4";
|
||||
typnam->name = "int8";
|
||||
coldef->colname = "increment_by";
|
||||
value[i - 1] = Int32GetDatum(new.increment_by);
|
||||
value[i - 1] = Int64GetDatumFast(new.increment_by);
|
||||
break;
|
||||
case SEQ_COL_MAXVALUE:
|
||||
typnam->name = "int4";
|
||||
typnam->name = "int8";
|
||||
coldef->colname = "max_value";
|
||||
value[i - 1] = Int32GetDatum(new.max_value);
|
||||
value[i - 1] = Int64GetDatumFast(new.max_value);
|
||||
break;
|
||||
case SEQ_COL_MINVALUE:
|
||||
typnam->name = "int4";
|
||||
typnam->name = "int8";
|
||||
coldef->colname = "min_value";
|
||||
value[i - 1] = Int32GetDatum(new.min_value);
|
||||
value[i - 1] = Int64GetDatumFast(new.min_value);
|
||||
break;
|
||||
case SEQ_COL_CACHE:
|
||||
typnam->name = "int4";
|
||||
typnam->name = "int8";
|
||||
coldef->colname = "cache_value";
|
||||
value[i - 1] = Int32GetDatum(new.cache_value);
|
||||
value[i - 1] = Int64GetDatumFast(new.cache_value);
|
||||
break;
|
||||
case SEQ_COL_LOG:
|
||||
typnam->name = "int4";
|
||||
typnam->name = "int8";
|
||||
coldef->colname = "log_cnt";
|
||||
value[i - 1] = Int32GetDatum((int32) 1);
|
||||
value[i - 1] = Int64GetDatum((int64) 1);
|
||||
break;
|
||||
case SEQ_COL_CYCLE:
|
||||
typnam->name = "char";
|
||||
typnam->name = "bool";
|
||||
coldef->colname = "is_cycled";
|
||||
value[i - 1] = CharGetDatum(new.is_cycled);
|
||||
value[i - 1] = BoolGetDatum(new.is_cycled);
|
||||
break;
|
||||
case SEQ_COL_CALLED:
|
||||
typnam->name = "char";
|
||||
typnam->name = "bool";
|
||||
coldef->colname = "is_called";
|
||||
value[i - 1] = CharGetDatum('f');
|
||||
value[i - 1] = BoolGetDatum(false);
|
||||
break;
|
||||
}
|
||||
stmt->tableElts = lappend(stmt->tableElts, coldef);
|
||||
@ -207,7 +217,7 @@ DefineSequence(CreateSeqStmt *seq)
|
||||
Form_pg_sequence newseq = (Form_pg_sequence) GETSTRUCT(tuple);
|
||||
|
||||
/* We do not log first nextval call, so "advance" sequence here */
|
||||
newseq->is_called = 't';
|
||||
newseq->is_called = true;
|
||||
newseq->log_cnt = 0;
|
||||
|
||||
xlrec.node = rel->rd_node;
|
||||
@ -217,7 +227,7 @@ DefineSequence(CreateSeqStmt *seq)
|
||||
rdata[0].next = &(rdata[1]);
|
||||
|
||||
rdata[1].buffer = InvalidBuffer;
|
||||
rdata[1].data = (char*) tuple->t_data;
|
||||
rdata[1].data = (char *) tuple->t_data;
|
||||
rdata[1].len = tuple->t_len;
|
||||
rdata[1].next = NULL;
|
||||
|
||||
@ -242,14 +252,14 @@ nextval(PG_FUNCTION_ARGS)
|
||||
SeqTable elm;
|
||||
Buffer buf;
|
||||
Form_pg_sequence seq;
|
||||
int32 incby,
|
||||
int64 incby,
|
||||
maxv,
|
||||
minv,
|
||||
cache,
|
||||
log,
|
||||
fetch,
|
||||
last;
|
||||
int32 result,
|
||||
int64 result,
|
||||
next,
|
||||
rescnt = 0;
|
||||
bool logit = false;
|
||||
@ -266,7 +276,7 @@ nextval(PG_FUNCTION_ARGS)
|
||||
if (elm->last != elm->cached) /* some numbers were cached */
|
||||
{
|
||||
elm->last += elm->increment;
|
||||
PG_RETURN_INT32(elm->last);
|
||||
PG_RETURN_INT64(elm->last);
|
||||
}
|
||||
|
||||
seq = read_info("nextval", elm, &buf); /* lock page' buffer and
|
||||
@ -279,7 +289,7 @@ nextval(PG_FUNCTION_ARGS)
|
||||
fetch = cache = seq->cache_value;
|
||||
log = seq->log_cnt;
|
||||
|
||||
if (seq->is_called != 't')
|
||||
if (!seq->is_called)
|
||||
{
|
||||
rescnt++; /* last_value if not called */
|
||||
fetch--;
|
||||
@ -294,7 +304,6 @@ nextval(PG_FUNCTION_ARGS)
|
||||
|
||||
while (fetch) /* try to fetch cache [+ log ] numbers */
|
||||
{
|
||||
|
||||
/*
|
||||
* Check MAXVALUE for ascending sequences and MINVALUE for
|
||||
* descending sequences
|
||||
@ -307,8 +316,8 @@ nextval(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (rescnt > 0)
|
||||
break; /* stop fetching */
|
||||
if (seq->is_cycled != 't')
|
||||
elog(ERROR, "%s.nextval: reached MAXVALUE (%d)",
|
||||
if (!seq->is_cycled)
|
||||
elog(ERROR, "%s.nextval: reached MAXVALUE (" INT64_FORMAT ")",
|
||||
elm->name, maxv);
|
||||
next = minv;
|
||||
}
|
||||
@ -323,8 +332,8 @@ nextval(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (rescnt > 0)
|
||||
break; /* stop fetching */
|
||||
if (seq->is_cycled != 't')
|
||||
elog(ERROR, "%s.nextval: reached MINVALUE (%d)",
|
||||
if (!seq->is_cycled)
|
||||
elog(ERROR, "%s.nextval: reached MINVALUE (" INT64_FORMAT ")",
|
||||
elm->name, minv);
|
||||
next = maxv;
|
||||
}
|
||||
@ -361,7 +370,7 @@ nextval(PG_FUNCTION_ARGS)
|
||||
rdata[0].next = &(rdata[1]);
|
||||
|
||||
seq->last_value = next;
|
||||
seq->is_called = 't';
|
||||
seq->is_called = true;
|
||||
seq->log_cnt = 0;
|
||||
rdata[1].buffer = InvalidBuffer;
|
||||
rdata[1].data = (char *) page + ((PageHeader) page)->pd_upper;
|
||||
@ -380,7 +389,7 @@ nextval(PG_FUNCTION_ARGS)
|
||||
|
||||
/* update on-disk data */
|
||||
seq->last_value = last; /* last fetched number */
|
||||
seq->is_called = 't';
|
||||
seq->is_called = true;
|
||||
Assert(log >= 0);
|
||||
seq->log_cnt = log; /* how much is logged */
|
||||
END_CRIT_SECTION();
|
||||
@ -390,7 +399,7 @@ nextval(PG_FUNCTION_ARGS)
|
||||
if (WriteBuffer(buf) == STATUS_ERROR)
|
||||
elog(ERROR, "%s.nextval: WriteBuffer failed", elm->name);
|
||||
|
||||
PG_RETURN_INT32(result);
|
||||
PG_RETURN_INT64(result);
|
||||
}
|
||||
|
||||
Datum
|
||||
@ -399,7 +408,7 @@ currval(PG_FUNCTION_ARGS)
|
||||
text *seqin = PG_GETARG_TEXT_P(0);
|
||||
char *seqname = get_seq_name(seqin);
|
||||
SeqTable elm;
|
||||
int32 result;
|
||||
int64 result;
|
||||
|
||||
if (pg_aclcheck(seqname, GetUserId(), ACL_SELECT) != ACLCHECK_OK)
|
||||
elog(ERROR, "%s.currval: you don't have permissions to read sequence %s",
|
||||
@ -416,7 +425,7 @@ currval(PG_FUNCTION_ARGS)
|
||||
|
||||
pfree(seqname);
|
||||
|
||||
PG_RETURN_INT32(result);
|
||||
PG_RETURN_INT64(result);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -433,7 +442,7 @@ currval(PG_FUNCTION_ARGS)
|
||||
* sequence.
|
||||
*/
|
||||
static void
|
||||
do_setval(char *seqname, int32 next, bool iscalled)
|
||||
do_setval(char *seqname, int64 next, bool iscalled)
|
||||
{
|
||||
SeqTable elm;
|
||||
Buffer buf;
|
||||
@ -449,7 +458,7 @@ do_setval(char *seqname, int32 next, bool iscalled)
|
||||
* read tuple */
|
||||
|
||||
if ((next < seq->min_value) || (next > seq->max_value))
|
||||
elog(ERROR, "%s.setval: value %d is out of bounds (%d,%d)",
|
||||
elog(ERROR, "%s.setval: value " INT64_FORMAT " is out of bounds (" INT64_FORMAT "," INT64_FORMAT ")",
|
||||
seqname, next, seq->min_value, seq->max_value);
|
||||
|
||||
/* save info in local cache */
|
||||
@ -471,7 +480,7 @@ do_setval(char *seqname, int32 next, bool iscalled)
|
||||
rdata[0].next = &(rdata[1]);
|
||||
|
||||
seq->last_value = next;
|
||||
seq->is_called = 't';
|
||||
seq->is_called = true;
|
||||
seq->log_cnt = 0;
|
||||
rdata[1].buffer = InvalidBuffer;
|
||||
rdata[1].data = (char *) page + ((PageHeader) page)->pd_upper;
|
||||
@ -486,7 +495,7 @@ do_setval(char *seqname, int32 next, bool iscalled)
|
||||
}
|
||||
/* save info in sequence relation */
|
||||
seq->last_value = next; /* last fetched number */
|
||||
seq->is_called = iscalled ? 't' : 'f';
|
||||
seq->is_called = iscalled;
|
||||
seq->log_cnt = (iscalled) ? 0 : 1;
|
||||
END_CRIT_SECTION();
|
||||
|
||||
@ -496,7 +505,6 @@ do_setval(char *seqname, int32 next, bool iscalled)
|
||||
elog(ERROR, "%s.setval: WriteBuffer failed", seqname);
|
||||
|
||||
pfree(seqname);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -507,12 +515,12 @@ Datum
|
||||
setval(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *seqin = PG_GETARG_TEXT_P(0);
|
||||
int32 next = PG_GETARG_INT32(1);
|
||||
int64 next = PG_GETARG_INT64(1);
|
||||
char *seqname = get_seq_name(seqin);
|
||||
|
||||
do_setval(seqname, next, true);
|
||||
|
||||
PG_RETURN_INT32(next);
|
||||
PG_RETURN_INT64(next);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -523,13 +531,13 @@ Datum
|
||||
setval_and_iscalled(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *seqin = PG_GETARG_TEXT_P(0);
|
||||
int32 next = PG_GETARG_INT32(1);
|
||||
int64 next = PG_GETARG_INT64(1);
|
||||
bool iscalled = PG_GETARG_BOOL(2);
|
||||
char *seqname = get_seq_name(seqin);
|
||||
|
||||
do_setval(seqname, next, iscalled);
|
||||
|
||||
PG_RETURN_INT32(next);
|
||||
PG_RETURN_INT64(next);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -694,7 +702,7 @@ init_sequence(char *caller, char *name)
|
||||
|
||||
/*
|
||||
* CloseSequences
|
||||
* is calling by xact mgr at commit/abort.
|
||||
* is called by xact mgr at commit/abort.
|
||||
*/
|
||||
void
|
||||
CloseSequences(void)
|
||||
@ -704,9 +712,9 @@ CloseSequences(void)
|
||||
|
||||
for (elm = seqtab; elm != (SeqTable) NULL; elm = elm->next)
|
||||
{
|
||||
if (elm->rel != (Relation) NULL) /* opened in current xact */
|
||||
rel = elm->rel;
|
||||
if (rel != (Relation) NULL) /* opened in current xact */
|
||||
{
|
||||
rel = elm->rel;
|
||||
elm->rel = (Relation) NULL;
|
||||
heap_close(rel, AccessShareLock);
|
||||
}
|
||||
@ -724,7 +732,7 @@ init_params(CreateSeqStmt *seq, Form_pg_sequence new)
|
||||
DefElem *cache_value = NULL;
|
||||
List *option;
|
||||
|
||||
new->is_cycled = 'f';
|
||||
new->is_cycled = false;
|
||||
foreach(option, seq->options)
|
||||
{
|
||||
DefElem *defel = (DefElem *) lfirst(option);
|
||||
@ -743,7 +751,7 @@ init_params(CreateSeqStmt *seq, Form_pg_sequence new)
|
||||
{
|
||||
if (defel->arg != (Node *) NULL)
|
||||
elog(ERROR, "DefineSequence: CYCLE ??");
|
||||
new->is_cycled = 't';
|
||||
new->is_cycled = true;
|
||||
}
|
||||
else
|
||||
elog(ERROR, "DefineSequence: option \"%s\" not recognized",
|
||||
@ -760,7 +768,7 @@ init_params(CreateSeqStmt *seq, Form_pg_sequence new)
|
||||
if (new->increment_by > 0)
|
||||
new->max_value = SEQ_MAXVALUE; /* ascending seq */
|
||||
else
|
||||
new->max_value = -1;/* descending seq */
|
||||
new->max_value = -1; /* descending seq */
|
||||
}
|
||||
else
|
||||
new->max_value = get_param(max_value);
|
||||
@ -776,7 +784,7 @@ init_params(CreateSeqStmt *seq, Form_pg_sequence new)
|
||||
new->min_value = get_param(min_value);
|
||||
|
||||
if (new->min_value >= new->max_value)
|
||||
elog(ERROR, "DefineSequence: MINVALUE (%d) can't be >= MAXVALUE (%d)",
|
||||
elog(ERROR, "DefineSequence: MINVALUE (" INT64_FORMAT ") can't be >= MAXVALUE (" INT64_FORMAT ")",
|
||||
new->min_value, new->max_value);
|
||||
|
||||
if (last_value == (DefElem *) NULL) /* START WITH */
|
||||
@ -790,31 +798,40 @@ init_params(CreateSeqStmt *seq, Form_pg_sequence new)
|
||||
new->last_value = get_param(last_value);
|
||||
|
||||
if (new->last_value < new->min_value)
|
||||
elog(ERROR, "DefineSequence: START value (%d) can't be < MINVALUE (%d)",
|
||||
elog(ERROR, "DefineSequence: START value (" INT64_FORMAT ") can't be < MINVALUE (" INT64_FORMAT ")",
|
||||
new->last_value, new->min_value);
|
||||
if (new->last_value > new->max_value)
|
||||
elog(ERROR, "DefineSequence: START value (%d) can't be > MAXVALUE (%d)",
|
||||
elog(ERROR, "DefineSequence: START value (" INT64_FORMAT ") can't be > MAXVALUE (" INT64_FORMAT ")",
|
||||
new->last_value, new->max_value);
|
||||
|
||||
if (cache_value == (DefElem *) NULL) /* CACHE */
|
||||
new->cache_value = 1;
|
||||
else if ((new->cache_value = get_param(cache_value)) <= 0)
|
||||
elog(ERROR, "DefineSequence: CACHE (%d) can't be <= 0",
|
||||
elog(ERROR, "DefineSequence: CACHE (" INT64_FORMAT ") can't be <= 0",
|
||||
new->cache_value);
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
static int64
|
||||
get_param(DefElem *def)
|
||||
{
|
||||
if (def->arg == (Node *) NULL)
|
||||
elog(ERROR, "DefineSequence: \"%s\" value unspecified", def->defname);
|
||||
|
||||
if (nodeTag(def->arg) == T_Integer)
|
||||
return intVal(def->arg);
|
||||
if (IsA(def->arg, Integer))
|
||||
return (int64) intVal(def->arg);
|
||||
|
||||
/*
|
||||
* Values too large for int4 will be represented as Float constants
|
||||
* by the lexer. Accept these if they are valid int8 strings.
|
||||
*/
|
||||
if (IsA(def->arg, Float))
|
||||
return DatumGetInt64(DirectFunctionCall1(int8in,
|
||||
CStringGetDatum(strVal(def->arg))));
|
||||
|
||||
/* Shouldn't get here unless parser messed up */
|
||||
elog(ERROR, "DefineSequence: \"%s\" value must be integer", def->defname);
|
||||
return -1;
|
||||
return 0; /* not reached; keep compiler quiet */
|
||||
}
|
||||
|
||||
void
|
||||
@ -857,8 +874,6 @@ seq_redo(XLogRecPtr lsn, XLogRecord *record)
|
||||
PageSetLSN(page, lsn);
|
||||
PageSetSUI(page, ThisStartUpID);
|
||||
UnlockAndWriteBuffer(buffer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: view.c,v 1.56 2001/08/12 21:35:18 tgl Exp $
|
||||
* $Id: view.c,v 1.57 2001/08/16 20:38:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -68,7 +68,6 @@ DefineVirtualRelation(char *relname, List *tlist)
|
||||
def->typename = typename;
|
||||
|
||||
def->is_not_null = false;
|
||||
def->is_sequence = false;
|
||||
def->raw_default = NULL;
|
||||
def->cooked_default = NULL;
|
||||
def->constraints = NIL;
|
||||
|
@ -15,7 +15,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.152 2001/08/10 18:57:36 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.153 2001/08/16 20:38:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1708,7 +1708,6 @@ _copyColumnDef(ColumnDef *from)
|
||||
newnode->colname = pstrdup(from->colname);
|
||||
Node_Copy(from, newnode, typename);
|
||||
newnode->is_not_null = from->is_not_null;
|
||||
newnode->is_sequence = from->is_sequence;
|
||||
Node_Copy(from, newnode, raw_default);
|
||||
if (from->cooked_default)
|
||||
newnode->cooked_default = pstrdup(from->cooked_default);
|
||||
|
@ -20,7 +20,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.100 2001/08/10 18:57:36 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.101 2001/08/16 20:38:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1543,8 +1543,6 @@ _equalColumnDef(ColumnDef *a, ColumnDef *b)
|
||||
return false;
|
||||
if (a->is_not_null != b->is_not_null)
|
||||
return false;
|
||||
if (a->is_sequence != b->is_sequence)
|
||||
return false;
|
||||
if (!equal(a->raw_default, b->raw_default))
|
||||
return false;
|
||||
if (!equalstr(a->cooked_default, b->cooked_default))
|
||||
|
@ -5,7 +5,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.143 2001/08/10 18:57:36 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.144 2001/08/16 20:38:53 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Every (plan) node in POSTGRES has an associated "out" routine which
|
||||
@ -175,9 +175,8 @@ _outColumnDef(StringInfo str, ColumnDef *node)
|
||||
_outToken(str, node->colname);
|
||||
appendStringInfo(str, " :typename ");
|
||||
_outNode(str, node->typename);
|
||||
appendStringInfo(str, " :is_not_null %s :is_sequence %s :raw_default ",
|
||||
booltostr(node->is_not_null),
|
||||
booltostr(node->is_sequence));
|
||||
appendStringInfo(str, " :is_not_null %s :raw_default ",
|
||||
booltostr(node->is_not_null));
|
||||
_outNode(str, node->raw_default);
|
||||
appendStringInfo(str, " :cooked_default ");
|
||||
_outToken(str, node->cooked_default);
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.194 2001/08/11 00:02:13 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.195 2001/08/16 20:38:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -702,6 +702,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
||||
*pkey = NULL;
|
||||
IndexElem *iparam;
|
||||
bool saw_nullable;
|
||||
bool is_serial;
|
||||
|
||||
q = makeNode(Query);
|
||||
q->commandType = CMD_UTILITY;
|
||||
@ -723,10 +724,25 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
||||
column = (ColumnDef *) element;
|
||||
columns = lappend(columns, column);
|
||||
|
||||
/* Check for SERIAL pseudo-types */
|
||||
is_serial = false;
|
||||
if (strcmp(column->typename->name, "serial") == 0 ||
|
||||
strcmp(column->typename->name, "serial4") == 0)
|
||||
{
|
||||
is_serial = true;
|
||||
column->typename->name = pstrdup("int4");
|
||||
}
|
||||
else if (strcmp(column->typename->name, "serial8") == 0)
|
||||
{
|
||||
is_serial = true;
|
||||
column->typename->name = pstrdup("int8");
|
||||
}
|
||||
|
||||
/* Do necessary work on the column type declaration */
|
||||
transformColumnType(pstate, column);
|
||||
|
||||
/* Special case SERIAL type? */
|
||||
if (column->is_sequence)
|
||||
/* Special actions for SERIAL pseudo-types */
|
||||
if (is_serial)
|
||||
{
|
||||
char *sname;
|
||||
char *qstring;
|
||||
@ -778,13 +794,18 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
||||
column->constraints = lappend(column->constraints,
|
||||
constraint);
|
||||
|
||||
/*
|
||||
* Build a CREATE SEQUENCE command to create the
|
||||
* sequence object, and add it to the list of things
|
||||
* to be done before this CREATE TABLE.
|
||||
*/
|
||||
sequence = makeNode(CreateSeqStmt);
|
||||
sequence->seqname = pstrdup(sname);
|
||||
sequence->istemp = stmt->istemp;
|
||||
sequence->options = NIL;
|
||||
|
||||
elog(NOTICE, "CREATE TABLE will create implicit sequence '%s' for SERIAL column '%s.%s'",
|
||||
sequence->seqname, stmt->relname, column->colname);
|
||||
sequence->seqname, stmt->relname, column->colname);
|
||||
|
||||
blist = lappend(blist, sequence);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.245 2001/08/15 18:42:15 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.246 2001/08/16 20:38:53 tgl Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@ -354,7 +354,7 @@ static void doNegateFloat(Value *v);
|
||||
NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,
|
||||
OFFSET, OIDS, OPERATOR, OWNER, PASSWORD, PROCEDURAL,
|
||||
REINDEX, RENAME, RESET, RETURNS, ROW, RULE,
|
||||
SEQUENCE, SERIAL, SETOF, SHARE, SHOW, START, STATEMENT,
|
||||
SEQUENCE, SETOF, SHARE, SHOW, START, STATEMENT,
|
||||
STATISTICS, STDIN, STDOUT, SYSID,
|
||||
TEMP, TEMPLATE, TOAST, TRUNCATE, TRUSTED,
|
||||
UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
|
||||
@ -1249,22 +1249,6 @@ columnDef: ColId Typename ColQualList opt_collate
|
||||
n->typename = $2;
|
||||
n->constraints = $3;
|
||||
|
||||
if ($4 != NULL)
|
||||
elog(NOTICE,"CREATE TABLE/COLLATE %s not yet implemented"
|
||||
"; clause ignored", $4);
|
||||
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ColId SERIAL ColQualList opt_collate
|
||||
{
|
||||
ColumnDef *n = makeNode(ColumnDef);
|
||||
n->colname = $1;
|
||||
n->typename = makeNode(TypeName);
|
||||
n->typename->name = xlateSqlType("integer");
|
||||
n->typename->typmod = -1;
|
||||
n->is_sequence = TRUE;
|
||||
n->constraints = $3;
|
||||
|
||||
if ($4 != NULL)
|
||||
elog(NOTICE,"CREATE TABLE/COLLATE %s not yet implemented"
|
||||
"; clause ignored", $4);
|
||||
@ -1630,7 +1614,7 @@ OptSeqList: OptSeqList OptSeqElem
|
||||
| { $$ = NIL; }
|
||||
;
|
||||
|
||||
OptSeqElem: CACHE IntegerOnly
|
||||
OptSeqElem: CACHE NumericOnly
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "cache";
|
||||
@ -1642,25 +1626,25 @@ OptSeqElem: CACHE IntegerOnly
|
||||
$$->defname = "cycle";
|
||||
$$->arg = (Node *)NULL;
|
||||
}
|
||||
| INCREMENT IntegerOnly
|
||||
| INCREMENT NumericOnly
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "increment";
|
||||
$$->arg = (Node *)$2;
|
||||
}
|
||||
| MAXVALUE IntegerOnly
|
||||
| MAXVALUE NumericOnly
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "maxvalue";
|
||||
$$->arg = (Node *)$2;
|
||||
}
|
||||
| MINVALUE IntegerOnly
|
||||
| MINVALUE NumericOnly
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "minvalue";
|
||||
$$->arg = (Node *)$2;
|
||||
}
|
||||
| START IntegerOnly
|
||||
| START NumericOnly
|
||||
{
|
||||
$$ = makeNode(DefElem);
|
||||
$$->defname = "start";
|
||||
@ -5593,7 +5577,6 @@ ColId: IDENT { $$ = $1; }
|
||||
| NATIONAL { $$ = "national"; }
|
||||
| NONE { $$ = "none"; }
|
||||
| PATH_P { $$ = "path"; }
|
||||
| SERIAL { $$ = "serial"; }
|
||||
| TIME { $$ = "time"; }
|
||||
| TIMESTAMP { $$ = "timestamp"; }
|
||||
;
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.95 2001/08/15 18:42:15 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.96 2001/08/16 20:38:54 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -228,7 +228,6 @@ static ScanKeyword ScanKeywords[] = {
|
||||
{"second", SECOND_P},
|
||||
{"select", SELECT},
|
||||
{"sequence", SEQUENCE},
|
||||
{"serial", SERIAL},
|
||||
{"serializable", SERIALIZABLE},
|
||||
{"session", SESSION},
|
||||
{"session_user", SESSION_USER},
|
||||
|
@ -22,7 +22,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.221 2001/08/12 19:02:39 petere Exp $
|
||||
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.222 2001/08/16 20:38:54 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -4019,6 +4019,8 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
|
||||
/* First - dump SEQUENCEs */
|
||||
if (tablename && strlen(tablename) > 0)
|
||||
{
|
||||
/* XXX this code only works for serial columns named "id" */
|
||||
/* We really need dependency analysis! */
|
||||
serialSeq = malloc(strlen(tablename) + strlen(serialSeqSuffix) + 1);
|
||||
strcpy(serialSeq, tablename);
|
||||
strcat(serialSeq, serialSeqSuffix);
|
||||
@ -4036,7 +4038,7 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
|
||||
dumpACL(fout, tblinfo[i]);
|
||||
}
|
||||
}
|
||||
if (tablename)
|
||||
if (serialSeq)
|
||||
free(serialSeq);
|
||||
|
||||
for (i = 0; i < numTables; i++)
|
||||
@ -4737,14 +4739,13 @@ static void
|
||||
dumpSequence(Archive *fout, TableInfo tbinfo, const bool schemaOnly, const bool dataOnly)
|
||||
{
|
||||
PGresult *res;
|
||||
int4 last,
|
||||
incby,
|
||||
maxv,
|
||||
minv,
|
||||
cache;
|
||||
char cycled,
|
||||
char *last,
|
||||
*incby,
|
||||
*maxv,
|
||||
*minv,
|
||||
*cache;
|
||||
bool cycled,
|
||||
called;
|
||||
const char *t;
|
||||
PQExpBuffer query = createPQExpBuffer();
|
||||
PQExpBuffer delqry = createPQExpBuffer();
|
||||
|
||||
@ -4774,20 +4775,18 @@ dumpSequence(Archive *fout, TableInfo tbinfo, const bool schemaOnly, const bool
|
||||
exit_nicely();
|
||||
}
|
||||
|
||||
last = atoi(PQgetvalue(res, 0, 1));
|
||||
incby = atoi(PQgetvalue(res, 0, 2));
|
||||
maxv = atoi(PQgetvalue(res, 0, 3));
|
||||
minv = atoi(PQgetvalue(res, 0, 4));
|
||||
cache = atoi(PQgetvalue(res, 0, 5));
|
||||
t = PQgetvalue(res, 0, 6);
|
||||
cycled = *t;
|
||||
t = PQgetvalue(res, 0, 7);
|
||||
called = *t;
|
||||
last = PQgetvalue(res, 0, 1);
|
||||
incby = PQgetvalue(res, 0, 2);
|
||||
maxv = PQgetvalue(res, 0, 3);
|
||||
minv = PQgetvalue(res, 0, 4);
|
||||
cache = PQgetvalue(res, 0, 5);
|
||||
cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0);
|
||||
called = (strcmp(PQgetvalue(res, 0, 7), "t") == 0);
|
||||
|
||||
/*
|
||||
* The logic we use for restoring sequences is as follows: - Add a
|
||||
* basic CREATE SEQUENCE statement (use last_val for start if called
|
||||
* with 'f', else use min_val for start_val).
|
||||
* is false, else use min_val for start_val).
|
||||
*
|
||||
* Add a 'SETVAL(seq, last_val, iscalled)' at restore-time iff
|
||||
* we load data
|
||||
@ -4795,22 +4794,22 @@ dumpSequence(Archive *fout, TableInfo tbinfo, const bool schemaOnly, const bool
|
||||
|
||||
if (!dataOnly)
|
||||
{
|
||||
PQclear(res);
|
||||
|
||||
resetPQExpBuffer(delqry);
|
||||
appendPQExpBuffer(delqry, "DROP SEQUENCE %s;\n", fmtId(tbinfo.relname, force_quotes));
|
||||
appendPQExpBuffer(delqry, "DROP SEQUENCE %s;\n",
|
||||
fmtId(tbinfo.relname, force_quotes));
|
||||
|
||||
resetPQExpBuffer(query);
|
||||
appendPQExpBuffer(query,
|
||||
"CREATE SEQUENCE %s start %d increment %d maxvalue %d "
|
||||
"minvalue %d cache %d %s;\n",
|
||||
"CREATE SEQUENCE %s start %s increment %s "
|
||||
"maxvalue %s minvalue %s cache %s%s;\n",
|
||||
fmtId(tbinfo.relname, force_quotes),
|
||||
(called == 't') ? minv : last,
|
||||
(called ? minv : last),
|
||||
incby, maxv, minv, cache,
|
||||
(cycled == 't') ? "cycle" : "");
|
||||
(cycled ? " cycle" : ""));
|
||||
|
||||
ArchiveEntry(fout, tbinfo.oid, tbinfo.relname, "SEQUENCE", NULL,
|
||||
query->data, delqry->data, "", tbinfo.usename, NULL, NULL);
|
||||
query->data, delqry->data, "", tbinfo.usename,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
if (!schemaOnly)
|
||||
@ -4818,7 +4817,8 @@ dumpSequence(Archive *fout, TableInfo tbinfo, const bool schemaOnly, const bool
|
||||
resetPQExpBuffer(query);
|
||||
appendPQExpBuffer(query, "SELECT setval (");
|
||||
formatStringLiteral(query, fmtId(tbinfo.relname, force_quotes), CONV_ALL);
|
||||
appendPQExpBuffer(query, ", %d, '%c');\n", last, called);
|
||||
appendPQExpBuffer(query, ", %s, %s);\n",
|
||||
last, (called ? "true" : "false"));
|
||||
|
||||
ArchiveEntry(fout, tbinfo.oid, tbinfo.relname, "SEQUENCE SET", NULL,
|
||||
query->data, "" /* Del */ , "", "", NULL, NULL);
|
||||
@ -4834,6 +4834,8 @@ dumpSequence(Archive *fout, TableInfo tbinfo, const bool schemaOnly, const bool
|
||||
"pg_class", 0, NULL);
|
||||
}
|
||||
|
||||
PQclear(res);
|
||||
|
||||
destroyPQExpBuffer(query);
|
||||
destroyPQExpBuffer(delqry);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: catversion.h,v 1.89 2001/08/14 22:21:58 tgl Exp $
|
||||
* $Id: catversion.h,v 1.90 2001/08/16 20:38:54 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -53,6 +53,6 @@
|
||||
*/
|
||||
|
||||
/* yyyymmddN */
|
||||
#define CATALOG_VERSION_NO 200108132
|
||||
#define CATALOG_VERSION_NO 200108151
|
||||
|
||||
#endif
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pg_proc.h,v 1.205 2001/08/15 07:07:40 ishii Exp $
|
||||
* $Id: pg_proc.h,v 1.206 2001/08/16 20:38:54 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* The script catalog/genbki.sh reads this file and generates .bki
|
||||
@ -2003,13 +2003,13 @@ DESCR("convert int8 to int8 (no-op)");
|
||||
|
||||
|
||||
/* SEQUENCEs nextval & currval functions */
|
||||
DATA(insert OID = 1574 ( nextval PGUID 12 f t f t 1 f 23 "25" 100 0 0 100 nextval - ));
|
||||
DATA(insert OID = 1574 ( nextval PGUID 12 f t f t 1 f 20 "25" 100 0 0 100 nextval - ));
|
||||
DESCR("sequence next value");
|
||||
DATA(insert OID = 1575 ( currval PGUID 12 f t f t 1 f 23 "25" 100 0 0 100 currval - ));
|
||||
DATA(insert OID = 1575 ( currval PGUID 12 f t f t 1 f 20 "25" 100 0 0 100 currval - ));
|
||||
DESCR("sequence current value");
|
||||
DATA(insert OID = 1576 ( setval PGUID 12 f t f t 2 f 23 "25 23" 100 0 0 100 setval - ));
|
||||
DATA(insert OID = 1576 ( setval PGUID 12 f t f t 2 f 20 "25 20" 100 0 0 100 setval - ));
|
||||
DESCR("set sequence value");
|
||||
DATA(insert OID = 1765 ( setval PGUID 12 f t f t 3 f 23 "25 23 16" 100 0 0 100 setval_and_iscalled - ));
|
||||
DATA(insert OID = 1765 ( setval PGUID 12 f t f t 3 f 20 "25 20 16" 100 0 0 100 setval_and_iscalled - ));
|
||||
DESCR("set sequence value and iscalled status");
|
||||
|
||||
DATA(insert OID = 1579 ( varbit_in PGUID 12 f t t t 1 f 1562 "0" 100 0 0 100 varbit_in - ));
|
||||
|
@ -3,6 +3,10 @@
|
||||
* sequence.h
|
||||
* prototypes for sequence.c.
|
||||
*
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: sequence.h,v 1.16 2001/08/16 20:38:55 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -12,17 +16,38 @@
|
||||
#include "nodes/parsenodes.h"
|
||||
#include "access/xlog.h"
|
||||
|
||||
/*
|
||||
* On a machine with no 64-bit-int C datatype, sizeof(int64) will not be 8,
|
||||
* but we need this struct type to line up with the way that a sequence
|
||||
* table is defined --- and pg_type will say that int8 is 8 bytes anyway.
|
||||
* So, we need padding. Ugly but necessary.
|
||||
*/
|
||||
typedef struct FormData_pg_sequence
|
||||
{
|
||||
NameData sequence_name;
|
||||
#ifndef INT64_IS_BUSTED
|
||||
int64 last_value;
|
||||
int64 increment_by;
|
||||
int64 max_value;
|
||||
int64 min_value;
|
||||
int64 cache_value;
|
||||
int64 log_cnt;
|
||||
#else
|
||||
int32 last_value;
|
||||
int32 pad1;
|
||||
int32 increment_by;
|
||||
int32 pad2;
|
||||
int32 max_value;
|
||||
int32 pad3;
|
||||
int32 min_value;
|
||||
int32 pad4;
|
||||
int32 cache_value;
|
||||
int32 pad5;
|
||||
int32 log_cnt;
|
||||
char is_cycled;
|
||||
char is_called;
|
||||
int32 pad6;
|
||||
#endif
|
||||
bool is_cycled;
|
||||
bool is_called;
|
||||
} FormData_pg_sequence;
|
||||
|
||||
typedef FormData_pg_sequence *Form_pg_sequence;
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: parsenodes.h,v 1.140 2001/08/10 18:57:41 tgl Exp $
|
||||
* $Id: parsenodes.h,v 1.141 2001/08/16 20:38:55 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1097,8 +1097,7 @@ typedef struct ColumnDef
|
||||
NodeTag type;
|
||||
char *colname; /* name of column */
|
||||
TypeName *typename; /* type of column */
|
||||
bool is_not_null; /* flag to NOT NULL constraint */
|
||||
bool is_sequence; /* is a sequence? */
|
||||
bool is_not_null; /* NOT NULL constraint specified? */
|
||||
Node *raw_default; /* default value (untransformed parse
|
||||
* tree) */
|
||||
char *cooked_default; /* nodeToString representation */
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.42 2001/07/16 05:07:00 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.43 2001/08/16 20:38:55 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -227,7 +227,6 @@ static ScanKeyword ScanKeywords[] = {
|
||||
{"second", SECOND_P},
|
||||
{"select", SELECT},
|
||||
{"sequence", SEQUENCE},
|
||||
{"serial", SERIAL},
|
||||
{"serializable", SERIALIZABLE},
|
||||
{"session", SESSION},
|
||||
{"session_user", SESSION_USER},
|
||||
|
@ -223,7 +223,7 @@ make_name(void)
|
||||
MINVALUE, MODE, MOVE, NEW, NOCREATEDB, NOCREATEUSER,
|
||||
NONE, NOTHING, NOTIFY, NOTNULL, OFFSET, OIDS,
|
||||
OPERATOR, OWNER, PASSWORD, PROCEDURAL, REINDEX, RENAME, RESET,
|
||||
RETURNS, ROW, RULE, SEQUENCE, SERIAL, SETOF, SHARE,
|
||||
RETURNS, ROW, RULE, SEQUENCE, SETOF, SHARE,
|
||||
SHOW, START, STATEMENT, STATISTICS, STDIN, STDOUT, SYSID TEMP,
|
||||
TEMPLATE, TOAST, TRUNCATE, TRUSTED, UNLISTEN, UNTIL, VACUUM,
|
||||
VALID, VERBOSE, VERSION
|
||||
@ -1107,15 +1107,6 @@ columnDef: ColId Typename ColQualList opt_collate
|
||||
}
|
||||
$$ = cat_str(4, $1, $2, $3, $4);
|
||||
}
|
||||
| ColId SERIAL ColQualList opt_collate
|
||||
{
|
||||
if (strlen($4) > 0)
|
||||
{
|
||||
sprintf(errortext, "CREATE TABLE/COLLATE %s not yet implemented; clause ignored", $4);
|
||||
mmerror(ET_NOTICE, errortext);
|
||||
}
|
||||
$$ = cat_str(4, $1, make_str(" serial "), $3, $4);
|
||||
}
|
||||
;
|
||||
|
||||
ColQualList: ColQualList ColConstraint { $$ = cat2_str($1,$2); }
|
||||
@ -5106,7 +5097,6 @@ ECPGColId: ident { $$ = $1; }
|
||||
| NATIONAL { $$ = make_str("national"); }
|
||||
| NONE { $$ = make_str("none"); }
|
||||
| PATH_P { $$ = make_str("path_p"); }
|
||||
| SERIAL { $$ = make_str("serial"); }
|
||||
| TIME { $$ = make_str("time"); }
|
||||
| TIMESTAMP { $$ = make_str("timestamp"); }
|
||||
| ECPGKeywords { $$ = $1; }
|
||||
|
@ -1317,10 +1317,10 @@ SELECT tablename, rulename, definition FROM pg_rules
|
||||
rtest_nothn1 | rtest_nothn_r2 | CREATE RULE rtest_nothn_r2 AS ON INSERT TO rtest_nothn1 WHERE ((new.a >= 30) AND (new.a < 40)) DO INSTEAD NOTHING;
|
||||
rtest_nothn2 | rtest_nothn_r3 | CREATE RULE rtest_nothn_r3 AS ON INSERT TO rtest_nothn2 WHERE (new.a >= 100) DO INSTEAD INSERT INTO rtest_nothn3 (a, b) VALUES (new.a, new.b);
|
||||
rtest_nothn2 | rtest_nothn_r4 | CREATE RULE rtest_nothn_r4 AS ON INSERT TO rtest_nothn2 DO INSTEAD NOTHING;
|
||||
rtest_order1 | rtest_order_r1 | CREATE RULE rtest_order_r1 AS ON INSERT TO rtest_order1 DO INSTEAD INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, nextval('rtest_seq'::text), 'rule 1 - this should run 3rd or 4th'::text);
|
||||
rtest_order1 | rtest_order_r2 | CREATE RULE rtest_order_r2 AS ON INSERT TO rtest_order1 DO INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, nextval('rtest_seq'::text), 'rule 2 - this should run 1st'::text);
|
||||
rtest_order1 | rtest_order_r3 | CREATE RULE rtest_order_r3 AS ON INSERT TO rtest_order1 DO INSTEAD INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, nextval('rtest_seq'::text), 'rule 3 - this should run 3rd or 4th'::text);
|
||||
rtest_order1 | rtest_order_r4 | CREATE RULE rtest_order_r4 AS ON INSERT TO rtest_order1 WHERE (new.a < 100) DO INSTEAD INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, nextval('rtest_seq'::text), 'rule 4 - this should run 2nd'::text);
|
||||
rtest_order1 | rtest_order_r1 | CREATE RULE rtest_order_r1 AS ON INSERT TO rtest_order1 DO INSTEAD INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, int4(nextval('rtest_seq'::text)), 'rule 1 - this should run 3rd or 4th'::text);
|
||||
rtest_order1 | rtest_order_r2 | CREATE RULE rtest_order_r2 AS ON INSERT TO rtest_order1 DO INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, int4(nextval('rtest_seq'::text)), 'rule 2 - this should run 1st'::text);
|
||||
rtest_order1 | rtest_order_r3 | CREATE RULE rtest_order_r3 AS ON INSERT TO rtest_order1 DO INSTEAD INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, int4(nextval('rtest_seq'::text)), 'rule 3 - this should run 3rd or 4th'::text);
|
||||
rtest_order1 | rtest_order_r4 | CREATE RULE rtest_order_r4 AS ON INSERT TO rtest_order1 WHERE (new.a < 100) DO INSTEAD INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, int4(nextval('rtest_seq'::text)), 'rule 4 - this should run 2nd'::text);
|
||||
rtest_person | rtest_pers_del | CREATE RULE rtest_pers_del AS ON DELETE TO rtest_person DO DELETE FROM rtest_admin WHERE (rtest_admin.pname = old.pname);
|
||||
rtest_person | rtest_pers_upd | CREATE RULE rtest_pers_upd AS ON UPDATE TO rtest_person DO UPDATE rtest_admin SET pname = new.pname WHERE (rtest_admin.pname = old.pname);
|
||||
rtest_system | rtest_sys_del | CREATE RULE rtest_sys_del AS ON DELETE TO rtest_system DO (DELETE FROM rtest_interface WHERE (rtest_interface.sysname = old.sysname); DELETE FROM rtest_admin WHERE (rtest_admin.sysname = old.sysname); );
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.47 2001/03/22 04:01:44 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.48 2001/08/16 20:38:56 tgl Exp $
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
@ -565,6 +565,8 @@ ttdummy(PG_FUNCTION_ARGS)
|
||||
|
||||
newoff = DirectFunctionCall1(nextval,
|
||||
PointerGetDatum(seqname));
|
||||
/* nextval now returns int64; coerce down to int32 */
|
||||
newoff = Int32GetDatum((int32) DatumGetInt64(newoff));
|
||||
pfree(seqname);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user