Skip to content

Commit 7bd631b

Browse files
committed
Use the dependency mechanism to manage column defaults. We need this
so that dependencies in default expressions (on operators, functions, etc) can be expressed properly.
1 parent 3c580b8 commit 7bd631b

File tree

8 files changed

+307
-191
lines changed

8 files changed

+307
-191
lines changed

src/backend/catalog/dependency.c

Lines changed: 126 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.1 2002/07/12 18:43:13 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.2 2002/07/15 16:33:31 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -21,6 +21,7 @@
2121
#include "catalog/heap.h"
2222
#include "catalog/index.h"
2323
#include "catalog/indexing.h"
24+
#include "catalog/pg_attrdef.h"
2425
#include "catalog/pg_constraint.h"
2526
#include "catalog/pg_depend.h"
2627
#include "catalog/pg_language.h"
@@ -46,6 +47,7 @@ typedef enum ObjectClasses
4647
OCLASS_PROC, /* pg_proc */
4748
OCLASS_TYPE, /* pg_type */
4849
OCLASS_CONSTRAINT, /* pg_constraint */
50+
OCLASS_DEFAULT, /* pg_attrdef */
4951
OCLASS_LANGUAGE, /* pg_language */
5052
OCLASS_OPERATOR, /* pg_operator */
5153
OCLASS_REWRITE, /* pg_rewrite */
@@ -59,6 +61,7 @@ static bool recursiveDeletion(const ObjectAddress *object,
5961
static void doDeletion(const ObjectAddress *object);
6062
static ObjectClasses getObjectClass(const ObjectAddress *object);
6163
static char *getObjectDescription(const ObjectAddress *object);
64+
static void getRelationDescription(StringInfo buffer, Oid relid);
6265

6366

6467
/*
@@ -285,7 +288,7 @@ recursiveDeletion(const ObjectAddress *object,
285288
* RESTRICT case. (However, normal dependencies on the
286289
* component object could still cause failure.)
287290
*/
288-
elog(DEBUG1, "Drop internally cascades to %s",
291+
elog(DEBUG1, "Drop auto-cascades to %s",
289292
getObjectDescription(&otherObject));
290293

291294
if (!recursiveDeletion(&otherObject, behavior,
@@ -392,6 +395,10 @@ doDeletion(const ObjectAddress *object)
392395
RemoveConstraintById(object->objectId);
393396
break;
394397

398+
case OCLASS_DEFAULT:
399+
RemoveAttrDefaultById(object->objectId);
400+
break;
401+
395402
case OCLASS_LANGUAGE:
396403
DropProceduralLanguageById(object->objectId);
397404
break;
@@ -425,6 +432,7 @@ getObjectClass(const ObjectAddress *object)
425432
{
426433
static bool reloids_initialized = false;
427434
static Oid reloid_pg_constraint;
435+
static Oid reloid_pg_attrdef;
428436
static Oid reloid_pg_language;
429437
static Oid reloid_pg_operator;
430438
static Oid reloid_pg_rewrite;
@@ -456,6 +464,7 @@ getObjectClass(const ObjectAddress *object)
456464
if (!reloids_initialized)
457465
{
458466
reloid_pg_constraint = get_system_catalog_relid(ConstraintRelationName);
467+
reloid_pg_attrdef = get_system_catalog_relid(AttrDefaultRelationName);
459468
reloid_pg_language = get_system_catalog_relid(LanguageRelationName);
460469
reloid_pg_operator = get_system_catalog_relid(OperatorRelationName);
461470
reloid_pg_rewrite = get_system_catalog_relid(RewriteRelationName);
@@ -468,6 +477,11 @@ getObjectClass(const ObjectAddress *object)
468477
Assert(object->objectSubId == 0);
469478
return OCLASS_CONSTRAINT;
470479
}
480+
if (object->classId == reloid_pg_attrdef)
481+
{
482+
Assert(object->objectSubId == 0);
483+
return OCLASS_DEFAULT;
484+
}
471485
if (object->classId == reloid_pg_language)
472486
{
473487
Assert(object->objectSubId == 0);
@@ -509,63 +523,12 @@ getObjectDescription(const ObjectAddress *object)
509523
switch (getObjectClass(object))
510524
{
511525
case OCLASS_CLASS:
512-
{
513-
HeapTuple relTup;
514-
Form_pg_class relForm;
515-
516-
relTup = SearchSysCache(RELOID,
517-
ObjectIdGetDatum(object->objectId),
518-
0, 0, 0);
519-
if (!HeapTupleIsValid(relTup))
520-
elog(ERROR, "getObjectDescription: Relation %u does not exist",
521-
object->objectId);
522-
relForm = (Form_pg_class) GETSTRUCT(relTup);
523-
524-
switch (relForm->relkind)
525-
{
526-
case RELKIND_RELATION:
527-
appendStringInfo(&buffer, "table %s",
528-
NameStr(relForm->relname));
529-
break;
530-
case RELKIND_INDEX:
531-
appendStringInfo(&buffer, "index %s",
532-
NameStr(relForm->relname));
533-
break;
534-
case RELKIND_SPECIAL:
535-
appendStringInfo(&buffer, "special system relation %s",
536-
NameStr(relForm->relname));
537-
break;
538-
case RELKIND_SEQUENCE:
539-
appendStringInfo(&buffer, "sequence %s",
540-
NameStr(relForm->relname));
541-
break;
542-
case RELKIND_UNCATALOGED:
543-
appendStringInfo(&buffer, "uncataloged table %s",
544-
NameStr(relForm->relname));
545-
break;
546-
case RELKIND_TOASTVALUE:
547-
appendStringInfo(&buffer, "toast table %s",
548-
NameStr(relForm->relname));
549-
break;
550-
case RELKIND_VIEW:
551-
appendStringInfo(&buffer, "view %s",
552-
NameStr(relForm->relname));
553-
break;
554-
default:
555-
/* shouldn't get here */
556-
appendStringInfo(&buffer, "relation %s",
557-
NameStr(relForm->relname));
558-
break;
559-
}
560-
526+
getRelationDescription(&buffer, object->objectId);
561527
if (object->objectSubId != 0)
562528
appendStringInfo(&buffer, " column %s",
563529
get_attname(object->objectId,
564530
object->objectSubId));
565-
566-
ReleaseSysCache(relTup);
567531
break;
568-
}
569532

570533
case OCLASS_PROC:
571534
/* XXX could improve on this */
@@ -614,17 +577,61 @@ getObjectDescription(const ObjectAddress *object)
614577

615578
con = (Form_pg_constraint) GETSTRUCT(tup);
616579

617-
appendStringInfo(&buffer, "constraint %s",
618-
NameStr(con->conname));
619580
if (OidIsValid(con->conrelid))
620-
appendStringInfo(&buffer, " on table %s",
621-
get_rel_name(con->conrelid));
581+
{
582+
appendStringInfo(&buffer, "constraint %s on ",
583+
NameStr(con->conname));
584+
getRelationDescription(&buffer, con->conrelid);
585+
}
586+
else
587+
{
588+
appendStringInfo(&buffer, "constraint %s",
589+
NameStr(con->conname));
590+
}
622591

623592
systable_endscan(rcscan);
624593
heap_close(conDesc, AccessShareLock);
625594
break;
626595
}
627596

597+
case OCLASS_DEFAULT:
598+
{
599+
Relation attrdefDesc;
600+
ScanKeyData skey[1];
601+
SysScanDesc adscan;
602+
HeapTuple tup;
603+
Form_pg_attrdef attrdef;
604+
ObjectAddress colobject;
605+
606+
attrdefDesc = heap_openr(AttrDefaultRelationName, AccessShareLock);
607+
608+
ScanKeyEntryInitialize(&skey[0], 0x0,
609+
ObjectIdAttributeNumber, F_OIDEQ,
610+
ObjectIdGetDatum(object->objectId));
611+
612+
adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndex, true,
613+
SnapshotNow, 1, skey);
614+
615+
tup = systable_getnext(adscan);
616+
617+
if (!HeapTupleIsValid(tup))
618+
elog(ERROR, "getObjectDescription: Default %u does not exist",
619+
object->objectId);
620+
621+
attrdef = (Form_pg_attrdef) GETSTRUCT(tup);
622+
623+
colobject.classId = RelOid_pg_class;
624+
colobject.objectId = attrdef->adrelid;
625+
colobject.objectSubId = attrdef->adnum;
626+
627+
appendStringInfo(&buffer, "default for %s",
628+
getObjectDescription(&colobject));
629+
630+
systable_endscan(adscan);
631+
heap_close(attrdefDesc, AccessShareLock);
632+
break;
633+
}
634+
628635
case OCLASS_LANGUAGE:
629636
{
630637
HeapTuple langTup;
@@ -672,11 +679,9 @@ getObjectDescription(const ObjectAddress *object)
672679

673680
rule = (Form_pg_rewrite) GETSTRUCT(tup);
674681

675-
appendStringInfo(&buffer, "rule %s",
682+
appendStringInfo(&buffer, "rule %s on ",
676683
NameStr(rule->rulename));
677-
if (OidIsValid(rule->ev_class))
678-
appendStringInfo(&buffer, " on table %s",
679-
get_rel_name(rule->ev_class));
684+
getRelationDescription(&buffer, rule->ev_class);
680685

681686
systable_endscan(rcscan);
682687
heap_close(ruleDesc, AccessShareLock);
@@ -708,11 +713,9 @@ getObjectDescription(const ObjectAddress *object)
708713

709714
trig = (Form_pg_trigger) GETSTRUCT(tup);
710715

711-
appendStringInfo(&buffer, "trigger %s",
716+
appendStringInfo(&buffer, "trigger %s on ",
712717
NameStr(trig->tgname));
713-
if (OidIsValid(trig->tgrelid))
714-
appendStringInfo(&buffer, " on table %s",
715-
get_rel_name(trig->tgrelid));
718+
getRelationDescription(&buffer, trig->tgrelid);
716719

717720
systable_endscan(tgscan);
718721
heap_close(trigDesc, AccessShareLock);
@@ -729,3 +732,60 @@ getObjectDescription(const ObjectAddress *object)
729732

730733
return buffer.data;
731734
}
735+
736+
/*
737+
* subroutine for getObjectDescription: describe a relation
738+
*/
739+
static void
740+
getRelationDescription(StringInfo buffer, Oid relid)
741+
{
742+
HeapTuple relTup;
743+
Form_pg_class relForm;
744+
745+
relTup = SearchSysCache(RELOID,
746+
ObjectIdGetDatum(relid),
747+
0, 0, 0);
748+
if (!HeapTupleIsValid(relTup))
749+
elog(ERROR, "getObjectDescription: Relation %u does not exist",
750+
relid);
751+
relForm = (Form_pg_class) GETSTRUCT(relTup);
752+
753+
switch (relForm->relkind)
754+
{
755+
case RELKIND_RELATION:
756+
appendStringInfo(buffer, "table %s",
757+
NameStr(relForm->relname));
758+
break;
759+
case RELKIND_INDEX:
760+
appendStringInfo(buffer, "index %s",
761+
NameStr(relForm->relname));
762+
break;
763+
case RELKIND_SPECIAL:
764+
appendStringInfo(buffer, "special system relation %s",
765+
NameStr(relForm->relname));
766+
break;
767+
case RELKIND_SEQUENCE:
768+
appendStringInfo(buffer, "sequence %s",
769+
NameStr(relForm->relname));
770+
break;
771+
case RELKIND_UNCATALOGED:
772+
appendStringInfo(buffer, "uncataloged table %s",
773+
NameStr(relForm->relname));
774+
break;
775+
case RELKIND_TOASTVALUE:
776+
appendStringInfo(buffer, "toast table %s",
777+
NameStr(relForm->relname));
778+
break;
779+
case RELKIND_VIEW:
780+
appendStringInfo(buffer, "view %s",
781+
NameStr(relForm->relname));
782+
break;
783+
default:
784+
/* shouldn't get here */
785+
appendStringInfo(buffer, "relation %s",
786+
NameStr(relForm->relname));
787+
break;
788+
}
789+
790+
ReleaseSysCache(relTup);
791+
}

0 commit comments

Comments
 (0)