Avoid invalid array reference in transformAlterTableStmt().
authorTom Lane
Mon, 18 Apr 2022 16:16:45 +0000 (12:16 -0400)
committerTom Lane
Mon, 18 Apr 2022 16:16:45 +0000 (12:16 -0400)
Don't try to look at the attidentity field of system attributes,
because they're not there in the TupleDescAttr array.  Sometimes
this is harmless because we accidentally pick up a zero, but
otherwise we'll report "no owned sequence found" from an attempt
to alter a system attribute.  (It seems possible that a SIGSEGV
could occur, too, though I've not seen it in testing.)

It's not in this function's charter to complain that you can't
alter a system column, so instead just hard-wire an assumption
that system attributes aren't identities.  I didn't bother with
a regression test because the appearance of the bug is very
erratic.

Per bug #17465 from Roman Zharkov.  Back-patch to all supported
branches.  (There's not actually a live bug before v12, because
before that get_attidentity() did the right thing anyway.
But for consistency I changed the test in the older branches too.)

Discussion: https://postgr.es/m/17465-f2a554a6cb5740d3@postgresql.org

src/backend/parser/parse_utilcmd.c

index 2826559d09b746bd3d7c02dfc68d987d0137550d..1a64a522798919c7e1252867fd4446938740cbe8 100644 (file)
@@ -3424,7 +3424,8 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt,
                                 errmsg("column \"%s\" of relation \"%s\" does not exist",
                                        cmd->name, RelationGetRelationName(rel))));
 
-                   if (TupleDescAttr(tupdesc, attnum - 1)->attidentity)
+                   if (attnum > 0 &&
+                       TupleDescAttr(tupdesc, attnum - 1)->attidentity)
                    {
                        Oid         seq_relid = getIdentitySequence(relid, attnum, false);
                        Oid         typeOid = typenameTypeId(pstate, def->typeName);