1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-03 22:24:49 +03:00

Parse sequence type and integer metadata in dumpSequence().

This commit modifies dumpSequence() to parse all the sequence
metadata into the appropriate types instead of carting around
string pointers to the PGresult data.  Besides allowing us to free
the PGresult storage earlier in the function, this eliminates the
need to compare min_value and max_value to their respective
defaults as strings.

This is preparatory work for a follow-up commit that will improve
the performance of dumpSequence() in a similar manner to how commit
2329cad1b9 optimized binary_upgrade_set_pg_class_oids().

Reviewed-by: Euler Taveira
Discussion: https://postgr.es/m/20240503025140.GA1227404%40nathanxps13
This commit is contained in:
Nathan Bossart 2024-07-31 10:12:41 -05:00
parent 057ee9183c
commit 23687e925f
2 changed files with 61 additions and 44 deletions

View File

@ -104,6 +104,24 @@ typedef struct
RelFileNumber toast_index_relfilenumber; /* toast table index filenode */
} BinaryUpgradeClassOidItem;
/* sequence types */
typedef enum SeqType
{
SEQTYPE_SMALLINT,
SEQTYPE_INTEGER,
SEQTYPE_BIGINT,
} SeqType;
const char *const SeqTypeNames[] =
{
[SEQTYPE_SMALLINT] = "smallint",
[SEQTYPE_INTEGER] = "integer",
[SEQTYPE_BIGINT] = "bigint",
};
StaticAssertDecl(lengthof(SeqTypeNames) == (SEQTYPE_BIGINT + 1),
"array length mismatch");
typedef enum OidOptions
{
zeroIsError = 1,
@ -17251,6 +17269,19 @@ dumpTableConstraintComment(Archive *fout, const ConstraintInfo *coninfo)
free(qtabname);
}
static inline SeqType
parse_sequence_type(const char *name)
{
for (int i = 0; i < lengthof(SeqTypeNames); i++)
{
if (strcmp(SeqTypeNames[i], name) == 0)
return (SeqType) i;
}
pg_fatal("unrecognized sequence type: %s", name);
return (SeqType) 0; /* keep compiler quiet */
}
/*
* dumpSequence
* write the declaration (not data) of one user-defined sequence
@ -17260,18 +17291,16 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo)
{
DumpOptions *dopt = fout->dopt;
PGresult *res;
char *startv,
*incby,
*maxv,
*minv,
*cache,
*seqtype;
SeqType seqtype;
bool cycled;
bool is_ascending;
int64 default_minv,
default_maxv;
char bufm[32],
bufx[32];
default_maxv,
minv,
maxv,
startv,
incby,
cache;
PQExpBuffer query = createPQExpBuffer();
PQExpBuffer delqry = createPQExpBuffer();
char *qseqname;
@ -17313,50 +17342,39 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo)
PQntuples(res)),
tbinfo->dobj.name, PQntuples(res));
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);
seqtype = parse_sequence_type(PQgetvalue(res, 0, 0));
startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10);
incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10);
maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10);
minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10);
cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10);
cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0);
PQclear(res);
/* Calculate default limits for a sequence of this type */
is_ascending = (incby[0] != '-');
if (strcmp(seqtype, "smallint") == 0)
is_ascending = (incby >= 0);
if (seqtype == SEQTYPE_SMALLINT)
{
default_minv = is_ascending ? 1 : PG_INT16_MIN;
default_maxv = is_ascending ? PG_INT16_MAX : -1;
}
else if (strcmp(seqtype, "integer") == 0)
else if (seqtype == SEQTYPE_INTEGER)
{
default_minv = is_ascending ? 1 : PG_INT32_MIN;
default_maxv = is_ascending ? PG_INT32_MAX : -1;
}
else if (strcmp(seqtype, "bigint") == 0)
else if (seqtype == SEQTYPE_BIGINT)
{
default_minv = is_ascending ? 1 : PG_INT64_MIN;
default_maxv = is_ascending ? PG_INT64_MAX : -1;
}
else
{
pg_fatal("unrecognized sequence type: %s", seqtype);
pg_fatal("unrecognized sequence type: %d", seqtype);
default_minv = default_maxv = 0; /* keep compiler quiet */
}
/*
* 64-bit strtol() isn't very portable, so convert the limits to strings
* and compare that way.
*/
snprintf(bufm, sizeof(bufm), INT64_FORMAT, default_minv);
snprintf(bufx, sizeof(bufx), INT64_FORMAT, default_maxv);
/* Don't print minv/maxv if they match the respective default limit */
if (strcmp(minv, bufm) == 0)
minv = NULL;
if (strcmp(maxv, bufx) == 0)
maxv = NULL;
/*
* Identity sequences are not to be dropped separately.
*/
@ -17404,26 +17422,26 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo)
"UNLOGGED " : "",
fmtQualifiedDumpable(tbinfo));
if (strcmp(seqtype, "bigint") != 0)
appendPQExpBuffer(query, " AS %s\n", seqtype);
if (seqtype != SEQTYPE_BIGINT)
appendPQExpBuffer(query, " AS %s\n", SeqTypeNames[seqtype]);
}
appendPQExpBuffer(query, " START WITH %s\n", startv);
appendPQExpBuffer(query, " START WITH " INT64_FORMAT "\n", startv);
appendPQExpBuffer(query, " INCREMENT BY %s\n", incby);
appendPQExpBuffer(query, " INCREMENT BY " INT64_FORMAT "\n", incby);
if (minv)
appendPQExpBuffer(query, " MINVALUE %s\n", minv);
if (minv != default_minv)
appendPQExpBuffer(query, " MINVALUE " INT64_FORMAT "\n", minv);
else
appendPQExpBufferStr(query, " NO MINVALUE\n");
if (maxv)
appendPQExpBuffer(query, " MAXVALUE %s\n", maxv);
if (maxv != default_maxv)
appendPQExpBuffer(query, " MAXVALUE " INT64_FORMAT "\n", maxv);
else
appendPQExpBufferStr(query, " NO MAXVALUE\n");
appendPQExpBuffer(query,
" CACHE %s%s",
" CACHE " INT64_FORMAT "%s",
cache, (cycled ? "\n CYCLE" : ""));
if (tbinfo->is_identity_sequence)
@ -17510,8 +17528,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo)
tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
PQclear(res);
destroyPQExpBuffer(query);
destroyPQExpBuffer(delqry);
free(qseqname);

View File

@ -2572,6 +2572,7 @@ SeqScan
SeqScanState
SeqTable
SeqTableData
SeqType
SerCommitSeqNo
SerialControl
SerialIOData