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.
This commit is contained in:
parent
e403732ef6
commit
6d16ecc646
@ -18,12 +18,12 @@
|
||||
|
||||
<refsynopsisdiv>
|
||||
<synopsis>
|
||||
CREATE COLLATION <replaceable>name</replaceable> (
|
||||
CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> (
|
||||
[ LOCALE = <replaceable>locale</replaceable>, ]
|
||||
[ LC_COLLATE = <replaceable>lc_collate</replaceable>, ]
|
||||
[ LC_CTYPE = <replaceable>lc_ctype</replaceable> ]
|
||||
)
|
||||
CREATE COLLATION <replaceable>name</replaceable> FROM <replaceable>existing_collation</replaceable>
|
||||
CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replaceable>existing_collation</replaceable>
|
||||
</synopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
@ -47,6 +47,17 @@ CREATE COLLATION <replaceable>name</replaceable> FROM <replaceable>existing_coll
|
||||
<title>Parameters</title>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><literal>IF NOT EXISTS</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Do not throw an error if a collation with the same name already exists.
|
||||
A notice is issued in this case. Note that there is no guarantee that
|
||||
the existing collation is anything like the one that would have been created.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable>name</replaceable></term>
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -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",
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
||||
/* ----------------------
|
||||
|
@ -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 = ' ||
|
||||
|
@ -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 = ' ||
|
||||
|
Loading…
x
Reference in New Issue
Block a user