mirror of
https://github.com/postgres/postgres.git
synced 2025-06-04 00:02:37 -04:00
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>
|
<refsynopsisdiv>
|
||||||
<synopsis>
|
<synopsis>
|
||||||
CREATE COLLATION <replaceable>name</replaceable> (
|
CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> (
|
||||||
[ LOCALE = <replaceable>locale</replaceable>, ]
|
[ LOCALE = <replaceable>locale</replaceable>, ]
|
||||||
[ LC_COLLATE = <replaceable>lc_collate</replaceable>, ]
|
[ LC_COLLATE = <replaceable>lc_collate</replaceable>, ]
|
||||||
[ LC_CTYPE = <replaceable>lc_ctype</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>
|
</synopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
@ -47,6 +47,17 @@ CREATE COLLATION <replaceable>name</replaceable> FROM <replaceable>existing_coll
|
|||||||
<title>Parameters</title>
|
<title>Parameters</title>
|
||||||
|
|
||||||
<variablelist>
|
<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>
|
<varlistentry>
|
||||||
<term><replaceable>name</replaceable></term>
|
<term><replaceable>name</replaceable></term>
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
* CREATE COLLATION
|
* CREATE COLLATION
|
||||||
*/
|
*/
|
||||||
ObjectAddress
|
ObjectAddress
|
||||||
DefineCollation(ParseState *pstate, List *names, List *parameters)
|
DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_exists)
|
||||||
{
|
{
|
||||||
char *collName;
|
char *collName;
|
||||||
Oid collNamespace;
|
Oid collNamespace;
|
||||||
@ -137,7 +137,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters)
|
|||||||
GetDatabaseEncoding(),
|
GetDatabaseEncoding(),
|
||||||
collcollate,
|
collcollate,
|
||||||
collctype,
|
collctype,
|
||||||
false);
|
if_not_exists);
|
||||||
|
|
||||||
if (!OidIsValid(newoid))
|
if (!OidIsValid(newoid))
|
||||||
return InvalidObjectAddress;
|
return InvalidObjectAddress;
|
||||||
|
@ -3105,6 +3105,7 @@ _copyDefineStmt(const DefineStmt *from)
|
|||||||
COPY_NODE_FIELD(defnames);
|
COPY_NODE_FIELD(defnames);
|
||||||
COPY_NODE_FIELD(args);
|
COPY_NODE_FIELD(args);
|
||||||
COPY_NODE_FIELD(definition);
|
COPY_NODE_FIELD(definition);
|
||||||
|
COPY_SCALAR_FIELD(if_not_exists);
|
||||||
|
|
||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
|
@ -1211,6 +1211,7 @@ _equalDefineStmt(const DefineStmt *a, const DefineStmt *b)
|
|||||||
COMPARE_NODE_FIELD(defnames);
|
COMPARE_NODE_FIELD(defnames);
|
||||||
COMPARE_NODE_FIELD(args);
|
COMPARE_NODE_FIELD(args);
|
||||||
COMPARE_NODE_FIELD(definition);
|
COMPARE_NODE_FIELD(definition);
|
||||||
|
COMPARE_SCALAR_FIELD(if_not_exists);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -5610,6 +5610,16 @@ DefineStmt:
|
|||||||
n->definition = $4;
|
n->definition = $4;
|
||||||
$$ = (Node *)n;
|
$$ = (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
|
| CREATE COLLATION any_name FROM any_name
|
||||||
{
|
{
|
||||||
DefineStmt *n = makeNode(DefineStmt);
|
DefineStmt *n = makeNode(DefineStmt);
|
||||||
@ -5619,6 +5629,16 @@ DefineStmt:
|
|||||||
n->definition = list_make1(makeDefElem("from", (Node *) $5, @5));
|
n->definition = list_make1(makeDefElem("from", (Node *) $5, @5));
|
||||||
$$ = (Node *)n;
|
$$ = (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; }
|
definition: '(' def_list ')' { $$ = $2; }
|
||||||
|
@ -1271,7 +1271,8 @@ ProcessUtilitySlow(ParseState *pstate,
|
|||||||
Assert(stmt->args == NIL);
|
Assert(stmt->args == NIL);
|
||||||
address = DefineCollation(pstate,
|
address = DefineCollation(pstate,
|
||||||
stmt->defnames,
|
stmt->defnames,
|
||||||
stmt->definition);
|
stmt->definition,
|
||||||
|
stmt->if_not_exists);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "unrecognized define stmt type: %d",
|
elog(ERROR, "unrecognized define stmt type: %d",
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include "catalog/objectaddress.h"
|
#include "catalog/objectaddress.h"
|
||||||
#include "nodes/parsenodes.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);
|
extern void IsThereCollationInNamespace(const char *collname, Oid nspOid);
|
||||||
|
|
||||||
#endif /* COLLATIONCMDS_H */
|
#endif /* COLLATIONCMDS_H */
|
||||||
|
@ -2380,6 +2380,7 @@ typedef struct DefineStmt
|
|||||||
List *defnames; /* qualified name (list of Value strings) */
|
List *defnames; /* qualified name (list of Value strings) */
|
||||||
List *args; /* a list of TypeName (if needed) */
|
List *args; /* a list of TypeName (if needed) */
|
||||||
List *definition; /* a list of DefElem */
|
List *definition; /* a list of DefElem */
|
||||||
|
bool if_not_exists; /* just do nothing if it already exists? */
|
||||||
} DefineStmt;
|
} DefineStmt;
|
||||||
|
|
||||||
/* ----------------------
|
/* ----------------------
|
||||||
|
@ -963,6 +963,10 @@ END
|
|||||||
$$;
|
$$;
|
||||||
CREATE COLLATION test0 FROM "C"; -- fail, duplicate name
|
CREATE COLLATION test0 FROM "C"; -- fail, duplicate name
|
||||||
ERROR: collation "test0" for encoding "UTF8" already exists
|
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 $$
|
do $$
|
||||||
BEGIN
|
BEGIN
|
||||||
EXECUTE 'CREATE COLLATION test1 (lc_collate = ' ||
|
EXECUTE 'CREATE COLLATION test1 (lc_collate = ' ||
|
||||||
|
@ -325,6 +325,8 @@ BEGIN
|
|||||||
END
|
END
|
||||||
$$;
|
$$;
|
||||||
CREATE COLLATION test0 FROM "C"; -- fail, duplicate name
|
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 $$
|
do $$
|
||||||
BEGIN
|
BEGIN
|
||||||
EXECUTE 'CREATE COLLATION test1 (lc_collate = ' ||
|
EXECUTE 'CREATE COLLATION test1 (lc_collate = ' ||
|
||||||
|
Loading…
x
Reference in New Issue
Block a user