diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c index 4f3469d..b10ec6b 100644 --- a/src/bin/pg_dump/pg_dump_sort.c +++ b/src/bin/pg_dump/pg_dump_sort.c @@ -174,6 +174,8 @@ static int findLoop(DumpableObject *obj, DumpId *searchFailed, DumpableObject **workspace, int depth); +static void repairExtensionOwnedSchemaLoop(DumpableObject *extobj, + DumpableObject *nspobj); static void repairDependencyLoop(DumpableObject **loop, int nLoop); static void describeDumpableObject(DumpableObject *obj, @@ -928,6 +930,24 @@ findLoop(DumpableObject *obj, return 0; } +/* + * An extension whose control file sets owned_schema=true has a dependency + * loop with its schema: the extension is in the schema, and the schema is a + * member of the extension. Break the loop by dropping the extension's + * dependency on the schema, since CREATE EXTENSION creates the schema. + */ +static void +repairExtensionOwnedSchemaLoop(DumpableObject *extobj, DumpableObject *nspobj) +{ + /* + * An extension with owned_schema=true creates its schema itself, as part + * of CREATE EXTENSION, so the extension need not wait for the schema to + * be created first. (The schema is a member of the extension, hence the + * dependency in the other direction, which is the one we keep.) + */ + removeObjectDependency(extobj, nspobj->dumpId); +} + /* * A user-defined datatype will have a dependency loop with each of its * I/O functions (since those have the datatype as input or output). @@ -1191,6 +1211,22 @@ repairDependencyLoop(DumpableObject **loop, return; } + /* Extension and the schema that the extension itself creates */ + if (nLoop == 2 && + loop[0]->objType == DO_EXTENSION && + loop[1]->objType == DO_NAMESPACE) + { + repairExtensionOwnedSchemaLoop(loop[0], loop[1]); + return; + } + if (nLoop == 2 && + loop[1]->objType == DO_EXTENSION && + loop[0]->objType == DO_NAMESPACE) + { + repairExtensionOwnedSchemaLoop(loop[1], loop[0]); + return; + } + /* View (including matview) and its ON SELECT rule */ if (nLoop == 2 && loop[0]->objType == DO_TABLE &&