]> granicus.if.org Git - postgresql/commitdiff
Implement IF NOT EXISTS for CREATE SEQUENCE.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Tue, 26 Aug 2014 13:05:18 +0000 (16:05 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Tue, 26 Aug 2014 13:18:17 +0000 (16:18 +0300)
Fabrízio de Royes Mello

doc/src/sgml/ref/create_sequence.sgml
src/backend/commands/sequence.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/parser/gram.y
src/include/nodes/parsenodes.h
src/test/regress/expected/sequence.out
src/test/regress/sql/sequence.sql

index b8468b5bb254f129477a912a086bd46708abbee5..7292c3fa36155bebfde2d45784b5e80c1abda704 100644 (file)
@@ -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 } ]
@@ -89,6 +89,18 @@ SELECT * FROM <replaceable>name</replaceable>;
     </listitem>
    </varlistentry>
 
+   <varlistentry>
+    <term><literal>IF NOT EXISTS</literal></term>
+    <listitem>
+     <para>
+      Do not throw an error if a relation with the same name already exists.
+      A notice is issued in this case. Note that there is no guarantee that
+      the existing relation is anything like the sequence that would have
+      been created - it might not even be a sequence.
+     </para>
+    </listitem>
+   </varlistentry>
+
    <varlistentry>
     <term><replaceable class="parameter">name</replaceable></term>
     <listitem>
index e6084203a88d8353bd71c98de26c023103b113da..3b89dd009bcbec95f7689f3e7af494fa8a69b881 100644 (file)
@@ -122,6 +122,24 @@ DefineSequence(CreateSeqStmt *seq)
                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                 errmsg("unlogged sequences are not supported")));
 
+       /*
+        * If if_not_exists was given and a relation with the same name already
+        * exists, bail out. (Note: we needn't check this when not if_not_exists,
+        * because DefineRelation will complain anyway.)
+        */
+       if (seq->if_not_exists)
+       {
+               RangeVarGetAndCheckCreationNamespace(seq->sequence, NoLock, &seqoid);
+               if (OidIsValid(seqoid))
+               {
+                       ereport(NOTICE,
+                                       (errcode(ERRCODE_DUPLICATE_TABLE),
+                                        errmsg("relation \"%s\" already exists, skipping",
+                                                       seq->sequence->relname)));
+                       return InvalidOid;
+               }
+       }
+
        /* Check and set all option values */
        init_params(seq->options, true, &new, &owned_by);
 
@@ -210,7 +228,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);
index f5ddc1ced7c4345e7459169ea01ff9dd534af20a..aa053a0f158889c409bc2a042bcda19c0ce43ddc 100644 (file)
@@ -3330,6 +3330,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;
 }
index ccd6064bf7d6c6feb305f19e6ec7048969723f23..719923e02e764d188b9d5ffe72ea7d7f056113eb 100644 (file)
@@ -1566,6 +1566,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;
 }
index 71ce7ee2ddffcbfd2e7986c6811eb08217ef8a45..6f4d6455df69d2e31ea3c76c1bb38c577eb77e0d 100644 (file)
@@ -3486,6 +3486,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;
                                }
                ;
index 28029fe69ee8b0121be9aa7e96fe27c5c98b8525..d2c0b29c0d7e3a2b18119ef208c7b82e3a7f1258 100644 (file)
@@ -1979,6 +1979,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;  /* just do nothing if it already exists? */
 } CreateSeqStmt;
 
 typedef struct AlterSeqStmt
index 8fcb70015fb58e5b22355e48f89fd2d25276d4aa..a27b5fda04500773e89cd4d8f087e0f94c0ae3d3 100644 (file)
@@ -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 
 ---------
index be5e9a97bf40e8c5afd8951faebd6fb0b491bdb8..8d3b700f7da73caa030652703552d2adad7170d2 100644 (file)
@@ -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);