2 # Copyright (c) 2021-2025, PostgreSQL Global Development Group
5 use warnings FATAL
=> 'all';
7 use PostgreSQL
::Test
::Cluster
;
8 use PostgreSQL
::Test
::Utils
;
11 program_help_ok
('createdb');
12 program_version_ok
('createdb');
13 program_options_handling_ok
('createdb');
15 my $node = PostgreSQL
::Test
::Cluster
->new('main');
19 $node->issues_sql_like(
20 [ 'createdb', 'foobar1' ],
21 qr/statement: CREATE DATABASE foobar1/,
22 'SQL CREATE DATABASE run');
23 $node->issues_sql_like(
27 '--encoding' => 'LATIN1',
28 '--template' => 'template0',
31 qr/statement: CREATE DATABASE foobar2 ENCODING 'LATIN1'/,
32 'create database with encoding');
34 if ($ENV{with_icu
} eq 'yes')
36 # This fails because template0 uses libc provider and has no ICU
37 # locale set. It would succeed if template0 used the icu
38 # provider. XXX Maybe split into multiple tests?
42 '--template' => 'template0',
43 '--encoding' => 'UTF8',
44 '--locale-provider' => 'icu',
47 'create database with ICU fails without ICU locale specified');
49 $node->issues_sql_like(
52 '--template' => 'template0',
53 '--encoding' => 'UTF8',
54 '--locale-provider' => 'icu',
56 '--icu-locale' => 'en',
59 qr/statement: CREATE DATABASE foobar5 .* LOCALE_PROVIDER icu ICU_LOCALE 'en'/,
60 'create database with ICU locale specified');
65 '--template' => 'template0',
66 '--encoding' => 'UTF8',
67 '--locale-provider' => 'icu',
68 '--icu-locale' => '@colNumeric=lower',
71 'fails for invalid ICU locale');
73 $node->command_fails_like(
76 '--template' => 'template0',
77 '--locale-provider' => 'icu',
78 '--encoding' => 'SQL_ASCII',
81 qr/ERROR: encoding "SQL_ASCII" is not supported with ICU provider/,
82 'fails for encoding not supported by ICU');
84 # additional node, which uses the icu provider
85 my $node2 = PostgreSQL
::Test
::Cluster
->new('icu');
86 $node2->init(extra
=> [ '--locale-provider=icu', '--icu-locale=en' ]);
92 '--template' => 'template0',
93 '--locale-provider' => 'libc',
96 'create database with libc provider from template database with icu provider'
102 '--template' => 'template0',
103 '--icu-locale' => 'en-US',
106 'create database with icu locale from template database with icu provider'
112 '--template' => 'template0',
113 '--locale-provider' => 'icu',
115 '--lc-collate' => 'C',
119 'create database with locale as ICU locale');
123 $node->command_fails(
126 '--template' => 'template0',
127 '--locale-provider' => 'icu',
130 'create database with ICU fails since no ICU support');
133 $node->command_fails(
136 '--template' => 'template0',
137 '--locale-provider' => 'builtin',
140 'create database with provider "builtin" fails without --locale');
145 '--template' => 'template0',
146 '--locale-provider' => 'builtin',
150 'create database with provider "builtin" and locale "C"');
155 '--template' => 'template0',
156 '--locale-provider' => 'builtin',
158 '--lc-collate' => 'C',
161 'create database with provider "builtin" and LC_COLLATE=C');
166 '--template' => 'template0',
167 '--locale-provider' => 'builtin',
172 'create database with provider "builtin" and LC_CTYPE=C');
177 '--template' => 'template0',
178 '--locale-provider' => 'builtin',
179 '--lc-collate' => 'C',
181 '--encoding' => 'UTF-8',
182 '--builtin-locale' => 'C.UTF8',
185 'create database with --builtin-locale C.UTF-8 and -E UTF-8');
187 $node->command_fails(
190 '--template' => 'template0',
191 '--locale-provider' => 'builtin',
192 '--lc-collate' => 'C',
194 '--encoding' => 'LATIN1',
195 '--builtin-locale' => 'C.UTF-8',
198 'create database with --builtin-locale C.UTF-8 and -E LATIN1');
200 $node->command_fails(
203 '--template' => 'template0',
204 '--locale-provider' => 'builtin',
206 '--icu-locale' => 'en',
209 'create database with provider "builtin" and ICU_LOCALE="en"');
211 $node->command_fails(
214 '--template' => 'template0',
215 '--locale-provider' => 'builtin',
217 '--icu-rules' => '""',
220 'create database with provider "builtin" and ICU_RULES=""');
222 $node->command_fails(
225 '--template' => 'template1',
226 '--locale-provider' => 'builtin',
230 'create database with provider "builtin" not matching template');
232 $node->command_fails([ 'createdb', 'foobar1' ],
233 'fails if database already exists');
235 $node->command_fails(
238 '--template' => 'template0',
239 '--locale-provider' => 'xyz',
242 'fails for invalid locale provider');
244 # Check use of templates with shared dependencies copied from the template.
245 my ($ret, $stdout, $stderr) = $node->psql(
247 'CREATE ROLE role_foobar;
248 CREATE TABLE tab_foobar (id int);
249 ALTER TABLE tab_foobar owner to role_foobar;
250 CREATE POLICY pol_foobar ON tab_foobar FOR ALL TO role_foobar;');
251 $node->issues_sql_like(
252 [ 'createdb', '--locale' => 'C', '--template' => 'foobar2', 'foobar3' ],
253 qr/statement: CREATE DATABASE foobar3 TEMPLATE foobar2 LOCALE 'C'/,
254 'create database with template');
255 ($ret, $stdout, $stderr) = $node->psql(
257 "SELECT pg_describe_object(classid, objid, objsubid) AS obj,
258 pg_describe_object(refclassid, refobjid, 0) AS refobj
259 FROM pg_shdepend s JOIN pg_database d ON (d.oid = s.dbid)
260 WHERE d.datname = 'foobar3' ORDER BY obj;", on_error_die
=> 1);
264 qr
/^policy pol_foobar on table tab_foobar\
|role role_foobar
265 table tab_foobar\
|role role_foobar
$/,
266 'shared dependencies copied over to target database');
268 # Check quote handling with incorrect option values.
269 $node->command_checks_all(
270 [ 'createdb', '--encoding', "foo'; SELECT '1", 'foobar2' ],
273 [qr/^createdb: error: "foo'; SELECT '1" is not a valid encoding name/s],
274 'createdb with incorrect --encoding');
275 $node->command_checks_all(
276 [ 'createdb', '--lc-collate', "foo'; SELECT '1", 'foobar2' ],
280 qr/^createdb: error: database creation failed: ERROR: invalid LC_COLLATE locale name|^createdb: error: database creation failed: ERROR: new collation \(foo'; SELECT '1\) is incompatible with the collation of the template database/s,
282 'createdb with incorrect --lc-collate');
283 $node->command_checks_all(
284 [ 'createdb', '--lc-ctype', "foo'; SELECT '1", 'foobar2' ],
288 qr/^createdb: error: database creation failed: ERROR: invalid LC_CTYPE locale name|^createdb: error: database creation failed: ERROR: new LC_CTYPE \(foo'; SELECT '1\) is incompatible with the LC_CTYPE of the template database/s,
290 'createdb with incorrect --lc-ctype');
292 $node->command_checks_all(
293 [ 'createdb', '--strategy', "foo", 'foobar2' ],
297 qr/^createdb: error: database creation failed: ERROR: invalid create database strategy "foo"/s,
299 'createdb with incorrect --strategy');
301 # Check database creation strategy
302 $node->issues_sql_like(
305 '--template' => 'foobar2',
306 '--strategy' => 'wal_log',
309 qr/statement: CREATE DATABASE foobar6 STRATEGY wal_log TEMPLATE foobar2/,
310 'create database with WAL_LOG strategy');
312 $node->issues_sql_like(
315 '--template' => 'foobar2',
316 '--strategy' => 'WAL_LOG',
319 qr/statement: CREATE DATABASE foobar6s STRATEGY "WAL_LOG" TEMPLATE foobar2/,
320 'create database with WAL_LOG strategy');
322 $node->issues_sql_like(
325 '--template' => 'foobar2',
326 '--strategy' => 'file_copy',
329 qr/statement: CREATE DATABASE foobar7 STRATEGY file_copy TEMPLATE foobar2/,
330 'create database with FILE_COPY strategy');
332 $node->issues_sql_like(
335 '--template' => 'foobar2',
336 '--strategy' => 'FILE_COPY',
339 qr/statement: CREATE DATABASE foobar7s STRATEGY "FILE_COPY" TEMPLATE foobar2/,
340 'create database with FILE_COPY strategy');
342 # Create database owned by role_foobar.
343 $node->issues_sql_like(
346 '--template' => 'foobar2',
347 '--owner' => 'role_foobar',
350 qr/statement: CREATE DATABASE foobar8 OWNER role_foobar TEMPLATE foobar2/,
351 'create database with owner role_foobar');
352 ($ret, $stdout, $stderr) =
353 $node->psql('foobar2', 'DROP OWNED BY role_foobar;', on_error_die
=> 1,);
354 ok
($ret == 0, "DROP OWNED BY role_foobar");
355 ($ret, $stdout, $stderr) =
356 $node->psql('foobar2', 'DROP DATABASE foobar8;', on_error_die
=> 1,);
357 ok
($ret == 0, "DROP DATABASE foobar8");