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 ,
4044 InhInfo * inhinfo , int numInherits ,
4145 const 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 ,
4550 InhInfo * 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 last argument .
130+ * and assign the number of parents, and parent indices to the last arguments .
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 ,
133138 InhInfo * inhinfo , int numInherits , const char * oid ,
134- int * numParentsPtr )
139+ int * numParentsPtr , int ( * * parentIndices )[] )
135140{
136141 int i ,
137142 j ;
@@ -152,6 +157,7 @@ findParentsByOid(TableInfo *tblinfo, int numTables,
152157 if (numParents > 0 )
153158 {
154159 result = (char * * ) malloc (sizeof (char * ) * numParents );
160+ (* parentIndices ) = malloc (sizeof (int ) * numParents );
155161 j = 0 ;
156162 for (i = 0 ; i < numInherits ; i ++ )
157163 {
@@ -169,13 +175,17 @@ findParentsByOid(TableInfo *tblinfo, int numTables,
169175 oid );
170176 exit (2 );
171177 }
178+ (* * parentIndices )[j ] = parentInd ;
172179 result [j ++ ] = tblinfo [parentInd ].relname ;
173180 }
174181 }
175182 return result ;
176183 }
177184 else
185+ {
186+ (* parentIndices ) = NULL ;
178187 return NULL ;
188+ }
179189}
180190
181191/*
@@ -415,6 +425,14 @@ flagInhAttrs(TableInfo *tblinfo, int numTables,
415425 j ,
416426 k ;
417427 int 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 */
424442 for (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. */
426450 tblinfo [i ].parentRels = findParentsByOid (tblinfo , numTables ,
427451 inhinfo , numInherits ,
428452 tblinfo [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 }
0 commit comments