88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.54 2001/03/22 04:00:11 momjian Exp $
11+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.55 2001/04/03 08:52:59 pjw Exp $
1212 *
1313 * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
1414 *
2121 *string to return - formatted type, or base type. If the base type
2222 *is returned then fmtId is called on the string.
2323 *
24+ * Modifications 4-Apr-2001 - pjw@rhyme.com.au
25+ *-Changed flagInhAttrs to check all parent tables for overridden settings
26+ *and set flags accordingly.
27+ *
2428 *BEWARE: Since fmtId uses a static buffer, using 'useBaseTypeName' on more
2529 *than one call in a line will cause problems.
2630 *
3943static char * * findParentsByOid (TableInfo * tbinfo ,int numTables ,
4044InhInfo * inhinfo ,int numInherits ,
4145const char * oid ,
42- int * numParents );
46+ int * numParents ,
47+ int (* * parentIndices )[]);
4348static int findTableByOid (TableInfo * tbinfo ,int numTables ,const char * oid );
4449static void flagInhAttrs (TableInfo * tbinfo ,int numTables ,
4550InhInfo * inhinfo ,int numInherits );
@@ -122,7 +127,7 @@ findOprByOid(OprInfo *oprinfo, int numOprs, const char *oid)
122127/*
123128 * findParentsByOid
124129 * given the oid of a class, return the names of its parent classes
125- * and assign the number of parents to the lastargument .
130+ * and assign the number of parents, and parent indices to the lastarguments .
126131 *
127132 *
128133 * returns NULL if none
@@ -131,7 +136,7 @@ findOprByOid(OprInfo *oprinfo, int numOprs, const char *oid)
131136static char * *
132137findParentsByOid (TableInfo * tblinfo ,int numTables ,
133138InhInfo * inhinfo ,int numInherits ,const char * oid ,
134- int * numParentsPtr )
139+ int * numParentsPtr , int ( * * parentIndices )[] )
135140{
136141int i ,
137142j ;
@@ -152,6 +157,7 @@ findParentsByOid(TableInfo *tblinfo, int numTables,
152157if (numParents > 0 )
153158{
154159result = (char * * )malloc (sizeof (char * )* numParents );
160+ (* parentIndices )= malloc (sizeof (int )* numParents );
155161j = 0 ;
156162for (i = 0 ;i < numInherits ;i ++ )
157163{
@@ -169,13 +175,17 @@ findParentsByOid(TableInfo *tblinfo, int numTables,
169175oid );
170176exit (2 );
171177}
178+ (* * parentIndices )[j ]= parentInd ;
172179result [j ++ ]= tblinfo [parentInd ].relname ;
173180}
174181}
175182return result ;
176183}
177184else
185+ {
186+ (* parentIndices )= NULL ;
178187return NULL ;
188+ }
179189}
180190
181191/*
@@ -415,6 +425,14 @@ flagInhAttrs(TableInfo *tblinfo, int numTables,
415425j ,
416426k ;
417427int parentInd ;
428+ int inhAttrInd ;
429+ int (* parentIndices )[];
430+ bool foundAttr ;/* Attr was found in a parent */
431+ bool foundNotNull ;/* Attr was NOT NULL in a parent */
432+ bool defaultsMatch ;/* All non-empty defaults match */
433+ bool defaultsFound ;/* Found a default in a parent */
434+ char * attrDef ;
435+ char * inhDef ;
418436
419437/*
420438 * we go backwards because the tables in tblinfo are in OID order,
@@ -423,27 +441,97 @@ flagInhAttrs(TableInfo *tblinfo, int numTables,
423441 */
424442for (i = numTables - 1 ;i >=0 ;i -- )
425443{
444+
445+ /* Sequences can never have parents, and attr info is undefined */
446+ if (tblinfo [i ].sequence )
447+ continue ;
448+
449+ /* Get all the parents and their indexes. */
426450tblinfo [i ].parentRels = findParentsByOid (tblinfo ,numTables ,
427451inhinfo ,numInherits ,
428452tblinfo [i ].oid ,
429- & tblinfo [i ].numParents );
430- for (k = 0 ;k < tblinfo [i ].numParents ;k ++ )
453+ & tblinfo [i ].numParents ,
454+ & parentIndices );
455+
456+ /*
457+ * For each attr, check the parent info: if no parent has
458+ * an attr with the same name, then it's not inherited. If there
459+ * *is* an attr with the same name, then only dump it if:
460+ *
461+ * - it is NOT NULL and zero parents are NOT NULL
462+ * OR
463+ * - it has a default value AND the default value
464+ * does not match all parent default values, or
465+ * no parents specify a default.
466+ *
467+ * See discussion on -hackers around 2-Apr-2001.
468+ */
469+ for (j = 0 ;j < tblinfo [i ].numatts ;j ++ )
431470{
432- parentInd = findTableByName (tblinfo ,numTables ,
433- tblinfo [i ].parentRels [k ]);
434- if (parentInd < 0 )
471+ foundAttr = false;
472+ foundNotNull = false;
473+ defaultsMatch = true;
474+ defaultsFound = false;
475+
476+ attrDef = tblinfo [i ].adef_expr [j ];
477+
478+ for (k = 0 ;k < tblinfo [i ].numParents ;k ++ )
435479{
436- /* shouldn't happen unless findParentsByOid is broken */
437- fprintf (stderr ,"failed sanity check, table %s not found by flagInhAttrs\n" ,
438- tblinfo [i ].parentRels [k ]);
439- exit (2 );
440- }
441- for (j = 0 ;j < tblinfo [i ].numatts ;j ++ )
480+ parentInd = (* parentIndices )[k ];
481+
482+ if (parentInd < 0 )
483+ {
484+ /* shouldn't happen unless findParentsByOid is broken */
485+ fprintf (stderr ,"failed sanity check, table %s not found by flagInhAttrs\n" ,
486+ tblinfo [i ].parentRels [k ]);
487+ exit (2 );
488+ };
489+
490+ inhAttrInd = strInArray (tblinfo [i ].attnames [j ],
491+ tblinfo [parentInd ].attnames ,
492+ tblinfo [parentInd ].numatts );
493+
494+ if (inhAttrInd != -1 )
495+ {
496+ foundAttr = true;
497+ foundNotNull |=tblinfo [parentInd ].notnull [inhAttrInd ];
498+ if (attrDef != NULL )/* It we have a default, check parent */
499+ {
500+ inhDef = tblinfo [parentInd ].adef_expr [inhAttrInd ];
501+
502+ if (inhDef != NULL )
503+ {
504+ defaultsFound = true;
505+ defaultsMatch &= (strcmp (attrDef ,inhDef )== 0 );
506+ };
507+ };
508+ };
509+ };
510+
511+ /*
512+ * Based on the scan of the parents, decide if we
513+ * can rely on the inherited attr
514+ */
515+ if (foundAttr )/* Attr was inherited */
442516{
443- if (strInArray (tblinfo [i ].attnames [j ],
444- tblinfo [parentInd ].attnames ,
445- tblinfo [parentInd ].numatts )!= -1 )
446- tblinfo [i ].inhAttrs [j ]= 1 ;
517+ /* Set inherited flag by default */
518+ tblinfo [i ].inhAttrs [j ]= 1 ;
519+ tblinfo [i ].inhAttrDef [j ]= 1 ;
520+ tblinfo [i ].inhNotNull [j ]= 1 ;
521+
522+ /* Clear it if attr had a default, but parents did not, or mismatch */
523+ if ( (attrDef != NULL )&& (!defaultsFound || !defaultsMatch ) )
524+ {
525+ tblinfo [i ].inhAttrs [j ]= 0 ;
526+ tblinfo [i ].inhAttrDef [j ]= 0 ;
527+ }
528+
529+ /* Clear it if NOT NULL and none of the parents were NOT NULL */
530+ if (tblinfo [i ].notnull [j ]&& !foundNotNull )
531+ {
532+ tblinfo [i ].inhAttrs [j ]= 0 ;
533+ tblinfo [i ].inhNotNull [j ]= 0 ;
534+ }
447535}
448536}
449537}