On Tue, Apr 1, 2014 at 2:46 PM, Robert Haas <robertmh...@gmail.com> wrote: > > >> Where this is a bit more interesting is in the case of sequences, where > >> resetting the sequence to zero may cause further inserts into an > >> existing table to fail. > > > > Yeah. Sequences do have contained data, which makes COR harder to define > > --- that's part of the reason why we have CINE not COR for tables, and > > maybe we have to do the same for sequences. The point being exactly > > that if you use CINE, you're implicitly accepting that you don't know > > the ensuing state fully. > > Yeah. I think CINE is more sensible than COR for sequences, for > precisely the reason that they do have contained data (even if it's > basically only one value). >
The attached patch contains CINE for sequences. I just strip this code from the patch rejected before. Regards, -- Fabrízio de Royes Mello Consultoria/Coaching PostgreSQL >> Timbira: http://www.timbira.com.br >> Blog sobre TI: http://fabriziomello.blogspot.com >> Perfil Linkedin: http://br.linkedin.com/in/fabriziomello >> Twitter: http://twitter.com/fabriziomello
diff --git a/doc/src/sgml/ref/create_sequence.sgml b/doc/src/sgml/ref/create_sequence.sgml index 70b9f3d..de85b18 100644 --- a/doc/src/sgml/ref/create_sequence.sgml +++ b/doc/src/sgml/ref/create_sequence.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> -CREATE [ TEMPORARY | TEMP ] SEQUENCE <replaceable class="parameter">name</replaceable> [ INCREMENT [ BY ] <replaceable class="parameter">increment</replaceable> ] +CREATE [ TEMPORARY | TEMP ] [ IF NOT EXISTS ] 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 ] [ START [ WITH ] <replaceable class="parameter">start</replaceable> ] [ CACHE <replaceable class="parameter">cache</replaceable> ] [ [ NO ] CYCLE ] [ OWNED BY { <replaceable class="parameter">table_name</replaceable>.<replaceable class="parameter">column_name</replaceable> | NONE } ] @@ -90,6 +90,16 @@ SELECT * FROM <replaceable>name</replaceable>; </varlistentry> <varlistentry> + <term><literal>IF NOT EXISTS</literal></term> + <listitem> + <para> + Do nothing (except issuing a notice) if a sequence with the same name + already exists. + </para> + </listitem> + </varlistentry> + + <varlistentry> <term><replaceable class="parameter">name</replaceable></term> <listitem> <para> diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index ed696be..54be1b8 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -122,6 +122,17 @@ DefineSequence(CreateSeqStmt *seq) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("unlogged sequences are not supported"))); + /* Check for IF NOT EXISTS clause */ + RangeVarGetAndCheckCreationNamespace(seq->sequence, NoLock, &seqoid); + if (seq->if_not_exists && OidIsValid(seqoid)) + { + ereport(NOTICE, + (errcode(ERRCODE_DUPLICATE_TABLE), + errmsg("relation \"%s\" already exists, skipping", + seq->sequence->relname))); + return seqoid; + } + /* Check and set all option values */ init_params(seq->options, true, &new, &owned_by); @@ -210,7 +221,7 @@ DefineSequence(CreateSeqStmt *seq) stmt->options = NIL; stmt->oncommit = ONCOMMIT_NOOP; stmt->tablespacename = NULL; - stmt->if_not_exists = false; + stmt->if_not_exists = seq->if_not_exists; seqoid = DefineRelation(stmt, RELKIND_SEQUENCE, seq->ownerId); Assert(seqoid != InvalidOid); diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 98ad910..fecf4b7 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -3317,6 +3317,7 @@ _copyCreateSeqStmt(const CreateSeqStmt *from) COPY_NODE_FIELD(sequence); COPY_NODE_FIELD(options); COPY_SCALAR_FIELD(ownerId); + COPY_SCALAR_FIELD(if_not_exists); return newnode; } diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 9901d23..21663fb 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -1565,6 +1565,7 @@ _equalCreateSeqStmt(const CreateSeqStmt *a, const CreateSeqStmt *b) COMPARE_NODE_FIELD(sequence); COMPARE_NODE_FIELD(options); COMPARE_SCALAR_FIELD(ownerId); + COMPARE_SCALAR_FIELD(if_not_exists); return true; } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 7b9895d..27c24ea 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -3391,6 +3391,17 @@ CreateSeqStmt: n->sequence = $4; n->options = $5; n->ownerId = InvalidOid; + n->if_not_exists = false; + $$ = (Node *)n; + } + | CREATE OptTemp SEQUENCE IF_P NOT EXISTS qualified_name OptSeqOptList + { + CreateSeqStmt *n = makeNode(CreateSeqStmt); + $7->relpersistence = $2; + n->sequence = $7; + n->options = $8; + n->ownerId = InvalidOid; + n->if_not_exists = true; $$ = (Node *)n; } ; diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 18d4991..3facff7 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -1941,6 +1941,7 @@ typedef struct CreateSeqStmt RangeVar *sequence; /* the sequence to create */ List *options; Oid ownerId; /* ID of owner, or InvalidOid for default */ + bool if_not_exists; /* skip error if a Sequence already exists */ } CreateSeqStmt; typedef struct AlterSeqStmt diff --git a/src/test/regress/expected/sequence.out b/src/test/regress/expected/sequence.out index 8fcb700..a27b5fd 100644 --- a/src/test/regress/expected/sequence.out +++ b/src/test/regress/expected/sequence.out @@ -91,6 +91,8 @@ SELECT nextval('serialTest2_f6_seq'); -- basic sequence operations using both text and oid references CREATE SEQUENCE sequence_test; +CREATE SEQUENCE IF NOT EXISTS sequence_test; +NOTICE: relation "sequence_test" already exists, skipping SELECT nextval('sequence_test'::text); nextval --------- diff --git a/src/test/regress/sql/sequence.sql b/src/test/regress/sql/sequence.sql index be5e9a9..8d3b700 100644 --- a/src/test/regress/sql/sequence.sql +++ b/src/test/regress/sql/sequence.sql @@ -59,6 +59,7 @@ SELECT nextval('serialTest2_f6_seq'); -- basic sequence operations using both text and oid references CREATE SEQUENCE sequence_test; +CREATE SEQUENCE IF NOT EXISTS sequence_test; SELECT nextval('sequence_test'::text); SELECT nextval('sequence_test'::regclass);
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers