aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/collationcmds.c4
-rw-r--r--src/backend/nodes/copyfuncs.c1
-rw-r--r--src/backend/nodes/equalfuncs.c1
-rw-r--r--src/backend/parser/gram.y20
-rw-r--r--src/backend/tcop/utility.c3
-rw-r--r--src/include/commands/collationcmds.h2
-rw-r--r--src/include/nodes/parsenodes.h1
-rw-r--r--src/test/regress/expected/collate.linux.utf8.out4
-rw-r--r--src/test/regress/sql/collate.linux.utf8.sql2
9 files changed, 34 insertions, 4 deletions
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index e165d4b2a6b..919cfc6a067 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -37,7 +37,7 @@
* CREATE COLLATION
*/
ObjectAddress
-DefineCollation(ParseState *pstate, List *names, List *parameters)
+DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_exists)
{
char *collName;
Oid collNamespace;
@@ -137,7 +137,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters)
GetDatabaseEncoding(),
collcollate,
collctype,
- false);
+ if_not_exists);
if (!OidIsValid(newoid))
return InvalidObjectAddress;
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 12324ab63f1..05d8538717a 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -3105,6 +3105,7 @@ _copyDefineStmt(const DefineStmt *from)
COPY_NODE_FIELD(defnames);
COPY_NODE_FIELD(args);
COPY_NODE_FIELD(definition);
+ COPY_SCALAR_FIELD(if_not_exists);
return newnode;
}
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 6d1dabe17e9..d595cd74812 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1211,6 +1211,7 @@ _equalDefineStmt(const DefineStmt *a, const DefineStmt *b)
COMPARE_NODE_FIELD(defnames);
COMPARE_NODE_FIELD(args);
COMPARE_NODE_FIELD(definition);
+ COMPARE_SCALAR_FIELD(if_not_exists);
return true;
}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 174773bdf31..5cb82977d5d 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -5610,6 +5610,16 @@ DefineStmt:
n->definition = $4;
$$ = (Node *)n;
}
+ | CREATE COLLATION IF_P NOT EXISTS any_name definition
+ {
+ DefineStmt *n = makeNode(DefineStmt);
+ n->kind = OBJECT_COLLATION;
+ n->args = NIL;
+ n->defnames = $6;
+ n->definition = $7;
+ n->if_not_exists = true;
+ $$ = (Node *)n;
+ }
| CREATE COLLATION any_name FROM any_name
{
DefineStmt *n = makeNode(DefineStmt);
@@ -5619,6 +5629,16 @@ DefineStmt:
n->definition = list_make1(makeDefElem("from", (Node *) $5, @5));
$$ = (Node *)n;
}
+ | CREATE COLLATION IF_P NOT EXISTS any_name FROM any_name
+ {
+ DefineStmt *n = makeNode(DefineStmt);
+ n->kind = OBJECT_COLLATION;
+ n->args = NIL;
+ n->defnames = $6;
+ n->definition = list_make1(makeDefElem("from", (Node *) $8, @8));
+ n->if_not_exists = true;
+ $$ = (Node *)n;
+ }
;
definition: '(' def_list ')' { $$ = $2; }
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 5d3be38bf50..3bc0ae5e7e6 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1271,7 +1271,8 @@ ProcessUtilitySlow(ParseState *pstate,
Assert(stmt->args == NIL);
address = DefineCollation(pstate,
stmt->defnames,
- stmt->definition);
+ stmt->definition,
+ stmt->if_not_exists);
break;
default:
elog(ERROR, "unrecognized define stmt type: %d",
diff --git a/src/include/commands/collationcmds.h b/src/include/commands/collationcmds.h
index 699ce2f9ee3..3b2fcb82711 100644
--- a/src/include/commands/collationcmds.h
+++ b/src/include/commands/collationcmds.h
@@ -18,7 +18,7 @@
#include "catalog/objectaddress.h"
#include "nodes/parsenodes.h"
-extern ObjectAddress DefineCollation(ParseState *pstate, List *names, List *parameters);
+extern ObjectAddress DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_exists);
extern void IsThereCollationInNamespace(const char *collname, Oid nspOid);
#endif /* COLLATIONCMDS_H */
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 07a84361432..5afc3ebea04 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -2380,6 +2380,7 @@ typedef struct DefineStmt
List *defnames; /* qualified name (list of Value strings) */
List *args; /* a list of TypeName (if needed) */
List *definition; /* a list of DefElem */
+ bool if_not_exists; /* just do nothing if it already exists? */
} DefineStmt;
/* ----------------------
diff --git a/src/test/regress/expected/collate.linux.utf8.out b/src/test/regress/expected/collate.linux.utf8.out
index 286c972fbba..293e78641ec 100644
--- a/src/test/regress/expected/collate.linux.utf8.out
+++ b/src/test/regress/expected/collate.linux.utf8.out
@@ -963,6 +963,10 @@ END
$$;
CREATE COLLATION test0 FROM "C"; -- fail, duplicate name
ERROR: collation "test0" for encoding "UTF8" already exists
+CREATE COLLATION IF NOT EXISTS test0 FROM "C"; -- ok, skipped
+NOTICE: collation "test0" for encoding "UTF8" already exists, skipping
+CREATE COLLATION IF NOT EXISTS test0 (locale = 'foo'); -- ok, skipped
+NOTICE: collation "test0" for encoding "UTF8" already exists, skipping
do $$
BEGIN
EXECUTE 'CREATE COLLATION test1 (lc_collate = ' ||
diff --git a/src/test/regress/sql/collate.linux.utf8.sql b/src/test/regress/sql/collate.linux.utf8.sql
index 3b7cc6cf2bc..c349cbde2b9 100644
--- a/src/test/regress/sql/collate.linux.utf8.sql
+++ b/src/test/regress/sql/collate.linux.utf8.sql
@@ -325,6 +325,8 @@ BEGIN
END
$$;
CREATE COLLATION test0 FROM "C"; -- fail, duplicate name
+CREATE COLLATION IF NOT EXISTS test0 FROM "C"; -- ok, skipped
+CREATE COLLATION IF NOT EXISTS test0 (locale = 'foo'); -- ok, skipped
do $$
BEGIN
EXECUTE 'CREATE COLLATION test1 (lc_collate = ' ||