Add CREATE DATABASE LOCALE option
This sets both LC_COLLATE and LC_CTYPE with one option. Similar behavior is already supported in initdb, CREATE COLLATION, and createdb. Reviewed-by: Fabien COELHO <coelho@cri.ensmp.fr> Discussion: https://www.postgresql.org/message-id/flat/d9d5043a-dc70-da8a-0166-1e218e6e34d4%402ndquadrant.com
This commit is contained in:
parent
3cae75f420
commit
06140c201b
|
@ -25,6 +25,7 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
|
||||||
[ [ WITH ] [ OWNER [=] <replaceable class="parameter">user_name</replaceable> ]
|
[ [ WITH ] [ OWNER [=] <replaceable class="parameter">user_name</replaceable> ]
|
||||||
[ TEMPLATE [=] <replaceable class="parameter">template</replaceable> ]
|
[ TEMPLATE [=] <replaceable class="parameter">template</replaceable> ]
|
||||||
[ ENCODING [=] <replaceable class="parameter">encoding</replaceable> ]
|
[ ENCODING [=] <replaceable class="parameter">encoding</replaceable> ]
|
||||||
|
[ LOCALE [=] <replaceable class="parameter">locale</replaceable> ]
|
||||||
[ LC_COLLATE [=] <replaceable class="parameter">lc_collate</replaceable> ]
|
[ LC_COLLATE [=] <replaceable class="parameter">lc_collate</replaceable> ]
|
||||||
[ LC_CTYPE [=] <replaceable class="parameter">lc_ctype</replaceable> ]
|
[ LC_CTYPE [=] <replaceable class="parameter">lc_ctype</replaceable> ]
|
||||||
[ TABLESPACE [=] <replaceable class="parameter">tablespace_name</replaceable> ]
|
[ TABLESPACE [=] <replaceable class="parameter">tablespace_name</replaceable> ]
|
||||||
|
@ -111,6 +112,26 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><replaceable class="parameter">locale</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
This is a shortcut for setting <symbol>LC_COLLATE</symbol>
|
||||||
|
and <symbol>LC_CTYPE</symbol> at once. If you specify this,
|
||||||
|
you cannot specify either of those parameters.
|
||||||
|
</para>
|
||||||
|
<tip>
|
||||||
|
<para>
|
||||||
|
The other locale settings <xref linkend="guc-lc-messages"/>, <xref
|
||||||
|
linkend="guc-lc-monetary"/>, <xref linkend="guc-lc-numeric"/>, and
|
||||||
|
<xref linkend="guc-lc-time"/> are not fixed per database and are not
|
||||||
|
set by this command. If you want to make them the default for a
|
||||||
|
specific database, you can use <literal>ALTER DATABASE
|
||||||
|
... SET</literal>.
|
||||||
|
</para>
|
||||||
|
</tip>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><replaceable class="parameter">lc_collate</replaceable></term>
|
<term><replaceable class="parameter">lc_collate</replaceable></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -287,7 +308,7 @@ CREATE DATABASE sales OWNER salesapp TABLESPACE salesspace;
|
||||||
To create a database <literal>music</literal> with a different locale:
|
To create a database <literal>music</literal> with a different locale:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
CREATE DATABASE music
|
CREATE DATABASE music
|
||||||
LC_COLLATE 'sv_SE.utf8' LC_CTYPE 'sv_SE.utf8'
|
LOCALE 'sv_SE.utf8'
|
||||||
TEMPLATE template0;
|
TEMPLATE template0;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
In this example, the <literal>TEMPLATE template0</literal> clause is required if
|
In this example, the <literal>TEMPLATE template0</literal> clause is required if
|
||||||
|
@ -300,7 +321,7 @@ CREATE DATABASE music
|
||||||
different character set encoding:
|
different character set encoding:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
CREATE DATABASE music2
|
CREATE DATABASE music2
|
||||||
LC_COLLATE 'sv_SE.iso885915' LC_CTYPE 'sv_SE.iso885915'
|
LOCALE 'sv_SE.iso885915'
|
||||||
ENCODING LATIN9
|
ENCODING LATIN9
|
||||||
TEMPLATE template0;
|
TEMPLATE template0;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
|
@ -124,6 +124,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
|
||||||
DefElem *downer = NULL;
|
DefElem *downer = NULL;
|
||||||
DefElem *dtemplate = NULL;
|
DefElem *dtemplate = NULL;
|
||||||
DefElem *dencoding = NULL;
|
DefElem *dencoding = NULL;
|
||||||
|
DefElem *dlocale = NULL;
|
||||||
DefElem *dcollate = NULL;
|
DefElem *dcollate = NULL;
|
||||||
DefElem *dctype = NULL;
|
DefElem *dctype = NULL;
|
||||||
DefElem *distemplate = NULL;
|
DefElem *distemplate = NULL;
|
||||||
|
@ -184,6 +185,15 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
|
||||||
parser_errposition(pstate, defel->location)));
|
parser_errposition(pstate, defel->location)));
|
||||||
dencoding = defel;
|
dencoding = defel;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(defel->defname, "locale") == 0)
|
||||||
|
{
|
||||||
|
if (dlocale)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
|
errmsg("conflicting or redundant options"),
|
||||||
|
parser_errposition(pstate, defel->location)));
|
||||||
|
dlocale = defel;
|
||||||
|
}
|
||||||
else if (strcmp(defel->defname, "lc_collate") == 0)
|
else if (strcmp(defel->defname, "lc_collate") == 0)
|
||||||
{
|
{
|
||||||
if (dcollate)
|
if (dcollate)
|
||||||
|
@ -244,6 +254,12 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
|
||||||
parser_errposition(pstate, defel->location)));
|
parser_errposition(pstate, defel->location)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dlocale && (dcollate || dctype))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
|
errmsg("conflicting or redundant options"),
|
||||||
|
errdetail("LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE.")));
|
||||||
|
|
||||||
if (downer && downer->arg)
|
if (downer && downer->arg)
|
||||||
dbowner = defGetString(downer);
|
dbowner = defGetString(downer);
|
||||||
if (dtemplate && dtemplate->arg)
|
if (dtemplate && dtemplate->arg)
|
||||||
|
@ -276,6 +292,11 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
|
||||||
parser_errposition(pstate, dencoding->location)));
|
parser_errposition(pstate, dencoding->location)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (dlocale && dlocale->arg)
|
||||||
|
{
|
||||||
|
dbcollate = defGetString(dlocale);
|
||||||
|
dbctype = defGetString(dlocale);
|
||||||
|
}
|
||||||
if (dcollate && dcollate->arg)
|
if (dcollate && dcollate->arg)
|
||||||
dbcollate = defGetString(dcollate);
|
dbcollate = defGetString(dcollate);
|
||||||
if (dctype && dctype->arg)
|
if (dctype && dctype->arg)
|
||||||
|
|
|
@ -2812,15 +2812,23 @@ dumpDatabase(Archive *fout)
|
||||||
appendPQExpBufferStr(creaQry, " ENCODING = ");
|
appendPQExpBufferStr(creaQry, " ENCODING = ");
|
||||||
appendStringLiteralAH(creaQry, encoding, fout);
|
appendStringLiteralAH(creaQry, encoding, fout);
|
||||||
}
|
}
|
||||||
if (strlen(collate) > 0)
|
if (strlen(collate) > 0 && strcmp(collate, ctype) == 0)
|
||||||
{
|
{
|
||||||
appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
|
appendPQExpBufferStr(creaQry, " LOCALE = ");
|
||||||
appendStringLiteralAH(creaQry, collate, fout);
|
appendStringLiteralAH(creaQry, collate, fout);
|
||||||
}
|
}
|
||||||
if (strlen(ctype) > 0)
|
else
|
||||||
{
|
{
|
||||||
appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
|
if (strlen(collate) > 0)
|
||||||
appendStringLiteralAH(creaQry, ctype, fout);
|
{
|
||||||
|
appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
|
||||||
|
appendStringLiteralAH(creaQry, collate, fout);
|
||||||
|
}
|
||||||
|
if (strlen(ctype) > 0)
|
||||||
|
{
|
||||||
|
appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
|
||||||
|
appendStringLiteralAH(creaQry, ctype, fout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1407,6 +1407,15 @@ my %tests = (
|
||||||
like => { pg_dumpall_dbprivs => 1, },
|
like => { pg_dumpall_dbprivs => 1, },
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"CREATE DATABASE dump_test2 LOCALE = 'C'" => {
|
||||||
|
create_order => 47,
|
||||||
|
create_sql => "CREATE DATABASE dump_test2 LOCALE = 'C' TEMPLATE = template0;",
|
||||||
|
regexp => qr/^
|
||||||
|
\QCREATE DATABASE dump_test2 \E.*\QLOCALE = 'C';\E
|
||||||
|
/xm,
|
||||||
|
like => { pg_dumpall_dbprivs => 1, },
|
||||||
|
},
|
||||||
|
|
||||||
'CREATE EXTENSION ... plpgsql' => {
|
'CREATE EXTENSION ... plpgsql' => {
|
||||||
regexp => qr/^
|
regexp => qr/^
|
||||||
\QCREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;\E
|
\QCREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;\E
|
||||||
|
|
Loading…
Reference in New Issue