From: William Bernbaum <wbernbaum@freezerworks.com>
Subject: [PATCH] Fix pg_dump emitting OVERRIDING SYSTEM VALUE for tables
 with dropped identity columns

When a column with GENERATED ALWAYS AS IDENTITY is dropped via
ALTER TABLE ... DROP COLUMN, PostgreSQL marks the column as dropped
(attisdropped = true) but does not clear pg_attribute.attidentity.

In getTableAttrs(), pg_dump processes all attributes (attnum > 0),
including dropped ones.  The needs_override flag is then set based
on attidentity without checking attisdropped, causing
dumpTableData_insert() to emit OVERRIDING SYSTEM VALUE for tables
that no longer have any identity column.

Fix by moving the attisdropped evaluation before the needs_override
calculation and gating the check on !attisdropped.

---
 src/bin/pg_dump/pg_dump.c                          |  5 +++--
 src/bin/pg_dump/t/008_pg_dump_dropped_identity.pl  | 55 ++++++++++++++++++++++
 2 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -9370,8 +9370,9 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
 			tbinfo->typstorage[j] = *(PQgetvalue(res, r, i_typstorage));
 			tbinfo->attidentity[j] = *(PQgetvalue(res, r, i_attidentity));
 			tbinfo->attgenerated[j] = *(PQgetvalue(res, r, i_attgenerated));
-			tbinfo->needs_override = tbinfo->needs_override || (tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS);
 			tbinfo->attisdropped[j] = (PQgetvalue(res, r, i_attisdropped)[0] == 't');
+			tbinfo->needs_override = tbinfo->needs_override || (!tbinfo->attisdropped[j] && tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS);
 			tbinfo->attlen[j] = atoi(PQgetvalue(res, r, i_attlen));
 			tbinfo->attalign[j] = *(PQgetvalue(res, r, i_attalign));
 			tbinfo->attislocal[j] = (PQgetvalue(res, r, i_attislocal)[0] == 't');

diff --git a/src/bin/pg_dump/t/008_pg_dump_dropped_identity.pl b/src/bin/pg_dump/t/008_pg_dump_dropped_identity.pl
new file mode 100644
--- /dev/null
+++ b/src/bin/pg_dump/t/008_pg_dump_dropped_identity.pl
@@ -0,0 +1,55 @@
+use strict;
+use warnings;
+
+use PostgreSQL::Test::Cluster;
+use PostgreSQL::Test::Utils;
+use Test::More;
+
+# Verify that pg_dump does not emit OVERRIDING SYSTEM VALUE for a table
+# whose only identity column has been dropped.
+
+my $node = PostgreSQL::Test::Cluster->new('identity_override');
+$node->init;
+$node->start;
+
+# Create a table with an identity column, insert a row, then drop the
+# identity column and switch to a composite primary key.
+$node->safe_psql('postgres', q{
+    CREATE TABLE demo (
+        id   BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
+        fk_a BIGINT NOT NULL,
+        fk_b BIGINT NOT NULL
+    );
+
+    INSERT INTO demo (fk_a, fk_b)
+    OVERRIDING SYSTEM VALUE VALUES (1, 2);
+
+    ALTER TABLE demo DROP COLUMN id;
+    ALTER TABLE demo ADD PRIMARY KEY (fk_a, fk_b);
+});
+
+# Dump data with INSERT statements
+my $dumpfile = $node->basedir . '/dump.sql';
+
+command_ok(
+    [
+        'pg_dump',
+        '--data-only',
+        '--inserts',
+        '--table=demo',
+        '--file=' . $dumpfile,
+        'postgres'
+    ],
+    'pg_dump with --inserts runs');
+
+my $dump = slurp_file($dumpfile);
+
+# Ensure no spurious OVERRIDING SYSTEM VALUE is emitted
+unlike(
+    $dump,
+    qr/OVERRIDING SYSTEM VALUE/,
+    'no OVERRIDING SYSTEM VALUE for dropped identity column'
+);
+
+# Ensure the row is still dumped correctly
+like(
+    $dump,
+    qr/insert into.*demo.*1.*2/i,
+    'row is dumped correctly'
+);
+
+done_testing();