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);
    }
}


Reply via email to