From 9ef14f2f67cbec9df2a1d30978efdeda059fa12f Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Fri, 27 Feb 2015 12:23:42 +0000 Subject: [PATCH 1/3] Fix ordering of tables part of extensions linked with constraints Additional checks on FK constraints potentially linking between them extension objects are done and data dump ordering is ensured. --- src/bin/pg_dump/pg_dump.c | 58 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 2b53c72..e210f88 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -15236,7 +15236,8 @@ dumpRule(Archive *fout, DumpOptions *dopt, RuleInfo *rinfo) } /* - * getExtensionMembership --- obtain extension membership data + * getExtensionMembership --- obtain extension membership data and check FK + * dependencies among relations interacting with the ones in extensions. */ void getExtensionMembership(Archive *fout, DumpOptions *dopt, ExtensionInfo extinfo[], @@ -15249,7 +15250,9 @@ getExtensionMembership(Archive *fout, DumpOptions *dopt, ExtensionInfo extinfo[] int i_classid, i_objid, i_refclassid, - i_refobjid; + i_refobjid, + i_conrelid, + i_confrelid; DumpableObject *dobj, *refdobj; @@ -15431,6 +15434,57 @@ getExtensionMembership(Archive *fout, DumpOptions *dopt, ExtensionInfo extinfo[] } destroyPQExpBuffer(query); + + /* + * Now that all the TableInfoData objects have been created for all + * the extensions, check their FK dependencies and register them to + * ensure correct data ordering. Note that this is not a problem + * for user tables not included in an extension referencing with a + * FK tables in extensions as their constraint is declared after + * dumping their data. In --data-only mode the table ordering is + * ensured as well thanks to getTableDataFKConstraints(). + */ + query = createPQExpBuffer(); + + appendPQExpBuffer(query, + "SELECT conrelid, confrelid " + "FROM pg_constraint " + "LEFT JOIN pg_depend ON (objid = confrelid) " + "WHERE contype = 'f' " + "AND refclassid = 'pg_extension'::regclass " + "AND classid = 'pg_class'::regclass;"); + + res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); + ntups = PQntuples(res); + + i_conrelid = PQfnumber(res, "conrelid"); + i_confrelid = PQfnumber(res, "confrelid"); + + /* Now get the dependencies and register them */ + for (i = 0; i < ntups; i++) + { + Oid conrelid, confrelid; + TableInfo *reftable, *contable; + + conrelid = atooid(PQgetvalue(res, i, i_conrelid)); + confrelid = atooid(PQgetvalue(res, i, i_confrelid)); + contable = findTableByOid(conrelid); + reftable = findTableByOid(confrelid); + + if (reftable == NULL || + reftable->dataObj == NULL || + contable == NULL || + contable->dataObj == NULL) + continue; + + /* + * Make referencing TABLE_DATA object depend on the + * referenced table's TABLE_DATA object. + */ + addObjectDependency(&contable->dataObj->dobj, + reftable->dataObj->dobj.dumpId); + } + resetPQExpBuffer(query); } /* -- 2.3.1