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 (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to