aboutsummaryrefslogtreecommitdiff
path: root/src/backend/catalog/heap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/catalog/heap.c')
-rw-r--r--src/backend/catalog/heap.c88
1 files changed, 80 insertions, 8 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 6045c17bb6a..ec9165c55b1 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.214 2002/07/31 17:19:51 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.215 2002/08/02 18:15:05 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -97,37 +97,37 @@ static void RemoveStatistics(Relation rel);
static FormData_pg_attribute a1 = {
0, {"ctid"}, TIDOID, 0, sizeof(ItemPointerData),
SelfItemPointerAttributeNumber, 0, -1, -1,
- false, 'p', false, 'i', true, false
+ false, 'p', false, 'i', true, false, false
};
static FormData_pg_attribute a2 = {
0, {"oid"}, OIDOID, 0, sizeof(Oid),
ObjectIdAttributeNumber, 0, -1, -1,
- true, 'p', false, 'i', true, false
+ true, 'p', false, 'i', true, false, false
};
static FormData_pg_attribute a3 = {
0, {"xmin"}, XIDOID, 0, sizeof(TransactionId),
MinTransactionIdAttributeNumber, 0, -1, -1,
- true, 'p', false, 'i', true, false
+ true, 'p', false, 'i', true, false, false
};
static FormData_pg_attribute a4 = {
0, {"cmin"}, CIDOID, 0, sizeof(CommandId),
MinCommandIdAttributeNumber, 0, -1, -1,
- true, 'p', false, 'i', true, false
+ true, 'p', false, 'i', true, false, false
};
static FormData_pg_attribute a5 = {
0, {"xmax"}, XIDOID, 0, sizeof(TransactionId),
MaxTransactionIdAttributeNumber, 0, -1, -1,
- true, 'p', false, 'i', true, false
+ true, 'p', false, 'i', true, false, false
};
static FormData_pg_attribute a6 = {
0, {"cmax"}, CIDOID, 0, sizeof(CommandId),
MaxCommandIdAttributeNumber, 0, -1, -1,
- true, 'p', false, 'i', true, false
+ true, 'p', false, 'i', true, false, false
};
/*
@@ -139,7 +139,7 @@ static FormData_pg_attribute a6 = {
static FormData_pg_attribute a7 = {
0, {"tableoid"}, OIDOID, 0, sizeof(Oid),
TableOidAttributeNumber, 0, -1, -1,
- true, 'p', false, 'i', true, false
+ true, 'p', false, 'i', true, false, false
};
static Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7};
@@ -893,6 +893,78 @@ DeleteAttributeTuples(Oid relid)
}
/*
+ * RemoveAttributeById
+ *
+ * This is the guts of ALTER TABLE DROP COLUMN: actually mark the attribute
+ * deleted in pg_attribute. (Everything else needed, such as getting rid
+ * of any pg_attrdef entry, is handled by dependency.c.)
+ */
+void
+RemoveAttributeById(Oid relid, AttrNumber attnum)
+{
+ Relation rel;
+ Relation attr_rel;
+ HeapTuple tuple;
+ Form_pg_attribute attStruct;
+ char newattname[NAMEDATALEN];
+
+ /*
+ * Grab an exclusive lock on the target table, which we will NOT
+ * release until end of transaction. (In the simple case where
+ * we are directly dropping this column, AlterTableDropColumn already
+ * did this ... but when cascading from a drop of some other object,
+ * we may not have any lock.)
+ */
+ rel = heap_open(relid, AccessExclusiveLock);
+
+ attr_rel = heap_openr(AttributeRelationName, RowExclusiveLock);
+
+ tuple = SearchSysCacheCopy(ATTNUM,
+ ObjectIdGetDatum(relid),
+ Int16GetDatum(attnum),
+ 0, 0);
+ if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
+ elog(ERROR, "RemoveAttributeById: Failed to find attribute %d in relation %u",
+ attnum, relid);
+ attStruct = (Form_pg_attribute) GETSTRUCT(tuple);
+
+ /* Mark the attribute as dropped */
+ attStruct->attisdropped = true;
+
+ /* Remove any NOT NULL constraint the column may have */
+ attStruct->attnotnull = false;
+
+ /* We don't want to keep stats for it anymore */
+ attStruct->attstattarget = 0;
+
+ /* Change the column name to something that isn't likely to conflict */
+ snprintf(newattname, NAMEDATALEN, "........pg.dropped.%d........", attnum);
+ namestrcpy(&(attStruct->attname), newattname);
+
+ 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);
+ }
+
+ /*
+ * Because updating the pg_attribute row will trigger a relcache flush
+ * for the target relation, we need not do anything else to notify
+ * other backends of the change.
+ */
+
+ heap_close(attr_rel, RowExclusiveLock);
+
+ heap_close(rel, NoLock);
+}
+
+/*
* RemoveAttrDefault
*
* If the specified relation/attribute has a default, remove it.