1212 * by PostgreSQL
1313 *
1414 * IDENTIFICATION
15- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.499 2008/07/30 19:35:13 tgl Exp $
15+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.500 2008/09/08 15:26:23 tgl Exp $
1616 *
1717 *-------------------------------------------------------------------------
1818 */
@@ -166,6 +166,7 @@ static void dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
166166static void getDependencies (void );
167167static void getDomainConstraints (TypeInfo * tinfo );
168168static void getTableData (TableInfo * tblinfo , int numTables , bool oids );
169+ static void getTableDataFKConstraints (void );
169170static char * format_function_arguments (FuncInfo * finfo , char * funcargs );
170171static char * format_function_arguments_old (FuncInfo * finfo , int nallargs ,
171172 char * * allargtypes ,
@@ -659,7 +660,11 @@ main(int argc, char **argv)
659660 guessConstraintInheritance (tblinfo , numTables );
660661
661662 if (!schemaOnly )
663+ {
662664 getTableData (tblinfo , numTables , oids );
665+ if (dataOnly )
666+ getTableDataFKConstraints ();
667+ }
663668
664669 if (outputBlobs && hasBlobs (g_fout ))
665670 {
@@ -1392,10 +1397,59 @@ getTableData(TableInfo *tblinfo, int numTables, bool oids)
13921397 tdinfo -> tdtable = & (tblinfo [i ]);
13931398 tdinfo -> oids = oids ;
13941399 addObjectDependency (& tdinfo -> dobj , tblinfo [i ].dobj .dumpId );
1400+
1401+ tblinfo [i ].dataObj = tdinfo ;
13951402 }
13961403 }
13971404}
13981405
1406+ /*
1407+ * getTableDataFKConstraints -
1408+ * add dump-order dependencies reflecting foreign key constraints
1409+ *
1410+ * This code is executed only in a data-only dump --- in schema+data dumps
1411+ * we handle foreign key issues by not creating the FK constraints until
1412+ * after the data is loaded. In a data-only dump, however, we want to
1413+ * order the table data objects in such a way that a table's referenced
1414+ * tables are restored first. (In the presence of circular references or
1415+ * self-references this may be impossible; we'll detect and complain about
1416+ * that during the dependency sorting step.)
1417+ */
1418+ static void
1419+ getTableDataFKConstraints (void )
1420+ {
1421+ DumpableObject * * dobjs ;
1422+ int numObjs ;
1423+ int i ;
1424+
1425+ /* Search through all the dumpable objects for FK constraints */
1426+ getDumpableObjects (& dobjs , & numObjs );
1427+ for (i = 0 ; i < numObjs ; i ++ )
1428+ {
1429+ if (dobjs [i ]-> objType == DO_FK_CONSTRAINT )
1430+ {
1431+ ConstraintInfo * cinfo = (ConstraintInfo * ) dobjs [i ];
1432+ TableInfo * ftable ;
1433+
1434+ /* Not interesting unless both tables are to be dumped */
1435+ if (cinfo -> contable == NULL ||
1436+ cinfo -> contable -> dataObj == NULL )
1437+ continue ;
1438+ ftable = findTableByOid (cinfo -> confrelid );
1439+ if (ftable == NULL ||
1440+ ftable -> dataObj == NULL )
1441+ continue ;
1442+ /*
1443+ * Okay, make referencing table's TABLE_DATA object depend on
1444+ * the referenced table's TABLE_DATA object.
1445+ */
1446+ addObjectDependency (& cinfo -> contable -> dataObj -> dobj ,
1447+ ftable -> dataObj -> dobj .dumpId );
1448+ }
1449+ }
1450+ free (dobjs );
1451+ }
1452+
13991453
14001454/*
14011455 * guessConstraintInheritance:
@@ -3626,6 +3680,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
36263680 constrinfo [j ].condomain = NULL ;
36273681 constrinfo [j ].contype = contype ;
36283682 constrinfo [j ].condef = NULL ;
3683+ constrinfo [j ].confrelid = InvalidOid ;
36293684 constrinfo [j ].conindex = indxinfo [j ].dobj .dumpId ;
36303685 constrinfo [j ].conislocal = true;
36313686 constrinfo [j ].separate = true;
@@ -3666,10 +3721,11 @@ getConstraints(TableInfo tblinfo[], int numTables)
36663721 ConstraintInfo * constrinfo ;
36673722 PQExpBuffer query ;
36683723 PGresult * res ;
3669- int i_condef ,
3670- i_contableoid ,
3724+ int i_contableoid ,
36713725 i_conoid ,
3672- i_conname ;
3726+ i_conname ,
3727+ i_confrelid ,
3728+ i_condef ;
36733729 int ntups ;
36743730
36753731 /* pg_constraint was created in 7.3, so nothing to do if older */
@@ -3697,7 +3753,7 @@ getConstraints(TableInfo tblinfo[], int numTables)
36973753
36983754 resetPQExpBuffer (query );
36993755 appendPQExpBuffer (query ,
3700- "SELECT tableoid, oid, conname, "
3756+ "SELECT tableoid, oid, conname, confrelid, "
37013757 "pg_catalog.pg_get_constraintdef(oid) as condef "
37023758 "FROM pg_catalog.pg_constraint "
37033759 "WHERE conrelid = '%u'::pg_catalog.oid "
@@ -3711,6 +3767,7 @@ getConstraints(TableInfo tblinfo[], int numTables)
37113767 i_contableoid = PQfnumber (res , "tableoid" );
37123768 i_conoid = PQfnumber (res , "oid" );
37133769 i_conname = PQfnumber (res , "conname" );
3770+ i_confrelid = PQfnumber (res , "confrelid" );
37143771 i_condef = PQfnumber (res , "condef" );
37153772
37163773 constrinfo = (ConstraintInfo * ) malloc (ntups * sizeof (ConstraintInfo ));
@@ -3727,6 +3784,7 @@ getConstraints(TableInfo tblinfo[], int numTables)
37273784 constrinfo [j ].condomain = NULL ;
37283785 constrinfo [j ].contype = 'f' ;
37293786 constrinfo [j ].condef = strdup (PQgetvalue (res , j , i_condef ));
3787+ constrinfo [j ].confrelid = atooid (PQgetvalue (res , j , i_confrelid ));
37303788 constrinfo [j ].conindex = 0 ;
37313789 constrinfo [j ].conislocal = true;
37323790 constrinfo [j ].separate = true;
@@ -3810,6 +3868,7 @@ getDomainConstraints(TypeInfo *tinfo)
38103868 constrinfo [i ].condomain = tinfo ;
38113869 constrinfo [i ].contype = 'c' ;
38123870 constrinfo [i ].condef = strdup (PQgetvalue (res , i , i_consrc ));
3871+ constrinfo [i ].confrelid = InvalidOid ;
38133872 constrinfo [i ].conindex = 0 ;
38143873 constrinfo [i ].conislocal = true;
38153874 constrinfo [i ].separate = false;
@@ -4788,6 +4847,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
47884847 constrs [j ].condomain = NULL ;
47894848 constrs [j ].contype = 'c' ;
47904849 constrs [j ].condef = strdup (PQgetvalue (res , j , 3 ));
4850+ constrs [j ].confrelid = InvalidOid ;
47914851 constrs [j ].conindex = 0 ;
47924852 constrs [j ].conislocal = (PQgetvalue (res , j , 4 )[0 ] == 't' );
47934853 constrs [j ].separate = false;
0 commit comments