diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c index 21d7ca2e2c2aa2c631131d41d241a47dc15612cd..957796b8bdd72d918618a98f6d78f45b1292544e 100644 --- a/src/bin/pg_dump/common.c +++ b/src/bin/pg_dump/common.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.54 2001/03/22 04:00:11 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.55 2001/04/03 08:52:59 pjw Exp $ * * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2 * @@ -21,6 +21,10 @@ * string to return - formatted type, or base type. If the base type * is returned then fmtId is called on the string. * + * Modifications 4-Apr-2001 - pjw@rhyme.com.au + * - Changed flagInhAttrs to check all parent tables for overridden settings + * and set flags accordingly. + * * BEWARE: Since fmtId uses a static buffer, using 'useBaseTypeName' on more * than one call in a line will cause problems. * @@ -39,7 +43,8 @@ static char **findParentsByOid(TableInfo *tbinfo, int numTables, InhInfo *inhinfo, int numInherits, const char *oid, - int *numParents); + int *numParents, + int (**parentIndices)[]); static int findTableByOid(TableInfo *tbinfo, int numTables, const char *oid); static void flagInhAttrs(TableInfo *tbinfo, int numTables, InhInfo *inhinfo, int numInherits); @@ -122,7 +127,7 @@ findOprByOid(OprInfo *oprinfo, int numOprs, const char *oid) /* * findParentsByOid * given the oid of a class, return the names of its parent classes - * and assign the number of parents to the last argument. + * and assign the number of parents, and parent indices to the last arguments. * * * returns NULL if none @@ -131,7 +136,7 @@ findOprByOid(OprInfo *oprinfo, int numOprs, const char *oid) static char ** findParentsByOid(TableInfo *tblinfo, int numTables, InhInfo *inhinfo, int numInherits, const char *oid, - int *numParentsPtr) + int *numParentsPtr, int (**parentIndices)[]) { int i, j; @@ -152,6 +157,7 @@ findParentsByOid(TableInfo *tblinfo, int numTables, if (numParents > 0) { result = (char **) malloc(sizeof(char *) * numParents); + (*parentIndices) = malloc(sizeof(int) * numParents); j = 0; for (i = 0; i < numInherits; i++) { @@ -169,13 +175,17 @@ findParentsByOid(TableInfo *tblinfo, int numTables, oid); exit(2); } + (**parentIndices)[j] = parentInd; result[j++] = tblinfo[parentInd].relname; } } return result; } else + { + (*parentIndices) = NULL; return NULL; + } } /* @@ -415,6 +425,14 @@ flagInhAttrs(TableInfo *tblinfo, int numTables, j, k; int parentInd; + int inhAttrInd; + int (*parentIndices)[]; + bool foundAttr; /* Attr was found in a parent */ + bool foundNotNull; /* Attr was NOT NULL in a parent */ + bool defaultsMatch; /* All non-empty defaults match */ + bool defaultsFound; /* Found a default in a parent */ + char *attrDef; + char *inhDef; /* * we go backwards because the tables in tblinfo are in OID order, @@ -423,27 +441,97 @@ flagInhAttrs(TableInfo *tblinfo, int numTables, */ for (i = numTables - 1; i >= 0; i--) { + + /* Sequences can never have parents, and attr info is undefined */ + if (tblinfo[i].sequence) + continue; + + /* Get all the parents and their indexes. */ tblinfo[i].parentRels = findParentsByOid(tblinfo, numTables, inhinfo, numInherits, tblinfo[i].oid, - &tblinfo[i].numParents); - for (k = 0; k < tblinfo[i].numParents; k++) + &tblinfo[i].numParents, + &parentIndices); + + /* + * For each attr, check the parent info: if no parent has + * an attr with the same name, then it's not inherited. If there + * *is* an attr with the same name, then only dump it if: + * + * - it is NOT NULL and zero parents are NOT NULL + * OR + * - it has a default value AND the default value + * does not match all parent default values, or + * no parents specify a default. + * + * See discussion on -hackers around 2-Apr-2001. + */ + for (j = 0; j < tblinfo[i].numatts; j++) { - parentInd = findTableByName(tblinfo, numTables, - tblinfo[i].parentRels[k]); - if (parentInd < 0) + foundAttr = false; + foundNotNull = false; + defaultsMatch = true; + defaultsFound = false; + + attrDef = tblinfo[i].adef_expr[j]; + + for (k = 0; k < tblinfo[i].numParents; k++) { - /* shouldn't happen unless findParentsByOid is broken */ - fprintf(stderr, "failed sanity check, table %s not found by flagInhAttrs\n", - tblinfo[i].parentRels[k]); - exit(2); - } - for (j = 0; j < tblinfo[i].numatts; j++) + parentInd = (*parentIndices)[k]; + + if (parentInd < 0) + { + /* shouldn't happen unless findParentsByOid is broken */ + fprintf(stderr, "failed sanity check, table %s not found by flagInhAttrs\n", + tblinfo[i].parentRels[k]); + exit(2); + }; + + inhAttrInd = strInArray(tblinfo[i].attnames[j], + tblinfo[parentInd].attnames, + tblinfo[parentInd].numatts); + + if (inhAttrInd != -1) + { + foundAttr = true; + foundNotNull |= tblinfo[parentInd].notnull[inhAttrInd]; + if (attrDef != NULL) /* It we have a default, check parent */ + { + inhDef = tblinfo[parentInd].adef_expr[inhAttrInd]; + + if (inhDef != NULL) + { + defaultsFound = true; + defaultsMatch &= (strcmp(attrDef, inhDef) == 0); + }; + }; + }; + }; + + /* + * Based on the scan of the parents, decide if we + * can rely on the inherited attr + */ + if (foundAttr) /* Attr was inherited */ { - if (strInArray(tblinfo[i].attnames[j], - tblinfo[parentInd].attnames, - tblinfo[parentInd].numatts) != -1) - tblinfo[i].inhAttrs[j] = 1; + /* Set inherited flag by default */ + tblinfo[i].inhAttrs[j] = 1; + tblinfo[i].inhAttrDef[j] = 1; + tblinfo[i].inhNotNull[j] = 1; + + /* Clear it if attr had a default, but parents did not, or mismatch */ + if ( (attrDef != NULL) && (!defaultsFound || !defaultsMatch) ) + { + tblinfo[i].inhAttrs[j] = 0; + tblinfo[i].inhAttrDef[j] = 0; + } + + /* Clear it if NOT NULL and none of the parents were NOT NULL */ + if (tblinfo[i].notnull[j] && !foundNotNull) + { + tblinfo[i].inhAttrs[j] = 0; + tblinfo[i].inhNotNull[j] = 0; + } } } } diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h index 8bbc2ae1617d51ced55f94bedd32ba85b1891066..fb85685fbc14ff761a6403d75f8859022f8c6417 100644 --- a/src/bin/pg_dump/pg_backup_archiver.h +++ b/src/bin/pg_dump/pg_backup_archiver.h @@ -17,7 +17,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.28 2001/04/01 05:42:51 pjw Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.29 2001/04/03 08:52:59 pjw Exp $ * * Modifications - 28-Jun-2000 - pjw@rhyme.com.au * - Initial version. @@ -68,7 +68,7 @@ typedef z_stream *z_streamp; #define K_VERS_MAJOR 1 #define K_VERS_MINOR 5 -#define K_VERS_REV 0 +#define K_VERS_REV 1 /* Data block types */ #define BLK_DATA 1 diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 8cb17e2c1a1e699ee1c25e4d43d62b292b24051e..c4a79aa054af3aa7258c0b2664e61322b5be6327 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -22,7 +22,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.198 2001/04/01 05:42:51 pjw Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.199 2001/04/03 08:52:59 pjw Exp $ * * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb * @@ -1603,6 +1603,10 @@ clearTableInfo(TableInfo *tblinfo, int numTables) free((int *) tblinfo[i].atttypmod); if (tblinfo[i].inhAttrs) free((int *) tblinfo[i].inhAttrs); + if (tblinfo[i].inhAttrDef) + free((int *) tblinfo[i].inhAttrDef); + if (tblinfo[i].inhNotNull) + free((int *) tblinfo[i].inhNotNull); if (tblinfo[i].attnames) free(tblinfo[i].attnames); if (tblinfo[i].atttypedefns) @@ -2138,7 +2142,8 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs) " where i.inhrelid = pg_relcheck.rcrelid " " and c.rcname = pg_relcheck.rcname " " and c.rcsrc = pg_relcheck.rcsrc " - " and c.rcrelid = i.inhparent) ", + " and c.rcrelid = i.inhparent) " + " Order By oid ", tblinfo[i].oid); res2 = PQexec(g_conn, query->data); if (!res2 || @@ -2656,6 +2661,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables) tblinfo[i].typnames = (char **) malloc(ntups * sizeof(char *)); tblinfo[i].atttypmod = (int *) malloc(ntups * sizeof(int)); tblinfo[i].inhAttrs = (int *) malloc(ntups * sizeof(int)); + tblinfo[i].inhAttrDef = (int *) malloc(ntups * sizeof(int)); + tblinfo[i].inhNotNull = (int *) malloc(ntups * sizeof(int)); tblinfo[i].notnull = (bool *) malloc(ntups * sizeof(bool)); tblinfo[i].adef_expr = (char **) malloc(ntups * sizeof(char *)); tblinfo[i].parentRels = NULL; @@ -2678,6 +2685,9 @@ getTableAttrs(TableInfo *tblinfo, int numTables) tblinfo[i].atttypmod[j] = atoi(PQgetvalue(res, j, i_atttypmod)); tblinfo[i].inhAttrs[j] = 0; /* this flag is set in * flagInhAttrs() */ + tblinfo[i].inhAttrDef[j] = 0; + tblinfo[i].inhNotNull[j] = 0; + tblinfo[i].notnull[j] = (PQgetvalue(res, j, i_attnotnull)[0] == 't') ? true : false; if (PQgetvalue(res, j, i_atthasdef)[0] == 't') { @@ -3829,12 +3839,12 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables, tblinfo[i].atttypedefns[j]); /* Default value */ - if (tblinfo[i].adef_expr[j] != NULL) + if (tblinfo[i].adef_expr[j] != NULL && tblinfo[i].inhAttrDef[j] == 0) appendPQExpBuffer(q, " DEFAULT %s", tblinfo[i].adef_expr[j]); /* Not Null constraint */ - if (tblinfo[i].notnull[j]) + if (tblinfo[i].notnull[j] && tblinfo[i].inhNotNull[j] == 0) appendPQExpBuffer(q, " NOT NULL"); actual_atts++; diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index 73b6c35bd998aec5d7c518b709a306785ef401f8..8069a8f779bcbf6fd753fcfbdea2455abad3da11 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_dump.h,v 1.60 2001/03/23 04:49:56 momjian Exp $ + * $Id: pg_dump.h,v 1.61 2001/04/03 08:52:59 pjw Exp $ * * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2 * @@ -93,6 +93,8 @@ typedef struct _tableInfo int *inhAttrs; /* an array of flags, one for each * attribute if the value is 1, then this * attribute is an inherited attribute */ + int *inhAttrDef; /* Flags indicating if attrdef is inherited */ + int *inhNotNull; /* Flags indicating if NOT NULL in inherited */ char **attnames; /* the attribute names */ char **attoids; /* oids of the various attributes */ char **atttypedefns; /* formatted column type definitions */