From 7fb84d68df023d913c448f2498987ca4f0a70595 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@otacoo.com>
Date: Tue, 17 Feb 2015 07:39:23 +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. Note
that this does not take into account foreign keys of tables that are
not part of an extension linking to an extension table.
---
 src/bin/pg_dump/pg_dump.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 2b53c72..5b1b240 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 extension tables.
  */
 void
 getExtensionMembership(Archive *fout, DumpOptions *dopt, ExtensionInfo extinfo[],
@@ -15423,6 +15424,59 @@ getExtensionMembership(Archive *fout, DumpOptions *dopt, ExtensionInfo extinfo[]
 					}
 				}
 			}
+
+			/*
+			 * 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().
+			 */
+			for (j = 0; j < nconfigitems; j++)
+			{
+				int			i_confrelid, k;
+				PQExpBuffer query2 = createPQExpBuffer();
+				TableInfo  *configtbl;
+				Oid			configtbloid = atooid(extconfigarray[j]);
+
+				configtbl = findTableByOid(configtbloid);
+				if (configtbl == NULL || configtbl->dataObj == NULL)
+					continue;
+
+				appendPQExpBuffer(query2,
+					  "SELECT confrelid "
+					  "FROM pg_catalog.pg_constraint "
+					  "WHERE conrelid = '%u' "
+					  "AND contype = 'f'",
+					  configtbloid);
+
+				res = ExecuteSqlQuery(fout, query2->data, PGRES_TUPLES_OK);
+				ntups = PQntuples(res);
+				i_confrelid = PQfnumber(res, "confrelid");
+
+				for (k = 0; k < ntups; k++)
+				{
+					Oid			confrelid;
+					TableInfo  *reftable;
+
+					confrelid = atooid(PQgetvalue(res, k, i_confrelid));
+					reftable = findTableByOid(confrelid);
+
+					if (reftable == NULL || reftable->dataObj == NULL)
+						continue;
+
+					/*
+					 * Make referencing TABLE_DATA object depend on the
+					 * referenced table's TABLE_DATA object.
+					 */
+					addObjectDependency(&configtbl->dataObj->dobj,
+										reftable->dataObj->dobj.dumpId);
+				}
+				resetPQExpBuffer(query2);
+			}
 		}
 		if (extconfigarray)
 			free(extconfigarray);
-- 
2.3.0

