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

Commit408f759

Browse files
committed
Fix pg_dump's handling of dependencies for custom opclasses.
Since pg_dump doesn't treat the member operators and functions of operatorclasses/families (that is, the pg_amop and pg_amproc entries, not theunderlying operators/functions) as separate dumpable objects, it missedtheir dependency information. I think this was safe when the code wasdesigned, because the default object sorting rule emits operators andfunctions before opclasses, and there were no dependency types that couldmess that up. However, the introduction of range types in 9.2 broke it:now a type can have a dependency on an opclass, allowing dependency rulesto push the opclass before the type and hence before custom operators.Lacking any information showing that it shouldn't do so, pg_dump emittedthe objects in the wrong order.Fix by teaching getDependencies() to translate pg_depend entries forpg_amop/amproc rows to look like dependencies for their parent opfamily.I added a regression test for this in HEAD/v12, but not further back;life is too short to fight with 002_pg_dump.pl.Per bug #15934 from Tom Gottfried. Back-patch to all supported branches.Discussion:https://postgr.es/m/15934-58b8c8ab7a09ea15@postgresql.org
1 parentc4b7bb3 commit408f759

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

‎src/bin/pg_dump/pg_dump.c

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17905,14 +17905,45 @@ getDependencies(Archive *fout)
1790517905
query = createPQExpBuffer();
1790617906

1790717907
/*
17908+
* Messy query to collect the dependency data we need. Note that we
17909+
* ignore the sub-object column, so that dependencies of or on a column
17910+
* look the same as dependencies of or on a whole table.
17911+
*
1790817912
* PIN dependencies aren't interesting, and EXTENSION dependencies were
1790917913
* already processed by getExtensionMembership.
1791017914
*/
1791117915
appendPQExpBufferStr(query, "SELECT "
1791217916
"classid, objid, refclassid, refobjid, deptype "
1791317917
"FROM pg_depend "
17914-
"WHERE deptype != 'p' AND deptype != 'e' "
17915-
"ORDER BY 1,2");
17918+
"WHERE deptype != 'p' AND deptype != 'e'\n");
17919+
17920+
/*
17921+
* Since we don't treat pg_amop entries as separate DumpableObjects, we
17922+
* have to translate their dependencies into dependencies of their parent
17923+
* opfamily. Ignore internal dependencies though, as those will point to
17924+
* their parent opclass, which we needn't consider here (and if we did,
17925+
* it'd just result in circular dependencies). Also, "loose" opfamily
17926+
* entries will have dependencies on their parent opfamily, which we
17927+
* should drop since they'd likewise become useless self-dependencies.
17928+
* (But be sure to keep deps on *other* opfamilies; see amopsortfamily.)
17929+
*/
17930+
appendPQExpBufferStr(query, "UNION ALL\n"
17931+
"SELECT 'pg_opfamily'::regclass AS classid, amopfamily AS objid, refclassid, refobjid, deptype "
17932+
"FROM pg_depend d, pg_amop o "
17933+
"WHERE deptype NOT IN ('p', 'e', 'i') AND "
17934+
"classid = 'pg_amop'::regclass AND objid = o.oid "
17935+
"AND NOT (refclassid = 'pg_opfamily'::regclass AND amopfamily = refobjid)\n");
17936+
17937+
/* Likewise for pg_amproc entries */
17938+
appendPQExpBufferStr(query, "UNION ALL\n"
17939+
"SELECT 'pg_opfamily'::regclass AS classid, amprocfamily AS objid, refclassid, refobjid, deptype "
17940+
"FROM pg_depend d, pg_amproc p "
17941+
"WHERE deptype NOT IN ('p', 'e', 'i') AND "
17942+
"classid = 'pg_amproc'::regclass AND objid = p.oid "
17943+
"AND NOT (refclassid = 'pg_opfamily'::regclass AND amprocfamily = refobjid)\n");
17944+
17945+
/* Sort the output for efficiency below */
17946+
appendPQExpBufferStr(query, "ORDER BY 1,2");
1791617947

1791717948
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
1791817949

‎src/bin/pg_dump/t/002_pg_dump.pl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,6 +1562,35 @@
15621562
unlike => { exclude_dump_test_schema => 1, },
15631563
},
15641564
1565+
# verify that a custom operator/opclass/range type is dumped in right order
1566+
'CREATE OPERATOR CLASS dump_test.op_class_custom' => {
1567+
create_order => 74,
1568+
create_sql => 'CREATE OPERATOR dump_test.~~ (
1569+
PROCEDURE = int4eq,
1570+
LEFTARG = int,
1571+
RIGHTARG = int);
1572+
CREATE OPERATOR CLASS dump_test.op_class_custom
1573+
FOR TYPE int USING btree AS
1574+
OPERATOR 3 dump_test.~~;
1575+
CREATE TYPE dump_test.range_type_custom AS RANGE (
1576+
subtype = int,
1577+
subtype_opclass = dump_test.op_class_custom);',
1578+
regexp => qr/^
1579+
\QCREATE OPERATOR dump_test.~~ (\E\n.+
1580+
\QCREATE OPERATOR FAMILY dump_test.op_class_custom USING btree;\E\n.+
1581+
\QCREATE OPERATOR CLASS dump_test.op_class_custom\E\n\s+
1582+
\QFOR TYPE integer USING btree FAMILY dump_test.op_class_custom AS\E\n\s+
1583+
\QOPERATOR 3 dump_test.~~(integer,integer);\E\n.+
1584+
\QCREATE TYPE dump_test.range_type_custom AS RANGE (\E\n\s+
1585+
\Qsubtype = integer,\E\n\s+
1586+
\Qsubtype_opclass = dump_test.op_class_custom\E\n
1587+
\Q);\E
1588+
/xms,
1589+
like =>
1590+
{%full_runs,%dump_test_schema_runs, section_pre_data => 1, },
1591+
unlike => { exclude_dump_test_schema => 1, },
1592+
},
1593+
15651594
'CREATE OPERATOR CLASS dump_test.op_class_empty' => {
15661595
create_order => 89,
15671596
create_sql => 'CREATE OPERATOR CLASS dump_test.op_class_empty

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp