Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6568cef

Browse files
committed
Add support for --extension in pg_dump
When specified, only extensions matching the given pattern are includedin dumps. Similarly to --table and --schema, when --strict-names isused, a perfect match is required. Also, like the two other options,this new option offers no guarantee that dependent objects have beendumped, so a restore may fail on a clean database.Tests are added in test_pg_dump/, checking after a set of positive andnegative cases, with or without an extension's contents added to thedump generated.Author: Guillaume LelargeReviewed-by: David Fetter, Tom Lane, Michael Paquier, Asif Rehman,Julien RouhaudDiscussion:https://postgr.es/m/CAECtzeXOt4cnMU5+XMZzxBPJ_wu76pNy6HZKPRBL-j7yj1E4+g@mail.gmail.com
1 parent65158f4 commit6568cef

File tree

3 files changed

+161
-28
lines changed

3 files changed

+161
-28
lines changed

‎doc/src/sgml/ref/pg_dump.sgml

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,38 @@ PostgreSQL documentation
215215
</listitem>
216216
</varlistentry>
217217

218+
<varlistentry>
219+
<term><option>-e <replaceable class="parameter">pattern</replaceable></option></term>
220+
<term><option>--extension=<replaceable class="parameter">pattern</replaceable></option></term>
221+
<listitem>
222+
<para>
223+
Dump only extensions matching <replaceable
224+
class="parameter">pattern</replaceable>. When this option is not
225+
specified, all non-system extensions in the target database will be
226+
dumped. Multiple extensions can be selected by writing multiple
227+
<option>-e</option> switches. The <replaceable
228+
class="parameter">pattern</replaceable> parameter is interpreted as a
229+
pattern according to the same rules used by
230+
<application>psql</application>'s <literal>\d</literal> commands (see
231+
<xref linkend="app-psql-patterns"/>), so multiple extensions can also
232+
be selected by writing wildcard characters in the pattern. When using
233+
wildcards, be careful to quote the pattern if needed to prevent the
234+
shell from expanding the wildcards.
235+
</para>
236+
237+
<note>
238+
<para>
239+
When <option>-e</option> is specified,
240+
<application>pg_dump</application> makes no attempt to dump any other
241+
database objects that the selected extension(s) might depend upon.
242+
Therefore, there is no guarantee that the results of a
243+
specific-extension dump can be successfully restored by themselves
244+
into a clean database.
245+
</para>
246+
</note>
247+
</listitem>
248+
</varlistentry>
249+
218250
<varlistentry>
219251
<term><option>-E <replaceable class="parameter">encoding</replaceable></option></term>
220252
<term><option>--encoding=<replaceable class="parameter">encoding</replaceable></option></term>
@@ -1079,11 +1111,12 @@ PostgreSQL documentation
10791111
<term><option>--strict-names</option></term>
10801112
<listitem>
10811113
<para>
1082-
Require that each schema
1083-
(<option>-n</option>/<option>--schema</option>) and table
1084-
(<option>-t</option>/<option>--table</option>) qualifier match at
1085-
least one schema/table in the database to be dumped. Note that if
1086-
none of the schema/table qualifiers find
1114+
Require that each
1115+
extension (<option>-e</option>/<option>--extension</option>),
1116+
schema (<option>-n</option>/<option>--schema</option>) and
1117+
table (<option>-t</option>/<option>--table</option>) qualifier
1118+
match at least one extension/schema/table in the database to be dumped.
1119+
Note that if none of the extension/schema/table qualifiers find
10871120
matches, <application>pg_dump</application> will generate an error
10881121
even without <option>--strict-names</option>.
10891122
</para>

‎src/bin/pg_dump/pg_dump.c

Lines changed: 87 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ static SimpleOidList tabledata_exclude_oids = {NULL, NULL};
123123
static SimpleStringList foreign_servers_include_patterns = {NULL, NULL};
124124
static SimpleOidList foreign_servers_include_oids = {NULL, NULL};
125125

