summaryrefslogtreecommitdiff
path: root/src/bin/pg_dump/pg_dump.c
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2017-02-10 15:12:32 -0500
committerPeter Eisentraut <peter_e@gmx.net>2017-02-10 15:34:35 -0500
commit2ea5b06c7a7056dca0af1610aadebe608fbcca08 (patch)
tree368b0cb5ac34c4450238da2c6161f20852fe242f /src/bin/pg_dump/pg_dump.c
parent9401883a7a598f1f1664c74835821f697932666f (diff)
downloadpostgresql-2ea5b06c7a7056dca0af1610aadebe608fbcca08.tar.gz
Add CREATE SEQUENCE AS <data type> clause
This stores a data type, required to be an integer type, with the sequence. The sequences min and max values default to the range supported by the type, and they cannot be set to values exceeding that range. The internal implementation of the sequence is not affected. Change the serial types to create sequences of the appropriate type. This makes sure that the min and max values of the sequence for a serial column match the range of values supported by the table column. So the sequence can no longer overflow the table column. This also makes monitoring for sequence exhaustion/wraparound easier, which currently requires various contortions to cross-reference the sequences with the table columns they are used with. This commit also effectively reverts the pg_sequence column reordering in f3b421da5f4addc95812b9db05a24972b8fd9739, because the new seqtypid column allows us to fill the hole in the struct and create a more natural overall column ordering. Reviewed-by: Steve Singer <steve@ssinger.info> Reviewed-by: Michael Paquier <michael.paquier@gmail.com>
Diffstat (limited to 'src/bin/pg_dump/pg_dump.c')
-rw-r--r--src/bin/pg_dump/pg_dump.c103
1 files changed, 57 insertions, 46 deletions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 9afacdb900..7364a12c25 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -15912,39 +15912,29 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
PGresult *res;
char *startv,
*incby,
- *maxv = NULL,
- *minv = NULL,
- *cache;
- char bufm[100],
- bufx[100];
+ *maxv,
+ *minv,
+ *cache,
+ *seqtype;
bool cycled;
+ bool is_ascending;
PQExpBuffer query = createPQExpBuffer();
PQExpBuffer delqry = createPQExpBuffer();
PQExpBuffer labelq = createPQExpBuffer();
- snprintf(bufm, sizeof(bufm), INT64_FORMAT, PG_INT64_MIN);
- snprintf(bufx, sizeof(bufx), INT64_FORMAT, PG_INT64_MAX);
-
if (fout->remoteVersion >= 100000)
{
/* Make sure we are in proper schema */
selectSourceSchema(fout, "pg_catalog");
appendPQExpBuffer(query,
- "SELECT seqstart, seqincrement, "
- "CASE WHEN seqincrement > 0 AND seqmax = %s THEN NULL "
- " WHEN seqincrement < 0 AND seqmax = -1 THEN NULL "
- " ELSE seqmax "
- "END AS seqmax, "
- "CASE WHEN seqincrement > 0 AND seqmin = 1 THEN NULL "
- " WHEN seqincrement < 0 AND seqmin = %s THEN NULL "
- " ELSE seqmin "
- "END AS seqmin, "
+ "SELECT format_type(seqtypid, NULL), "
+ "seqstart, seqincrement, "
+ "seqmax, seqmin, "
"seqcache, seqcycle "
"FROM pg_class c "
"JOIN pg_sequence s ON (s.seqrelid = c.oid) "
"WHERE c.oid = '%u'::oid",
- bufx, bufm,
tbinfo->dobj.catId.oid);
}
else if (fout->remoteVersion >= 80400)
@@ -15958,17 +15948,9 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
appendPQExpBuffer(query,
- "SELECT start_value, increment_by, "
- "CASE WHEN increment_by > 0 AND max_value = %s THEN NULL "
- " WHEN increment_by < 0 AND max_value = -1 THEN NULL "
- " ELSE max_value "
- "END AS max_value, "
- "CASE WHEN increment_by > 0 AND min_value = 1 THEN NULL "
- " WHEN increment_by < 0 AND min_value = %s THEN NULL "
- " ELSE min_value "
- "END AS min_value, "
+ "SELECT 'bigint'::name AS sequence_type, "
+ "start_value, increment_by, max_value, min_value, "
"cache_value, is_cycled FROM %s",
- bufx, bufm,
fmtId(tbinfo->dobj.name));
}
else
@@ -15977,17 +15959,9 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
appendPQExpBuffer(query,
- "SELECT 0 AS start_value, increment_by, "
- "CASE WHEN increment_by > 0 AND max_value = %s THEN NULL "
- " WHEN increment_by < 0 AND max_value = -1 THEN NULL "
- " ELSE max_value "
- "END AS max_value, "
- "CASE WHEN increment_by > 0 AND min_value = 1 THEN NULL "
- " WHEN increment_by < 0 AND min_value = %s THEN NULL "
- " ELSE min_value "
- "END AS min_value, "
+ "SELECT 'bigint'::name AS sequence_type, "
+ "0 AS start_value, increment_by, max_value, min_value, "
"cache_value, is_cycled FROM %s",
- bufx, bufm,
fmtId(tbinfo->dobj.name));
}
@@ -16002,14 +15976,48 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
exit_nicely(1);
}
- startv = PQgetvalue(res, 0, 0);
- incby = PQgetvalue(res, 0, 1);
- if (!PQgetisnull(res, 0, 2))
- maxv = PQgetvalue(res, 0, 2);
- if (!PQgetisnull(res, 0, 3))
- minv = PQgetvalue(res, 0, 3);
- cache = PQgetvalue(res, 0, 4);
- cycled = (strcmp(PQgetvalue(res, 0, 5), "t") == 0);
+ seqtype = PQgetvalue(res, 0, 0);
+ startv = PQgetvalue(res, 0, 1);
+ incby = PQgetvalue(res, 0, 2);
+ maxv = PQgetvalue(res, 0, 3);
+ minv = PQgetvalue(res, 0, 4);
+ cache = PQgetvalue(res, 0, 5);
+ cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0);
+
+ is_ascending = incby[0] != '-';
+
+ if (is_ascending && atoi(minv) == 1)
+ minv = NULL;
+ if (!is_ascending && atoi(maxv) == -1)
+ maxv = NULL;
+
+ if (strcmp(seqtype, "smallint") == 0)
+ {
+ if (!is_ascending && atoi(minv) == PG_INT16_MIN)
+ minv = NULL;
+ if (is_ascending && atoi(maxv) == PG_INT16_MAX)
+ maxv = NULL;
+ }
+ else if (strcmp(seqtype, "integer") == 0)
+ {
+ if (!is_ascending && atoi(minv) == PG_INT32_MIN)
+ minv = NULL;
+ if (is_ascending && atoi(maxv) == PG_INT32_MAX)
+ maxv = NULL;
+ }
+ else if (strcmp(seqtype, "bigint") == 0)
+ {
+ char bufm[100],
+ bufx[100];
+
+ snprintf(bufm, sizeof(bufm), INT64_FORMAT, PG_INT64_MIN);
+ snprintf(bufx, sizeof(bufx), INT64_FORMAT, PG_INT64_MAX);
+
+ if (!is_ascending && strcmp(minv, bufm) == 0)
+ minv = NULL;
+ if (is_ascending && strcmp(maxv, bufx) == 0)
+ maxv = NULL;
+ }
/*
* DROP must be fully qualified in case same name appears in pg_catalog
@@ -16033,6 +16041,9 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
"CREATE SEQUENCE %s\n",
fmtId(tbinfo->dobj.name));
+ if (strcmp(seqtype, "bigint") != 0)
+ appendPQExpBuffer(query, " AS %s\n", seqtype);
+
if (fout->remoteVersion >= 80400)
appendPQExpBuffer(query, " START WITH %s\n", startv);