@@ -281,7 +281,13 @@ flagInhTables(TableInfo *tblinfo, int numTables,
281
281
282
282
/* flagInhAttrs -
283
283
* for each dumpable table in tblinfo, flag its inherited attributes
284
- * so when we dump the table out, we don't dump out the inherited attributes
284
+ *
285
+ * What we need to do here is detect child columns that inherit NOT NULL
286
+ * bits from their parents (so that we needn't specify that again for the
287
+ * child) and child columns that have DEFAULT NULL when their parents had
288
+ * some non-null default. In the latter case, we make up a dummy AttrDefInfo
289
+ * object so that we'll correctly emit the necessary DEFAULT NULL clause;
290
+ * otherwise the backend will apply an inherited default to the column.
285
291
*
286
292
* modifies tblinfo
287
293
*/
@@ -297,7 +303,6 @@ flagInhAttrs(TableInfo *tblinfo, int numTables)
297
303
TableInfo * tbinfo = & (tblinfo [i ]);
298
304
int numParents ;
299
305
TableInfo * * parents ;
300
- TableInfo * parent ;
301
306
302
307
/* Sequences and views never have parents */
303
308
if (tbinfo -> relkind == RELKIND_SEQUENCE ||
@@ -314,132 +319,70 @@ flagInhAttrs(TableInfo *tblinfo, int numTables)
314
319
if (numParents == 0 )
315
320
continue ; /* nothing to see here, move along */
316
321
317
- /*----------------------------------------------------------------
318
- * For each attr, check the parent info: if no parent has an attr
319
- * with the same name, then it's not inherited. If there *is* an
320
- * attr with the same name, then only dump it if:
321
- *
322
- * - it is NOT NULL and zero parents are NOT NULL
323
- * OR
324
- * - it has a default value AND the default value does not match
325
- * all parent default values, or no parents specify a default.
326
- *
327
- * See discussion on -hackers around 2-Apr-2001.
328
- *----------------------------------------------------------------
329
- */
322
+ /* For each column, search for matching column names in parent(s) */
330
323
for (j = 0 ; j < tbinfo -> numatts ; j ++ )
331
324
{
332
- bool foundAttr ; /* Attr was found in a parent */
333
325
bool foundNotNull ; /* Attr was NOT NULL in a parent */
334
- bool defaultsMatch ; /* All non-empty defaults match */
335
- bool defaultsFound ; /* Found a default in a parent */
336
- AttrDefInfo * attrDef ;
337
-
338
- foundAttr = false;
339
- foundNotNull = false;
340
- defaultsMatch = true;
341
- defaultsFound = false;
326
+ bool foundDefault ; /* Found a default in a parent */
342
327
343
- attrDef = tbinfo -> attrdefs [j ];
328
+ /* no point in examining dropped columns */
329
+ if (tbinfo -> attisdropped [j ])
330
+ continue ;
344
331
332
+ foundNotNull = false;
333
+ foundDefault = false;
345
334
for (k = 0 ; k < numParents ; k ++ )
346
335
{
336
+ TableInfo * parent = parents [k ];
347
337
int inhAttrInd ;
348
338
349
- parent = parents [k ];
350
339
inhAttrInd = strInArray (tbinfo -> attnames [j ],
351
340
parent -> attnames ,
352
341
parent -> numatts );
353
-
354
- if (inhAttrInd != -1 )
342
+ if (inhAttrInd >= 0 )
355
343
{
356
- AttrDefInfo * inhDef = parent -> attrdefs [inhAttrInd ];
357
-
358
- foundAttr = true;
359
344
foundNotNull |= parent -> notnull [inhAttrInd ];
360
- if (inhDef != NULL )
361
- {
362
- defaultsFound = true;
363
-
364
- /*
365
- * If any parent has a default and the child doesn't,
366
- * we have to emit an explicit DEFAULT NULL clause for
367
- * the child, else the parent's default will win.
368
- */
369
- if (attrDef == NULL )
370
- {
371
- attrDef = (AttrDefInfo * ) pg_malloc (sizeof (AttrDefInfo ));
372
- attrDef -> dobj .objType = DO_ATTRDEF ;
373
- attrDef -> dobj .catId .tableoid = 0 ;
374
- attrDef -> dobj .catId .oid = 0 ;
375
- AssignDumpId (& attrDef -> dobj );
376
- attrDef -> adtable = tbinfo ;
377
- attrDef -> adnum = j + 1 ;
378
- attrDef -> adef_expr = pg_strdup ("NULL" );
379
-
380
- attrDef -> dobj .name = pg_strdup (tbinfo -> dobj .name );
381
- attrDef -> dobj .namespace = tbinfo -> dobj .namespace ;
382
-
383
- attrDef -> dobj .dump = tbinfo -> dobj .dump ;
384
-
385
- attrDef -> separate = false;
386
- addObjectDependency (& tbinfo -> dobj ,
387
- attrDef -> dobj .dumpId );
388
-
389
- tbinfo -> attrdefs [j ] = attrDef ;
390
- }
391
- if (strcmp (attrDef -> adef_expr , inhDef -> adef_expr ) != 0 )
392
- {
393
- defaultsMatch = false;
394
-
395
- /*
396
- * Whenever there is a non-matching parent
397
- * default, add a dependency to force the parent
398
- * default to be dumped first, in case the
399
- * defaults end up being dumped as separate
400
- * commands. Otherwise the parent default will
401
- * override the child's when it is applied.
402
- */
403
- addObjectDependency (& attrDef -> dobj ,
404
- inhDef -> dobj .dumpId );
405
- }
406
- }
345
+ foundDefault |= (parent -> attrdefs [inhAttrInd ] != NULL );
407
346
}
408
347
}
409
348
410
- /*
411
- * Based on the scan of the parents, decide if we can rely on the
412
- * inherited attr
413
- */
414
- if (foundAttr ) /* Attr was inherited */
349
+ /* Remember if we found inherited NOT NULL */
350
+ tbinfo -> inhNotNull [ j ] = foundNotNull ;
351
+
352
+ /* Manufacture a DEFAULT NULL clause if necessary */
353
+ if (foundDefault && tbinfo -> attrdefs [ j ] == NULL )
415
354
{
416
- /* Set inherited flag by default */
417
- tbinfo -> inhAttrs [j ] = true;
418
- tbinfo -> inhAttrDef [j ] = true;
419
- tbinfo -> inhNotNull [j ] = true;
420
-
421
- /*
422
- * Clear it if attr had a default, but parents did not, or
423
- * mismatch
424
- */
425
- if ((attrDef != NULL ) && (!defaultsFound || !defaultsMatch ))
355
+ AttrDefInfo * attrDef ;
356
+
357
+ attrDef = (AttrDefInfo * ) pg_malloc (sizeof (AttrDefInfo ));
358
+ attrDef -> dobj .objType = DO_ATTRDEF ;
359
+ attrDef -> dobj .catId .tableoid = 0 ;
360
+ attrDef -> dobj .catId .oid = 0 ;
361
+ AssignDumpId (& attrDef -> dobj );
362
+ attrDef -> dobj .name = pg_strdup (tbinfo -> dobj .name );
363
+ attrDef -> dobj .namespace = tbinfo -> dobj .namespace ;
364
+ attrDef -> dobj .dump = tbinfo -> dobj .dump ;
365
+
366
+ attrDef -> adtable = tbinfo ;
367
+ attrDef -> adnum = j + 1 ;
368
+ attrDef -> adef_expr = pg_strdup ("NULL" );
369
+
370
+ /* Will column be dumped explicitly? */
371
+ if (shouldPrintColumn (tbinfo , j ))
426
372
{
427
- tbinfo -> inhAttrs [ j ] = false;
428
- tbinfo -> inhAttrDef [ j ] = false;
373
+ attrDef -> separate = false;
374
+ /* No dependency needed: NULL cannot have dependencies */
429
375
}
430
-
431
- /*
432
- * Clear it if NOT NULL and none of the parents were NOT NULL
433
- */
434
- if (tbinfo -> notnull [j ] && !foundNotNull )
376
+ else
435
377
{
436
- tbinfo -> inhAttrs [j ] = false;
437
- tbinfo -> inhNotNull [j ] = false;
378
+ /* column will be suppressed, print default separately */
379
+ attrDef -> separate = true;
380
+ /* ensure it comes out after the table */
381
+ addObjectDependency (& attrDef -> dobj ,
382
+ tbinfo -> dobj .dumpId );
438
383
}
439
384
440
- /* Clear it if attr has local definition */
441
- if (tbinfo -> attislocal [j ])
442
- tbinfo -> inhAttrs [j ] = false;
385
+ tbinfo -> attrdefs [j ] = attrDef ;
443
386
}
444
387
}
445
388
}
0 commit comments