126+
static SimpleStringList extension_include_patterns = {NULL, NULL};
127+
static SimpleOidList extension_include_oids = {NULL, NULL};
128+
126129
static const CatalogId nilCatalogId = {0, 0};
127130

128131
/* override for standard extra_float_digits setting */
@@ -151,6 +154,10 @@ static void expand_schema_name_patterns(Archive *fout,
151154
SimpleStringList *patterns,
152155
SimpleOidList *oids,
153156
bool strict_names);
157+
static void expand_extension_name_patterns(Archive *fout,
158+
SimpleStringList *patterns,
159+
SimpleOidList *oids,
160+
bool strict_names);
154161
static void expand_foreign_server_name_patterns(Archive *fout,
155162
SimpleStringList *patterns,
156163
SimpleOidList *oids);
@@ -335,6 +342,7 @@ main(int argc, char **argv)
335342
{"clean", no_argument, NULL, 'c'},
336343
{"create", no_argument, NULL, 'C'},
337344
{"dbname", required_argument, NULL, 'd'},
345+
{"extension", required_argument, NULL, 'e'},
338346
{"file", required_argument, NULL, 'f'},
339347
{"format", required_argument, NULL, 'F'},
340348
{"host", required_argument, NULL, 'h'},
@@ -426,7 +434,7 @@ main(int argc, char **argv)
426434

427435
InitDumpOptions(&dopt);
428436

