Avoid invalid array reference in transformAlterTableStmt().
authorTom Lane <[email protected]>
Mon, 18 Apr 2022 16:16:45 +0000 (12:16 -0400)
committerTom Lane <[email protected]>
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);