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

Commit 3486bcf

Browse files
committed
Fix pg_dump's logic for eliding sequence limits that match the defaults.
The previous coding here applied atoi() to strings that could represent values too large to fit in an int. If the overflowed value happened to match one of the cases it was looking for, it would drop that limit value from the output, leading to incorrect restoration of the sequence. Avoid the unsafe behavior, and also make the logic cleaner by explicitly calculating the default min/max values for the appropriate kind of sequence. Reported and patched by Alexey Bashtanov, though I whacked his patch around a bit. Back-patch to v10 where the faulty logic was added. Discussion: https://postgr.es/m/cb85a9a5-946b-c7c4-9cf2-6cd6e25d7a33@imap.cc
1 parent 9a89f6d commit 3486bcf

File tree

1 file changed

+29
-24
lines changed

1 file changed

+29
-24
lines changed

src/bin/pg_dump/pg_dump.c

+29-24
Original file line numberDiff line numberDiff line change
@@ -16843,6 +16843,10 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
1684316843
*seqtype;
1684416844
bool cycled;
1684516845
bool is_ascending;
16846+
int64 default_minv,
16847+
default_maxv;
16848+
char bufm[32],
16849+
bufx[32];
1684616850
PQExpBuffer query = createPQExpBuffer();
1684716851
PQExpBuffer delqry = createPQExpBuffer();
1684816852
PQExpBuffer labelq = createPQExpBuffer();
@@ -16912,40 +16916,41 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
1691216916
cache = PQgetvalue(res, 0, 5);
1691316917
cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0);
1691416918

16915-
is_ascending = incby[0] != '-';
16916-
16917-
if (is_ascending && atoi(minv) == 1)
16918-
minv = NULL;
16919-
if (!is_ascending && atoi(maxv) == -1)
16920-
maxv = NULL;
16921-
16919+
/* Calculate default limits for a sequence of this type */
16920+
is_ascending = (incby[0] != '-');
1692216921
if (strcmp(seqtype, "smallint") == 0)
1692316922
{
16924-
if (!is_ascending && atoi(minv) == PG_INT16_MIN)
16925-
minv = NULL;
16926-
if (is_ascending && atoi(maxv) == PG_INT16_MAX)
16927-
maxv = NULL;
16923+
default_minv = is_ascending ? 1 : PG_INT16_MIN;
16924+
default_maxv = is_ascending ? PG_INT16_MAX : -1;
1692816925
}
1692916926
else if (strcmp(seqtype, "integer") == 0)
1693016927
{
16931-
if (!is_ascending && atoi(minv) == PG_INT32_MIN)
16932-
minv = NULL;
16933-
if (is_ascending && atoi(maxv) == PG_INT32_MAX)
16934-
maxv = NULL;
16928+
default_minv = is_ascending ? 1 : PG_INT32_MIN;
16929+
default_maxv = is_ascending ? PG_INT32_MAX : -1;
1693516930
}
1693616931
else if (strcmp(seqtype, "bigint") == 0)
1693716932
{
16938-
char bufm[100],
16939-
bufx[100];
16933+
default_minv = is_ascending ? 1 : PG_INT64_MIN;
16934+
default_maxv = is_ascending ? PG_INT64_MAX : -1;
16935+
}
16936+
else
16937+
{
16938+
exit_horribly(NULL, "unrecognized sequence type: %s\n", seqtype);
16939+
default_minv = default_maxv = 0; /* keep compiler quiet */
16940+
}
1694016941

16941-
snprintf(bufm, sizeof(bufm), INT64_FORMAT, PG_INT64_MIN);
16942-
snprintf(bufx, sizeof(bufx), INT64_FORMAT, PG_INT64_MAX);
16942+
/*
16943+
* 64-bit strtol() isn't very portable, so convert the limits to strings
16944+
* and compare that way.
16945+
*/
16946+
snprintf(bufm, sizeof(bufm), INT64_FORMAT, default_minv);
16947+
snprintf(bufx, sizeof(bufx), INT64_FORMAT, default_maxv);
1694316948

16944-
if (!is_ascending && strcmp(minv, bufm) == 0)
16945-
minv = NULL;
16946-
if (is_ascending && strcmp(maxv, bufx) == 0)
16947-
maxv = NULL;
16948-
}
16949+
/* Don't print minv/maxv if they match the respective default limit */
16950+
if (strcmp(minv, bufm) == 0)
16951+
minv = NULL;
16952+
if (strcmp(maxv, bufx) == 0)
16953+
maxv = NULL;
1694916954

1695016955
/*
1695116956
* DROP must be fully qualified in case same name appears in pg_catalog

0 commit comments

Comments
 (0)