diff options
author | Nathan Bossart <nathan@postgresql.org> | 2024-07-31 10:12:41 -0500 |
---|---|---|
committer | Nathan Bossart <nathan@postgresql.org> | 2024-07-31 10:12:41 -0500 |
commit | 23687e925f94e36d2d3172faa053f4540bfbb8d2 (patch) | |
tree | a4a3e80cae4dd0e58b1053f871f39506deba424a /src | |
parent | 057ee9183c2142f6ecd9035aa6b96c5509c18a27 (diff) | |
download | postgresql-23687e925f94e36d2d3172faa053f4540bfbb8d2.tar.gz postgresql-23687e925f94e36d2d3172faa053f4540bfbb8d2.zip |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/pg_dump/pg_dump.c | 104 | ||||
-rw-r--r-- | src/tools/pgindent/typedefs.list | 1 |
2 files changed, 61 insertions, 44 deletions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 2b02148559b..9c463137c05 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -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,51 +17342,40 @@ 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. */ if (!tbinfo->is_identity_sequence) @@ -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); diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index 3deb6113b80..343a8dae7da 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -2572,6 +2572,7 @@ SeqScan SeqScanState SeqTable SeqTableData +SeqType SerCommitSeqNo SerialControl SerialIOData |