On Wed, Jun 10, 2026 at 5:06 PM Chao Li <[email protected]> wrote:
>
>
> After reading the other implementation in [1], I realized that I had missed
> the partial-index case, so I added coverage for that.
>
> I am still sending an updated version of this patch because my implementation
> is different from the one in [1]. I would like people to compare the two
> approaches and decide which direction is better.
>
I tried your patch before but abandoned it due to many regression test failures.
RememberAllDependentForRebuilding
{
default:
/*
* We don't expect any other sorts of objects to depend on a
* column. A whole-relation scan can find the relation's row
* type, which doesn't need rebuilding for SET EXPRESSION.
*/
if (attnum == 0 &&
foundObject.classId == TypeRelationId &&
get_typ_typrelid(foundObject.objectId) ==
RelationGetRelid(rel))
continue;
elog(ERROR, "unexpected object depending on column: %s",
getObjectDescription(&foundObject, false));
break;
}
RememberAllDependentForRebuilding(tab, AT_SetExpression, rel, 0, NULL) scans for
all dependencies on the relation (not just a specific column, since attnum=0).
This is much broader than a column-level scan.
The above DEFAULT branch in the SWITCH currently only exempts the relation's own
row type (TypeRelationId). But a table can have many other kinds of dependents
— indexes, triggers, foreign keys, views, etc. — and any of them that
hitting this
DEFAULT branch would incorrectly fire:
elog(ERROR, "unexpected object depending on column: %s", ...)
We need to check that every possible object type that can depend on a relation
and ensure none of them fall through to that `elog(ERROR, ...)`.
In RememberAllDependentForRebuilding, we have `if (subtype ==
AT_AlterColumnType)` guards against AT_SetExpression, — those branches
silently skip AT_SetExpression, which is good.
But the real risk is the DEFAULT branch, which lacks such a guard and
will error on anything unexpected.