pg_dump-identity-dropped-column.patch
application/octet-stream
Filename: pg_dump-identity-dropped-column.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/bin/pg_dump/pg_dump.c | 1 | 1 |
| src/bin/pg_dump/t/008_pg_dump_dropped_identity.pl | 55 | 0 |
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();