mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Add a RESTART (without parameter) option to ALTER SEQUENCE, allowing a
sequence to be reset to its original starting value. This requires adding the original start value to the set of parameters (columns) of a sequence object, which is a user-visible change with potential compatibility implications; it also forces initdb. Also add hopefully-SQL-compatible RESTART/CONTINUE IDENTITY options to TRUNCATE TABLE. RESTART IDENTITY executes ALTER SEQUENCE RESTART for all sequences "owned by" any of the truncated relations. CONTINUE IDENTITY is a no-op option. Zoltan Boszormenyi
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_sequence.sgml,v 1.19 2007/10/25 18:54:03 tgl Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_sequence.sgml,v 1.20 2008/05/16 23:36:04 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ PostgreSQL documentation
|
|||||||
<synopsis>
|
<synopsis>
|
||||||
ALTER SEQUENCE <replaceable class="parameter">name</replaceable> [ INCREMENT [ BY ] <replaceable class="parameter">increment</replaceable> ]
|
ALTER SEQUENCE <replaceable class="parameter">name</replaceable> [ INCREMENT [ BY ] <replaceable class="parameter">increment</replaceable> ]
|
||||||
[ MINVALUE <replaceable class="parameter">minvalue</replaceable> | NO MINVALUE ] [ MAXVALUE <replaceable class="parameter">maxvalue</replaceable> | NO MAXVALUE ]
|
[ MINVALUE <replaceable class="parameter">minvalue</replaceable> | NO MINVALUE ] [ MAXVALUE <replaceable class="parameter">maxvalue</replaceable> | NO MAXVALUE ]
|
||||||
[ RESTART [ WITH ] <replaceable class="parameter">start</replaceable> ] [ CACHE <replaceable class="parameter">cache</replaceable> ] [ [ NO ] CYCLE ]
|
[ RESTART [ [ WITH ] <replaceable class="parameter">start</replaceable> ] ] [ CACHE <replaceable class="parameter">cache</replaceable> ] [ [ NO ] CYCLE ]
|
||||||
[ OWNED BY { <replaceable class="parameter">table</replaceable>.<replaceable class="parameter">column</replaceable> | NONE } ]
|
[ OWNED BY { <replaceable class="parameter">table</replaceable>.<replaceable class="parameter">column</replaceable> | NONE } ]
|
||||||
ALTER SEQUENCE <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
|
ALTER SEQUENCE <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
|
||||||
ALTER SEQUENCE <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
|
ALTER SEQUENCE <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
|
||||||
@ -112,12 +112,15 @@ ALTER SEQUENCE <replaceable class="parameter">name</replaceable> SET SCHEMA <rep
|
|||||||
<term><replaceable class="parameter">start</replaceable></term>
|
<term><replaceable class="parameter">start</replaceable></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The optional clause <literal>RESTART WITH <replaceable
|
The optional clause <literal>RESTART [ WITH <replaceable
|
||||||
class="parameter">start</replaceable></literal> changes the
|
class="parameter">start</replaceable> ]</literal> changes the
|
||||||
current value of the sequence. This is equivalent to calling the
|
current value of the sequence. This is equivalent to calling the
|
||||||
<function>setval</> function with <literal>is_called</literal> =
|
<function>setval</> function with <literal>is_called</literal> =
|
||||||
<literal>false</>: the specified value will be returned by the
|
<literal>false</>: the specified value will be returned by the
|
||||||
<emphasis>next</> call of <function>nextval</>.
|
<emphasis>next</> call of <function>nextval</>.
|
||||||
|
Writing <literal>RESTART</> with no <replaceable
|
||||||
|
class="parameter">start</replaceable> value is equivalent to supplying
|
||||||
|
the start value used when the sequence was created.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/truncate.sgml,v 1.25 2008/03/28 00:21:55 tgl Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/truncate.sgml,v 1.26 2008/05/16 23:36:04 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -20,7 +20,8 @@ PostgreSQL documentation
|
|||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<synopsis>
|
<synopsis>
|
||||||
TRUNCATE [ TABLE ] <replaceable class="PARAMETER">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
|
TRUNCATE [ TABLE ] <replaceable class="PARAMETER">name</replaceable> [, ... ]
|
||||||
|
[ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]
|
||||||
</synopsis>
|
</synopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
@ -50,6 +51,25 @@ TRUNCATE [ TABLE ] <replaceable class="PARAMETER">name</replaceable> [, ...] [ C
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>RESTART IDENTITY</literal></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Automatically restart sequences owned by columns of
|
||||||
|
the truncated table(s).
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>CONTINUE IDENTITY</literal></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Do not change the values of sequences. This is the default.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><literal>CASCADE</literal></term>
|
<term><literal>CASCADE</literal></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -66,7 +86,7 @@ TRUNCATE [ TABLE ] <replaceable class="PARAMETER">name</replaceable> [, ...] [ C
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Refuse to truncate if any of the tables have foreign-key references
|
Refuse to truncate if any of the tables have foreign-key references
|
||||||
from tables that are not to be truncated. This is the default.
|
from tables that are not listed in the command. This is the default.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -119,11 +139,23 @@ TRUNCATE [ TABLE ] <replaceable class="PARAMETER">name</replaceable> [, ...] [ C
|
|||||||
cause visible inconsistency between the contents of the truncated
|
cause visible inconsistency between the contents of the truncated
|
||||||
table and other tables in the database.
|
table and other tables in the database.
|
||||||
</para>
|
</para>
|
||||||
|
</warning>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<command>TRUNCATE</> is transaction-safe with respect to the data
|
||||||
|
in the tables: the truncation will be safely rolled back if the surrounding
|
||||||
|
transaction does not commit.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<warning>
|
||||||
<para>
|
<para>
|
||||||
<command>TRUNCATE</> is transaction-safe, however: the truncation
|
Any <command>ALTER SEQUENCE RESTART</> operations performed as a
|
||||||
will be safely rolled back if the surrounding transaction does not
|
consequence of using the <literal>RESTART IDENTITY</> option are
|
||||||
commit.
|
nontransactional and will not be rolled back. To minimize risk,
|
||||||
|
these operations are performed only after all the rest of
|
||||||
|
<command>TRUNCATE</>'s work is done. In practice this will only
|
||||||
|
be an issue if <command>TRUNCATE</> is performed inside a
|
||||||
|
transaction block that is aborted afterwards.
|
||||||
</para>
|
</para>
|
||||||
</warning>
|
</warning>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
@ -132,13 +164,22 @@ TRUNCATE [ TABLE ] <replaceable class="PARAMETER">name</replaceable> [, ...] [ C
|
|||||||
<title>Examples</title>
|
<title>Examples</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Truncate the tables <literal>bigtable</literal> and <literal>fattable</literal>:
|
Truncate the tables <literal>bigtable</literal> and
|
||||||
|
<literal>fattable</literal>:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
TRUNCATE bigtable, fattable;
|
TRUNCATE bigtable, fattable;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The same, and also reset any associated sequence generators:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
TRUNCATE bigtable, fattable RESTART IDENTITY;
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Truncate the table <literal>othertable</literal>, and cascade to any tables
|
Truncate the table <literal>othertable</literal>, and cascade to any tables
|
||||||
that reference <literal>othertable</literal> via foreign-key
|
that reference <literal>othertable</literal> via foreign-key
|
||||||
@ -154,7 +195,10 @@ TRUNCATE othertable CASCADE;
|
|||||||
<title>Compatibility</title>
|
<title>Compatibility</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
There is no <command>TRUNCATE</command> command in the SQL standard.
|
The draft SQL:2008 standard includes a <command>TRUNCATE</command> command,
|
||||||
|
but at this writing it is uncertain whether that will reach standardization
|
||||||
|
or be fully compatible with <productname>PostgreSQL</productname>'s
|
||||||
|
implementation.
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
</refentry>
|
</refentry>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/catalog/pg_depend.c,v 1.27 2008/03/26 21:10:37 alvherre Exp $
|
* $PostgreSQL: pgsql/src/backend/catalog/pg_depend.c,v 1.28 2008/05/16 23:36:04 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -418,6 +418,58 @@ markSequenceUnowned(Oid seqId)
|
|||||||
heap_close(depRel, RowExclusiveLock);
|
heap_close(depRel, RowExclusiveLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Collect a list of OIDs of all sequences owned by the specified relation.
|
||||||
|
*/
|
||||||
|
List *
|
||||||
|
getOwnedSequences(Oid relid)
|
||||||
|
{
|
||||||
|
List *result = NIL;
|
||||||
|
Relation depRel;
|
||||||
|
ScanKeyData key[2];
|
||||||
|
SysScanDesc scan;
|
||||||
|
HeapTuple tup;
|
||||||
|
|
||||||
|
depRel = heap_open(DependRelationId, AccessShareLock);
|
||||||
|
|
||||||
|
ScanKeyInit(&key[0],
|
||||||
|
Anum_pg_depend_refclassid,
|
||||||
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(RelationRelationId));
|
||||||
|
ScanKeyInit(&key[1],
|
||||||
|
Anum_pg_depend_refobjid,
|
||||||
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(relid));
|
||||||
|
|
||||||
|
scan = systable_beginscan(depRel, DependReferenceIndexId, true,
|
||||||
|
SnapshotNow, 2, key);
|
||||||
|
|
||||||
|
while (HeapTupleIsValid(tup = systable_getnext(scan)))
|
||||||
|
{
|
||||||
|
Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We assume any auto dependency of a sequence on a column must be
|
||||||
|
* what we are looking for. (We need the relkind test because indexes
|
||||||
|
* can also have auto dependencies on columns.)
|
||||||
|
*/
|
||||||
|
if (deprec->classid == RelationRelationId &&
|
||||||
|
deprec->objsubid == 0 &&
|
||||||
|
deprec->refobjsubid != 0 &&
|
||||||
|
deprec->deptype == DEPENDENCY_AUTO &&
|
||||||
|
get_rel_relkind(deprec->objid) == RELKIND_SEQUENCE)
|
||||||
|
{
|
||||||
|
result = lappend_oid(result, deprec->objid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
systable_endscan(scan);
|
||||||
|
|
||||||
|
heap_close(depRel, AccessShareLock);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get_constraint_index
|
* get_constraint_index
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.150 2008/05/12 00:00:47 alvherre Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.151 2008/05/16 23:36:04 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -91,7 +91,7 @@ static Relation open_share_lock(SeqTable seq);
|
|||||||
static void init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel);
|
static void init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel);
|
||||||
static Form_pg_sequence read_info(SeqTable elm, Relation rel, Buffer *buf);
|
static Form_pg_sequence read_info(SeqTable elm, Relation rel, Buffer *buf);
|
||||||
static void init_params(List *options, bool isInit,
|
static void init_params(List *options, bool isInit,
|
||||||
Form_pg_sequence new, List **owned_by);
|
Form_pg_sequence new, Form_pg_sequence old, List **owned_by);
|
||||||
static void do_setval(Oid relid, int64 next, bool iscalled);
|
static void do_setval(Oid relid, int64 next, bool iscalled);
|
||||||
static void process_owned_by(Relation seqrel, List *owned_by);
|
static void process_owned_by(Relation seqrel, List *owned_by);
|
||||||
|
|
||||||
@ -119,10 +119,10 @@ DefineSequence(CreateSeqStmt *seq)
|
|||||||
NameData name;
|
NameData name;
|
||||||
|
|
||||||
/* Check and set all option values */
|
/* Check and set all option values */
|
||||||
init_params(seq->options, true, &new, &owned_by);
|
init_params(seq->options, true, &new, NULL, &owned_by);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create relation (and fill *null & *value)
|
* Create relation (and fill value[] and null[] for the tuple)
|
||||||
*/
|
*/
|
||||||
stmt->tableElts = NIL;
|
stmt->tableElts = NIL;
|
||||||
for (i = SEQ_COL_FIRSTCOL; i <= SEQ_COL_LASTCOL; i++)
|
for (i = SEQ_COL_FIRSTCOL; i <= SEQ_COL_LASTCOL; i++)
|
||||||
@ -151,6 +151,11 @@ DefineSequence(CreateSeqStmt *seq)
|
|||||||
coldef->colname = "last_value";
|
coldef->colname = "last_value";
|
||||||
value[i - 1] = Int64GetDatumFast(new.last_value);
|
value[i - 1] = Int64GetDatumFast(new.last_value);
|
||||||
break;
|
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:
|
case SEQ_COL_INCBY:
|
||||||
coldef->typename = makeTypeNameFromOid(INT8OID, -1);
|
coldef->typename = makeTypeNameFromOid(INT8OID, -1);
|
||||||
coldef->colname = "increment_by";
|
coldef->colname = "increment_by";
|
||||||
@ -314,6 +319,29 @@ void
|
|||||||
AlterSequence(AlterSeqStmt *stmt)
|
AlterSequence(AlterSeqStmt *stmt)
|
||||||
{
|
{
|
||||||
Oid relid;
|
Oid relid;
|
||||||
|
|
||||||
|
/* find sequence */
|
||||||
|
relid = RangeVarGetRelid(stmt->sequence, false);
|
||||||
|
|
||||||
|
/* allow ALTER to sequence owner only */
|
||||||
|
/* if you change this, see also callers of AlterSequenceInternal! */
|
||||||
|
if (!pg_class_ownercheck(relid, GetUserId()))
|
||||||
|
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
|
||||||
|
stmt->sequence->relname);
|
||||||
|
|
||||||
|
/* do the work */
|
||||||
|
AlterSequenceInternal(relid, stmt->options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AlterSequenceInternal
|
||||||
|
*
|
||||||
|
* Same as AlterSequence except that the sequence is specified by OID
|
||||||
|
* and we assume the caller already checked permissions.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
AlterSequenceInternal(Oid relid, List *options)
|
||||||
|
{
|
||||||
SeqTable elm;
|
SeqTable elm;
|
||||||
Relation seqrel;
|
Relation seqrel;
|
||||||
Buffer buf;
|
Buffer buf;
|
||||||
@ -323,23 +351,14 @@ AlterSequence(AlterSeqStmt *stmt)
|
|||||||
List *owned_by;
|
List *owned_by;
|
||||||
|
|
||||||
/* open and AccessShareLock sequence */
|
/* open and AccessShareLock sequence */
|
||||||
relid = RangeVarGetRelid(stmt->sequence, false);
|
|
||||||
init_sequence(relid, &elm, &seqrel);
|
init_sequence(relid, &elm, &seqrel);
|
||||||
|
|
||||||
/* allow ALTER to sequence owner only */
|
|
||||||
if (!pg_class_ownercheck(elm->relid, GetUserId()))
|
|
||||||
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
|
|
||||||
stmt->sequence->relname);
|
|
||||||
|
|
||||||
/* lock page' buffer and read tuple into new sequence structure */
|
/* lock page' buffer and read tuple into new sequence structure */
|
||||||
seq = read_info(elm, seqrel, &buf);
|
seq = read_info(elm, seqrel, &buf);
|
||||||
page = BufferGetPage(buf);
|
page = BufferGetPage(buf);
|
||||||
|
|
||||||
/* Copy old values of options into workspace */
|
/* Fill workspace with appropriate new info */
|
||||||
memcpy(&new, seq, sizeof(FormData_pg_sequence));
|
init_params(options, false, &new, seq, &owned_by);
|
||||||
|
|
||||||
/* Check and set new values */
|
|
||||||
init_params(stmt->options, false, &new, &owned_by);
|
|
||||||
|
|
||||||
/* Clear local cache so that we don't think we have cached numbers */
|
/* Clear local cache so that we don't think we have cached numbers */
|
||||||
/* Note that we do not change the currval() state */
|
/* Note that we do not change the currval() state */
|
||||||
@ -970,7 +989,7 @@ read_info(SeqTable elm, Relation rel, Buffer *buf)
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
init_params(List *options, bool isInit,
|
init_params(List *options, bool isInit,
|
||||||
Form_pg_sequence new, List **owned_by)
|
Form_pg_sequence new, Form_pg_sequence old, List **owned_by)
|
||||||
{
|
{
|
||||||
DefElem *last_value = NULL;
|
DefElem *last_value = NULL;
|
||||||
DefElem *increment_by = NULL;
|
DefElem *increment_by = NULL;
|
||||||
@ -982,6 +1001,12 @@ init_params(List *options, bool isInit,
|
|||||||
|
|
||||||
*owned_by = NIL;
|
*owned_by = NIL;
|
||||||
|
|
||||||
|
/* Copy old values of options into workspace */
|
||||||
|
if (old != NULL)
|
||||||
|
memcpy(new, old, sizeof(FormData_pg_sequence));
|
||||||
|
else
|
||||||
|
memset(new, 0, sizeof(FormData_pg_sequence));
|
||||||
|
|
||||||
foreach(option, options)
|
foreach(option, options)
|
||||||
{
|
{
|
||||||
DefElem *defel = (DefElem *) lfirst(option);
|
DefElem *defel = (DefElem *) lfirst(option);
|
||||||
@ -994,13 +1019,24 @@ init_params(List *options, bool isInit,
|
|||||||
errmsg("conflicting or redundant options")));
|
errmsg("conflicting or redundant options")));
|
||||||
increment_by = defel;
|
increment_by = defel;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(defel->defname, "start") == 0)
|
||||||
/*
|
|
||||||
* start is for a new sequence restart is for alter
|
|
||||||
*/
|
|
||||||
else if (strcmp(defel->defname, "start") == 0 ||
|
|
||||||
strcmp(defel->defname, "restart") == 0)
|
|
||||||
{
|
{
|
||||||
|
if (!isInit)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
|
errmsg("use RESTART not START in ALTER SEQUENCE")));
|
||||||
|
if (last_value)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
|
errmsg("conflicting or redundant options")));
|
||||||
|
last_value = defel;
|
||||||
|
}
|
||||||
|
else if (strcmp(defel->defname, "restart") == 0)
|
||||||
|
{
|
||||||
|
if (isInit)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
|
errmsg("use START not RESTART in CREATE SEQUENCE")));
|
||||||
if (last_value)
|
if (last_value)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
@ -1109,24 +1145,59 @@ init_params(List *options, bool isInit,
|
|||||||
bufm, bufx)));
|
bufm, bufx)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* START WITH */
|
/* START/RESTART [WITH] */
|
||||||
if (last_value != NULL)
|
if (last_value != NULL)
|
||||||
{
|
{
|
||||||
new->last_value = defGetInt64(last_value);
|
if (last_value->arg != NULL)
|
||||||
|
new->last_value = defGetInt64(last_value);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert(old != NULL);
|
||||||
|
new->last_value = old->start_value;
|
||||||
|
}
|
||||||
|
if (isInit)
|
||||||
|
new->start_value = new->last_value;
|
||||||
new->is_called = false;
|
new->is_called = false;
|
||||||
new->log_cnt = 1;
|
new->log_cnt = 1;
|
||||||
}
|
}
|
||||||
else if (isInit)
|
else if (isInit)
|
||||||
{
|
{
|
||||||
if (new->increment_by > 0)
|
if (new->increment_by > 0)
|
||||||
new->last_value = new->min_value; /* ascending seq */
|
new->start_value = new->min_value; /* ascending seq */
|
||||||
else
|
else
|
||||||
new->last_value = new->max_value; /* descending seq */
|
new->start_value = new->max_value; /* descending seq */
|
||||||
|
new->last_value = new->start_value;
|
||||||
new->is_called = false;
|
new->is_called = false;
|
||||||
new->log_cnt = 1;
|
new->log_cnt = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* crosscheck */
|
/* crosscheck START */
|
||||||
|
if (new->start_value < new->min_value)
|
||||||
|
{
|
||||||
|
char bufs[100],
|
||||||
|
bufm[100];
|
||||||
|
|
||||||
|
snprintf(bufs, sizeof(bufs), INT64_FORMAT, new->start_value);
|
||||||
|
snprintf(bufm, sizeof(bufm), INT64_FORMAT, new->min_value);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
char bufs[100],
|
||||||
|
bufm[100];
|
||||||
|
|
||||||
|
snprintf(bufs, sizeof(bufs), INT64_FORMAT, new->start_value);
|
||||||
|
snprintf(bufm, sizeof(bufm), INT64_FORMAT, new->max_value);
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
|
errmsg("START value (%s) cannot be greater than MAXVALUE (%s)",
|
||||||
|
bufs, bufm)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* must crosscheck RESTART separately */
|
||||||
if (new->last_value < new->min_value)
|
if (new->last_value < new->min_value)
|
||||||
{
|
{
|
||||||
char bufs[100],
|
char bufs[100],
|
||||||
@ -1136,7 +1207,7 @@ init_params(List *options, bool isInit,
|
|||||||
snprintf(bufm, sizeof(bufm), INT64_FORMAT, new->min_value);
|
snprintf(bufm, sizeof(bufm), INT64_FORMAT, new->min_value);
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
errmsg("START value (%s) cannot be less than MINVALUE (%s)",
|
errmsg("RESTART value (%s) cannot be less than MINVALUE (%s)",
|
||||||
bufs, bufm)));
|
bufs, bufm)));
|
||||||
}
|
}
|
||||||
if (new->last_value > new->max_value)
|
if (new->last_value > new->max_value)
|
||||||
@ -1148,7 +1219,7 @@ init_params(List *options, bool isInit,
|
|||||||
snprintf(bufm, sizeof(bufm), INT64_FORMAT, new->max_value);
|
snprintf(bufm, sizeof(bufm), INT64_FORMAT, new->max_value);
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
errmsg("START value (%s) cannot be greater than MAXVALUE (%s)",
|
errmsg("RESTART value (%s) cannot be greater than MAXVALUE (%s)",
|
||||||
bufs, bufm)));
|
bufs, bufm)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.253 2008/05/12 00:00:48 alvherre Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.254 2008/05/16 23:36:04 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -37,6 +37,7 @@
|
|||||||
#include "catalog/toasting.h"
|
#include "catalog/toasting.h"
|
||||||
#include "commands/cluster.h"
|
#include "commands/cluster.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
|
#include "commands/sequence.h"
|
||||||
#include "commands/tablecmds.h"
|
#include "commands/tablecmds.h"
|
||||||
#include "commands/tablespace.h"
|
#include "commands/tablespace.h"
|
||||||
#include "commands/trigger.h"
|
#include "commands/trigger.h"
|
||||||
@ -531,6 +532,7 @@ ExecuteTruncate(TruncateStmt *stmt)
|
|||||||
{
|
{
|
||||||
List *rels = NIL;
|
List *rels = NIL;
|
||||||
List *relids = NIL;
|
List *relids = NIL;
|
||||||
|
List *seq_relids = NIL;
|
||||||
EState *estate;
|
EState *estate;
|
||||||
ResultRelInfo *resultRelInfos;
|
ResultRelInfo *resultRelInfos;
|
||||||
ResultRelInfo *resultRelInfo;
|
ResultRelInfo *resultRelInfo;
|
||||||
@ -596,6 +598,40 @@ ExecuteTruncate(TruncateStmt *stmt)
|
|||||||
heap_truncate_check_FKs(rels, false);
|
heap_truncate_check_FKs(rels, false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we are asked to restart sequences, find all the sequences,
|
||||||
|
* lock them (we only need AccessShareLock because that's all that
|
||||||
|
* ALTER SEQUENCE takes), and check permissions. We want to do this
|
||||||
|
* early since it's pointless to do all the truncation work only to fail
|
||||||
|
* on sequence permissions.
|
||||||
|
*/
|
||||||
|
if (stmt->restart_seqs)
|
||||||
|
{
|
||||||
|
foreach(cell, rels)
|
||||||
|
{
|
||||||
|
Relation rel = (Relation) lfirst(cell);
|
||||||
|
List *seqlist = getOwnedSequences(RelationGetRelid(rel));
|
||||||
|
ListCell *seqcell;
|
||||||
|
|
||||||
|
foreach(seqcell, seqlist)
|
||||||
|
{
|
||||||
|
Oid seq_relid = lfirst_oid(seqcell);
|
||||||
|
Relation seq_rel;
|
||||||
|
|
||||||
|
seq_rel = relation_open(seq_relid, AccessShareLock);
|
||||||
|
|
||||||
|
/* This check must match AlterSequence! */
|
||||||
|
if (!pg_class_ownercheck(seq_relid, GetUserId()))
|
||||||
|
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
|
||||||
|
RelationGetRelationName(seq_rel));
|
||||||
|
|
||||||
|
seq_relids = lappend_oid(seq_relids, seq_relid);
|
||||||
|
|
||||||
|
relation_close(seq_rel, NoLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Prepare to catch AFTER triggers. */
|
/* Prepare to catch AFTER triggers. */
|
||||||
AfterTriggerBeginQuery();
|
AfterTriggerBeginQuery();
|
||||||
|
|
||||||
@ -694,6 +730,25 @@ ExecuteTruncate(TruncateStmt *stmt)
|
|||||||
|
|
||||||
heap_close(rel, NoLock);
|
heap_close(rel, NoLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lastly, restart any owned sequences if we were asked to. This is done
|
||||||
|
* last because it's nontransactional: restarts will not roll back if
|
||||||
|
* we abort later. Hence it's important to postpone them as long as
|
||||||
|
* possible. (This is also a big reason why we locked and
|
||||||
|
* permission-checked the sequences beforehand.)
|
||||||
|
*/
|
||||||
|
if (stmt->restart_seqs)
|
||||||
|
{
|
||||||
|
List *options = list_make1(makeDefElem("restart", NULL));
|
||||||
|
|
||||||
|
foreach(cell, seq_relids)
|
||||||
|
{
|
||||||
|
Oid seq_relid = lfirst_oid(cell);
|
||||||
|
|
||||||
|
AlterSequenceInternal(seq_relid, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.393 2008/04/29 14:59:16 alvherre Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.394 2008/05/16 23:36:05 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -2156,6 +2156,7 @@ _copyTruncateStmt(TruncateStmt *from)
|
|||||||
TruncateStmt *newnode = makeNode(TruncateStmt);
|
TruncateStmt *newnode = makeNode(TruncateStmt);
|
||||||
|
|
||||||
COPY_NODE_FIELD(relations);
|
COPY_NODE_FIELD(relations);
|
||||||
|
COPY_SCALAR_FIELD(restart_seqs);
|
||||||
COPY_SCALAR_FIELD(behavior);
|
COPY_SCALAR_FIELD(behavior);
|
||||||
|
|
||||||
return newnode;
|
return newnode;
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.322 2008/04/29 14:59:16 alvherre Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.323 2008/05/16 23:36:05 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1010,6 +1010,7 @@ static bool
|
|||||||
_equalTruncateStmt(TruncateStmt *a, TruncateStmt *b)
|
_equalTruncateStmt(TruncateStmt *a, TruncateStmt *b)
|
||||||
{
|
{
|
||||||
COMPARE_NODE_FIELD(relations);
|
COMPARE_NODE_FIELD(relations);
|
||||||
|
COMPARE_SCALAR_FIELD(restart_seqs);
|
||||||
COMPARE_SCALAR_FIELD(behavior);
|
COMPARE_SCALAR_FIELD(behavior);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.614 2008/04/29 20:44:49 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.615 2008/05/16 23:36:05 tgl Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -206,7 +206,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
|||||||
%type <str> OptSchemaName
|
%type <str> OptSchemaName
|
||||||
%type <list> OptSchemaEltList
|
%type <list> OptSchemaEltList
|
||||||
|
|
||||||
%type <boolean> TriggerActionTime TriggerForSpec opt_trusted
|
%type <boolean> TriggerActionTime TriggerForSpec opt_trusted opt_restart_seqs
|
||||||
%type <str> opt_lancompiler
|
%type <str> opt_lancompiler
|
||||||
|
|
||||||
%type <str> TriggerEvents
|
%type <str> TriggerEvents
|
||||||
@ -381,7 +381,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
|||||||
CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
|
CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
|
||||||
CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
|
CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
|
||||||
COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS
|
COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS
|
||||||
CONTENT_P CONVERSION_P COPY COST CREATE CREATEDB
|
CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
|
||||||
CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE
|
CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE
|
||||||
CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
|
CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
|
||||||
|
|
||||||
@ -399,10 +399,10 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
|||||||
|
|
||||||
HANDLER HAVING HEADER_P HOLD HOUR_P
|
HANDLER HAVING HEADER_P HOLD HOUR_P
|
||||||
|
|
||||||
IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT
|
IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P
|
||||||
INDEX INDEXES INHERIT INHERITS INITIALLY INNER_P INOUT INPUT_P
|
INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY
|
||||||
INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
|
INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
|
||||||
INTERVAL INTO INVOKER IS ISNULL ISOLATION
|
INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
|
||||||
|
|
||||||
JOIN
|
JOIN
|
||||||
|
|
||||||
@ -2489,6 +2489,10 @@ OptSeqElem: CACHE NumericOnly
|
|||||||
{
|
{
|
||||||
$$ = makeDefElem("start", (Node *)$3);
|
$$ = makeDefElem("start", (Node *)$3);
|
||||||
}
|
}
|
||||||
|
| RESTART
|
||||||
|
{
|
||||||
|
$$ = makeDefElem("restart", NULL);
|
||||||
|
}
|
||||||
| RESTART opt_with NumericOnly
|
| RESTART opt_with NumericOnly
|
||||||
{
|
{
|
||||||
$$ = makeDefElem("restart", (Node *)$3);
|
$$ = makeDefElem("restart", (Node *)$3);
|
||||||
@ -3364,15 +3368,22 @@ attrs: '.' attr_name
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
TruncateStmt:
|
TruncateStmt:
|
||||||
TRUNCATE opt_table qualified_name_list opt_drop_behavior
|
TRUNCATE opt_table qualified_name_list opt_restart_seqs opt_drop_behavior
|
||||||
{
|
{
|
||||||
TruncateStmt *n = makeNode(TruncateStmt);
|
TruncateStmt *n = makeNode(TruncateStmt);
|
||||||
n->relations = $3;
|
n->relations = $3;
|
||||||
n->behavior = $4;
|
n->restart_seqs = $4;
|
||||||
|
n->behavior = $5;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
opt_restart_seqs:
|
||||||
|
CONTINUE_P IDENTITY_P { $$ = false; }
|
||||||
|
| RESTART IDENTITY_P { $$ = true; }
|
||||||
|
| /* EMPTY */ { $$ = false; }
|
||||||
|
;
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* The COMMENT ON statement can take different forms based upon the type of
|
* The COMMENT ON statement can take different forms based upon the type of
|
||||||
@ -8964,6 +8975,7 @@ unreserved_keyword:
|
|||||||
| CONNECTION
|
| CONNECTION
|
||||||
| CONSTRAINTS
|
| CONSTRAINTS
|
||||||
| CONTENT_P
|
| CONTENT_P
|
||||||
|
| CONTINUE_P
|
||||||
| CONVERSION_P
|
| CONVERSION_P
|
||||||
| COPY
|
| COPY
|
||||||
| COST
|
| COST
|
||||||
@ -9014,6 +9026,7 @@ unreserved_keyword:
|
|||||||
| HEADER_P
|
| HEADER_P
|
||||||
| HOLD
|
| HOLD
|
||||||
| HOUR_P
|
| HOUR_P
|
||||||
|
| IDENTITY_P
|
||||||
| IF_P
|
| IF_P
|
||||||
| IMMEDIATE
|
| IMMEDIATE
|
||||||
| IMMUTABLE
|
| IMMUTABLE
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.195 2008/03/27 03:57:33 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.196 2008/05/16 23:36:05 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -101,6 +101,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"constraint", CONSTRAINT, RESERVED_KEYWORD},
|
{"constraint", CONSTRAINT, RESERVED_KEYWORD},
|
||||||
{"constraints", CONSTRAINTS, UNRESERVED_KEYWORD},
|
{"constraints", CONSTRAINTS, UNRESERVED_KEYWORD},
|
||||||
{"content", CONTENT_P, UNRESERVED_KEYWORD},
|
{"content", CONTENT_P, UNRESERVED_KEYWORD},
|
||||||
|
{"continue", CONTINUE_P, UNRESERVED_KEYWORD},
|
||||||
{"conversion", CONVERSION_P, UNRESERVED_KEYWORD},
|
{"conversion", CONVERSION_P, UNRESERVED_KEYWORD},
|
||||||
{"copy", COPY, UNRESERVED_KEYWORD},
|
{"copy", COPY, UNRESERVED_KEYWORD},
|
||||||
{"cost", COST, UNRESERVED_KEYWORD},
|
{"cost", COST, UNRESERVED_KEYWORD},
|
||||||
@ -181,6 +182,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"header", HEADER_P, UNRESERVED_KEYWORD},
|
{"header", HEADER_P, UNRESERVED_KEYWORD},
|
||||||
{"hold", HOLD, UNRESERVED_KEYWORD},
|
{"hold", HOLD, UNRESERVED_KEYWORD},
|
||||||
{"hour", HOUR_P, UNRESERVED_KEYWORD},
|
{"hour", HOUR_P, UNRESERVED_KEYWORD},
|
||||||
|
{"identity", IDENTITY_P, UNRESERVED_KEYWORD},
|
||||||
{"if", IF_P, UNRESERVED_KEYWORD},
|
{"if", IF_P, UNRESERVED_KEYWORD},
|
||||||
{"ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD},
|
{"ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD},
|
||||||
{"immediate", IMMEDIATE, UNRESERVED_KEYWORD},
|
{"immediate", IMMEDIATE, UNRESERVED_KEYWORD},
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* by PostgreSQL
|
* by PostgreSQL
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.491 2008/05/12 00:00:53 alvherre Exp $
|
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.492 2008/05/16 23:36:05 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -9525,7 +9525,8 @@ static void
|
|||||||
dumpSequence(Archive *fout, TableInfo *tbinfo)
|
dumpSequence(Archive *fout, TableInfo *tbinfo)
|
||||||
{
|
{
|
||||||
PGresult *res;
|
PGresult *res;
|
||||||
char *last,
|
char *startv,
|
||||||
|
*last,
|
||||||
*incby,
|
*incby,
|
||||||
*maxv = NULL,
|
*maxv = NULL,
|
||||||
*minv = NULL,
|
*minv = NULL,
|
||||||
@ -9543,19 +9544,40 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
|
|||||||
snprintf(bufm, sizeof(bufm), INT64_FORMAT, SEQ_MINVALUE);
|
snprintf(bufm, sizeof(bufm), INT64_FORMAT, SEQ_MINVALUE);
|
||||||
snprintf(bufx, sizeof(bufx), INT64_FORMAT, SEQ_MAXVALUE);
|
snprintf(bufx, sizeof(bufx), INT64_FORMAT, SEQ_MAXVALUE);
|
||||||
|
|
||||||
appendPQExpBuffer(query,
|
if (g_fout->remoteVersion >= 80400)
|
||||||
"SELECT sequence_name, last_value, increment_by, "
|
{
|
||||||
"CASE WHEN increment_by > 0 AND max_value = %s THEN NULL "
|
appendPQExpBuffer(query,
|
||||||
" WHEN increment_by < 0 AND max_value = -1 THEN NULL "
|
"SELECT sequence_name, "
|
||||||
" ELSE max_value "
|
"start_value, last_value, increment_by, "
|
||||||
"END AS max_value, "
|
"CASE WHEN increment_by > 0 AND max_value = %s THEN NULL "
|
||||||
"CASE WHEN increment_by > 0 AND min_value = 1 THEN NULL "
|
" WHEN increment_by < 0 AND max_value = -1 THEN NULL "
|
||||||
" WHEN increment_by < 0 AND min_value = %s THEN NULL "
|
" ELSE max_value "
|
||||||
" ELSE min_value "
|
"END AS max_value, "
|
||||||
"END AS min_value, "
|
"CASE WHEN increment_by > 0 AND min_value = 1 THEN NULL "
|
||||||
"cache_value, is_cycled, is_called from %s",
|
" WHEN increment_by < 0 AND min_value = %s THEN NULL "
|
||||||
bufx, bufm,
|
" ELSE min_value "
|
||||||
fmtId(tbinfo->dobj.name));
|
"END AS min_value, "
|
||||||
|
"cache_value, is_cycled, is_called from %s",
|
||||||
|
bufx, bufm,
|
||||||
|
fmtId(tbinfo->dobj.name));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
appendPQExpBuffer(query,
|
||||||
|
"SELECT sequence_name, "
|
||||||
|
"0 as start_value, last_value, increment_by, "
|
||||||
|
"CASE WHEN increment_by > 0 AND max_value = %s THEN NULL "
|
||||||
|
" WHEN increment_by < 0 AND max_value = -1 THEN NULL "
|
||||||
|
" ELSE max_value "
|
||||||
|
"END AS max_value, "
|
||||||
|
"CASE WHEN increment_by > 0 AND min_value = 1 THEN NULL "
|
||||||
|
" WHEN increment_by < 0 AND min_value = %s THEN NULL "
|
||||||
|
" ELSE min_value "
|
||||||
|
"END AS min_value, "
|
||||||
|
"cache_value, is_cycled, is_called from %s",
|
||||||
|
bufx, bufm,
|
||||||
|
fmtId(tbinfo->dobj.name));
|
||||||
|
}
|
||||||
|
|
||||||
res = PQexec(g_conn, query->data);
|
res = PQexec(g_conn, query->data);
|
||||||
check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
|
check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
|
||||||
@ -9577,15 +9599,16 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
last = PQgetvalue(res, 0, 1);
|
startv = PQgetvalue(res, 0, 1);
|
||||||
incby = PQgetvalue(res, 0, 2);
|
last = PQgetvalue(res, 0, 2);
|
||||||
if (!PQgetisnull(res, 0, 3))
|
incby = PQgetvalue(res, 0, 3);
|
||||||
maxv = PQgetvalue(res, 0, 3);
|
|
||||||
if (!PQgetisnull(res, 0, 4))
|
if (!PQgetisnull(res, 0, 4))
|
||||||
minv = PQgetvalue(res, 0, 4);
|
maxv = PQgetvalue(res, 0, 4);
|
||||||
cache = PQgetvalue(res, 0, 5);
|
if (!PQgetisnull(res, 0, 5))
|
||||||
cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0);
|
minv = PQgetvalue(res, 0, 5);
|
||||||
called = (strcmp(PQgetvalue(res, 0, 7), "t") == 0);
|
cache = PQgetvalue(res, 0, 6);
|
||||||
|
cycled = (strcmp(PQgetvalue(res, 0, 7), "t") == 0);
|
||||||
|
called = (strcmp(PQgetvalue(res, 0, 8), "t") == 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The logic we use for restoring sequences is as follows:
|
* The logic we use for restoring sequences is as follows:
|
||||||
@ -9615,8 +9638,18 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
|
|||||||
"CREATE SEQUENCE %s\n",
|
"CREATE SEQUENCE %s\n",
|
||||||
fmtId(tbinfo->dobj.name));
|
fmtId(tbinfo->dobj.name));
|
||||||
|
|
||||||
if (!called)
|
if (g_fout->remoteVersion >= 80400)
|
||||||
appendPQExpBuffer(query, " START WITH %s\n", last);
|
appendPQExpBuffer(query, " START WITH %s\n", startv);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Versions before 8.4 did not remember the true start value. If
|
||||||
|
* is_called is false then the sequence has never been incremented
|
||||||
|
* so we can use last_val. Otherwise punt and let it default.
|
||||||
|
*/
|
||||||
|
if (!called)
|
||||||
|
appendPQExpBuffer(query, " START WITH %s\n", last);
|
||||||
|
}
|
||||||
|
|
||||||
appendPQExpBuffer(query, " INCREMENT BY %s\n", incby);
|
appendPQExpBuffer(query, " INCREMENT BY %s\n", incby);
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.460 2008/05/16 16:31:01 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.461 2008/05/16 23:36:05 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200805161
|
#define CATALOG_VERSION_NO 200805162
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.34 2008/03/24 19:47:35 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.35 2008/05/16 23:36:05 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -207,6 +207,8 @@ extern bool sequenceIsOwned(Oid seqId, Oid *tableId, int32 *colId);
|
|||||||
|
|
||||||
extern void markSequenceUnowned(Oid seqId);
|
extern void markSequenceUnowned(Oid seqId);
|
||||||
|
|
||||||
|
extern List *getOwnedSequences(Oid relid);
|
||||||
|
|
||||||
extern Oid get_constraint_index(Oid constraintId);
|
extern Oid get_constraint_index(Oid constraintId);
|
||||||
|
|
||||||
extern Oid get_index_constraint(Oid indexId);
|
extern Oid get_index_constraint(Oid indexId);
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/commands/sequence.h,v 1.40 2008/03/27 03:57:34 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/commands/sequence.h,v 1.41 2008/05/16 23:36:05 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -30,6 +30,7 @@ typedef struct FormData_pg_sequence
|
|||||||
NameData sequence_name;
|
NameData sequence_name;
|
||||||
#ifndef INT64_IS_BUSTED
|
#ifndef INT64_IS_BUSTED
|
||||||
int64 last_value;
|
int64 last_value;
|
||||||
|
int64 start_value;
|
||||||
int64 increment_by;
|
int64 increment_by;
|
||||||
int64 max_value;
|
int64 max_value;
|
||||||
int64 min_value;
|
int64 min_value;
|
||||||
@ -38,16 +39,18 @@ typedef struct FormData_pg_sequence
|
|||||||
#else
|
#else
|
||||||
int32 last_value;
|
int32 last_value;
|
||||||
int32 pad1;
|
int32 pad1;
|
||||||
int32 increment_by;
|
int32 start_value;
|
||||||
int32 pad2;
|
int32 pad2;
|
||||||
int32 max_value;
|
int32 increment_by;
|
||||||
int32 pad3;
|
int32 pad3;
|
||||||
int32 min_value;
|
int32 max_value;
|
||||||
int32 pad4;
|
int32 pad4;
|
||||||
int32 cache_value;
|
int32 min_value;
|
||||||
int32 pad5;
|
int32 pad5;
|
||||||
int32 log_cnt;
|
int32 cache_value;
|
||||||
int32 pad6;
|
int32 pad6;
|
||||||
|
int32 log_cnt;
|
||||||
|
int32 pad7;
|
||||||
#endif
|
#endif
|
||||||
bool is_cycled;
|
bool is_cycled;
|
||||||
bool is_called;
|
bool is_called;
|
||||||
@ -61,13 +64,14 @@ typedef FormData_pg_sequence *Form_pg_sequence;
|
|||||||
|
|
||||||
#define SEQ_COL_NAME 1
|
#define SEQ_COL_NAME 1
|
||||||
#define SEQ_COL_LASTVAL 2
|
#define SEQ_COL_LASTVAL 2
|
||||||
#define SEQ_COL_INCBY 3
|
#define SEQ_COL_STARTVAL 3
|
||||||
#define SEQ_COL_MAXVALUE 4
|
#define SEQ_COL_INCBY 4
|
||||||
#define SEQ_COL_MINVALUE 5
|
#define SEQ_COL_MAXVALUE 5
|
||||||
#define SEQ_COL_CACHE 6
|
#define SEQ_COL_MINVALUE 6
|
||||||
#define SEQ_COL_LOG 7
|
#define SEQ_COL_CACHE 7
|
||||||
#define SEQ_COL_CYCLE 8
|
#define SEQ_COL_LOG 8
|
||||||
#define SEQ_COL_CALLED 9
|
#define SEQ_COL_CYCLE 9
|
||||||
|
#define SEQ_COL_CALLED 10
|
||||||
|
|
||||||
#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
|
||||||
@ -90,6 +94,7 @@ extern Datum lastval(PG_FUNCTION_ARGS);
|
|||||||
|
|
||||||
extern void DefineSequence(CreateSeqStmt *stmt);
|
extern void DefineSequence(CreateSeqStmt *stmt);
|
||||||
extern void AlterSequence(AlterSeqStmt *stmt);
|
extern void AlterSequence(AlterSeqStmt *stmt);
|
||||||
|
extern void AlterSequenceInternal(Oid relid, List *options);
|
||||||
|
|
||||||
extern void seq_redo(XLogRecPtr lsn, XLogRecord *rptr);
|
extern void seq_redo(XLogRecPtr lsn, XLogRecord *rptr);
|
||||||
extern void seq_desc(StringInfo buf, uint8 xl_info, char *rec);
|
extern void seq_desc(StringInfo buf, uint8 xl_info, char *rec);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.365 2008/05/09 23:32:04 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.366 2008/05/16 23:36:05 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1452,6 +1452,7 @@ typedef struct TruncateStmt
|
|||||||
{
|
{
|
||||||
NodeTag type;
|
NodeTag type;
|
||||||
List *relations; /* relations (RangeVars) to be truncated */
|
List *relations; /* relations (RangeVars) to be truncated */
|
||||||
|
bool restart_seqs; /* restart owned sequences? */
|
||||||
DropBehavior behavior; /* RESTRICT or CASCADE behavior */
|
DropBehavior behavior; /* RESTRICT or CASCADE behavior */
|
||||||
} TruncateStmt;
|
} TruncateStmt;
|
||||||
|
|
||||||
|
@ -99,9 +99,27 @@ DROP SEQUENCE sequence_test;
|
|||||||
CREATE SEQUENCE foo_seq;
|
CREATE SEQUENCE foo_seq;
|
||||||
ALTER TABLE foo_seq RENAME TO foo_seq_new;
|
ALTER TABLE foo_seq RENAME TO foo_seq_new;
|
||||||
SELECT * FROM foo_seq_new;
|
SELECT * FROM foo_seq_new;
|
||||||
sequence_name | last_value | increment_by | max_value | min_value | cache_value | log_cnt | is_cycled | is_called
|
sequence_name | last_value | start_value | increment_by | max_value | min_value | cache_value | log_cnt | is_cycled | is_called
|
||||||
---------------+------------+--------------+---------------------+-----------+-------------+---------+-----------+-----------
|
---------------+------------+-------------+--------------+---------------------+-----------+-------------+---------+-----------+-----------
|
||||||
foo_seq | 1 | 1 | 9223372036854775807 | 1 | 1 | 1 | f | f
|
foo_seq | 1 | 1 | 1 | 9223372036854775807 | 1 | 1 | 1 | f | f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT nextval('foo_seq_new');
|
||||||
|
nextval
|
||||||
|
---------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT nextval('foo_seq_new');
|
||||||
|
nextval
|
||||||
|
---------
|
||||||
|
2
|
||||||
|
(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 | 32 | f | t
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
DROP SEQUENCE foo_seq_new;
|
DROP SEQUENCE foo_seq_new;
|
||||||
@ -155,18 +173,49 @@ SELECT nextval('sequence_test2');
|
|||||||
32
|
32
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
ALTER SEQUENCE sequence_test2 RESTART WITH 16
|
ALTER SEQUENCE sequence_test2 RESTART WITH 24
|
||||||
INCREMENT BY 4 MAXVALUE 22 MINVALUE 5 CYCLE;
|
INCREMENT BY 4 MAXVALUE 36 MINVALUE 5 CYCLE;
|
||||||
SELECT nextval('sequence_test2');
|
SELECT nextval('sequence_test2');
|
||||||
nextval
|
nextval
|
||||||
---------
|
---------
|
||||||
16
|
24
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT nextval('sequence_test2');
|
SELECT nextval('sequence_test2');
|
||||||
nextval
|
nextval
|
||||||
---------
|
---------
|
||||||
20
|
28
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT nextval('sequence_test2');
|
||||||
|
nextval
|
||||||
|
---------
|
||||||
|
32
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT nextval('sequence_test2');
|
||||||
|
nextval
|
||||||
|
---------
|
||||||
|
36
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT nextval('sequence_test2');
|
||||||
|
nextval
|
||||||
|
---------
|
||||||
|
5
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
ALTER SEQUENCE sequence_test2 RESTART;
|
||||||
|
SELECT nextval('sequence_test2');
|
||||||
|
nextval
|
||||||
|
---------
|
||||||
|
32
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT nextval('sequence_test2');
|
||||||
|
nextval
|
||||||
|
---------
|
||||||
|
36
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT nextval('sequence_test2');
|
SELECT nextval('sequence_test2');
|
||||||
|
@ -223,3 +223,41 @@ SELECT * FROM trunc_trigger_log;
|
|||||||
DROP TABLE trunc_trigger_test;
|
DROP TABLE trunc_trigger_test;
|
||||||
DROP TABLE trunc_trigger_log;
|
DROP TABLE trunc_trigger_log;
|
||||||
DROP FUNCTION trunctrigger();
|
DROP FUNCTION trunctrigger();
|
||||||
|
-- test TRUNCATE ... RESTART IDENTITY
|
||||||
|
CREATE SEQUENCE truncate_a_id1 START WITH 33;
|
||||||
|
CREATE TABLE truncate_a (id serial,
|
||||||
|
id1 integer default nextval('truncate_a_id1'));
|
||||||
|
NOTICE: CREATE TABLE will create implicit sequence "truncate_a_id_seq" for serial column "truncate_a.id"
|
||||||
|
ALTER SEQUENCE truncate_a_id1 OWNED BY truncate_a.id1;
|
||||||
|
INSERT INTO truncate_a DEFAULT VALUES;
|
||||||
|
INSERT INTO truncate_a DEFAULT VALUES;
|
||||||
|
SELECT * FROM truncate_a;
|
||||||
|
id | id1
|
||||||
|
----+-----
|
||||||
|
1 | 33
|
||||||
|
2 | 34
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
TRUNCATE truncate_a;
|
||||||
|
INSERT INTO truncate_a DEFAULT VALUES;
|
||||||
|
INSERT INTO truncate_a DEFAULT VALUES;
|
||||||
|
SELECT * FROM truncate_a;
|
||||||
|
id | id1
|
||||||
|
----+-----
|
||||||
|
3 | 35
|
||||||
|
4 | 36
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
TRUNCATE truncate_a RESTART IDENTITY;
|
||||||
|
INSERT INTO truncate_a DEFAULT VALUES;
|
||||||
|
INSERT INTO truncate_a DEFAULT VALUES;
|
||||||
|
SELECT * FROM truncate_a;
|
||||||
|
id | id1
|
||||||
|
----+-----
|
||||||
|
1 | 33
|
||||||
|
2 | 34
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
DROP TABLE truncate_a;
|
||||||
|
SELECT nextval('truncate_a_id1'); -- fail, seq should have been dropped
|
||||||
|
ERROR: relation "truncate_a_id1" does not exist
|
||||||
|
@ -33,6 +33,9 @@ DROP SEQUENCE sequence_test;
|
|||||||
CREATE SEQUENCE foo_seq;
|
CREATE SEQUENCE foo_seq;
|
||||||
ALTER TABLE foo_seq RENAME TO foo_seq_new;
|
ALTER TABLE foo_seq RENAME TO foo_seq_new;
|
||||||
SELECT * FROM foo_seq_new;
|
SELECT * FROM foo_seq_new;
|
||||||
|
SELECT nextval('foo_seq_new');
|
||||||
|
SELECT nextval('foo_seq_new');
|
||||||
|
SELECT * FROM foo_seq_new;
|
||||||
DROP SEQUENCE foo_seq_new;
|
DROP SEQUENCE foo_seq_new;
|
||||||
|
|
||||||
-- renaming serial sequences
|
-- renaming serial sequences
|
||||||
@ -68,8 +71,16 @@ CREATE SEQUENCE sequence_test2 START WITH 32;
|
|||||||
|
|
||||||
SELECT nextval('sequence_test2');
|
SELECT nextval('sequence_test2');
|
||||||
|
|
||||||
ALTER SEQUENCE sequence_test2 RESTART WITH 16
|
ALTER SEQUENCE sequence_test2 RESTART WITH 24
|
||||||
INCREMENT BY 4 MAXVALUE 22 MINVALUE 5 CYCLE;
|
INCREMENT BY 4 MAXVALUE 36 MINVALUE 5 CYCLE;
|
||||||
|
SELECT nextval('sequence_test2');
|
||||||
|
SELECT nextval('sequence_test2');
|
||||||
|
SELECT nextval('sequence_test2');
|
||||||
|
SELECT nextval('sequence_test2');
|
||||||
|
SELECT nextval('sequence_test2');
|
||||||
|
|
||||||
|
ALTER SEQUENCE sequence_test2 RESTART;
|
||||||
|
|
||||||
SELECT nextval('sequence_test2');
|
SELECT nextval('sequence_test2');
|
||||||
SELECT nextval('sequence_test2');
|
SELECT nextval('sequence_test2');
|
||||||
SELECT nextval('sequence_test2');
|
SELECT nextval('sequence_test2');
|
||||||
|
@ -130,3 +130,29 @@ DROP TABLE trunc_trigger_test;
|
|||||||
DROP TABLE trunc_trigger_log;
|
DROP TABLE trunc_trigger_log;
|
||||||
|
|
||||||
DROP FUNCTION trunctrigger();
|
DROP FUNCTION trunctrigger();
|
||||||
|
|
||||||
|
-- test TRUNCATE ... RESTART IDENTITY
|
||||||
|
CREATE SEQUENCE truncate_a_id1 START WITH 33;
|
||||||
|
CREATE TABLE truncate_a (id serial,
|
||||||
|
id1 integer default nextval('truncate_a_id1'));
|
||||||
|
ALTER SEQUENCE truncate_a_id1 OWNED BY truncate_a.id1;
|
||||||
|
|
||||||
|
INSERT INTO truncate_a DEFAULT VALUES;
|
||||||
|
INSERT INTO truncate_a DEFAULT VALUES;
|
||||||
|
SELECT * FROM truncate_a;
|
||||||
|
|
||||||
|
TRUNCATE truncate_a;
|
||||||
|
|
||||||
|
INSERT INTO truncate_a DEFAULT VALUES;
|
||||||
|
INSERT INTO truncate_a DEFAULT VALUES;
|
||||||
|
SELECT * FROM truncate_a;
|
||||||
|
|
||||||
|
TRUNCATE truncate_a RESTART IDENTITY;
|
||||||
|
|
||||||
|
INSERT INTO truncate_a DEFAULT VALUES;
|
||||||
|
INSERT INTO truncate_a DEFAULT VALUES;
|
||||||
|
SELECT * FROM truncate_a;
|
||||||
|
|
||||||
|
DROP TABLE truncate_a;
|
||||||
|
|
||||||
|
SELECT nextval('truncate_a_id1'); -- fail, seq should have been dropped
|
||||||
|
Reference in New Issue
Block a user