@@ -1666,68 +1666,56 @@ RemoveAttributeById(Oid relid, AttrNumber attnum)
16661666 attnum , relid );
16671667 attStruct = (Form_pg_attribute ) GETSTRUCT (tuple );
16681668
1669- if (attnum < 0 )
1670- {
1671- /* System attribute (probably OID) ... just delete the row */
1672-
1673- CatalogTupleDelete (attr_rel , & tuple -> t_self );
1674- }
1675- else
1676- {
1677- /* Dropping user attributes is lots harder */
1669+ /* Mark the attribute as dropped */
1670+ attStruct -> attisdropped = true;
16781671
1679- /* Mark the attribute as dropped */
1680- attStruct -> attisdropped = true;
1681-
1682- /*
1683- * Set the type OID to invalid. A dropped attribute's type link
1684- * cannot be relied on (once the attribute is dropped, the type might
1685- * be too). Fortunately we do not need the type row --- the only
1686- * really essential information is the type's typlen and typalign,
1687- * which are preserved in the attribute's attlen and attalign. We set
1688- * atttypid to zero here as a means of catching code that incorrectly
1689- * expects it to be valid.
1690- */
1691- attStruct -> atttypid = InvalidOid ;
1692-
1693- /* Remove any NOT NULL constraint the column may have */
1694- attStruct -> attnotnull = false;
1672+ /*
1673+ * Set the type OID to invalid. A dropped attribute's type link cannot be
1674+ * relied on (once the attribute is dropped, the type might be too).
1675+ * Fortunately we do not need the type row --- the only really essential
1676+ * information is the type's typlen and typalign, which are preserved in
1677+ * the attribute's attlen and attalign. We set atttypid to zero here as a
1678+ * means of catching code that incorrectly expects it to be valid.
1679+ */
1680+ attStruct -> atttypid = InvalidOid ;
16951681
1696- /* We don't want to keep stats for it anymore */
1697- attStruct -> attstattarget = 0 ;
1682+ /* Remove any NOT NULL constraint the column may have */
1683+ attStruct -> attnotnull = false ;
16981684
1699- /* Unset this so no one tries to look up the generation expression */
1700- attStruct -> attgenerated = '\0' ;
1685+ /* We don't want to keep stats for it anymore */
1686+ attStruct -> attstattarget = 0 ;
17011687
1702- /*
1703- * Change the column name to something that isn't likely to conflict
1704- */
1705- snprintf (newattname , sizeof (newattname ),
1706- "........pg.dropped.%d........" , attnum );
1707- namestrcpy (& (attStruct -> attname ), newattname );
1688+ /* Unset this so no one tries to look up the generation expression */
1689+ attStruct -> attgenerated = '\0' ;
17081690
1709- /* clear the missing value if any */
1710- if (attStruct -> atthasmissing )
1711- {
1712- Datum valuesAtt [Natts_pg_attribute ] = {0 };
1713- bool nullsAtt [Natts_pg_attribute ] = {0 };
1714- bool replacesAtt [Natts_pg_attribute ] = {0 };
1715-
1716- /* update the tuple - set atthasmissing and attmissingval */
1717- valuesAtt [Anum_pg_attribute_atthasmissing - 1 ] =
1718- BoolGetDatum (false);
1719- replacesAtt [Anum_pg_attribute_atthasmissing - 1 ] = true;
1720- valuesAtt [Anum_pg_attribute_attmissingval - 1 ] = (Datum ) 0 ;
1721- nullsAtt [Anum_pg_attribute_attmissingval - 1 ] = true;
1722- replacesAtt [Anum_pg_attribute_attmissingval - 1 ] = true;
1723-
1724- tuple = heap_modify_tuple (tuple , RelationGetDescr (attr_rel ),
1725- valuesAtt , nullsAtt , replacesAtt );
1726- }
1691+ /*
1692+ * Change the column name to something that isn't likely to conflict
1693+ */
1694+ snprintf (newattname , sizeof (newattname ),
1695+ "........pg.dropped.%d........" , attnum );
1696+ namestrcpy (& (attStruct -> attname ), newattname );
17271697
1728- CatalogTupleUpdate (attr_rel , & tuple -> t_self , tuple );
1698+ /* clear the missing value if any */
1699+ if (attStruct -> atthasmissing )
1700+ {
1701+ Datum valuesAtt [Natts_pg_attribute ] = {0 };
1702+ bool nullsAtt [Natts_pg_attribute ] = {0 };
1703+ bool replacesAtt [Natts_pg_attribute ] = {0 };
1704+
1705+ /* update the tuple - set atthasmissing and attmissingval */
1706+ valuesAtt [Anum_pg_attribute_atthasmissing - 1 ] =
1707+ BoolGetDatum (false);
1708+ replacesAtt [Anum_pg_attribute_atthasmissing - 1 ] = true;
1709+ valuesAtt [Anum_pg_attribute_attmissingval - 1 ] = (Datum ) 0 ;
1710+ nullsAtt [Anum_pg_attribute_attmissingval - 1 ] = true;
1711+ replacesAtt [Anum_pg_attribute_attmissingval - 1 ] = true;
1712+
1713+ tuple = heap_modify_tuple (tuple , RelationGetDescr (attr_rel ),
1714+ valuesAtt , nullsAtt , replacesAtt );
17291715 }
17301716
1717+ CatalogTupleUpdate (attr_rel , & tuple -> t_self , tuple );
1718+
17311719 /*
17321720 * Because updating the pg_attribute row will trigger a relcache flush for
17331721 * the target relation, we need not do anything else to notify other
@@ -1736,8 +1724,7 @@ RemoveAttributeById(Oid relid, AttrNumber attnum)
17361724
17371725 table_close (attr_rel , RowExclusiveLock );
17381726
1739- if (attnum > 0 )
1740- RemoveStatistics (relid , attnum );
1727+ RemoveStatistics (relid , attnum );
17411728
17421729 relation_close (rel , NoLock );
17431730}
0 commit comments