From 7ef2912519fdea0dd0f6747c4dc008c99dc51e90 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 12 Jul 2023 16:12:34 +0200 Subject: [PATCH] Remove ancient special case code for dropping oid columns The special handling of negative attribute numbers in RemoveAttributeById() was introduced to support SET WITHOUT OIDS (commit 24614a9880). But that feature doesn't exist anymore, so we can revert to the previous, simpler version. Reviewed-by: Alvaro Herrera Discussion: https://www.postgresql.org/message-id/flat/52a125e4-ff9a-95f5-9f61-b87cf447e4da@eisentraut.org --- src/backend/catalog/heap.c | 105 ++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 59 deletions(-) diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 9196dcd39f..4c30c7d461 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -1666,67 +1666,55 @@ RemoveAttributeById(Oid relid, AttrNumber attnum) attnum, relid); attStruct = (Form_pg_attribute) GETSTRUCT(tuple); - if (attnum < 0) + /* Mark the attribute as dropped */ + attStruct->attisdropped = true; + + /* + * Set the type OID to invalid. A dropped attribute's type link cannot be + * relied on (once the attribute is dropped, the type might be too). + * Fortunately we do not need the type row --- the only really essential + * information is the type's typlen and typalign, which are preserved in + * the attribute's attlen and attalign. We set atttypid to zero here as a + * means of catching code that incorrectly expects it to be valid. + */ + attStruct->atttypid = InvalidOid; + + /* 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; + + /* Unset this so no one tries to look up the generation expression */ + attStruct->attgenerated = '\0'; + + /* + * Change the column name to something that isn't likely to conflict + */ + snprintf(newattname, sizeof(newattname), + "........pg.dropped.%d........", attnum); + namestrcpy(&(attStruct->attname), newattname); + + /* clear the missing value if any */ + if (attStruct->atthasmissing) { - /* System attribute (probably OID) ... just delete the row */ + Datum valuesAtt[Natts_pg_attribute] = {0}; + bool nullsAtt[Natts_pg_attribute] = {0}; + bool replacesAtt[Natts_pg_attribute] = {0}; - CatalogTupleDelete(attr_rel, &tuple->t_self); + /* update the tuple - set atthasmissing and attmissingval */ + valuesAtt[Anum_pg_attribute_atthasmissing - 1] = + BoolGetDatum(false); + replacesAtt[Anum_pg_attribute_atthasmissing - 1] = true; + valuesAtt[Anum_pg_attribute_attmissingval - 1] = (Datum) 0; + nullsAtt[Anum_pg_attribute_attmissingval - 1] = true; + replacesAtt[Anum_pg_attribute_attmissingval - 1] = true; + + tuple = heap_modify_tuple(tuple, RelationGetDescr(attr_rel), + valuesAtt, nullsAtt, replacesAtt); } - else - { - /* Dropping user attributes is lots harder */ - /* Mark the attribute as dropped */ - attStruct->attisdropped = true; - - /* - * Set the type OID to invalid. A dropped attribute's type link - * cannot be relied on (once the attribute is dropped, the type might - * be too). Fortunately we do not need the type row --- the only - * really essential information is the type's typlen and typalign, - * which are preserved in the attribute's attlen and attalign. We set - * atttypid to zero here as a means of catching code that incorrectly - * expects it to be valid. - */ - attStruct->atttypid = InvalidOid; - - /* 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; - - /* Unset this so no one tries to look up the generation expression */ - attStruct->attgenerated = '\0'; - - /* - * Change the column name to something that isn't likely to conflict - */ - snprintf(newattname, sizeof(newattname), - "........pg.dropped.%d........", attnum); - namestrcpy(&(attStruct->attname), newattname); - - /* clear the missing value if any */ - if (attStruct->atthasmissing) - { - Datum valuesAtt[Natts_pg_attribute] = {0}; - bool nullsAtt[Natts_pg_attribute] = {0}; - bool replacesAtt[Natts_pg_attribute] = {0}; - - /* update the tuple - set atthasmissing and attmissingval */ - valuesAtt[Anum_pg_attribute_atthasmissing - 1] = - BoolGetDatum(false); - replacesAtt[Anum_pg_attribute_atthasmissing - 1] = true; - valuesAtt[Anum_pg_attribute_attmissingval - 1] = (Datum) 0; - nullsAtt[Anum_pg_attribute_attmissingval - 1] = true; - replacesAtt[Anum_pg_attribute_attmissingval - 1] = true; - - tuple = heap_modify_tuple(tuple, RelationGetDescr(attr_rel), - valuesAtt, nullsAtt, replacesAtt); - } - - CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple); - } + CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple); /* * Because updating the pg_attribute row will trigger a relcache flush for @@ -1736,8 +1724,7 @@ RemoveAttributeById(Oid relid, AttrNumber attnum) table_close(attr_rel, RowExclusiveLock); - if (attnum > 0) - RemoveStatistics(relid, attnum); + RemoveStatistics(relid, attnum); relation_close(rel, NoLock); }