429-
while ((c = getopt_long(argc, argv, "abBcCd:E:f:F:h:j:n:N:Op:RsS:t:T:U:vwWxZ:",
437+
while ((c = getopt_long(argc, argv, "abBcCd:e:E:f:F:h:j:n:N:Op:RsS:t:T:U:vwWxZ:",
430438
long_options, &optindex)) != -1)
431439
{
432440
switch (c)
@@ -455,6 +463,11 @@ main(int argc, char **argv)
455463
dopt.cparams.dbname = pg_strdup(optarg);
456464
break;
457465

466+
case 'e':/* include extension(s) */
467+
simple_string_list_append(&extension_include_patterns, optarg);
468+
dopt.include_everything = false;
469+
break;
470+
458471
case 'E':/* Dump encoding */
459472
dumpencoding = pg_strdup(optarg);
460473
break;
@@ -834,6 +847,16 @@ main(int argc, char **argv)
834847

835848
/* non-matching exclusion patterns aren't an error */
836849

850+
/* Expand extension selection patterns into OID lists */
851+
if (extension_include_patterns.head != NULL)
852+
{
853+
expand_extension_name_patterns(fout, &extension_include_patterns,
854+
&extension_include_oids,
855+
strict_names);
856+
if (extension_include_oids.head == NULL)
857+
fatal("no matching extensions were found");
858+
}
859+
837860
/*
838861
* Dumping blobs is the default for dumps where an inclusion switch is not
839862
* used (an "include everything" dump). -B can be used to exclude blobs
@@ -1025,6 +1048,7 @@ help(const char *progname)
10251048
printf(_(" -B, --no-blobs exclude large objects in dump\n"));
10261049
printf(_(" -c, --clean clean (drop) database objects before recreating\n"));
10271050
printf(_(" -C, --create include commands to create database in dump\n"));
1051+
printf(_(" -e, --extension=PATTERN dump the specified extension(s) only\n"));
10281052
printf(_(" -E, --encoding=ENCODING dump the data in encoding ENCODING\n"));
10291053
printf(_(" -n, --schema=PATTERN dump the specified schema(s) only\n"));
10301054
printf(_(" -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n"));
@@ -1367,6 +1391,53 @@ expand_schema_name_patterns(Archive *fout,
13671391
destroyPQExpBuffer(query);
13681392
}
13691393

1394+
/*
1395+
* Find the OIDs of all extensions matching the given list of patterns,
1396+
* and append them to the given OID list.
1397+
*/
1398+
static void
1399+
expand_extension_name_patterns(Archive *fout,
1400+
SimpleStringList *patterns,
1401+
SimpleOidList *oids,
1402+
bool strict_names)
1403+
{
1404+
PQExpBuffer query;
1405+
PGresult *res;
1406+
SimpleStringListCell *cell;
1407+
inti;
1408+
1409+
if (patterns->head == NULL)
1410+
return;/* nothing to do */
1411+
1412+
query = createPQExpBuffer();
1413+
1414+
/*
1415+
* The loop below runs multiple SELECTs might sometimes result in
1416+
* duplicate entries in the OID list, but we don't care.
1417+
*/
1418+
for (cell = patterns->head; cell; cell = cell->next)
1419+
{
1420+
appendPQExpBufferStr(query,
1421+
"SELECT oid FROM pg_catalog.pg_extension e\n");
1422+
processSQLNamePattern(GetConnection(fout), query, cell->val, false,
1423+
false, NULL, "e.extname", NULL, NULL);
1424+
1425+
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1426+
if (strict_names && PQntuples(res) == 0)
1427+
fatal("no matching extensions were found for pattern \"%s\"", cell->val);
1428+
1429+
for (i = 0; i < PQntuples(res); i++)
1430+
{
1431+
simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
1432+
}
1433+
1434+
PQclear(res);
1435+
resetPQExpBuffer(query);
1436+
}
1437+
1438+
destroyPQExpBuffer(query);
1439+
}
1440+
13701441
/*
13711442
* Find the OIDs of all foreign servers matching the given list of patterns,
13721443
* and append them to the given OID list.
@@ -1793,8 +1864,9 @@ selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout)
17931864
* Built-in extensions should be skipped except for checking ACLs, since we
17941865
* assume those will already be installed in the target database. We identify
17951866
* such extensions by their having OIDs in the range reserved for initdb.
1796-
* We dump all user-added extensions by default, or none of them if
1797-
* include_everything is false (i.e., a --schema or --table switch was given).
1867+
* We dump all user-added extensions by default. No extensions are dumped
1868+
* if include_everything is false (i.e., a --schema or --table switch was
1869+
* given), except if --extension specifies a list of extensions to dump.
17981870
*/
17991871
static void
18001872
selectDumpableExtension(ExtensionInfo *extinfo, DumpOptions *dopt)
@@ -1807,9 +1879,18 @@ selectDumpableExtension(ExtensionInfo *extinfo, DumpOptions *dopt)
18071879
if (extinfo->dobj.catId.oid <= (Oid) g_last_builtin_oid)
18081880
extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_ACL;
18091881
else
1810-
extinfo->dobj.dump = extinfo->dobj.dump_contains =
1811-
dopt->include_everything ? DUMP_COMPONENT_ALL :
1812-
DUMP_COMPONENT_NONE;
1882+
{
1883+
/* check if there is a list of extensions to dump */
1884+
if (extension_include_oids.head != NULL)
1885+
extinfo->dobj.dump = extinfo->dobj.dump_contains =
1886+
simple_oid_list_member(&extension_include_oids,
1887+
extinfo->dobj.catId.oid) ?
1888+
DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
1889+
else
1890+
extinfo->dobj.dump = extinfo->dobj.dump_contains =
1891+
dopt->include_everything ?
1892+
DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
1893+
}
18131894
}
18141895

18151896
/*

‎src/test/modules/test_pg_dump/t/001_base.pl

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,20 @@
194194
'pg_dump','--no-sync',"--file=$tempdir/section_post_data.sql",
195195
'--section=post-data','postgres',
196196
],
197+
},
198+
with_extension=> {
199+
dump_cmd=> [
200+
'pg_dump','--no-sync',"--file=$tempdir/with_extension.sql",
201+
'--extension=test_pg_dump','--no-sync','postgres',
202+
],
203+
},
204+
205+
# plgsql in the list blocks the dump of extension test_pg_dump
206+
without_extension=> {
207+
dump_cmd=> [
208+
'pg_dump','--no-sync',"--file=$tempdir/without_extension.sql",
209+
'--extension=plpgsql','--no-sync','postgres',
210+
],
197211
},);
198212

199213
###############################################################
@@ -228,14 +242,16 @@
228242
# Tests which are considered 'full' dumps by pg_dump, but there
229243
# are flags used to exclude specific items (ACLs, blobs, etc).
230244
my%full_runs = (
231-
binary_upgrade=> 1,
232-
clean=> 1,
233-
clean_if_exists=> 1,
234-
createdb=> 1,
235-
defaults=> 1,
236-
exclude_table=> 1,
237-
no_privs=> 1,
238-
no_owner=> 1,);
245+
binary_upgrade=> 1,
246+
clean=> 1,
247+
clean_if_exists=> 1,
248+
createdb=> 1,
249+
defaults=> 1,
250+
exclude_table=> 1,
251+
no_privs=> 1,
252+
no_owner=> 1,
253+
with_extension=> 1,
254+
without_extension=> 1);
239255

240256
my%tests = (
241257
'ALTER EXTENSION test_pg_dump'=> {
@@ -261,7 +277,7 @@
261277
schema_only => 1,
262278
section_pre_data => 1,
263279
},
264-
unlike => { binary_upgrade => 1, },
280+
unlike => { binary_upgrade => 1,without_extension => 1},
265281
},
266282
267283
'CREATE ROLE regress_dump_test_role' => {
@@ -320,6 +336,7 @@
320336
section_data => 1,
321337
extension_schema => 1,
322338
},
339+
unlike => { without_extension => 1, },
323340
},
324341
325342
'CREATE TABLE regress_pg_dump_table' => {
@@ -343,8 +360,9 @@
343360
extension_schema => 1,
344361
},
345362
unlike => {
346-
binary_upgrade => 1,
347-
exclude_table => 1,
363+
binary_upgrade => 1,
364+
exclude_table => 1,
365+
without_extension => 1,
348366
},
349367
},
350368
@@ -367,7 +385,7 @@
367385
schema_only => 1,
368386
section_pre_data => 1,
369387
},
370-
unlike => { no_privs => 1, },
388+
unlike => { no_privs => 1,without_extension => 1,},
371389
},
372390
373391
'REVOKE GRANT OPTION FOR UPDATE ON SEQUENCE wgo_then_regular' => {
@@ -384,7 +402,7 @@
384402
schema_only => 1,
385403
section_pre_data => 1,
386404
},
387-
unlike => { no_privs => 1, },
405+
unlike => { no_privs => 1,without_extension => 1,},
388406
},
389407
390408
'CREATE ACCESS METHOD regress_test_am' => {
@@ -404,6 +422,7 @@
404422
schema_only => 1,
405423
section_pre_data => 1,
406424
},
425+
unlike => { without_extension => 1, },
407426
},
408427
409428
'GRANT SELECT regress_pg_dump_table_added pre-ALTER EXTENSION' => {
@@ -428,7 +447,7 @@
428447
schema_only => 1,
429448
section_pre_data => 1,
430449
},
431-
unlike => { no_privs => 1, },
450+
unlike => { no_privs => 1,without_extension => 1,},
432451
},
433452
434453
'GRANT SELECT ON TABLE regress_pg_dump_table' => {
@@ -462,7 +481,7 @@
462481
schema_only => 1,
463482
section_pre_data => 1,
464483
},
465-
unlike => { no_privs => 1, },
484+
unlike => { no_privs => 1,without_extension => 1},
466485
},
467486
468487
'GRANT USAGE ON regress_pg_dump_table_col1_seq TO regress_dump_test_role'
@@ -478,7 +497,7 @@
478497
schema_only => 1,
479498
section_pre_data => 1,
480499
},
481-
unlike => { no_privs => 1, },
500+
unlike => { no_privs => 1,without_extension => 1,},
482501
},
483502
484503
'GRANT USAGE ON regress_pg_dump_seq TO regress_dump_test_role' => {
@@ -500,7 +519,7 @@
500519
schema_only => 1,
501520
section_pre_data => 1,
502521
},
503-
unlike => { no_privs => 1, },
522+
unlike => { no_privs => 1,without_extension => 1,},
504523
},
505524
506525
# Objects included in extension part of a schema created by this extension */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp