Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6d16ecc

Browse files
committed
Add CREATE COLLATION IF NOT EXISTS clause
The core of the functionality was already implemented when pg_import_system_collations was added. This just exposes it as an option in the SQL command.
1 parent e403732 commit 6d16ecc

File tree

10 files changed

+47
-6
lines changed

10 files changed

+47
-6
lines changed

doc/src/sgml/ref/create_collation.sgml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818

1919
<refsynopsisdiv>
2020
<synopsis>
21-
CREATE COLLATION <replaceable>name</replaceable> (
21+
CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> (
2222
[ LOCALE = <replaceable>locale</replaceable>, ]
2323
[ LC_COLLATE = <replaceable>lc_collate</replaceable>, ]
2424
[ LC_CTYPE = <replaceable>lc_ctype</replaceable> ]
2525
)
26-
CREATE COLLATION <replaceable>name</replaceable> FROM <replaceable>existing_collation</replaceable>
26+
CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replaceable>existing_collation</replaceable>
2727
</synopsis>
2828
</refsynopsisdiv>
2929

@@ -47,6 +47,17 @@ CREATE COLLATION <replaceable>name</replaceable> FROM <replaceable>existing_coll
4747
<title>Parameters</title>
4848

4949
<variablelist>
50+
<varlistentry>
51+
<term><literal>IF NOT EXISTS</literal></term>
52+
<listitem>
53+
<para>
54+
Do not throw an error if a collation with the same name already exists.
55+
A notice is issued in this case. Note that there is no guarantee that
56+
the existing collation is anything like the one that would have been created.
57+
</para>
58+
</listitem>
59+
</varlistentry>
60+
5061
<varlistentry>
5162
<term><replaceable>name</replaceable></term>
5263

src/backend/commands/collationcmds.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
* CREATE COLLATION
3838
*/
3939
ObjectAddress
40-
DefineCollation(ParseState *pstate, List *names, List *parameters)
40+
DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_exists)
4141
{
4242
char *collName;
4343
Oid collNamespace;
@@ -137,7 +137,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters)
137137
GetDatabaseEncoding(),
138138
collcollate,
139139
collctype,
140-
false);
140+
if_not_exists);
141141

142142
if (!OidIsValid(newoid))
143143
return InvalidObjectAddress;

src/backend/nodes/copyfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3105,6 +3105,7 @@ _copyDefineStmt(const DefineStmt *from)
31053105
COPY_NODE_FIELD(defnames);
31063106
COPY_NODE_FIELD(args);
31073107
COPY_NODE_FIELD(definition);
3108+
COPY_SCALAR_FIELD(if_not_exists);
31083109

31093110
return newnode;
31103111
}

src/backend/nodes/equalfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,6 +1211,7 @@ _equalDefineStmt(const DefineStmt *a, const DefineStmt *b)
12111211
COMPARE_NODE_FIELD(defnames);
12121212
COMPARE_NODE_FIELD(args);
12131213
COMPARE_NODE_FIELD(definition);
1214+
COMPARE_SCALAR_FIELD(if_not_exists);
12141215

12151216
return true;
12161217
}

src/backend/parser/gram.y

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5610,6 +5610,16 @@ DefineStmt:
56105610
n->definition = $4;
56115611
$$ = (Node *)n;
56125612
}
5613+
| CREATE COLLATION IF_P NOT EXISTS any_name definition
5614+
{
5615+
DefineStmt *n = makeNode(DefineStmt);
5616+
n->kind = OBJECT_COLLATION;
5617+
n->args = NIL;
5618+
n->defnames = $6;
5619+
n->definition = $7;
5620+
n->if_not_exists = true;
5621+
$$ = (Node *)n;
5622+
}
56135623
| CREATE COLLATION any_name FROM any_name
56145624
{
56155625
DefineStmt *n = makeNode(DefineStmt);
@@ -5619,6 +5629,16 @@ DefineStmt:
56195629
n->definition = list_make1(makeDefElem("from", (Node *) $5, @5));
56205630
$$ = (Node *)n;
56215631
}
5632+
| CREATE COLLATION IF_P NOT EXISTS any_name FROM any_name
5633+
{
5634+
DefineStmt *n = makeNode(DefineStmt);
5635+
n->kind = OBJECT_COLLATION;
5636+
n->args = NIL;
5637+
n->defnames = $6;
5638+
n->definition = list_make1(makeDefElem("from", (Node *) $8, @8));
5639+
n->if_not_exists = true;
5640+
$$ = (Node *)n;
5641+
}
56225642
;
56235643

56245644
definition: '(' def_list ')' { $$ = $2; }

src/backend/tcop/utility.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1271,7 +1271,8 @@ ProcessUtilitySlow(ParseState *pstate,
12711271
Assert(stmt->args == NIL);
12721272
address = DefineCollation(pstate,
12731273
stmt->defnames,
1274-
stmt->definition);
1274+
stmt->definition,
1275+
stmt->if_not_exists);
12751276
break;
12761277
default:
12771278
elog(ERROR, "unrecognized define stmt type: %d",

src/include/commands/collationcmds.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#include "catalog/objectaddress.h"
1919
#include "nodes/parsenodes.h"
2020

21-
extern ObjectAddress DefineCollation(ParseState *pstate, List *names, List *parameters);
21+
extern ObjectAddress DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_exists);
2222
extern void IsThereCollationInNamespace(const char *collname, Oid nspOid);
2323

2424
#endif /* COLLATIONCMDS_H */

src/include/nodes/parsenodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2380,6 +2380,7 @@ typedef struct DefineStmt
23802380
List *defnames; /* qualified name (list of Value strings) */
23812381
List *args; /* a list of TypeName (if needed) */
23822382
List *definition; /* a list of DefElem */
2383+
bool if_not_exists; /* just do nothing if it already exists? */
23832384
} DefineStmt;
23842385

23852386
/* ----------------------

src/test/regress/expected/collate.linux.utf8.out

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,10 @@ END
963963
$$;
964964
CREATE COLLATION test0 FROM "C"; -- fail, duplicate name
965965
ERROR: collation "test0" for encoding "UTF8" already exists
966+
CREATE COLLATION IF NOT EXISTS test0 FROM "C"; -- ok, skipped
967+
NOTICE: collation "test0" for encoding "UTF8" already exists, skipping
968+
CREATE COLLATION IF NOT EXISTS test0 (locale = 'foo'); -- ok, skipped
969+
NOTICE: collation "test0" for encoding "UTF8" already exists, skipping
966970
do $$
967971
BEGIN
968972
EXECUTE 'CREATE COLLATION test1 (lc_collate = ' ||

src/test/regress/sql/collate.linux.utf8.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,8 @@ BEGIN
325325
END
326326
$$;
327327
CREATE COLLATION test0 FROM "C"; -- fail, duplicate name
328+
CREATE COLLATION IF NOT EXISTS test0 FROM "C"; -- ok, skipped
329+
CREATE COLLATION IF NOT EXISTS test0 (locale = 'foo'); -- ok, skipped
328330
do $$
329331
BEGIN
330332
EXECUTE 'CREATE COLLATION test1 (lc_collate = ' ||

0 commit comments

Comments
 (0)