I thought SearchSysCacheCopyAttNum is expensive.
Relation->rd_att is enough for checking attnotnull.
What do you think of the following refactoring of set_attnotnull?
static void
set_attnotnull(List **wqueue, Relation rel, AttrNumber attnum,
LOCKMODE lockmode)
{
Oid reloid = RelationGetRelid(rel);
HeapTuple tuple;
Form_pg_attribute attForm;
Form_pg_attribute attr;
TupleDesc tupleDesc;
CheckAlterTableIsSafe(rel);
tupleDesc = RelationGetDescr(rel);
attr = TupleDescAttr(tupleDesc, attnum - 1);
if (attr->attisdropped)
return;
if (!attr->attnotnull)
{
Relation attr_rel;
attr_rel = table_open(AttributeRelationId, RowExclusiveLock);
tuple = SearchSysCacheCopyAttNum(reloid, attnum);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for attribute %d of relation %u",
attnum, reloid);
attForm = (Form_pg_attribute) GETSTRUCT(tuple);
attForm->attnotnull = true;
CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple);
if (wqueue && !NotNullImpliedByRelConstraints(rel, attForm))
{
AlteredTableInfo *tab;
tab = ATGetQueueEntry(wqueue, rel);
tab->verify_new_notnull = true;
}
CommandCounterIncrement();
heap_freetuple(tuple);
table_close(attr_rel, RowExclusiveLock);
}
}