summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2002-07-15 16:33:32 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2002-07-15 16:33:32 +0000
commit7bd631bfa4740c20625ae1f16856707baeda466d (patch)
treee851f618c76895be9e78fc8458315a34c9c938a5 /src
parent3c580b8d979a94ea0e41578c7ac1d4625d242853 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/dependency.c192
-rw-r--r--src/backend/catalog/heap.c198
-rw-r--r--src/backend/catalog/indexing.c6
-rw-r--r--src/backend/commands/tablecmds.c77
-rw-r--r--src/include/catalog/catversion.h4
-rw-r--r--src/include/catalog/heap.h5
-rw-r--r--src/include/catalog/indexing.h10
-rw-r--r--src/include/catalog/pg_attrdef.h6
8 files changed, 307 insertions, 191 deletions
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index b7c431d3727..7622d035f7c 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 48f7cae1aa0..5c9499c86b5 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 9925c39af1e..9f16b4d4cc1 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 0d4d277bae4..3722a071082 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 9d3acbe35f5..5fd581b2548 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 44c8e13bf61..3148fd32633 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 d4ca744172b..91e35934470 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 7df4f324e05..3d39911d83f 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;