diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index b7c431d3727232c4cbff26be43f98efec0f1e606..7622d035f7c177bc6f46d45dada2147f5dc06005 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.1 2002/07/12 18:43:13 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.2 2002/07/15 16:33:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -21,6 +21,7 @@ #include "catalog/heap.h" #include "catalog/index.h" #include "catalog/indexing.h" +#include "catalog/pg_attrdef.h" #include "catalog/pg_constraint.h" #include "catalog/pg_depend.h" #include "catalog/pg_language.h" @@ -46,6 +47,7 @@ typedef enum ObjectClasses OCLASS_PROC, /* pg_proc */ OCLASS_TYPE, /* pg_type */ OCLASS_CONSTRAINT, /* pg_constraint */ + OCLASS_DEFAULT, /* pg_attrdef */ OCLASS_LANGUAGE, /* pg_language */ OCLASS_OPERATOR, /* pg_operator */ OCLASS_REWRITE, /* pg_rewrite */ @@ -59,6 +61,7 @@ static bool recursiveDeletion(const ObjectAddress *object, static void doDeletion(const ObjectAddress *object); static ObjectClasses getObjectClass(const ObjectAddress *object); static char *getObjectDescription(const ObjectAddress *object); +static void getRelationDescription(StringInfo buffer, Oid relid); /* @@ -285,7 +288,7 @@ recursiveDeletion(const ObjectAddress *object, * RESTRICT case. (However, normal dependencies on the * component object could still cause failure.) */ - elog(DEBUG1, "Drop internally cascades to %s", + elog(DEBUG1, "Drop auto-cascades to %s", getObjectDescription(&otherObject)); if (!recursiveDeletion(&otherObject, behavior, @@ -392,6 +395,10 @@ doDeletion(const ObjectAddress *object) RemoveConstraintById(object->objectId); break; + case OCLASS_DEFAULT: + RemoveAttrDefaultById(object->objectId); + break; + case OCLASS_LANGUAGE: DropProceduralLanguageById(object->objectId); break; @@ -425,6 +432,7 @@ getObjectClass(const ObjectAddress *object) { static bool reloids_initialized = false; static Oid reloid_pg_constraint; + static Oid reloid_pg_attrdef; static Oid reloid_pg_language; static Oid reloid_pg_operator; static Oid reloid_pg_rewrite; @@ -456,6 +464,7 @@ getObjectClass(const ObjectAddress *object) if (!reloids_initialized) { reloid_pg_constraint = get_system_catalog_relid(ConstraintRelationName); + reloid_pg_attrdef = get_system_catalog_relid(AttrDefaultRelationName); reloid_pg_language = get_system_catalog_relid(LanguageRelationName); reloid_pg_operator = get_system_catalog_relid(OperatorRelationName); reloid_pg_rewrite = get_system_catalog_relid(RewriteRelationName); @@ -468,6 +477,11 @@ getObjectClass(const ObjectAddress *object) Assert(object->objectSubId == 0); return OCLASS_CONSTRAINT; } + if (object->classId == reloid_pg_attrdef) + { + Assert(object->objectSubId == 0); + return OCLASS_DEFAULT; + } if (object->classId == reloid_pg_language) { Assert(object->objectSubId == 0); @@ -509,63 +523,12 @@ getObjectDescription(const ObjectAddress *object) switch (getObjectClass(object)) { case OCLASS_CLASS: - { - HeapTuple relTup; - Form_pg_class relForm; - - relTup = SearchSysCache(RELOID, - ObjectIdGetDatum(object->objectId), - 0, 0, 0); - if (!HeapTupleIsValid(relTup)) - elog(ERROR, "getObjectDescription: Relation %u does not exist", - object->objectId); - relForm = (Form_pg_class) GETSTRUCT(relTup); - - switch (relForm->relkind) - { - case RELKIND_RELATION: - appendStringInfo(&buffer, "table %s", - NameStr(relForm->relname)); - break; - case RELKIND_INDEX: - appendStringInfo(&buffer, "index %s", - NameStr(relForm->relname)); - break; - case RELKIND_SPECIAL: - appendStringInfo(&buffer, "special system relation %s", - NameStr(relForm->relname)); - break; - case RELKIND_SEQUENCE: - appendStringInfo(&buffer, "sequence %s", - NameStr(relForm->relname)); - break; - case RELKIND_UNCATALOGED: - appendStringInfo(&buffer, "uncataloged table %s", - NameStr(relForm->relname)); - break; - case RELKIND_TOASTVALUE: - appendStringInfo(&buffer, "toast table %s", - NameStr(relForm->relname)); - break; - case RELKIND_VIEW: - appendStringInfo(&buffer, "view %s", - NameStr(relForm->relname)); - break; - default: - /* shouldn't get here */ - appendStringInfo(&buffer, "relation %s", - NameStr(relForm->relname)); - break; - } - + getRelationDescription(&buffer, object->objectId); if (object->objectSubId != 0) appendStringInfo(&buffer, " column %s", get_attname(object->objectId, object->objectSubId)); - - ReleaseSysCache(relTup); break; - } case OCLASS_PROC: /* XXX could improve on this */ @@ -614,17 +577,61 @@ getObjectDescription(const ObjectAddress *object) con = (Form_pg_constraint) GETSTRUCT(tup); - appendStringInfo(&buffer, "constraint %s", - NameStr(con->conname)); if (OidIsValid(con->conrelid)) - appendStringInfo(&buffer, " on table %s", - get_rel_name(con->conrelid)); + { + appendStringInfo(&buffer, "constraint %s on ", + NameStr(con->conname)); + getRelationDescription(&buffer, con->conrelid); + } + else + { + appendStringInfo(&buffer, "constraint %s", + NameStr(con->conname)); + } systable_endscan(rcscan); heap_close(conDesc, AccessShareLock); break; } + case OCLASS_DEFAULT: + { + Relation attrdefDesc; + ScanKeyData skey[1]; + SysScanDesc adscan; + HeapTuple tup; + Form_pg_attrdef attrdef; + ObjectAddress colobject; + + attrdefDesc = heap_openr(AttrDefaultRelationName, AccessShareLock); + + ScanKeyEntryInitialize(&skey[0], 0x0, + ObjectIdAttributeNumber, F_OIDEQ, + ObjectIdGetDatum(object->objectId)); + + adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndex, true, + SnapshotNow, 1, skey); + + tup = systable_getnext(adscan); + + if (!HeapTupleIsValid(tup)) + elog(ERROR, "getObjectDescription: Default %u does not exist", + object->objectId); + + attrdef = (Form_pg_attrdef) GETSTRUCT(tup); + + colobject.classId = RelOid_pg_class; + colobject.objectId = attrdef->adrelid; + colobject.objectSubId = attrdef->adnum; + + appendStringInfo(&buffer, "default for %s", + getObjectDescription(&colobject)); + + systable_endscan(adscan); + heap_close(attrdefDesc, AccessShareLock); + break; + } + case OCLASS_LANGUAGE: { HeapTuple langTup; @@ -672,11 +679,9 @@ getObjectDescription(const ObjectAddress *object) rule = (Form_pg_rewrite) GETSTRUCT(tup); - appendStringInfo(&buffer, "rule %s", + appendStringInfo(&buffer, "rule %s on ", NameStr(rule->rulename)); - if (OidIsValid(rule->ev_class)) - appendStringInfo(&buffer, " on table %s", - get_rel_name(rule->ev_class)); + getRelationDescription(&buffer, rule->ev_class); systable_endscan(rcscan); heap_close(ruleDesc, AccessShareLock); @@ -708,11 +713,9 @@ getObjectDescription(const ObjectAddress *object) trig = (Form_pg_trigger) GETSTRUCT(tup); - appendStringInfo(&buffer, "trigger %s", + appendStringInfo(&buffer, "trigger %s on ", NameStr(trig->tgname)); - if (OidIsValid(trig->tgrelid)) - appendStringInfo(&buffer, " on table %s", - get_rel_name(trig->tgrelid)); + getRelationDescription(&buffer, trig->tgrelid); systable_endscan(tgscan); heap_close(trigDesc, AccessShareLock); @@ -729,3 +732,60 @@ getObjectDescription(const ObjectAddress *object) return buffer.data; } + +/* + * subroutine for getObjectDescription: describe a relation + */ +static void +getRelationDescription(StringInfo buffer, Oid relid) +{ + HeapTuple relTup; + Form_pg_class relForm; + + relTup = SearchSysCache(RELOID, + ObjectIdGetDatum(relid), + 0, 0, 0); + if (!HeapTupleIsValid(relTup)) + elog(ERROR, "getObjectDescription: Relation %u does not exist", + relid); + relForm = (Form_pg_class) GETSTRUCT(relTup); + + switch (relForm->relkind) + { + case RELKIND_RELATION: + appendStringInfo(buffer, "table %s", + NameStr(relForm->relname)); + break; + case RELKIND_INDEX: + appendStringInfo(buffer, "index %s", + NameStr(relForm->relname)); + break; + case RELKIND_SPECIAL: + appendStringInfo(buffer, "special system relation %s", + NameStr(relForm->relname)); + break; + case RELKIND_SEQUENCE: + appendStringInfo(buffer, "sequence %s", + NameStr(relForm->relname)); + break; + case RELKIND_UNCATALOGED: + appendStringInfo(buffer, "uncataloged table %s", + NameStr(relForm->relname)); + break; + case RELKIND_TOASTVALUE: + appendStringInfo(buffer, "toast table %s", + NameStr(relForm->relname)); + break; + case RELKIND_VIEW: + appendStringInfo(buffer, "view %s", + NameStr(relForm->relname)); + break; + default: + /* shouldn't get here */ + appendStringInfo(buffer, "relation %s", + NameStr(relForm->relname)); + break; + } + + ReleaseSysCache(relTup); +} diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 48f7cae1aa0e4a87f30be1179c6750cb55e843fb..5c9499c86b5b51cbeb89945f8c9c56951e122f54 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.206 2002/07/14 21:08:08 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.207 2002/07/15 16:33:31 tgl Exp $ * * * INTERFACE ROUTINES @@ -75,7 +75,6 @@ static void StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin); static void StoreRelCheck(Relation rel, char *ccname, char *ccbin); static void StoreConstraints(Relation rel, TupleDesc tupdesc); static void SetRelationNumChecks(Relation rel, int numchecks); -static void RemoveDefaults(Relation rel); static void RemoveStatistics(Relation rel); @@ -767,18 +766,18 @@ static void RelationRemoveInheritance(Relation relation) { Relation catalogRelation; - HeapTuple tuple; SysScanDesc scan; - ScanKeyData entry; + ScanKeyData key; + HeapTuple tuple; catalogRelation = heap_openr(InheritsRelationName, RowExclusiveLock); - ScanKeyEntryInitialize(&entry, 0x0, + ScanKeyEntryInitialize(&key, 0x0, Anum_pg_inherits_inhrelid, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(relation))); scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndex, true, - SnapshotNow, 1, &entry); + SnapshotNow, 1, &key); while (HeapTupleIsValid(tuple = systable_getnext(scan))) { @@ -859,6 +858,125 @@ DeleteAttributeTuples(Oid relid) heap_close(attrel, RowExclusiveLock); } +/* + * RemoveAttrDefault + * + * If the specified relation/attribute has a default, remove it. + * (If no default, raise error if complain is true, else return quietly.) + */ +void +RemoveAttrDefault(Oid relid, AttrNumber attnum, + DropBehavior behavior, bool complain) +{ + Relation attrdef_rel; + ScanKeyData scankeys[2]; + SysScanDesc scan; + HeapTuple tuple; + bool found = false; + + attrdef_rel = heap_openr(AttrDefaultRelationName, RowExclusiveLock); + + ScanKeyEntryInitialize(&scankeys[0], 0x0, + Anum_pg_attrdef_adrelid, F_OIDEQ, + ObjectIdGetDatum(relid)); + ScanKeyEntryInitialize(&scankeys[1], 0x0, + Anum_pg_attrdef_adnum, F_INT2EQ, + Int16GetDatum(attnum)); + + scan = systable_beginscan(attrdef_rel, AttrDefaultIndex, true, + SnapshotNow, 2, scankeys); + + /* There should be at most one matching tuple, but we loop anyway */ + while (HeapTupleIsValid(tuple = systable_getnext(scan))) + { + ObjectAddress object; + + object.classId = RelationGetRelid(attrdef_rel); + object.objectId = tuple->t_data->t_oid; + object.objectSubId = 0; + + performDeletion(&object, behavior); + + found = true; + } + + systable_endscan(scan); + heap_close(attrdef_rel, RowExclusiveLock); + + if (complain && !found) + elog(ERROR, "RemoveAttrDefault: no default found for rel %u attnum %d", + relid, attnum); +} + +/* + * RemoveAttrDefaultById + * + * Remove a pg_attrdef entry specified by OID. This is the guts of + * attribute-default removal. Note it should be called via performDeletion, + * not directly. + */ +void +RemoveAttrDefaultById(Oid attrdefId) +{ + Relation attrdef_rel; + Relation attr_rel; + ScanKeyData scankeys[1]; + SysScanDesc scan; + HeapTuple tuple; + Oid myrelid; + AttrNumber myattnum; + + /* Grab an appropriate lock on the pg_attrdef relation */ + attrdef_rel = heap_openr(AttrDefaultRelationName, RowExclusiveLock); + + ScanKeyEntryInitialize(&scankeys[0], 0x0, + ObjectIdAttributeNumber, F_OIDEQ, + ObjectIdGetDatum(attrdefId)); + + scan = systable_beginscan(attrdef_rel, AttrDefaultOidIndex, true, + SnapshotNow, 1, scankeys); + + tuple = systable_getnext(scan); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "RemoveAttrDefaultById: cache lookup failed for attrdef %u", + attrdefId); + + myrelid = ((Form_pg_attrdef) GETSTRUCT(tuple))->adrelid; + myattnum = ((Form_pg_attrdef) GETSTRUCT(tuple))->adnum; + + simple_heap_delete(attrdef_rel, &tuple->t_self); + + systable_endscan(scan); + heap_close(attrdef_rel, RowExclusiveLock); + + /* Fix the pg_attribute row */ + attr_rel = heap_openr(AttributeRelationName, RowExclusiveLock); + + tuple = SearchSysCacheCopy(ATTNUM, + ObjectIdGetDatum(myrelid), + Int16GetDatum(myattnum), + 0, 0); + if (!HeapTupleIsValid(tuple)) /* shouldn't happen */ + elog(ERROR, "RemoveAttrDefaultById: cache lookup failed for rel %u attr %d", + myrelid, myattnum); + + ((Form_pg_attribute) GETSTRUCT(tuple))->atthasdef = false; + + simple_heap_update(attr_rel, &tuple->t_self, tuple); + + /* keep the system catalog indices current */ + if (RelationGetForm(attr_rel)->relhasindex) + { + Relation idescs[Num_pg_attr_indices]; + + CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs); + CatalogIndexInsert(idescs, Num_pg_attr_indices, attr_rel, tuple); + CatalogCloseIndices(Num_pg_attr_indices, idescs); + } + + heap_close(attr_rel, RowExclusiveLock); +} + /* ---------------------------------------------------------------- * heap_drop_with_catalog - removes specified relation from catalogs * @@ -866,7 +984,7 @@ DeleteAttributeTuples(Oid relid) * 2) flush relation buffers from bufmgr * 3) remove inheritance information * 4) remove pg_statistic tuples - * 5) remove pg_attribute tuples and related items + * 5) remove pg_attribute tuples * 6) remove pg_class tuple * 7) unlink relation file * @@ -908,12 +1026,10 @@ heap_drop_with_catalog(Oid rid) RemoveStatistics(rel); /* - * delete attribute tuples and associated defaults + * delete attribute tuples */ DeleteAttributeTuples(RelationGetRelid(rel)); - RemoveDefaults(rel); - /* * delete relation tuple */ @@ -957,6 +1073,9 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin) Relation attridescs[Num_pg_attr_indices]; HeapTuple atttup; Form_pg_attribute attStruct; + Oid attrdefOid; + ObjectAddress colobject, + defobject; /* * Need to construct source equivalent of given node-string. @@ -971,21 +1090,33 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin) RelationGetRelid(rel)), false); + /* + * Make the pg_attrdef entry. + */ values[Anum_pg_attrdef_adrelid - 1] = RelationGetRelid(rel); values[Anum_pg_attrdef_adnum - 1] = attnum; values[Anum_pg_attrdef_adbin - 1] = DirectFunctionCall1(textin, CStringGetDatum(adbin)); values[Anum_pg_attrdef_adsrc - 1] = DirectFunctionCall1(textin, CStringGetDatum(adsrc)); + adrel = heap_openr(AttrDefaultRelationName, RowExclusiveLock); + tuple = heap_formtuple(adrel->rd_att, values, nulls); - simple_heap_insert(adrel, tuple); + attrdefOid = simple_heap_insert(adrel, tuple); + CatalogOpenIndices(Num_pg_attrdef_indices, Name_pg_attrdef_indices, idescs); CatalogIndexInsert(idescs, Num_pg_attrdef_indices, adrel, tuple); CatalogCloseIndices(Num_pg_attrdef_indices, idescs); + + defobject.classId = RelationGetRelid(adrel); + defobject.objectId = attrdefOid; + defobject.objectSubId = 0; + heap_close(adrel, RowExclusiveLock); + /* now can free some of the stuff allocated above */ pfree(DatumGetPointer(values[Anum_pg_attrdef_adbin - 1])); pfree(DatumGetPointer(values[Anum_pg_attrdef_adsrc - 1])); heap_freetuple(tuple); @@ -1016,6 +1147,16 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin) } heap_close(attrrel, RowExclusiveLock); heap_freetuple(atttup); + + /* + * Make a dependency so that the pg_attrdef entry goes away if the + * column (or whole table) is deleted. + */ + colobject.classId = RelOid_pg_class; + colobject.objectId = RelationGetRelid(rel); + colobject.objectSubId = attnum; + + recordDependencyOn(&defobject, &colobject, DEPENDENCY_AUTO); } /* @@ -1497,29 +1638,6 @@ cookDefault(ParseState *pstate, } -static void -RemoveAttrDefaults(Relation rel) -{ - Relation adrel; - HeapScanDesc adscan; - ScanKeyData key; - HeapTuple tup; - - adrel = heap_openr(AttrDefaultRelationName, RowExclusiveLock); - - ScanKeyEntryInitialize(&key, 0, Anum_pg_attrdef_adrelid, - F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(rel))); - - adscan = heap_beginscan(adrel, SnapshotNow, 1, &key); - - while ((tup = heap_getnext(adscan, ForwardScanDirection)) != NULL) - simple_heap_delete(adrel, &tup->t_self); - - heap_endscan(adscan); - heap_close(adrel, RowExclusiveLock); -} - /* * Removes all constraints on a relation that match the given name. * @@ -1577,18 +1695,6 @@ RemoveRelConstraints(Relation rel, const char *constrName, return ndeleted; } -static void -RemoveDefaults(Relation rel) -{ - TupleConstr *constr = rel->rd_att->constr; - - /* - * We can skip looking at pg_attrdef if there are no defaults recorded - * in the Relation. - */ - if (constr && constr->num_defval > 0) - RemoveAttrDefaults(rel); -} static void RemoveStatistics(Relation rel) diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c index 9925c39af1e1cac39d7b31d3c4d2e88763129f45..9f16b4d4cc18ea3cd89a2ddb94509c6a0776436d 100644 --- a/src/backend/catalog/indexing.c +++ b/src/backend/catalog/indexing.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.96 2002/07/12 18:43:14 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.97 2002/07/15 16:33:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -42,13 +42,13 @@ char *Name_pg_amproc_indices[Num_pg_amproc_indices] = char *Name_pg_attr_indices[Num_pg_attr_indices] = {AttributeRelidNameIndex, AttributeRelidNumIndex}; char *Name_pg_attrdef_indices[Num_pg_attrdef_indices] = -{AttrDefaultIndex}; +{AttrDefaultIndex, AttrDefaultOidIndex}; char *Name_pg_class_indices[Num_pg_class_indices] = {ClassNameNspIndex, ClassOidIndex}; char *Name_pg_constraint_indices[Num_pg_constraint_indices] = {ConstraintNameNspIndex, ConstraintOidIndex, ConstraintRelidIndex}; char *Name_pg_conversion_indices[Num_pg_conversion_indices] = -{ConversionNameNspIndex, ConversionDefaultIndex}; +{ConversionDefaultIndex, ConversionNameNspIndex, ConversionOidIndex}; char *Name_pg_database_indices[Num_pg_database_indices] = {DatabaseNameIndex, DatabaseOidIndex}; char *Name_pg_depend_indices[Num_pg_depend_indices] = diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 0d4d277bae4e6faa10102e912018314b6853d4e1..3722a071082acb6f3975c81e8b7d63f38bf89213 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.20 2002/07/12 18:43:16 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.21 2002/07/15 16:33:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -23,7 +23,6 @@ #include "catalog/index.h" #include "catalog/indexing.h" #include "catalog/namespace.h" -#include "catalog/pg_attrdef.h" #include "catalog/pg_constraint.h" #include "catalog/pg_inherits.h" #include "catalog/pg_namespace.h" @@ -57,7 +56,6 @@ static bool change_varattnos_of_a_node(Node *node, const AttrNumber *newattno); static void StoreCatalogInheritance(Oid relationId, List *supers); static int findAttrByName(const char *attributeName, List *schema); static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass); -static void drop_default(Oid relid, int16 attnum); static void CheckTupleType(Form_pg_class tuple_class); static bool needs_toast_table(Relation rel); static void validateForeignKeyConstraint(FkConstraint *fkconstraint, @@ -2080,14 +2078,18 @@ AlterTableAlterColumnDefault(Oid myrelid, attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum; ReleaseSysCache(tuple); + /* + * Remove any old default for the column. We use RESTRICT here for + * safety, but at present we do not expect anything to depend on the + * default. + */ + RemoveAttrDefault(myrelid, attnum, DROP_RESTRICT, false); + if (newDefault) { /* SET DEFAULT */ RawColumnDefault *rawEnt; - /* Get rid of the old one first */ - drop_default(myrelid, attnum); - rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault)); rawEnt->attnum = attnum; rawEnt->raw_default = newDefault; @@ -2098,73 +2100,10 @@ AlterTableAlterColumnDefault(Oid myrelid, */ AddRelationRawConstraints(rel, makeList1(rawEnt), NIL); } - else - { - /* DROP DEFAULT */ - Relation attr_rel; - - /* Fix the pg_attribute row */ - attr_rel = heap_openr(AttributeRelationName, RowExclusiveLock); - - tuple = SearchSysCacheCopy(ATTNAME, - ObjectIdGetDatum(myrelid), - PointerGetDatum(colName), - 0, 0); - if (!HeapTupleIsValid(tuple)) /* shouldn't happen */ - elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"", - RelationGetRelationName(rel), colName); - - ((Form_pg_attribute) GETSTRUCT(tuple))->atthasdef = FALSE; - - simple_heap_update(attr_rel, &tuple->t_self, tuple); - - /* keep the system catalog indices current */ - if (RelationGetForm(attr_rel)->relhasindex) - { - Relation idescs[Num_pg_attr_indices]; - - CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs); - CatalogIndexInsert(idescs, Num_pg_attr_indices, attr_rel, tuple); - CatalogCloseIndices(Num_pg_attr_indices, idescs); - } - - heap_close(attr_rel, RowExclusiveLock); - - /* get rid of actual default definition in pg_attrdef */ - drop_default(myrelid, attnum); - } heap_close(rel, NoLock); } - -static void -drop_default(Oid relid, int16 attnum) -{ - ScanKeyData scankeys[2]; - HeapScanDesc scan; - Relation attrdef_rel; - HeapTuple tuple; - - attrdef_rel = heap_openr(AttrDefaultRelationName, RowExclusiveLock); - ScanKeyEntryInitialize(&scankeys[0], 0x0, - Anum_pg_attrdef_adrelid, F_OIDEQ, - ObjectIdGetDatum(relid)); - ScanKeyEntryInitialize(&scankeys[1], 0x0, - Anum_pg_attrdef_adnum, F_INT2EQ, - Int16GetDatum(attnum)); - - scan = heap_beginscan(attrdef_rel, SnapshotNow, 2, scankeys); - - if ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) - simple_heap_delete(attrdef_rel, &tuple->t_self); - - heap_endscan(scan); - - heap_close(attrdef_rel, NoLock); -} - - /* * ALTER TABLE ALTER COLUMN SET STATISTICS / STORAGE */ diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 9d3acbe35f558ebbf77884997d6af9c5fb69a9e5..5fd581b254870a82320ff205d5b0944d2e526674 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: catversion.h,v 1.139 2002/07/12 18:43:19 tgl Exp $ + * $Id: catversion.h,v 1.140 2002/07/15 16:33:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200207112 +#define CATALOG_VERSION_NO 200207141 #endif diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index 44c8e13bf61721aef89ca1a02f1b7eaaa5d3ec0e..3148fd32633c3d3fe7adde956660e161e09e542a 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: heap.h,v 1.53 2002/07/14 21:08:08 tgl Exp $ + * $Id: heap.h,v 1.54 2002/07/15 16:33:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -63,6 +63,9 @@ extern int RemoveRelConstraints(Relation rel, const char *constrName, extern void DeleteRelationTuple(Oid relid); extern void DeleteAttributeTuples(Oid relid); +extern void RemoveAttrDefault(Oid relid, AttrNumber attnum, + DropBehavior behavior, bool complain); +extern void RemoveAttrDefaultById(Oid attrdefId); extern Form_pg_attribute SystemAttributeDefinition(AttrNumber attno, bool relhasoids); diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index d4ca744172b621279ac10331b7ffa37008db20b6..91e35934470387e668f8cf8d4d409db5dee0f367 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: indexing.h,v 1.69 2002/07/12 18:43:19 tgl Exp $ + * $Id: indexing.h,v 1.70 2002/07/15 16:33:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -25,10 +25,10 @@ #define Num_pg_amop_indices 2 #define Num_pg_amproc_indices 1 #define Num_pg_attr_indices 2 -#define Num_pg_attrdef_indices 1 +#define Num_pg_attrdef_indices 2 #define Num_pg_class_indices 2 #define Num_pg_constraint_indices 3 -#define Num_pg_conversion_indices 2 +#define Num_pg_conversion_indices 3 #define Num_pg_database_indices 2 #define Num_pg_depend_indices 2 #define Num_pg_description_indices 1 @@ -57,6 +57,7 @@ #define AmNameIndex "pg_am_name_index" #define AmOidIndex "pg_am_oid_index" #define AttrDefaultIndex "pg_attrdef_adrelid_adnum_index" +#define AttrDefaultOidIndex "pg_attrdef_oid_index" #define AttributeRelidNameIndex "pg_attribute_relid_attnam_index" #define AttributeRelidNumIndex "pg_attribute_relid_attnum_index" #define ClassNameNspIndex "pg_class_relname_nsp_index" @@ -66,6 +67,7 @@ #define ConstraintRelidIndex "pg_constraint_conrelid_index" #define ConversionDefaultIndex "pg_conversion_default_index" #define ConversionNameNspIndex "pg_conversion_name_nsp_index" +#define ConversionOidIndex "pg_conversion_oid_index" #define DatabaseNameIndex "pg_database_datname_index" #define DatabaseOidIndex "pg_database_oid_index" #define DependDependerIndex "pg_depend_depender_index" @@ -161,6 +163,7 @@ DECLARE_UNIQUE_INDEX(pg_amop_opc_opr_index on pg_amop using btree(amopclaid oid_ DECLARE_UNIQUE_INDEX(pg_amop_opc_strategy_index on pg_amop using btree(amopclaid oid_ops, amopstrategy int2_ops)); DECLARE_UNIQUE_INDEX(pg_amproc_opc_procnum_index on pg_amproc using btree(amopclaid oid_ops, amprocnum int2_ops)); DECLARE_UNIQUE_INDEX(pg_attrdef_adrelid_adnum_index on pg_attrdef using btree(adrelid oid_ops, adnum int2_ops)); +DECLARE_UNIQUE_INDEX(pg_attrdef_oid_index on pg_attrdef using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index on pg_attribute using btree(attrelid oid_ops, attname name_ops)); DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnum_index on pg_attribute using btree(attrelid oid_ops, attnum int2_ops)); DECLARE_UNIQUE_INDEX(pg_class_oid_index on pg_class using btree(oid oid_ops)); @@ -173,6 +176,7 @@ DECLARE_UNIQUE_INDEX(pg_constraint_oid_index on pg_constraint using btree(oid oi /* This following index is not used for a cache and is not unique */ DECLARE_INDEX(pg_conversion_default_index on pg_conversion using btree(connamespace oid_ops, conforencoding int4_ops, contoencoding int4_ops)); DECLARE_UNIQUE_INDEX(pg_conversion_name_nsp_index on pg_conversion using btree(conname name_ops, connamespace oid_ops)); +DECLARE_UNIQUE_INDEX(pg_conversion_oid_index on pg_conversion using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_database_datname_index on pg_database using btree(datname name_ops)); DECLARE_UNIQUE_INDEX(pg_database_oid_index on pg_database using btree(oid oid_ops)); /* This following index is not used for a cache and is not unique */ diff --git a/src/include/catalog/pg_attrdef.h b/src/include/catalog/pg_attrdef.h index 7df4f324e050f7a6c7a8429e13a06beb167f1e9a..3d39911d83f504dbc1773edbfcef571becb5ece3 100644 --- a/src/include/catalog/pg_attrdef.h +++ b/src/include/catalog/pg_attrdef.h @@ -1,11 +1,15 @@ /*------------------------------------------------------------------------- * * pg_attrdef.h + * definition of the system "attribute defaults" relation (pg_attrdef) + * along with the relation's initial contents. * * * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * + * $Id: pg_attrdef.h,v 1.13 2002/07/15 16:33:32 tgl Exp $ + * * NOTES * the genbki.sh script reads this file and generates .bki * information from the DATA() statements. @@ -27,7 +31,7 @@ * typedef struct FormData_pg_attrdef * ---------------- */ -CATALOG(pg_attrdef) BKI_WITHOUT_OIDS +CATALOG(pg_attrdef) { Oid adrelid; int2 adnum;