I wrote:
> I've pushed this with minor additional twiddling. We can work on the
> "UI issues" you mentioned at leisure. One that I noted is that psql's
> version-mismatch-warning messages aren't two-part-version aware, and
> will print "10.0" where they should say "10". Probably that fix should
> get back-patched, so that older psql branches will do the right thing
> if possible.
Attached is a WIP patch for that. I've only fixed psql/command.c
so far, but I put the support logic into fe_utils since we're going
to need it in some other places too (pg_dump at least). Any objections
to this general approach?
regards, tom lane
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 9c0af4e..4aaf657 100644
*** a/src/bin/psql/command.c
--- b/src/bin/psql/command.c
*************** exec_command(const char *cmd,
*** 635,642 ****
if (pset.sversion < 80400)
{
! psql_error("The server (version %d.%d) does not support editing function source.\n",
! pset.sversion / 10000, (pset.sversion / 100) % 100);
status = PSQL_CMD_ERROR;
}
else if (!query_buf)
--- 635,645 ----
if (pset.sversion < 80400)
{
! char sverbuf[32];
!
! psql_error("The server (version %s) does not support editing function source.\n",
! formatPGVersionNumber(pset.sversion, false,
! sverbuf, sizeof(sverbuf)));
status = PSQL_CMD_ERROR;
}
else if (!query_buf)
*************** exec_command(const char *cmd,
*** 731,738 ****
if (pset.sversion < 70400)
{
! psql_error("The server (version %d.%d) does not support editing view definitions.\n",
! pset.sversion / 10000, (pset.sversion / 100) % 100);
status = PSQL_CMD_ERROR;
}
else if (!query_buf)
--- 734,744 ----
if (pset.sversion < 70400)
{
! char sverbuf[32];
!
! psql_error("The server (version %s) does not support editing view definitions.\n",
! formatPGVersionNumber(pset.sversion, false,
! sverbuf, sizeof(sverbuf)));
status = PSQL_CMD_ERROR;
}
else if (!query_buf)
*************** exec_command(const char *cmd,
*** 1362,1369 ****
OT_WHOLE_LINE, NULL, true);
if (pset.sversion < 80400)
{
! psql_error("The server (version %d.%d) does not support showing function source.\n",
! pset.sversion / 10000, (pset.sversion / 100) % 100);
status = PSQL_CMD_ERROR;
}
else if (!func)
--- 1368,1378 ----
OT_WHOLE_LINE, NULL, true);
if (pset.sversion < 80400)
{
! char sverbuf[32];
!
! psql_error("The server (version %s) does not support showing function source.\n",
! formatPGVersionNumber(pset.sversion, false,
! sverbuf, sizeof(sverbuf)));
status = PSQL_CMD_ERROR;
}
else if (!func)
*************** exec_command(const char *cmd,
*** 1441,1448 ****
OT_WHOLE_LINE, NULL, true);
if (pset.sversion < 70400)
{
! psql_error("The server (version %d.%d) does not support showing view definitions.\n",
! pset.sversion / 10000, (pset.sversion / 100) % 100);
status = PSQL_CMD_ERROR;
}
else if (!view)
--- 1450,1460 ----
OT_WHOLE_LINE, NULL, true);
if (pset.sversion < 70400)
{
! char sverbuf[32];
!
! psql_error("The server (version %s) does not support showing view definitions.\n",
! formatPGVersionNumber(pset.sversion, false,
! sverbuf, sizeof(sverbuf)));
status = PSQL_CMD_ERROR;
}
else if (!view)
*************** connection_warnings(bool in_startup)
*** 2014,2035 ****
if (!pset.quiet && !pset.notty)
{
int client_ver = PG_VERSION_NUM;
if (pset.sversion != client_ver)
{
const char *server_version;
- char server_ver_str[16];
/* Try to get full text form, might include "devel" etc */
server_version = PQparameterStatus(pset.db, "server_version");
if (!server_version)
{
! snprintf(server_ver_str, sizeof(server_ver_str),
! "%d.%d.%d",
! pset.sversion / 10000,
! (pset.sversion / 100) % 100,
! pset.sversion % 100);
! server_version = server_ver_str;
}
printf(_("%s (%s, server %s)\n"),
--- 2026,2046 ----
if (!pset.quiet && !pset.notty)
{
int client_ver = PG_VERSION_NUM;
+ char cverbuf[32];
+ char sverbuf[32];
if (pset.sversion != client_ver)
{
const char *server_version;
/* Try to get full text form, might include "devel" etc */
server_version = PQparameterStatus(pset.db, "server_version");
+ /* Otherwise fall back on pset.sversion */
if (!server_version)
{
! formatPGVersionNumber(pset.sversion, true,
! sverbuf, sizeof(sverbuf));
! server_version = sverbuf;
}
printf(_("%s (%s, server %s)\n"),
*************** connection_warnings(bool in_startup)
*** 2040,2049 ****
printf("%s (%s)\n", pset.progname, PG_VERSION);
if (pset.sversion / 100 > client_ver / 100)
! printf(_("WARNING: %s major version %d.%d, server major version %d.%d.\n"
" Some psql features might not work.\n"),
! pset.progname, client_ver / 10000, (client_ver / 100) % 100,
! pset.sversion / 10000, (pset.sversion / 100) % 100);
#ifdef WIN32
checkWin32Codepage();
--- 2051,2063 ----
printf("%s (%s)\n", pset.progname, PG_VERSION);
if (pset.sversion / 100 > client_ver / 100)
! printf(_("WARNING: %s major version %s, server major version %s.\n"
" Some psql features might not work.\n"),
! pset.progname,
! formatPGVersionNumber(client_ver, false,
! cverbuf, sizeof(cverbuf)),
! formatPGVersionNumber(pset.sversion, false,
! sverbuf, sizeof(sverbuf)));
#ifdef WIN32
checkWin32Codepage();
diff --git a/src/fe_utils/string_utils.c b/src/fe_utils/string_utils.c
index f986dbc..2c566b1 100644
*** a/src/fe_utils/string_utils.c
--- b/src/fe_utils/string_utils.c
*************** fmtQualifiedId(int remoteVersion, const
*** 169,174 ****
--- 169,212 ----
/*
+ * Format a Postgres version number (in the PG_VERSION_NUM integer format
+ * returned by PQserverVersion()) as a string. This exists mainly to
+ * encapsulate knowledge about two-part vs. three-part version numbers.
+ *
+ * For re-entrancy, caller must supply the buffer the string is put in.
+ * Recommended size of the buffer is 32 bytes.
+ *
+ * Returns address of 'buf', as a notational convenience.
+ */
+ char *
+ formatPGVersionNumber(int version_number, bool include_minor,
+ char *buf, size_t buflen)
+ {
+ if (version_number >= 100000)
+ {
+ /* New two-part style */
+ if (include_minor)
+ snprintf(buf, buflen, "%d.%d", version_number / 10000,
+ version_number % 10000);
+ else
+ snprintf(buf, buflen, "%d", version_number / 10000);
+ }
+ else
+ {
+ /* Old three-part style */
+ if (include_minor)
+ snprintf(buf, buflen, "%d.%d.%d", version_number / 10000,
+ (version_number / 100) % 100,
+ version_number % 100);
+ else
+ snprintf(buf, buflen, "%d.%d", version_number / 10000,
+ (version_number / 100) % 100);
+ }
+ return buf;
+ }
+
+
+ /*
* Convert a string value to an SQL string literal and append it to
* the given buffer. We assume the specified client_encoding and
* standard_conforming_strings settings.
diff --git a/src/include/fe_utils/string_utils.h b/src/include/fe_utils/string_utils.h
index 7bbed36..452ffc0 100644
*** a/src/include/fe_utils/string_utils.h
--- b/src/include/fe_utils/string_utils.h
*************** extern const char *fmtId(const char *ide
*** 30,35 ****
--- 30,38 ----
extern const char *fmtQualifiedId(int remoteVersion,
const char *schema, const char *id);
+ extern char *formatPGVersionNumber(int version_number, bool include_minor,
+ char *buf, size_t buflen);
+
extern void appendStringLiteral(PQExpBuffer buf, const char *str,
int encoding, bool std_strings);
extern void appendStringLiteralConn(PQExpBuffer buf, const char *str,
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers