Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7b8cb9c

Browse files
committed
Fix possible crash in pg_dump with identity sequences.
If an owned sequence is considered interesting, force its owning table to be marked interesting too. This ensures, in particular, that we'll fetch the owning table's column names so we have the data needed for ALTER TABLE ... ADD GENERATED. Previously there were edge cases where pg_dump could get SIGSEGV due to not having filled in the column names. (The known case is where the owning table has been made part of an extension while its identity sequence is not a member; but there may be others.) Also, if it's an identity sequence, force its dumped-components mask to exactly match the owning table: dump definition only if we're dumping the table's definition, dump data only if we're dumping the table's data, etc. This generalizes the code introduced in commit b965f26 that set the sequence's dump mask to NONE if the owning table's mask is NONE. That's insufficient to prevent failures, because for example the table's mask might only request dumping ACLs, which would lead us to still emit ALTER TABLE ADD GENERATED even though we didn't create the table. It seems better to treat an identity sequence as though it were an inseparable aspect of the table, matching the treatment used in the backend's dependency logic. Perhaps this policy needs additional refinement, but let's wait to see some field use-cases before changing it further. While here, add a comment in pg_dump.h warning against writing tests like "if (dobj->dump == DUMP_COMPONENT_NONE)", which was a bug in this case. There is one other example in getPublicationNamespaces, which if it's not a bug is at least remarkably unclear and under-documented. Changing that requires a separate discussion, however. Per report from Artur Zakirov. Back-patch to all supported branches. Discussion: https://postgr.es/m/CAKNkYnwXFBf136=u9UqUxFUVagevLQJ=zGd5BsLhCsatDvQsKQ@mail.gmail.com
1 parent 3191ecc commit 7b8cb9c

File tree

2 files changed

+27
-17
lines changed

2 files changed

+27
-17
lines changed

src/bin/pg_dump/pg_dump.c

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7253,20 +7253,15 @@ getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables)
72537253
seqinfo->owning_tab, seqinfo->dobj.catId.oid);
72547254

72557255
/*
7256-
* Only dump identity sequences if we're going to dump the table that
7257-
* it belongs to.
7258-
*/
7259-
if (owning_tab->dobj.dump == DUMP_COMPONENT_NONE &&
7260-
seqinfo->is_identity_sequence)
7261-
{
7262-
seqinfo->dobj.dump = DUMP_COMPONENT_NONE;
7263-
continue;
7264-
}
7265-
7266-
/*
7267-
* Otherwise we need to dump the components that are being dumped for
7268-
* the table and any components which the sequence is explicitly
7269-
* marked with.
7256+
* For an identity sequence, dump exactly the same components for the
7257+
* sequence as for the owning table. This is important because we
7258+
* treat the identity sequence as an integral part of the table. For
7259+
* example, there is not any DDL command that allows creation of such
7260+
* a sequence independently of the table.
7261+
*
7262+
* For other owned sequences such as serial sequences, we need to dump
7263+
* the components that are being dumped for the table and any
7264+
* components that the sequence is explicitly marked with.
72707265
*
72717266
* We can't simply use the set of components which are being dumped
72727267
* for the table as the table might be in an extension (and only the
@@ -7279,10 +7274,17 @@ getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables)
72797274
* marked by checkExtensionMembership() and this will be a no-op as
72807275
* the table will be equivalently marked.
72817276
*/
7282-
seqinfo->dobj.dump = seqinfo->dobj.dump | owning_tab->dobj.dump;
7277+
if (seqinfo->is_identity_sequence)
7278+
seqinfo->dobj.dump = owning_tab->dobj.dump;
7279+
else
7280+
seqinfo->dobj.dump |= owning_tab->dobj.dump;
72837281

7282+
/* Make sure that necessary data is available if we're dumping it */
72847283
if (seqinfo->dobj.dump != DUMP_COMPONENT_NONE)
7284+
{
72857285
seqinfo->interesting = true;
7286+
owning_tab->interesting = true;
7287+
}
72867288
}
72877289
}
72887290

src/bin/pg_dump/pg_dump.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,16 @@ typedef enum
8989
/*
9090
* DumpComponents is a bitmask of the potentially dumpable components of
9191
* a database object: its core definition, plus optional attributes such
92-
* as ACL, comments, etc. The NONE and ALL symbols are convenient
93-
* shorthands.
92+
* as ACL, comments, etc.
93+
*
94+
* The NONE and ALL symbols are convenient shorthands for assigning values,
95+
* but be careful about using them in tests. For example, a test like
96+
* "if (dobj->dump == DUMP_COMPONENT_NONE)" is probably wrong; you likely want
97+
* "if (!(dobj->dump & DUMP_COMPONENT_DEFINITION))" instead. This is because
98+
* we aren't too careful about the values of irrelevant bits, as indeed can be
99+
* seen in the definition of DUMP_COMPONENT_ALL. It's also possible that an
100+
* object has only subsidiary bits such as DUMP_COMPONENT_ACL set, leading to
101+
* unexpected behavior of a test against NONE.
94102
*/
95103
typedef uint32 DumpComponents;
96104
#define DUMP_COMPONENT_NONE (0)

0 commit comments

Comments
 (0)