aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/ref/create_sequence.sgml14
-rw-r--r--src/backend/commands/sequence.c20
-rw-r--r--src/backend/nodes/copyfuncs.c1
-rw-r--r--src/backend/nodes/equalfuncs.c1
-rw-r--r--src/backend/parser/gram.y11
-rw-r--r--src/include/nodes/parsenodes.h1
-rw-r--r--src/test/regress/expected/sequence.out2
-rw-r--r--src/test/regress/sql/sequence.sql1
8 files changed, 49 insertions, 2 deletions
diff --git a/doc/src/sgml/ref/create_sequence.sgml b/doc/src/sgml/ref/create_sequence.sgml
index b8468b5bb25..7292c3fa361 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,18 @@ SELECT * FROM <replaceable>name</replaceable>;
</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>
<para>
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index e6084203a88..3b89dd009bc 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -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);
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index f5ddc1ced7c..aa053a0f158 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -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;
}
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index ccd6064bf7d..719923e02e7 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -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;
}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 71ce7ee2ddf..6f4d6455df6 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -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;
}
;
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 28029fe69ee..d2c0b29c0d7 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -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
diff --git a/src/test/regress/expected/sequence.out b/src/test/regress/expected/sequence.out
index 8fcb70015fb..a27b5fda045 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 be5e9a97bf4..8d3b700f7da 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);